Skip to content

fix(crew-state): gate terminal PR read on real gh state#404

Open
lukeforshort wants to merge 4 commits into
kunchenguid:mainfrom
lukeforshort:fm/crewstate-terminal-fix-a2
Open

fix(crew-state): gate terminal PR read on real gh state#404
lukeforshort wants to merge 4 commits into
kunchenguid:mainfrom
lukeforshort:fm/crewstate-terminal-fix-a2

Conversation

@lukeforshort

Copy link
Copy Markdown

Intent

Fix false-terminal read in bin/fm-crew-state.sh: gate the 'passed: merged/closed' report on real gh PR state instead of inferring it from a no-mistakes outcome label that also covers checks-passed-awaiting-merge, so supervision never ends on unlanded work.

What Changed

  • Gated fm-crew-state.sh's outcome=passed terminal reading on a direct gh pr view check via a new pr_landed_state helper: merged/closed reports done, an open PR reports working (unlanded, awaiting merge), and an unresolvable/gh-unavailable state degrades to done (merge state unverified), so supervision is never ended on unlanded work by a false terminal label. Refactored the bounded no-mistakes runner into a generic run_bounded reused for the gh call.
  • Hardened fm-watch.sh singleton-lock release by adding explicit TERM/INT/HUP traps alongside the existing EXIT trap, so a checkpoint killed by timeout's SIGTERM deterministically frees the lock instead of leaving a stale "already running" holder.
  • Hardened fm-crew-state, fm-session-start, and fm-dispatch-select tests against environment assumptions and synced AGENTS.md, CONTRIBUTING.md, and the docs/ references for the gh-gated terminal read.

Risk Assessment

✅ Low: A tightly-scoped, well-tested fix that adds a real gh state check before a terminal supervision read, is safe by construction (open→working, unverifiable→done-without-merged-claim), backstopped by teardown's own landed-work verification, and introduces no correctness regressions.

Testing

Completed 1 recorded test check.

  • Outcome: ⚠️ 1 error across 4 runs (1h4m46s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 2 infos
  • ℹ️ bin/fm-crew-state.sh:508 - During the passed-but-still-open awaiting-merge window, every fm-crew-state.sh read for that crew now issues a bounded gh pr view API call (previously the outcome=passed path was purely log/pane-local). The watcher already runs a dedicated merge-detection poll (fm-pr-check's check.sh), so this is somewhat redundant network work on the supervision read path. It is bounded by NM_TIMEOUT (10s) and only fires on outcome=passed, so it is acceptable, but worth being aware of if crew-state read frequency grows.
  • ℹ️ bin/fm-crew-state.sh:511 - When gh is unavailable/unauthenticated the outcome=passed path degrades to done (merge state unverified), i.e. the pre-fix behavior of reading a possibly-open PR as terminal. This is a deliberate, documented tradeoff and is backstopped by fm-teardown.sh's independent landed-work check, so unlanded work still cannot be torn down; noting it only so the protection's dependence on gh availability is explicit.
⚠️ **Test** - 1 error
  • 🚨 tests failed with exit code 1
  • command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"

🔧 Fix: harden session-start and dispatch-select tests against env assumptions
1 error still open:

  • 🚨 tests failed with exit code 1
  • command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"

🔧 Fix: crew-state tests pass; remaining failures are herdr-env and flaky watcher-lock
1 error still open:

  • 🚨 tests failed with exit code 1
  • command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"

🔧 Fix: release watcher singleton lock on terminating signals, not just EXIT
1 error still open:

  • 🚨 tests failed with exit code 1
  • command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

outcome=passed was read as a terminal "run passed: PR merged/closed", but
no-mistakes reports passed while a PR is still open and unmerged
(mgmt-audit 2026-07-10, finding B4/L1). That false terminal can end
supervision of unlanded work.

Confirm merged/closed with a direct, bounded gh read before reporting the
terminal state: an open PR reads as non-terminal working (awaiting merge),
a merged or closed PR stays terminal done, and an unverifiable PR reports
done without claiming merged/closed. Adds regression coverage for all
three paths.
@kunchenguid

kunchenguid commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Thanks for the PR! This branch currently has a merge conflict with the base branch.

When you get a chance, please rebase onto (or merge) the latest base branch, resolve the conflict, and push. After that, checks will re-run and the PR will get looked at again.

Noted for firstmate#404 at a93bc007.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants