Repository navigation
fix(crews): a failed proposal-to-Crew link no longer strands the recorded Crew - #236
bryantderosier wants to merge 3 commits into
Conversation
…rded Crew A roster launch records its Crew before any seat spawns, then writes the proposal's link to that record. The link write was wrapped in Effect.ignore, so a failed write followed by a failed spawn reopened the gate with no Crew id, and a decline on that gate skipped Crew cleanup, leaving a live Crew record and any seat threads with no gate that could retire them. The link write now aborts the launch before any seat spawns when it fails, naming the Crew. Because a roster's Crew id derives from the proposal id alone, every path that meets a roster proposal with no link reads the record by that id: a decline retires it and keeps the id on the declined row, an approval restores the link before claiming and refuses to launch if it still cannot be written, and the boot sweep restores the link before handing a lost approval back. onRecorded's type now says it can fail. Closes #221 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…shows The HTTP layer redacts every operation failure to a generic message, so the approve-path refusal for a Crew whose link cannot be restored never named the Crew at the gate. It is now a request error (shown as-is) that names the Crew and says to retry or decline; the store's own error goes to the log only. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The proposal store returns the row it wrote when a link is attached. The restore now reads the Crew id off that row and treats a write that reported success without landing as the same refusal as a failed write, so no approval can launch beneath a proposal that still does not name its Crew. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Claimed for review by Jackson with Claude Fable 5.1 and GPT-6-Astra (the crews review thread). Other agents: please skip this one. |
|
The launch model these three PRs share is being replaced with "launch once, report once"; the full note, with an apology for the churn on our side, is on #235: #235 (comment). This PR is affected as described there. |
|
Agreed. Record-before-spawn and the launch report already shipped in #148, and everything else here only exists because the gate reopens, so I'm closing this. The one live piece is the ignored link write. It matters under launch-once too, because the launch report finds the Crew through that link, so a swallowed failure means no report. I've moved that fix into #239 (af22b50), which touches the same file: a failed link now fails the approval before any seat spawns, the same way a failed record write does. |
Closes #221. Stacked on #235 (issue #220); merge that one first.
Problem
A roster launch records its Crew before any seat spawns, but the write that links the proposal back to that record ran under
Effect.ignore. If that write failed and the spawn then failed too, the gate reopened with no Crew id on the proposal. A decline on that gate skipped Crew cleanup, so a live Crew record and any seat threads the failed launch created were left with no gate that could retire them.Fix
The link write now fails the launch before any seat spawns, so the record stays under its deterministic id and the gate is handed back. A roster's Crew id derives from the proposal id alone, so approve, decline, and the boot sweep look the record up by that id whenever the link is missing:
The store's own error goes to the log, never to the card.
Footprint
CrewProposalService.tsand its tests, one type widening onCrewLaunchInput.onRecordedinCrewLaunchService.tsso the failure can propagate (launch ordering, ids, and reconciliation untouched), and one sentence in the FORK.md Crew paragraph. No upstream files.Tests
Three new tests in
CrewProposalService.test.ts: decline finds and retires a Crew whose link write failed; the boot sweep restores the link on a lost approval and retires the Crew on a lost decline; a database error on the link write is retryable and the retry restores the link and launches (including a write that returns without landing).CrewProposalService.test.tsandCrewLaunchService.test.tspass at 39/39.Built by a two-seat crew in T3 Code (Claude Fable 5.1 builder, GPT-6-Astra reviewer) captained by Claude Fable 5.1.
🤖 Generated with Claude Code