devrites 7.3.2 → 7.3.4

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 (69) hide show
  1. package/CHANGELOG.md +41 -2
  2. package/README.md +21 -1
  3. package/docs/cli.md +98 -13
  4. package/docs/command-map.md +2 -2
  5. package/docs/engine/commands.md +10 -5
  6. package/docs/engine/workspace-schema.md +4 -3
  7. package/engine/commands.go +1 -1
  8. package/engine/help.go +3 -1
  9. package/engine/internal/hostpack/hostpack.go +1 -1
  10. package/engine/internal/lib/apply_bundle.go +25 -8
  11. package/engine/internal/lib/continuation.go +33 -4
  12. package/engine/internal/lib/dispatch.go +46 -31
  13. package/engine/internal/lib/frontier.go +808 -0
  14. package/engine/internal/lib/handoff.go +2 -5
  15. package/engine/internal/lib/next.go +10 -0
  16. package/engine/internal/lib/regression.go +0 -5
  17. package/engine/internal/lib/resolve.go +33 -16
  18. package/engine/internal/parallel/cli.go +16 -5
  19. package/engine/internal/parallel/ops.go +7 -5
  20. package/engine/internal/parallel/repository.go +13 -0
  21. package/engine/internal/release/release.go +96 -5
  22. package/engine/internal/rootfacts/facts.go +11 -0
  23. package/engine/internal/state/lock_other.go +4 -0
  24. package/engine/internal/state/write.go +54 -13
  25. package/engine/main.go +6 -2
  26. package/pack/.claude/skills/devrites-lib/reference/parallel-workspaces.md +41 -40
  27. package/pack/.claude/skills/rite-autocomplete/SKILL.md +10 -10
  28. package/pack/.claude/skills/rite-autocomplete/reference/loop.md +6 -6
  29. package/pack/.claude/skills/rite-build/reference/parallel-batch.md +7 -7
  30. package/pack/.claude/skills/rite-doctor/SKILL.md +70 -68
  31. package/pack/generated/README.md +1 -1
  32. package/pack/generated/claude/skills/devrites-lib/reference/parallel-workspaces.md +41 -40
  33. package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +10 -10
  34. package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +6 -6
  35. package/pack/generated/claude/skills/rite-build/reference/parallel-batch.md +7 -7
  36. package/pack/generated/claude/skills/rite-doctor/SKILL.md +70 -68
  37. package/pack/generated/codex/skills/devrites-lib/reference/parallel-workspaces.md +41 -40
  38. package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +10 -10
  39. package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +6 -6
  40. package/pack/generated/codex/skills/rite-build/reference/parallel-batch.md +7 -7
  41. package/pack/generated/codex/skills/rite-doctor/SKILL.md +70 -68
  42. package/pack/generated/devin/skills/devrites-lib/reference/parallel-workspaces.md +41 -40
  43. package/pack/generated/devin/skills/rite-autocomplete/SKILL.md +10 -10
  44. package/pack/generated/devin/skills/rite-autocomplete/reference/loop.md +6 -6
  45. package/pack/generated/devin/skills/rite-build/reference/parallel-batch.md +7 -7
  46. package/pack/generated/devin/skills/rite-doctor/SKILL.md +70 -68
  47. package/pack/generated/dsh/skills/devrites-lib/reference/parallel-workspaces.md +41 -40
  48. package/pack/generated/dsh/skills/rite-autocomplete/SKILL.md +10 -10
  49. package/pack/generated/dsh/skills/rite-autocomplete/reference/loop.md +6 -6
  50. package/pack/generated/dsh/skills/rite-build/reference/parallel-batch.md +7 -7
  51. package/pack/generated/dsh/skills/rite-doctor/SKILL.md +70 -68
  52. package/pack/generated/omp/skills/devrites-lib/reference/parallel-workspaces.md +41 -40
  53. package/pack/generated/omp/skills/devrites-lib/reference/standards/agents.md +1 -1
  54. package/pack/generated/omp/skills/rite-autocomplete/SKILL.md +10 -10
  55. package/pack/generated/omp/skills/rite-autocomplete/reference/loop.md +6 -6
  56. package/pack/generated/omp/skills/rite-build/reference/parallel-batch.md +7 -7
  57. package/pack/generated/omp/skills/rite-build/reference/wright-dispatch.md +1 -1
  58. package/pack/generated/omp/skills/rite-doctor/SKILL.md +70 -68
  59. package/pack/generated/pi/AGENTS.md +1 -1
  60. package/pack/generated/pi/skills/devrites-lib/reference/parallel-workspaces.md +41 -40
  61. package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +10 -10
  62. package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +6 -6
  63. package/pack/generated/pi/skills/rite-build/reference/parallel-batch.md +7 -7
  64. package/pack/generated/pi/skills/rite-doctor/SKILL.md +70 -68
  65. package/package.json +1 -1
  66. package/scripts/build-host-artifacts.sh +1 -1
  67. package/scripts/dsh-generate.py +5 -1
  68. package/scripts/omp-generate.sh +4 -4
  69. package/scripts/pi-generate.sh +3 -3
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
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
+ ## [7.3.4](https://github.com/ViktorsBaikers/DevRites/compare/v7.3.3...v7.3.4) (2026-11-03)
6
+
7
+ ### Fixed
8
+
9
+ * **devrites:** restore global frontier and authenticated updates ([#207](https://github.com/ViktorsBaikers/DevRites/issues/207)) ([05cb719](https://github.com/ViktorsBaikers/DevRites/commit/05cb7198330b7ffa4d7176fc8398ff5a86b13f45))
10
+
11
+ ## [7.3.3](https://github.com/ViktorsBaikers/DevRites/compare/v7.3.2...v7.3.3) (2026-11-02)
12
+
13
+ ### Fixed
14
+
15
+ * **devrites:** harden workflow mutations and host diagnostics ([#206](https://github.com/ViktorsBaikers/DevRites/issues/206)) ([849a7d1](https://github.com/ViktorsBaikers/DevRites/commit/849a7d182c13453f4a542bd2b4c58f9adccebe22))
16
+
5
17
  ## [7.3.2](https://github.com/ViktorsBaikers/DevRites/compare/v7.3.1...v7.3.2) (2026-11-02)
6
18
 
7
19
  ### Fixed
@@ -28,8 +40,35 @@ All notable changes to DevRites are documented here. The format follows [Keep a
28
40
  parallel controller, with rolling landings and refills across workspace sources.
29
41
  - Prune clean integrated worker checkouts without discarding transfer branches,
30
42
  proof identities, retained lease rows, or running siblings.
31
-
32
- ### Fixed
43
+ - Add read-only `frontier [slug]` reporting across recorded live and archived
44
+ sequence workspaces, with scoped preparation/repair/wait actions, explicit
45
+ mixed-workspace selection, and ambiguous-source refusal. Source-local selection
46
+ exposes the frontier without silently admitting other workspaces.
47
+
48
+ ### Fixed
49
+
50
+ - Use `GH_TOKEN`, then `GITHUB_TOKEN`, then optional bounded noninteractive GitHub
51
+ CLI credential lookup for release API requests. Keep credentials off release
52
+ assets and off-origin redirects, fail explicit invalid credentials, and document
53
+ headless login and rate-limit recovery without exposing tokens.
54
+ - Continue AFK from the narrow Vet-ready state and from actionable global native
55
+ preparation, preserving human gates, source cursors, and separate Ship approval.
56
+ - Allow independent refill and capacity reconciliation after a parallel integration
57
+ failure without clearing its failure status or weakening pending-landing,
58
+ control-tip, overlap, capacity, or proof guards.
59
+ - Enforce wright fanout and wider-batch guards even when a reslice review admits
60
+ another round window.
61
+ - Recover a completed dispatch wave's retained claim through an exact recorded
62
+ return handle after claim-release failure, without replaying result admission.
63
+ - Confine question resolution to checked workspaces and restore question/cursor
64
+ files together when publication fails. Bundle rollback now includes the failing
65
+ target and reports incomplete restoration.
66
+ - Verify Windows root-handle rename protection in resolution race tests while
67
+ preserving replacement coverage on platforms that permit renaming open roots.
68
+ - Honor explicitly acknowledged backward-phase repair checkpoints in regression
69
+ baselines while retaining ordinary regression and empty-acceptance checks.
70
+ - Check Pi/omp native role loading in doctor, clarify instruction-only shell
71
+ boundaries, and validate OMP invocations plus Codex reference documents.
33
72
 
34
73
  - Recover exact recorded parallel landings after interrupted lease persistence;
35
74
  preserve late worker edits, ignored data, extra commits, and missing-checkout
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:** [`v7.3.2`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v7.3.2): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
34
+ **Status:** [`v7.3.4`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v7.3.4): 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
 
@@ -273,6 +273,15 @@ no-recommendation questions still pause. When bounded recovery runs out,
273
273
  agents record a technical blocker instead of asking you. The full contract is
274
274
  in [`afk-hitl.md`](pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md).
275
275
 
276
+ `devrites-engine frontier [slug]` reports the recorded sequence across live and
277
+ archived workspaces without changing `ACTIVE`, creating workspaces, or launching
278
+ agents. It distinguishes preparation, repair, waiting, and completed work, and
279
+ prints an explicit mixed-workspace selection command when available. A source-local
280
+ `parallel select --from-plan` exposes that frontier but still selects only its own
281
+ workspace unless `--workspaces` is supplied. Native Autocomplete owns preparation
282
+ and semantic admission; the report is neither Build readiness nor Ship approval.
283
+ See the [frontier contract](docs/cli.md#sequence-frontier).
284
+
276
285
  ## Install, update, and remove
277
286
 
278
287
  ```bash
@@ -419,6 +428,17 @@ release assets. If an older engine reports `missing codex/hooks.json` or asks
419
428
  for `--source-dir`, use the npm or verified shell route once to reach a
420
429
  release with the self-contained updater.
421
430
 
431
+ GitHub release API authentication uses `GH_TOKEN`, then `GITHUB_TOKEN`, then an
432
+ optional, bounded, noninteractive `gh auth token --hostname github.com` lookup.
433
+ GitHub CLI is not required. Credentials go only to the exact GitHub API origin,
434
+ never release assets or off-origin redirects. Explicit invalid credentials fail
435
+ instead of silently falling back to another identity. For a headless machine,
436
+ run `gh auth login --hostname github.com --web` and complete its device-code flow
437
+ in a browser on another device. Do not paste credentials into commands, logs, or
438
+ support reports. `--force` controls managed-file replacement; it does not bypass
439
+ GitHub authentication or rate limits. If authentication does not clear a rate
440
+ limit, wait before retrying.
441
+
422
442
  `/rite-upgrade` is the separate, preservation-first route for reconciling an
423
443
  unfinished workspace; it never migrates cursor format or invents historical
424
444
  proof. `devrites-engine migrate` owns deterministic v5 schema normalization.
package/docs/cli.md CHANGED
@@ -43,6 +43,7 @@ devrites-engine observe summary <slug>
43
43
  devrites-engine orient <slug>
44
44
  devrites-engine observe slice <slug> <SLICE-ID>
45
45
  devrites-engine next [slug]
46
+ devrites-engine frontier [slug]
46
47
  devrites-engine handoff [slug] [--resume]
47
48
  devrites-engine recall --paths <p1,p2,...> [--limit n]
48
49
  devrites-engine context [slug] (--phase <p>|--skill <name>) [--role <r>] [--whole]
@@ -90,6 +91,21 @@ downloading assets. `--source-dir` and `--payload-dir` remain the advanced local
90
91
  update path for npm, shell, source-checkout, and test callers; a local `--check`
91
92
  needs only `--source-dir`.
92
93
 
94
+ Release metadata requests to the exact HTTPS `api.github.com` origin use the
95
+ first available credential: `GH_TOKEN`, then `GITHUB_TOKEN`, then optional
96
+ `gh auth token --hostname github.com`. The helper is noninteractive, bounded to
97
+ three seconds and 4 KiB of output; missing, failed, timed-out, or oversized helper
98
+ output does not prevent an unauthenticated request. GitHub CLI is not required.
99
+ An explicitly supplied invalid credential fails; the updater does not silently
100
+ retry under another identity. Credentials are never sent to release assets or
101
+ off-origin redirects. Same-origin GitHub API redirects may retain them.
102
+
103
+ On a headless machine, run `gh auth login --hostname github.com --web`, then use
104
+ the displayed device code in a browser on another device. Do not put credential
105
+ values in commands, examples, logs, or support reports. `--force` permits
106
+ managed-file replacement, not authentication or rate-limit bypass. Authenticated
107
+ requests can still be rate-limited; wait before retrying when necessary.
108
+
93
109
  ## npm adapter
94
110
 
95
111
  The `npx devrites` adapter accepts `add` as an alias for `install`, `upgrade` for
@@ -143,18 +159,27 @@ self-contained updater.
143
159
  against the durable `regression-baseline.json` high-water mark. A lost fact
144
160
  prints `REGRESSION: <detail>` and exits `3`. `--update` rewrites the baseline
145
161
  under the feature lock at a durable checkpoint and prints each regression it
146
- blesses as `REGRESSION-BLESSED`; with no baseline recorded the check reports
147
- `unproven` and exits `0`. Recommended placement: compare on a cold resume or
148
- scheduled wake before acting on durable state, ratchet after a landed slice
149
- checkpoint or phase advance, and treat `BLOCKED` at Seal as NO-GO; `--update`
150
- never excuses an unreconciled regression.
162
+ blesses as `REGRESSION-BLESSED`. A deliberate owner-authorized repair checkpoint
163
+ may accept a backward phase along with other acknowledged facts: the current
164
+ phase becomes the new baseline. Ordinary checks never bless losses or change
165
+ the baseline. If the update would remove every checked acceptance criterion and
166
+ met gate, `--allow-empty` is also required. With no baseline recorded the check
167
+ reports `unproven` and exits `0`. Recommended placement: compare on a cold
168
+ resume or scheduled wake before acting on durable state, ratchet after a landed
169
+ slice checkpoint or phase advance, and treat `BLOCKED` at Seal as NO-GO.
170
+ Never use automatic updates to hide an unreconciled regression.
151
171
  - `check continuation [slug]` prints `continuation: required` and
152
- `invoke: <next_action>` when `.devrites/AFK` is present, `status` is
153
- `running`, no question cursor is set, no blocking or escalating question is
154
- open, and `next_action` is an internal phase command (`/rite-vet`,
155
- `/rite-build`, not `/rite-ship`). Otherwise it prints `continuation: clear`.
156
- Exit `0` either way: `required` means invoke that command, not pause for a
157
- human. `handoff` prints the same lines.
172
+ `invoke: <next_action>` when `.devrites/AFK` is a regular file, `status` is
173
+ `running` (or specifically `phase=vet,status=ready`), no question cursor is
174
+ set, no blocking or escalating question is open, and `next_action` is a valid
175
+ internal phase command, not `/rite-ship`. Other ready statuses do not inherit
176
+ this exception. It also reports the sequence frontier: when the local cursor
177
+ is clear but related work needs native preparation, it can print
178
+ `continuation: required` with `invoke: /rite-autocomplete` and the original
179
+ source identity. Waiting, human-blocked, or completed work alone does not
180
+ require continuation. Neither result authorizes Ship, overrides a human gate,
181
+ or declares an unvetted workspace Build-ready. Successful verdicts exit `0`;
182
+ malformed or ambiguous state fails visibly. `handoff` prints the same lines.
158
183
  - `check drift <slug>` attributes readiness-input drift to the exact artifact.
159
184
  `--record` snapshots per-input SHA-256 digests into `readiness-inputs.json`
160
185
  under the feature lock after Vet records the aggregate binding; a later
@@ -227,6 +252,62 @@ checked by the root's explicit native re-read checklist. Repository build,
227
252
  test, lint, typecheck, schema, and release commands belong to that repository
228
253
  or CI.
229
254
 
255
+ ## Sequence frontier
256
+
257
+ `devrites-engine frontier [slug]` is a read-only structural report across the
258
+ source's recorded sequence. An explicit slug may name a live or archived
259
+ workspace. Without one, the command uses the selected source; if `ACTIVE` is
260
+ absent, recovery requires a unique archived terminal sequence tip with an exact
261
+ recorded native `/rite-spec <next>` edge. Multiple possible sources fail as ambiguous;
262
+ folder names and numeric suffixes are not authority.
263
+
264
+ The report emits:
265
+
266
+ - `frontier: actionable|waiting|blocked|clear`, or `frontier: none` for a
267
+ non-sequence source.
268
+ - `frontier-source: <slug>` and `frontier-workspace:` rows naming each related
269
+ workspace's `location=live|archive|missing`, `action=inspect|prepare|repair|wait|complete`,
270
+ and reason. Archived intermediaries do not hide live descendants, and archived
271
+ workspaces never become writer candidates.
272
+ Running or execution-unknown dispatch roles wait; completed writer returns
273
+ without durable acceptance require native inspection, not another writer launch.
274
+ - `frontier-select-command:` with an explicit `parallel select --from-plan
275
+ --workspaces ...` command when a live controller is available. Selection still
276
+ enforces current readiness, recorded dependencies and independence, retained
277
+ leases, path conflicts, and the repository-wide capacity. `frontier-picks:`
278
+ names eligible source-qualified slices; `frontier-selection: blocked` names a
279
+ selection refusal. These are observations, not writer launches.
280
+ The explicit pool excludes retained dispatch and human/question/scope-held
281
+ sources; their workspace rows remain visible. `--workspaces` is the exact
282
+ candidate list; `--slug` identifies the controller, not an implicit candidate.
283
+ Legacy per-source slice counters never reduce the global writer cap or exclude
284
+ independent children; recorded workspace-opening limits still apply.
285
+ - `frontier-prepare:` for a recorded next Spec cursor or an unambiguous next entry
286
+ in an exact position/workspace table, or `frontier-review-sequence:` artifact
287
+ paths when remaining work or conflicting sequence maps require native review.
288
+
289
+ Relations come from exact recorded `sequence_parent` edges, not name prefixes.
290
+ Conflicting identities, cycles, malformed related state, or invalid declared
291
+ sequence positions are refused. Missing or stale planning is a repair action,
292
+ not permission to build. Continuation flags and remaining counts constrain new
293
+ workspace preparation without silently discarding existing children.
294
+ Conflicting or amended sequence maps suppress missing-workspace preparation even
295
+ with a recorded Spec cursor until native authority normalization resolves them;
296
+ valid existing live descendants remain visible and eligible for guarded selection.
297
+
298
+ Under AFK, `next`, `handoff`, and `check continuation` expose the same frontier.
299
+ A source-local `parallel select --from-plan` without `--workspaces` also prints
300
+ the report to stderr, preserving its machine-readable selection on stdout and
301
+ source-local picks: reporting another workspace never silently admits it.
302
+ Native Autocomplete must inspect the returned preparation and review
303
+ actions, read the approved roadmap and recorded restrictions, then invoke the
304
+ owning Spec/Plan/Vet steps or explicit mixed selection. Path disjointness alone
305
+ does not establish semantic independence or lift a planning-only restriction.
306
+
307
+ The engine does not invoke models, create workspaces, change `ACTIVE`, resolve
308
+ semantic authority, or grant Ship approval. These outputs guide the native host;
309
+ they cannot guarantee that an arbitrary host follows the workflow.
310
+
230
311
  ## Acceptance ledger
231
312
 
232
313
  `gates` operates the `gates.md` ledger inside a feature workspace: one gate per
@@ -254,8 +335,12 @@ without it any `answered_by:` line in the resolved block, whatever its indentati
254
335
  `state close` transactionally archives a shipped workspace and clears matching
255
336
  `ACTIVE`.
256
337
 
257
- The mutating forms share the engine's root-safety, locking, and atomic-write
258
- boundary.
338
+ Mutations share root-safety checks, feature locks, and atomic per-file writes.
339
+ `state resolve` and `state apply-bundle` restore attempted files after returned
340
+ publication errors; `rollback incomplete` identifies files needing inspection
341
+ and recovery. These multi-file operations are not crash-atomic: process
342
+ termination can leave partial updates, and unlocked readers can see intermediate
343
+ state. Inspect both artifacts before resuming after an interrupted publication.
259
344
 
260
345
  The root scans and rechecks `questions.md` to allocate the next unused qid,
261
346
  manages Clarify return fields without rewriting unrelated Markdown, charges an
@@ -41,8 +41,8 @@ The Go surface is intentionally closed and deterministic:
41
41
 
42
42
  | Lane | Commands | Owner |
43
43
  |---|---|---|
44
- | Candidate and deterministic checks | `check candidate`, `check readiness [--emit-binding]`, `check preconditions <slug> [--slice <SLICE-ID>]`, `check seal`, `check slice <slug> <SLICE-ID>`, `check task-graph`, `check regression <slug> [--update]`, `check continuation [slug]`, `check drift <slug> [--record]`, `check windows <slug>`, `check dup`, `check path-disjoint`, `parallel select`, `check skill-trust`, `check indexes`, `detect commands [--root <dir>] [--json]` | Candidate validates/hashes the strict project manifest; readiness checks phase files, the required `tasks.md` slice graph, or emits the vetted Build-input binding; `check preconditions` runs the `test-plan.md` preflight rows whose `Run at` is `vet` (or `pre-dispatch <SLICE>`) with candidate-bound transcripts; seal checks final files/open gates, that graph and binding, then exact candidate bindings. `check slice` preflights one slice before wright dispatch — contract present, exact Writer allowlist paths, `Satisfies` AC ids resolvable, bounded scope — so a malformed slice fails before a writer context is spent. `check indexes` reports install manifest and optional code-index directory presence as JSON. `parallel select` returns the greedy path-disjoint subset ≤ cap from the supplied ready slices, or with `--from-plan` from tasks.md slices whose dependencies state.md checks built. `check regression` compares current workspace progress against the durable `regression-baseline.json` high-water mark and `--update` ratchets it at a checkpoint, so a lost slice, unchecked criterion, or reopened question fails closed instead of passing silently. `check continuation` prints `required` and the phase command to invoke when AFK, `status=running`, and `next_action` is an internal phase edge; `clear` otherwise. Exit 0 either way. `handoff` prints the same lines. `check windows` scans the feature diff for newly introduced deferral markers (TODO/FIXME/skipped test/stub idioms) and fails when any lacks a `windows.md` waiver row — silent deferrals block the seal. `check dup` reports advisory near-duplicate clusters that survive renaming (normalized token shingles, transitive clusters, distance-boosted rank, `*`-marked diff overlap, stable content hashes, `.devrites/dup-ignore` dismissal ledger) — leads for reviewer triage, never a gate. `check drift` attributes readiness-input drift to the exact artifact: `--record` snapshots per-input SHA-256 digests into `readiness-inputs.json` under the feature lock, and a later compare names each `changed`/`missing`/`added` input (falling back to the aggregate `eng-review.md` binding plus mtime candidates when no baseline exists) so a stale-binding repair starts at the right file — advisory, never a gate. `detect commands` resolves the repository's own test/lint/vet/build commands (Makefile targets, then `package.json` scripts, then language-manifest fallbacks, plus the lockfile-derived package manager) so `gates.md` `CHECK` lines and proof steps cite real wiring instead of invented commands — read-only, no installs, no execution. |
45
- | Workspace observation | `observe summary`, `orient`, `observe slice <slug> <SLICE-ID>`, `next`, `handoff` | JSON workspace snapshot for agents (cursor, task graph, `artifact_budgets`, `bulk_files`); `orient` is an alias for `observe summary`. `observe slice` prints one `SLICE-###` section of `tasks.md` so Build reads a slice, not the file. `next` prints the minimal remaining lifecycle path plus advisory skips (e.g. clarify at zero open questions). `handoff` emits the deterministic resume record (cursor, `awaiting_human`, blocking question gates, ledger reduction with unmet/stale ids, dead ends, read-next order, continuation verdict) — the `/rite-handoff` spine and compaction-fallback entry. |
44
+ | Candidate and deterministic checks | `check candidate`, `check readiness [--emit-binding]`, `check preconditions <slug> [--slice <SLICE-ID>]`, `check seal`, `check slice <slug> <SLICE-ID>`, `check task-graph`, `check regression <slug> [--update]`, `check continuation [slug]`, `check drift <slug> [--record]`, `check windows <slug>`, `check dup`, `check path-disjoint`, `parallel select`, `check skill-trust`, `check indexes`, `detect commands [--root <dir>] [--json]` | Candidate validates/hashes the strict project manifest; readiness checks phase files, the required `tasks.md` slice graph, or emits the vetted Build-input binding; `check preconditions` runs the `test-plan.md` preflight rows whose `Run at` is `vet` (or `pre-dispatch <SLICE>`) with candidate-bound transcripts; seal checks final files/open gates, that graph and binding, then exact candidate bindings. `check slice` preflights one slice before wright dispatch — contract present, exact Writer allowlist paths, `Satisfies` AC ids resolvable, bounded scope — so a malformed slice fails before a writer context is spent. `check indexes` reports install manifest and optional code-index directory presence as JSON. `parallel select` returns the greedy path-disjoint subset ≤ cap from the supplied ready slices, or with `--from-plan` from tasks.md slices whose dependencies state.md checks built; source-local selection reports the sequence frontier without silently admitting other workspaces. `check regression` compares current workspace progress against the durable `regression-baseline.json` high-water mark and `--update` ratchets it at a checkpoint, so a lost slice, unchecked criterion, or reopened question fails closed instead of passing silently. `check continuation` prints `required` and the phase command when AFK, `status=running` (or specifically `phase=vet,status=ready`), and an internal phase edge passes human/question guards; actionable global preparation may instead require `/rite-autocomplete`, never Ship authorization. Successful `required`/`clear` verdicts exit 0; malformed or ambiguous state fails visibly. `handoff` prints the same lines. `check windows` scans the feature diff for newly introduced deferral markers (TODO/FIXME/skipped test/stub idioms) and fails when any lacks a `windows.md` waiver row — silent deferrals block the seal. `check dup` reports advisory near-duplicate clusters that survive renaming (normalized token shingles, transitive clusters, distance-boosted rank, `*`-marked diff overlap, stable content hashes, `.devrites/dup-ignore` dismissal ledger) — leads for reviewer triage, never a gate. `check drift` attributes readiness-input drift to the exact artifact: `--record` snapshots per-input SHA-256 digests into `readiness-inputs.json` under the feature lock, and a later compare names each `changed`/`missing`/`added` input (falling back to the aggregate `eng-review.md` binding plus mtime candidates when no baseline exists) so a stale-binding repair starts at the right file — advisory, never a gate. `detect commands` resolves the repository's own test/lint/vet/build commands (Makefile targets, then `package.json` scripts, then language-manifest fallbacks, plus the lockfile-derived package manager) so `gates.md` `CHECK` lines and proof steps cite real wiring instead of invented commands — read-only, no installs, no execution. |
45
+ | Workspace observation | `observe summary`, `orient`, `observe slice <slug> <SLICE-ID>`, `next`, `frontier [slug]`, `handoff` | JSON workspace snapshot for agents (cursor, task graph, `artifact_budgets`, `bulk_files`); `orient` is an alias for `observe summary`. `observe slice` prints one `SLICE-###` section of `tasks.md` so Build reads a slice, not the file. `next` prints the minimal remaining lifecycle path plus advisory skips (e.g. clarify at zero open questions). `frontier` reports recorded live/archive sequence relations, scoped actions, explicit mixed selection, and native preparation/review needs without changing ACTIVE or admitting writers; ambiguous source recovery refuses. Under AFK, `next` and `handoff` expose the same frontier while retaining the source cursor. `handoff` emits the deterministic resume record (cursor, `awaiting_human`, blocking question gates, ledger reduction with unmet/stale ids, dead ends, read-next order, continuation verdict) — the `/rite-handoff` spine and compaction-fallback entry. |
46
46
  | Context packets, dispatch waves, metrics, claims, notes | `context [slug] (--phase <p> \| --skill <name>) [--role <r>] [--trigger a,b]`, `dispatch <slug> <open\|start\|seal\|return\|status\|abandon>`, `candidate freeze`, `packet`, `metrics record`, `metrics summary`, `claim <add\|release\|list\|check>`, `note <add\|list\|check\|rm>` | `context` emits one deduplicated read-set bundle per phase/role/skill from each skill's `loads:` manifest — a dispatch target reads it instead of selecting files; `--skill` works without a workspace when `--out` is given. `dispatch` owns the launch-wave barrier (seal needs a handle per role; return needs seal; the last start seals; open --claim-session/--claim takes the wave's file claim, released by the completing return or abandon --release) and auto-records dispatch/return metrics. `candidate freeze` writes a wave's frozen `packets/<w>.diff` + `.sha256`; `packet` renders and lints one role's by-reference packet. `metrics` owns the append-only `metrics.jsonl` ledger. `claim` owns the append-only `.devrites/claims.jsonl` ledger — advisory, session-scoped file claims with TTL so concurrent same-tree sessions see each other's write intent before edits collide (conflict exits 3; never a substitute for one-writer-per-worktree). `note` owns the anchored `notes.md` ledger — notes bound to verbatim code quotes, regraded `exact`/`moved`/`stale`/`ambiguous`/`lost` as the code drifts; `check seal` refuses non-`exact` anchors. `check diff-scope` is the mechanical changed-paths ⊆ allowlist gate run before reviewer dispatch. |
47
47
  | Atomic workspace state | `state resolve`, `state merge-manifest`, `state apply-bundle <slug> <bundle.json>... [--dry-run]`, `state set <slug> key=value... [--unset key]`, `state append <slug> <ledger.md> --heading <text> --body-file <path\|->`, `state close`, `migrate [--dry-run] [--answer id=choice]` | Go owns answer/drop/batch resolution, the recorded predecessor-chain manifest union for a release milestone, the all-or-nothing apply of plan-drafter hunk bundles (base-hash pins, unique non-overlapping anchors, no lost IDs, no new task-graph or budget defect, no appended dated delta section), cursor writes (known phase, engine-owned schema, no return-cursor overwrite; an AFK pause names auto-pickable questions), append-only ledger sections that refuse a duplicate heading, transactional close, and fail-closed v5 schema normalization. |
48
48
  | Acceptance ledger | `gates scaffold`, `gates status`, `gates run [--timeout N]`, `gates reverify [--timeout N]`, `gates lint [--strict]`, `gates precheck <slug> --worktree <path> [--slice <SLICE-ID>]`, `gates attest <id> <note>`, `gates abandon <id> <why>` | Go owns the `gates.md` ledger: per-outcome gates whose runnable `CHECK`/`CWD` must exactly match a `test-plan.md` Build-entry preflight row, evidence bound to the gate definition digest (stale = unmet), `ABANDON:` handoffs, oracle lint, and the wright's never-evidence `precheck` of `RUN: writer` gates. Readiness/seal require a parse-clean, all-met ledger whenever `gates.md` is a required artifact. |
@@ -9,7 +9,7 @@ workflow strategy.
9
9
  | Command | Deterministic responsibility |
10
10
  | --- | --- |
11
11
  | `install [flags]` | Install manifest-owned host artifacts and the optional shared binary. |
12
- | `update [flags]` | Refresh an existing managed installation. |
12
+ | `update [flags]` | Refresh an existing managed installation. Release API authentication uses `GH_TOKEN`, then `GITHUB_TOKEN`, then optional bounded noninteractive `gh auth token --hostname github.com`; explicit invalid credentials fail. Never sends credentials to assets or off-origin redirects. `--force` does not bypass rate limits. See [release authentication](../cli.md#updates). |
13
13
  | `uninstall [flags]` | Remove managed artifacts while preserving runtime workspace state. |
14
14
  | `check candidate <slug>` | Validate the strict manifest and compute the content-bound project-candidate identity. Exits `3` when the manifest omits a path the feature's `WIP(<slug>):` checkpoint commits changed (net from the feature base to HEAD). Also exits `3` with `unattributed root edit: <paths>` while the feature's `tree-baseline.json` tripwire flags a product path (ADR-0038; see `dispatch`). |
15
15
  | `check readiness <slug>` | Check target-Phase files, open human gates from Clarify onward, the `tasks.md` slice graph when that artifact is required, canonical `AC-###` presence in `tasks.md`/`test-plan.md` when those artifacts are required, and the current stable Build-input binding when applicable. Leaving Vet with a `Run at` column, a slice whose `Files likely touched`/`Writer allowlist` names a dependency manifest or lockfile needs a `dependency-dry-run SLICE-###` row at `vet` with a passing transcript. Leaving Vet, every slice `state.md` does not check built (a deferred `Satisfies: none` slice excepted) must also pass the Build-entry `check slice` contract; each failure prints one `invariant: slice-check:` line naming the slice and its exact `check slice` reason, to fix in `/rite-plan` before READY. |
@@ -17,11 +17,11 @@ workflow strategy.
17
17
  | `check preconditions <slug> [--slice SLICE-###] [--timeout N]` | Run the `test-plan.md` Build-entry preflight rows whose optional `Run at` cell is `vet` (with `--slice`, `pre-dispatch <SLICE>`); `action` rows and rows without the cell never run. Writes one candidate-bound transcript per row under `references/gates/preflight-*/`; a row passes on exit 0. A `pre-dispatch` row whose newest transcript passed is kept, not re-run: it is a pre-edit baseline, so a re-dispatch never runs it against the slice's own edits; changing its command or cwd retires the pass. Exit `3` on any failure or an invalid `Run at` value. |
18
18
  | `check seal <slug>` | Check files required by target Phase `seal`, open human gates, the `tasks.md` slice graph, canonical `AC-###` presence when `tasks.md`/`test-plan.md` are required, the stable Build-input binding, and exact candidate bindings. `check readiness` and `check seal` also block a `scripts/` test driver that a tasks.md Writer allowlist plans or touched-files.md lists when no gates.md `CHECK` runs it and no `Driver waiver: <path> — DEC-### <reason>` line cites a recorded decision; waived drivers print as `note: unexecuted driver (waived by DEC-###): <path>` lines, on pass or block. |
19
19
  | `check path-disjoint [--root <dir>] [<json-file> | -]` | Verify slice path sets are pairwise disjoint. |
20
- | `parallel select --cap <1-10> [--root <dir>] [--slug <controller>] [--from-plan [--workspaces <slug,...>] \| <json-file> \| -]` | Choose a plan-order path-disjoint ready subset, seeded by all retained repository-controller slots and paths. `--from-plan` uses canonical built checkpoints, local and declared workspace producer dependencies, exact write sets and required dependency manifests. The internal `--workspaces` data-source parameter pools recorded forward continuations with current readiness and explicit native-vetted per-slice declarations; blocked/stale/missing candidates print scoped notices without hiding other ready work. Foreign identities print `<workspace>/<slice>`. |
20
+ | `parallel select --cap <1-10> [--root <dir>] [--slug <controller>] [--from-plan [--workspaces <slug,...>] \| <json-file> \| -]` | Choose a plan-order path-disjoint ready subset, seeded by all retained repository-controller slots and paths. `--from-plan` uses canonical built checkpoints, local and declared workspace producer dependencies, exact write sets and required dependency manifests. Without `--workspaces`, it also reports the full recorded sequence frontier but keeps source-local picks; other workspaces are never silently admitted. The explicit `--workspaces` data-source parameter pools recorded forward continuations with current readiness and explicit native-vetted per-slice declarations; blocked/stale/missing candidates print scoped notices without hiding other ready work. Foreign identities print `<workspace>/<slice>`. |
21
21
  | `parallel <create\|add\|integrate\|prune\|cleanup\|status\|abort\|lease-read\|lease-write\|lease-clear\|record-green>` | One repository controller owns isolated workers across source workspaces. `create` accepts a single initial worker; `create`/`add --cap N` persist the global admission capacity. Explicit `add --cap N --json -` with stdin `[]` updates capacity only; lowering below active count refuses without canceling workers. A completed retained lease can refill at unchanged control tip. `record-green` and per-slice `integrate --slice <workspace/id> --apply-to-control` target source-qualified lanes (bare IDs mean controller lanes); integration keeps exact ancestry/path/dirty-work checks and lands `WIP(<source>):`. `prune` removes only verified clean integrated checkouts, retaining branches, proof identities, lease rows and controller. Status exposes the retained controller and pending landing; cleanup preserves salvage/unknown work. |
22
22
  | `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:`. A `Dependencies` ID may carry a `(via <interface>)` suffix (empty or unclosed is a malformed token); prints a non-blocking `ADVISORY edge:` line (and records an `edge-advisory` metric) for each edge with no via, or whose via text is not a case-insensitive substring of the dependency's `Consumes / Produces:`. Prints `schedule: <n> slices in <r> build rounds at cap 10` (the `/rite-build` batch selection replayed over each slice's Writer allowlist, else Files likely touched, plus the manifest parallel select reserves; omitted when a slice has no path) and a non-blocking `ADVISORY hub:` line (top five; records a `hub-advisory` metric) for each path, compared case-folded, that three or more slices without `Serial rationale:` write. Advisories print only when the graph is valid. |
23
- | `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. |
24
- | `check continuation [slug]` | Print whether an armed AFK run must invoke its cursor instead of replying. `continuation: required` plus `invoke: <next_action>` when `.devrites/AFK` is a regular file, `status` is `running`, `question_id` is empty, no blocking or escalating question is open, and `next_action` is an internal phase command (`/rite-spec` through `/rite-seal`, including `/rite-plan`, not `/rite-ship` or `/rite-autocomplete`). Otherwise `continuation: clear` with a one-line `reason`. Exit `0` either way. `handoff` prints the same lines. |
23
+ | `check regression <slug> [--update [--allow-empty]]` | 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. Ordinary checks block lost facts without changing the baseline. `--update` records the current facts under the feature lock and prints each blessed regression; a deliberate owner-authorized repair checkpoint can accept a backward phase as the new baseline. Removing every checked AC and met gate also requires `--allow-empty`. Never automatically bless an unreconciled regression. |
24
+ | `check continuation [slug]` | Print whether an armed AFK run must invoke its cursor instead of replying. `continuation: required` plus `invoke: <next_action>` requires a regular `.devrites/AFK`, `status=running` or specifically `phase=vet,status=ready`, empty `question_id`, no blocking/escalating question, and a valid internal phase command (`/rite-spec` through `/rite-seal`, including `/rite-plan`, not `/rite-ship` or `/rite-autocomplete`). Also emits the sequence frontier; a clear local cursor with actionable global preparation can require `invoke: /rite-autocomplete` while preserving the source identity. Waiting, human-blocked, or completed work alone does not require continuation. Neither route authorizes Ship or bypasses human/readiness gates. Successful `required`/`clear` verdicts exit `0`; malformed or ambiguous state fails visibly. `handoff` prints the same lines. |
25
25
  | `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). `--record` also stores each slice's proof bytes (its `tasks.md` block plus the `test-plan.md` lines naming it); both modes print `ADVISORY proportion:` for a slice whose proof grew over 2x since that baseline or carries over 3x the median proof per AC. |
26
26
  | `check windows <slug> [--worktree\|--staged\|--base <ref>\|--since-dispatch <wave>]` | 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. `--since-dispatch <wave>` reports only `deleted-test`/`removed-assertion` against the work-tree snapshot (`tree` in `dispatch.json`) recorded when that build wright wave opened, untracked files included; it takes no `--cwd` and records the `windows-since` metric. |
27
27
  | `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`. |
@@ -35,6 +35,7 @@ workflow strategy.
35
35
  | `orient <slug>` | Alias for `observe summary`. |
36
36
  | `observe slice <slug> <SLICE-ID>` | Print one `SLICE-###` section of `tasks.md` so Build reads a slice, not the file. |
37
37
  | `next [slug]` | Print the minimal remaining lifecycle path plus advisory skips; in Build also `eligible_now:`, `batch:` and the `select-command:` (`parallel select --root <project> --slug <slug> --cap N --from-plan`, N = AFK max_parallel else 10) that reproduces the batch. Prints `blocked: unattributed root edit: ...` after `open-questions:` and exits `3` while the ADR-0038 tripwire flags a product path; the rest of the output still prints. |
38
+ | `frontier [slug]` | Read-only report across exact recorded sequence relations, including archived intermediaries and live descendants. Emits `frontier: actionable\|waiting\|blocked\|clear` (`none` for a non-sequence source), `frontier-source:`, and `frontier-workspace:` rows with location, `inspect\|prepare\|repair\|wait\|complete` action, and reason. Emits `frontier-select-command:`, `frontier-picks:`, `frontier-selection: blocked`, `frontier-prepare:`, or `frontier-review-sequence:` where applicable. Explicit slug may be archived; absent ACTIVE recovery requires a unique archived terminal tip with a recorded native Spec edge, otherwise refuses ambiguity. Never changes ACTIVE, restores archives, creates workspaces, or launches writers. Native preparation and semantic admission remain required; see [sequence frontier](../cli.md#sequence-frontier). |
38
39
  | `handoff [slug] [--resume]` | 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, in-flight dispatch waves (`inflight_wave:` lines: phase, state, pending roles, slices), missing required files, the canonical read-next order, and the same `continuation:` lines as `check continuation`. Read-only unless `--resume`, which appends one `resume` event (role root) to `metrics.jsonl`; `metrics summary` then reports minutes from each resume to the next dispatch. The `/rite-handoff` spine and the compaction-fallback entry point. |
39
40
  | `recall --paths <p1,p2,...> [--limit n]` | Read-time query over `.devrites/archive/`: list archived features whose `touched-files.md` candidate manifest covers a queried project-relative path (exact or directory prefix, case-folded), ranked by overlap count, then newest archive-directory mtime, then slug (default 10 features). Each feature prints up to 8 `archive/<slug>/<file>:<line>` pointers, then `+N more`: `decisions.md` `DEC-###` entries and `## Carry-forward constraints` bullets whose `Files:` overlap (or a constraint naming no files), plus `review.md`/`seal.md`/`drift.md` lines that mention a queried path; fenced examples are ignored. Never writes, caches, or indexes (no metric either); symlinked archive entries are refused. An unreadable archive file prints `unreadable:` and the scan continues. Exit `0` (including `recall: no archive`), `1` invalid archive directory, `2` usage. |
40
41
  | `context [slug] (--phase <p>\|--skill <name>) [--role <r>] [--slice <SLICE-ID>] [--recheck <inventory>] [--trigger a,b] [--inline-contract] [--whole]` | 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 root `--phase build\|autocomplete` bundle (no `--role`, no `--slice`) defaults to `--slice <active_slice>` while the state.md cursor phase is `build` and active_slice names a slice present in tasks.md (prints `scope: slice SLICE-### (auto from state.md) ...`), unless `.devrites/AFK` `max_parallel` is 2 or more or a parallel lease is `running` (the bundle stays whole); `--whole` opts out. Every bundle opens, after its header comments, with a table of contents: one `L<start>-<end> <section label>` line per `===== label =====` section, giving its exact line range in the bundle file. A bundle without `--role` (the root's own read) gives over-budget artifacts as by-reference indexes; a `--role` bundle leads with the role's agent contract and names the manifest's `rootOnly` paths instead of inlining them. When the contract resolves under `.claude/agents`, `.omp/agents`, or `.codex/agents` (the host loads it as the agent's system prompt), the bundle writes one header line naming its path, size, and SHA-256 instead of the body; other layouts (pi, devin, unknown) and `--inline-contract` (only with `--role`) inline the body, and a missing contract still exits `3`. Inside inlined files, a `--role` bundle replaces each `<!-- root-only -->`…`<!-- /root-only -->` block with a one-line stub naming the omitted heading, and does the same for each `<!-- model-surface -->` block unless the role is `security-auditor`, the feature has an `ai-spec.md`, or `spec.md`/`plan.md`/`tasks.md`/`design-brief.md` are absent or (outside the spec template's `AI-SPEC annex`) name a model, agent, RAG, or tool surface; an unbalanced or headingless marker exits `2`. `--slice` inlines that slice's `tasks.md` block and turns each over-budget artifact, and each artifact over 16 KiB except `spec.md`, 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`. In phase `build`, a `--role` bundle other than `slice-wright` without `--slice` exits `3` (`unscoped build reviewer bundle`). `--recheck <inventory>` (phase `build`, with `--role` and `--slice`; path relative to the workspace) writes `<phase>-<role>.<slice>.recheck.bundle.md`: the inventory file and `core.md` inline whole, every other non-`rootOnly` pack file becomes a by-reference index (path, SHA-256, headings with line numbers) followed by each section the inventory cites as `<file>.md § <heading>`; workspace handling matches `--slice`. A missing or empty inventory exits `2`. First reviews, full-inventory rechecks, Vet, `/rite-review`, and Seal do not use it. |
@@ -46,7 +47,7 @@ workflow strategy.
46
47
  | `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 every unreleased claim (live, expired, dead) plus one `N released (use --all)` count; `--all` includes released rows; a claim whose holding session has provably exited on this host shows `dead` and no longer conflicts. `check` is the read-only preflight for a path set. Coordination aid only — never a substitute for one-writer-per-worktree. |
47
48
  | `note <add\|list\|check\|rm> <slug> ...` | Anchored workspace notes in `notes.md`: `add <slug> <subject> <quote> <title> [body]` binds a note to a verbatim quote in one repository file and assigns `NOTE-###`; `list` and `check` regrade each anchor `exact`/`moved`/`stale`/`ambiguous`/`lost` by searching the repo for the quote (dependency and workspace trees excluded); `check --repair` rewrites a `moved` subject to its new file; `rm` deletes by ID. `check seal` refuses a malformed `notes.md` and any non-`exact` anchor. |
48
49
  | `gates <scaffold\|status\|run\|reverify\|lint\|precheck\|attest\|abandon> <slug>` | Operate the `gates.md` acceptance ledger: seed per-AC gates, execute runnable gates bound to `test-plan.md` preflight rows, attest manual gates, and reduce to `all-met`/`not-met`/`handoff`/`malformed`. A gate with `INPUTS:` records its files' content digest and is reused by `run` and `reverify` while they are unchanged. `run`/`reverify --transcripts` atomically publishes a private redacted v2 executed transcript, or returns its verified originating record unchanged, under `references/gates/<gate-id>/`; legacy v1/reuse-only logs cannot authorize reuse. `precheck <slug> --worktree <path> [--slice <SLICE-ID>]` runs every `RUN: writer` gate and `check windows` against the wright's worktree (with `--slice`, it prints `SKIP <gate-id>` for a gate whose id only other unbuilt slices name in `tasks.md`, since gate ids reuse `AC-###` ids; a gate no slice names still runs), prints PASS/FAIL per gate id, exits `3` on any FAIL or on a malformed ledger, and writes no ledger, EVIDENCE line or transcript (`check windows` still appends its metric event); its output is never evidence. |
49
- | `state resolve <qid> "<answer>"` | Resolve an open question and update `questions.md` plus `state.md` atomically. |
50
+ | `state resolve <qid> "<answer>"` | Resolve an open question and update `questions.md` plus `state.md` under the feature lock, with rollback on returned publication errors. Per-file writes are atomic; the pair is not crash-atomic. Incomplete rollback requires inspection and recovery. |
50
51
  | `state merge-manifest <slug> [pred...]` | Fold the complete recorded predecessor chain's manifests into the release candidate manifest. Numbered sequences must reach position 1 through consecutive, unique positive positions; explicit predecessor lists cannot omit recorded members. Fully unnumbered legacy chains remain supported. Invalid or missing members leave the manifest unchanged. |
51
52
  | `state set <slug> <key>=<value>... [--unset <key>]...` | Write `state.md` cursor fields all-or-nothing under the feature lock. Refuses an unknown `phase`, the engine-owned `schema` row, a pipe or line break in a value, and an overwrite of a saved `return_phase`/`return_next_action`. Setting `status=awaiting_human` under `.devrites/AFK` prints each open question the sentinel's `allow_gates` auto-picks. |
52
53
  | `state append <slug> <ledger.md> --heading "<text>" --body-file <path\|->` | Append one `## <heading>` section to `assumptions.md`, `decisions.md`, `drift.md`, `evidence.md`, or `questions.md` atomically. Refuses a heading that already exists outside fenced code and a body line that opens another `#`/`##` section; for a new `questions.md` `q-` entry, also refuses a non-open status, a missing or unknown gate, a raised_at that is not a full RFC 3339 timestamp, options outside 2-4 concrete choices plus the closing "Something else" escape hatch, `(Recommended)` on any option but 1, and `proposed:` without a `(Recommended)` option 1 (or option 1 without `proposed:`); question or entry length is advisory only; reports an advisory when the ledger passes its line budget, and blocks (exit 3, nothing written) when a ledger other than evidence.md would land at or above 1.5x its line or byte budget without a covering `Budget override: <=N lines; <reason>` (N at most 2x the line budget). |
@@ -58,6 +59,10 @@ workflow strategy.
58
59
  | `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). |
59
60
  | `version` | Print the engine version. |
60
61
 
62
+ Under AFK, `next`, `handoff`, and `check continuation` include the sequence
63
+ frontier without replacing the source-local cursor. Reporting actionable work
64
+ does not authorize Build or Ship, and cannot guarantee native-host compliance.
65
+
61
66
  For `context --role`, optional `devrites-` prefixes and `.lane` suffixes resolve
62
67
  the base specialist's contract, workspace read-set, and role-specific rules.
63
68
  The full label remains in bundle filenames and attribution. Reviewer
@@ -157,8 +157,9 @@ not runtime authorities. See
157
157
 
158
158
  - New question IDs are `q-YYYY-MM-DD-NNN`. The root scans all same-day headers,
159
159
  chooses the next unused suffix, re-reads immediately before append, and
160
- recomputes on collision. `state resolve` remains the atomic answer/drop/batch
161
- writer; it does not allocate IDs.
160
+ recomputes on collision. `state resolve` remains the locked, rollback-protected
161
+ answer/drop/batch writer; it does not allocate IDs. Paired file updates are not
162
+ a crash-atomic transaction.
162
163
  - The root directly owns later-phase Clarify entry/restore cursor edits and AFK
163
164
  slice accounting, preserving unrelated Markdown. See
164
165
  [`state-schema.md`](state-schema.md).
@@ -187,7 +188,7 @@ The engine provides only:
187
188
  - `check seal`: final file completeness and open-human-gate checks, the
188
189
  `tasks.md` slice graph, then the readiness-binding recheck, then exact
189
190
  candidate bindings after that aggregate gate passes;
190
- - atomic `state resolve` answer/drop/batch and transactional `state close`;
191
+ - locked, rollback-protected `state resolve` answer/drop/batch and transactional `state close`;
191
192
  - secret scanning, version reporting, and local install lifecycle primitives.
192
193
 
193
194
  A marker or file can satisfy structural presence without proving semantic
@@ -48,7 +48,7 @@ func rootModeFor(command string, args []string) rootMode {
48
48
  return rootLenient
49
49
  }
50
50
  return rootUnused
51
- case "orient", "next", "context", "metrics", "dispatch", "handoff", "note", "packet":
51
+ case "orient", "next", "frontier", "context", "metrics", "dispatch", "handoff", "note", "packet":
52
52
  return rootStrictUsage
53
53
  case "candidate":
54
54
  if subcommand == "freeze" {
package/engine/help.go CHANGED
@@ -189,7 +189,7 @@ func shouldPrintHelp(args []string) bool {
189
189
  return true
190
190
  }
191
191
  switch args[0] {
192
- case "check", "state", "observe", "parallel", "gates", "claim", "detect", "note", "metrics", "handoff", "context", "orient", "migrate", "overhaul", "next", "dispatch", "secret-scan", "open-visual", "recall", "packet", "candidate":
192
+ case "check", "state", "observe", "parallel", "gates", "claim", "detect", "note", "metrics", "handoff", "context", "orient", "migrate", "overhaul", "next", "frontier", "dispatch", "secret-scan", "open-visual", "recall", "packet", "candidate":
193
193
  return len(args) >= 2 && args[1] == "help"
194
194
  default:
195
195
  return false
@@ -231,6 +231,8 @@ func commandHelp(args []string) (string, bool) {
231
231
  return orientUsage, true
232
232
  case "next":
233
233
  return nextUsage, true
234
+ case "frontier":
235
+ return "usage: devrites-engine frontier [slug]", true
234
236
  case "handoff":
235
237
  return handoffUsage, true
236
238
  case "recall":
@@ -128,7 +128,7 @@ var CodexConfigMerge = MarkerMerge{
128
128
  Begin: "# BEGIN DEVRITES CODEX PERMISSIONS",
129
129
  End: "# END DEVRITES CODEX PERMISSIONS",
130
130
  MarkerRel: ".claude/devrites.codex-config-merge",
131
- MarkerText: ".codex/config.toml contains the DevRites read-only-root permission profile.",
131
+ MarkerText: ".codex/config.toml contains the DevRites workspace-capable root permission profile.",
132
132
  }
133
133
 
134
134
  // HostConfig is a host project config DevRites creates only when absent; an
@@ -437,20 +437,37 @@ func checkBundleResult(targets []*bundleTarget, retired map[string]bool) []strin
437
437
  return problems
438
438
  }
439
439
 
440
- // writeBundleTargets writes every target atomically and, if one write fails,
441
- // restores the files already written so the workspace never holds half a
442
- // bundle.
440
+ // writeBundleTargets writes every target atomically. A failed write may already
441
+ // have published its bytes, so rollback covers every attempted target and reports
442
+ // any restoration failures.
443
443
  func writeBundleTargets(ws *os.Root, targets []*bundleTarget) error {
444
+ return writeBundleTargetsWith(ws, targets, fsutil.WriteFileAtomicIn)
445
+ }
446
+
447
+ func writeBundleTargetsWith(ws *os.Root, targets []*bundleTarget, write func(*os.Root, string, []byte, fs.FileMode) error) error {
444
448
  for i, target := range targets {
445
- if err := fsutil.WriteFileAtomicIn(ws, filepath.FromSlash(target.rel), target.after, 0o644); err != nil {
446
- for _, done := range targets[:i] {
449
+ if err := write(ws, filepath.FromSlash(target.rel), target.after, 0o644); err != nil {
450
+ writeErr := fmt.Errorf("write %s: %w", target.rel, err)
451
+ var rollbackErrors []error
452
+ for j := i; j >= 0; j-- {
453
+ done := targets[j]
454
+ var rollbackErr error
447
455
  if done.existed {
448
- _ = fsutil.WriteFileAtomicIn(ws, filepath.FromSlash(done.rel), done.before, 0o644)
456
+ rollbackErr = write(ws, filepath.FromSlash(done.rel), done.before, 0o644)
449
457
  } else {
450
- _ = ws.Remove(filepath.FromSlash(done.rel))
458
+ rollbackErr = ws.Remove(filepath.FromSlash(done.rel))
459
+ if errors.Is(rollbackErr, fs.ErrNotExist) {
460
+ rollbackErr = nil
461
+ }
451
462
  }
463
+ if rollbackErr != nil {
464
+ rollbackErrors = append(rollbackErrors, fmt.Errorf("rollback %s: %w", done.rel, rollbackErr))
465
+ }
466
+ }
467
+ if len(rollbackErrors) > 0 {
468
+ return errors.Join(writeErr, fmt.Errorf("rollback incomplete: %w", errors.Join(rollbackErrors...)))
452
469
  }
453
- return fmt.Errorf("write %s: %w (earlier files restored)", target.rel, err)
470
+ return fmt.Errorf("%w (attempted files restored)", writeErr)
454
471
  }
455
472
  }
456
473
  return nil
@@ -10,6 +10,7 @@ import (
10
10
 
11
11
  "github.com/devrites/devrites/internal/devritespaths"
12
12
  "github.com/devrites/devrites/internal/gate"
13
+ "github.com/devrites/devrites/internal/markdowntext"
13
14
  "github.com/devrites/devrites/internal/state"
14
15
  "github.com/devrites/devrites/internal/workflow"
15
16
  )
@@ -44,7 +45,21 @@ func RunCheckContinuation(root string, args []string, stdout, stderr io.Writer)
44
45
  fmt.Fprintf(stderr, "check continuation: %v\n", err)
45
46
  return 2
46
47
  }
48
+ var frontier []string
49
+ if afkPresent(root) {
50
+ frontier, err = FrontierLines(root, slug)
51
+ if err != nil {
52
+ fmt.Fprintf(stderr, "check continuation: frontier: %v\n", err)
53
+ return 2
54
+ }
55
+ if !verdict.Required && len(frontier) > 0 && frontier[0] == "frontier: actionable" {
56
+ verdict = continuationVerdict{Required: true, Invoke: "/rite-autocomplete", Source: slug, Reason: "global frontier requires native preparation, authority review, or selection; no Ship approval"}
57
+ }
58
+ }
47
59
  writeContinuation(stdout, verdict)
60
+ for _, line := range frontier {
61
+ fmt.Fprintln(stdout, line)
62
+ }
48
63
  return 0
49
64
  }
50
65
 
@@ -59,12 +74,16 @@ func classifyContinuation(root, slug string) (continuationVerdict, error) {
59
74
  }
60
75
  invoke, internal, err := internalPhaseEdge(report.NextAction, slug)
61
76
  if err != nil {
62
- return continuationVerdict{}, err
77
+ if !frontierBoundSpec(root, slug, report.NextAction) {
78
+ return continuationVerdict{}, err
79
+ }
80
+ // A successor Spec belongs to the global controller, never this source's phase invocation.
81
+ invoke, internal = "", false
63
82
  }
64
83
  if !afkPresent(root) {
65
84
  return continuationVerdict{Reason: "no AFK sentinel"}, nil
66
85
  }
67
- if report.Status != "running" {
86
+ if report.Status != "running" && !(report.Phase == state.PhaseVet && report.Status == "ready") {
68
87
  if report.Status == "" {
69
88
  return continuationVerdict{Reason: "status unset"}, nil
70
89
  }
@@ -75,7 +94,17 @@ func classifyContinuation(root, slug string) (continuationVerdict, error) {
75
94
  if err != nil {
76
95
  return continuationVerdict{}, err
77
96
  }
78
- if qid, ok := state.CursorField(strings.Split(string(data), "\n"), state.CursorQuestionID); ok && strings.TrimSpace(qid) != "" {
97
+ structural, err := markdowntext.Structural(data)
98
+ if err != nil {
99
+ return continuationVerdict{Reason: "malformed source cursor; native normalization required"}, nil
100
+ }
101
+ cursorLines := strings.Split(string(structural), "\n")
102
+ for _, key := range []string{state.CursorPhase, state.CursorStatus, state.CursorNextAction, state.CursorQuestionID} {
103
+ if _, _, err := frontierField(cursorLines, key); err != nil {
104
+ return continuationVerdict{Reason: err.Error() + "; native normalization required"}, nil
105
+ }
106
+ }
107
+ if qid, ok := state.CursorField(cursorLines, state.CursorQuestionID); ok && strings.TrimSpace(qid) != "" {
79
108
  return continuationVerdict{Reason: "question cursor set"}, nil
80
109
  }
81
110
  // #nosec G304 -- questions.md inside the checked feature workspace
@@ -93,7 +122,7 @@ func classifyContinuation(root, slug string) (continuationVerdict, error) {
93
122
  if !internal {
94
123
  return continuationVerdict{Reason: "next_action is not an internal phase edge"}, nil
95
124
  }
96
- return continuationVerdict{Required: true, Invoke: invoke, Source: slug, Reason: "AFK status=running internal phase edge"}, nil
125
+ return continuationVerdict{Required: true, Invoke: invoke, Source: slug, Reason: "AFK status=" + report.Status + " internal phase edge"}, nil
97
126
  }
98
127
 
99
128
  func afkPresent(root string) bool {