Skip to main content

Determinism and Replay

This document explains how the C_AI Platform ensures deterministic replay of assessment runs through snapshot pinning and immutability rules.

Why Determinism Matters

Compliance platforms require:

  1. Reproducibility - Same inputs produce same outputs
  2. Auditability - Ability to reconstruct exactly what happened
  3. Regulatory defense - Prove assessment results are accurate

Snapshot Pinning

When a run is created, the platform captures a snapshot of all configuration versions that affect the run outcome.

What Gets Pinned at Run Creation

Location: server/lib/assessmentPipeline.ts:128-146

const [run] = await db.insert(runs).values({
tenantId,
packId,
environment: snapshot.environment,
status: RunStatus.IN_PROGRESS,
// Snapshot pinning (Step 9) - deterministic replay
snapshotCriteriaVersionId: snapshot.snapshotCriteriaVersionId,
snapshotCorpusActivationId: snapshot.snapshotCorpusActivationId,
snapshotRetrievalVersionId: snapshot.snapshotRetrievalVersionId,
snapshotPromptVersionId: snapshot.snapshotPromptVersionId,
snapshotChunkingVersionId: snapshot.snapshotChunkingVersionId,
snapshotAgentVersionId: snapshot.snapshotAgentVersionId
}).returning();

Pinned version IDs (defined in runs table, shared/schema.ts:354-359):

FieldPurpose
snapshotCriteriaVersionIdWhich criteria set version
snapshotCorpusActivationIdWhich regulatory corpus activation
snapshotRetrievalVersionIdRetrieval engine config version
snapshotPromptVersionIdPrompt template version
snapshotChunkingVersionIdChunking config version
snapshotAgentVersionIdAgent workflow version

How Pinning Works

Pack resolution (server/lib/packResolver.ts:25-105):

  1. resolvePackBinding(tenantId, packId, environment) queries current bindings
  2. Returns EffectivePackBinding with all version IDs
  3. createRunSnapshot(binding) extracts snapshot fields (lines 107-117)
  4. Snapshot is persisted to runs table at run creation
export function createRunSnapshot(binding: EffectivePackBinding) {
return {
environment: binding.environment,
snapshotCriteriaVersionId: binding.criteriaVersionId,
snapshotCorpusActivationId: binding.corpusActivationId,
snapshotRetrievalVersionId: binding.retrievalVersionId,
snapshotPromptVersionId: binding.promptVersionId,
snapshotChunkingVersionId: binding.chunkingVersionId,
snapshotAgentVersionId: binding.agentVersionId
};
}

Immutable Replay Snapshots

At run completion, a full immutable snapshot is captured.

What Gets Frozen

Location: shared/schema.ts:382-397 (run_replay_snapshots table)

FieldContent
assessmentsDataAll assessment records (jsonb)
tasksDataAll generated tasks (jsonb)
exportsDataAll export records (jsonb)
configSnapshotFrozen configuration state (jsonb)
snapshotHashSHA256 of snapshot content

Snapshot Status Tracking

Location: shared/schema.ts:306-311

export const SnapshotStatus = {
PENDING: "PENDING", // Run not yet completed
CAPTURED: "CAPTURED", // Snapshot successfully captured
FAILED: "FAILED", // Snapshot capture failed
LEGACY: "LEGACY" // Pre-Step 9 run - no snapshot exists
} as const;

The snapshotStatus column on runs table tracks this state.

Replay Guard

The replay guard prevents non-deterministic operations during replay.

How It Works

Location: server/lib/replayGuard.ts

const replayStorage = new AsyncLocalStorage<ReplayContext>();

export function runInReplayMode<T>(runId: string, fn: () => T | Promise<T>) {
return replayStorage.run({ runId, isReplay: true }, fn);
}

export function assertReplaySafe(operation: string): void {
const store = replayStorage.getStore();
if (store?.isReplay) {
throw new ReplayModeError(operation);
}
}

Forbidden Operations in Replay Mode

Operations that call assertReplaySafe() will throw ReplayModeError during replay:

OperationLocationWhy Forbidden
generateSimpleEmbeddingassessmentPipeline.ts:66Non-deterministic
vector searchvectorStore.ts:60Live DB query
corpus vector searchvectorStore.ts:89Live DB query

Pack Immutability

Once a pack has ACTIVE bindings, it becomes immutable.

Immutability Service

Location: server/lib/packSafetyService.ts

Key functions:

  • isPackScopeActive(scope) - Checks if pack has any ACTIVE binding (lines 60-114)
  • enforcePackImmutability(scope) - Throws PackActiveImmutableError if active (lines 120-131)

Pack is ACTIVE if it has any of (documented at lines 55-58):

  • corpus_activations with is_active=1 for (tenant_id, pack_id, environment)
  • pack_criteria_bindings for (tenant_id, pack_id, environment)
  • engine_active_bindings for (tenant_id, pack_id, environment)

Error Response

When attempting to modify an ACTIVE pack:

Location: server/lib/packSafetyService.ts:27-46

export class PackActiveImmutableError extends Error {
code = "PACK_ACTIVE_IMMUTABLE";
httpStatus = 409;
// ...
}

Returns HTTP 409 with error details.

What Must Never Mutate

During a Run

These must remain constant from run start to completion:

DataReason
Criteria definitionsAssessment targets
Corpus text unitsRegulatory reference
Engine configsAssessment behavior
Evidence documentsAssessment inputs

After Run Completion

These are frozen permanently:

DataLocation
run_replay_snapshotsImmutable table with runUnique constraint
Pinned version IDs on runsSet at creation, never updated
Audit log entriesAppend-only (server/lib/audit.ts)

Replay Process

For CAPTURED Runs

  1. Load run_replay_snapshots by runId
  2. Return frozen assessmentsData, tasksData, exportsData
  3. No live queries executed

For FAILED Runs

  1. Check snapshotStatus = FAILED
  2. Return error: "REPLAY_UNAVAILABLE: Snapshot capture failed"
  3. Operator must investigate original failure

For LEGACY Runs

  1. Check snapshotStatus = LEGACY
  2. Fall back to live table queries with warning
  3. Results may differ from original run

Uniqueness Constraints

Environment-scoped uniqueness prevents conflicts:

Corpus activations (shared/schema.ts):

CREATE UNIQUE INDEX corpus_activations_unique_active_idx 
ON corpus_activations (tenant_id, pack_id, environment)
WHERE is_active = 1;

Criteria bindings:

CREATE UNIQUE INDEX pack_criteria_bindings_env_unique 
ON pack_criteria_bindings (tenant_id, pack_id, environment);

Engine bindings:

CREATE UNIQUE INDEX engine_binding_env_unique 
ON engine_active_bindings (tenant_id, pack_id, environment, config_type);

Testing Determinism

To verify deterministic replay:

  1. Complete a run (status: COMPLETED, snapshotStatus: CAPTURED)
  2. Request replay via admin API
  3. Compare replay output hash with original snapshotHash
  4. Hashes must match exactly