163 lines
11 KiB
Markdown
163 lines
11 KiB
Markdown
# The Clarify Chain — a plan to clean up Balinyaar's documentation
|
||
|
||
**Status:** planned, not started · **Written:** 2026-07-29 · **Baseline commit:** `96b57eb`
|
||
|
||
This folder is a **plan**, not documentation. It describes eight phases that take the repo from its
|
||
current state — 260 markdown files, ~10 competing rule sources, five unreconciled backlogs, and a
|
||
contract layer that stopped tracking the code on 2026-07-13 — to a single navigable `docs/` tree that
|
||
tells the truth.
|
||
|
||
When the chain finishes, **this folder moves to `archive/`**. It is temporary by design.
|
||
|
||
---
|
||
|
||
## Why this exists (the diagnosis)
|
||
|
||
Measured against the working tree at `96b57eb`:
|
||
|
||
| Finding | Evidence |
|
||
| --- | --- |
|
||
| **3.0 MB / 199 files of build history in [`dev/`](../../dev/)** reads as instruction, not record | [`dev/phases/`](../../dev/phases/) last touched 2026-06-28 (already-executed prompts) sits beside [`dev/post-phase/`](../../dev/post-phase/) touched 2026-07-28 (live plan). Nothing marks the difference. |
|
||
| **Rules live in ~10 places** | root [CLAUDE.md](../../CLAUDE.md) · [client/CLAUDE.md](../../client/CLAUDE.md) **161 KB** · [server/CLAUDE.md](../../server/CLAUDE.md) 75 KB · [server/CONVENTIONS.md](../../server/CONVENTIONS.md) · [client/messages/STYLE.md](../../client/messages/STYLE.md) · [.claude/skills/frontend-designer/SKILL.md](../../.claude/skills/frontend-designer/SKILL.md) · [dev/phases/_shared/](../../dev/phases/_shared/) ×4 · [dev/contracts/conventions/](../../dev/contracts/conventions/) ×2 · 3× `AGENTS.md` · [.githooks/README.md](../../.githooks/README.md) |
|
||
| **Loading `client/CLAUDE.md` costs ~40k tokens** on any client edit | 161 KB, of which lines 103–421 are a project-structure listing and lines 421–1100 are explanatory reference |
|
||
| **Remaining work is split across 5 ledgers** | 67 REQs in a 1,115-line append-only file · **18 hardening items, none ticked** · per-phase "Follow-ups" buried in 50+ reports · backend deferrals-with-pull-triggers · [product/notes/open-questions.md](../../product/notes/open-questions.md) · two raw feedback notes in [dev/manual-testing/](../../dev/manual-testing/) |
|
||
| **Contracts drifted from code** | [`dev/contracts/`](../../dev/contracts/) frozen 2026-07-13; `server/src` moved through 2026-07-28. OpenAPI snapshot is from 07-13; a second stale copy sat at `temp/swagger.json` (07-06). **Phase 0 correction:** that copy was **untracked** (`.gitignore:1`), and the measured OpenAPI drift turned out to be one endpoint — see [open-contradictions.md](open-contradictions.md#openapi-drift). |
|
||
| **18 files still instruct you to use `dotnet user-secrets`** — removed in `5885280` | includes [manual-testing-plan.md](../../dev/post-phase/manual-testing-plan.md), the closest thing to a test guide |
|
||
| **No single "what's implemented + how to test it"** | knowledge split across manual-testing-plan, [RUNBOOK.md](../../dev/post-phase/refinement/RUNBOOK.md), `product/business/`, and 18 contract files |
|
||
| **The client↔server dependency is implicit** | envelope shape, casing, idempotency, cookies/refresh, CORS, `NEXT_PUBLIC_API_URL`, 3 containers + Caddy + remote SQL + the OTP bot — described nowhere as one thing |
|
||
|
||
The code itself is **not** the mess. 83 client routes, 22 service domains, 125 client tests; 56
|
||
controllers, 199 handlers, 24 migrations. The problem is that nothing tells you which parts of that
|
||
are real, which are mocked, and which are described by a document written three weeks ago.
|
||
|
||
---
|
||
|
||
## Decisions this plan implements
|
||
|
||
Agreed 2026-07-29, before any file was written:
|
||
|
||
| Decision | Choice |
|
||
| --- | --- |
|
||
| Doc home | **New top-level `docs/` tree.** `product/` stays as-is; `dev/` becomes `archive/`; CLAUDE.md files shrink to hard rules + pointers |
|
||
| `dev/` history | **Distill, then archive in-repo.** Every live fact extracted first; raw files moved under `archive/` with a do-not-obey banner |
|
||
| Rules | **Tiered.** CLAUDE.md keeps only non-negotiables (~200 lines); everything explanatory becomes reference read on demand |
|
||
| Verification | **Verify the load-bearing claims.** Flow status, the 18 hardening items, REQ dispositions, bring-up steps, OpenAPI — checked against code, not copied |
|
||
| Flow docs | **One file per flow, indexed** by a status table |
|
||
| Backlog | **One triaged file, new `BL-###` ids**, each carrying its origin id |
|
||
| `product/` | **Untouched.** An implementation overlay in `docs/status/` maps business areas → build state |
|
||
| Language | **English throughout** |
|
||
| Skills | **Small set, reality-checked.** Rewrite `frontend-designer`; add a backend-feature and a flow-testing skill |
|
||
| Roadmap | **Record + propose** a sequenced next chain; ordering is a proposal you can overrule |
|
||
| Anti-drift | **Lightweight guardrails.** A documentation convention, `Last verified:` stamps, a pre-commit warning |
|
||
|
||
---
|
||
|
||
## Target tree
|
||
|
||
```
|
||
docs/
|
||
README.md the one entry point — a map, nothing else
|
||
rules/ what must never be broken
|
||
index.md
|
||
documentation.md the anti-drift convention
|
||
shared/ naming, money & types, api conventions, git
|
||
client/ structure, theme, forms, i18n, services, auth, testing
|
||
server/ structure, cqrs, persistence, identity, conventions
|
||
integration/ the client<->server dependency, in one place
|
||
index.md the seam, as a single picture
|
||
api-contract.md envelope, casing, pagination, errors, idempotency
|
||
domains/ per-domain contracts (refreshed from dev/contracts)
|
||
openapi/swagger.v1.json regenerated, dated
|
||
config-matrix.md every env var / setting, both projects + docker
|
||
topology.md 3 containers + Caddy + remote SQL + OTP bot
|
||
flows/ what is implemented and how to test it
|
||
index.md status table of every flow
|
||
testing-setup.md bring-up, accounts, seeded world, reset
|
||
<flow>.md one per flow
|
||
status/ where the project actually is
|
||
index.md
|
||
implemented.md product/business area -> build state overlay
|
||
backlog.md BL-### triaged, every open item
|
||
backlog-closed.md
|
||
decisions.md distilled ADR log from the phase chain
|
||
roadmap/ where it goes next
|
||
index.md next-up.md deferred.md tech-debt.md pre-launch.md
|
||
_plan/ this folder (moves to archive/ when done)
|
||
|
||
archive/
|
||
README.md "historical record. Do NOT treat as instructions."
|
||
build-chain/ was dev/phases + dev/shared-working-context
|
||
post-phase/ was dev/post-phase
|
||
manual-testing/ was dev/manual-testing (screenshots kept)
|
||
|
||
product/ unchanged
|
||
CLAUDE.md slim, points into docs/
|
||
DEPLOY.md stays at root — the deploy *procedure*; topology lives in docs/integration/
|
||
```
|
||
|
||
**The rule that keeps these apart:** `product/` = what the business is. `docs/` = what we built and how
|
||
we work. `archive/` = how we got here. A file belongs in exactly one.
|
||
|
||
---
|
||
|
||
## The eight phases
|
||
|
||
| # | Phase | Depends on | Rough size | Output |
|
||
| --- | --- | --- | --- | --- |
|
||
| 0 | [Inventory & scaffold](phase-0-inventory-and-scaffold.md) | — | 1 session | `docs/` skeleton + a disposition for all 260 files + fresh OpenAPI |
|
||
| 1 | [Rules consolidation](phase-1-rules-consolidation.md) | 0 | 1–2 sessions | `docs/rules/` + slim CLAUDE.md files |
|
||
| 2 | [Integration & dependency](phase-2-integration.md) | 0 | 1 session | `docs/integration/` |
|
||
| 3 | [Flow atlas (verified)](phase-3-flow-atlas.md) | 0, 2 | 2–4 sessions | `docs/flows/` — the biggest phase |
|
||
| 4 | [Backlog reconciliation](phase-4-backlog.md) | 0, 3 | 1–2 sessions | `docs/status/` |
|
||
| 5 | [Roadmap & tech requirements](phase-5-roadmap.md) | 4 | 1 session | `docs/roadmap/` |
|
||
| 6 | [Archive & prune](phase-6-archive.md) | 1–5 | 1 session | `archive/`, `dev/` gone, links fixed |
|
||
| 7 | [Skills & guardrails](phase-7-skills-and-guardrails.md) | 1, 3 | 1 session | `.claude/skills/` rewritten + anti-drift hooks |
|
||
|
||
```
|
||
┌─ 1 rules ──────────────┐
|
||
0 ──────┼─ 2 integration ─ 3 flows ─ 4 backlog ─ 5 roadmap ─┼─ 6 archive
|
||
└────────────────────────┴──── 7 skills ────────────┘
|
||
```
|
||
|
||
Phases 1 and 2 can run in parallel with each other after 0. Everything else is a chain.
|
||
|
||
---
|
||
|
||
## How to run a phase
|
||
|
||
Point a fresh agent session at one phase file:
|
||
|
||
> Execute `docs/_plan/phase-2-integration.md`.
|
||
|
||
Each phase file states its own inputs, outputs, steps, verification, and definition of done. It ends
|
||
by ticking its own row in the progress table below and writing a short handoff note at the bottom of
|
||
its own file. **Do not run two phases in one session** — the point of this exercise is that context
|
||
stays small.
|
||
|
||
## Non-negotiables for every phase
|
||
|
||
1. **Nothing is deleted before it is distilled.** Phase 6 is the only phase that removes files, and it
|
||
may only remove files that Phase 0's inventory marked as *archived* or *extracted*.
|
||
2. **Verify, don't copy.** If a claim is load-bearing (a flow works, an item is closed, a command
|
||
boots the app), check it against the code or run it. If you cannot verify it, write it with an
|
||
explicit `UNVERIFIED:` prefix rather than asserting it.
|
||
3. **Every status/flow doc carries a `> Last verified: <date> against <commit>` header line.**
|
||
4. **Write short.** The failure mode this chain fixes is length. A reference doc over ~400 lines
|
||
should be split. A phase that produces a 30 KB file has misunderstood the assignment.
|
||
5. **Record contradictions, don't silently pick.** When two docs disagree, check the code, write the
|
||
truth, and log the contradiction in `docs/status/decisions.md`.
|
||
6. **Update this README's progress table** in the same change that finishes a phase.
|
||
|
||
## Progress
|
||
|
||
| Phase | Status | Finished | Notes |
|
||
| --- | --- | --- | --- |
|
||
| 0 Inventory & scaffold | **done** | 2026-07-29 | 275 files surveyed (not ~260). OpenAPI refreshed — drift is **1 endpoint**, not a rewrite. 3 of 5 seeded contradictions were narrower than stated; see [open-contradictions.md](open-contradictions.md#corrections-to-the-seeded-list). Phase 4 owns 149 files |
|
||
| 1 Rules consolidation | **done** | 2026-07-30 | Row reconstructed by phase 2 — phase 1 finished without updating it. Evidence: all 18 `docs/rules/**` files exist and are stamped `2026-07-30 against d3ec723`, `docs/README.md` marks the section **written**, and C-11 + R-1…R-6 are recorded as resolved-by-phase-1 |
|
||
| 2 Integration & dependency | **done** | 2026-07-30 | 27 files under `docs/integration/`. All 186 operations assigned to exactly one of 22 domain files (1:1 with `client/src/services/`). **Main finding: 24 phantom endpoints** — the client↔swagger axis nobody had checked; 2 are live 404s. Also 5 mis-filed REQs, 1 never-filed REQ (**C-15**), 8 client drifts, 5 config gaps. Resolved C-2, C-6, C-7, C-8, C-9 + C-3's contract half |
|
||
| 3 Flow atlas | not started | | |
|
||
| 4 Backlog reconciliation | not started | | |
|
||
| 5 Roadmap | not started | | |
|
||
| 6 Archive & prune | not started | | |
|
||
| 7 Skills & guardrails | not started | | |
|