176 lines
9.3 KiB
Markdown
176 lines
9.3 KiB
Markdown
# Phase 1 — Rules consolidation
|
||
|
||
**Depends on:** Phase 0 · **Can run in parallel with:** Phase 2 · **Size:** 1–2 sessions
|
||
|
||
## Goal
|
||
|
||
Collapse ~10 rule sources into one tiered system, and cut the cost of editing client code from
|
||
~40k tokens to ~5k.
|
||
|
||
**The tiering rule:**
|
||
|
||
| Tier | Where | What goes in it | Budget |
|
||
| --- | --- | --- | --- |
|
||
| **Hard rules** | `client/CLAUDE.md`, `server/CLAUDE.md`, root `CLAUDE.md` | Constraints whose violation breaks the build, the gate, or a business invariant. Stated imperatively, no explanation. | ~200 lines each |
|
||
| **Reference** | `docs/rules/{shared,client,server}/*.md` | The *how* and the *why*. Read on demand when working on that area. | ~200–400 lines per file |
|
||
| **Procedure** | `.claude/skills/` | Step-by-step playbooks for recurring tasks. **Phase 7** owns these. | — |
|
||
|
||
A rule that only matters when you are already editing theme code is **reference**, not a hard rule.
|
||
A rule like "never change `Seams:FieldEncryption:Key`" is a hard rule — it belongs inline.
|
||
|
||
---
|
||
|
||
## Inputs
|
||
|
||
Read these in full; they are the raw material:
|
||
|
||
| Source | Size | Contains |
|
||
| --- | --- | --- |
|
||
| [client/CLAUDE.md](../../client/CLAUDE.md) | 161 KB | 22 sections; lines 103–421 are a structure listing, 421+ is reference |
|
||
| [server/CLAUDE.md](../../server/CLAUDE.md) | 75 KB | 11 sections; lines 89–603 are the project map |
|
||
| [server/CONVENTIONS.md](../../server/CONVENTIONS.md) | 27 KB | naming, layering, CQRS shape |
|
||
| [client/messages/STYLE.md](../../client/messages/STYLE.md) | 8 KB | Persian copy rules (enforced by `lint:copy`) |
|
||
| [.claude/skills/frontend-designer/SKILL.md](../../.claude/skills/frontend-designer/SKILL.md) | 21 KB | brand, tokens, typography, component library, layout, icons |
|
||
| [dev/phases/_shared/agent-operating-rules.md](../../dev/phases/_shared/agent-operating-rules.md) | 13 KB | how agents were told to work |
|
||
| [dev/phases/_shared/definition-of-done.md](../../dev/phases/_shared/definition-of-done.md) | 3 KB | the gate |
|
||
| [dev/phases/_shared/backend-conventions-checklist.md](../../dev/phases/_shared/backend-conventions-checklist.md) | 4 KB | |
|
||
| [dev/phases/_shared/frontend-conventions-checklist.md](../../dev/phases/_shared/frontend-conventions-checklist.md) | 3 KB | |
|
||
| [dev/contracts/conventions/api-conventions.md](../../dev/contracts/conventions/api-conventions.md) | 3 KB | → **Phase 2 owns this**; read for cross-check only |
|
||
| [dev/contracts/conventions/money-and-types.md](../../dev/contracts/conventions/money-and-types.md) | 3 KB | → **Phase 2 owns this**; read for cross-check only |
|
||
| root [CLAUDE.md](../../CLAUDE.md) · 3× `AGENTS.md` · [.githooks/README.md](../../.githooks/README.md) | small | working agreements, pointers, the pre-commit hook |
|
||
|
||
Plus: `docs/_plan/inventory.md` and `docs/_plan/open-contradictions.md` from Phase 0.
|
||
|
||
## Outputs
|
||
|
||
```
|
||
docs/rules/
|
||
index.md what's here, and the tiering rule restated
|
||
documentation.md the anti-drift convention (Phase 7 adds the hook that enforces it)
|
||
shared/
|
||
naming.md Baya* vs balinyaar-client, @/* alias, file/dir conventions
|
||
git-and-gates.md branch, commit, pre-commit hook, what "done" means per project
|
||
code-quality.md no dead code, comment the why, no starter scaffolding
|
||
client/
|
||
structure.md the route/folder map (regenerated from reality, not copied)
|
||
theme.md tokens, palette, dark mode, RTL, fonts
|
||
components.md the App* library, when to reach for it vs raw MUI
|
||
forms.md react-hook-form (post-iteration-2), validation, field components
|
||
i18n.md next-intl v4, en/fa parity, STYLE.md copy rules folded in
|
||
services.md services/{domain} pattern, fetch layer, envelope, query keys
|
||
auth.md cookies, session state, refresh, RoleGuard, middleware/PUBLIC_PATHS
|
||
testing.md what is tested, how, the 125 existing tests
|
||
server/
|
||
structure.md the project map (condensed from server/CLAUDE.md lines 89-603)
|
||
cqrs.md how a feature is shaped: command/query/handler/validator
|
||
persistence.md EF Core, migrations, interceptors, the audit interceptor
|
||
identity.md JWE, sessions, rotation, field encryption, PhoneHash
|
||
conventions.md successor to CONVENTIONS.md
|
||
```
|
||
|
||
Rewritten in place: `CLAUDE.md` (root), `client/CLAUDE.md`, `server/CLAUDE.md`, 3× `AGENTS.md`.
|
||
Deleted after distillation: `server/CONVENTIONS.md`, `client/messages/STYLE.md` (content moves to
|
||
`docs/rules/client/i18n.md`; **check `lint:copy` doesn't read STYLE.md by path before deleting**).
|
||
|
||
---
|
||
|
||
## Steps
|
||
|
||
### 1. Extract every distinct rule into a ledger first
|
||
|
||
Before writing any output file, build a working list (scratch, not committed) of every *rule* found
|
||
across all inputs, tagged with: source file:line, scope (client/server/shared), tier
|
||
(hard/reference), and whether it is **contradicted or obsoleted** by another source or by the code.
|
||
|
||
This is the step that prevents loss. Merging by reading two documents side by side and writing a
|
||
third loses whatever was in neither's first half.
|
||
|
||
### 2. Reality-check the client rules against the post-overhaul code
|
||
|
||
`client/CLAUDE.md` and the frontend-designer skill both predate iterations 1–2 (commits `baa3cc6`,
|
||
`e6a8f93`). Those commits changed load-bearing things:
|
||
|
||
- **Mobile-scoped shell** — max-width container, no desktop sidebar for the nurse side
|
||
- **Bottom navigation** replacing the drawer, grouped root pages with domain summaries
|
||
- **Icon set replaced** wholesale
|
||
- **react-hook-form** for every form with >1 field (28 files currently import it — confirm coverage
|
||
and note any state-based forms left behind; that gap belongs in Phase 4's backlog)
|
||
- **Theme/language switches** moved into settings only, out of every top bar
|
||
- **Paper border-radius** reduced globally
|
||
|
||
Any rule in either document that describes the *old* behaviour is obsolete. Rewrite it against the
|
||
code, and log the correction in `docs/_plan/open-contradictions.md` as resolved.
|
||
|
||
Do the same, more briefly, for the server: `server/CLAUDE.md`'s "Project map" (514 lines) must match
|
||
the 14 `.csproj` projects and 56 controllers actually present.
|
||
|
||
### 3. Write the reference layer
|
||
|
||
One file per row of the Outputs tree. Each opens with a two-line purpose and a
|
||
`> Last verified: <date> against <commit>` line. Keep them under ~400 lines; if `client/structure.md`
|
||
wants to be longer, it is listing files it should be describing patterns for.
|
||
|
||
### 4. Rewrite the three CLAUDE.md files
|
||
|
||
Each becomes, in order:
|
||
|
||
1. One paragraph: what this project is.
|
||
2. **Stack** and **Commands** (keep — they are consulted constantly).
|
||
3. **Quality gates** — the exact commands that must pass.
|
||
4. **Hard rules** — a numbered list, imperative, no prose. Target 15–25 items.
|
||
5. **Where to read more** — a table mapping "working on X" → `docs/rules/…/X.md`.
|
||
|
||
Root `CLAUDE.md` keeps its "What Balinyaar is", "Repository layout" (updated for `docs/` and
|
||
`archive/`), and the working agreements — but agreement 7 ("keep the architecture map current") now
|
||
points at `docs/rules/` as well.
|
||
|
||
Rules that must survive into the hard-rule lists verbatim (do not soften):
|
||
|
||
- `Seams:FieldEncryption:Key` / `:HashKey` are load-bearing — changing them makes every PII read throw
|
||
and every phone lookup miss.
|
||
- Config lives in files, not a secret store — **`dotnet user-secrets` is not used and is not read**.
|
||
(This is the single most-repeated stale instruction in the repo; state it loudly.)
|
||
- Stay within one project per change.
|
||
- No dead code; the client fails the build on unused vars.
|
||
- Don't reintroduce starter scaffolding or `_TITLE_`/`_DESCRIPTION_` placeholders.
|
||
- Read `product/` before changing behaviour.
|
||
|
||
### 5. Rewrite the three `AGENTS.md`
|
||
|
||
They stay thin pointers. Update the paths they point at.
|
||
|
||
### 6. Write `docs/rules/documentation.md`
|
||
|
||
The anti-drift convention, as agreed:
|
||
|
||
- What to update when X changes (endpoint → `docs/integration/`; flow ships → `docs/flows/<flow>.md`;
|
||
backlog item closed → tick it in `docs/status/backlog.md`, never delete it; structure changes →
|
||
the matching architecture section).
|
||
- The `> Last verified: <date> against <commit>` header convention, and which docs must carry it.
|
||
- The one-home rule: `product/` = business, `docs/` = engineering + status, `archive/` = history.
|
||
- Length budgets, so this doesn't regrow.
|
||
|
||
Phase 7 adds the pre-commit warning that enforces the first bullet.
|
||
|
||
---
|
||
|
||
## Verification
|
||
|
||
- [ ] `client/CLAUDE.md` under 250 lines; `server/CLAUDE.md` under 250 lines.
|
||
- [ ] Every rule in the Step-1 ledger appears in exactly one output file — spot-check 20 at random.
|
||
- [ ] No rule describes pre-iteration-1/2 client behaviour.
|
||
- [ ] `grep -rn "user-secrets" client/ server/ CLAUDE.md docs/` returns only statements that it is
|
||
**not** used.
|
||
- [ ] `cd client && npm run check` still passes (in case `lint:copy` referenced `STYLE.md` by path).
|
||
- [ ] Both `AGENTS.md` pointer files resolve.
|
||
- [ ] Every contradiction Phase 0 logged in the rules domain is marked resolved with its resolution.
|
||
|
||
## Definition of done
|
||
|
||
An agent opening `client/CLAUDE.md` learns what it may not do in under 250 lines, and knows exactly
|
||
which one file to open next for the area it is touching.
|
||
|
||
## Handoff
|
||
|
||
_(filled in by the agent that runs this phase)_
|