ADR-0009: One knowledge monorepo, folders per project, promote to core

  • Status: Accepted
  • Date: 2026-06-05
  • Scope: core (the handbook itself)

Context

This repo began as expenses-knowledge, the shared brain for one product. A
second project is starting, and it should reuse every non-business decision
already made (git flow, architecture skeletons, i18n discipline, mobile-first,
…). Three storage shapes were considered:

  1. A knowledge repo per project — multiplies repos, scatters decisions, and
    makes “have we solved this before, in any project?” unanswerable in one place.
  2. A documentation platform (Notion, Docmost) — nice reading UI, but the
    primary consumer of these docs is the AI assistant, which needs plain files
    in a working tree (grep, no auth, no rate limits, offline in headless runs).
    Moving the brain behind an API breaks the curator agent, hooks, and skills.
  3. One git monorepo of knowledge, partitioned by folders — chosen.

Branch-per-project partitioning was explicitly rejected: branches are for
divergent versions that converge, not for permanently parallel content. They
prevent seeing the whole brain in one tree, break cross-project links and
search, and turn promotion into cherry-picks.

Decision

This repo — dev-handbook — is the single knowledge monorepo for all
projects:

docs/
├── core/<area>/          ← generic decisions (workflow, backend, frontend, infra)
├── <project>/<area>/     ← project-scoped decisions (e.g. expenses/)
kit/
├── core/                 ← plugin "handbook" — generic skills/agents (handbook:*)
└── <project>/            ← per-project plugin (e.g. expenses:*)
  • Decisions are born project-scoped and promoted to core/ when they
    prove generic (or a second project wants them). Promotion = git mv + a
    generalization pass; the project’s specifics stay as illustrations.
  • ADR numbering: the handbook’s own sequence is global (0001…, this doc is
    0009, next is 0010); ADR sets imported from code repos keep their original
    numbers inside their folder (e.g. expenses/backend/0001-…). Full filenames
    (number + slug) stay unique handbook-wide, and a doc keeps its number when
    promoted between folders.
  • Wikilinks are filename-based ([[0001-three-step-git-flow]], no folder
    prefix) so links survive promotion moves.
  • Code repos keep no docs/adr/ of their own — their ADRs live here under
    the project’s folder, and each code repo’s CLAUDE.md points here. Trade-off
    accepted: doc edits no longer ride in the same commit as the code they govern.
  • Generic kit skills are manifest-driven, not duplicated per project: a
    handbook.json at each workspace root declares the project’s repos, version
    files, and locale paths; skills read it instead of hardcoding repo names.
  • Reading UX is solved by rendering, not migrating: a static site (Quartz)
    built from docs/, deployed like any other frontend. Git stays the single
    source of truth.

Consequences

  • One place to ask “how do we do X?” — for humans (rendered site / Obsidian
    vault) and for the assistant (grep).
  • New projects start by installing the handbook plugin and adding a
    docs/<project>/ folder + handbook.json manifest — every core decision is
    inherited for free.
  • The handbook repo becomes a dependency of every project’s workflow; it keeps
    the same three-step git flow and approval gates as any code repo.
  • Cross-project content lives further from the code it governs; the
    docs-curator agent is the drift watchdog.