Skip to content

fix(spawn): render no-mistakes invocation for the resolved harness - #1440

Open
JaredHuynhning wants to merge 4 commits into
kunchenguid:mainfrom
JaredHuynhning:fm/fm-codex-brief-skill-invocation-fresh
Open

fix(spawn): render no-mistakes invocation for the resolved harness#1440
JaredHuynhning wants to merge 4 commits into
kunchenguid:mainfrom
JaredHuynhning:fm/fm-codex-brief-skill-invocation-fresh

Conversation

@JaredHuynhning

Copy link
Copy Markdown

Intent

Generate every Firstmate ship brief with no-mistakes invocation wording that matches the concrete resolved worker harness: Codex uses $no-mistakes; Claude, Grok, and Kimi use /no-mistakes; OpenCode, Pi, pi-signed, and unknown mappings use natural language. Keep harness-adapters as the single owner of those per-harness facts and render only after fm-spawn resolves the actual harness. Fail closed, with the task and missing FM_NO_MISTAKES_INVOCATION token named, when a current generated no-mistakes validation contract has lost its token. Preserve pre-existing work without guessing: an exact pre-token Firstmate scaffold is recognized by its historical contract signature, warns with the task name, renders only a private owner-only state/.launch-brief.md through the resolved harness mapping, and leaves the durable legacy brief unchanged; ordinary handwritten briefs without that validation contract remain unaffected, while any other malformed tokenless validation contract refuses. Store rendered briefs under the private firstmate home rather than predictable /tmp, remove them on aborted spawn and teardown, and state this exact legacy behavior in the PR. Prove the Codex, Claude, natural-language fallback, malformed-current refusal, exact legacy Codex and Claude relaunch, file permissions, aborted-spawn cleanup, and teardown cleanup through red-first behavior tests.

What Changed

  • bin/fm-brief.sh now emits the harness-neutral __FM_NO_MISTAKES_INVOCATION__ token in no-mistakes ship scaffolds, and bin/fm-spawn.sh renders it only after it resolves the concrete harness, reading the per-harness form from the harness-adapters skill ($no-mistakes for codex, /no-mistakes for claude, grok and kimi, natural language for opencode, pi, pi-signed and any unmatched or unreadable mapping). The rendered copy is written owner-only (umask 077) to state/<id>.launch-brief.md under the private firstmate home rather than /tmp, and is removed by a spawn that aborts before the launch command reaches the pane and by bin/fm-teardown.sh (including secondmate children); a spawn that fails after delivery keeps it so the live pane retains its instructions.
  • Delivery mode and yolo now resolve before any worker endpoint is created, so a current generated no-mistakes validation contract that has lost its token refuses launch (naming the task and the missing token) with no pane, worktree or state file left behind. The one compatibility exception is an exact pre-token Firstmate scaffold, recognised by its three historical contract lines: spawn warns with the task name, substitutes the resolved invocation only inside those lines, writes the private state/<id>.launch-brief.md, and leaves the durable data/<id>/brief.md unchanged. Ordinary handwritten briefs with no validation contract launch exactly as before and get no private copy.
  • Docs follow the behaviour: harness-adapters becomes the machine-readable owner of the invocation forms, AGENTS.md records the new state file and the leave-the-token rule, and stuck-crewmate-recovery points relaunches at the retained launch brief. Nine behaviour tests cover codex, claude, the natural-language fallback, the malformed-current refusal, exact legacy codex and claude relaunch, file permissions, aborted-spawn cleanup and teardown cleanup; the Test gate notes two of the nine are not strictly red-first on base and were instead confirmed load-bearing by mutation, with the other seven failing red. Review raised a case where abort cleanup deleted a live kimi pane's brief after a post-delivery timeout, which was fixed by retaining the brief once the launch is delivered and folding the two renderers into one.

Risk Assessment

✅ Low: The follow-up commit closes the round-1 retention gap at the correct boundary (the flag is set immediately after the launch command reaches the pane, and always after the meta write, so no retained brief can become teardown-unreachable), the renderer dedup is behaviour-preserving with both branches still covered, the reworded CI-ready sentence keeps the token in invocation position only, and both the abort and retain directions now have pinned behavioural tests.

Testing

Ran the three changed behaviour suites plus tests/fm-brief.test.sh (all green), verified red-first by re-running each new test against the base bin/ scripts (7 of 9 go red; the other two were proven load-bearing by mutating the change), and then drove fm-spawn end to end through a fake pane to capture the actual product surface: the launch command handed to the worker, the rendered brief path and 0600 mode under the private firstmate home, and the exact per-harness invocation wording for Codex, Claude and OpenCode, the malformed-contract refusal, the exact-legacy warning with an unchanged durable brief, the untouched handwritten-brief path, and the aborted-spawn and teardown cleanups. The change is shell and brief-text only with no rendered UI surface, so the reviewer-visible artifact is the CLI transcript of the real launch commands and rendered brief text rather than a screenshot.

Evidence: End-to-end launch brief transcript (all intent branches)

===== harness: codex (spawn exit 0) ===== launch command handed to the pane: codex --dangerously-bypass-approvals-and-sandbox -c "notify=[...]" "$('<repo>/bin/fm-operational-input.sh' encode launch-brief < '<fm-home>/state/demo-codex.launch-brief.md')" mode: 600 56:Firstmate will then instruct you to invoke $no-mistakes to validate and ship a PR. 68:Once you have invoked $no-mistakes and it reports CI green ... You are finished. --- durable source brief still tokenized --- token occurrences: 3 ===== harness: claude (spawn exit 0) ===== mode: 600 56:Firstmate will then instruct you to invoke /no-mistakes to validate and ship a PR. ===== harness: opencode (spawn exit 0) ===== mode: 600 56:Firstmate will then instruct you to invoke the no-mistakes skill by name in natural language to validate and ship a PR. ===== exact pre-token legacy scaffold, harness: codex (spawn exit 0) ===== warning: task demo-legacy-codex has a legacy no-mistakes brief without FM_NO_MISTAKES_INVOCATION; rendering a private launch copy for resolved harness codex and leaving <fm-home>/data/demo-legacy-codex/brief.md unchanged rendered brief path: <fm-home>/state/demo-legacy-codex.launch-brief.md (mode 600) 56:Firstmate will then instruct you to run $no-mistakes to validate and ship a PR. --- durable legacy brief left unchanged --- 56:Firstmate will then instruct you to run /no-mistakes to validate and ship a PR. ===== malformed current validation contract (token deleted) ===== spawn exit: 1 error: refusing task demo-malformed launch for harness codex because ship brief <fm-home>/data/demo-malformed/brief.md is missing FM_NO_MISTAKES_INVOCATION worker launch attempted: no state/ rendered brief created: 0 ===== ordinary handwritten brief without a validation contract ===== spawn exit: 0 launched brief path: <firstmate-home>/data/demo-handwritten/brief.md private rendered copies in state/: 0 ===== aborted spawn (launch delivery fails) ===== spawn exit: 1 leftover state/<id>.launch-brief.md: removed


===== harness: codex (spawn exit 0) =====
launch command handed to the pane:
  codex --dangerously-bypass-approvals-and-sandbox -c "notify=[\"bash\",\"-c\",\"touch '/private/var/folders/_s/01tmj3vx0bn03t1t29k76npw0000gn/T/fm-launch-brief-demo.cKSclL/demo-codex/home/state/demo-codex.turn-ended'\"]" "$('<repo>/bin/fm-operational-input.sh' encode launch-brief < '/private/var/folders/_s/01tmj3vx0bn03t1t29k76npw0000gn/T/fm-launch-brief-demo.cKSclL/demo-codex/home/state/demo-codex.launch-brief.md')"
rendered brief path: /private/var/folders/_s/01tmj3vx0bn03t1t29k76npw0000gn/T/fm-launch-brief-demo.cKSclL/demo-codex/home/state/demo-codex.launch-brief.md
mode: 600
--- rendered "Definition of done" lines mentioning no-mistakes ---
19:2. Run `no-mistakes doctor`; if it reports the repo is not initialized here, run `no-mistakes init`.
42:7. Never stop, restart, or update the shared `no-mistakes` daemon - it is one instance serving
43:   every lane/home, so restarting it kills other lanes' in-flight pipeline runs. On ANY no-mistakes
47:If `AGENTS.md` or `CLAUDE.md` already exists, or if this task produced durable project-intrinsic knowledge, run `<repo>/bin/fm-ensure-agents-md.sh .` in the worktree.
50:If you touch a project `AGENTS.md` that lacks `## Maintaining this file`, add that short self-governance section from `<repo>/bin/fm-ensure-agents-md.sh` in the same pass.
56:Firstmate will then instruct you to invoke `$no-mistakes` to validate and ship a PR.
58:You drive no-mistakes by responding to its gates, not by implementing fixes.
59:Follow the guidance no-mistakes itself provides for the mechanics: it loads when you invoke `$no-mistakes`, and `no-mistakes axi run --help` plus the `help` lines in each `axi` response are authoritative and version-matched to the installed binary.
65:  When the decision comes back, feed it to the gate with `no-mistakes axi respond` and let the pipeline apply it - do not route the question to "the user" or implement the fix yourself.
68:Once you have invoked `$no-mistakes` and it reports CI green (the CI-ready return point - do not wait for it to keep monitoring in the background until merge), append `done: PR {url} checks green` and stop. You are finished.
--- durable source brief (data/demo-codex/brief.md) still tokenized ---
  token occurrences: 3

===== harness: claude (spawn exit 0) =====
launch command handed to the pane:
  CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=false claude --dangerously-skip-permissions "$('<repo>/bin/fm-operational-input.sh' encode launch-brief < '/private/var/folders/_s/01tmj3vx0bn03t1t29k76npw0000gn/T/fm-launch-brief-demo.cKSclL/demo-claude/home/state/demo-claude.launch-brief.md')"
rendered brief path: /private/var/folders/_s/01tmj3vx0bn03t1t29k76npw0000gn/T/fm-launch-brief-demo.cKSclL/demo-claude/home/state/demo-claude.launch-brief.md
mode: 600
--- rendered "Definition of done" lines mentioning no-mistakes ---
19:2. Run `no-mistakes doctor`; if it reports the repo is not initialized here, run `no-mistakes init`.
42:7. Never stop, restart, or update the shared `no-mistakes` daemon - it is one instance serving
43:   every lane/home, so restarting it kills other lanes' in-flight pipeline runs. On ANY no-mistakes
47:If `AGENTS.md` or `CLAUDE.md` already exists, or if this task produced durable project-intrinsic knowledge, run `<repo>/bin/fm-ensure-agents-md.sh .` in the worktree.
50:If you touch a project `AGENTS.md` that lacks `## Maintaining this file`, add that short self-governance section from `<repo>/bin/fm-ensure-agents-md.sh` in the same pass.
56:Firstmate will then instruct you to invoke `/no-mistakes` to validate and ship a PR.
58:You drive no-mistakes by responding to its gates, not by implementing fixes.
59:Follow the guidance no-mistakes itself provides for the mechanics: it loads when you invoke `/no-mistakes`, and `no-mistakes axi run --help` plus the `help` lines in each `axi` response are authoritative and version-matched to the installed binary.
65:  When the decision comes back, feed it to the gate with `no-mistakes axi respond` and let the pipeline apply it - do not route the question to "the user" or implement the fix yourself.
68:Once you have invoked `/no-mistakes` and it reports CI green (the CI-ready return point - do not wait for it to keep monitoring in the background until merge), append `done: PR {url} checks green` and stop. You are finished.
--- durable source brief (data/demo-claude/brief.md) still tokenized ---
  token occurrences: 3

===== harness: opencode (spawn exit 0) =====
launch command handed to the pane:
  OPENCODE_CONFIG_CONTENT='{"permission":{"*":"allow"}}' opencode --prompt "$('<repo>/bin/fm-operational-input.sh' encode launch-brief < '/private/var/folders/_s/01tmj3vx0bn03t1t29k76npw0000gn/T/fm-launch-brief-demo.cKSclL/demo-opencode/home/state/demo-opencode.launch-brief.md')"
rendered brief path: /private/var/folders/_s/01tmj3vx0bn03t1t29k76npw0000gn/T/fm-launch-brief-demo.cKSclL/demo-opencode/home/state/demo-opencode.launch-brief.md
mode: 600
--- rendered "Definition of done" lines mentioning no-mistakes ---
19:2. Run `no-mistakes doctor`; if it reports the repo is not initialized here, run `no-mistakes init`.
42:7. Never stop, restart, or update the shared `no-mistakes` daemon - it is one instance serving
43:   every lane/home, so restarting it kills other lanes' in-flight pipeline runs. On ANY no-mistakes
47:If `AGENTS.md` or `CLAUDE.md` already exists, or if this task produced durable project-intrinsic knowledge, run `<repo>/bin/fm-ensure-agents-md.sh .` in the worktree.
50:If you touch a project `AGENTS.md` that lacks `## Maintaining this file`, add that short self-governance section from `<repo>/bin/fm-ensure-agents-md.sh` in the same pass.
56:Firstmate will then instruct you to invoke the `no-mistakes` skill by name in natural language to validate and ship a PR.
58:You drive no-mistakes by responding to its gates, not by implementing fixes.
59:Follow the guidance no-mistakes itself provides for the mechanics: it loads when you invoke the `no-mistakes` skill by name in natural language, and `no-mistakes axi run --help` plus the `help` lines in each `axi` response are authoritative and version-matched to the installed binary.
65:  When the decision comes back, feed it to the gate with `no-mistakes axi respond` and let the pipeline apply it - do not route the question to "the user" or implement the fix yourself.
68:Once you have invoked the `no-mistakes` skill by name in natural language and it reports CI green (the CI-ready return point - do not wait for it to keep monitoring in the background until merge), append `done: PR {url} checks green` and stop. You are finished.
--- durable source brief (data/demo-opencode/brief.md) still tokenized ---
  token occurrences: 3

===== exact pre-token legacy scaffold, harness: codex (spawn exit 0) =====
stderr/stdout:
  warning: task demo-legacy-codex has a legacy no-mistakes brief without __FM_NO_MISTAKES_INVOCATION__; rendering a private launch copy for resolved harness codex and leaving /private/var/folders/_s/01tmj3vx0bn03t1t29k76npw0000gn/T/fm-launch-brief-demo.cKSclL/demo-legacy-codex/home/data/demo-legacy-codex/brief.md unchanged
rendered brief path: /private/var/folders/_s/01tmj3vx0bn03t1t29k76npw0000gn/T/fm-launch-brief-demo.cKSclL/demo-legacy-codex/home/state/demo-legacy-codex.launch-brief.md (mode 600)
19:2. Run `no-mistakes doctor`; if it reports the repo is not initialized here, run `no-mistakes init`.
42:7. Never stop, restart, or update the shared `no-mistakes` daemon - it is one instance serving
43:   every lane/home, so restarting it kills other lanes' in-flight pipeline runs. On ANY no-mistakes
47:If `AGENTS.md` or `CLAUDE.md` already exists, or if this task produced durable project-intrinsic knowledge, run `<repo>/bin/fm-ensure-agents-md.sh .` in the worktree.
50:If you touch a project `AGENTS.md` that lacks `## Maintaining this file`, add that short self-governance section from `<repo>/bin/fm-ensure-agents-md.sh` in the same pass.
56:Firstmate will then instruct you to run `$no-mistakes` to validate and ship a PR.
58:You drive no-mistakes by responding to its gates, not by implementing fixes.
59:Follow the guidance no-mistakes itself provides for the mechanics: it loads when you invoke `$no-mistakes`, and `no-mistakes axi run --help` plus the `help` lines in each `axi` response are authoritative and version-matched to the installed binary.
65:  When the decision comes back, feed it to the gate with `no-mistakes axi respond` and let the pipeline apply it - do not route the question to "the user" or implement the fix yourself.
68:After `$no-mistakes` reports CI green (the CI-ready return point - do not wait for it to keep monitoring in the background until merge), append `done: PR {url} checks green` and stop. You are finished.
--- durable legacy brief left unchanged ---
  56:Firstmate will then instruct you to run /no-mistakes to validate and ship a PR.

===== exact pre-token legacy scaffold, harness: claude (spawn exit 0) =====
stderr/stdout:
  warning: task demo-legacy-claude has a legacy no-mistakes brief without __FM_NO_MISTAKES_INVOCATION__; rendering a private launch copy for resolved harness claude and leaving /private/var/folders/_s/01tmj3vx0bn03t1t29k76npw0000gn/T/fm-launch-brief-demo.cKSclL/demo-legacy-claude/home/data/demo-legacy-claude/brief.md unchanged
rendered brief path: /private/var/folders/_s/01tmj3vx0bn03t1t29k76npw0000gn/T/fm-launch-brief-demo.cKSclL/demo-legacy-claude/home/state/demo-legacy-claude.launch-brief.md (mode 600)
19:2. Run `no-mistakes doctor`; if it reports the repo is not initialized here, run `no-mistakes init`.
42:7. Never stop, restart, or update the shared `no-mistakes` daemon - it is one instance serving
43:   every lane/home, so restarting it kills other lanes' in-flight pipeline runs. On ANY no-mistakes
47:If `AGENTS.md` or `CLAUDE.md` already exists, or if this task produced durable project-intrinsic knowledge, run `<repo>/bin/fm-ensure-agents-md.sh .` in the worktree.
50:If you touch a project `AGENTS.md` that lacks `## Maintaining this file`, add that short self-governance section from `<repo>/bin/fm-ensure-agents-md.sh` in the same pass.
56:Firstmate will then instruct you to run `/no-mistakes` to validate and ship a PR.
58:You drive no-mistakes by responding to its gates, not by implementing fixes.
59:Follow the guidance no-mistakes itself provides for the mechanics: it loads when you invoke `/no-mistakes`, and `no-mistakes axi run --help` plus the `help` lines in each `axi` response are authoritative and version-matched to the installed binary.
65:  When the decision comes back, feed it to the gate with `no-mistakes axi respond` and let the pipeline apply it - do not route the question to "the user" or implement the fix yourself.
68:After `/no-mistakes` reports CI green (the CI-ready return point - do not wait for it to keep monitoring in the background until merge), append `done: PR {url} checks green` and stop. You are finished.
--- durable legacy brief left unchanged ---
  56:Firstmate will then instruct you to run /no-mistakes to validate and ship a PR.

===== malformed current validation contract (token deleted) =====
spawn exit: 1
  error: refusing task demo-malformed launch for harness codex because ship brief /private/var/folders/_s/01tmj3vx0bn03t1t29k76npw0000gn/T/fm-launch-brief-demo.cKSclL/demo-malformed/home/data/demo-malformed/brief.md is missing __FM_NO_MISTAKES_INVOCATION__
worker launch attempted: no
state/ rendered brief created: 0

===== ordinary handwritten brief without a validation contract =====
spawn exit: 0
launched brief path: <firstmate-home>/data/demo-handwritten/brief.md
private rendered copies in state/: 0

===== aborted spawn (launch delivery fails) =====
spawn exit: 1
leftover state/<id>.launch-brief.md: removed
Evidence: Per-harness invocation mapping resolved from harness-adapters

harness rendered invocation wording ------- --------------------------- codex $no-mistakes claude /no-mistakes grok /no-mistakes kimi /no-mistakes opencode the no-mistakes skill by name in natural language pi the no-mistakes skill by name in natural language pi-signed the no-mistakes skill by name in natural language some-future-harness the no-mistakes skill by name in natural language adapters missing, harness=codex -> the no-mistakes skill by name in natural language

harness      rendered invocation wording
-------      ---------------------------
codex        `$no-mistakes`
claude       `/no-mistakes`
grok         `/no-mistakes`
kimi         `/no-mistakes`
opencode     the `no-mistakes` skill by name in natural language
pi           the `no-mistakes` skill by name in natural language
pi-signed    the `no-mistakes` skill by name in natural language
some-future-harness the `no-mistakes` skill by name in natural language
adapters missing, harness=codex -> the `no-mistakes` skill by name in natural language
Evidence: Red-first check against base commit 3772964

test_token_stripped_current_ship_brief_refuses_launch not ok - expected exit 1, got 0 test_legacy_claude_ship_brief_migrates_private_launch_copy not ok - legacy migration warning did not name the task test_legacy_codex_ship_brief_migrates_private_launch_copy not ok - legacy migration warning did not name the task test_aborted_spawn_removes_private_launch_brief ok (vacuous on base; mutation-proven on the change) test_claude_launch_brief_uses_slash_no_mistakes_invocation ok (base scaffold already literal /no-mistakes; mutation-proven) test_opencode_launch_brief_uses_harness_agnostic_wording not ok - did not use the harness-agnostic fallback test_codex_launch_brief_uses_dollar_no_mistakes_invocation not ok - did not use the dollar-prefixed invocation test_teardown_removes_private_launch_brief not ok - teardown left the private rendered launch brief test_kimi_post_delivery_failure_retains_private_launch_brief not ok - fixture did not generate a tokenized ship brief

test_token_stripped_current_ship_brief_refuses_launch                  not ok - token-stripped current ship brief should refuse launch: expected exit 1, got 0
test_legacy_claude_ship_brief_migrates_private_launch_copy             not ok - legacy migration warning did not name the task (missing: 'warning: task profile-brief-legacy-claude-z1j')
test_legacy_codex_ship_brief_migrates_private_launch_copy              not ok - legacy migration warning did not name the task (missing: 'warning: task profile-brief-legacy-codex-z1i')
test_aborted_spawn_removes_private_launch_brief                        ok - aborted spawn removes its private rendered launch brief
test_claude_launch_brief_uses_slash_no_mistakes_invocation             ok - claude launch receives a generated brief with /no-mistakes
test_opencode_launch_brief_uses_harness_agnostic_no_mistakes_wording   not ok - opencode launch brief did not use the harness-agnostic fallback
test_codex_launch_brief_uses_dollar_no_mistakes_invocation             not ok - codex launch brief did not use the harness-adapters dollar-prefixed invocation
test_teardown_removes_private_launch_brief                             not ok - teardown left the private rendered launch brief
test_kimi_post_delivery_failure_retains_private_launch_brief           not ok - kimi fixture did not generate a tokenized no-mistakes ship brief
Evidence: Mutation checks proving the two non-red tests are load-bearing

mutation A (abort cleanup removed): not ok - aborted spawn orphaned its private rendered launch brief mutation B (all harnesses fall back to natural language): not ok - claude launch brief did not use the harness-adapters slash invocation

mutation A (abort cleanup removed): not ok - aborted spawn orphaned its private rendered launch brief
mutation B (all harnesses fall back to natural language): not ok - claude launch brief did not use the harness-adapters slash invocation
Evidence: Targeted suite logs
FM_TEST_BEGIN 2026-08-01T00:43:20Z tests/fm-spawn-dispatch-profile.test.sh family=backend-dispatch expected_gate_skip=none

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 16.7ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - no --model/--effort records defaults and types the claude launch instructions

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 16.7ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - token-stripped current ship brief refuses with task and token details

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 16.5ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - legacy Claude brief migrates only a private launch copy through the resolved harness

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 16.2ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - legacy Codex brief migrates only a private launch copy through the resolved harness

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 16.7ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - aborted spawn removes its private rendered launch brief

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 35.3ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - claude launch receives a generated brief with /no-mistakes

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 17.3ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - opencode launch receives a generated brief with natural-language validation wording

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 17ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - codex launch receives a generated brief with $no-mistakes

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 16.8ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - relative home overrides ignore CDPATH and become absolute before spawn launch construction

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 17ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - FM_HOME defaults resolve relative paths and preserve absolute spellings

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 20.2ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - absolute override spellings are preserved in spawn launch paths

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 31ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - unresolvable relative spawn overrides fail with named diagnostics

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 17.8ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - active crew-dispatch profile requires an explicit harness for ship spawns

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 22.3ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - active crew-dispatch profile requires an explicit harness for scout spawns

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 18.3ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - active crew-dispatch profile allows an explicit resolved harness

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 20.5ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - active crew-dispatch profile allows the legacy positional harness form

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 17.6ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - active crew-dispatch profile allows the raw launch-command escape hatch

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:43AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 20.8ms�[0m
�[90m10:43AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - claude receives --model and --effort profile flags

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 33.7ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - codex receives --model and model_reasoning_effort profile flags

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 18.8ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - codex omits unsupported max effort instead of passing a bad config value

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 16.3ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - grok receives --model and --reasoning-effort profile flags

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 16.5ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - grok omits unsupported max reasoning effort

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 20.3ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - grok omits unsupported xhigh reasoning effort

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 16.6ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - opencode receives --model and omits the unsupported effort axis

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 16.3ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - pi receives --model and --thinking max profile flags

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 16.8ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - pi-signed shares Pi launch semantics while preserving its configured and recorded identity

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 18.7ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - pi-signed refuses safely and actionably when the selected executable is unavailable

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 16.3ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - pi-signed is a distinct persistent secondmate runtime with shared Pi supervision semantics

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 17.5ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - batch dispatch forwards shared --harness, --model, and --effort to every pair

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 18.5ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - claude forwards firstmate's CLAUDE_CONFIG_DIR so the crewmate uses the same credential store

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 21.1ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - claude omits the config-dir prefix when firstmate runs with the single-store default

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 20.7ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - non-claude harnesses do not receive the claude CLAUDE_CONFIG_DIR prefix

    ○
    │╲
    │ ○
    ○ ░
    ░    gitleaks

�[90m10:44AM�[0m �[32mINF�[0m �[1m0 commits scanned.�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mscanned ~10 bytes (10 bytes) in 20.5ms�[0m
�[90m10:44AM�[0m �[32mINF�[0m �[1mno leaks found�[0m
ok - active crew-dispatch profile does not block secondmate launches
# all fm-spawn-dispatch-profile tests passed
FM_TEST_END 2026-08-01T00:44:37Z tests/fm-spawn-dispatch-profile.test.sh exit=0 duration_ms=77113 gate_skip=false
FM_TEST_SUMMARY total=1 failed=0 skipped_gate=0 duration_ms=77173
FM_TEST_SUMMARY_FAMILY family=backend-dispatch count=1 duration_ms=77113 failed=0
FM_TEST_SLOWEST rank=1 script=tests/fm-spawn-dispatch-profile.test.sh duration_ms=77113
- Outcome: ⚠️ 1 info across 1 run (9m55s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 4 issues found → auto-fixed ✅
  • ⚠️ bin/fm-spawn.sh:300 - bin/fm-spawn.sh:300 | spawn_abort_cleanup rm -f's LAUNCH_BRIEF on every non-zero exit, including kimi's post-delivery failure paths that intentionally keep the pane and meta alive. kimi has no BRIEF in its launch template - line 1831 submits "Read the brief at $BRIEF_REAL", which is now state/<id>.launch-brief.md. When kimi_wait_for_delivery (1408) times out after ~20s despite the pointer having landed, kimi_spawn_fail (1419) only appends failed: and prints "inspect window $T", then exit 1 deletes the brief out from under the live agent; data/<id>/brief.md is no fallback because it still holds the literal FM_NO_MISTAKES_INVOCATION. Same deletion hits a still-running task if an operator re-spawns that id and the second run fails after line 1492. Fix: clear LAUNCH_BRIEF once the pointer submit is attempted (or in kimi_spawn_fail, alongside the retained pane and meta), keeping removal for genuine pre-delivery aborts.
  • ℹ️ bin/fm-spawn.sh:986 - bin/fm-spawn.sh:986 | brief_is_recognized_legacy_no_mistakes pins all three historical lines, but line 3 was reworded in 295c13d (2026-07-06) and line 2 in 362fb54 (2026-06-26), later than the unchanged line 1. A ship brief scaffolded before 2026-07-06 fails the exact-signature match yet still matches brief_carries_no_mistakes_validation, so it is hard-refused instead of migrated. Fail-closed and loud, and the intent explicitly authorises refusing anything outside the exact signature, so no change required - noted only because a ~4-week-old in-flight task is still plausibly respawnable.
  • ℹ️ bin/fm-spawn.sh:618 - bin/fm-spawn.sh:618 | the fallback "the no-mistakes skill by name in natural language" is worded as a verb object, but fm-brief.sh:355 substitutes the token as a sentence subject, rendering "After the no-mistakes skill by name in natural language reports CI green ..." for opencode, pi, pi-signed and unknown harnesses. The test only asserts the phrase is present. Reword fm-brief.sh:355 (e.g. "After no-mistakes reports CI green") so the token stays in invocation positions only.
  • ℹ️ bin/fm-spawn.sh:657 - bin/fm-spawn.sh:657 | render_launch_brief_for_harness and render_legacy_launch_brief_for_harness differ only in the awk substitution rule, and write_private_launch_brief wraps each in an identical if/else to capture a status that set -eu already propagates from the simple-command call site at 1493 (its trailing if [ &#34;$status&#34; -ne 0 ] returns 0 on success only by fall-through). Collapsing to one awk parameterised by the match rule would drop the legacy flag threading entirely.

🔧 Fix: retain launch brief for live panes, dedup renderer
✅ Re-checked - no issues remain.

⚠️ **Test** - 1 info
  • ℹ️ tests/fm-spawn-dispatch-profile.test.sh:274 - Two of the nine new behaviour tests are not strictly red-first against the base commit: test_aborted_spawn_removes_private_launch_brief passes vacuously on base (base never creates a private brief, so the absence assertion is trivially true) and test_claude_launch_brief_uses_slash_no_mistakes_invocation passes on base (the pre-change scaffold already contains a literal /no-mistakes). Both were confirmed load-bearing on the change by mutation: removing the abort-time rm and forcing the natural-language fallback each make the respective test fail. The other seven new tests fail red on base as intended.
  • bin/fm-test-run.sh tests/fm-spawn-dispatch-profile.test.sh (all pass, including the 7 new launch-brief tests)
  • bin/fm-test-run.sh tests/fm-teardown.test.sh tests/fm-kimi-harness.test.sh (all pass, including test_teardown_removes_private_launch_brief and test_kimi_post_delivery_failure_retains_private_launch_brief)
  • bin/fm-test-run.sh tests/fm-brief.test.sh (scaffold generation with the new token)
  • Red-first check: reverted bin/fm-spawn.sh, bin/fm-brief.sh, bin/fm-teardown.sh to base 3772964 and ran each new test in isolation - 7 of 9 fail red
  • Mutation check on the change: removed the abort-time rm -f -- &#34;$LAUNCH_BRIEF&#34; and separately forced the natural-language fallback for all harnesses, confirming test_aborted_spawn_removes_private_launch_brief and test_claude_launch_brief_uses_slash_no_mistakes_invocation both fail
  • Manual end-to-end spawn through the fake tmux pane for codex, claude and opencode: captured the literal launch command, the rendered brief path and mode, the rendered invocation lines, and the untouched tokenized durable brief
  • Manual end-to-end spawn of the exact pre-token legacy scaffold for codex and claude: captured the warning, the private rendered copy, and the unchanged durable legacy brief
  • Manual end-to-end spawn of a token-stripped current validation contract (refusal, no launch, no state file) and an ordinary handwritten brief (launches unchanged, no private copy)
  • Manual end-to-end aborted spawn with a failing launch delivery, confirming the private brief is removed
  • Direct probe of no_mistakes_invocation_for_harness for codex, claude, grok, kimi, opencode, pi, pi-signed, an unknown harness, and an unreadable harness-adapters file
⚠️ **Document** - 1 info
  • ℹ️ .agents/skills/harness-adapters/SKILL.md:185 - harness-adapters/SKILL.md now declares the "## no-mistakes skill invocation" bullets the machine-readable authority that fm-spawn parses, but the per-harness fact tables still carry duplicate "Skill invocation" rows (claude line 185, codex 215, grok 320, kimi 377). The copies currently agree, so nothing is stale, but a maintainer who edits only a table row would silently leave fm-spawn rendering the old form or falling back to natural language. Worth a follow-up that reduces those rows to a pointer at the owner section. Left alone here as an out-of-scope consolidation.
✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@JaredHuynhning
JaredHuynhning force-pushed the fm/fm-codex-brief-skill-invocation-fresh branch from 8c14feb to cf5daad Compare August 1, 2026 05:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant