Files
maka/docs/architecture/runtime-resume-phase0-crash-contract.md
agent-radar 7be535059e
Dependency audit / audit (push) Canceled after 0s
CI / plan (push) Canceled after 0s
Gitoxide helper admission / macos-latest (push) Canceled after 0s
Gitoxide helper admission / ubuntu-latest (push) Canceled after 0s
Gitoxide helper admission / windows-latest (push) Canceled after 0s
Runtime Host peer admission / quality (push) Canceled after 0s
Windows recovery / windows_recovery (push) Canceled after 0s
CI / heavy (push) Canceled after 0s
CI / test (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 19:05:14 +08:00

4.5 KiB

Runtime Resume Phase 0 Crash Contract

Phase 0 defines replay safety for a fully committed RuntimeEvent prefix. It does not resume execution, reconcile tool side effects, or introduce the future SQLite tool journal.

The production API is pure:

committed RuntimeEvent prefix
  -> ToolOperation projection
  -> ResumePlan
  -> safe_replay or blocked

Stable failpoints

RUNTIME_RESUME_FAILPOINTS is the machine-readable source of truth. The committedPrefix column means the last complete RuntimeEvent prefix available after a crash. It deliberately does not pretend that the future T1/T2 journal already exists.

ID Injection boundary Last fully committed RuntimeEvent prefix
P0 Before tool preparation (T1) before_function_call
P1 Function call committed, prepared journal not committed after_function_call
P2 Prepared journal committed, implementation not started after_function_call
P3 Tool implementation in progress after_function_call
P4 Side effect finished, outcome transaction (T2) not committed after_function_call
P5 Function response committed, outcome journal not committed after_function_response
P6 Outcome committed, result not delivered to the model after_function_response
P7 Result delivered, next provider step not started after_function_response
P8 Terminal RuntimeEvent commit after_function_response
P9 Terminal run-header commit after_terminal_event
P10 Recovery-decision commit after_terminal_event
P11 Continuation-run creation after_terminal_event

For P8, Phase 0 reasons only about the prefix before the terminal append. The post-terminal prefix is represented by P9. A torn JSON row is storage corruption, not a legal committed prefix, and must not be upgraded into a recovery fact.

Required decisions

Prefix Expected result
before_function_call safe_replay; no tool operation exists
after_function_call blocked; operation is indeterminate; reason is dangling_tool_state; unresolved call is absent from provider replay
after_function_response safe_replay; operation is succeeded or failed; call and response remain paired in provider replay
after_terminal_event Same tool decision as the preceding prefix; the terminal fact remains in the canonical ledger

An expected RuntimeEvent high-water that differs from the reopened prefix is always rejected with runtime_offset_mismatch.

Process harness

The Phase 0 crash test must use the real file-backed RuntimeEventStore:

  1. Create a temporary workspace.
  2. Start a child Node.js process.
  3. Append the failpoint's complete prefix through RuntimeEventStore.
  4. Signal the parent only after the append promises resolve.
  5. Have the parent terminate the child with SIGKILL.
  6. Verify a finally cleanup marker was not written.
  7. Reopen the workspace with a new RuntimeEventStore instance.
  8. Project the reopened prefix twice and require identical ResumePlan values.
  9. Verify projection did not mutate the durable ledger.

The harness covers all twelve stable failpoint IDs on Windows, macOS, and Linux. It tests process-crash recovery, not power-loss durability or filesystem fsync guarantees.

Phase boundary

Phase 0 changes no tool execution behavior. The following remain out of scope:

  • automatic continuation;
  • workspace restoration;
  • T1/T2 transactional tool boundaries;
  • side-effect reconciliation;
  • idempotent tool re-execution;
  • SQLite as the canonical RuntimeEvent and tool-journal store.

Those capabilities require later phases. Phase 0 only makes the decision over the evidence currently available deterministic and fail-closed.