devrites 2.1.0 → 2.3.0
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/CHANGELOG.md +29 -0
- package/README.md +31 -17
- package/docs/architecture.md +30 -24
- package/docs/command-map.md +15 -6
- package/docs/flow.md +20 -6
- package/docs/orchestration.md +81 -0
- package/docs/skills.md +32 -8
- package/pack/.claude/agents/devrites-code-reviewer.md +40 -4
- package/pack/.claude/agents/devrites-devex-reviewer.md +94 -0
- package/pack/.claude/agents/devrites-forge-judge.md +92 -0
- package/pack/.claude/agents/devrites-frontend-reviewer.md +8 -0
- package/pack/.claude/agents/devrites-retrospector.md +91 -0
- package/pack/.claude/agents/devrites-security-auditor.md +21 -1
- package/pack/.claude/agents/devrites-slice-wright.md +18 -5
- package/pack/.claude/rules/README.md +7 -2
- package/pack/.claude/rules/afk-hitl.md +6 -0
- package/pack/.claude/rules/agents.md +30 -2
- package/pack/.claude/rules/anti-patterns.md +11 -0
- package/pack/.claude/rules/code-review.md +16 -6
- package/pack/.claude/rules/core.md +13 -4
- package/pack/.claude/rules/deprecation.md +50 -0
- package/pack/.claude/rules/developer-experience.md +119 -0
- package/pack/.claude/rules/observability.md +60 -0
- package/pack/.claude/rules/patterns.md +3 -0
- package/pack/.claude/rules/principles.md +158 -0
- package/pack/.claude/rules/security.md +31 -0
- package/pack/.claude/rules/spec-grammar.md +106 -0
- package/pack/.claude/skills/devrites-browser-proof/SKILL.md +42 -3
- package/pack/.claude/skills/devrites-lib/SKILL.md +9 -2
- package/pack/.claude/skills/devrites-lib/scripts/devrites.sh +8 -0
- package/pack/.claude/skills/devrites-lib/scripts/spec-validate.sh +130 -0
- package/pack/.claude/skills/rite-adopt/SKILL.md +13 -1
- package/pack/.claude/skills/rite-autocomplete/SKILL.md +3 -1
- package/pack/.claude/skills/rite-build/SKILL.md +36 -1
- package/pack/.claude/skills/rite-build/reference/anti-patterns.md +12 -0
- package/pack/.claude/skills/rite-build/reference/forge.md +171 -0
- package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +2 -0
- package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +22 -2
- package/pack/.claude/skills/rite-define/SKILL.md +14 -1
- package/pack/.claude/skills/rite-frame/SKILL.md +7 -2
- package/pack/.claude/skills/rite-learn/SKILL.md +17 -4
- package/pack/.claude/skills/rite-polish/SKILL.md +3 -1
- package/pack/.claude/skills/rite-prove/SKILL.md +40 -1
- package/pack/.claude/skills/rite-quick/SKILL.md +9 -4
- package/pack/.claude/skills/rite-review/SKILL.md +5 -2
- package/pack/.claude/skills/rite-review/reference/five-axis-review.md +15 -1
- package/pack/.claude/skills/rite-seal/SKILL.md +33 -4
- package/pack/.claude/skills/rite-ship/SKILL.md +21 -0
- package/pack/.claude/skills/rite-spec/SKILL.md +29 -5
- package/pack/.claude/skills/rite-spec/reference/spec-template.md +11 -1
- package/pack/.claude/skills/rite-status/SKILL.md +3 -1
- package/pack/.claude/skills/rite-vet/SKILL.md +46 -14
- package/package.json +1 -1
- package/scripts/check-cross-refs.py +4 -0
- package/scripts/run-behavioral-evals.sh +170 -0
- package/scripts/run-evals.sh +3 -0
- package/scripts/validate.sh +16 -7
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Forge — competing candidate builds for one slice
|
|
2
|
+
|
|
3
|
+
How `/rite-build` builds a slice that `/rite-vet` flagged `Forge: yes`: instead of one wright,
|
|
4
|
+
**K = 2–3 candidate wrights** each build the slice a genuinely different way in **isolation**, a
|
|
5
|
+
read-only judge scores them, and exactly **one** winner's diff lands in the working tree. Loaded
|
|
6
|
+
on demand by `/rite-build` step 3; the sibling of single-path
|
|
7
|
+
[`wright-dispatch.md`](wright-dispatch.md).
|
|
8
|
+
|
|
9
|
+
Forge is the **rare** path. Most slices are single-path (cheaper, and the default). A slice
|
|
10
|
+
forges only when the work is a genuine architecture fork — two or three approaches that actually
|
|
11
|
+
differ, no clear winner on paper, at high enough stakes that building the wrong one costs more
|
|
12
|
+
than building all of them. That judgment is made at `/rite-vet` and recorded as the slice's
|
|
13
|
+
`Forge:` field; build acts on the flag, it does not invent it.
|
|
14
|
+
|
|
15
|
+
## Why this doesn't break the single-writer invariant
|
|
16
|
+
|
|
17
|
+
DevRites forbids a parallel fan-out of writers **sharing one tree** — concurrent writers on one
|
|
18
|
+
working tree make conflicting implicit decisions and produce incoherent code
|
|
19
|
+
([`wright-dispatch.md`](wright-dispatch.md)). Forge keeps that invariant intact by **isolation**:
|
|
20
|
+
every candidate writes in its own worktree (or its own throwaway branch), never touching another
|
|
21
|
+
candidate's tree, and the orchestrator lands exactly one. No tree ever has two authors; exactly
|
|
22
|
+
one author's work ships. "N isolated complete attempts, winner-takes-all" is not "N writers on
|
|
23
|
+
one slice."
|
|
24
|
+
|
|
25
|
+
## Trust the flag, but clear a stale one
|
|
26
|
+
|
|
27
|
+
Before competing anything, confirm the flag still earns its cost — `/rite-vet` set it, but the
|
|
28
|
+
plan may have moved:
|
|
29
|
+
|
|
30
|
+
- **No objective scorecard** — the slice has no acceptance criteria and no `test-plan.md`
|
|
31
|
+
coverage the judge can score against → clear `Forge` to `no`, build single-path. A competition
|
|
32
|
+
with no rubric is a coin toss with K× the cost.
|
|
33
|
+
- **Can't name two genuinely different strategies** — if the candidates would be variations of
|
|
34
|
+
one approach, there is nothing to compete → single-path.
|
|
35
|
+
- **Slice shrank below the bar** (now Complexity ≤3, or a dependency landed that picks the
|
|
36
|
+
approach) → single-path.
|
|
37
|
+
|
|
38
|
+
A cleared flag is recorded in `decisions.md` (one line: why forge was dropped). Never forge a
|
|
39
|
+
slice you can't score, and never forge to avoid making a decision the plan already made.
|
|
40
|
+
|
|
41
|
+
## Mechanics
|
|
42
|
+
|
|
43
|
+
The orchestrator runs F1–F7. Steps 4–7 of the [one-slice-cycle](one-slice-cycle.md) (doubt,
|
|
44
|
+
fail-on-red, reconcile, record, stop) then run **unchanged** on the winner.
|
|
45
|
+
|
|
46
|
+
### F1 — Confirm the K strategies
|
|
47
|
+
Take the 2–3 candidate strategies `/rite-vet` named (in the slice brief). Each must be a
|
|
48
|
+
**distinct, complete approach** to the same slice contract — a different seam, data shape,
|
|
49
|
+
reuse-vs-build call, or algorithm — not a tweak of one. Name them `A`, `B`, (`C`) with a
|
|
50
|
+
one-line description each. K is capped at 3: a fourth candidate rarely changes the winner and
|
|
51
|
+
multiplies cost.
|
|
52
|
+
|
|
53
|
+
### F2 — Snapshot, then isolate each candidate
|
|
54
|
+
Snapshot the working tree first (the winner's landing is reconciled against it later), then give
|
|
55
|
+
each candidate its own isolated tree. **Prefer parallel isolated worktrees** when the harness can
|
|
56
|
+
dispatch a sub-agent with worktree isolation; the **always-available** path is one throwaway git
|
|
57
|
+
branch per candidate, built sequentially (slower, universally works — the
|
|
58
|
+
[`tooling.md`](../../../rules/tooling.md) "fallback is first-class" discipline):
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
SLUG="$(cat .devrites/ACTIVE 2>/dev/null)"
|
|
62
|
+
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || echo "(not a git repo — forge needs git for isolation; degrade to single-path)"
|
|
63
|
+
BASE="$(git rev-parse --abbrev-ref HEAD)"
|
|
64
|
+
# one isolated worktree per candidate (parallel-capable); falls back to branches if worktrees are unavailable
|
|
65
|
+
for C in A B; do
|
|
66
|
+
git worktree add ".devrites/work/$SLUG/forge/cand-$C" -b "forge/$SLUG/cand-$C" 2>/dev/null \
|
|
67
|
+
|| git branch "forge/$SLUG/cand-$C" "$BASE"
|
|
68
|
+
done
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### F3 — Dispatch K candidate wrights
|
|
72
|
+
Send **each** candidate the identical single-path slice contract from
|
|
73
|
+
[`wright-dispatch.md`](wright-dispatch.md), with **one** line added naming its assigned strategy
|
|
74
|
+
and its isolated tree:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
Forge candidate <A|B|C> of <K>. Build this slice using ONLY this approach:
|
|
78
|
+
Strategy: <the distinct approach, one or two sentences — the seam / data shape / reuse call>
|
|
79
|
+
Work in your isolated tree: <worktree path | branch name>. Do not consult or merge another
|
|
80
|
+
candidate's work. Same discipline as always — orient → RED → implement smallest complete →
|
|
81
|
+
verify → return your structured artifact. Code + tests only.
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Each is still **one wright, one tree** — the invariant holds per candidate. Parallel where the
|
|
85
|
+
harness isolates them; otherwise build candidate A to green, capture its diff, reset to `BASE`,
|
|
86
|
+
then candidate B. A candidate that hits an irreversible-risk item escalates exactly as a
|
|
87
|
+
single-path wright does — **forge never bypasses a gate** (see AFK below).
|
|
88
|
+
|
|
89
|
+
### F4 — Judge (read-only, fresh context)
|
|
90
|
+
Dispatch [`devrites-forge-judge`](../../../agents/devrites-forge-judge.md) with the K finished
|
|
91
|
+
candidate diffs and the scorecard inputs (slice acceptance, `test-plan.md`, `.devrites/principles.md`,
|
|
92
|
+
the anti-slop charter). It scores each candidate, ranks them, names the **winner** and the
|
|
93
|
+
specific runner-up ideas worth grafting, and returns the structured verdict. The judge **never
|
|
94
|
+
writes code** — it reads the diffs and returns findings, like every reviewer agent. If sub-agent
|
|
95
|
+
dispatch is unavailable, do the judge's rubric pass yourself in a fresh read, discarding your
|
|
96
|
+
authoring reasoning (a flagged fallback, not an independent judgment).
|
|
97
|
+
|
|
98
|
+
### F5 — Land the winner, graft sparingly
|
|
99
|
+
Apply **only** the winner's diff to the working tree (merge its worktree / cherry-pick its
|
|
100
|
+
branch). If the judge named a cheap, specific improvement in a runner-up, graft it by
|
|
101
|
+
**continuing the winning wright once** with that instruction — never hand-merge two candidates'
|
|
102
|
+
code (that re-creates the incoherent-tree failure the invariant exists to prevent). The landed
|
|
103
|
+
tree has exactly one author: the winner (plus its own grafted follow-up).
|
|
104
|
+
|
|
105
|
+
### F6 — Write `forge-report.md`
|
|
106
|
+
The durable record of the competition (template below). One per forged slice; archived with the
|
|
107
|
+
feature.
|
|
108
|
+
|
|
109
|
+
### F7 — Clean up, then return to the cycle
|
|
110
|
+
Remove the losing worktrees / delete the candidate branches:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
SLUG="$(cat .devrites/ACTIVE 2>/dev/null)"
|
|
114
|
+
for C in A B; do
|
|
115
|
+
git worktree remove ".devrites/work/$SLUG/forge/cand-$C" --force 2>/dev/null || true
|
|
116
|
+
git branch -D "forge/$SLUG/cand-$C" 2>/dev/null || true
|
|
117
|
+
done
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Then hand the **winner's** structured artifact to [one-slice-cycle](one-slice-cycle.md) step 4 as
|
|
121
|
+
if a single wright produced it. Doubt, fail-on-red, reconcile (against the F2 snapshot, claimed =
|
|
122
|
+
the winner's files), record, and stop all run unchanged.
|
|
123
|
+
|
|
124
|
+
## `forge-report.md` template
|
|
125
|
+
|
|
126
|
+
```markdown
|
|
127
|
+
# Forge report: <slice id — name>
|
|
128
|
+
Forged on <iso>. Reason: <the architecture fork /rite-vet flagged>.
|
|
129
|
+
|
|
130
|
+
## Candidates
|
|
131
|
+
| # | Strategy | Gates | Score | Notes |
|
|
132
|
+
|---|---|---|---|---|
|
|
133
|
+
| A | <approach> | green/red | <judge score> | <one line> |
|
|
134
|
+
| B | <approach> | green/red | <judge score> | <one line> |
|
|
135
|
+
|
|
136
|
+
## Verdict
|
|
137
|
+
Winner: <A|B|C> — <why it won, in the judge's terms: acceptance coverage, simplicity, principle
|
|
138
|
+
fit, anti-slop, reuse>.
|
|
139
|
+
Grafted from runner-up: <specific idea + which candidate | none>.
|
|
140
|
+
Discarded: <the losing approaches + the one-line reason each lost — load-bearing for a later
|
|
141
|
+
slice that might be tempted to retry one>.
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The **Discarded** section matters: it is a dead-end record at the slice level, the same role
|
|
145
|
+
`decisions.md` "Dead ends" plays for the feature — a later slice shouldn't re-litigate an
|
|
146
|
+
approach forge already rejected.
|
|
147
|
+
|
|
148
|
+
## AFK & budget
|
|
149
|
+
|
|
150
|
+
- **Cost.** Forge multiplies the build by K. Under `.devrites/AFK`, each candidate counts against
|
|
151
|
+
the slice budget (`tick-afk.sh` once per candidate dispatched), so a forge slice can exhaust the
|
|
152
|
+
cap faster — that is intended back-pressure, not a bug.
|
|
153
|
+
- **Gates are unchanged.** Forge changes *how many candidates build*, never *what pauses*. An
|
|
154
|
+
irreversible-risk item, a blocking/escalating gate, or a red-on-completion in **any** candidate
|
|
155
|
+
pauses per [`afk-hitl.md`](../../../rules/afk-hitl.md) exactly as single-path. AFK widens what is
|
|
156
|
+
automatic, never what is irreversible — forge included.
|
|
157
|
+
- **Stuck loop still applies.** Re-dispatching the same candidate without progress trips
|
|
158
|
+
`stuck.sh` the same as a single wright.
|
|
159
|
+
|
|
160
|
+
## When isolation is impossible
|
|
161
|
+
|
|
162
|
+
No git, or neither worktrees nor throwaway branches are usable → **degrade to single-path** and
|
|
163
|
+
say so. Forge is an accelerator for choosing between real alternatives; it is never a requirement
|
|
164
|
+
for building the slice. A slice always has a single-path build available — the competition is the
|
|
165
|
+
optional part.
|
|
166
|
+
|
|
167
|
+
## Anti-patterns
|
|
168
|
+
|
|
169
|
+
See [`anti-patterns.md`](anti-patterns.md) § Forge — the short version: don't forge a decided or
|
|
170
|
+
trivial slice, don't forge to dodge a decision, don't hand-merge candidates, don't exceed K=3,
|
|
171
|
+
and don't let a forged slice skip the post-return doubt because "the judge already looked."
|
|
@@ -9,6 +9,8 @@ The orchestrator (`/rite-build`) gates and records; the **wright** writes. See
|
|
|
9
9
|
```
|
|
10
10
|
SELECT → orchestrator: restate slice goal + acceptance + scope boundary; HITL gate (pause pre-code)
|
|
11
11
|
(SHAPE) → orchestrator: if UI and no design-brief.md, shape it (devrites-ux-shape) before dispatch
|
|
12
|
+
(FORGE) → orchestrator: if slice is Forge: yes, compete K=2–3 isolated candidate wrights →
|
|
13
|
+
devrites-forge-judge → land one winner → forge-report.md, then continue at DOUBT (forge.md)
|
|
12
14
|
DISPATCH → hand the slice contract to devrites-slice-wright (fresh context). Inside the wright:
|
|
13
15
|
ORIENT → load only the files this slice touches; learn the project's idiom; reuse-first
|
|
14
16
|
(RED) → if behavior change: write the failing test first
|
|
@@ -16,8 +16,11 @@ The orchestrator's window is full of spec investigation, planning, prior slices,
|
|
|
16
16
|
output — the exact "lost-in-the-middle" load that degrades instruction-following and pulls the
|
|
17
17
|
model toward generic code. The wright starts clean and sees only the contract, so it holds the
|
|
18
18
|
slice boundary strictly and writes to the *project's* idiom instead of drifting. Single-threaded
|
|
19
|
-
by design: **one** wright per slice, never a parallel fan-out of writers
|
|
20
|
-
make conflicting implicit decisions and produce incoherent
|
|
19
|
+
by design: **one** wright per slice, never a parallel fan-out of writers *sharing a tree* —
|
|
20
|
+
concurrent writers on one working tree make conflicting implicit decisions and produce incoherent
|
|
21
|
+
code. The one sanctioned exception is a **forge** slice, which competes K candidates in *isolated*
|
|
22
|
+
worktrees and lands exactly one — no tree ever has two authors, so the invariant holds (see
|
|
23
|
+
[Forge](#forge--competing-candidates-the-deliberate-exception)).
|
|
21
24
|
|
|
22
25
|
## The contract `/rite-build` sends
|
|
23
26
|
One `Task` call to `devrites-slice-wright` carrying everything the writer needs and nothing it
|
|
@@ -91,6 +94,23 @@ set.
|
|
|
91
94
|
[`evidence-standard.md`](evidence-standard.md). Evidence is the wright's real command output,
|
|
92
95
|
not its say-so. Then tick AFK if `.devrites/AFK` is present (`tick-afk.sh`; exit 3 → STOP).
|
|
93
96
|
|
|
97
|
+
## Forge — competing candidates (the deliberate exception)
|
|
98
|
+
|
|
99
|
+
The single-writer rule forbids parallel writers **sharing one tree**. A `Forge: yes` slice
|
|
100
|
+
(flagged by `/rite-vet` as a genuine architecture fork at Complexity ≥4) is the one sanctioned
|
|
101
|
+
fan-out, and it keeps the rule intact by **isolation**: each candidate wright works in its own
|
|
102
|
+
`git worktree`, sees the identical slice contract plus one **distinct strategy**, and never
|
|
103
|
+
touches another candidate's tree. A read-only [`devrites-forge-judge`](../../../agents/devrites-forge-judge.md)
|
|
104
|
+
then scores the finished candidates against acceptance + `test-plan.md` + `.devrites/principles.md`
|
|
105
|
+
+ the anti-slop charter, and the orchestrator lands **exactly one** winner's diff in the working
|
|
106
|
+
tree. No tree ever has two authors; exactly one author's work ships. Everything downstream (doubt,
|
|
107
|
+
fail-on-red, reconcile against the winner's claimed set, record) runs on the winner as if a single
|
|
108
|
+
wright had built it.
|
|
109
|
+
|
|
110
|
+
Full mechanics — strategy derivation, worktree setup, the judge contract, landing + grafting the
|
|
111
|
+
winner, `forge-report.md`, AFK budgeting, and the worktree-unavailable fallback — live in
|
|
112
|
+
[`forge.md`](forge.md).
|
|
113
|
+
|
|
94
114
|
## Fallback
|
|
95
115
|
If the `Task` tool / sub-agent dispatch is unavailable, `/rite-build` runs the wright's
|
|
96
116
|
discipline **inline** in its own context and flags it as a fallback (no clean-context benefit).
|
|
@@ -17,6 +17,7 @@ nothing gets missed in one batch. **No code here.**
|
|
|
17
17
|
as their first step; the other rule files load on demand. Pull these via `Read` when shaping
|
|
18
18
|
the plan:
|
|
19
19
|
- `development-workflow.md` — small batches, trunk-always-green, definition of done.
|
|
20
|
+
- `principles.md` — the project invariants (`.devrites/principles.md`) the chosen approach must conform to.
|
|
20
21
|
- `documentation.md` — record plan-time decisions and rationale.
|
|
21
22
|
|
|
22
23
|
## Operating rules
|
|
@@ -90,6 +91,12 @@ the plan:
|
|
|
90
91
|
```
|
|
91
92
|
5. **Complexity & deviations gate** — justify anything off DevRites defaults (new dep,
|
|
92
93
|
extra abstraction, second design system) in the plan; if you can't justify it, simplify.
|
|
94
|
+
**Principles conformance:** read `.devrites/principles.md` (if present) and confirm the
|
|
95
|
+
approach honors every declared invariant. A plan that conflicts with one is not "a deviation
|
|
96
|
+
to justify away" — either reshape the approach to conform, or, when the conflict is genuine and
|
|
97
|
+
intended, route it through the Spec Drift Guard plus a recorded decision and a scoped principle
|
|
98
|
+
exception a human approves. Never ready a plan that silently violates an invariant. (Re-scored
|
|
99
|
+
as a blocking gate at `/rite-vet`; no file → none declared → nothing to check.)
|
|
93
100
|
6. **Write** `plan.md` + `tasks.md`; update `state.md` (phase: plan → next `/rite-build`).
|
|
94
101
|
7. **Readiness gate** (bottom of plan-template): every acceptance criterion covered by a
|
|
95
102
|
slice, dependency order acyclic + risk-first, no unjustified deviation, rollback for
|
|
@@ -105,6 +112,9 @@ Goal:
|
|
|
105
112
|
Satisfies: AC-n[, AC-m] # reverse traceability — which spec acceptance criteria this slice satisfies
|
|
106
113
|
Acceptance criteria: # which spec FR/criteria this satisfies
|
|
107
114
|
Complexity: N/5 — <reason> # 1=trivial … 5=hairy; >3 triggers a reslice unless the reason justifies it
|
|
115
|
+
Forge: no | yes — <reason> # default no. Propose yes ONLY when Complexity ≥4 AND the slice has ≥2 genuinely-viable
|
|
116
|
+
# approaches with no clear winner (an architecture fork, not just "hard"). /rite-vet confirms
|
|
117
|
+
# or clears it; /rite-build then competes K isolated candidates and keeps one. See rite-build/reference/forge.md.
|
|
108
118
|
Mode: AFK | HITL # AFK = implementable + mergeable without human gating;
|
|
109
119
|
# HITL = needs a human decision mid-slice (design call,
|
|
110
120
|
# architectural choice, destructive migration sign-off).
|
|
@@ -139,7 +149,10 @@ Evidence required:
|
|
|
139
149
|
> coverage. Keep `Blocked by` cycle-free. `depends_on` is the machine-readable mirror tools read
|
|
140
150
|
> to pick the next *buildable* slice; `Complexity` (>3 → reslice) sizes it; `Satisfies` +
|
|
141
151
|
> `Consumes/Produces` + `Known-Gotchas` + `Validation commands` make each slice a self-contained,
|
|
142
|
-
> one-pass-implementable brief (the PRP target `/rite-vet` checks).
|
|
152
|
+
> one-pass-implementable brief (the PRP target `/rite-vet` checks). `Forge` flags the rare slice
|
|
153
|
+
> worth *competing* — a genuine architecture fork at high complexity, not a slice that is merely
|
|
154
|
+
> hard. Define only proposes it; `/rite-vet` confirms or clears it and `/rite-build` acts on it.
|
|
155
|
+
> The bulk of slices stay `no` (single-path is cheaper and the default).
|
|
143
156
|
|
|
144
157
|
> **Mid-flight discipline.** When tempted to skip vertical slicing, coverage mapping, or dependency-order discipline — see [`anti-patterns`](reference/anti-patterns.md) (Common Rationalizations + Red Flags). Load it the moment you reach for the excuse.
|
|
145
158
|
|
|
@@ -77,6 +77,9 @@ map + worked examples: [`reference/failure-modes.md`](reference/failure-modes.md
|
|
|
77
77
|
- [ ] **4 · Unverifiable goal** — is there a command that proves this, run, with output? Or am
|
|
78
78
|
I asserting "it works"? Tautological test that can't fail? → run the FRAME verify command;
|
|
79
79
|
record command + output (`testing.md`, evidence-over-confidence).
|
|
80
|
+
- [ ] **Principle check** — if `.devrites/principles.md` exists, does the change break a declared
|
|
81
|
+
invariant? A violation with no recorded, human-approved exception is a **Critical** — the
|
|
82
|
+
express lane is not a way around a project gate; escalate it, don't ship it (`principles.md`).
|
|
80
83
|
|
|
81
84
|
The test for each changed line: **it traces directly to the criterion, and the criterion can
|
|
82
85
|
be proven false.** A line that fails either is a finding.
|
|
@@ -85,8 +88,10 @@ be proven false.** A line that fails either is a finding.
|
|
|
85
88
|
|
|
86
89
|
If FRAME can't produce a falsifiable criterion, or AUDIT surfaces a mode-1 / mode-3 issue that
|
|
87
90
|
is actually a hidden design decision (new dependency, data model, second design system, an
|
|
88
|
-
auth/migration/public-API touch)
|
|
89
|
-
|
|
91
|
+
auth/migration/public-API touch), or a **declared-principle violation** with no recorded
|
|
92
|
+
exception → **STOP and route to `/rite-spec`** (a needed exception is a human-approved decision,
|
|
93
|
+
not an inline call). Same drift guard the express lane enforces — don't quietly grow an unframed
|
|
94
|
+
ask into unreviewed work.
|
|
90
95
|
|
|
91
96
|
## Rules
|
|
92
97
|
- Self-applied and inline. No subagent, no `.devrites/` workspace required. For an adversarial
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rite-learn
|
|
3
|
-
description: Review the auto-captured learning ledger and promote recurring lessons to project rules — the human-gated half of the cross-feature learning loop. Capture is automatic (`/rite-seal` appends dismissed-finding classes + dead-ends to `.devrites/learnings.md` on every GO; the review skills load it before a fan-out), so the system learns without a command; this skill mines that ledger across features and decides which recurring lessons graduate into a rule (propose, don't impose). Use when the user says "what have we learned", "rite learn", "harvest lessons", "promote our learnings", or after several features ship. Not for the install (`/rite-doctor`), feature status (`/rite-status`), onboarding (`/rite-adopt`), or a diff review (`/rite-review`).
|
|
3
|
+
description: Review the auto-captured learning ledger and promote recurring lessons to project rules or principles — the human-gated half of the cross-feature learning loop. Capture is automatic (`/rite-seal` appends dismissed-finding classes + dead-ends to `.devrites/learnings.md` on every GO; the review skills load it before a fan-out), so the system learns without a command; this skill mines that ledger across features and decides which recurring lessons graduate into a rule (propose, don't impose). Use when the user says "what have we learned", "rite learn", "harvest lessons", "promote our learnings", or after several features ship. Not for the install (`/rite-doctor`), feature status (`/rite-status`), onboarding (`/rite-adopt`), or a diff review (`/rite-review`).
|
|
4
4
|
argument-hint: "[--mine | \"<lesson to record>\"]"
|
|
5
5
|
user-invocable: true
|
|
6
6
|
disable-model-invocation: true
|
|
@@ -45,6 +45,11 @@ it never edits source or rule files on its own.
|
|
|
45
45
|
you could swap onto any project says nothing).
|
|
46
46
|
3. **Classify each candidate** into its durable home:
|
|
47
47
|
- **project rule** — a craft/standard that belongs in a `.claude/rules/*` file or `CLAUDE.md`.
|
|
48
|
+
- **project principle** — a recurring correction that is really a *non-negotiable invariant*
|
|
49
|
+
(not just an idiom or a craft standard): graduate it to `.devrites/principles.md`
|
|
50
|
+
([`principles.md`](../../rules/principles.md)). This is the **trusted, gating** layer — higher
|
|
51
|
+
stakes than a rule — so `/rite-learn` **drafts** the principle + a dated Governance entry for
|
|
52
|
+
the human to confirm; it never writes a principle silently.
|
|
48
53
|
- **conventions-ledger entry** — a proven project idiom for `.devrites/conventions.md`.
|
|
49
54
|
- **dismissed-finding class** — a pattern reviewers keep flagging that is *intentional here*;
|
|
50
55
|
recording it stops the recurring false positive (`learnings.md`, loaded pre-fan-out).
|
|
@@ -53,9 +58,12 @@ it never edits source or rule files on its own.
|
|
|
53
58
|
times, the proposed home) via `AskUserQuestion` — the human picks which to promote. Never
|
|
54
59
|
promote a lesson to a rule silently; an unproven "lesson" hardened into a rule is its own slop.
|
|
55
60
|
5. **Record the accepted.** For each the user accepts, append it with `learnings.sh add <slug>
|
|
56
|
-
"<lesson>" <tag>` (`tag` ∈ `rule | convention | dismiss`). If the user approves a **rule
|
|
57
|
-
**ledger** promotion, draft the exact edit and let the user confirm it through
|
|
58
|
-
— `/rite-learn` writes the ledger, not the rule files.
|
|
61
|
+
"<lesson>" <tag>` (`tag` ∈ `rule | convention | dismiss`). If the user approves a **rule**,
|
|
62
|
+
**principle**, or **ledger** promotion, draft the exact edit and let the user confirm it through
|
|
63
|
+
the normal flow — `/rite-learn` writes the ledger, not the rule or principle files. A
|
|
64
|
+
**principle** promotion is the highest-stakes of these: draft the `.devrites/principles.md` entry
|
|
65
|
+
**plus its dated Governance line**, and let the human confirm before it lands — a principle is a
|
|
66
|
+
gate, so it is amended deliberately, never auto-written. Then `touch .devrites/.learnings-reviewed`
|
|
59
67
|
so the SessionStart learnings nudge snoozes until new signal accumulates.
|
|
60
68
|
|
|
61
69
|
## How the ledger is used
|
|
@@ -66,6 +74,11 @@ convention** raises the bar. The ledger is an **untrusted prior** — a fresh ob
|
|
|
66
74
|
live code always overrides a ledger entry (see `.claude/rules/security.md`). Confidence in a
|
|
67
75
|
recorded lesson never raises its authority.
|
|
68
76
|
|
|
77
|
+
A **project principle** (`.devrites/principles.md`) is the opposite layer — prescriptive,
|
|
78
|
+
trusted, and **gating**. Promoting a lesson there is a deliberate amendment, not a prior the next
|
|
79
|
+
fan-out can override: a violation becomes a blocking finding, not a suppressed false positive.
|
|
80
|
+
That asymmetry is why principle promotion is human-confirmed and dated, never auto-written.
|
|
81
|
+
|
|
69
82
|
## Gotchas
|
|
70
83
|
- Evidence first: a lesson without ≥2 real occurrences is speculation. Cite the features.
|
|
71
84
|
- Don't pad the ledger. Five real lessons that change behaviour beat thirty rubber-stamped rows.
|
|
@@ -49,7 +49,9 @@ don't load both up front.
|
|
|
49
49
|
4. **If UI scope detected** read [`reference/ui.md`](reference/ui.md), and read
|
|
50
50
|
`design-brief.md` if present (the UX/UI contract `devrites-ux-shape` shaped at spec and
|
|
51
51
|
`devrites-frontend-craft` refined while building) so the polish honors the agreed
|
|
52
|
-
direction + states.
|
|
52
|
+
direction + states. **Read the `## Visual Verdict` table in `browser-evidence.md` if present:
|
|
53
|
+
its `FAIL` and `PARTIAL` rows are the normalize/quality-bar worklist** — fix the root cause of
|
|
54
|
+
each (a missing state, an off-token CTA, an anti-slop hit), don't decorate around it. Then run
|
|
53
55
|
**Phase 3 (normalize)** → **Phase 4 (UI polish)**. Honor argument modes:
|
|
54
56
|
- `bolder | quieter | distill | harden` — passed to Phase 4 as the
|
|
55
57
|
emphasis dial.
|
|
@@ -36,7 +36,14 @@ the affected criteria/routes to refresh proof before `/rite-seal`.
|
|
|
36
36
|
**Step 0:** Read `.claude/rules/core.md` first. The other rule files load on demand;
|
|
37
37
|
pull these via `Read` when relevant:
|
|
38
38
|
- `testing.md` — pyramid, determinism, no-flake discipline.
|
|
39
|
+
- `spec-grammar.md` — when the spec uses structured `### Requirement:` / `#### Scenario:`
|
|
40
|
+
blocks, each scenario (WHEN/THEN) is one observable behavior to walk and prove.
|
|
39
41
|
- `performance.md` — measure first when perf is in scope.
|
|
42
|
+
- `observability.md` — when the change has a runtime surface (endpoint, job, integration,
|
|
43
|
+
user flow): telemetry must be present **and observed to emit**, not assumed.
|
|
44
|
+
- `developer-experience.md` — when the change ships a developer-facing surface (API / CLI / SDK /
|
|
45
|
+
webhook / config / error messages / getting-started): **measure** the DX scorecard (run the flow,
|
|
46
|
+
time time-to-hello-world, capture the verbatim error text), don't assert it.
|
|
40
47
|
|
|
41
48
|
## Operating rules
|
|
42
49
|
- Evidence over confidence. Feature scope only — fix within the feature or record a
|
|
@@ -69,7 +76,19 @@ pull these via `Read` when relevant:
|
|
|
69
76
|
(`devrites-browser-proof`): routes, viewports, screenshots (opened + described),
|
|
70
77
|
console, network, interaction paths, and design-reference match if references exist.
|
|
71
78
|
5. **Map results to acceptance** — walk `spec.md` acceptance criteria; note which are now
|
|
72
|
-
proven and which aren't. If
|
|
79
|
+
proven and which aren't. **If the spec uses the structured grammar** (`### Requirement:` /
|
|
80
|
+
`#### Scenario:` blocks — `spec-grammar.md`), walk it **per scenario**: each `#### Scenario:`
|
|
81
|
+
WHEN/THEN is one observable behavior that needs a passing asserting test (the WHEN is the
|
|
82
|
+
arrange, the THEN the assert). A scenario with no covering result is an unproven gap =
|
|
83
|
+
blocker, the same standing as an uncovered acceptance criterion. Re-run the grammar gate
|
|
84
|
+
first so a requirement hand-edited to malformed since `/rite-spec` can't masquerade as proven:
|
|
85
|
+
```bash
|
|
86
|
+
SV=.claude/skills/devrites-lib/scripts/spec-validate.sh
|
|
87
|
+
[ -f "$SV" ] || SV="${CLAUDE_SKILL_DIR:-}/../devrites-lib/scripts/spec-validate.sh"
|
|
88
|
+
[ -f "$SV" ] || SV=pack/.claude/skills/devrites-lib/scripts/spec-validate.sh
|
|
89
|
+
[ -f "$SV" ] && { bash "$SV" ".devrites/work/<slug>"; echo "spec-validate rc=$?"; } || true
|
|
90
|
+
```
|
|
91
|
+
If `test-plan.md` exists, also walk its acceptance→test map and
|
|
73
92
|
per-gap requirements — a planned test (especially a regression-Critical) with no covering
|
|
74
93
|
result is an unproven gap, not a pass. **Also walk the test-plan interaction inventory**
|
|
75
94
|
(every interactive element + user flow): each must have a passing asserting test. An
|
|
@@ -97,6 +116,24 @@ pull these via `Read` when relevant:
|
|
|
97
116
|
example tests miss the edge cases these explore. If the same unit regenerated from a paraphrased
|
|
98
117
|
spec (or a second sample) **diverges in behaviour on shared inputs**, treat that as a low-confidence
|
|
99
118
|
signal: under AFK it blocks an auto-GO and routes to HITL.
|
|
119
|
+
5b. **Observability check (runtime surface only).** If the feature added an endpoint, job,
|
|
120
|
+
queue consumer, external integration, user-facing flow, or a new error path, apply the
|
|
121
|
+
on-call test (`observability.md`): are the signals needed to debug a prod failure present —
|
|
122
|
+
structured logs on the failure path, a metric/counter on errors, a trace id across any
|
|
123
|
+
boundary? Then **observe them fire**: trigger the path and confirm the log line / metric /
|
|
124
|
+
span actually emits, and record that observation in `evidence.md`. Instrumentation never seen
|
|
125
|
+
emitting is unproven, not done. Skip entirely for pure-internal / docs / config / type-only
|
|
126
|
+
changes — don't instrument a typo fix.
|
|
127
|
+
5c. **Developer-experience measure (developer-facing surface only).** If the feature ships a public
|
|
128
|
+
API, CLI, SDK/library, webhook, config/env contract, error/exit path, or the getting-started flow
|
|
129
|
+
(`developer-experience.md`), **exercise it** rather than reading it: run the getting-started steps
|
|
130
|
+
on a clean state and **time time-to-hello-world**; invoke the CLI `--help` / call the endpoint /
|
|
131
|
+
import the package; trigger the failure path and capture the **verbatim** error text. For a docs or
|
|
132
|
+
quickstart page, capture it through the browser-proof ladder (`devrites-browser-proof`) and describe
|
|
133
|
+
the screenshot. Write the **measured** scorecard to `devex.md` (beside the `/rite-vet` prediction the
|
|
134
|
+
boomerang reconciles at `/rite-seal`) and the headline numbers + error strings to `evidence.md`. A
|
|
135
|
+
scorecard from "the code looks fine" is Source mode, not proof. Skip entirely when no developer-facing
|
|
136
|
+
surface is in scope — don't DX-measure an internal refactor.
|
|
100
137
|
6. **On failure** → [failure-triage](reference/failure-triage.md) +
|
|
101
138
|
`devrites-debug-recovery`. Reproduce → isolate → fix within scope → re-run; if a fix
|
|
102
139
|
would exceed scope, record a blocker.
|
|
@@ -110,9 +147,11 @@ pull these via `Read` when relevant:
|
|
|
110
147
|
```
|
|
111
148
|
Proved: <feature>
|
|
112
149
|
Acceptance criteria proven: <n / total>
|
|
150
|
+
Scenarios proven: <n / total | n/a (flat acceptance)>
|
|
113
151
|
Tests: <cmd → pass/fail (counts)>
|
|
114
152
|
Build: <cmd → pass/fail> Lint: <cmd → pass/fail>
|
|
115
153
|
Browser: <ladder rung used + summary | n/a>
|
|
154
|
+
DevEx: <measured TTHW + getting-started/error-message verdict → devex.md | n/a (no dev-facing surface)>
|
|
116
155
|
Unresolved failures / blockers: <none | list>
|
|
117
156
|
Next: /rite-polish (finish the feature → /rite-review → /rite-seal)
|
|
118
157
|
↻ Hygiene: /clear before /rite-polish (evidence.md + browser-evidence.md captured; debug trails noisy). See rules/context-hygiene.md.
|
|
@@ -23,6 +23,9 @@ express lane:**
|
|
|
23
23
|
- **Ambiguous scope** — you'd have to guess what "done" means, or the ask hides a design
|
|
24
24
|
decision (data model, new dependency, second design system).
|
|
25
25
|
- Security-sensitive input handling, or a measurable performance-critical path.
|
|
26
|
+
- Would **break a declared project principle** (`.devrites/principles.md`) with no recorded,
|
|
27
|
+
human-approved exception — the express lane never relaxes a project gate; a needed exception is
|
|
28
|
+
a deliberate human decision, so route it to `/rite-spec`.
|
|
26
29
|
|
|
27
30
|
If none hold, the change is small + reversible + unambiguous → proceed. **When in doubt,
|
|
28
31
|
escalate** — the cost of the full lifecycle on a small change is minutes; the cost of the
|
|
@@ -34,6 +37,7 @@ Read `.claude/rules/core.md` first. Then the small set this lane actually needs:
|
|
|
34
37
|
- `testing.md` — TDD, **completeness** (every touched behavior/element asserted) +
|
|
35
38
|
**assertion strength** (no tautological tests; see it fail first), scaled to the change.
|
|
36
39
|
- `error-handling.md` / `security.md` — only if the change touches input/errors.
|
|
40
|
+
- `principles.md` — when `.devrites/principles.md` exists; a change that breaks an invariant is a gate, not a quick fix.
|
|
37
41
|
|
|
38
42
|
## Workflow
|
|
39
43
|
0. **Orient.** Read `core.md`. If a `.devrites/` workspace is active, run the preamble to
|
|
@@ -53,10 +57,11 @@ Read `.claude/rules/core.md` first. Then the small set this lane actually needs:
|
|
|
53
57
|
4. **Prove (scoped).** Run the **targeted** tests + typecheck / lint for what changed (not
|
|
54
58
|
the whole suite) → green. Record the command + output. A tautological test that can't
|
|
55
59
|
fail is not proof.
|
|
56
|
-
5. **Review-lite + ship.** Self-review the diff (correctness, scope, idiom —
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
5. **Review-lite + ship.** Self-review the diff (correctness, scope, idiom, and — if
|
|
61
|
+
`.devrites/principles.md` exists — no declared invariant broken; this is `/rite-frame`'s AUDIT
|
|
62
|
+
pass — one pass, no subagent fan-out). Show the diff, then on the user's confirm commit it
|
|
63
|
+
(Conventional Commits, atomic) — or hand to `/rite-ship` if a workspace is active. **Never push
|
|
64
|
+
without the user asking.**
|
|
60
65
|
|
|
61
66
|
## Escalation (mid-flight) — the Spec Drift Guard still applies
|
|
62
67
|
If the "small" change turns out to be not small — a second slice appears, a real design
|
|
@@ -21,6 +21,7 @@ if none, tell the user to run `/rite-spec <feature>`.
|
|
|
21
21
|
**Step 0:** Read `.claude/rules/core.md` first. The other rule files load on demand;
|
|
22
22
|
pull these via `Read` when the diff demands them:
|
|
23
23
|
- `code-review.md` — small PRs, severity labels, tests-first review focus.
|
|
24
|
+
- `principles.md` — declared project invariants (`.devrites/principles.md`); a diff that violates one with no recorded exception is a Critical, blocking finding.
|
|
24
25
|
- `testing.md` — confirm the tests prove the spec, not just pass.
|
|
25
26
|
- `agents.md` — when to fan out to which review subagent.
|
|
26
27
|
- `security.md` — when input / auth / data / integrations / secrets are in scope.
|
|
@@ -48,7 +49,8 @@ pull these via `Read` when the diff demands them:
|
|
|
48
49
|
[ -f "$P" ] && bash "$P" || echo "(orientation preamble unavailable on this install — read state.md directly to orient)"
|
|
49
50
|
```
|
|
50
51
|
1. Read `spec.md`, `tasks.md`, `state.md`, `decisions.md`, `evidence.md`,
|
|
51
|
-
`touched-files.md`,
|
|
52
|
+
`touched-files.md`, `.devrites/principles.md` (if present — the binding invariants to score
|
|
53
|
+
the diff against), and the `git diff`. For "what would this change break"
|
|
52
54
|
questions, prefer a code-intelligence index if available — codebase-memory-mcp first,
|
|
53
55
|
cross-checked with codegraph + graphify, else standard methods (LSP / Read/Grep/Glob); see
|
|
54
56
|
`.claude/rules/tooling.md` — over file reads;
|
|
@@ -77,7 +79,8 @@ pull these via `Read` when the diff demands them:
|
|
|
77
79
|
where 20 would do) and the silent-failure bugs (a missing value coerced to 0/''/[],
|
|
78
80
|
a dropped Result/err return, off-by-one / boundary, logic that contradicts the
|
|
79
81
|
comment/docstring/name). Per hunk, check whether working code was deleted that the
|
|
80
|
-
task did not ask to remove.
|
|
82
|
+
task did not ask to remove. Score the diff against `.devrites/principles.md` — a change
|
|
83
|
+
that breaks a declared invariant with no recorded, human-approved exception is a Critical."
|
|
81
84
|
- **Do NOT merge or re-rank** their findings. Present them under separate
|
|
82
85
|
`## Spec` and `## Code review` sub-sections in `review.md`. Surface contradictions
|
|
83
86
|
between the axes explicitly (e.g. "Spec axis says complete, Code-review axis says
|
|
@@ -20,10 +20,21 @@ is complete, and to scope anything the agent could not (e.g. UI-only lenses belo
|
|
|
20
20
|
## 2. Readability
|
|
21
21
|
- Can the next engineer understand it without the author? Naming, function length,
|
|
22
22
|
nesting depth, comments that explain *why* not *what*.
|
|
23
|
+
- Structural smells: a conditional **bolted onto an unrelated flow** (wants its own
|
|
24
|
+
helper/state/policy — a design smell, not a nit); **repeated conditionals on the same
|
|
25
|
+
shape** (a missing model or dispatcher).
|
|
23
26
|
|
|
24
27
|
## 3. Architecture
|
|
25
28
|
- Right seam/boundary? Coupling and cohesion. Does it fit existing patterns or
|
|
26
29
|
introduce a competing one? Is the abstraction earned (not premature)?
|
|
30
|
+
- Does a refactor **reduce** complexity or just **relocate** it? Count the concepts a
|
|
31
|
+
reader must hold; a "cleaner" version that leaves that count unchanged isn't cleaner.
|
|
32
|
+
- Is feature-specific logic **leaking into a shared module** instead of its owning layer?
|
|
33
|
+
Is a **type boundary** left implicit by a gratuitous `any`/cast or a silent fallback?
|
|
34
|
+
- **Name the remedy, not just the smell** — replace a conditional chain with a typed
|
|
35
|
+
dispatcher, separate orchestration from business logic, move feature logic to its owning
|
|
36
|
+
package, delete a pass-through wrapper, split a large file. Prefer the move that removes
|
|
37
|
+
moving pieces over one that re-centralizes the same complexity.
|
|
27
38
|
|
|
28
39
|
## 4. Security
|
|
29
40
|
- Trust boundaries, input validation, authz checks, secrets handling. Hand off to
|
|
@@ -43,4 +54,7 @@ is complete, and to scope anything the agent could not (e.g. UI-only lenses belo
|
|
|
43
54
|
|
|
44
55
|
## Sizing & speed
|
|
45
56
|
Prefer reviewing roughly one slice / ~100 lines of meaningful change at a time. Larger
|
|
46
|
-
diffs hide defects — recommend splitting rather than rubber-stamping.
|
|
57
|
+
diffs hide defects — recommend splitting rather than rubber-stamping. Watch **file size,
|
|
58
|
+
not just diff size**: a small diff that pushes an already-large file further past a healthy
|
|
59
|
+
boundary wants decomposition (extract helpers / split modules) *first* — decompose, then
|
|
60
|
+
add.
|
|
@@ -17,7 +17,11 @@ live in `/rite-ship`, which refuses to run without a GO recorded here.
|
|
|
17
17
|
pull these via `Read` before sealing:
|
|
18
18
|
- `agents.md` — review-subagent fan-out at seal.
|
|
19
19
|
- `code-review.md` — severity labels (Critical / Important / Suggestion / Nit / FYI).
|
|
20
|
+
- `principles.md` — declared project invariants (`.devrites/principles.md`) are a pass/fail gate; a diff that violates one with no recorded, human-approved exception is a NO-GO.
|
|
20
21
|
- `documentation.md` — record decisions in `decisions.md` before sealing.
|
|
22
|
+
- `observability.md` — a runtime surface that ships blind is an Important finding.
|
|
23
|
+
- `deprecation.md` — when the diff removes / migrates code, API, or data (read with the
|
|
24
|
+
risk-and-rollback step below).
|
|
21
25
|
|
|
22
26
|
## Operating rules
|
|
23
27
|
- Evidence over confidence — a criterion is met only if evidence proves it.
|
|
@@ -34,6 +38,8 @@ Read `review.md` and the latest reviewer outputs.
|
|
|
34
38
|
| `Critical == 0` and `Important > 0` and acceptance proven and drift resolved | Render interactive prompt: *"`Important > 0` open. Proceed to seal? [y/N]"*. Default **N**. If the user types `y`, GO; otherwise NO-GO with the open Important findings listed as blockers-by-policy. |
|
|
35
39
|
| `Critical > 0` | **NO-GO**, no exceptions. List every Critical with `file:line` and fix direction. |
|
|
36
40
|
| Any acceptance criterion unproven | **NO-GO**, list the unproven criteria. |
|
|
41
|
+
| Visual Verdict `FAIL` on an acceptance-mapped UI criterion (`browser-evidence.md`) | **NO-GO** — an unmet acceptance criterion. A declared-state `FAIL` is Important (the `Important > 0` row). UI build with a `design-brief.md` but no Visual Verdict → Important evidence gap. No brief → not applicable. |
|
|
42
|
+
| Diff violates a declared project principle (`.devrites/principles.md`) with no recorded, human-approved exception | **NO-GO**, list each violated principle with `file:line`. Same standing as an unproven criterion (absent / empty file → none declared → not a blocker). |
|
|
37
43
|
| Unresolved drift in `drift.md` | **NO-GO**, route through `/rite-plan` first. |
|
|
38
44
|
| Any `questions.md` entry with `gate: validating` and `status: open` | **NO-GO** regardless of behavior impact — an open validating gate is merge-blocking by definition. A slice marked `built (pending review)` is not done. |
|
|
39
45
|
|
|
@@ -50,7 +56,7 @@ Read `review.md` and the latest reviewer outputs.
|
|
|
50
56
|
Then read all artifacts: `brief.md`, `spec.md`, `plan.md`, `tasks.md`, `state.md`,
|
|
51
57
|
`decisions.md`, `assumptions.md`, `questions.md`, `drift.md`, `evidence.md`,
|
|
52
58
|
`browser-evidence.md`, `polish-report.md`, `review.md`, `design-brief.md` (if UI),
|
|
53
|
-
`strategy.md` (if present), and the **final diff**. If a code-intelligence index is available
|
|
59
|
+
`devex.md` (if a developer-facing surface), `strategy.md` (if present), and the **final diff**. If a code-intelligence index is available
|
|
54
60
|
(codebase-memory-mcp first, cross-checked with codegraph + graphify, else standard methods LSP / Read/Grep/Glob — see `.claude/rules/tooling.md`), use it for
|
|
55
61
|
blast-radius checks on the final diff in step 5; context7 if available can confirm a current
|
|
56
62
|
external-API signature a reviewer flags.
|
|
@@ -60,7 +66,11 @@ Read `review.md` and the latest reviewer outputs.
|
|
|
60
66
|
proof; the `devrites-spec-reviewer` + `devrites-test-analyst` fan-out in step 7 is the
|
|
61
67
|
independent cross-check (a verifier that never saw the optimistic narrative).
|
|
62
68
|
3. Verify tests, build/typecheck/lint, and browser proof are present and green for the
|
|
63
|
-
scope. Re-run if cheap and in doubt.
|
|
69
|
+
scope. Re-run if cheap and in doubt. **For a UI feature with a `design-brief.md`**, read the
|
|
70
|
+
`## Visual Verdict` table in `browser-evidence.md`: a `FAIL` on an **acceptance-mapped**
|
|
71
|
+
criterion is an unmet acceptance criterion (NO-GO, per the severity gate), a declared-state
|
|
72
|
+
`FAIL` is **Important**, and a UI build whose brief exists but whose verdict is **absent** is an
|
|
73
|
+
Important evidence gap (the scorecard should have been emitted at browser-proof).
|
|
64
74
|
4. Check unresolved **questions** and **drift** — any open item that changes product
|
|
65
75
|
behavior blocks. **Any `questions.md` entry with `gate: validating` and `status: open`
|
|
66
76
|
is a NO-GO regardless of behavior impact** (an open validating gate is merge-blocking by
|
|
@@ -70,6 +80,23 @@ Read `review.md` and the latest reviewer outputs.
|
|
|
70
80
|
`/rite-temper`), confirm its **top pre-mortem risks are mitigated** in the diff/evidence and
|
|
71
81
|
that no **Non-goal / deferred item crept into the diff** (scope creep) — either is a finding
|
|
72
82
|
(an unmitigated top risk or smuggled-in out-of-scope work).
|
|
83
|
+
- **Principles** (`principles.md`): score the final diff against each declared invariant in
|
|
84
|
+
`.devrites/principles.md`. A violation with no matching, human-approved exception in the
|
|
85
|
+
register is a **Critical** finding and a NO-GO; an exception that is stale (past its review
|
|
86
|
+
trigger) or wider than its stated scope is itself a finding. No file / no principles → skip.
|
|
87
|
+
- **Observability** (`observability.md`): if the diff added a runtime surface (endpoint,
|
|
88
|
+
job, integration, user flow, error path), a feature shipping with no way to debug it in
|
|
89
|
+
prod is an **Important** finding, not a pass — `evidence.md` should show telemetry observed
|
|
90
|
+
to emit (`/rite-prove` step 5b).
|
|
91
|
+
- **Developer experience** (`developer-experience.md`): if the diff ships a developer-facing
|
|
92
|
+
surface, reconcile `devex.md` (the `/rite-vet` predicted scorecard vs the `/rite-prove`
|
|
93
|
+
measured one — the boomerang). A broken public dev contract (a documented command that errors,
|
|
94
|
+
a getting-started flow that can't complete) or an unexplained measured DX regression is
|
|
95
|
+
**Important** — **Critical** on a frozen public surface (`principles.md`). No surface → skip.
|
|
96
|
+
- **Removal / migration** (`deprecation.md`): if the diff deletes or migrates code, an API,
|
|
97
|
+
or data, confirm it followed expand→contract, proved the old path unused before removing it,
|
|
98
|
+
and carries a rollback for every destructive step. A surprise deletion or a one-shot
|
|
99
|
+
breaking migration is a finding (and trips the irreversible-risk gate, `afk-hitl.md`).
|
|
73
100
|
6. Check **frontend polish** if UI is involved (states, a11y, responsive, design-system,
|
|
74
101
|
browser evidence).
|
|
75
102
|
7. **Independent review** — seal is the final gate, not a re-run of `/rite-review`.
|
|
@@ -87,8 +114,10 @@ Read `review.md` and the latest reviewer outputs.
|
|
|
87
114
|
`devrites-spec-reviewer` (does the diff implement
|
|
88
115
|
the spec?), `devrites-test-analyst` (do the tests prove acceptance?),
|
|
89
116
|
`devrites-code-reviewer`, `devrites-frontend-reviewer` (UI features),
|
|
90
|
-
`devrites-security-auditor` (input/auth/data/integrations),
|
|
91
|
-
`devrites-performance-reviewer` (perf-relevant)
|
|
117
|
+
`devrites-security-auditor` (input/auth/data/integrations),
|
|
118
|
+
`devrites-performance-reviewer` (perf-relevant), and `devrites-devex-reviewer`
|
|
119
|
+
(developer-facing surface — measure mode: grade the measured DX scorecard and reconcile
|
|
120
|
+
the boomerang against the `/rite-vet` prediction). Give each the workspace
|
|
92
121
|
path + diff *without the author's reasoning*. If subagents are unavailable,
|
|
93
122
|
run the equivalent reviews sequentially yourself.
|
|
94
123
|
The reviewer **AGENTS** here (fresh context, no author reasoning) are the seal
|