# Changelog — combined view (legacy) (/docs/changelog/combined)



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`](/docs/changelog) — each one excerpts the
entries below that materially touched its docs surface.

The mirror copy at
[`/CHANGELOG.md`](https://github.com/pleachhq/getpleach/blob/main/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](https://keepachangelog.com/en/1.1.0/).

## Unreleased [#unreleased]

### Added [#added]

* **Mermaid flowcharts now render as diagrams.** Twelve `mermaid`
  fenced blocks across seven pages — including the
  [Overview](/docs/overview) "mental model", [Architecture](/docs/architecture),
  [Turn lifecycle](/docs/turn-lifecycle), [Determinism](/docs/determinism),
  [Family lock](/docs/family-lock), [Config manifest](/docs/config-manifest),
  and [Replay](/docs/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 [#changed]

* **Two hand-drawn ASCII diagrams converted to Mermaid.** The build
  pipeline on [Supply-chain risk & SBOM](/docs/use-cases/government/scrm-and-sbom)
  and the reference architecture on
  [Air-gapped architecture](/docs/use-cases/government/air-gapped-architecture)
  were box-drawing text; both now render as Mermaid diagrams. Node text
  is preserved verbatim — no claim change.

### Fixed [#fixed]

* **Two family-cascade diagrams used an invalid Mermaid arrow.** The
  "no crossover to the other family" edge on
  [Architecture](/docs/architecture) and [Family lock](/docs/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 [#added-1]

* **[Comparison](/docs/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`](/docs/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](/docs/auditable-call-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`](/docs/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`](/docs/observe),
  [adoption paths](/docs/adoption-paths), and
  [BYOK observability](/docs/recipes/byok-observability). The
  `ObserveRow`-is-a-strict-subset-of-`AuditableCall` runway claim is the
  figure caption.

* **[`/investors`](/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](/docs/architecture#the-execution-graph-cluster) and
  [Concept clusters](/docs/concept-clusters#execution-graph-cluster) 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](/docs/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](/docs/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](/docs/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](/docs/skills) updated to import `SkillLoader`,
  `parseSkillFrontmatter`, `Skill`, and `SkillFrontmatter` from the
  `@pleach/core/skills` barrel (no `/loader`, `/parser`, `/types`
  sub-subpaths); [Agents](/docs/agents) prose corrected from
  "wildcard path" to a real emitted `@pleach/core/agents/types` subpath.

### Changed [#changed-1]

* **`@pleach/core/internal/…` subpaths retired from the public docs
  surface** (pkgclean 06 D8). [streamSingleTurn](/docs/stream-single-turn)
  and [Subpath exports](/docs/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`](/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 [#fixed-1]

* **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/&#x60;) 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](/docs/customer-support-agent),
  [internal-knowledge-agent](/docs/internal-knowledge-agent),
  [regulated-domain-agent](/docs/regulated-domain-agent),
  [region-pinned-agent](/docs/region-pinned-agent),
  [cloud-routed-agent](/docs/cloud-routed-agent&#x29;); **`OrchestratorRegistry`
  shape** — [langchain](/docs/langchain)'s `setOrchestratorRegistry({
  tools })` rewritten to the ergonomic `definePleachPlugin`
  `contributeTools&#x60; path; &#x2A;*`WithTenantHeaderOptions`** —
  `withTenantHeader(fetch, { runtime, header })` corrected to `{ header,
  tenantId }` ([multi-tenant](/docs/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 (`configProjection` →
  `session.created`; `messageProjection` → `message.user` /
  `message.assistant` / `content.delta`; `toolCallProjection` →
  `tool.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? }`; `HarnessEventReader` →
  `HarnessEventLogReader`; the fabricated pre-filter `selector` replaced
  with the real post-fold `finalize`. *audit-ledger*: `TamperEvidence` →
  `link` / `verifySequence` / `schemeId` (sync); `PIIRedactor` →
  `redact(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 `halt` → `stop`;
  `definePromptPlugin` → `definePromptsPlugin`. *hash-chain*: `prev_hash`
  is the prior `row_hash` copied verbatim; `created_at` →
  `sequence_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:
  `SectionContributor` → `PromptContribution`; 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&#x60;-shaped payload — none of which exist. The real hook is
  &#x2A;*`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&#x60; envelope), and decisions are an
  &#x2A;*`ApprovalDecision`** (`{ approved, note?, modifiedArguments? }`).
  Rewrote both usages: [interrupts](/docs/interrupts) now shows the
  `useInterruptUI` handler pattern, and [platform recipes](/docs/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](/docs/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.** &#x2A;Recipes:* `observableChatbot({ serviceName })` takes no
  `subagent` field — the row label is `observeSubagent(serviceName)`, and the
  disable switch is `serviceName: false`
  ([Pleach recipes](/docs/recipes-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](/docs/recipes/byok-observability),
  [observable chatbot](/docs/recipes/observable-chatbot)). &#x2A;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](/docs/facets)). &#x2A;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](/docs/graph), [nodes](/docs/nodes)). The `reasoning` seam is
  **reserved/planned** — the default runtime has no live consumer routing
  through it ([seams](/docs/seams)). &#x2A;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](/docs/interrupts)). &#x2A;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](/docs/query)).
  Subagent provenance is `delegated_from`, not `used_result_of`
  ([lineage](/docs/lineage)). &#x2A;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](/docs/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](/docs/runtime-construction));
  an absent `providerFallback` loader &#x2A;*throws `MODULE_NOT_FOUND`** rather
  than falling through a built-in chain ([runtime strategies](/docs/runtime-strategies));
  and a custom `streamSingleTurn` body registers through the global
  module-loader seam, not a `SessionRuntimeConfig` strategy slot
  ([stream single turn](/docs/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`](/docs/family-lock) 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`](/docs/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`](/docs/event-log), 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`](/docs/graph); `CallClass` /
  `ProviderFamily` → `@pleach/core/modelfamily`; `ProviderMessage` / `ProviderToolDef`
  (and the sibling provider types) → [`@pleach/core/providers`](/docs/providers);
  `FabricationDetector` / `FabricationDetectorContext` / `FabricationFinding` /
  `SanitizerPass` / `FinalizationPassContext` / `PluginGraphNodeRegistration` /
  `PluginGraphNodeContext` / `composePlugin` →
  [`@pleach/core/plugins`](/docs/plugin-contract); `StreamObserverRegistration` →
  `@pleach/core/plugins/stream`; `Scrubber` → [`@pleach/core/scrubbers`](/docs/scrubbers);
  `EventLogRow` → [`@pleach/core/eventLog`](/docs/event-log); `MemoryProviderDecisionLedger`
  → [`@pleach/core/audit`](/docs/audit-ledger); the guest-interrupt bus helpers
  (`setGuestInterruptStore` / `publishInterruptRequest` / `popInterruptRequest` /
  `recordInterruptDecision` / `waitForInterruptDecision`) → `@pleach/core/guestInterruptBus`;
  `ToolDefinition` → `@pleach/core/types/generic`; `ConnectivityMonitor` →
  [`@pleach/core/sync`](/docs/sync); and the BYOK gateway helpers
  (`createCredentialRoutingMiddleware` → [`@pleach/gateway`](/docs/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`](/docs/event-log); 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 `declare`s the proposed helper.

* **mcp / sandbox / coding-agent / replay doc pages reconciled with the shipped
  surface (devharness FINDING 94–103).** [MCP](/docs/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](/docs/coding-agent): the `@pleach/sandbox` peer-dep is `^0.1.0`
  (was `^1.0.0`). [Sandbox](/docs/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](/docs/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](/docs/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](/docs/eval): cross-mode buckets are `interactive`/`headless-eval`/`headless-replay`
  (not `production`/`replay`/`eval-noncached`). [Replay](/docs/replay): eval-coupling is
  `new EvalSuite({ suiteId, runtime })` + `suite.setReplayClient(replay)` (no `replay`
  ctor field; `suiteId` required). [Determinism](/docs/determinism): ledger read is
  `await ledger.getSession(sessionId)` (not `ledger.list({ sessionId })`), and `runtimeMode`
  distinguishes **five** contracts (not three). [OTel observability](/docs/otel-observability):
  `executeMessage(sessionId, "hello")` is positional. [Stream events](/docs/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](/docs/fabrication-detection) custom-detector
  example (no `ctx.toolArgs`; real `FabricationFinding` = `{detectorId, severity, reason,
  evidence?}`, no `suspect`/`tier`); [Multi-tenant](/docs/multi-tenant) `getAggregateUsage`
  is 3-positional `(client, store, filters)`, no `groupBy:"tenantId"`, dates under
  `dateRange`, requires `userId`; [Determinism](/docs/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](/docs/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](/docs/session-runtime)
  config table gains `eventLogWriter` + `eventReader`; [Storage](/docs/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](/docs/building-chat-ui) fabricated a
  `@pleach/react` chat-hook API (`useChat`/`HarnessProvider` from root,
  `useInterruptDecision`, `useChatVercelCompat`, `sendMessage`) → corrected to the real
  surface. [LangChain](/docs/langchain): `LangChainProvider` positional ctor + top-level
  `provider:` slot. [Base tools](/docs/base-tools): scratchpad is per-session, param
  `operation`, string value. [Coding agent](/docs/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](/docs/otel-observability) + [Observability](/docs/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](/docs/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](/docs/subagents): dropped the fabricated `spawnsSubagent` flag;
  `LightweightRuntime` → `LightweightSessionRuntime` 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](/docs/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](/docs/session-lifecycle), [SessionRuntime](/docs/session-runtime),
  [turn lifecycle](/docs/turn-lifecycle), [API routes](/docs/api-routes). And
  [resuming a session](/docs/session-lifecycle#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](/docs/family-lock)) and
  `@pleach/core/ai/modelFamily/matrix.ts` ([quickstart](/docs/quickstart),
  [provider detection](/docs/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/plugins/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](/docs/time-travel) (`fork` sets
  `parent_id: source.id`), [Checkpointing](/docs/checkpointing) (message/event-boundary
  checkpoints discriminated by `CheckpointMetadata.source`, no per-stage `stageId`;
  `SupabaseSaver` `"replicated"`; rollback `source: "manual"`; string `fork` arg),
  [Session lifecycle](/docs/session-lifecycle) (checkpoint snapshot authoritative;
  event-log canonical reader is a flag-gated shadow), [Sync](/docs/sync) (interactive
  conflict resolution / `sync.conflict` / 3xxx codes are enterprise-tier/planned;
  open-core is `SyncCoordinator` last-writer-wins-on-push), [Query](/docs/query)
  (dropped non-existent `queryAuditableCalls`; fixed `getChatUsage` /
  `lookupModelCost` / `getSessionReview` / `getInterruptChain` sigs+shapes),
  [Memory](/docs/memory) (graph-node extraction path is production, not the
  `memoryExtractionHook` → queue pipeline; `LearnedFact.source` string+object), and
  [Lineage](/docs/lineage) (opt-in via `config.lineageTracker`; runtime records the
  node + `branched_from` fork edge, other relations host-recorded; `completeSession`
  host-called).

### Added [#added-2]

* **[Landscape](/docs/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](/docs/auditable-call-row), [deterministic
  replay](/docs/determinism) + [family-lock](/docs/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](/docs/comparison).

* **[Family-locked routing](/docs/family-lock) 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](/docs/landscape) page.

* **[Comparison](/docs/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](/docs/recipes/agent-instrumentation)** —
  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](/docs/recipes/observable-chatbot) (recipe
  wrapper) and [BYOK observability](/docs/recipes/byok-observability)
  (no-`@pleach/core` brownfield path). Registered in
  [`meta.json`](/docs/recipes) and the llms.txt Recipe-walkthroughs
  group.

* **["Live lifecycle events" on observable-chatbot](/docs/recipes/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](/docs/ci-enforcement)** —
  new Reference page indexing the [audit-gate
  catalog](/docs/audit-gates) 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](/docs/audit-gates).

* **[Contribution namespaces](/docs/plugins/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](/docs/plugin-contract).

* **[Config manifest](/docs/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](/docs/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](/docs/emitted-data)** —
  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](/docs/event-log) (stamping section + `EventLogRow`
  field) and [Schema](/docs/schema) (rolling-out
  `harness_config_manifest` section).

* **MCP Server Card (SEP-1649) at
  [`/.well-known/mcp/server-card.json`](/.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`](/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`](/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`](/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](/sitemap.xml),
  [`llms.txt`](/llms.txt), [`llms-full.txt`](/llms-full.txt),
  per-page `.md` twins via `Accept: text/markdown`,
  [`robots.txt`](/robots.txt), [`ai.txt`](/ai.txt),
  [`/api-catalog`](/api-catalog) (RFC 9727), and RFC 8288 `Link`
  headers — is what an agent actually needs to crawl the docs
  effectively.

* **[Node catalog](/docs/graph-node-catalog) and
  [Edge catalog](/docs/graph-edge-catalog) reference pages,
  slotted into the Architecture sidebar after
  [Channels](/docs/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](/docs/graph-node-catalog) and
  [Edge catalog](/docs/graph-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](/docs/ownership) page, slotted into
  the Get Started sidebar after [Which SKU do I need?](/docs/which-sku).**
  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](/docs/graph#the-lattice-gate)
  and the [`AuditableCall`](/docs/auditable-call-row) 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?](/docs/which-sku) (task → install list)
  and [Plugin contract](/docs/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](/docs/auditable-call-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](/docs/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](/docs/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](/docs/observability) gains an "Extending
  observability — plugin hooks" section surfacing
  `contributeStreamObservers` and `contributeFinalizationPasses`;
  (5) [`@pleach/mcp`](/docs/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](/docs/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 [#fixed-2]

* **[AuditableCall row](/docs/auditable-call-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](/docs/plugin-contract)** on [Install](/docs/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`](/docs/base-tools),
  [`@pleach/observe`](/docs/observe),
  [`@pleach/compliance`](/docs/compliance),
  [`@pleach/compliance-contract`](/docs/compliance),
  [`@pleach/gateway`](/docs/gateway),
  [`@pleach/mcp`](/docs/mcp), and
  [`@pleach/recipes`](/docs/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`](/docs/core), [`@pleach/tools`](/docs/tools),
  [`@pleach/eval`](/docs/eval), [`@pleach/replay`](/docs/replay),
  [`@pleach/sandbox`](/docs/sandbox),
  [`@pleach/coding-agent`](/docs/coding-agent), and
  [`@pleach/react`](/docs/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`](/docs/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](/docs/glossary#p) 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](/docs), the
  [overview](/docs/overview), and the
  [audit ledger](/docs/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](/docs/auditable-call-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](/docs/replay) (which uses *branch* generically and
  was already metaphor-safe).

### Removed [#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](/docs/compliance)
  and [Architecture](/docs/architecture), which the deleted
  pillars linked to anyway. The [Agent shapes](/docs/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 [#changed-2]

* **`@pleach/observe` repositioned from shipping to alpha across the
  site.** [Packages](/docs/packages), the docs home, and
  [Which SKU](/docs/which-sku) had listed it at `0.1.0 · npm`;
  [`@pleach/observe`](/docs/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](/docs/packages).

* **[Which SKU](/docs/which-sku) persona section rewritten to named
  archetypes.** Internal persona codes became plain audience shapes.

* **[What's new — June 2026](/docs/whats-new-2026-06) 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](/docs/graph), [Node catalog](/docs/graph-node-catalog),
  [Edge catalog](/docs/graph-edge-catalog), [Nodes](/docs/nodes),
  [Architecture](/docs/architecture),
  [Ownership boundaries](/docs/ownership), and
  [Plugin contract](/docs/plugin-contract);
  [Audit gates](/docs/audit-gates) gains graph + config-manifest
  gate rows. [Node catalog](/docs/graph-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](/docs/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](/docs/plugins/authoring) informal
  "12 buckets" reframed as the scan view of the canonical nine
  namespaces.** The at-a-glance hook grouping now points at
  [Contribution namespaces](/docs/plugins/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](/docs/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](/docs/graph-node-catalog),
  [Edge catalog](/docs/graph-edge-catalog)) as the enumerated
  references.

* **Schema [`@pleach/core`](/docs/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`](https://getpleach.com/ai.txt). The description now
  names the wire shapes — HTTP+SSE, `StreamEvent`,
  [`AuditableCall`](/docs/auditable-call-row),
  [`Checkpoint`](/docs/checkpointing), 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](/docs/language-agnostic-contract)
  for the full wire-shape inventory.

* **[`/llms.txt`](https://getpleach.com/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 [#added-3]

* **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`](https://getpleach.com/llms.txt) +
  [`/ai.txt`](https://getpleach.com/ai.txt) +
  [`/.well-known/api-catalog`](https://getpleach.com/.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](/docs/glossary#p)'s `P` section. The homepage
  hero and the [docs index](/docs) 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](/docs/comparison) carries the
  pot-and-stakes-vs-lattice contrast right under the lede;
  [Audit ledger](/docs/audit-ledger) adds "the lattice
  carrying weight — every branch lands in a row at the same
  grain" after the stage walkthrough;
  [`@pleach/replay`](/docs/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 components** —
  `StatusBadge` (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`](/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`](/docs/auditable-call-row) converts
  all five sub-shape tables (Identity, Principal, Call, Decision,
  Outcome) into `<TypeTable>` blocks.
  [`/docs/stream-events`](/docs/stream-events) and
  [`/docs/env-vars`](/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`](/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`](/docs/migrating-from-ai-sdk) and
  [`/docs/migrating-from-langchain`](/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 [#changed-3]

* **[`/docs/replay`](/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/overview),
  [`/docs/architecture`](/docs/architecture),
  [`/docs/determinism`](/docs/determinism),
  [`/docs/family-lock`](/docs/family-lock), and
  [`/docs/turn-lifecycle`](/docs/turn-lifecycle).

* **Four SKU placement pages** — [`/docs/sandbox`](/docs/sandbox),
  [`/docs/transport-bedrock`](/docs/transport-bedrock),
  [`/docs/transport-azure-openai`](/docs/transport-azure-openai),
  and [`/docs/transport-vertex`](/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`](/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`](/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`](/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`](/docs/transport-azure-openai),
  [`transport-bedrock`](/docs/transport-bedrock), and
  [`transport-vertex`](/docs/transport-vertex).
  [`sandbox`](/docs/sandbox) slots into `Bundled packages`
  after `base-tools`.

### Changed [#changed-4]

* **[`/docs/session-runtime`](/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`](/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 cases` → `Agent patterns`.**
  Same six pages
  ([`customer-support-agent`](/docs/customer-support-agent) …
  [`regulated-domain-agent`](/docs/regulated-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`](/docs/recipes) lead** — count flipped
  `Nine` → `Ten` and the inline name list extended to include
  the regulated-host end-to-end recipe.

### Fixed [#fixed-3]

* **[`/docs/plugin-authoring-standards`](/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 [#added-4]

* **Rank-2 per-recipe deep-dive pages** — four additional
  pages under [`/docs/recipes/`](/docs/recipes/simple-chatbot)
  covering the recipes excluded from the prior six because
  their peer SKUs were outside the first-publish wave:
  [`observableChatbot`](/docs/recipes/observable-chatbot)
  (composes `@pleach/observe`),
  [`instrumentedCodingAgent`](/docs/recipes/instrumented-coding-agent)
  (composes `@pleach/coding-agent` + `@pleach/sandbox` +
  `@pleach/observe`),
  [`enterpriseAgent`](/docs/recipes/enterprise-agent)
  (composes `@pleach/compliance` + `@pleach/observe`, surfaces
  the procurement-visible `ENTERPRISE_PERMITTED_FAMILIES_TAG`
  envelope a gateway-aware host reads), and
  [`evalLab`](/docs/recipes/eval-lab) (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/`](/docs/recipes/simple-chatbot)** — six new
  pages covering the first-publish wave (`@pleach/core`,
  `@pleach/tools`, `@pleach/compliance`, `@pleach/gateway`) and
  the brownfield observability SDK:
  [`simpleChatbot`](/docs/recipes/simple-chatbot),
  [`ragChatbot`](/docs/recipes/rag-chatbot),
  [`compliantChatbot`](/docs/recipes/compliant-chatbot),
  [`verticalAgent`](/docs/recipes/vertical-agent),
  [`subagentSwarm`](/docs/recipes/subagent-swarm), and
  [`BYOK observability`](/docs/recipes/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`](/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`](/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`](/.well-known/api-catalog)
  (`rel="api-catalog"`), [`/docs`](/docs) (`rel="service-doc"`),
  [`/llms.txt`](/llms.txt) (`rel="alternate"; type="text/markdown"` —
  the markdown twin of `/` under content negotiation),
  [`/ai.txt`](/ai.txt) (`rel="describedby"`),
  [`/sitemap.xml`](/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`](/.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 [#changed-5]

* **Markdown-for-Agents on the homepage** — `/` with
  `Accept: text/markdown` now rewrites to
  [`/llms.txt`](/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.

* **[`/pricing`](/pricing)** — &#x2A;Two 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`](/faq) and [`/docs/faq`](/docs/faq)** — &#x2A;Is 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.

* **[`/pricing`](/pricing)** — *What stays free, and what doesn't*
  rewritten as &#x2A;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`](/faq) and [`/docs/faq`](/docs/faq)** — &#x2A;Is 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 [#added-5]

* **[`@pleach/observe`](/docs/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](/docs/auditable-call-row)
  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`](/docs/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`](/docs/gateway).

* **[Adoption paths](/docs/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](/docs/migrating-from-ai-sdk),
  [LangChain](/docs/migrating-from-langchain),
  [Anthropic Enterprise](/docs/migrating-from-anthropic-enterprise),
  [OpenAI Enterprise](/docs/migrating-from-openai-enterprise))
  sit downstream of.

* **[Packages](/docs/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`](/docs/packages) (placeholder,
  no contract published) from [`@pleach/observe`](/docs/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`](/docs/gateway), and
  [Adoption paths](/docs/adoption-paths) at the top of
  Compose & migrate ahead of the migrating-from-\* pages.

* **[Attestation](/docs/attestation)** — new top-level page on
  the Ed25519-signed envelope substrate that sits on top of the
  [hash chain](/docs/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`](/docs/compliance) or host-side. Slotted
  into the Tamper evidence cluster directly after
  [Hash chain](/docs/hash-chain).

* **[Audit gates](/docs/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](/docs/subpath-exports).

* **[Project layout](/docs/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`](/docs/session-runtime)
  per process, a chosen [`ProviderDecisionLedger`](/docs/audit-ledger),
  a [host adapter](/docs/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](/docs/customer-support-agent),
  [research](/docs/research-agent), [coding](/docs/coding-agent),
  [internal knowledge](/docs/internal-knowledge-agent),
  [multi-tenant SaaS](/docs/multi-tenant-saas-agent),
  [regulated domain](/docs/regulated-domain-agent)) via a
  `<Cards>` block; points at the three filesystem-touching
  [recipes](/docs/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](/docs/agents) is a
  channel-path string, not a directory). Slots into a new
  Project layout sidebar cluster between
  [Getting started](/docs/getting-started) and
  [Agent shapes](/docs/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](/docs/customer-support-agent#project-layout),
  [Research](/docs/research-agent#project-layout),
  [Coding agent](/docs/coding-agent#project-layout),
  [Internal knowledge](/docs/internal-knowledge-agent#project-layout),
  [Multi-tenant SaaS](/docs/multi-tenant-saas-agent#project-layout),
  [Regulated domain](/docs/regulated-domain-agent#project-layout).
  Each shows the same baseline tree from
  [Project layout](/docs/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](/docs/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 [#changed-6]

* **Cross-docs status-flip pass** — rolling correction across
  \~55 docs pages tracking the alpha-ship of
  [`@pleach/compliance`](/docs/compliance),
  [`@pleach/gateway`](/docs/gateway), and
  [`@pleach/replay`](/docs/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](/docs/audit-ledger),
  [Compliance](/docs/compliance), [Gateway](/docs/gateway),
  [Replay](/docs/replay), [Hash chain](/docs/hash-chain),
  [Eval and replay](/docs/eval-and-replay),
  [Event log](/docs/event-log),
  [Event-log projections](/docs/event-log-projections),
  [Subpath exports](/docs/subpath-exports),
  [Seams](/docs/seams), [Prompts](/docs/prompts),
  [Prompt builder](/docs/prompt-builder),
  [Session runtime](/docs/session-runtime),
  [Recipes](/docs/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](/docs/project-layout)** — corrected the
  multi-tenant card description. Originally read "One runtime
  per process serves many tenants"; the
  [use-case page](/docs/multi-tenant-saas-agent#per-tenant-runtime-construction)
  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](/docs/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`](/docs/cli#pleach-schema--copy-the-sql-bundle);
  [`pleach init`](/docs/cli#pleach-init--the-wizard) 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 [#added-6]

* **[CLI — `pleach init` wizard](/docs/cli#pleach-init--the-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`](/docs/cli#pleach-schema--copy-the-sql-bundle)** —
  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](/docs/cli#project-layout--after-the-wizard)** —
  matches the per-use-case layout sections added in the prior
  pass. Shows the [baseline](/docs/project-layout#a-layout-that-works)
  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`](/docs/subpath-exports)** —
  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](/docs/getting-started#the-quickstart-subpath)** —
  new section after the existing
  [Shortest-path quickstart — `createPleachRuntime`](/docs/getting-started#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`](/docs/getting-started#shortest-path-quickstart--createpleachruntime)
  (substrate), `createPleachRoute` (HTTP), and the bare
  [`SessionRuntime`](/docs/session-runtime) constructor (custom
  transport / multi-tenant). Voice-aligned: failure modes named
  at mechanism, not vibes.

### Changed [#changed-7]

* **[CLI](/docs/cli)** — wizard-section cross-links retargeted
  from
  [Shortest-path quickstart](/docs/getting-started#shortest-path-quickstart--createpleachruntime)
  (a related but different surface) to
  [The quickstart subpath](/docs/getting-started#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](/docs/getting-started#scaffold-a-new-project)** —
  the second instance of the stale `pleach init` claim that
  [CLI](/docs/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`](/docs/cli#pleach-init--the-wizard) for
  the framework matrix and walkthrough.

### Fixed [#fixed-4]

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

### Changed [#changed-8]

* **[Pricing](/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
  &#x2A;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 &#x2A;No enterprise tier, no
  hosted-only features.* → &#x2A;No procurement-style enterprise
  tier; paid surfaces won't gate runtime features.* Aligns the
  headline-scale claim with the [Pricing](/pricing) revision.
* **[FAQ → Is there a hosted version?](/docs/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-runtime*
  → *fair-source agent-runtime*. Restores the labeling-discipline
  qualifier the rest of the site already carries.

### Added [#added-7]

* **[Security → Deployment shape](/security)** — 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 [#2026-06-08--canonical-contact-collapsed-to-a-single-inbox]

### Changed [#changed-9]

* **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](/security) page and the security-disclosures channel
  on [Community](/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](/security),
  [Privacy](/legal/privacy), [Terms](/legal/terms),
  [License](/license), [Pricing](/pricing),
  [Community](/community), [FAQ](/faq), the [docs FAQ](/docs/faq),
  the [contributing guide](/docs/contributing), the blog RSS feed,
  and `/ai.txt`.

## 2026-06-08 — chat-pipeline lift into `@pleach/core` + `audit:domain-string-purity` Pre-Merge Gate [#2026-06-08--chat-pipeline-lift-into-pleachcore--auditdomain-string-purity-pre-merge-gate]

### Added [#added-8]

* **[OrchestratorClient](/docs/orchestrator-client)** — 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`](/docs/session-runtime) and
  [`Providers`](/docs/providers). Pairs with the
  `audit:orchestrator-facet-coverage` CI gate already documented
  at [Facets](/docs/facets#ci-gates-enforcing-facet-coverage).
* **[streamSingleTurn](/docs/stream-single-turn)** — 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`](/docs/runtime-strategies#newer-injection-hooks),
  `continuationMetaToolNames`, `repetitionGuard`,
  `orchestrator.providers.providerFallback`,
  `EMPTY_SINGLE_TURN_FLAGS`), what it never sees (the five
  forbidden literal categories the
  [domain-string purity gate](/docs/architecture#10-boundary-rules)
  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`](/docs/runtime-strategies).
* **[Subpath exports](/docs/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](/docs/architecture#10-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](/docs/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 [#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`](/docs/architecture#10-boundary-rules)
(the import-side companion); the string-side gate is a structural
guarantee the docs now name alongside it.

## 2026-06-08 — page-level restructuring (splits, renames, related-shapes nav) [#2026-06-08--page-level-restructuring-splits-renames-related-shapes-nav]

### Added [#added-9]

* **[Platform & operations recipes](/docs/platform-recipes)** —
  extracts four platform-team recipes from
  [Recipes](/docs/recipes) (long-running async jobs, multi-step
  [interrupts](/docs/interrupts), per-call cost reporter,
  OpenTelemetry wiring) into a dedicated page under the
  Operations sidebar group. Lets a consumer reader on
  [`/docs/recipes`](/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](/docs/runtime-strategies)** — extracts
  the \~140-line *Strategy injection* section from
  [SessionRuntime](/docs/session-runtime) (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](/docs/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](/docs/customer-support-agent),
  [Research](/docs/research-agent),
  [Coding](/docs/coding-agent),
  [Internal knowledge](/docs/internal-knowledge-agent),
  [Multi-tenant SaaS](/docs/multi-tenant-saas-agent), and
  [Regulated-domain](/docs/regulated-domain-agent&#x29; 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.,
  &#x2A;"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 [#changed-10]

* **[Examples](/docs/reference-apps) reframed and renamed to
  [Reference apps](/docs/reference-apps).** The duplicated
  *Agent shapes* and *Recipes* hub sections (word-for-word
  repeats of [Agent shapes](/docs/agent-shapes) and
  [Recipes](/docs/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`](/docs/reference-apps); inbound links
  on [Getting started](/docs/getting-started),
  [`@pleach/base-tools`](/docs/base-tools), and the prior
  changelog entry are repointed.
* **Sidebar reorder in the Start group:**
  [Getting started](/docs/getting-started) →
  [Agent shapes](/docs/agent-shapes) →
  [Recipes](/docs/recipes) →
  [Reference apps](/docs/reference-apps) →
  [Comparison](/docs/comparison&#x29;. Brings the &#x2A;"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](/docs/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](/docs/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](/docs/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](/docs/platform-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](/docs/session-runtime) shrunk** from 472
  lines to \~330. The *Strategy injection* section is now a
  one-paragraph framing + pointer at
  [Runtime strategies](/docs/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 [#2026-06-08--docs-de-dup--dx-ordered-sidebar]

### Changed [#changed-11]

* **Sidebar reorder** — reshuffled groups to a build → ship →
  internals walk. [Audit ledger](/docs/audit-ledger) lifts from
  group 10 to group 4 (right after [Composing agents](/docs/agents)),
  [Observability](/docs/observability) and
  [Operations](/docs/deployment) follow, [Frontend integration](/docs/react)
  becomes its own top-level group at 7, and the substrate
  internals ([Architecture](/docs/architecture), [Execution graph](/docs/graph),
  [Routing](/docs/seams), [Runtime lifecycle](/docs/session-lifecycle),
  [State](/docs/storage), [Safety](/docs/safety), [Plugins](/docs/plugin-contract))
  collapse into a contiguous internals block at groups 9–15.
  [Compose & migrate](/docs/migrating-from-anthropic-enterprise)
  drops to group 16 — it's an existing-stack on-ramp, not a first
  walk. No URLs change; only group ordering and labels (the
  `Core API` group becomes `Build an agent`, the lone
  [`plugin-contract`](/docs/plugin-contract) page gets its own
  `Plugins` group instead of riding under Composing agents).
  Fixes the encyclopedic-not-DX order the cluster groupings were
  producing — readers now reach the load-bearing audit-ledger
  story before the substrate deep-dives.
* **Cluster-host triplet sections collapsed to one-paragraph
  framings.** [Family lock → the routing cluster](/docs/family-lock#the-routing-cluster),
  [Audit ledger → the audit-ledger cluster](/docs/audit-ledger#the-audit-ledger-cluster),
  [Storage → the state-and-persistence cluster](/docs/storage#the-state-and-persistence-cluster),
  [Agents → the composing-agents cluster](/docs/agents#the-composing-agents-cluster),
  and [Session lifecycle → the runtime-lifecycle cluster](/docs/session-lifecycle#the-runtime-lifecycle-cluster)
  no longer restate the three-concept bullets that already live
  on [Concept clusters](/docs/concept-clusters). Each cluster
  anchor stays — sibling pages still link to it — but the section
  now carries one paragraph framing the triplet and pointing at
  the cluster map. Matches the lighter-weight pattern
  [Seams](/docs/seams) and [Call classes](/docs/call-classes)
  were already using.
* **[Architecture](/docs/architecture) trimmed from 486 lines to
  233.** Each of the per-piece sections (1. Stage lattice through
  9\. Determinism) reduces to a 2–3 sentence framing plus a pointer
  to the deep-dive page that owns the topic, instead of restating
  the full per-class table / cascade walk / event-log three-layer
  prose / facets inventory / channel-snapshot walk. The TL;DR
  mermaid, the six-piece numbered list, the stage-lattice mermaid,
  the family-strict cascade mermaid, the audit-ledger row-fan
  mermaid, and the unique-to-architecture
  [10. Boundary rules](/docs/architecture#10-boundary-rules)
  table all stay. Drops verbatim duplication of [Graph](/docs/graph),
  [Nodes](/docs/nodes), [Channels](/docs/channels),
  [Seams](/docs/seams), [Call classes](/docs/call-classes),
  [Family-locked routing](/docs/family-lock),
  [Audit ledger](/docs/audit-ledger),
  [The AuditableCall row](/docs/auditable-call-row),
  [Event log](/docs/event-log), [Cache](/docs/cache),
  [Facets](/docs/facets), [Storage](/docs/storage),
  [Sync](/docs/sync), [Plugin contract](/docs/plugin-contract),
  and [Determinism](/docs/determinism).
* **[Session lifecycle → Time-travel and rollback](/docs/session-lifecycle#time-travel-and-rollback)**
  reduced to the session-level invariants (audit rows never
  rolled back; subagent provenance preserved). The rollback
  mechanic and the rollback-vs-fork choice already live on
  [Checkpointing → Rolling back to a checkpoint](/docs/checkpointing#rolling-back-to-a-checkpoint);
  the prior 97% identical paragraph here was a copy-paste.
* **[Audit ledger → Tamper-evident hash chain](/docs/audit-ledger#tamper-evident-hash-chain)**
  reduced to one paragraph pointing at [Hash chain](/docs/hash-chain).
  The prior section restated the two-column contract, the
  back-compat policy, and the verification walk that the
  dedicated page already covers.
* **`audit:c8-event-type-allowlist-coverage` mentions** thinned
  to single-canonical home on [Scrubbers](/docs/scrubbers).
  [The AuditableCall row](/docs/auditable-call-row) lost a
  trailing *Event-type allowlist for redaction* section that
  purely restated the gate (the page already carries the
  Scrubbers card in its *Where to go next*).
  [Plugin contract → `contributeScrubbers`](/docs/plugin-contract#contributescrubbers)
  keeps one sentence naming the gate and pointing at scrubbers,
  instead of re-explaining its purpose.

## 2026-06-08 — sidebar + homepage label consistency [#2026-06-08--sidebar--homepage-label-consistency]

### Changed [#changed-12]

* **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](/docs/architecture#the-execution-graph-cluster)
  on architecture, [the routing cluster](/docs/family-lock#the-routing-cluster)
  on family-lock. No URLs change; only the separator labels.

## 2026-06-08 — concept-map closeout (three more triplets + map page) [#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 [#added-10]

* **Composing-agents cluster** (Skill + Subagent + Agent profile).
  New section on
  [Agents](/docs/agents#the-composing-agents-cluster). Sibling
  openers added to [Subagents](/docs/subagents) and
  [Skills](/docs/skills).
* **Runtime-lifecycle cluster** (Session lifecycle + Turn
  lifecycle + Event log). New section on
  [Session lifecycle](/docs/session-lifecycle#the-runtime-lifecycle-cluster).
  Sibling openers added to [Turn lifecycle](/docs/turn-lifecycle)
  and [Event log](/docs/event-log).
* **State-and-persistence cluster** (Storage adapter + Checkpoint
  * Sync version vector). New section on
    [Storage](/docs/storage#the-state-and-persistence-cluster).
    Sibling openers added to [Checkpointing](/docs/checkpointing)
    and [Sync](/docs/sync).
* **New [Concept clusters](/docs/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 [#changed-13]

* **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](/docs/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) [#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 [#added-11]

* **Execution-graph cluster (graph + node + channel).** New
  *The execution-graph cluster* section on
  [Architecture](/docs/architecture#the-execution-graph-cluster)
  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](/docs/graph), [Nodes](/docs/nodes), and
  [Channels](/docs/channels), each pointing at the new
  architecture anchor.
* **Routing cluster (CallClass + Seam + family-lock).** New
  *The routing cluster* section on
  [Family-locked routing](/docs/family-lock#the-routing-cluster),
  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](/docs/call-classes) and
  [Seams](/docs/seams). Reference-page pointers added to
  [Providers](/docs/providers) (transport layer) and
  [Model resolution matrix](/docs/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](/docs/audit-ledger#the-audit-ledger-cluster)
  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](/docs/auditable-call-row) and
  [Tamper-evident hash chain](/docs/hash-chain).

### Why [#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 [#2026-06-08--slow-ramp-entry-point-pass]

### Added [#added-12]

* **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](/docs/session-runtime),
  [Turn lifecycle](/docs/turn-lifecycle), and
  [The AuditableCall row](/docs/auditable-call-row).
* **[Docs index](/docs)*&#x2A;: opening rewritten to lead with
  &#x2A;"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 [#why-1]

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 [#2026-06-08--discovery--entry-point-depth-pass]

### Added [#added-13]

* **[`/llms.txt`](/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`](/ai.txt)** — new "High-signal entry points for
  enterprise readers" section naming both migration docs and
  [Language-agnostic contract](/docs/language-agnostic-contract).
* **[Overview](/docs/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](/docs/architecture) §5 Audit ledger** —
  paragraph after the identity-tuple claim connecting it to
  per-axis attribution inside one Workspace or Project.
* **[Getting started](/docs/getting-started)** — Enterprise
  callout after the server quick-start naming
  `AnthropicSdkProvider` and the AI SDK's OpenAI provider as the
  composition entry points.
* **[FAQ](/docs/faq)** — new entry "Does Pleach replace my
  Anthropic or OpenAI Enterprise contract?" before "Who's behind
  this?"
* **[Core](/docs/core)** "What you get" — new bullet
  "Composes under an existing Enterprise contract" after the
  AuditableCall ledger bullet.

### Changed [#changed-14]

* **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](/docs/agent-shapes)*&#x2A; 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)."
  &#x2A;(Originally on `/docs/examples`; that page was reframed as
  [Reference apps](/docs/reference-apps) on 2026-06-08, with the
  agent-shapes cards moved to their canonical home on
  `/docs/agent-shapes`.)*
* **[Pleach + OpenAI SDK](/docs/with-openai-sdk)*&#x2A; and
  &#x2A;*[Comparison](/docs/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&#x60;
  and the language-agnostic contract; load-bearing sentence
  &#x2A;"answers 'is this TypeScript-only?' before Enterprise IT asks"*
  preserved verbatim.

## 2026-06-08 — sibling-SKU references [#2026-06-08--sibling-sku-references]

### Added [#added-14]

* **Homepage Enterprise section** — two new paragraphs after the
  cloud-mediated transports note. First paragraph names
  [`@pleach/coding-agent`](/docs/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](/docs/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](/docs/migrating-from-anthropic-enterprise#sibling-skus-that-ride-alongside-the-contract)*&#x2A; and
  &#x2A;*[Migrating from OpenAI Enterprise](/docs/migrating-from-openai-enterprise#sibling-skus-that-ride-alongside-the-contract)** —
  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](/docs/comparison#if-you-already-buy-direct-from-anthropic-or-openai)
  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 [#2026-06-08--re-settling-pass]

### Added [#added-15]

* **Marketing surface.** New CostRow body on
  [Pricing](/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](/faq) page.
* **Docs adjacency.** Enterprise-contract bridge paragraphs added
  to [Pleach + Anthropic SDK](/docs/with-anthropic-sdk) and
  [Pleach + OpenAI SDK](/docs/with-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](/docs/multi-tenant) and
  [The AuditableCall row](/docs/auditable-call-row), plus a
  `GatewayClient`-per-cost-center note on
  [Gateway](/docs/gateway#tenant-scoping).

### Changed [#changed-15]

* **Sidebar reorder.** The "Migrate & coexist" group now opens
  with the two enterprise migration docs
  ([Migrating from Anthropic Enterprise](/docs/migrating-from-anthropic-enterprise),
  [Migrating from OpenAI Enterprise](/docs/migrating-from-openai-enterprise))
  above [Migrating from the AI SDK](/docs/migrating-from-ai-sdk)
  and [Migrating from LangChain](/docs/migrating-from-langchain).
* **[Agent shapes](/docs/agent-shapes) shape 04*&#x2A; renamed from
  &#x2A;"Per-customer cost attribution"&#x2A; to &#x2A;"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](/docs/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](/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 [#fixed-5]

* **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 [#2026-06-08--later]

### Added [#added-16]

* 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`](/docs/auditable-call-row) 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](/docs/comparison#if-you-already-buy-direct-from-anthropic-or-openai),
  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](/docs), immediately after "Start
  here," with two cards linking to
  [Migrating from Anthropic Enterprise](/docs/migrating-from-anthropic-enterprise)
  and
  [Migrating from OpenAI Enterprise](/docs/migrating-from-openai-enterprise).
* New paragraph on
  [Audit ledger](/docs/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 [#changed-16]

* [Migrating from Anthropic Enterprise](/docs/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](/docs/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 [#2026-06-08]

### Added [#added-17]

* New page [Runtime inspector](/docs/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](/docs/plugin-contract#definepleachplugin--the-typed-factory)
  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](/docs/host-adapter#createpleachruntimeconfighoststrategies-modules-raw)
  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](/docs/hash-chain#c9-probes--proof-the-writer-is-reaching-prod)
  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](/docs/coding-agent#pleachcoding-agent-runtime-contract)
  with the typed `CodingAgentRuntime` interface and the per-method
  first-slice behavior.
* `@pleach/core/inspector` row in [Subpath exports](/docs/subpath-exports).
* `@pleach/sandbox` row in [Packages](/docs/packages) (Phase A
  contract + in-memory fixture, version `0.1.0`).
* This changelog page.

### Changed [#changed-17]

* [Packages](/docs/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](/docs/plugin-contract#sibling-skus-as-plugins)
  "Sibling SKUs as plugins" section retitled (was "(planned
  shape; not yet shipping)") and rewritten with per-row real
  Phase A status.
* [@pleach/replay](/docs/replay) Phase B note now distinguishes
  the landed `replayTurn` body from the still-throwing
  `fromSnapshot` / `fork` / `multiTenantAggregate`.
* [Fabrication detection](/docs/fabrication-detection) plugin-
  supplied strategies subsection now references the typed
  `FabricationGuardImpl` hook.

### Fixed [#fixed-6]

* [Runtime inspector](/docs/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 contract](/docs/plugin-contract) — `definePleachPlugin`
  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 adapter](/docs/host-adapter) — `host.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](/docs/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](/docs/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](/docs/subpath-exports) — inspector row's
  type names corrected from `RuntimeInspection` to the real
  `InspectionReport`, `CapabilityReport`, `PluginReport`,
  `CapabilityDescriptor`.
