@xhulz/nina 0.28.19 → 0.28.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/releases/0.28.20/core/GAPS.md +125 -0
- package/releases/0.28.20/core/answered.json +29 -0
- package/releases/0.28.20/core/defaults/tree/.claude/agents/architect.md +1 -0
- package/releases/0.28.20/core/defaults/tree/.claude/agents/dba.md +3 -0
- package/releases/0.28.20/core/defaults/tree/.claude/agents/devops.md +1 -0
- package/releases/0.28.20/core/defaults/tree/.claude/agents/implementer.md +1 -0
- package/releases/0.28.20/core/defaults/tree/.claude/agents/integration-tester.md +3 -0
- package/releases/0.28.20/core/defaults/tree/.claude/agents/qa.md +2 -0
- package/releases/0.28.20/core/defaults/tree/.claude/agents/reviewer.md +3 -0
- package/releases/0.28.20/core/defaults/tree/.claude/agents/secops.md +3 -0
- package/releases/0.28.20/core/defaults/tree/.claude/agents/solidity-auditor.md +3 -0
- package/releases/0.28.20/core/defaults/tree/.claude/agents/solidity-dev.md +3 -0
- package/releases/0.28.20/core/tree/.claude/agents/architect.md +125 -0
- package/releases/0.28.20/core/tree/.claude/agents/dba.md +107 -0
- package/releases/0.28.20/core/tree/.claude/agents/devops.md +113 -0
- package/releases/0.28.20/core/tree/.claude/agents/implementer.md +155 -0
- package/releases/0.28.20/core/tree/.claude/agents/integration-tester.md +160 -0
- package/releases/0.28.20/core/tree/.claude/agents/planner.md +132 -0
- package/releases/0.28.20/core/tree/.claude/agents/qa.md +146 -0
- package/releases/0.28.20/core/tree/.claude/agents/reviewer.md +180 -0
- package/releases/0.28.20/core/tree/.claude/agents/secops.md +121 -0
- package/releases/0.28.20/core/tree/.claude/agents/solidity-auditor.md +126 -0
- package/releases/0.28.20/core/tree/.claude/agents/solidity-dev.md +123 -0
- package/releases/0.28.20/core/tree/.claude/agents-overview.md +64 -0
- package/releases/0.28.20/core/tree/.claude/graph.md +73 -0
- package/releases/0.28.20/core/tree/.claude/patterns.md +212 -0
- package/releases/0.28.20/core/tree/.claude/pills/README.md +145 -0
- package/releases/0.28.20/core/tree/.claude/pipeline.md +102 -0
- package/releases/0.28.20/core/tree/.claude/retrieval.md +104 -0
- package/releases/0.28.20/core/tree/.claude/router.md +201 -0
- package/releases/0.28.20/core/tree/.claude/templates/integration.md +45 -0
- package/releases/0.28.20/core/tree/CLAUDE.md +155 -0
- package/releases/0.28.20/core/tree/scripts/edit-guard.mjs +16 -0
- package/releases/0.28.20/core/tree/scripts/harness-check.mjs +71 -0
- package/releases/0.28.20/core/tree/scripts/loop-gate.mjs +19 -0
- package/releases/0.28.20/core/vocabulary.json +12 -0
- package/releases/0.28.20/surfaces/blockchain/tree/.claude/agents/architect.md +5 -0
- package/releases/0.28.20/surfaces/blockchain/tree/.claude/agents/devops.md +5 -0
- package/releases/0.28.20/surfaces/blockchain/tree/.claude/agents/reviewer.md +5 -0
- package/releases/0.28.20/surfaces/blockchain/tree/.claude/agents/solidity-auditor.md +18 -0
- package/releases/0.28.20/surfaces/blockchain/tree/.claude/agents/solidity-dev.md +16 -0
- package/releases/0.28.20/surfaces/blockchain/tree/.claude/agents-overview.md +6 -0
- package/releases/0.28.20/surfaces/blockchain/tree/.claude/graph.md +11 -0
- package/releases/0.28.20/surfaces/blockchain/tree/.claude/router.md +9 -0
- package/releases/0.28.20/surfaces/blockchain/tree/CLAUDE.md +12 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/agents/architect.md +8 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/agents/dba.md +84 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/agents/devops.md +14 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/agents/implementer.md +5 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/agents/integration-tester.md +13 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/agents/planner.md +2 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/agents/reviewer.md +25 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/agents/secops.md +2 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/agents-overview.md +5 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/graph.md +8 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/patterns.md +29 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/pipeline.md +13 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/retrieval.md +5 -0
- package/releases/0.28.20/surfaces/db/tree/.claude/router.md +10 -0
- package/releases/0.28.20/surfaces/db/tree/CLAUDE.md +23 -0
- package/releases/0.28.20/surfaces/edge-cf/tree/.claude/agents/architect.md +14 -0
- package/releases/0.28.20/surfaces/edge-cf/tree/.claude/agents/dba.md +2 -0
- package/releases/0.28.20/surfaces/edge-cf/tree/.claude/agents/devops.md +31 -0
- package/releases/0.28.20/surfaces/edge-cf/tree/.claude/agents/implementer.md +14 -0
- package/releases/0.28.20/surfaces/edge-cf/tree/.claude/agents/integration-tester.md +11 -0
- package/releases/0.28.20/surfaces/edge-cf/tree/.claude/agents/qa.md +3 -0
- package/releases/0.28.20/surfaces/edge-cf/tree/.claude/agents/reviewer.md +8 -0
- package/releases/0.28.20/surfaces/edge-cf/tree/.claude/agents/secops.md +8 -0
- package/releases/0.28.20/surfaces/edge-cf/tree/.claude/patterns.md +17 -0
- package/releases/0.28.20/surfaces/edge-cf/tree/.claude/retrieval.md +8 -0
- package/releases/0.28.20/surfaces/edge-cf/tree/.claude/router.md +21 -0
- package/releases/0.28.20/surfaces/edge-cf/tree/CLAUDE.md +27 -0
- package/releases/0.28.20/surfaces/frontend/tree/.claude/agents/architect.md +20 -0
- package/releases/0.28.20/surfaces/frontend/tree/.claude/agents/devops.md +28 -0
- package/releases/0.28.20/surfaces/frontend/tree/.claude/agents/implementer.md +25 -0
- package/releases/0.28.20/surfaces/frontend/tree/.claude/agents/qa.md +17 -0
- package/releases/0.28.20/surfaces/frontend/tree/.claude/agents/reviewer.md +62 -0
- package/releases/0.28.20/surfaces/frontend/tree/.claude/patterns.md +15 -0
- package/releases/0.28.20/surfaces/frontend/tree/.claude/retrieval.md +5 -0
- package/releases/0.28.20/surfaces/frontend/tree/.claude/router.md +17 -0
- package/releases/0.28.20/surfaces/frontend/tree/CLAUDE.md +5 -0
- package/releases/0.28.20/surfaces/integrations/tree/.claude/agents/architect.md +16 -0
- package/releases/0.28.20/surfaces/integrations/tree/.claude/agents/implementer.md +12 -0
- package/releases/0.28.20/surfaces/integrations/tree/.claude/agents/integration-tester.md +20 -0
- package/releases/0.28.20/surfaces/integrations/tree/.claude/agents/planner.md +2 -0
- package/releases/0.28.20/surfaces/integrations/tree/.claude/agents/reviewer.md +21 -0
- package/releases/0.28.20/surfaces/integrations/tree/.claude/agents/secops.md +2 -0
- package/releases/0.28.20/surfaces/integrations/tree/.claude/agents-overview.md +8 -0
- package/releases/0.28.20/surfaces/integrations/tree/.claude/graph.md +9 -0
- package/releases/0.28.20/surfaces/integrations/tree/.claude/patterns.md +38 -0
- package/releases/0.28.20/surfaces/integrations/tree/.claude/pipeline.md +16 -0
- package/releases/0.28.20/surfaces/integrations/tree/.claude/retrieval.md +16 -0
- package/releases/0.28.20/surfaces/integrations/tree/.claude/router.md +6 -0
- package/releases/0.28.20/surfaces/integrations/tree/CLAUDE.md +17 -0
- package/releases/0.28.20/surfaces/money/tree/.claude/agents/architect.md +12 -0
- package/releases/0.28.20/surfaces/money/tree/.claude/agents/dba.md +14 -0
- package/releases/0.28.20/surfaces/money/tree/.claude/agents/implementer.md +11 -0
- package/releases/0.28.20/surfaces/money/tree/.claude/agents/integration-tester.md +3 -0
- package/releases/0.28.20/surfaces/money/tree/.claude/agents/reviewer.md +23 -0
- package/releases/0.28.20/surfaces/money/tree/.claude/agents/secops.md +5 -0
- package/releases/0.28.20/surfaces/money/tree/.claude/agents/solidity-auditor.md +4 -0
- package/releases/0.28.20/surfaces/money/tree/.claude/agents/solidity-dev.md +4 -0
- package/releases/0.28.20/surfaces/money/tree/.claude/graph.md +2 -0
- package/releases/0.28.20/surfaces/money/tree/.claude/patterns.md +49 -0
- package/releases/0.28.20/surfaces/money/tree/.claude/pipeline.md +2 -0
- package/releases/0.28.20/surfaces/money/tree/.claude/retrieval.md +2 -0
- package/releases/0.28.20/surfaces/money/tree/CLAUDE.md +11 -0
- package/releases/0.28.20/surfaces/pii/tree/.claude/agents/dba.md +2 -0
- package/releases/0.28.20/surfaces/pii/tree/.claude/agents/devops.md +8 -0
- package/releases/0.28.20/surfaces/pii/tree/.claude/agents/reviewer.md +8 -0
- package/releases/0.28.20/surfaces/pii/tree/.claude/agents/secops.md +2 -0
- package/releases/0.28.20/surfaces/pii/tree/.claude/agents/solidity-auditor.md +5 -0
- package/releases/0.28.20/surfaces/pii/tree/CLAUDE.md +5 -0
- package/releases/0.28.21/core/GAPS.md +125 -0
- package/releases/0.28.21/core/answered.json +29 -0
- package/releases/0.28.21/core/defaults/tree/.claude/agents/architect.md +1 -0
- package/releases/0.28.21/core/defaults/tree/.claude/agents/dba.md +3 -0
- package/releases/0.28.21/core/defaults/tree/.claude/agents/devops.md +1 -0
- package/releases/0.28.21/core/defaults/tree/.claude/agents/implementer.md +1 -0
- package/releases/0.28.21/core/defaults/tree/.claude/agents/integration-tester.md +3 -0
- package/releases/0.28.21/core/defaults/tree/.claude/agents/qa.md +2 -0
- package/releases/0.28.21/core/defaults/tree/.claude/agents/reviewer.md +3 -0
- package/releases/0.28.21/core/defaults/tree/.claude/agents/secops.md +3 -0
- package/releases/0.28.21/core/defaults/tree/.claude/agents/solidity-auditor.md +3 -0
- package/releases/0.28.21/core/defaults/tree/.claude/agents/solidity-dev.md +3 -0
- package/releases/0.28.21/core/tree/.claude/agents/architect.md +125 -0
- package/releases/0.28.21/core/tree/.claude/agents/dba.md +107 -0
- package/releases/0.28.21/core/tree/.claude/agents/devops.md +113 -0
- package/releases/0.28.21/core/tree/.claude/agents/implementer.md +155 -0
- package/releases/0.28.21/core/tree/.claude/agents/integration-tester.md +160 -0
- package/releases/0.28.21/core/tree/.claude/agents/planner.md +132 -0
- package/releases/0.28.21/core/tree/.claude/agents/qa.md +146 -0
- package/releases/0.28.21/core/tree/.claude/agents/reviewer.md +180 -0
- package/releases/0.28.21/core/tree/.claude/agents/secops.md +121 -0
- package/releases/0.28.21/core/tree/.claude/agents/solidity-auditor.md +126 -0
- package/releases/0.28.21/core/tree/.claude/agents/solidity-dev.md +123 -0
- package/releases/0.28.21/core/tree/.claude/agents-overview.md +64 -0
- package/releases/0.28.21/core/tree/.claude/graph.md +73 -0
- package/releases/0.28.21/core/tree/.claude/patterns.md +212 -0
- package/releases/0.28.21/core/tree/.claude/pills/README.md +145 -0
- package/releases/0.28.21/core/tree/.claude/pipeline.md +102 -0
- package/releases/0.28.21/core/tree/.claude/retrieval.md +104 -0
- package/releases/0.28.21/core/tree/.claude/router.md +201 -0
- package/releases/0.28.21/core/tree/.claude/templates/integration.md +45 -0
- package/releases/0.28.21/core/tree/CLAUDE.md +155 -0
- package/releases/0.28.21/core/tree/scripts/edit-guard.mjs +16 -0
- package/releases/0.28.21/core/tree/scripts/harness-check.mjs +71 -0
- package/releases/0.28.21/core/tree/scripts/loop-gate.mjs +19 -0
- package/releases/0.28.21/core/vocabulary.json +12 -0
- package/releases/0.28.21/surfaces/blockchain/tree/.claude/agents/architect.md +5 -0
- package/releases/0.28.21/surfaces/blockchain/tree/.claude/agents/devops.md +5 -0
- package/releases/0.28.21/surfaces/blockchain/tree/.claude/agents/reviewer.md +5 -0
- package/releases/0.28.21/surfaces/blockchain/tree/.claude/agents/solidity-auditor.md +18 -0
- package/releases/0.28.21/surfaces/blockchain/tree/.claude/agents/solidity-dev.md +16 -0
- package/releases/0.28.21/surfaces/blockchain/tree/.claude/agents-overview.md +6 -0
- package/releases/0.28.21/surfaces/blockchain/tree/.claude/graph.md +11 -0
- package/releases/0.28.21/surfaces/blockchain/tree/.claude/router.md +9 -0
- package/releases/0.28.21/surfaces/blockchain/tree/CLAUDE.md +12 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/agents/architect.md +8 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/agents/dba.md +84 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/agents/devops.md +14 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/agents/implementer.md +5 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/agents/integration-tester.md +13 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/agents/planner.md +2 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/agents/reviewer.md +25 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/agents/secops.md +2 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/agents-overview.md +5 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/graph.md +8 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/patterns.md +29 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/pipeline.md +13 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/retrieval.md +5 -0
- package/releases/0.28.21/surfaces/db/tree/.claude/router.md +10 -0
- package/releases/0.28.21/surfaces/db/tree/CLAUDE.md +23 -0
- package/releases/0.28.21/surfaces/edge-cf/tree/.claude/agents/architect.md +14 -0
- package/releases/0.28.21/surfaces/edge-cf/tree/.claude/agents/dba.md +2 -0
- package/releases/0.28.21/surfaces/edge-cf/tree/.claude/agents/devops.md +31 -0
- package/releases/0.28.21/surfaces/edge-cf/tree/.claude/agents/implementer.md +14 -0
- package/releases/0.28.21/surfaces/edge-cf/tree/.claude/agents/integration-tester.md +11 -0
- package/releases/0.28.21/surfaces/edge-cf/tree/.claude/agents/qa.md +3 -0
- package/releases/0.28.21/surfaces/edge-cf/tree/.claude/agents/reviewer.md +8 -0
- package/releases/0.28.21/surfaces/edge-cf/tree/.claude/agents/secops.md +8 -0
- package/releases/0.28.21/surfaces/edge-cf/tree/.claude/patterns.md +17 -0
- package/releases/0.28.21/surfaces/edge-cf/tree/.claude/retrieval.md +8 -0
- package/releases/0.28.21/surfaces/edge-cf/tree/.claude/router.md +21 -0
- package/releases/0.28.21/surfaces/edge-cf/tree/CLAUDE.md +27 -0
- package/releases/0.28.21/surfaces/frontend/tree/.claude/agents/architect.md +20 -0
- package/releases/0.28.21/surfaces/frontend/tree/.claude/agents/devops.md +28 -0
- package/releases/0.28.21/surfaces/frontend/tree/.claude/agents/implementer.md +25 -0
- package/releases/0.28.21/surfaces/frontend/tree/.claude/agents/qa.md +17 -0
- package/releases/0.28.21/surfaces/frontend/tree/.claude/agents/reviewer.md +62 -0
- package/releases/0.28.21/surfaces/frontend/tree/.claude/patterns.md +15 -0
- package/releases/0.28.21/surfaces/frontend/tree/.claude/retrieval.md +5 -0
- package/releases/0.28.21/surfaces/frontend/tree/.claude/router.md +17 -0
- package/releases/0.28.21/surfaces/frontend/tree/CLAUDE.md +5 -0
- package/releases/0.28.21/surfaces/integrations/tree/.claude/agents/architect.md +16 -0
- package/releases/0.28.21/surfaces/integrations/tree/.claude/agents/implementer.md +12 -0
- package/releases/0.28.21/surfaces/integrations/tree/.claude/agents/integration-tester.md +20 -0
- package/releases/0.28.21/surfaces/integrations/tree/.claude/agents/planner.md +2 -0
- package/releases/0.28.21/surfaces/integrations/tree/.claude/agents/reviewer.md +21 -0
- package/releases/0.28.21/surfaces/integrations/tree/.claude/agents/secops.md +2 -0
- package/releases/0.28.21/surfaces/integrations/tree/.claude/agents-overview.md +8 -0
- package/releases/0.28.21/surfaces/integrations/tree/.claude/graph.md +9 -0
- package/releases/0.28.21/surfaces/integrations/tree/.claude/patterns.md +38 -0
- package/releases/0.28.21/surfaces/integrations/tree/.claude/pipeline.md +16 -0
- package/releases/0.28.21/surfaces/integrations/tree/.claude/retrieval.md +16 -0
- package/releases/0.28.21/surfaces/integrations/tree/.claude/router.md +6 -0
- package/releases/0.28.21/surfaces/integrations/tree/CLAUDE.md +17 -0
- package/releases/0.28.21/surfaces/money/tree/.claude/agents/architect.md +12 -0
- package/releases/0.28.21/surfaces/money/tree/.claude/agents/dba.md +14 -0
- package/releases/0.28.21/surfaces/money/tree/.claude/agents/implementer.md +11 -0
- package/releases/0.28.21/surfaces/money/tree/.claude/agents/integration-tester.md +3 -0
- package/releases/0.28.21/surfaces/money/tree/.claude/agents/reviewer.md +23 -0
- package/releases/0.28.21/surfaces/money/tree/.claude/agents/secops.md +5 -0
- package/releases/0.28.21/surfaces/money/tree/.claude/agents/solidity-auditor.md +4 -0
- package/releases/0.28.21/surfaces/money/tree/.claude/agents/solidity-dev.md +4 -0
- package/releases/0.28.21/surfaces/money/tree/.claude/graph.md +2 -0
- package/releases/0.28.21/surfaces/money/tree/.claude/patterns.md +49 -0
- package/releases/0.28.21/surfaces/money/tree/.claude/pipeline.md +2 -0
- package/releases/0.28.21/surfaces/money/tree/.claude/retrieval.md +2 -0
- package/releases/0.28.21/surfaces/money/tree/CLAUDE.md +11 -0
- package/releases/0.28.21/surfaces/pii/tree/.claude/agents/dba.md +2 -0
- package/releases/0.28.21/surfaces/pii/tree/.claude/agents/devops.md +8 -0
- package/releases/0.28.21/surfaces/pii/tree/.claude/agents/reviewer.md +8 -0
- package/releases/0.28.21/surfaces/pii/tree/.claude/agents/secops.md +2 -0
- package/releases/0.28.21/surfaces/pii/tree/.claude/agents/solidity-auditor.md +5 -0
- package/releases/0.28.21/surfaces/pii/tree/CLAUDE.md +5 -0
- package/src/commands/pipeline.mjs +2 -4
- package/src/commands/stats.mjs +83 -48
- package/src/commands/upgrade.mjs +19 -4
- package/src/look.mjs +118 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Pipeline graph
|
|
2
|
+
|
|
3
|
+
The one place this project's stages, and the edges between them, are stated. Every other document that
|
|
4
|
+
routes work — `CLAUDE.md`, `router.md`, `pipeline.md`, each role's loop-back rules — describes this
|
|
5
|
+
graph; where one of them disagrees with it, this file is right and the other is a defect to report
|
|
6
|
+
(Hard Rule #17). It is composed for this project, so a stage this project does not have is not in it,
|
|
7
|
+
and no edge points at one.
|
|
8
|
+
|
|
9
|
+
`nina check` validates it: every stage has a spec, every spec is a stage, every edge leaves on a verdict
|
|
10
|
+
its stage can actually emit, every verdict a stage can emit goes somewhere, and every loop-back edge has
|
|
11
|
+
a cap.
|
|
12
|
+
|
|
13
|
+
## Stages
|
|
14
|
+
|
|
15
|
+
- `planner` — decomposes ambiguous or multi-step work into ordered steps
|
|
16
|
+
- `architect` — designs the approach and writes the spec, with cited premises
|
|
17
|
+
- `implementer` — writes code and tests to the spec; never runs the tests
|
|
18
|
+
<!-- nina:slot db.1 -->
|
|
19
|
+
<!-- nina:slot integrations.1 -->
|
|
20
|
+
<!-- nina:slot blockchain.1 -->
|
|
21
|
+
- `reviewer` — audits the diff against the spec, and confirms every gate the diff triggered ran
|
|
22
|
+
- `qa` — runs the tests, once, at the end
|
|
23
|
+
- `devops` — deploys to preview and smokes it; production only on the owner's explicit go
|
|
24
|
+
- `secops` — the security gate, once per milestone
|
|
25
|
+
|
|
26
|
+
The two terminals are `done` and `human`. `human` is the owner: a decision nobody in the pipeline can
|
|
27
|
+
make, or a loop that has run out of rounds.
|
|
28
|
+
|
|
29
|
+
## Edges
|
|
30
|
+
|
|
31
|
+
One per line: the stage, where its work goes, on which verdict, and when. A loop-back edge ends with
|
|
32
|
+
its **cap** — how many times the SAME issue may travel it, the issue being what the stage names on the
|
|
33
|
+
`ISSUES` line under its verdict. When the next round would exceed the cap,
|
|
34
|
+
the orchestrator stops and hands the owner the reports from every round, instead of dispatching again:
|
|
35
|
+
a third attempt at a fix that failed twice is rarely different from the second, and each round costs
|
|
36
|
+
minutes to hours. A different issue on the same edge starts its own count. Where the project wires the loop
|
|
37
|
+
gate, the dispatch past a cap waits for the owner to confirm it; `router.md` says how rounds are counted.
|
|
38
|
+
|
|
39
|
+
- `planner` → `architect` on `PLAN-READY`
|
|
40
|
+
- `planner` → `human` on `BLOCKED` — the work cannot be decomposed without an answer
|
|
41
|
+
- `architect` → `implementer` on `SPEC-READY`
|
|
42
|
+
- `architect` → `human` on `BLOCKED` — an unverifiable premise or a missing decision
|
|
43
|
+
- `architect` → `planner` on `BLOCKED` — the plan itself is wrong, not the design · max 1
|
|
44
|
+
- `implementer` → `reviewer` on `DIFF-READY`
|
|
45
|
+
- `implementer` → `architect` on `BLOCKED` — the spec is wrong, needs a file it does not list, or asks one run for more files than a step may write · max 2
|
|
46
|
+
- `implementer` → `planner` on `BLOCKED` — the spec is too large for one step · max 1
|
|
47
|
+
<!-- nina:slot db.2 -->
|
|
48
|
+
<!-- nina:slot integrations.2 -->
|
|
49
|
+
<!-- nina:slot blockchain.2 -->
|
|
50
|
+
<!-- nina:slot money.1 -->
|
|
51
|
+
- `reviewer` → `qa` on `APPROVED`
|
|
52
|
+
- `reviewer` → `implementer` on `REJECTED` — an implementation bug · max 2
|
|
53
|
+
- `reviewer` → `architect` on `REJECTED` — a design flaw, or no preview-deploy plan · max 2
|
|
54
|
+
- `qa` → `devops` on `PASS` — the change touches a deployed surface
|
|
55
|
+
- `qa` → `secops` on `PASS` — the last step of a milestone
|
|
56
|
+
- `qa` → `done` on `PASS` — nothing to deploy
|
|
57
|
+
- `qa` → `implementer` on `FAIL` — a test fails, the run exits non-zero, or a "pre-existing" failure does not reproduce · max 2
|
|
58
|
+
- `qa` → `architect` on `FAIL` — the test is right and the spec was wrong · max 2
|
|
59
|
+
- `devops` → `done` on `DEPLOYED` — preview is green; production waits for the owner
|
|
60
|
+
- `devops` → `implementer` on `BLOCKED` — the deploy failed because the code is wrong · max 2
|
|
61
|
+
- `devops` → `architect` on `BLOCKED` — the spec has no workable deploy plan · max 2
|
|
62
|
+
- `secops` → `done` on `SECURE`
|
|
63
|
+
- `secops` → `implementer` on `BLOCKED` — a CRITICAL or HIGH that is a bug · max 2
|
|
64
|
+
- `secops` → `architect` on `BLOCKED` — a CRITICAL or HIGH that is a design flaw · max 2
|
|
65
|
+
|
|
66
|
+
## Concurrency
|
|
67
|
+
|
|
68
|
+
Stages that only read may run together: after the implementer, the `reviewer` and every gate the diff
|
|
69
|
+
triggered go out in one message; at a milestone's end, `secops` runs beside `qa` or `devops`.
|
|
70
|
+
`qa` always runs alone. These may run as several agents at once, each on its own share of the work:
|
|
71
|
+
- `architect` × many — the sibling specs of one milestone, each its own spec
|
|
72
|
+
- `implementer` × many — work that shares no file and builds on nothing the other writes: side by side in different packages, each in its own worktree within one
|
|
73
|
+
- `reviewer` × many — one per axis of risk the diff carries, for a diff over ~200 lines
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Patterns & Conventions
|
|
2
|
+
|
|
3
|
+
Read this before writing code. Architects cite it in specs; implementers follow it; reviewers enforce it.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Language & tooling
|
|
8
|
+
|
|
9
|
+
- **TypeScript strict mode** everywhere. No `any` without a justifying comment.
|
|
10
|
+
- **pnpm workspaces + Turborepo**. Never `npm` or `yarn`. Use `turbo run <task>` for orchestrated work.
|
|
11
|
+
- **Biome** for format + lint. No ESLint / Prettier.
|
|
12
|
+
- **Vitest** for unit tests.
|
|
13
|
+
<!-- nina:slot edge-cf.3 -->
|
|
14
|
+
- **Zod** for runtime validation at all trust boundaries (API ingress, env loading, queue payload, an RPC between services, webhook body, integration responses).
|
|
15
|
+
|
|
16
|
+
### Relative imports carry a `.js` extension — this is intentional, do NOT "fix" it
|
|
17
|
+
|
|
18
|
+
Relative imports in `.ts`/`.tsx` source MUST use the `.js` extension (e.g. `import { x } from './client.js'`, never `'./client'` or `'./client.ts'`). This looks wrong but is correct ESM-TypeScript and is load-bearing:
|
|
19
|
+
|
|
20
|
+
- The repo is ESM (`"type": "module"`, `module: ESNext`, `moduleResolution: Bundler`, `verbatimModuleSyntax: true` in `packages/tsconfig/base.json`). **TypeScript never rewrites import specifiers** — what you write is what lands in the emitted `.js`.
|
|
21
|
+
- Emitting packages ({{EMITTING_PKGS}}) compile with `tsc` to real `.js` in `dist/` and are consumed via their `exports` map (`./dist/*.js`). At runtime the file IS `client.js`; a source `'./client.ts'` would emit a dead `'./client.ts'` reference → broken import. The `.js` form is the only one that works for these.
|
|
22
|
+
- Bundled apps (`{{API_DIR}}` and `{{APP_DIR}}`, each via its bundler) resolve `'./x.js'` back to `./x.ts` source transparently, so the same convention works everywhere.
|
|
23
|
+
- Switching to `.ts` extensions would require `allowImportingTsExtensions`, which only works with `noEmit` — it would break every emitting package. Do not propose it.
|
|
24
|
+
|
|
25
|
+
This is the official TypeScript guidance for ESM. A reviewer/AI that "corrects" `.js` → `.ts` (or strips the extension) is introducing a bug, not a cleanup.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Folder structure within a TS package
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
package/
|
|
33
|
+
├── src/
|
|
34
|
+
│ ├── index.ts # public exports only — this is the package API
|
|
35
|
+
│ ├── internal/ # not re-exported; no deep imports allowed from outside
|
|
36
|
+
│ └── types.ts # shared types
|
|
37
|
+
├── test/ # *.test.ts mirroring src/ structure
|
|
38
|
+
└── package.json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- External code imports from `{{PKG_SCOPE}}/<name>` (barrel `index.ts`), never `{{PKG_SCOPE}}/<name>/src/internal/...`.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## `export` only what crosses a module boundary
|
|
46
|
+
|
|
47
|
+
**`export` is a claim that something outside this file needs the symbol.** If nothing does, drop the
|
|
48
|
+
keyword — the declaration stays, it just stops pretending to be API.
|
|
49
|
+
|
|
50
|
+
This is not cosmetic. An unused export is invisible to every tool we have: TypeScript's
|
|
51
|
+
`noUnusedLocals` and Biome's `noUnusedVariables` both stop at the file boundary, so an exported dead
|
|
52
|
+
symbol is the one kind of dead code nothing flags. It also makes the symbol look load-bearing to the
|
|
53
|
+
next reader, which is how a second implementation gets written next to the first.
|
|
54
|
+
|
|
55
|
+
- A React component's `Props` type used only by that component is **not** exported. Export it only
|
|
56
|
+
when another module actually imports it.
|
|
57
|
+
- The same goes for a service's internal result/input shapes, an error code union that never leaves
|
|
58
|
+
its module, and a constant only its own file reads.
|
|
59
|
+
<!-- nina:slot project.1 library-packages -->
|
|
60
|
+
- The standing report is `.claude/code-map.generated.md` § *Rot signals* (`pnpm code-map`). The
|
|
61
|
+
reviewer checks it for symbols the current diff introduced: **a new export nothing consumes is
|
|
62
|
+
dead on arrival.**
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Naming
|
|
67
|
+
|
|
68
|
+
- **Files:** `kebab-case.ts` for modules, `PascalCase.tsx` for React components.
|
|
69
|
+
- **Types / interfaces:** `PascalCase`. No `I` prefix.
|
|
70
|
+
- **Functions / vars:** `camelCase`.
|
|
71
|
+
- **Constants:** `SCREAMING_SNAKE_CASE` only for true compile-time constants.
|
|
72
|
+
- **Env vars:** `SCREAMING_SNAKE_CASE`, loaded through a typed `env.ts` with Zod validation.
|
|
73
|
+
<!-- nina:slot db.1 -->
|
|
74
|
+
<!-- nina:slot money.1 -->
|
|
75
|
+
<!-- nina:slot money.2 -->
|
|
76
|
+
<!-- nina:slot money.3 -->
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## API conventions
|
|
81
|
+
|
|
82
|
+
### Layering: Route → Service → Data Objects
|
|
83
|
+
|
|
84
|
+
Every request (and queue/webhook invocation) traverses three layers in order. **No layer may skip the next.** Full diagram in `.claude/architecture.md`.
|
|
85
|
+
|
|
86
|
+
- **Route** (`{{API_DIR}}/src/routes/<resource>.ts`): Zod validation, auth + role extraction, envelope shaping, privacy-safe log, deps construction. Nothing else.
|
|
87
|
+
<!-- nina:slot integrations.1 -->
|
|
88
|
+
- **Service** (`{{API_DIR}}/src/services/<resource>.ts`): business orchestration, owner scoping (every read and write filtered by who owns the data), Date→ISO mapping, named-error taxonomy. HTTP-agnostic.
|
|
89
|
+
- **Data Objects:** the database client, the platform bindings, and each integration's boundary module.
|
|
90
|
+
|
|
91
|
+
**Hard rules (reviewer enforces):**
|
|
92
|
+
|
|
93
|
+
<!-- nina:slot db.2 -->
|
|
94
|
+
- Routes must NOT call `.toISOString()` on service results — services do that.
|
|
95
|
+
- Services must NOT import the HTTP framework's request context, shape a response, or reference status codes.
|
|
96
|
+
<!-- nina:slot db.3 -->
|
|
97
|
+
<!-- nina:slot db.4 -->
|
|
98
|
+
<!-- nina:slot money.4 -->
|
|
99
|
+
<!-- nina:slot money.5 -->
|
|
100
|
+
<!-- nina:slot integrations.2 -->
|
|
101
|
+
|
|
102
|
+
### Other API rules
|
|
103
|
+
|
|
104
|
+
- **Zod validation at the request boundary.** No ad-hoc `if (!body.foo) return 400`.
|
|
105
|
+
- Response shape is always `{ok: true, data: T} | {ok: false, error: {code, message}}`. No bare throws leaking to clients.
|
|
106
|
+
- Custom errors: `class AppError extends Error { code: string; status: number }`. Each route maps known classes to HTTP codes.
|
|
107
|
+
<!-- nina:slot money.6 -->
|
|
108
|
+
<!-- nina:slot db.5 -->
|
|
109
|
+
<!-- nina:slot integrations.3 -->
|
|
110
|
+
<!-- nina:slot project.2 integration-error-types -->
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## SDK / shared package conventions
|
|
115
|
+
|
|
116
|
+
- **Tree-shakeable:** barrel `index.ts` only re-exports. No side effects at module top level.
|
|
117
|
+
- Works in: modern browsers, Node 20+, and every runtime the project deploys to.
|
|
118
|
+
- No `console.log` in production paths. Use a `debug(msg)` helper that's a no-op in prod, and never log PII.
|
|
119
|
+
<!-- nina:slot frontend.1 -->
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Tests
|
|
124
|
+
|
|
125
|
+
### Unit tests
|
|
126
|
+
- Test **pure functions** directly. No mocks of our own code.
|
|
127
|
+
<!-- nina:slot money.7 -->
|
|
128
|
+
- Don't test implementation details. Test behavior at the module boundary.
|
|
129
|
+
|
|
130
|
+
### Integration tests
|
|
131
|
+
<!-- nina:slot edge-cf.4 -->
|
|
132
|
+
<!-- nina:slot db.6 -->
|
|
133
|
+
<!-- nina:slot integrations.4 -->
|
|
134
|
+
|
|
135
|
+
### Fixtures
|
|
136
|
+
<!-- nina:slot project.3 test-fixtures -->
|
|
137
|
+
|
|
138
|
+
### Test files MUST be inside the typecheck program
|
|
139
|
+
|
|
140
|
+
A package whose `tsconfig.json` has `include: ["src"]` **does not typecheck its own tests.** That is
|
|
141
|
+
a false green, and an expensive one: the test still imports the symbol you deleted and still passes
|
|
142
|
+
a fixture whose shape drifted, and you find out at vitest time — or never, if nobody runs that
|
|
143
|
+
suite. It is the mechanism behind the pill *test-files-not-typechecked-on-symbol-removal*.
|
|
144
|
+
<!-- nina:slot project.4 typecheck-current-state -->
|
|
145
|
+
|
|
146
|
+
A package that emits (`build: tsc`, with `rootDir: "src"`) cannot simply add `test` to its build
|
|
147
|
+
config. Give it a second config instead and point the script at it:
|
|
148
|
+
|
|
149
|
+
```jsonc
|
|
150
|
+
// tsconfig.typecheck.json
|
|
151
|
+
{
|
|
152
|
+
"extends": "./tsconfig.json",
|
|
153
|
+
"compilerOptions": { "rootDir": ".", "noEmit": true },
|
|
154
|
+
"include": ["src", "test"]
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
```jsonc
|
|
158
|
+
// package.json — build keeps using tsconfig.json, typecheck does not
|
|
159
|
+
"typecheck": "tsc --noEmit -p tsconfig.typecheck.json"
|
|
160
|
+
```
|
|
161
|
+
<!-- nina:slot project.5 typecheck-coverage -->
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Correcting a document
|
|
166
|
+
|
|
167
|
+
When you correct a document, **delete what you are correcting.** A document that contradicts itself
|
|
168
|
+
is worse than one that is merely wrong: every reader picks the half that suits what they are already
|
|
169
|
+
writing, so two readers reach opposite conclusions from the same file and both believe they followed
|
|
170
|
+
it. The correction and the text it replaces cannot coexist "for history" — that is what the commit
|
|
171
|
+
log is for.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## TSDoc — required on all TS declarations
|
|
176
|
+
|
|
177
|
+
Every named declaration gets a TSDoc block (`/** ... */`) — exported or not: functions, classes + members, interfaces + members, type aliases, enums + members, and top-level constants whose name doesn't convey intent.
|
|
178
|
+
|
|
179
|
+
### Structure
|
|
180
|
+
- **First line:** a concise one-sentence summary.
|
|
181
|
+
- **`@param`** when the purpose isn't fully encoded in name and type.
|
|
182
|
+
- **`@returns`** when the return carries information the type alone doesn't convey.
|
|
183
|
+
- **`@throws`** whenever the function can throw — name the error type and condition.
|
|
184
|
+
- **`@example`** for non-trivially composed APIs.
|
|
185
|
+
- **`@remarks`** for invariants, perf trade-offs, caveats.
|
|
186
|
+
|
|
187
|
+
### What TSDoc is NOT
|
|
188
|
+
- Not a restatement of the signature. Not a changelog. Not a crutch for bad naming.
|
|
189
|
+
|
|
190
|
+
### Enforcement
|
|
191
|
+
Reviewer verifies coverage. **Missing TSDoc on any new declaration = request changes.**
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Inline comments — default: none
|
|
196
|
+
|
|
197
|
+
Separate from TSDoc. Regular `//` comments stay rare:
|
|
198
|
+
- **Only** for non-obvious **WHY**: an invariant, a subtle perf trade-off, a workaround.
|
|
199
|
+
- **Never** for WHAT — if code doesn't read clearly, fix the code.
|
|
200
|
+
- **Never** reference callers, tickets, or PR history.
|
|
201
|
+
<!-- nina:slot edge-cf.1 -->
|
|
202
|
+
<!-- nina:slot project.7 required-secrets -->
|
|
203
|
+
<!-- nina:slot edge-cf.2 -->
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Commit / PR conventions
|
|
208
|
+
|
|
209
|
+
- One logical change per PR. Multi-concern PRs get split by reviewer.
|
|
210
|
+
- Conventional Commits (`feat:`, `fix:`, `chore:`, `refactor:`, `docs:`).
|
|
211
|
+
- PR description answers **why**, not **what**.
|
|
212
|
+
- Reviewer verifies: typecheck clean, Biome clean, every gate the diff triggered approved (`.claude/graph.md`), no secret leaked, no PII in logs or tests.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Pills of Knowledge
|
|
2
|
+
|
|
3
|
+
Hard-won, per-agent **behavioral corrections** — lessons learned the expensive way (a loop-back,
|
|
4
|
+
a rejected diff, a blocked milestone, a user correction). Each agent reads its own pills **before
|
|
5
|
+
acting** so it does not repeat a past mistake.
|
|
6
|
+
|
|
7
|
+
This is a knowledge surface, not a convention doc. Keep the niche clean:
|
|
8
|
+
|
|
9
|
+
| Surface | Holds | Example |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| `CLAUDE.md` / `.claude/patterns.md` | **Codebase law / conventions** | "relative imports carry a `.js` extension" |
|
|
12
|
+
| `.claude/integrations/<slug>.md` | **External premises**, with evidence | "the client's `signOut()` never rejects" |
|
|
13
|
+
| **`.claude/pills/<role>/` (here)** | **Agent behavioral corrections** | "implementer: `waitFor()` hangs under fake timers" |
|
|
14
|
+
|
|
15
|
+
If a lesson is really a code convention or an external premise, it belongs in those files — not here.
|
|
16
|
+
|
|
17
|
+
## Layout
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
.claude/pills/
|
|
21
|
+
├── README.md # this file
|
|
22
|
+
├── shared/ # pills that apply to MORE THAN ONE role
|
|
23
|
+
└── <role>/ # one directory per role, named exactly as its spec in .claude/agents/
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
A role directory is created on demand, when its first pill is written. One **lesson per file**,
|
|
27
|
+
`kebab-case.md`. An agent reads `pills/<its-role>/*.md` **and** the `pills/shared/*.md` whose
|
|
28
|
+
`applies_to` includes it.
|
|
29
|
+
|
|
30
|
+
Placement is not decoration — it is delivery. A pill sitting in `architect/` that declares
|
|
31
|
+
`applies_to: [architect, implementer]` is never read by the implementer, because the implementer
|
|
32
|
+
only globs its own directory and `shared/`. So the rule is mechanical, and `nina pills` enforces it:
|
|
33
|
+
|
|
34
|
+
- **one role in `applies_to`** → the pill lives in that role's directory
|
|
35
|
+
- **more than one** → the pill lives in `shared/`
|
|
36
|
+
|
|
37
|
+
A pill loose at the top level of `pills/` is read by nobody.
|
|
38
|
+
|
|
39
|
+
## Pill format
|
|
40
|
+
|
|
41
|
+
Frontmatter is mandatory. A pill without it still reads like prose to a human, but it is invisible
|
|
42
|
+
to every filter the agents and the tooling run — `status`, `trigger` and `applies_to` all stop
|
|
43
|
+
working, so the pill is either ignored or applied where it does not belong.
|
|
44
|
+
|
|
45
|
+
```markdown
|
|
46
|
+
---
|
|
47
|
+
id: <role-dir>-<file-slug> # derived from the path, so it cannot drift
|
|
48
|
+
applies_to: [implementer] # one or more roles; drives who reads it, and where it lives
|
|
49
|
+
severity: low | medium | high
|
|
50
|
+
status: active | retired # retired = graduated into a rule, kept for history
|
|
51
|
+
date: YYYY-MM-DD # when learned; this is what lets staleness be spotted
|
|
52
|
+
occurrences: 1 # bump when the SAME lesson is learned again — see Graduation
|
|
53
|
+
last_seen: YYYY-MM-DD # set with every bump; how the harness knows the lesson is current
|
|
54
|
+
trigger: <when this pill is relevant — the agent applies it only if the task matches>
|
|
55
|
+
citations: [path/to/file.ts:42] # the code this pill is a claim about, when there is any
|
|
56
|
+
---
|
|
57
|
+
**What went wrong:** <the concrete mistake, with where it happened>
|
|
58
|
+
**Rule:** <the imperative — what to do / not do next time>
|
|
59
|
+
**Why:** <the mechanism, so the rule is understood and not merely obeyed>
|
|
60
|
+
**How to apply:** <the concrete check or step the agent runs>
|
|
61
|
+
source: <the run / commit / conversation that produced the lesson>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The `id` is the pill's directory and filename joined. When the filename already opens with the
|
|
65
|
+
role — `reviewer/reviewer-never-write-to-repo-files.md` — the role is not repeated.
|
|
66
|
+
|
|
67
|
+
**Every pill carries evidence: `citations`, or `source`, or both.** A pill is a claim about how
|
|
68
|
+
this system behaves, and a claim with nothing behind it is the thing this harness exists to remove.
|
|
69
|
+
The two are not interchangeable, and that is why they sit in different places:
|
|
70
|
+
|
|
71
|
+
- `citations` point at code in this repository, so a machine can later ask whether the cited line
|
|
72
|
+
still exists. Use them whenever the lesson is about code. They are a **frontmatter field**
|
|
73
|
+
because tooling reads them back.
|
|
74
|
+
- `source` points at the episode — a run, a commit, a conversation. Use it when the lesson is about
|
|
75
|
+
a tool or a process and there is no line to cite. Only a person ever reads it, so it closes the
|
|
76
|
+
body rather than crowding the header.
|
|
77
|
+
|
|
78
|
+
## The four guardrails (so this stays an asset, not noise)
|
|
79
|
+
|
|
80
|
+
1. **Bounded growth + graduation.** "Read all my pills" only works while the set is small. See
|
|
81
|
+
*Graduation* below.
|
|
82
|
+
2. **Staleness.** A pill that cites code rots like any note. `date` flags age and `citations` make
|
|
83
|
+
the rot findable; **verify before trusting**, and prune or update when you next touch the topic.
|
|
84
|
+
3. **Defined authoring trigger.** A pill is written on **every loop-back** (qa → implementer, a
|
|
85
|
+
reviewer rejection, a mandatory gate blocking) **or user correction**. The orchestrator writes it
|
|
86
|
+
as a named pipeline step — not "when someone remembers". If the lesson already has a pill, do not
|
|
87
|
+
write a second one: increment that pill's `occurrences` instead.
|
|
88
|
+
4. **Trigger-targeted, not blanket.** The agent reads its pills but **applies only those whose
|
|
89
|
+
`trigger` matches the current task**. This is what lets the corpus grow without drowning the agent.
|
|
90
|
+
|
|
91
|
+
## Graduation
|
|
92
|
+
|
|
93
|
+
`occurrences` is the counter that decides when a correction has stopped being an anecdote. A pill
|
|
94
|
+
learned once is a note. The same pill learned a third time is evidence that the surrounding rules do
|
|
95
|
+
not cover the case, and the fix belongs where nobody has to remember it:
|
|
96
|
+
|
|
97
|
+
- a convention the codebase should state → `.claude/patterns.md` or `CLAUDE.md`
|
|
98
|
+
- a premise about a dependency → `.claude/integrations/<slug>.md`
|
|
99
|
+
- a correction that would apply to **any** project of this shape → back into the harness itself, as
|
|
100
|
+
a rule in the core or in the surface that implies it
|
|
101
|
+
|
|
102
|
+
Once the rule is written where it belongs, set the pill `status: retired` and leave it in place. A
|
|
103
|
+
retired pill is history, not instruction: agents skip it. Deleting it would lose the reason the rule
|
|
104
|
+
exists.
|
|
105
|
+
|
|
106
|
+
A lesson that belongs in the harness cannot be written there from this project — the core and the
|
|
107
|
+
surfaces live in another repository, and this project composes a frozen version of them. So
|
|
108
|
+
graduating it is a request, and nobody has to remember to make it: when a pill reaches three
|
|
109
|
+
occurrences, `harness:check` writes one under `.nina/requests/`, carrying the pinned version, the
|
|
110
|
+
layer the rule belongs in and the lesson in this project's words. **Commit it with the pill.** The
|
|
111
|
+
harness maintainer answers it in a release — with the rule, or with the reason it stays here — and
|
|
112
|
+
the `nina upgrade` that installs that release closes the request: a rule retires the pill, a decline
|
|
113
|
+
leaves it active as this project's own lesson. Until then the pill stays active; retiring it earlier
|
|
114
|
+
drops the lesson in the gap. (`nina learn --graduate <pill>` sends one sooner, by hand.)
|
|
115
|
+
|
|
116
|
+
`nina pills` names every active pill that has reached three occurrences and proposes where it
|
|
117
|
+
should go: the core when its roles are composed by every project, or the surface that its roles
|
|
118
|
+
exist for. That is a proposal, not a verdict — a reviewer lesson can still be about one surface, and
|
|
119
|
+
only a person can tell. It is reported as a note, never a failure: a recurring lesson is work to
|
|
120
|
+
do, not a defect.
|
|
121
|
+
|
|
122
|
+
## Reading contract (referenced from each agent spec)
|
|
123
|
+
|
|
124
|
+
> Before acting, read `.claude/pills/<your-role>/*.md` and the `pills/shared/*.md` whose
|
|
125
|
+
> `applies_to` includes your role. Treat `status: active` pills as binding for any task matching
|
|
126
|
+
> their `trigger`. Skip `retired` pills. If a pill cites code that no longer exists, prefer the
|
|
127
|
+
> current code and flag the pill as stale.
|
|
128
|
+
|
|
129
|
+
## Checking
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
nina pills --project .
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Reports malformed frontmatter, pills filed where their audience will not read them, roles this
|
|
136
|
+
project does not compose, and pills carrying no evidence.
|
|
137
|
+
|
|
138
|
+
It also resolves every `citations` entry against the repository. A path that no longer exists, or a
|
|
139
|
+
line past the end of the file it names, is a failure: the pill is telling an agent to look at
|
|
140
|
+
something that is not there. A citation that still resolves in a file which **changed after the
|
|
141
|
+
pill's `date`** is only a note — the line survived, but the code on it may have moved on, and no
|
|
142
|
+
machine can settle that. Verify it before trusting it, then update the pill or retire it.
|
|
143
|
+
|
|
144
|
+
This is what `citations` buys, and it is the reason the format asks for them. A pill with only a
|
|
145
|
+
`source` cannot be checked this way at all.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Pipeline
|
|
2
|
+
|
|
3
|
+
<!-- nina:slot project.1 track-summary -->
|
|
4
|
+
|
|
5
|
+
<!-- nina:slot project.2 pipeline-diagram -->
|
|
6
|
+
|
|
7
|
+
The `reviewer` and every gate the diff triggers are read-only, so **dispatch them together in one
|
|
8
|
+
message** after the implementer rather than in sequence. The reviewer remains the gate — it does not
|
|
9
|
+
approve until the applicable guardrails have signed off. After approval, `qa` runs vitest once, on
|
|
10
|
+
its own. On a diff over ~200 lines, fan the reviewer out by dimension. Full rules:
|
|
11
|
+
`.claude/router.md` § *Parallelization*.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Stage contracts
|
|
16
|
+
|
|
17
|
+
Each stage has: **Input** → what arrives, **Output** → the artifact handed on, **Tools** → what it may use, **Exit criteria** → what must be true before handing off.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
### Planner
|
|
22
|
+
|
|
23
|
+
- **Input:** user request, often ambiguous or multi-step.
|
|
24
|
+
- **Output:** ordered list of subtasks, each tagged with a 1-line goal + scope (S/M/L) + retrieval list + parallelization tag (`SEQUENTIAL` / `PARALLEL-SAFE`).
|
|
25
|
+
- **Tools:** Read, Grep, Glob, WebSearch, WebFetch. **No edits except planning artifacts.**
|
|
26
|
+
- **Exit criteria:** each subtask is small enough for an architect to design in a single pass.
|
|
27
|
+
- **Skip if:** task is already small, single-concern, and concrete.
|
|
28
|
+
|
|
29
|
+
### Architect
|
|
30
|
+
|
|
31
|
+
- **Input:** one subtask from planner, or a well-scoped direct request.
|
|
32
|
+
- **Output:** technical spec — files to touch, function signatures, data flow, edge cases, tests to add, patterns to follow. Marks which gates in `.claude/graph.md` the change will trigger — the database gate if the schema or a query will be touched, the integration gate if an integration boundary will be — AND, for the latter, includes an **Integration premises** section: every behavior the implementation depends on, each carrying the evidence its kind requires — a `node_modules/.pnpm/<lib>@<version>/.../<file>:<line>` citation, a contract-test case, an observed response, or a `P<n>` reference into `.claude/integrations/<slug>.md`. No premise without a citation.
|
|
33
|
+
- **Tools:** Read, Write, Edit, Grep, Glob, WebSearch, WebFetch. **No edits except spec files + `.claude/integrations/**`.**
|
|
34
|
+
- **Exit criteria:** implementer can code without re-planning AND the integration gate, where `.claude/graph.md` has one, can verify each premise / contract case without re-deriving it.
|
|
35
|
+
|
|
36
|
+
### Implementer
|
|
37
|
+
|
|
38
|
+
- **Input:** architect's spec.
|
|
39
|
+
- **Output:** working TS code + tests. `{{TYPECHECK_CMD}}`, `{{LINT_CMD}}`, and (when frontend) `{{BUILD_CMD}}` clean for the affected packages. Diff scoped to the spec. **Does NOT run vitest.**
|
|
40
|
+
- **Tools:** Read, Write, Edit, Glob, Grep, Bash.
|
|
41
|
+
- **Exit criteria:** typecheck/lint/build pass; no scope creep; if the database was touched, says so on first line; if an external service surface touched, says so.
|
|
42
|
+
<!-- nina:slot db.1 -->
|
|
43
|
+
<!-- nina:slot integrations.1 -->
|
|
44
|
+
|
|
45
|
+
### Reviewer (gate before qa)
|
|
46
|
+
|
|
47
|
+
- **Input:** implementer's diff + all upstream artifacts.
|
|
48
|
+
- **Output:** approve, or request changes with `path:line` references.
|
|
49
|
+
- **Tools:** Read, Grep, Glob, Bash, WebFetch. **No edits. No vitest.**
|
|
50
|
+
- **Exit criteria:**
|
|
51
|
+
- `{{TYPECHECK_CMD}}`, `{{LINT_CMD}}` pass; `{{BUILD_CMD}}` when frontend touched.
|
|
52
|
+
- Diff matches spec (reject scope creep).
|
|
53
|
+
- `.claude/patterns.md` conventions followed (TSDoc, layering, naming, owner scoping).
|
|
54
|
+
<!-- nina:slot db.2 -->
|
|
55
|
+
<!-- nina:slot integrations.2 -->
|
|
56
|
+
- No security / privacy regression (no PII in logs, no leaked secret, no query missing its owner scope).
|
|
57
|
+
<!-- nina:slot money.1 -->
|
|
58
|
+
- **Preview-first deploy invariant:** a spec that culminates in prod deploy names a preview URL where smoke runs FIRST.
|
|
59
|
+
|
|
60
|
+
### QA (test execution)
|
|
61
|
+
|
|
62
|
+
- **Input:** reviewer's APPROVED verdict + the implementer's touched-package list.
|
|
63
|
+
- **Output:** PASS (ready for deploy) or FAIL (loops back to implementer/architect).
|
|
64
|
+
- **Tools:** Read, Grep, Glob, Bash.
|
|
65
|
+
- Runs vitest **once**, per affected package, **sequentially** (configs enforce single-fork). Kills stray test processes at start and end. See `.claude/agents/qa.md`.
|
|
66
|
+
|
|
67
|
+
### Devops (deploy)
|
|
68
|
+
|
|
69
|
+
- **Trigger:** qa PASS on a step that changes a deployed surface. Not for test-only, docs-only or harness-only steps.
|
|
70
|
+
- **Input:** qa PASS + the touched-package list + the architect spec's preview-deploy plan.
|
|
71
|
+
- **Output:** `DEPLOYED` (targets, migrations, the smoke it actually ran, the rollback) or `BLOCKED` (what stopped it, which stage owns the fix).
|
|
72
|
+
- **Tools:** Read, Grep, Glob, Bash, WebFetch. **No edits to code, tests or config.**
|
|
73
|
+
- **Checks:** clean rebuild of emitting packages; both targets when the API surface changed; `VITE_*` present at build time; `migrate deploy` against the intended database; secret parity; smoke against preview exercising the changed path; a named rollback.
|
|
74
|
+
- **Production:** never on its own initiative — an explicit go from {{OWNER}}, for that change.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Handoff discipline
|
|
79
|
+
|
|
80
|
+
Each stage produces a **written artifact** — spec, diff, review comments. The next stage consumes the artifact, **not** the original user message. If the implementer finds itself re-reading the original user message, something is wrong with the spec.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Examples
|
|
85
|
+
<!-- nina:slot project.3 worked-example-a -->
|
|
86
|
+
<!-- nina:slot project.4 worked-example-b -->
|
|
87
|
+
|
|
88
|
+
### Example C — Trivial fix
|
|
89
|
+
|
|
90
|
+
User: "Fix the typo in the dashboard page title."
|
|
91
|
+
|
|
92
|
+
No planner, no architect. Implementer fixes, typecheck passes, reviewer verifies scope. → QA (only if a test file changed). Done.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## When the pipeline breaks
|
|
97
|
+
|
|
98
|
+
Where each failing verdict sends the work, and how many rounds it gets, is in `.claude/graph.md` —
|
|
99
|
+
the one place it is stated, composed for this project.<!-- nina:why --> This section used to restate it, and had
|
|
100
|
+
already drifted from it: it sent an architect back to the planner along an edge the graph did not
|
|
101
|
+
have.<!-- /nina:why --> One thing the graph cannot express, so it stays here: a stage that hits something no spec
|
|
102
|
+
anticipated stops and says so. It does not guess.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Retrieval Map (RAG for workflow)
|
|
2
|
+
|
|
3
|
+
Which documents to pull into context for a given task type. Goal: **avoid loading all docs on every task** — that wastes tokens and crowds out the actual work.
|
|
4
|
+
|
|
5
|
+
This is the closest thing the harness has to RAG for development. Treat it as authoritative.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Always loaded (by Claude Code itself)
|
|
10
|
+
- `CLAUDE.md` — loads automatically. Don't re-read.
|
|
11
|
+
|
|
12
|
+
## Pills (per-agent behavioral corrections — loaded by the agent itself)
|
|
13
|
+
|
|
14
|
+
`.claude/pills/<role>/*.md` + `.claude/pills/shared/*.md` hold hard-won corrections from past mistakes (a loop-back, a rejected diff, a blocked milestone, a user correction). **Each subagent reads its own pills before acting** (the instruction is in every `.claude/agents/<role>.md`). Distinct from the surfaces above: pills capture *agent behavior* ("the implementer did X wrong"), not codebase conventions (→ `patterns.md`) or library premises (→ `integrations/`). The orchestrator writes a pill on every loop-back or user correction. Graduation: when a pill becomes law, move it to `patterns.md`/`CLAUDE.md` and mark the pill `retired`. Format + guardrails: `.claude/pills/README.md`.
|
|
15
|
+
<!-- nina:slot integrations.1 -->
|
|
16
|
+
<!-- nina:slot project.1 integration-doc-list -->
|
|
17
|
+
<!-- nina:slot integrations.2 -->
|
|
18
|
+
|
|
19
|
+
## Code map (load first for file-location tasks)
|
|
20
|
+
|
|
21
|
+
**Rule:** Before grepping the repo to find which files participate in a domain, load `.claude/code-map.md`. Two layers:
|
|
22
|
+
|
|
23
|
+
- **`.claude/code-map.md`** — hand-curated. Purpose, invariants, the critical paths, what to reuse. **Read this one.**
|
|
24
|
+
- **`.claude/code-map.generated.md`** — the exhaustive mechanical inventory (every module, its exports, its test) plus the dead-export and untested-module reports. Produced by `pnpm code-map`. Go here when you need the full list.
|
|
25
|
+
|
|
26
|
+
`pnpm code-map:check` fails when the curated map has drifted from the tree, and a Stop hook runs it automatically. **A "does this helper already exist?" question is answered here, not by writing a second one.**
|
|
27
|
+
|
|
28
|
+
## Load on demand
|
|
29
|
+
|
|
30
|
+
### Task types
|
|
31
|
+
|
|
32
|
+
| Task type | Load these docs | Dispatch |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| New API endpoint | `.claude/architecture.md` § *API*, § *Layering*, `.claude/patterns.md` § *API conventions* | architect → implementer → reviewer → qa |
|
|
35
|
+
<!-- nina:slot db.1 -->
|
|
36
|
+
<!-- nina:slot db.2 -->
|
|
37
|
+
<!-- nina:slot edge-cf.1 -->
|
|
38
|
+
<!-- nina:slot integrations.3 -->
|
|
39
|
+
<!-- nina:slot edge-cf.2 -->
|
|
40
|
+
<!-- nina:slot money.1 -->
|
|
41
|
+
<!-- nina:slot frontend.1 -->
|
|
42
|
+
<!-- nina:slot frontend.2 -->
|
|
43
|
+
<!-- nina:slot edge-cf.3 -->
|
|
44
|
+
| Performance investigation | `.claude/architecture.md` § *Performance targets*, relevant source | architect → implementer |
|
|
45
|
+
|
|
46
|
+
### Meta tasks
|
|
47
|
+
|
|
48
|
+
**Before changing anything under `.claude/` or `CLAUDE.md`, settle where it goes.** Most of those
|
|
49
|
+
files are composed and cannot be changed from this project; the rest are yours outright, and the
|
|
50
|
+
first question is mechanical rather than a judgement call: **does the file carry `nina:generated`?**
|
|
51
|
+
`nina where <path>` answers that and the rest for any path — including a path that does not exist
|
|
52
|
+
yet, which is the case no file's own header can answer — and it prints the same sentence that file's
|
|
53
|
+
header carries rather than a second wording of it. Inside a generated file the second question is
|
|
54
|
+
the judgement one, and it is only about that case: is the wrong text **this project's fact**, which
|
|
55
|
+
belongs in a `project.N` slot, or **a rule for every project**, which cannot be changed from here?
|
|
56
|
+
|
|
57
|
+
| Task type | Load these docs | Dispatch |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| A rule an agent follows is wrong | `nina where <the composed file>` — it is a **request against the pinned core**, quoting file and line. It cannot be edited here | report it; it arrives back through `nina upgrade` |
|
|
60
|
+
| A number, path, command or provider in a composed file is wrong | `nina where <the composed file>` — it is **this project's fact**, so it belongs in the slot it names under `.nina/project/tree/` | whoever found it, now |
|
|
61
|
+
| A spec the harness should compose is not on disk | `nina where <the path>` — a file gated on a surface this project does not declare is **not missing**, it is switched off. Declaring the surface is a decision about the project, not a fix | whoever is asking why it is absent |
|
|
62
|
+
| A mistake just happened and should not happen twice | `.claude/pills/README.md` — a **pill** under `.claude/pills/<role>/`, written directly. Never an edit to the agent's spec | the orchestrator, on the loop-back |
|
|
63
|
+
| What a library actually does, proven at runtime | `.claude/integrations/<slug>.md` — yours to write, and the slug belongs in `.nina/profile.json` or nothing knows the doc exists | the integration gate, or whoever proved it |
|
|
64
|
+
| A plan for work in progress | `.claude/plans/**` — yours, and nothing composes it, ever | whoever is planning |
|
|
65
|
+
| Anything that is not one of the above | `nina where <the path>` — it will say "not harness", which is an answer: the file is ordinary project code and the harness has no opinion about it | whoever is editing it |
|
|
66
|
+
| New subagent role | `.claude/pipeline.md`, `.claude/router.md`, existing `.claude/agents/*.md` | human decision |
|
|
67
|
+
| Package / route / service / RPC method added or removed | `.claude/code-map.md` — update the curated map, then run `pnpm code-map:check` | whoever shipped the change, at the close of the step |
|
|
68
|
+
| Update this map | the project's slot in it — `nina where .claude/retrieval.md` names it; a row every project needs is a request against the pinned core | architect (light) → reviewer |
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## How to scope loads
|
|
73
|
+
|
|
74
|
+
- **Load a section, not a full doc, when possible.** Architecture and patterns docs have headings; jump to the relevant one.
|
|
75
|
+
- **Don't preload.** Only read a doc when the task actually requires it.
|
|
76
|
+
- **Re-read existing code before editing it**, even if read this session — it may have changed.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Anti-patterns
|
|
81
|
+
|
|
82
|
+
- ❌ Loading `.claude/architecture.md` in full for a 3-line bug fix.
|
|
83
|
+
- ❌ Loading `.claude/patterns.md` when the task is a pure design discussion (no code yet).
|
|
84
|
+
- ❌ Loading every subagent spec manually — they load automatically when dispatched via Agent.
|
|
85
|
+
- ❌ Re-reading `CLAUDE.md` after Claude Code has loaded it.
|
|
86
|
+
- ❌ Skipping the retrieval map and loading "everything just in case."
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## When unsure
|
|
91
|
+
|
|
92
|
+
1. Read the **first 50 lines** of `.claude/architecture.md` (table of contents).
|
|
93
|
+
2. Identify the relevant section.
|
|
94
|
+
3. Read that section only.
|
|
95
|
+
4. If still unclear, escalate to the user — don't guess with more tokens.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Updating this map
|
|
100
|
+
|
|
101
|
+
When a new kind of task appears that isn't in the table:
|
|
102
|
+
1. Add a row here first.
|
|
103
|
+
2. Commit the update alongside the change it describes.
|
|
104
|
+
3. Don't let the map rot — a stale retrieval map is worse than no map.
|