ADR landing
What this page is
ADRs are Ratiba's locked architectural commitments — the load-bearing
decisions that the rest of the codebase, plans, and runbooks reference by
number. Each ADR is rendered as-is (no rewrite, no summarisation) at
/adr/ADR-NNNN-<slug> via Docusaurus's multi-instance content-docs plugin
reading directly from docs/adr/. This page is the index — one row per ADR,
chronological, with a one-line decision extract so you can find the right
ADR without opening eleven tabs.
For the methodology behind why ADRs are written this way and where amendments live, see ADR-0011 D8.
The 11 ADRs
| ADR | Title | Status | Supersedes | Decision (1 line) |
|---|---|---|---|---|
| 0001 | Tech stack | Accepted (amended 2026-04-25) | — | FastAPI + Next.js + Postgres schema-per-tenant + Keycloak + Redis + Python 3.13 pin + library-currency policy. |
| 0002 | Multi-tenant isolation | Accepted | — | Schema-per-tenant operational specifics: 3-table public registry; 2 pools; per-tenant Alembic; atomic onboarding with Keycloak compensating actions. |
| 0003 | Conversation FSM persistence | Accepted | — | Two-tier Redis hot + Postgres LangGraph checkpoints; shared Redis with prefixed keys; fresh thread_id per booking; 90-day retention. |
| 0004 | Testing strategy | Accepted | — | Per-scenario fresh tenant fixture; calibration set Adrian-owned monthly cadence; production-replay PII masking floor; DeepEval 4-tuple cache key. |
| 0005 | Orchestration model | Accepted | — | Single bilingual intent classifier; tenant-locale fallback; cost ceilings; LLMRouter role-based config; shallow 4-state AdminOrchestrator. |
| 0006 | Handoff model | Accepted | — | 120s/10min/60min conservative timing; voice Phase 1 = WhatsApp follow-up; verbatim transcript fold; 90-day retention. |
| 0007 | Payments orchestration | Accepted | — | M-Pesa STK via Daraja primary; cards via PesaPal; one-shot stkpushquery; daily 3 AM EAT reaper; payment_callbacks_unrouted dead-letter. |
| 0008 | WhatsApp ingress | Accepted | ADR-0001 (BSP entry) | Cloud API direct (Meta first-party); €0/month; project-level WHATSAPP_APP_SECRET HMAC; per-tenant credentials. |
| 0009 | Channel-agnostic substrate | Accepted | ROADMAP "no widget" exclusion | Channel protocol + ChannelKind + Tier enums; Tier-1 phone-known vs Tier-2 progressive phone capture; phone-only deterministic identity. |
| 0010 | Tenant self-service customisation | Accepted | — | 3-prong scope (catalog onboarding + conversational steady-state + 6-dial personality); curated dials only; per-vertical YAML defaults. |
| 0011 | Docs IA + tooling | Accepted | — | Single-tree progressive disclosure (IA Z); Mermaid + Excalidraw hybrid; per-leaf P-template; demo-led Welcome; architecture-index plugin extensions. |
How to read this list
ADRs are numbered in chronological order — ADR-0001 was the first decision locked, ADR-0011 the most recent. Reading top-to-bottom traces how Ratiba's architecture evolved: the early ADRs (0001-0007) settle the substrate (stack, tenancy, FSM, payments, handoff); the middle ADRs (0008-0009) react to channel-shape pressure (WhatsApp BSP cost, Tier-2 expansion); the late ADRs (0010-0011) tackle product self-service and the docs surface itself.
The Supersedes column flags where a decision evolved. ADR-0008 supersedes the BSP entry in ADR-0001 (€49/month → €0/month by going Cloud API direct); ADR-0009 supersedes the original ROADMAP "no web widget" exclusion. The superseded text isn't deleted from the older ADR — it's struck through with a forward-pointer to the newer ADR, so the historical reasoning stays auditable.
Every ADR currently carries Accepted status. Ratiba has never had to reject or supersede a whole ADR; amendments live as inline strikethrough plus a date-stamped "Amended YYYY-MM-DD" header section within the existing ADR, not as a new ADR. ADR-0011 D8 codifies this convention.
Future ADR territory
The architecture phase is complete for pilot scope, but four pending ADR areas are flagged in existing ADRs as deferred:
- SMS OTP gating — ADR-0009 D5 deferred per-tenant SMS OTP for phone validation; default flow uses STK-push-as-oracle. An ADR will land if any pilot tenant requires OTP for compliance or fraud reasons.
- Embeddable widget Phase 2 — ADR-0009 + M10 Phase 1 shipped the web widget as a standalone page; embedded-into-third-party-site (script tag, Shadow DOM, postMessage handshake) deferred to Phase 2.
- Privacy / data retention — multiple ADRs (0006, 0009) flag a future privacy ADR for compliance pivots (health-data verticals, GDPR-style data-subject requests, per-vertical retention rules).
- Free-text personality overrides — ADR-0010 D2 deferred free-text personality fields in favour of curated dials. An ADR will land if pilot data shows tenants need expressive overrides the dials can't cover.
Each is currently deferred — no ADR draft exists. They'll land as the operational pressure justifies.