devrites 6.0.1 → 6.0.3

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 (156) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +15 -64
  3. package/SECURITY.md +7 -11
  4. package/bin/devrites.mjs +0 -8
  5. package/docs/adr/0034-workflow-artifact-byte-corrections-get-code-review.md +60 -0
  6. package/docs/adr/README.md +2 -1
  7. package/docs/architecture.md +2 -5
  8. package/docs/cli.md +4 -11
  9. package/docs/command-map.md +1 -2
  10. package/docs/engine/commands.md +6 -6
  11. package/docs/release.md +5 -6
  12. package/engine/help.go +12 -7
  13. package/engine/help_test.go +1 -0
  14. package/engine/internal/gate/readiness_binding.go +19 -0
  15. package/engine/internal/lib/cli_observe.go +16 -0
  16. package/engine/internal/lib/context.go +191 -19
  17. package/engine/internal/lib/context_next_test.go +186 -0
  18. package/engine/internal/lib/dispatch.go +146 -11
  19. package/engine/internal/lib/drift.go +10 -2
  20. package/engine/internal/lib/drift_test.go +29 -0
  21. package/engine/internal/lib/slicecheck.go +19 -0
  22. package/engine/internal/lib/slicecheck_test.go +41 -0
  23. package/engine/internal/lib/windows.go +109 -13
  24. package/engine/internal/lib/windows_test.go +85 -0
  25. package/engine/internal/release/release.go +3 -13
  26. package/engine/internal/release/release_test.go +6 -197
  27. package/engine/main.go +2 -2
  28. package/install.sh +1 -116
  29. package/pack/.claude/agents/devrites-slice-wright.md +3 -1
  30. package/pack/.claude/skills/devrites-debug-recovery/reference/hypotheses.md +6 -0
  31. package/pack/.claude/skills/devrites-lib/reference/parallel-dispatch.md +1 -0
  32. package/pack/.claude/skills/devrites-lib/reference/standards/README.md +1 -1
  33. package/pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md +2 -0
  34. package/pack/.claude/skills/devrites-lib/reference/standards/code-review.md +3 -0
  35. package/pack/.claude/skills/devrites-lib/reference/standards/glossary.md +1 -1
  36. package/pack/.claude/skills/devrites-lib/reference/standards/security.md +1 -0
  37. package/pack/.claude/skills/devrites-lib/reference/standards/windows.md +11 -3
  38. package/pack/.claude/skills/devrites-lib/reference/workspace-artifact-schema.md +5 -2
  39. package/pack/.claude/skills/rite-build/SKILL.md +1 -1
  40. package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +3 -2
  41. package/pack/.claude/skills/rite-build/reference/parallel-batch.md +5 -3
  42. package/pack/.claude/skills/rite-build/reference/phase-contract.md +5 -3
  43. package/pack/.claude/skills/rite-build/reference/spec-drift-guard.md +3 -1
  44. package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +23 -9
  45. package/pack/.claude/skills/rite-define/SKILL.md +2 -1
  46. package/pack/.claude/skills/rite-plan/SKILL.md +2 -1
  47. package/pack/.claude/skills/rite-pressure-test/SKILL.md +6 -3
  48. package/pack/.claude/skills/rite-vet/SKILL.md +9 -1
  49. package/pack/.claude/skills/rite-vet/reference/review-axes.md +6 -2
  50. package/pack/generated/claude/agents/devrites-slice-wright.md +3 -1
  51. package/pack/generated/claude/skills/devrites-debug-recovery/reference/hypotheses.md +6 -0
  52. package/pack/generated/claude/skills/devrites-lib/reference/parallel-dispatch.md +1 -0
  53. package/pack/generated/claude/skills/devrites-lib/reference/standards/README.md +1 -1
  54. package/pack/generated/claude/skills/devrites-lib/reference/standards/afk-hitl.md +2 -0
  55. package/pack/generated/claude/skills/devrites-lib/reference/standards/code-review.md +3 -0
  56. package/pack/generated/claude/skills/devrites-lib/reference/standards/glossary.md +1 -1
  57. package/pack/generated/claude/skills/devrites-lib/reference/standards/security.md +1 -0
  58. package/pack/generated/claude/skills/devrites-lib/reference/standards/windows.md +11 -3
  59. package/pack/generated/claude/skills/devrites-lib/reference/workspace-artifact-schema.md +5 -2
  60. package/pack/generated/claude/skills/rite-build/SKILL.md +1 -1
  61. package/pack/generated/claude/skills/rite-build/reference/one-slice-cycle.md +3 -2
  62. package/pack/generated/claude/skills/rite-build/reference/parallel-batch.md +5 -3
  63. package/pack/generated/claude/skills/rite-build/reference/phase-contract.md +5 -3
  64. package/pack/generated/claude/skills/rite-build/reference/spec-drift-guard.md +3 -1
  65. package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +23 -9
  66. package/pack/generated/claude/skills/rite-define/SKILL.md +2 -1
  67. package/pack/generated/claude/skills/rite-plan/SKILL.md +2 -1
  68. package/pack/generated/claude/skills/rite-pressure-test/SKILL.md +6 -3
  69. package/pack/generated/claude/skills/rite-vet/SKILL.md +9 -1
  70. package/pack/generated/claude/skills/rite-vet/reference/review-axes.md +6 -2
  71. package/pack/generated/codex/agents/devrites-slice-wright.toml +3 -1
  72. package/pack/generated/codex/skills/devrites-debug-recovery/reference/hypotheses.md +6 -0
  73. package/pack/generated/codex/skills/devrites-lib/reference/parallel-dispatch.md +1 -0
  74. package/pack/generated/codex/skills/devrites-lib/reference/standards/README.md +1 -1
  75. package/pack/generated/codex/skills/devrites-lib/reference/standards/afk-hitl.md +2 -0
  76. package/pack/generated/codex/skills/devrites-lib/reference/standards/code-review.md +3 -0
  77. package/pack/generated/codex/skills/devrites-lib/reference/standards/glossary.md +1 -1
  78. package/pack/generated/codex/skills/devrites-lib/reference/standards/security.md +1 -0
  79. package/pack/generated/codex/skills/devrites-lib/reference/standards/windows.md +11 -3
  80. package/pack/generated/codex/skills/devrites-lib/reference/workspace-artifact-schema.md +5 -2
  81. package/pack/generated/codex/skills/rite-build/SKILL.md +1 -1
  82. package/pack/generated/codex/skills/rite-build/reference/one-slice-cycle.md +3 -2
  83. package/pack/generated/codex/skills/rite-build/reference/parallel-batch.md +5 -3
  84. package/pack/generated/codex/skills/rite-build/reference/phase-contract.md +5 -3
  85. package/pack/generated/codex/skills/rite-build/reference/spec-drift-guard.md +3 -1
  86. package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +23 -9
  87. package/pack/generated/codex/skills/rite-define/SKILL.md +2 -1
  88. package/pack/generated/codex/skills/rite-plan/SKILL.md +2 -1
  89. package/pack/generated/codex/skills/rite-pressure-test/SKILL.md +6 -3
  90. package/pack/generated/codex/skills/rite-vet/SKILL.md +9 -1
  91. package/pack/generated/codex/skills/rite-vet/reference/review-axes.md +6 -2
  92. package/pack/generated/devin/agents/devrites-slice-wright.md +3 -1
  93. package/pack/generated/devin/skills/devrites-debug-recovery/reference/hypotheses.md +6 -0
  94. package/pack/generated/devin/skills/devrites-lib/reference/parallel-dispatch.md +1 -0
  95. package/pack/generated/devin/skills/devrites-lib/reference/standards/README.md +1 -1
  96. package/pack/generated/devin/skills/devrites-lib/reference/standards/afk-hitl.md +2 -0
  97. package/pack/generated/devin/skills/devrites-lib/reference/standards/code-review.md +3 -0
  98. package/pack/generated/devin/skills/devrites-lib/reference/standards/glossary.md +1 -1
  99. package/pack/generated/devin/skills/devrites-lib/reference/standards/security.md +1 -0
  100. package/pack/generated/devin/skills/devrites-lib/reference/standards/windows.md +11 -3
  101. package/pack/generated/devin/skills/devrites-lib/reference/workspace-artifact-schema.md +5 -2
  102. package/pack/generated/devin/skills/rite-build/SKILL.md +1 -1
  103. package/pack/generated/devin/skills/rite-build/reference/one-slice-cycle.md +3 -2
  104. package/pack/generated/devin/skills/rite-build/reference/parallel-batch.md +5 -3
  105. package/pack/generated/devin/skills/rite-build/reference/phase-contract.md +5 -3
  106. package/pack/generated/devin/skills/rite-build/reference/spec-drift-guard.md +3 -1
  107. package/pack/generated/devin/skills/rite-build/reference/wright-dispatch.md +23 -9
  108. package/pack/generated/devin/skills/rite-define/SKILL.md +2 -1
  109. package/pack/generated/devin/skills/rite-plan/SKILL.md +2 -1
  110. package/pack/generated/devin/skills/rite-pressure-test/SKILL.md +6 -3
  111. package/pack/generated/devin/skills/rite-vet/SKILL.md +9 -1
  112. package/pack/generated/devin/skills/rite-vet/reference/review-axes.md +6 -2
  113. package/pack/generated/omp/agents/devrites-slice-wright.md +3 -1
  114. package/pack/generated/omp/skills/devrites-debug-recovery/reference/hypotheses.md +6 -0
  115. package/pack/generated/omp/skills/devrites-lib/reference/parallel-dispatch.md +1 -0
  116. package/pack/generated/omp/skills/devrites-lib/reference/standards/README.md +1 -1
  117. package/pack/generated/omp/skills/devrites-lib/reference/standards/afk-hitl.md +2 -0
  118. package/pack/generated/omp/skills/devrites-lib/reference/standards/code-review.md +3 -0
  119. package/pack/generated/omp/skills/devrites-lib/reference/standards/glossary.md +1 -1
  120. package/pack/generated/omp/skills/devrites-lib/reference/standards/security.md +1 -0
  121. package/pack/generated/omp/skills/devrites-lib/reference/standards/windows.md +11 -3
  122. package/pack/generated/omp/skills/devrites-lib/reference/workspace-artifact-schema.md +5 -2
  123. package/pack/generated/omp/skills/rite-build/SKILL.md +1 -1
  124. package/pack/generated/omp/skills/rite-build/reference/one-slice-cycle.md +3 -2
  125. package/pack/generated/omp/skills/rite-build/reference/parallel-batch.md +5 -3
  126. package/pack/generated/omp/skills/rite-build/reference/phase-contract.md +5 -3
  127. package/pack/generated/omp/skills/rite-build/reference/spec-drift-guard.md +3 -1
  128. package/pack/generated/omp/skills/rite-build/reference/wright-dispatch.md +23 -9
  129. package/pack/generated/omp/skills/rite-define/SKILL.md +2 -1
  130. package/pack/generated/omp/skills/rite-plan/SKILL.md +2 -1
  131. package/pack/generated/omp/skills/rite-pressure-test/SKILL.md +6 -3
  132. package/pack/generated/omp/skills/rite-vet/SKILL.md +9 -1
  133. package/pack/generated/omp/skills/rite-vet/reference/review-axes.md +6 -2
  134. package/pack/generated/pi/agents/devrites-slice-wright.md +3 -1
  135. package/pack/generated/pi/skills/devrites-debug-recovery/reference/hypotheses.md +6 -0
  136. package/pack/generated/pi/skills/devrites-lib/reference/parallel-dispatch.md +1 -0
  137. package/pack/generated/pi/skills/devrites-lib/reference/standards/README.md +1 -1
  138. package/pack/generated/pi/skills/devrites-lib/reference/standards/afk-hitl.md +2 -0
  139. package/pack/generated/pi/skills/devrites-lib/reference/standards/code-review.md +3 -0
  140. package/pack/generated/pi/skills/devrites-lib/reference/standards/glossary.md +1 -1
  141. package/pack/generated/pi/skills/devrites-lib/reference/standards/security.md +1 -0
  142. package/pack/generated/pi/skills/devrites-lib/reference/standards/windows.md +11 -3
  143. package/pack/generated/pi/skills/devrites-lib/reference/workspace-artifact-schema.md +5 -2
  144. package/pack/generated/pi/skills/rite-build/SKILL.md +1 -1
  145. package/pack/generated/pi/skills/rite-build/reference/one-slice-cycle.md +3 -2
  146. package/pack/generated/pi/skills/rite-build/reference/parallel-batch.md +5 -3
  147. package/pack/generated/pi/skills/rite-build/reference/phase-contract.md +5 -3
  148. package/pack/generated/pi/skills/rite-build/reference/spec-drift-guard.md +3 -1
  149. package/pack/generated/pi/skills/rite-build/reference/wright-dispatch.md +23 -9
  150. package/pack/generated/pi/skills/rite-define/SKILL.md +2 -1
  151. package/pack/generated/pi/skills/rite-plan/SKILL.md +2 -1
  152. package/pack/generated/pi/skills/rite-pressure-test/SKILL.md +6 -3
  153. package/pack/generated/pi/skills/rite-vet/SKILL.md +9 -1
  154. package/pack/generated/pi/skills/rite-vet/reference/review-axes.md +6 -2
  155. package/package.json +1 -1
  156. package/scripts/install-lib.sh +0 -16
package/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
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
+ ## [6.0.3](https://github.com/ViktorsBaikers/DevRites/compare/v6.0.2...v6.0.3) (2026-10-14)
6
+
7
+ ### Changed
8
+
9
+ * **devrites:** cut rite-build time without weakening gates ([#104](https://github.com/ViktorsBaikers/DevRites/issues/104)) ([64133ca](https://github.com/ViktorsBaikers/DevRites/commit/64133ca070947c3e9b170f1ee978302d63937c03))
10
+
11
+ ### Fixed
12
+
13
+ * **no-release:** accept --help after dispatch subcommand ([#103](https://github.com/ViktorsBaikers/DevRites/issues/103)) ([532ce43](https://github.com/ViktorsBaikers/DevRites/commit/532ce4324ae155f891345f825cbd2e04dd37ae85))
14
+
15
+ ## [6.0.2](https://github.com/ViktorsBaikers/DevRites/compare/v6.0.1...v6.0.2) (2026-10-14)
16
+
17
+ ### Fixed
18
+
19
+ * **installer:** drop gh attestation requirement from installers ([ff27b58](https://github.com/ViktorsBaikers/DevRites/commit/ff27b58f569dffdc956ce4a4c759cb6427abc9bd))
20
+
5
21
  ## [6.0.1](https://github.com/ViktorsBaikers/DevRites/compare/v6.0.0...v6.0.1) (2026-10-14)
6
22
 
7
23
  ### Fixed
package/README.md CHANGED
@@ -31,7 +31,7 @@ history can't lose it. After you clear the conversation, switch hosts, or hand
31
31
  the feature to another engineer, the next session reads the same plan,
32
32
  decisions, and evidence before it continues.
33
33
 
34
- **Status:** [`v6.0.1`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v6.0.1): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
34
+ **Status:** [`v6.0.3`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v6.0.3): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
35
35
 
36
36
  This is the latest published release; `main` may contain unreleased work.
37
37
 
@@ -51,11 +51,6 @@ This is the latest published release; `main` may contain unreleased work.
51
51
  install and run DevRites. Development in this repository (`npm ci`, which
52
52
  `.npmrc` runs with `engine-strict=true`) needs Node.js 22.22.2 or later within
53
53
  22.x, or 24.15 or later; Node 23.x and 24.0 through 24.14 fail with `EBADENGINE`.
54
- `gh` (GitHub CLI) must also be installed and authenticated, not merely
55
- installed, because DevRites verifies the build-provenance attestation of every
56
- release asset it downloads. Run `gh auth login` once, then `gh auth status` to
57
- confirm. See [Install, update, and remove](#install-update-and-remove) for
58
- which routes fail without it and which fall back to a local build.
59
54
 
60
55
  ```bash
61
56
  npx devrites@latest
@@ -315,8 +310,7 @@ Run `npx devrites@latest --help` for common flags and
315
310
  <br>
316
311
 
317
312
  Download the release-owned installer and its checksum before executing it. It
318
- needs `curl`, `gzip`, and `tar`, plus `gh` (GitHub CLI) installed and
319
- authenticated (`gh auth login`).
313
+ needs `curl`, `gzip`, and `tar`.
320
314
 
321
315
  ```bash
322
316
  bootstrap_dir="$(mktemp -d)"
@@ -349,8 +343,6 @@ project_dir="$PWD"
349
343
  exit 1
350
344
  fi
351
345
  [ "$got" = "$want" ] || { echo 'error: install.sh checksum mismatch' >&2; exit 1; }
352
- command -v gh >/dev/null 2>&1 || { echo 'error: gh (GitHub CLI) is required and was not found' >&2; exit 1; }
353
- gh attestation verify install.sh --repo ViktorsBaikers/DevRites --signer-workflow ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main || { if gh auth status >/dev/null 2>&1; then echo 'error: install.sh attestation verification failed: no build provenance from ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main' >&2; else echo 'error: gh is not authenticated; run gh auth login' >&2; fi; exit 1; }
354
346
 
355
347
  # Choose one Node-free operation:
356
348
  bash ./install.sh --target "$project_dir" # install into the directory you ran this from
@@ -403,59 +395,19 @@ proof. `devrites-engine migrate` owns deterministic v5 schema normalization.
403
395
  See the [CLI contract](docs/cli.md) and
404
396
  [ADR-0029](docs/adr/0029-v5-workspace-schema-and-native-migration.md).
405
397
 
406
- Every release asset is verified with `gh attestation verify` before it is
407
- decompressed, extracted, or executed, so `gh` must be installed and
408
- authenticated (`gh auth login`). Without that, the Bash bootstrap (`install.sh`
409
- fetched with `curl`) and `devrites-engine update` are fatal: they stop with no
410
- fallback. `npx devrites@latest` instead falls back to compiling the shipped
411
- `engine/` with `go build` when Go is installed, and the engine acquisition in
412
- `scripts/install-lib.sh` (used by `install.sh` from a clone or an extracted
413
- bundle) has its own fallback of the same kind.
414
-
415
- Release binaries and installers ship with SHA-256 sidecars and
416
- build-provenance attestations. Verify a download with both
417
- `shasum -a 256 -c <file>.sha256` and
398
+ Every release asset is checked against its exact-filename SHA-256 sidecar
399
+ before it is decompressed, extracted, or executed. The installers do not need
400
+ GitHub CLI and do not run `gh attestation verify`.
401
+
402
+ Release binaries and installers also ship with build-provenance attestations.
403
+ The `.sha256` sidecar is fetched from the same origin as the artifact, so it is
404
+ a corruption check, not a provenance one. To check provenance yourself, run
418
405
  `gh attestation verify <file> -R ViktorsBaikers/DevRites --signer-workflow ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main`
419
- before it runs; the checksum alone is not enough (see the verified Bash
420
- bootstrap above).
421
- Pin the signer workflow, because valid provenance shows where a build ran
422
- but does not show that the intended publishing step produced it. See
406
+ on the downloaded file before it runs. This step is optional. Pin the signer
407
+ workflow, because valid provenance shows where a build ran but does not show
408
+ that the intended publishing step produced it. See
423
409
  [docs/release.md](docs/release.md).
424
410
 
425
- Read a failure as "prove provenance or stop", not as a verdict about your
426
- build. The bootstrap checks `gh` itself, exits 1 before `install.sh` runs, and
427
- prints the cause. It says `error: gh (GitHub CLI) is required and was not
428
- found` when `gh` is absent. When `gh` is present but logged out (`gh auth
429
- status` fails) it says `error: gh is not authenticated; run gh auth login`.
430
- Only when `gh` is logged in and still rejects the attestation does it say
431
- `error: install.sh attestation verification failed: no build provenance from
432
- ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main`. After that,
433
- `install.sh` verifies the release bundle `devrites-<tag>.tar.gz` and reports the
434
- same three causes as `attestation verification failed: gh (GitHub CLI) is
435
- required and was not found`, `attestation verification failed: gh is not
436
- authenticated ...; run 'gh auth login' and retry`, and `attestation verification
437
- failed: no build provenance from <signer>`. The engine binary is acquired
438
- separately: the bundled installer (`scripts/install-lib.sh`) and the npm route
439
- report `attestation verification failed (gh must be installed and
440
- authenticated)` for any of these causes, discard the downloaded binary, and
441
- fall back to other sources. The bundled installer builds from the bundle's
442
- `engine/` source when `go` is available, then tries an already-installed
443
- `devrites-engine`, and only when none works does `install.sh` exit 1 with
444
- `could not acquire devrites-engine` followed by that cause. `npx devrites@latest` repeats the combined message
445
- before exiting 127 when no other engine is available. `devrites-engine update` reports `gh (GitHub CLI) is
446
- required and must be authenticated for attestation verification` when `gh` is
447
- absent, and `attestation verification failed for <asset>` whenever a present
448
- `gh` rejects the asset, logged out or not.
449
-
450
- There is no flag to skip, disable, or bypass attestation verification. The
451
- `.sha256` sidecar is fetched from the same origin as the artifact, so a
452
- substituted origin supplies a digest that matches its own payload, which is why
453
- the sidecar is a corruption check and not a provenance one. If you cannot run
454
- `gh auth login`, install Go and use `npx devrites@latest`, or clone this
455
- repository and run `bash install.sh`: both compile `engine/` locally when the
456
- download is refused, with `cd engine && go build -o devrites-engine .` as the
457
- manual equivalent.
458
-
459
411
  </details>
460
412
 
461
413
  ## Hosts
@@ -527,10 +479,9 @@ traces. DevRites detects these tools but does not install them.
527
479
 
528
480
  - Installed host artifacts stay in the project. Use `--no-binary` or
529
481
  `DEVRITES_NO_BINARY=1` to avoid keeping a shared binary outside it.
530
- - npm, Bash, and `devrites-engine update` all require checksummed release
531
- assets that also pass `gh attestation verify`, pinned to
532
- `ViktorsBaikers/DevRites` and signer workflow
533
- `ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main` (see
482
+ - npm, Bash, and `devrites-engine update` all require release assets that
483
+ match their SHA-256 sidecars. Build-provenance attestations can be checked
484
+ manually with `gh attestation verify` (see
534
485
  [Install, update, and remove](#install-update-and-remove)). Remote fetches use HTTPS at every redirect hop, are bounded in size,
535
486
  and never fall back to an unchecked raw file, source archive, tag, or default
536
487
  branch.
package/SECURITY.md CHANGED
@@ -119,23 +119,20 @@ and `.codex/config.toml` without replacing unrelated user settings. The shared
119
119
  `devrites-engine` executable is the only allowed artifact outside the project.
120
120
  It is installed to `DEVRITES_BIN_DIR`, a writable `~/.local/bin`, or a writable
121
121
  `/usr/local/bin`; `--no-binary` / `DEVRITES_NO_BINARY=1` skips it. The bootstrap
122
- and direct updater may fetch the release bundle and checksummed engine assets,
123
- each of which must also pass `gh attestation verify` (pinned to `ViktorsBaikers/DevRites` and signer workflow `ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main`).
122
+ and direct updater may fetch the release bundle and checksummed engine assets.
124
123
  They never invoke `sudo` or edit shell startup files.
125
124
 
126
125
  The documented Node-free boundary downloads the release-owned `install.sh` and
127
- its exact-name sidecar, then requires both the checksum and the build-provenance
128
- attestation (`gh attestation verify`, pinned to `ViktorsBaikers/DevRites` and
129
- signer workflow `ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main`)
130
- to pass before execution, as in the README "verified Bash bootstrap"; mutable
126
+ its exact-name sidecar, then requires the checksum to pass before execution, as
127
+ in the README "verified Bash bootstrap"; mutable
131
128
  default-branch scripts are not recommended. Legacy local and extracted shim invocations remain compatible, but
132
129
  their exact-release guarantee begins at that verified asset. A piped shim never
133
130
  treats current-directory siblings as its bundle.
134
131
 
135
132
  Network acquisition accepts only an exact SemVer release asset and its mandatory
136
- exact-filename SHA-256 sidecar, and every release asset must also pass
137
- `gh attestation verify` (pinned to `ViktorsBaikers/DevRites` and signer workflow `ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main`;
138
- `gh` must be installed and authenticated, with no bypass). Every redirect hop must remain HTTPS, private
133
+ exact-filename SHA-256 sidecar. Installers do not run `gh attestation verify`;
134
+ release assets carry build-provenance attestations that users may verify
135
+ manually (see [docs/release.md](docs/release.md)). Every redirect hop must remain HTTPS, private
139
136
  temporary-directory creation must succeed, and unchecked raw/source/default-
140
137
  branch fallbacks are absent. Representative in-stream ceilings are 1 MiB for
141
138
  release metadata, 4 KiB for a sidecar, and 64 MiB for an archive or binary, with
@@ -154,8 +151,7 @@ and [ADR-0028](docs/adr/0028-self-contained-engine-update.md) own the rationale.
154
151
  With `npx devrites@latest`, the CLI (`bin/devrites.mjs`) calls
155
152
  `devrites-engine` directly instead of running `install.sh`. The bundled host
156
153
  payload is pinned to the requested npm package version. The shim first tries the
157
- matching exact-release binary, which must pass its mandatory SHA-256 sidecar and
158
- `gh attestation verify` (pinned to `ViktorsBaikers/DevRites` and signer workflow `ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main`),
154
+ matching exact-release binary, which must pass its mandatory SHA-256 sidecar,
159
155
  then a package-local Go build, and then an existing engine. Remote responses are
160
156
  byte-bounded and every redirect is checked before following it. It has no
161
157
  runtime npm dependencies. The same project and shared-binary boundaries apply
package/bin/devrites.mjs CHANGED
@@ -190,14 +190,6 @@ async function downloadEngine() {
190
190
  rmSync(`${out}.sha256`, { force: true });
191
191
  return null;
192
192
  }
193
- const signer = `${repo}/.github/workflows/ci.yml@refs/heads/main`;
194
- const attestation = spawnSync('gh', ['attestation', 'verify', out, '--repo', repo, '--signer-workflow', signer], { stdio: 'ignore', timeout: 120_000 });
195
- if (attestation.error || attestation.status !== 0) {
196
- acquisitionFailure = `release ${tag} asset ${name}: attestation verification failed (gh must be installed and authenticated)`;
197
- rmSync(out, { force: true });
198
- rmSync(`${out}.sha256`, { force: true });
199
- return null;
200
- }
201
193
  try {
202
194
  chmodSync(out, 0o755);
203
195
  } catch {
@@ -0,0 +1,60 @@
1
+ # ADR-0034: Workflow Artifact byte corrections get code review, not a plan loop
2
+
3
+ - **Status:** Accepted
4
+ - **Date:** 2026-10-15
5
+
6
+ ## Context
7
+
8
+ A Workflow Artifact is a root-authored executable file under `.devrites/` that
9
+ proves a slice (for example a native UI test launcher). Vet admits its design:
10
+ paths, modes, behavior/interface/fixture rows, and the proof command. The root
11
+ authors the bytes in a disposable preflight after Vet `READY`. The source handle
12
+ derives from the readiness binding (ADR-0027), so promoting corrected bytes
13
+ needs a new binding, and only Vet may record one.
14
+
15
+ In practice every bug fix in such a script ran `/rite-plan repair` (plan-drafter)
16
+ plus an affected `/rite-vet` (plan-reviewer). The plan reviewer then reviewed
17
+ Python cleanup and rollback code. One measured feature spent 36% of agent time
18
+ after Build started in Plan and Vet. All 144 of its Plan/Vet waves served one
19
+ slice's proof harness, for example four consecutive archive-policy repair/Vet
20
+ pairs for close and rollback bugs.
21
+
22
+ ## Decision
23
+
24
+ - A correction that leaves every admission row and `WA-*` reference row
25
+ unchanged is a technical fix. It follows `OFFLINE_RECOVERY` and never
26
+ `/rite-plan repair`.
27
+ - The root records the corrected bytes' identity digest as one exact
28
+ `test-plan.md` line below the admission block:
29
+ `Workflow Artifact reviewed identity: <64 lowercase hex>`.
30
+ - `devrites-engine check drift` keeps a second digest of `test-plan.md` with
31
+ only that exact line shape removed. When it is the only change across all
32
+ readiness inputs, the drift is reported as `reviewed-identity-only`.
33
+ - In that case narrow `/rite-vet` dispatches one fresh `devrites-code-reviewer`
34
+ on the prior-source→re-preflight diff against the unchanged admission rows,
35
+ instead of a plan drafter and plan reviewer. Fold and recheck follow the
36
+ canonical retry contract. Green review lets Vet record the new binding as
37
+ usual (ADR-0027 still applies; the engine never refreshes it).
38
+ - Any other drift, including a malformed identity line, keeps the existing
39
+ narrow recheck by the plan reviewer.
40
+
41
+ This narrows ADR-0027's "semantic review" for this one case to an independent
42
+ code review of the exact bytes. The Workflow Artifact module, source-handle
43
+ derivation, routes, and golden values are unchanged.
44
+
45
+ ## Consequences
46
+
47
+ - The reviewed bytes are now bound into a readiness input. Before this, Vet
48
+ approved the design but never the exact corrected bytes.
49
+ - A contract change to a Workflow Artifact still goes through Plan and Vet.
50
+ - Slice-bound Vet rechecks also count toward the per-slice round cap
51
+ (`dispatch open --slice`), so a harness that keeps failing forces a recorded
52
+ reslice or simpler-proof review.
53
+
54
+ ## Alternatives considered
55
+
56
+ | Option | Why not |
57
+ |---|---|
58
+ | Derive the source handle from the identity digest | Changes the protocol's crypto, golden values, and the reference model test, for the same saving. |
59
+ | Let the engine refresh the binding after review | ADR-0027 keeps binding renewal a Vet act; the engine stays thin. |
60
+ | Keep plan-reviewer for byte fixes | Measured cost above; a plan reviewer is the wrong specialist for code defects. |
@@ -72,10 +72,11 @@ architecture; per-feature `decisions.md` files stay scoped to that feature.
72
72
  | [0024](0024-native-policy-offline-installer-boundary.md) | Native policy and offline installer boundary | Accepted in part; offline engine-update clause superseded by 0028 | `tests/native-orchestration-contract-test.sh`, `tests/phase-gate-routing-test.sh`, `tests/install-smoke.sh`, `tests/host-artifacts-test.sh` |
73
73
  | [0025](0025-evidence-gated-workspace-upgrades.md) | Evidence-gated semantic workspace upgrades | Accepted; no-migrator scope superseded by 0029 | `tests/phase-gate-routing-test.sh`, `tests/host-artifacts-test.sh` |
74
74
  | [0026](0026-content-bound-proof-and-bounded-inputs.md) | Content-bound proof and bounded inputs | Accepted | `engine/internal/lib/candidate_test.go`, `engine/internal/lib/evidencefresh_test.go`, `engine/internal/gate/gate_test.go`, `engine/root_routing_test.go`, `engine/tests/parity_githelpers_test.go`, `tests/native-orchestration-contract-test.sh`, `tests/phase-gate-routing-test.sh`, `tests/install-smoke.sh`, `tests/update-smoke.sh`, `tests/npx-pack-smoke.sh`, `tests/release-tarball-test.sh` |
75
- | [0027](0027-content-bound-build-readiness.md) | Content-bound build readiness | Accepted; AC ID map amended 2026-09-04 | `engine/tests/adr_0027_readiness_binding_test.go`, `engine/internal/state/acceptance_test.go` |
75
+ | [0027](0027-content-bound-build-readiness.md) | Content-bound build readiness | Accepted; AC ID map amended 2026-09-04; semantic review narrowed by 0034 for Workflow Artifact byte fixes | `engine/tests/adr_0027_readiness_binding_test.go`, `engine/internal/state/acceptance_test.go` |
76
76
  | [0028](0028-self-contained-engine-update.md) | Self-contained engine update | Accepted | `engine/internal/install/install_test.go`, `engine/internal/release/release_test.go`, `engine/tests/meta_test.go` |
77
77
  | [0029](0029-v5-workspace-schema-and-native-migration.md) | v5 workspace schema and native migration | Accepted | `engine/internal/state/workspaceschema_test.go`, `engine/tests/parity_resolve_test.go`, `engine/tests/parity_closeout_test.go` |
78
78
  | 0030 | Reserved number; no ADR is published under it | Unpublished | none |
79
79
  | [0031](0031-overhaul-agents-keep-every-tool.md) | `/overhaul` ships its own agents that keep every tool | Accepted; scopes the one-writer clauses of 0010/0015/0017/0018/0019 to `devrites-*` specialists | `scripts/validate-agent-composition.py`, `tests/codex-agent-generation-test.sh` |
80
80
  | [0032](0032-single-lint-gate-and-cached-pr-tests.md) | One engine lint gate, and PR tests that reuse main's results | Accepted | `tests/validation-governance-test.sh` |
81
81
  | [0033](0033-rite-fast-own-agents.md) | `/rite-fast` ships its own agents and its own writer | Accepted; adds `fast-builder` as a writer outside the `devrites-*` one-writer rule | `scripts/validate-agent-composition.py`, `tests/rite-fast-contract-test.sh` |
82
+ | [0034](0034-workflow-artifact-byte-corrections-get-code-review.md) | Workflow Artifact byte corrections get code review, not a plan loop | Accepted; narrows 0027's semantic review for contract-preserving Workflow Artifact byte fixes | `engine/internal/lib/drift_test.go` |
@@ -154,8 +154,7 @@ consume only local source, payload, and binary candidates.
154
154
 
155
155
  Direct `devrites-engine update` uses the separate `engine/internal/release`
156
156
  boundary to resolve the latest stable release and acquire its checksummed bundle
157
- and platform engine, each also checked with `gh attestation verify` (pinned to `ViktorsBaikers/DevRites` and signer workflow `ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main`;
158
- `gh` must be installed and authenticated). It then invokes the downloaded engine with local paths, so
157
+ and platform engine. It then invokes the downloaded engine with local paths, so
159
158
  the candidate validates its own payload schema. `update --check` resolves only
160
159
  release metadata and downloads no assets. Engine `--to` and `--pre` selectors do
161
160
  not exist.
@@ -164,9 +163,7 @@ The shell entrypoints
164
163
  (`bin/devrites.mjs`) remain equivalent acquisition adapters. They acquire and
165
164
  verify the exact-release bundle or binary, then pass local paths and user flags
166
165
  through to the deterministic engine operation. All network paths require exact SemVer,
167
- HTTPS-only redirects, exact-filename SHA-256 sidecars, a `gh attestation verify`
168
- pass for every release asset (pinned to `ViktorsBaikers/DevRites` and signer workflow `ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main`;
169
- see [Install, update, and remove](../README.md#install-update-and-remove)), private temporary
166
+ HTTPS-only redirects, exact-filename SHA-256 sidecars, private temporary
170
167
  directories, bounded transfers, and full archive preflight. They provide no
171
168
  unchecked raw, source-archive, tag, or default-branch fallback.
172
169
 
package/docs/cli.md CHANGED
@@ -76,11 +76,7 @@ Run `devrites-engine update` in an installed project to resolve the latest
76
76
  stable release and update the project pack plus shared engine binary. The
77
77
  command downloads the release bundle and platform engine, verifies both exact
78
78
  filenames against their SHA-256 sidecars, then hands the extracted candidate to
79
- the downloaded engine. Each release asset must also pass `gh attestation verify`,
80
- pinned to `ViktorsBaikers/DevRites` and signer workflow `ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main`,
81
- so `gh` must be installed and authenticated, with no bypass (see
82
- [Install, update, and remove](../README.md#install-update-and-remove)). This
83
- avoids asking an old engine to validate a newer payload schema.
79
+ the downloaded engine. This avoids asking an old engine to validate a newer payload schema.
84
80
 
85
81
  `devrites-engine update --check` resolves and compares release metadata without
86
82
  downloading assets. `--source-dir` and `--payload-dir` remain the advanced local
@@ -100,9 +96,8 @@ comparison without changing the installation. Use
100
96
  retaining the shared `devrites-engine` binary.
101
97
 
102
98
  If an older direct engine reports `missing codex/hooks.json` or asks for
103
- `--source-dir`, run `npx devrites@latest update`, or use a release `install.sh` that is both
104
- checksum-verified and attestation-verified (pinned repo and signer workflow, see
105
- the verified Bash bootstrap under
99
+ `--source-dir`, run `npx devrites@latest update`, or use a release `install.sh` that is
100
+ checksum-verified (see the verified Bash bootstrap under
106
101
  [README Install, update, and remove](../README.md#install-update-and-remove))
107
102
  and run `bash ./install.sh update` once to install a release with the
108
103
  self-contained updater.
@@ -271,9 +266,7 @@ commands refuse ambiguous, escaped, symlinked, or otherwise unsafe roots.
271
266
  Install, update application, and uninstall remain manifest-owned local
272
267
  operations. Direct engine update, shell, and npm may acquire a release candidate;
273
268
  all remote acquisition uses exact SemVer, HTTPS-only redirect hops, mandatory
274
- exact-filename SHA-256 sidecars, a `gh attestation verify` check of every release
275
- asset (pinned to `ViktorsBaikers/DevRites` and signer workflow `ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main`;
276
- `gh` must be installed and authenticated, with no bypass), private temporary
269
+ exact-filename SHA-256 sidecars, private temporary
277
270
  directories, and byte/archive bounds, with no unchecked raw/source/default-branch
278
271
  fallback. Update accepts
279
272
  `--check` to compare the installed manifest version with the latest stable
@@ -74,8 +74,7 @@ Scans cap captured input at 64 MiB and entries/findings at 4,096; findings expos
74
74
  metadata only and source or limit errors fail closed.
75
75
 
76
76
  Direct `devrites-engine update` acquires the latest exact-release pack and
77
- platform binary, each verified by SHA-256 sidecar and `gh attestation verify`
78
- (`gh` installed and authenticated), then hands local paths to the downloaded engine. Shell/npm may
77
+ platform binary, each verified by SHA-256 sidecar, then hands local paths to the downloaded engine. Shell/npm may
79
78
  perform the same acquisition before invoking the local path. `--check` compares
80
79
  the installed version with latest release metadata without downloading assets;
81
80
  engine release selectors are unsupported.
@@ -18,12 +18,12 @@ workflow strategy.
18
18
  | `check path-disjoint [--root <dir>] [<json-file> | -]` | Verify slice path sets are pairwise disjoint. |
19
19
  | `parallel select --cap <1-10> [--root <dir>] [<json-file> | -]` | Choose the greedy path-disjoint subset ≤ cap from supplied ready slices. |
20
20
  | `parallel <create\|integrate\|cleanup\|status\|abort\|lease-read\|lease-write\|lease-clear\|record-green>` | Deterministic parallel worktree leases, integration, and cleanup for parallel writer batches. |
21
- | `check task-graph <slug>` | Validate `tasks.md` slice dependency graph for cycles, unknown deps, malformed tokens, duplicate IDs, missing `Dependencies`, and `depends_on` mismatch. |
21
+ | `check task-graph <slug>` | Validate `tasks.md` slice dependency graph for cycles, unknown deps, malformed tokens, duplicate IDs, missing `Dependencies`, and `depends_on` mismatch. Prints a non-blocking `ADVISORY size:` line (and records a `size-advisory` metric) for each slice with 12+ Writer allowlist files and no `Size rationale:`. |
22
22
  | `check regression <slug> [--update]` | Compare the workspace's structural progress facts (phase ordinal, checked ACs, met/abandoned gates, done slices, resolved questions, present artifacts) against the recorded `regression-baseline.json` high-water mark; `--update` ratchets the baseline forward under the feature lock and prints each blessed regression. |
23
- | `check drift <slug> [--record]` | Attribute readiness-input changes to the exact artifact. `--record` writes the per-input `readiness-inputs.json` digest baseline under the feature lock; without it the workspace diffs current inputs against that baseline (or falls back to the aggregate binding recorded in `eng-review.md`). Advisory: exit `0` on drift; a corrupt baseline exits `3`. |
24
- | `check windows <slug> [--worktree\|--staged\|--base <ref>]` | Fail on deferral markers (TODO/FIXME/XXX/HACK, skipped-test and stub idioms) the change's added lines introduce without a waiver row in the workspace's `windows.md`. |
23
+ | `check drift <slug> [--record]` | Attribute readiness-input changes to the exact artifact. `--record` writes the per-input `readiness-inputs.json` digest baseline under the feature lock; without it the workspace diffs current inputs against that baseline (or falls back to the aggregate binding recorded in `eng-review.md`). Advisory: exit `0` on drift; a corrupt baseline exits `3`. A `test-plan.md` change limited to exact `Workflow Artifact reviewed identity: <64hex>` lines is reported as `reviewed-identity-only` (ADR-0034). |
24
+ | `check windows <slug> [--worktree\|--staged\|--base <ref>]` | Fail on deferral and bar-lowering markers the change introduces without a waiver row in the workspace's `windows.md`: added TODO/FIXME/XXX/HACK, skipped/focused-test and stub idioms, checker suppressions, one-line empty catch; removed `deleted-test` files and net `removed-assertion` lines in remaining test files. |
25
25
  | `check dup [slug] [--all\|--worktree\|--staged\|--base <ref>] [--min-lines n] [--threshold f] [--ignore-file <path>] [--limit n] [--exclude <csv>]` | Report near-duplicate code clusters that survive comment stripping, literal collapsing, and identifier renaming — token-shingle matches chained into segments, clustered transitively, ranked with bounded path/line-distance boosts. Diff modes mark units overlapping changed hunks with `*`; stable content-derived cluster hashes let `.devrites/dup-ignore` dismissals survive line moves but resurface on structural edits. Staged mode reads index blobs and excludes untracked files. Bounded heuristic: successful scans/leads exit `0`; usage, unavailable input, and partial scans exit `2`. |
26
- | `check slice <slug> <SLICE-ID>` | Pre-dispatch lint of one slice's wright contract: contract present, exact Writer allowlist paths, resolvable `Satisfies` AC ids, bounded scope. |
26
+ | `check slice <slug> <SLICE-ID>` | Pre-dispatch lint of one slice's wright contract: contract present, exact Writer allowlist paths, resolvable `Satisfies` AC ids, bounded scope. Same non-blocking size advisory as `check task-graph`. |
27
27
  | `check diff-scope <slug> --allow <csv>\|--allow-file <path> [--worktree\|--staged\|--base <ref>]` | Verify the changed-path set stays inside the declared allowlist; the mechanical gate run before reviewer dispatch. |
28
28
  | `check skill-trust <path>` | Scan one skill/agent Markdown file for structural trust violations. |
29
29
  | `check indexes [--root <dir>]` | Report install manifest and code-index presence as JSON. |
@@ -32,8 +32,8 @@ workflow strategy.
32
32
  | `observe slice <slug> <SLICE-ID>` | Print one `SLICE-###` section of `tasks.md` so Build reads a slice, not the file. |
33
33
  | `next [slug]` | Print the minimal remaining lifecycle path plus advisory skips. |
34
34
  | `handoff [slug]` | Emit the deterministic resume record: cursor fields, `awaiting_human`, open `questions.md` gate kinds, the `gates.md` reduction with unmet/stale/abandoned ids, `decisions.md` dead ends, missing required files, and the canonical read-next order. Read-only; the `/rite-handoff` spine and the compaction-fallback entry point. |
35
- | `context [slug] (--phase <p>\|--skill <name>) [--role <r>] [--trigger a,b]` | Emit one deduplicated read-set bundle per phase/role/skill from each skill's `loads:` manifest; `--skill` works without a workspace when `--out` is given. |
36
- | `dispatch <slug> <open\|start\|seal\|return\|status\|abandon>` | Launch-wave barrier for parallel dispatch: seal needs a handle per role, return needs seal; start/return auto-record metrics. |
35
+ | `context [slug] (--phase <p>\|--skill <name>) [--role <r>] [--slice <SLICE-ID>] [--trigger a,b]` | Emit one deduplicated read-set bundle per phase/role/skill from each skill's `loads:` manifest; `--skill` works without a workspace when `--out` is given. A `--role` bundle leads with the role's agent contract and names the manifest's `rootOnly` paths instead of inlining them. `--slice` inlines that slice's `tasks.md` block and turns each over-budget artifact into a by-reference index (path, SHA-256, headings, line hits for every ID the block cites); repeat `--slice` for several slices; an unknown slice exits `3`. |
36
+ | `dispatch <slug> <open\|start\|seal\|return\|status\|abandon>` | Launch-wave barrier for parallel dispatch: seal needs a handle per role, return needs seal; start/return auto-record metrics. A build wave with a wright role needs `--slice <SLICE-ID>` per slice, and a slice-bound vet wave takes it too; every 5 rounds of either kind on one slice, `open` exits `3` until `--reslice-review <DRIFT-ID>` names an unused `drift.md` `## <DRIFT-ID>` heading for that slice. |
37
37
  | `metrics record <slug> --phase <p> --event <e> [--role r] [--bytes n] [--note s]` | Append an event to the workspace's `metrics.jsonl` ledger. |
38
38
  | `metrics summary [slug]` | Reduce `metrics.jsonl` into a per-phase roll-up. |
39
39
  | `claim <add\|release\|list\|check>` | Advisory session-scoped file claims in `.devrites/claims.jsonl` (append-only). `add` records intent to write a path set with a TTL (1–240 min, default 30); a live claim by another session exits `3` and names the holder. `release` appends a release event owned by the claiming session. `list` shows live claims (`--all` includes expired/released). `check` is the read-only preflight for a path set. Coordination aid only — never a substitute for one-writer-per-worktree. |
package/docs/release.md CHANGED
@@ -31,9 +31,8 @@ the missing host payload before handing that local candidate to the engine. The
31
31
  engine itself only validates and copies host payloads; it never generates them.
32
32
  The npm entrypoint, verified release installer, and direct engine updater acquire
33
33
  only an exact-SemVer release bundle or platform binary with its mandatory
34
- exact-filename SHA-256 sidecar, and each such asset must also pass
35
- `gh attestation verify` (pinned to `ViktorsBaikers/DevRites` and signer workflow `ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main`;
36
- `gh` must be installed and authenticated, with no bypass).
34
+ exact-filename SHA-256 sidecar. They do not run `gh attestation verify`; that
35
+ check is an optional manual step (below).
37
36
 
38
37
  Verify a downloaded engine binary from a GitHub Release:
39
38
 
@@ -45,7 +44,8 @@ curl -q -LO "https://github.com/ViktorsBaikers/DevRites/releases/download/v<vers
45
44
 
46
45
  Every release artifact also carries a GitHub artifact attestation (build
47
46
  provenance generated inside the release job, bound to the artifact digest).
48
- Verify it, pinning the signer workflow so an attestation minted from any other
47
+ The installers do not check it, and GitHub CLI is not needed to install.
48
+ To verify it manually, pin the signer workflow so an attestation minted from any other
49
49
  workflow path in this repository is rejected — provenance proves where a build
50
50
  ran, not that the publishing step was the intended one:
51
51
 
@@ -80,8 +80,7 @@ or path breach before extraction (at most 10,000 members, 4,096-byte paths, and
80
80
  256 MiB expanded files). Metadata is capped at 1 MiB, sidecars at 4 KiB,
81
81
  archives/binaries at 64 MiB, and the Node adapter follows at most five redirects.
82
82
  There is no raw, source-archive, tag, or default-branch acquisition fallback;
83
- exact-release guarantees begin at the checksummed release `install.sh` asset that
84
- also passes `gh attestation verify` (pinned to `ViktorsBaikers/DevRites` and signer workflow `ViktorsBaikers/DevRites/.github/workflows/ci.yml@refs/heads/main`).
83
+ exact-release guarantees begin at the checksummed release `install.sh` asset.
85
84
  The Go release boundary may acquire the latest stable candidate; the downloaded
86
85
  engine then supplies local paths to the manifest-owned update core. Engine
87
86
  `update --check` resolves release metadata but downloads no assets. `--to` and
package/engine/help.go CHANGED
@@ -125,16 +125,20 @@ func takesSubcommand(command string) bool {
125
125
  }
126
126
  }
127
127
 
128
- // claimValueFlags are the claim flags that consume the next argument as a value.
129
- var claimValueFlags = map[string]bool{"--session": true, "--reason": true, "--ttl": true, "--id": true}
128
+ // valueFlags lists, per command, the flags that consume the next argument as a
129
+ // value. A command listed here has known flags, so its help flag is honoured
130
+ // anywhere except as the value of one of these flags.
131
+ var valueFlags = map[string]map[string]bool{
132
+ "claim": {"--session": true, "--reason": true, "--ttl": true, "--id": true},
133
+ "dispatch": {"--phase": true, "--wave": true, "--role": true, "--handle": true, "--reason": true},
134
+ }
130
135
 
131
136
  // hasHelpFlag reports whether args (the arguments after the command word) are a
132
137
  // help request. The command path is consumed by dispatch, so a help flag is
133
138
  // honoured among the leading flags that follow it. The scan stops at the first
134
139
  // argument that does not start with a dash, because from there the engine
135
- // cannot tell a flag from a value or operand. Only claim, whose value flags are
136
- // known, honours a help flag later, and never one that is the value of such a
137
- // flag.
140
+ // cannot tell a flag from a value or operand. Commands in valueFlags honour a
141
+ // help flag later, and never one that is the value of such a flag.
138
142
  func hasHelpFlag(command string, args []string) bool {
139
143
  if len(args) > 0 && !strings.HasPrefix(args[0], "-") && takesSubcommand(command) {
140
144
  args = args[1:]
@@ -143,9 +147,10 @@ func hasHelpFlag(command string, args []string) bool {
143
147
  if isHelpFlag(args[i]) {
144
148
  return true
145
149
  }
146
- if command == "claim" && claimValueFlags[args[i]] {
150
+ known, ok := valueFlags[command]
151
+ if ok && known[args[i]] {
147
152
  i++
148
- } else if command != "claim" && !strings.HasPrefix(args[i], "-") {
153
+ } else if !ok && !strings.HasPrefix(args[i], "-") {
149
154
  return false
150
155
  }
151
156
  }
@@ -48,6 +48,7 @@ func TestCommandHelp(t *testing.T) {
48
48
  {args: []string{"handoff", "--help"}, want: "handoff [slug]"},
49
49
  {args: []string{"next", "help"}, want: "devrites-engine next [slug]"},
50
50
  {args: []string{"dispatch", "help"}, want: "devrites-engine dispatch <slug>"},
51
+ {args: []string{"dispatch", "x", "open", "--help"}, want: "devrites-engine dispatch <slug>"},
51
52
  {args: []string{"secret-scan", "help"}, want: "secret-scan [--staged] [--stdin]"},
52
53
  {args: []string{"open-visual", "help"}, want: "open-visual <path-or-name>"},
53
54
  {args: []string{"claim", "--help"}, want: "claim <add|release|list|check>"},
@@ -7,6 +7,7 @@ import (
7
7
  "errors"
8
8
  "fmt"
9
9
  "hash"
10
+ "regexp"
10
11
  "strings"
11
12
 
12
13
  "github.com/devrites/devrites/internal/markdowntext"
@@ -147,6 +148,20 @@ type ReadinessInputDigest struct {
147
148
  Path string `json:"path"`
148
149
  Present bool `json:"present"`
149
150
  SHA256 string `json:"sha256,omitempty"`
151
+ // Normalized is test-plan.md's digest without its reviewed-identity lines,
152
+ // so drift can prove a Workflow Artifact byte correction changed nothing
153
+ // else Vet approved.
154
+ Normalized string `json:"normalized,omitempty"`
155
+ }
156
+
157
+ // reviewedIdentityRE is the exact test-plan.md line binding the Workflow
158
+ // Artifact bytes an independent code review approved. Only this exact shape
159
+ // is ignored, so the exclusion cannot hide any other edit.
160
+ var reviewedIdentityRE = regexp.MustCompile(`(?m)^Workflow Artifact reviewed identity: [0-9a-f]{64}\r?\n?`)
161
+
162
+ // withoutReviewedIdentity drops every exact reviewed-identity line.
163
+ func withoutReviewedIdentity(content []byte) []byte {
164
+ return reviewedIdentityRE.ReplaceAll(content, nil)
150
165
  }
151
166
 
152
167
  // ReadinessInputDigests returns each readiness input's content digest plus the
@@ -172,6 +187,10 @@ func ReadinessInputDigests(root, slug string) ([]ReadinessInputDigest, string, e
172
187
  if present {
173
188
  sum := sha256.Sum256(content)
174
189
  entry.SHA256 = hex.EncodeToString(sum[:])
190
+ if input.logical == "test-plan.md" {
191
+ normalized := sha256.Sum256(withoutReviewedIdentity(content))
192
+ entry.Normalized = hex.EncodeToString(normalized[:])
193
+ }
175
194
  }
176
195
  digests = append(digests, entry)
177
196
  }
@@ -5,6 +5,7 @@ import (
5
5
  "io"
6
6
 
7
7
  "github.com/devrites/devrites/internal/devritespaths"
8
+ "github.com/devrites/devrites/internal/state"
8
9
  )
9
10
 
10
11
  // RunTaskGraphCheck validates tasks.md for one slug.
@@ -21,6 +22,21 @@ func RunTaskGraphCheck(root, slug string, stdout, stderr io.Writer) int {
21
22
  return 3
22
23
  }
23
24
  fmt.Fprintf(stdout, "task-graph: ok (%d slices)\n", len(graph.Slices))
25
+ // Size advisory: never changes the exit code; the metric shows how often
26
+ // it would have fired before anyone makes it blocking.
27
+ if raw, err := readWorkspaceArtifact(root, slug, "tasks.md"); err == nil {
28
+ over := 0
29
+ for _, s := range graph.Slices {
30
+ block, _ := state.ExtractTaskSlice(raw, s.ID)
31
+ if n, ok := sliceSizeAdvisory(block); ok {
32
+ fmt.Fprintf(stdout, "task-graph: ADVISORY size: %s has %d Writer allowlist files (>= %d); split it (acceptance-preserving) or record `Size rationale:`\n", s.ID, n, sliceFileAdvisory)
33
+ over++
34
+ }
35
+ }
36
+ if over > 0 {
37
+ recordMetric(root, slug, "define", "size-advisory", "", int64(over))
38
+ }
39
+ }
24
40
  return 0
25
41
  }
26
42