Skip to content

fix(spawn): resume recorded worktree on ship relaunch - #122

Merged
dnth merged 14 commits into
mainfrom
fm/fm-relaunch-ship-pos1-fix
Sep 7, 2026
Merged

fix(spawn): resume recorded worktree on ship relaunch#122
dnth merged 14 commits into
mainfrom
fm/fm-relaunch-ship-pos1-fix

Conversation

@dnth

@dnth dnth commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Intent

Fix bin/fm-spawn.sh so ship --relaunch resumes the exact recorded worktree and endpoint across supported backends, preserves WIP, restores recorded harness/model/effort when flags are omitted, requires no project positional, and refuses unsupported raw or unsafe relaunches instead of allocating fresh worktrees. Keep secondmate and normal spawn behavior unchanged. Add executable regression tests and maintainer-verification evidence. Firstmate-Validation-Generation: def2aecdd97439865a03f8929121bed4

What Changed

  • Updated bin/fm-spawn.sh to relaunch from the recorded project, worktree, profile, and backend endpoint without requiring a project positional, preserving existing WIP and avoiding fresh worktree allocation.
  • Added safety checks that reject raw, unrelated, active, or otherwise unverified relaunches, including unsafe Herdr presentation recovery.
  • Added executable regression/e2e coverage and maintainer-verification documentation for worktree settling, profile restoration, and refusal behavior.

Risk Assessment

⚠️ Medium: The relaunch changes span multiple terminal backends and safety gates, but the reviewed paths preserve recorded worktrees/endpoints and refuse unverifiable recovery without a substantiated remaining defect.

Testing

Ran the focused executable relaunch suite; all ship relaunch regression scenarios passed. A broader dispatch-profile suite was also started but did not complete within the targeted validation window and was terminated; no source or worktree artifacts were left behind.

Evidence: Focused ship relaunch regression output
ok - a single transient stale pane_current_path read is not accepted as the worktree
ok - an already-settled pane confirms via the existing inter-poll sleep, not an extra full cycle
ok - a sandbox relaunch records the isolated copy published by its own acquisition
ok - a bare ship relaunch resumes the recorded worktree and preserves WIP
ok - a bare ship relaunch restores recorded harness, model, and effort
ok - a raw ship relaunch requiring a worktree is refused
ok - a ship relaunch refuses an active tmux endpoint before sending input
ok - a ship relaunch refuses a worktree from an unrelated repository
# all fm-spawn-worktree-settle tests passed
- Outcome: 🔧 1 issue found → auto-fixed ✅ across 2 runs (15m17s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed (5) ✅
  • 🚨 bin/fm-spawn.sh:3419 - A tmux ship relaunch verifies only the pane cwd, then proceeds to send GOTMPDIR, the launch command, and Enter to the recorded pane. fm_backend_tmux_current_path is passive and does not prove the pane is an idle shell, so if the prior Codex/Claude process is still running while cwd remains the recorded worktree, these inputs are injected into the active harness and can corrupt or duplicate the task. Before any relaunch writes to a tmux endpoint, require the existing fm_backend_tmux_idle_foreground_shell_pid proof (or refuse).

🔧 Fix: Require idle tmux shell before ship relaunch
1 error still open:

  • 🚨 bin/fm-spawn.sh:3166 - The Herdr presentation relaunch path does not preserve the recorded endpoint: when a projection journal is present, fm_backend_herdr_projection_reclaim_task creates a replacement tab/pane and lines 3174-3178 overwrite HERDR_TAB_ID/HERDR_PANE_ID with the new IDs. This contradicts the required “ship --relaunch resumes the exact recorded worktree and endpoint across supported backends” and the prior decision to preserve the recorded Herdr session/pane binding or refuse loudly. The smallest remedy is to revert this replacement/reclaim behavior to an exact-binding check with refusal when recovery is not possible; changing the recovery contract needs authorization.

🔧 Fix: Refuse Herdr relaunch endpoint replacement
1 warning still open:

  • ⚠️ docs/verification/spawn-relaunch.md:9 - The maintainer-verification transcript is stale: tests/fm-spawn-worktree-settle.test.sh now emits the added active-tmux regression result (ok - a ship relaunch refuses an active tmux endpoint before sending input), but the output block at lines 9-17 omits it while presenting the transcript as complete. Update the evidence to match the current executable test output.

🔧 Fix: Update relaunch verification transcript
1 error still open:

  • 🚨 bin/fm-spawn.sh:2910 - validate_spawn_worktree only checks that WT is the root of some separate Git checkout and differs from PROJ_ABS; it never verifies that the recorded path is a worktree belonging to the recorded project. A corrupted/stale metadata pair with project A and worktree B (an unrelated repository) therefore passes lines 2910-2915, and the relaunch can send the worker into B while rewriting the task metadata. Validate the worktree's Git common directory/git worktree list membership against the recorded project before endpoint reuse.

🔧 Fix: Validate relaunch worktree project ownership
1 warning still open:

  • ⚠️ docs/verification/spawn-relaunch.md:9 - The maintainer-verification transcript is incomplete: tests/fm-spawn-worktree-settle.test.sh now emits the additional ok - a ship relaunch refuses a worktree from an unrelated repository result, but docs/verification/spawn-relaunch.md omits it while presenting the output as complete. Update the evidence block to match the current executable test output.

🔧 Fix: Update relaunch verification transcript
✅ Re-checked - no issues remain.

🔧 **Test** - 1 issue found → auto-fixed ✅
  • ⚠️ The focused relaunch suite passes, but the broader dispatch-profile suite did not complete in this environment and no targeted executable assertion directly demonstrates omitted relaunch flags restoring recorded harness/model/effort. Re-run the profile-focused validation or add that regression scenario before treating the full intent as proven.
  • bash tests/fm-spawn-worktree-settle.test.sh
  • bash tests/fm-backend-herdr-presentation-e2e.test.sh (started; environment/tool timeout prevented complete transcript)
  • bash tests/fm-spawn-dispatch-profile.test.sh (started; interrupted after environment hang)

🔧 Fix: Added executable regression for recorded relaunch profile restoration
✅ Re-checked - no issues remain.

  • tests/fm-spawn-worktree-settle.test.sh
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@dnth
dnth merged commit 945a213 into main Sep 7, 2026
16 checks passed
@dnth
dnth deleted the fm/fm-relaunch-ship-pos1-fix branch September 7, 2026 23:29
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