pleach
ReferenceChangelog

@pleach/core changelog

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

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

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

Unreleased

Added

  • Comparison gains a category for agent-memory & knowledge-graph substrates (a read-side category). Pins the read-vs-write delineation for @pleach/core: memory layers and knowledge-graph engines (Letta, Mem0, Zep) are a read substrate — the graph exists so the agent can query it to decide; @pleach/core is a write substrate — the ledger exists so every provider call is recorded, then read to account. Shared skeleton (append-only, content-addressed, causal chain, fork/replay); divergent object of record (the agent's knowledge/decisions vs. one provider call with model/tokens/cost). Compose-not-compete — a memory graph reads the same session the AuditableCall row writes.

Fixed

  • Unknown safety-policy ids now throw at construction — even with no plugins. Safety promises "Construction throws UnknownSafetyPolicyError if the config references an id no plugin registered — operator typos surface at boot, not on the first turn." Previously the enable/validate loop was gated behind the plugin block, so a plugin-less createPleachRuntime({ enabledSafetyPolicies: ["typo"] }) silently no-op'd the enable and the typo surfaced (or silently didn't) only at first turn. The enable loop now runs unconditionally (core SessionRuntime.ts); the register() loop stays plugin-gated, so a legitimately plugin-contributed id is registered before the enable finds it and valid constructions are unaffected. The impl now matches the documented guarantee.

  • The chronological error trail (errorCodesChronological) now captures every error class. A completed tool call carrying a structured _error_code (its status looks successful, so it tripped neither the failed-status nor the schema-validation branch) and a caught async-planner throw (AsyncPlannerHandler, previously console-only) now each persist an error.code row. A live turn with these errors previously persisted zero rows; the durable trail is now complete. (Direct-API tool errors were already covered by the host emit path.)

  • Core-concept doc snippets reconciled with shipped signatures (devharness FINDING 88, 91–93). Determinism — the ledger read used a non-existent ledger.list({ sessionId }); the real AuditableCallQuery read is async positional await ledger.getSession(sessionId) (core audit/ProviderDecisionLedger.ts), and the "distinguishes three operating contracts" line corrected to five (the RuntimeMode union — and the page's own table — lists five). OTel observabilityexecuteMessage is positional executeMessage(sessionId, "hello"), not the object form executeMessage({ sessionId, content }) (core SessionRuntime.ts). Stream events — the LangGraph "values" mapping used runtime.sessions.get(), which RuntimeSessionsFacet (core facets/sessions.ts) does not expose; corrected to runtime.sessions.resume(sessionId).

Added

  • Gate failures → fixes — the failure-string lookup. Maps each gate's verbatim, greppable failure string to its meaning and the fix doc — [graph-stages] Node "<name>" missing stageId in NODE_STAGE_MAP, [audit:c8-event-type-allowlist-coverage] FAIL, [auditable-call-version] FAIL rule 3, [audit:plugin-contract-completeness] FAIL, and others, all verified against scripts/audit/. The agent-facing close of the self-extension loop.

  • AuditRecordVersion corrected 1418 on CI enforcement to match the source (export type AuditRecordVersion = 18;) and the AuditableCall row.

  • Extending Pleach — the gate-paired authoring map. Pairs each extension point with the interface, the registration call, and the audit gate that fails if the addition is wrong — nodes (audit:graph-stages), event types via contributeEventTypes (audit:c8-union-member-has-producer

    • audit:c8-event-type-allowlist-coverage), scrubbers, plugin hooks (audit:plugin-contract-completeness), prompt blocks, and a custom audit field via pluginPayloads (audit:auditable-call — the structural column set is locked). Draws the host-extension vs upstream-contribution line, and adds an "Agent-driven self-extension" section: the gates as an autonomous write → audit:* → read-failure → fix loop, plus injecting the extension contract into the operating agent's prompt via contributeRuntimeAwarePrompts. Nodes, channels, and scrubbers gained a "What CI checks when you add one" footer linking into it.
  • createPleachRoute({ demo }) keyless first-run + demo-first pleach init scaffold documented. Getting started, Quickstart, and Install now lead the wizard path with a keyless demo: with no provider key, createPleachRoute({ demo: process.env.NODE_ENV !== "production" }) drives a real graph turn over canned model text and writes real AuditableCall rows, flagged x-pleach-mode: demo. A resolved <PROVIDER>_API_KEY always wins; demo never engages in a production build. The Next.js App Router scaffold adds an /audit view (app/audit/page.tsx + app/api/audit/route.ts) rendering the per-model-family rollup (family · rows · tokens · est. cost). The bare createPleachRoute() no-key contract is unchanged (HTTP 503).

  • engine/ superstep scheduler named as an architecture piece + facets.mdx synced to the shipped facet inventory (pkgclean 06 D7/D9). Architecture and Concept clusters now name the engine/ scheduler (SuperstepRunner + its primitives) as the deterministic superstep executor that runs the compiled graph. Facets gained the two shipped SessionRuntime accessors it omitted — runtime.observe and runtime.probes — plus the four per-stage graph introspection facets graph.anchor / graph.toolLoop / graph.synthesize / graph.postTurn.

  • @pleach/core/skills + @pleach/core/agents/types are real emitted subpaths. Skills updated to import SkillLoader, parseSkillFrontmatter, Skill, and SkillFrontmatter from the @pleach/core/skills barrel (the /loader, /parser, /types sub-subpaths do not exist); Agents prose corrected from "wildcard path" to a real emitted @pleach/core/agents/types subpath.

Changed

  • @pleach/core/internal/… subpaths retired from the public docs surface (pkgclean 06 D8). streamSingleTurn and Subpath exports no longer document @pleach/core/internal/strategies/streamSingleTurn/helpers (+ its four direct helper entries) or @pleach/core/internal/tools/execution/registryResolvedTools as stable public imports. The internal/ segment marks implementation details, not a supported API; the copy-paste helper-barrel import is removed and both paths moved to a "Not a public import surface" section with their public alternatives — ToolDefinition from @pleach/core/types/generic, and @pleach/core/tools/execution (which re-exports the resolved-tools registry functions). No package.json:exports change.

  • core.mdx stale numbers corrected. auditRecordVersion updated 13 → 18 (real value at AuditableCall.ts), and the HarnessPlugin plugin-hook count updated ~41 → 67 contributeX hooks (derived by grepping packages/core/src/plugins/types.ts).

Fixed

  • More SKU doc-page snippets reconciled with the shipped signatures (devharness FINDING 80–82). Fabrication detection — the custom-detector example used a non-existent ctx.toolArgs and returned {suspect, tier}; corrected to the real FabricationDetectorContext fields + the FabricationFinding shape ({detectorId, severity, reason, evidence?}), and the tier-routing bullet corrected (routing keys on the tool's safetyTier, not a finding's severity). Multi-tenantgetAggregateUsage is 3-positional ((client, store, filters)), has no groupBy: "tenantId" value (session/agent/model/tool/day/week), nests dates under dateRange, and requires userId (it's single-user scoped; tenant rollups use the raw SQL). Determinism — the fingerprint round-trip read a non-existent .fingerprint audit field (real: fingerprintComposite, a string) and compared a string to a Fingerprint object; corrected to a like-for-like comparison over a real FingerprintInput. These are the ctor-shape / call-arity / field-name classes the new audit:doc-import-resolution gate doesn't cover (import-resolution only).

  • Event-log read side documented as store-agnostic — eventReader / HarnessEventReader. Event-log projections said runtime.events.iterate / .fold read harness_event_log rows ordered by (chat_id, sequence_number) and became live "on the Supabase backend in PA-1 Phase A.2" — store-specific claims that no longer match the shipped surface. Corrected: both accessors delegate to a HarnessEventReader injected as the runtime's eventReader (the read-side counterpart to eventLogWriter), so the host casts its own store into the reader at construction and @pleach/core itself stays free of backing-store knowledge — Postgres, Supabase, SQLite/pglite, or an HTTP API back the same surface. iterate's options gain tenantId; the reader is required to read the durable log (no built-in reader, no implicit store fallback — a bare runtime yields nothing, matching the MemoryAdapter path) and throws a typed error at the call site when absent. New Backing the reader section shows the one-method contract yielding EventLogRow (the shape reconstructSessionState and the shipped projections fold). Session runtime config table gains eventLogWriter + eventReader rows; Storage grows the ci:devharness-sql value-prop battery from four durable properties to nine — adding the @pleach/observe postgres() destination, time-travel fork, SQL-queryable audit ledger (harness_auditable_calls), tamper-evident hash chain, and @pleach/replay deterministic replay over the injected reader.

  • SKU doc pages reconciled with the shipped import/construction surface (devharness FINDING 76–79). Four doc-site pages drifted from the (correct) package READMEs: Building a chat UI advertised a fabricated @pleach/react chat-hook API (useChat/HarnessProvider from the root, useInterruptDecision, useChatVercelCompat, sendMessage) — corrected to the real surface (useSessionRuntime/useSessionMessageStream/useInterruptUI from @pleach/react; useChatsubmit from @pleach/core/quickstart; HarnessProvider from @pleach/react/legacy/@pleach/core/react; useVercelAISDKCompat from @pleach/react/adapters/vercel-ai-sdk). LangChainLangChainProvider takes a POSITIONAL model arg and wires via the top-level provider: slot (not { model } / host.strategies.provider). Base tools — the scratchpad is per-SESSION (chatId-scoped, not per-turn), its param is operation (not op), and its value is a string. Coding agent — the four sandbox tools register via a contributeTools HarnessPlugin in plugins: (SessionRuntimeConfig has no tools/context field). A new packages/core/test/docImportSurface.smoke.test.mjs regression-locks the import-path half.

  • Observability + gateway-cost docs corrected to the shipped exporter/cost surface (devharness FINDING 73–75). @pleach/core ships no @opentelemetry/* dependency and never reads the global tracer provider — the documented NodeSDK + OTLP recipe captured zero pleach spans. OTel observability and Observability now show the real path: a host-supplied OtelExporter bridge injected via new SessionRuntime({ otelExporter }) (default is NoopOtelExporter, which drops spans). runtime.spans.snapshot() returns { inFlightCount, isShutdown } (exporter state) — to inspect emitted spans you wire a CapturingOtelExporter and read .captured (real fields startTimeNs/endTimeNs/ parentId). And Gateway cost events + the gateway OTel wiring: computeCost was reading tenantId/family/callClass/byokActive/ routingDecision off RouteChatCompletionOutput, which carries none of them (asTenantId(undefined) threw → zero CostEvents) — the example now reads only real output fields + host-supplied observation context, and flags that routeChatCompletion is currently a slice-2 stub (costUsd: 0).

  • Subagents + async-tasks docs reconciled with the host-completion-required reality (devharness FINDING 66–72). Bare @pleach/core's subagent surface is host-completion-required (the host supplies subagentExecutor / drives SubagentManager); the docs presented it as substrate-delivered. Corrected in Subagents: removed the fabricated spawnsSubagent: true auto-escalation flag; LightweightRuntime → the real LightweightSessionRuntime imported from @pleach/core/subagents (not root) with its real constructor; fetchWorkspaceContext/formatWorkspaceContextPrompt moved to the @pleach/core/subagents subpath; the concurrency model corrected (the runtime spawn path caps on the hard SUBAGENT_LIMITS constant and FAILS over-cap rather than queueing — the SubagentManager queue/DAG is host-driven); context.variables noted as currently inert; plus a host-completion caveat. And Async tasks: the async-task tool-loop bridge is not wired in bare core (ASYNC_TASK_BRIDGE_NOT_WIRED), and the "subagent"/"sandbox_exec" task executors are host/plugin-supplied (the in-tree SubagentTaskExecutor is server-only), not "in-tree defaults".

  • Abort + resume docs synced to the shipped runtime behavior (devharness FINDING 56 + 62). Aborting an in-flight turn now records outcome.status: "user-aborted" (not "aborted" / not lumped into provider-error) at BOTH the tool-loop decision call and the synthesis terminal, so cost rollups + compliance separate caller cancellation from provider failure — corrected across session lifecycle, SessionRuntime, turn lifecycle, and API routes. And resuming a session now describes the real three-layer rebuild: storage row → version-guarded checkpoint overlay (the crash-recovery path) → server-only event-log hydration of the ephemeral card-lifecycle state (interrupts/subagents/exports/user cards) onto a transient Session.hydratedHarnessState field — correcting the prior claim that hydrateFromEvents rebuilt messages/channel state.

  • Model-resolution-matrix path corrected — it is host-supplied, not a @pleach/core dir (pkgclean 06 D7). The docs cited the family-lock matrix at the fictional src/graph/modelfamily/ (family-lock) and @pleach/core/ai/modelFamily/matrix.ts (quickstart, provider detection) — neither path exists in the package. The (family × callClass) matrix table is host-supplied and reached through the AgentAdapter.resolveModel<C>() seam; the ProviderFamily set is now pointed at the real @pleach/core/modelfamily export. The routing-decision seam's Ivy-internal host path was removed from routing decisions.

  • Docs reconciled with the shipped @pleach/core runtime (value-prop-vs-impl audit, devharness FINDING 56–64). Corrected doc claims that diverged from the implementation:

    • Time travelfork sets parent_id: source.id (not null).
    • Checkpointing — checkpoints write at message/event boundaries (discriminated by CheckpointMetadata.source), not stamped with a per-stage stageId; SupabaseSaver durability is "replicated"; rollback writes source: "manual" + writes: ["rollback"]; the fork snippet takes a string newSessionId.
    • Session lifecycle — the checkpoint snapshot is authoritative on the live restore path; the event-log canonical reader is a flag-gated shadow today.
    • Sync — interactive conflict resolution (runtime.resolveConflict, the sync.conflict event, the 3xxx code range) is enterprise-tier/planned; open-core uses SyncCoordinator last-writer-wins-on-push with a free-text lastError.
    • Query — dropped the non-existent queryAuditableCalls; corrected getChatUsage / lookupModelCost / getSessionReview / getInterruptChain signatures + return shapes to the real @pleach/core/query surface.
    • Memory — the production extraction path is the graph node (createMemoryExtractionNode), not the memoryExtractionHook → queue pipeline; LearnedFact.source is a provenance string (+createdAt/lastConfirmedAt) on extractor facts, with the object form documented alongside.
    • Lineage — opt-in via config.lineageTracker; the runtime records the session node + a branched_from fork edge, the other relations are host-recorded; completeSession is host-called.

Added

  • Opt-in tool-event preview enrichment for the manifest projection. New runtimeQuirks.enrichToolEventPreviewsForReplay flag (default OFF) lets the host write compact args_preview (tool.started) + output_preview (tool.completed) onto tool events; chatManifestProjection folds them into richer manifest params/output, closing the projection's intentional lossiness vs. the live provider. The previews are scrub-allowlisted (the C8 redaction chain processes them). OFF by default preserves the arguments_hash-only privacy posture. This makes the projection canonical-capable; the projection-canonical flip itself stays gated. See Replay.
  • TimeTravel surfaces the chat manifest (StateSnapshot.manifest). getState / getStateHistory / fork / bulkUpdate now carry the chat-manifest ledger AS-OF a checkpoint, for inspection (it does not feed the next generation — that runs through rollbackToCheckpoint / resumeSession into the live provider). The snapshot rides the checkpoint metadata (round-tripped via SupabaseSaver.metadata_extra; Memory/IndexedDB ride free), mirroring the pendingTasks pattern. See Time travel.
  • ProviderFamilyExhaustedError promoted to the top-level @pleach/core surface. The provider-family cascade terminal (raised when every in-family rung is exhausted) + its isProviderFamilyExhaustedError guard are now public on @pleach/core — previously reachable only via the deep @pleach/core/graph/seams/providerExhaustion path. Catch + narrow it from the top-level import.
  • @pleach/core/cache — content-hash deriver. deriveContentHashKey, canonicalizeKeyInput, and ContentHashKeyInput now have their canonical home in @pleach/core/cache (relocated from @pleach/replay/cache, which re-exports them for back-compat). The move lets @pleach/core derive + stamp a cacheKey into tool.completed / turn.completed events without the forbidden core → replay import. See Subpath exports.
  • @pleach/core/manifest — reload-durability + the manifest as a projection. The chat-manifest ledger (the [Session Manifest] prompt block) now survives a process reload: SessionRuntime.saveSession stamps the live snapshot into the persisted session state and resumeSession rehydrates it (complementing the existing checkpoint rollback restore). New chatManifestProjection / foldChatManifest fold the manifest deterministically from the event log (tool.* / job.* / model.upgraded), replayable via runtime.events.fold and the @pleach/replay stepper — intentionally lossy vs. the live provider (the log carries hashes/sizes, not full params/output), measured by a flag-gated [UXParity:manifest-projection-divergence] shadow probe. See Subpath exports.
  • tool.completed / turn.completed — optional cacheKey payload slot. Lets a deterministic replay consult the provider cache on the row (consumed by @pleach/replay's ReplayHandle). Host- / createCacheMiddleware-populated; core does not derive it (the core → replay boundary forbids importing deriveContentHashKey). See Replay.

Added

  • CI enforcement of the audit contract — new Reference page indexing the audit-gate catalog by the auditability and replayability clause each gate enforces. Covers the @pleach/core event-log gates (audit:auditable-call, audit:auditable-call-soak, audit:event-log-manifest-hash-completeness, the three audit:config-manifest-* gates, audit:c8-event-type-allowlist-coverage, audit:c9-hash-chain-integrity) and the CI jobs that carry them (graphnoderef, local-clone, per-SKU consumer-rehearsal). Cross-linked from Audit gates.
  • Contribution namespaces — new page documenting the nine namespaces every HarnessPlugin contribution hook resolves to (prompts, stream, safety, audit, intent, tools, middleware, policy, lifecycle) — the canonical, audit:plugin-hook-category-assigned-gated contract layout, with representative hooks per namespace and the rolling-out typed namespaced authoring form. Plugin contract gains a cross-link; Authoring a HarnessPlugin reframes its informal 12-bucket grouping as the scan view of these nine canonical namespaces.
  • Config manifest — new page documenting the content-addressable substrate snapshot the runtime writes to harness_config_manifest: one row per distinct plugin/prompt/node/channel/filter set, keyed by a SHA-256 Merkle roll-up (pleach.manifest.v1 prefix, 0x1F separator, mirroring the hash chain's pleach.c9.v1 canonicalization). Per-surface child hashes, the nullable manifest_hash foreign reference on harness_event_log, reference-counted retention (default forever), full-snapshot storage, and the canonical replay/audit query shapes. Marked in-flight — table and event-log column land as additive schema files during rollout.
  • What Pleach writes to your database — new page mapping every @pleach/core table written to a buyer's database, what's default versus opt-in, and the destination-is-yours posture (no phone-home).
  • manifest_hash cross-references added to Event log (stamping section + EventLogRow field) and Schema (rolling-out harness_config_manifest section).
  • OrchestratorClient — new top-level page documenting the per-turn handle the runtime threads through the stream body. Lifted from app-side into the substrate; canonical import path is @pleach/core/runtime/orchestratorClient. Covers the six user-facing facets (config, history, context, tools, model, prompts) and the _internal.graph snapshot consumer code must not touch.
  • streamSingleTurn — new top-level page documenting the canonical per-turn body. Lifted into @pleach/core/strategies/streamSingleTurn/ with a stable helpers barrel re-exporting TurnAccumulator, ToolDefinition, OrchestratorMessage, and ProviderFallbackConfig.
  • Subpath exports — adds two rows to the Runtime + composition table: @pleach/core/runtime/orchestratorClient and @pleach/core/strategies/streamSingleTurn. Both are now named subpath exports rather than wildcard-only reachable.
  • Subpath exports → @pleach/core/quickstart — added under the Wire + tooling cluster. Lists the five LANDED deliverables — createPleachRoute (fetch-handler factory), useChat (Pleach-native React hook), <ChatBox /> (unstyled, accessible), defaultPlugin (empty baseline), providerDetection helpers + constants — plus the benchmark-adjacent createBenchmarkPlugin.
  • Attestation — new top-level page on the Ed25519-signed envelope substrate that sits on top of the hash chain. Documents the @pleach/core/attestation subpath (signer, verifier, key-store interface), the two stub production adapters (AWS KMS, Vault Transit), and the file-backed attestation/testing adapter.
  • Architecture § Boundary rules — adds a sixth row to the gate table: audit:domain-string-purity forbids domain-specific literals in packages/core/src/** across five pattern families. Pairs with the existing lint:harness-boundary row, which forbids domain imports — the new gate covers domain strings.
  • Core "What you get" — new bullet "Composes under an existing Enterprise contract" after the AuditableCall ledger bullet.

Changed

  • Family-lock page documents the host-internal planner carve-out. family-lock.mdx gains a "Host-internal planner calls" section. The lock governs seam calls — synthesize / converse / reasoning / utility on the provider seam — but a host's anchor-plan planner cold-start can run on a pinned host-configured model that never consults the (family x callClass) matrix, so it sits outside the lock by construction, not as a leak. The row is identifiable by stage: "anchor-plan", callClass: "utility", payload.kind: "planGeneration" and carries no fallbackStep / family-exhausted / providerCascade. Guidance: alert on any other non-locked-family row; allow this planner row.
  • The tool-loop decision call is utility-class on its own seam, not the synthesize seam (singleton-per-call-class, D-72). Five pages carried the prior claim that the synthesizer node and the tool-loop llmDecision node share one ProviderSeam<"synthesize"> identity (the old "D-35" statement). The tool-loop continuation decision — "call another tool or finish?" — now runs on a dedicated utility seam, so the synthesize cap is structural: the synthesizer (and the recovery path) are the only consumers of the synthesize seam, and the decision node can't reach the TurnSynthesizeCounter. Corrected in Seams (the singleton section + the LangGraph callout's ProviderSeam<"utility"> type), Graph, Graph node catalog (the llmDecision row's acceptsSeam converseutility, the Stage 2 intro, and the singleton-invariant wire-check), Call classes (the utility row + section now name the tool-loop decision as the canonical utility call), and Multi-synthesize. A reader on the old "shared seam" model would have mis-predicted which node bumps the synthesize counter.
  • Graph lattice docs synced to the current @pleach/core topology across eight pages. The NODE_STAGE_MAP registry is 43 names, not 48. ALLOWED_EDGE_PATTERNS carries nine rows and FORBIDDEN_EDGE_PATTERNS seven, not eight/eight — the tool-loop → post-turn recovery-dispatch edge moved from the forbidden table into the allowed table. Recovery shaping is no longer four synthesize-stage graph nodes (recovery, refusalHint, retryNarration, garbleRecovery) plus a recoveryDispatchPredicate derivation node and a shouldContinueWithGarbleRoute wrapper; it is four post-turn stream filters (refusalHintFilter 100, retryNarrationFilter 200, garbleRecoveryFilter 300, standardRecoveryFilter 400) dispatched via StreamObserverRegistry and locked by audit:recovery-dispatch-single-surface. synthesize is now a true singleton — only synthesizer. Touched Graph, Node catalog, Edge catalog, Nodes, Architecture, Ownership boundaries, Plugin contract, and Audit gates. Node catalog also gains a "How the substrate source is organized" section documenting the src/graph/ layout (nodes/ one-file-per-node, wiring/ registrars split by stage, the topology.ts lattice layer, concern-split seams/ / predicates/ / strategies/), with upstream-contributor steps pointing at the wiring/register<Stage>Nodes.ts registrar.
  • Config manifest foreign key corrected in Config manifest. The harness_event_log.manifest_hash reference is a real foreign key with ON DELETE SET NULL and a load-bearing DEFERRABLE INITIALLY DEFERRED clause, not gate-only as the page previously claimed. Added the reference_count column to the table DDL and cited the audit:config-manifest-fk-constraint-applied and audit:config-manifest-referential-integrity gates.
  • Schema description for @pleach/core amended to name the language-agnostic contract. The description field in the site's Organization + SoftwareApplication JSON-LD graph (inlined in <head> on every page) previously described @pleach/core only in TypeScript terms, contradicting both the marketing surface and the editorial position at /ai.txt. The description now names the wire shapes — HTTP+SSE, StreamEvent, AuditableCall, Checkpoint, version vector — as language-agnostic and clarifies that the npm package is the TypeScript reference distribution. programmingLanguage: ["TypeScript"] stays accurate — the npm package IS TypeScript; the language-agnosticism belongs to the contract, not the publishable artifact. See Language-agnostic contract for the full wire-shape inventory.
  • Cross-docs status-flip pass — rolling correction across ~55 docs pages tracking the alpha-ship of @pleach/compliance, @pleach/gateway, and @pleach/replay. Touched pages include Audit ledger, Event log, Subpath exports, Seams, Prompts, Prompt builder, and Session runtime.

Fixed

  • Family-lock lifetime claim corrected — the page stated "switching family means a new session." The runtime ships a sanctioned in-session re-lock path (sessions.updateProviderModel, emitting a session-lock-resynced event), so switching family is an explicit operation, not a new-session requirement. The lock's real invariant is no silent mid-turn widen, not lifetime immutability.
  • AuditableCall row AuditRecordVersion corrected 13 → 14 — both the literal description and the version-log range (v8 through v14) now match the upstream AUDIT_RECORD_VERSION_HISTORY, whose latest entry is to: 14 (Cluster C: additive rewriteStatus? + tokenCost.callClass).

2026-06-08 — chat-pipeline lift into @pleach/core

Foundational lift bringing OrchestratorClient and streamSingleTurn into the substrate. See the Unreleased section above for the Added/Changed entries. The Pre-Merge Gate audit:domain-string-purity landed alongside.

2026-06-08

Added

  • New page Runtime inspector documenting inspectRuntime() from @pleach/core/inspector — the typed read-only introspection surface, the InspectionReport / CapabilityReport / PluginReport / CapabilityDescriptor shapes, and the 38 known capabilities (29 modern + 9 deprecated).
  • definePleachPlugin() factory section in Plugin contract covering the 8-key PluginCapabilities cluster and the _raw escape hatch.
  • contributeFabricationGuard section documenting the typed FabricationGuardImpl hook (7 methods) that retires the orchestratorHotpath.fabricationGuard untyped-bag entry.
  • CreatePleachRuntimeConfig.host.{strategies, modules, raw} section in Host adapter with the 15-key HostExtensionBundle list and the host.modules list (eventLogWriter, store, interrupt).
  • C9 hash-chain probe section in Tamper-evident hash chain documenting [UXParity:c9-hash-chain-row-stamp] (PE-1) and [UXParity:c9-hash-chain-verify] (PE-2).
  • @pleach/core/inspector row in Subpath exports.

Changed

  • Packages table corrected to real published version — @pleach/core 1.1.0 (was largely stale "Reserved · placeholder" framing).

Fixed

  • Runtime inspector — replaced fictional RuntimeInspection / CapabilityState types with the real InspectionReport / CapabilityReport / PluginReport / CapabilityDescriptor. Corrected the status discriminator to "wired" | "deprecated-wired" | "unwired".
  • Plugin contractdefinePleachPlugin capability fields take values, not thunks. Corrected to the real 8 capability keys (prompts, runtimeAwarePrompts, safetyPolicies, fabricationDetectors, tools, streamObservers, intentToolMap, toolCouplingHints).
  • Host adapterhost.modules corrected to { eventLogWriter, store, interrupt }. host.strategies populated with the real 15-key HostExtensionBundle list.
  • Tamper-evident hash chain — subpath corrected from @pleach/core/event-log to @pleach/core/eventLog (camelCase is the real export).
  • Event-log projections — subpath corrected from @pleach/core/event-log/projections to @pleach/core/eventLog (projections export from the ./eventLog barrel; there is no /projections subpath).

On this page