devrites 1.19.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/.claude-plugin/marketplace.json +24 -0
- package/.claude-plugin/plugin.json +43 -0
- package/CHANGELOG.md +391 -0
- package/LICENSE +56 -0
- package/NOTICE.md +18 -0
- package/README.md +582 -0
- package/SECURITY.md +193 -0
- package/bin/devrites.mjs +100 -0
- package/docs/architecture.md +272 -0
- package/docs/cli-mcp.md +57 -0
- package/docs/command-map.md +143 -0
- package/docs/flow.md +360 -0
- package/docs/release.md +29 -0
- package/docs/skills.md +214 -0
- package/docs/usage.md +325 -0
- package/install.sh +359 -0
- package/mcp/devrites-mcp.mjs +103 -0
- package/pack/.claude/agents/devrites-code-reviewer.md +50 -0
- package/pack/.claude/agents/devrites-doubt-reviewer.md +55 -0
- package/pack/.claude/agents/devrites-frontend-reviewer.md +52 -0
- package/pack/.claude/agents/devrites-performance-reviewer.md +47 -0
- package/pack/.claude/agents/devrites-plan-reviewer.md +79 -0
- package/pack/.claude/agents/devrites-security-auditor.md +53 -0
- package/pack/.claude/agents/devrites-simplifier-reviewer.md +75 -0
- package/pack/.claude/agents/devrites-slice-wright.md +181 -0
- package/pack/.claude/agents/devrites-spec-reviewer.md +72 -0
- package/pack/.claude/agents/devrites-strategy-reviewer.md +62 -0
- package/pack/.claude/agents/devrites-test-analyst.md +47 -0
- package/pack/.claude/hooks/devrites-a1-guard.sh +81 -0
- package/pack/.claude/hooks/devrites-allow.sh +44 -0
- package/pack/.claude/hooks/devrites-cursor.sh +28 -0
- package/pack/.claude/hooks/devrites-orient.sh +53 -0
- package/pack/.claude/hooks/devrites-redwatch.sh +39 -0
- package/pack/.claude/hooks/devrites-refresh-indexes.sh +127 -0
- package/pack/.claude/hooks/devrites-reviewer-readonly.sh +28 -0
- package/pack/.claude/hooks/devrites-statusline.sh +18 -0
- package/pack/.claude/hooks/devrites-stop-gate.sh +45 -0
- package/pack/.claude/hooks/devrites-wright-scope.sh +35 -0
- package/pack/.claude/hooks/hooks.json +52 -0
- package/pack/.claude/rules/README.md +48 -0
- package/pack/.claude/rules/afk-hitl.md +245 -0
- package/pack/.claude/rules/agents.md +98 -0
- package/pack/.claude/rules/anti-patterns.md +48 -0
- package/pack/.claude/rules/code-review.md +38 -0
- package/pack/.claude/rules/coding-style.md +55 -0
- package/pack/.claude/rules/context-hygiene.md +97 -0
- package/pack/.claude/rules/core.md +119 -0
- package/pack/.claude/rules/development-workflow.md +40 -0
- package/pack/.claude/rules/documentation.md +27 -0
- package/pack/.claude/rules/error-handling.md +33 -0
- package/pack/.claude/rules/git-workflow.md +35 -0
- package/pack/.claude/rules/hooks.md +38 -0
- package/pack/.claude/rules/patterns.md +45 -0
- package/pack/.claude/rules/performance.md +27 -0
- package/pack/.claude/rules/prose-style.md +101 -0
- package/pack/.claude/rules/security.md +63 -0
- package/pack/.claude/rules/testing.md +88 -0
- package/pack/.claude/rules/tooling.md +72 -0
- package/pack/.claude/settings.json +53 -0
- package/pack/.claude/skills/devrites-api-interface/SKILL.md +45 -0
- package/pack/.claude/skills/devrites-audit/SKILL.md +73 -0
- package/pack/.claude/skills/devrites-browser-proof/SKILL.md +38 -0
- package/pack/.claude/skills/devrites-debug-recovery/SKILL.md +50 -0
- package/pack/.claude/skills/devrites-debug-recovery/reference/build-the-loop.md +47 -0
- package/pack/.claude/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +17 -0
- package/pack/.claude/skills/devrites-debug-recovery/reference/hypotheses.md +17 -0
- package/pack/.claude/skills/devrites-debug-recovery/reference/instrumentation.md +21 -0
- package/pack/.claude/skills/devrites-debug-recovery/reference/regression-test.md +31 -0
- package/pack/.claude/skills/devrites-doubt/SKILL.md +75 -0
- package/pack/.claude/skills/devrites-frontend-craft/SKILL.md +96 -0
- package/pack/.claude/skills/devrites-frontend-craft/reference/craft.md +59 -0
- package/pack/.claude/skills/devrites-frontend-craft/reference/design-references.md +116 -0
- package/pack/.claude/skills/devrites-frontend-craft/reference/fullstack.md +45 -0
- package/pack/.claude/skills/devrites-frontend-craft/reference/quality-standards.md +215 -0
- package/pack/.claude/skills/devrites-frontend-craft/reference/reuse-first.md +59 -0
- package/pack/.claude/skills/devrites-frontend-craft/reference/shape.md +60 -0
- package/pack/.claude/skills/devrites-interview/SKILL.md +81 -0
- package/pack/.claude/skills/devrites-lib/SKILL.md +76 -0
- package/pack/.claude/skills/devrites-lib/scripts/analyze.sh +78 -0
- package/pack/.claude/skills/devrites-lib/scripts/check-acceptance.sh +75 -0
- package/pack/.claude/skills/devrites-lib/scripts/close-out.sh +47 -0
- package/pack/.claude/skills/devrites-lib/scripts/conventions.py +273 -0
- package/pack/.claude/skills/devrites-lib/scripts/coverage.sh +51 -0
- package/pack/.claude/skills/devrites-lib/scripts/devrites.sh +69 -0
- package/pack/.claude/skills/devrites-lib/scripts/doctor.sh +92 -0
- package/pack/.claude/skills/devrites-lib/scripts/evidence-fresh.sh +63 -0
- package/pack/.claude/skills/devrites-lib/scripts/footprint.sh +45 -0
- package/pack/.claude/skills/devrites-lib/scripts/learnings.sh +74 -0
- package/pack/.claude/skills/devrites-lib/scripts/mutation-gate.sh +52 -0
- package/pack/.claude/skills/devrites-lib/scripts/package-existence.sh +68 -0
- package/pack/.claude/skills/devrites-lib/scripts/preamble.sh +76 -0
- package/pack/.claude/skills/devrites-lib/scripts/progress.sh +103 -0
- package/pack/.claude/skills/devrites-lib/scripts/readiness.sh +62 -0
- package/pack/.claude/skills/devrites-lib/scripts/reconcile.sh +123 -0
- package/pack/.claude/skills/devrites-lib/scripts/resolve.sh +279 -0
- package/pack/.claude/skills/devrites-lib/scripts/stuck.sh +67 -0
- package/pack/.claude/skills/devrites-lib/scripts/test-integrity.sh +87 -0
- package/pack/.claude/skills/devrites-lib/scripts/tick-afk.sh +52 -0
- package/pack/.claude/skills/devrites-prose-craft/SKILL.md +105 -0
- package/pack/.claude/skills/devrites-prose-craft/reference/banned-phrases.md +95 -0
- package/pack/.claude/skills/devrites-prose-craft/reference/examples.md +88 -0
- package/pack/.claude/skills/devrites-prose-craft/reference/structures.md +134 -0
- package/pack/.claude/skills/devrites-refresh-indexes/SKILL.md +54 -0
- package/pack/.claude/skills/devrites-source-driven/SKILL.md +36 -0
- package/pack/.claude/skills/devrites-ux-shape/SKILL.md +121 -0
- package/pack/.claude/skills/devrites-ux-shape/reference/brief-template.md +93 -0
- package/pack/.claude/skills/devrites-ux-shape/reference/visual-direction-probe.md +48 -0
- package/pack/.claude/skills/rite/SKILL.md +135 -0
- package/pack/.claude/skills/rite/reference/menu.md +32 -0
- package/pack/.claude/skills/rite-adopt/SKILL.md +83 -0
- package/pack/.claude/skills/rite-adopt/reference/adoption.md +58 -0
- package/pack/.claude/skills/rite-adopt/reference/anti-patterns.md +19 -0
- package/pack/.claude/skills/rite-autocomplete/SKILL.md +96 -0
- package/pack/.claude/skills/rite-autocomplete/reference/decision-policy.md +35 -0
- package/pack/.claude/skills/rite-autocomplete/reference/loop.md +54 -0
- package/pack/.claude/skills/rite-autocomplete/reference/stop-conditions.md +59 -0
- package/pack/.claude/skills/rite-build/SKILL.md +261 -0
- package/pack/.claude/skills/rite-build/reference/afk-discipline.md +145 -0
- package/pack/.claude/skills/rite-build/reference/anti-patterns.md +25 -0
- package/pack/.claude/skills/rite-build/reference/checkpoint-protocol.md +149 -0
- package/pack/.claude/skills/rite-build/reference/evidence-standard.md +32 -0
- package/pack/.claude/skills/rite-build/reference/frontend-trigger.md +39 -0
- package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +38 -0
- package/pack/.claude/skills/rite-build/reference/spec-drift-guard.md +43 -0
- package/pack/.claude/skills/rite-build/reference/tdd.md +26 -0
- package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +115 -0
- package/pack/.claude/skills/rite-define/SKILL.md +157 -0
- package/pack/.claude/skills/rite-define/reference/anti-patterns.md +25 -0
- package/pack/.claude/skills/rite-define/reference/gates.md +152 -0
- package/pack/.claude/skills/rite-define/reference/plan-template.md +65 -0
- package/pack/.claude/skills/rite-doctor/SKILL.md +50 -0
- package/pack/.claude/skills/rite-frame/SKILL.md +116 -0
- package/pack/.claude/skills/rite-frame/reference/failure-modes.md +68 -0
- package/pack/.claude/skills/rite-handoff/SKILL.md +95 -0
- package/pack/.claude/skills/rite-handoff/reference/handoff-template.md +34 -0
- package/pack/.claude/skills/rite-learn/SKILL.md +82 -0
- package/pack/.claude/skills/rite-plan/SKILL.md +82 -0
- package/pack/.claude/skills/rite-plan/reference/anti-patterns.md +24 -0
- package/pack/.claude/skills/rite-plan/reference/dependency-graph.md +33 -0
- package/pack/.claude/skills/rite-plan/reference/replan-and-repair.md +42 -0
- package/pack/.claude/skills/rite-plan/reference/slicing.md +52 -0
- package/pack/.claude/skills/rite-plan/reference/task-breakdown.md +34 -0
- package/pack/.claude/skills/rite-polish/SKILL.md +90 -0
- package/pack/.claude/skills/rite-polish/reference/anti-ai-slop.md +177 -0
- package/pack/.claude/skills/rite-polish/reference/anti-patterns.md +27 -0
- package/pack/.claude/skills/rite-polish/reference/backend-polish.md +80 -0
- package/pack/.claude/skills/rite-polish/reference/browser-polish-evidence.md +31 -0
- package/pack/.claude/skills/rite-polish/reference/code.md +85 -0
- package/pack/.claude/skills/rite-polish/reference/design-system-discovery.md +35 -0
- package/pack/.claude/skills/rite-polish/reference/harden-checklist.md +109 -0
- package/pack/.claude/skills/rite-polish/reference/ui.md +136 -0
- package/pack/.claude/skills/rite-pressure-test/SKILL.md +43 -0
- package/pack/.claude/skills/rite-prototype/SKILL.md +87 -0
- package/pack/.claude/skills/rite-prove/SKILL.md +120 -0
- package/pack/.claude/skills/rite-prove/reference/anti-patterns.md +25 -0
- package/pack/.claude/skills/rite-prove/reference/browser-proof.md +26 -0
- package/pack/.claude/skills/rite-prove/reference/failure-triage.md +25 -0
- package/pack/.claude/skills/rite-prove/reference/proof-ladder.md +26 -0
- package/pack/.claude/skills/rite-prove/reference/test-command-discovery.md +30 -0
- package/pack/.claude/skills/rite-quick/SKILL.md +81 -0
- package/pack/.claude/skills/rite-resolve/SKILL.md +113 -0
- package/pack/.claude/skills/rite-resolve/reference/answer-protocol.md +114 -0
- package/pack/.claude/skills/rite-review/SKILL.md +170 -0
- package/pack/.claude/skills/rite-review/reference/anti-patterns.md +32 -0
- package/pack/.claude/skills/rite-review/reference/cognitive-load.md +90 -0
- package/pack/.claude/skills/rite-review/reference/feature-scoped-review.md +26 -0
- package/pack/.claude/skills/rite-review/reference/five-axis-review.md +46 -0
- package/pack/.claude/skills/rite-review/reference/nielsen-heuristics.md +130 -0
- package/pack/.claude/skills/rite-review/reference/parallel-dispatch.md +62 -0
- package/pack/.claude/skills/rite-review/reference/performance-review.md +28 -0
- package/pack/.claude/skills/rite-review/reference/security-review.md +32 -0
- package/pack/.claude/skills/rite-seal/SKILL.md +183 -0
- package/pack/.claude/skills/rite-seal/reference/anti-patterns.md +27 -0
- package/pack/.claude/skills/rite-seal/reference/conventions-ledger.md +63 -0
- package/pack/.claude/skills/rite-seal/reference/final-evidence.md +72 -0
- package/pack/.claude/skills/rite-seal/reference/go-no-go.md +37 -0
- package/pack/.claude/skills/rite-seal/reference/parallel-dispatch.md +69 -0
- package/pack/.claude/skills/rite-seal/reference/risk-and-rollback.md +30 -0
- package/pack/.claude/skills/rite-seal/reference/seal-template.md +36 -0
- package/pack/.claude/skills/rite-ship/SKILL.md +120 -0
- package/pack/.claude/skills/rite-ship/reference/anti-patterns.md +25 -0
- package/pack/.claude/skills/rite-ship/reference/close-out.md +31 -0
- package/pack/.claude/skills/rite-ship/reference/design-memory.md +120 -0
- package/pack/.claude/skills/rite-ship/reference/git-ship.md +42 -0
- package/pack/.claude/skills/rite-ship/reference/ship-template.md +33 -0
- package/pack/.claude/skills/rite-spec/SKILL.md +126 -0
- package/pack/.claude/skills/rite-spec/reference/acceptance-criteria.md +31 -0
- package/pack/.claude/skills/rite-spec/reference/anti-patterns.md +25 -0
- package/pack/.claude/skills/rite-spec/reference/interview-patterns.md +56 -0
- package/pack/.claude/skills/rite-spec/reference/investigation.md +64 -0
- package/pack/.claude/skills/rite-spec/reference/question-protocol.md +61 -0
- package/pack/.claude/skills/rite-spec/reference/references-intake.md +57 -0
- package/pack/.claude/skills/rite-spec/reference/spec-checklists.md +73 -0
- package/pack/.claude/skills/rite-spec/reference/spec-template.md +124 -0
- package/pack/.claude/skills/rite-spec/reference/state-workspace.md +159 -0
- package/pack/.claude/skills/rite-status/SKILL.md +101 -0
- package/pack/.claude/skills/rite-temper/SKILL.md +119 -0
- package/pack/.claude/skills/rite-temper/reference/anti-patterns.md +29 -0
- package/pack/.claude/skills/rite-temper/reference/review-dimensions.md +65 -0
- package/pack/.claude/skills/rite-temper/reference/scope-modes.md +53 -0
- package/pack/.claude/skills/rite-temper/reference/significance.md +46 -0
- package/pack/.claude/skills/rite-temper/reference/strategy-template.md +90 -0
- package/pack/.claude/skills/rite-vet/SKILL.md +155 -0
- package/pack/.claude/skills/rite-vet/reference/anti-patterns.md +29 -0
- package/pack/.claude/skills/rite-vet/reference/artifacts.md +135 -0
- package/pack/.claude/skills/rite-vet/reference/cross-model.md +41 -0
- package/pack/.claude/skills/rite-vet/reference/depth.md +53 -0
- package/pack/.claude/skills/rite-vet/reference/eng-lenses.md +48 -0
- package/pack/.claude/skills/rite-vet/reference/review-axes.md +167 -0
- package/pack/.claude/skills/rite-zoom-out/SKILL.md +75 -0
- package/package.json +68 -0
- package/scripts/build-release-tarball.sh +74 -0
- package/scripts/check-cross-refs.py +121 -0
- package/scripts/check-no-global-writes.sh +44 -0
- package/scripts/check-rule-uniqueness.sh +73 -0
- package/scripts/devrites-detect.sh +175 -0
- package/scripts/eval-runner.py +273 -0
- package/scripts/grade-feature.sh +104 -0
- package/scripts/install-lib.sh +83 -0
- package/scripts/pin.sh +166 -0
- package/scripts/render-eval-summary.py +48 -0
- package/scripts/run-evals.sh +149 -0
- package/scripts/run-outcome-evals.sh +49 -0
- package/scripts/scan-pack-security.py +209 -0
- package/scripts/scan-supply-chain-iocs.py +127 -0
- package/scripts/supply-chain-iocs.json +11 -0
- package/scripts/sync-version.sh +56 -0
- package/scripts/validate-frontmatter.py +149 -0
- package/scripts/validate-workflow-security.py +86 -0
- package/scripts/validate.sh +234 -0
- package/uninstall.sh +137 -0
- package/update.sh +196 -0
package/SECURITY.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Security policy
|
|
2
|
+
|
|
3
|
+
## Reporting a vulnerability
|
|
4
|
+
|
|
5
|
+
If you believe you have found a security issue in DevRites, please report it
|
|
6
|
+
**privately**. Do not open a public GitHub issue.
|
|
7
|
+
|
|
8
|
+
- **Preferred channel:** open a private security advisory on GitHub —
|
|
9
|
+
<https://github.com/ViktorsBaikers/DevRites/security/advisories/new>.
|
|
10
|
+
- **Alternate channel:** email the maintainer via the contact link on the
|
|
11
|
+
GitHub profile <https://github.com/ViktorsBaikers>.
|
|
12
|
+
|
|
13
|
+
Please include:
|
|
14
|
+
|
|
15
|
+
- A clear description of the vulnerability and its impact.
|
|
16
|
+
- A minimal reproduction (commands, files, or a target project layout).
|
|
17
|
+
- The DevRites version (commit SHA or release tag) and Claude Code version.
|
|
18
|
+
- Your name / handle for credit (optional).
|
|
19
|
+
|
|
20
|
+
You should receive an acknowledgement within **5 business days** and a triage
|
|
21
|
+
verdict within **14 days**. Coordinated disclosure window is **90 days** from
|
|
22
|
+
the acknowledgement unless a shorter or longer window is mutually agreed.
|
|
23
|
+
|
|
24
|
+
## Supported versions
|
|
25
|
+
|
|
26
|
+
DevRites is pre-1.0. Only the latest minor release line receives security
|
|
27
|
+
updates.
|
|
28
|
+
|
|
29
|
+
| Version | Supported |
|
|
30
|
+
|---|---|
|
|
31
|
+
| `0.1.x` | yes |
|
|
32
|
+
| earlier | no |
|
|
33
|
+
|
|
34
|
+
Once a `1.0` release ships, the latest two minor lines will be supported.
|
|
35
|
+
|
|
36
|
+
## DevRites security model
|
|
37
|
+
|
|
38
|
+
### Scope
|
|
39
|
+
|
|
40
|
+
DevRites is a Claude Code **skills pack**: Markdown skill files, a few helper
|
|
41
|
+
shell scripts, a bash installer, and (in plugin form) a `.claude-plugin/`
|
|
42
|
+
manifest. It ships **no binary and no network service**. The only server is an
|
|
43
|
+
**optional, opt-in MCP stdio server** (`mcp/devrites-mcp.mjs`) that speaks
|
|
44
|
+
JSON-RPC over stdin/stdout (no port, no socket), is not installed or registered
|
|
45
|
+
by default, and only shells out to the local `devrites` CLI — read/gate ops over
|
|
46
|
+
`.devrites/` plus a single `ACTIVE`-pointer write. The attack surface is the
|
|
47
|
+
content of the skill files plus the installer.
|
|
48
|
+
|
|
49
|
+
### Supply-chain self-scan (shipped pack)
|
|
50
|
+
|
|
51
|
+
Because the skill files **are** the attack surface, CI scans the shipped pack
|
|
52
|
+
(`pack/.claude/`) on every PR and fails the build (blocking, not advisory) on:
|
|
53
|
+
|
|
54
|
+
- **Prompt-injection patterns** — the "ignore previous instructions" family,
|
|
55
|
+
system-prompt overrides, permission-escalation, and data-exfiltration phrasing.
|
|
56
|
+
- **Hidden unicode** — bidi controls, zero-width characters, and homoglyph
|
|
57
|
+
confusables (a word mixing ASCII with look-alike Cyrillic/Greek letters) that a
|
|
58
|
+
human reviewer can't see in a diff.
|
|
59
|
+
|
|
60
|
+
Run it locally with `python3 scripts/scan-pack-security.py pack/.claude`. A
|
|
61
|
+
finding prints as `FINDING <file>:<line>: <class>: <excerpt>`. If the match is
|
|
62
|
+
DevRites' own *defensive* content (e.g. a rule that quotes an attack string, or a
|
|
63
|
+
QA checklist that demonstrates an adversarial character), add an auditable
|
|
64
|
+
suppression on the line — `<!-- pack-scan-ignore: <reason> -->` — or opt a whole
|
|
65
|
+
file out of one class with `<!-- pack-scan-ignore-file: injection -->`.
|
|
66
|
+
Suppressions live in the file, so every exception is visible in the diff and
|
|
67
|
+
reviewable; never suppress a hidden-unicode finding you can't explain.
|
|
68
|
+
|
|
69
|
+
### State loading (project-local script, no `!` injection)
|
|
70
|
+
|
|
71
|
+
`/rite`, `/rite-status`, and every workspace-operating skill load state by running
|
|
72
|
+
a **read-only shell script via the `Bash` tool** — *not* Claude Code's
|
|
73
|
+
preprocessing-only `` !`<command>` `` dynamic-context injection, which DevRites
|
|
74
|
+
**removed** for cross-harness portability:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
P=.claude/skills/devrites-lib/scripts/preamble.sh
|
|
78
|
+
[ -f "$P" ] && bash "$P" || echo "(unavailable — read state.md directly)"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`preamble.sh` is a project-local read of DevRites' own `.devrites/` state: no user
|
|
82
|
+
input is concatenated into a command, no network access, no write side effects.
|
|
83
|
+
The gate scripts (`readiness.sh`, `evidence-fresh.sh`, `check-acceptance.sh`) are
|
|
84
|
+
likewise read-only; only the explicit mutators (`resolve.sh`, `tick-afk.sh`,
|
|
85
|
+
`close-out.sh`, and the CLI's `use`) write, and only under `.devrites/`.
|
|
86
|
+
|
|
87
|
+
If your environment disallows skill-initiated shell execution, the scripts simply
|
|
88
|
+
don't run — each skill degrades gracefully to reading `state.md` directly (the
|
|
89
|
+
`|| echo "(… unavailable …)"` fallback above), and the rest of the pack is
|
|
90
|
+
unaffected.
|
|
91
|
+
|
|
92
|
+
### Auto-trigger is deliberate
|
|
93
|
+
|
|
94
|
+
All `rite-*` skills are **auto-invocable** by Claude when their descriptions
|
|
95
|
+
match the user's intent. This is a conscious DevRites design choice (see
|
|
96
|
+
`DECISIONS.md` Q3). The safety nets are:
|
|
97
|
+
|
|
98
|
+
- **Body discipline**: every skill stops at its phase boundary. `rite-build`
|
|
99
|
+
stops after one slice, `rite-prove` runs proofs only when all slices are
|
|
100
|
+
built, etc.
|
|
101
|
+
- **Readiness gates**: each rite reads `.devrites/work/<slug>/state.md`
|
|
102
|
+
before acting; phases out of order refuse to run.
|
|
103
|
+
- **Spec Drift Guard**: any deviation from the spec halts and routes to
|
|
104
|
+
`rite-plan`.
|
|
105
|
+
- **Interactive type-GO confirmation** in `rite-ship` before irreversible
|
|
106
|
+
git actions (commit, push, tag) — present even with auto-trigger; `rite-seal`
|
|
107
|
+
only decides GO/NO-GO.
|
|
108
|
+
|
|
109
|
+
If you prefer explicit-only invocation in a given project, add a Claude Code
|
|
110
|
+
`permissions` rule disabling `Skill(rite-*)` auto-invocation in that
|
|
111
|
+
project's `.claude/settings.json`.
|
|
112
|
+
|
|
113
|
+
### Installer safety
|
|
114
|
+
|
|
115
|
+
The bash installer (`install.sh`) refuses any target under `~/.claude`
|
|
116
|
+
(`GUARD:no-global` block) and writes only to a manifest-tracked file list.
|
|
117
|
+
`./uninstall.sh` removes exactly the manifested files. The
|
|
118
|
+
`.devrites/` runtime state in the target project is preserved across
|
|
119
|
+
uninstall.
|
|
120
|
+
|
|
121
|
+
The installer touches no global state. It does not invoke `sudo`, modify
|
|
122
|
+
shell rc files, fetch remote code, or alter Claude Code settings.
|
|
123
|
+
|
|
124
|
+
### Plugin install path
|
|
125
|
+
|
|
126
|
+
When installed via `claude plugin install devrites@devrites-marketplace`,
|
|
127
|
+
the plugin runtime owns file placement. DevRites does not ship a post-install
|
|
128
|
+
hook that modifies user files. The plugin manifest ships only skills and agents —
|
|
129
|
+
the engineering rules are not delivered by the plugin and are never written into
|
|
130
|
+
the user's `~/.claude/CLAUDE.md` (add them with a `--rules-only` bash install).
|
|
131
|
+
|
|
132
|
+
### Recommended Claude Code permissions for managed deployments
|
|
133
|
+
|
|
134
|
+
For organizations evaluating DevRites under a managed Claude Code policy:
|
|
135
|
+
|
|
136
|
+
```jsonc
|
|
137
|
+
{
|
|
138
|
+
"permissions": {
|
|
139
|
+
"Skill(rite-seal)": "ask",
|
|
140
|
+
"Bash(git push *)": "ask",
|
|
141
|
+
"Bash(git tag *)": "ask"
|
|
142
|
+
},
|
|
143
|
+
"disableSkillShellExecution": true
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The first three lines surface a confirmation prompt before any irreversible
|
|
148
|
+
git action; the last disables the `/rite` and `/rite-status` dynamic-state
|
|
149
|
+
read described above (DevRites still works).
|
|
150
|
+
|
|
151
|
+
### Hooks (auto-approve scope + orientation)
|
|
152
|
+
|
|
153
|
+
DevRites ships two `Bash`-matched hooks (`pack/.claude/hooks/`, wired via the
|
|
154
|
+
plugin's `hooks.json` or a seeded `.claude/settings.json`):
|
|
155
|
+
|
|
156
|
+
- **`devrites-allow.sh` (PreToolUse)** — auto-approves *only* the five **read-only**
|
|
157
|
+
helper scripts (`preamble.sh`, `progress.sh`, `readiness.sh`, `evidence-fresh.sh`,
|
|
158
|
+
`check-acceptance.sh`) so they stop prompting on every skill run. It is **fail-open**:
|
|
159
|
+
it never denies, parses the command, and emits an `allow` *only* when the command runs
|
|
160
|
+
one of those five scripts **and** contains no dangerous/exfiltration tokens
|
|
161
|
+
(`rm`, `>`/redirects, `curl`/`wget`, `sudo`, `chmod`, `$(...)`/backticks, `eval`,
|
|
162
|
+
package managers, `git push/commit/reset`, …). Mutating scripts (`resolve.sh`,
|
|
163
|
+
`tick-afk.sh`, `close-out.sh`) are **deliberately excluded** and still prompt. On any
|
|
164
|
+
parse failure or non-match it emits nothing — Claude Code's normal permission flow is
|
|
165
|
+
untouched. It widens approval for read-only orientation; it never widens it for anything
|
|
166
|
+
that writes, deletes, or reaches the network.
|
|
167
|
+
- **`devrites-orient.sh` (SessionStart)** — read-only; injects the active feature's
|
|
168
|
+
`preamble.sh` digest as session context, and stays silent when no `.devrites/` workspace
|
|
169
|
+
is active. No tool approval, no writes.
|
|
170
|
+
|
|
171
|
+
Delete `.claude/settings.json` (or disable the plugin) to remove both. The seeded
|
|
172
|
+
settings file is never overwritten on update, so your own permission rules are safe.
|
|
173
|
+
|
|
174
|
+
### Third-party trust
|
|
175
|
+
|
|
176
|
+
DevRites vendors no third-party code (see `NOTICE.md`). It depends on Claude
|
|
177
|
+
Code itself and, optionally and at the user's choice, on codegraph /
|
|
178
|
+
graphify / browser-harness — each of which is invoked through its own
|
|
179
|
+
documented interface, not bundled.
|
|
180
|
+
|
|
181
|
+
### Known non-issues
|
|
182
|
+
|
|
183
|
+
- **`!` injection in `/rite`** — local read of own state; safe. See above.
|
|
184
|
+
- **`Write` / `Edit` tool allowance in `rite-*` skills** — required to
|
|
185
|
+
author `.devrites/` and project files. No skill grants `Bash(*)`.
|
|
186
|
+
- **Auto-trigger** — deliberate design choice; mitigated as above.
|
|
187
|
+
|
|
188
|
+
### CVE relevance
|
|
189
|
+
|
|
190
|
+
DevRites does not ship `permissions.defaultMode: bypassPermissions` in any
|
|
191
|
+
file (cf. **CVE-2026-33068**, workspace-trust bypass via committed bypass
|
|
192
|
+
mode). The installer refuses to write any `defaultMode: bypassPermissions`
|
|
193
|
+
into target projects.
|
package/bin/devrites.mjs
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// devrites — npx entry point for the DevRites installer.
|
|
3
|
+
//
|
|
4
|
+
// A thin shim over the bundled bash installers. The npm package ships
|
|
5
|
+
// install.sh / uninstall.sh / update.sh alongside pack/ and scripts/, so the
|
|
6
|
+
// installer's network-bootstrap branch is skipped and the install runs offline,
|
|
7
|
+
// locked to whatever @version was invoked. The bash scripts remain the single
|
|
8
|
+
// source of truth for all install logic, flags, manifest, and guards.
|
|
9
|
+
import { spawnSync } from 'node:child_process';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
import { dirname, join } from 'node:path';
|
|
12
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
13
|
+
|
|
14
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const root = dirname(here); // bin/ -> package root
|
|
16
|
+
|
|
17
|
+
const SUBCOMMANDS = {
|
|
18
|
+
install: 'install.sh',
|
|
19
|
+
add: 'install.sh',
|
|
20
|
+
uninstall: 'uninstall.sh',
|
|
21
|
+
remove: 'uninstall.sh',
|
|
22
|
+
update: 'update.sh',
|
|
23
|
+
upgrade: 'update.sh',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
function pkgVersion() {
|
|
27
|
+
try {
|
|
28
|
+
return JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')).version || 'unknown';
|
|
29
|
+
} catch {
|
|
30
|
+
return 'unknown';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function printHelp() {
|
|
35
|
+
process.stdout.write(`devrites — install the full DevRites pack into a project
|
|
36
|
+
|
|
37
|
+
Usage:
|
|
38
|
+
npx devrites [install] [flags] Install skills + agents + rules + hooks (default)
|
|
39
|
+
npx devrites uninstall [flags] Remove a DevRites install (preserves .devrites/ state)
|
|
40
|
+
npx devrites update [flags] Upgrade an existing install in place
|
|
41
|
+
|
|
42
|
+
Common flags (passed straight through to the installer):
|
|
43
|
+
--target DIR Install into DIR (default: current directory)
|
|
44
|
+
--dry-run Show the plan, change nothing
|
|
45
|
+
--force Overwrite existing non-DevRites files
|
|
46
|
+
--rules-only Install only the engineering rules
|
|
47
|
+
--short-aliases=all Also install /define /build /prove /seal
|
|
48
|
+
--no-agents Skip the review subagents
|
|
49
|
+
|
|
50
|
+
--version Print the devrites version
|
|
51
|
+
--help Show this help (use "<subcommand> --help" for installer-level detail)
|
|
52
|
+
|
|
53
|
+
DevRites is project-local — it never writes to ~/.claude.
|
|
54
|
+
Requires bash (Git Bash or WSL on Windows). No-Node fallback:
|
|
55
|
+
curl -fsSL https://raw.githubusercontent.com/ViktorsBaikers/DevRites/main/install.sh | bash
|
|
56
|
+
`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const argv = process.argv.slice(2);
|
|
60
|
+
const first = argv[0];
|
|
61
|
+
|
|
62
|
+
if (first === '--version' || first === '-v') {
|
|
63
|
+
process.stdout.write(pkgVersion() + '\n');
|
|
64
|
+
process.exit(0);
|
|
65
|
+
}
|
|
66
|
+
if (first === '--help' || first === '-h') {
|
|
67
|
+
printHelp();
|
|
68
|
+
process.exit(0);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Route the subcommand; default to install when the first arg is a flag or absent.
|
|
72
|
+
let sub = 'install';
|
|
73
|
+
let rest = argv;
|
|
74
|
+
if (first && Object.prototype.hasOwnProperty.call(SUBCOMMANDS, first)) {
|
|
75
|
+
sub = first;
|
|
76
|
+
rest = argv.slice(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const script = join(root, SUBCOMMANDS[sub]);
|
|
80
|
+
if (!existsSync(script)) {
|
|
81
|
+
console.error(`devrites: bundled ${SUBCOMMANDS[sub]} not found at ${script}`);
|
|
82
|
+
console.error('devrites: the package looks incomplete — reinstall, or use the curl | bash installer.');
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const res = spawnSync('bash', [script, ...rest], { stdio: 'inherit', cwd: process.cwd() });
|
|
87
|
+
|
|
88
|
+
if (res.error) {
|
|
89
|
+
if (res.error.code === 'ENOENT') {
|
|
90
|
+
console.error('devrites: `bash` was not found on your PATH.');
|
|
91
|
+
console.error('DevRites is bash-based. On Windows, run inside Git Bash or WSL,');
|
|
92
|
+
console.error('or use the no-Node installer:');
|
|
93
|
+
console.error(' curl -fsSL https://raw.githubusercontent.com/ViktorsBaikers/DevRites/main/install.sh | bash');
|
|
94
|
+
process.exit(127);
|
|
95
|
+
}
|
|
96
|
+
console.error('devrites: failed to launch installer:', res.error.message);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
process.exit(res.status === null ? 1 : res.status);
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# DevRites Architecture
|
|
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 → polish → review → seal →
|
|
6
|
+
ship.
|
|
7
|
+
|
|
8
|
+
## Layers
|
|
9
|
+
|
|
10
|
+
1. **Public workflow skills** — `.claude/skills/rite-*`, `user-invocable: true`. Each
|
|
11
|
+
owns exactly one phase and reads/writes the `.devrites/` workspace.
|
|
12
|
+
Sequence: `rite-spec`, `rite-define`, `rite-plan`, `rite-build`,
|
|
13
|
+
`rite-prove`, `rite-polish`, `rite-review`, `rite-seal`, `rite-ship`,
|
|
14
|
+
plus the read-only `rite-status`, the resume verb `rite-resolve` (answer
|
|
15
|
+
a HITL gate and clear `Awaiting human`), and the thin `/rite` menu.
|
|
16
|
+
`/rite-seal` **decides** GO/NO-GO and writes the verdict to `seal.md`;
|
|
17
|
+
`/rite-ship` is the eighth lifecycle phase that **executes** the
|
|
18
|
+
irreversible git ladder and **closes** the task (archives the workspace,
|
|
19
|
+
clears `ACTIVE`). Keeping the decision and the irreversible action as two
|
|
20
|
+
separately-auditable steps is the point.
|
|
21
|
+
2. **Public utility skills** — `.claude/skills/rite-zoom-out`,
|
|
22
|
+
`rite-prototype`, `rite-handoff`, `rite-pressure-test`, and
|
|
23
|
+
`rite-autocomplete` — public commands. `rite-autocomplete` is the
|
|
24
|
+
unattended orchestrator: it drives the whole lifecycle (spec → … → seal →
|
|
25
|
+
ship) end-to-end, choosing the best option at each soft gate, pausing only
|
|
26
|
+
on hard irreversible-risk / blocking / escalating gates or a NO-GO. The
|
|
27
|
+
`devrites-` prefix is **namespace** (collision avoidance against bundled
|
|
28
|
+
Claude Code skill names like `prototype`, `handoff`, `triage`, `diagnose`),
|
|
29
|
+
not a visibility marker; `rite-pressure-test` carries no prefix because it
|
|
30
|
+
doesn't collide.
|
|
31
|
+
3. **Internal specialist skills** — `.claude/skills/devrites-*` with
|
|
32
|
+
`user-invocable: false`: `devrites-interview`, `-source-driven`,
|
|
33
|
+
`-doubt`, `-ux-shape` (plans UX/UI into `design-brief.md` at `/rite-spec`),
|
|
34
|
+
`-frontend-craft`, `-browser-proof`, `-debug-recovery`,
|
|
35
|
+
`-api-interface`, `-audit` (dispatches the security / perf / simplify
|
|
36
|
+
reviewer subagent on an axis argument). Model-invoked by public skills
|
|
37
|
+
or Claude's auto-selection; not menu noise. Whether a skill is public or
|
|
38
|
+
internal is governed by the `user-invocable:` flag, not by the name
|
|
39
|
+
prefix.
|
|
40
|
+
|
|
41
|
+
Engineering rules live at `.claude/rules/` (each `rite-*` skill Reads
|
|
42
|
+
`.claude/rules/core.md` as its first step; the other 15 files load on
|
|
43
|
+
demand — no session-start autoload). Parallel reviewer fan-out at
|
|
44
|
+
`/rite-seal` is a reference file
|
|
45
|
+
(`rite-seal/reference/parallel-dispatch.md`), not a skill.
|
|
46
|
+
4. **Supporting references** — `reference/*.md` inside each skill. Long checklists,
|
|
47
|
+
templates, and anti-rationalization tables loaded on demand (progressive
|
|
48
|
+
disclosure) so `SKILL.md` bodies stay small.
|
|
49
|
+
5. **Agents** — `.claude/agents/devrites-*` fresh-context subagents. Nine **read-only
|
|
50
|
+
reviewers**: the post-build set used by `/rite-seal` and the doubt loop
|
|
51
|
+
(`devrites-spec-reviewer`, `-code-reviewer`, `-test-analyst`, `-frontend-reviewer`,
|
|
52
|
+
`-security-auditor`, `-performance-reviewer`, `-doubt-reviewer`, `-simplifier-reviewer`),
|
|
53
|
+
plus the **pre-plan** `devrites-strategy-reviewer` used by `/rite-temper`. Plus one
|
|
54
|
+
**write-capable** executor, `devrites-slice-wright`, dispatched by `/rite-build` to write
|
|
55
|
+
one slice in a clean context (the write-side mirror of the reviewers).
|
|
56
|
+
6. **Engineering rules** — DevRites' own stack-agnostic rules installed to
|
|
57
|
+
`.claude/rules/`. Each `rite-*` skill Reads `core.md` as its first step
|
|
58
|
+
(step 0); 15 on-demand files load by the phase that needs them:
|
|
59
|
+
- **Craft:** `coding-style.md` · `patterns.md` · `error-handling.md` ·
|
|
60
|
+
`testing.md` · `documentation.md`.
|
|
61
|
+
- **Quality / safety:** `code-review.md` · `security.md` ·
|
|
62
|
+
`performance.md` · `anti-patterns.md`.
|
|
63
|
+
- **Workflow / ops:** `development-workflow.md` · `git-workflow.md` ·
|
|
64
|
+
`hooks.md` · `agents.md` · `context-hygiene.md` · `afk-hitl.md`.
|
|
65
|
+
- **Index:** `README.md` (phase mapping, loading model).
|
|
66
|
+
|
|
67
|
+
State lives in `.devrites/` as human-readable Markdown so it survives context
|
|
68
|
+
compaction and new sessions. The optional `.devrites/AFK` sentinel toggles
|
|
69
|
+
the session-level run mode (see "Run modes" below). See `usage.md` for the
|
|
70
|
+
workspace file list, and [`command-map.md`](command-map.md) for the full
|
|
71
|
+
per-skill catalog with triggers + I/O.
|
|
72
|
+
|
|
73
|
+
## Design rationale
|
|
74
|
+
|
|
75
|
+
### Why a shared orientation preamble (`devrites-lib`)
|
|
76
|
+
Every workspace-operating skill's first move is the same: orient on the active feature —
|
|
77
|
+
slug, phase, artifacts present, run mode, open-question tally — before acting. Re-deriving
|
|
78
|
+
that from raw Markdown in each skill was duplicated (step-0 prose across ~15 skills),
|
|
79
|
+
token-heavy (counting open gates meant re-reading the append-only `questions.md`, which
|
|
80
|
+
only grows), and error-prone (a missed AFK sentinel or a miscounted gate changes behavior).
|
|
81
|
+
So orientation is computed once by one read-only script, `devrites-lib/scripts/preamble.sh`,
|
|
82
|
+
which prints a compact digest each skill reads at step 0. `devrites-lib` is an internal
|
|
83
|
+
library skill (`user-invocable: false`, not a command) that houses the cross-cutting
|
|
84
|
+
scripts — the preamble, the read-only gate scripts (`readiness.sh` / `evidence-fresh.sh` /
|
|
85
|
+
`check-acceptance.sh`), the state mutators (`tick-afk.sh` / `resolve.sh` / `close-out.sh`),
|
|
86
|
+
and the unified `devrites.sh` CLI that dispatches to all of them — *inside* `skills/` so
|
|
87
|
+
they ship on both the bash-installer and plugin channels. Skills resolve them with a three-layout snippet (installed `.claude/` → plugin
|
|
88
|
+
`${CLAUDE_SKILL_DIR}` → repo `pack/`). Bundled-script execution is reliable on the
|
|
89
|
+
bash-installer channel (CWD-relative `.claude/`); Claude Code does **not** expose a stable
|
|
90
|
+
script path to skill-invoked bash on the plugin channel (only to hooks — confirmed against
|
|
91
|
+
`anthropics/claude-code` issues #48230 / #38699), so there the preamble is best-effort via
|
|
92
|
+
`${CLAUDE_SKILL_DIR}` and degrades gracefully to reading `state.md` directly. The preamble is read-only; all mutation stays in
|
|
93
|
+
the dedicated scripts.
|
|
94
|
+
|
|
95
|
+
### Why `/engine` was rejected
|
|
96
|
+
A single `/engine` (or `/devrites`) mega-command would load every phase's instructions
|
|
97
|
+
into one context, creating constant context pressure and hiding the intent of each
|
|
98
|
+
step. It also makes "do only this phase" hard to enforce and bloats the recurring
|
|
99
|
+
token cost (skill bodies stay in context once loaded). DevRites splits the lifecycle
|
|
100
|
+
into small skills that load only what the current phase needs.
|
|
101
|
+
|
|
102
|
+
### Why `rite-*` names
|
|
103
|
+
Short, memorable, brand-aligned ("rites" = disciplined steps), and **collision-free**.
|
|
104
|
+
Built-in / bundled Claude Code commands include `/plan`, `/review`, `/run`, `/verify`,
|
|
105
|
+
`/code-review`, `/simplify`, `/security-review`, `/init`, `/compact`, `/debug`. The
|
|
106
|
+
`rite-` prefix avoids all of them. (Collision audit: `research/claude-code-skills-notes.md`.)
|
|
107
|
+
|
|
108
|
+
### Why a thin menu skill, not a mega-router
|
|
109
|
+
`/rite` is **only** an entrypoint: it shows a compact phase-grouped menu, prints live
|
|
110
|
+
`.devrites/ACTIVE` status via `` !`cmd` `` injection, and suggests the next command.
|
|
111
|
+
It deliberately does **not** execute workflows or duplicate skill logic — that would
|
|
112
|
+
recreate the mega-command problem. DevRites keeps selection thin and lets each phase
|
|
113
|
+
own its context, rather than centralizing every workflow behind one command.
|
|
114
|
+
|
|
115
|
+
### Why internal skills exist
|
|
116
|
+
Specialist processes (doubt, source-driven, frontend craft, browser proof, audits)
|
|
117
|
+
are **disciplines**, not user commands. As `user-invocable: false` skills they:
|
|
118
|
+
- stay out of the command menu (less cognitive load);
|
|
119
|
+
- are invoked automatically by Claude or explicitly by a public skill when their
|
|
120
|
+
trigger conditions hit;
|
|
121
|
+
- keep each public `SKILL.md` small by housing the heavy process elsewhere.
|
|
122
|
+
|
|
123
|
+
### Why spec and plan are separate phases (`/rite-spec`, `/rite-define`, `/rite-plan`)
|
|
124
|
+
Doing investigation, spec, plan, and slicing in one batch lets things slip — a gap goes
|
|
125
|
+
unasked, placement is guessed, a slice misses a requirement. DevRites splits them so each
|
|
126
|
+
is focused and gated. `/rite-spec` **investigates deeply and writes `spec.md`** (what/why,
|
|
127
|
+
placement, issues, gaps closed with the user, design references) and must pass its
|
|
128
|
+
readiness gate. `/rite-define` then turns that **approved spec** into `plan.md` +
|
|
129
|
+
`tasks.md` (the how + vertical slices), checking every acceptance criterion maps to a
|
|
130
|
+
slice. The spec is fully covered before any planning begins. `/rite-plan` is the separate
|
|
131
|
+
repair/reslice/re-order tool for an *active* plan when it goes stale or drifts.
|
|
132
|
+
|
|
133
|
+
### Why `/rite-polish` is one skill with two progressive-disclosure halves
|
|
134
|
+
Polish has two natural halves — **code** (simplify, dead code, naming, plus
|
|
135
|
+
backend if BE was touched) and **UI** (normalize to the design system, then
|
|
136
|
+
ship-quality detail). The earlier design split them into `rite-polish-code`
|
|
137
|
+
and `rite-polish-ui` sub-skills, but a skill-on-skill dispatch is fragile
|
|
138
|
+
(the caller has to re-discover the callee by description) and the two halves
|
|
139
|
+
share the same operating rules. They now live as `reference/code.md` and
|
|
140
|
+
`reference/ui.md` inside the same skill, loaded only when their phase
|
|
141
|
+
trigger fires — the canonical progressive-disclosure pattern from
|
|
142
|
+
<https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices>.
|
|
143
|
+
`/rite-polish` is the orchestrator: always reads `reference/code.md`
|
|
144
|
+
(Phase 1 + 2), detects UI scope from the diff and reads `reference/ui.md`
|
|
145
|
+
(Phase 3 + 4) when needed. The orchestrator accepts mode tokens (`bolder`,
|
|
146
|
+
`quieter`, `distill`, `harden`, `normalize-only`) that pass through to
|
|
147
|
+
Phase 4.
|
|
148
|
+
|
|
149
|
+
Normalization remains the entry gate of UI polish — polishing UI that hasn't
|
|
150
|
+
been aligned to the project's design system is "decoration on drift," and
|
|
151
|
+
the UI reference refuses to run Phase 4 before Phase 3.
|
|
152
|
+
|
|
153
|
+
### Why seal and ship are separate phases (`/rite-seal`, `/rite-ship`)
|
|
154
|
+
Deciding "is this safe to ship" and *actually shipping* are different acts with
|
|
155
|
+
different blast radii. `/rite-seal` is a **pure decision gate**: it walks acceptance
|
|
156
|
+
against evidence, fans out the fresh-context reviewers, and writes the GO / NO-GO
|
|
157
|
+
verdict to `seal.md` — it runs no git. On GO it sets `state.md` `Next step:
|
|
158
|
+
/rite-ship` and stops. `/rite-ship` is the eighth lifecycle phase: it refuses to run
|
|
159
|
+
without a GO recorded in `seal.md`, renders the type-`GO` prompt, runs the irreversible
|
|
160
|
+
git ladder (commit → push → tag/PR per the project's convention), writes `ship.md`,
|
|
161
|
+
then **closes the task** — sets phase `done` and archives `.devrites/work/<slug>/` →
|
|
162
|
+
`.devrites/archive/<slug>/` (every `.md` preserved, never deleted) and clears
|
|
163
|
+
`.devrites/ACTIVE`. A GO seal is a verdict, not an authorization to push; keeping the
|
|
164
|
+
decision and the irreversible action as two separately-auditable steps is the point.
|
|
165
|
+
|
|
166
|
+
### Why `/rite-autocomplete` exists (the unattended orchestrator)
|
|
167
|
+
Some features are routine enough to run end-to-end without per-phase human iteration.
|
|
168
|
+
`/rite-autocomplete` drives the whole lifecycle (spec → define → build×N → prove →
|
|
169
|
+
polish → review → seal → ship) by reading each phase's `SKILL.md` and executing its
|
|
170
|
+
workflow, carrying state through the workspace files rather than chat. A vague prompt
|
|
171
|
+
triggers an up-front `devrites-interview` — the only interactive window — after which it
|
|
172
|
+
runs unattended, choosing the best option at each soft gate and recording the rationale
|
|
173
|
+
in `decisions.md`. It does **not** weaken the safety gates: hard irreversible-risk
|
|
174
|
+
(auth / migration / public-API / red tests), blocking / escalating gates, an open
|
|
175
|
+
`gate: validating`, a NO-GO, exhausted `max_slices`, or low confidence all still pause.
|
|
176
|
+
By default it stops at the final type-`GO`; the `--ship` flag (alias `--yolo`)
|
|
177
|
+
auto-confirms it for a zero-touch push.
|
|
178
|
+
|
|
179
|
+
### Why persistent `.devrites/` state
|
|
180
|
+
Long features outlive a single context window. Durable Markdown (spec/plan/tasks/
|
|
181
|
+
state/evidence/drift/decisions) lets any phase — in any session, after any compaction
|
|
182
|
+
— reload exactly where work stands. This is the main thing DevRites adds over typical
|
|
183
|
+
session-scoped workflows, which don't persist feature state.
|
|
184
|
+
|
|
185
|
+
### Run modes — HITL & AFK
|
|
186
|
+
|
|
187
|
+
DevRites runs the same lifecycle two ways, configured at two levels:
|
|
188
|
+
|
|
189
|
+
- **Per-slice** (planning-time) — each `tasks.md` slice declares `Mode: AFK | HITL`.
|
|
190
|
+
HITL slices add `Gate: advisory | validating | blocking | escalating`, `SLA`, and
|
|
191
|
+
`Checkpoint` so the agent knows how disruptive the pause should be.
|
|
192
|
+
- **Per-session** (run-time) — the presence of `.devrites/AFK` flips the session-level
|
|
193
|
+
default. Empty file = AFK with safe defaults; YAML body widens behavior
|
|
194
|
+
(`max_slices`, `notify`, `allow_gates`).
|
|
195
|
+
|
|
196
|
+
The pause primitive is a **pre-action interrupt**, not a post-action review queue —
|
|
197
|
+
inspired by LangGraph's `interrupt()` / `Command(resume=)` model. `/rite-build` writes
|
|
198
|
+
an `Awaiting human` block to `state.md` and a question to `questions.md`, then stops.
|
|
199
|
+
`/rite-resolve` is the canonical resume verb. Restarting a session reads the workspace
|
|
200
|
+
back into a consistent state because the pause is durable Markdown, not chat memory.
|
|
201
|
+
|
|
202
|
+
Why a four-gate taxonomy (instead of a single "ask the user" pause): a single gate
|
|
203
|
+
becomes a queue under load. Mixing `advisory` (audit-only log) with `validating`
|
|
204
|
+
(async — build continues, merge blocks) and reserving `blocking` for synchronous halts
|
|
205
|
+
keeps the loop alive when the answer can wait, and pauses hard when it can't. The
|
|
206
|
+
"AFK never silently accepts irreversible risk" rule — destructive migrations,
|
|
207
|
+
auth/authz boundaries, public API breaks, red tests/types/lint — always pauses
|
|
208
|
+
regardless of the sentinel. See
|
|
209
|
+
[`pack/.claude/rules/afk-hitl.md`](../pack/.claude/rules/afk-hitl.md) for the full
|
|
210
|
+
contract.
|
|
211
|
+
|
|
212
|
+
## Design choices at a glance
|
|
213
|
+
|
|
214
|
+
- **Surface**: 19 public `rite-*` skills (28 total) — the thin `/rite` menu
|
|
215
|
+
(carries the routing) + 8 lifecycle phases (`rite-spec`, `rite-define`,
|
|
216
|
+
`rite-build`, `rite-prove`, `rite-polish`, `rite-review`, `rite-seal`,
|
|
217
|
+
`rite-ship` — seal **decides**, ship **executes + closes**) + the
|
|
218
|
+
`rite-temper` (strategic, optional) and `rite-vet` (engineering, every plan)
|
|
219
|
+
reviews +
|
|
220
|
+
`rite-status` +
|
|
221
|
+
the `rite-plan` replan verb + the `rite-resolve` resume verb + 5 utilities
|
|
222
|
+
(`rite-zoom-out`, `rite-prototype`, `rite-handoff`, `rite-pressure-test`,
|
|
223
|
+
`rite-autocomplete` — the unattended full-lifecycle orchestrator) — plus 9
|
|
224
|
+
internal model-invoked `devrites-*` specialists, not one mega-command. The
|
|
225
|
+
`devrites-` prefix is a namespace (collision avoidance), not a
|
|
226
|
+
public/internal marker — `user-invocable:` is. All `devrites-*` skills are
|
|
227
|
+
model-invoked.
|
|
228
|
+
- **Selection**: the `/rite` menu skill carries the routing table; every
|
|
229
|
+
workflow skill enforces a "right skill, right time" rule in its body.
|
|
230
|
+
- **State**: durable `.devrites/` Markdown that survives compaction and new sessions.
|
|
231
|
+
`.devrites/AFK` presence is the single source of truth for run mode (HITL/AFK);
|
|
232
|
+
there is no `state.md` run-mode field to drift out of sync.
|
|
233
|
+
- **Run modes**: same lifecycle runs HITL (default; pause at typed gate) or AFK
|
|
234
|
+
(drop `.devrites/AFK`; loop continues, discretionary pauses downgrade to
|
|
235
|
+
advisory log, irreversible risk always pauses).
|
|
236
|
+
- **Slice rule**: build **one vertical slice, then stop** — no auto-continue.
|
|
237
|
+
- **Drift**: an explicit **Spec Drift Guard** in build/prove/polish/review/seal.
|
|
238
|
+
- **Design**: `devrites-frontend-craft` + a four-phase `/rite-polish` orchestrator (code + backend always; UI normalize + polish when UI is in scope).
|
|
239
|
+
- **Review**: **feature-scoped** five-axis review with severity labels + fresh-context
|
|
240
|
+
subagents at the seal.
|
|
241
|
+
- **Scope**: clarify → seal (decide) → ship (the irreversible git ladder —
|
|
242
|
+
commit → push → tag/PR — per the project's own convention) → close; the CI
|
|
243
|
+
pipeline stays with the project.
|
|
244
|
+
- **Install**: project-local, manifest-managed; ships DevRites' own engineering rules.
|
|
245
|
+
|
|
246
|
+
## Deviations from the original build brief (and why)
|
|
247
|
+
|
|
248
|
+
1. **`user-invocable` semantics corrected from the docs.** The brief said set
|
|
249
|
+
`user-invocable: true` for public and `false` for internal. That is exactly right
|
|
250
|
+
for internal skills. For public skills we keep them model-invocable (no
|
|
251
|
+
`disable-model-invocation`) so phases can hand off and the selector can route;
|
|
252
|
+
per-phase side-effect discipline (e.g. "stop after one slice") is enforced in the
|
|
253
|
+
skill **body**, which is the correct mechanism (invocation flags can't express it).
|
|
254
|
+
2. **`context: fork` used selectively.** Verified it is a real field (isolated
|
|
255
|
+
subagent, body-as-prompt, no conversation history). It is applied only to the three
|
|
256
|
+
self-contained read-only audit skills (`devrites-audit simplify`,
|
|
257
|
+
`devrites-audit security`, `devrites-audit perf`), which re-read
|
|
258
|
+
`.devrites/` + `git diff` themselves. Interactive skills (doubt, interview, craft)
|
|
259
|
+
are **not** forked because they need live context and user turns.
|
|
260
|
+
3. **Fresh-context adversarial review via real `.claude/agents/`** rather than relying
|
|
261
|
+
on `context: fork` everywhere, because an agent can be handed the workspace path to
|
|
262
|
+
read, whereas a forked skill cannot see the conversation.
|
|
263
|
+
|
|
264
|
+
Everything else follows the brief's structure, command names, state model, and
|
|
265
|
+
acceptance criteria.
|
|
266
|
+
|
|
267
|
+
## Repository layout
|
|
268
|
+
|
|
269
|
+
See the top-level tree in `README.md` and the installed-target tree in `usage.md`.
|
|
270
|
+
Source pack lives under `pack/.claude/` (skills, agents, and rules); the installer copies
|
|
271
|
+
it into a target project's `.claude/`, including DevRites' engineering rules in
|
|
272
|
+
`.claude/rules/`.
|
package/docs/cli-mcp.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Tool-agnostic state core — the `devrites` CLI + MCP server
|
|
2
|
+
|
|
3
|
+
DevRites' discipline lives in the `.devrites/` Markdown files and the state scripts under
|
|
4
|
+
`devrites-lib/scripts/`, **not** in the Claude Code harness. So any tool — Cursor, Codex,
|
|
5
|
+
Gemini CLI, a CI job, or a human — can drive a DevRites workflow through the same files.
|
|
6
|
+
Two portable surfaces expose them.
|
|
7
|
+
|
|
8
|
+
## The `devrites` CLI
|
|
9
|
+
|
|
10
|
+
Installed at `.claude/skills/devrites-lib/scripts/devrites.sh` (ships on both the bash
|
|
11
|
+
installer and the plugin). Run it from the project root:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
D=.claude/skills/devrites-lib/scripts/devrites.sh
|
|
15
|
+
bash "$D" orient # workspace digest for the active feature (read-only)
|
|
16
|
+
bash "$D" ready # build-readiness gate (exit 0 ready · 2/3/4/5 not)
|
|
17
|
+
bash "$D" evidence-fresh # evidence-freshness gate (exit 0 fresh · 3 stale)
|
|
18
|
+
bash "$D" acceptance # acceptance-criteria gate (exit 0 proven · 1 gap)
|
|
19
|
+
bash "$D" active | list | use <slug>
|
|
20
|
+
bash "$D" resolve <qid> "<answer>" # answer a HITL gate
|
|
21
|
+
bash "$D" help
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Each command is a thin wrapper over an existing state script, so the **exit code is the
|
|
25
|
+
gate**: a non-zero `ready` / `evidence-fresh` / `acceptance` is a hard stop, scriptable in
|
|
26
|
+
any agent's loop or a pre-merge CI step. `devrites help` lists them all.
|
|
27
|
+
|
|
28
|
+
## The MCP server
|
|
29
|
+
|
|
30
|
+
`mcp/devrites-mcp.mjs` (in the DevRites source) is a dependency-free MCP **stdio** server
|
|
31
|
+
that exposes the read/gate operations as MCP tools (`devrites_orient`, `devrites_ready`,
|
|
32
|
+
`devrites_evidence_fresh`, `devrites_acceptance`, `devrites_status`, `devrites_active`,
|
|
33
|
+
`devrites_list`, `devrites_use`). It shells out to the CLI, so it stays a thin surface over
|
|
34
|
+
the same scripts — no SDK, no dependencies.
|
|
35
|
+
|
|
36
|
+
Register it in a project's `.mcp.json`, running from the project root (it auto-finds the
|
|
37
|
+
installed CLI; override the path with the `DEVRITES_CLI` env var):
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"mcpServers": {
|
|
42
|
+
"devrites": { "command": "node", "args": ["/abs/path/to/mcp/devrites-mcp.mjs"] }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Now any MCP client can ask "is this feature ready to ship?" and the server runs the
|
|
48
|
+
deterministic gates against `.devrites/` — the same verdict the lifecycle skills compute,
|
|
49
|
+
available to tools that don't speak DevRites' skill prose.
|
|
50
|
+
|
|
51
|
+
## Why this exists
|
|
52
|
+
|
|
53
|
+
Spec-kit, task-master, and BMAD all run across many agents; DevRites was Claude-Code-only.
|
|
54
|
+
Its workspace and rules were already tool-agnostic *data* — the CLI and MCP server are the
|
|
55
|
+
thin shims that make the *workflow* drivable from anywhere, without reimplementing the
|
|
56
|
+
discipline. The deterministic gates (`ready`, `evidence-fresh`, `acceptance`) are the same
|
|
57
|
+
scripts the skills call, so a verdict from the CLI, the MCP server, or `/rite-seal` agrees.
|