devrites 3.0.3 → 3.0.5

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 (59) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +55 -43
  3. package/SECURITY.md +72 -58
  4. package/docs/adr/0001-go-engine-as-control-plane.md +43 -0
  5. package/docs/adr/0002-dual-host-harness.md +34 -0
  6. package/docs/adr/0003-gate-model-hitl-pause.md +38 -0
  7. package/docs/adr/0004-state-schema-phases-sections.md +6 -3
  8. package/docs/adr/0005-hooks-as-engine-subcommands.md +39 -0
  9. package/docs/adr/0006-clock-seam-and-engine-ci-gates.md +50 -0
  10. package/docs/adr/0007-canonical-live-workspace-filenames.md +36 -0
  11. package/docs/adr/0008-sanctioned-engine-network-boundary.md +33 -0
  12. package/docs/adr/README.md +58 -0
  13. package/docs/agents/issue-driven-rites.md +5 -5
  14. package/docs/architecture.md +61 -45
  15. package/docs/capability-surface-selection.md +3 -1
  16. package/docs/cli.md +9 -2
  17. package/docs/command-map.md +6 -2
  18. package/docs/engine/agent-contract.md +5 -3
  19. package/docs/engine/commands.md +27 -14
  20. package/docs/engine/state-schema.md +14 -9
  21. package/docs/engine/workspace-schema.md +5 -4
  22. package/docs/flow.md +18 -7
  23. package/docs/porting-to-a-new-harness.md +6 -2
  24. package/docs/release.md +10 -9
  25. package/docs/skills.md +1 -1
  26. package/docs/templates/CRITIC_REVIEW_PACKET_TEMPLATE.md +35 -0
  27. package/docs/usage.md +26 -16
  28. package/engine/internal/lib/packageexistence.go +729 -52
  29. package/engine/internal/lib/packageexistence_test.go +343 -0
  30. package/engine/internal/lib/util.go +1 -1
  31. package/engine/internal/migrate/migrate.go +16 -11
  32. package/engine/internal/migrate/migrate_test.go +26 -4
  33. package/engine/internal/state/feature.go +28 -14
  34. package/engine/internal/state/schema.go +20 -8
  35. package/engine/internal/state/state_test.go +6 -6
  36. package/engine/tests/budget_test.go +2 -2
  37. package/engine/tests/meta_test.go +3 -3
  38. package/engine/tests/migrate_cli_test.go +24 -22
  39. package/pack/.claude/skills/devrites-lib/SKILL.md +7 -9
  40. package/pack/.claude/skills/devrites-lib/reference/reply-contract.md +11 -3
  41. package/pack/.claude/skills/devrites-lib/reference/standards/development-workflow.md +2 -3
  42. package/pack/.claude/skills/rite/SKILL.md +6 -7
  43. package/pack/.claude/skills/rite/reference/menu.md +5 -5
  44. package/pack/.claude/skills/rite-adopt/SKILL.md +2 -3
  45. package/pack/generated/claude/skills/devrites-lib/SKILL.md +7 -9
  46. package/pack/generated/claude/skills/devrites-lib/reference/reply-contract.md +11 -3
  47. package/pack/generated/claude/skills/devrites-lib/reference/standards/development-workflow.md +2 -3
  48. package/pack/generated/claude/skills/rite/SKILL.md +6 -7
  49. package/pack/generated/claude/skills/rite/reference/menu.md +5 -5
  50. package/pack/generated/claude/skills/rite-adopt/SKILL.md +2 -3
  51. package/pack/generated/codex/skills/devrites-lib/SKILL.md +7 -9
  52. package/pack/generated/codex/skills/devrites-lib/reference/reply-contract.md +11 -3
  53. package/pack/generated/codex/skills/devrites-lib/reference/standards/development-workflow.md +2 -3
  54. package/pack/generated/codex/skills/rite/SKILL.md +6 -7
  55. package/pack/generated/codex/skills/rite/reference/menu.md +5 -5
  56. package/pack/generated/codex/skills/rite-adopt/SKILL.md +2 -3
  57. package/package.json +2 -1
  58. package/scripts/skills-inventory.mjs +18 -0
  59. package/scripts/validate-workflow-security.py +3 -8
@@ -3,6 +3,10 @@
3
3
  - **Status:** Accepted
4
4
  - **Date:** 2026-07-08 (backfilled)
5
5
 
6
+ > Artifact filename direction was amended by
7
+ > [ADR-0007](0007-canonical-live-workspace-filenames.md). Phase-relative section
8
+ > completeness remains unchanged.
9
+
6
10
  ## Context
7
11
 
8
12
  A feature's working state must be legible to both humans and the engine, and
@@ -13,9 +17,8 @@ that don't exist yet (there's no proof during framing).
13
17
 
14
18
  ## Decision
15
19
 
16
- Model feature state as **six single-concern section files** — `spec`, `plan`,
17
- `decisions`, `tasks`, `proof`, `status` (with transitional aliases
18
- `evidence→proof`, `state→status` that `migrate` normalizes). Drive the lifecycle
20
+ Model feature state as **six single-concern sections** — `spec`, `plan`,
21
+ `decisions`, `tasks`, `proof`, `status`. Drive the lifecycle
19
22
  through the ordered rite-\* arc:
20
23
  `frame → spec → temper → define → plan → vet → build → converge → prove → polish → review → seal → ship → done`.
21
24
  Completeness is **phase-relative and additive**: the typed phase registry maps
@@ -0,0 +1,39 @@
1
+ # ADR-0005: Hooks are engine subcommands, not shell scripts
2
+
3
+ - **Status:** Accepted
4
+ - **Date:** 2026-07-08 (backfilled; see commits porting `reviewer-readonly`,
5
+ `subagent-orient`, and the guard hooks into the Go engine)
6
+
7
+ ## Context
8
+
9
+ Lifecycle hooks (orient on session start, readonly-guard for reviewers,
10
+ stop-gate, statusline, redwatch, …) began as standalone `pack/.claude/hooks/*.sh`
11
+ scripts. Shell hooks drift from the engine's own state logic, are hard to test
12
+ in isolation, behave differently across the two hosts, and duplicate parsing the
13
+ engine already does.
14
+
15
+ ## Decision
16
+
17
+ Hooks are **subcommands of the one Go binary**: `devrites-engine hook <id>`.
18
+ The pack ships only `hooks.json` wiring plus host settings; every hook's logic
19
+ lives in the engine, sharing the `orient`/`gate`/`state` core. A control plane
20
+ selects which hooks fire: `DEVRITES_HOOK_PROFILE` (minimal / standard / strict)
21
+ and `DEVRITES_DISABLED_HOOKS`. Each hook has a golden parity test
22
+ (`tests/parity_*_test.go`) pinning its stdout + exit across both hosts.
23
+
24
+ ## Alternatives considered
25
+
26
+ | Option | Why not |
27
+ |--------|---------|
28
+ | Keep hooks as `.sh` scripts | Drift from engine state logic, per-host divergence, poor testability, duplicated parsing. |
29
+ | One monolithic hook entry point | Loses per-hook enable/disable and per-hook golden tests. |
30
+ | Node hook runtime | Reintroduces a runtime dependency ADR-0001 deliberately avoids. |
31
+
32
+ ## Consequences
33
+
34
+ - Hooks are unit-testable Go with golden parity snapshots, not shell fixtures.
35
+ - One implementation serves both hosts; the harness (ADR-0002) handles edge
36
+ translation.
37
+ - Profiles make the hook surface tunable without editing wiring.
38
+ - The pack's `hooks/*.sh` files are removed; `hooks.json` is the only pack-side
39
+ hook artifact.
@@ -0,0 +1,50 @@
1
+ # ADR-0006: Clock seam + Go static-analysis CI gates
2
+
3
+ - **Status:** Accepted
4
+ - **Date:** 2026-07-08
5
+
6
+ ## Context
7
+
8
+ Two gaps surfaced while studying a more mature peer system (GSD Core; see
9
+ `docs/research/gsd-core-adoption.md`):
10
+
11
+ 1. **Unwired static analysis.** `engine/Makefile` defined `staticcheck` and
12
+ `govulncheck` targets, but CI ran only `gofmt` + `go vet`. No `-race`, no
13
+ custom analysis on the trust-root binary.
14
+ 2. **A wall-clock leak.** `resolve next-qid` derived today's date from a raw
15
+ `time.Now()` with no seam, so its golden snapshot was pinned to the date it
16
+ was recorded and failed **every other day** — a latent red the peer system's
17
+ clock-seam lint would have caught at author time.
18
+
19
+ ## Decision
20
+
21
+ - **Clock seam.** Wall-clock reads in the resolve command flow through one
22
+ overridable point, `clockNow()`, honoring `DEVRITES_NOW` (RFC-3339 or bare
23
+ `YYYY-MM-DD`). Date-derived output is deterministic under test; goldens pin the
24
+ clock instead of tracking the real date.
25
+ - **Engine CI gates.** The `engine` CI job installs pinned `staticcheck`
26
+ (2025.1.1) + `govulncheck` and runs both as **blocking** steps, and runs the
27
+ suite with `-race`. `make quality` mirrors this so a green local gate means a
28
+ green pipeline.
29
+ - **Coverage** is measured (`make cover`) but **not** yet a hard floor: the
30
+ number is understated because most behaviour is exercised through CLI-level
31
+ integration tests in `tests/` that don't attribute to per-package coverage.
32
+ A ratchet-only floor is a follow-up once attribution is meaningful.
33
+
34
+ ## Alternatives considered
35
+
36
+ | Option | Why not |
37
+ |--------|---------|
38
+ | Regenerate the date golden and move on | Fixes it for one day; the test rots again at the next date boundary. The seam fixes the class. |
39
+ | Introduce `golangci-lint` | New dependency + config surface; `staticcheck` + `govulncheck` were already defined in the Makefile — wire what exists. |
40
+ | Inject a full `Clock` interface everywhere | Heavier than the one failing path needs; the env seam is the minimal correct fix. A shared clock package is a Proposed generalization. |
41
+ | Hard coverage floor now | Misleading at ~23% aggregate due to integration-test attribution; a floor here would gate on noise. |
42
+
43
+ ## Consequences
44
+
45
+ - The engine suite is deterministic across dates and race-checked; static
46
+ analysis and CVE scanning block on the trust-root binary.
47
+ - `DEVRITES_NOW` is a supported test seam; other date-deriving commands
48
+ (`learnings`, `conventions`, `footprint`, `stuck`) still read `time.Now()`
49
+ directly and can adopt the same seam when they need deterministic output.
50
+ - Guard test `tests/adr_0006_clock_seam_test.go` locks the seam behaviour.
@@ -0,0 +1,36 @@
1
+ # ADR-0007: Canonical live workspace filenames
2
+
3
+ - **Status:** Accepted
4
+ - **Date:** 2026-07-20
5
+
6
+ ## Context
7
+
8
+ ADR-0004 established phase-relative `proof` and `status` sections while the
9
+ live workspace later standardized its human-facing artifacts on `README.md`,
10
+ `state.md`, and `evidence.md`. Shipped skills, validators, the typed workflow
11
+ registry, and user documentation already write those names, but migration and
12
+ some engine comments still normalized in the opposite direction.
13
+
14
+ ## Decision
15
+
16
+ Use `README.md`, `state.md`, and `evidence.md` as the canonical live workspace
17
+ map, cursor, and proof log. Continue reading `feature.md`/`index.md`, `status.md`,
18
+ and `proof.md` as compatibility aliases. `devrites-engine migrate` adds missing
19
+ canonical files from aliases without deleting or overwriting either form.
20
+ Internal `proof` and `status` section identifiers remain conceptual completeness
21
+ names, not canonical filename declarations.
22
+
23
+ ## Alternatives considered
24
+
25
+ | Option | Why not |
26
+ |--------|---------|
27
+ | Restore `feature.md`, `status.md`, and `proof.md` as canonical | Would reverse the shipped workspace contract and require coordinated changes across skills, validators, docs, fixtures, and generated hosts. |
28
+ | Treat both directions as equally canonical | Makes migration non-idempotent and leaves writers without one preferred target. |
29
+ | Delete aliases after migration | Risks data loss and breaks existing workspaces and older installed packs. |
30
+
31
+ ## Consequences
32
+
33
+ - Migration direction matches the files produced and required by the live pack.
34
+ - Existing aliases remain losslessly readable and are preserved on disk.
35
+ - Schema version remains `1`; this is an additive filename normalization, not a
36
+ content-schema break.
@@ -0,0 +1,33 @@
1
+ # ADR-0008: Sanctioned engine network boundary
2
+
3
+ - **Status:** Accepted
4
+ - **Date:** 2026-07-20
5
+
6
+ ## Context
7
+
8
+ ADR-0001 described the Go control plane as network-free. The binary now also
9
+ owns explicit installation/update and source-cache operations that require HTTP,
10
+ while deterministic workspace bookkeeping still must not depend on network or
11
+ model responses. The implemented boundary already isolates HTTP in one package.
12
+
13
+ ## Decision
14
+
15
+ Keep deterministic workspace state, gate, hook, migration, and derivation logic
16
+ network- and model-free. Permit network access only in `internal/iohooks` for
17
+ explicit updater and source-cache operations. No other first-party package may
18
+ import network clients, and no engine package may call a model API.
19
+
20
+ ## Alternatives considered
21
+
22
+ | Option | Why not |
23
+ |--------|---------|
24
+ | Forbid all network access in the binary | Would remove the verified updater and source-cache refresh behavior users already rely on. |
25
+ | Allow each consumer its own HTTP client | Expands the audit surface and weakens the executable package boundary. |
26
+ | Ship a second updater binary | Adds packaging, release, and cross-platform complexity without improving the existing package isolation. |
27
+
28
+ ## Consequences
29
+
30
+ - Workspace verdicts remain deterministic and offline-capable.
31
+ - Network behavior has one auditable package and one guard test.
32
+ - The binary as a whole is not network-free; documentation must distinguish the
33
+ control-plane core from explicit I/O commands.
@@ -0,0 +1,58 @@
1
+ # Architecture Decision Records
2
+
3
+ An ADR captures **one** load-bearing decision: the context that forced it, the
4
+ decision itself, the alternatives that were rejected and *why*, and the
5
+ consequences accepted. The rejected-alternatives table is the point — it keeps
6
+ the "why not X" from being re-litigated every quarter.
7
+
8
+ `CLAUDE.md` points every agent here (`CONTEXT.md` + `docs/adr/` are the
9
+ single-context domain record). Keep this directory the source of truth for
10
+ architecture; per-feature `decisions.md` files stay scoped to that feature.
11
+
12
+ ## Convention
13
+
14
+ - Filename: `NNNN-kebab-title.md`, zero-padded, monotonic.
15
+ - Frontmatter fields: **Status** (Proposed / Accepted / Superseded by NNNN),
16
+ **Date** (YYYY-MM-DD), **Deciders** (optional).
17
+ - Sections: **Context** → **Decision** → **Alternatives considered** (a table:
18
+ option · why rejected) → **Consequences**.
19
+ - **Guard test:** an accepted ADR that asserts a runtime invariant SHOULD have a
20
+ named regression test — `engine/tests/adr_NNNN_*_test.go` — so the decision
21
+ has an executable proof it still holds. Reference the ADR number in the test's
22
+ doc comment.
23
+
24
+ ## Template
25
+
26
+ ```markdown
27
+ # ADR-NNNN: <title>
28
+
29
+ - **Status:** Accepted
30
+ - **Date:** YYYY-MM-DD
31
+
32
+ ## Context
33
+ <the forces: what problem, what constraints, what was true at the time>
34
+
35
+ ## Decision
36
+ <what we chose, stated as a present-tense rule>
37
+
38
+ ## Alternatives considered
39
+ | Option | Why not |
40
+ |--------|---------|
41
+ | ... | ... |
42
+
43
+ ## Consequences
44
+ <what this makes easy, what it costs, what follow-up it implies>
45
+ ```
46
+
47
+ ## Index
48
+
49
+ | ADR | Title | Status | Guard test |
50
+ |-----|-------|--------|-----------|
51
+ | [0001](0001-go-engine-as-control-plane.md) | Go engine as deterministic control plane | Accepted | — |
52
+ | [0002](0002-dual-host-harness.md) | Dual-host harness (Claude + Codex) | Accepted | `tests/parity_*_test.go` |
53
+ | [0003](0003-gate-model-hitl-pause.md) | Gates block as HITL pause, never crash | Accepted | `tests/adr_0003_gate_exit_code_test.go` |
54
+ | [0004](0004-state-schema-phases-sections.md) | Phase-relative section completeness | Accepted | `tests/adr_0004_required_by_phase_test.go` |
55
+ | [0005](0005-hooks-as-engine-subcommands.md) | Hooks are engine subcommands, not shell scripts | Accepted | `tests/parity_*_test.go` |
56
+ | [0006](0006-clock-seam-and-engine-ci-gates.md) | Clock seam + Go static-analysis CI gates | Accepted | `tests/adr_0006_clock_seam_test.go` |
57
+ | [0007](0007-canonical-live-workspace-filenames.md) | Canonical live workspace filenames | Accepted | `internal/migrate/migrate_test.go`, `tests/migrate_cli_test.go` |
58
+ | [0008](0008-sanctioned-engine-network-boundary.md) | Sanctioned engine network boundary | Accepted | `tests/meta_test.go` |
@@ -4,8 +4,8 @@ Local issue files are the source of truth; external trackers are references only
4
4
 
5
5
  ## Flow
6
6
 
7
- 1. Create `.scratch/<slug>/issue.md` for the problem and optional `.scratch/<slug>/prd.md` for product detail.
8
- 2. Start `/rite-spec <slug>` from those files; copy decisions into `.devrites/work/<slug>/`, not back to the tracker.
9
- 3. Run the normal lifecycle: `/rite-define` → `/rite-vet` → `/rite-build` → `/rite-prove` → `/rite-review` → `/rite-seal`.
10
- 4. `/rite-ship` may include `Closes #NNN` only after a recorded type-GO.
11
- 5. Follow-ups go to a new local `.scratch/<next-slug>/issue.md` first; external auto-posting is out of scope.
7
+ 1. Create `.scratch/<slug>/PRD.md` when product detail is needed and one or more numbered implementation issues under `.scratch/<slug>/issues/<NN>-<issue-slug>.md`, starting at `01`.
8
+ 2. Start `/rite-spec <slug>` from the relevant PRD/issues; copy lifecycle decisions into `.devrites/work/<slug>/`, while tracker status/comments remain in the local issue files.
9
+ 3. Run the normal lifecycle: `/rite-define` → `/rite-vet` → `/rite-build` → `/rite-prove` → `/rite-polish` → `/rite-review` → `/rite-seal` → `/rite-ship`.
10
+ 4. After a recorded type-GO, mark completed local issues `Status: resolved` and append the ship evidence; include `Closes #NNN` only when an external issue reference actually exists.
11
+ 5. Follow-ups become the next numbered local issue under `.scratch/<slug>/issues/` (or a new feature directory when scope differs); external auto-posting is out of scope.
@@ -1,9 +1,11 @@
1
1
  # DevRites Architecture
2
2
 
3
- DevRites is a **distributed but coordinated** set of project-local Claude Code skills
4
- that make an AI coding agent behave like a disciplined senior engineer: clarify
5
- spec+plan build one verified slice prove with evidence polishreview → seal →
6
- ship.
3
+ DevRites is a **distributed but coordinated** set of project-local Claude Code
4
+ and Codex skill surfaces backed by one Go control plane. It makes an AI coding
5
+ agent behave like a disciplined senior engineer: framespecoptional temper
6
+ → define → mandatory vet → build one verified slice → prove with evidence →
7
+ polish → review → seal → ship. `converge` is the recovery state when live code
8
+ and recorded intent need to meet again.
7
9
 
8
10
  For the `.devrites/` load order, file budgets, artifact schema, aliases,
9
11
  traceability rules, and phase-relative completeness model, see
@@ -11,20 +13,25 @@ traceability rules, and phase-relative completeness model, see
11
13
 
12
14
  ## Layers
13
15
 
14
- 1. **Public workflow skills** — `.claude/skills/rite-*`, `user-invocable: true`. Each
15
- owns exactly one phase and reads/writes the `.devrites/` workspace.
16
- Sequence: `rite-spec`, `rite-define`, `rite-plan`, `rite-build`,
17
- `rite-prove`, `rite-polish`, `rite-review`, `rite-seal`, `rite-ship`,
18
- plus the read-only `rite-status`, the resume verb `rite-resolve` (answer
19
- a HITL gate and clear `Awaiting human`), and the thin `/rite` menu.
16
+ 1. **Public lifecycle and workspace skills** — `.claude/skills/rite-*`,
17
+ `user-invocable: true`. Each owns one bounded phase or workspace transition.
18
+ Sequence: `rite-spec`, optional `rite-temper`, `rite-define`, mandatory
19
+ `rite-vet`, `rite-build`, recovery `rite-converge`, `rite-prove`,
20
+ `rite-polish`, `rite-review`, `rite-seal`, `rite-ship`; `rite-plan` repairs
21
+ or reslices an active plan,
22
+ plus the resume verb `rite-resolve` (answer a HITL gate and clear
23
+ `Awaiting human`). The thin `/rite` menu and read-only `rite-status` live in
24
+ the public utility layer below.
20
25
  `/rite-seal` **decides** GO/NO-GO and writes the verdict to `seal.md`;
21
- `/rite-ship` is the eighth lifecycle phase that **executes** the
26
+ `/rite-ship` is the eighth core lifecycle rite that **executes** the
22
27
  irreversible git ladder and **closes** the task (archives the workspace,
23
28
  clears `ACTIVE`). Keeping the decision and the irreversible action as two
24
29
  separately-auditable steps is the point.
25
- 2. **Public utility skills** — `.claude/skills/rite-zoom-out`,
26
- `rite-prototype`, `rite-handoff`, `rite-pressure-test`, `rite-pov`,
27
- `rite-dogfood`, `rite-pr-feedback`, and `rite-autocomplete` — public commands. `rite-autocomplete` is the
30
+ 2. **Public utility and on-ramp skills** — `rite-adopt`, `rite-quick`,
31
+ `rite-frame`, `rite-status`, `rite-doctor`, `rite-learn`, `rite-explain`,
32
+ `rite-customize`, `rite-zoom-out`, `rite-prototype`, `rite-handoff`,
33
+ `rite-pressure-test`, `rite-pov`, `rite-dogfood`, `rite-pr-feedback`, and
34
+ `rite-autocomplete` — public commands. `rite-autocomplete` is the
28
35
  unattended orchestrator: it drives the whole lifecycle (spec → … → seal →
29
36
  ship) end-to-end, choosing the best option at each soft gate, pausing only
30
37
  on hard irreversible-risk / blocking / escalating gates or a NO-GO. The
@@ -37,16 +44,17 @@ traceability rules, and phase-relative completeness model, see
37
44
  `-doubt`, `-ux-shape` (plans UX/UI into `design-brief.md` at `/rite-spec`),
38
45
  `-frontend-craft`, `-browser-proof`, `-debug-recovery`,
39
46
  `-api-interface`, `-audit` (dispatches the security / perf / simplify
40
- reviewer subagent on an axis argument). Model-invoked by public skills
41
- or Claude's auto-selection; not menu noise. Whether a skill is public or
47
+ reviewer subagent on an axis argument), `-prose-craft`, and
48
+ `-refresh-indexes`. These 11 specialists are model-invoked by public skills
49
+ or host auto-selection; not menu noise. Whether a skill is public or
42
50
  internal is governed by the `user-invocable:` flag, not by the name
43
51
  prefix.
44
52
 
45
53
  Engineering rules live at `.claude/skills/devrites-lib/reference/standards/`.
46
54
  Workspace-operating lifecycle rites load `core.md` first and disclose phase-specific
47
- files on demand; compact utilities keep a narrower local contract. Parallel reviewer fan-out at
48
- `/rite-seal` is a reference file
49
- (`rite-seal/reference/parallel-dispatch.md`), not a skill.
55
+ files on demand; compact utilities keep a narrower local contract. Parallel
56
+ reviewer fan-out at `/rite-seal` is the shared reference file
57
+ `devrites-lib/reference/parallel-dispatch.md`, not a skill.
50
58
  4. **Supporting references** — `reference/*.md` inside each skill. Long checklists,
51
59
  templates, and anti-rationalization tables loaded on demand (progressive
52
60
  disclosure) so `SKILL.md` bodies stay small.
@@ -131,17 +139,19 @@ Built-in / bundled Claude Code commands include `/plan`, `/review`, `/run`, `/ve
131
139
  `rite-` prefix avoids all of them. (Collision audit: `research/claude-code-skills-notes.md`.)
132
140
 
133
141
  ### Why a thin menu skill, not a mega-router
134
- `/rite` is **only** an entrypoint: it shows a compact phase-grouped menu, prints live
135
- `.devrites/ACTIVE` status via `` !`cmd` `` injection, and suggests the next command.
136
- It deliberately does **not** execute workflows or duplicate skill logic that would
137
- recreate the mega-command problem. DevRites keeps selection thin and lets each phase
138
- own its context, rather than centralizing every workflow behind one command.
142
+ `/rite` is **only** an entrypoint: it shows a compact phase-grouped menu, prints
143
+ recommended-start guidance from `devrites-engine first-task`, and dispatches a
144
+ named verb to its owning skill. Menu mode does not read raw workspace state;
145
+ `/rite-status` owns detailed status. `/rite` deliberately does **not** duplicate
146
+ workflow logic that would recreate the mega-command problem. DevRites keeps
147
+ selection thin and lets each phase own its context.
139
148
 
140
149
  ### Why internal skills exist
141
150
  Specialist processes (doubt, source-driven, frontend craft, browser proof, audits)
142
- are **disciplines**, not user commands. As `user-invocable: false` skills they:
151
+ are **disciplines**, not user commands. As `user-invocable: false` specialist
152
+ skills they:
143
153
  - stay out of the command menu (less cognitive load);
144
- - are invoked automatically by Claude or explicitly by a public skill when their
154
+ - are invoked automatically by the host model or explicitly by a public skill when their
145
155
  trigger conditions hit;
146
156
  - keep each public `SKILL.md` small by housing the heavy process elsewhere.
147
157
 
@@ -165,8 +175,8 @@ and `rite-polish-ui` sub-skills, but a skill-on-skill dispatch is fragile
165
175
  (the caller has to re-discover the callee by description) and the two halves
166
176
  share the same operating rules. They now live as `reference/code.md` and
167
177
  `reference/ui.md` inside the same skill, loaded only when their phase
168
- trigger fires — the canonical progressive-disclosure pattern from
169
- <https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices>.
178
+ trigger fires — the supporting-files pattern from Claude Code's current
179
+ [skills reference](https://code.claude.com/docs/en/slash-commands#add-supporting-files).
170
180
  `/rite-polish` is the orchestrator: always reads `reference/code.md`
171
181
  (Phase 1 + 2), detects UI scope from the diff and reads `reference/ui.md`
172
182
  (Phase 3 + 4) when needed. The orchestrator accepts mode tokens (`bolder`,
@@ -182,7 +192,7 @@ Deciding "is this safe to ship" and *actually shipping* are different acts with
182
192
  different blast radii. `/rite-seal` is a **pure decision gate**: it walks acceptance
183
193
  against evidence, fans out the fresh-context reviewers, and writes the GO / NO-GO
184
194
  verdict to `seal.md` — it runs no git. On GO it sets `state.md` `Next step:
185
- /rite-ship` and stops. `/rite-ship` is the eighth lifecycle phase: it refuses to run
195
+ /rite-ship` and stops. `/rite-ship` is the eighth core lifecycle rite: it refuses to run
186
196
  without a GO recorded in `seal.md`, renders the type-`GO` prompt, runs the irreversible
187
197
  git ladder (commit → push → tag/PR per the project's convention), writes `ship.md`,
188
198
  then **closes the task** — sets phase `done` and archives `.devrites/work/<slug>/` →
@@ -192,8 +202,9 @@ decision and the irreversible action as two separately-auditable steps is the po
192
202
 
193
203
  ### Why `/rite-autocomplete` exists (the unattended orchestrator)
194
204
  Some features are routine enough to run end-to-end without per-phase human iteration.
195
- `/rite-autocomplete` drives the whole lifecycle (spec → definebuild×Nprove
196
- polish → review → seal → ship) by reading each phase's `SKILL.md` and executing its
205
+ `/rite-autocomplete` drives the whole lifecycle (spec → temperdefinevet
206
+ build×N → prove → polish → review → seal → ship) by reading each phase's
207
+ `SKILL.md` and executing its
197
208
  workflow, carrying state through the workspace files rather than chat. A vague prompt
198
209
  triggers an up-front `devrites-interview` — the only interactive window — after which it
199
210
  runs unattended, choosing the best option at each soft gate and recording the rationale
@@ -247,15 +258,18 @@ contract.
247
258
  lens + `rite-adopt` (onboard an existing codebase) + `rite-learn` (cross-feature
248
259
  lessons) + `rite-status` + `rite-doctor` (install health) +
249
260
  `rite-customize` (project-local overrides/extensions) +
261
+ `rite-explain` (grounded concept/diff/idea/recap explanation) +
250
262
  `rite-pov` (external-option verdicts) + `rite-dogfood` (browser QA) +
251
263
  `rite-pr-feedback` (review-thread closure) +
252
- the `rite-plan` replan verb + the `rite-resolve` resume verb + 4 ideation /
264
+ the `rite-plan` replan verb + `rite-converge` recovery + the `rite-resolve`
265
+ resume verb + 4 ideation /
253
266
  handoff utilities (`rite-zoom-out`, `rite-prototype`, `rite-handoff`,
254
267
  `rite-pressure-test`) + `rite-autocomplete` (the unattended full-lifecycle
255
268
  orchestrator) — plus 11 internal model-invoked `devrites-*` specialists and the
256
269
  `devrites-lib` library, not one mega-command. The `devrites-` prefix is a
257
270
  namespace (collision avoidance), not a public/internal marker —
258
- `user-invocable:` is. All `devrites-*` skills are model-invoked.
271
+ `user-invocable:` is. The 11 specialists are model-invoked;
272
+ `devrites-lib` explicitly disables model invocation.
259
273
  - **Selection**: the `/rite` menu skill carries the routing table; every
260
274
  workflow skill enforces a "right skill, right time" rule in its body.
261
275
  - **State**: durable `.devrites/` Markdown that survives compaction and new sessions.
@@ -267,21 +281,22 @@ contract.
267
281
  - **Slice rule**: build **one vertical slice, then stop** — no auto-continue.
268
282
  - **Drift**: an explicit **Spec Drift Guard** in build/prove/polish/review/seal.
269
283
  - **Design**: `devrites-frontend-craft` + a four-phase `/rite-polish` orchestrator (code + backend always; UI normalize + polish when UI is in scope).
270
- - **Review**: **feature-scoped** five-axis review with severity labels + fresh-context
271
- subagents at the seal.
284
+ - **Review**: **feature-scoped** multi-axis review with severity labels +
285
+ fresh-context subagents at the seal.
272
286
  - **Scope**: clarify → seal (decide) → ship (the irreversible git ladder —
273
287
  commit → push → tag/PR — per the project's own convention) → close; the CI
274
288
  pipeline stays with the project.
275
- - **Install**: project-local, manifest-managed; ships DevRites' own engineering rules.
289
+ - **Install**: project-local, manifest-managed host artifacts; the optional
290
+ shared engine binary is the sole sanctioned global artifact.
276
291
 
277
292
  ## Deviations from the original build brief (and why)
278
293
 
279
- 1. **`user-invocable` semantics corrected from the docs.** The brief said set
280
- `user-invocable: true` for public and `false` for internal. That is exactly right
281
- for internal skills. For public skills we keep them model-invocable (no
282
- `disable-model-invocation`) so phases can hand off and the selector can route;
283
- per-phase side-effect discipline (e.g. "stop after one slice") is enforced in the
284
- skill **body**, which is the correct mechanism (invocation flags can't express it).
294
+ 1. **Invocation semantics are explicit in frontmatter.** `user-invocable`
295
+ controls whether a skill is a public command; `disable-model-invocation`
296
+ independently marks explicit-only public utilities and the internal
297
+ `devrites-lib` library. Model-invocable phases can still hand off and route;
298
+ per-phase side-effect discipline (for example, "stop after one slice") is
299
+ enforced in the skill **body**, because invocation flags cannot express it.
285
300
  2. **`context: fork` used selectively.** Verified it is a real field (isolated
286
301
  subagent, body-as-prompt, no conversation history). It is applied only to the three
287
302
  self-contained read-only audit skills (`devrites-audit simplify`,
@@ -298,6 +313,7 @@ acceptance criteria.
298
313
  ## Repository layout
299
314
 
300
315
  See the top-level tree in `README.md` and the installed-target tree in `usage.md`.
301
- Source pack lives under `pack/.claude/` (skills, agents, and rules); the installer copies
302
- it into a target project's `.claude/`, including DevRites' engineering rules in
303
- `.claude/skills/devrites-lib/reference/standards/`.
316
+ The canonical source pack lives under `pack/.claude/` (skills, agents, rules,
317
+ and Claude hook wiring). The build renders `pack/generated/` host artifacts;
318
+ the installer writes Claude assets under project `.claude/` and Codex assets
319
+ under `.agents/`, `.codex/`, and the managed `AGENTS.md` block.
@@ -12,7 +12,9 @@ Pick the smallest surface that keeps the behavior deterministic:
12
12
 
13
13
  Rules:
14
14
 
15
- - Install and update through npm: `npx devrites ...`. No Claude/Codex plugin path.
15
+ - npm (`npx devrites ...`) is the canonical distribution path. The supported
16
+ `curl | bash` bootstrap exists for environments without Node; neither path is
17
+ a Claude/Codex plugin or marketplace install.
16
18
  - Prefer the engine for gates; prompts may call gates, not reimplement them.
17
19
  - Prefer scripts for repo-local release/build glue that is not part of the user contract.
18
20
  - Do not add a dependency for what the Go engine or shell can do in a few lines.
package/docs/cli.md CHANGED
@@ -9,6 +9,9 @@ project root.
9
9
 
10
10
  Install DevRites normally, then run the engine from the project root:
11
11
 
12
+ The examples below are a curated working set. `devrites-engine help` is the
13
+ exhaustive current command and hook inventory.
14
+
12
15
  ```bash
13
16
  devrites-engine preamble # workspace digest for the active feature
14
17
  devrites-engine snapshot [slug] # machine-readable workspace/status snapshot
@@ -19,8 +22,10 @@ devrites-engine ledger sync <dir> # fold a feature's spec deltas into the
19
22
  devrites-engine ledger list|show <cap> # read the ledger — what the system already does
20
23
  devrites-engine context show --json # report root, active workspace, and host command forms
21
24
  devrites-engine timeline log|list # append/list session events, decisions, and state moves
22
- devrites-engine health record|list # append/list compact workspace health history
25
+ devrites-engine health run # run known project checks + record a code-health dashboard
26
+ devrites-engine health record|list # append/list manual or dashboard health history
23
27
  devrites-engine review-fingerprints [slug] # stable IDs for review findings; --write saves JSONL
28
+ devrites-engine reviewer-stats report --json # direct structured reviewer-dispatch verdicts
24
29
  devrites-engine progress [slug] # compact phase/slice footer
25
30
  devrites-engine resolve <qid> "<answer>" # answer a HITL gate
26
31
  devrites-engine close-out <slug> # archive a shipped feature and clear ACTIVE
@@ -34,7 +39,9 @@ The AFK-parsed read commands (`status`, `readiness`, `seal`, `spec-validate`,
34
39
  structured JSON contract and emits `schemaVersion: devrites.workspace.v1`
35
40
  directly rather than wrapping human text. Snapshot consumers should read
36
41
  `nextCommands.claude` or `nextCommands.codex` for the current host instead of
37
- hardcoding a `/rite-*` or `$rite-*` command form.
42
+ hardcoding a `/rite-*` or `$rite-*` command form. `context show --json` and
43
+ `reviewer-stats report --json` are also direct structured reports rather than
44
+ envelopes.
38
45
 
39
46
  The npm `devrites` shim remains the installer/updater/uninstaller entry point and
40
47
  proxies these engine subcommands when `devrites-engine` is installed. Install and
@@ -54,7 +54,7 @@ must say who runs them.
54
54
  | Command | Phase | Argument | What it does | Reads | Writes |
55
55
  |---|---|---|---|---|---|
56
56
  | [`/rite`](../pack/.claude/skills/rite/SKILL.md) | menu | `[subcommand]` | Compact menu + suggested next command. Pure router; does **not** read state — that's `/rite-status`. | — | — |
57
- | [`/rite-spec`](../pack/.claude/skills/rite-spec/SKILL.md) | spec | `<feature>` | **Start here.** Deep investigation → writes a product-focused `spec.md` (WHAT/WHY, requirements, ACs, boundaries, gaps closed with options, design references). Checks the shipped archive for prior art before speccing. Creates the workspace map. | codebase + codegraph/graphify + shipped archive (`devrites-engine archive-search`) | `README.md`/`feature.md`, `brief.md`, `spec.md`, `references/`, `references.md`, `questions.md`, `decisions.md`, `assumptions.md`, `state.md` |
57
+ | [`/rite-spec`](../pack/.claude/skills/rite-spec/SKILL.md) | spec | `<feature>` | **New feature.** Deep investigation → writes a product-focused `spec.md` (WHAT/WHY, requirements, ACs, boundaries, gaps closed with options, design references). Checks the shipped archive for prior art before speccing. Creates the workspace map. | codebase + codegraph/graphify + shipped archive (`devrites-engine archive-search`) | `README.md`/`feature.md`, `brief.md`, `spec.md`, `references/`, `references.md`, `questions.md`, `decisions.md`, `assumptions.md`, `state.md` |
58
58
  | [`/rite-temper`](../pack/.claude/skills/rite-temper/SKILL.md) | temper | `[slug] [--mode]` | **Optional, before define.** Strategic review of the readied spec: scope mode (expand / selective / hold-rigor / reduce-to-MVP) + pre-mortem + 9-dimension floor-gate; folds decisions into the spec via the Spec Drift Guard. Significance-gated; **mandatory in `/rite-autocomplete`**. Reviewer: `devrites-strategy-reviewer`. | `spec.md` + decisions/assumptions + design-brief | `strategy.md`, `spec.md`, `decisions.md`, `assumptions.md` |
59
59
  | [`/rite-define`](../pack/.claude/skills/rite-define/SKILL.md) | plan | `[slug]` | Turns the approved `spec.md` into architecture, plan, vertical `SLICE-###` task slices, traceability, and state. Reads `strategy.md` if present. | `spec.md` (+ `strategy.md`) + references | `architecture.md`, `plan.md`, `tasks.md`, `traceability.md`, `state.md`, `decisions.md` |
60
60
  | [`/rite-vet`](../pack/.claude/skills/rite-vet/SKILL.md) | vet | `[slug] [--cross-model] [--full]` | **Before build — every feature.** Engineering review of the defined plan: scope challenge (reuse / minimum-diff / complexity smell) + architecture / plan code-quality / test-coverage design / performance, confidence-banded with a quote-the-source verification gate; failure-mode + parallelization map. Hardens `plan.md` / `tasks.md` in place; writes the build-readable `test-plan.md`; acceptance-changing deltas route via the Spec Drift Guard. Runs on every plan — depth scales to stakes (light pass on simple plans, full on big/risky), never skipped; **always in `/rite-autocomplete`**. Reviewer: `devrites-plan-reviewer` (+ optional `--cross-model`). | `plan.md` + `tasks.md` + `spec.md` (+ `strategy.md`) | `eng-review.md`, `test-plan.md`, `plan.md`, `tasks.md`, `decisions.md`, `state.md` |
@@ -84,7 +84,11 @@ must say who runs them.
84
84
  | [`/rite-pressure-test`](../pack/.claude/skills/rite-pressure-test/SKILL.md) | utility | `[idea]` | Pressure-test a rough idea: 3–5 genuinely different options → converge on one with trade-off + hinge. | spec / surrounding code | `decisions.md` (optional) |
85
85
  | [`/rite-doctor`](../pack/.claude/skills/rite-doctor/SKILL.md) | diagnostic | `[--code \| --reindex]` | Diagnose DevRites install, workspace, and optional index health. `--reindex` explicitly runs the internal synchronous refresh. Triggers: "rite doctor", "is DevRites healthy", "reindex". | install + workspace + optional indexes | — |
86
86
 
87
- ## Internal skills (`user-invocable: false`, model-invoked)
87
+ ## Internal specialist skills (`user-invocable: false`, model-invoked)
88
+
89
+ The 11 specialist skills below are model-invoked. `devrites-lib` is the twelfth
90
+ internal skill, but it sets `disable-model-invocation: true` and serves only as
91
+ the shared reference library.
88
92
 
89
93
  | Skill | Triggered by | Role | Notable |
90
94
  |---|---|---|---|
@@ -16,9 +16,11 @@ Other subcommands (hooks, `footprint`, `tick-afk`, mutating commands) do not acc
16
16
  `--json` — they are not parsed for a decision. This is deliberate scope, not an
17
17
  oversight; the flag is added where a machine reads the result.
18
18
 
19
- Exception: `snapshot` and `context show --json` are already direct structured reports, not
20
- envelopes. `context show --json` emits `root`, `project`, `activeWorkspace`, `source`,
21
- `hostCommands`, and `status` so wrappers can tell where DevRites will act.
19
+ Exception: `snapshot`, `context show --json`, and
20
+ `reviewer-stats report --json` are already direct structured reports, not
21
+ envelopes. `context show --json` emits `root`, `project`, `activeWorkspace`,
22
+ `source`, `hostCommands`, and `status` so wrappers can tell where DevRites will
23
+ act; reviewer stats emits the deterministic per-reviewer dispatch verdicts.
22
24
 
23
25
  ## Envelope
24
26
 
@@ -1,11 +1,14 @@
1
1
  # `devrites-engine` commands (engine core)
2
2
 
3
3
  The `devrites-engine` binary is the deterministic control plane over a project's
4
- `.devrites/` state. It makes **zero model or network calls** the in-session
5
- LLM stays the judgment data plane; the engine only sequences, gates, and reads.
4
+ `.devrites/` state. Workspace state, gate, and derivation commands make no model
5
+ calls and are network-free; explicit install/update/source-cache I/O is isolated under
6
+ `engine/internal/iohooks` (ADR-0008). The in-session LLM remains the judgment
7
+ data plane.
6
8
 
7
- This covers the commands added in issues 03–07, on top of `status`
8
- (see [state-schema.md](state-schema.md)).
9
+ This page expands selected contracts. Run `devrites-engine help` for the
10
+ exhaustive current command and hook inventory; see
11
+ [state-schema.md](state-schema.md) for `status` and the underlying state model.
9
12
 
10
13
  ## Exit codes
11
14
 
@@ -49,8 +52,8 @@ $ echo $?
49
52
  one legible verdict:
50
53
 
51
54
  ```
52
- binary: 2.6.1
53
- pack: 2.6.1
55
+ binary: X.Y.Z
56
+ pack: X.Y.Z
54
57
  state-schema: v1 (binary supports v1)
55
58
  verdict: ok: binary, pack, and state schema are compatible
56
59
  ```
@@ -90,7 +93,8 @@ readable, and the migration path is:
90
93
  timestamped `.migrate-backup-*` directory before anything changes;
91
94
  - **lossless** — canonical files are added without deleting aliases. `README.md`
92
95
  is the preferred workspace map while `feature.md` / `index.md` remain readable;
93
- `evidence.md` is preferred while `proof.md` remains a proof alias.
96
+ `state.md` is preferred while `status.md` remains a cursor alias; `evidence.md`
97
+ is preferred while `proof.md` remains a proof alias.
94
98
 
95
99
  The phase is derived from the legacy `state.md`, defaulting to `build` when it
96
100
  can't be read.
@@ -199,14 +203,22 @@ Records are JSONL, append-only, and safe for concurrent short-lived engine calls
199
203
  update DevRites through the npm flow (`npx devrites ...`); this command is part of the installed
200
204
  engine, not a Claude/Codex plugin distribution path.
201
205
 
202
- ## `health` — compact quality history
206
+ ## `health` — code-health dashboard and history
203
207
 
204
- `devrites-engine health record|list` keeps `.devrites/health-history.jsonl`, a small longitudinal
205
- quality signal for the workspace. The score is intentionally caller-owned: an agent, CI job, or
206
- human can record the observed health after a review, quality gate, or cleanup pass without the
207
- engine pretending to infer a universal metric.
208
+ `devrites-engine health`, `health run`, and `health check` run the known project
209
+ checks (available npm test/lint/typecheck/build scripts, `go test`, `pytest`, and
210
+ DevRites scans where present), print a PASS/WARN/FAIL dashboard, and append the
211
+ result to `.devrites/health.jsonl`. These commands execute project checks; they
212
+ are not a substitute for reviewing those scripts before use.
213
+
214
+ The legacy `health record|list` surface remains available for manual scores.
215
+ `record` appends `.devrites/health-history.jsonl`; `list` tails
216
+ `.devrites/health.jsonl` when dashboard history exists, otherwise the legacy file.
217
+ Manual scores are intentionally caller-owned: name the observed evidence rather
218
+ than asking the engine to infer a universal metric.
208
219
 
209
220
  ```bash
221
+ devrites-engine health run
210
222
  devrites-engine health record 8.5 "tests green; one follow-up" --note "review-fingerprints stable"
211
223
  devrites-engine health list --limit 10
212
224
  ```
@@ -240,8 +252,9 @@ outcome to `.devrites/reviewer-stats.jsonl` (cross-feature, append-only).
240
252
  - `run (insurance — never gated)` — `security-auditor` and `doubt-reviewer`: a dry streak is
241
253
  success, never a reason to skip.
242
254
  - `gate-candidate` — a conditional reviewer with zero surviving findings in its last 10+
243
- dispatches; the fan-out may skip it as a *recorded* skip (see
244
- `parallel-dispatch.md § Hit-rate gating`).
255
+ dispatches; the fan-out may skip it as a *recorded* skip (see the shared
256
+ `pack/.claude/skills/devrites-lib/reference/parallel-dispatch.md` contract,
257
+ § Hit-rate gating).
245
258
  - `run` — everything else.
246
259
 
247
260
  ```bash