Skip to main content

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

ADRTitleStatusSupersedesDecision (1 line)
0001Tech stackAccepted (amended 2026-04-25)FastAPI + Next.js + Postgres schema-per-tenant + Keycloak + Redis + Python 3.13 pin + library-currency policy.
0002Multi-tenant isolationAcceptedSchema-per-tenant operational specifics: 3-table public registry; 2 pools; per-tenant Alembic; atomic onboarding with Keycloak compensating actions.
0003Conversation FSM persistenceAcceptedTwo-tier Redis hot + Postgres LangGraph checkpoints; shared Redis with prefixed keys; fresh thread_id per booking; 90-day retention.
0004Testing strategyAcceptedPer-scenario fresh tenant fixture; calibration set Adrian-owned monthly cadence; production-replay PII masking floor; DeepEval 4-tuple cache key.
0005Orchestration modelAcceptedSingle bilingual intent classifier; tenant-locale fallback; cost ceilings; LLMRouter role-based config; shallow 4-state AdminOrchestrator.
0006Handoff modelAccepted120s/10min/60min conservative timing; voice Phase 1 = WhatsApp follow-up; verbatim transcript fold; 90-day retention.
0007Payments orchestrationAcceptedM-Pesa STK via Daraja primary; cards via PesaPal; one-shot stkpushquery; daily 3 AM EAT reaper; payment_callbacks_unrouted dead-letter.
0008WhatsApp ingressAcceptedADR-0001 (BSP entry)Cloud API direct (Meta first-party); €0/month; project-level WHATSAPP_APP_SECRET HMAC; per-tenant credentials.
0009Channel-agnostic substrateAcceptedROADMAP "no widget" exclusionChannel protocol + ChannelKind + Tier enums; Tier-1 phone-known vs Tier-2 progressive phone capture; phone-only deterministic identity.
0010Tenant self-service customisationAccepted3-prong scope (catalog onboarding + conversational steady-state + 6-dial personality); curated dials only; per-vertical YAML defaults.
0011Docs IA + toolingAcceptedSingle-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.