devrites 2.2.0 → 2.4.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +30 -17
  3. package/docs/architecture.md +30 -24
  4. package/docs/command-map.md +15 -6
  5. package/docs/flow.md +19 -5
  6. package/docs/orchestration.md +17 -7
  7. package/docs/skills.md +32 -8
  8. package/pack/.claude/agents/devrites-code-reviewer.md +6 -1
  9. package/pack/.claude/agents/devrites-devex-reviewer.md +94 -0
  10. package/pack/.claude/agents/devrites-forge-judge.md +92 -0
  11. package/pack/.claude/agents/devrites-frontend-reviewer.md +8 -0
  12. package/pack/.claude/agents/devrites-retrospector.md +91 -0
  13. package/pack/.claude/agents/devrites-slice-wright.md +18 -5
  14. package/pack/.claude/rules/README.md +5 -2
  15. package/pack/.claude/rules/agents.md +30 -2
  16. package/pack/.claude/rules/anti-patterns.md +11 -0
  17. package/pack/.claude/rules/code-review.md +16 -6
  18. package/pack/.claude/rules/core.md +13 -4
  19. package/pack/.claude/rules/developer-experience.md +119 -0
  20. package/pack/.claude/rules/principles.md +158 -0
  21. package/pack/.claude/rules/spec-grammar.md +106 -0
  22. package/pack/.claude/skills/devrites-browser-proof/SKILL.md +42 -3
  23. package/pack/.claude/skills/devrites-doubt/SKILL.md +1 -1
  24. package/pack/.claude/skills/devrites-lib/SKILL.md +9 -2
  25. package/pack/.claude/skills/devrites-lib/scripts/devrites.sh +8 -0
  26. package/pack/.claude/skills/devrites-lib/scripts/doubt-coverage.sh +39 -0
  27. package/pack/.claude/skills/devrites-lib/scripts/spec-validate.sh +130 -0
  28. package/pack/.claude/skills/rite-adopt/SKILL.md +13 -1
  29. package/pack/.claude/skills/rite-autocomplete/SKILL.md +3 -1
  30. package/pack/.claude/skills/rite-build/SKILL.md +51 -2
  31. package/pack/.claude/skills/rite-build/reference/anti-patterns.md +12 -0
  32. package/pack/.claude/skills/rite-build/reference/forge.md +171 -0
  33. package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +2 -0
  34. package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +22 -2
  35. package/pack/.claude/skills/rite-define/SKILL.md +14 -1
  36. package/pack/.claude/skills/rite-frame/SKILL.md +7 -2
  37. package/pack/.claude/skills/rite-learn/SKILL.md +17 -4
  38. package/pack/.claude/skills/rite-polish/SKILL.md +3 -1
  39. package/pack/.claude/skills/rite-prove/SKILL.md +30 -1
  40. package/pack/.claude/skills/rite-quick/SKILL.md +9 -4
  41. package/pack/.claude/skills/rite-review/SKILL.md +5 -2
  42. package/pack/.claude/skills/rite-seal/SKILL.md +39 -4
  43. package/pack/.claude/skills/rite-seal/reference/anti-patterns.md +2 -0
  44. package/pack/.claude/skills/rite-ship/SKILL.md +21 -0
  45. package/pack/.claude/skills/rite-spec/SKILL.md +29 -5
  46. package/pack/.claude/skills/rite-spec/reference/spec-template.md +11 -1
  47. package/pack/.claude/skills/rite-status/SKILL.md +3 -1
  48. package/pack/.claude/skills/rite-vet/SKILL.md +46 -14
  49. package/package.json +1 -1
  50. package/scripts/check-cross-refs.py +4 -0
  51. package/scripts/run-behavioral-evals.sh +170 -0
  52. package/scripts/run-evals.sh +3 -0
  53. package/scripts/validate.sh +1 -1
@@ -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** or
57
- **ledger** promotion, draft the exact edit and let the user confirm it through the normal flow
58
- — `/rite-learn` writes the ledger, not the rule files. Then `touch .devrites/.learnings-reviewed`
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. Then run
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,9 +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.
40
42
  - `observability.md` — when the change has a runtime surface (endpoint, job, integration,
41
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.
42
47
 
43
48
  ## Operating rules
44
49
  - Evidence over confidence. Feature scope only — fix within the feature or record a
@@ -71,7 +76,19 @@ pull these via `Read` when relevant:
71
76
  (`devrites-browser-proof`): routes, viewports, screenshots (opened + described),
72
77
  console, network, interaction paths, and design-reference match if references exist.
73
78
  5. **Map results to acceptance** — walk `spec.md` acceptance criteria; note which are now
74
- proven and which aren't. If `test-plan.md` exists, also walk its acceptance→test map and
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
75
92
  per-gap requirements — a planned test (especially a regression-Critical) with no covering
76
93
  result is an unproven gap, not a pass. **Also walk the test-plan interaction inventory**
77
94
  (every interactive element + user flow): each must have a passing asserting test. An
@@ -107,6 +124,16 @@ pull these via `Read` when relevant:
107
124
  span actually emits, and record that observation in `evidence.md`. Instrumentation never seen
108
125
  emitting is unproven, not done. Skip entirely for pure-internal / docs / config / type-only
109
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.
110
137
  6. **On failure** → [failure-triage](reference/failure-triage.md) +
111
138
  `devrites-debug-recovery`. Reproduce → isolate → fix within scope → re-run; if a fix
112
139
  would exceed scope, record a blocker.
@@ -120,9 +147,11 @@ pull these via `Read` when relevant:
120
147
  ```
121
148
  Proved: <feature>
122
149
  Acceptance criteria proven: <n / total>
150
+ Scenarios proven: <n / total | n/a (flat acceptance)>
123
151
  Tests: <cmd → pass/fail (counts)>
124
152
  Build: <cmd → pass/fail> Lint: <cmd → pass/fail>
125
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)>
126
155
  Unresolved failures / blockers: <none | list>
127
156
  Next: /rite-polish (finish the feature → /rite-review → /rite-seal)
128
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 — one pass, no
57
- subagent fan-out). Show the diff, then on the user's confirm commit it (Conventional
58
- Commits, atomic) or hand to `/rite-ship` if a workspace is active. **Never push without
59
- the user asking.**
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
+ passone 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`, and the `git diff`. For "what would this change break"
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
@@ -17,6 +17,7 @@ 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.
21
22
  - `observability.md` — a runtime surface that ships blind is an Important finding.
22
23
  - `deprecation.md` — when the diff removes / migrates code, API, or data (read with the
@@ -37,8 +38,11 @@ Read `review.md` and the latest reviewer outputs.
37
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. |
38
39
  | `Critical > 0` | **NO-GO**, no exceptions. List every Critical with `file:line` and fix direction. |
39
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). |
40
43
  | Unresolved drift in `drift.md` | **NO-GO**, route through `/rite-plan` first. |
41
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. |
45
+ | `doubt-coverage` rc=1, or a stood decision (boundary / data-model / auth / public-API / migration / branching) recorded in `decisions.md` with no `devrites-doubt` verdict | **Important** — and **NO-GO** when the undoubted decision is an irreversible-risk class (auth / public-API / migration), the same standing as an unproven acceptance criterion. `/rite-build` step 4 records the verdict + logs a `doubt` footprint; absence here means doubt was skipped. Genuinely-empty `Decisions stood` on every slice is a valid pass — confirm, don't assume. |
42
46
 
43
47
  ## Workflow
44
48
  1. **Run the shared orientation preamble** — it prints `state.md`, the artifacts present,
@@ -53,7 +57,7 @@ Read `review.md` and the latest reviewer outputs.
53
57
  Then read all artifacts: `brief.md`, `spec.md`, `plan.md`, `tasks.md`, `state.md`,
54
58
  `decisions.md`, `assumptions.md`, `questions.md`, `drift.md`, `evidence.md`,
55
59
  `browser-evidence.md`, `polish-report.md`, `review.md`, `design-brief.md` (if UI),
56
- `strategy.md` (if present), and the **final diff**. If a code-intelligence index is available
60
+ `devex.md` (if a developer-facing surface), `strategy.md` (if present), and the **final diff**. If a code-intelligence index is available
57
61
  (codebase-memory-mcp first, cross-checked with codegraph + graphify, else standard methods LSP / Read/Grep/Glob — see `.claude/rules/tooling.md`), use it for
58
62
  blast-radius checks on the final diff in step 5; context7 if available can confirm a current
59
63
  external-API signature a reviewer flags.
@@ -63,20 +67,49 @@ Read `review.md` and the latest reviewer outputs.
63
67
  proof; the `devrites-spec-reviewer` + `devrites-test-analyst` fan-out in step 7 is the
64
68
  independent cross-check (a verifier that never saw the optimistic narrative).
65
69
  3. Verify tests, build/typecheck/lint, and browser proof are present and green for the
66
- scope. Re-run if cheap and in doubt.
70
+ scope. Re-run if cheap and in doubt. **For a UI feature with a `design-brief.md`**, read the
71
+ `## Visual Verdict` table in `browser-evidence.md`: a `FAIL` on an **acceptance-mapped**
72
+ criterion is an unmet acceptance criterion (NO-GO, per the severity gate), a declared-state
73
+ `FAIL` is **Important**, and a UI build whose brief exists but whose verdict is **absent** is an
74
+ Important evidence gap (the scorecard should have been emitted at browser-proof).
67
75
  4. Check unresolved **questions** and **drift** — any open item that changes product
68
76
  behavior blocks. **Any `questions.md` entry with `gate: validating` and `status: open`
69
77
  is a NO-GO regardless of behavior impact** (an open validating gate is merge-blocking by
70
78
  definition); a slice marked `built (pending review)` is not done.
79
+ 4a. **Doubt coverage — every stood decision was independently doubted.** Run the deterministic
80
+ check, then judge it against `decisions.md`:
81
+ ```bash
82
+ DC=.claude/skills/devrites-lib/scripts/doubt-coverage.sh
83
+ [ -f "$DC" ] || DC="${CLAUDE_SKILL_DIR:-}/../devrites-lib/scripts/doubt-coverage.sh"
84
+ [ -f "$DC" ] || DC=pack/.claude/skills/devrites-lib/scripts/doubt-coverage.sh
85
+ [ -f "$DC" ] && { bash "$DC" <slug>; echo "doubt-coverage rc=$?"; } || echo "(doubt-coverage gate unavailable — confirm by hand each stood decision carries a devrites-doubt verdict)"
86
+ ```
87
+ The script proves the **footprint half** (a `doubt` dispatch was logged per `/rite-build`
88
+ step 4); you prove the **verdict half**: every decision in `decisions.md` that crosses a doubt
89
+ trigger (boundary / data-model / auth / public-API / migration / branching / "safe" / "scales")
90
+ must carry a recorded `devrites-doubt` verdict — `accept`, or a `reject` whose required changes
91
+ were resolved. Per the severity gate: **rc=1 or a triggering decision with no verdict is an
92
+ Important finding**, escalating to **NO-GO** when the undoubted decision is irreversible-risk
93
+ (auth / public-API / migration). A genuinely-empty `Decisions stood` across every slice passes —
94
+ confirm it against `decisions.md`, don't assume it.
71
95
  5. Check **security, data, migration, rollback** risk —
72
96
  [risk-and-rollback](reference/risk-and-rollback.md). If `strategy.md` exists (from
73
97
  `/rite-temper`), confirm its **top pre-mortem risks are mitigated** in the diff/evidence and
74
98
  that no **Non-goal / deferred item crept into the diff** (scope creep) — either is a finding
75
99
  (an unmitigated top risk or smuggled-in out-of-scope work).
100
+ - **Principles** (`principles.md`): score the final diff against each declared invariant in
101
+ `.devrites/principles.md`. A violation with no matching, human-approved exception in the
102
+ register is a **Critical** finding and a NO-GO; an exception that is stale (past its review
103
+ trigger) or wider than its stated scope is itself a finding. No file / no principles → skip.
76
104
  - **Observability** (`observability.md`): if the diff added a runtime surface (endpoint,
77
105
  job, integration, user flow, error path), a feature shipping with no way to debug it in
78
106
  prod is an **Important** finding, not a pass — `evidence.md` should show telemetry observed
79
107
  to emit (`/rite-prove` step 5b).
108
+ - **Developer experience** (`developer-experience.md`): if the diff ships a developer-facing
109
+ surface, reconcile `devex.md` (the `/rite-vet` predicted scorecard vs the `/rite-prove`
110
+ measured one — the boomerang). A broken public dev contract (a documented command that errors,
111
+ a getting-started flow that can't complete) or an unexplained measured DX regression is
112
+ **Important** — **Critical** on a frozen public surface (`principles.md`). No surface → skip.
80
113
  - **Removal / migration** (`deprecation.md`): if the diff deletes or migrates code, an API,
81
114
  or data, confirm it followed expand→contract, proved the old path unused before removing it,
82
115
  and carries a rollback for every destructive step. A surprise deletion or a one-shot
@@ -98,8 +131,10 @@ Read `review.md` and the latest reviewer outputs.
98
131
  `devrites-spec-reviewer` (does the diff implement
99
132
  the spec?), `devrites-test-analyst` (do the tests prove acceptance?),
100
133
  `devrites-code-reviewer`, `devrites-frontend-reviewer` (UI features),
101
- `devrites-security-auditor` (input/auth/data/integrations), and
102
- `devrites-performance-reviewer` (perf-relevant). Give each the workspace
134
+ `devrites-security-auditor` (input/auth/data/integrations),
135
+ `devrites-performance-reviewer` (perf-relevant), and `devrites-devex-reviewer`
136
+ (developer-facing surface — measure mode: grade the measured DX scorecard and reconcile
137
+ the boomerang against the `/rite-vet` prediction). Give each the workspace
103
138
  path + diff *without the author's reasoning*. If subagents are unavailable,
104
139
  run the equivalent reviews sequentially yourself.
105
140
  The reviewer **AGENTS** here (fresh context, no author reasoning) are the seal
@@ -16,6 +16,7 @@ see [rules/anti-patterns.md](../../../rules/anti-patterns.md).
16
16
  | "Drift is small; resolve it inline and seal." | Unresolved drift = NO-GO, no exceptions. Route through `/rite-plan` to repair, then seal. |
17
17
  | "Reviewer findings overlap; average them away." | Surface disagreements explicitly. Averaging hides where the reviewers actually disagree. |
18
18
  | "Carry the old reviewer verdicts though the diff changed." | If the diff changed since `/rite-review`, re-run the Spec + Code axes — don't carry stale verdicts forward. |
19
+ | "Build never doubted a decision, but the wright seemed confident — GO without checking." | Doubt is a gate, not a vibe. `doubt-coverage` rc=1 — or a stood boundary / data-model / auth / public-API / migration decision in `decisions.md` with no recorded `devrites-doubt` verdict — is an Important finding, escalating to NO-GO when the undoubted decision is irreversible-risk (auth / public-API / migration). An empty `Decisions stood` on every slice passes only when confirmed against `decisions.md`, never assumed. |
19
20
 
20
21
  ## Red Flags
21
22
 
@@ -25,3 +26,4 @@ see [rules/anti-patterns.md](../../../rules/anti-patterns.md).
25
26
  - `seal.md` written before walking *every* acceptance criterion one by one.
26
27
  - A NO-GO rounded up to GO "to be agreeable".
27
28
  - Unresolved drift, unresolved questions, or pending tasks — and you're sealing anyway.
29
+ - `doubt-coverage` rc=1 left unexamined, or a stood irreversible-risk decision (auth / public-API / migration) carrying no recorded `devrites-doubt` verdict — and you're sealing GO anyway.
@@ -97,6 +97,26 @@ Refuses to ship unless `seal.md` records a **GO** verdict.
97
97
  `bash .claude/skills/devrites-lib/scripts/close-out.sh <slug>` to archive
98
98
  `.devrites/work/<slug>/` → `.devrites/archive/<slug>/` and clear `.devrites/ACTIVE`.
99
99
  Every `.md` is preserved in the archive.
100
+ 6a. **Cross-feature retro (automatic, cadence-gated, advisory).** The just-shipped feature is now in
101
+ the archive, so this is where the **cross-feature** learning loop closes on its own — the synthesis
102
+ that otherwise waits for a human to run `/rite-learn`. Run the cheap cadence gate first; it stays
103
+ silent unless a finding/drift class recurs across **>=2 shipped features** with new signal since the
104
+ last review (so it never fires on an early or one-off ship):
105
+ ```bash
106
+ L=.claude/skills/devrites-lib/scripts/learnings.sh
107
+ [ -f "$L" ] || L="${CLAUDE_SKILL_DIR:-}/../devrites-lib/scripts/learnings.sh"
108
+ [ -f "$L" ] || L=pack/.claude/skills/devrites-lib/scripts/learnings.sh
109
+ [ -f "$L" ] && bash "$L" nudge || true
110
+ ```
111
+ **If the nudge emits** (a recurring pattern crossed the threshold), dispatch the read-only
112
+ `devrites-retrospector` (`.claude/agents/`) over `.devrites/archive/` for the cross-feature
113
+ synthesis. Persist its digest to `.devrites/retro.md` (append a dated entry — the project-level
114
+ retro ledger, never rewritten) and surface the **graduation candidates** with a one-line pointer
115
+ to `/rite-learn`, which is where the human confirms a promotion to a rule / principle / convention.
116
+ **Propose, never impose:** retro **drafts**; it never auto-writes a rule or principle (a principle
117
+ is a gate, amended deliberately and dated — `principles.md` governance), and it never blocks the
118
+ ship, which has already happened. If the nudge is silent, skip — no retro this close. Then `touch
119
+ .devrites/.learnings-reviewed` only when the human acts on it via `/rite-learn`, not here.
100
120
 
101
121
  > **Mid-flight discipline.** When tempted to ship without a GO seal, skip the type-GO,
102
122
  > stage files outside `touched-files.md`, or delete the workspace instead of archiving
@@ -112,6 +132,7 @@ Commit: <sha> on <branch> Tag/PR: <ref | none>
112
132
  Acceptance: <n/total> proven
113
133
  Archived: .devrites/archive/<slug>/ · ACTIVE cleared
114
134
  ship.md: .devrites/archive/<slug>/ship.md
135
+ Retro: <n graduation candidates drafted → .devrites/retro.md · promote with /rite-learn | quiet (no cross-feature signal yet)>
115
136
  ```
116
137
  If the user declined type-GO: state that nothing shipped, the seal still reads GO, and
117
138
  the resume command (`/rite-ship`).
@@ -21,7 +21,13 @@ are `/rite-define` and `/rite-build`.
21
21
  ## Rules consulted (read on demand from `.claude/rules/`)
22
22
  **Step 0:** Read `.claude/rules/core.md` first. DevRites skills Read `.claude/rules/core.md`
23
23
  as their first step; the other rule files load on demand. Pull `documentation.md` via `Read`
24
- when capturing significant spec decisions (why-not-what, ADR-style notes in `decisions.md`).
24
+ when capturing significant spec decisions (why-not-what, ADR-style notes in `decisions.md`);
25
+ pull `principles.md` when the project has declared invariants (`.devrites/principles.md`) — a
26
+ new spec must respect them, and a requirement that can only be met by breaking one is a blocking gap.
27
+ Pull `spec-grammar.md` when writing acceptance for a behavioral / high-risk requirement (auth,
28
+ data model, state machine, public API, money, migration) — the structured `### Requirement:` /
29
+ `#### Scenario:` (SHALL · WHEN/THEN) form, lint-checked by `spec-validate.sh`. Simple criteria
30
+ stay flat `[ACn]` bullets; the grammar is opt-in by rigor, never forced.
25
31
 
26
32
  ## Operating rules (DevRites core)
27
33
  - No silent assumptions · no guessing through confusion · prefer existing conventions ·
@@ -55,7 +61,8 @@ when capturing significant spec decisions (why-not-what, ADR-style notes in `dec
55
61
  Also discover the project's **test / build/typecheck/lint** commands and the
56
62
  frontend/backend systems; read `PRODUCT.md` / `DESIGN.md` / `CLAUDE.md` / `AGENTS.md` if
57
63
  present (`AGENTS.md` is the cross-tool agent-conventions standard — treat it as project
58
- conventions the build must follow, same standing as `CLAUDE.md`).
64
+ conventions the build must follow, same standing as `CLAUDE.md`), and read
65
+ `.devrites/principles.md` if present — the declared invariants the feature must respect.
59
66
  3. **Gather design references (optional)** — [references-intake](reference/references-intake.md).
60
67
  The human **may** attach screenshots, mockups, a Figma link, a video, or links — or
61
68
  **none at all** (perfectly normal; skip this step then). If any are given: **view/fetch**
@@ -79,12 +86,19 @@ when capturing significant spec decisions (why-not-what, ADR-style notes in `dec
79
86
  can predict them (don't interrogate). Aim for **zero blocking gaps**. *If a gap is genuinely undecidable on paper (state
80
87
  machine that may deadlock, data shape ambiguity, "which UX wins") → suggest a
81
88
  scoped detour to `/rite-prototype` to answer that ONE question before
82
- continuing.*
89
+ continuing.* **Invariant conflict is a blocking gap:** if a requirement or acceptance
90
+ criterion can only be satisfied by breaking a declared principle (`.devrites/principles.md`),
91
+ surface it — the principle wins by default; breaking it needs a recorded, scoped exception a
92
+ human approves, never a spec that silently contradicts an invariant.
83
93
  5. **Create the workspace** + set `.devrites/ACTIVE`
84
94
  ([state-workspace](reference/state-workspace.md)). Write `spec.md`
85
95
  ([spec-template](reference/spec-template.md)) — WHAT/WHY, technology-agnostic, with
86
96
  **Placement & integration**, **Design references**, **Gaps/issues/decisions**, and
87
- measurable acceptance ([acceptance-criteria](reference/acceptance-criteria.md)). Also
97
+ measurable acceptance ([acceptance-criteria](reference/acceptance-criteria.md)). For a
98
+ behavioral / high-risk requirement, write the acceptance as a structured
99
+ `### Requirement:` (SHALL) + `#### Scenario:` (WHEN/THEN) block per
100
+ [`spec-grammar.md`](../../rules/spec-grammar.md), nesting the `[ACn]` id inside each scenario
101
+ so `/rite-seal` still grades it; routine criteria stay flat `[ACn]` bullets. Also
88
102
  write `brief.md`, `references.md`, `questions.md`, `decisions.md`, `assumptions.md`,
89
103
  and an initial `state.md` (phase: spec). When the feature touches UI, `design-brief.md`
90
104
  is written here too (by `devrites-ux-shape`, step 3a).
@@ -98,7 +112,16 @@ when capturing significant spec decisions (why-not-what, ADR-style notes in `dec
98
112
  `[NEEDS CLARIFICATION]`, placement decided, all material gaps resolved, any design
99
113
  references provided are saved, **UX/UI shaped into `design-brief.md` if the feature is
100
114
  UI**, requirements testable, success criteria measurable, **every `checklists/<domain>.md` at
101
- `Verdict: pass`**. When it passes, write `Spec gate: passed <iso>` to `state.md`. **Stop** when
115
+ `Verdict: pass`**, and **any structured requirement blocks are grammar-valid** run
116
+ `spec-validate.sh` (resolved like the step-0 preamble), a non-zero exit is a blocking
117
+ failure to fix, not soften:
118
+ ```bash
119
+ SV=.claude/skills/devrites-lib/scripts/spec-validate.sh
120
+ [ -f "$SV" ] || SV="${CLAUDE_SKILL_DIR:-}/../devrites-lib/scripts/spec-validate.sh"
121
+ [ -f "$SV" ] || SV=pack/.claude/skills/devrites-lib/scripts/spec-validate.sh
122
+ [ -f "$SV" ] && bash "$SV" ".devrites/work/<slug>" || echo "(spec-grammar validator unavailable — eyeball the Requirement/Scenario blocks)"
123
+ ```
124
+ When it passes, write `Spec gate: passed <iso>` to `state.md`. **Stop** when
102
125
  it passes.
103
126
 
104
127
  > **Mid-flight discipline.** When tempted to skip investigation depth, gap-closing, or placement decisions — see [`anti-patterns`](reference/anti-patterns.md) (Common Rationalizations + Red Flags). Load it the moment you reach for the excuse.
@@ -114,6 +137,7 @@ References: <n saved | none provided>
114
137
  Design brief: <design-brief.md shaped (compact|full) | n/a — not UI>
115
138
  Gaps closed: <n> Open (non-blocking): <n>
116
139
  Checklists: <n domains scored — all pass | BLOCKED: n CRITICAL open>
140
+ Grammar: <n requirements / m scenarios — valid | n/a (flat acceptance)>
117
141
  Next: big / risky feature (auth · data model · public API · migration · multi-slice · ambiguous scope)?
118
142
  → /rite-temper (strategic review: scope mode + pre-mortem, hardens the spec) — then /rite-define.
119
143
  Small / reversible / unambiguous? → /rite-define directly.
@@ -65,7 +65,16 @@ Observable outcomes that mean "this worked". Numbers where possible. No tech nam
65
65
 
66
66
  ## Acceptance criteria
67
67
  Binary, evidence-backed checklist; each maps to a scenario/FR. See acceptance-criteria.md.
68
- - [ ] <criterion> (FR-00x)
68
+ - [ ] [AC1] <criterion> (FR-00x)
69
+
70
+ For a behavioral / high-risk requirement (auth, data model, state machine, public API, money,
71
+ migration), write it as a structured Requirement/Scenario block instead — testable by
72
+ construction and lint-checked by spec-validate.sh (see spec-grammar.md). Keep the [ACn] id
73
+ inside the scenario so the seal still grades it; routine criteria stay flat bullets above.
74
+ ### Requirement: <name>
75
+ The system SHALL <core observable behavior>.
76
+ #### Scenario: <name>
77
+ - [ ] [AC2] **WHEN** <trigger> **THEN** <observable outcome> (**AND** <extra condition>)
69
78
 
70
79
  ## Non-goals
71
80
  Explicitly out of scope for this version.
@@ -119,6 +128,7 @@ List every open marker; blocking ones must be zero at the gate.
119
128
  - [ ] Design references gathered + saved (if the human supplied any)
120
129
  - [ ] **UX/UI shaped into `design-brief.md`** (if the feature touches UI) — direction, key states, interaction model decided
121
130
  - [ ] Requirements are testable and unambiguous
131
+ - [ ] **Structured requirements are grammar-valid** (if any) — `### Requirement:` / `#### Scenario:` blocks pass `spec-validate.sh` (SHALL + WHEN/THEN, unique headers); flat `[ACn]` bullets need no check (see spec-grammar.md)
122
132
  - [ ] Success criteria are measurable and technology-agnostic
123
133
  - [ ] **Spec-quality checklists pass** — every `checklists/<domain>.md` reaches `Verdict: pass` (zero CRITICAL "unit-tests-for-English" fails; see [spec-checklists.md](spec-checklists.md))
124
134
  ```
@@ -49,7 +49,9 @@ Otherwise summarize from the loaded state, concisely:
49
49
  6. **Open questions** — count by gate (from `questions.md`:
50
50
  `n open: x blocking · y validating · z advisory`) + the blocking qids by id and one-line question.
51
51
  7. **Unresolved drift** (`drift.md`).
52
- 8. **Risks** (from `state.md` / `spec.md`).
52
+ 8. **Risks** (from `state.md` / `spec.md`); if `.devrites/principles.md` exists, note the count
53
+ of declared invariants and flag any exception in its register that is past its review/removal
54
+ trigger (a stale exception is a standing risk). Omit if there's no principles file.
53
55
  9. **Ready for handoff?** — see section below.
54
56
 
55
57
  Flag anything blocking: unresolved drift, failing evidence, `Status: awaiting_human`,
@@ -22,11 +22,16 @@ This is the engineering counterpart to `/rite-temper` (which is strategic, on th
22
22
  Temper decides *the right thing*; vet decides *the right way to build it*.
23
23
 
24
24
  ## Rules consulted (read on demand from `.claude/rules/`)
25
- **Step 0:** Read `.claude/rules/core.md` first. Pull on demand: `patterns.md` +
25
+ **Step 0:** Read `.claude/rules/core.md` first. Pull on demand: `principles.md` (the project
26
+ invariants gate — how `.devrites/principles.md` is scored pass/fail), `patterns.md` +
26
27
  `coding-style.md` (the over-engineering / reuse-first / YAGNI rubric — reuse the pack's
27
- standard), `testing.md` (the test-coverage axis), `performance.md` (the perf axis),
28
+ standard), `testing.md` (the test-coverage axis) + `spec-grammar.md` (when the spec uses
29
+ structured Requirement/Scenario blocks, each scenario is a coverage unit `test-plan.md` must
30
+ map), `performance.md` (the perf axis),
28
31
  `error-handling.md` (failure-mode coverage), `development-workflow.md` (parallel lanes,
29
- definition of done), `afk-hitl.md` (irreversible-risk list + gate ceiling).
32
+ definition of done), `afk-hitl.md` (irreversible-risk list + gate ceiling),
33
+ `developer-experience.md` (when the plan ships a developer-facing surface — API / CLI / SDK /
34
+ webhook / config / error messages / getting-started — predict the DX scorecard here).
30
35
 
31
36
  ## Operating rules
32
37
  - **Review the plan, not the spec's ambition.** The spec's scope/ambition is `/rite-temper`'s
@@ -78,15 +83,22 @@ definition of done), `afk-hitl.md` (irreversible-risk list + gate ceiling).
78
83
  against a built-in (dispatch `devrites-source-driven`); completeness check (with AI, full
79
84
  coverage is ~100× cheaper than the human-hours saved by a shortcut — prefer complete); and a
80
85
  distribution check for any new artifact.
81
- 2a. **Cross-artifact analyze gate + charter/conventions gate.** Before the axes, run one read-only
82
- consistency+coverage pass over `spec.md` + `plan.md` + `tasks.md` (+ `coverage.md` if present);
83
- any **CRITICAL** — an acceptance criterion with no slice, a slice satisfying no criterion, a
84
- contradiction across artifacts — **blocks `/rite-build`** until resolved. Then score the anti-slop
85
- charter (`coding-style.md` + `prose-style.md`) and the conventions ledger
86
- (`.devrites/conventions.md`) as an explicit **pass/fail** on the planned approach — a plan that
87
- bakes in a god-module, a speculative abstraction with no second caller, or a dependency where an
88
- in-repo option exists is a **top-severity** violation, walked first. **Re-check both after the
89
- axes harden the plan** (post-design). Write the result to `analysis.md`.
86
+ 2a. **Cross-artifact analyze gate + principles / charter / conventions gate.** Before the axes, run
87
+ one read-only consistency+coverage pass over `spec.md` + `plan.md` + `tasks.md` (+ `coverage.md`
88
+ if present); any **CRITICAL** — an acceptance criterion with no slice, a slice satisfying no
89
+ criterion, a contradiction across artifacts — **blocks `/rite-build`** until resolved. Then score
90
+ the three project gates as explicit **pass/fail** on the planned approach:
91
+ - **Principles** (`.devrites/principles.md`, rubric in [`principles.md`](../../rules/principles.md))
92
+ the authored invariants the project will not break. A plan that bakes in a violation of a
93
+ declared principle with **no recorded, human-approved exception** is a **top-severity** finding,
94
+ walked **first**, and **blocks `/rite-build`**. Absent or empty file → none declared → passes;
95
+ **never block for the absence of principles**. A genuine need to break one routes to a scoped,
96
+ dated exception in the principles register — never a silent work-around (adding the exception is
97
+ an irreversible-risk decision: it always pauses for a human, even in AFK).
98
+ - **The anti-slop charter** (`coding-style.md` + `prose-style.md`) and **the conventions ledger**
99
+ (`.devrites/conventions.md`) — a plan that bakes in a god-module, a speculative abstraction with
100
+ no second caller, or a dependency where an in-repo option exists is a **top-severity** violation.
101
+ **Re-check all three after the axes harden the plan** (post-design). Write the result to `analysis.md`.
90
102
  ```bash
91
103
  A=.claude/skills/devrites-lib/scripts/analyze.sh
92
104
  [ -f "$A" ] || A="${CLAUDE_SKILL_DIR:-}/../devrites-lib/scripts/analyze.sh"
@@ -103,12 +115,31 @@ definition of done), `afk-hitl.md` (irreversible-risk list + gate ceiling).
103
115
  coverage-increasing findings auto-apply; **anything that grows scope or changes acceptance is a
104
116
  blocking pause**; irreversible-risk always pauses.)
105
117
  4. **Required outputs** — the test-coverage diagram + per-gap test requirements (the **regression
106
- rule** is mandatory, no question), failure-mode table, "NOT in scope", "What already exists",
118
+ rule** is mandatory, no question). When the spec uses the structured grammar
119
+ (`spec-grammar.md`), the diagram maps **each `#### Scenario:` (WHEN/THEN) to ≥1 planned
120
+ test** — an unmapped scenario is a coverage gap the build must close. Then the failure-mode
121
+ table, "NOT in scope", "What already exists",
107
122
  and the worktree parallelization strategy. Shapes in [`reference/review-axes.md`](reference/review-axes.md).
123
+ **Developer-facing surface?** If the plan ships one (`developer-experience.md` — API / CLI / SDK /
124
+ webhook / config / error messages / getting-started), predict the DX scorecard: the time-to-hello-world
125
+ estimate plus the getting-started, error-message, and ergonomics friction the plan bakes in. Write it
126
+ to `devex.md` as the **prediction the boomerang measures against** at `/rite-prove` / `/rite-seal`.
127
+ Absent surface → skip, no `devex.md` (greenfield no-op, like the principles gate).
108
128
  Also a **PRP one-pass-implementable check** per slice brief (the build's pre-flight): confirm each
109
129
  slice's Consumes/Produces, Known-Gotchas, validation commands, and reuse targets are present and
110
130
  concrete — a brief that can't be built in one pass is a finding; harden the slice until it clears,
111
131
  before `/rite-build`.
132
+ 4a. **Forge gate (rare — confirm or clear).** For each slice carrying `Forge: yes` (proposed by
133
+ `/rite-define`), and any slice the architecture axis showed has **≥2 genuinely-viable approaches
134
+ with no clear winner at Complexity ≥4**, confirm the flag: name the 2–3 candidate strategies that
135
+ actually differ (different data shape, different seam, reuse-vs-build — not variations of one), and
136
+ confirm the slice's acceptance + `test-plan.md` give the judge an objective scorecard. **Clear**
137
+ `Forge: yes` back to `no` when the review settled on one approach, the slice is below the complexity
138
+ bar, or you can't name two real strategies — competing a decided or trivial slice burns K× the build
139
+ for nothing. Forge is a **build-cost** decision, not an irreversible one: it never bypasses a gate,
140
+ and under AFK its K candidates count against the slice budget. Record the confirmed strategies in
141
+ the slice brief so `/rite-build` competes them
142
+ ([`rite-build/reference/forge.md`](../rite-build/reference/forge.md)). No flagged slice → nothing to do.
112
143
  5. **Write `eng-review.md` + `test-plan.md`, fold back** — [`reference/artifacts.md`](reference/artifacts.md).
113
144
  `eng-review.md` is the durable record; `test-plan.md` is the build-readable coverage target
114
145
  (`/rite-build` and `/rite-prove` read it). Harden `plan.md` / `tasks.md` directly for
@@ -144,9 +175,10 @@ Depth: light | full (<trigger that escalated it>)
144
175
  Scope: reuse <n found> / minimum-diff <ok|trimmed N> / complexity <ok|smell: N files, M new services → asked>
145
176
  Axes (floor → verdict): Architecture <band> · Code-quality <band> · Tests <band> · Performance <band>
146
177
  Findings: <Critical n / Important n / Suggestion n> (suppressed low-confidence: n)
147
- Coverage: <x/y paths> planned · GAPS closed <n> · regressions flagged <n> → test-plan.md
178
+ Coverage: <x/y paths> planned (<s/t scenarios mapped | n/a>) · GAPS closed <n> · regressions flagged <n> → test-plan.md
148
179
  Failure modes: <n> mapped (<n critical: no test + no handling + silent>)
149
180
  Parallelization: <n lanes — n parallel / n sequential> | sequential (no opportunity)
181
+ Forge: <n slices flagged — strategies named | none> (competed candidate builds at /rite-build)
150
182
  Reviewer loop: <n> iter · cross-model: ran (codex) | off
151
183
  Plan: hardened in place | <n> deltas routed via Spec Drift Guard → /rite-plan repair
152
184
  Next: /rite-build (builds the vetted plan)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devrites",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "description": "DevRites — disciplined senior-engineer workflow skills pack for Claude Code",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://github.com/ViktorsBaikers/DevRites#readme",
@@ -29,7 +29,11 @@ WORKSPACE_ARTIFACTS = {
29
29
  "questions.md", "drift.md", "evidence.md", "browser-evidence.md", "touched-files.md",
30
30
  "review.md", "seal.md", "ship.md", "brief.md", "design-brief.md", "strategy.md",
31
31
  "polish-report.md", "handoff.md", "eng-review.md", "test-plan.md", "references.md",
32
+ # forge competition record (work/<slug>/forge-report.md) — written when a Forge: yes slice competes candidates
33
+ "forge-report.md",
32
34
  "conventions.md", "coverage.md", "analysis.md", "learnings.md",
35
+ # developer-experience scorecard (work/<slug>/devex.md) + project-level retro ledger (.devrites/retro.md)
36
+ "devex.md", "retro.md",
33
37
  # spec-quality checklists (.devrites/work/<slug>/checklists/<domain>.md)
34
38
  "functional.md", "data-model.md", "interaction.md", "non-functional.md", "edge-cases.md",
35
39
  }