Skip to content

fix(bin): release live captain-held work on a keyed answer instead of closing it - #83

Merged
MrGTV-love merged 13 commits into
mainfrom
fm/fm-board-answer-closes-live-work
Oct 10, 2026
Merged

MrGTV-love merged 13 commits into
mainfrom
fm/fm-board-answer-closes-live-work

Conversation

@MrGTV-love

Copy link
Copy Markdown
Owner

Intent

I would like all bugs to be fixed so tomorrow can be focused entirely to Vernant and not problems preventning Vernant from getting built.

A recommended architecture should come with proof.

Context (the backlog record for this bug, as filed):

A board answer on a captain-held work item closes the item while its worker is still running (repo: firstmate) (kind: ship) (priority: 2) (since 2026-10-08)
Observed 2026-10-08: board batch lavish-82c7cf68f2a2600b.110 answered decisions held on the live work items fm-lifecycle-phase3, fm-jev-retire-invented, fm-supervision-watchdog-outside-session and fm-task-copy-reassociate; each was closed to Done (fm-captain-hold answer's question-shaped close) while its worker was still validating; retention then pruned fm-task-copy-reassociate entirely. Main reopened three and re-created one. Policy (captain-hold-lifecycle skill): a hold on the work item a question gates must release the item to proceed, never record completion before landing. Fix the answers intake so a keyed answer on an in-flight or spawned work item releases it (records the words) instead of closing it; behavioral test with a live task meta. mode=no-mistakes yolo=off.

What Changed

  • bin/fm-captain-hold.sh: answers now sends the empty and done modes through a new internal answer --auto-release path. Under the task control lock, that path releases the hold (and records the captain's words) when the task is In flight or still has a $STATE/<id>.meta runtime record, and completes the task only when no worker owns it. Resolution records now carry a Resolves hold set: line. An interrupted release can then finish safely after teardown, a re-held task gets its own new record, and a legacy release with no hold association is refused for automatic completion. hold now takes the task control lock before it picks its stamp, and it refuses a FM_CAPTAIN_HOLD_NOW value that collides with the newest resolved hold. Keyed replays re-check the task under the lock and skip a snapshot that a concurrent hold changed.
  • bin/fm-backlog-transition-lib.sh: close-marker replay now selects the transition from the current row. A mode=retain record whose hold was released before replay closes the finished row instead of reopening unheld work, and it drops only a known-unsupported relocated report artifact.
  • tests/fm-captain-hold-lifecycle.test.sh adds behavioral regressions, including test_keyed_answer_releases_a_live_work_item with a live task meta, plus cases for cleanup ordering, interrupted and completed release replay, a concurrent hold, a repeated answer on a re-held task, and the legacy refusal. docs/captain-hold-lifecycle.md and docs/verification/process-event-sources.md describe automatic resolution and point to the script help as the owner of keyed syntax and replay rules.

Risk Assessment

⚠️ Medium: The fix satisfies the intent and the recorded owner decisions (D, review-6), and every traced path behaved correctly, but it changes a lock-guarded, crash-recovery state machine across the answer intake, hold stamping, and cleanup replay, so it carries more than trivial merge risk.

Testing

I drove the real firstmate commands (fm-captain-hold.sh, fm-teardown.sh, fm-procevent.sh, tasks-axi) in a marked throwaway lab home with plain FM_HOME. Only the external tools tmux, treehouse, gh, gh-axi, no-mistakes and herdr were stubs, so the real fleet was safe. Eight live scenarios passed. Six were on the fixed code. Two reproduced the bug on the base commit. On base commit 924f479, the same batch closed all live work items to Done. That is the reported bug. Three race and crash scenarios need fault injection, so they are marked untested. The existing targeted tests for them passed, but those tests do not count as live runs. I did not start a Claude primary or a Herdr session, because this change is a command-line change with no agent or screen surface. There is no screenshot for the same reason; the evidence is command transcripts. One behavior did not change, by owner decision: a direct answer without --release still closes the item. I removed both labs and the base copy. The worktree is clean.

  • Live validation: ✅ go - 8 of 11 scenarios driven live against the product
Scenario Result Live Evidence
Captain answers a board batch for held work that still has a worker (in-flight scout, spawned ship, in-flight row with no worker record): each item stays open, the hold lifts, the words are recorded a… ✅ pass live s1-fixed.txt (real fm-captain-hold.sh answers in a lab home; default and done modes)
The same batch on the base commit 924f479 closes every live work item to Done (the reported bug reproduces before the fix) ✅ pass live s1-base-924f479c.txt and s5-base-924f479c.txt (base scripts from git archive, run in a second lab home)
A plain captain question with no worker still closes to Done on a keyed answer ✅ pass live s1-fixed.txt, task lab-plain-question: state done, mode answered
A board result in the Lavish poll shape flows through fm-procevent to the intake and releases a live work item instead of closing it ✅ pass live s5-fixed.txt (fm-procevent.sh register, bind, start; answers-fed; task in_flight, released). The board source was a script that prints a poll result; no real Lavish server was used.
After the release, the worker finishes and cleanup closes the item to Done; the same answer sent again (before and after cleanup) reports closed and changes nothing ✅ pass live s2-fixed.txt (real fm-teardown.sh in the lab; state done, record still released, exit 0 on both replays)
Adversarial: work finishes and cleanup runs while the item is still held; a late keyed answer closes it to Done with its report and does not make it runnable again ✅ pass live s3-fixed.txt (after teardown: queued, held, no worker record; after answer: done, answered, report line kept)
Adversarial: a re-hold in the same pinned second is refused with a clear message; a later re-hold plus the identical answer writes a second record and leaves record 1 unchanged ✅ pass live s4-fixed.txt (FM_CAPTAIN_HOLD_NOW collides ... exit 1; resolution records now: 2; record 1 text UNCHANGED)
Boundary: explicit release mode releases, an unknown mode is skipped, the reserved value reconcile is refused, and held items stay held when skipped ✅ pass live s6-fixed.txt (closed=1 skipped=2, exit 1; bogus and reconcile items still held and in_flight)
Race: an answer that arrives while cleanup holds the task lock waits, then closes the finished item instead of releasing it ⏸️ untested no The prior payload did not establish a live result for this scenario. It needs a pause injected inside teardown at an exact point, and only the test barriers can do that. The targeted test `test_keyed_…
Crash recovery: a release interrupted before the hold lifts closes after teardown; a completed release replays after a failed parent publication without a record rewrite ⏸️ untested no The prior payload did not establish a live result for this scenario. It needs a forced failure in the middle of one command and a secondmate parent home, and only the test fault injection can do that.…
Race: a stale replay does not resolve a new hold opened at the same time and does not delete its reconcile request; a legacy release with no hold stamp needs an explicit close ⏸️ untested no The prior payload did not establish a live result for this scenario. It needs two commands interleaved at an exact point under the lock, and only the test barriers can do that. The targeted tests `tes…
Evidence: S1 fixed code: board batch releases live work

Source: S1 fixed code: board batch releases live work

$ fm-captain-hold.sh answers --source "lab board batch" < batch.tsv closed: lab-live-scout closed: lab-live-ship closed: lab-row-only closed: lab-plain-question answers: closed=4 skipped=0 [exit 0] --- task lab-live-scout --- state: in_flight held: no Resolution mode: released Answer: go-b / Option B worker record: PRESENT --- task lab-live-ship --- state: queued held: no Resolution mode: released worker record: PRESENT --- task lab-row-only --- state: in_flight held: no Resolution mode: released worker record: absent --- task lab-plain-question --- state: done held: no Resolution mode: answered


\### S1 setup: four captain-held items (in-flight scout with worker, spawned ship with worker, in-flight row only, plain question)
$ cap hold lab-live-scout --reason captain design pick needed
lab-live-scout
[exit 0]
$ cap hold lab-live-ship --reason captain design pick needed
lab-live-ship
[exit 0]
$ cap hold lab-row-only --reason captain design pick needed
lab-row-only
[exit 0]
$ cap hold lab-plain-question --title Captain call: plain --reason captain choice pending --repo sample
lab-plain-question
[exit 0]
--- task lab-live-scout ---
  state: in_flight
  held: yes
  kind: scout
  body| Captain hold set: 2026-10-09T22:31:59Z
  worker record: PRESENT
--- task lab-live-ship ---
  state: queued
  held: yes
  kind: ship
  body| Captain hold set: 2026-10-09T22:32:00Z
  worker record: PRESENT
--- task lab-row-only ---
  state: in_flight
  held: yes
  kind: ship
  body| Captain hold set: 2026-10-09T22:32:02Z
  worker record: absent
--- task lab-plain-question ---
  state: queued
  held: yes
  kind: captain
  body| Captain hold set: 2026-10-09T22:32:04Z
  worker record: absent

\### S1 act: one keyed board batch answers all four (default, done, done, default)
$ fm-captain-hold.sh answers --source "lab board batch" < batch.tsv
lab-live-scout^Igo-b^IOption B$
lab-live-ship^Igo-b^IOption B^Idone$
lab-row-only^Igo-b^IOption B^Idone$
lab-plain-question^Iyes^IYes$
closed: lab-live-scout
closed: lab-live-ship
closed: lab-row-only
closed: lab-plain-question
answers: closed=4 skipped=0
[exit 0]

\### S1 result
--- task lab-live-scout ---
  state: in_flight
  held: no
  kind: scout
  body: "Resolution recorded by fm-captain-hold.\nDecision digest: 59d2f078f3888c5fccda18c86991c53610842075a9a149787975e4674bdd8e3d\nResolution mode: released\nResolves hold set: 2026-10-09T22:31:59Z\n\nCaptain decision:\nCaptain answered this call through lab board batch.\nTask: lab-live-scout\nAnswer: go-b\nAnswer as shown to the captain: Option B"
  body| Resolution mode: released
  body| Resolves hold set: 2026-10-09T22:31:59Z
  body| Captain decision:
  body| Captain answered this call through lab board batch.
  body| Answer: go-b
  body| Answer as shown to the captain: Option B
  worker record: PRESENT
--- task lab-live-ship ---
  state: queued
  held: no
  kind: ship
  body: "Resolution recorded by fm-captain-hold.\nDecision digest: 5c17cff96b7305530f8123214b23f6c55fff4b9b8dbb8872b5c51d1e4e178397\nResolution mode: released\nResolves hold set: 2026-10-09T22:32:00Z\n\nCaptain decision:\nCaptain answered this call through lab board batch.\nTask: lab-live-ship\nAnswer: go-b\nAnswer as shown to the captain: Option B"
  body| Resolution mode: released
  body| Resolves hold set: 2026-10-09T22:32:00Z
  body| Captain decision:
  body| Captain answered this call through lab board batch.
  body| Answer: go-b
  body| Answer as shown to the captain: Option B
  worker record: PRESENT
--- task lab-row-only ---
  state: in_flight
  held: no
  kind: ship
  body: "Resolution recorded by fm-captain-hold.\nDecision digest: a4ed1563462a6c924fedb42020855feb48557a66991379824aa481b8d4ae34f4\nResolution mode: released\nResolves hold set: 2026-10-09T22:32:02Z\n\nCaptain decision:\nCaptain answered this call through lab board batch.\nTask: lab-row-only\nAnswer: go-b\nAnswer as shown to the captain: Option B"
  body| Resolution mode: released
  body| Resolves hold set: 2026-10-09T22:32:02Z
  body| Captain decision:
  body| Captain answered this call through lab board batch.
  body| Answer: go-b
  body| Answer as shown to the captain: Option B
  worker record: absent
--- task lab-plain-question ---
  state: done
  held: no
  kind: captain
  body: "Resolution recorded by fm-captain-hold.\nDecision digest: 14f078e010c38ed1dd098b9978ec74e9081573872a83e31e0ba17083476e4ffb\nResolution mode: answered\nResolves hold set: 2026-10-09T22:32:04Z\n\nCaptain decision:\nCaptain answered this call through lab board batch.\nTask: lab-plain-question\nAnswer: yes\nAnswer as shown to the captain: Yes"
  body| Resolution mode: answered
  body| Resolves hold set: 2026-10-09T22:32:04Z
  body| Captain decision:
  body| Captain answered this call through lab board batch.
  body| Answer: yes
  body| Answer as shown to the captain: Yes
  worker record: absent
--- backlog.md ---
## In flight
- [ ] lab-row-only - Ship the row-only sample (repo: sample) (kind: ship) (since 2026-10-09)
  Resolution recorded by fm-captain-hold.
  Decision digest: a4ed1563462a6c924fedb42020855feb48557a66991379824aa481b8d4ae34f4
  Resolution mode: released
  Resolves hold set: 2026-10-09T22:32:02Z

  Captain decision:
  Captain answered this call through lab board batch.
  Task: lab-row-only
  Answer: go-b
  Answer as shown to the captain: Option B

- [ ] lab-live-scout - Review the live sample (repo: sample) (kind: scout) (since 2026-10-09)
  Resolution recorded by fm-captain-hold.
  Decision digest: 59d2f078f3888c5fccda18c86991c53610842075a9a149787975e4674bdd8e3d
  Resolution mode: released
  Resolves hold set: 2026-10-09T22:31:59Z

  Captain decision:
  Captain answered this call through lab board batch.
  Task: lab-live-scout
  Answer: go-b
  Answer as shown to the captain: Option B

## Queued
- [ ] lab-live-ship - Ship the live sample (repo: sample) (kind: ship) (since 2026-10-09)
  Resolution recorded by fm-captain-hold.
  Decision digest: 5c17cff96b7305530f8123214b23f6c55fff4b9b8dbb8872b5c51d1e4e178397
  Resolution mode: released
  Resolves hold set: 2026-10-09T22:32:00Z

  Captain decision:
  Captain answered this call through lab board batch.
  Task: lab-live-ship
  Answer: go-b
  Answer as shown to the captain: Option B

## Done
- [x] lab-plain-question - Captain call: plain (repo: sample) (kind: captain) (done 2026-10-09) (hold: fm-hold-v1:Y2FwdGFpbiBjaG9pY2UgcGVuZGluZw==) (hold-kind: 
  Resolution recorded by fm-captain-hold.
  Decision digest: 14f078e010c38ed1dd098b9978ec74e9081573872a83e31e0ba17083476e4ffb
  Resolution mode: answered
  Resolves hold set: 2026-10-09T22:32:04Z

  Captain decision:
  Captain answered this call through lab board batch.
  Task: lab-plain-question
  Answer: yes
  Answer as shown to the captain: Yes
Evidence: S1 base commit 924f479: same batch closes live work (the bug)

Source: S1 base commit 924f479c: same batch closes live work (the bug)

--- task lab-live-scout --- state: done held: no Resolution mode: answered worker record: PRESENT --- task lab-live-ship --- state: done held: no Resolution mode: answered worker record: PRESENT --- task lab-row-only --- state: done held: no Resolution mode: answered --- task lab-plain-question --- state: done held: no Resolution mode: answered


\### S1 setup: four captain-held items (in-flight scout with worker, spawned ship with worker, in-flight row only, plain question)
$ cap hold lab-live-scout --reason captain design pick needed
lab-live-scout
[exit 0]
$ cap hold lab-live-ship --reason captain design pick needed
lab-live-ship
[exit 0]
$ cap hold lab-row-only --reason captain design pick needed
lab-row-only
[exit 0]
$ cap hold lab-plain-question --title Captain call: plain --reason captain choice pending --repo sample
lab-plain-question
[exit 0]
--- task lab-live-scout ---
  state: in_flight
  held: yes
  kind: scout
  body| Captain hold set: 2026-10-09T22:34:03Z
  worker record: PRESENT
--- task lab-live-ship ---
  state: queued
  held: yes
  kind: ship
  body| Captain hold set: 2026-10-09T22:34:04Z
  worker record: PRESENT
--- task lab-row-only ---
  state: in_flight
  held: yes
  kind: ship
  body| Captain hold set: 2026-10-09T22:34:06Z
  worker record: absent
--- task lab-plain-question ---
  state: queued
  held: yes
  kind: captain
  body| Captain hold set: 2026-10-09T22:34:07Z
  worker record: absent

\### S1 act: one keyed board batch answers all four (default, done, done, default)
$ fm-captain-hold.sh answers --source "lab board batch" < batch.tsv
lab-live-scout^Igo-b^IOption B$
lab-live-ship^Igo-b^IOption B^Idone$
lab-row-only^Igo-b^IOption B^Idone$
lab-plain-question^Iyes^IYes$
closed: lab-live-scout
closed: lab-live-ship
closed: lab-row-only
closed: lab-plain-question
answers: closed=4 skipped=0
[exit 0]

\### S1 result
--- task lab-live-scout ---
  state: done
  held: no
  kind: scout
  body| Resolution mode: answered
  body| Captain decision:
  body| Captain answered this call through lab board batch.
  body| Answer: go-b
  body| Answer as shown to the captain: Option B
  worker record: PRESENT
--- task lab-live-ship ---
  state: done
  held: no
  kind: ship
  body| Resolution mode: answered
  body| Captain decision:
  body| Captain answered this call through lab board batch.
  body| Answer: go-b
  body| Answer as shown to the captain: Option B
  worker record: PRESENT
--- task lab-row-only ---
  state: done
  held: no
  kind: ship
  body| Resolution mode: answered
  body| Captain decision:
  body| Captain answered this call through lab board batch.
  body| Answer: go-b
  body| Answer as shown to the captain: Option B
  worker record: absent
--- task lab-plain-question ---
  state: done
  held: no
  kind: captain
  body| Resolution mode: answered
  body| Captain decision:
  body| Captain answered this call through lab board batch.
  body| Answer: yes
  body| Answer as shown to the captain: Yes
  worker record: absent
Evidence: S2 fixed code: cleanup completes released work; replays are safe

Source: S2 fixed code: cleanup completes released work; replays are safe


\### S2: the worker of lab-live-scout finishes; cleanup (teardown) runs; then the same board answer arrives again

\### replay while the worker still runs
closed: lab-live-scout
answers: closed=1 skipped=0
[exit 0]
--- task lab-live-scout ---
  state: in_flight
  held: no
  kind: scout
  body: "Resolution recorded by fm-captain-hold.\nDecision digest: 59d2f078f3888c5fccda18c86991c53610842075a9a149787975e4674bdd8e3d\nResolution mode: released\nResolves hold set: 2026-10-09T22:31:59Z\n\nCaptain decision:\nCaptain answered this call through lab board batch.\nTask: lab-live-scout\nAnswer: go-b\nAnswer as shown to the captain: Option B"
  body| Resolution mode: released
  body| Resolves hold set: 2026-10-09T22:31:59Z
  body| Captain decision:
  body| Captain answered this call through lab board batch.
  body| Answer: go-b
  body| Answer as shown to the captain: Option B
  worker record: PRESENT
$ cap complete lab-live-scout --none
complete: lab-live-scout captain-call inventory reviewed
[exit 0]
$ td lab-live-scout
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/tmp/fm-lab.Z8wqvn
●━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
●  WATCHER DOWN - SUPERVISION IS OFF
●  2 task(s) in flight, but no watcher has a fresh beacon (last beat: never, grace 900s).
●  Trust the emitted supervision protocol for this harness; do not use shell & for watcher repair.
●  This is a supervision warning only; the guarded operation WILL still run.
●  watcher supervision needs Stop-owned automatic recovery; inspect the hook registration and startup status before ending the turn.
●━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
teardown lab-live-scout complete (window firstmate:fm-lab-live-scout, worktree ~/tmp/fm-lab.Z8wqvn/projects/missing-lab-live-scout)
Backlog: lab-live-scout is closed in ~/tmp/fm-lab.Z8wqvn/data/backlog.md. Run bin/fm-tasks-axi.sh ready for dependency-cleared candidates, check date gates, and dispatch only work whose blockers are gone and date is due.
[exit 0]
--- task lab-live-scout ---
  state: done
  held: no
  kind: scout
  body: "Resolution recorded by fm-captain-hold.\nDecision digest: 59d2f078f3888c5fccda18c86991c53610842075a9a149787975e4674bdd8e3d\nResolution mode: released\nResolves hold set: 2026-10-09T22:31:59Z\n\nCaptain decision:\nCaptain answered this call through lab board batch.\nTask: lab-live-scout\nAnswer: go-b\nAnswer as shown to the captain: Option B"
  body| Resolution mode: released
  body| Resolves hold set: 2026-10-09T22:31:59Z
  body| Captain decision:
  body| Captain answered this call through lab board batch.
  body| Answer: go-b
  body| Answer as shown to the captain: Option B
  worker record: absent

\### replay after cleanup completed the work
closed: lab-live-scout
answers: closed=1 skipped=0
[exit 0]
--- task lab-live-scout ---
  state: done
  held: no
  kind: scout
  body: "Resolution recorded by fm-captain-hold.\nDecision digest: 59d2f078f3888c5fccda18c86991c53610842075a9a149787975e4674bdd8e3d\nResolution mode: released\nResolves hold set: 2026-10-09T22:31:59Z\n\nCaptain decision:\nCaptain answered this call through lab board batch.\nTask: lab-live-scout\nAnswer: go-b\nAnswer as shown to the captain: Option B"
  body| Resolution mode: released
  body| Resolves hold set: 2026-10-09T22:31:59Z
  body| Captain decision:
  body| Captain answered this call through lab board batch.
  body| Answer: go-b
  body| Answer as shown to the captain: Option B
  worker record: absent
Evidence: S3 fixed code: late answer on finished held work closes it with its report

Source: S3 fixed code: late answer on finished held work closes it with its report


\### S3 (adversarial): work is finished and cleaned up while still held; the answer arrives late. It must close, not reopen.
$ cap hold lab-late-answer --reason captain report choice pending
lab-late-answer
[exit 0]
$ cap complete lab-late-answer lab-late-answer-call
complete: lab-late-answer captain-call inventory reviewed (lab-late-answer-call)
[exit 0]
$ td lab-late-answer
fm-gate-refuse: gate agent lifecycle permitted only against lab home ~/tmp/fm-lab.Z8wqvn
WARNING: watcher still down (same stale episode; last beat: never, grace 900s) - full banner already printed this episode.
teardown lab-late-answer complete (window firstmate:fm-lab-late-answer, worktree ~/tmp/fm-lab.Z8wqvn/projects/missing-lab-late-answer)
Backlog: lab-late-answer stays open in ~/tmp/fm-lab.Z8wqvn/data/backlog.md, still held for the captain with its deliverable recorded. Relay the question and close it only with bin/fm-captain-hold.sh answer.
[exit 0]
--- task lab-late-answer ---
  state: queued
  held: yes
  kind: scout
  body: "Captain hold set: 2026-10-09T22:33:01Z\n\nDeliverable of the finished work: report data/lab-late-answer/report.md"
  body| Captain hold set: 2026-10-09T22:33:01Z
  body| Deliverable of the finished work: report data/lab-late-answer/report.md
  worker record: absent
closed: lab-late-answer
answers: closed=1 skipped=0
[exit 0]
--- task lab-late-answer ---
  state: done
  held: no
  kind: scout
  body: "Resolution recorded by fm-captain-hold.\nDecision digest: c145b88435712dd4bac993f1855f61b426c5823ced2f433c4acdb689cb22a7b8\nResolution mode: answered\nResolves hold set: 2026-10-09T22:33:01Z\n\nCaptain decision:\nCaptain answered this call through lab late board.\nTask: lab-late-answer\nAnswer: go\nAnswer as shown to the captain: Proceed\n\nDeliverable of the finished work: report data/lab-late-answer/report.md"
  body| Resolution mode: answered
  body| Resolves hold set: 2026-10-09T22:33:01Z
  body| Captain decision:
  body| Captain answered this call through lab late board.
  body| Answer: go
  body| Answer as shown to the captain: Proceed
  body| Deliverable of the finished work: report data/lab-late-answer/report.md
  worker record: absent
Evidence: S4 fixed code: same-second re-hold refused; repeated answer writes record 2

Source: S4 fixed code: same-second re-hold refused; repeated answer writes record 2

(pinned FM_CAPTAIN_HOLD_NOW=2026-07-14T12:00:00Z) $ cap hold lab-rehold --reason second question fm-captain-hold: FM_CAPTAIN_HOLD_NOW collides with the newest resolved hold for task lab-rehold; choose a later timestamp [exit 1] ... resolution records now: 2 record 1 text: UNCHANGED inside the new body


\### S4 (adversarial): release, re-hold in the same pinned second, re-hold later, same answer again
(pinned FM_CAPTAIN_HOLD_NOW=2026-07-14T12:00:00Z)
$ cap hold lab-rehold --reason first question
lab-rehold
[exit 0]
closed: lab-rehold
answers: closed=1 skipped=0
[exit 0]
--- task lab-rehold ---
  state: in_flight
  held: no
  kind: scout
  body| Resolution mode: released
  body| Resolves hold set: 2026-07-14T12:00:00Z
  body| Captain decision:
  body| Captain answered this call through lab rehold board.
  body| Answer: go
  body| Answer as shown to the captain: Proceed
  worker record: PRESENT

\### same-second re-hold with pinned time must refuse
(pinned FM_CAPTAIN_HOLD_NOW=2026-07-14T12:00:00Z)
$ cap hold lab-rehold --reason second question
fm-captain-hold: FM_CAPTAIN_HOLD_NOW collides with the newest resolved hold for task lab-rehold; choose a later timestamp
[exit 1]
--- task lab-rehold ---
  state: in_flight
  held: no
  kind: scout
  body| Resolution mode: released
  body| Resolves hold set: 2026-07-14T12:00:00Z
  body| Captain decision:
  body| Captain answered this call through lab rehold board.
  body| Answer: go
  body| Answer as shown to the captain: Proceed
  worker record: PRESENT

\### later re-hold, then the identical answer
(pinned FM_CAPTAIN_HOLD_NOW=2026-07-14T12:00:01Z)
$ cap hold lab-rehold --reason second question
lab-rehold
[exit 0]
--- task lab-rehold ---
  state: in_flight
  held: yes
  kind: scout
  body| Captain hold set: 2026-07-14T12:00:01Z
  body| Resolution mode: released
  body| Resolves hold set: 2026-07-14T12:00:00Z
  body| Captain decision:
  body| Captain answered this call through lab rehold board.
  body| Answer: go
  body| Answer as shown to the captain: Proceed
  worker record: PRESENT
closed: lab-rehold
answers: closed=1 skipped=0
[exit 0]
--- task lab-rehold ---
  state: in_flight
  held: no
  kind: scout
  body| Resolution mode: released
  body| Resolves hold set: 2026-07-14T12:00:01Z
  body| Captain decision:
  body| Captain answered this call through lab rehold board.
  body| Answer: go
  body| Answer as shown to the captain: Proceed
  body| Resolution mode: released
  body| Resolves hold set: 2026-07-14T12:00:00Z
  body| Captain decision:
  body| Captain answered this call through lab rehold board.
  body| Answer: go
  body| Answer as shown to the captain: Proceed
  worker record: PRESENT
resolution records now: 2
record 1 text: UNCHANGED inside the new body
Evidence: S5 fixed code: board result through fm-procevent releases live work

Source: S5 fixed code: board result through fm-procevent releases live work

$ pe start lavish-b0a4d0000000f1e2 reconciles-fed: lavish-b0a4d0000000f1e2 answers-fed: lavish-b0a4d0000000f1e2 --- task lab-board-work --- state: in_flight held: no Resolution mode: released Captain answered this call through the captured result lavish-b0a4d0000000f1e2 sequence 1. Answer: north worker record: PRESENT


\### S5: a real board result (Lavish poll shape) flows through fm-procevent into the intake, for a live work item
$ cap hold lab-board-work --reason captain board route choice pending
lab-board-work
[exit 0]
$ pe register lavish lavish-b0a4d0000000f1e2 -- ~/tmp/fm-lab.Z8wqvn/board-source.sh
registered: lavish-b0a4d0000000f1e2 (lavish)
[exit 0]
$ cap bind lavish-b0a4d0000000f1e2
bound: lavish-b0a4d0000000f1e2 -> (any)
[exit 0]
$ pe start lavish-b0a4d0000000f1e2
reconciles-fed: lavish-b0a4d0000000f1e2
answers-fed: lavish-b0a4d0000000f1e2
not-autohandled: lavish-b0a4d0000000f1e2 (left for the handler; still unacknowledged)
captured: ~/tmp/fm-lab.Z8wqvn/state/procevent-inbox/lavish-b0a4d0000000f1e2.1.result
[exit 0]
--- task lab-board-work ---
  state: in_flight
  held: no
  kind: ship
  body| Resolution mode: released
  body| Resolves hold set: 2026-10-09T22:33:39Z
  body| Captain decision:
  body| Captain answered this call through the captured result lavish-b0a4d0000000f1e2 sequence 1.
  body| Answer: north
  body| Answer as shown to the captain: Take the north route
  worker record: PRESENT
Evidence: S5 base commit 924f479: board result closes live work (the bug)

Source: S5 base commit 924f479c: board result closes live work (the bug)

--- task lab-board-work --- state: done held: no Resolution mode: answered worker record: PRESENT


\### S5: a real board result (Lavish poll shape) flows through fm-procevent into the intake, for a live work item
$ cap hold lab-board-work --reason captain board route choice pending
lab-board-work
[exit 0]
$ pe register lavish lavish-b0a4d0000000f1e2 -- ~/tmp/fm-lab.5D7oJk/board-source.sh
registered: lavish-b0a4d0000000f1e2 (lavish)
[exit 0]
$ cap bind lavish-b0a4d0000000f1e2
bound: lavish-b0a4d0000000f1e2 -> (any)
[exit 0]
$ pe start lavish-b0a4d0000000f1e2
reconciles-fed: lavish-b0a4d0000000f1e2
answers-fed: lavish-b0a4d0000000f1e2
not-autohandled: lavish-b0a4d0000000f1e2 (left for the handler; still unacknowledged)
captured: ~/tmp/fm-lab.5D7oJk/state/procevent-inbox/lavish-b0a4d0000000f1e2.1.result
[exit 0]
--- task lab-board-work ---
  state: done
  held: no
  kind: ship
  body| Resolution mode: answered
  body| Captain decision:
  body| Captain answered this call through the captured result lavish-b0a4d0000000f1e2 sequence 1.
  body| Answer: north
  body| Answer as shown to the captain: Take the north route
  worker record: PRESENT
Evidence: S6 fixed code: explicit release, unknown mode, reconcile, direct answer

Source: S6 fixed code: explicit release, unknown mode, reconcile, direct answer

closed: lab-m-release skipped: lab-m-bogus (unknown close mode bogus) refused: lab-m-reconcile (reconcile requests require a bound captured source) answers: closed=1 skipped=2 [exit 1]


\### S6 (boundary): explicit release mode, unknown mode, reserved reconcile value, direct answer without --release
closed: lab-m-release
skipped: lab-m-bogus (unknown close mode bogus)
refused: lab-m-reconcile (reconcile requests require a bound captured source)
answers: closed=1 skipped=2
[exit 1]
--- task lab-m-release ---
  state: in_flight
  held: no
  kind: ship
  body| Resolution mode: released
  body| Resolves hold set: 2026-10-09T22:33:45Z
  body| Captain decision:
  body| Captain answered this call through lab modes.
  body| Answer: go
  body| Answer as shown to the captain: Go
  worker record: PRESENT
--- task lab-m-bogus ---
  state: in_flight
  held: yes
  kind: ship
  body| Captain hold set: 2026-10-09T22:33:46Z
  worker record: PRESENT
--- task lab-m-reconcile ---
  state: in_flight
  held: yes
  kind: ship
  body| Captain hold set: 2026-10-09T22:33:48Z
  worker record: PRESENT

\### direct 'answer' without --release keeps its documented explicit close (not changed by this fix)
$ cap answer lab-m-direct --decision-file ~/tmp/fm-lab.Z8wqvn/direct.txt
answered: lab-m-direct
[exit 0]
--- task lab-m-direct ---
  state: done
  held: no
  kind: ship
  body| Resolution mode: answered
  body| Resolves hold set: 2026-10-09T22:33:49Z
  body| Captain decision:
  worker record: PRESENT
Evidence: Targeted keyed-answer tests (race and crash cases)

Source: Targeted keyed-answer tests (race and crash cases)

ok - a keyed answer releases a live work item and still closes a question
ok - default and done keyed answers choose their mode after cleanup releases the lock
ok - interrupted default and done releases close finished work while explicit mode checks stay strict
ok - completed default and done releases replay and recover failed publication without rewriting history
ok - stale default, done and release replays preserve a concurrent hold until a fresh answer
ok - repeated default and done answers preserve prior holds and resolve the current parent decision
ok - ambiguous legacy default and done releases require explicit closure without rewriting history
ok - a bound channel's captured answers close their captain-held tasks at answer time
ok - a board answer reaches the keyed-answer intake and wakes firstmate
ok - an unsupported relocated report does not wedge the captain's answer
ok - an unsupported relocated report does not wedge the captain's answer
ok - cleanup replay closes answered work and preserves the report after direct or keyed answers
Evidence: Lab driver script used for all live scenarios

Source: Lab driver script used for all live scenarios

#!/usr/bin/env bash
# Live driver: runs the real fm-captain-hold.sh / fm-teardown.sh / fm-procevent.sh
# from a given checkout root against a disposable marked lab home.
# usage: drive-lab.sh <root-with-bin> <lab-home> <scenario>
set -u
ROOT=$1; LAB=$2; SCN=$3
export PATH="$LAB/fakebin:$PATH"
# Plain FM_HOME only; no FM_*_OVERRIDE (lab contract). External tools stubbed.
cap() { env -u FM_ROOT_OVERRIDE -u FM_STATE_OVERRIDE -u FM_DATA_OVERRIDE -u FM_CONFIG_OVERRIDE -u FM_PROJECTS_OVERRIDE -u TMUX \
  FM_HOME="$LAB" TMUX_TMPDIR="$LAB/tmux" "$ROOT/bin/fm-captain-hold.sh" "$@"; }
td()  { env -u FM_ROOT_OVERRIDE -u FM_STATE_OVERRIDE -u FM_DATA_OVERRIDE -u FM_CONFIG_OVERRIDE -u FM_PROJECTS_OVERRIDE -u TMUX \
  FM_HOME="$LAB" TMUX_TMPDIR="$LAB/tmux" "$ROOT/bin/fm-teardown.sh" "$@"; }
pe()  { env -u FM_ROOT_OVERRIDE -u FM_STATE_OVERRIDE -u FM_DATA_OVERRIDE -u FM_CONFIG_OVERRIDE -u FM_PROJECTS_OVERRIDE -u TMUX \
  FM_HOME="$LAB" TMUX_TMPDIR="$LAB/tmux" FM_PROCEVENT_CLAIM_ROOT="$LAB/procevent-claims" "$ROOT/bin/fm-procevent.sh" "$@"; }
t()   { (cd "$LAB" && tasks-axi "$@"); }
meta() { printf 'window=firstmate:fm-%s\nworktree=%s/projects/missing-%s\nproject=%s/projects/sample\nharness=codex\nkind=%s\nmode=%s\nspawn_gen=lab-%s\n' \
  "$1" "$LAB" "$1" "$LAB" "$2" "$2" "$1" > "$LAB/state/$1.meta"; }
say() { printf '\n### %s\n' "$*"; }
run() { printf '$ %s\n' "$*"; "$@"; printf '[exit %s]\n' "$?"; }
show() { printf -- '--- task %s ---\n' "$1"; t show "$1" --full 2>&1 | grep -E '^  (state|held|kind):|Resolution mode|Resolves hold set|Answer:|Label:|Source:|Deliverable' ; t show "$1" --full 2>&1 | sed -n 's/^  body: //p' | jq -r . 2>/dev/null | grep -E 'Resolution mode|Resolves hold set|^Answer|Captain|Deliverable' | sed 's/^/  body| /'; ls "$LAB/state/$1.meta" >/dev/null 2>&1 && echo "  worker record: PRESENT" || echo "  worker record: absent"; }

case "$SCN" in
setup)
  cp "$ROOT/.tasks.toml" "$LAB/.tasks.toml"
  printf '## In flight\n\n## Queued\n\n## Done\n' > "$LAB/data/backlog.md"
  git init -q -b main "$LAB/projects/sample"
  mkdir -p "$LAB/fakebin" "$LAB/tmux"
  for b in tmux treehouse no-mistakes gh gh-axi herdr; do printf '#!/bin/sh\nexit 0\n' > "$LAB/fakebin/$b"; chmod +x "$LAB/fakebin/$b"; done
  echo "lab ready: $LAB (root $ROOT)"
  ;;
s1)
  say "S1 setup: four captain-held items (in-flight scout with worker, spawned ship with worker, in-flight row only, plain question)"
  t add lab-live-scout "Review the live sample" --kind scout --repo sample --start >/dev/null; meta lab-live-scout scout
  t add lab-live-ship "Ship the live sample" --kind ship --repo sample >/dev/null; meta lab-live-ship ship
  t add lab-row-only "Ship the row-only sample" --kind ship --repo sample --start >/dev/null
  run cap hold lab-live-scout --reason "captain design pick needed"
  run cap hold lab-live-ship --reason "captain design pick needed"
  run cap hold lab-row-only --reason "captain design pick needed"
  run cap hold lab-plain-question --title "Captain call: plain" --reason "captain choice pending" --repo sample
  for i in lab-live-scout lab-live-ship lab-row-only lab-plain-question; do show $i; done
  say "S1 act: one keyed board batch answers all four (default, done, done, default)"
  printf 'lab-live-scout\tgo-b\tOption B\nlab-live-ship\tgo-b\tOption B\tdone\nlab-row-only\tgo-b\tOption B\tdone\nlab-plain-question\tyes\tYes\n' > "$LAB/batch.tsv"
  printf '$ fm-captain-hold.sh answers --source "lab board batch" < batch.tsv\n'; cat -A "$LAB/batch.tsv" 2>/dev/null || cat -vet "$LAB/batch.tsv"
  cap answers --source "lab board batch" < "$LAB/batch.tsv"; printf '[exit %s]\n' "$?"
  say "S1 result"
  for i in lab-live-scout lab-live-ship lab-row-only lab-plain-question; do show $i; done
  printf -- '--- backlog.md ---\n'; cat "$LAB/data/backlog.md" | cut -c1-160
  ;;
s2)
  say "S2: the worker of lab-live-scout finishes; cleanup (teardown) runs; then the same board answer arrives again"
  mkdir -p "$LAB/data/lab-live-scout"; printf '# Live sample report\n' > "$LAB/data/lab-live-scout/report.md"
  printf 'done: report complete\n' > "$LAB/state/lab-live-scout.status"
  say "replay while the worker still runs"
  printf 'lab-live-scout\tgo-b\tOption B\n' | cap answers --source "lab board batch"; printf '[exit %s]\n' "$?"
  show lab-live-scout
  run cap complete lab-live-scout --none
  run td lab-live-scout
  show lab-live-scout
  say "replay after cleanup completed the work"
  printf 'lab-live-scout\tgo-b\tOption B\n' | cap answers --source "lab board batch"; printf '[exit %s]\n' "$?"
  show lab-live-scout
  ;;
s3)
  say "S3 (adversarial): work is finished and cleaned up while still held; the answer arrives late. It must close, not reopen."
  t add lab-late-answer "Investigate the late answer" --kind scout --repo sample --start >/dev/null; meta lab-late-answer scout
  mkdir -p "$LAB/data/lab-late-answer"; printf '# Late answer report\n' > "$LAB/data/lab-late-answer/report.md"
  printf 'done: report complete\n' > "$LAB/state/lab-late-answer.status"
  run cap hold lab-late-answer --reason "captain report choice pending"
  cap hold lab-late-answer-call --title "Sibling call" --reason "sibling" --repo sample --origin lab-late-answer >/dev/null
  run cap complete lab-late-answer lab-late-answer-call
  run td lab-late-answer
  show lab-late-answer
  printf 'lab-late-answer\tgo\tProceed\n' | cap answers --source "lab late board"; printf '[exit %s]\n' "$?"
  show lab-late-answer
  ;;
s4)
  say "S4 (adversarial): release, re-hold in the same pinned second, re-hold later, same answer again"
  t add lab-rehold "Investigate repeated answers" --kind scout --repo sample --start >/dev/null; meta lab-rehold scout
  echo "(pinned FM_CAPTAIN_HOLD_NOW=2026-07-14T12:00:00Z)"; FM_CAPTAIN_HOLD_NOW=2026-07-14T12:00:00Z run cap hold lab-rehold --reason "first question"
  printf 'lab-rehold\tgo\tProceed\n' | cap answers --source "lab rehold board"; printf '[exit %s]\n' "$?"
  show lab-rehold
  t show lab-rehold --full | sed -n 's/^  body: //p' | jq -r . > "$LAB/rehold-record1.txt"
  say "same-second re-hold with pinned time must refuse"
  echo "(pinned FM_CAPTAIN_HOLD_NOW=2026-07-14T12:00:00Z)"; FM_CAPTAIN_HOLD_NOW=2026-07-14T12:00:00Z run cap hold lab-rehold --reason "second question"
  show lab-rehold
  say "later re-hold, then the identical answer"
  echo "(pinned FM_CAPTAIN_HOLD_NOW=2026-07-14T12:00:01Z)"; FM_CAPTAIN_HOLD_NOW=2026-07-14T12:00:01Z run cap hold lab-rehold --reason "second question"
  show lab-rehold
  printf 'lab-rehold\tgo\tProceed\n' | cap answers --source "lab rehold board"; printf '[exit %s]\n' "$?"
  show lab-rehold
  printf 'resolution records now: %s\n' "$(t show lab-rehold --full | sed -n 's/^  body: //p' | jq -r . | grep -c '^Resolution recorded by fm-captain-hold')"
  t show lab-rehold --full | sed -n 's/^  body: //p' | jq -r . > "$LAB/rehold-after.txt"
  if grep -qF "$(cat "$LAB/rehold-record1.txt")" "$LAB/rehold-after.txt" 2>/dev/null || python3 -c 'import sys;a=open(sys.argv[1]).read().strip();b=open(sys.argv[2]).read();sys.exit(0 if a in b else 1)' "$LAB/rehold-record1.txt" "$LAB/rehold-after.txt"; then echo "record 1 text: UNCHANGED inside the new body"; else echo "record 1 text: CHANGED"; fi
  ;;
s5)
  say "S5: a real board result (Lavish poll shape) flows through fm-procevent into the intake, for a live work item"
  t add lab-board-work "Ship the board-gated sample" --kind ship --repo sample --start >/dev/null; meta lab-board-work ship
  run cap hold lab-board-work --reason "captain board route choice pending"
  cat > "$LAB/board-source.sh" <<'SH'
#!/usr/bin/env bash
cat <<'OUT'
session:
  status: feedback
  session_ended: false
prompts[1]{tag,text,prompt}:
  "choice","Take the north route","Context data: {\"schema\":\"fm-bearings-answer.v1\",\"question\":\"lab-board-work\",\"selection\":\"north\",\"note\":\"\"}"
OUT
SH
  chmod +x "$LAB/board-source.sh"
  sid=lavish-b0a4d0000000f1e2
  run pe register lavish "$sid" -- "$LAB/board-source.sh"
  run cap bind "$sid"
  run pe start "$sid"
  show lab-board-work
  ;;
s6)
  say "S6 (boundary): explicit release mode, unknown mode, reserved reconcile value, direct answer without --release"
  for i in lab-m-release lab-m-bogus lab-m-reconcile lab-m-direct; do t add $i "Mode sample $i" --kind ship --repo sample --start >/dev/null; meta $i ship; cap hold $i --reason "captain pick" >/dev/null; done
  printf 'lab-m-release\tgo\tGo\trelease\nlab-m-bogus\tgo\tGo\tbogus\nlab-m-reconcile\treconcile\tReconcile\n' | cap answers --source "lab modes"; printf '[exit %s]\n' "$?"
  for i in lab-m-release lab-m-bogus lab-m-reconcile; do show $i; done
  say "direct 'answer' without --release keeps its documented explicit close (not changed by this fix)"
  printf 'The captain said close it.\n' > "$LAB/direct.txt"
  run cap answer lab-m-direct --decision-file "$LAB/direct.txt"
  show lab-m-direct
  ;;
esac

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - medium risk

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • Live validation: ✅ go - 8 of 11 scenarios driven live against the product
Scenario Result Live Evidence
Captain answers a board batch for held work that still has a worker (in-flight scout, spawned ship, in-flight row with no worker record): each item stays open, the hold lifts, the words are recorded a… ✅ pass live s1-fixed.txt (real fm-captain-hold.sh answers in a lab home; default and done modes)
The same batch on the base commit 924f479 closes every live work item to Done (the reported bug reproduces before the fix) ✅ pass live s1-base-924f479c.txt and s5-base-924f479c.txt (base scripts from git archive, run in a second lab home)
A plain captain question with no worker still closes to Done on a keyed answer ✅ pass live s1-fixed.txt, task lab-plain-question: state done, mode answered
A board result in the Lavish poll shape flows through fm-procevent to the intake and releases a live work item instead of closing it ✅ pass live s5-fixed.txt (fm-procevent.sh register, bind, start; answers-fed; task in_flight, released). The board source was a script that prints a poll result; no real Lavish server was used.
After the release, the worker finishes and cleanup closes the item to Done; the same answer sent again (before and after cleanup) reports closed and changes nothing ✅ pass live s2-fixed.txt (real fm-teardown.sh in the lab; state done, record still released, exit 0 on both replays)
Adversarial: work finishes and cleanup runs while the item is still held; a late keyed answer closes it to Done with its report and does not make it runnable again ✅ pass live s3-fixed.txt (after teardown: queued, held, no worker record; after answer: done, answered, report line kept)
Adversarial: a re-hold in the same pinned second is refused with a clear message; a later re-hold plus the identical answer writes a second record and leaves record 1 unchanged ✅ pass live s4-fixed.txt (FM_CAPTAIN_HOLD_NOW collides ... exit 1; resolution records now: 2; record 1 text UNCHANGED)
Boundary: explicit release mode releases, an unknown mode is skipped, the reserved value reconcile is refused, and held items stay held when skipped ✅ pass live s6-fixed.txt (closed=1 skipped=2, exit 1; bogus and reconcile items still held and in_flight)
Race: an answer that arrives while cleanup holds the task lock waits, then closes the finished item instead of releasing it ⏸️ untested no The prior payload did not establish a live result for this scenario. It needs a pause injected inside teardown at an exact point, and only the test barriers can do that. The targeted test `test_keyed_…
Crash recovery: a release interrupted before the hold lifts closes after teardown; a completed release replays after a failed parent publication without a record rewrite ⏸️ untested no The prior payload did not establish a live result for this scenario. It needs a forced failure in the middle of one command and a secondmate parent home, and only the test fault injection can do that.…
Race: a stale replay does not resolve a new hold opened at the same time and does not delete its reconcile request; a legacy release with no hold stamp needs an explicit close ⏸️ untested no The prior payload did not establish a live result for this scenario. It needs two commands interleaved at an exact point under the lock, and only the test barriers can do that. The targeted tests `tes…
  • bin/fm-lab-home.sh create &#34;$LAB&#34; to make a marked throwaway lab home (two labs: one for the fixed code, one for the base commit)
  • drive-lab.sh &lt;worktree&gt; $LAB s1: real bin/fm-captain-hold.sh hold x4, then bin/fm-captain-hold.sh answers --source &#34;lab board batch&#34; with one 4-row keyed batch, then tasks-axi show --full on each item
  • drive-lab.sh &lt;worktree&gt; $LAB s2: replay of the same answer while the worker runs, fm-captain-hold.sh complete --none, real bin/fm-teardown.sh lab-live-scout, replay again after cleanup
  • drive-lab.sh &lt;worktree&gt; $LAB s3: hold finished work, real bin/fm-teardown.sh, then a late keyed answer
  • drive-lab.sh &lt;worktree&gt; $LAB s4: release, same-second re-hold with FM_CAPTAIN_HOLD_NOW pinned, later re-hold, identical answer again
  • drive-lab.sh &lt;worktree&gt; $LAB s5: bin/fm-procevent.sh register lavish, fm-captain-hold.sh bind, bin/fm-procevent.sh start with a board result in the Lavish poll shape for a live work item
  • drive-lab.sh &lt;worktree&gt; $LAB s6: answers with modes release, bogus, and the reserved value reconcile; direct fm-captain-hold.sh answer without --release
  • git archive 924f479c bin .tasks.toml into a temp directory, then drive-lab.sh &lt;base&gt; $LAB2 s1 and s5 to reproduce the bug on the base commit
  • bash tests/fm-captain-hold-lifecycle.test.sh test_keyed_answer_releases_a_live_work_item test_keyed_answer_waits_for_cleanup_before_selecting_its_mode test_interrupted_keyed_release_closes_after_teardown test_completed_keyed_release_replays_after_publication_failure test_stale_keyed_replay_preserves_a_concurrent_hold test_repeated_keyed_answer_resolves_its_own_hold test_legacy_keyed_release_requires_explicit_closure test_bound_channel_answers_close_at_answer_time test_board_answer_reaches_the_keyed_answer_intake test_relocated_report_does_not_wedge_released_cleanup_replay test_answer_before_cleanup_replay_preserves_the_retained_report (12 ok lines, 0 failures)
  • rm -rf of both lab homes and the base copy; git status --short shows a clean worktree
✅ **Document** - passed

✅ No issues found.

🔧 **Lint** - 1 issue found → auto-fixed ✅
  • ⚠️ linter found issues (exit code 1)

🔧 Fix applied.
✅ Re-checked - no issues remain.

✅ **Push** - passed

✅ No issues found.

…ing it

A keyed answer with no close mode (or done) completed a captain-held work
item while its worker was still running. The answers intake now releases any
task a worker still owns (live runtime record or In flight row), records the
captain's words, and keeps a late replay a release.
…ing it

A keyed answer with no close mode (or done) completed a captain-held work
item while its worker was still running. The answers intake now releases any
task a worker still owns (live runtime record or In flight row), records the
captain's words, and keeps a late replay a release.
@MrGTV-love
MrGTV-love merged commit 8c33fba into main Oct 10, 2026
40 of 41 checks passed
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