You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Long-lived OMP worker sessions can stop starting turns while transport still acknowledges durable delivery. PR #153 fixed the false-receipt side: fallback now requires bounded turn proof and unproven rings remain queued, so wedges are correctly reported as omp-native-queued / delivered-no-turn. Nothing yet performs a custody-safe automatic recovery.
This issue is the narrow deterministic recovery adapter for that specific incident class. The broader task-completion control loop is tracked in #156.
Evidence (2026-09-20)
Three workers wedged the same way in one day and recovered only after a manual same-worktree relaunch through fm-control with a progress note:
ic-prod-outage-astra-fix — /fresh returned delivered-no-turn; the four-hour session remained alive but swallowed input.
fm-omp-compact-adviser-adapter — three durable inbox decisions remained unhandled while the pane idled.
ic-ingest-auto-readiness — QA-blocking decisions remained unhandled for about 30 minutes; releasing its supervision lease also required watcher-cycle repair through fm_watch_arm_omp.
All three manual recoveries preserved their worktrees and existing work. The Astra root-cause scout at data/fm-stuck-crew-astra-debug/report.md attributed the initiating runtime trigger upstream of FirstMate. These incidents establish usefulness, not a complete automatic-safety proof or a calibrated retry threshold.
Scope
Define the adapter input as a generation-bound, persistent instruction-delivery incident and its output as a structured recovery disposition plus evidence.
generic provider-loop diagnosis, supervisor-health repair or secondmate recovery;
replaying a typed command when no matching durable instruction exists;
merge, deployment or destructive cleanup authority.
Corrected safety contract
The earlier statement “any active run or unlanded work blocks auto-action” is too broad and unsafe in both directions.
Unlanded or dirty work does not itself block same-worktree recovery. It is precisely what recovery must preserve. However, preserved work is not permission to terminate a live writer.
An automatic replacement requires all of the following:
Authority — current FirstMate mutation authority for the exact home/task and a supported ordinary-task recovery capability.
Preservation binding — canonical existing worktree and project/lease binding; branch, HEAD, pending instructions, staged/untracked content and commits remain accounted for. No fresh allocation, reset, stash, cleanup or implicit migration.
Fresh identity — task generation and process/start identity still match the incident. Acquire existing control/spawn exclusion in documented lock order.
Atomic custody — a positive authoritative validation/branch-custody verdict, with query failures and freshness retained, plus a reservation preventing new custody across the effect boundary. Unknown, conflicting, failed-query or pipeline-owned cases are ineligible.
Owner transition — for a dead owner, recovery-grade death/absence proof. For a live-but-wedged owner, a separately supported quiesce-and-stop transition with fresh turn/pending checks. Prove old writers stopped before the successor receives write authority.
Journal then mutate — recheck identity/custody under reservation, preserve all bytes and commits, durably reserve the attempt, then execute the existing relaunch transaction.
Reconcile partial effects — after crash or ambiguous failure, reconcile the journal and current process/generation before another attempt. Release reservation only after durable successor binding or an explicit preserved failure state.
A preceding read-only state query is not sufficient mutation authority. A finite run search or a helper that suppresses query failures cannot prove global owner absence.
Candidate and action lifecycle
Existing inbox/watcher owner detects a persistent supported incident after its normal grace/re-ring ladder.
Publish exactly one durable candidate identity; duplicate/concurrent detectors reconcile the same candidate.
FirstMate rereads current task, instruction, endpoint, completion and custody evidence.
If applicable completion already passes, route normal delivery—do not relaunch.
If safe deterministic predicate and task-wide budget pass, reserve custody and attempt identity.
Recheck for a late turn, handled instruction, new custody, generation change or completion at the effect boundary.
Journal intent and relaunch through existing fm-control/fm-spawn ownership.
Bind the successor generation and verify target-message consumption plus expected downstream progress.
Record recovered, retry eligible, or escalated with work preserved.
A process launch or alive endpoint is not recovery.
Progress and retry policy
Use at most two automatic relaunches per task lifetime, spanning generations and incident identities. This is a conservative starting policy, not an empirically optimized threshold.
Reserve an attempt durably before the first lifecycle effect. A positively proven pre-effect refusal may release it; a crash with uncertain effects does not.
Strong recovery evidence:
the target durable instruction is handled by the successor and its expected downstream effect becomes visible; or
the applicable completion gate passes.
Useful activity that may cancel/settle an incident but does not prove task success:
a request-correlated turn starts;
attributed validation advances;
a new criterion becomes successfully evidenced;
exact PR/check state advances for the current head.
Do not reset or replenish retry authority for a new PID/generation, turn counter, enqueue, duplicate receipt, status/log timestamp, pane animation, dirty-flag toggle, arbitrary HEAD change, commit restamping, repeated validation loop, or Jev confidence.
After the second unsuccessful attempt, preserve all work and escalate with the failed instruction, custody evidence, attempts and observed consequences. Do not call the underlying implementation irrecoverable merely because automatic recovery is exhausted.
Jev boundary
No Jev call is required for this adapter's supported deterministic predicate. Jev may later advise #156 about semantic ambiguity, but it cannot establish custody, grant completion, authorize restart, replenish retries or override merge authority.
Known actuator gaps to resolve
The 2026-09-20 Astra medium review identified two source-level gaps that must be verified and repaired before automatic recovery:
Relaunch transaction publication identity — fm-control.sh passes FM_CONTROL_RELAUNCH_TX and expects control_relaunch_tx to identify an ambiguously published successor, but the inspected fm-spawn.sh metadata writer did not publish that field. Add the handoff identity and a regression for failure/crash after successor publication.
Task evidence versus process metadata — successor metadata replacement changes process identity but can discard task-scoped validation, implementation-completion and PR bindings. Define which task evidence survives, which process fields rotate, and which stale bindings require authoritative revalidation.
Extend the existing transaction rather than wrapping it in a check-then-relaunch script.
Acceptance criteria
Trigger and idempotency
A persistent pending native instruction reaches exactly one generation-bound candidate.
Transient queueing and positively busy/productive workers do not become candidates.
Typed no-turn without a matching durable instruction does not invent or replay instructions.
Duplicate notifications, concurrent reconciliation and old-generation events cause at most one lifecycle effect.
Stable incident, snapshot and attempt identities are separate; timestamps/log churn do not create new incidents.
Effect-boundary safety
A late turn or handled acknowledgement before stop cancels replacement.
Custody acquired between observation and effect prevents stop.
Query timeout, malformed output, incomplete coverage or unknown ownership is not treated as no owner.
Missing worktree, foreign lease, unsupported backend or unresolved endpoint identity preserves state and escalates.
Live-owner recovery uses an explicit quiesce-and-stop contract; old writers are proven stopped before successor write authority.
Preservation and crash recovery
Eligible dirty tracked, staged and untracked content plus unpushed commits survive byte-for-byte in the same worktree.
No reset, stash, cleanup, fresh worktree allocation or implicit migration occurs.
Still-valid task-scoped validation, implementation and PR evidence survives process replacement; stale evidence is explicitly reconciled.
Crashes after reservation, stop, launch and successor publication reconcile the same journal transaction without duplicate execution or budget evasion.
Spawn failure after metadata publication is attributable to the exact relaunch transaction.
Outcome and authority
An alive successor without target-message/downstream progress remains unrecovered.
Two unsuccessful relaunches exhaust the task-lifetime allowance despite generation, HEAD, turns or receipt changes.
Applicable completion routes normal delivery without restart.
PR-ready work does not merge without explicit authority, and unrelated/new-head CI does not satisfy stale evidence.
Parked or active pipeline custody remains intact unless a future explicit run-preserving handoff contract exists.
Exhaustion escalates loudly with work preserved and complete evidence.
Likely implementation areas
bin/fm-watch.sh and bin/fm-task-inbox-lib.sh — integrate candidates with the existing pending/re-ring owner.
Existing durable wake reconciliation — FirstMate-owned decision and audit path.
bin/fm-control.sh, bin/fm-spawn.sh and shared custody/lease owner — in-transaction authorization, generation exclusion and handoff.
bin/fm-nm-run-lib.sh or the authoritative validation owner — checked positive custody observations without turning permissive display queries into mutation authority.
Existing behavioral tests including relaunch, OMP guard, send/turn-start, watcher recovery, task inbox, crew state and receipt suites.
.agents/skills/stuck-crewmate-recovery/SKILL.md and supervision protocol/configuration docs — one canonical supported path, budget and exclusions.
Do not replace existing completion or PR logic. In particular, pipeline-accounted head advancement/restamping may be valid; a new literal HEAD-equality rule would be incorrect.
Supervisor-health and renderer defects remain separate fault domains and must not spend a worker's retry budget.
Review provenance
A read-only Astra medium design review was completed 2026-09-20 against a4fa70111b2f20ebc1fd20e97f4dda9078a94dad.
Verdict: retain #155 as the deterministic first adapter, but revise its safety contract before implementation. The review did not reproduce a new wedge, run validation, modify source, or authorize implementation.
Problem
Long-lived OMP worker sessions can stop starting turns while transport still acknowledges durable delivery. PR #153 fixed the false-receipt side: fallback now requires bounded turn proof and unproven rings remain queued, so wedges are correctly reported as
omp-native-queued/delivered-no-turn. Nothing yet performs a custody-safe automatic recovery.This issue is the narrow deterministic recovery adapter for that specific incident class. The broader task-completion control loop is tracked in #156.
Evidence (2026-09-20)
Three workers wedged the same way in one day and recovered only after a manual same-worktree relaunch through
fm-controlwith a progress note:ic-prod-outage-astra-fix—/freshreturned delivered-no-turn; the four-hour session remained alive but swallowed input.fm-omp-compact-adviser-adapter— three durable inbox decisions remained unhandled while the pane idled.ic-ingest-auto-readiness— QA-blocking decisions remained unhandled for about 30 minutes; releasing its supervision lease also required watcher-cycle repair throughfm_watch_arm_omp.All three manual recoveries preserved their worktrees and existing work. The Astra root-cause scout at
data/fm-stuck-crew-astra-debug/report.mdattributed the initiating runtime trigger upstream of FirstMate. These incidents establish usefulness, not a complete automatic-safety proof or a calibrated retry threshold.Scope
Define the adapter input as a generation-bound, persistent instruction-delivery incident and its output as a structured recovery disposition plus evidence.
In scope:
delivered-no-turn/ pending durable instruction incidents;Out of scope:
Corrected safety contract
The earlier statement “any active run or unlanded work blocks auto-action” is too broad and unsafe in both directions.
Unlanded or dirty work does not itself block same-worktree recovery. It is precisely what recovery must preserve. However, preserved work is not permission to terminate a live writer.
An automatic replacement requires all of the following:
A preceding read-only state query is not sufficient mutation authority. A finite run search or a helper that suppresses query failures cannot prove global owner absence.
Candidate and action lifecycle
fm-control/fm-spawnownership.recovered,retry eligible, orescalated with work preserved.A process launch or alive endpoint is not recovery.
Progress and retry policy
Use at most two automatic relaunches per task lifetime, spanning generations and incident identities. This is a conservative starting policy, not an empirically optimized threshold.
Reserve an attempt durably before the first lifecycle effect. A positively proven pre-effect refusal may release it; a crash with uncertain effects does not.
Strong recovery evidence:
Useful activity that may cancel/settle an incident but does not prove task success:
Do not reset or replenish retry authority for a new PID/generation, turn counter, enqueue, duplicate receipt, status/log timestamp, pane animation, dirty-flag toggle, arbitrary HEAD change, commit restamping, repeated validation loop, or Jev confidence.
After the second unsuccessful attempt, preserve all work and escalate with the failed instruction, custody evidence, attempts and observed consequences. Do not call the underlying implementation irrecoverable merely because automatic recovery is exhausted.
Jev boundary
No Jev call is required for this adapter's supported deterministic predicate. Jev may later advise #156 about semantic ambiguity, but it cannot establish custody, grant completion, authorize restart, replenish retries or override merge authority.
Known actuator gaps to resolve
The 2026-09-20 Astra medium review identified two source-level gaps that must be verified and repaired before automatic recovery:
fm-control.shpassesFM_CONTROL_RELAUNCH_TXand expectscontrol_relaunch_txto identify an ambiguously published successor, but the inspectedfm-spawn.shmetadata writer did not publish that field. Add the handoff identity and a regression for failure/crash after successor publication.Extend the existing transaction rather than wrapping it in a check-then-relaunch script.
Acceptance criteria
Trigger and idempotency
Effect-boundary safety
Preservation and crash recovery
Outcome and authority
Likely implementation areas
bin/fm-watch.shandbin/fm-task-inbox-lib.sh— integrate candidates with the existing pending/re-ring owner.bin/fm-control.sh,bin/fm-spawn.shand shared custody/lease owner — in-transaction authorization, generation exclusion and handoff.bin/fm-nm-run-lib.shor the authoritative validation owner — checked positive custody observations without turning permissive display queries into mutation authority..agents/skills/stuck-crewmate-recovery/SKILL.mdand supervision protocol/configuration docs — one canonical supported path, budget and exclusions.Do not replace existing completion or PR logic. In particular, pipeline-accounted head advancement/restamping may be valid; a new literal HEAD-equality rule would be incorrect.
Relationship to other work
Review provenance
A read-only Astra medium design review was completed 2026-09-20 against
a4fa70111b2f20ebc1fd20e97f4dda9078a94dad.Verdict: retain #155 as the deterministic first adapter, but revise its safety contract before implementation. The review did not reproduce a new wedge, run validation, modify source, or authorize implementation.