Skip to main content

DemozPay — Documentation Audit & Cleanup Plan

Author posture: Principal Technical Writer + Staff Architect. Snapshot: 2026-05-31. Method: enumerated all 143 markdown files; six parallel Explore agents read clusters; characterisations cited file:line. Code is the source of truth — where docs and code conflict, the code wins and the gap is named.

Why this exists: the repo has 143 .md files. A new developer cannot read them all and cannot tell which to trust. This document audits every one, names the duplication, designs a clean structure, and proposes a cleanup plan.


Table of contents

  1. Headline findings
  2. Phase 1 — Documentation inventory
  3. Phase 2 — Duplication matrix
  4. Phase 3 — New documentation structure
  5. Phase 4 — New-developer onboarding review
  6. Phase 5 — Document quality scores
  7. Phase 6 — Cleanup execution plan
  8. Single source of truth — final assignments

1. Headline findings

  • 143 markdown files in the repo. After cleanup the target is ~70 active files plus an archive.
  • The repo has at least 8 documents that claim to describe the system's status / roadmapSYSTEM_GAP.md, SYSTEM_GAP_ACTION_PLAN.md, 90_DAY_EXECUTION_PLAN.md, GO_LIVE_BLOCKERS.md, PRODUCTION_READINESS.md, REAL_SYSTEM_STATE.md, SYSTEM_NOT_IMPLEMENTED.md, DOMAIN_COMPLETENESS_MATRIX.md — plus the three new audits I wrote (CURRENT_STATE_AUDIT.md, API_INVENTORY_FRESH.md, ROADMAP_REALITY_CHECK.md). This is the single biggest source of confusion.
  • README.md + CLAUDE.md + PROJECT_STRUCTURE.md triple-document the same stack, layout, and commands. A new reader doesn't know which to start with.
  • 11 .md files under dist/ are accidentally committed (.gitignore:4 already ignores dist/). Remove via git rm --cached.
  • 20+ Docusaurus template files under apps/docs-web/ are 95% boilerplate (tutorial-basics/*, tutorial-extras/*, the 3 example blog posts, half the portals/*.md). If we wire docs-web up for real, these get wiped first.
  • Onboarding is split between two competing treesdocs/onboarding/01-09-*.md (older, partially stale) and the newer DEVELOPER_GUIDE.md + DOMAIN_KNOWLEDGE_BASE.md. A new dev opens both, reads contradictions, leaves confused.
  • README.md still says Payroll + Equb are Planned (line 14, 19). Both are Live (backend) — Payroll closed E3 on 2026-05-29; Equb Phase 1 Alpha shipped. This is the most consequential stale claim because README is what a new contributor reads first.
  • 25 ADRs (001–025). ADR-015 and ADR-016 are Proposed (no code yet); ADR-018–025 (added 2026-06-18) capture the target-platform decisions; the rest are accepted and code-matched. (This audit was written when only 17 existed.)
  • 9 of 11 runbooks are real and useful, contradicting the earlier "9 stubs" guess in docs/audits/CURRENT_STATE_AUDIT.md. That audit needs a one-line correction.

2. Phase 1 — Documentation inventory

Legend. K=Keep, M=Merge into another doc, S=Split, A=Archive (move to docs/archive/), D=Delete, R=Rewrite. Sup-by = superseded by.

2.1 Top-level (/)

FileLinesPurposeActionReason
README.md272Project pitch + clone-and-run + statusRStale: payroll + equb status. Should be the ONE entry point; today competes with CLAUDE.md / PROJECT_STRUCTURE.md
CLAUDE.md127AI-session contextK (trim)Keep terse (<100 lines); drop everything that duplicates README — keep only non-negotiables + behavioural rules
PROJECT_STRUCTURE.md202Intern-friendly layout walkM → docs/architecture/HANDBOOK.md §1Pure overlap with README "layout" + HANDBOOK §1. Save the intern-friendly tone, fold into HANDBOOK. Then archive.
SECURITY_CONTROLS.md663Partner-questionnaire / control inventoryRMany "Live" rows are actually Planned. Need an evidence column citing migrations/code. Audience is partners — keep at root for visibility.
INTERN_PROGRAM.md93316-week intern curriculumRBaseline (§"already in repo") contradicts code — assumes greenfield auth build (svc-identity), but better-auth is Live in apps/api/src/identity/auth/. Re-phase against actual code state.
equb-financial-projection.md136Founder pitch / 3-stage revenue modelA (→ docs/business/)Not engineering doc; doesn't belong at root. Create docs/business/ for material like this.

2.2 docs/ root

FileLinesPurposeActionReason
docs/README.md45Index of docs/RRewrite as the canonical entry index pointing at the new structure
docs/STATUS_LEGEND.md50Defines 6 status tagsKEssential reference; cited by everything
docs/SYSTEM_GAP.md68912 gaps in bank-orchestrator transition (all marked [x] FIXED)ASnapshot in time. Now historical because gaps are closed. Move to archive with a redirect to current audits.
docs/SYSTEM_GAP_ACTION_PLAN.md281Sprint plan for those 12 gapsASame reason — historical. The gaps it sequences are closed.
docs/API_INVENTORY.md533HTTP route catalogue (2026-05-29)A (sup-by docs/audits/API_INVENTORY_FRESH.md)2 days stale; superseded by the fresh audit. Keep redirect note.

2.3 docs/adr/ (17 files)

FileStatusAction
adr/README.mdTemplate + governanceK
ADR-001ADR-014Accepted, code-matchedK (all 14)
ADR-015 (adjustment-journal process)Proposed; blocker for soak gateK + tag as critical-path in roadmap
ADR-016 (dispute workflow)Proposed; depends on ADR-015K + tag as critical-path

All ADRs are accurate. No action needed beyond the two Proposed ones being tracked.

2.4 docs/architecture/ (17 files)

FileLinesActionReason
SYSTEM_OVERVIEW.md370K (canonical exec overview)Newest, evidence-grounded, mermaid diagrams
HANDBOOK.md496K (canonical engineer handbook)Newest; merge in PROJECT_STRUCTURE.md content + system-topology details
restructure-2026-05.md123ASelf-marked "complete, historical reference"; belongs in archive
SYSTEM_TOPOLOGY.md673M → HANDBOOK.md §8 + new infra docsTopology / ports / deploy details belong in HANDBOOK or under docs/operations/. Don't keep as standalone
BANK_ORCHESTRATION.md210M → ADR-014 supplement / DOMAIN_KNOWLEDGE_BASEThe architectural commitment lives in ADR-014; flow detail belongs in DOMAIN_KB. Cherry-pick what's not redundant, fold in.
MONEY_FLOWS.md286M → DOMAIN_KNOWLEDGE_BASE.md12 canonical money flows — most are duplicated in DOMAIN_KB now. Fold the additional sequence diagrams into DOMAIN_KB.
PAYROLL_ARCHITECTURE.md303KDomain-specific deep dive complementing DOMAIN_KB
ETHIOPIAN_TAX_ENGINE.md132KCompliance + rule-engine reference
RECONCILIATION_ARCHITECTURE.md252KOps-critical detail not duplicated elsewhere
SLOS_AND_ALERTING.md172KSLO authority
PHASE_C_LOOKUP_ACCOUNT.md169APhase-specific delivery note; archive once it stops being referenced
DOMAIN_COMPLETENESS_MATRIX.md224A (sup-by audits)Same content covered by docs/audits/CURRENT_STATE_AUDIT.md
REAL_SYSTEM_STATE.md408A (sup-by docs/audits/CURRENT_STATE_AUDIT.md)Self-superseded by the newer audit
SYSTEM_NOT_IMPLEMENTED.md215A (sup-by docs/audits/ROADMAP_REALITY_CHECK.md)Audit covers the same ground with fresher evidence
90_DAY_EXECUTION_PLAN.md299K (move to docs/roadmap/)The one canonical sequenced plan
GO_LIVE_BLOCKERS.md402K (move to docs/roadmap/)Companion to execution plan
PRODUCTION_READINESS.md291R + move to docs/operations/Risk register is stale (Phase C/D closed 4 of 5 risks); re-score

2.5 docs/onboarding/ (12 files)

FileLinesActionReason
README.md93RRewrite as the index pointing at DEVELOPER_GUIDE + DOMAIN_KB
01-what-is-demozpay.md272A (sup-by SYSTEM_OVERVIEW.md + DOMAIN_KB.md)Has stale "Payroll Planned" claim
02-running-locally.md321A (sup-by DEVELOPER_GUIDE.md §2-3)Stale: Node 20+, port 8000 (real is Node 22.13+, port 3030)
03-the-codebase-tour.md423A (sup-by HANDBOOK.md §1)Stale ledger status ("Compile-only")
04-how-the-backend-works.md460A (sup-by HANDBOOK.md + DOMAIN_KB)Pre-restructure diagrams
05-the-frontend-apps.md130KAccurate; mock-only frontend description still applies
06-status-matrix.md150A (sup-by docs/audits/CURRENT_STATE_AUDIT.md)Stale: payroll marked Planned
07-rules-and-patterns.md420KSeven non-negotiables — current and well-written
08-how-to-add-things.md414KRecipes — current and useful
09-common-mistakes.md354K (minor edit re ledger status)Diagnostics; mostly accurate
DEVELOPER_GUIDE.md388K (primary onboarding)Newest, accurate, hands-on
DOMAIN_KNOWLEDGE_BASE.md448K (primary business primer)Newest, accurate

2.6 docs/runbooks/ (11 files)

FileStatusAction
README.mdIndexK
bank-statement-parse-failed.mdLiveK
cron-migration.mdStub-template (technical how-to, not a runbook)R or M into a deployment playbook
drift-detected.mdLiveK
gateway-down.mdLiveK
payroll-ledger-enablement.mdLiveK
payroll-migration-deploy.mdLiveK
permission-matrix.mdLive — canonical RBAC referenceK (move to docs/security/) — it's not really a runbook
sms-smpp-to-http-migration.mdLiveK
transport-swap-pattern.mdLiveK
webhook-failure.mdLiveK

Correction to prior audit: my earlier CURRENT_STATE_AUDIT.md said "9 of 10 runbooks are stub templates." That was wrong — only cron-migration.md is stubby; the rest are real. Will fix.

2.7 docs/security/ (4 files)

All four are coherent, evidence-grounded, no contradictions with code.

FileActionNote
AUTH_SYSTEM_REVIEW.mdKExec summary
AUTH_RISK_MATRIX.mdKRisk-tracking
AUTH_MIGRATION_STRATEGY.mdK + updateFlag packages/shared/auth/identity as the prerequisite that's now Live (post R1)
LONG_TERM_IAM_ARCHITECTURE.mdKNorth-star target

2.8 docs/archive/ (6 files)

FileActionNote
README.mdKGuard rail
CORE_BANKING_MICROSERVICES_PLAN.mdKHas regulatory/FI research value
DEMOZPAY_ARCHITECTURE.mdKGenesis architecture doc, ADR-referenced
SYSTEM_DOCUMENTATION.mdKStale paths, intact domain knowledge
NX_WORKSPACE_EXPLAINED.mdR or DReplace with a current Nx walkthrough or delete
theme-system-plan.mdDFully superseded by packages/shared/ui/README.md

2.9 docs/audits/ (3 new files)

FileAction
API_INVENTORY_FRESH.mdK — supersedes docs/API_INVENTORY.md
CURRENT_STATE_AUDIT.mdK — supersedes REAL_SYSTEM_STATE.md
ROADMAP_REALITY_CHECK.mdK — supersedes SYSTEM_NOT_IMPLEMENTED.md
DOCUMENTATION_AUDIT.md (this file)K

2.10 Package + service READMEs (27 files)

Every one is hand-authored and substantive. None are Nx scaffolds. All accurate to code. Action: K all 27.

The one nuance: packages/shared/auth/README.md says it's Live; CLAUDE.md tags it Deprecated. After the R1 work, packages/shared/auth is Live as the identity-port boundary — CLAUDE.md is the one that's wrong. Will fix.

2.11 apps/docs-web/ content (21 files)

ClusterAction
docs/intro.md, docs/architecture/overview.md, docs/api/introduction.md, docs/portals/{admin,business}.mdD — pure boilerplate placeholders
docs/portals/{client,mfi}.md, docs/guides/{contributing,deployment}.mdR — hollow stubs; either fill with real content or delete
docs/tutorial-basics/* (5 files), docs/tutorial-extras/* (2 files)D — Docusaurus learn-ware, unrelated to DemozPay
blog/2019-05-28-first-blog-post.md, blog/2019-05-29-long-blog-post.md, blog/2021-08-26-welcome/index.mdD — Docusaurus example posts
src/pages/markdown-page.mdD — Docusaurus example
apps/docs-web/README.mdK
sidebars.ts, docusaurus.config.tsR — when we wire docs-web to surface the real /docs/ content

Decision needed: is docs-web a real public docs site or dead weight? Status today: Stub. Until that decision is made, all the template content is noise.

2.12 dist/ accidentally tracked

11 README.md files under dist/packages/*/ are tracked despite .gitignore:4 ignoring dist/. Action: git rm --cached dist/ in a follow-up commit.


3. Phase 2 — Duplication matrix

3.1 The seven major duplication clusters

Cluster A — Stack / repo layout / commands

DocumentSectionOverlap
README.md§"Clone & run" (42-221), §"Repo layout" (155-180)Authoritative
CLAUDE.md§"Stack" (24-37), §"Layout" (39-67)~95% identical to README
PROJECT_STRUCTURE.md§"Top-level folders" (16-24), §"Generators" (169-179)~85% identical to README
docs/architecture/HANDBOOK.md§1 "Monorepo layout"New; should absorb the intern-friendly tone from PROJECT_STRUCTURE.md
docs/architecture/SYSTEM_TOPOLOGY.md§"Directory map"Same content again
docs/onboarding/03-the-codebase-tour.mdFolder-by-folder walkSame content, plus stale ledger note

Single source of truth: README.md (audience: first-time reader) + docs/architecture/HANDBOOK.md §1 (audience: engineer who already cloned). Delete the duplicates.

Cluster B — System status / what's Live

DocumentCoverageSnapshot date
docs/SYSTEM_GAP.md12-gap inventory2026-05-28
docs/SYSTEM_GAP_ACTION_PLAN.mdSprint plan for those 12 gaps2026-05-28
docs/architecture/REAL_SYSTEM_STATE.mdNarrative audit2026-05-29
docs/architecture/DOMAIN_COMPLETENESS_MATRIX.md23 domains × 15 capabilities2026-05-29
docs/architecture/SYSTEM_NOT_IMPLEMENTED.mdWhat's missing, by tier2026-05-29
docs/architecture/PRODUCTION_READINESS.mdOperational scoring2026-05-29
docs/onboarding/06-status-matrix.mdCapability matrix2026-05-31
docs/audits/CURRENT_STATE_AUDIT.mdNEW — Live/Partial/Stub/Dead2026-05-31

Single source of truth: docs/audits/CURRENT_STATE_AUDIT.md. Archive the four older snapshots; keep docs/onboarding/06-status-matrix.md's table format if a one-page view is wanted (or absorb into CURRENT_STATE_AUDIT).

Cluster C — Roadmap / what to build next

DocumentCoverage
docs/SYSTEM_GAP_ACTION_PLAN.md4-sprint plan for 12 gaps (now closed)
docs/architecture/90_DAY_EXECUTION_PLAN.md3 × 30-day phases for 22 blockers
docs/architecture/GO_LIVE_BLOCKERS.md22 blockers with acceptance + effort
docs/architecture/SYSTEM_NOT_IMPLEMENTED.mdTier 1-4 priority
docs/audits/ROADMAP_REALITY_CHECK.mdNEW — claimed vs. actual, ranked priorities

Single source of truth: keep two docs only — GO_LIVE_BLOCKERS.md (the what — list of blockers) and 90_DAY_EXECUTION_PLAN.md (the when — phased sequence). Archive SYSTEM_GAP_ACTION_PLAN.md (gaps closed) and SYSTEM_NOT_IMPLEMENTED.md (sup-by ROADMAP_REALITY_CHECK). Move both keep-docs into docs/roadmap/.

Cluster D — API surface

DocumentCoverage
docs/API_INVENTORY.md2026-05-29 catalogue
docs/audits/API_INVENTORY_FRESH.mdNEW — 2026-05-31 catalogue with packages/*/backend/presentation/ controllers included

Single source of truth: docs/audits/API_INVENTORY_FRESH.md. Archive the old one with a forward-link.

Cluster E — Architecture / system overview

DocumentAudienceAction
docs/architecture/SYSTEM_OVERVIEW.mdFounders, PMs, new devs — NEWK — canonical exec overview
docs/architecture/HANDBOOK.mdBackend engineers — NEWK — canonical engineer reference
docs/architecture/SYSTEM_TOPOLOGY.mdOps + new engineersM → HANDBOOK §8 (ports, RPCs, deploy)
docs/architecture/BANK_ORCHESTRATION.mdEngineers, architectsM → DOMAIN_KB + ADR-014
docs/architecture/restructure-2026-05.mdHistoriansA

Single source of truth: SYSTEM_OVERVIEW.md (exec) and HANDBOOK.md (engineer). Two layers, two audiences.

Cluster F — Onboarding

DocumentAction
docs/onboarding/DEVELOPER_GUIDE.md (new)K — primary entry
docs/onboarding/DOMAIN_KNOWLEDGE_BASE.md (new)K — primary business primer
docs/onboarding/01-what-is-demozpay.mdA — sup-by SYSTEM_OVERVIEW + DOMAIN_KB
docs/onboarding/02-running-locally.mdA — sup-by DEVELOPER_GUIDE §2-3
docs/onboarding/03-the-codebase-tour.mdA — sup-by HANDBOOK §1
docs/onboarding/04-how-the-backend-works.mdA — sup-by HANDBOOK + DOMAIN_KB
docs/onboarding/06-status-matrix.mdA — sup-by CURRENT_STATE_AUDIT
docs/onboarding/05-the-frontend-apps.mdK
docs/onboarding/07-rules-and-patterns.mdK
docs/onboarding/08-how-to-add-things.mdK
docs/onboarding/09-common-mistakes.mdK

Cluster G — Money flows

DocumentCoverage
docs/architecture/MONEY_FLOWS.md12 canonical flows with status
docs/architecture/BANK_ORCHESTRATION.md4 architectural flows
docs/onboarding/DOMAIN_KNOWLEDGE_BASE.mdPer-domain money flow
docs/architecture/SYSTEM_OVERVIEW.md §53 mermaid sequence diagrams

Single source of truth: DOMAIN_KNOWLEDGE_BASE.md (business view) and SYSTEM_OVERVIEW.md (architectural view). Merge MONEY_FLOWS.md content into the relevant per-domain section of DOMAIN_KB, archive the original.

3.2 The most consequential stale claims (code wins)

ClaimDocReality
"Payroll: Planned"README.md:14, docs/onboarding/01-what-is-demozpay.md, 06-status-matrix.mdLive (backend) — E3 closed 2026-05-29, 38 use cases, 22+ events, 34 tests, 24 Prisma models. Code: packages/payroll/
"Equb / savings: Planned"README.md:19Equb Live Phase 1 Alpha — 8 use cases, 8 events, 6 Prisma models incl. partner-bank escrow. Code: packages/equb/. Savings remains Planned.
"Ledger Go server is Compile-only"restructure-2026-05.md:86, 03-the-codebase-tour.mdLive — all 8 RPCs implemented; 7 store integration tests pass. Code: services/ledger/internal/server/
"Phone OTP: Partial"restructure-2026-05.md:89LivephoneNumber plugin wired; SMS via pluggable module
"Node 20+ required"02-running-locally.md:10Node 22.13+ (pnpm@11 requires it) — apps/api/Dockerfile, observed pnpm failure
"API on port 8000"02-running-locally.md, 04-how-the-backend-works.mdPort 3030 (offset to coexist with telemedhin). README.md:75, infra/docker-compose.full.yml
"LookupAccount stub / DANGEROUS"BANK_ORCHESTRATION.md, DOMAIN_COMPLETENESS_MATRIX.mdLive (Phase C closed 2026-05-29)services/integration-gateway/internal/server/lookup_and_health.go
"EWA/Lending repayment Planned"DOMAIN_COMPLETENESS_MATRIX.mdLive admin pathRecordEwaRepaymentUseCase, RemitInstallmentToFiUseCase
"svc-identity (new NestJS service) to be built by interns"INTERN_PROGRAM.md §9Better-auth is Live in apps/api/src/identity/auth/ — no separate identity service. Intern plan needs re-baselining.
"TLS 1.3 mandatory"SECURITY_CONTROLS.md §A.1Planned — no enforcement; HMAC over plain TCP between services. Status tag says Planned but body text says "mandatory"
"9 of 10 runbooks are stubs"docs/audits/CURRENT_STATE_AUDIT.md (mine)Only cron-migration.md is template. 9 of 10 are real runbooks. My audit is wrong.
"packages/shared/auth is Deprecated"CLAUDE.md:36Live — superseded application (better-auth) but the package is the identity-port boundary, actively imported. Should be tagged Live.

4. Phase 3 — New documentation structure

4.1 The target tree

docs/
├── README.md # NEW — single entry-point, ~80 lines, links only

├── ARCHITECTURE/ # capital so it's visually distinct from old layout
│ ├── SYSTEM_OVERVIEW.md # exec-level (✓ already written)
│ ├── HANDBOOK.md # engineer-level (✓ already written; absorbs PROJECT_STRUCTURE + SYSTEM_TOPOLOGY)
│ ├── LEDGER.md # NEW — extracted from HANDBOOK §5
│ ├── BANK_ORCHESTRATION.md # (existing; one architectural commitment doc tied to ADR-014)
│ ├── RECONCILIATION.md # rename of RECONCILIATION_ARCHITECTURE.md
│ └── SLOS_AND_ALERTING.md # ops contract

├── DOMAINS/
│ ├── DOMAIN_KNOWLEDGE_BASE.md # canonical business + flows (✓ already written)
│ ├── PAYROLL.md # rename of PAYROLL_ARCHITECTURE.md
│ ├── ETHIOPIAN_TAX_ENGINE.md # compliance reference
│ └── (future) BNPL.md, SAVINGS.md # when those packages land

├── API/
│ ├── INVENTORY.md # ✓ API_INVENTORY_FRESH.md, renamed
│ └── (future) per-endpoint detail

├── SECURITY/
│ ├── README.md # NEW — index
│ ├── PERMISSION_MATRIX.md # moved from runbooks/
│ ├── AUTH_SYSTEM_REVIEW.md
│ ├── AUTH_RISK_MATRIX.md
│ ├── AUTH_MIGRATION_STRATEGY.md
│ └── LONG_TERM_IAM_ARCHITECTURE.md

├── OPERATIONS/
│ ├── PRODUCTION_READINESS.md # rewritten + moved from architecture/
│ ├── SLOS_AND_ALERTING.md # symlink-of-record from ARCHITECTURE/
│ └── LOCAL_DEVELOPMENT.md # NEW — extracted from DEVELOPER_GUIDE §2-4

├── ROADMAP/
│ ├── README.md # NEW — index
│ ├── EXECUTION_PLAN_90_DAY.md # ✓ 90_DAY_EXECUTION_PLAN.md, renamed
│ ├── GO_LIVE_BLOCKERS.md # ✓ existing
│ └── PRIORITIES.md # derived from ROADMAP_REALITY_CHECK §6

├── DECISIONS/ # rename of adr/
│ ├── README.md
│ ├── ADR-001..ADR-016 # all 17 files
│ └── (template)

├── RUNBOOKS/
│ ├── README.md # index — 11 real runbooks
│ ├── bank-statement-parse-failed.md
│ ├── drift-detected.md
│ ├── gateway-down.md
│ ├── payroll-ledger-enablement.md
│ ├── payroll-migration-deploy.md
│ ├── sms-smpp-to-http-migration.md
│ ├── transport-swap-pattern.md
│ ├── webhook-failure.md
│ └── deployment-tasks.md # NEW — absorbs cron-migration.md

├── AUDITS/
│ ├── DOCUMENTATION_AUDIT.md # this file
│ ├── CURRENT_STATE_AUDIT.md # ✓ existing
│ └── ROADMAP_REALITY_CHECK.md # ✓ existing

├── ONBOARDING/ # smaller than today
│ ├── README.md # NEW — the one-stop index
│ ├── DEVELOPER_GUIDE.md # ✓ existing
│ ├── RULES_AND_PATTERNS.md # rename of 07-rules-and-patterns.md
│ ├── HOW_TO_ADD_THINGS.md # rename of 08-how-to-add-things.md
│ ├── COMMON_MISTAKES.md # rename of 09-common-mistakes.md
│ ├── FRONTENDS.md # rename of 05-the-frontend-apps.md
│ └── DOMAIN_KNOWLEDGE_BASE.md # symlink-of-record from DOMAINS/

├── PRODUCT/ # NEW — for biz/founder material
│ ├── README.md
│ └── EQUB_FINANCIAL_PROJECTION.md # moved from repo root

├── STATUS_LEGEND.md # stays at docs/ root — universal reference

└── ARCHIVE/
├── README.md # guard rail
├── (existing 6 files)
├── SYSTEM_GAP.md # archived (gaps closed)
├── SYSTEM_GAP_ACTION_PLAN.md # archived
├── API_INVENTORY.md # archived (sup-by AUDITS/INVENTORY)
├── REAL_SYSTEM_STATE.md # archived (sup-by AUDITS)
├── SYSTEM_NOT_IMPLEMENTED.md # archived (sup-by AUDITS)
├── DOMAIN_COMPLETENESS_MATRIX.md # archived
├── PHASE_C_LOOKUP_ACCOUNT.md # archived (phase-specific)
├── restructure-2026-05.md # archived (self-marked historical)
├── MONEY_FLOWS.md # archived (folded into DOMAIN_KB)
├── BANK_ORCHESTRATION.md # archived after merge into ADR-014 + DOMAIN_KB
├── SYSTEM_TOPOLOGY.md # archived after merge into HANDBOOK §8
├── 01-what-is-demozpay.md # archived
├── 02-running-locally.md # archived
├── 03-the-codebase-tour.md # archived
├── 04-how-the-backend-works.md # archived
└── 06-status-matrix.md # archived

Top-level (/)

README.md # single project intro, ~150 lines, points at docs/
CLAUDE.md # ~90 lines: non-negotiables + AI behaviour
PROJECT_STRUCTURE.md # DELETE (content folded into HANDBOOK)
SECURITY_CONTROLS.md # KEEP for partner visibility; REWRITE with evidence column
INTERN_PROGRAM.md # KEEP at root; REWRITE baseline
equb-financial-projection.md # MOVE to docs/PRODUCT/

apps/docs-web/

Decision: either gut and re-wire, or delete.

  • If we wire docs-web up: delete docs/, blog/, src/pages/markdown-page.md from inside docs-web; replace sidebars.ts with a sidebar mirroring the new docs/ tree above; symlink-import the real docs/ content.
  • If we don't: leave docs-web in Stub status indefinitely; nothing broken, just visible noise.

Recommendation: wire it (option 1) once the cleanup above lands.

4.2 Why each top-level folder

FolderWhy
ARCHITECTURE/Patterns + system shape. Engineer reference.
DOMAINS/Business + domain primer per domain. Per-domain README is inside the package; deep dives live here.
API/Catalogue of HTTP/gRPC surface. Single inventory file plus future per-endpoint detail.
SECURITY/Auth model, RBAC, threat model, prior reviews.
OPERATIONS/Day-2 ops: dev setup, production readiness, SLOs.
ROADMAP/What we will build next. Two docs only (blockers + plan).
DECISIONS/The ADRs. The "why" of every rule.
RUNBOOKS/First-responder playbooks per failure mode.
AUDITS/Snapshots in time. Living docs are elsewhere.
ONBOARDING/New-hire path; six docs only.
PRODUCT/Business material; founder pitch decks etc.
ARCHIVE/Out-of-date docs preserved for reference.

5. Phase 4 — New-developer onboarding review

The thought experiment. A developer joins on a Monday morning. What do they read? What confuses them? What slows them down?

5.1 What they should read first (in the new structure)

WhenDocTime
Morning 1README.md (top-level)5 min
Morning 1docs/ARCHITECTURE/SYSTEM_OVERVIEW.md30 min
Morning 1docs/ONBOARDING/DEVELOPER_GUIDE.md §1-545 min
Morning 1clone + boot stack (DEVELOPER_GUIDE.md §2-3)60 min
Afternoon 1docs/DOMAINS/DOMAIN_KNOWLEDGE_BASE.md60 min
Afternoon 1docs/DECISIONS/ — all 16 ADRs90 min
Day 2docs/ARCHITECTURE/HANDBOOK.md90 min
Day 2docs/ONBOARDING/RULES_AND_PATTERNS.md30 min
Day 3Pick a domain. Read its package README + docs/DOMAINS/<DOMAIN>.md if it exists. Trace one HTTP request from controller to ledger.half a day

Total reading time before contributing: ~6 hours, spread across 2 days.

5.2 What is confusing today

  1. Three different "where to start" docs at the root: README.md, CLAUDE.md, PROJECT_STRUCTURE.md. A new dev opens all three and notices contradictions (the payroll status mismatch alone is enough to undermine trust).
  2. Eight competing status docs. A new dev who wants to know "what's actually built?" finds SYSTEM_GAP.md, REAL_SYSTEM_STATE.md, DOMAIN_COMPLETENESS_MATRIX.md, SYSTEM_NOT_IMPLEMENTED.md, 06-status-matrix.md, CURRENT_STATE_AUDIT.md, API_INVENTORY.md, ROADMAP_REALITY_CHECK.md. They don't know which to trust.
  3. Onboarding split between old and new. docs/onboarding/01-09 and DEVELOPER_GUIDE.md say different things about Node version, port, and payroll status.
  4. Docs-web is a Docusaurus tutorial template. A new dev who opens it sees "Tutorial Basics: Create a Page" — and thinks the project is unfinished or abandoned.
  5. INTERN_PROGRAM.md says interns will "build svc-identity" — but the codebase has better-auth Live in apps/api/src/identity/auth/. The intern plan reads like fiction.
  6. SECURITY_CONTROLS.md mixes Live with Planned without clearly partitioning. A partner reading it thinks "TLS 1.3 mandatory" — which is documented as Planned.

5.3 What's missing

  • Single project intro for a non-engineer. README.md mixes pitch with clone-and-run; a PM or partner has to skim. A 1-page docs/PRODUCT/INTRODUCTION.md would help.
  • First-issue checklist. "Here are 5 issues a new contributor can pick up today" — none of the onboarding docs name concrete starter tasks.
  • Glossary. Done in DOMAIN_KB §15; needs to be linked from README.md and DEVELOPER_GUIDE.md.
  • Per-domain runbook index. Today there's one runbooks folder for all of ops; map runbooks to domains so a payroll engineer reads only payroll runbooks.
  • A real Nx primer for engineers new to monorepos. The existing one in docs/archive/NX_WORKSPACE_EXPLAINED.md is stale.

5.4 What appears too many times

TopicWhere it appears todayRecommended single source
Repo layoutREADME + CLAUDE + PROJECT_STRUCTURE + HANDBOOK + 03-codebase-tour + SYSTEM_TOPOLOGY (×6)docs/ARCHITECTURE/HANDBOOK.md §1
Money is santimREADME + CLAUDE + every domain README + every ADR + every architecture docADR-005 + one line in HANDBOOK
RLS / tenant isolationREADME + CLAUDE + ADR-013 + RLS.md + every domain README + SYSTEM_GAP + restructureADR-013 + RLS.md (apps/api/prisma/)
Ledger as truthREADME + CLAUDE + ADR-006 + ADR-012 + LEDGER doc + every flow docADR-006 + new LEDGER.md
"What's Live today"8 docs (see §3.1 cluster B)docs/AUDITS/CURRENT_STATE_AUDIT.md
"What's next"5 docs (see §3.1 cluster C)docs/ROADMAP/ (2 files only)
Money flow walkMONEY_FLOWS + BANK_ORCHESTRATION + DOMAIN_KB + SYSTEM_OVERVIEW (×4)docs/DOMAINS/DOMAIN_KNOWLEDGE_BASE.md per-domain section

5.5 Recommended onboarding path (post-cleanup)

Day 1 — orient

  • Read: README.mddocs/ARCHITECTURE/SYSTEM_OVERVIEW.mddocs/STATUS_LEGEND.md.
  • Run: clone repo, docker compose up, hit every health endpoint, open Prisma Studio.
  • Read all 16 ADRs.

Day 2 — internalise the patterns

  • Read: docs/ARCHITECTURE/HANDBOOK.md (full).
  • Read: docs/ONBOARDING/RULES_AND_PATTERNS.md.
  • Read: docs/DOMAINS/DOMAIN_KNOWLEDGE_BASE.md.

Day 3 — see one flow end-to-end

  • Pick EWA. Read packages/ewa/README.md, all 4 use cases, the EWA controller in apps/api/src/products/ewa/, the Go ledger handler services/ledger/internal/server/post_transaction.go. Trace a POST /api/ewa/requests/:id/disburse from controller → use case → ledger → integration-gateway → mock bank → webhook → ConfirmSettlement.
  • Run the EWA test suite. Modify one assertion. Watch it fail.

Day 4 — touch the schema

  • Read docs/STATUS_LEGEND.md again, then docs/AUDITS/CURRENT_STATE_AUDIT.md to find a documented gap.
  • Pick a small bug or test gap (e.g. one of the KYC use cases that lacks a spec). Write the spec. Get it green. Open a PR.

Day 5 — write your first real change

  • Pick a small feature from docs/ROADMAP/GO_LIVE_BLOCKERS.md that aligns with your domain. Pair with a reviewer. Land a small slice.
  • Read docs/ONBOARDING/HOW_TO_ADD_THINGS.md recipe for whatever you're touching.

By end of week 1, a new engineer should:

  • Be able to boot the stack from scratch.
  • Know which doc to consult for each kind of question.
  • Have one merged PR.

6. Phase 5 — Document quality scores

Scored 1-10 on four axes. Total /40. Only major docs scored — package READMEs, ADRs, and runbooks are uniformly high (~8-9/10 each) and not scored individually.

6.1 The best documents (keep, model others on these)

DocAccCompMaintDXTotalWhy it's good
docs/STATUS_LEGEND.md1010101040Tiny, precise, universally referenced
docs/adr/ADR-013-tenant-isolation.md101010939RLS pattern documented end-to-end
docs/adr/ADR-006-ledger-sole-source-of-truth.md10109938Foundational, code-matched
services/ledger/README.md10991038Self-contained service explanation
packages/shared/money/README.md10991038Crystal clear on santim semantics
docs/audits/CURRENT_STATE_AUDIT.md (new)998935Evidence-grounded, file:line cited
docs/onboarding/07-rules-and-patterns.md1098835The seven non-negotiables; durable
docs/runbooks/drift-detected.md1099836Real runbook with steps + diagnosis
docs/runbooks/webhook-failure.md1099836Same shape
docs/runbooks/permission-matrix.md998935Canonical RBAC reference

6.2 The dangerous documents (action required — they actively mislead)

DocAccCompMaintDXTotalSpecific lies
README.md (top-level)586726Says Payroll + Equb are Planned; both are Live. First doc a new dev reads.
INTERN_PROGRAM.md494623Plan-builds-svc-identity contradicts better-auth being Live in apps/api/src/identity/auth/
SECURITY_CONTROLS.md595524"TLS 1.3 mandatory" + status=Planned — partner-facing doc with contradictory claims
docs/onboarding/02-running-locally.md474520Wrong Node version, wrong port, missing infra/docker-compose.full.yml flow
docs/onboarding/01-what-is-demozpay.md575623"Payroll Planned — no payroll domain package"
docs/onboarding/06-status-matrix.md586726Stale payroll row
docs/architecture/REAL_SYSTEM_STATE.md685726Self-superseded by the new audit
docs/architecture/DOMAIN_COMPLETENESS_MATRIX.md684725EWA/Lending repayment marked Planned; LookupAccount marked DANGEROUS — both Live
docs/architecture/restructure-2026-05.md784827Says ledger Go server is Compile-only; it has 8 RPCs Live
docs/SYSTEM_GAP_ACTION_PLAN.md685625Header says "no commits while standing instruction in force" — gaps are closed, instruction is stale

6.3 The bulk of the mid-tier

All package READMEs, all ADRs (except 015/016 which are Proposed), all 9 real runbooks, my four new audit docs, HANDBOOK.md, SYSTEM_OVERVIEW.md, DOMAIN_KNOWLEDGE_BASE.md, DEVELOPER_GUIDE.md, the security docs — all score 30-36/40. They are the documentation that should remain.

6.4 Score summary

TierCountAction
Excellent (35+)~30 docsKeep, treat as templates
Good (28-34)~30 docsKeep, occasional edits
Needs rewrite (22-27)~10 docsRewrite or archive
Dangerous (<22)~3 docsRewrite urgently
Boilerplate / template / scaffold~30 docs (docs-web template + dist + archive)Delete or wipe

7. Phase 6 — Cleanup execution plan

Constraint: every batch is a single PR that runs git mv + edits without touching application code. Reviewable in <30 min.

Week 1 — kill the lies

DayWorkPR
MonFix README.md payroll + equb status. Add date stamp _Last reviewed: 2026-05-31_. Link to docs/audits/ for ground truth.#1
MonFix CLAUDE.md payroll line + packages/shared/auth tag (Deprecated → Live).#1
TueMove equb-financial-projection.mddocs/PRODUCT/. Delete apps/docs-web/docs/tutorial-basics/*, tutorial-extras/*, blog/*, src/pages/markdown-page.md. Delete docs/portals/admin.md, business.md.#2
Tuegit rm --cached dist/ — remove the 11 accidentally-tracked README files.#3
WedArchive cluster B (system status): move SYSTEM_GAP.md, SYSTEM_GAP_ACTION_PLAN.md, REAL_SYSTEM_STATE.md, DOMAIN_COMPLETENESS_MATRIX.md, SYSTEM_NOT_IMPLEMENTED.mddocs/archive/. Add forward-links to docs/audits/CURRENT_STATE_AUDIT.md.#4
WedArchive cluster D: move docs/API_INVENTORY.mddocs/archive/. Rename docs/audits/API_INVENTORY_FRESH.mddocs/API/INVENTORY.md.#4
ThuArchive cluster F onboarding: move 01-04, 06docs/archive/. Rename 05FRONTENDS.md, 07-09 to keyword names. Update docs/onboarding/README.md to be the new index.#5
FriOne-line fix in docs/audits/CURRENT_STATE_AUDIT.md about runbooks ("only cron-migration.md is template, not 9 of 10").#6

Output: 6 PRs. ~30 docs archived. README + CLAUDE.md no longer mislead.

Week 2 — merge the duplicates

DayWorkPR
MonMerge PROJECT_STRUCTURE.md content into HANDBOOK.md §1. Archive PROJECT_STRUCTURE.md.#7
MonMerge SYSTEM_TOPOLOGY.md content into HANDBOOK.md §8. Archive SYSTEM_TOPOLOGY.md.#7
TueMerge MONEY_FLOWS.md into per-domain sections of DOMAIN_KNOWLEDGE_BASE.md. Archive MONEY_FLOWS.md.#8
TueMerge BANK_ORCHESTRATION.md content — keep half in ADR-014 supplement, half in DOMAIN_KB. Archive original.#8
WedMove restructure-2026-05.mddocs/archive/ (self-marked historical).#9
WedMove PHASE_C_LOOKUP_ACCOUNT.mddocs/archive/ (phase-specific delivery note).#9
ThuRename folders: docs/adr/docs/DECISIONS/. Update all references.#10
ThuPromote runbooks/permission-matrix.md → docs/SECURITY/. Merge cron-migration.md into a new deployment-tasks.md.#10
FriCreate docs/ROADMAP/ and move 90_DAY_EXECUTION_PLAN.md + GO_LIVE_BLOCKERS.md there.#11
FriCreate docs/OPERATIONS/ and move + rewrite PRODUCTION_READINESS.md.#11

Output: 5 PRs. Architecture folder shrinks from 17 → 6 files.

Week 3 — rewrite the dangerous

DayWorkPR
Mon-TueRewrite SECURITY_CONTROLS.md with an evidence column. Each row points to migration/code/test or marks as Planned.#12
WedRewrite INTERN_PROGRAM.md baseline to match current code state. Re-phase the curriculum so interns build next things, not already done things.#13
ThuWrite a new top-level README.md that is ~150 lines, points at the new docs/ tree, no duplication.#14
ThuTrim CLAUDE.md to <100 lines: just non-negotiables + AI behaviour rules, no duplication.#14
FriWrite the new docs/README.md as the canonical index.#14
FriWrite docs/ONBOARDING/README.md as the entry point linking DEVELOPER_GUIDE + DOMAIN_KB + RULES + HOW_TO_ADD + COMMON_MISTAKES.#14

Output: 3 PRs. Three "dangerous" docs fixed. Entry experience clean.

DayWork
MonDecide: wire docs-web or delete. If wire:
TueInstall @docusaurus/theme-mermaid (the new architecture docs have mermaid diagrams).
Tue-WedReplace apps/docs-web/sidebars.ts to mirror the new docs/ tree.
WedSymlink-import or git-submodule the real docs/ content into apps/docs-web/docs/.
ThuBoot, screenshot, send link.
FriDocument the docs-web wiring in docs/OPERATIONS/.

Output: 1 PR. docs-web Stub → Live.

Cleanup totals

ActionCount
Total markdown files today143
Keep (after move/rename)~70
Merge~10 (content folded elsewhere)
Archive~25
Delete (boilerplate + dist + obsolete)~30
Rewrite~5
Result~70 active + ~25 archived

8. Single source of truth — final assignments

The table every reviewer should consult when asked "where does this belong?":

TopicThe one place
Project pitch + clone-and-runREADME.md (top-level)
AI / Claude behaviour rulesCLAUDE.md (top-level, terse)
Repo layout + monorepo structuredocs/ARCHITECTURE/HANDBOOK.md §1
Stack + commandsdocs/ARCHITECTURE/HANDBOOK.md + docs/ONBOARDING/DEVELOPER_GUIDE.md
Status tag definitionsdocs/STATUS_LEGEND.md
What's actually Live / Partial / Stub todaydocs/AUDITS/CURRENT_STATE_AUDIT.md
API endpointsdocs/API/INVENTORY.md
What's next / roadmapdocs/ROADMAP/GO_LIVE_BLOCKERS.md + docs/ROADMAP/EXECUTION_PLAN_90_DAY.md
Architectural decisions ("why")docs/DECISIONS/ADR-*.md
Money flow per domaindocs/DOMAINS/DOMAIN_KNOWLEDGE_BASE.md
Ledger architecture (deep)docs/ARCHITECTURE/HANDBOOK.md §5 + services/ledger/README.md
Tax engine (Ethiopia compliance)docs/DOMAINS/ETHIOPIAN_TAX_ENGINE.md
Payroll deep-divedocs/DOMAINS/PAYROLL.md
Reconciliation operationsdocs/ARCHITECTURE/RECONCILIATION.md
SLOs + alertsdocs/ARCHITECTURE/SLOS_AND_ALERTING.md
Auth + RBAC + permission matrixdocs/SECURITY/PERMISSION_MATRIX.md (+ AUTH_*.md)
Long-term IAM targetdocs/SECURITY/LONG_TERM_IAM_ARCHITECTURE.md
Local dev setupdocs/ONBOARDING/DEVELOPER_GUIDE.md §2-3
Production readiness scorecarddocs/OPERATIONS/PRODUCTION_READINESS.md
First-responder playbooksdocs/RUNBOOKS/*.md
Domain business primerdocs/DOMAINS/DOMAIN_KNOWLEDGE_BASE.md
Coding standards + rulesdocs/ONBOARDING/RULES_AND_PATTERNS.md
How to add a new endpoint/domain/migrationdocs/ONBOARDING/HOW_TO_ADD_THINGS.md
Debuggingdocs/ONBOARDING/COMMON_MISTAKES.md
First-week curriculumdocs/ONBOARDING/DEVELOPER_GUIDE.md §9
Intern curriculumINTERN_PROGRAM.md (top-level)
Partner-facing security stanceSECURITY_CONTROLS.md (top-level)
Founder / business materialdocs/PRODUCT/*.md
Historical contextdocs/archive/*.md

8.1 The deletion-vs-archive judgement

  • Delete = the content is dangerous or pure noise. Docusaurus template, dist accidents, theme-system-plan, the placeholder portals/admin.md etc.
  • Archive = the content was once true and may have research/audit value. SYSTEM_GAP (gaps closed but log of how we got here), restructure-2026-05, REAL_SYSTEM_STATE (predecessor of current audit), old onboarding sequence.
  • Keep = the content is current and load-bearing today.
  • Rewrite = the content is right-shaped but wrong-detailed. README payroll status, SECURITY_CONTROLS evidence column, INTERN_PROGRAM baseline.

8.2 What survives long-term

If we did nothing else, the 20 documents below are enough for a new engineer to understand and work on DemozPay:

  1. README.md
  2. CLAUDE.md
  3. docs/STATUS_LEGEND.md
  4. docs/ARCHITECTURE/SYSTEM_OVERVIEW.md
  5. docs/ARCHITECTURE/HANDBOOK.md
  6. docs/DOMAINS/DOMAIN_KNOWLEDGE_BASE.md
  7. docs/ONBOARDING/DEVELOPER_GUIDE.md
  8. docs/ONBOARDING/RULES_AND_PATTERNS.md
  9. docs/ONBOARDING/HOW_TO_ADD_THINGS.md
  10. docs/ONBOARDING/COMMON_MISTAKES.md
  11. docs/API/INVENTORY.md
  12. docs/AUDITS/CURRENT_STATE_AUDIT.md
  13. docs/AUDITS/ROADMAP_REALITY_CHECK.md
  14. docs/ROADMAP/GO_LIVE_BLOCKERS.md
  15. docs/ROADMAP/EXECUTION_PLAN_90_DAY.md
  16. docs/DECISIONS/ADR-001 through ADR-016 (counted as one item)
  17. docs/RUNBOOKS/README.md + the 9 live runbooks
  18. docs/SECURITY/*.md (4 docs)
  19. Every domain package's packages/<x>/README.md
  20. Every service's services/<x>/README.md

Everything else is supporting material. Anything beyond this list deserves justification.


Closing assertion

DemozPay's documentation is in better shape than it feels, but the volume and contradictions make it feel worse than it is. The cleanup work is mechanical (move, archive, delete) plus three rewrites (README.md, SECURITY_CONTROLS.md, INTERN_PROGRAM.md). After three weeks of effort, the doc tree shrinks from 143 files to ~70 active + ~25 archived, with no information loss — only deduplication, freshness, and clarity gained.

Do this before onboarding the next engineer. The cost of an extra week of doc cleanup is repaid by every future hire reading less and contributing sooner.