The Role of continuation-replay.ts in Apache Maka's Crash Recovery Mechanism

The continuation-replay.ts module serves as the core orchestrator of Apache Maka's crash-recovery strategy, validating immutable event prefixes, constructing replayable segment plans, and generating SHA-256 digests to verify that a crashed process can resume execution from a deterministic state without re-processing completed events.

When an Apache Maka process crashes due to interrupted tool execution or runtime inconsistencies, the system must reconstruct a deterministic continuation to resume without re-processing completed work. The continuation-replay.ts file, located in packages/runtime/src/, implements the three-stage pipeline that transforms corrupted or interrupted event logs into verified, replay-ready plans. This module determines whether a crashed session can safely continue or must be abandoned due to unrecoverable corruption.

Core Responsibilities of continuation-replay.ts

The module performs three tightly-coupled tasks that translate a crash-affected event log into a verified, replay-ready plan, or explicitly reject the continuation when the log shows corruption or unresolved tool recovery.

Validating the Immutable Event Prefix

Before any replay plan is constructed, continuation-replay.ts calls resolveRuntimeRecovery (defined in packages/runtime/src/recovery-resolver.ts) to scan the event prefix for tool-ledger issues and corruption. If any corruption or unsettled tool-recovery facts are detected, the function returns a blocked result with a concrete ContinuationReplayBlockReason such as tool_recovery_corruption or tool_recovery_unsettled. This halts the replay-plan creation early, ensuring that the system never attempts to resume from a malformed state.

Building the Replayable Segment Plan

After the prefix passes validation, buildContinuationReplaySegment constructs a segment plan (ContinuationReplaySegmentPlanV1). It leverages buildRuntimeEventModelReplayPlan (from packages/runtime/src/model-history.ts) to analyze the model-visible events, detect unmatched tool calls, and compute which events belong to the trimmed suffix—the part that must be discarded because it was not fully materialized. The function then isolates the stable provider items (the last tool result or user message that can safely become a replay anchor) and sets trimmedSuffixEventIds and replayRuntimeEvents to define the exact slice of the original execution that can be safely replayed.

Creating Deterministic Digests for Verification

To ensure the recovered state matches the original execution, digestProviderReplay generates a SHA-256 digest of the provider-replay plan (protocol, version, and provider items) using stable JSON stringification. This RuntimeBoundaryDigest is stored on the boundary cursor and later compared against the digest of a newly-generated continuation plan. If the digests differ, Maka aborts the continuation, preventing resumption from an inconsistent state.

Building a Continuation Replay Plan

The exported entry point, buildContinuationReplayPlan, iterates over all prefixes (each representing a potential continuation boundary) and aggregates the segment plans into a full ContinuationReplayPlanV1. The plan includes the boundary (a RuntimeBoundaryCursorV1 marking the exact resume point), the providerReplayDigest (the deterministic hash), the segments (ordered list of replayable segments with their trimmed suffixes), and the runtimeContext (combined set of runtime events to replay). If any segment is blocked, the function bubbles up the failure with the segment index and diagnostic details.

import { buildContinuationReplayPlan } from '@maka/runtime/continuation-replay';

// Assume `prefixes` is an array of immutable runtime prefixes collected
// from a persisted log after a crash.
const result = buildContinuationReplayPlan({
  prefixes,
  providerProjectionVersion: 1,   // MUST match PROVIDER_REPLAY_PROJECTION_VERSION
});

if (result.kind === 'replayable') {
  // The plan can be handed to the runtime to resume execution.
  const plan = result.plan;
  console.log('Continuation plan ready – digest:', plan.providerReplayDigest);
} else {
  // Recoverable errors are surfaced with a clear reason.
  console.error('Continuation blocked:', result.reason);
  console.error('Diagnostics:', result.diagnostics);
}

Integrating with the Maka Runtime

In production, the runtime loads persisted event logs after a crash and delegates recovery decisions to continuation-replay.ts. The typical integration pattern validates the continuation plan before injection, ensuring that only verified, replayable plans are executed while surfacing clear errors for blocked states.

// 1. Load persisted event log after a crash.
const persistedPrefixes = await loadPersistedPrefixes();

// 2. Build the continuation plan.
const continuation = buildContinuationReplayPlan({
  prefixes: persistedPrefixes,
  providerProjectionVersion: PROVIDER_REPLAY_PROJECTION_VERSION,
});

// 3. If the plan is replayable, inject it into the runtime.
if (continuation.kind === 'replayable') {
  runtime.injectContinuationPlan(continuation.plan);
} else {
  // Abort with a user-friendly error message.
  throw new Error(`Cannot resume: ${continuation.reason}`);
}

Summary

  • continuation-replay.ts acts as the central coordinator for Maka's crash recovery, bridging raw event logs and executable continuation plans.
  • The module validates event prefixes via recovery-resolver.ts to block recovery when it detects tool_recovery_corruption or unsettled tool states.
  • It constructs segment plans that isolate stable provider items and trim incomplete suffixes to prevent replaying partially-executed operations.
  • SHA-256 digests generated by digestProviderReplay provide cryptographic verification that the reconstructed state matches the original execution context.
  • The buildContinuationReplayPlan function aggregates segments across all potential boundaries, producing either a replayable ContinuationReplayPlanV1 or a detailed block reason.

Frequently Asked Questions

What happens when continuation-replay.ts detects corruption in the event log?

When resolveRuntimeRecovery identifies tool-ledger corruption or unsettled recovery facts, buildContinuationReplayPlan returns a blocked result containing a ContinuationReplayBlockReason such as tool_recovery_corruption or tool_recovery_unsettled. The function bubbles up the specific segment index and diagnostic details, causing the runtime to abort resumption and surface a clear error to the user rather than risk executing from an invalid state.

How does the module distinguish between events to replay and events to discard?

The buildContinuationReplaySegment function uses buildRuntimeEventModelReplayPlan (from model-history.ts) to analyze model-visible events and detect unmatched tool calls. It isolates stable provider items—the last successfully materialized tool result or user message—to serve as the replay anchor. All events occurring after this anchor are classified as the trimmed suffix and discarded via trimmedSuffixEventIds, while replayRuntimeEvents contains only the validated prefix that can safely be re-executed.

What is the purpose of the provider replay digest in the continuation process?

The digestProviderReplay function generates a SHA-256 hash of the provider-replay plan (including protocol, version, and provider items) using stable JSON stringification. This RuntimeBoundaryDigest acts as a deterministic fingerprint of the intended continuation state. By comparing this stored digest against a newly-generated plan's digest, Maka verifies that the recovered state exactly matches the original execution context, aborting continuation if any discrepancy indicates state divergence.

Which supporting modules does continuation-replay.ts interact with during recovery?

According to the Apache Maka source code, continuation-replay.ts relies on three critical dependencies: recovery-resolver.ts (to validate event prefixes for corruption), model-history.ts (to build runtime event models and detect unmatched tool calls via buildRuntimeEventModelReplayPlan), and runtime-boundary.ts (to define the RuntimeBoundaryCursorV1 and digest structures referenced throughout the workflow). Together, these files implement the complete crash-recovery pipeline.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →