Three content registers — the OKF KB stays a pristine sovereign showcase; product docs and blog are SEPARATE authored collections (REFINED 2026-06-22 — TWO renderers split by register, not one)

0072-three-content-registers-one-renderer

decision read as Explain confidence asserted status active 2026-06-21 owner documentation-engineer
Reversibility
one-way door

DEC-0072 — Three content registers (REFINED 2026-06-22 — two renderers, split by register)

Reversibility: one-way door — in practice, once content is authored into the wrong register. The route/collection wiring is trivially undoable, but content provenance is not: marketing prose written as OKF atoms into knowledge/** forks the system of record and, once a tenant has pointed DOSSIER_KB at a repo so structured, the brochure has already propagated. The durable commitment is the register boundary (which content lives in which collection), locked before any product-docs/blog content is written — not the specific routes.

Founder-ratified this session as the topology that the visibility strategy (DEC-0073) executes on. confidence: asserted — the boundary is decided; the /docs/* and /blog/* collections are not yet built. Recorded automatically in the same turn (the standing rule).

Context

Dossier renders a client's (and its own dogfood) OKF knowledge base as a derived, read-only docs surface (Adopt OKF as Dossier's canonical knowledge format, Astro Starlight as the docs-site generator + the product-owner, starlight-engineer, and documentation-engineer functions): the Astro/Starlight @dossier/docs app glob-loads knowledge/** from knowledgeDir() and serves /knowledge/* plus the atom routes. The surface is KB-agnosticDOSSIER_KB repoints it at any tenant's OKF repo (KB-agnostic @dossier/site (renders any tenant's OKF KB) + runtime-driven site rendering + the Node-26 Windows build fix) — which is exactly why what goes into knowledge/** is load-bearing for sovereignty.

The founder directed this session: "keep the dogfooding content but build official, professionally-polished product docs; dogfood lives close to the graph, product docs need to be official." That raises a topology question that must be answered before a single product-docs page is written, because the wrong answer is expensive to unwind: where do official product docs and (later) a blog live, relative to the sovereign OKF KB?

Two failure modes make this a direction-setting ADR rather than an implementation detail:

  1. Authoring product docs/blog as OKF atoms inside knowledge/**. This would put marketing prose about Dossier into Dossier's own system of record — and because the renderer is KB-agnostic, any tenant who points DOSSIER_KB at a repo seeded this way inherits Dossier's brochure as if it were their institutional memory. That is a direct sovereignty break and a fork of the truth (Adopt OKF as Dossier's canonical knowledge format, KB-agnostic @dossier/site (renders any tenant's OKF KB) + runtime-driven site rendering + the Node-26 Windows build fix, Do not scan/mirror Anthropic's docs into the KB — distill curated references instead's reference-don't-absorb line).
  2. Treating product docs as "a second OKF KB via DOSSIER_KB". DOSSIER_KB resolves to one directory per build, so a single deploy physically cannot render both the dogfood KB and a product-docs KB. Product docs are not OKF atoms and must not be modeled as a parallel KB.

Options considered

  1. Product docs/blog as OKF atoms in knowledge/** (rejected). Reuse the existing glob loader by writing docs/blog as atoms. Rejected: forks the system of record with marketing prose and breaks sovereignty for every DOSSIER_KB tenant (Context failure mode 1). The KB is the showcase; polluting it with brochure copy destroys the very thing it showcases.
  2. A second OKF KB rendered via DOSSIER_KB (rejected). Model product docs as their own OKF repo and swap DOSSIER_KB. Rejected: DOSSIER_KB is one dir per build — one deploy cannot render both the dogfood KB and a docs KB (Context failure mode 2); and product docs aren't OKF atoms, so forcing them into the atom model is a category error.
  3. A separate Starlight project / second Vercel deploy (rejected for now). Stand up product docs as their own Astro/Starlight site on its own origin. Rejected as overkill: it forks chrome, theme, and deploy topology against the one-origin / shared-chrome posture and the two-apps-one-origin arrangement we already run — for content that belongs on the same renderer.
  4. Three registers on ONE Starlight renderer / ONE Vercel project (chosen as to register-separation; the ONE-renderer clause REFINED 2026-06-22 — see Refinement). Keep the existing single docs deploy; add separate authored Starlight content collections for /docs/* (product docs) and later /blog/* (editorial), strictly disjoint from the /knowledge/* OKF collection. Docs/blog reference the OKF graph, never become it. (The register split this option locks is retained verbatim; only its "one Starlight renderer" rendering assignment was later refined to a two-renderer split — the founder judged the dogfood KB should render app-native near the graph and "look much better than the old docs," with "Docs" reserved for polished official product docs. The Refinement section records the new renderer assignment.)

Decision

Three content registers, strictly separate. On ONE Starlight renderer / ONE Vercel project. REFINED 2026-06-22 (founder direction): the renderer assignment is now TWO renderers split by register — product docs own the Astro/Starlight surface; the sovereign dogfood KB is rendered app-native in @dossier/app. See ## Refinement below. The register separation invariant (which content lives in which register; ZERO marketing prose in knowledge/**; docs reference the OKF graph, never become it) is unchanged and reaffirmed — only the where-it-renders clause moved.

Register Route Source What it is Renderer (refined 2026-06-22)
OKF KB /knowledge/* + atom routes glob-loaded from knowledgeDir() (the DOSSIER_KB repo) The sovereign dogfood OKF KB — the showcase + system of record. ZERO marketing prose ever enters knowledge/**. App-native in @dossier/app (was: Starlight) — near /graph, via @dossier/okf-view + @dossier/design.
Product docs /docs/* a SEPARATE authored Starlight content collection (MDX/Markdown) Official product docs ABOUT Dossier. NOT OKF atoms; NOT a second DOSSIER_KB KB. Astro/Starlight @dossier/docs (the repurposed docs deploy) — the official "Docs" destination.
Blog (later) /blog/* a third dated editorial content collection Editorial essays; built after docs. TBD (editorial; not yet built).

The contract:

  • Docs/blog REFERENCE and link INTO the OKF graph; they never become it. A docs page may deep-link to a /knowledge/* atom; an atom is never authored as a docs/blog page and vice-versa.
  • Link, don't duplicate. The README stays the canonical repo TL;DR; the product docs are the canonical long-form. One fact, one home (Dossier — The Knowledge Model (v0) principle 2).
  • Route namespaces /docs/* and /knowledge/* are kept strictly disjoint, and must not collide with the DEC-0058 no-root-index invariant — adding /docs/* must not break the rule that /knowledge/ resolves for any served KB.

Refinement (2026-06-22, founder direction)

The register-separation INVARIANT is unchanged and reaffirmed: three content registers stay strictly separate; ZERO marketing prose ever enters knowledge/**; the KB stays the sovereign OKF system of record; product docs reference the OKF graph and never become it. What the founder changed is ONLY the renderer-assignment clause — DEC-0072 as originally written said "three registers on ONE Starlight renderer." Corrected to TWO renderers, split by register:

  1. Product docs own the Astro/Starlight surface (@dossier/docs). The existing docs deploy is REPURPOSED — from rendering the dogfood KB to rendering official product docs. It becomes the polished, official "Docs" destination, opened in a NEW TAB from the app header's "Docs" link (the docsUrl() seam still resolves the origin; the link target shifts from /knowledge/ to the product-docs root).
  2. The sovereign dogfood KB renders APP-NATIVE in @dossier/app, anchored near /graph, via @dossier/okf-view (the same readKbAtoms + route-map/sidebar reader the Astro docs already use) + @dossier/design — presented as first-class site content, NOT the stock Starlight docs reader. The KB pages live under the persistent `(app)` chrome route group. The /graph explorer stays as the entry; clicking a node lands on an app-native styled atom page (in-app nav), not an external docs origin.

Why (founder rationale, not embellished): the founder directed that "Docs" must mean professionally-polished official product docs, while the dogfood KB should live in the app near the graph and "look much better than the old docs" — leveraging the app's full design language + motion. Feasibility is grounded, not speculative: @dossier/okf-view already exposes readKbAtoms + the route map / sidebar / view-model (the exact reader the Astro docs consume), and the app already renders the real OKF graph (DEC-0047) and reads KB atoms (DEC-0044) — so this is mostly authoring + routing, not new machinery.

Why amend, not supersede: same-day, pre-build (nothing is built against DEC-0072 yet), and the invariant — the load-bearing one-way-door commitment — is intact. A same-day supersede would churn the graph for a clause-level correction; the register boundary the ADR locks is unchanged. The original "ONE Starlight renderer" wording is struck (not deleted) in the Decision body + Options so the history is legible and the SSOT is not self-contradictory.

Tasks: the product-docs register task (Stand up the product-docs register — REPURPOSE the @dossier/docs Starlight surface to official product docs at /docs/* (new-tab "Docs")) is updated for the repurpose; the prerequisite move — render the dogfood KB app-native and free Starlight — is filed as Render the dogfood OKF KB app-native in @dossier/app near /graph (the prerequisite that frees Starlight for product docs) (p0).

Rationale

Consequences

  • The product-docs register is now buildable, gated on this lock. (Refined 2026-06-22:) product docs repurpose the existing Astro/Starlight @dossier/docs deploy (no longer "a second collection alongside the dogfood KB on the same renderer") into the official "Docs" destination; the dogfood KB moves off Starlight to app-native rendering first. The product-docs work is filed as Stand up the product-docs register — REPURPOSE the @dossier/docs Starlight surface to official product docs at /docs/* (new-tab "Docs") (now scoped to the repurpose, depends on the KB-move task below); the prerequisite app-native KB move is Render the dogfood OKF KB app-native in @dossier/app near /graph (the prerequisite that frees Starlight for product docs) (p0). Both execute the first move of DEC-0073.
  • FLAG — two KB-render paths now coexist (open downstream question, NOT resolved here). Moving the dogfood KB to app-native rendering means Dossier has two ways to render an OKF KB: (a) the KB-agnostic Starlight renderer (DEC-0026) — our "render a client's KB as a docs site" product capability, repointed via DOSSIER_KB; and (b) the new app-native rendering in @dossier/app. Open question: does app-native eventually become the client KB surface too (i.e. supersede the Starlight KB-agnostic path for tenants), or do the two paths persist with different jobs (app-native = Dossier's own showcase, Starlight = the per-tenant delivered docs site)? Out of scope now — named here so it doesn't silently drift; a future ADR resolves it when client-surface work forces the call.
  • knowledge/** gains a standing invariant: no marketing prose, ever. This is a curation rule the log-auditor and Principal Knowledge-Format Architect enforce — a docs/blog page authored as an atom is a finding, not a feature.
  • /docs/* must respect DEC-0058. Adding the docs namespace must not regress the /knowledge/ resolves for any KB invariant; the two route trees stay disjoint by construction.
  • Blog is deferred but pre-shaped. /blog/* is a known third register (dated editorial), built after docs — so the topology already has a slot for it and no later retrofit forks the truth.

Review

status: active (the register split is ratified) · confidence: assertedheld, NOT promoted to verified: both tracks of the two-renderer refinement are now implemented + locally browser-verified, but the new topology is not yet deployed to production. Honest status: built + locally verified, not yet live.

Gate status (refined 2026-06-22; updated 2026-06-22 — implementation landed):

  1. Track 1 — dogfood KB renders app-native in @dossier/app near /graph (Render the dogfood OKF KB app-native in @dossier/app near /graph (the prerequisite that frees Starlight for product docs), done): the app's (app)/[...slug] catch-all renders each atom at its byte-preserved URL over the shared @dossier/okf-view reader; the app proxy was flipped and the docsUrl()/kbUrl() seam updated (KB links same-origin in-app). Met (locally).
  2. Track 2 — product-docs register ships at /docs/* on the repurposed Starlight surface (Stand up the product-docs register — REPURPOSE the @dossier/docs Starlight surface to official product docs at /docs/* (new-tab "Docs"), done): @dossier/docs renders authored docs at /docs/* (Astro base: '/docs') as the default mode when DOSSIER_KB is unset, with the KB-agnostic mode (DEC-0026) preserved behind the env branch (regression-verified at 161 pages); 4 Diátaxis pages + index, every command verified against live --help/CLI; the app header's "Docs" link opens /docs/ in a new tab and packages/app/vercel.json carries the /docs/* apex rewrite. Met (locally).
  3. Zero OKF atoms / marketing prose written into knowledge/** to back the docs (the KB-purity invariant): nothing was authored into knowledge/** for either track. Met.
  4. README→docs link-don't-duplicate contract holds. Met.

Single remaining promotion condition (assertedverified): the production Vercel deploy reflecting the new topology — both surfaces live (app-native /knowledge/* + atom routes served by the app with prior URLs redirecting in; product docs at /docs/* on the repurposed Starlight origin; the header "Docs" link resolving to the live product-docs root). Until that deploy is verified in production, this stays asserted: the boundary + refined renderer assignment are built and locally browser-verified, not yet shipped.