fix(pi-workflow): preserve recovery gate ownership
This commit is contained in:
@@ -70,7 +70,7 @@ An analysis run uses `action: "start"` with `workflow: { mode: "analysis-script"
|
||||
|
||||
## Recovery
|
||||
|
||||
Interrupted work opens a Recovery Gate with retry, inspect, and abort choices. Completed Assignments and Decisions remain persisted. Potentially mutating interrupted Assignments are preserved and are not replayed automatically; an explicit retry creates newly fenced work where policy permits it.
|
||||
Interrupted work opens a Recovery Gate with retry, inspect, and abort choices. Completed Assignments and Decisions remain persisted. Potentially mutating interrupted Assignments are preserved and are not replayed automatically; an explicit retry creates newly fenced work where policy permits it. Startup recovery leaves an idle run already waiting at Recovery under its current parent instead of letting another Pi session claim it. If that parent's process has exited, an explicit retry from a previously attached parent session may reclaim the stale lease before continuing.
|
||||
|
||||
## Artifacts
|
||||
|
||||
|
||||
@@ -508,7 +508,7 @@ Writes are atomic and mode `0600`. Serialization, transcript, source, argument,
|
||||
|
||||
The snapshot contains Decisions and prior Assignment outcomes, so a separate event store is unnecessary. Every `start`, `decide`, and `abort` command requires an idempotency key. The launch key and initial result are persisted before workspace creation. State-changing commands use revisions and idempotency keys to reject stale or duplicate transitions. Repeating a completed key returns its recorded result without another transition.
|
||||
|
||||
An active run owns a persisted lease containing process identity, active parent-session identity, heartbeat time, and worktree identity. The run retains every parent session ID attached through a handoff so `/workflow` can discover it from either session, but only the active ID may mutate the run. Startup and session recovery reconcile stale leases, child processes, workspace-creation intent, Git identity, context handoffs, compaction intents, and assignments left `running`.
|
||||
An active run owns a persisted lease containing process identity, active parent-session identity, heartbeat time, and worktree identity. The run retains every parent session ID attached through a handoff so `/workflow` can discover it from either session, but only the active ID may mutate the run. The narrow exception is an explicit Recovery retry from a retained parent ID after the recorded lease process has died; that retry reclaims the stale lease before applying the Decision. Startup and session recovery reconcile stale leases, child processes, workspace-creation intent, Git identity, context handoffs, compaction intents, and assignments left `running`. An idle run that already has an open Recovery Gate is left attached to its current parent so unrelated Pi sessions cannot steal ownership during startup.
|
||||
|
||||
Fresh-session handoff intent is durable before `newSession()`. A `session_shutdown` with reason `new` bypasses ordinary interruption recovery only when its source session matches the pending intent; that handler atomically claims the event's `targetSessionFile` and marks the intent `claimed-target-awaiting-withSession`. The claimed target's immediately following `session_start` is exempt from recovery only when its reason is `new` and `previousSessionFile` matches the source. The replacement `withSession` callback must then match the claimed target before it atomically consumes the intent, rotates the active parent-session ID, records both session IDs, and resumes delivery. Any later `session_start` caused by `startup`, `reload`, `resume`, or `fork`, or a bounded claim expiry before consumption, follows normal recovery and leaves implementation blocked.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user