@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 adds a governance-control-plane / AI-gateway category. Frames
@pleach/coreagainst governed-proxy control planes (Portkey, Cloudflare AI Gateway, and the enterprise control planes above them) as altitude, not timing: a proxy governs the call at the HTTP boundary; core governs the agent's execution graph and writes theAuditableCallrow to a database you own. Relatedly, Landscape row 1 now notes that proxy-advertised "tamper-evident audit trails" live on the vendor's side, not as a hash-chained row you own. -
Five more
@pleach/corepublic exports documented (720a6e8a3/de4403b6a). Interrupts addsrewriteToolArguments— the natural-language → structured-args rewrite for approval-with-edit flows; it runs on theutilitycall class and never throws, resolving to the original arguments on every fallback path. Tools adds the standalonecreateDiscoverToolsTool/DISCOVER_TOOLS_TOOL_NAMEfactory for hand-rolled servers. Server addscreatePluginToolRegistry— the getter-backed registry behind/toolsand/tools/:name. Storage addscomposeDurableStore(build aDurableStorefrom adapters you already hold) plus the optionalblobmember andcreateMemoryBlobStore/MemoryBlobStore. Adoption paths names theBrownfieldRuntimeMenuoptions type; Prompts names the optionalPromptDescriptor({ title?, summary? }) surfaced byruntime.prompts.describe(). Upstream trunk, not yet published to npm. -
New Pricing math page. Documents the
@pleach/core/pricingsubpath —computeTurnCost,DEFAULT_PRICING_MATRIX,createPricingResolver, the OpenRouter fetch, andresolveCostEventUsd. -
React lab component kit documented. The full
@pleach/core/react/labsurface — PleachLab's composable panels plususeLatticeState/useEventLogCapture/useChannelSnapshot— with@pleach/core/react/labnamed as the canonical subpath. -
Three prompt- and context-management capabilities documented. Orchestrator middleware adds the optional
summaryProviderfield onSummarizationConfig— a callback supplying a higher-quality (e.g. LLM-generated) rolling summary in place of the default extractive char-slice summary, falling back to the extractive default when it returns an empty value or throws. Prompt builder adds the "Cache-stable prefix" section: thestability: "stable" | "volatile"tag onBudgetedSectionand thestableBoundaryIndexfield onComposedPrompt—composeBudgetedPrompthoistsstablesections into a contiguous prefix (untagged input stays byte-identical) and reports where the volatile suffix begins, so a consumer places its providercache_controlbreakpoint afterincluded[stableBoundaryIndex - 1]. Prompts adds "Persisting an agent's role" — put durable persona in thecore.role-templateslot viareplaceCore/prependPersonaand tag itstability: "stable". Upstream trunk, not yet published to npm. -
condenseTools.intentPriorityMapgiven its real type. Tools replaces theintentPriorityMapplaceholder withRecord<string, readonly string[]>— an intent name mapped to the tool names that keep their full schema when that intent is active. Upstream trunk, not yet published to npm. -
condenseTools+ the discovery meta-tool documented. Tools gains thecreatePleachRouteoption that trims thetools[]array above a threshold — keepingmaxSchemaToolsfull schemas and surfacing the rest as one-line names — plus the discovery meta-tool (metaToolName) the model calls to pull a dropped schema back. Distinct from the prompt-directiveweakToolSchemaBudgetPluginon the same page. Upstream trunk, not yet published to npm. -
Model-pipeline surface documented — two new pages plus eight section additions. Model hooks documents the
@pleach/core/hookspre/post-model seam (PreModelHook,PostModelHook,ModelProfile+historyTrimmerHook,lazyModelDefaultsHook,toolCallValidatorHook,repetitionDetectorHook, wired viaruntime.model.registerPreHook/registerPostHook). Orchestrator middleware documents@pleach/core/middleware(OrchestratorMiddleware,MiddlewareStack,ResultEvictionMiddleware,SummarizationMiddleware,LanguageModelMiddleware,CHARS_PER_TOKEN, wired viasetOrchestratorMiddlewareInit). Both join Subpath exports under a new "Model pipeline" category with@pleach/core/synthesis(SynthesisEmitter,enrichOffloadedToolPreviews). Sections added:finalizeAnswer+ the{ banner }return onpostSynthesisGuard(Plugin authoring);ProviderCatalogContractand theSLOW_COLD_START_PLANNER_FAMILIES/isSlowColdStartPlannerFamilygate (Providers);InterruptManager.requestApprovalWithId(Interrupts);runtime.abort(reason)/AbortCoordinator+TURN_ABORT_REASON(Session runtime); the durablesubagent.tool_usedaudit row (Subagents); theharness_event_log_owner_selectper-user RLS policy +harness_event_log_service_rolewrite bypass (Multi-tenant); andMemoryStoreas theconfig.storeship-a-default. Existing published@pleach/coresurface; upstream trunk, not yet on npm. -
Four runtime-behavior sections documented. Each mechanism shipped upstream but had no doc home. Tools gains
weakToolSchemaBudgetPlugin(@pleach/core/prompts) pluscreateWeakToolSchemaPredicate(@pleach/core/modelfamily) — the proactive tool-call budget for weak-tool-schema families (google/deepseek/moonshot, defaultsmaxBatch: 4/maxSameTool: 2), gated onPromptContext.family. Turn lifecycle documents the no-first-token dead-air hard-cut (reduceTurnDeadAir; upstreamd062ab24d5). Providers documents the stalled-rung cascade pivot, classedSYSTEM_ABORTnotUSER_ABORT(upstreame1fa3f1487). Fabrication detection documentsmetadata.uncoveredPlanStepsand the honest "not dispatched" note (upstreambb0f995fce,ca9dc86644). All from published subpaths or documented runtime behavior; upstream tree8f224cbf42on trunk, not yet published to npm. -
Standalone hosted-agent route family —
createPleachRoutes,createPleachAgent,DurableStore,MemoryEventLog.@pleach/corenow mounts the whole route family from one factory, not just the single execute leg.createPleachRoutesand the three-armcreatePleachAgent({ context, tools, db })façade (both@pleach/core/quickstart) mount sessions CRUD, execute+SSE, interrupts, checkpoints, rollback, events-recall, sync, and fork;createPleachAgentreturns{ fetch, nextRoutes(), nodeHttp(), store }.DurableStore+createMemoryDurableStore()(@pleach/core/store) unify storage, checkpointer, event-write, event-read, and recall behind one binding, andMemoryEventLog(@pleach/core/query) is the keyless in-memory recall ledger with anasQueryClient()shim — so recall works with no Supabase whendbis omitted.createHarnessServer({ runtime, storage, checkpointer?, events? })is the build-only auto-bind factory over the still- unpublished@pleach/core/serversubpath. Known limitation: the default interrupt resolver binds a per-request in-processInterruptManager; a durable multi-request deployment supplies its own viacreatePleachRoutes(...).capabilities.interrupts. Landed across API routes, Server, Quickstart, Storage, and Query. Upstream: pleachtui Track A,@pleach/core@0.1.0on trunk (Waves0b34ab8742,095d037933,add6562a15,2b20c9c4be) — on trunk, not yet published to npm. -
Runtime strategies documents the
resolveCallReasoningEfforthook. A new per-callSessionRuntimeConfigstrategy slot. The runtime consults it before every provider stream with the resolved{ callClass, family, modelId }; the returnedReasoningEffort("low" | "medium" | "high","none"to disable the budget,undefinedto leave it untouched) threads ontoStreamChatOptions.reasoningEffortand the adapter lowers it to the provider request. Capability-gated — a model that doesn't advertise reasoning control ignores the field, so an unsupported model never 400s on the param.ReasoningEffortis opaque to core: the host owns the policy of which call class on which family to cap. Unset ⇒ no field attached, request byte-identical. Fail-soft — a throwing resolver is caught and treated asundefined. Added to the "Newer injection hooks" table plus a per-call cadence note. -
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/coreis 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 theAuditableCallrow writes.
Changed
-
Replay-determinism claims reconciled from "byte-identical" to "deterministic; divergence-detected." Determinism, Comparison, and Migrating from Anthropic Enterprise no longer claim a recorded turn re-generates a live model call byte-for-byte. Deterministic replay reproduces the recorded response, tool-call sequence, and terminal state, and names any drift with
ReplayDivergenceError; a replay re-serves the recorded response, it does not re-run the provider. "Byte-identical" is kept only where it holds by construction — fold-based state hydration and deterministic channel reducers. Corrects a load-bearing over-claim; the property is reproducible control flow + attributable divergence, not byte-equality. Adds the serial-execution caveat to the replay claim: replay determinism holds only under serial graph execution (one node per superstep). -
Reasoning-only recovery documented as default-on for the packaged surface. Providers already documented the opt-in
SessionRuntimereasoningRecoveryDI; it now records thatcreatePleachRoutedefaults it on (opt out withrecoverReasoningOnly: false), so a reasoning model that emits only chain-of-thought gets one same-model re-elicitation instead of a false family-exhausted. Interrupts gains a pointer from "Cross-request approval" to theinterruptResolveroption (createInMemorySharedInterruptResolver()/ a store-backedDurableInterruptResolver).
Fixed
-
Model-resolution matrix — Google's fast tier was stale. Model resolution matrix listed
gemini-3-flash-previewfor the Googleconverseandutilityrungs; the live matrix resolves both togemini-3.5-flash-lite. A reader who saw the old id would have keyed a fingerprint or cost estimate off a model that no longer fires. -
Off-policy example term scrubbed from Prompts. Two
gatedPromptexamples keyed on a"modal"tool; both now key on the neutral"sandbox"capability. Example-only — no API or claim change. -
@pleach/coredoc corrections from a ~200-commit upstream sweep. Graph node catalog: core registry corrected 44 → 43 — two domain plugin nodes were listed as core, and the core nodesyntheticExpansionDetectorwas missing. Config manifest: added a partial-coverage caveat (only the plugin surface is content-hashed today). Fabrication detection: documented the ~13-detector grounding/offloaded-data cohort the exports table omitted. Air-gapped deployment: corrected from "v2+ roadmap item" to the shipped fail-closedairGappedenforcement. Adoption paths:createBrownfieldRuntime(@pleach/core/runtime) is shipped, no longer "proposed." -
Four broken root imports corrected to their real subpath. Five code blocks imported a symbol from
@pleach/corethat the root barrel does not re-export (verified against the packageexportsmap):SupabaseAdapter/createSupabaseAdapter(Research agent) →@pleach/core/sessions;withTenantHeader(Multi-tenant SaaS agent) →@pleach/core/tenant;computeFingerprint(Testing) →@pleach/core/fingerprint;EventLogWriter(Event log and Recipes) →@pleach/core/eventLog. Each would fail to resolve on copy-paste; the subpaths are public per Subpath exports. -
Two orphaned pages wired into the sidebar — Install (Get Started) and Cycle-break contract packages (Reference) existed but were reachable only by direct URL.
-
Adoption paths "Host adapters" card corrected — it promised "implement OrchestratorAdapter / StorageAdapter", but Host adapter documents the
setHarnessModuleLoadermodule-loader seam. Reworded to match. -
Stale
AuditRecordVersionclaim corrected —18→19. CI enforcement stated the locked row shape was "currently 18"; upstream shipped the additive bump to 19. A version claim is load-bearing — a reader who saw "18" needs this row to know it moved. The package's published value is the source of truth; this tracks the shipped bump. -
Hash-chain verifier home corrected to
@pleach/core/eventLog. Audit ledger (two spots) and Recipes saidverifyChainForChat/generateProof"ship in@pleach/replay@0.1.0". They are defined in@pleach/core/eventLog;@pleach/replayconsumes them. Corrected across Audit ledger (two spots), Recipes, Which SKU, and Regulated-domain agent; now consistent with Hash chain. -
Error-code range corrected to
1xxx–11xxx. The authoritative band table in Error codes defines10xxx(caller-auth) and11xxx(runtime/infra). Stale1xxx–9xxx(frontmatter + Troubleshooting ×2) and1xxx–7xxx(Contributing, Stream events) summaries now match the table. -
maxConcurrentSubagentsclamp claim corrected. Research agent said amaxConcurrentSubagentsaboveSUBAGENT_LIMITS.maxConcurrentis clamped to it. They are separate limits on separate paths (default4caps theSubagentManager;3caps the imperative spawn path), neither clamped to the other — now consistent with Subagents. -
Unknown safety-policy ids now throw at construction — even with no plugins. Safety promises "Construction throws
UnknownSafetyPolicyErrorif 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-lesscreatePleachRuntime({ 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 (coreSessionRuntime.ts); theregister()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 anerror.coderow. 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 realAuditableCallQueryread is async positionalawait ledger.getSession(sessionId)(coreaudit/ProviderDecisionLedger.ts), and the "distinguishes three operating contracts" line corrected to five (theRuntimeModeunion — and the page's own table — lists five). OTel observability —executeMessageis positionalexecuteMessage(sessionId, "hello"), not the object formexecuteMessage({ sessionId, content })(coreSessionRuntime.ts). Stream events — the LangGraph"values"mapping usedruntime.sessions.get(), whichRuntimeSessionsFacet(corefacets/sessions.ts) does not expose; corrected toruntime.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 againstscripts/audit/. The agent-facing close of the self-extension loop. -
AuditRecordVersioncorrected14→18on 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 viacontributeEventTypes(audit:c8-union-member-has-produceraudit:c8-event-type-allowlist-coverage), scrubbers, plugin hooks (audit:plugin-contract-completeness), prompt blocks, and a custom audit field viapluginPayloads(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 viacontributeRuntimeAwarePrompts. Nodes, channels, and scrubbers gained a "What CI checks when you add one" footer linking into it.
-
createPleachRoute({ demo })keyless first-run + demo-firstpleach initscaffold 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 realAuditableCallrows, flaggedx-pleach-mode: demo. A resolved<PROVIDER>_API_KEYalways wins; demo never engages in a production build. The Next.js App Router scaffold adds an/auditview (app/audit/page.tsx+app/api/audit/route.ts) rendering the per-model-family rollup (family · rows · tokens · est. cost). The barecreatePleachRoute()no-key contract is unchanged (HTTP 503). -
engine/superstep scheduler named as an architecture piece +facets.mdxsynced to the shipped facet inventory (pkgclean 06 D7/D9). Architecture and Concept clusters now name theengine/scheduler (SuperstepRunner+ its primitives) as the deterministic superstep executor that runs the compiled graph. Facets gained the two shippedSessionRuntimeaccessors it omitted —runtime.observeandruntime.probes— plus the four per-stage graph introspection facetsgraph.anchor/graph.toolLoop/graph.synthesize/graph.postTurn. -
@pleach/core/skills+@pleach/core/agents/typesare real emitted subpaths. Skills updated to importSkillLoader,parseSkillFrontmatter,Skill, andSkillFrontmatterfrom the@pleach/core/skillsbarrel (the/loader,/parser,/typessub-subpaths do not exist); Agents prose corrected from "wildcard path" to a real emitted@pleach/core/agents/typessubpath.
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/registryResolvedToolsasstablepublic imports. Theinternal/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 —ToolDefinitionfrom@pleach/core/types/generic, and@pleach/core/tools/execution(which re-exports the resolved-tools registry functions). Nopackage.json:exportschange. -
core.mdxstale numbers corrected.auditRecordVersionupdated13 → 18(real value atAuditableCall.ts), and theHarnessPluginplugin-hook count updated~41 → 67contributeXhooks (derived by greppingpackages/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.toolArgsand returned{suspect, tier}; corrected to the realFabricationDetectorContextfields + theFabricationFindingshape ({detectorId, severity, reason, evidence?}), and thetier-routing bullet corrected (routing keys on the tool'ssafetyTier, not a finding'sseverity). Multi-tenant —getAggregateUsageis 3-positional ((client, store, filters)), has nogroupBy: "tenantId"value (session/agent/model/tool/day/week), nests dates underdateRange, and requiresuserId(it's single-user scoped; tenant rollups use the raw SQL). Determinism — the fingerprint round-trip read a non-existent.fingerprintaudit field (real:fingerprintComposite, a string) and compared a string to aFingerprintobject; corrected to a like-for-like comparison over a realFingerprintInput. These are the ctor-shape / call-arity / field-name classes the newaudit:doc-import-resolutiongate doesn't cover (import-resolution only). -
Event-log read side documented as store-agnostic —
eventReader/HarnessEventReader. Event-log projections saidruntime.events.iterate/.foldreadharness_event_logrows 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 aHarnessEventReaderinjected as the runtime'seventReader(the read-side counterpart toeventLogWriter), so the host casts its own store into the reader at construction and@pleach/coreitself stays free of backing-store knowledge — Postgres, Supabase, SQLite/pglite, or an HTTP API back the same surface.iterate's options gaintenantId; the reader is required to read the durable log (no built-in reader, no implicit store fallback — a bare runtime yields nothing, matching theMemoryAdapterpath) and throws a typed error at the call site when absent. New Backing the reader section shows the one-method contract yieldingEventLogRow(the shapereconstructSessionStateand the shipped projections fold). Session runtime config table gainseventLogWriter+eventReaderrows; Storage grows theci:devharness-sqlvalue-prop battery from four durable properties to nine — adding the@pleach/observepostgres()destination, time-travel fork, SQL-queryable audit ledger (harness_auditable_calls), tamper-evident hash chain, and@pleach/replaydeterministic 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/reactchat-hook API (useChat/HarnessProviderfrom the root,useInterruptDecision,useChatVercelCompat,sendMessage) — corrected to the real surface (useSessionRuntime/useSessionMessageStream/useInterruptUIfrom@pleach/react;useChat→submitfrom@pleach/core/quickstart;HarnessProviderfrom@pleach/react/legacy/@pleach/core/react;useVercelAISDKCompatfrom@pleach/react/adapters/vercel-ai-sdk). LangChain —LangChainProvidertakes a POSITIONAL model arg and wires via the top-levelprovider:slot (not{ model }/host.strategies.provider). Base tools — the scratchpad is per-SESSION (chatId-scoped, not per-turn), its param isoperation(notop), and its value is a string. Coding agent — the four sandbox tools register via acontributeToolsHarnessPlugininplugins:(SessionRuntimeConfighas notools/contextfield). A newpackages/core/test/docImportSurface.smoke.test.mjsregression-locks the import-path half. -
Observability + gateway-cost docs corrected to the shipped exporter/cost surface (devharness FINDING 73–75).
@pleach/coreships 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-suppliedOtelExporterbridge injected vianew SessionRuntime({ otelExporter })(default isNoopOtelExporter, which drops spans).runtime.spans.snapshot()returns{ inFlightCount, isShutdown }(exporter state) — to inspect emitted spans you wire aCapturingOtelExporterand read.captured(real fieldsstartTimeNs/endTimeNs/parentId). And Gateway cost events + the gateway OTel wiring:computeCostwas readingtenantId/family/callClass/byokActive/routingDecisionoffRouteChatCompletionOutput, which carries none of them (asTenantId(undefined)threw → zero CostEvents) — the example now reads only real output fields + host-supplied observation context, and flags thatrouteChatCompletionis 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 suppliessubagentExecutor/ drivesSubagentManager); the docs presented it as substrate-delivered. Corrected in Subagents: removed the fabricatedspawnsSubagent: trueauto-escalation flag;LightweightRuntime→ the realLightweightSessionRuntimeimported from@pleach/core/subagents(not root) with its real constructor;fetchWorkspaceContext/formatWorkspaceContextPromptmoved to the@pleach/core/subagentssubpath; the concurrency model corrected (the runtime spawn path caps on the hardSUBAGENT_LIMITSconstant and FAILS over-cap rather than queueing — theSubagentManagerqueue/DAG is host-driven);context.variablesnoted 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-treeSubagentTaskExecutoris 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 intoprovider-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 transientSession.hydratedHarnessStatefield — correcting the prior claim thathydrateFromEventsrebuilt messages/channel state. -
Model-resolution-matrix path corrected — it is host-supplied, not a
@pleach/coredir (pkgclean 06 D7). The docs cited the family-lock matrix at the fictionalsrc/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 theAgentAdapter.resolveModel<C>()seam; theProviderFamilyset is now pointed at the real@pleach/core/modelfamilyexport. The routing-decision seam's Ivy-internal host path was removed from routing decisions. -
Docs reconciled with the shipped
@pleach/coreruntime (value-prop-vs-impl audit, devharness FINDING 56–64). Corrected doc claims that diverged from the implementation:- Time travel —
forksetsparent_id: source.id(notnull). - Checkpointing — checkpoints write at message/event
boundaries (discriminated by
CheckpointMetadata.source), not stamped with a per-stagestageId;SupabaseSaverdurability is"replicated"; rollback writessource: "manual"+writes: ["rollback"]; theforksnippet takes a stringnewSessionId. - 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, thesync.conflictevent, the 3xxx code range) is enterprise-tier/planned; open-core usesSyncCoordinatorlast-writer-wins-on-push with a free-textlastError. - Query — dropped the non-existent
queryAuditableCalls; correctedgetChatUsage/lookupModelCost/getSessionReview/getInterruptChainsignatures + return shapes to the real@pleach/core/querysurface. - Memory — the production extraction path is the graph node
(
createMemoryExtractionNode), not thememoryExtractionHook→ queue pipeline;LearnedFact.sourceis 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 + abranched_fromfork edge, the other relations are host-recorded;completeSessionis host-called.
- Time travel —
Added
- Opt-in tool-event preview enrichment for the manifest projection. New
runtimeQuirks.enrichToolEventPreviewsForReplayflag (default OFF) lets the host write compactargs_preview(tool.started) +output_preview(tool.completed) onto tool events;chatManifestProjectionfolds them into richer manifestparams/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 thearguments_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/bulkUpdatenow carry the chat-manifest ledger AS-OF a checkpoint, for inspection (it does not feed the next generation — that runs throughrollbackToCheckpoint/resumeSessioninto the live provider). The snapshot rides the checkpointmetadata(round-tripped viaSupabaseSaver.metadata_extra; Memory/IndexedDB ride free), mirroring thependingTaskspattern. See Time travel. ProviderFamilyExhaustedErrorpromoted to the top-level@pleach/coresurface. The provider-family cascade terminal (raised when every in-family rung is exhausted) + itsisProviderFamilyExhaustedErrorguard are now public on@pleach/core— previously reachable only via the deep@pleach/core/graph/seams/providerExhaustionpath. Catch + narrow it from the top-level import.@pleach/core/cache— content-hash deriver.deriveContentHashKey,canonicalizeKeyInput, andContentHashKeyInputnow have their canonical home in@pleach/core/cache(relocated from@pleach/replay/cache, which re-exports them for back-compat). The move lets@pleach/corederive + stamp acacheKeyintotool.completed/turn.completedevents without the forbiddencore → replayimport. 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.saveSessionstamps the live snapshot into the persisted session state andresumeSessionrehydrates it (complementing the existing checkpoint rollback restore). NewchatManifestProjection/foldChatManifestfold the manifest deterministically from the event log (tool.*/job.*/model.upgraded), replayable viaruntime.events.foldand the@pleach/replaystepper — 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— optionalcacheKeypayload slot. Lets a deterministic replay consult the provider cache on the row (consumed by@pleach/replay'sReplayHandle). Host- /createCacheMiddleware-populated; core does not derive it (thecore → replayboundary forbids importingderiveContentHashKey). 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/coreevent-log gates (audit:auditable-call,audit:auditable-call-soak,audit:event-log-manifest-hash-completeness, the threeaudit: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-SKUconsumer-rehearsal). Cross-linked from Audit gates. - Contribution namespaces — new page
documenting the nine namespaces every
HarnessPlugincontribution 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.v1prefix,0x1Fseparator, mirroring the hash chain'spleach.c9.v1canonicalization). Per-surface child hashes, the nullablemanifest_hashforeign reference onharness_event_log, reference-counted retention (default forever), full-snapshot storage, and the canonical replay/audit query shapes. Markedin-flight— table and event-log column land as additive schema files during rollout. - What Pleach writes to your database —
new page mapping every
@pleach/coretable written to a buyer's database, what's default versus opt-in, and the destination-is-yours posture (no phone-home). manifest_hashcross-references added to Event log (stamping section +EventLogRowfield) and Schema (rolling-outharness_config_manifestsection).- 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.graphsnapshot 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-exportingTurnAccumulator,ToolDefinition,OrchestratorMessage, andProviderFallbackConfig. - Subpath exports — adds two rows
to the Runtime + composition table:
@pleach/core/runtime/orchestratorClientand@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),providerDetectionhelpers + constants — plus the benchmark-adjacentcreateBenchmarkPlugin. - Attestation — new top-level page on
the Ed25519-signed envelope substrate that sits on top of the
hash chain. Documents the
@pleach/core/attestationsubpath (signer, verifier, key-store interface), the two stub production adapters (AWS KMS, Vault Transit), and the file-backedattestation/testingadapter. - Architecture § Boundary rules —
adds a sixth row to the gate table:
audit:domain-string-purityforbids domain-specific literals inpackages/core/src/**across five pattern families. Pairs with the existinglint:harness-boundaryrow, 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.mdxgains a "Host-internal planner calls" section. The lock governs seam calls —synthesize/converse/reasoning/utilityon the provider seam — but a host'sanchor-planplanner 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 bystage: "anchor-plan",callClass: "utility",payload.kind: "planGeneration"and carries nofallbackStep/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-loopllmDecisionnode share oneProviderSeam<"synthesize">identity (the old "D-35" statement). The tool-loop continuation decision — "call another tool or finish?" — now runs on a dedicatedutilityseam, 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 theTurnSynthesizeCounter. Corrected in Seams (the singleton section + the LangGraph callout'sProviderSeam<"utility">type), Graph, Graph node catalog (thellmDecisionrow'sacceptsSeamconverse→utility, the Stage 2 intro, and the singleton-invariant wire-check), Call classes (theutilityrow + 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/coretopology across eight pages. TheNODE_STAGE_MAPregistry is 43 names, not 48.ALLOWED_EDGE_PATTERNScarries nine rows andFORBIDDEN_EDGE_PATTERNSseven, not eight/eight — thetool-loop → post-turnrecovery-dispatch edge moved from the forbidden table into the allowed table. Recovery shaping is no longer foursynthesize-stage graph nodes (recovery,refusalHint,retryNarration,garbleRecovery) plus arecoveryDispatchPredicatederivation node and ashouldContinueWithGarbleRoutewrapper; it is four post-turn stream filters (refusalHintFilter100,retryNarrationFilter200,garbleRecoveryFilter300,standardRecoveryFilter400) dispatched viaStreamObserverRegistryand locked byaudit:recovery-dispatch-single-surface.synthesizeis now a true singleton — onlysynthesizer. 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 thesrc/graph/layout (nodes/one-file-per-node,wiring/registrars split by stage, thetopology.tslattice layer, concern-splitseams//predicates//strategies/), with upstream-contributor steps pointing at thewiring/register<Stage>Nodes.tsregistrar. - Config manifest foreign key corrected in
Config manifest. The
harness_event_log.manifest_hashreference is a real foreign key withON DELETE SET NULLand a load-bearingDEFERRABLE INITIALLY DEFERREDclause, not gate-only as the page previously claimed. Added thereference_countcolumn to the table DDL and cited theaudit:config-manifest-fk-constraint-appliedandaudit:config-manifest-referential-integritygates. - Schema description for
@pleach/coreamended to name the language-agnostic contract. Thedescriptionfield in the site's Organization + SoftwareApplication JSON-LD graph (inlined in<head>on every page) previously described@pleach/coreonly 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 asession-lock-resyncedevent), 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
AuditRecordVersioncorrected 13 → 14 — both the literal description and the version-log range (v8 through v14) now match the upstreamAUDIT_RECORD_VERSION_HISTORY, whose latest entry isto: 14(Cluster C: additiverewriteStatus?+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, theInspectionReport/CapabilityReport/PluginReport/CapabilityDescriptorshapes, and the 38 known capabilities (29 modern + 9 deprecated). definePleachPlugin()factory section in Plugin contract covering the 8-keyPluginCapabilitiescluster and the_rawescape hatch.contributeFabricationGuardsection documenting the typedFabricationGuardImplhook (7 methods) that retires theorchestratorHotpath.fabricationGuarduntyped-bag entry.CreatePleachRuntimeConfig.host.{strategies, modules, raw}section in Host adapter with the 15-keyHostExtensionBundlelist and thehost.moduleslist (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/inspectorrow 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/CapabilityStatetypes with the realInspectionReport/CapabilityReport/PluginReport/CapabilityDescriptor. Corrected thestatusdiscriminator to"wired" | "deprecated-wired" | "unwired". - Plugin contract —
definePleachPlugincapability fields take values, not thunks. Corrected to the real 8 capability keys (prompts,runtimeAwarePrompts,safetyPolicies,fabricationDetectors,tools,streamObservers,intentToolMap,toolCouplingHints). - Host adapter —
host.modulescorrected to{ eventLogWriter, store, interrupt }.host.strategiespopulated with the real 15-keyHostExtensionBundlelist. - Tamper-evident hash chain — subpath corrected
from
@pleach/core/event-logto@pleach/core/eventLog(camelCase is the real export). - Event-log projections — subpath
corrected from
@pleach/core/event-log/projectionsto@pleach/core/eventLog(projections export from the./eventLogbarrel; there is no/projectionssubpath).
@pleach/compliance changelog
Release history for @pleach/compliance — site-docs entries that materially touched the @pleach/compliance surface, newest-first. Canonical runtime history lives upstream.
@pleach/eval changelog
Release history for @pleach/eval — site-docs entries that materially touched the @pleach/eval surface, newest-first. Canonical runtime history lives upstream.