fix: fail-closed fm-send targets and herdr AFK escalation delivery - #2
Merged
Merged
Conversation
* Make fm-send fail loudly on unresolved targets * no-mistakes(review): Document fm-send FM_HOME contract * Fix fm-send readiness docs and backend send path * Fix fm-send docs for cmux and X skill metadata * Make gotmp teardown test home-explicit * Scope watcher warning wording to fm-send * Fix fm-send review findings * Verify explicit tmux targets before sending * Isolate turnend guard test home * no-mistakes(document): Documented fm-send FM_HOME/backend guard additions missing from doc inventories --------- Co-authored-by: mielyemitchell <249051873+mielyemitchell@users.noreply.github.com>
* fix afk codex ghost composer delivery * no-mistakes(review): Harden AFK startup flag writes * no-mistakes(review): Harden AFK daemon liveness checks * no-mistakes(document): Sync AFK herdr docs * no-mistakes: apply CI fixes * no-mistakes: apply CI fixes
There was a problem hiding this comment.
Pull request overview
Captain, this PR tightens fm-send so it fails closed on ambiguous/unscoped targets (requiring an explicit FM_HOME) and improves away-mode (/afk) escalation delivery when the supervisor pane is managed via herdr, including a new tracked foreground entrypoint for the daemon.
Changes:
- Make
bin/fm-send.shrequireFM_HOMEand refuse unresolved selectors instead of guessing a tmux window, with clearer failure reporting and explicit-endpoint liveness verification. - Add
bin/fm-afk-start.shto start (or reuse) the away-mode supervisor daemon safely, and improve daemon lock identity tracking to avoid stale/reused-pid false positives. - Improve herdr composer detection using ANSI capture so faint Codex “ghost suggestions” don’t block away-mode escalation injection; update docs/tests accordingly.
Reviewed changes
Copilot reviewed 23 out of 33 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/fm-watcher-lock.test.sh | Asserts the generic guard banner continuation line and ensures fm-send-specific wording only appears when set by fm-send. |
| tests/fm-turnend-guard.test.sh | Sets FM_HOME when invoking the turn-end guard and tightens shellcheck directives for hermetic tests. |
| tests/fm-send-strict.test.sh | New unit tests pinning strict fm-send target resolution and fail-closed behaviors (missing FM_HOME, unresolved selectors, etc.). |
| tests/fm-gotmp.test.sh | Ensures teardown tests run with FM_HOME to match the newer home-scoping behavior. |
| tests/fm-daemon.test.sh | Adds coverage for fm-afk-start.sh lifecycle behaviors and updates fm-send test invocations to include FM_HOME. |
| tests/fm-backend.test.sh | Updates old-vs-new conformance testing to account for tmux explicit-target preflight without changing core send semantics. |
| tests/fm-backend-zellij.test.sh | Sets FM_HOME for fm-send invocations in zellij backend tests. |
| tests/fm-backend-orca.test.sh | Sets FM_HOME and adjusts fixtures so Orca send verification passes through the updated send path. |
| tests/fm-backend-herdr.test.sh | Adds ANSI-aware composer-state regressions (faint vs non-faint Codex suggestions) and updates FM_HOME usage for send tests. |
| docs/zellij-backend.md | Documents FM_HOME=... bin/fm-send.sh ... for routine supervision from an active firstmate session. |
| docs/tmux-backend.md | Updates supervision guidance to include explicit FM_HOME for fm-send. |
| docs/scripts.md | Documents FM_GUARD_CONTINUE_LINE and updates script descriptions for strict fm-send + ANSI-aware herdr behavior + new fm-afk-start.sh. |
| docs/orca-backend.md | Updates routine supervision examples to include explicit FM_HOME for fm-send. |
| docs/herdr-backend.md | Adds/updates incident documentation and records the ANSI-capture-based resolution for Codex ghost suggestions impacting AFK injection. |
| docs/configuration.md | Clarifies FM_HOME behavior and explicitly documents that fm-send requires FM_HOME; documents FM_GUARD_CONTINUE_LINE. |
| docs/cmux-backend.md | Updates routine supervision examples to include explicit FM_HOME for fm-send and clarifies cmux capture limitations vs herdr ANSI. |
| docs/architecture.md | Updates architecture notes to reflect fm-afk-start.sh and ANSI-aware herdr composer classification in the daemon injection path. |
| CONTRIBUTING.md | Adds/updates test list entries to include the new strict fm-send test and expanded daemon/herdr coverage notes. |
| bin/fm-supervise-daemon.sh | Writes pid-identity into the daemon lock to improve live/false-positive discrimination (reused PID protection). |
| bin/fm-spawn.sh | Adds --help handling/usage output without affecting normal spawn behavior. |
| bin/fm-send.sh | Implements strict FM_HOME requirement, fail-closed target resolution, explicit endpoint verification, and clearer backend send failure reporting. |
| bin/fm-promote.sh | Updates the suggested “next” instruction to include FM_HOME=... bin/fm-send.sh ... for the promoted task. |
| bin/fm-guard.sh | Adds configurable continuation line via FM_GUARD_CONTINUE_LINE and prints it in the watcher-down banner. |
| bin/fm-brief.sh | Adds --help handling/usage output without affecting normal brief scaffolding. |
| bin/fm-afk-start.sh | New helper to enter away mode and start/reuse the supervise daemon via identity-backed locking in a harness-tracked foreground process. |
| bin/backends/tmux.sh | Preflights explicit tmux targets for --key sends via display-message before send-keys. |
| bin/backends/herdr.sh | Adds ANSI capture + stripping helpers and uses faint-style detection to treat Codex ghost suggestions as empty in composer-state. |
| bin/backends/cmux.sh | Clarifies capture constraints (no ANSI channel) relative to herdr’s ANSI path; retains border-row structural approach. |
| AGENTS.md | Documents that fm-send is intentionally stricter (requires FM_HOME) and updates various guidance snippets accordingly. |
| .agents/skills/updatefirstmate/SKILL.md | Updates secondmate nudge command examples to include explicit FM_HOME. |
| .agents/skills/stuck-crewmate-recovery/SKILL.md | Updates recovery playbook examples to include FM_HOME for fm-send usage. |
| .agents/skills/harness-adapters/SKILL.md | Updates trust-dialog acceptance instructions to include explicit FM_HOME for fm-send. |
| .agents/skills/afk/SKILL.md | Switches away-mode start instructions to bin/fm-afk-start.sh and updates the verification model explanation for herdr/tmux. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
What Changed
fm-sendtarget resolution: fail loudly on unresolvable send targets instead of guessing a tmux window;FM_HOMEis required and resolution is fail-closed (fix(fm-send): fail loudly on unresolvable send targets kunchenguid/firstmate#254).bin/fm-afk-start.shand routes away-mode escalations through the herdr supervisor path (fix: deliver AFK escalations through herdr supervisors kunchenguid/firstmate#353).state/.afkwith no daemon managing wakes.Note: this recreates upstream PR kunchenguid#437 against the fork. That PR's diff bundled 12 fork-only commits (cursor/hermes adapters, watchdog metrics, etc.) because it was opened against upstream main; those are already on this fork's main and are not part of this PR. This PR is exactly the branch's own delta vs fork main.
Risk Assessment
Low-medium: bounded lifecycle changes to fm-send resolution and AFK escalation delivery, validated through the full local pipeline.
Validation (no-mistakes run 01KX6VF6598SAPAVG29ME7Z6S0)
bin/fm-watchdog-lib.sh(session-id path traversal; session source attribution) - pre-existing code on both fork main and upstream main, untouched by this diff; carried to the watchdog/producer branch work.