devrites 5.12.0 → 5.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +5 -3
- package/docs/architecture.md +2 -2
- package/docs/command-map.md +3 -1
- package/docs/engine/commands.md +21 -0
- package/docs/flow.md +2 -1
- package/docs/skills.md +13 -4
- package/engine/help.go +4 -1
- package/engine/help_test.go +2 -0
- package/engine/internal/overhaul/admit/admit_test.go +170 -0
- package/engine/internal/overhaul/admit/run.go +416 -0
- package/engine/internal/overhaul/bench/run.go +248 -0
- package/engine/internal/overhaul/bench/run_test.go +139 -0
- package/engine/internal/overhaul/overhaul.go +64 -0
- package/engine/internal/overhaul/ovio/ovio.go +158 -0
- package/engine/internal/overhaul/records/check.go +834 -0
- package/engine/internal/overhaul/records/records_test.go +577 -0
- package/engine/internal/overhaul/records/run.go +392 -0
- package/engine/internal/overhaul/render/run.go +776 -0
- package/engine/internal/overhaul/render/run_test.go +293 -0
- package/engine/internal/overhaul/score/run.go +600 -0
- package/engine/internal/overhaul/score/run_test.go +405 -0
- package/engine/internal/overhaul/snapshot/run.go +563 -0
- package/engine/internal/overhaul/snapshot/run_test.go +360 -0
- package/engine/main.go +4 -0
- package/engine/root_routing_test.go +2 -1
- package/pack/.claude/skills/overhaul/SKILL.md +201 -0
- package/pack/.claude/skills/overhaul/references/audit-domains.md +263 -0
- package/pack/.claude/skills/overhaul/references/lifecycle.md +308 -0
- package/pack/.claude/skills/overhaul/references/orchestration.md +264 -0
- package/pack/.claude/skills/overhaul/references/records.md +137 -0
- package/pack/.claude/skills/overhaul/references/repair-and-measurement.md +207 -0
- package/pack/.claude/skills/overhaul/references/review-and-report.md +137 -0
- package/pack/.claude/skills/overhaul/references/scope-and-safety.md +191 -0
- package/pack/.claude/skills/overhaul/references/scoring.md +222 -0
- package/pack/.claude/skills/overhaul/references/stack-profiles.md +264 -0
- package/pack/.claude/skills/overhaul/roles/backend-engineer.md +61 -0
- package/pack/.claude/skills/overhaul/roles/boundary.md +56 -0
- package/pack/.claude/skills/overhaul/roles/craft.md +77 -0
- package/pack/.claude/skills/overhaul/roles/frontend-engineer.md +63 -0
- package/pack/.claude/skills/overhaul/roles/implementer.md +59 -0
- package/pack/.claude/skills/overhaul/roles/recon.md +60 -0
- package/pack/.claude/skills/overhaul/roles/specialist.md +56 -0
- package/pack/.claude/skills/overhaul/roles/verifier.md +60 -0
- package/pack/generated/claude/skills/overhaul/SKILL.md +201 -0
- package/pack/generated/claude/skills/overhaul/references/audit-domains.md +263 -0
- package/pack/generated/claude/skills/overhaul/references/lifecycle.md +308 -0
- package/pack/generated/claude/skills/overhaul/references/orchestration.md +264 -0
- package/pack/generated/claude/skills/overhaul/references/records.md +137 -0
- package/pack/generated/claude/skills/overhaul/references/repair-and-measurement.md +207 -0
- package/pack/generated/claude/skills/overhaul/references/review-and-report.md +137 -0
- package/pack/generated/claude/skills/overhaul/references/scope-and-safety.md +191 -0
- package/pack/generated/claude/skills/overhaul/references/scoring.md +222 -0
- package/pack/generated/claude/skills/overhaul/references/stack-profiles.md +264 -0
- package/pack/generated/claude/skills/overhaul/roles/backend-engineer.md +61 -0
- package/pack/generated/claude/skills/overhaul/roles/boundary.md +56 -0
- package/pack/generated/claude/skills/overhaul/roles/craft.md +77 -0
- package/pack/generated/claude/skills/overhaul/roles/frontend-engineer.md +63 -0
- package/pack/generated/claude/skills/overhaul/roles/implementer.md +59 -0
- package/pack/generated/claude/skills/overhaul/roles/recon.md +60 -0
- package/pack/generated/claude/skills/overhaul/roles/specialist.md +56 -0
- package/pack/generated/claude/skills/overhaul/roles/verifier.md +60 -0
- package/pack/generated/codex/skills/overhaul/SKILL.md +201 -0
- package/pack/generated/codex/skills/overhaul/agents/openai.yaml +2 -0
- package/pack/generated/codex/skills/overhaul/references/audit-domains.md +263 -0
- package/pack/generated/codex/skills/overhaul/references/lifecycle.md +308 -0
- package/pack/generated/codex/skills/overhaul/references/orchestration.md +264 -0
- package/pack/generated/codex/skills/overhaul/references/records.md +137 -0
- package/pack/generated/codex/skills/overhaul/references/repair-and-measurement.md +207 -0
- package/pack/generated/codex/skills/overhaul/references/review-and-report.md +137 -0
- package/pack/generated/codex/skills/overhaul/references/scope-and-safety.md +191 -0
- package/pack/generated/codex/skills/overhaul/references/scoring.md +222 -0
- package/pack/generated/codex/skills/overhaul/references/stack-profiles.md +264 -0
- package/pack/generated/codex/skills/overhaul/roles/backend-engineer.md +61 -0
- package/pack/generated/codex/skills/overhaul/roles/boundary.md +56 -0
- package/pack/generated/codex/skills/overhaul/roles/craft.md +77 -0
- package/pack/generated/codex/skills/overhaul/roles/frontend-engineer.md +63 -0
- package/pack/generated/codex/skills/overhaul/roles/implementer.md +59 -0
- package/pack/generated/codex/skills/overhaul/roles/recon.md +60 -0
- package/pack/generated/codex/skills/overhaul/roles/specialist.md +56 -0
- package/pack/generated/codex/skills/overhaul/roles/verifier.md +60 -0
- package/pack/generated/devin/skills/overhaul/SKILL.md +201 -0
- package/pack/generated/devin/skills/overhaul/references/audit-domains.md +263 -0
- package/pack/generated/devin/skills/overhaul/references/lifecycle.md +308 -0
- package/pack/generated/devin/skills/overhaul/references/orchestration.md +264 -0
- package/pack/generated/devin/skills/overhaul/references/records.md +137 -0
- package/pack/generated/devin/skills/overhaul/references/repair-and-measurement.md +207 -0
- package/pack/generated/devin/skills/overhaul/references/review-and-report.md +137 -0
- package/pack/generated/devin/skills/overhaul/references/scope-and-safety.md +191 -0
- package/pack/generated/devin/skills/overhaul/references/scoring.md +222 -0
- package/pack/generated/devin/skills/overhaul/references/stack-profiles.md +264 -0
- package/pack/generated/devin/skills/overhaul/roles/backend-engineer.md +61 -0
- package/pack/generated/devin/skills/overhaul/roles/boundary.md +56 -0
- package/pack/generated/devin/skills/overhaul/roles/craft.md +77 -0
- package/pack/generated/devin/skills/overhaul/roles/frontend-engineer.md +63 -0
- package/pack/generated/devin/skills/overhaul/roles/implementer.md +59 -0
- package/pack/generated/devin/skills/overhaul/roles/recon.md +60 -0
- package/pack/generated/devin/skills/overhaul/roles/specialist.md +56 -0
- package/pack/generated/devin/skills/overhaul/roles/verifier.md +60 -0
- package/pack/generated/omp/skills/overhaul/SKILL.md +201 -0
- package/pack/generated/omp/skills/overhaul/references/audit-domains.md +263 -0
- package/pack/generated/omp/skills/overhaul/references/lifecycle.md +308 -0
- package/pack/generated/omp/skills/overhaul/references/orchestration.md +264 -0
- package/pack/generated/omp/skills/overhaul/references/records.md +137 -0
- package/pack/generated/omp/skills/overhaul/references/repair-and-measurement.md +207 -0
- package/pack/generated/omp/skills/overhaul/references/review-and-report.md +137 -0
- package/pack/generated/omp/skills/overhaul/references/scope-and-safety.md +191 -0
- package/pack/generated/omp/skills/overhaul/references/scoring.md +222 -0
- package/pack/generated/omp/skills/overhaul/references/stack-profiles.md +264 -0
- package/pack/generated/omp/skills/overhaul/roles/backend-engineer.md +61 -0
- package/pack/generated/omp/skills/overhaul/roles/boundary.md +56 -0
- package/pack/generated/omp/skills/overhaul/roles/craft.md +77 -0
- package/pack/generated/omp/skills/overhaul/roles/frontend-engineer.md +63 -0
- package/pack/generated/omp/skills/overhaul/roles/implementer.md +59 -0
- package/pack/generated/omp/skills/overhaul/roles/recon.md +60 -0
- package/pack/generated/omp/skills/overhaul/roles/specialist.md +56 -0
- package/pack/generated/omp/skills/overhaul/roles/verifier.md +60 -0
- package/pack/generated/pi/skills/overhaul/SKILL.md +201 -0
- package/pack/generated/pi/skills/overhaul/references/audit-domains.md +263 -0
- package/pack/generated/pi/skills/overhaul/references/lifecycle.md +308 -0
- package/pack/generated/pi/skills/overhaul/references/orchestration.md +264 -0
- package/pack/generated/pi/skills/overhaul/references/records.md +137 -0
- package/pack/generated/pi/skills/overhaul/references/repair-and-measurement.md +207 -0
- package/pack/generated/pi/skills/overhaul/references/review-and-report.md +137 -0
- package/pack/generated/pi/skills/overhaul/references/scope-and-safety.md +191 -0
- package/pack/generated/pi/skills/overhaul/references/scoring.md +222 -0
- package/pack/generated/pi/skills/overhaul/references/stack-profiles.md +264 -0
- package/pack/generated/pi/skills/overhaul/roles/backend-engineer.md +61 -0
- package/pack/generated/pi/skills/overhaul/roles/boundary.md +56 -0
- package/pack/generated/pi/skills/overhaul/roles/craft.md +77 -0
- package/pack/generated/pi/skills/overhaul/roles/frontend-engineer.md +63 -0
- package/pack/generated/pi/skills/overhaul/roles/implementer.md +59 -0
- package/pack/generated/pi/skills/overhaul/roles/recon.md +60 -0
- package/pack/generated/pi/skills/overhaul/roles/specialist.md +56 -0
- package/pack/generated/pi/skills/overhaul/roles/verifier.md +60 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to DevRites are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and DevRites adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Releases are generated automatically by [semantic-release](https://semantic-release.gitbook.io/) from Conventional Commits on `main`.
|
|
4
4
|
|
|
5
|
+
## [5.13.0](https://github.com/ViktorsBaikers/DevRites/compare/v5.12.0...v5.13.0) (2026-09-25)
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
* **skills:** add approval-gated /overhaul skill with engine tools ([#82](https://github.com/ViktorsBaikers/DevRites/issues/82)) ([79d0af0](https://github.com/ViktorsBaikers/DevRites/commit/79d0af0518d2536c5fd9278ca4891c95f4576a59))
|
|
10
|
+
|
|
5
11
|
## [5.12.0](https://github.com/ViktorsBaikers/DevRites/compare/v5.11.0...v5.12.0) (2026-09-20)
|
|
6
12
|
|
|
7
13
|
### Added
|
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ project-conventional push, tag, or PR action, and archive the workspace.
|
|
|
34
34
|
Unattended runs may create local WIP checkpoint commits along the way, but they
|
|
35
35
|
remain local unless Ship's disclosed plan includes an approved remote action.
|
|
36
36
|
|
|
37
|
-
**Status:** [`v5.
|
|
37
|
+
**Status:** [`v5.13.0`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v5.13.0): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
|
|
38
38
|
|
|
39
39
|
This is the latest published release; `main` may contain unreleased work.
|
|
40
40
|
|
|
@@ -423,8 +423,10 @@ through Claude Code or Codex plugin stores.
|
|
|
423
423
|
|
|
424
424
|
## Skills and agents
|
|
425
425
|
|
|
426
|
-
The pack ships
|
|
427
|
-
the `rite` menu
|
|
426
|
+
The pack ships 45 skills: 34 public and 11 internal. The public surface contains
|
|
427
|
+
the `rite` menu, 32 `rite-*` workflows and utilities, and the standalone,
|
|
428
|
+
explicit-only `/overhaul` (approval-gated project, PR or branch audit with verified
|
|
429
|
+
repairs; it runs without a DevRites workspace). Ten `devrites-*`
|
|
428
430
|
specialists load when a matching task needs them; `devrites-lib` carries the
|
|
429
431
|
shared contracts and engineering standards.
|
|
430
432
|
|
package/docs/architecture.md
CHANGED
|
@@ -389,8 +389,8 @@ contract.
|
|
|
389
389
|
|
|
390
390
|
## Design choices at a glance
|
|
391
391
|
|
|
392
|
-
- **Surface**: 32 public `rite-*` skills (
|
|
393
|
-
menu:
|
|
392
|
+
- **Surface**: 32 public `rite-*` skills (45 total), plus the thin `/rite`
|
|
393
|
+
menu and the standalone `overhaul` skill: 34 public and 11 internal. The lifecycle
|
|
394
394
|
includes mandatory adaptive Clarify, optional Temper, mandatory Vet, and
|
|
395
395
|
Converge recovery; Seal **decides** and Ship **executes + closes**. Ten
|
|
396
396
|
`devrites-*` specialist skills are model-invoked; `devrites-lib` is the
|
package/docs/command-map.md
CHANGED
|
@@ -22,7 +22,8 @@ visibility. Public utilities use the `rite-*` prefix: `rite-quick`,
|
|
|
22
22
|
`rite-autocomplete`, `rite-explain`, `rite-pov`, `rite-dogfood`,
|
|
23
23
|
`rite-pr-feedback`, and `rite-watch-pr`, plus the evidence-gated workspace compatibility command
|
|
24
24
|
`rite-upgrade`. The host may invoke `devrites-*` specialists through the model.
|
|
25
|
-
`devrites-lib` is the non-workflow library exception.
|
|
25
|
+
`devrites-lib` is the non-workflow library exception. `overhaul` is a standalone,
|
|
26
|
+
explicit-only skill outside both prefixes; it runs without any DevRites workspace.
|
|
26
27
|
|
|
27
28
|
## Surface lifecycle
|
|
28
29
|
|
|
@@ -121,6 +122,7 @@ See [`cli.md`](cli.md).
|
|
|
121
122
|
| [`/rite-watch-pr`](../pack/.claude/skills/rite-watch-pr/SKILL.md) | utility | `[PR number\|PR URL\|blank for current branch]` | Observe one GitHub PR/CI/review snapshot, classify one next action, and stop. Safe for capability-admitted native schedules/events; never mutates code, Git, checks, threads, or PR state. | PR/check/review metadata + bounded failed-log excerpts | none |
|
|
122
123
|
| [`/rite-pressure-test`](../pack/.claude/skills/rite-pressure-test/SKILL.md) | utility | `[idea]` | Pressure-test a rough idea: 3 to 5 genuinely different options → converge on one with trade-off + hinge. | spec / surrounding code | `decisions.md` (optional) |
|
|
123
124
|
| [`/rite-doctor`](../pack/.claude/skills/rite-doctor/SKILL.md) | diagnostic | none | Diagnose the DevRites binary, pack, schema, and native host permission/profile configuration. | install + host config | none |
|
|
125
|
+
| [`/overhaul`](../pack/.claude/skills/overhaul/SKILL.md) | standalone | `[full \| pr <n\|url> \| branch <head> --base <base> \| audit <scope> \| apply <run-id> --plan <rev> \| status <run-id> \| resume <run-id>]` | Explicit-only, outside the lifecycle. Concurrent frontend and backend engineering review plus boundary, craft and specialist roles (skill-local role files dispatched as fresh contexts); one verified plan; stops for the user's approval of the exact plan revision; then test-first repairs, independent verification, measurement and evidence-backed scoring, cycling inside the approved envelope. `audit` never repairs. Never commits, pushes, stashes or touches the index. | target repository (read-only until approval) | run area outside the repository (JSON records, HTML/Markdown views, evidence); approved target paths only after approval |
|
|
124
126
|
|
|
125
127
|
`/rite use <slug>` and `/rite guide` are inline router operations owned by
|
|
126
128
|
`/rite`, not separate skills. There is no `/rite-use` or `/rite-guide` shortcut.
|
package/docs/engine/commands.md
CHANGED
|
@@ -46,6 +46,7 @@ workflow strategy.
|
|
|
46
46
|
| `secret-scan [--staged] [--stdin] [slug]` | Scan exact staged blobs, stdin, or touched regular files for credential material. |
|
|
47
47
|
| `open-visual <path-or-name> [--slug <slug>] [--no-open]` | Resolve a local visual HTML file, optionally open it in the OS browser, warn if the sibling outline is missing or inventory ids are absent from HTML, and print agent path tips. No network. |
|
|
48
48
|
| `detect commands [--root <dir>] [--json]` | Resolve the repository's own test/lint/vet/build commands: explicit Makefile targets first, then `package.json` scripts, then language-manifest fallbacks, plus the lockfile-derived package manager. Read-only, no installs, no execution. |
|
|
49
|
+
| `overhaul <records\|admit\|snapshot\|score\|bench\|render> ...` | Deterministic tools behind the standalone `/overhaul` skill: run-record generations and cross-record validation, worker-receipt admission and quote anchoring, index-safe baseline snapshots and per-attempt deltas, exact-rational readiness scoring, benchmark ratio intervals, and escaped offline review/report views. Operates only on explicit run-area and repository paths. See [Overhaul tools](#overhaul-tools). |
|
|
49
50
|
| `version` | Print the engine version. |
|
|
50
51
|
|
|
51
52
|
`help`, `-h`, and `--help` print this operational inventory. Each operational
|
|
@@ -136,6 +137,26 @@ the local file only — never a network fetch. Stdout prints the absolute HTML
|
|
|
136
137
|
path, outline path tip, playbook index hint, and an `ids=ok` / `ids=mismatch`
|
|
137
138
|
summary when an inventory is present.
|
|
138
139
|
|
|
140
|
+
## Overhaul tools
|
|
141
|
+
|
|
142
|
+
`overhaul` serves the explicit-only `/overhaul` skill. Each tool takes explicit
|
|
143
|
+
paths and never resolves a `.devrites` workspace, calls a model or uses the
|
|
144
|
+
network. The skill documents the record schemas and when to call each tool.
|
|
145
|
+
|
|
146
|
+
| Tool | Forms | Exit codes |
|
|
147
|
+
| --- | --- | --- |
|
|
148
|
+
| `records` | `digest <file>`, `stage <run>`, `publish <run>`, `validate <run>` | 0 ok; 1 violations (listed as `VIOLATION:` lines); 2 usage or I/O |
|
|
149
|
+
| `admit` | `receipt <run> <receipt.json> [--observed <file>]`, `anchor <tree> <proposals.json>` | 0 admissible; 1 rejected; 2 usage or I/O; 3 duplicate or late receipt |
|
|
150
|
+
| `snapshot` | `capture <repo> <out>`, `fingerprint <repo>`, `verify <repo> <out> [--agent-paths <file>]`, `state <repo> <out.json>`, `delta <before.json> <repo>` | 0 ok; 1 index changed or changes outside agent paths; 2 refusal, usage or I/O |
|
|
151
|
+
| `score` | `--rubric <r> --results <s> --gates <g> [--out <file>]`, `compare --rubric <r> --baseline <a> --candidate <b>` | 0 computed; 2 invalid input (nothing counts as scored) |
|
|
152
|
+
| `bench` | `<result.json>` | 0 computed; 2 invalid input |
|
|
153
|
+
| `render` | `<run> <staged-generation> <review\|report>` | 0 written; 2 usage, invalid records or I/O |
|
|
154
|
+
|
|
155
|
+
`snapshot` runs git read-only with `GIT_OPTIONAL_LOCKS=0`,
|
|
156
|
+
`diff.autoRefreshIndex=false` and no external diff drivers, so `.git/index`
|
|
157
|
+
stays byte-identical. Secret-pattern files and files holding private key material
|
|
158
|
+
are hashed only: never copied into the snapshot tree and never included in its patches.
|
|
159
|
+
|
|
139
160
|
## Output and exit contracts
|
|
140
161
|
|
|
141
162
|
`check candidate` passes with exactly:
|
package/docs/flow.md
CHANGED
|
@@ -381,7 +381,7 @@ separately by `disable-model-invocation`.
|
|
|
381
381
|
|
|
382
382
|
```mermaid
|
|
383
383
|
flowchart TB
|
|
384
|
-
subgraph Public["Public (user-invocable: true):
|
|
384
|
+
subgraph Public["Public (user-invocable: true): 34 skills"]
|
|
385
385
|
direction TB
|
|
386
386
|
R1[/rite/]
|
|
387
387
|
R2[/rite-spec/]
|
|
@@ -416,6 +416,7 @@ flowchart TB
|
|
|
416
416
|
D1[/rite-zoom-out/]
|
|
417
417
|
D2[/rite-prototype/]
|
|
418
418
|
D3[/rite-handoff/]
|
|
419
|
+
OVH[/overhaul<br/>standalone, outside the lifecycle/]
|
|
419
420
|
end
|
|
420
421
|
subgraph Internal["Internal (user-invocable: false): 11 skills (10 specialists + devrites-lib library)"]
|
|
421
422
|
direction TB
|
package/docs/skills.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# All
|
|
1
|
+
# All 45 skills
|
|
2
2
|
|
|
3
|
-
The pack contains
|
|
4
|
-
workflow and utility skills,
|
|
5
|
-
internal `devrites-lib` library. `devrites-lib` is not a command. It holds shared
|
|
3
|
+
The pack contains 45 skills: the `rite` menu, 32 user-invocable `rite-*`
|
|
4
|
+
workflow and utility skills, the standalone `overhaul` skill,
|
|
5
|
+
10 model-invoked `devrites-*` specialists, and the internal `devrites-lib` library. `devrites-lib` is not a command. It holds shared
|
|
6
6
|
references and the few explicit script exceptions.
|
|
7
7
|
|
|
8
8
|
Install DevRites through npm with `npx devrites ...`. DevRites is not available
|
|
@@ -49,6 +49,9 @@ contract when a rite names parallel reviewers.
|
|
|
49
49
|
Some specialized utilities set `disable-model-invocation: true` and run only
|
|
50
50
|
when explicitly invoked, which keeps the always-loaded skill surface small.
|
|
51
51
|
`devrites-*` is the specialist and library namespace used to avoid collisions.
|
|
52
|
+
`overhaul` sits outside both namespaces on purpose: it is a standalone,
|
|
53
|
+
explicit-only skill that needs no DevRites workspace or lifecycle; its deterministic
|
|
54
|
+
tools run as `devrites-engine overhaul` commands.
|
|
52
55
|
The `user-invocable:` and `disable-model-invocation:` fields, not the prefix,
|
|
53
56
|
set visibility and invocation policy. [`command-map.md`](command-map.md)
|
|
54
57
|
catalogs the effective values.
|
|
@@ -239,6 +242,12 @@ and `Shipped`. Utility commands keep the same compact labels and one-next-action
|
|
|
239
242
|
| [`rite-pr-feedback`](../pack/.claude/skills/rite-pr-feedback/SKILL.md) | Resolve PR review feedback: fetch unresolved threads, judge centrally, fix valid items, reply, resolve. | Explicit-only: `/rite-pr-feedback` / `/rite pr-feedback`. |
|
|
240
243
|
| [`rite-watch-pr`](../pack/.claude/skills/rite-watch-pr/SKILL.md) | Observe one PR/CI/review snapshot and report one next action without mutation. | Read-only capability-admitted native schedule/event observation or `/rite-watch-pr`. |
|
|
241
244
|
|
|
245
|
+
### Standalone: approval-gated overhaul
|
|
246
|
+
|
|
247
|
+
| Skill | What It Does | Use When |
|
|
248
|
+
|---|---|---|
|
|
249
|
+
| [`overhaul`](../pack/.claude/skills/overhaul/SKILL.md) | Audits a whole project, a PR or a branch comparison with separate frontend and backend engineering reviewers running concurrently, plus boundary, craft and specialist roles; reconciles verified findings into one plan and stops for the user's explicit approval of that exact plan revision. After approval it repairs test-first, verifies independently, measures, and keeps cycling inside the approved plan until the evidence-backed scores (global and per-lane 9.7, domains 9.0) and every hard gate pass or an honest blocker remains. It lives outside the DevRites lifecycle: no `.devrites/` workspace and no `/rite-*` phase; its records, admission, snapshot, scoring, benchmark and view tools are `devrites-engine overhaul` commands. Completion evidence is a run area outside the repository with canonical JSON records, a local HTML review and report, and a reviewable local patch; it never commits. | Explicit-only: `/overhaul`, `/overhaul full`, `/overhaul pr <n>`, `/overhaul branch <head> --base <base>`, `/overhaul audit …` (assessment only). |
|
|
250
|
+
|
|
242
251
|
### Foundation: engineering rules
|
|
243
252
|
|
|
244
253
|
| Skill | What It Does | Use When |
|
package/engine/help.go
CHANGED
|
@@ -5,6 +5,7 @@ import (
|
|
|
5
5
|
"io"
|
|
6
6
|
"strings"
|
|
7
7
|
|
|
8
|
+
"github.com/devrites/devrites/internal/overhaul"
|
|
8
9
|
"github.com/devrites/devrites/internal/parallel"
|
|
9
10
|
)
|
|
10
11
|
|
|
@@ -136,7 +137,7 @@ func shouldPrintHelp(args []string) bool {
|
|
|
136
137
|
return true
|
|
137
138
|
}
|
|
138
139
|
switch args[0] {
|
|
139
|
-
case "check", "state", "observe", "parallel", "gates", "claim", "detect", "note", "metrics", "handoff", "context", "orient", "migrate":
|
|
140
|
+
case "check", "state", "observe", "parallel", "gates", "claim", "detect", "note", "metrics", "handoff", "context", "orient", "migrate", "overhaul":
|
|
140
141
|
return len(args) >= 2 && args[1] == "help"
|
|
141
142
|
default:
|
|
142
143
|
return false
|
|
@@ -194,6 +195,8 @@ func commandHelp(args []string) (string, bool) {
|
|
|
194
195
|
return gatesFamilyUsage, true
|
|
195
196
|
case "note":
|
|
196
197
|
return noteFamilyUsage, true
|
|
198
|
+
case "overhaul":
|
|
199
|
+
return overhaul.Usage, true
|
|
197
200
|
case "migrate":
|
|
198
201
|
return migrateUsage, true
|
|
199
202
|
case "secret-scan":
|
package/engine/help_test.go
CHANGED
|
@@ -47,6 +47,8 @@ func TestCommandHelp(t *testing.T) {
|
|
|
47
47
|
{args: []string{"migrate", "--help"}, want: "migrate <slug>"},
|
|
48
48
|
{args: []string{"secret-scan", "--help"}, want: "secret-scan [--staged] [--stdin]"},
|
|
49
49
|
{args: []string{"open-visual", "--help"}, want: "open-visual <path-or-name>"},
|
|
50
|
+
{args: []string{"overhaul", "--help"}, want: "overhaul records validate <run>"},
|
|
51
|
+
{args: []string{"overhaul", "help"}, want: "overhaul snapshot capture <repo> <out>"},
|
|
50
52
|
{args: []string{"version", "--help"}, want: "devrites-engine version"},
|
|
51
53
|
{args: []string{"install", "--help"}, want: "usage: devrites-engine install"},
|
|
52
54
|
{args: []string{"update", "--help"}, want: "usage: devrites-engine update"},
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
package admit
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"encoding/json"
|
|
6
|
+
"os"
|
|
7
|
+
"path/filepath"
|
|
8
|
+
"strings"
|
|
9
|
+
"testing"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
type J = map[string]any
|
|
13
|
+
type L = []any
|
|
14
|
+
|
|
15
|
+
func write(t *testing.T, path string, v any) string {
|
|
16
|
+
t.Helper()
|
|
17
|
+
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
18
|
+
t.Fatal(err)
|
|
19
|
+
}
|
|
20
|
+
b, ok := v.(string)
|
|
21
|
+
if !ok {
|
|
22
|
+
raw, err := json.Marshal(v)
|
|
23
|
+
if err != nil {
|
|
24
|
+
t.Fatal(err)
|
|
25
|
+
}
|
|
26
|
+
b = string(raw)
|
|
27
|
+
}
|
|
28
|
+
if err := os.WriteFile(path, []byte(b), 0o644); err != nil {
|
|
29
|
+
t.Fatal(err)
|
|
30
|
+
}
|
|
31
|
+
return path
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
func run(args ...string) (int, string, string) {
|
|
35
|
+
var out, errb bytes.Buffer
|
|
36
|
+
code := Run(args, &out, &errb)
|
|
37
|
+
return code, out.String(), errb.String()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func newRun(t *testing.T) string {
|
|
41
|
+
dir := filepath.Join(t.TempDir(), "run")
|
|
42
|
+
write(t, filepath.Join(dir, "CURRENT"), "g0001\n")
|
|
43
|
+
write(t, filepath.Join(dir, "g0001/run.json"), J{"run_id": "run-1",
|
|
44
|
+
"revisions": J{"plan": J{"rev": 1, "file": "revisions/plan-r1.json"}}})
|
|
45
|
+
write(t, filepath.Join(dir, "g0001/dispatch.json"), J{"attempts": L{
|
|
46
|
+
J{"task_id": "T-1", "attempt_id": "A0", "role": "implementer", "lane": "fix", "snapshot": "s1", "status": "admitted"},
|
|
47
|
+
J{"task_id": "T-1", "attempt_id": "A1", "role": "implementer", "lane": "fix", "snapshot": "s1", "status": "running"},
|
|
48
|
+
J{"task_id": "R-1", "attempt_id": "A1", "role": "reviewer", "lane": "security", "snapshot": "s1", "status": "running"},
|
|
49
|
+
}})
|
|
50
|
+
write(t, filepath.Join(dir, "revisions/plan-r1.json"), J{"rev": 1, "tasks": L{
|
|
51
|
+
J{"id": "T-1", "allowed_paths": L{"src/a.py"}}, J{"id": "T-2", "allowed_paths": L{"src/b.py"}}}})
|
|
52
|
+
return dir
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
func writerReceipt() J {
|
|
56
|
+
return J{"schema": "overhaul.receipt/1", "run_id": "run-1", "task_id": "T-1", "attempt_id": "A1",
|
|
57
|
+
"role": "implementer", "lane": "fix", "snapshot": "s1", "started_at": "t0", "finished_at": "t1",
|
|
58
|
+
"outcome": "patch", "changed_paths": L{"src/a.py"}}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
func TestReceipt(t *testing.T) {
|
|
62
|
+
cases := []struct {
|
|
63
|
+
name string
|
|
64
|
+
mutate func(J)
|
|
65
|
+
observed string // "-" means no --observed flag
|
|
66
|
+
code int
|
|
67
|
+
want string
|
|
68
|
+
}{
|
|
69
|
+
{"writer admissible", func(J) {}, "src/a.py\n\n", 0, `{"verdict": "ADMISSIBLE", "reasons": []}`},
|
|
70
|
+
{"observed differs", func(J) {}, "src/b.py\n", 1, "observed paths ['src/b.py'] differ from claimed ['src/a.py']"},
|
|
71
|
+
{"claimed outside contract", func(r J) { r["changed_paths"] = L{"src/a.py", "src/c.py"} }, "src/a.py\nsrc/c.py\n", 1, "changed paths outside contract: ['src/c.py']"},
|
|
72
|
+
{"writer needs observed", func(J) {}, "-", 1, "writer receipt needs observed changed paths (--observed)"},
|
|
73
|
+
{"snapshot mismatch", func(r J) { r["snapshot"] = "s2" }, "src/a.py\n", 1, "snapshot differs from the dispatch packet"},
|
|
74
|
+
{"bad outcome", func(r J) { r["outcome"] = "done" }, "src/a.py\n", 1, "outcome must be one of ['findings', 'gap', 'no-findings', 'patch', 'verdict']"},
|
|
75
|
+
{"missing finished_at", func(r J) { delete(r, "finished_at") }, "src/a.py\n", 1, "missing finished_at"},
|
|
76
|
+
{"wrong run", func(r J) { r["run_id"] = "run-2" }, "src/a.py\n", 1, "wrong schema or run"},
|
|
77
|
+
{"unknown attempt", func(r J) { r["attempt_id"] = "A9" }, "-", 1, "no such dispatched attempt"},
|
|
78
|
+
{"duplicate or late", func(r J) { r["attempt_id"] = "A0" }, "src/a.py\n", 3, `{"verdict": "DUPLICATE_OR_LATE", "attempt_status": "admitted"}`},
|
|
79
|
+
{"reviewer no-findings without inspected", func(r J) {
|
|
80
|
+
r["task_id"], r["role"], r["lane"], r["outcome"] = "R-1", "reviewer", "security", "no-findings"
|
|
81
|
+
delete(r, "changed_paths")
|
|
82
|
+
}, "-", 1, "no-findings without inspected ranges is malformed"},
|
|
83
|
+
{"reviewer admissible", func(r J) {
|
|
84
|
+
r["task_id"], r["role"], r["lane"], r["outcome"], r["inspected"] = "R-1", "reviewer", "security", "no-findings", L{"src/a.py:1-9"}
|
|
85
|
+
}, "-", 0, "ADMISSIBLE"},
|
|
86
|
+
}
|
|
87
|
+
for _, c := range cases {
|
|
88
|
+
t.Run(c.name, func(t *testing.T) {
|
|
89
|
+
dir := newRun(t)
|
|
90
|
+
rc := writerReceipt()
|
|
91
|
+
c.mutate(rc)
|
|
92
|
+
args := []string{"receipt", dir, write(t, filepath.Join(dir, "receipts/r.json"), rc)}
|
|
93
|
+
if c.observed != "-" {
|
|
94
|
+
args = append(args, "--observed", write(t, filepath.Join(dir, "observed.txt"), c.observed))
|
|
95
|
+
}
|
|
96
|
+
code, out, errs := run(args...)
|
|
97
|
+
if code != c.code || !strings.Contains(out, c.want) {
|
|
98
|
+
t.Fatalf("want %d with %q, got %d:\n%s%s", c.code, c.want, code, out, errs)
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
func TestReceiptIOError(t *testing.T) {
|
|
105
|
+
dir := newRun(t)
|
|
106
|
+
if code, _, errs := run("receipt", dir, filepath.Join(dir, "missing.json")); code != 2 || !strings.HasPrefix(errs, "ERROR: ") {
|
|
107
|
+
t.Fatalf("got %d %s", code, errs)
|
|
108
|
+
}
|
|
109
|
+
if code, _, _ := run("receipt", dir, "x.json", "--observed"); code != 2 {
|
|
110
|
+
t.Fatalf("dangling --observed exit %d", code)
|
|
111
|
+
}
|
|
112
|
+
if code, _, _ := run("anchor"); code != 2 {
|
|
113
|
+
t.Fatalf("usage exit %d", code)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
func TestAnchor(t *testing.T) {
|
|
118
|
+
loc := func(path string, start, end int, quote string) J {
|
|
119
|
+
return J{"path": path, "start": start, "end": end, "quote": quote}
|
|
120
|
+
}
|
|
121
|
+
cases := []struct {
|
|
122
|
+
name string
|
|
123
|
+
findings L
|
|
124
|
+
code int
|
|
125
|
+
want string
|
|
126
|
+
}{
|
|
127
|
+
{"match", L{J{"id": "F-1", "locations": L{loc("src/a.py", 2, 2, " return request.user ")}}}, 0, `{"verdict": "ANCHORED", "reasons": []}`},
|
|
128
|
+
{"multi-line match", L{J{"id": "F-1", "locations": L{loc("src/a.py", 1, 2, "(request): return request")}}}, 0, "ANCHORED"},
|
|
129
|
+
{"wrong quote", L{J{"id": "F-1", "locations": L{loc("src/a.py", 2, 2, "return request.admin")}}}, 1, "F-1: quote not found at src/a.py:2-2"},
|
|
130
|
+
{"lines outside file", L{J{"id": "F-1", "locations": L{loc("src/a.py", 2, 9, "return request.user")}}}, 1, "F-1: src/a.py lines 2-9 outside file (3 lines)"},
|
|
131
|
+
{"path escape", L{J{"id": "F-1", "locations": L{loc("../secret.py", 1, 1, "top secret value")}}}, 1, "F-1: ../secret.py is not a file under the reviewed tree"},
|
|
132
|
+
{"directory", L{J{"id": "F-1", "locations": L{loc("src", 1, 1, "whatever long")}}}, 1, "is not a file under"},
|
|
133
|
+
{"too short", L{J{"id": "F-1", "locations": L{loc("src/a.py", 2, 2, "return")}}}, 1, "F-1: quote at src/a.py:2 is too short to anchor; quote the whole line"},
|
|
134
|
+
{"short quote equal to window", L{J{"id": "F-1", "locations": L{loc("src/a.py", 3, 3, "x = 1")}}}, 0, "ANCHORED"},
|
|
135
|
+
{"no locations", L{J{"id": "F-2"}}, 1, "F-2: no locations to anchor"},
|
|
136
|
+
}
|
|
137
|
+
for _, c := range cases {
|
|
138
|
+
t.Run(c.name, func(t *testing.T) {
|
|
139
|
+
dir := t.TempDir()
|
|
140
|
+
tree := filepath.Join(dir, "tree")
|
|
141
|
+
write(t, filepath.Join(tree, "src/a.py"), "def handler(request):\n return request.user\nx = 1\n")
|
|
142
|
+
write(t, filepath.Join(dir, "secret.py"), "top secret value\n")
|
|
143
|
+
code, out, errs := run("anchor", tree, write(t, filepath.Join(dir, "p.json"), J{"findings": c.findings}))
|
|
144
|
+
if code != c.code || !strings.Contains(out, c.want) {
|
|
145
|
+
t.Fatalf("want %d with %q, got %d:\n%s%s", c.code, c.want, code, out, errs)
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
func TestAnchorBadInput(t *testing.T) {
|
|
152
|
+
dir := t.TempDir()
|
|
153
|
+
for _, doc := range []any{J{"findings": L{}}, L{}, J{"items": L{J{"id": "F-1"}}}} {
|
|
154
|
+
code, _, errs := run("anchor", dir, write(t, filepath.Join(dir, "p.json"), doc))
|
|
155
|
+
if code != 2 || !strings.Contains(errs, `expected {"findings": [...]} with at least one finding`) {
|
|
156
|
+
t.Fatalf("%v: got %d %s", doc, code, errs)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
func TestSplitlines(t *testing.T) {
|
|
162
|
+
got := splitlines("a\r\nb\rc\n\nd\u2028e")
|
|
163
|
+
want := []string{"a", "b", "c", "", "d", "e"}
|
|
164
|
+
if strings.Join(got, "|") != strings.Join(want, "|") {
|
|
165
|
+
t.Fatalf("splitlines = %q", got)
|
|
166
|
+
}
|
|
167
|
+
if pyJSON("é\"<\x01") != `"\u00e9\"<\u0001"` {
|
|
168
|
+
t.Fatalf("pyJSON = %s", pyJSON("é\"<\x01"))
|
|
169
|
+
}
|
|
170
|
+
}
|