fix: sync upstream fixes for fleet safety and x-mode reliability#18
Merged
Conversation
…uid#518) * feat: contain no-mistakes gate agents from driving the fleet Add bin/fm-gate-refuse-lib.sh, sourced at the top of fm-spawn/fm-send/ fm-teardown before any fleet mutation. It fails closed when NO_MISTAKES_GATE is set, and via an unspoofable git-common-dir backstop when invoked from a no-mistakes gate worktree (.no-mistakes/repos/*.git) even with the marker unset. A normal firstmate session has neither signal and is unaffected. Set disable_project_settings: true in the tracked .no-mistakes.yaml so the installed pipeline neutralizes gate agents' project instructions for this repo (trusted-only, honored from the default branch). firstmate's own suite runs from a gate worktree during validation, so the shared test helpers set FM_GATE_REFUSE_BYPASS=1 to exempt it; the dedicated tests/fm-gate-refuse.test.sh strips it to verify real refusal. * no-mistakes(review): Captain, refuse empty no-mistakes gate markers * no-mistakes(document): Document no-mistakes gate authority boundary
…uid#505) * fix: guard secondmate own-home turn ends Remove the .fm-secondmate-home early-exit in fm-turnend-guard.sh so the 'no turn ends blind' backstop fires in a secondmate's own primary session, matching the cd-guard's scope: the own home is guarded, child crew/scout worktrees stay exempt via the retained git-dir/git-common-dir test. This was pure scoping from the guard's primary-only origin and guarded against no secondmate-specific hazard. Add secondmate regression tests (blind-turn block, idle-by-default, stop_hook_active loop guard, deferred-death recovery loop, child-worktree exemption) and record the autonomous background-notify re-invoke measurement (Claude Code 2.1.207, 11s) in docs/turnend-guard.md. * no-mistakes(document): Correct secondmate guard documentation, captain * fix: force-include marked secondmate homes in turn-end guard The prior remove-only form (just deleting the .fm-secondmate-home check) left the DEFAULT secondmate topology unguarded: a treehouse-leased home is a linked git worktree (git-dir != git-common-dir), which the retained git-dir exemption still skipped, so its own primary session could still end a turn blind. Invert the marker: a genuinely-marked home is force-included as a guarded primary (treehouse-leased linked OR git-cloned plain), and the git-dir exemption applies only to UNMARKED child worktrees. Marker validation (regular non-symlink file, non-empty id-token content) blocks a stray or empty marker from spoofing inclusion. Add real linked-worktree regression tests: a treehouse-leased LINKED secondmate home is guarded, a stray/empty marker stays exempt, and the unmarked child worktree stays exempt - the topology the plain git-init fixtures masked. Predicates, in-flight gate, and loop guard untouched. * fix: force ASCII collation in secondmate marker validation Add a function-scoped local LC_ALL=C in fm_root_is_secondmate_home so the [A-Za-z0-9._-] id allowlist matches under C collation, not the ambient locale - a locale-crafted non-ASCII marker id can no longer slip through the range match and spoof force-inclusion of a linked child worktree. Add a regression test proving a non-ASCII marker id is rejected and the linked worktree stays exempt. * no-mistakes(test): fix backend baseline gate-refusal dependency * no-mistakes(document): Correct secondmate turn-end guard documentation
* fix: make bootstrap required-tool detection backend-aware Bootstrap demanded tmux and treehouse for every backend except orca, so a herdr/zellij/cmux home with tmux absent was wrongly told MISSING: tmux. Required tools now follow the resolved backend via the single-owner fm_backend_required_tools helper (bin/fm-backend.sh): each backend's own session-provider CLI, jq for the JSON-emitting adapters (herdr/zellij/cmux), and treehouse for session-provider-only backends (orca owns its worktree). The treehouse lease-support check is gated to backends that use treehouse. Adds install hints for herdr/zellij/cmux, regression tests for the full backend dependency matrix (herdr-without-tmux repro plus each boundary), and updates the authoritative Toolchain docs. * no-mistakes(review): Captain, prevent executing Herdr install guidance * no-mistakes(review): Captain, harden backend-aware bootstrap diagnostics * no-mistakes(review): Captain, separate manual dependency remediation * no-mistakes(review): Captain, align bootstrap diagnostic consumers * no-mistakes(document): Align backend adapter dependency comments
…guid#520) * fix: recover X/Discord follow-up platform after inbox cleanup A milestone follow-up posted directly by request_id after the inbox was drained - and with no task link, because one persistent secondmate's single x_request slot collides across concurrent requests - resolved platform only from the local inbox, so a >280 Discord reply silently defaulted to the X 280-char budget and threaded as (1/2). - fm-x-poll records a durable per-request reply context (state/x-context/<rid>.json) at stash time, keyed by request_id so concurrent requests never overwrite each other; it survives inbox cleanup and restart. - fm-x-reply resolves platform/budget through registry -> inbox -> relay (the relay lookup confined to a live follow-up), recovering the original platform independent of task-link availability. - Fail-safe: a follow-up whose platform/budget cannot be authoritatively resolved and that would split is refused (exit 8) and held for retry, never wrongly split; fm-x-followup keeps the link on that exit. - fm-x-dismiss clears the durable context for a dismissed mention. Refactors reply-context extraction into a single owner and adds regression coverage for all four cases. * no-mistakes(review): Captain, fail closed on incomplete follow-up context * no-mistakes(review): Captain, bound X context registry retention * no-mistakes(review): Captain, align context retention with answer binding * no-mistakes(document): Align X follow-up context documentation * no-mistakes(document): Align durable X follow-up documentation
…id#533) * fix: preserve secondmate routing markers * no-mistakes(review): Captain, preserve trailing newlines in marked secondmate sends * no-mistakes(test): Captain, tolerate bootstrap timeout elapsed drift * no-mistakes(document): Refresh Herdr marker documentation
* fix: align grok effort docs and spawn with 0.2.99 ceiling grok 0.2.99 accepts only low|medium|high for --reasoning-effort and rejects both xhigh and max. Omit unsupported values on spawn, flag them in crew-dispatch validation, and update harness-adapters. * no-mistakes(test): Captain: refresh gotmp teardown fixture dependencies * no-mistakes(document): Clarify Grok effort documentation ownership
Merged upstream/main through 8c0d9eb (six commits after ad9f3a7). Integration report: - popup-risk unknown hard-fail + idle-to-busy probe: survived/re-applied in bin/fm-send.sh. Evidence: grep found the idle-to-busy comments, pre/post fm_backend_busy_state reads, and the 'could not be verified' hard-fail; tests/fm-send-popup-settle.test.sh passed twice, including 'codex $skill over herdr fails loudly on unknown submit verification'. - secondmate routing markers: re-applied with upstream's idempotent fm_message_mark_from_firstmate transformation while preserving fork ack tracking and popup verification. Evidence: tests/fm-send-secondmate-marker.test.sh and tests/fm-send-popup-settle.test.sh passed twice. - fleet freeze refusal: survived and now coexists with upstream gate refusal. Evidence: grep found fm_fleet_freeze_refuse in fm-watch.sh, fm-send.sh, fm-spawn.sh, fm-watch-arm.sh, and fm-supervise-daemon.sh; tests/fm-freeze.test.sh passed twice. - AGENTS.md judgment criteria and yolo routine definition: survived. Evidence: grep found the yolo relaxation, routine internal-churn line, and routine approval criteria in AGENTS.md; turn-end/secondmate doc overlaps resolved without dropping those lines. - FM_NO_MISTAKES_PROBE_TIMEOUT: survived/re-applied in backend-aware bootstrap diagnostics. Evidence: grep found FM_NO_MISTAKES_PROBE_TIMEOUT in bin/fm-bootstrap.sh and tests/fm-bootstrap.test.sh; tests/fm-bootstrap.test.sh passed twice. - secondmate blind turn-end guard: upstream behavior kept. Evidence: tests/fm-turnend-guard.test.sh passed twice, including secondmate-home blind-turn-end cases. - no-mistakes gate fleet-drive guard: upstream behavior kept and combined with fork fleet-freeze guards. Evidence: tests/fm-gate-refuse.test.sh passed twice; .no-mistakes.yaml includes disable_project_settings: true. - cleanup during validation: fixed bin/fm-crew-state.sh typo from nonexistent log_note_of to status_line_note after the first full test pass exposed noisy stderr; focused rerun and second full pass were clean. Verification: - git fetch upstream; git log origin/main..upstream/main showed exactly 6556882, 2364817, 547acd7, b708731, 85b7a29, 8c0d9eb. - bash -n bin/fm-send.sh bin/fm-spawn.sh bin/fm-bootstrap.sh bin/fm-watch.sh. - Full tests/*.test.sh passed, then after the crew-state typo fix the full tests/*.test.sh loop was rerun and passed again. Skips observed: cmux socket unavailable, zellij not installed, FM_PI_LIVE_E2E unset, tsc not found, tasks-axi below atomic multi-ID mv support, FM_SEND_MARKER_HERDR_E2E unset. - bin/fm-lint.sh passed under pinned ShellCheck 0.11.0. - git diff --cached --check passed.
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
Follow-up upstream sync: merge all remaining commits from kunchenguid/firstmate upstream/main into the fork on a true merge commit without rebasing. Preserve the fork-restored guardrails while taking upstream behavior: fm-send popup-risk unknown hard-fail plus idle-to-busy proof, secondmate routing markers in terminal sends, fleet freeze refusal on watcher/send/spawn paths, AGENTS.md yolo/judgment criteria including the routine definition, and FM_NO_MISTAKES_PROBE_TIMEOUT in backend-aware bootstrap diagnostics. Resolve conflicts semantically, include an honest integration report in the merge commit body, and validate with full tests/*.test.sh plus pinned ShellCheck.
What Changed
bin/fm-gate-refuse-lib.shand wired fleet-freeze refusal into watcher, send, and spawn paths; blocked no-mistakes gate agents from driving the fleetFM_NO_MISTAKES_PROBE_TIMEOUT), aligned Grok effort handling with 0.2.99, and expanded coverage acrossfm-bootstrap,fm-gate-refuse,fm-turnend-guard, andfm-x-modetestsRisk Assessment
✅ Low: This is a true merge of six well-scoped upstream commits into the fork; every changed script parses cleanly, cross-file contracts (fm_meta_get, status_line_note rename, exit-code 8 handling between fm-x-reply.sh and fm-x-followup.sh, fm_backend_required_tools wiring into bootstrap) are internally consistent, docs were updated in lockstep with code, and the fork-specific guardrails (popup-risk hard-fail/idle-to-busy proof, secondmate routing markers, fleet-freeze refusal, AGENTS.md yolo criteria, FM_NO_MISTAKES_PROBE_TIMEOUT) are verifiably still present alongside the new upstream behavior (gate-agent fleet-drive refusal, backend-aware bootstrap diagnostics, durable X-mode reply-context registry, secondmate turn-end guard coverage).
Testing
Ran the full tests/*.test.sh suite (75 files) fresh against the merge commit (3af4934) with tmux 3.6a present - all 75 passed with zero failures in about 15.5 minutes, matching the merge commit's own claimed second full pass result. I then independently grepped the actual current source, not just the commit message, for each guardrail the user intent called out: fm-send.sh still has the idle-to-busy busy-state snapshot/recheck and the could-not-be-verified popup-risk hard-fail; fm-marker-lib.sh still carries the secondmate from-firstmate marker/ack machinery; fm_fleet_freeze_refuse is wired into fm-send.sh, fm-spawn.sh, fm-watch.sh, fm-watch-arm.sh, fm-supervise-daemon.sh, and fm-reconcile-stale.sh; AGENTS.md still contains the yolo routine-definition clause and the judgment criteria; and FM_NO_MISTAKES_PROBE_TIMEOUT is wired through fm-bootstrap.sh, its test, and docs/configuration.md. Skipped the pinned-ShellCheck lint pass the merge commit also claims, per this task's explicit rule against running linters or static analysis tools - that is the one piece of the author's stated verification not independently redone.
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
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"full loop: for t in tests/*.test.sh; do bash $t; done -- 75/75 passed, covering fm-send-popup-settle.test.sh, fm-send-secondmate-marker.test.sh, fm-freeze.test.sh, fm-bootstrap.test.sh, fm-gate-refuse.test.sh, fm-turnend-guard.test.sh and 69 other filesgrep -n for idle-to-busy/popup hard-fail text in bin/fm-send.shgrep -n for fm_fleet_freeze_refuse across bin/*.shgrep -n for yolo/routine clauses in AGENTS.mdgrep -rn for FM_NO_MISTAKES_PROBE_TIMEOUT across bin/, tests/, docs/git status --short to confirm no stray test artifacts left in the worktree✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.