@xhulz/nina 0.28.16 → 0.28.17
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.17/core/GAPS.md +125 -0
- package/releases/0.28.17/core/answered.json +29 -0
- package/releases/0.28.17/core/defaults/tree/.claude/agents/architect.md +1 -0
- package/releases/0.28.17/core/defaults/tree/.claude/agents/dba.md +3 -0
- package/releases/0.28.17/core/defaults/tree/.claude/agents/devops.md +1 -0
- package/releases/0.28.17/core/defaults/tree/.claude/agents/implementer.md +1 -0
- package/releases/0.28.17/core/defaults/tree/.claude/agents/integration-tester.md +3 -0
- package/releases/0.28.17/core/defaults/tree/.claude/agents/qa.md +2 -0
- package/releases/0.28.17/core/defaults/tree/.claude/agents/reviewer.md +3 -0
- package/releases/0.28.17/core/defaults/tree/.claude/agents/secops.md +3 -0
- package/releases/0.28.17/core/defaults/tree/.claude/agents/solidity-auditor.md +3 -0
- package/releases/0.28.17/core/defaults/tree/.claude/agents/solidity-dev.md +3 -0
- package/releases/0.28.17/core/tree/.claude/agents/architect.md +125 -0
- package/releases/0.28.17/core/tree/.claude/agents/dba.md +107 -0
- package/releases/0.28.17/core/tree/.claude/agents/devops.md +113 -0
- package/releases/0.28.17/core/tree/.claude/agents/implementer.md +155 -0
- package/releases/0.28.17/core/tree/.claude/agents/integration-tester.md +160 -0
- package/releases/0.28.17/core/tree/.claude/agents/planner.md +132 -0
- package/releases/0.28.17/core/tree/.claude/agents/qa.md +146 -0
- package/releases/0.28.17/core/tree/.claude/agents/reviewer.md +180 -0
- package/releases/0.28.17/core/tree/.claude/agents/secops.md +121 -0
- package/releases/0.28.17/core/tree/.claude/agents/solidity-auditor.md +126 -0
- package/releases/0.28.17/core/tree/.claude/agents/solidity-dev.md +123 -0
- package/releases/0.28.17/core/tree/.claude/agents-overview.md +64 -0
- package/releases/0.28.17/core/tree/.claude/graph.md +72 -0
- package/releases/0.28.17/core/tree/.claude/patterns.md +212 -0
- package/releases/0.28.17/core/tree/.claude/pills/README.md +145 -0
- package/releases/0.28.17/core/tree/.claude/pipeline.md +102 -0
- package/releases/0.28.17/core/tree/.claude/retrieval.md +104 -0
- package/releases/0.28.17/core/tree/.claude/router.md +201 -0
- package/releases/0.28.17/core/tree/.claude/templates/integration.md +45 -0
- package/releases/0.28.17/core/tree/CLAUDE.md +155 -0
- package/releases/0.28.17/core/tree/scripts/edit-guard.mjs +16 -0
- package/releases/0.28.17/core/tree/scripts/harness-check.mjs +71 -0
- package/releases/0.28.17/core/tree/scripts/loop-gate.mjs +19 -0
- package/releases/0.28.17/core/vocabulary.json +12 -0
- package/releases/0.28.17/surfaces/blockchain/tree/.claude/agents/architect.md +5 -0
- package/releases/0.28.17/surfaces/blockchain/tree/.claude/agents/devops.md +5 -0
- package/releases/0.28.17/surfaces/blockchain/tree/.claude/agents/reviewer.md +5 -0
- package/releases/0.28.17/surfaces/blockchain/tree/.claude/agents/solidity-auditor.md +18 -0
- package/releases/0.28.17/surfaces/blockchain/tree/.claude/agents/solidity-dev.md +16 -0
- package/releases/0.28.17/surfaces/blockchain/tree/.claude/agents-overview.md +6 -0
- package/releases/0.28.17/surfaces/blockchain/tree/.claude/graph.md +11 -0
- package/releases/0.28.17/surfaces/blockchain/tree/.claude/router.md +9 -0
- package/releases/0.28.17/surfaces/blockchain/tree/CLAUDE.md +12 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/agents/architect.md +8 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/agents/dba.md +84 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/agents/devops.md +14 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/agents/implementer.md +5 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/agents/integration-tester.md +13 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/agents/planner.md +2 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/agents/reviewer.md +25 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/agents/secops.md +2 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/agents-overview.md +5 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/graph.md +8 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/patterns.md +29 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/pipeline.md +13 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/retrieval.md +5 -0
- package/releases/0.28.17/surfaces/db/tree/.claude/router.md +10 -0
- package/releases/0.28.17/surfaces/db/tree/CLAUDE.md +23 -0
- package/releases/0.28.17/surfaces/edge-cf/tree/.claude/agents/architect.md +14 -0
- package/releases/0.28.17/surfaces/edge-cf/tree/.claude/agents/dba.md +2 -0
- package/releases/0.28.17/surfaces/edge-cf/tree/.claude/agents/devops.md +31 -0
- package/releases/0.28.17/surfaces/edge-cf/tree/.claude/agents/implementer.md +14 -0
- package/releases/0.28.17/surfaces/edge-cf/tree/.claude/agents/integration-tester.md +11 -0
- package/releases/0.28.17/surfaces/edge-cf/tree/.claude/agents/qa.md +3 -0
- package/releases/0.28.17/surfaces/edge-cf/tree/.claude/agents/reviewer.md +8 -0
- package/releases/0.28.17/surfaces/edge-cf/tree/.claude/agents/secops.md +8 -0
- package/releases/0.28.17/surfaces/edge-cf/tree/.claude/patterns.md +17 -0
- package/releases/0.28.17/surfaces/edge-cf/tree/.claude/retrieval.md +8 -0
- package/releases/0.28.17/surfaces/edge-cf/tree/.claude/router.md +21 -0
- package/releases/0.28.17/surfaces/edge-cf/tree/CLAUDE.md +27 -0
- package/releases/0.28.17/surfaces/frontend/tree/.claude/agents/architect.md +20 -0
- package/releases/0.28.17/surfaces/frontend/tree/.claude/agents/devops.md +28 -0
- package/releases/0.28.17/surfaces/frontend/tree/.claude/agents/implementer.md +25 -0
- package/releases/0.28.17/surfaces/frontend/tree/.claude/agents/qa.md +17 -0
- package/releases/0.28.17/surfaces/frontend/tree/.claude/agents/reviewer.md +62 -0
- package/releases/0.28.17/surfaces/frontend/tree/.claude/patterns.md +15 -0
- package/releases/0.28.17/surfaces/frontend/tree/.claude/retrieval.md +5 -0
- package/releases/0.28.17/surfaces/frontend/tree/.claude/router.md +17 -0
- package/releases/0.28.17/surfaces/frontend/tree/CLAUDE.md +5 -0
- package/releases/0.28.17/surfaces/integrations/tree/.claude/agents/architect.md +16 -0
- package/releases/0.28.17/surfaces/integrations/tree/.claude/agents/implementer.md +12 -0
- package/releases/0.28.17/surfaces/integrations/tree/.claude/agents/integration-tester.md +20 -0
- package/releases/0.28.17/surfaces/integrations/tree/.claude/agents/planner.md +2 -0
- package/releases/0.28.17/surfaces/integrations/tree/.claude/agents/reviewer.md +21 -0
- package/releases/0.28.17/surfaces/integrations/tree/.claude/agents/secops.md +2 -0
- package/releases/0.28.17/surfaces/integrations/tree/.claude/agents-overview.md +8 -0
- package/releases/0.28.17/surfaces/integrations/tree/.claude/graph.md +9 -0
- package/releases/0.28.17/surfaces/integrations/tree/.claude/patterns.md +38 -0
- package/releases/0.28.17/surfaces/integrations/tree/.claude/pipeline.md +16 -0
- package/releases/0.28.17/surfaces/integrations/tree/.claude/retrieval.md +16 -0
- package/releases/0.28.17/surfaces/integrations/tree/.claude/router.md +6 -0
- package/releases/0.28.17/surfaces/integrations/tree/CLAUDE.md +17 -0
- package/releases/0.28.17/surfaces/money/tree/.claude/agents/architect.md +12 -0
- package/releases/0.28.17/surfaces/money/tree/.claude/agents/dba.md +14 -0
- package/releases/0.28.17/surfaces/money/tree/.claude/agents/implementer.md +11 -0
- package/releases/0.28.17/surfaces/money/tree/.claude/agents/integration-tester.md +3 -0
- package/releases/0.28.17/surfaces/money/tree/.claude/agents/reviewer.md +23 -0
- package/releases/0.28.17/surfaces/money/tree/.claude/agents/secops.md +5 -0
- package/releases/0.28.17/surfaces/money/tree/.claude/agents/solidity-auditor.md +4 -0
- package/releases/0.28.17/surfaces/money/tree/.claude/agents/solidity-dev.md +4 -0
- package/releases/0.28.17/surfaces/money/tree/.claude/graph.md +2 -0
- package/releases/0.28.17/surfaces/money/tree/.claude/patterns.md +49 -0
- package/releases/0.28.17/surfaces/money/tree/.claude/pipeline.md +2 -0
- package/releases/0.28.17/surfaces/money/tree/.claude/retrieval.md +2 -0
- package/releases/0.28.17/surfaces/money/tree/CLAUDE.md +11 -0
- package/releases/0.28.17/surfaces/pii/tree/.claude/agents/dba.md +2 -0
- package/releases/0.28.17/surfaces/pii/tree/.claude/agents/devops.md +8 -0
- package/releases/0.28.17/surfaces/pii/tree/.claude/agents/reviewer.md +8 -0
- package/releases/0.28.17/surfaces/pii/tree/.claude/agents/secops.md +2 -0
- package/releases/0.28.17/surfaces/pii/tree/.claude/agents/solidity-auditor.md +5 -0
- package/releases/0.28.17/surfaces/pii/tree/CLAUDE.md +5 -0
- package/src/commands/wire.mjs +1 -1
- package/src/wiring.mjs +5 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xhulz/nina",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.17",
|
|
4
4
|
"description": "Composes an agent harness into a project from a versioned core, its surfaces, and the project's own layer.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Marcos Schulz",
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Known gaps
|
|
2
|
+
|
|
3
|
+
The harness was extracted by slicing one live project, and a slice cannot be cleaner than the
|
|
4
|
+
thing it was cut from. This file tracks what is still shaped by that origin.
|
|
5
|
+
|
|
6
|
+
## Closed
|
|
7
|
+
|
|
8
|
+
**Domain examples in the core.** The extraction had to leave money and PII nouns in otherwise
|
|
9
|
+
invariant rules, because byte-exact recomposition was the proof that nothing was lost and
|
|
10
|
+
rewriting a line broke it. Once projects started pinning a release, that constraint lifted:
|
|
11
|
+
the core no longer names payouts, escrow, KYC, PIX, CPF or a single provider, and the
|
|
12
|
+
`db` surface no longer assumes the write it protects is a money movement. `fixtures/acme`
|
|
13
|
+
holds the line — it declares no `money` and no `pii` surface, and the test fails on any of
|
|
14
|
+
those words reappearing.
|
|
15
|
+
|
|
16
|
+
**The single-provider assumption.** `external-api` became `integrations`, plural, cut by how
|
|
17
|
+
a premise is settled (`installed-library` / `live-api` / `platform-binding`) rather than by
|
|
18
|
+
one project's payment provider.
|
|
19
|
+
|
|
20
|
+
**The `money` surface was one project's money path.** It shipped that project's state machine
|
|
21
|
+
(`DETECTADA → CASADA | DIVERGENTE | SEM_REGRA`) as a harness rule, named its models, its
|
|
22
|
+
currency and its escrow vocabulary, and assumed one payment provider. It now states the
|
|
23
|
+
invariants and nothing else: conservation, idempotency of an irreversible send, one
|
|
24
|
+
serialization point per balance, integer minor units, and a state machine the **project**
|
|
25
|
+
declares in its own `.claude/architecture.md`. `fixtures/ledger` holds that line — a money
|
|
26
|
+
project whose minor unit is `cents`, whose engine is `packages/settlement`, and whose deny
|
|
27
|
+
list fails on `escrow`, `centavos`, `Payout`, `DETECTADA` or any of the rest reappearing.
|
|
28
|
+
|
|
29
|
+
**The `pii` surface was one country's regime.** It named CPF/CNPJ, PIX keys, KYC documents, LGPD,
|
|
30
|
+
R2 and Postgres as if they were universal categories. It now says that sensitive categories are
|
|
31
|
+
**declared by the project** in its own `.claude/architecture.md`, and states what is invariant:
|
|
32
|
+
classified, encrypted at rest, never in a log, an error, a URL, an analytics event or an agent
|
|
33
|
+
transcript, and document bytes only in the object store. `fixtures/ledger` declares `pii` with a
|
|
34
|
+
`GDPR` regime and fails on any of the old words returning.
|
|
35
|
+
|
|
36
|
+
**Incident dates that read as false history.** Five places told a rule through a date it happened
|
|
37
|
+
on — a wiped database on 2026-09-16, a blocked deploy on 2026-09-21, specs split across two
|
|
38
|
+
directories before 2026-09-04. In the project where it happened that is provenance; in a new one it
|
|
39
|
+
is a claim about a past it does not have, and an agent will go looking for it. The rules keep their
|
|
40
|
+
force without the date: *"the command completes with a reassuring 'empty migration' result and no
|
|
41
|
+
error, having already destroyed everything in the database it was pointed at."*
|
|
42
|
+
|
|
43
|
+
**A rule cross-reference that pointed at nothing.** The hard rules are one numbered list assembled
|
|
44
|
+
from several layers, so a project that declares no `integrations` surface has no rule 12 — while the
|
|
45
|
+
core still said "the premise rule (#12 below)". `compose-test` now checks every `Hard Rule #N`
|
|
46
|
+
against the rules the project actually composed, and `fixtures/plain` declares no surface at all, so
|
|
47
|
+
the most reduced case is exercised on every run.
|
|
48
|
+
|
|
49
|
+
**Invariant rules that landed in the project layer.** Four rules were generically valuable but were
|
|
50
|
+
stated through an incident or an inventory belonging to one project, so the project layer swallowed
|
|
51
|
+
them and a new project got nothing. Each was restated in the layer that actually owns it:
|
|
52
|
+
|
|
53
|
+
| Spec | What it got back |
|
|
54
|
+
|---|---|
|
|
55
|
+
| secops | the **AuthN / session** dimension is now core: credential issuance and consumption, cookie flags, fixation across a privilege change, origin allowlist, and any dev bypass that could reach production. The project slot survives for the auth library and the bypasses that project actually has. |
|
|
56
|
+
| qa | the *"pre-existing failure"* traps moved to `surfaces/frontend` — they are facts about a jsdom + vitest harness, not about one feature. The project slot held only the provenance, so it was dropped. |
|
|
57
|
+
| architect, implementer | both specs now state the Route → Service → Data rule themselves instead of only `patterns.md` stating it. The project slot survives for the package names. |
|
|
58
|
+
| patterns | *"when correcting a document, delete what you are correcting"* is now a core section. |
|
|
59
|
+
|
|
60
|
+
**The threat model was numbered, and the numbers came from slots.** Dimensions 1–8 lived in surface
|
|
61
|
+
fragments and 9–10 in the core, so a project declaring every surface got 1–10 and everyone else got
|
|
62
|
+
a list with holes: `acme` read `2, 3, 6, 8, 9, 10`, and a surfaceless project began at **9**. The
|
|
63
|
+
list is bullets now, valid under any combination. The core's rate-limiting dimension also named one
|
|
64
|
+
project's auth strategy (`magic-link request, dev routes`); it says `issues a credential` instead.
|
|
65
|
+
|
|
66
|
+
**A surface's technology was named in files nothing gated.** The item above used to bundle two
|
|
67
|
+
different things under "stack-specific", and only one of them was a choice. `Prisma` appeared in 7
|
|
68
|
+
ungated core files and Cloudflare's runtime in 10 — technologies that already *have* surfaces, named
|
|
69
|
+
in text every project composes. A frontend-only project read a `CLAUDE.md` that discussed Prisma, a
|
|
70
|
+
`patterns.md` headed *API (Cloudflare Worker / Hono) conventions*, and a qa spec telling it to kill
|
|
71
|
+
stray `workerd` processes that could not exist. The reviewer even pointed at `CLAUDE.md` §
|
|
72
|
+
*Cloudflare plugin skills*, a section that lives in the edge-cf surface — a dangling cross-reference
|
|
73
|
+
of exactly the kind already closed once here.
|
|
74
|
+
|
|
75
|
+
42 sites were fixed by saying what the rule means rather than which product implements it: "if the
|
|
76
|
+
database was touched" instead of "if Prisma touched", "deploy config" instead of "wrangler config",
|
|
77
|
+
"the local emulator" instead of "Miniflare". None of it lost precision, because the instruction was
|
|
78
|
+
never about the product. Where a genuine specific was worth keeping it moved into `surfaces/edge-cf`
|
|
79
|
+
behind a slot.
|
|
80
|
+
|
|
81
|
+
The deny lists never caught this, and could not: they guard one fixture's output against *domain*
|
|
82
|
+
leaks, and a substring match makes a word like `Hono` unusable because it fires on `Honor`. The
|
|
83
|
+
guard is now a layer audit in `compose:test` — for every core file, a surface's technology may be
|
|
84
|
+
named only if the file is gated on that surface. It asks the question once, of everything, instead
|
|
85
|
+
of only of what a fixture happens to compose.
|
|
86
|
+
|
|
87
|
+
**Money in the core, and the heavy-gate list that carried it.** The extraction closed money's nouns
|
|
88
|
+
(payout, escrow, the state machine) but not the word itself: ten places in the core listed "money, the
|
|
89
|
+
database, auth, an integration" as the changes that are always gated in full, so a project with no
|
|
90
|
+
money was told that under-gating a money movement was a protocol violation, and its devops that a
|
|
91
|
+
production deploy "moves real money". The audit now holds `money` like a technology, and found 19 of
|
|
92
|
+
them. The list is one definition of **critical paths** in `CLAUDE.md` — auth in the core, and the
|
|
93
|
+
database, an integration boundary, money movement, personal data and contract code each added by its
|
|
94
|
+
own surface — and the ten places say "a critical path". Two copies of money's own rules had also
|
|
95
|
+
landed in `surfaces/db` (`BigInt` columns, a money-integrity check in the dba's report), contradicting
|
|
96
|
+
the money surface's integer minor unit; they are gone, since the money surface already says it better.
|
|
97
|
+
The same pass found Cloudflare's `Pages`, `Worker` and a capitalised `Wrangler` in the core and in
|
|
98
|
+
two surfaces, and the leftovers no audit could name: a model called `DestinationAccount` and a spec
|
|
99
|
+
set called `retention-spec1..8` in the router's examples, "all nine stages" where a profile composes
|
|
100
|
+
seven to eleven, `userId` as the name of owner scoping, and "the harness's first three months" told
|
|
101
|
+
as the history of whichever project was reading it.
|
|
102
|
+
|
|
103
|
+
## Open
|
|
104
|
+
|
|
105
|
+
**The core is domain-agnostic, not stack-agnostic — deliberately.** The stack's own commands are
|
|
106
|
+
vocabulary now, with the release's defaults (`core/vocabulary.json`): the typecheck, lint and build
|
|
107
|
+
commands a spec tells a stage to run, and the test command every stage but qa is told not to run. qa's
|
|
108
|
+
own targeted `vitest run` stays literal. What remains is the stack's substance, not its commands:
|
|
109
|
+
`vitest` and its memory discipline, `TSDoc`, `TypeScript`, `turbo`, and `pnpm` wherever a sentence
|
|
110
|
+
describes the workspace rather than a command to run. That is the single track
|
|
111
|
+
this harness is for, and most of it is load-bearing: the qa spec's memory discipline is a fact about
|
|
112
|
+
vitest, not about testing. Unlike the surface leak above, this is not a defect — there is no
|
|
113
|
+
`pnpm` surface a project could decline. It becomes a gap only when a project on another stack
|
|
114
|
+
appears. The `.js`-extension and barrel-export rules are the sharpest case — they assume a
|
|
115
|
+
TypeScript monorepo that emits `dist/`, and `fixtures/plain` needs `PKG_SCOPE` and `EMITTING_PKGS`
|
|
116
|
+
in its vocabulary to compose at all. If a second stack ever arrives, those are a `ts-monorepo`
|
|
117
|
+
surface, not core.
|
|
118
|
+
|
|
119
|
+
**A composed project is not a finished project — by design.** With no project layer, `CLAUDE.md`
|
|
120
|
+
still opens with blank lines and no title, mission or stack. That is not a defect to fix in the
|
|
121
|
+
core: the missing text is the part only this project can say. `init` conducts the interview and
|
|
122
|
+
writes it to `.nina/TODO.md`, and it deliberately writes **no stub fragments**, because a stub is
|
|
123
|
+
a filled slot as far as every tool is concerned — a tree of TODOs would compose and check clean
|
|
124
|
+
while saying nothing. So `compose` keeps naming the unfilled slots until a person fills them, and
|
|
125
|
+
the blank opening is that list being honest rather than the core being incomplete.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"2026-09-22-integration-tester__regenerate-the-premise-index-after-editing-an-integration-doc": {
|
|
3
|
+
"in": "core/tree/.claude/agents/integration-tester.md"
|
|
4
|
+
},
|
|
5
|
+
"2026-09-22-qa__exit-code-is-the-verdict": {
|
|
6
|
+
"in": "core/tree/.claude/agents/qa.md"
|
|
7
|
+
},
|
|
8
|
+
"2026-09-22-shared__test-must-name-the-mutation-that-fails-it": {
|
|
9
|
+
"in": "core/tree/.claude/agents/reviewer.md"
|
|
10
|
+
},
|
|
11
|
+
"2026-09-25-shared__docs-match-final-code": {
|
|
12
|
+
"in": "core/tree/.claude/agents/implementer.md"
|
|
13
|
+
},
|
|
14
|
+
"2026-09-25-shared__fail-closed-on-every-branch": {
|
|
15
|
+
"in": "core/tree/.claude/agents/implementer.md"
|
|
16
|
+
},
|
|
17
|
+
"2026-09-25-shared__test-must-fail-under-its-mutation": {
|
|
18
|
+
"in": "core/tree/.claude/agents/implementer.md"
|
|
19
|
+
},
|
|
20
|
+
"2026-09-25-shared__tsdoc-covers-members": {
|
|
21
|
+
"in": "core/tree/CLAUDE.md"
|
|
22
|
+
},
|
|
23
|
+
"2026-09-26-architect__revision-sweeps-contradicted-text": {
|
|
24
|
+
"in": "core/tree/.claude/agents/architect.md"
|
|
25
|
+
},
|
|
26
|
+
"2026-09-26-shared__validate-patterns-against-real-samples": {
|
|
27
|
+
"in": "core/tree/.claude/agents/implementer.md"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!-- nina:slot project.7 -->
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<!-- nina:slot project.1 -->
|
|
2
|
+
description: Use when a diff touches the schema, a migration or a query, in the same message as the reviewer. Architect and implementer may also ask it while designing one. Checks migration safety, query cost and indexes, cache and freshness rules, and data integrity, and returns APPROVED or REJECTED. The reviewer does not approve without its sign-off. Never writes application code.
|
|
3
|
+
<!-- nina:slot project.4 -->
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!-- nina:slot project.4 -->
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!-- nina:slot project.4 -->
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<!-- nina:slot project.1 -->
|
|
2
|
+
description: Use when a diff touches an integration boundary, meaning a service, library or platform binding whose behavior this project does not define. Verifies each premise against the real dependency rather than the mock, and returns APPROVED or REJECTED. A wrong premise goes back to the architect, code that does not honor a premise to the implementer.
|
|
3
|
+
<!-- nina:slot project.5 -->
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- nina:slot project.1 -->
|
|
2
|
+
description: Use after the reviewer approves. Runs the tests of the packages the diff touched, once and never beside another test run, and returns PASS or FAIL with the exit code as the verdict. A failure loops back to the implementer, or to the architect when the test is right and the spec was wrong. Never writes code.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<!-- nina:slot project.1 -->
|
|
2
|
+
description: Use after the implementer produces a diff, in the same message as every gate the diff triggered. Audits the diff against the architect's spec, runs typecheck, lint and build (never the tests, which qa runs after approval), and confirms every triggered gate ran and approved. Returns APPROVED or REJECTED. Read-only, never fixes.
|
|
3
|
+
<!-- nina:slot project.3 -->
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<!-- nina:slot project.1 -->
|
|
2
|
+
description: Use after the last step of a milestone passes qa, or when the owner asks for a security pass. Audits the assembled system as an attacker and as a privacy and compliance auditor, scoped to the milestone's diff, and returns SECURE or BLOCKED with each finding's severity. Not a substitute for the reviewer. Writes nothing to the repo.
|
|
3
|
+
<!-- nina:slot project.7 -->
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<!-- nina:slot project.1 -->
|
|
2
|
+
description: Use on any diff that touches a contract, a deploy script, or a library version the contracts import, wherever the pipeline is. Audits the diff as an attacker before anything deploys, and returns APPROVED or REJECTED with the path and call sequence of each finding. The reviewer does not approve, and devops does not deploy, without its sign-off.
|
|
3
|
+
<!-- nina:slot project.5 -->
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<!-- nina:slot project.1 -->
|
|
2
|
+
description: Use when the architect's spec changes contract code. Writes the contract change and its adversarial tests, treating deployed code as immutable, so work that cannot be made safe as specified is BLOCKED rather than merged with a follow-up. Hands its diff to the solidity-auditor.
|
|
3
|
+
<!-- nina:slot project.5 -->
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: architect
|
|
3
|
+
description: Use after the planner, or directly for a well-scoped single-component change. Designs the technical approach and produces a written spec (files, signatures, data flow, tests) that the implementer can code from without re-planning. Do NOT use for trivial edits or pure Q&A.
|
|
4
|
+
tools: Read, Write, Edit, Grep, Glob, WebSearch, WebFetch, Skill
|
|
5
|
+
model: {{DEEP_MODEL}}
|
|
6
|
+
effort: {{ARCHITECT_EFFORT}}
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Consult your pills first
|
|
10
|
+
|
|
11
|
+
Before acting, read `.claude/pills/architect/*.md` and any `.claude/pills/shared/*.md` whose `applies_to` includes **architect**. These are hard-won corrections from past mistakes. Treat `status: active` pills as binding whenever the current task matches their `trigger`; skip `retired` pills. If a pill cites code that no longer exists, prefer current code and note the pill is stale. See `.claude/pills/README.md`.
|
|
12
|
+
|
|
13
|
+
## Skills you MUST consult
|
|
14
|
+
|
|
15
|
+
Retrieval beats recall — the same standard as the `node_modules:<line>` premise rule. Invoke via the
|
|
16
|
+
`Skill` tool **before** acting, and only when the trigger matches; a skill pulled for a task it does
|
|
17
|
+
not cover is wasted context.
|
|
18
|
+
|
|
19
|
+
| Skill | Invoke when the spec will touch… |
|
|
20
|
+
|---|---|
|
|
21
|
+
<!-- nina:slot edge-cf.1 -->
|
|
22
|
+
<!-- nina:slot edge-cf.2 -->
|
|
23
|
+
<!-- nina:slot edge-cf.3 -->
|
|
24
|
+
<!-- nina:slot edge-cf.4 -->
|
|
25
|
+
<!-- nina:slot db.1 -->
|
|
26
|
+
<!-- nina:slot frontend.1 -->
|
|
27
|
+
<!-- nina:slot blockchain.1 -->
|
|
28
|
+
<!-- nina:slot project.7 skills -->
|
|
29
|
+
|
|
30
|
+
Cite in your report which skills you consulted, or state that no trigger matched.
|
|
31
|
+
|
|
32
|
+
<!-- nina:slot project.1 role-intro -->
|
|
33
|
+
|
|
34
|
+
<!-- nina:slot project.2 scope -->
|
|
35
|
+
|
|
36
|
+
## Inputs
|
|
37
|
+
- A single subtask from the planner, OR a direct user request that is already well-scoped for a single change, OR a **group of sibling steps the planner marked `ONE-SPEC`** (steps that change no observable behavior on their own).
|
|
38
|
+
|
|
39
|
+
For a `ONE-SPEC` group, write **one** spec covering the whole group, with the "Files to touch" list
|
|
40
|
+
numbered per step so the implementer still lands them one at a time and each step stays small and
|
|
41
|
+
auditable. If the group's combined diff would exceed ~400 lines, push back — it was not a group.
|
|
42
|
+
|
|
43
|
+
If the planner marked the subtask as **L** or **XL** without further decomposition, push back: ask the planner to decompose further before you spec it. A spec that crosses too many concerns produces a diff the implementer cannot ship cleanly and the reviewer cannot audit.
|
|
44
|
+
|
|
45
|
+
## Outputs
|
|
46
|
+
A **technical spec** containing:
|
|
47
|
+
- **Goal** — 1–2 sentences.
|
|
48
|
+
- **Files to touch** — absolute paths, each marked `new` / `modify` / `delete`. **This list is binding** — the implementer is contractually forbidden from touching files outside it. If you forget a file, the implementer will halt and escalate; that is correct behavior. Be exhaustive.
|
|
49
|
+
- **Steps, when the list is long.** One implementer run writes at most {{STEP_FILES}} files. When "Files to touch" lists more, split it into numbered steps, each one piece that typechecks and builds on its own (a data pipeline, a worker, a runner, each with its own tests), in the order they must land. Each step file opens by naming the package it writes in and the steps it builds on (`Builds on: 1, 2`, or `Builds on: nothing`): steps that build on nothing still open and share no file can be implemented at the same time. So a file every step would edit (a README, a changelog, an index) goes in one step, the last that needs it: shared, it orders steps that nothing else orders. Keep what every step shares in the spec, and write each step in its own file beside it, `.claude/plans/specs/<feature>-spec.step-<n>.md`, with that step's files, signatures and tests, so a step's implementer reads the spec and its own step rather than every other step's. One package is not one step: a run re-reads the context it has built on every turn, so its cost grows faster than its size.<!-- nina:why --> A spike specified as one 49-file step ran 68 minutes in a single implementer run and read 357M tokens from cache, 6.9M a file, where runs of 10 to 19 files read 1.1M a file. Its spec was 141 KB, and every implementer turn and every reviewer read all of it.<!-- /nina:why -->
|
|
50
|
+
- **Out-of-scope guardrail** — explicit list of nearby files / concerns that this spec must NOT touch (so the implementer doesn't drift into adjacent work).
|
|
51
|
+
- **Function / module signatures** — types, inputs, outputs, error cases.
|
|
52
|
+
- **Data flow** — how data moves through the change. The layering must be explicit; where the change is one stage of a longer pipeline, say which stage, what triggers it, and what serializes it against concurrent runs.
|
|
53
|
+
<!-- nina:slot db.2 -->
|
|
54
|
+
- **Edge cases** — explicit list of what can go wrong.
|
|
55
|
+
- **Tests to add** — unit tests for the pure logic, naming the invariants to cover exhaustively rather than the happy path alone; integration tests against the real runtime, not a mock of it; and the fixtures they need, with realistic values. For a `live-api`, the contract-test cases BOTH implementations must satisfy.
|
|
56
|
+
- **Patterns to follow** — cite specific sections of `.claude/patterns.md`.
|
|
57
|
+
<!-- nina:slot db.3 -->
|
|
58
|
+
<!-- nina:slot money.1 -->
|
|
59
|
+
|
|
60
|
+
- **Obsolescence list (MANDATORY).** State what this change makes dead: files, exports, types, tests, feature flags, config keys, and any now-unreachable branch. Mark each `delete` in the "Files to touch" list. **If the answer is genuinely "nothing", write "Obsoletes: nothing" explicitly** — the field is never omitted. Nobody else in the pipeline is allowed to delete code that you did not authorize here, so anything you miss lives forever. Run `pnpm code-map` and check the dead-export report when a change removes or replaces a call site.
|
|
61
|
+
<!-- nina:slot blockchain.2 -->
|
|
62
|
+
<!-- nina:slot integrations.1 -->
|
|
63
|
+
<!-- nina:slot edge-cf.5 -->
|
|
64
|
+
- **Preview deploy plan** — if the spec culminates in a feature that will be deployed, explicitly name the preview URL pattern where smoke runs FIRST (a preview deployment for `{{APP_DIR}}`; a staging route for the API). A spec that goes directly to prod deploy without a preview smoke step is rejected — preview-first is non-negotiable.
|
|
65
|
+
|
|
66
|
+
## You MUST
|
|
67
|
+
- Read the planner's artifact (if any) in full before starting.
|
|
68
|
+
- Consult `.claude/retrieval.md` and read only the doc sections that apply.
|
|
69
|
+
- Read `.claude/architecture.md` when your task involves locating which files participate in a domain or confirming the planned layout.
|
|
70
|
+
<!-- nina:slot project.3 integration-docs-to-read -->
|
|
71
|
+
- Verify current code state with `Read` / `Grep` before specifying changes — do not assume.
|
|
72
|
+
<!-- nina:slot integrations.3 -->
|
|
73
|
+
<!-- nina:slot project.4 code-map-and-helpers -->
|
|
74
|
+
- **Cite the existing code you are extending.** Every claim about how the current system behaves carries a `path:line` reference, the same way external-library premises carry `node_modules:<line>`. "The service already does X" without a citation is an assumption, and assumptions are how a second seam gets built next to the first one.
|
|
75
|
+
- **Respect the Route → Service → Data layering** that `.claude/patterns.md` defines: a route never
|
|
76
|
+
reaches past the service into the data layer, and a service never touches the HTTP context. A spec
|
|
77
|
+
that puts a query in a route is where the second seam starts, and the second seam is what every
|
|
78
|
+
later inconsistency is built on.
|
|
79
|
+
<!-- nina:slot project.5 layering-rule -->
|
|
80
|
+
- Keep the spec self-sufficient: the implementer should never need to re-read the original user request or planner output.
|
|
81
|
+
- **Say each thing once, and briefly.** Every stage after you reads the whole spec, and an implementer reads it again on every turn of its run. Cite `.claude/architecture.md`, `.claude/patterns.md` and any other document by section rather than restating it; give each test as one line naming the case and what must hold; write code only where a signature, a type or a schema is itself the decision. When a stage sends the spec back, correct it where it is wrong: the spec says what to build, not how it came to be, and what changed and why goes in your report. A correction is done when the whole spec agrees with it: search every section and step file for the old behavior's terms, and compute every number, hand example and table value rather than estimating it.<!-- nina:why --> The first new project's spike spec reached 156 KB, 10% of it code, where the other project's specs had a median of 40 KB. The four rounds it was sent back through were kept as revision sections at its head, which every later stage read first.<!-- /nina:why -->
|
|
82
|
+
- **Write the spec directly** to `.claude/plans/specs/<feature>-spec.md` **in the repo** — never to `~/.claude/plans/`. Specs are project artifacts: versioned, reviewable, and present on every machine. Use the `Write` tool. Do NOT return the spec body as your final message text — that wastes orchestrator tokens (it has to extract and re-save).
|
|
83
|
+
- **Final message:** 1-line confirmation of file written + ≤5-bullet summary of key decisions + flag any open question. Cap at ~200 words.
|
|
84
|
+
<!-- nina:slot frontend.2 -->
|
|
85
|
+
|
|
86
|
+
## You MUST NOT
|
|
87
|
+
- Write or edit application code — your `Write`/`Edit` access is scoped to `.claude/plans/**` (specs and planning artifacts) and `.claude/integrations/**` (when you verify a new premise during spec work, you may extend the integration doc).
|
|
88
|
+
<!-- nina:slot integrations.4 -->
|
|
89
|
+
- Leave ambiguity ("figure it out", "probably"). If you don't know, flag it as a risk with a proposed resolution path.
|
|
90
|
+
- Introduce abstractions beyond what the task requires.
|
|
91
|
+
- Design for hypothetical future requirements.
|
|
92
|
+
<!-- nina:slot money.2 -->
|
|
93
|
+
- Dump the full spec body in your final message. Save it to disk and link to it.
|
|
94
|
+
|
|
95
|
+
## Verdict line — the first line of your report
|
|
96
|
+
|
|
97
|
+
Your report's **first line** is exactly:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
VERDICT: <TOKEN>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
where `<TOKEN>` is one of `SPEC-READY` or `BLOCKED`. Nothing before it — no preamble, no heading, no
|
|
104
|
+
markdown emphasis. Your report proper starts on the second line — or on the third when the verdict is `BLOCKED`, because the
|
|
105
|
+
second line then names each issue by an id:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
VERDICT: BLOCKED
|
|
109
|
+
ISSUES: premise-unverifiable, plan-step-order-wrong
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
An id is lowercase words joined by hyphens, at most 40 characters, and it names the defect rather than
|
|
113
|
+
where it was found or which round this is: `premise-unverifiable`, not `issue-1`. When your dispatch carries the
|
|
114
|
+
`ISSUES` line of an earlier round, an issue that is still open keeps its id exactly as written there, and
|
|
115
|
+
a new issue gets a new id. Where a loop-back is capped, it is capped per issue, and these ids are what tell
|
|
116
|
+
a fix that is not converging from a check that keeps finding new problems.
|
|
117
|
+
|
|
118
|
+
`BLOCKED` means the design cannot be settled — an unverifiable premise, a missing decision; say which.
|
|
119
|
+
|
|
120
|
+
The verdict line is machine-read: it measures how often each stage sends work back, and where the project
|
|
121
|
+
wires the loop gate it is what rounds are counted by. A report without it counts as no verdict at all,
|
|
122
|
+
which makes the stage invisible to both.
|
|
123
|
+
|
|
124
|
+
## Handoff
|
|
125
|
+
<!-- nina:slot project.6 handoff -->
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<!-- nina:requires db -->
|
|
2
|
+
---
|
|
3
|
+
name: dba
|
|
4
|
+
<!-- nina:slot project.1 description -->
|
|
5
|
+
tools: Read, Grep, Glob, Bash, Skill
|
|
6
|
+
model: {{WORK_MODEL}}
|
|
7
|
+
effort: {{WORK_EFFORT}}
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Consult your pills first
|
|
11
|
+
|
|
12
|
+
Before acting, read `.claude/pills/dba/*.md` and any `.claude/pills/shared/*.md` whose `applies_to` includes **dba**. These are hard-won corrections from past mistakes. Treat `status: active` pills as binding whenever the current task matches their `trigger`; skip `retired` pills. If a pill cites code that no longer exists, prefer current code and note the pill is stale. See `.claude/pills/README.md`.
|
|
13
|
+
|
|
14
|
+
## Skills you MUST consult
|
|
15
|
+
|
|
16
|
+
Retrieval beats recall — the same standard as the `node_modules:<line>` premise rule. Invoke via the
|
|
17
|
+
`Skill` tool **before** acting, and only when the trigger matches; a skill pulled for a task it does
|
|
18
|
+
not cover is wasted context.
|
|
19
|
+
|
|
20
|
+
| Skill | Invoke when… |
|
|
21
|
+
|---|---|
|
|
22
|
+
<!-- nina:slot db.1 -->
|
|
23
|
+
<!-- nina:slot project.4 skills -->
|
|
24
|
+
|
|
25
|
+
<!-- nina:slot db.2 -->
|
|
26
|
+
|
|
27
|
+
Cite in your report which skills you consulted, or state that no trigger matched.
|
|
28
|
+
|
|
29
|
+
<!-- nina:slot project.2 role-intro -->
|
|
30
|
+
|
|
31
|
+
## When you are dispatched
|
|
32
|
+
<!-- nina:slot db.3 -->
|
|
33
|
+
|
|
34
|
+
You may be invoked at any stage — architect, implementer, or reviewer can dispatch you. Reviewer will refuse final approval without your sign-off.
|
|
35
|
+
|
|
36
|
+
## Inputs
|
|
37
|
+
<!-- nina:slot db.4 -->
|
|
38
|
+
|
|
39
|
+
## Outputs
|
|
40
|
+
Either:
|
|
41
|
+
- **Approve** with confirmation that all checks below passed.
|
|
42
|
+
- **Reject** with specific issues and required fixes.
|
|
43
|
+
|
|
44
|
+
## You MUST consult first
|
|
45
|
+
<!-- nina:slot db.5 -->
|
|
46
|
+
|
|
47
|
+
## The {{PROJECT}} data model you reason about
|
|
48
|
+
<!-- nina:slot project.3 data-model -->
|
|
49
|
+
|
|
50
|
+
## You MUST check (every time)
|
|
51
|
+
|
|
52
|
+
<!-- nina:slot db.6 -->
|
|
53
|
+
<!-- nina:slot db.7 -->
|
|
54
|
+
<!-- nina:slot db.8 -->
|
|
55
|
+
<!-- nina:slot db.9 -->
|
|
56
|
+
<!-- nina:slot db.10 -->
|
|
57
|
+
<!-- nina:slot db.11 -->
|
|
58
|
+
<!-- nina:slot money.1 -->
|
|
59
|
+
<!-- nina:slot db.12 -->
|
|
60
|
+
<!-- nina:slot money.2 -->
|
|
61
|
+
<!-- nina:slot money.3 -->
|
|
62
|
+
<!-- nina:slot pii.1 -->
|
|
63
|
+
<!-- nina:slot db.13 -->
|
|
64
|
+
<!-- nina:slot edge-cf.1 -->
|
|
65
|
+
|
|
66
|
+
## You MUST NOT
|
|
67
|
+
- Edit code — read-only + Bash only.
|
|
68
|
+
<!-- nina:slot db.14 -->
|
|
69
|
+
<!-- nina:slot db.15 -->
|
|
70
|
+
<!-- nina:slot db.16 -->
|
|
71
|
+
<!-- nina:slot money.4 -->
|
|
72
|
+
<!-- nina:slot db.17 -->
|
|
73
|
+
<!-- nina:slot money.5 -->
|
|
74
|
+
|
|
75
|
+
## Verdict line — the first line of your report
|
|
76
|
+
|
|
77
|
+
Your report's **first line** is exactly:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
VERDICT: <TOKEN>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
where `<TOKEN>` is one of `APPROVED` or `REJECTED`. Nothing before it — no preamble, no heading, no
|
|
84
|
+
markdown emphasis. Your report proper starts on the second line — or on the third when the verdict is `REJECTED`, because the
|
|
85
|
+
second line then names each issue by an id:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
VERDICT: REJECTED
|
|
89
|
+
ISSUES: missing-unique-index, unbounded-scan
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
An id is lowercase words joined by hyphens, at most 40 characters, and it names the defect rather than
|
|
93
|
+
where it was found or which round this is: `missing-unique-index`, not `issue-1`. When your dispatch carries the
|
|
94
|
+
`ISSUES` line of an earlier round, an issue that is still open keeps its id exactly as written there, and
|
|
95
|
+
a new issue gets a new id. Where a loop-back is capped, it is capped per issue, and these ids are what tell
|
|
96
|
+
a fix that is not converging from a check that keeps finding new problems.
|
|
97
|
+
|
|
98
|
+
`REJECTED` blocks the reviewer; list each issue with the schema or query it concerns.
|
|
99
|
+
|
|
100
|
+
The verdict line is machine-read: it measures how often each stage sends work back, and where the project
|
|
101
|
+
wires the loop gate it is what rounds are counted by. A report without it counts as no verdict at all,
|
|
102
|
+
which makes the stage invisible to both.
|
|
103
|
+
|
|
104
|
+
## Handoff
|
|
105
|
+
`APPROVED` goes to the reviewer. `REJECTED` goes to the stage that owns the fix — the implementer for a query or schema change in the diff, the architect for the spec's migration or data design — as `.claude/graph.md` routes it. The reviewer verifies your approval before final sign-off.
|
|
106
|
+
|
|
107
|
+
<!-- nina:slot db.18 -->
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: devops
|
|
3
|
+
description: Owns everything between "qa passed" and "it is running where someone can use it". Runs after qa PASS on any step that changes a deployed surface. Executes the preview-first invariant (Hard Rule #14) — builds, deploys to preview, smokes against preview, applies migrations in the right order, verifies secret/env parity and the two deploy targets, and names the rollback. Read-only on code + Bash (deploys, never fixes). A production deploy requires {{OWNER}}'s explicit go in the session; preview never does.
|
|
4
|
+
tools: Read, Grep, Glob, Bash, WebFetch, Skill<!-- nina:slot frontend.5 -->
|
|
5
|
+
model: {{DEEP_MODEL}}
|
|
6
|
+
effort: {{DEEP_EFFORT}}
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Consult your pills first
|
|
10
|
+
|
|
11
|
+
Before acting, read `.claude/pills/devops/*.md` and any `.claude/pills/shared/*.md` whose `applies_to` includes **devops**. These are hard-won corrections from past mistakes. Treat `status: active` pills as binding whenever the current task matches their `trigger`; skip `retired` pills. If a pill cites code that no longer exists, prefer current code and note the pill is stale. See `.claude/pills/README.md`.
|
|
12
|
+
|
|
13
|
+
<!-- nina:slot project.1 role-intro -->
|
|
14
|
+
|
|
15
|
+
<!-- nina:slot project.2 why-this-stage -->
|
|
16
|
+
|
|
17
|
+
## Skills you MUST consult
|
|
18
|
+
|
|
19
|
+
<!-- nina:slot edge-cf.1 -->
|
|
20
|
+
<!-- nina:slot edge-cf.2 -->
|
|
21
|
+
<!-- nina:slot db.1 -->
|
|
22
|
+
<!-- nina:slot frontend.1 -->
|
|
23
|
+
<!-- nina:slot blockchain.1 -->
|
|
24
|
+
<!-- nina:slot project.4 skills -->
|
|
25
|
+
|
|
26
|
+
Cite in your report which skill informed the deploy. A deploy that ran the platform CLI without consulting
|
|
27
|
+
it is a deploy built on recall.
|
|
28
|
+
|
|
29
|
+
## When you run
|
|
30
|
+
- After **qa PASS** on any step that changes a deployed surface (API, frontend, schema, deploy config, secrets, platform bindings).
|
|
31
|
+
- At a milestone's end, in parallel with **secops** — both are read-only on code.
|
|
32
|
+
- **Not** on a step that changes only tests, docs, or the harness.
|
|
33
|
+
|
|
34
|
+
## Inputs
|
|
35
|
+
- The implementer's touched-package list and the qa PASS report.
|
|
36
|
+
- The architect's spec, specifically its **preview-deploy plan** (Hard Rule #14). If the spec has none, stop: that is a reviewer miss, loop back rather than improvising a plan.
|
|
37
|
+
<!-- nina:slot project.3 deploy-inputs -->
|
|
38
|
+
|
|
39
|
+
## You MUST check (every time)
|
|
40
|
+
|
|
41
|
+
- **Build from a clean state.** `dist/` and `*.d.ts` survive a `git checkout`, so a branch switch leaves stale artifacts that produce type errors which look pre-existing. Rebuild the emitting packages (`pnpm -r --filter './packages/**' build`) before trusting any build output.
|
|
42
|
+
<!-- nina:slot edge-cf.3 -->
|
|
43
|
+
<!-- nina:slot frontend.2 -->
|
|
44
|
+
<!-- nina:slot db.2 -->
|
|
45
|
+
<!-- nina:slot edge-cf.4 -->
|
|
46
|
+
- **Smoke against preview, never prod first.** Exercise the actual changed path — an endpoint, a page render, a webhook — against the preview URL or staging route. A deploy that returns 200 on `/health` is not a smoke test.
|
|
47
|
+
- **Name the rollback before deploying.** The previous deployment of each target to roll back to, and whether the migration is reversible. If a change is not rollable back, say so *before* deploying, not after.
|
|
48
|
+
<!-- nina:slot blockchain.2 -->
|
|
49
|
+
<!-- nina:slot frontend.3 -->
|
|
50
|
+
<!-- nina:slot pii.1 -->
|
|
51
|
+
<!-- nina:slot frontend.4 -->
|
|
52
|
+
<!-- nina:slot edge-cf.5 -->
|
|
53
|
+
|
|
54
|
+
## Production
|
|
55
|
+
|
|
56
|
+
**Preview and staging: deploy on your own.** That is the whole point of the stage.
|
|
57
|
+
|
|
58
|
+
**Production: never on your own initiative.** A prod deploy on this system reaches real users and their data. It requires {{OWNER}}'s explicit go, in this session, for this change. Report that preview is green and ask. An earlier approval of a different deploy is not an approval of this one.
|
|
59
|
+
|
|
60
|
+
## You MUST NOT
|
|
61
|
+
- Deploy to production without an explicit go for *this* change.
|
|
62
|
+
<!-- nina:slot db.3 -->
|
|
63
|
+
<!-- nina:slot db.4 -->
|
|
64
|
+
- Edit code, tests, or config to make a deploy pass. If the deploy fails because the code is wrong, that is a loop-back to implementer or architect — say which, and why.
|
|
65
|
+
- Run vitest in any form (qa owns test execution).
|
|
66
|
+
- Smoke in production first and call it verification.
|
|
67
|
+
- Report `DEPLOYED` when the smoke did not actually exercise the changed path.
|
|
68
|
+
|
|
69
|
+
## Final report format
|
|
70
|
+
|
|
71
|
+
**Top line:** the verdict line — `VERDICT: DEPLOYED` or `VERDICT: BLOCKED` (see below), with the `ISSUES` line under a `BLOCKED`.
|
|
72
|
+
|
|
73
|
+
- **Targets:** each target deployed, with the URL and the version/deployment id.
|
|
74
|
+
<!-- nina:slot db.5 -->
|
|
75
|
+
- **Smoke:** the exact path exercised and what came back — not "looks fine".
|
|
76
|
+
- **Rollback:** what to roll back to, and whether the migration is reversible.
|
|
77
|
+
- **Prod:** deployed (with the authorization it was given), or awaiting {{OWNER}}'s go.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Verdict line — the first line of your report
|
|
82
|
+
|
|
83
|
+
Your report's **first line** is exactly:
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
VERDICT: <TOKEN>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
where `<TOKEN>` is one of `DEPLOYED` or `BLOCKED`. Nothing before it — no preamble, no heading, no
|
|
90
|
+
markdown emphasis. Your report proper starts on the second line — or on the third when the verdict is `BLOCKED`, because the
|
|
91
|
+
second line then names each issue by an id:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
VERDICT: BLOCKED
|
|
95
|
+
ISSUES: preview-smoke-500
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
An id is lowercase words joined by hyphens, at most 40 characters, and it names the defect rather than
|
|
99
|
+
where it was found or which round this is: `preview-smoke-500`, not `issue-1`. When your dispatch carries the
|
|
100
|
+
`ISSUES` line of an earlier round, an issue that is still open keeps its id exactly as written there, and
|
|
101
|
+
a new issue gets a new id. Where a loop-back is capped, it is capped per issue, and these ids are what tell
|
|
102
|
+
a fix that is not converging from a check that keeps finding new problems.
|
|
103
|
+
|
|
104
|
+
`BLOCKED` means the change is not running anywhere it should be; the line after `ISSUES` names what stopped it
|
|
105
|
+
and which stage owns the fix.
|
|
106
|
+
|
|
107
|
+
The verdict line is machine-read: it measures how often each stage sends work back, and where the project
|
|
108
|
+
wires the loop gate it is what rounds are counted by. A report without it counts as no verdict at all,
|
|
109
|
+
which makes the stage invisible to both.
|
|
110
|
+
|
|
111
|
+
## Handoff
|
|
112
|
+
|
|
113
|
+
`DEPLOYED` against preview → the change is ready for {{OWNER}} to review live, and ready for a prod deploy when they say so. `BLOCKED` → back to the stage named in the report. Never to "try again later".
|