Skip to main content

ADR-0011: Docs Information Architecture + Tooling

Status: Accepted Date: 2026-05-06

Context

By the close of M11 (2026-05-06), Ratiba's product surface is feature-complete for the pilot scope: 5 channels (WhatsApp, voice, web widget, IG, Messenger), M-Pesa STK push, multi-tenant isolation, admin orchestrator, cross-sell, personality dials, catalog onboarding. Backend at 1093 tests; frontend at 81 Vitest. The architecture phase is complete with 10 ADRs landed.

The remaining gap before any real-tenant traffic touches Ratiba is operational readiness — both for the pilot operator (Adrian, who needs a runbook he can follow verbatim) and for prospects (who need to understand what they're buying without a sales call). Three structural problems block this:

  • The Docusaurus site at docusaurus/ratiba/ is a 3-page skeleton. It has the multi-instance plugin plumbing for ADRs / research / methodology subtrees, the architecture-index.js post-build coverage plugin, and @docusaurus/theme-mermaid enabled — but no content shaped for either prospect-pitching or runbook-following. The current intro.md reads like a contributor README, not a product surface.
  • Operational knowledge sits in subagent close-out memos and the orchestrator's head, not in any place the pilot operator can grep at 2 AM. There is no runbook section, no incident playbook, no per-feature "Try this on local dev" block.
  • Code-pointer drift across markdown files is asymptotic without a forcing function. ~40 file:line references will be needed across the academic rewrite; without a build-time staleness gate, they rot silently.

Two industry references shape the answer. Stripe Docs is the gold standard for single-tree progressive disclosure — prospect skim-paths and engineer deep-dives share one navigation, no /learn / /build schism. Anthropic's docs sit one rung lower in detail-density but match Stripe's IA philosophy. Both eschew video-as-primary-medium; both lean heavily on diagrams (Stripe via custom illustrators; Anthropic via mostly-Mermaid). The pilot-stage scope here is tighter than either — ~30 pages, not ~300 — but the IA pattern transplants cleanly.

The diagram-tool choice has evolved. M5–M11 used inline Mermaid in plan docs and ADRs; the rendering came for free wherever GitHub or Docusaurus parsed it. M12's academic rewrite needs ~24 Mermaid diagrams (one architecture + one flow per "How it works" leaf, plus C4 context/container on the Architecture overview, plus a couple of state diagrams). It also needs ~5 hero illustrations — the kind of cartoon-style "channels → substrate → bookings" picture that lives at the top of the Welcome page and on the Architecture overview's masthead. Hand-coded SVG is too labour-intensive for the volume; D2 the diagram tool was considered and rejected as additional toolchain surface; animated GIFs were rejected as prospects-don't-want-to-watch-them and engineers-can't-grep-them.

Decisions

D1. Single-tree progressive disclosure

The Docusaurus site at docusaurus/ratiba/ is a single sidebar tree that progressively discloses depth, NOT split into /learn (prospect) and /build (engineer) sub-sites.

The bifurcated approach was considered: a top-level "I'm shopping" path and a separate "I'm building" path that diverge below the homepage. Three reasons against:

  • Pilot-stage scale. ~30 pages doesn't justify the maintenance cost of two trees. Stripe's bifurcation pays off at 300+ pages.
  • Audience overlap. The technical evaluator at a mid-size dental clinic IS the buyer. A single path that opens with "what is this" and ends with "where the service registry lives" matches their reading pattern.
  • Reversibility. A single tree can split later (lift the "How it works" + "Architecture" + "Reference" + "Methodology" branches into a /build sub-route) without rewriting any individual page. The reverse — merging two trees that grew apart — is far costlier.

The single tree opens shallowest at the top (Welcome — prose, demo, visuals) and deepens as the reader descends (Quick start → How it works → Architecture → Reference). Methodology + Runbook sit alongside as peer trees for the engineer / on-call audience.

D2. IA Z — 7 top-level sections

The sidebar lists exactly 7 top-level sections, in this order: Welcome → Quick start → How it works → Architecture → Reference → Methodology → Runbook.

The order matters. Welcome anchors prospect entry; Quick start gives the technical evaluator their first hands-on win; How it works is the academic core (one leaf per major feature, P-template uniform); Architecture goes deeper on cross-cutting concerns (C4, schema evolution, component map, data flow); Reference holds the structured artifacts (ADR landing index, API surface, schema reference); Methodology cross-links to the upstream s4u-methodology repo; Runbook is the operational playbook (Local dev / Pilot deployment / Incidents).

Two alternatives were considered and rejected:

  • Add a "Tutorials" section between Quick start and How it works. Every "Try this on local dev" block in a How it works leaf already serves the tutorial role. A separate Tutorials section would duplicate content and beg the question "which one does the contributor read?".
  • Put Reference at the top. API-first docs shops do this; we are not API-first. Ratiba's product surface is conversational, not REST. The API table is a reference tier, not a marquee.

D3. Mermaid only for v1; narrative-illustration heroes deferred (amended 2026-05-07)

All technical diagrams render via Mermaid (~24 anticipated). Hero / narrative / cover illustrations are deferred to M13 polish — see amendment note below.

Amendment note (2026-05-07). The original D3 commitment was "Mermaid + Excalidraw hybrid (~24 + 5 diagrams)". M12 W1/W3 attempted to ship 5 hand-drawn-style SVG hero illustrations generated programmatically (not from the Excalidraw editor — hand-coded SVG with feTurbulence/feDisplacementMap filter approximations of the Excalidraw aesthetic). The output did not meet professional bar for prospect-facing documentation; the SVGs read as "amateur" / "small children's drawings" against a Stripe / Anthropic / Modal docs benchmark. Adrian flagged this at M12 W6 review. Remediation: all 5 hero embeds removed from the docs site; the corresponding SVG + Excalidraw JSON files deleted; D3 amended to Mermaid-only for v1. Real Excalidraw editor passes or AI-image-generation passes deferred to M13 polish. The Welcome page's demo recording slot + bilingual en/sw transcript carry the prospect-facing emotional weight; clean Mermaid for technical content matches industry benchmark.

Mermaid is the load-bearing 90%. Choices:

AspectConvention
Themedefault light + dark dark (already wired into themeConfig.mermaid.theme); no custom palette in v1
Layout directiongraph TB for system architecture; graph LR for flow
Node hierarchyRectangles [ ] = code modules / FSM nodes; stadium ( ) = external dependencies; subgraph clusters = bounded contexts
Edge labelsEvery arrow carries a verb-noun label; no bare arrows
Length capSoft 50 lines / 25 nodes per block; hard 80 lines / 40 nodes
ReusabilityCommon subgraphs live as MDX partials at docusaurus/ratiba/docs/_partials/*.md (~5 anticipated)

Excalidraw is the 10% — the hero illustrations on Welcome, Architecture overview, the "How it works" landing page, the Methodology page, and the Channel substrate cover. Storage convention: .excalidraw JSON at docusaurus/ratiba/static/excalidraw/<topic>.excalidraw (the editable source); pre-rendered SVG at docusaurus/ratiba/static/img/<topic>.svg (what pages embed via <img src="/img/<topic>.svg" />). Style: hand-drawn aesthetic via Excalidraw's default Cascadia / Virgil font, 16:9 aspect ratio, KE-context elements where applicable (M-Pesa logo silhouette, WhatsApp icon, Swahili text snippets in speech bubbles).

Anti-patterns explicitly NOT done:

  • Pixel-perfect art. Mermaid's auto-layout is good enough; we don't fight it.
  • Inline SVG hand-coded. Too labour-intensive at the diagram volume.
  • D2 (the diagram tool). Additional toolchain surface for marginal expressiveness gain over Mermaid.
  • Animated GIFs / video walkthroughs as diagrams. Prospects skim; engineers grep. Neither audience benefits from a 90-second loop.

D4. Per-leaf P-template

Every "How it works" leaf (and every Architecture deep page) follows a uniform P-template: 150–300 word prose lead + 2 Mermaid diagrams (1 architecture + 1 flow / sequence) + file:line code-pointer table + linked ADR(s) + 3-step "Try this on local dev" runbook block.

The template is reproduced in canonical form in the M12 design doc (docs/plans/2026-05-06-m12-pilot-readiness-design.md §1) and is enforced by the frontmatter validator added in T0 (D6).

The uniformity is load-bearing. A reader who has read one "How it works" leaf knows the shape of every other leaf — they jump straight to the diagram or the code-pointer table without re-orienting. For the AI agent collaborator, the uniform shape means the page is indexable: every leaf has a components: frontmatter listing, making it a structured target for downstream tooling.

D5. Welcome page is demo-led with bilingual transcript fallback

The Welcome page leads with a 16:9 demo recording slot + bilingual (en + sw) transcript fallback + Excalidraw architecture hero + 3 prospect-friendly "see it work" cards + Get Started CTA. M12 ships with the recording slot empty (placeholder div) and the bilingual transcript fallback as the primary medium. The recording is M13 polish.

Three reasons for transcript-as-primary at M12:

  • Recording requires Adrian's screen + voice. Blocking M12 ✅ on a recording session that needs scheduling is bad sequencing.
  • The transcript is real product output, not synthetic. M12 W1 T1 pulls verbatim from tests/e2e/test_m11_personality_and_cross_sell.py::test_cross_sell_happy_path — what an actual booking conversation looks like when the system is running.
  • Bilingualism is structurally informative. Side-by-side en + sw is the product's most-distinctive surface; prospects who are curious about the Swahili side want to read it, not infer it from a video they may not understand.

When the recording lands in M13, it overlays the placeholder; the transcript stays as the no-video / read-faster path.

D6. architecture-index.js plugin extended for stale-pointer detection + ADR cross-validation + runbook-step extraction

The existing post-build plugin at docusaurus/ratiba/plugins/architecture-index.js is extended with three additive behaviours: stale-pointer detection (per-component git-log lookup vs last_verified frontmatter), ADR cross-validation (adrs: frontmatter list checked against docs/adr/ADR-NNNN-*.md existence), and runbook-step extraction (runbook_steps: frontmatter aggregated into docs/architecture-index.json under a new runbook_steps_by_page key).

Why each:

  • Stale-pointer detection. ~40 file:line code references across the rewrite will rot as M13+ change code. Without a forcing function, rot becomes silent. The plugin compares each page's last_verified date against the most-recent commit timestamp of every file in its components: list. If the page hasn't been re-verified within 30 days of the latest component commit, the build emits a warning. Per R7 mitigation, git-log results are cached within the single build pass — same component referenced by multiple pages reuses the cached lookup.
  • ADR cross-validation. Pages cite ADRs by number (adrs: [5, 6]); fat-fingering or ADR renumbers would break links silently. The plugin parses each page's adrs: list and verifies the corresponding docs/adr/ADR-NNNN-*.md files exist on disk. Missing ADRs fail the build with a clear error.
  • Runbook-step extraction. Each leaf page's runbook_steps: frontmatter (3-step "Try this on local dev" block) is aggregated into architecture-index.json. Future tooling can generate a consolidated runbook view from this data without re-parsing every leaf. M12 doesn't ship that view; the data is captured for M13+.

The extension is purely additive — existing plugin behaviour (component_map, coverage percent, undocumented modules, stale pages) is unchanged.

D7. Runbook is its own top-level section

The Runbook lives at docusaurus/ratiba/docs/runbook/ as its own top-level IA section with three sub-pages: Local dev, Pilot deployment, Incidents. Per-leaf "Try this on local dev" blocks in How it works leaves are short illustrations, not full runbook duplicates.

The split is intentional:

  • The per-leaf 3-step block answers "how do I see this feature work on my laptop right now?" — scoped to that one feature.
  • The Runbook section answers "how do I run the pilot end-to-end? what do I do when something breaks?" — scoped to the operator's whole-system journey.

Both reference the same commands; the duplication is illusory because the per-leaf block is 3 steps and the Runbook page sequences 30+ steps across phases. The frontmatter validator (D6) checks that every "How it works" leaf has a non-empty runbook_steps: list, so the illustration always exists.

D8. ADR pages render as-is from docs/adr/*.md via the existing multi-instance plugin

The 11 ADRs (0001–0011 after this commit) render as-is from docs/adr/ADR-NNNN-*.md via the existing @docusaurus/plugin-content-docs multi-instance configuration in docusaurus.config.ts. The ADR landing index at docusaurus/ratiba/docs/reference/adrs.md is a one-row-per-ADR table linking to the rendered pages. No ADR rewriting; no per-ADR companion page.

Three reasons:

  • Single source of truth. ADRs are repository-authored markdown; the rendering should not require re-shaping or duplication.
  • Discoverability. A landing index that lists all 11 ADRs with status + 1-line decision summary lets the reader find the right ADR without opening every one.
  • Already-wired plumbing. The multi-instance plugin already resolves docs/adr//adr/ route; no new tooling required.

D9. Pilot validation pass exercises 4 channels (WhatsApp + voice + web + SMS)

The local-dev pilot validation pass in M12 W5 exercises WhatsApp test number + local LiveKit voice + localhost:3010/widget + Africa's Talking SMS sandbox. Instagram DM and Messenger DM are deferred to M13 (paired with their real-business-account onboarding).

Two reasons:

  • Test surface availability. Meta's WhatsApp test number, local LiveKit, the embedded web widget, and Africa's Talking SMS sandbox all run end-to-end on Adrian's laptop with no human-in-the-loop approval gates. Instagram DM and Messenger DM both require a real Meta Business account and reviewer approval — sandbox parity is insufficient to validate the production paths.
  • M11 inheritance. M10 shipped the IG and Messenger adapters with stub-fixture coverage; their channel-substrate behaviour is test-asserted. The M12 pilot exercises behaviours the substrate doesn't already prove (latency under realistic network conditions, STK callback round-tripping, SMS reminder routing); IG and Messenger don't add unique behaviours to that pilot scope.

M13 picks up the IG + Messenger live-channel pass alongside real-tenant onboarding.

D10. Methodology v2.1.4 codification ships as a separate s4u-methodology PR

The 14+ amendment candidates accumulated across M9+1, M10, M11, and M12 close-outs ship as ONE bundled PR upstream in the s4u-methodology repo. M12 close-out marks methodology codification as "in-flight, separate PR" if not merged at close-out time and unblocks STATE.md M12 ✅ regardless. The PR is advisory at M12 close-out, not blocking.

The bundled-PR shape mirrors precedents c92f3a3 (v2.1) and e5b5b40 (v2.1.2). Three reasons:

  • Reviewer cost is lower with shared context. A single PR review pass evaluates the whole amendment surface once, rather than serialising 14 PRs.
  • Cross-cutting amendment interactions are visible. Several candidates from M11 and M12 reference each other (e.g., M11's "shared-interface contract pinning at parallel-dispatch" + M12's "wide-W3 fallback split" interlock). Bundling makes the interactions visible in one diff.
  • Upstream merge cadence is independent of Ratiba. The s4u-methodology repo serves multiple consumers; Ratiba pinning M12 ✅ on its merge would couple two cadences artificially.

Reversibility

Every D1–D10 commitment is reversible by design:

  • D1 single-tree — splitting the tree into /learn + /build later is additive: lift the existing branches into a sub-route without rewriting individual pages.
  • D2 IA Z — adding or removing a top-level section is a sidebars.ts edit + a section folder under docs/.
  • D3 Mermaid + Excalidraw — swapping diagram tools is a per-page rewrite; the tooling commitment is repo-level config only.
  • D4 P-template — relaxing or extending the template is a validator update; existing pages comply by construction.
  • D5 demo-led Welcome — overlaying the recording when ready doesn't disturb the transcript; transcript can stay or hide behind a "show transcript" toggle.
  • D6 plugin extension — the three new behaviours are additive to a single file; reverting is a 50-LOC removal that preserves the existing component_map + coverage logic.
  • D7 runbook own-section — moving the runbook into a sub-tree of How it works is a folder rename + sidebar reshape.
  • D8 ADR render-as-is — moving to per-ADR companion pages is additive (the ADR pages stay; companions add).
  • D9 4-channel pilot — adding IG / Messenger to the pilot pass is a runbook-page extension when sandbox parity becomes meaningful.
  • D10 methodology PR scope — splitting the bundled PR into per-amendment PRs is a git rebase --interactive exercise on the upstream branch.

Cross-references

  • ADR-0001 (Tech stack) — pins Docusaurus 3.10 + multi-instance plugin + Python 3.13 / Node 20+. M12's tooling sits on top of this stack; no tech-stack changes.
  • ADR-0009 (Channel-agnostic substrate) — D9's pilot scope (4 channels) maps onto the Tier-1 (WhatsApp, voice) + Tier-2 partial (web widget) + NotificationSink (SMS) surface from ADR-0009. IG / Messenger Tier-2 channels deferred per D9.
  • CLAUDE.md Architecture Documentation Protocol — D6's plugin extension is fully compatible with the existing scripts/check-docs-sync.sh pre-commit hook; the hook reads the same docs/architecture-index.json the plugin emits.

Implementation

Land in M12 — Pilot Readiness: Local-Dev Validation + Academic Docusaurus. Plan at docs/superpowers/plans/2026-05-06-m12-pilot-readiness.md. Companion design doc at docs/plans/2026-05-06-m12-pilot-readiness-design.md.

23 task commits across 7 waves; W2 = 8-way parallel, W3 = 7-way parallel (W3a/W3b 4+3 fallback at dispatch time per Q1 resolution). Estimated +35 backend tests post-M12 (mostly Docusaurus build invariants); frontend Vitest unchanged.

Pre-flight: M11 must be COMPLETE per STATE.md before Wave 0 dispatch. (Already satisfied as of 2026-05-06.)

Open questions deferred to future ADRs

  • Public hosting + custom domain (Vercel / Netlify / GitHub Pages). Future polish post-M13.
  • Algolia DocSearch + analytics + versioning + i18n. Future polish.
  • Auto-generated API reference from FastAPI OpenAPI schema. M13+.
  • Welcome video recording — M13 polish, not future ADR territory.