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, thearchitecture-index.jspost-build coverage plugin, and@docusaurus/theme-mermaidenabled — but no content shaped for either prospect-pitching or runbook-following. The currentintro.mdreads 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:linereferences 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
/buildsub-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:
| Aspect | Convention |
|---|---|
| Theme | default light + dark dark (already wired into themeConfig.mermaid.theme); no custom palette in v1 |
| Layout direction | graph TB for system architecture; graph LR for flow |
| Node hierarchy | Rectangles [ ] = code modules / FSM nodes; stadium ( ) = external dependencies; subgraph clusters = bounded contexts |
| Edge labels | Every arrow carries a verb-noun label; no bare arrows |
| Length cap | Soft 50 lines / 25 nodes per block; hard 80 lines / 40 nodes |
| Reusability | Common 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:linecode references across the rewrite will rot as M13+ change code. Without a forcing function, rot becomes silent. The plugin compares each page'slast_verifieddate against the most-recent commit timestamp of every file in itscomponents: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'sadrs:list and verifies the correspondingdocs/adr/ADR-NNNN-*.mdfiles 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 intoarchitecture-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+/buildlater 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.tsedit + a section folder underdocs/. - 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 --interactiveexercise 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.shpre-commit hook; the hook reads the samedocs/architecture-index.jsonthe 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.