Merge master and check registered failover cursors

Use the registered controller state when checkpoint persistence replaces the local journal with an external marker. The new regression follows registration and real checkpoint conversion before remote preparation, reproducing the stale-copy bypass on the prior guard. Current backups retain the existing integrity checks. Resolve the workflow fixture conflict by keeping each normal-route input once.

Verified 1,192 native session/execution-driver tests, ten workflow checks, fresh server declarations and the workflow project typecheck. Maintained preflight, module boundaries, whitespace and secrets/PII checks pass. Fresh CI and exact-head Apex review remain required.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Devin FoleyandPaperclip committed 2026-11-06 13:23:39 -08:00
commit cd8c9cd07c
17 files changed
+537 -120

No files matched your search

+23
View File
@@ -2379,6 +2379,22 @@ All of these must be true:
- Each quarantined root for the scope passes the same journal and local
Runner evidence checks for the same owner.
A local per-turn Runner can end the same way: the result was accepted, but its
`runner.suspend` command did not finish, so its own receipt is still
unsuspended. The next local run retires that owner with the same checks and
these differences:
- The Runner's own receipt may be unsuspended. It may not be unreadable or
name another owner.
- Only the Runner's own lifecycle commands (`runner.suspend`, `runner.drain`,
`runner.shutdown`) may be unfinished. All other commands must be complete.
- The prior run's recorded Runner process is proven stopped by exact PID and
start time, as in restart recovery. A PID that now belongs to another
process counts as stopped. A live recorded process, a live process group, a
live recorded provider process, a missing identity, or a start time that
cannot be compared keeps the rejection, for example
`retirement_refused=runner_process_alive`. A later Retry checks again.
The provider session then follows the normal resume-or-replace policy. A
resumed sandbox, a warm session, a plugin task, a restart claim, or any
missing proof keeps the existing `prior_owner_terminal_state_indeterminate`
@@ -3317,6 +3333,13 @@ A graceful shutdown can also suspend a restart-recovery claim whose execution
has not yet reached provider dispatch. That execution has lost its authority:
it leaves the run running, its budget hold held and its workspace unmarked, and
the next controller adopts the same run. It does not settle the run as failed.
Shutdown closes the runtime API listener before it drains runs. A local Runner
execution that then needs the listener (for example, to give a new runner its
callback origin) detaches the same way instead of failing. It keeps its claim,
the drain suspends it, and the next controller adopts the run. A remote Runner
execution has no process evidence on the controller host, so it keeps the
same-run bootstrap retry. A listener that never started is still a startup
failure.
Remote Runner processes use their authenticated connection lease as the bound
on disconnected lifetime. The controller's shorter connection-recovery budget
limits its own attempt; it must not terminate the remote owner while another
+3
View File
@@ -71,6 +71,9 @@ copy is behind, the run fails with `native_event_replay_conflict` and automatic
recovery stops. No files are copied to the sandbox. Resuming that copy would make
Runner reject the controller's acknowledgement, and it could repeat work the
controller already accepted.
When a controller is registered, the comparison uses its current live cursor.
The local marker written for external checkpoint storage does not replace that
authority.
An hourly background sweep expires the copy once the session can only resume by
reopening closed work. It checks at most 200 sessions and expires at most 50 per