pleach
Reference

Changelog — combined view (legacy)

Site-content changes for getpleach.com, newest-first, unified view across every SKU. Per-SKU pages live one directory level up at /docs/changelog/<sku>.

This is the combined view — the original chronological, multi-SKU site-content changelog for getpleach.com. It records changes to the site itself: new docs pages, corrections, and the upstream packs each change reflects. It is not the runtime changelog; the per-package CHANGELOG.md files in the upstream @pleach/* repository hold the canonical record of runtime behavior.

For a SKU-scoped view, see the per-SKU pages under /docs/changelog — each one excerpts the entries below that materially touched its docs surface.

The mirror copy at /CHANGELOG.md is the source of truth in the repo. Both files update together, not separately. When a site change tracks an upstream pack, the entry cites the upstream commit so the linkage is auditable.

Format follows Keep a Changelog.

Unreleased

Added

  • Mermaid flowcharts now render as diagrams. Twelve mermaid fenced blocks across seven pages — including the Overview "mental model", Architecture, Turn lifecycle, Determinism, Family lock, Config manifest, and Replay — were authored as Mermaid but had no renderer, so each showed as bare text. The site now renders them as theme-aware diagrams via the fumadocs Mermaid integration. Mermaid is loaded only on pages that carry a diagram.

Changed

  • Two hand-drawn ASCII diagrams converted to Mermaid. The build pipeline on Supply-chain risk & SBOM and the reference architecture on Air-gapped architecture were box-drawing text; both now render as Mermaid diagrams. Node text is preserved verbatim — no claim change.

Fixed

  • Two family-cascade diagrams used an invalid Mermaid arrow. The "no crossover to the other family" edge on Architecture and Family lock was written with an unparseable -.x link; corrected to -.-x (dotted line, cross head). The diagrams rendered as bare text before the Mermaid renderer landed, so the break was never visible. All Mermaid blocks on the site now parse.

Added

  • Comparison gains a category for agent-memory & knowledge-graph substrates (a read-side category). Generalizes the event-sourced-memory-graph shape — memory layers and knowledge-graph engines (Letta, Mem0, Zep) whose reader is the agent itself, not a human dashboard. The section pins the read-vs-write delineation: a memory substrate is 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). Framed as compose-not-compete — a memory graph reads the same session the AuditableCall row writes. Distinguishes this read-side from the observability read-side (reads for a human dashboard).

  • Homepage rebuilt as six diagram-paired blocks in a side-by-side layout. Every block — hero, "What you can do", "Should you stay", "Already paying the lab", "How it works", and "Quick answers" — now pairs left-aligned copy with one SQL-grounded diagram: a full AuditableCall record (SELECT *), the per-tenant GROUP BY rollup, a shape → tool decision flow, the contract-composes-underneath stack, the four-stage lattice, and a new append-only session_manifest event log with a fork-point checkpoint. Diagrams animate via CSS only, gated on prefers-reduced-motion, with gentle continuous pulsing on the load-bearing fields. Content width moved to ~75vw; the footer aligns to the same width.

  • Homepage gains a seventh block — "Keep your stack", the brownfield @pleach/observe path. A new top-level section between "Should you stay where you are?" and "Already paying the lab": a buyer already shipping on the Vercel AI SDK, LangChain, or a hand-rolled loop adds the audit row in ~15 lines, no rewrite. Its diagram (components/observe-brownfield-diagram.tsx) shows the existing loop on top, the init + per-turn recorder + destination-plug hook in the middle, and a fan-out to the four destinations you pick — postgres(), supabase(), otel(), memory() — over the BYOK code shape. Cross-links @pleach/observe, adoption paths, and BYOK observability. The ObserveRow-is-a-strict-subset-of-AuditableCall runway claim is the figure caption.

  • /investors — public-safe positioning page, footer-linked. A new top-level page states the fair-source thesis without numbers: the runtime is free and trust-protected, the hosted operational layer is the business, and the FSL conversion clock makes the openness contractual rather than revocable. Investment specifics route to getpleach@protonmail.com rather than living on the page. Linked from the footer only, between Pricing and Security — not in the top nav.

  • 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 — previously determinism/scheduling was attributed only to "the graph". Facets gained the two shipped SessionRuntime accessors it omitted — runtime.observe (record(row)) and runtime.probes (emit / typed typed<K>) — plus the four per-stage graph introspection facets graph.anchor / graph.toolLoop / graph.synthesize / graph.postTurn.

  • @pleach/gateway/next documented as shipped (createGatewayRoute). Gateway → migration from core flipped from "roadmap / NOT shipped today" to shipped. The factory is a Web-standard (req) => Response POST handler wrapping GatewayClient; docs now carry the real opts shape (client | clientOptions + tenantId, optional transports / resolveRoute) and the { family, callClass, model, prompt, byokKey? } request body. The never-shipped { runtime, credentialStore, costEmitter } params were removed.

  • @pleach/coding-agent/context documented as shipped (createLruContextStrategy, createImportanceContextStrategy). Coding-agent → long session flipped from "(roadmap)" to shipped for the two pure ContextStrategy eviction factories. The fictional importance options (recencyWeight/frequencyWeight) were corrected to { maxEntries }, the additive ContextEntry.accessCount field documented, and the runtime-side CodingContextManager kept honestly labeled as roadmap.

  • @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 (no /loader, /parser, /types sub-subpaths); 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 present @pleach/core/internal/strategies/streamSingleTurn/helpers (+ its four direct helper entries) or @pleach/core/internal/tools/execution/registryResolvedTools as stable, installable public imports — the internal/ segment marks implementation details, not a supported API. The removed copy-paste example that imported the streamSingleTurn helper barrel is replaced; the internal paths now live in a "Not a public import surface" section with their public alternatives: ToolDefinition from @pleach/core/types/generic, and @pleach/core/tools/execution for the resolved-tools registry functions. No package.json:exports change.

  • Homepage section order resequenced to a how-then-whether-then-where arc. "How it works" moves up ahead of "Should you stay where you are?" so the reader learns the structure before the qualification, and the new "Keep your stack" block lands between "Should you stay" and "Already paying the lab". Final order: hero → What you can do → How it works → Should you stay → Keep your stack → Already paying the lab → Quick answers. No copy on the moved blocks changed.

  • /pricing FSL-conversion explainer deduplicated to one canonical statement. The "fair source = source-available with delayed Apache-2.0 conversion" definition appeared four times (hero, License table row, "What FSL-1.1-Apache-2.0 lets you do" opener, "For procurement & legal"). It now reads once, canonically, in the hero; the table's License row keeps its tabular one-liner. No load-bearing claim changed — the pleach.fslConversionDate package.json pointer, the LICENSE link, and the permission rows are intact.

Fixed

  • Doc-fence drift campaign — 129 findings surfaced by the fixed audit:doc-snippet-typecheck gate; all doc TypeScript fences now compile against the shipped @pleach/* APIs. The gate now resolves @pleach/* against source (not a build-state-dependent dist/) and excludes syntax-broken fences that had been suppressing program-wide semantic analysis — the honest run exposed 129 usage-drift snippets. Corrections span: SessionRuntimeConfig capabilities → plugins — the invented flat safety:, systemPrompt:, routing:, context:, callClassFamilies:, transport:, and region: fields on new SessionRuntime({...}) removed; safety policies + system prompts now flow through definePleachPlugin(name, { safetyPolicies, prompts }), permittedFamilies / permittedRegions hoisted to their real top-level ReadonlySet config fields, userId / organizationId / tenantId hoisted out of the fictional context wrapper, and per-call-class family pinning reframed as the model-family matrix (family × callClass) rather than a session field (customer-support-agent, internal-knowledge-agent, regulated-domain-agent, region-pinned-agent, cloud-routed-agent); OrchestratorRegistry shapelangchain's setOrchestratorRegistry({ tools }) rewritten to the ergonomic definePleachPlugin contributeTools path; WithTenantHeaderOptionswithTenantHeader(fetch, { runtime, header }) corrected to { header, tenantId } (multi-tenant); plus earlier waves: AuditableCall nested payload paths, VersionHistoryEntry fields, ReplayTurnOutput / ReplayTurnInput / replay RuntimeConfig shapes, and VerifyResult narrowing.

  • Contract / plugin / audit-page accuracy sweep (F260–F331) — 31 doc/impl divergences corrected against packages/core + packages/compliance. event-log-projections: real folded event types restored per projection (configProjectionsession.created; messageProjectionmessage.user / message.assistant / content.delta; toolCallProjectiontool.started / tool.completed / tool.failed; jobProjection states → pending | completed | failed | timeout); the fabricated sessionStateProjection export replaced with the real reconstructSessionState function; built-in count "six" → nine + composite; events.iterate / fold options corrected to { chatId?, fromSequenceNumber?, tenantId? }; HarnessEventReaderHarnessEventLogReader; the fabricated pre-filter selector replaced with the real post-fold finalize. audit-ledger: TamperEvidencelink / verifySequence / schemeId (sync); PIIRedactorredact(record): AuditableCall + policyId; GDPRSoftDelete → single softDelete(...); AuditEmitter 5 → 10 methods. scrubbers: scrubbers do not declare event-type allowlists (global SCRUBBABLE_FIELDS); ScrubResult{ redacted, matchCount, matchedScrubberIds }; the three bundled scrubbers independently implements Scrubber; opt-out via [] / SCRUB_NONE_AUDITED. plugin-contract / authoring / stream-observers / plugin-authoring-standards: retired onSessionCreated / onToolCompleted / onMessageAdded removed (→ runtime.events); hook tally 65+5 → 67 contributeX + 7 top-level; not-contributed collectors 5 → 11; stream-observer verdict haltstop; definePromptPlugindefinePromptsPlugin. hash-chain: prev_hash is the prior row_hash copied verbatim; created_atsequence_number in the canonical field order. attestation: deleted the fabricated pleach.unsigned.v1 short-circuit paragraph. audit-gates: NODE_STAGE_MAP 43 → 44. tenant-facet: withTenantHeader({ header, tenantId }) (raw string at wrap time, header required with no default).

  • Reference-page accuracy sweep (F226–F295) — 34 doc/impl divergences corrected against packages/core. Error codes re-derived from src/errors/codes.ts (1002 TOOL_VALIDATION_FAILED, 1003 TOOL_EXECUTION_FAILED, 1004 TOOL_TIMEOUT, 2002 SESSION_CONFLICT, 2003 SESSION_EXPIRED, 2004 SESSION_LOCKED, 3001 SYNC_NETWORK_ERROR, 4003 STORAGE_QUOTA_EXCEEDED, 5001–5005 provider codes, 6002/6003 checkpoint codes); the fabricated "safety-refusal on code 5004" example rewritten to model-not-found (no safety-refusal code exists in the enum). Graph node catalog 43 → 44 nodes (added the answerSufficiency post-turn judge; post-turn 6 → 7) with corrected source-org file counts. Edge catalog: "three conditional routers" → two (shouldContinue + afterHallucination); recovery dispatch is a stream-filter collection, not a router. Model matrix + env-vars: mistral marked unrouted (excluded from EXPOSED_FAMILIES), GOOGLE_GENERATIVE_AI_API_KEY added as the primary Google var, and FEATURE_HARNESS_V2_RUNTIME / FEATURE_TOOL_CALL_RUNAWAY_HARD_BLOCK moved to a host-read section (core reads no FEATURE_*). Auditable-call row + typed records: version 18 → 19 (outcome.why); the fabricated payload.kind discriminated-union framing replaced with the real named optional slots narrowed on stageId (no payload.identity / payload.output.auditNote; principal is top-level; pluginPayloads[] is the extension slot); interrupt outcomes corrected to verdict: approved | edited | rejected | timeout. Glossary tenant facet fixed to the runtime.tenant.id / .subId properties (no getTenantId() methods). Subpath exports: SectionContributorPromptContribution; capability list 38 → 35 (31 modern + 4 deprecated). Schema: 10 → 12 SQL files (added 000_supabase_compat.sql + 011_spawn_event_fields.sql) and the config manifest renumbered to 012_harness_config_manifest.sql. Removed the fabricated config_manifest_retention_days identifier.

  • Fictional @pleach/* identifiers in .mdx snippets corrected — surfaced by the audit:doc-import-resolution TS2724 pass. The React interrupt hook was documented as useInterrupt with a { pending, resolve, ignore } return and a resolve({ type, args }) HumanResponse-shaped payload — none of which exist. The real hook is useInterruptUI(config) (handler-driven: { activeInterrupts, renderActive, resolveInterrupt, cancelInterrupt }); it surfaces a PendingInterrupt (interrupt.toolCall.name / .arguments, not action_request / config.allow_* / description — those live on the separate HumanInterrupt envelope), and decisions are an ApprovalDecision ({ approved, note?, modifiedArguments? }). Rewrote both usages: interrupts now shows the useInterruptUI handler pattern, and platform recipes uses the imperative runtime.interrupts.resolve(id, decision) loop. Grouped with two other identifier corrections from the same TS2724 pass: the plugin-bundles page's definePromptsPlugin rename (was a fictional factory name), and the query page's tool-inspection + cross-session analytics signature fixes.

  • Behavioral / semantic prose drift corrected across the conceptual and recipe pages (findings 150–225), each verified against shipped @pleach/* source. Recipes: observableChatbot({ serviceName }) takes no subagent field — the row label is observeSubagent(serviceName), and the disable switch is serviceName: false (Pleach recipes); a second init(...) on @pleach/observe throws (singleton-per-process), it does not warn-and-return; and destination errors — sync throws and async rejections alike — are swallowed by default, surfacing them is opt-in via init({ throwOnDestinationError: true }) (BYOK observability, observable chatbot). Facets: graph.synthesize.getSeamIdentity() always returns undefined today; the sync.resolveConflict receipt has no conflictedPaths; runtime.interrupts exposes a manager property (not getInterruptManager) and runtime.timeTravel an api property (not getTimeTravelApi()) (facets). Graph / nodes: the compiled graph ships 44 node names / 7 post-turn nodes (adding answerSufficiency, D-NC-6), and a metadata-less node subscribes to every channel rather than inferring reads/writes from its body (graph, nodes). The reasoning seam is reserved/planned — the default runtime has no live consumer routing through it (seams). Interrupts: removed fabricated surfaces (plugin ctx.raiseInterrupt / ctx.tokenUsage, ApprovalDecisionKind with reason/riskLevel, and runtime.getInterruptScratchpad); InterruptConfig enables via interruptBefore / interruptAfter / interruptOn (not enabled/perToolApproval/globalApprovalThreshold); and resolving an interrupt consumes an ApprovalDecision — an approval-with-edit is { approved: true, modifiedArguments }, so an { type: "edit", args } payload leaves approved === undefined and reads as a rejection (interrupts). Query: usage rollups read ai_chat_messages (not harness_auditable_calls); getSessionReview throws QueryError("NOT_FOUND") so the never-throws guarantee is scoped, and the three codes are NOT_FOUND / DB_ERROR / INVALID_INPUT; queryHarnessEvents orders by created_at, cursors on a base64 created_at|id compound, and returns { events, nextCursor, count }; getEnrichedSessionReview gates on includeCitations / includeEntities / includeUsage; and the chat-keyed readers take a chatId, not a sessionId (a session id silently returns []) (query). Subagent provenance is delegated_from, not used_result_of (lineage). Host adapter / runtime: the module-loader probe sample uses an early-resolved key rather than the post-stream streamDegenerationGuards; metaToolNames is probed lazily on first read and setOrchestratorAdapter is a deprecated delegating stub; module loaders re-invoke every call (dedup is the process-wide import() cache, not per-runtime) (host adapter); HARNESS_MOCK_MODE is read only by the host-side MockToolExecutor (it synthesizes tool results; it does not classify seams or write AuditableCall/ledger rows — the default ledger is the no-op) (runtime construction); an absent providerFallback loader throws MODULE_NOT_FOUND rather than falling through a built-in chain (runtime strategies); and a custom streamSingleTurn body registers through the global module-loader seam, not a SessionRuntimeConfig strategy slot (stream single turn).

  • Method / field / type prose drift corrected across the migration and comparison pages (findings F107–F140). Usage-shape corrections (not import paths), each verified against the shipped @pleach/* source: ProviderFamily now lists all seven families including xai; provider-detection prose reframed to "six of the seven families (xai has no standalone env-var detection) plus openrouter"; the @pleach/transport-bedrock credentials note corrected to "static AWS keys or an STS session token today; container/role-assumption resolution is planned" (the BedrockCredentials shape requires accessKeyId + secretAccessKey). Method/field fixes: useHarness() returns isLoading, not isStreaming; the AgentProvider seam method is execute, not invokeStream; tool.started is a StreamEvent on the executeMessage() iterable, not a runtime.on(...) emitter event; session read is runtime.sessions.find(id) (returns Session | null) then session.state.messages, not runtime.getSession(id).messages; AuditableCall nests call.call.model + call.outcome.latencyMs; the ad-hoc runtime.audit.recordCall(meta, fn) wrapper rewritten to the shipped runtime.observe.record(row); the family + transport lock is applied at runtime.sessions.create({ provider, model }) (runtime.providerLock does not exist); @pleach/eval usage is new EvalSuite({ ... }).run(), not runEval({ suite, target }); the checkpoint rollback surface is runtime.checkpoints.rollback(sessionId, checkpointId) / .list() (not checkpointer.snapshot() / restore() or restoreCheckpoint(...)); the fabricated SubagentSpawnRecord type replaced with the real primitives (SpawnTreeState / parentTurnId / rootTurnCostCap, and the AuditableCall row's parent turnId where the claim is about a stored, GROUP BY-queryable rollup); and hash-chain verification (verifyChainForChat / generateProof) re-attributed to @pleach/core/eventLog, which @pleach/replay composes.

  • @pleach/* doc import paths corrected across 26 concept pages, surfaced by the now-fixed audit:doc-import-resolution gate. The gate had been resolving @pleach/* doc imports against dist/ — build-state-dependent, so an absent .d.ts silently typed the module as any and false-greened real drift. It now resolves against package source via tsc, which exposed 59 imports naming a symbol on a path where it does not ship. Most were root-vs-subpath drift, now pointed at the barrel that actually re-exports each symbol: StateGraphNodeMetadata / START / DefaultAgentState / buildDefaultAgentGraph / DEFAULT_TURN_FLAGS / AnnotationSchema / InferAnnotationState@pleach/core/graph; CallClass / ProviderFamily@pleach/core/modelfamily; ProviderMessage / ProviderToolDef (and the sibling provider types) → @pleach/core/providers; FabricationDetector / FabricationDetectorContext / FabricationFinding / SanitizerPass / FinalizationPassContext / PluginGraphNodeRegistration / PluginGraphNodeContext / composePlugin@pleach/core/plugins; StreamObserverRegistration@pleach/core/plugins/stream; Scrubber@pleach/core/scrubbers; EventLogRow@pleach/core/eventLog; MemoryProviderDecisionLedger@pleach/core/audit; the guest-interrupt bus helpers (setGuestInterruptStore / publishInterruptRequest / popInterruptRequest / recordInterruptDecision / waitForInterruptDecision) → @pleach/core/guestInterruptBus; ToolDefinition@pleach/core/types/generic; ConnectivityMonitor@pleach/core/sync; and the BYOK gateway helpers (createCredentialRoutingMiddleware@pleach/gateway root, createPostgresCredentialStore@pleach/gateway/byok/adapters/postgres). Four snippets imported symbols that ship nowhere and were rewritten to the real API: @pleach/observe's startTurn() / turn.recordCall() → the shipped init + top-level recordCall(row) surface; the fabricated appRegistries.setProviderDecisionLedgerFactory(...) object → the free setProviderDecisionLedgerFactory({ fromSupabase }) accessor from @pleach/core/runtime; durableFlush.register(...)setWaitUntilImpl(...) from @pleach/core/eventLog; and pickNextInFamily / deriveFamilyFromModelId (host-supplied — the harness ships no model registry) reframed as host functions handed in through the contributeFamilyPivot plugin hook. The registerIntentLabel() roadmap page now imports only the shipped definePleachPlugin and declares the proposed helper.

  • mcp / sandbox / coding-agent / replay doc pages reconciled with the shipped surface (devharness FINDING 94–103). MCP: registerSession(sessionId, runtime, { tenantId? }) is a live in-memory session registry (plus getSession / listSessions / unregisterSession) — no longer a NotImplementedError("D-PA-184") throw; resources/* and prompts/* are dispatched live on the MCPServer wire (both the SDK setRequestHandler path and the pluggable dispatchPluggableMethod); the pluggable dispatcher implements the initialize handshake (not -32601 Method not found); McpRuntime.registerCapability lands resource / prompt kinds in the last-wins ledger without throwing; the createSSETransport().start() factory throws a generic Error (the typed NotImplementedError("D-PA-181") is the options-bag server.start({ transport: "sse" }) path). Coding agent: the @pleach/sandbox peer-dep is ^0.1.0 (was ^1.0.0). Sandbox: there is no ctx.sandbox — the low-level SandboxProvider contract is execute / readFile / writeFile / listFiles, and @pleach/coding-agent exposes a thin SandboxClient facade (exec / readFile / writeFile, no list) the tool handlers close over. Region-pinned agent: createReplayRuntime takes sessionRuntime (not liveRuntime); replayTurn input is { chatId, tenantId, messageId } (not { turnId, mode }) and returns { chatId, tenantId, messageId, state, sequenceNumberRange } — there is no .diff field (the hash-chain verifyIntegrity verdict covers tamper-evidence, not parity).

  • observe / eval / replay / core concept-page snippets reconciled with the shipped signatures (devharness FINDING 83–93). Observe: getRecorder() returns ObserveRecorder and throws pre-init (never undefined); a second init throws (singleton-per-process); a throwing redactor is fail-closed (swallow + warn [Observe:redactor-threw] + drop the row, never write raw); the OTel envelope is span `<family>.<callClass>` + gen_ai.* / pleach.observe.* attrs (not pleach.audit.call); BUILT_IN_MATCHERS = email + phone + SSN (no credit card). Eval: cross-mode buckets are interactive/headless-eval/headless-replay (not production/replay/eval-noncached). Replay: eval-coupling is new EvalSuite({ suiteId, runtime }) + suite.setReplayClient(replay) (no replay ctor field; suiteId required). Determinism: ledger read is await ledger.getSession(sessionId) (not ledger.list({ sessionId })), and runtimeMode distinguishes five contracts (not three). OTel observability: executeMessage(sessionId, "hello") is positional. Stream events: re-read via runtime.sessions.resume(sessionId) (there is no sessions.get()).

  • More SKU doc-page snippets reconciled with the shipped signatures (devharness FINDING 80–82). Fabrication detection custom-detector example (no ctx.toolArgs; real FabricationFinding = {detectorId, severity, reason, evidence?}, no suspect/tier); Multi-tenant getAggregateUsage is 3-positional (client, store, filters), no groupBy:"tenantId", dates under dateRange, requires userId; Determinism fingerprint round-trip reads fingerprintComposite (string), not .fingerprint. The ctor-shape/call-arity/ field-name classes the audit:doc-import-resolution gate doesn't cover.

  • Event-log read side documented as store-agnostic — eventReader / HarnessEventReader. Event-log projections claimed runtime.events.iterate / .fold read harness_event_log rows and went live "on the Supabase backend in PA-1 Phase A.2" — store-specific language corrected to the shipped surface: both accessors delegate to a HarnessEventReader you inject as eventReader (read-side counterpart to eventLogWriter), backing the same iterate/fold/resume surface with Postgres, Supabase, SQLite/pglite, or an HTTP API. iterate gains tenantId; the reader is required (no implicit store fallback). New Backing the reader section shows the one-method contract. Session runtime config table gains eventLogWriter + eventReader; Storage grows the ci:devharness-sql battery from four durable properties to nine.

  • SKU doc pages reconciled with the shipped import/construction surface (devharness FINDING 76–79). Building a chat UI fabricated a @pleach/react chat-hook API (useChat/HarnessProvider from root, useInterruptDecision, useChatVercelCompat, sendMessage) → corrected to the real surface. LangChain: LangChainProvider positional ctor + top-level provider: slot. Base tools: scratchpad is per-session, param operation, string value. Coding agent: sandbox tools register via a contributeTools plugin (no tools/context config field). Import-path half regression-locked by docImportSurface.smoke.test.mjs.

  • Observability + gateway-cost docs corrected to the shipped surface (devharness FINDING 73–75). @pleach/core ships no @opentelemetry/* dep + never reads the global tracer provider — the NodeSDK/OTLP recipe captured zero pleach spans; OTel observability + Observability now show the real new SessionRuntime({ otelExporter }) bridge path (default NoopOtelExporter drops spans), and runtime.spans.snapshot() returns {inFlightCount,isShutdown} (use CapturingOtelExporter.captured for emitted spans). Gateway cost events: computeCost read fields absent from RouteChatCompletionOutput (asTenantId(undefined) threw → zero CostEvents) — corrected to real output fields + host context, with a slice-2-stub note.

  • 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 docs over-promised a substrate-delivered one. Subagents: dropped the fabricated spawnsSubagent flag; LightweightRuntimeLightweightSessionRuntime from @pleach/core/subagents with its real ctor; fetchWorkspaceContext/formatWorkspaceContextPrompt moved to the subpath; concurrency corrected (hard SUBAGENT_LIMITS cap, fail-not-queue on the runtime path; SubagentManager queue/DAG is host-driven); context.variables inert; host-completion caveat added. Async tasks: the tool-loop async bridge is not wired in bare core (ASYNC_TASK_BRIDGE_NOT_WIRED), and the task executors are host/plugin-supplied, not "in-tree defaults".

  • Abort + resume docs synced to the shipped runtime behavior (devharness FINDING 56 + 62). Aborting a turn now records outcome.status: "user-aborted" (not "aborted" / not provider-error) at both the decision call and the synthesis terminal — corrected across session lifecycle, SessionRuntime, turn lifecycle, API routes. And resuming a session now describes the real three-layer rebuild (storage row → version-guarded checkpoint overlay → server-only event-log hydration of ephemeral card state onto a transient Session.hydratedHarnessState), correcting the prior "hydrateFromEvents rebuilds messages" claim.

  • 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 (there is no ai/ or graph/modelfamily/ dir). 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 also 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 across Time travel (fork sets parent_id: source.id), Checkpointing (message/event-boundary checkpoints discriminated by CheckpointMetadata.source, no per-stage stageId; SupabaseSaver "replicated"; rollback source: "manual"; string fork arg), Session lifecycle (checkpoint snapshot authoritative; event-log canonical reader is a flag-gated shadow), Sync (interactive conflict resolution / sync.conflict / 3xxx codes are enterprise-tier/planned; open-core is SyncCoordinator last-writer-wins-on-push), Query (dropped non-existent queryAuditableCalls; fixed getChatUsage / lookupModelCost / getSessionReview / getInterruptChain sigs+shapes), Memory (graph-node extraction path is production, not the memoryExtractionHook → queue pipeline; LearnedFact.source string+object), and Lineage (opt-in via config.lineageTracker; runtime records the node + branched_from fork edge, other relations host-recorded; completeSession host-called).

Added

  • Landscape — new page. Twenty agent-runtime capabilities ranked by how differentiated @pleach/core actually is, in three tiers: structural to the audit row, assembled here from parts the market sells separately, and table stakes. Each capability names its mechanism and where the rest of the field lands, graded against the observability / cost / eval / durable-execution cohort (Helicone, Langfuse, LangSmith, Portkey, LiteLLM, OpenMeter, MLflow, Logfire, Braintrust, LangGraph, Temporal, Inngest, the OpenTelemetry GenAI conventions). States plainly where the substrate is structural (hash-chained AuditableCall row, deterministic replay + family-lock, subagent spend rolled to the turn) and where it is commodity (per-tenant cost, checkpointing, PII redaction). Linked into the sidebar after Comparison.

  • Family-locked routing gains a "Why the lock matters: provenance" section. Frames the value around audit provenance, not operational breakage: when the model that answers changes (transient failover, or a migration over a release cycle), the ledger has to record which provider and model ran, and when it changed. In-family-only fallback (fallbackStep with inFamily: true) plus an explicit sessions.updateProviderModel re-lock (session-lock-resynced event) keep the provider / transport on every AuditableCall row trustworthy — provenance for an auditor, not a UI label or a local dev-tool file.

  • Homepage value-prop tiles reordered to lead with the differentiated capabilities. Leads with deterministic replay, family-lock, subagent-cost rollup, and the hash-chained row; demotes the commodity per-tenant-cost framing and drops the niche sync-conflict tile. The family-lock tile reframes around model provenance — proving which provider and model produced each answer after a failover or migration. Links the new Landscape page.

  • Comparison gains a read-side cohort table. Adds an "Observability, cost, and eval tools" section covering Helicone, Langfuse, LangSmith, LiteLLM, MLflow, Logfire, Braintrust, and OpenMeter — the tools a team shops against for "audit, cost, replay" and which the prior matrix omitted. Draws the write-side-substrate vs read-side-store boundary, marks where each lands data (their store vs your DB), and states the compose pattern (Pleach writes the row; the read tools stay good at reading).

  • Agent instrumentation recipe — new recipe page for the do-it-yourself instrumentation path. Subscribe to the runtime lifecycle with runtime.events.on(kind, handler) over model.called plus the stage.* / turn.* / recovery.fired / retry.attempted / stream.* kinds, then bridge model.called to a destination with observeSink({ destinations }) in one line. model.called now fires for both the main agentic turn and each synthesize / reasoning / utility seam call — seam-call rows carry real costUSD from per-1M-token rates, main-turn rows carry a 0 sentinel (cost derived downstream from llm.turn token counts). Distinct from observable-chatbot (recipe wrapper) and BYOK observability (no-@pleach/core brownfield path). Registered in meta.json and the llms.txt Recipe-walkthroughs group.

  • "Live lifecycle events" on observable-chatbot — links the chatbot recipe to the bare-subscription instrumentation path and shows bot.runtime.events.on("model.called", ...) off the recipe's runtime escape hatch.

  • CI enforcement of the audit contract — new Reference page indexing the audit-gate catalog by the auditability and replayability clause each gate enforces. Pairs every clause with its named gate and the condition that turns it red — audit:auditable-call and audit:auditable-call-soak for the row shape and DB wire-format, audit:event-log-manifest-hash-completeness plus the three audit:config-manifest-* gates for substrate reconstruction, audit:c8-event-type-allowlist-coverage for scrubber coverage, audit:c9-hash-chain-integrity and audit:eval-phase-a-coverage for replay. Names the graphnoderef, local-clone, and per-SKU consumer-rehearsal CI jobs. 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) as the canonical, audit-gated contract layout, with representative hooks per namespace and the rolling-out typed namespaced authoring form (plugin.stream.contributeX, additive alongside the flat form). Cross-linked from Plugin contract.

  • 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). Covers the five per-surface child hashes, the nullable manifest_hash foreign reference on harness_event_log, reference-counted retention (default forever, tenant-overridable floor), full-snapshot storage, and the replay-by-config, cross-tenant-by-plugin-set, and substrate-reconstruction 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 table the runtime and its plugins write, what's on by default versus opt-in, and what each row carries. Leads with the destination-is-yours posture: no phone-home; writes land in your Postgres / Supabase / OTel collector / Memory buffer.

  • manifest_hash cross-references added to Event log (stamping section + EventLogRow field) and Schema (rolling-out harness_config_manifest section).

  • MCP Server Card (SEP-1649) at /.well-known/mcp/server-card.json and a backing JSON-RPC endpoint at /api/mcp. The card declares streamable-http transport (MCP protocol 2025-06-18) pointing at /api/mcp and enumerates two read-only docs tools — search_docs (full-text over the docs corpus) and get_doc_markdown (markdown twin of any docs page by slug). The endpoint handles initialize, tools/list, tools/call, resources/list, ping, and the notifications/* no-ops; tools/call for search_docs runs the same createFromSource(source) engine that backs /api/search, and get_doc_markdown resolves through source.getPage() against the same processed body the agent-skills index digests. Advertised via rel="mcp-server-card" in the Link headers on / and /docs/:path*, in the <link rel> mirror in the root layout, and under service-meta in the RFC 9727 /api-catalog linkset.

  • WebMCP browser provider mounted from the root layout. Calls navigator.modelContext.provideContext({ tools }) (with a fallback to per-tool registerTool for older Chrome origin-trial builds) to expose the same two tools — search_docs, get_doc_markdown — to AI agents embedded in the browser. Silent no-op on browsers without the API. Tool shapes are identical to the HTTP MCP surface, so an agent reaches the same operations whether it dials in over /api/mcp or rides inside a browser tab.

  • Agent Skills Discovery index at /.well-known/agent-skills/index.json. Follows Cloudflare's RFC v0.2.0 shape. Every docs page is exposed as a documentation-type skill whose url points at the per-page markdown twin (/llms.mdx/docs/<slug>/content.md) and whose sha256 digests the same processed body that URL serves. A changed digest is the signal a page has been re-authored; agents can verify ingestion against it byte-for-byte. The index iterates source.getPages() so any new docs page joins automatically. Advertised via rel="agent-skills" in the Link headers on / and /docs/:path*, in the <link rel> mirror in the root layout, and under service-meta in the RFC 9727 /api-catalog linkset.

    An isitagentready.com audit also flagged OAuth metadata, /auth.md, MCP Server Card (SEP-1649), WebMCP, and DNS-AID. The MCP Server Card and WebMCP additions above resolve two of those flags; the remainder still don't apply — this site has no protected APIs and no agent-registration surface, so OAuth metadata and /auth.md would advertise endpoints that don't exist. The existing crawl surface — sitemap, llms.txt, llms-full.txt, per-page .md twins via Accept: text/markdown, robots.txt, ai.txt, /api-catalog (RFC 9727), and RFC 8288 Link headers — is what an agent actually needs to crawl the docs effectively.

  • Node catalog and Edge catalog reference pages, slotted into the Architecture sidebar after Channels. Node catalog enumerates the 43-name registry the audit:graph-stages script accepts, grouped by lattice stage with the acceptsSeam literal and a per-node gated column (always vs. config.<field> — the executor or hook the host must supply for the node to wire). Edge catalog enumerates the nine allowed cross-stage edge patterns plus the seven forbidden ones verbatim, then documents the four static chains (pre-LLM, enrich-route, post-tool, terminal), the two conditional routers (post-LLM four-arm, post-hallucination two-arm), and the four post-turn recovery stream filters (refusalHintFilter 100, retryNarrationFilter 200, garbleRecoveryFilter 300, standardRecoveryFilter 400) with per-arm target tables.

  • DX sections in Node catalog and Edge catalog documenting the three extension paths external developers can use. Node catalog adds an "Adding or removing nodes" matrix covering config omission (drop a gated executor, the chain composes around the absent node via .filter(hasNode)), the plugin path (HarnessPlugin.extraGraphNodes() with the substrate's registration constraints), and the custom-builder path (a raw StateGraph for full topology control under the lattice gate). Edge catalog adds a parallel matrix plus the asymmetric removal story: a synthesize → tool-loop edge cannot be re-added through any extension path, and removing an allowed pattern requires upstream contribution to topology.ts. Both pages keep the upstream-contributor checklist as a separate section so the two audiences don't collide.

  • Ownership boundaries page, slotted into the Get Started sidebar after Which SKU do I need?. Single-page map of where each SKU's locked surface ends and host code begins. Three columns per SKU: Owned by the SKU (locked, upstream-contribution-only), You configure (typed config field, plugin hook, or registry), You must supply (required at construction). Covers every shipping @pleach/* SKU. Names the two structural pins that hold across every SKU — the four-stage lattice and the AuditableCall row shape — and the cross-SKU concerns where ownership spans packages (audit ledger, cost rollup, storage, determinism). Closes with a "Quick lookup — I want to change X" table mapping 20 common host-side change requests to their surface and path. Fills the gap between Which SKU do I need? (task → install list) and Plugin contract (full extension API).

  • DX additions to six existing pages after a corpus-wide audit of where extension guidance was missing or weak. The audit scanned 177 MDX files; the pass rate was high (the site was already DX-aware on most surfaces). Six rows landed: (1) The AuditableCall row gains a locked-contract callout naming the three extension slots (tenantId, payload.identity, payload.output.auditNote) and pointing the rest at upstream contribution; (2) Fabrication detection gains an "Adding a custom detector" section with a worked contributeFabricationDetectors example plus the three detector rules (sync detect, side-effect-free, tier-determines-routing); (3) Event log gains an "Authoring a custom projection" section against the verified GraphProjection<T> interface plus the three contract rules (pure, order-preserving, total); (4) Observability gains an "Extending observability — plugin hooks" section surfacing contributeStreamObservers and contributeFinalizationPasses; (5) @pleach/mcp gains a "Registering custom capabilities" section honest about what works today (McpToolRegistration) versus what throws (McpResourceRegistration + McpPromptRegistration are shape-stable but body-deferred until Phase B second slice); (6) Audit gates gains a "Mirroring gates in your own repo" section citing the audit:plugin-contract-completeness script shape as a small reference for host-side invariant gates. Every hook name in every example was verified against the upstream source before landing — no fabricated APIs.

Fixed

  • 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).

  • Dead link /docs/plugins-and-extensions corrected to Plugin contract on Install.

  • Docs home "Three paths" header corrected — it preceded four cards; the count was dropped.

  • Schema codeRepository + sameAs corrected across seven SKUs in the site's Organization + SoftwareApplication JSON-LD @graph. @pleach/base-tools, @pleach/observe, @pleach/compliance, @pleach/compliance-contract, @pleach/gateway, @pleach/mcp, and @pleach/recipes each declared https://github.com/pleachhq as their canonical repository — a leftover from when the SKU schemas were drafted against an upstream monorepo. Both codeRepository and sameAs now point at https://github.com/pleachhq/<sku>, matching the canonical pattern set by @pleach/core, @pleach/tools, @pleach/eval, @pleach/replay, @pleach/sandbox, @pleach/coding-agent, and @pleach/react. Load-bearing because sameAs is the field AI search engines (ChatGPT, Perplexity, Gemini, AI Overviews) use for entity reconciliation across the npm ↔ GitHub ↔ docs boundary; the wrong URL was being served to every crawler on every page request via the JSON-LD @graph inlined in the docs root layout.

  • Schema codeRepository + GitHub sameAs entry added to @pleach/langchain. The langchain SKU's SoftwareApplication block was the only entry in the JSON-LD graph without a codeRepository field, and its sameAs array referenced only the npm page and the docs page (not the GitHub repo). Now declares https://github.com/pleachhq/langchain consistent with the other SKUs.

  • Pleaching metaphor branches list corrected across four surfaces. The prior framing named the four stages (intent / tool pick / refusal / answer) as the branches woven into the lattice, but stages are sequential phases of one turn — not parallel branches the metaphor needs. The glossary already had the right framing, matching the upstream @pleach/core README: branches are the addressable events (each LLM call, tool dispatch, subagent spawn) — each one writes a row to the ledger. The bad list had been introduced during the lift-and-rewrite from the upstream metaphor passage and replicated to the homepage hero, the docs index, the overview, and the audit ledger page. All four now align with the glossary and the upstream README, and a closing line on the homepage and docs index/overview names the four stages as the trellis and the audit row as the weave so the metaphor's load-bearing parts each have a job. No change to the glossary, the upstream README, or replay (which uses branch generically and was already metaphor-safe).

Removed

  • Company attribution and private references stripped from shipped copy. A company name, private repository links, a private filesystem path, and internal tracker links were removed from the homepage and docs; a few domain-specific example terms in prose were genericized.

  • Internal planning citations removed across the docs. Decision, pack, slice, and open-question IDs that meant nothing to an outside reader were stripped, each annotated claim left intact. Live runtime symbols a consumer sees — the PACK_* constants and the literal NotImplementedError("D-PA-181") / ("D-PA-184") payloads — were retained.

  • Homepage Four Properties section deleted, plus the duplicate hero "From those three" paragraph. The Four Properties grid (cost / audit / compliance / legibility) restated the same primitive — tenantId / turnId / tokenUsage rolled up via GROUP BY — that the What you can do with it section two blocks above already covered, with different labels. The hero paragraph "From those three: per-tenant cost in a GROUP BY, compliance review in SQL…" restated the load-bearing fact the previous paragraph (session / turn / row) had just landed. Both cuts follow a verbosity audit of every public non-docs page; the deletions shorten the homepage by ~120 lines without losing a load-bearing claim — scrubber names and the four-stage shape are still documented at Compliance and Architecture, which the deleted pillars linked to anyway. The Agent shapes CTA the deleted section carried is rewired into the Should you stay where you are? section, folded into the existing shape-enumeration paragraph so it lands where a reader is already asking the what-shape-am-I question.

Changed

  • @pleach/observe repositioned from shipping to alpha across the site. Packages, the docs home, and Which SKU had listed it at 0.1.0 · npm; @pleach/observe is 0.1.0-alpha.0 — scoped, not yet on npm. Install recommendations now tag it (alpha).

  • Package-count framing corrected to 14 published. @pleach/compliance-contract joins the first-wave list; @pleach/observe (alpha) and @pleach/trust-pack (reserved) move out of the shipping set.

  • Homepage @pleach/coding-agent version aligned to 0.1.0 — it had shown 0.2.0-alpha.0, contradicting the first-wave cut on Packages.

  • Which SKU persona section rewritten to named archetypes. Internal persona codes became plain audience shapes.

  • What's new — June 2026 reframed as reader-facing release notes — reorganized by package; slice numbers, commit SHAs, and persona codes removed.

  • Graph lattice docs synced to the current @pleach/core topology across eight pages. Corrected three load-bearing claims that shipped against an older substrate. 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, and Plugin contract; Audit gates gains graph + config-manifest gate rows. Node catalog also gains a "How the substrate source is organized" section — the src/graph/ layout (nodes/ one-file-per-node, wiring/ registrars split by stage, the topology.ts lattice layer, concern-split seams/ / predicates/ / strategies/) — and its upstream-contributor steps now point at the wiring/register<Stage>Nodes.ts registrar rather than the thin defaultAgentGraph.ts orchestrator.

  • Config manifest foreign key corrected in Config manifest. The page claimed the harness_event_log.manifest_hash reference was gate-enforced "rather than a database foreign key." It is a real foreign key with ON DELETE SET NULL and a load-bearing DEFERRABLE INITIALLY DEFERRED clause — deferring to commit time lets the fire-and-forget manifest write race the first event-log write within one transaction without a transient FK violation. Added the missing reference_count column to the table DDL and cited the audit:config-manifest-fk-constraint-applied and audit:config-manifest-referential-integrity gates.

  • Authoring a HarnessPlugin informal "12 buckets" reframed as the scan view of the canonical nine namespaces. The at-a-glance hook grouping now points at Contribution namespaces as the canonical, audit-gated contract layout. Hooks and counts unchanged; the framing reconciles the two pages so the site carries one canonical taxonomy.

  • Graph structural pin corrected from a fixed "32 nodes / 70 edges" count to a config-honest framing. The old prose claimed the canonical graph "compiles to 32 nodes and 70 edges" and that the audit asserts that count is byte-identical PR-to-PR. The numbers were correct for a specific compile config but misleading as a general claim: the NODE_STAGE_MAP registry in topology.ts carries 43 names, and the actual compiled count depends on which executors and hooks the host supplies to buildDefaultAgentGraph(config). The corrected prose names the 43-name registry as the upper bound, names the audit:graph-stages byte-identity guarantee as per-config not absolute, and links to the two new catalogs (Node catalog, Edge catalog) as the enumerated references.

  • Schema @pleach/core description amended to name the language-agnostic contract. The description field in the Organization + SoftwareApplication JSON-LD graph previously described @pleach/core only in TypeScript terms, contradicting both the marketing surface (which states the wire contract is language-agnostic with an independent Go implementation) 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.

  • /llms.txt per-page markdown advice tightened from .mdx to .md. The closing ## Machine-readable surface block in the curated AI index previously instructed agents to construct URLs like https://getpleach.com/llms.mdx/docs/<slug>.mdx, hitting the underlying route handler directly. The site's markdown-negotiation proxy supports the more idiomatic https://getpleach.com/docs/<slug>.md form, which is the pattern most AI crawlers actually look for. The instruction now recommends the proxied form and notes it's equivalent to requesting the same URL with Accept: text/markdown.

  • Pricing page export-bridge prose tightened, "What we sell on top" restructured. The export-bridge paragraph collapsed from four sentences with dual "If your team / If you don't" framing to two sentences carrying the same destination list (Postgres, Supabase, OTel collector, custom) and the same bridge-vs-destination framing. The "What we sell on top" paragraph — a 70-word run-on with three nested parentheticals (Hosted Gateway, Hosted Observe at enterprise scope, marketplace bundles) — became a three-item bulleted list, one SKU per line. Same audit pass as the homepage cut above.

Added

  • Agent-discovery surface extended to deep-link landings and body-only fetchers. Three reach extensions to the existing RFC 8288 Link: header + robots.txt + /llms.txt + /ai.txt + /.well-known/api-catalog stack — none of them corrections, each one closes a gap where a non-default crawler shape misses the discovery surface.
    • The docs root layout mirrors the homepage Link: headers as <link rel> elements in <head> on every page, so agents that read rendered HTML body but never see response headers (cached archive fetchers, lightweight AI ingestors) discover api-catalog, service-doc, alternate/llms.txt, describedby/ai.txt, sitemap, and author the same way they would from the header.
    • The site's Next.js header config extends the same Link: headers (with Vary: Accept) to every /docs/* URL. Agents arriving at a deep-link citation in an AI answer now get the same discovery hints — api-catalog, service-doc, ai.txt, sitemap, author — without traversing back to /. The home-only /llms.txt alternate is omitted from this path because the per-page markdown twin is the same URL with .md appended, served via the markdown-negotiation proxy; advertising /llms.txt would falsely imply that's the markdown twin of the current page.
    • The sitemap generator emits a .md twin entry for every docs page at priority 0.4 (below the 0.7 HTML form, so search engines prefer the human-facing URL for ranking). Sitemap-only crawlers — some AI ingestors don't follow Accept: text/markdown content negotiation — now discover the machine-readable surface from the sitemap alone.
  • Pleaching metaphor surfaces on the homepage hero and docs index. The horticultural framing the runtime takes its name from previously lived only in the brand motif component and the glossary's P section. The homepage hero and the docs index now carry a single voice-tightened paragraph between the lede and the payoff — pot-and-stakes for ai-sdk/LangChain, lattice for Pleach, branches for intent / tool pick / refusal / answer. Lifted and rewritten from the metaphor passage in the upstream @pleach/core README; the docs-index version cross-links the canonical glossary entry. One flourish per page per voice rules; mechanism still leads, metaphor follows. Three concept pages pick up a single sub-metaphor each: Comparison carries the pot-and-stakes-vs-lattice contrast right under the lede; Audit ledger adds "the lattice carrying weight — every branch lands in a row at the same grain" after the stage walkthrough; @pleach/replay adds "walking the rows in order is walking the lattice" under the determinism claim. Skipped determinism.mdx, concept-clusters.mdx, checkpointing.mdx, and API references — too instrumental for the flourish to earn its weight.
  • Fumadocs UI surface broadened — the docs MDX registry now carries Steps/Step, Accordion/Accordions, TypeTable, File/Files/Folder, Banner, ImageZoom, InlineTOC, DynamicCodeBlock, and GithubInfo alongside the existing defaults. Card/Cards and Callout were already in the fumadocs defaults; the new registrations unlock the rest across every page without further wiring.
  • Three first-party enterprise-shape componentsStatusBadge (8 semantic statuses: stable, beta, preview, alpha, deprecated, reserved, pre-1.0, in-flight), VersionPill (monospace pkg@version pill with optional href), and Kbd (themed keyboard-shortcut display). Pure-SSR React, theme-aware via text-fd-* tokens, no client JS. /docs/replay adopts <StatusBadge status="in-flight">Phase A + Phase B</StatusBadge> under its Status heading as the reference adoption.
  • <TypeTable> on reference pages/docs/auditable-call-row converts all five sub-shape tables (Identity, Principal, Call, Decision, Outcome) into <TypeTable> blocks. /docs/stream-events and /docs/env-vars each convert one representative table as the pattern reference for follow-up work.
  • <Accordions> on the FAQ Capabilities cluster — the 9-question "Capabilities" section of /docs/faq now renders as a single <Accordions> with each Q an <Accordion> carrying an explicit id for deep-link stability. The main FAQ above stays as ##-headed prose; the FAQPage JSON-LD graph is unaffected.
  • <Steps> on the migration pages/docs/migrating-from-ai-sdk and /docs/migrating-from-langchain wrap their six step sections in <Steps>/<Step>. The auto-numbered left-rail track replaces the ## Step N — prefix in each heading, so H2 anchor IDs are now content-only (#convert-your-tools instead of #step-2-convert-your-tools). No inbound links pointed at the old anchors.
  • <Callout type="info"> on migration scoping blocks — the "You don't need this migration if" pre-flight bullets and the "Costs that don't go away" sections in both migration pages now render as info callouts.

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, /docs/architecture, /docs/determinism, /docs/family-lock, and /docs/turn-lifecycle.

  • Four SKU placement pages/docs/sandbox, /docs/transport-bedrock, /docs/transport-azure-openai, and /docs/transport-vertex. Each page is a thin orientation: what the SKU is for, where it slots in the substrate, which contract page it implements, and a pointer to the package's npm README as the canonical source for constructor signature and option shape. Authored to retire four audit failures for SKUs already on SKU_PUBLISHED. The repo's audit:docs-vs-contract script now reports 0 missing pages.

  • /docs/recipes jump-link table — 10-row index inserted after the lead so a reader scanning for one recipe doesn't sift through ~1,000 lines. Each row names the recipe's central primitive (@pleach/react + createPleachRoute, ProviderDecisionLedger, etc.) in 3–8 words.

  • HowTo schema on /docs/adoption-paths — 5-step JSON-LD mirroring the brownfield→greenfield progression. Improves AI-search citability on a load-bearing discovery page.

  • FAQPage schema on /docs/comparison — 11 Q/A entries across the four comparison clusters (TS LLM libraries, durable-execution platforms, agent harnesses, Enterprise contracts). Each Q matches a question shape a reader would type into ChatGPT or Perplexity; each A is the load-bearing fact from the page.

  • ---Transport providers--- sidebar group below Bundled packages, listing transport-azure-openai, transport-bedrock, and transport-vertex. sandbox slots into Bundled packages after base-tools.

Changed

  • /docs/session-runtime — facets-first restructure. The facets inventory (runtime.sessions, runtime.events, runtime.sync, runtime.dev) now appears directly after Strategy injection. The flat method surface relocated under a new Flat method surface (legacy) H2 with a one-line banner forward-pointing to facets. Readers previously learned the deprecated path first; the new order matches the deprecation contract the page already states.
  • /docs/adoption-paths — brownfield→greenfield framing promoted. What used to be a page-bottom section is now a callout directly after the two-paths comparison table, so decision-makers see the upgrade path before they pick a lane. Hook sentence: "Every choice you make on the SDK destination travels with you when you adopt the full runtime."
  • Sidebar group rename: Use casesAgent patterns. Same six pages (customer-support-agentregulated-domain-agent) — the prior name read as features, the new name reads as patterns. Operations stays as a single group; cosmetic clustering wouldn't help scanning.
  • /docs/recipes lead — count flipped NineTen and the inline name list extended to include the regulated-host end-to-end recipe.

Fixed

  • /docs/plugin-authoring-standards — ghost hook reference. A code example referenced a non-existent contribute-prefixed spelling of the pre-plan primer hook; the real hook is prePlanPrimer (no contribute prefix — lifecycle hooks like prePlanPrimer, postSynthesisGuard, onJobDispatch carry no prefix; the contribute prefix is reserved for contribution-slot hooks). Caught by the in-repo audit:docs-vs-contract script — first F-11 drift hit since the SKU coverage check landed. Audit now reports 0 novel ghosts.

Added

  • Rank-2 per-recipe deep-dive pages — four additional pages under /docs/recipes/ covering the recipes excluded from the prior six because their peer SKUs were outside the first-publish wave: observableChatbot (composes @pleach/observe), instrumentedCodingAgent (composes @pleach/coding-agent + @pleach/sandbox + @pleach/observe), enterpriseAgent (composes @pleach/compliance + @pleach/observe, surfaces the procurement-visible ENTERPRISE_PERMITTED_FAMILIES_TAG envelope a gateway-aware host reads), and evalLab (composes @pleach/eval
    • @pleach/replay via DI-callback factories so the recipe doesn't take hard build-time peer deps). The four are rank-2-publish-relevant once eval, mcp, sandbox, and coding-agent ship per the upstream rank-2 runbook. Each page mirrors the prior six-page convention — best fit, quickstart, runtime composition, TypeScript config interface, common gotchas, cross-links. Sidebar registration in [the docs meta.json] adds the four pages immediately after the prior six under Bundled packages.
  • Per-recipe deep-dive pages under /docs/recipes/ — six new pages covering the first-publish wave (@pleach/core, @pleach/tools, @pleach/compliance, @pleach/gateway) and the brownfield observability SDK: simpleChatbot, ragChatbot, compliantChatbot, verticalAgent, subagentSwarm, and BYOK observability. Each carries a quickstart, the runtime composition the recipe wires, a TypeScript config interface, common gotchas, and cross-links. Recipes composing SKUs outside the first-publish wave (observableChatbot, instrumentedCodingAgent, enterpriseAgent, evalLab) are not yet covered and will land when those SKUs ship.
  • /robots.txt — emits Content-Signal: search=yes, ai-train=yes, ai-input=yes per the contentsignals.org draft. The signal mirrors the editorial position already on /ai.txt — crawling, indexing, retrieval, and training are all permitted.
  • Homepage Link: response header — the / response now ships RFC 8288 Link: advertising /.well-known/api-catalog (rel="api-catalog"), /docs (rel="service-doc"), /llms.txt (rel="alternate"; type="text/markdown" — the markdown twin of / under content negotiation), /ai.txt (rel="describedby"), /sitemap.xml (rel="sitemap"), and the maintainer inbox (rel="author"). / also gets Vary: Accept so a CDN can't cross-contaminate the HTML and markdown responses. Agents can find the discovery surface without parsing HTML.
  • /.well-known/api-catalog — RFC 9727 catalog returned as application/linkset+json (RFC 9264). Two anchors: the site root and /api/search (the docs search endpoint).

Changed

  • Markdown-for-Agents on the homepage/ with Accept: text/markdown now rewrites to /llms.txt (which uses fumadocs's q-value-aware isMarkdownPreferred to choose text/markdown over text/plain and ships Vary: Accept). Per-page markdown under /docs/* is unchanged.

  • /pricingTwo surfaces. One runtime. closing paragraphs refine to drop claims cohort research contradicted, without committing to hypothesis-grade tier prices still gated by buyer-outreach. Specifically: compliance attestation drops as a standalone enterprise surface and folds inside Hosted Observe at enterprise scope (nobody sells "cryptographic audit chain" as a standalone procurement category — Vanta / Drata / Credo AI all sell per-framework + per-headcount); Hosted Gateway description rewrites to per-tenant subscription pricing with optional consolidated billing, drops any percentage-on-routed-spend framing (100% of disclosed-pricing LLM router cohort runs zero markup on inference — Vercel + OpenRouter have done buyer education); the bridge paragraph expands to acknowledge the self-serve segment where Pleach becomes the destination (no existing observability stack to bridge to). New closing paragraph names self-serve tiers as in development without committing to specific prices.

  • /faq and /docs/faqIs there a hosted version? answer rewrites the hosted product list: compliance attestation folds inside Hosted Observe Enterprise (no separate SKU); Hosted Gateway names per-tenant subscription pricing and "no markup on inference"; self-serve tiers named as in development.

  • /pricingWhat stays free, and what doesn't rewritten as Two surfaces. One runtime. with a side-by-side comparison table (substrate vs hosted) across 11 dimensions: license, phone-home, license check, account-to-run, retro-paywall, self-host, SSO/SAML/SCIM, SLA, retention, SOC 2, pricing. The table makes the trust-vs-revenue boundary structurally instead of by meta-commentary. Two short closing paragraphs add: (a) audit rows ship where you point them — Postgres, Supabase, OTel collector into Datadog / Honeycomb / Grafana / your existing OTLP backend, or a custom destination; the enterprise integration is the bridge from @pleach/observe into the review surface your team already runs, not "adopt another dashboard"; (b) what we sell on top: Hosted Gateway, compliance attestation services, Hosted Observe at enterprise scope, AWS/Azure/GCP marketplace bundles. The prior absolutist lines — self-hosting the equivalent stays on the table at every release and no procurement-style enterprise tier today — drop because they foreclosed the only viable revenue stream.

  • / — homepage hero closer rewrites the no procurement-style enterprise tier line in favor of hosted products on the runtime are first-class enterprise products. Trust commitment intact; revenue posture honest.

  • /faq and /docs/faqIs there a hosted version? answer rewrites under the two-surface frame. Hosted Gateway, Hosted Observe at enterprise scope, and compliance attestation services name themselves as enterprise products with per-seat pricing, SSO/SAML/SCIM, retention SLAs, and SOC 2 wrappers. Runtime trust commitments intact.

Added

  • @pleach/observe — new top-level page for the brownfield audit-row SDK. Documents the five-entry facade surface (init, startTurn, flush, recordCall, subagent, getRecorder), the ObserveRow shape as a strict subset of the AuditableCall v7 schema, the four destinations (Postgres, Supabase, OTel, Memory) on the ./destinations subpath, the custom-destination interface (write + optional flush), the hookable-vs-not-hookable split against the runtime, and composition with @pleach/core when both surfaces run in the same process. Phase 0 status callout makes the design-target stance explicit — @pleach/observe@0.1.0-alpha.0 is scoped, not yet on npm; Phase 1 publish is the next cut. Slotted into the Bundled packages cluster after @pleach/gateway.

  • Adoption paths — new top-level orientation page making the brownfield-vs-greenfield decision first-class. Leads with a side-by-side capability table (audit row, family-locked routing, replay determinism, channels, checkpoint/restore, migration cost), then "pick brownfield when" and "pick greenfield when" sections with concrete code shapes for each, then the monotonic brownfield-to-greenfield composition story (runtime detects SDK init, startTurn becomes a no-op inside a runtime-managed turn, shared fingerprint compute, no double-recording), then "pick neither when" — single-shot RAG, provider-dashboard-is-enough, prototyping-and-changing- weekly. Slots in at the top of the Compose & migrate cluster as the orientation page the per-stack migrating-from-* walkthroughs (AI SDK, LangChain, Anthropic Enterprise, OpenAI Enterprise) sit downstream of.

  • Packages — added the @pleach/observe matrix row in the Reserved tier with the row note 0.0.1 · Reserved · 0.1.0-alpha.0 scoped, and reworked the Reserved bullet in the intro narrative to distinguish @pleach/trust-pack (placeholder, no contract published) from @pleach/observe (Phase 0 contract locked, scoped for Phase 1 under FSL-1.1-Apache-2.0).

  • Sidebar — added observe under Bundled packages after @pleach/gateway, and Adoption paths at the top of Compose & migrate ahead of the migrating-from-* pages.

  • Attestation — new top-level page on the Ed25519-signed envelope substrate that sits on top of the hash chain and turns a row-slice into third-party-verifiable evidence. 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. Frames the boundary against policy and rotation, which stay in @pleach/compliance or host-side. Slotted into the Tamper evidence cluster directly after Hash chain.

  • Audit gates — new top-level page cataloging the CI- and PR-time invariant checks in scripts/audit/ — package-shape, plugin-contract, tool- coverage, event-log integrity, runtime soak ledgers, and cross-repo reservations. Documents the :strict / :json / :list / :update-baseline suffix convention and the soak-ledger generalization. Slotted into the Reference cluster after Subpath exports.

  • Project layout — new top-level page giving the orientation that previously had to be reconstructed from the use-case and recipe pages. Leads with the three things the runtime actually requires (a SessionRuntime per process, a chosen ProviderDecisionLedger, a host adapter if HTTP is in play); shows one working Next.js-shaped layout with each piece cross-linked to its canonical docs page; descends into the six use-case shapes (customer support, research, coding, internal knowledge, multi-tenant SaaS, regulated domain) via a <Cards> block; points at the three filesystem-touching recipes (Next.js streaming, SQLite storage adapter, custom event-log projection); and closes with the deliberate non-choices (no pleach.config.ts, no reserved .pleach/ dir, no agents/ folder convention — the agents/<specName>/ prefix in Agents is a channel-path string, not a directory). Slots into a new Project layout sidebar cluster between Getting started and Agent shapes. Voice-aligned to the library-not-framework stance: describe, don't prescribe.

  • Sidebar — added the Project layout cluster. The cluster has room for siblings (deployment-shape layouts, multi-tenant layouts) without a future re-org.

  • Per-use-case Project layout sections appended to all six use-case pages — Customer support, Research, Coding agent, Internal knowledge, Multi-tenant SaaS, Regulated domain. Each shows the same baseline tree from Project layout with the shape-specific delta inlined (split tools by integration; subagents directory; sandbox boundary + durable checkpointer; index + ingestion split; per-request runtime factory; compliance/ wiring the three audit plug-points). Section is inserted before the existing Where to go next block so the descent from Project layout lands, deepens, and exits through each page's existing cards. Voice-aligned: each entry names the failure mode the structural choice fixes, not a generic benefit.

Changed

  • Cross-docs status-flip pass — rolling correction across ~55 docs pages tracking the alpha-ship of @pleach/compliance, @pleach/gateway, and @pleach/replay. Claims that previously read "planned" or "no shipping code yet" now name the actual alpha (@pleach/compliance@0.8.0-alpha.0 four-scrubber bundle; @pleach/gateway@0.8.0-alpha.0 Phase A with Anthropic transport real and other transports deferred to Phase B; @pleach/replay@0.7.0 hash-chain verifier shipping verifyChainForChat / generateProof, with writer-side stamping in @pleach/core/eventLog behind c9PhaseBEnabled). Touched pages include Audit ledger, Compliance, Gateway, Replay, Hash chain, Eval and replay, Event log, Event-log projections, Subpath exports, Seams, Prompts, Prompt builder, Session runtime, Recipes, and the rest of the Trust + integrity, Providers, and Reference clusters. Each edit is a load-bearing claim correction, not voice tightening — readers who saw the prior pages learned that pieces "weren't shipping" that now are, and the changelog entry exists so they can re-orient.
  • Project layout — corrected the multi-tenant card description. Originally read "One runtime per process serves many tenants"; the use-case page actually builds the runtime per request via a buildTenantRuntime(req) factory. Updated to match — the cards descent must not misrepresent the page it lands on.
  • CLI — substantial rewrite. The page previously described pleach init as a SQL-bundle scaffolder with --target / --dry-run / --apply / --timestamped flags. That surface still exists but is now pleach schema; pleach init is an interactive wizard that scaffolds a starter project (route, page, optional plugin stub, optional schema copy) for the detected framework. The old form pleach init --apply is routed to schema for back-compat (existing scripts keep working). Cited against the upstream scripts/harness-init.mjs already pinned in the page's <SourceMeta>. The rewrite is a correction to a load-bearing claim — readers who saw the old page learned that the binary "does one thing", which is no longer true.

Added

  • CLI — pleach init wizard — the four-question flow (template, provider, plugin stub, schema scaffold), the flag table (--template, --yes, --cwd), the framework-detection matrix (8 framework values), the package-manager detection (bun / pnpm / yarn / npm), the provider env-var matrix (anthropic / openai / openrouter / google with the four env-var names), the template-to-files matrix per framework, idempotence behavior (skip-not- overwrite), CI mode behavior (--yes and non-TTY auto-yes), exit codes (0 / 1), and a verbatim worked-example transcript of the wizard running in a Next.js App Router project.
  • CLI — pleach schema — the former init flag table, now under its true subcommand name. Adds honest exit codes (0 / 2 / 3) that the previous page omitted: schema bundle missing exits 2, overwrite refusal exits 3.
  • CLI — Project layout after the wizard — matches the per-use-case layout sections added in the prior pass. Shows the baseline Next.js layout with the four wizard-written paths inlined (app/api/chat/route.ts, app/page.tsx, pleach.plugin.ts, supabase/migrations/*pleach*.sql). Closes the loop between the CLI page and the project-layout cluster.
  • Subpath exports → @pleach/core/quickstart — added under the Wire + tooling cluster. Labeled experimental (matches upstream module status). 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. Closes the gap flagged in the prior cli.mdx pass.
  • Getting started → The quickstart subpath — new section after the existing Shortest-path quickstart — createPleachRuntime. Five-export table with shapes and jobs; zero-config + with- options createPleachRoute examples; two failure-mode behaviors (HTTP 503 on missing provider env var, Pleach-native vs Vercel-AI-SDK event taxonomy); useChat / <ChatBox /> composition example; createBenchmarkPlugin paragraph; a three-row "which factory do I reach for?" matrix differentiating createPleachRuntime (substrate), createPleachRoute (HTTP), and the bare SessionRuntime constructor (custom transport / multi-tenant). Voice-aligned: failure modes named at mechanism, not vibes.

Changed

  • CLI — wizard-section cross-links retargeted from Shortest-path quickstart (a related but different surface) to The quickstart subpath (the actual subpath the wizard scaffolds against). Also added a paragraph noting the wizard's 4-provider list is narrower than the runtime's 7-provider detection — a missed provider in the prompt does NOT mean the deployed handler will miss it, only that the wizard's default-selection logic doesn't know to highlight it.
  • Getting started → Scaffold a new project — the second instance of the stale pleach init claim that CLI's rewrite corrected last pass. The section previously said pleach init "scaffolds a minimal example agent plus the schema-bundle SQL migrations"; it now describes the four-question interactive wizard and cross-links to CLI → pleach init for the framework matrix and walkthrough.

Fixed

  • Resolved the Known gap entry from the previous Unreleased pass: @pleach/core/quickstart is now listed in Subpath exports and documented in Getting started, with cross-links from CLI. The wizard's emitted code (createPleachRoute, ChatBox, defaultPlugin) is no longer symbol-without-a-home.

Changed

  • Pricing — the What will and won't ever cost money section rewrites to What stays free, and what doesn't. Drops the absolutist One paid product, ever and No enterprise tier. No hosted-only features. framings; replaces with the net-additive + FSL-irrevocability commitment the license posture already provides for free. New phrasing: any paid surface is net-additive and can't gate a feature already in a published release; the FSL conversion clock guarantees that for FSL releases and Apache releases are irrevocably Apache on their published tag. Keeps the load-bearing Self-host means self-host row. Adds an explicit No procurement-style enterprise tier today qualifier that scopes what the brand commitment actually means (no contact-sales, no SSO behind paywall over substrate features, no per-seat upsells layered onto runtime functionality). The rewrite is a correction to a load-bearing claim — readers who saw the old page learned that no enterprise tier · one paid product, ever was a permanent commitment, which it is not.
  • Homepage hero — closing line No enterprise tier, no hosted-only features.No procurement-style enterprise tier; paid surfaces won't gate runtime features. Aligns the headline-scale claim with the Pricing revision.
  • FAQ → Is there a hosted version? — answer rewrites to lead with No today, name the gateway as the planned multi-tenant routing SKU, and close with the FSL-conversion-clock mechanism behind the net-additive guarantee.
  • /ai.txt — single-word fix: open-source agent-runtimefair-source agent-runtime. Restores the labeling-discipline qualifier the rest of the site already carries.

Added

  • Security → Deployment shape — new section after Scope. Scopes the self-host means self-host promise to what the runtime actually does today; names air-gapped operation, on-prem provider endpoints, and sub-tenant routing at scale as roadmap items with typed options today + runtime guards later. Points procurement teams at the canonical inbox for current state. Closes the gap between the pricing-page commitment and what the runtime literally does today for regulated buyers.

2026-06-08 — canonical contact collapsed to a single inbox

Changed

  • Canonical contact is now getpleach@protonmail.com. The previous split — admin@getpleach.com for general inquiries and security@getpleach.com for disclosures — is retired. Both roles now route to the single ProtonMail inbox; the Security page and the security-disclosures channel on Community include a ?subject=Security%20disclosure mailto hint so the inbox can still triage the two flows. Reflected on the homepage Organization JSON-LD, Security, Privacy, Terms, License, Pricing, Community, FAQ, the docs FAQ, the contributing guide, the blog RSS feed, and /ai.txt.

2026-06-08 — chat-pipeline lift into @pleach/core + audit:domain-string-purity Pre-Merge Gate

Added

  • OrchestratorClient — new top-level page documenting OrchestratorClient, 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. Page covers the six user-facing facets (config, history, context, tools, model, prompts), the _internal.graph snapshot consumer code must not touch, where a host receives the client (inside a custom strategy, inside a plugin hook, inside a custom turn body), and the imperative-vs-graph coexistence model. Slots into the "Build an agent" sidebar group between SessionRuntime and Providers. Pairs with the audit:orchestrator-facet-coverage CI gate already documented at Facets.
  • streamSingleTurn — new top-level page documenting streamSingleTurn, the canonical per-turn body. Lifted into @pleach/core/strategies/streamSingleTurn/ with a stable helpers barrel that re-exports TurnAccumulator, ToolDefinition, OrchestratorMessage, and ProviderFallbackConfig. Page documents what the body consumes (the typed strategy slots — hallucinationDetectorFactory, continuationMetaToolNames, repetitionGuard, orchestrator.providers.providerFallback, EMPTY_SINGLE_TURN_FLAGS), what it never sees (the five forbidden literal categories the domain-string purity gate enforces), and how a host wires a custom body when the linear-turn default doesn't fit. Slots into the "Plugins & strategies" sidebar group after Runtime strategies.
  • 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.
  • 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 (host vocabulary, vendor backend names, sandbox tool prefixes, identity discriminators, domain phrasing; ~50 patterns; baseline-gated :strict mode). Closes the rationale section with a fourth load-bearing-invariant sentence: the gate makes plugins the only legitimate channel for consumer-specific content. Pairs with the existing lint:harness-boundary row, which forbids domain imports — the new gate covers domain strings.
  • Language-agnostic contract § How the contract stays honest — promotes the three honest-keeping mechanisms (shared fixtures, cross-runtime replay, schema gate) to four by adding the domain-string purity gate. Frames the gate as a falsification mechanism: a TS-side string leak the Go runtime would otherwise have to mirror fails CI instead of becoming a wire-shape obligation.

Why now

The Pre-Merge Gate substrate landed upstream — the audit script, the five-family blocklist, the baseline, and the npm script variants are all live. The docs side previously only enumerated lint:harness-boundary (the import-side companion); the string-side gate is a structural guarantee the docs now name alongside it.

Added

  • Platform & operations recipes — extracts four platform-team recipes from Recipes (long-running async jobs, multi-step interrupts, per-call cost reporter, OpenTelemetry wiring) into a dedicated page under the Operations sidebar group. Lets a consumer reader on /docs/recipes skip patterns a platform team owns; lets a platform reader land directly on the four ops recipes without scrolling past chat/storage/BYOK.
  • Runtime strategies — extracts the ~140-line Strategy injection section from SessionRuntime (representative slots table, fabricationGuardStrategy bundle, newer injection hooks including hallucinationDetectorFactory, continuationMetaToolNames, the repetitionGuard extensions, the orchestrator.providers.providerFallback registry-seam, and EMPTY_SINGLE_TURN_FLAGS). Lands under a new Plugins & strategies sidebar group alongside Plugin contract. Frees the runtime page to read as a clean construction + lifecycle + executeMessage reference.
  • Related shapes blocks on every use-case page. Customer support, Research, Coding, Internal knowledge, Multi-tenant SaaS, and Regulated-domain agents each open with a three-bullet pointer at sibling use-case pages a reader on this one is likely to also need (e.g., "Regulated-domain agent if the SaaS serves a regulated vertical"). Fixes the brittle cross-page navigation — a reader on Customer support whose actual case is closer to Research now sees the pointer in the lead.

Changed

  • Examples reframed and renamed to Reference apps. The duplicated Agent shapes and Recipes hub sections (word-for-word repeats of Agent shapes and Recipes cards) are dropped; the page is now focused on the two runnable examples that ship inside the @pleach/core npm package (minimal-agent, host-adapter). Slug change updates the URL from /docs/examples to /docs/reference-apps; inbound links on Getting started, @pleach/base-tools, and the prior changelog entry are repointed.
  • Sidebar reorder in the Start group: Getting startedAgent shapesRecipesReference appsComparison. Brings the "which shape is mine" pattern lookup ahead of the catalog of wiring recipes — a reader matches their problem first, then opens the recipe that fits, then reads reference-apps only when they want a runnable starting skeleton.
  • Facets reordered so the inventory tables on SessionRuntime and OrchestratorClient lead the page, with the (now tightened) Why facets, not flat methods rationale moved to the section after. Drops the 28-line philosophical lead that buried what's actually on the runtime; rationale prose shrank from ~32 lines to ~18 while keeping the human + agent discoverability angle.
  • Prompt builder reordered so The composer signature leads directly after the lead paragraph and SourceMeta. The prior When you call it preamble (16 lines of "you usually don't") moved after the signature and tightened to a 9-line When you call it directly section. A reader who arrives wanting the API shape now sees the API shape first.
  • Recipes lead rewritten to reflect the consumer-facing split (chat, tools, storage, BYOK, moderation, multi-tenant, compliance, projections, hash chain) and to point at Platform & operations recipes for the platform-team patterns. Recipes 10–13 (multi-tenant, compliance, projection, hash-chain) renumbered to 6–9; anchor URLs for those four sections shift accordingly. No inbound docs links referenced the old #10/#11/#12/#13 anchors.
  • SessionRuntime shrunk from 472 lines to ~330. The Strategy injection section is now a one-paragraph framing + pointer at Runtime strategies; everything else (construction, SessionRuntimeConfig field table, sessions, executeMessage, abort, deletion, lifecycle methods, stream subscription, accessors, lifecycle events, facets, cacheBackend) stays.

2026-06-08 — docs de-dup + DX-ordered sidebar

Changed

2026-06-08 — sidebar + homepage label consistency

Changed

  • Homepage — renamed Four pillars section heading to Four properties. The intro paragraph already self-describes as "four properties"; the H2 now matches the body. Drops the architectural-pillars connotation that misframed the section: Cost / Audit / Compliance / Legibility are properties that fall out of the row primitive, not foundational supports.
  • Sidebar — split the Substrate group into Execution graph (graph, nodes, channels) and Routing (seams, call-classes, family-lock, model-resolution-matrix). Brings the sidebar group names into agreement with the cluster anchors the child pages point at — the execution-graph cluster on architecture, the routing cluster on family-lock. No URLs change; only the separator labels.

2026-06-08 — concept-map closeout (three more triplets + map page)

Completes the cluster-framing pattern across all sidebar groups where a clean triplet exists, and adds a dedicated concept-map landing page. Brings the total to seven cluster triplets at four depths: substrate-wide (session/turn/row) plus six cluster-level (execution-graph, routing, audit-ledger, composing-agents, runtime-lifecycle, state-and-persistence).

Added

  • Composing-agents cluster (Skill + Subagent + Agent profile). New section on Agents. Sibling openers added to Subagents and Skills.
  • Runtime-lifecycle cluster (Session lifecycle + Turn lifecycle + Event log). New section on Session lifecycle. Sibling openers added to Turn lifecycle and Event log.
  • State-and-persistence cluster (Storage adapter + Checkpoint
  • New Concept clusters landing page walking all seven cluster triplets as a navigable concept map. Opens with the substrate-wide triplet (session/turn/row), then the six cluster-level triplets in execution order. Closes with an explicit note on what lives outside the cluster pattern.
  • Sidebar entry for the new page in meta.json under "Architecture & comparison".
  • Footer extended with an Architecture link between Docs and FAQ, so readers landing on a marketing subpage have a second- level docs hook.

Changed

  • Docs index — dropped How the three concepts fit together section (now redundant with the cluster pattern propagating in the deep-dive pages) and added a one-line pointer to Concept clusters immediately after the substrate-wide triplet.
  • Docs index "Read next" cards trimmed from six to five: dropped Session lifecycle and Recipes; added Concept clusters as the new map entry.

2026-06-08 — cluster-framing pass (three triplets)

Extends the slow-ramp pattern from session/turn/row down through three more concept clusters, one layer in from the homepage. Each cluster lives on a host page that walks the three concepts in parallel-bulleted voice; the sibling concept pages each open with a one-paragraph cluster pointer that names the triplet and deep-links the host.

Added

  • Execution-graph cluster (graph + node + channel). New The execution-graph cluster section on Architecture between the TL;DR six-piece map and 1. Stage lattice, walking Graph, Node, Channel as the per-turn execution substrate that runs inside the lattice. Sibling-page openers added to Graph, Nodes, and Channels, each pointing at the new architecture anchor.
  • Routing cluster (CallClass + Seam + family-lock). New The routing cluster section on Family-locked routing, walking CallClass, Seam, and family-lock as the cluster that decides which model fires for which kind of call. Sibling-page openers added to Call classes and Seams. Reference-page pointers added to Providers (transport layer) and Model resolution matrix (the reference table), each naming the triplet and deep-linking the cluster framing.
  • Audit-ledger cluster (row + ProviderDecisionLedger + hash chain). New The audit-ledger cluster section on Audit ledger before the existing ProviderDecisionLedger deep-dive, walking the three concepts as a triplet so the row, the write interface, and the tamper-evidence layer each get one parallel bullet before the deep dive lands. Sibling-page openers added to The AuditableCall row and Tamper-evident hash chain.

Why

The slow-ramp pattern landed on the homepage + docs index for the foundational triplet (session/turn/row). Three more triplets sit one click in: execution-graph (inside a turn), routing (inside a stage), audit-ledger (after the call). Each gets the same parallel-bulleted treatment so a reader walking from the homepage into the docs hits the same shape at every depth.

2026-06-08 — slow-ramp entry-point pass

Added

  • Homepage hero: new substrate-framing paragraph between the H1 and the existing benefit paragraph. Defines Pleach as "a runtime substrate for LLM agents — the backbone an agent harness builds on, usable standalone or as the runtime layer underneath a product's agent loop" and names the three concepts inline (session, turn, row keyed by turnId). The existing benefit claims now read as the consequence of the three concepts, not the lead.
  • Homepage new section "Three concepts the substrate hangs on" between the hero and "What you can do with it," with three Pillar cards — Session, Turn, AuditableCall row — each carrying a definition and a deep-link to SessionRuntime, Turn lifecycle, and The AuditableCall row.
  • Docs index: opening rewritten to lead with "Pleach is a runtime substrate for LLM agents…", followed by a new "The three concepts" section walking session → turn → row, and a "How the three concepts fit together" section that retains the runtime + contract + ledger triangle framing. The existing "The shape, in one paragraph" remains as the next layer down.

Why

The initial entry point now opens high-level — what is a runtime substrate, what does it sit underneath, what are the three foundational primitives — before the load-bearing benefit claims land. The dense framing didn't disappear; it now reads as the consequence of the three concepts rather than the cold-open.

2026-06-08 — discovery + entry-point depth pass

Added

  • /llms.txt — lead paragraph appended with one sentence on Enterprise composition; "Migrating from other frameworks" group renamed to "Migrating & composing under enterprise contracts" with the two enterprise migration slugs added to the head so AI search retrievers see them first.
  • Homepage JSON-LD SoftwareApplication.description extended with the Enterprise composition clause for knowledge-graph entity extractors (Google AI Overviews, Gemini).
  • Root metadata.description in app/layout.tsx extended so every non-home page inherits the signal for OG / Twitter.
  • /ai.txt — new "High-signal entry points for enterprise readers" section naming both migration docs and Language-agnostic contract.
  • Overview — paragraph after the per-turn cost rollup SQL example naming tenantId as opaque (customer vs cost-center) and pointing to both migration docs.
  • Architecture §5 Audit ledger — paragraph after the identity-tuple claim connecting it to per-axis attribution inside one Workspace or Project.
  • Getting started — Enterprise callout after the server quick-start naming AnthropicSdkProvider and the AI SDK's OpenAI provider as the composition entry points.
  • FAQ — new entry "Does Pleach replace my Anthropic or OpenAI Enterprise contract?" before "Who's behind this?"
  • Core "What you get" — new bullet "Composes under an existing Enterprise contract" after the AuditableCall ledger bullet.

Changed

  • Sidebar separator Migrate & coexist renamed to Compose & migrate so the Enterprise composition story isn't mis-sold as a migration away from the lab.
  • Agent shapes Multi-tenant SaaS card blurb widened from "per-customer invoice" to "per-axis rollup (end-customer invoice, or employee / team / cost-center chargeback inside one Anthropic Workspace or OpenAI Project)." (Originally on /docs/examples; that page was reframed as Reference apps on 2026-06-08, with the agent-shapes cards moved to their canonical home on /docs/agent-shapes.)
  • Pleach + OpenAI SDK and Comparison — "per-customer monthly rollup" graduation claim widened to per-axis (per end customer in a SaaS, or per employee / team / cost-center under one Workspace or Project).
  • Homepage Enterprise section — two SKU paragraphs collapsed into one tighter paragraph naming both @pleach/coding-agent and the language-agnostic contract; load-bearing sentence "answers 'is this TypeScript-only?' before Enterprise IT asks" preserved verbatim.

2026-06-08 — sibling-SKU references

Added

  • Homepage Enterprise section — two new paragraphs after the cloud-mediated transports note. First paragraph names @pleach/coding-agent (typed CodingAgentRuntime contract at 0.2.0-alpha.0) as the sandboxed coding-agent surface for the internal dev-tools team that often sits inside the same Enterprise contract footprint — same row, same tenantId axis, same chargeback. Second paragraph names the language-agnostic contract (wire shapes: HTTP+SSE, StreamEvent, AuditableCall, checkpoint envelope, version vector) and the Go round-trip as the procurement-visible answer to "is this TypeScript-only?"
  • Migrating from Anthropic Enterprise and Migrating from OpenAI Enterprise — new "Sibling SKUs that ride alongside the contract" section before "Where to go next" on each migration doc, with one bullet for @pleach/coding-agent (Workspace or Project framing per doc) and one for the language-agnostic contract + Go round-trip.
  • Comparison Enterprise section — paragraph appended after the cloud-mediated transports note, mirroring the homepage's coding-agent + language-agnostic-contract framing for the doc-side reader.

2026-06-08 — re-settling pass

Added

  • Marketing surface. New CostRow body on Pricing for "LLM provider tokens" naming Anthropic Enterprise and OpenAI Enterprise composition, and the per-axis tenantId framing.
  • Marketing FAQ. New entry "Does this replace my Anthropic or OpenAI Enterprise contract?" on the FAQ page.
  • Docs adjacency. Enterprise-contract bridge paragraphs added to Pleach + Anthropic SDK and Pleach + OpenAI SDK, each pointing readers who graduated from a self-serve key to the right migration doc.
  • tenantId opacity paragraphs added to Multi-tenant deployments and The AuditableCall row, plus a GatewayClient-per-cost-center note on Gateway.

Changed

  • Sidebar reorder. The "Migrate & coexist" group now opens with the two enterprise migration docs (Migrating from Anthropic Enterprise, Migrating from OpenAI Enterprise) above Migrating from the AI SDK and Migrating from LangChain.
  • Agent shapes shape 04 renamed from "Per-customer cost attribution" to "Per-axis cost attribution" with body, team-shape, and sharpest-vertical lines rewritten to cover the internal-Enterprise case alongside SaaS. Anchor URL is now #04--per-axis-cost-attribution; the prior anchor was unreferenced elsewhere on the site.
  • Multi-tenant SaaS agent three-places list widened to four, naming the internal- Enterprise composition case.
  • Marketing FAQ "Who is this for?" answer on FAQ widened to name internal platform teams attributing employee, team, or cost-center spend under one Workspace or Project.
  • Homepage tightening. The FAQ entry "Already on Anthropic Enterprise or OpenAI Enterprise — what does Pleach add?" compressed since the new homepage section above it now earns the depth. The bridge sentence at the end of the comparison- table section rewritten to point forward at the Enterprise- contract section.

Fixed

  • A11y on Enterprise-card pseudo-CTAs. The "Migrating from Anthropic Enterprise →" and "Migrating from OpenAI Enterprise →" paragraphs inside the two homepage migration cards now carry aria-hidden="true" so screen readers announce each card once through its <h3>, not twice through both heading and pseudo- button text.

2026-06-08 — later

Added

  • New homepage section "Already paying the lab" between the comparison table and the four pillars, pitching Pleach as the substrate that composes underneath an Anthropic Enterprise or OpenAI Enterprise contract. Three pillars (per-axis rollup inside one Workspace / Project, hash-chained AuditableCall row in your own Postgres, replay-determinism across snapshots) and two cards linking to the migration paths below.
  • New homepage FAQ entry "Already on Anthropic Enterprise or OpenAI Enterprise — what does Pleach add?" mirrored into the JSON-LD FAQPage graph.
  • New section "If you already buy direct from Anthropic or OpenAI" on Comparison, before "Where to go next" — three load-bearing claims plus a note on cloud-mediated transports (Bedrock, Azure OpenAI, Vertex).
  • New "Already on Anthropic Enterprise or OpenAI Enterprise?" section on the docs index, immediately after "Start here," with two cards linking to Migrating from Anthropic Enterprise and Migrating from OpenAI Enterprise.
  • New paragraph on Audit ledger framing tenantId as an opaque rollup axis — end customer in a SaaS, or employee / team / cost-center in an internal-use enterprise deployment — with cross-links to both migration docs.

Changed

  • Migrating from Anthropic Enterprise opener widened from "end customers inside a Workspace" to "a meaningful axis inside a Workspace" (covering employees, teams, and cost centers in internal-use deployments), plus a shape-note paragraph that the same row, hash chain, and fingerprint cover both shapes; tenantId is opaque. Frontmatter description updated to match.
  • Migrating from OpenAI Enterprise opener and frontmatter description widened analogously for the OpenAI Projects case.
  • Homepage metadata.keywords extended with Anthropic Enterprise, OpenAI Enterprise, per-end-user cost rollup, per-employee LLM chargeback, internal AI cost attribution, Workspace tenant attribution, Project tenant attribution.

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.
  • [Pleach:capability-not-contributed] breadcrumb section with the 5 emitting capabilities and the payload shape.
  • CreatePleachRuntimeConfig.host.{strategies, modules, raw} section in Host adapter with the 15-key HostExtensionBundle list, the 3-key host.modules list (eventLogWriter, store, interrupt), the merge precedence, and the pleach-plugin-modernize codemod invocation.
  • bag-entry-retirement-readiness audit status table — streamHelpers RETIRED, toolCoupling RETIRE-READY, fabricationGuard NEAR-READY.
  • 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), payload shapes, and the 3-batch clean condition of audit:c9-hash-chain-integrity.
  • @pleach/coding-agent/runtime contract section in Coding agent with the typed CodingAgentRuntime interface and the per-method first-slice behavior.
  • @pleach/core/inspector row in Subpath exports.
  • @pleach/sandbox row in Packages (Phase A contract + in-memory fixture, version 0.1.0).
  • This changelog page.

Changed

  • Packages table corrected to real published versions (was largely stale "Reserved · placeholder" for shipping packages). New bucket framing: Published 1.x (@pleach/core 1.1.0, @pleach/tools 1.2.0, @pleach/react 1.0.0) / Pre-1.0 release (@pleach/replay 0.7.0, @pleach/base-tools 0.1.0, @pleach/sandbox 0.1.0, @pleach/langchain 0.1.0) / Pre-1.0 alpha (@pleach/compliance, @pleach/eval, @pleach/gateway all 0.8.0-alpha.0; @pleach/mcp 0.3.0-alpha.0; @pleach/coding-agent 0.2.0-alpha.0) / Reserved (@pleach/trust-pack only).
  • Plugin contract "Sibling SKUs as plugins" section retitled (was "(planned shape; not yet shipping)") and rewritten with per-row real Phase A status.
  • @pleach/replay Phase B note now distinguishes the landed replayTurn body from the still-throwing fromSnapshot / fork / multiTenantAggregate.
  • Fabrication detection plugin- supplied strategies subsection now references the typed FabricationGuardImpl hook.

Fixed

  • Runtime inspector — replaced fictional RuntimeInspection / CapabilityState types with the real InspectionReport / CapabilityReport / PluginReport / CapabilityDescriptor. Removed the invented top-level breadcrumbs field (the inspector is read-only; breadcrumbs are emitted from PluginManager, not pre-computed by the inspector). Corrected the status discriminator to "wired" | "deprecated-wired" | "unwired".
  • Plugin contractdefinePleachPlugin capability fields take values, not thunks. Corrected the 8 capability keys to the real cluster (prompts, runtimeAwarePrompts, safetyPolicies, fabricationDetectors, tools, streamObservers, intentToolMap, toolCouplingHints). Corrected contributeFabricationGuard to return one FabricationGuardImpl (not the fictional FabricationGuardContribution). Corrected the 5 breadcrumb capabilities to contributeStreamObservers, contributeSafetyPolicies, contributeFabricationDetectors, contributeToolCouplingHints, contributeIntentToolMap.
  • Host adapterhost.modules corrected to { eventLogWriter, store, interrupt }. host.strategies populated with the real 15-key HostExtensionBundle list. Codemod invocation corrected to node scripts/codemods/pleach-plugin-modernize.mjs <glob> (it's an internal repo script, not a published npm binary).
  • Tamper-evident hash chain — subpath corrected from @pleach/core/event-log to @pleach/core/eventLog (camelCase is the real export). C9 probe names corrected from the fictional [Pleach:c9-hash-chain] to the real [UXParity:c9-hash-chain-row-stamp] and [UXParity:c9-hash-chain-verify].
  • 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).
  • Subpath exports — inspector row's type names corrected from RuntimeInspection to the real InspectionReport, CapabilityReport, PluginReport, CapabilityDescriptor.

On this page