feat(bin): enable claude's native prompt suggestion for secondmates#642
Open
LuckyB-UF wants to merge 9 commits into
Open
feat(bin): enable claude's native prompt suggestion for secondmates#642LuckyB-UF wants to merge 9 commits into
LuckyB-UF wants to merge 9 commits into
Conversation
A secondmate is a captain-facing agent the captain reads and drives, so
its window should show claude's native predicted-next-prompt suggestion
exactly as the captain's own session does. A ship/scout crewmate is an
autonomous worker whose composer the captain never drives, so the ghost
text there has no reader to help and is pure classifier risk.
launch_template()'s claude case now branches on kind exactly as the codex
and pi cases already do: secondmate omits the
CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=false prefix, ship/scout keep it.
Safety rests on the existing shared fm_composer_strip_ghost
(bin/fm-composer-lib.sh), the one fleet-wide ANSI-aware extractor of real
typed content. Audited every secondmate-reachable read path; all already
route through it, so no new stripping was added:
- tmux: fm_tmux_composer_state strips ghost for content and keeps it for
the structural bordered-shape read, per that lib's documented contract.
- herdr: fm_backend_herdr_composer_state strips through the same owner.
- fm-send: fm_backend_send_text_submit -> fm_tmux_submit_core ->
fm_tmux_composer_state, so the submit check reads a ghost-only
composer as empty rather than a swallowed Enter.
- away-mode daemon: pane_input_pending -> fm_backend_composer_state ->
the same per-backend owners.
- agent liveness (fm_backend_{tmux,herdr}_agent_alive): reads the
foreground process / agent state, never composer content, so ghost
text cannot reach the verdict.
- orca and cmux read a plain screen with no ANSI channel, but both
refuse --secondmate spawns outright, so no secondmate can land on a
reader that cannot strip ghost text.
- zellij verifies submits by content diff and never reads composer
emptiness, so ghost text is not read as pending.
Tests extend the existing suites rather than adding a runner:
fm-spawn-dispatch-profile pins the kind split (scout keeps the prefix,
secondmate omits it; the existing byte-identical assertion already pins
ship), and fm-composer-ghost's dim SGR 2 fixtures already pin the
classifier both ways through the real path - its header now records that
those guarantees became load-bearing for secondmates.
Skipped the optional kill-switch: the audit found complete coverage and
orca/cmux cannot host a secondmate, so a force-disable guard would add a
config surface, a doc entry, and a test for a hypothetical with no
uncovered path behind it.
…refusals separately
4 tasks
Owner
|
Automated reminder: 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#642 at |
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
Let claude SECONDMATE agents launch with the native predicted-next-prompt suggestion ENABLED so the captain sees it as in their own session, while ship/scout crewmates keep it DISABLED. fm-spawn.sh launch_template's claude case branches on kind as codex/pi already did; ship/scout stay byte-identical. Safety rests on the EXISTING one-owner fm_composer_strip_ghost, which every secondmate-reachable read already routes through. Review also surfaced a real send risk on zellij (plain-screen reader, content-diff submit could report a false success against rotating ghost text), so per captain decision zellij now refuses --secondmate exactly as orca and cmux do, and the docs were reconciled to that three-backend refusing set.
RESUMING AFTER A PUSH-ONLY FAILURE - this is a re-run of run 01KXNK1KVVHEXQG3SZJ6MB2SGT on the same branch, whose review, document and lint steps ALL COMPLETED CLEAN on this exact HEAD; test was skipped by captain decision. The only failure was the push step: the gate had fork_url=NULL so it pushed at upstream kunchenguid/firstmate, where the captain has no write access (403). The captain has now set fork_url=https://github.com/LuckyB-UF/firstmate.git, PRs still open against upstream. Review/document/lint/test are skipped by captain decision to avoid ~1h of redundant re-review on unchanged content.
DOCUMENT IN THE PR BODY that the test step was skipped and why: this machine's local env is red independently of this change - cloning the clean base commit and running the full suite there fails the same 2 deterministic tests (fm-backend-orca state-dir; fm-dispatch-select missing quota-axi) because the orca binary is absent locally, plus 2 full-suite flakes that pass in isolation on base and this branch. No coverage is lost: every affected suite passes locally (fm-spawn-dispatch-profile, fm-composer-ghost, fm-composer-lib, fm-secondmate-harness, fm-instruction-owners, fm-brief, fm-spawn-batch, fm-backend-zellij), fm-lint is clean, and GitHub CI runs the same suite in a clean env and still gates this PR.
What Changed
bin/fm-spawn.shnow branches itsclaudelaunch template on task kind, the same shapecodexandpialready used: asecondmatelaunches without theCLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=falseprefix so its captain-facing window shows the native predicted-next-prompt suggestion, whileship/scoutcrewmates keep the suggestion disabled and their launch command byte-identical. Safety rests on the existing single-ownerfm_composer_strip_ghost, which every secondmate-reachable composer read already routes through.--secondmaterefusals infm-spawn.shcollapse into onecase, andzellijjoinsorcaandcmuxin that refusing set, since its plain-screen reader cannot strip ghost styling and a content-diff submit could report false success against rotating ghost text.tests/fm-backend-zellij.test.shpins that the refusal happens before any secondmate-home mutation.docs/configuration.md,docs/zellij-backend.md,docs/architecture.md,docs/herdr-backend.md,docs/tmux-backend.md,bin/fm-backend.sh, theharness-adaptersskill),bin/fm-watch.shnotes why the paused-secondmate stale arm stays reachable, andtests/fm-spawn-dispatch-profile.test.shplustests/fm-composer-ghost.test.shcover the kind split and the now load-bearing ghost-text extractor.Note on the skipped test step
The test step was skipped by captain decision because this machine's local environment is red independently of this change: cloning the clean base commit and running the full suite there fails the same two deterministic tests (
fm-backend-orcastate-dir andfm-dispatch-selectmissingquota-axi, both because theorcabinary is absent locally), plus two full-suite flakes that pass in isolation on both base and this branch. No coverage is lost — every affected suite passes locally (fm-spawn-dispatch-profile,fm-composer-ghost,fm-composer-lib,fm-secondmate-harness,fm-instruction-owners,fm-brief,fm-spawn-batch,fm-backend-zellij),fm-lintis clean, and GitHub CI runs the same suite in a clean environment and still gates this PR.This is a re-run of an earlier pipeline run on this exact HEAD, whose review, document, and lint steps all completed clean; that run's only failure was the push step pushing at an upstream the captain has no write access to. Review, document, and lint are skipped here to avoid roughly an hour of redundant re-review on unchanged content.
Testing
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
⏭️ **Review** - skipped
Step was skipped.
⏭️ **Test** - skipped
Step was skipped.
⏭️ **Document** - skipped
Step was skipped.
⏭️ **Lint** - skipped
Step was skipped.
✅ **Push** - passed
✅ No issues found.