feat(send): route secondmate replies for firstmate requests#93
Merged
Conversation
fm-send now prepends a distinct from-firstmate marker (new bin/fm-marker-lib.sh: the label [fm-from-firstmate] followed by ASCII unit separator 0x1f) when the resolved target is a bare fm-<id> whose meta records kind=secondmate. The marker reuses the afk untypable-separator concept but is deliberately distinct from the daemon's bare leading 0x1f, so it never conflates with a secondmate's own afk escalation marker. A secondmate is itself a firstmate, so a relayed request lands in its own chat, which the main firstmate never reads. The secondmate charter (fm-brief.sh) and AGENTS.md now document the recognize-and-respond-via-status contract: a marked request is answered via the status file (or a doc plus a status pointer), never chat-only; an unmarked message stays conversational captain intervention. Crewmate/scout targets, explicit session:window targets, and the --key path are unchanged. Backbone (watcher, daemon, tmux-lib, afk) untouched. Hermetic tests cover marked vs unmarked sends and the exact marker bytes.
085e6b5 to
3ab149f
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
Make a secondmate distinguish a request from the MAIN FIRSTMATE (its supervisor) from a request typed directly by the CAPTAIN, and route its response accordingly.
Problem: a secondmate is itself a firstmate, so it treats incoming fm-send/tmux messages as if from its captain and answers conversationally in its own chat - which the main firstmate never reads. The only main<-secondmate channel is the terse status file, so a detailed secondmate reply to a main-firstmate request strands unseen.
Design: when a request comes from the main firstmate, fm-send marks it so the secondmate recognizes it and responds via the STATUS/ESCALATION path instead of chat. This mirrors the existing afk FM_INJECT_MARK mechanism (which marks daemon->firstmate escalations) but in the OTHER direction: firstmate marks its requests TO a secondmate.
Key decision - a DISTINCT marker, not a reuse of the afk FM_INJECT_MARK. New helper bin/fm-marker-lib.sh defines FM_FROMFIRST_MARK as the human-readable label "[fm-from-firstmate]" followed by ASCII unit separator 0x1f. It reuses the afk untypable-0x1f concept (a byte a human cannot type, so a captain-typed message is never mistaken for a firstmate request) but is deliberately distinct from the afk daemon's BARE leading 0x1f. The afk-exit contract keys on a LEADING 0x1f; this marker leads with the label and uses 0x1f as a field separator, so it never starts with a bare 0x1f and cannot conflate with a secondmate's own afk-daemon escalation marker. This satisfies the captain's explicit constraint to avoid conflating with the afk use of 0x1f.
Hard constraint honored: the hardened backbone was deliberately NOT touched - bin/fm-watch.sh, fm-watch-arm.sh, fm-wake-lib.sh, fm-supervise-daemon.sh, fm-tmux-lib.sh, and the afk skill are unchanged. The afk daemon's message_is_injection/should_exit_afk are contract-encoding functions not invoked at runtime, so no backbone change was needed. (If a review finding suggests editing any of those files, that is intentionally out of scope and must be escalated, not applied.)
Scope of changes (deliberately confined):
Tests: new hermetic tests/fm-send-secondmate-marker.test.sh (stubbed tmux) asserts a kind=secondmate target gets the marker prepended, a crewmate (kind=ship) target does not, an explicit session:window target is never marked, the --key path carries no marker, and the marker is exactly "[fm-from-firstmate]" + 0x1f with the detector keying on that untypable sequence. tests/fm-secondmate-lifecycle-e2e.test.sh phase_send was updated to expect the now-marked secondmate send (window-routing intent preserved, marker + payload asserted). A CONTRIBUTING.md test-index line was added. The full suite (15 test files) and shellcheck bin/.sh tests/.sh are green.
What Changed
fm-sendto apply it only for barefm-<id>targets whose metadata recordskind=secondmate.session:window,--key, and secondmate lifecycle expectations. Captain, the pipeline reported passing intent, rebase, review, test, document, lint, and push stages.Risk Assessment
✅ Low: Captain, the change is narrowly scoped to secondmate message marking, documents the new contract, and preserves existing crewmate, explicit-window, and --key behavior.
Testing
Captain, author context reported prior full-suite and shellcheck success; in this run I reran the focused marker test, secondmate lifecycle E2E, and all
tests/*.test.shbehavior tests, then generated byte-level fake-tmux evidence for the user-facing send behavior. All executed checks passed, the worktree remained clean, and shellcheck was not rerun because static analysis was disallowed.Evidence: Secondmate marker fake-tmux transcript
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.
tests/fm-send-secondmate-marker.test.shtests/fm-secondmate-lifecycle-e2e.test.shfor test_script in tests/*.test.sh; do "$test_script"; doneManual fake-tmuxbin/fm-send.shcheck covering secondmate, crewmate, explicitsession:window, and--keypaths, with transcript written to/var/folders/5x/4nqprlbx0518k3ybcb1sz6gr0000gn/T/no-mistakes-evidence/01KW175787X7AVJDHRT2PKB8NV/secondmate-marker-evidence.txtsed -n '1,220p' /var/folders/5x/4nqprlbx0518k3ybcb1sz6gr0000gn/T/no-mistakes-evidence/01KW175787X7AVJDHRT2PKB8NV/secondmate-marker-evidence.txtgit status --short✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.