Determinism and Replay

MACP defines formal determinism guarantees that enable session replay, audit verification, and distributed state reconstruction. The SDK relies on those guarantees but does not define them — they are protocol-level. This page focuses on what an SDK user needs to do (version binding, replay testing) and links out for the rest.

Determinism classes — at a glance

Each mode declares a determinism class. The SDK does not enforce these — the runtime does — but they govern what you can assume on replay:

ClassModesReplay guarantee
semantic-deterministicDecision, Proposal, Quorumsame envelopes → same semantic outcome
structural-onlyTasksame envelopes → same lifecycle, outcomes may differ
context-frozenHandoffsame envelopes + same frozen context → same outcome
non-deterministic(extension modes)structural transitions only

Full definitions: RFC-MACP-0003 (Determinism). For Handoff mode's context-frozen nuance specifically, see Handoff Mode § Context-Frozen Determinism.

Version binding (SDK responsibility)

Three versions are bound at SessionStart and cannot change for the life of the session. The SDK passes them through verbatim — pin them explicitly when the session is part of an audit trail:

const session = new DecisionSession(client, {
  modeVersion: '1.0.0',
  configurationVersion: 'org-2025.q4',
  policyVersion: 'procurement-v3',
});

Different versions produce different sessions; replay uses the bound versions, not whatever is current. See Session Classes § Common Options for the full set of per-session options.

External side effects

When a mode triggers actions outside the session (deployments, payments, emails), use the established protocol patterns to keep replay meaningful — plan-then-execute, log external results, or idempotent external transactions. See Protocol Determinism § External side effects for the canonical guidance.

The SDK supports the plan-then-execute pattern naturally — the Commitment carries the plan and an idempotency key:

await session.commit({
  action: 'deployment.approved',
  authorityScope: 'release',
  reason: 'approved with idempotency_key=deploy-v2.1-20260329',
});

Testing determinism in TypeScript

Verify replay correctness by recording the transcript and feeding it through a fresh projection. applyEnvelope takes the envelope plus the client's ProtoRegistry (payload decode needs it) — see Projections § Common Interface:

import { DecisionProjection } from 'macp-sdk-typescript';

// Record during a live session
const transcript = session.projection.transcript;

// Replay against a new projection
const replay = new DecisionProjection();
for (const envelope of transcript) {
  replay.applyEnvelope(envelope, client.protoRegistry);
}

expect(replay.majorityWinner()).toBe(originalWinner);
expect(replay.isCommitted).toBe(originalCommitted);

For semantic-deterministic modes, the replayed projection must match the original. Build this into your test suite for any orchestrator that depends on replay — see Testing § Writing Projection Tests for the patterns this SDK's own test suite uses to exercise applyEnvelope directly.