fix: suppress false wedges for held green PRs - #116
Open
ruby-dlee wants to merge 3 commits into
Open
Conversation
ruby-dlee
force-pushed
the
fm/pause-vs-orphan-run-p6
branch
from
August 12, 2026 13:14
c9e06ca to
d9a2045
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Stop supervision from repeatedly wedge-escalating a lane that has finished, opened a green PR, and deliberately declared a pause because merge is held for a captain decision, while preserving the load-bearing rule that genuinely active authoritative working state outranks a stale pause and must still wedge-escalate. The implemented discriminator is conjunctive: the checks-green done event must be the immediately preceding non-empty status before the current pause, the ci log must be unknown with no newer re-arm or fixing marker, and the bounded liveness observation must specifically say the recorded run has no worktree. Treat that as heuristic corroboration, not a death verdict or abort authority; it could misclassify if a genuinely active CI run becomes undiscoverable while those adjacent stale events remain and its CI log is unavailable. Prove the negative direction explicitly: test_ci_pause_does_not_hide_a_real_active_run keeps positive work authoritative, and test_paused_authoritative_working_preserves_wedge_timer proves the watcher still escalates a real wedge. Do not claim to fix the no-mistakes lifecycle: the run itself still lacks a clean terminal state at the CI-ready point and can keep monitoring a held PR after its base moves; this change only suppresses the resulting false supervision alarm. The PR body must state this discriminator, its heuristic/misfire boundary, the named negative tests, and the remaining run-lifecycle defect so the alarm fix does not hide it.
What Changed
done, the CI log is unknown with no newer re-arm/fixing marker, and bounded liveness reports that the recorded run has no worktree.test_ci_pause_does_not_hide_a_real_active_runandtest_paused_authoritative_working_preserves_wedge_timer, while isolating crosscheck evidence from provider credentials and bounding tmux smoke-test socket paths.Risk Assessment
Testing
The configured baseline and targeted tests passed, real CLI transcripts demonstrate suppression and preserved escalation, the worktree remains clean at the target commit, and only the future PR-body requirement remains unverifiable because no PR exists yet.
Evidence: Crew-state CLI matrix
CASE 1: exact orphan conjunction → paused CASE 2: live processes → working CASE 3: newer CI re-arm → working CASE 4: non-adjacent checks-green → workingEvidence: Preserved wedge escalation
stale: test:fm-paused-working (idle 501s, possible wedge, escalation 1)Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ No issues found.
command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; base=$(mktemp -d); mdir="$base/manifests"; mkdir -p "$mdir"; pids=""; for s in 1 2 3 4 5 6 7 8; do ( TMPDIR="$base/$s/tmp"; TMUX_TMPDIR="$base/$s/tmux"; export TMPDIR TMUX_TMPDIR; mkdir -p "$TMPDIR" "$TMUX_TMPDIR"; bin/fm-behavior-shards.sh --run "$s" 8 "$mdir/executed-$s.tsv" >"$base/shard-$s.log" 2>&1 ) & pids="$pids $!"; done; for p in $pids; do wait "$p" || rc=1; done; for s in 1 2 3 4 5 6 7 8; do echo "== behavior shard $s/8 =="; cat "$base/shard-$s.log"; done; bin/fm-behavior-shards.sh --verify 8 "$mdir" || rc=1; rm -rf "$base"; uv run --directory tools/agent-fleet --locked pytest || rc=1; uv run --directory tools/agent-fleet --locked python -m compileall -q src || rc=1; exit "$rc"🔧 Fix: Leave code unchanged; failures are environment-contaminated
1 error still open:
command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; base=$(mktemp -d); mdir="$base/manifests"; mkdir -p "$mdir"; pids=""; for s in 1 2 3 4 5 6 7 8; do ( TMPDIR="$base/$s/tmp"; TMUX_TMPDIR="$base/$s/tmux"; export TMPDIR TMUX_TMPDIR; mkdir -p "$TMPDIR" "$TMUX_TMPDIR"; bin/fm-behavior-shards.sh --run "$s" 8 "$mdir/executed-$s.tsv" >"$base/shard-$s.log" 2>&1 ) & pids="$pids $!"; done; for p in $pids; do wait "$p" || rc=1; done; for s in 1 2 3 4 5 6 7 8; do echo "== behavior shard $s/8 =="; cat "$base/shard-$s.log"; done; bin/fm-behavior-shards.sh --verify 8 "$mdir" || rc=1; rm -rf "$base"; uv run --directory tools/agent-fleet --locked pytest || rc=1; uv run --directory tools/agent-fleet --locked python -m compileall -q src || rc=1; exit "$rc"🔧 Fix: Captain, leave code unchanged; failures are environment-contaminated
1 error still open:
command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; base=$(mktemp -d); mdir="$base/manifests"; mkdir -p "$mdir"; pids=""; for s in 1 2 3 4 5 6 7 8; do ( TMPDIR="$base/$s/tmp"; TMUX_TMPDIR="$base/$s/tmux"; export TMPDIR TMUX_TMPDIR; mkdir -p "$TMPDIR" "$TMUX_TMPDIR"; bin/fm-behavior-shards.sh --run "$s" 8 "$mdir/executed-$s.tsv" >"$base/shard-$s.log" 2>&1 ) & pids="$pids $!"; done; for p in $pids; do wait "$p" || rc=1; done; for s in 1 2 3 4 5 6 7 8; do echo "== behavior shard $s/8 =="; cat "$base/shard-$s.log"; done; bin/fm-behavior-shards.sh --verify 8 "$mdir" || rc=1; rm -rf "$base"; uv run --directory tools/agent-fleet --locked pytest || rc=1; uv run --directory tools/agent-fleet --locked python -m compileall -q src || rc=1; exit "$rc"🔧 Fix: Leave code unchanged; failures reproduce on pristine main
1 error still open:
command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; base=$(mktemp -d); mdir="$base/manifests"; mkdir -p "$mdir"; pids=""; for s in 1 2 3 4 5 6 7 8; do ( TMPDIR="$base/$s/tmp"; TMUX_TMPDIR="$base/$s/tmux"; export TMPDIR TMUX_TMPDIR; mkdir -p "$TMPDIR" "$TMUX_TMPDIR"; bin/fm-behavior-shards.sh --run "$s" 8 "$mdir/executed-$s.tsv" >"$base/shard-$s.log" 2>&1 ) & pids="$pids $!"; done; for p in $pids; do wait "$p" || rc=1; done; for s in 1 2 3 4 5 6 7 8; do echo "== behavior shard $s/8 =="; cat "$base/shard-$s.log"; done; bin/fm-behavior-shards.sh --verify 8 "$mdir" || rc=1; rm -rf "$base"; uv run --directory tools/agent-fleet --locked pytest || rc=1; uv run --directory tools/agent-fleet --locked python -m compileall -q src || rc=1; exit "$rc"🔧 Fix: Confirm targeted pause regressions pass unchanged
1 error still open:
command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; base=$(mktemp -d); mdir="$base/manifests"; mkdir -p "$mdir"; pids=""; for s in 1 2 3 4 5 6 7 8; do ( TMPDIR="$base/$s/tmp"; TMUX_TMPDIR="$base/$s/tmux"; export TMPDIR TMUX_TMPDIR; mkdir -p "$TMPDIR" "$TMUX_TMPDIR"; bin/fm-behavior-shards.sh --run "$s" 8 "$mdir/executed-$s.tsv" >"$base/shard-$s.log" 2>&1 ) & pids="$pids $!"; done; for p in $pids; do wait "$p" || rc=1; done; for s in 1 2 3 4 5 6 7 8; do echo "== behavior shard $s/8 =="; cat "$base/shard-$s.log"; done; bin/fm-behavior-shards.sh --verify 8 "$mdir" || rc=1; rm -rf "$base"; uv run --directory tools/agent-fleet --locked pytest || rc=1; uv run --directory tools/agent-fleet --locked python -m compileall -q src || rc=1; exit "$rc"🔧 Fix: Bound tmux smoke socket path
1 error still open:
command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; base=$(mktemp -d); mdir="$base/manifests"; mkdir -p "$mdir"; pids=""; for s in 1 2 3 4 5 6 7 8; do ( TMPDIR="$base/$s/tmp"; TMUX_TMPDIR="$base/$s/tmux"; export TMPDIR TMUX_TMPDIR; mkdir -p "$TMPDIR" "$TMUX_TMPDIR"; bin/fm-behavior-shards.sh --run "$s" 8 "$mdir/executed-$s.tsv" >"$base/shard-$s.log" 2>&1 ) & pids="$pids $!"; done; for p in $pids; do wait "$p" || rc=1; done; for s in 1 2 3 4 5 6 7 8; do echo "== behavior shard $s/8 =="; cat "$base/shard-$s.log"; done; bin/fm-behavior-shards.sh --verify 8 "$mdir" || rc=1; rm -rf "$base"; uv run --directory tools/agent-fleet --locked pytest || rc=1; uv run --directory tools/agent-fleet --locked python -m compileall -q src || rc=1; exit "$rc"🔧 Fix: Captain, isolate crosscheck evidence from provider credentials
1 error still open:
command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; base=$(mktemp -d); mdir="$base/manifests"; mkdir -p "$mdir"; pids=""; for s in 1 2 3 4 5 6 7 8; do ( TMPDIR="$base/$s/tmp"; TMUX_TMPDIR="$base/$s/tmux"; export TMPDIR TMUX_TMPDIR; mkdir -p "$TMPDIR" "$TMUX_TMPDIR"; bin/fm-behavior-shards.sh --run "$s" 8 "$mdir/executed-$s.tsv" >"$base/shard-$s.log" 2>&1 ) & pids="$pids $!"; done; for p in $pids; do wait "$p" || rc=1; done; for s in 1 2 3 4 5 6 7 8; do echo "== behavior shard $s/8 =="; cat "$base/shard-$s.log"; done; bin/fm-behavior-shards.sh --verify 8 "$mdir" || rc=1; rm -rf "$base"; uv run --directory tools/agent-fleet --locked pytest || rc=1; uv run --directory tools/agent-fleet --locked python -m compileall -q src || rc=1; exit "$rc"🔧 Fix: Leave code unchanged; isolate macOS Keychain timeout
1 warning still open:
fm/pause-vs-orphan-run-p6. Before delivery, the outer PR phase must verify the body states the conjunctive discriminator, heuristic/misfire boundary, both named negative tests, and remaining no-mistakes lifecycle defect.command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; base=$(mktemp -d); mdir="$base/manifests"; mkdir -p "$mdir"; pids=""; for s in 1 2 3 4 5 6 7 8; do ( TMPDIR="$base/$s/tmp"; TMUX_TMPDIR="$base/$s/tmux"; export TMPDIR TMUX_TMPDIR; mkdir -p "$TMPDIR" "$TMUX_TMPDIR"; bin/fm-behavior-shards.sh --run "$s" 8 "$mdir/executed-$s.tsv" >"$base/shard-$s.log" 2>&1 ) & pids="$pids $!"; done; for p in $pids; do wait "$p" || rc=1; done; for s in 1 2 3 4 5 6 7 8; do echo "== behavior shard $s/8 =="; cat "$base/shard-$s.log"; done; bin/fm-behavior-shards.sh --verify 8 "$mdir" || rc=1; rm -rf "$base"; uv run --directory tools/agent-fleet --locked pytest || rc=1; uv run --directory tools/agent-fleet --locked python -m compileall -q src || rc=1; exit "$rc"Configured behavior-shard, agent-fleet pytest, and compileall baseline (already passed).tests/fm-crew-state.test.shFocusedtest_paused_authoritative_working_preserves_wedge_timerfromtests/fm-watch-triage.test.sh.Hermetic real-CLIbin/fm-crew-state.shmatrix covering exact orphan corroboration, live-process precedence, newer CI re-arm precedence, and status adjacency.~/.local/bin/gh-axi api '/repos/ruby-dlee/firstmate/pulls?head=ruby-dlee:fm/pause-vs-orphan-run-p6'✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.