devrites 2.3.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to DevRites are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and DevRites adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Releases are generated automatically by [semantic-release](https://semantic-release.gitbook.io/) from Conventional Commits on `main`.
4
4
 
5
+ ## [2.4.0](https://github.com/ViktorsBaikers/DevRites/compare/v2.3.0...v2.4.0) (2026-06-27)
6
+
7
+ ### Added
8
+
9
+ * **devrites:** enforce the doubt gate from invocation through seal ([0397cca](https://github.com/ViktorsBaikers/DevRites/commit/0397cca2158ed1e798c29122485d4e2b69ea4f80))
10
+
5
11
  ## [2.3.0](https://github.com/ViktorsBaikers/DevRites/compare/v2.2.0...v2.3.0) (2026-06-23)
6
12
 
7
13
  ### Added
package/README.md CHANGED
@@ -101,7 +101,7 @@ Full diagram set (lifecycle, polish orchestrator, review fan-out, debug loop,
101
101
  rules carrier, workspace state, namespace map) →
102
102
  [`docs/flow.md`](docs/flow.md).
103
103
 
104
- **Status:** [`v2.3.0`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v2.3.0) — see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
104
+ **Status:** [`v2.4.0`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v2.4.0) — see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
105
105
 
106
106
  ## Contents
107
107
 
@@ -19,7 +19,7 @@ code · claiming "this is safe", "this scales", or "this matches the spec".
19
19
 
20
20
  - [ ] **1. CLAIM** — state the claim in 1–3 sentences + why it matters.
21
21
  - [ ] **2. EXTRACT** — isolate the smallest reviewable artifact + its contract; strip your reasoning so the reviewer sees only the code/decision.
22
- - [ ] **3. DOUBT** — invoke a fresh-context reviewer with an ADVERSARIAL prompt: *"find what's wrong; do not validate."* Prefer a real subagent (`.claude/agents/devrites-doubt-reviewer`) so it has no anchoring context.
22
+ - [ ] **3. DOUBT** — `Task` a fresh-context `devrites-doubt-reviewer` with an ADVERSARIAL prompt: *"find what's wrong; do not validate."* The subagent dispatch is **required** — doing the adversarial pass inline does **not** satisfy this step: you wrote the decision, so you are exactly the anchoring context the step exists to strip. Inline is a degraded fallback **only** when the `Task` tool is genuinely unavailable, and must be flagged as such in the verdict.
23
23
  - [ ] **4. RECONCILE** — classify EVERY finding: contract misread | valid & actionable | valid trade-off | noise.
24
24
  - [ ] **5. STOP** — met a stop condition (only trivial findings, 3 cycles done, or user override). Emit a **binary gate verdict** the orchestrator must clear: **accept** (no valid-&-actionable findings remain) or **reject + the specific required changes**. On reject, the orchestrator loops the wright on those changes before the slice is accepted; still reject after the 3-cycle cap → escalate to the user.
25
25
 
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env bash
2
+ # doubt-coverage.sh — did the build doubt the decisions it stood?
3
+ # Deterministic, zero-token. Reads the append-only footprint log the orchestrator writes at
4
+ # /rite-build step 4 (one `doubt` line per devrites-doubt dispatch) and reports doubt coverage
5
+ # against wright dispatches. It CANNOT prove a 1:1 verdict-per-decision match — `Decisions stood`
6
+ # is not a structured ledger — so it proves the cheap, unambiguous half: a feature that ran the
7
+ # wright but never once doubted a decision. The seal's prose gate (step 4a) + the reviewer fan-out
8
+ # judge severity against decisions.md.
9
+ #
10
+ # doubt-coverage.sh <slug>
11
+ #
12
+ # Exit: 0 = doubt dispatches present, or nothing to assess (no log / no wright) → pass.
13
+ # 1 = wright dispatch(es) logged but ZERO doubt dispatches → coverage gap. The seal treats
14
+ # it as a finding (Important; NO-GO when decisions.md records an irreversible-risk
15
+ # decision — auth / public-API / migration — with no verdict).
16
+ # 2 = usage.
17
+ set -u
18
+
19
+ slug="${1:-}"
20
+ [ -n "$slug" ] || { echo "usage: doubt-coverage.sh <slug>" >&2; exit 2; }
21
+
22
+ log=".devrites/work/$slug/footprint.log"
23
+ if [ ! -f "$log" ]; then
24
+ echo "doubt-coverage: no footprint log — nothing to assess (pass)"
25
+ exit 0
26
+ fi
27
+
28
+ w=$(awk '$2=="wright"{n++} END{print n+0}' "$log")
29
+ d=$(awk '$2=="doubt"{n++} END{print n+0}' "$log")
30
+
31
+ echo "doubt-coverage: $w wright · $d doubt"
32
+
33
+ if [ "$w" -gt 0 ] && [ "$d" -eq 0 ]; then
34
+ echo "doubt-coverage: GAP — $w wright dispatch(es), 0 doubt dispatches. Either every slice's"
35
+ echo "'Decisions stood' was genuinely empty, or step-4 doubt was skipped. Confirm against"
36
+ echo "decisions.md before GO."
37
+ exit 1
38
+ fi
39
+ exit 0
@@ -164,7 +164,21 @@ writes; read them yourself for the doubt/record gates or in the inline fallback:
164
164
  4. **Doubt the decisions it stood up.** For each entry in the wright's `Decisions stood`
165
165
  (branching, boundary crossing, data model, auth, public API, migration, user-flow change,
166
166
  "this is safe/scales") apply `devrites-doubt` **before accepting the slice** — the writer
167
- doesn't grade its own decisions. The doubt loop honours `.devrites/AFK` (see its AFK
167
+ doesn't grade its own decisions. Each `devrites-doubt` invocation **dispatches the
168
+ `devrites-doubt-reviewer` subagent** (doing the adversarial pass inline is the writer grading
169
+ itself — the thing this step exists to forbid). **Completion criterion (checkable):** step 4
170
+ is done only when **every** `Decisions stood` entry carries a recorded `devrites-doubt`
171
+ verdict — `accept`, or `reject` + the required changes — in `decisions.md` (accepted
172
+ trade-offs) / `questions.md` (open gates). A `Decisions stood` entry with **no verdict on
173
+ record** means doubt did not run for it: **do not enter step 5 and do not mark the slice
174
+ `built`.** Log each dispatch so the seal can prove doubt ran (the footprint already counts a
175
+ `doubt` kind):
176
+ ```bash
177
+ FP=.claude/skills/devrites-lib/scripts/footprint.sh
178
+ [ -f "$FP" ] || FP="${CLAUDE_SKILL_DIR:-}/../devrites-lib/scripts/footprint.sh"
179
+ [ -f "$FP" ] || FP=pack/.claude/skills/devrites-lib/scripts/footprint.sh
180
+ [ -f "$FP" ] && bash "$FP" log <slug> doubt "<decision id>" || true
181
+ ``` The doubt loop honours `.devrites/AFK` (see its AFK
168
182
  exception): findings below the slice's gate ceiling become advisory entries in `questions.md`;
169
183
  destructive / auth / public-API concerns always pause regardless. A non-empty `Escalation` in
170
184
  the artifact is handled here too: irreversible-risk / blockers → blocking question + set
@@ -42,6 +42,7 @@ Read `review.md` and the latest reviewer outputs.
42
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). |
43
43
  | Unresolved drift in `drift.md` | **NO-GO**, route through `/rite-plan` first. |
44
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. |
45
46
 
46
47
  ## Workflow
47
48
  1. **Run the shared orientation preamble** — it prints `state.md`, the artifacts present,
@@ -75,6 +76,22 @@ Read `review.md` and the latest reviewer outputs.
75
76
  behavior blocks. **Any `questions.md` entry with `gate: validating` and `status: open`
76
77
  is a NO-GO regardless of behavior impact** (an open validating gate is merge-blocking by
77
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.
78
95
  5. Check **security, data, migration, rollback** risk —
79
96
  [risk-and-rollback](reference/risk-and-rollback.md). If `strategy.md` exists (from
80
97
  `/rite-temper`), confirm its **top pre-mortem risks are mitigated** in the diff/evidence and
@@ -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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devrites",
3
- "version": "2.3.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",