Skip to content
pleach
ReferenceChangelog

@pleach/replay changelog

Release history for @pleach/replay — site-docs entries that materially touched the @pleach/replay surface, newest-first. Canonical runtime history lives upstream.

This page collects the site-content changelog entries that materially touched the @pleach/replay docs surface or named a @pleach/replay symbol. It is not the runtime changelog — the canonical record of @pleach/replay runtime behavior lives in the upstream package CHANGELOG.md and on npmjs.org/package/@pleach/replay.

See the combined site changelog at /docs/changelog/combined for the chronological unified view across every SKU.

Unreleased

Fixed

  • Replay no longer promises byte-identical output. A live model can't guarantee it. Eval and replay renames "Verifying byte-identical replay" to "Checking a replay for divergence", and deterministic: true now reads as "no step diverged in this check". The glossary, FAQ, and comparison tables say what ships: replay re-serves the recorded stream and drift raises ReplayDivergenceError.
  • Audit-record claims now match what the code enforces. The homepage pillar, components/session-manifest-diagram.tsx, content/docs/security.mdx, replay.mdx, ci-enforcement.mdx, audit-ledger.mdx, and compliance/gdpr-erasure.mdx said rows are "written once and never edited or deleted" or "immutable". The ledger API has no update or delete primitive, but that does not stop a writer with direct database access. The pages now say so, and say what the hash chain adds: edits, deletions, and reordering become detectable after the fact.

Fixed

  • Region-pinned agent replay snippet corrected to the shipped ReplayRuntime shapes (devharness FINDING 100–102). createReplayRuntime takes sessionRuntime, not liveRuntime (ReplayRuntimeConfig = { tenantId (required), sessionRuntime?, cacheReadMode?, clock?, eventSource? }, replay/src/runtime/types.ts:499). replayTurn input is { chatId, tenantId, messageId } — turnId → messageId, mode is not a field, and tenantId is required (ReplayRuntime.ts:521; ReplayTurnInput, types.ts:95). Its output is { chatId, tenantId, messageId, state, sequenceNumberRange } (ReplayRuntime.ts:573) — there is no .diff field, so the cross-family parity read was rewritten to compare the returned state yourself, with a pointer to the hash-chain verifyIntegrity verdict ({ valid, brokenAt? }) for tamper-evidence.

  • @pleach/replay eval-coupling snippet corrected (devharness FINDING 89). The DI example constructed new EvalSuite({ replay }), but EvalSuiteOptions (eval/src/index.ts) has no replay field and requires suiteId; the real cross-wire is suite.setReplayClient(client). Corrected to new EvalSuite({ suiteId, runtime }) + suite.setReplayClient(replay) (the source doc comment at replay/src/index.ts was likewise corrected).

Added

  • Replay Cache adapters section. Documents createDiskCacheProvider, createRedisCacheProvider, and createS3CacheProvider (@pleach/replay/cache/adapters/*) — the backing stores for createCacheMiddleware.
  • /docs/replay — createStrictHandleReplay determinism gate. New @pleach/replay/strict export (re-exported at the root) that walks N independent handles over the same (chatId, tenantId, window) and byte-compares the folded per-step state, returning { deterministic, steps, firstDivergenceAt? }. Documented in the Status section, a new "Determinism gate" subsection, and the Roadmap. Sibling of createStrictReplay (which gates the ReplayRuntime.replayTurn surface).
  • /docs/replay — cacheKey replay slot. @pleach/core's tool.completed / turn.completed events gained an optional cacheKey payload field; the ReplayHandle consults a wired cacheBackend for rows that carry it (per cacheReadMode). The "What's NOT" list notes core does not populate it (the core → replay boundary forbids importing deriveContentHashKey) — host- / createCacheMiddleware- populated.

Changed

  • /docs/replay — ReplayHandle stepper documented as wired. step() / seek() / replayTurn() no longer throw NotImplementedError; they walk the event log via runtime.events.iterate and fold through hydrateFromEvents. Updated the Status section, the ReplayHandle member table (all six members Live), the step()/seek()/replayTurn() behavior section, the determinism contract (one shared reducer → seek(N) == N steps == a full fold), the error-hierarchy note on NotImplementedError, and the "What's NOT in this package" list (now: no StrictReplay diff over the handle, no automatic cache-key derivation from rows). Mirrored the one-line status flip on /docs/eval-and-replay.

Added

  • <StatusBadge> reference adoption — /docs/replay adopts <StatusBadge status="in-flight">Phase A + Phase B</StatusBadge> under its Status heading as the reference adoption of the new first-party enterprise-shape component.

Changed

  • /docs/replay error hierarchy diagram — the ASCII tree rendering ReplayError / ReplayDivergenceError / ReplayCacheMissError / ReplayUnknownEventError / NotImplementedError is now a mermaid classDiagram with inheritance arrows and per-class fields. Matches the established mermaid idiom used on /docs/overview and elsewhere.
  • Cross-docs status-flip pass — @pleach/replay's ReplayRuntime invokes the @pleach/core/eventLog hash-chain verifier (verifyChainForChat / generateProof live in @pleach/core/eventLog), with writer-side stamping in @pleach/core/eventLog behind c9PhaseBEnabled. Touched the Replay and Hash chain pages.

2026-06-08

Changed

  • Packages table corrected to real published version — @pleach/replay 0.7.0 (was largely stale "Reserved · placeholder" framing).
  • @pleach/replay Phase B note now distinguishes the landed replayTurn body from the still-throwing fromSnapshot / fork / multiTenantAggregate.