Skip to content

fix(crews): a failed proposal-to-Crew link no longer strands the recorded Crew - #236

Closed
bryantderosier wants to merge 3 commits into
j5/issue-220-crew-launch-retry-convergencefrom
j5/issue-221-attach-recovery
Closed

bryantderosier wants to merge 3 commits into
j5/issue-220-crew-launch-retry-convergencefrom
j5/issue-221-attach-recovery

Conversation

@bryantderosier

Copy link
Copy Markdown
Collaborator

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:

  • Decline retires the recorded Crew, archives its seat threads, and keeps the Crew id on the declined row.
  • Approve restores the link before claiming. If the link still cannot be written, the approval is refused with the gate open and the refusal names the Crew (a request error, so the HTTP layer does not redact it). Nothing launches beneath a Crew the proposal cannot reach.
  • Boot sweep restores the link before reopening a lost approval, and a lost decline goes through the same retire path. A restore that fails leaves the claim for the next boot.

The store's own error goes to the log, never to the card.

Footprint

CrewProposalService.ts and its tests, one type widening on CrewLaunchInput.onRecorded in CrewLaunchService.ts so 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.ts and CrewLaunchService.test.ts pass 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

bryantderosier and others added 3 commits September 22, 2026 07:45
…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>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 effective changed lines (test files excluded in mixed PRs). labels Sep 22, 2026
@bryantderosier
bryantderosier added this pull request to stack #237 September 22, 2026 12:01
@bryantderosier bryantderosier self-assigned this Sep 22, 2026
@Jacksondr5 Jacksondr5 added the jackson-direct Taken by Jackson + Astra outside the fleet methodology; lanes never staff these label Sep 23, 2026
@Jacksondr5

Copy link
Copy Markdown
Owner

Claimed for review by Jackson with Claude Fable 5.1 and GPT-6-Astra (the crews review thread). Other agents: please skip this one.

@Jacksondr5

Copy link
Copy Markdown
Owner

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.

@bryantderosier

Copy link
Copy Markdown
Collaborator Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jackson-direct Taken by Jackson + Astra outside the fleet methodology; lanes never staff these size:L 100-499 effective changed lines (test files excluded in mixed PRs). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A failed proposal-to-Crew attach write no longer strands the recorded Crew

2 participants