Conversation
…hildren on relaunch fm-control.sh gains a herdr-only reproject verb that moves a live flat task tab into an ordered projected child under its exact parent and rebinds the task record plus the presentation journal. The pane keeps its process, agent registration, and cwd. A crash-recovery receipt makes reruns resume the rebind instead of moving again, and the new child is never closed as rollback. fm-spawn.sh relaunch rebind first attempts the same-token recreation when the recorded pane and its whole workspace are positively gone, keeping flat as the fallback for every ambiguous case. Covers the model-switch incident shape both live and on future relaunches.
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
In Herdr's left pane, workers normally appear as separate child groups under Firstmate. After their model was switched, the replacements appeared as tabs in one group. This is not acceptable. Find and fix that bug. Keep each worker's existing project work safe. The three live replacement tabs must return to child groups as well: add a guarded live repair for them plus safe child-group creation for future relaunches after a missing pane.
What Changed
reprojectcommand that moves a live worker tab into its own child workspace, preserves its process and worktree, and rebinds the task record and presentation journal.Risk Assessment
🚨 High: The three live default-session tabs remain unmoved and unverified, and the two upstream checks (CI, Require no-mistakes) have NOT run — both stand action_required with zero jobs on this fork PR head, waiting for upstream maintainer workflow approval, not passed. All code findings closed through review fix rounds at the gate head; Test passed.
Testing
Portable Herdr and control checks passed after fixing a host-specific process fixture. Named Herdr labs passed live reproject, adversarial rename, relaunch, and concurrent recovery checks; the long presentation run timed out after its relaunch proof, and a focused lab completed the remaining recovery check. The timed-out lab was removed through guarded teardown. No TUI screenshot was available because the lab viewer drains its pty output; captured Herdr workspace and pane responses show the live layout.
Evidence: Live Herdr control smoke test
Source: Live Herdr control smoke test
Evidence: Live model-switch relaunch evidence
Source: Live model-switch relaunch evidence
Evidence: Herdr workspace layout after concurrent recovery
Source: Herdr workspace layout after concurrent recovery
Evidence: Recovered primary pane
Source: Recovered primary pane
Evidence: Recovered secondmate pane
Source: Recovered secondmate pane
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
bin/backends/herdr.sh:3119- A missing-child relaunch advances the presentation journal before publishing the replacement task record. If record preparation or publication fails (bin/fm-spawn.sh:4896, 4958), abort cleanup closes the new pane (bin/fm-spawn.sh:1255), but the journal still names it. The next retry fails the old-record equality check (bin/backends/herdr.sh:2958) and creates a flat tab (bin/fm-spawn.sh:3538), reproducing the reported layout bug. Keep the journal and record recoverably consistent on prepublication abort.bin/backends/herdr.sh:3348- Herdr can apply a pane move and then return a CLI error. This branch treats that result as proof nothing moved; fm-control.sh:1237 then removes the recovery receipt and prior copies. Even with a successful move response, postmove failures at bin/backends/herdr.sh:3356, 3361, 3369, 3373, 3377, 3382, 3387, or 3391 return before the new IDs are exposed, so fm-control.sh:1242 records a moved receipt with an empty endpoint. Preserve uncertainty after issuing the move, expose response-derived IDs immediately, and make recovery consume the retained receipt.bin/backends/herdr.sh:3167- The live repair also accepts and upgrades version 1 journals (bin/backends/herdr.sh:3209, 3386, 3423). The specified model-switch case uses stale version 2 bindings; no intent requirement needs this less-bound legacy path. Remove version 1 acceptance from this repair.bin/backends/herdr.sh:3297- The new move acceptsstale-agentandno-agentshell panes, including on resume (bin/backends/herdr.sh:3416); fm-control.sh:1194 also admits a dead agent grade. The requested repair is for live replacement workers. Remove the idle-shell acceptance and require a live worker.bin/backends/herdr.sh:3003- The new recreation and live-move paths each copy the token workspace and pane scan (bin/backends/herdr.sh:3261), alongside the existing recovery scan. No intent requirement needs parallel copies of this safety rule. Remove the copies and use one read-only token-risk check.reprojectcommand and demonstrates it in a lab, but provides no evidence that it was applied to the three live tabs. Their actual layout is external to this worktree; confirm and complete that operational repair.🔧 Fix applied.
11 issues (4 errors, 7 warnings) still open:
bin/backends/herdr.sh:3119- A missing-child relaunch advances the presentation journal before publishing the replacement task record. If record preparation or publication fails (bin/fm-spawn.sh:4896, 4958), abort cleanup closes the new pane (bin/fm-spawn.sh:1255), but the journal still names it. The next retry fails the old-record equality check (bin/backends/herdr.sh:2958) and creates a flat tab (bin/fm-spawn.sh:3538), reproducing the reported layout bug. Keep the journal and record recoverably consistent on prepublication abort.bin/backends/herdr.sh:3348- Herdr can apply a pane move and then return a CLI error. This branch treats that result as proof nothing moved; fm-control.sh:1237 then removes the recovery receipt and prior copies. Even with a successful move response, postmove failures at bin/backends/herdr.sh:3356, 3361, 3369, 3373, 3377, 3382, 3387, or 3391 return before the new IDs are exposed, so fm-control.sh:1242 records a moved receipt with an empty endpoint. Preserve uncertainty after issuing the move, expose response-derived IDs immediately, and make recovery consume the retained receipt.bin/backends/herdr.sh:3167- The live repair also accepts and upgrades version 1 journals (bin/backends/herdr.sh:3209, 3386, 3423). The specified model-switch case uses stale version 2 bindings; no intent requirement needs this less-bound legacy path. Remove version 1 acceptance from this repair.bin/backends/herdr.sh:3297- The new move acceptsstale-agentandno-agentshell panes, including on resume (bin/backends/herdr.sh:3416); fm-control.sh:1194 also admits a dead agent grade. The requested repair is for live replacement workers. Remove the idle-shell acceptance and require a live worker.bin/backends/herdr.sh:3003- The new recreation and live-move paths each copy the token workspace and pane scan (bin/backends/herdr.sh:3261), alongside the existing recovery scan. No intent requirement needs parallel copies of this safety rule. Remove the copies and use one read-only token-risk check.reprojectcommand and demonstrates it in a lab, but provides no evidence that it was applied to the three live tabs. Their actual layout is external to this worktree; confirm and complete that operational repair.bin/backends/herdr.sh:3058- A Herdr tab-create error after workspace creation leaves the new token workspace and seeded pane behind, but the relaunch falls back flat. The 33bb3f6 fix round left this post-mutation path at bin/backends/herdr.sh:3058-3067; workspace-create uncertainty at 2586-2605 and seeded-tab prune failure at 2638-2644 have the same risk. A later retry sees the leftover token and again falls back flat. Refuse fallback unless cleanup proves the entire new workspace is gone.bin/fm-spawn.sh:1283- The 33bb3f6 rollback fix restores the old journal only in the EXIT trap and ignores a failed restore write here. A process crash before the trap, or a failed restore, leaves the journal naming the new endpoint while the old task record remains; the next retry fails the equality gate at bin/backends/herdr.sh:2958-2966 and creates a flat tab. Recover this same-identity, journal-ahead state at the shared recreation gate after proving the replacement cannot contain a live worker.bin/backends/herdr.sh:3217- Ifpane movereturns an error before moving and supplies no IDs, the 33bb3f6 fix round retains an empty moved receipt (bin/fm-control.sh:1272-1280). On every rerun,pane getconfirms the original live flat endpoint, but this branch refuses another move indefinitely. Resolve a retained uncertain receipt when the original endpoint and absence of a token child prove no move occurred.bin/fm-control.sh:1085- The change adds prior metadata and journal copies (bin/fm-control.sh:1161-1162, 1225-1228), receiptjournal_boundandmeta_boundfields (1085-1086), andcontrol_reproject_txin task metadata (1133-1141). No recovery path reads any of them, and the stated repair needs only the receipt phase and endpoint. Remove this unused transaction bookkeeping.docs/herdr-backend.md:404- This sentence says a live endpoint refusesreproject, contradicting the live-worker requirement and the allowed live path at bin/backends/herdr.sh:3233-3244. Change the refusal to the actual dead or unverified states.🔧 Fix applied.
13 issues (4 errors, 9 warnings) still open:
bin/backends/herdr.sh:3119- A missing-child relaunch advances the presentation journal before publishing the replacement task record. If record preparation or publication fails (bin/fm-spawn.sh:4896, 4958), abort cleanup closes the new pane (bin/fm-spawn.sh:1255), but the journal still names it. The next retry fails the old-record equality check (bin/backends/herdr.sh:2958) and creates a flat tab (bin/fm-spawn.sh:3538), reproducing the reported layout bug. Keep the journal and record recoverably consistent on prepublication abort.bin/backends/herdr.sh:3348- Herdr can apply a pane move and then return a CLI error. This branch treats that result as proof nothing moved; fm-control.sh:1237 then removes the recovery receipt and prior copies. Even with a successful move response, postmove failures at bin/backends/herdr.sh:3356, 3361, 3369, 3373, 3377, 3382, 3387, or 3391 return before the new IDs are exposed, so fm-control.sh:1242 records a moved receipt with an empty endpoint. Preserve uncertainty after issuing the move, expose response-derived IDs immediately, and make recovery consume the retained receipt.bin/backends/herdr.sh:3167- The live repair also accepts and upgrades version 1 journals (bin/backends/herdr.sh:3209, 3386, 3423). The specified model-switch case uses stale version 2 bindings; no intent requirement needs this less-bound legacy path. Remove version 1 acceptance from this repair.bin/backends/herdr.sh:3297- The new move acceptsstale-agentandno-agentshell panes, including on resume (bin/backends/herdr.sh:3416); fm-control.sh:1194 also admits a dead agent grade. The requested repair is for live replacement workers. Remove the idle-shell acceptance and require a live worker.bin/backends/herdr.sh:3003- The new recreation and live-move paths each copy the token workspace and pane scan (bin/backends/herdr.sh:3261), alongside the existing recovery scan. No intent requirement needs parallel copies of this safety rule. Remove the copies and use one read-only token-risk check.reprojectcommand and demonstrates it in a lab, but provides no evidence that it was applied to the three live tabs. Their actual layout is external to this worktree; confirm and complete that operational repair.bin/backends/herdr.sh:3058- A Herdr tab-create error after workspace creation leaves the new token workspace and seeded pane behind, but the relaunch falls back flat. The 33bb3f6 fix round left this post-mutation path at bin/backends/herdr.sh:3058-3067; workspace-create uncertainty at 2586-2605 and seeded-tab prune failure at 2638-2644 have the same risk. A later retry sees the leftover token and again falls back flat. Refuse fallback unless cleanup proves the entire new workspace is gone.bin/backends/herdr.sh:3217- Ifpane movereturns an error before moving and supplies no IDs, the 33bb3f6 fix round retains an empty moved receipt (bin/fm-control.sh:1272-1280). On every rerun,pane getconfirms the original live flat endpoint, but this branch refuses another move indefinitely. Resolve a retained uncertain receipt when the original endpoint and absence of a token child prove no move occurred.bin/fm-control.sh:1085- The change adds prior metadata and journal copies (bin/fm-control.sh:1161-1162, 1225-1228), receiptjournal_boundandmeta_boundfields (1085-1086), andcontrol_reproject_txin task metadata (1133-1141). No recovery path reads any of them, and the stated repair needs only the receipt phase and endpoint. Remove this unused transaction bookkeeping.bin/backends/herdr.sh:3157- Round 2 added a workspace-absence check but left the journal unchecked. If the journal rename takes effect and then reports an error, this branch closes the new workspace and returns 2 (bin/backends/herdr.sh:3159-3164). fm-spawn.sh:3547-3548 then launches flat while the journal names the removed child; the next relaunch refuses the mismatch. Permit flat fallback only after confirming the journal still matches the old task record, or restore that binding.bin/backends/herdr.sh:3369- With the parent followed by another workspace and ordering unavailable or failing, pane move succeeds but best-effort ordering leaves the child outside the parent block. The binding check then returns 2, leaving the live worker moved while its task record still names the old pane. Every retry has the same dependency. Preflight required ordering before the live move, and keep the endpoint record recoverable if ordering fails afterward. The same dependency affects recreation at bin/backends/herdr.sh:3134-3142; Round 2's resume path retains it at bin/backends/herdr.sh:3395-3397.bin/fm-control.sh:1292- The completed receipt phase is unnecessary once the task record and journal are bound: no recovery path readsphase=complete. Remove the completed receipt write and retain the receipt only for unresolved moves. Its write can currently fail after REPROJECT_PHASE becomes complete, causing the exit handler at bin/fm-control.sh:1093-1094 to skip releasing the session and metadata locks.bin/fm-control.sh:1129- This branch stripscontrol_reproject_tx, but the final change never writes or reads that field. No live-repair or recovery requirement needs this legacy branch from an intermediate fix round; remove it.🔧 Fix applied.
12 issues (4 errors, 8 warnings) still open:
bin/backends/herdr.sh:3119- A missing-child relaunch advances the presentation journal before publishing the replacement task record. If record preparation or publication fails (bin/fm-spawn.sh:4896, 4958), abort cleanup closes the new pane (bin/fm-spawn.sh:1255), but the journal still names it. The next retry fails the old-record equality check (bin/backends/herdr.sh:2958) and creates a flat tab (bin/fm-spawn.sh:3538), reproducing the reported layout bug. Keep the journal and record recoverably consistent on prepublication abort.bin/backends/herdr.sh:3348- Herdr can apply a pane move and then return a CLI error. This branch treats that result as proof nothing moved; fm-control.sh:1237 then removes the recovery receipt and prior copies. Even with a successful move response, postmove failures at bin/backends/herdr.sh:3356, 3361, 3369, 3373, 3377, 3382, 3387, or 3391 return before the new IDs are exposed, so fm-control.sh:1242 records a moved receipt with an empty endpoint. Preserve uncertainty after issuing the move, expose response-derived IDs immediately, and make recovery consume the retained receipt.bin/backends/herdr.sh:3167- The live repair also accepts and upgrades version 1 journals (bin/backends/herdr.sh:3209, 3386, 3423). The specified model-switch case uses stale version 2 bindings; no intent requirement needs this less-bound legacy path. Remove version 1 acceptance from this repair.bin/backends/herdr.sh:3297- The new move acceptsstale-agentandno-agentshell panes, including on resume (bin/backends/herdr.sh:3416); fm-control.sh:1194 also admits a dead agent grade. The requested repair is for live replacement workers. Remove the idle-shell acceptance and require a live worker.bin/backends/herdr.sh:3003- The new recreation and live-move paths each copy the token workspace and pane scan (bin/backends/herdr.sh:3261), alongside the existing recovery scan. No intent requirement needs parallel copies of this safety rule. Remove the copies and use one read-only token-risk check.reprojectcommand and demonstrates it in a lab, but provides no evidence that it was applied to the three live tabs. Their actual layout is external to this worktree; confirm and complete that operational repair.bin/backends/herdr.sh:3058- A Herdr tab-create error after workspace creation leaves the new token workspace and seeded pane behind, but the relaunch falls back flat. The 33bb3f6 fix round left this post-mutation path at bin/backends/herdr.sh:3058-3067; workspace-create uncertainty at 2586-2605 and seeded-tab prune failure at 2638-2644 have the same risk. A later retry sees the leftover token and again falls back flat. Refuse fallback unless cleanup proves the entire new workspace is gone.bin/backends/herdr.sh:3217- Ifpane movereturns an error before moving and supplies no IDs, the 33bb3f6 fix round retains an empty moved receipt (bin/fm-control.sh:1272-1280). On every rerun,pane getconfirms the original live flat endpoint, but this branch refuses another move indefinitely. Resolve a retained uncertain receipt when the original endpoint and absence of a token child prove no move occurred.bin/backends/herdr.sh:3157- Round 2 added a workspace-absence check but left the journal unchecked. If the journal rename takes effect and then reports an error, this branch closes the new workspace and returns 2 (bin/backends/herdr.sh:3159-3164). fm-spawn.sh:3547-3548 then launches flat while the journal names the removed child; the next relaunch refuses the mismatch. Permit flat fallback only after confirming the journal still matches the old task record, or restore that binding.bin/backends/herdr.sh:3369- With the parent followed by another workspace and ordering unavailable or failing, pane move succeeds but best-effort ordering leaves the child outside the parent block. The binding check then returns 2, leaving the live worker moved while its task record still names the old pane. Every retry has the same dependency. Preflight required ordering before the live move, and keep the endpoint record recoverable if ordering fails afterward. The same dependency affects recreation at bin/backends/herdr.sh:3134-3142; Round 2's resume path retains it at bin/backends/herdr.sh:3395-3397.bin/backends/herdr.sh:3342- The live repair assumes the journal’s old child is gone, but the token scan matches labels only. If that exact workspace survives under a renamed label, reproject moves the flat worker at bin/backends/herdr.sh:3396 and overwrites the old binding at :3442; resume can overwrite it at :3477. Round 3’s token-scan extraction left this ID check absent. Prove the journal workspace ID is absent before moving or rebinding.bin/backends/herdr.sh:3463- Round 4 left ordering before verification in the Round 3 resume path. After a move succeeds but rebind stops, a user can rename the new child; retry reorders that receipt-named workspace at :3463, then rejects its changed label at :3464. The callers at :3305, :3332, and :3500 reach this path. Verify the exact unordered binding before changing workspace order.🔧 Fix applied.
1 warning still open:
reprojectcommand and demonstrates it in a lab, but provides no evidence that it was applied to the three live tabs. Their actual layout is external to this worktree; confirm and complete that operational repair.🔧 **Test** - 2 issues found → no changes applied ✅
git -C ~/.no-mistakes/worktrees/f4bb769f35f8/01M3G8M8YGQPZF8RA5EE5Z86N8 statusandgit -C ~/.no-mistakes/worktrees/f4bb769f35f8/01M3G8M8YGQPZF8RA5EE5Z86N8 diff). Respond with fix to validate it, or abort.🔧 No changes applied.
✅ Re-checked - no issues remain.
tests/fm-backend-herdr.test.sh: initial fixture failure reproduced; fixture fixed and rerun passedtests/fm-control.test.sh: passedtimeout 420s tests/fm-control-herdr-smoke.test.sh: passedtimeout 900s tests/fm-backend-herdr-presentation-e2e.test.sh: passed through model-switch relaunch, then reached the time limitTwo focused named-lab runs of the concurrent recovery test body: passed; the second saved live workspace and pane responsesbin/fm-herdr-lab.sh teardown fm-lab-fm-herdr-present-2709868-20381: removed the stopped lab left by the timed-out runRead-only Herdr session inventory confirmed no remainingfm-lab-*sessions; working tree contains only the three validated test edits✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.
Upstream Checks
CI and Require no-mistakes both report action_required with zero jobs and no logs on this fork PR head, so no CI code ran. Both wait for upstream maintainer workflow approval. This PR is NOT ready to merge on checks, and the three live tabs stay unchanged until after merge and update.