Dev Handbook — Index (MOC)
The map of content for the dev-handbook: the single knowledge monorepo for
all projects (0009-one-knowledge-monorepo). Open this folder as an Obsidian
vault and the [[wikilinks]] render as a navigable graph.
What lives where
- Generic decisions (would hold for any project) →
core/, by area:
workflow/,backend/,frontend/,infra/. - Where the proven code lives →
docs/private/reference-implementations.md: for each
generic concern, the governing ADRs and the classes that implement them in each project.
A lookup page, not a decision record, and unpublished, since it names private repos’
internals; browse it in the repo or the Obsidian vault. - Project-scoped decisions → the project’s folder, e.g.
docs/expenses/
(start at itsindex.md). Project folders are private — they are not
published on the rendered site; browse them in the repo / Obsidian vault. - Behavior / SOPs (skills, agents, hooks) → the
kit/plugins:
handbook(generic, manifest-driven) + one per project (e.g.expenses). - Workspace manifest →
handbook.jsonat each workspace root (canonical
copies inmanifests/); generic kit skills read it instead of hardcoding
repo names. - Claude’s recall → the per-user memory store, which should point at these
ADRs rather than restate them.
Promotion convention: decisions are born in a project folder and move to
core/ when they prove generic — git mv + a generalization pass; the project’s
specifics stay as illustrations. Wikilinks are filename-based, so moves don’t
break them.
Core ADRs
| ADR | Title | Area | Status |
|---|---|---|---|
| 0001-three-step-git-flow | Three-step Git flow (feature → develop → main) | workflow | Accepted |
| 0003-collaboration-working-agreements | Collaboration & git working agreements | workflow | Accepted |
| 0004-version-keyed-changelog | Version-keyed changelog, written at release time | workflow | Accepted |
| 0009-one-knowledge-monorepo | One knowledge monorepo, folders per project, promote to core | workflow | Accepted |
| 0001-status-as-source-of-truth | Lifecycle status is an explicit enum, not derived at runtime | backend | Accepted |
| 0002-clean-architecture-and-use-cases | Clean Architecture with single-responsibility use cases | backend | Accepted — amended 2026-09-10 (transactional web services, whitelisted sort input, a catch-all only for server faults; a write that must survive a refusal commits on its own) |
| 0003-ddd-intent-methods | Domain entities own their invariants via intent-expressing methods | backend | Accepted |
| 0006-disambiguate-beans-by-concrete-type | Disambiguate Spring beans by concrete type, not field @Qualifier | backend | Accepted |
| 0010-schema-changes-via-migrations | Schema changes only via versioned migrations; profile-gated dev seeds | backend | Accepted — amended 2026-09-10 (the dev profile runs Flyway out of order) |
| 0011-dto-design-rules | DTO design — complete top-level representations, slim embedded children; collections return summaries | backend | Accepted — amended 2026-09-10 (collections return summaries) |
| 0012-profile-switched-outbound-gateways | Profile-switched outbound gateways — dev needs zero credentials | backend | Accepted — amended 2026-09-10 (required settings have no base-profile default; notifications are sent after commit) |
| 0013-value-objects-for-domain-primitives | Value objects for domain primitives — self-validating, with a converter | backend | Accepted |
| 0013-sessions-and-refresh-tokens | Sessions & refresh tokens — revocable auth, rotation, one door into “logged in” | backend | Accepted — promoted 2026-09-10 (from expenses/) |
| 0016-stable-pagination-tiebreaker | Every paginated query needs a unique sort tiebreaker | backend | Accepted |
| 0017-persistent-entity-baseline | Persistent-entity & new-backend baseline — generated id, protected no-arg ctor, audit base, Lombok subset | backend | Accepted — amended 2026-09-10 (on Boot 4, the starter, not the library) |
| 0018-resource-access-session-scoped-or-actor-declared | Who may touch a user’s resource — session-scoped or actor-declared, chosen at project start | backend | Accepted |
| 0019-llm-features-prompts-shape-code-enforces | LLM features — the prompt shapes the answer, code enforces the boundary | backend | Accepted |
| 0002-i18n-both-locales | Every user-facing string lives in both locales | frontend | Accepted |
| 0006-frontends-are-mobile-first | Frontends are mobile-first | frontend | Accepted |
| 0001-feature-vertical-slices | Feature vertical slices + folder-per-component | frontend | Accepted |
| 0003-masked-inputs-for-formattable-values | Masked inputs for every formattable value | frontend | Accepted |
| 0004-component-state-hygiene-and-shared-form-logic | Component state hygiene & shared form logic | frontend | Accepted — amended 2026-08-03 (unmount reused modals, don’t reset them) |
| 0013-centralized-api-layer-and-server-state | Centralized API layer & server-state discipline | frontend | Accepted |
| 0014-theme-tokens-not-hex | Semantic theme tokens, not hex literals | frontend | Accepted |
| 0015-design-system-as-single-visual-source | The design system is the only visual source — never hand-roll | frontend | Accepted |
| 0020-clients-disclose-nothing-the-privacy-policy-does-not-name | A client sends nothing the privacy policy does not name — self-hosted assets, image metadata stripped, unused permissions blocked | frontend | Accepted |
| 0021-failures-are-shown-not-guarded | Failures are shown, not guarded — failed is a render state, boundaries catch render errors, one handler reports failed queries | frontend | Accepted |
| 0007-rate-limiting-at-the-edge | Rate limiting & abuse protection live at the edge, not in the app | infra | Accepted — promoted 2026-09-10 (from expenses/) |
The handbook’s own ADR sequence is global — next is 0022 regardless of
area. Backend 0001/0002/0003/0006/0013 (sessions), frontend 0001/0003/0004 and
infra 0007 kept their numbers when promoted from theexpenses/folders
(0009-one-knowledge-monorepo); project folders imported from code repos
likewise keep their original folder-scoped numbering. New decisions: copy
_adr-template.md, fill it in, add a row here (or in the project index).Numbers therefore repeat across areas: core holds three 0013s (backend value
objects, backend sessions, frontend API layer). Wherever a bare number would be
ambiguous, cite the ADR by its slug.
Projects
Most workspaces live under the add-projects/ umbrella (AI Driven
Development), side by side with the single shared dev-handbook/ checkout.
A standalone workspace sits elsewhere and is its own repo root — it still
reads this handbook, via the handbook/projectDocs paths in its manifest:
| Project | Docs (private) | Plugin | Workspace |
|---|---|---|---|
| AllSensis | docs/allsensis/ | — (inherits core) | add-projects/allsensis/ |
| Expenses | docs/expenses/ | expenses | add-projects/expenses/ |
| Barbershop | docs/barbershop/ | — (inherits core) | add-projects/barbershop/ |
| Tickets | docs/tickets/ | — (inherits core) | add-projects/tickets/ |
| Dracomania | docs/dracomania/ | — (inherits core) | ~/projects/dracomania/ (standalone) |
The kit
Two plugins hosted by this repo’s marketplace (see the repo README.md for
install commands):
Plugin handbook (generic, namespace handbook:)
Skills:
| Skill | Does | Enforces |
|---|---|---|
handbook:i18n-parity | Diffs en.json vs pt.json across all apps in the workspace | 0002-i18n-both-locales |
handbook:release | Git-flow release: bump + CHANGELOG + tag (repos from handbook.json); for a repo whose manifest entry declares storeBuild, ends by starting that store build and handing over the link | 0001-three-step-git-flow, 0004-version-keyed-changelog |
handbook:changelog-backfill | Backfills a repo’s CHANGELOG from git tags | 0004-version-keyed-changelog |
handbook:feature-kickoff | Recap + branch off develop in each affected repo | 0001-three-step-git-flow, 0003-collaboration-working-agreements |
Agents (independent reviewers, read-only; all read handbook.json + the
project’s docs for context): handbook:ask-dev, ask-ba, ask-designer,
ask-finance, ask-marketing, ask-mobile (enforces
0006-frontends-are-mobile-first), ask-legal. They challenge, they don’t create.
ask-legal is split from the curator on purpose — they ask opposite questions.
The curator asks “is what we wrote still true?” (authority: the codebase).
ask-legal asks “does what we shipped create a disclosure/consent
obligation we haven’t met?” (authority: the live Terms of Use and Privacy Policy + the data the
code actually collects + the third parties it actually sends it to). An agent
tuned to code-fidelity reliably under-notices a new category of personal data.
It drafts clauses for human review; it never publishes legal text.
Maintainer (write-capable, no git): handbook:docs-curator — audits the ADR set
- each repo’s
CLAUDE.mdfor redundancy, wrong scope, drift, gaps and broken
links, and drafts the fixes in place; commits stay with the human.
Hooks: a Stop hook runs i18n-parity after every turn — advisory (silent on
parity, warns on gaps, never blocks), self-enforcing 0002-i18n-both-locales.
Plugin expenses (project-specific, namespace expenses:)
| Skill | Does |
|---|---|
expenses:new-use-case | Scaffold a backend use case (Clean Architecture + validation strategy) |
expenses:new-page | Scaffold a frontend vertical slice (i18n + mobile-first) |
Maintainer (write-capable, no git): expenses:assistant-curator — owns the
model-facing surface, where docs-curator owns the human-facing one: the
ChatTool set and their descriptions, the CHAT_ASSISTANT system prompt and its
tool routing, and the analysis sandbox schema. It exists because
ChatToolRegistry auto-discovers tools, so a new tool is callable the moment it
is written while the model only reaches it if the prompt’s routing block names it —
a capability can ship orphaned, as get_budget_status did in v1.63.0. It drafts
the fixes in place; commits stay with the human.