devrites 7.0.0 → 7.0.1

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 (52) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +1 -1
  3. package/docs/command-map.md +1 -1
  4. package/docs/usage.md +7 -2
  5. package/engine/internal/gate/gate.go +7 -0
  6. package/engine/internal/gate/predecessor.go +67 -0
  7. package/engine/internal/lib/claims.go +57 -7
  8. package/pack/.claude/skills/devrites-lib/reference/standards/performance.md +14 -0
  9. package/pack/.claude/skills/rite-autocomplete/SKILL.md +7 -3
  10. package/pack/.claude/skills/rite-autocomplete/reference/lookahead.md +50 -0
  11. package/pack/.claude/skills/rite-autocomplete/reference/loop.md +7 -0
  12. package/pack/.claude/skills/rite-build/reference/spec-drift-guard.md +4 -0
  13. package/pack/.claude/skills/rite-spec/SKILL.md +2 -1
  14. package/pack/.claude/skills/rite-vet/SKILL.md +3 -1
  15. package/pack/generated/claude/skills/devrites-lib/reference/standards/performance.md +14 -0
  16. package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +7 -3
  17. package/pack/generated/claude/skills/rite-autocomplete/reference/lookahead.md +50 -0
  18. package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +7 -0
  19. package/pack/generated/claude/skills/rite-build/reference/spec-drift-guard.md +4 -0
  20. package/pack/generated/claude/skills/rite-spec/SKILL.md +2 -1
  21. package/pack/generated/claude/skills/rite-vet/SKILL.md +3 -1
  22. package/pack/generated/codex/skills/devrites-lib/reference/standards/performance.md +14 -0
  23. package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +7 -3
  24. package/pack/generated/codex/skills/rite-autocomplete/reference/lookahead.md +50 -0
  25. package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +7 -0
  26. package/pack/generated/codex/skills/rite-build/reference/spec-drift-guard.md +4 -0
  27. package/pack/generated/codex/skills/rite-spec/SKILL.md +2 -1
  28. package/pack/generated/codex/skills/rite-vet/SKILL.md +3 -1
  29. package/pack/generated/devin/skills/devrites-lib/reference/standards/performance.md +14 -0
  30. package/pack/generated/devin/skills/rite-autocomplete/SKILL.md +7 -3
  31. package/pack/generated/devin/skills/rite-autocomplete/reference/lookahead.md +50 -0
  32. package/pack/generated/devin/skills/rite-autocomplete/reference/loop.md +7 -0
  33. package/pack/generated/devin/skills/rite-build/reference/spec-drift-guard.md +4 -0
  34. package/pack/generated/devin/skills/rite-spec/SKILL.md +2 -1
  35. package/pack/generated/devin/skills/rite-vet/SKILL.md +3 -1
  36. package/pack/generated/omp/commands/rite-autocomplete.md +1 -1
  37. package/pack/generated/omp/skills/devrites-lib/reference/standards/performance.md +14 -0
  38. package/pack/generated/omp/skills/rite-autocomplete/SKILL.md +7 -3
  39. package/pack/generated/omp/skills/rite-autocomplete/reference/lookahead.md +50 -0
  40. package/pack/generated/omp/skills/rite-autocomplete/reference/loop.md +7 -0
  41. package/pack/generated/omp/skills/rite-build/reference/spec-drift-guard.md +4 -0
  42. package/pack/generated/omp/skills/rite-spec/SKILL.md +2 -1
  43. package/pack/generated/omp/skills/rite-vet/SKILL.md +3 -1
  44. package/pack/generated/pi/prompts/rite-autocomplete.md +1 -1
  45. package/pack/generated/pi/skills/devrites-lib/reference/standards/performance.md +14 -0
  46. package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +7 -3
  47. package/pack/generated/pi/skills/rite-autocomplete/reference/lookahead.md +50 -0
  48. package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +7 -0
  49. package/pack/generated/pi/skills/rite-build/reference/spec-drift-guard.md +4 -0
  50. package/pack/generated/pi/skills/rite-spec/SKILL.md +2 -1
  51. package/pack/generated/pi/skills/rite-vet/SKILL.md +3 -1
  52. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
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.0.1](https://github.com/ViktorsBaikers/DevRites/compare/v7.0.0...v7.0.1) (2026-10-20)
6
+
7
+ ### Added
8
+
9
+ * **no-release:** plan the next sequence continuation in a second session ([#150](https://github.com/ViktorsBaikers/DevRites/issues/150)) ([d4be5b0](https://github.com/ViktorsBaikers/DevRites/commit/d4be5b01d6e3a074718d4a5cd9a3ba0a5e52e9aa))
10
+
11
+ ### Fixed
12
+
13
+ * **devrites:** a timing gate pins its protocol before Build ([#151](https://github.com/ViktorsBaikers/DevRites/issues/151)) ([2069caa](https://github.com/ViktorsBaikers/DevRites/commit/2069caa18199d9dd4664854eb3c6c8f599b8fdf2))
14
+
5
15
  ## [7.0.0](https://github.com/ViktorsBaikers/DevRites/compare/v6.10.0...v7.0.0) (2026-10-20)
6
16
 
7
17
  ### ⚠ BREAKING CHANGES
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.0.0`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v7.0.0): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
34
+ **Status:** [`v7.0.1`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v7.0.1): 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
 
@@ -104,7 +104,7 @@ See [`cli.md`](cli.md).
104
104
  | [`/rite-review`](../pack/.claude/skills/rite-review/SKILL.md) | review | `[scope: slice N \| feature] [--full]` | Feature-scoped parallel Spec + Standards review of the closed candidate; binds `review.md` to its digest. | workspace + candidate | `review.md`, `evidence.md`, `state.md` |
105
105
  | [`/rite-seal`](../pack/.claude/skills/rite-seal/SKILL.md) | seal | `[feature-slug] [--full]` | Candidate-bound GO / NO-GO **decision**. Rechecks exact proof/review bindings and runs no git; on GO sets `Next step: /rite-ship`. | all artifacts + candidate | `seal.md`, `state.md` |
106
106
  | [`/rite-ship`](../pack/.claude/skills/rite-ship/SKILL.md) | ship | `[slug]` | Starts with a read-only Seal/candidate check and exact plan disclosure, then requires fresh literal `GO`. Only then may it collapse checkpoints, stage exact candidate paths, validate staged scope/bytes/bindings/secrets, commit and reverify, perform optional separately approved push/tag/PR actions, and archive/close. | `seal.md` + candidate + Git index | `ship.md`, `state.md`, archive |
107
- | [`/rite-autocomplete`](../pack/.claude/skills/rite-autocomplete/SKILL.md) | (orchestrator) | `[idea] [--ship\|--yolo] [--max-slices N] [--full] [--cross-model]` | Full lifecycle (spec → clarify → … → seal → ship). Spec + clarify form the one interactive window; AFK/checkpoint mode arms only after decision coverage is CLEAR. Pauses for irreversible risk, escalating, unanswered blocking with no recommended option, human-only access, or remaining NO-GO — not recommended-option blocking questions, temper expand, validating gates, `--max-slices`, or default resource caps. Objective red checks use bounded technical recovery. Default stops at Seal GO; `--ship` (`--yolo`) reaches Ship preflight but still requires fresh literal `GO` and native approval; `--full` selects the Full profile and `--cross-model` arms Vet's second opinion. | idea + workspace | whole workspace (drives every phase) |
107
+ | [`/rite-autocomplete`](../pack/.claude/skills/rite-autocomplete/SKILL.md) | (orchestrator) | `[idea] [--ship\|--yolo] [--max-slices N] [--parallel N] [--full] [--cross-model] [--lookahead]` | Full lifecycle (spec → clarify → … → seal → ship). Spec + clarify form the one interactive window; AFK/checkpoint mode arms only after decision coverage is CLEAR. Pauses for irreversible risk, escalating, unanswered blocking with no recommended option, human-only access, or remaining NO-GO — not recommended-option blocking questions, temper expand, validating gates, `--max-slices`, or default resource caps. Objective red checks use bounded technical recovery. Default stops at Seal GO; `--ship` (`--yolo`) reaches Ship preflight but still requires fresh literal `GO` and native approval; `--full` selects the Full profile and `--cross-model` arms Vet's second opinion. | idea + workspace | whole workspace (drives every phase) |
108
108
  | [`/rite-quick`](../pack/.claude/skills/rite-quick/SKILL.md) | (express) | `<change>` | Express lane for a **small, reversible, unambiguous** change: one-line contract → TDD build (via `devrites-slice-wright`) → scoped prove → review-lite → standalone commit (a change in the active candidate routes to `/rite-prove` → `/rite-review` → `/rite-seal`), no full artifact tree. **Significance gate first**: auth / migration / public-API / destructive / multi-slice / ambiguous → escalates to `/rite-spec`. Triggers: "quick fix", "small change", "tiny tweak", "just do X". | the change + codebase | code + commit (optional `brief.md` / `evidence.md`) |
109
109
  | [`/rite-fast`](../pack/.claude/skills/rite-fast/SKILL.md) | (fast lane) | `<task \| slug>` | **Explicit-only** shortened lane for mid-size work: one SHAPE step (`fast-planner` drafts spec + ≤10 slices, root asks ≤5 ranked questions, 10 when risk is flagged, user approves) → BUILD with `fast-builder` and **no per-slice gate** → one CHECK (`fast-checker` completeness pass, ≤2 gap-fix rounds) → REFINE (`fast-critic` review + polish) → PROVE on the final tree. Outside the engine lifecycle: no `state.md`, no `ACTIVE`, no seal; commits only on confirmation. | the task + codebase | `spec.md`, `plan.md`, `evidence.md` under `.devrites/work/<slug>/` + code |
110
110
  | [`/rite-frame`](../pack/.claude/skills/rite-frame/SKILL.md) | lens | `[ask \| diff]` | Pre-flight + self-audit lens for ad-hoc work the lifecycle gates never see: **FRAME** turns an imperative ask into a falsifiable success criterion + verify command before code; **AUDIT** checks a raw diff against the four LLM coding failure modes (silent assumption / overcomplication / out-of-scope edit / unverifiable goal). Top of `/rite-quick` or before a plain "just do X". | the ask / a raw diff | success criterion + verify command (inline) |
package/docs/usage.md CHANGED
@@ -71,7 +71,7 @@ Project-root sentinel (outside the workspace):
71
71
  | `.devrites/AFK` | you (presence = AFK mode active) | optional YAML: `max_slices`, `notify`, `allow_gates`. Empty file = AFK with defaults. See [`pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md`](../pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md). |
72
72
  | `.devrites/CHECKPOINT` | unused as a gate | reserved path (not a candidate). After Independent Build review and fail-on-red proof are green (not when a wright returns), `/rite-build` / `/rite-prove` / `/rite-polish` / `/rite-review` land a local `WIP(<slug>): <imperative summary>` commit (serial: checkpoint git recipe or no-op if nothing staged; parallel: `devrites-engine parallel integrate`); `/rite-ship` later collapses an eligible WIP run. See [`pack/.claude/skills/rite-build/reference/checkpoint.md`](../pack/.claude/skills/rite-build/reference/checkpoint.md). |
73
73
  | `.devrites/dup-ignore` | you (optional) | One `check dup` cluster hash per line with a `#` reason — the dismissal ledger. Content-derived hashes survive line moves but resurface on structural edits. See [`pack/.claude/skills/devrites-lib/reference/standards/duplicate-code.md`](../pack/.claude/skills/devrites-lib/reference/standards/duplicate-code.md). |
74
- | `.devrites/claims.jsonl` | `devrites-engine claim add` | Append-only advisory file claims: `{id, session, paths, reason, claimed_at, expires_at, host, anchors}` plus release events. Session-scoped and TTL-bounded — per-checkout state, so gitignore it (a committed ledger exports stale claims to every clone). See [`standards/agents.md`](../pack/.claude/skills/devrites-lib/reference/standards/agents.md). |
74
+ | `.devrites/claims.jsonl` | `devrites-engine claim add` | Append-only advisory file claims: `{id, session, paths, reason, claimed_at, expires_at, host, anchors}` plus release events. `--workspace <slug>` leases a whole feature workspace for a lookahead session. Session-scoped and TTL-bounded — per-checkout state, so gitignore it (a committed ledger exports stale claims to every clone). See [`standards/agents.md`](../pack/.claude/skills/devrites-lib/reference/standards/agents.md). |
75
75
 
76
76
  The shape of this directory is also documented in
77
77
  [`flow.md` § Workspace state model](flow.md#7-workspace-state-model).
@@ -390,11 +390,16 @@ Autocomplete discloses the exact Git plan, then still stops for a fresh literal
390
390
  gates, unanswered blocking with no recommended option, a remaining NO-GO, or low confidence — not for recommended-option blocking questions, temper expand, validating
391
391
  gates, `--max-slices`, or default slice/agent/time/review-queue caps.
392
392
  Objective red checks use bounded recovery instead. Args:
393
- `[idea] [--ship|--yolo] [--max-slices N] [--full] [--cross-model]`.
393
+ `[idea] [--ship|--yolo] [--max-slices N] [--parallel N] [--full] [--cross-model] [--lookahead]`.
394
394
  Optional flags are inactive unless their exact token occurs in the invocation;
395
395
  `--max-slices` requires one positive base-10 integer and does not cap this run.
396
396
  `--full` selects the Full
397
397
  execution profile, and `--cross-model` arms Vet's second opinion.
398
+ `--lookahead` runs in a second session you start once the active workspace is
399
+ in Build: it plans the next sequence continuation through Vet under a
400
+ `claim add --workspace` lease, never builds, and leaves `.devrites/ACTIVE`
401
+ alone. The main loop then resumes that workspace instead of specifying it again;
402
+ a predecessor replan since that Vet blocks readiness and sends it back to Vet.
398
403
  Autocomplete never rewrites an existing `.devrites/AFK`. After Vet it seeds
399
404
  remaining from the pending-slice count and ignores leftover remaining and
400
405
  `--max-slices`.
@@ -62,6 +62,13 @@ func Check(kind Kind, root, slug string) (*Result, error) {
62
62
  result.ReasonID = ResultReasonID(kind, true)
63
63
  }
64
64
  }
65
+ if kind == Readiness {
66
+ for _, problem := range predecessorProblems(root, observation) {
67
+ result.StateProblems = append(result.StateProblems, "predecessor: "+problem)
68
+ result.Blocked = true
69
+ result.ReasonID = reason.GateReadinessStale
70
+ }
71
+ }
65
72
  for _, problem := range unsanctionedRootFiles(observation) {
66
73
  result.StateProblems = append(result.StateProblems, "placement: "+problem)
67
74
  // Keep a more specific reason (readiness-stale) when the observation
@@ -0,0 +1,67 @@
1
+ package gate
2
+
3
+ import (
4
+ "fmt"
5
+ "regexp"
6
+ "strings"
7
+
8
+ "github.com/devrites/devrites/internal/markdowntext"
9
+ "github.com/devrites/devrites/internal/state"
10
+ )
11
+
12
+ // predecessorLabel opens the line a lookahead Vet records in eng-review.md: the
13
+ // predecessor workspace this plan was written against and that predecessor's
14
+ // readiness binding digest at the time.
15
+ const predecessorLabel = "Predecessor readiness: "
16
+
17
+ // The slug pattern keeps the predecessor a single workspace name; the gate
18
+ // package resolves no workspace path itself.
19
+ var predecessorLineRE = regexp.MustCompile(`^Predecessor readiness: ([A-Za-z0-9][A-Za-z0-9._-]*) ([0-9a-f]{64})$`)
20
+
21
+ // predecessorProblems blocks readiness when the predecessor a lookahead plan
22
+ // was written against has since changed its planning inputs, so this plan must
23
+ // be re-vetted against them. A workspace without the line is never checked.
24
+ func predecessorProblems(root string, observation *state.WorkspaceObservation) []string {
25
+ phase, err := observation.DeclaredPhase()
26
+ if err != nil {
27
+ return nil
28
+ }
29
+ policy, ok := state.PolicyFor(phase)
30
+ if !ok || !phaseRequiresReadinessBinding(policy) {
31
+ return nil
32
+ }
33
+ fact, ok := observation.Fact("eng-review.md")
34
+ if !ok || fact.State() != state.ArtifactPresent {
35
+ return nil
36
+ }
37
+ visible, err := markdowntext.Structural(fact.Bytes())
38
+ if err != nil {
39
+ return nil
40
+ }
41
+ var lines []string
42
+ for _, raw := range strings.Split(string(visible), "\n") {
43
+ if line := strings.TrimSuffix(raw, "\r"); strings.Contains(line, predecessorLabel) {
44
+ lines = append(lines, line)
45
+ }
46
+ }
47
+ switch {
48
+ case len(lines) == 0:
49
+ return nil
50
+ case len(lines) > 1:
51
+ return []string{"eng-review.md holds more than one Predecessor readiness line; rerun /rite-vet and record exactly one"}
52
+ }
53
+ match := predecessorLineRE.FindStringSubmatch(lines[0])
54
+ if match == nil {
55
+ return []string{fmt.Sprintf("malformed %q; rerun /rite-vet and record `%s<slug> <64-hex digest>`", lines[0], predecessorLabel)}
56
+ }
57
+ slug, recorded := match[1], match[2]
58
+ current, err := ReadinessBinding(root, slug)
59
+ if err != nil {
60
+ return []string{fmt.Sprintf("predecessor %s readiness cannot be computed (%v); rerun /rite-vet against its current plan", slug, err)}
61
+ }
62
+ if strings.TrimPrefix(current, readinessBindingLabel) != recorded {
63
+ return []string{fmt.Sprintf("predecessor %s changed its planning inputs since this plan was vetted; rerun /rite-vet to re-check this plan against them and record `%s%s %s`",
64
+ slug, predecessorLabel, slug, strings.TrimPrefix(current, readinessBindingLabel))}
65
+ }
66
+ return nil
67
+ }
@@ -15,6 +15,7 @@ import (
15
15
  "strings"
16
16
  "time"
17
17
 
18
+ "github.com/devrites/devrites/internal/devritespaths"
18
19
  "github.com/devrites/devrites/internal/parallel"
19
20
  "github.com/devrites/devrites/internal/state"
20
21
  )
@@ -37,10 +38,13 @@ const (
37
38
 
38
39
  const claimUsage = `usage: devrites-engine claim <add|release|list|check> ...
39
40
 
40
- claim add --session <id> [--ttl <minutes>] [--reason <s>] <path>...
41
+ claim add --session <id> [--ttl <minutes>] [--reason <s>] [--workspace <slug>] <path>...
41
42
  claim release --session <id> --id <claim-id>
42
43
  claim list [--session <id>] [--all]
43
- claim check [--session <id>] <path>...
44
+ claim check [--session <id>] [--workspace <slug>] <path>...
45
+
46
+ --workspace leases a whole feature workspace, so two root sessions never work
47
+ one workspace at once (sequence lookahead).
44
48
  `
45
49
 
46
50
  type claimRecord struct {
@@ -184,6 +188,42 @@ func normalizeClaimPaths(raw []string) ([]string, error) {
184
188
  return out, nil
185
189
  }
186
190
 
191
+ // workspaceClaimPath is the lease path for one feature workspace. Only
192
+ // --workspace reaches it; a positional .devrites path stays refused.
193
+ func workspaceClaimPath(slug string) (string, error) {
194
+ if !devritespaths.ValidSlug(slug) {
195
+ return "", fmt.Errorf("--workspace expects a feature slug, got %q", slug)
196
+ }
197
+ return ".devrites/work/" + slug, nil
198
+ }
199
+
200
+ // claimTargets normalizes positional paths and adds each --workspace lease.
201
+ func claimTargets(raw, workspaces []string) ([]string, error) {
202
+ if len(workspaces) == 0 {
203
+ return normalizeClaimPaths(raw)
204
+ }
205
+ var out []string
206
+ if len(raw) > 0 {
207
+ paths, err := normalizeClaimPaths(raw)
208
+ if err != nil {
209
+ return nil, err
210
+ }
211
+ out = paths
212
+ }
213
+ for _, slug := range workspaces {
214
+ p, err := workspaceClaimPath(slug)
215
+ if err != nil {
216
+ return nil, err
217
+ }
218
+ if slices.Contains(out, p) {
219
+ return nil, fmt.Errorf("duplicate workspace %q", slug)
220
+ }
221
+ out = append(out, p)
222
+ }
223
+ sort.Strings(out)
224
+ return out, nil
225
+ }
226
+
187
227
  func validSession(s string) bool {
188
228
  if s == "" || len(s) > 128 {
189
229
  return false
@@ -247,12 +287,15 @@ func newClaimID() string {
247
287
  func claimAdd(root string, args []string, stdout, stderr io.Writer) int {
248
288
  session, reason := "", ""
249
289
  ttl := claimDefaultTTL
250
- var raw []string
290
+ var raw, workspaces []string
251
291
  for i := 0; i < len(args); i++ {
252
292
  switch args[i] {
253
293
  case "--session":
254
294
  session = argAt(args, i+1)
255
295
  i++
296
+ case "--workspace":
297
+ workspaces = append(workspaces, argAt(args, i+1))
298
+ i++
256
299
  case "--reason":
257
300
  reason = argAt(args, i+1)
258
301
  i++
@@ -272,18 +315,22 @@ func claimAdd(root string, args []string, stdout, stderr io.Writer) int {
272
315
  raw = append(raw, args[i])
273
316
  }
274
317
  }
275
- _, code := addClaim(root, session, reason, ttl, raw, stdout, stderr)
318
+ _, code := addClaimTargets(root, session, reason, ttl, raw, workspaces, stdout, stderr)
276
319
  return code
277
320
  }
278
321
 
279
322
  // addClaim records one claim and returns its id. It refuses, writing nothing,
280
323
  // while a live foreign session holds an overlapping path.
281
324
  func addClaim(root, session, reason string, ttl int, raw []string, stdout, stderr io.Writer) (string, int) {
325
+ return addClaimTargets(root, session, reason, ttl, raw, nil, stdout, stderr)
326
+ }
327
+
328
+ func addClaimTargets(root, session, reason string, ttl int, raw, workspaces []string, stdout, stderr io.Writer) (string, int) {
282
329
  if !validSession(session) {
283
330
  fmt.Fprintln(stderr, "claim: --session is required (1-128 chars: letters, digits, - _ . : /)")
284
331
  return "", 2
285
332
  }
286
- paths, err := normalizeClaimPaths(raw)
333
+ paths, err := claimTargets(raw, workspaces)
287
334
  if err != nil {
288
335
  fmt.Fprintf(stderr, "claim: %v\n", err)
289
336
  return "", 2
@@ -454,12 +501,15 @@ func claimList(root string, args []string, stdout, stderr io.Writer) int {
454
501
 
455
502
  func claimCheck(root string, args []string, stdout, stderr io.Writer) int {
456
503
  session := ""
457
- var raw []string
504
+ var raw, workspaces []string
458
505
  for i := 0; i < len(args); i++ {
459
506
  switch args[i] {
460
507
  case "--session":
461
508
  session = argAt(args, i+1)
462
509
  i++
510
+ case "--workspace":
511
+ workspaces = append(workspaces, argAt(args, i+1))
512
+ i++
463
513
  default:
464
514
  if strings.HasPrefix(args[i], "-") {
465
515
  fmt.Fprintf(stderr, "claim: unknown flag %q\n", args[i])
@@ -468,7 +518,7 @@ func claimCheck(root string, args []string, stdout, stderr io.Writer) int {
468
518
  raw = append(raw, args[i])
469
519
  }
470
520
  }
471
- paths, err := normalizeClaimPaths(raw)
521
+ paths, err := claimTargets(raw, workspaces)
472
522
  if err != nil {
473
523
  fmt.Fprintf(stderr, "claim: %v\n", err)
474
524
  return 2
@@ -28,6 +28,20 @@ Measure first. An optimization without a measurement is a guess that adds comple
28
28
  flaking wall-clock test is a flaky test, [`testing.md`](testing.md)). Budget regression:
29
29
  re-measure; fix to budget or record the accepted regression with reason and owner.
30
30
 
31
+ ## Performance gate protocol
32
+ - A gate that judges a timing budget or a regression percentage pins its protocol
33
+ before Build: the environment (isolated cores, swap state, build flags such as
34
+ `CGO_ENABLED`), the repetitions and the aggregate (a median of at least five runs,
35
+ never one sample), and a noise floor measured as an A/A spread on that same
36
+ environment. Vet blocks READY on a timing gate without one. A threshold at or
37
+ below the noise floor is a plan defect for the owner, never a Build repair.
38
+ - A timing gate that fails while no code changed (an A/A run, a rerun) is noise or
39
+ host state, not a code defect. Stop wright rounds on it and fix the protocol or the
40
+ environment first.
41
+ - **Failing case:** a 10% p99 regression gate runs one sample per run on a shared host;
42
+ 26 wright rounds repair code against noise until the owner reserves cores and asks
43
+ for a median of five.
44
+
31
45
  ## Frontend: Core Web Vitals
32
46
  For UI work, measure-first means LCP / INP / CLS judged against real numbers, each labeled
33
47
  by source (`Field (CrUX)`, `Lab (Lighthouse)`, `Trace (DevTools)`): field and lab are not
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: rite-autocomplete
3
3
  description: Run the full DevRites lifecycle unattended; --ship continues to the final Git approval boundary. Use for one-shot autonomous work; not for a single phase.
4
- argument-hint: "[idea] [--ship|--yolo] [--max-slices N] [--parallel N] [--full] [--cross-model]"
4
+ argument-hint: "[idea] [--ship|--yolo] [--max-slices N] [--parallel N] [--full] [--cross-model] [--lookahead]"
5
5
  user-invocable: true
6
6
  ---
7
7
 
8
- <!-- loads: {"always":["devrites-lib/reference/standards/core.md","devrites-lib/reference/standards/afk-hitl.md","devrites-lib/reference/standards/one-shot-actions.md","devrites-lib/reference/orchestration-profiles.md","devrites-lib/reference/standards/acceptance-preserving-reslice.md","rite-autocomplete/reference/decision-policy.md","rite-autocomplete/reference/loop.md","rite-autocomplete/reference/stop-conditions.md"],"triggers":{"workflow-artifacts":["devrites-lib/reference/standards/workflow-artifacts.md"]},"workspace":["state.md","spec.md","plan.md","tasks.md","questions.md","decisions.md","drift.md","evidence.md","test-plan.md"],"rootOnly":["devrites-lib/reference/standards/afk-hitl.md","devrites-lib/reference/orchestration-profiles.md","devrites-lib/reference/standards/workflow-artifacts.md"]} -->
8
+ <!-- loads: {"always":["devrites-lib/reference/standards/core.md","devrites-lib/reference/standards/afk-hitl.md","devrites-lib/reference/standards/one-shot-actions.md","devrites-lib/reference/orchestration-profiles.md","devrites-lib/reference/standards/acceptance-preserving-reslice.md","rite-autocomplete/reference/decision-policy.md","rite-autocomplete/reference/loop.md","rite-autocomplete/reference/stop-conditions.md"],"triggers":{"workflow-artifacts":["devrites-lib/reference/standards/workflow-artifacts.md"],"lookahead":["rite-autocomplete/reference/lookahead.md"]},"workspace":["state.md","spec.md","plan.md","tasks.md","questions.md","decisions.md","drift.md","evidence.md","test-plan.md"],"rootOnly":["devrites-lib/reference/standards/afk-hitl.md","devrites-lib/reference/orchestration-profiles.md","devrites-lib/reference/standards/workflow-artifacts.md","rite-autocomplete/reference/lookahead.md"]} -->
9
9
  > Read-set manifest: `devrites-engine context <slug> --phase autocomplete` bundles every file named below into one deduplicated read. Trigger names map to the conditional rules in the sections that follow.
10
10
 
11
11
 
@@ -67,7 +67,7 @@ executable controller/harness/bundle bytes or a missing writer, read
67
67
  not a stop either: follow it in your next tool call, never in a text-only
68
68
  acknowledgement.
69
69
  - Parse flags only from this invocation. `--ship`, `--yolo`, `--max-slices`,
70
- `--parallel`, `--full`, and `--cross-model` activate only as exact standalone
70
+ `--parallel`, `--full`, `--cross-model`, and `--lookahead` activate only as exact standalone
71
71
  tokens in `$ARGUMENTS`; examples or earlier messages can never arm them.
72
72
  `--max-slices` must occur once and be followed by a positive base-10 integer;
73
73
  `--parallel` must occur once and be followed by a base-10 integer in `1`–`10`.
@@ -80,6 +80,10 @@ executable controller/harness/bundle bytes or a missing writer, read
80
80
 
81
81
  ## Workflow
82
82
 
83
+ With `--lookahead` (trigger `lookahead`), follow
84
+ [`lookahead.md`](reference/lookahead.md) instead of the steps below: plan the
85
+ next sequence continuation through Vet in a second session, then stop.
86
+
83
87
  1. **Orient and parse.** Resolve the explicit or active slug; when a workspace exists,
84
88
  require its `state.md` and read its cursor; a fresh idea starts empty at step 2.
85
89
  Before honoring `blocked` with terminal `next_action`,
@@ -0,0 +1,50 @@
1
+ # Sequence lookahead (`--lookahead`)
2
+
3
+ > Root-only: not inlined in --role bundles.
4
+
5
+ A second session plans the next sequence continuation while the active
6
+ workspace builds, so the child's Spec → Vet overlaps its predecessor's
7
+ Build → Seal. The main loop later resumes the planned child instead of
8
+ specifying it again.
9
+
10
+ ## Start and target
11
+
12
+ The operator starts the second host session with `/rite-autocomplete
13
+ --lookahead` once the `.devrites/ACTIVE` workspace is in Build or later. The
14
+ agent never launches a session itself. The target is the next recorded
15
+ continuation after the active workspace: the entry
16
+ [sequence continuation](loop.md#sequence-continuation) would open. Stop with
17
+ nothing to do when the active workspace is before Build, no entry remains,
18
+ `continue_sequence: false`, or the sequence budget is spent.
19
+
20
+ ## Lease
21
+
22
+ Before any write, take the workspace lease:
23
+ `devrites-engine claim add --session lookahead-<target> --ttl 240 --workspace <target> --reason lookahead`.
24
+ Exit 3 means another session holds the target: stop. Re-add the lease with the
25
+ same session at each phase start, and release it with `devrites-engine claim
26
+ release` on every stop. A crashed session's lease reads `dead` and frees itself.
27
+
28
+ ## Rules
29
+
30
+ - Never read or write `.devrites/ACTIVE`. Pass the target slug explicitly to every
31
+ skill and engine command, including `/rite-spec <target> "<objective>"` and
32
+ `devrites-engine handoff <target> --resume`.
33
+ - After the workspace exists, run `devrites-engine state set <target> sequence_lookahead=yes`.
34
+ - Run Spec → Clarify → Temper → Define → Plan → Vet as the main loop does.
35
+ Define and Plan read the predecessor's current tree and plan. Record an
36
+ assumption for each predecessor interface the plan relies on.
37
+ - At Vet, beside the readiness binding, record exactly one line
38
+ `Predecessor readiness: <active-slug> <digest>` in `eng-review.md`. `<digest>`
39
+ is the hex that `devrites-engine check readiness --emit-binding <active-slug>`
40
+ prints. When the predecessor later changes its planning inputs, the child's
41
+ readiness check blocks with `DRV-GATE-READINESS-STALE` and the main loop
42
+ re-vets the child before Build.
43
+ - Never Build, never write product source or tests, never commit, and never
44
+ arm or rewrite `.devrites/AFK`. Owner questions go to the target's
45
+ `questions.md` and stop the lookahead.
46
+ - Stop at Vet `READY` with `next_action: build after predecessor Seal GO`, at a
47
+ human gate, or when the target's lease is lost.
48
+
49
+ **Failing case:** the lookahead passes Vet and starts Build while the
50
+ predecessor is still sealing, so two root sessions write one tree.
@@ -91,6 +91,13 @@ step 10 does not end the run: leave the sealed workspace unshipped with its
91
91
  (`/rite-spec <parent>-<n> "<objective>"` from the parent's `decisions.md` sequence)
92
92
  and re-enter step 1. Spend one workspace per opened continuation.
93
93
 
94
+ When that workspace already exists because a [lookahead](lookahead.md) session
95
+ planned it, do not specify it again. Wait while `devrites-engine claim check
96
+ --workspace <child>` exits 3 (a live lookahead holds it), then set
97
+ `.devrites/ACTIVE` to the child and resume from its cursor at step 1. A
98
+ predecessor replan since its Vet blocks the child's readiness with
99
+ `DRV-GATE-READINESS-STALE`; route that to `/rite-vet` before Build.
100
+
94
101
  Spend accounting is durable in `state.md` cursors, not chat. Before invoking the
95
102
  continuation, ensure the current workspace's `sequence_workspaces_remaining` is
96
103
  set — absent, write `max_workspaces - 1` and `sequence_position: 1` first — and
@@ -12,6 +12,10 @@ phases. Never silently code against a known-wrong plan.
12
12
  - the design system / existing UX pattern contradicts the planned UI;
13
13
  - a missing user decision that affects product behavior surfaces.
14
14
 
15
+ A timing gate that fails with no code cause is a protocol or environment defect
16
+ ([performance.md § Performance gate protocol](../../devrites-lib/reference/standards/performance.md#performance-gate-protocol)),
17
+ never another wright round.
18
+
15
19
  ## Workflow
16
20
  ```
17
21
  1. STOP coding.
@@ -124,7 +124,8 @@ load a routed standard to discover required behavior, not to prescribe implement
124
124
  owned prerequisites. Keep a build checkpoint only for unavailable pre-code evidence or a
125
125
  mandatory action-time approval. **Completion:** no foreseeable human choice is deferred.
126
126
  5. **Create or update the workspace** + set `.devrites/ACTIVE` from
127
- [state-workspace](reference/state-workspace.md). If the slug already exists,
127
+ [state-workspace](reference/state-workspace.md); a `--lookahead` run
128
+ leaves `.devrites/ACTIVE` unchanged. If the slug already exists,
128
129
  update the existing workspace rather than overwrite it; preserve history and
129
130
  unrelated settled content. Write every required artifact and conditional
130
131
  annex exactly from [spec-template](reference/spec-template.md)
@@ -209,7 +209,9 @@ plan declares a root-authored executable workflow file, read
209
209
  `marker sweep:` line is recorded in `eng-review.md`; a kept hit blocks READY. Write phase/next step and emit one
210
210
  `Readiness inputs SHA-256` with
211
211
  `devrites-engine check readiness --emit-binding <slug>`; normal readiness check
212
- must pass. Record the per-input drift baseline alongside it:
212
+ must pass. A `sequence_lookahead: yes` workspace also records one
213
+ `Predecessor readiness: <predecessor> <digest>` line from the predecessor's
214
+ `--emit-binding` hex; readiness re-checks it. Record the per-input drift baseline alongside it:
213
215
  `devrites-engine check drift <slug> --record` — a later stale binding then
214
216
  names the exact artifact that moved instead of "something changed". An `ADVISORY
215
217
  proportion:` line names a slice whose proof outgrew its ACs: move its rows without a
@@ -28,6 +28,20 @@ Measure first. An optimization without a measurement is a guess that adds comple
28
28
  flaking wall-clock test is a flaky test, [`testing.md`](testing.md)). Budget regression:
29
29
  re-measure; fix to budget or record the accepted regression with reason and owner.
30
30
 
31
+ ## Performance gate protocol
32
+ - A gate that judges a timing budget or a regression percentage pins its protocol
33
+ before Build: the environment (isolated cores, swap state, build flags such as
34
+ `CGO_ENABLED`), the repetitions and the aggregate (a median of at least five runs,
35
+ never one sample), and a noise floor measured as an A/A spread on that same
36
+ environment. Vet blocks READY on a timing gate without one. A threshold at or
37
+ below the noise floor is a plan defect for the owner, never a Build repair.
38
+ - A timing gate that fails while no code changed (an A/A run, a rerun) is noise or
39
+ host state, not a code defect. Stop wright rounds on it and fix the protocol or the
40
+ environment first.
41
+ - **Failing case:** a 10% p99 regression gate runs one sample per run on a shared host;
42
+ 26 wright rounds repair code against noise until the owner reserves cores and asks
43
+ for a median of five.
44
+
31
45
  ## Frontend: Core Web Vitals
32
46
  For UI work, measure-first means LCP / INP / CLS judged against real numbers, each labeled
33
47
  by source (`Field (CrUX)`, `Lab (Lighthouse)`, `Trace (DevTools)`): field and lab are not
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: rite-autocomplete
3
3
  description: Run the full DevRites lifecycle unattended; --ship continues to the final Git approval boundary. Use for one-shot autonomous work; not for a single phase.
4
- argument-hint: "[idea] [--ship|--yolo] [--max-slices N] [--parallel N] [--full] [--cross-model]"
4
+ argument-hint: "[idea] [--ship|--yolo] [--max-slices N] [--parallel N] [--full] [--cross-model] [--lookahead]"
5
5
  user-invocable: true
6
6
  ---
7
7
 
8
- <!-- loads: {"always":["devrites-lib/reference/standards/core.md","devrites-lib/reference/standards/afk-hitl.md","devrites-lib/reference/standards/one-shot-actions.md","devrites-lib/reference/orchestration-profiles.md","devrites-lib/reference/standards/acceptance-preserving-reslice.md","rite-autocomplete/reference/decision-policy.md","rite-autocomplete/reference/loop.md","rite-autocomplete/reference/stop-conditions.md"],"triggers":{"workflow-artifacts":["devrites-lib/reference/standards/workflow-artifacts.md"]},"workspace":["state.md","spec.md","plan.md","tasks.md","questions.md","decisions.md","drift.md","evidence.md","test-plan.md"],"rootOnly":["devrites-lib/reference/standards/afk-hitl.md","devrites-lib/reference/orchestration-profiles.md","devrites-lib/reference/standards/workflow-artifacts.md"]} -->
8
+ <!-- loads: {"always":["devrites-lib/reference/standards/core.md","devrites-lib/reference/standards/afk-hitl.md","devrites-lib/reference/standards/one-shot-actions.md","devrites-lib/reference/orchestration-profiles.md","devrites-lib/reference/standards/acceptance-preserving-reslice.md","rite-autocomplete/reference/decision-policy.md","rite-autocomplete/reference/loop.md","rite-autocomplete/reference/stop-conditions.md"],"triggers":{"workflow-artifacts":["devrites-lib/reference/standards/workflow-artifacts.md"],"lookahead":["rite-autocomplete/reference/lookahead.md"]},"workspace":["state.md","spec.md","plan.md","tasks.md","questions.md","decisions.md","drift.md","evidence.md","test-plan.md"],"rootOnly":["devrites-lib/reference/standards/afk-hitl.md","devrites-lib/reference/orchestration-profiles.md","devrites-lib/reference/standards/workflow-artifacts.md","rite-autocomplete/reference/lookahead.md"]} -->
9
9
  > Read-set manifest: `devrites-engine context <slug> --phase autocomplete` bundles every file named below into one deduplicated read. Trigger names map to the conditional rules in the sections that follow.
10
10
 
11
11
 
@@ -69,7 +69,7 @@ executable controller/harness/bundle bytes or a missing writer, read
69
69
  not a stop either: follow it in your next tool call, never in a text-only
70
70
  acknowledgement.
71
71
  - Parse flags only from this invocation. `--ship`, `--yolo`, `--max-slices`,
72
- `--parallel`, `--full`, and `--cross-model` activate only as exact standalone
72
+ `--parallel`, `--full`, `--cross-model`, and `--lookahead` activate only as exact standalone
73
73
  tokens in `$ARGUMENTS`; examples or earlier messages can never arm them.
74
74
  `--max-slices` must occur once and be followed by a positive base-10 integer;
75
75
  `--parallel` must occur once and be followed by a base-10 integer in `1`–`10`.
@@ -82,6 +82,10 @@ executable controller/harness/bundle bytes or a missing writer, read
82
82
 
83
83
  ## Workflow
84
84
 
85
+ With `--lookahead` (trigger `lookahead`), follow
86
+ [`lookahead.md`](reference/lookahead.md) instead of the steps below: plan the
87
+ next sequence continuation through Vet in a second session, then stop.
88
+
85
89
  1. **Orient and parse.** Resolve the explicit or active slug; when a workspace exists,
86
90
  require its `state.md` and read its cursor; a fresh idea starts empty at step 2.
87
91
  Before honoring `blocked` with terminal `next_action`,
@@ -0,0 +1,50 @@
1
+ # Sequence lookahead (`--lookahead`)
2
+
3
+ > Root-only: not inlined in --role bundles.
4
+
5
+ A second session plans the next sequence continuation while the active
6
+ workspace builds, so the child's Spec → Vet overlaps its predecessor's
7
+ Build → Seal. The main loop later resumes the planned child instead of
8
+ specifying it again.
9
+
10
+ ## Start and target
11
+
12
+ The operator starts the second host session with `/rite-autocomplete
13
+ --lookahead` once the `.devrites/ACTIVE` workspace is in Build or later. The
14
+ agent never launches a session itself. The target is the next recorded
15
+ continuation after the active workspace: the entry
16
+ [sequence continuation](loop.md#sequence-continuation) would open. Stop with
17
+ nothing to do when the active workspace is before Build, no entry remains,
18
+ `continue_sequence: false`, or the sequence budget is spent.
19
+
20
+ ## Lease
21
+
22
+ Before any write, take the workspace lease:
23
+ `devrites-engine claim add --session lookahead-<target> --ttl 240 --workspace <target> --reason lookahead`.
24
+ Exit 3 means another session holds the target: stop. Re-add the lease with the
25
+ same session at each phase start, and release it with `devrites-engine claim
26
+ release` on every stop. A crashed session's lease reads `dead` and frees itself.
27
+
28
+ ## Rules
29
+
30
+ - Never read or write `.devrites/ACTIVE`. Pass the target slug explicitly to every
31
+ skill and engine command, including `/rite-spec <target> "<objective>"` and
32
+ `devrites-engine handoff <target> --resume`.
33
+ - After the workspace exists, run `devrites-engine state set <target> sequence_lookahead=yes`.
34
+ - Run Spec → Clarify → Temper → Define → Plan → Vet as the main loop does.
35
+ Define and Plan read the predecessor's current tree and plan. Record an
36
+ assumption for each predecessor interface the plan relies on.
37
+ - At Vet, beside the readiness binding, record exactly one line
38
+ `Predecessor readiness: <active-slug> <digest>` in `eng-review.md`. `<digest>`
39
+ is the hex that `devrites-engine check readiness --emit-binding <active-slug>`
40
+ prints. When the predecessor later changes its planning inputs, the child's
41
+ readiness check blocks with `DRV-GATE-READINESS-STALE` and the main loop
42
+ re-vets the child before Build.
43
+ - Never Build, never write product source or tests, never commit, and never
44
+ arm or rewrite `.devrites/AFK`. Owner questions go to the target's
45
+ `questions.md` and stop the lookahead.
46
+ - Stop at Vet `READY` with `next_action: build after predecessor Seal GO`, at a
47
+ human gate, or when the target's lease is lost.
48
+
49
+ **Failing case:** the lookahead passes Vet and starts Build while the
50
+ predecessor is still sealing, so two root sessions write one tree.
@@ -93,6 +93,13 @@ step 10 does not end the run: leave the sealed workspace unshipped with its
93
93
  (`/rite-spec <parent>-<n> "<objective>"` from the parent's `decisions.md` sequence)
94
94
  and re-enter step 1. Spend one workspace per opened continuation.
95
95
 
96
+ When that workspace already exists because a [lookahead](lookahead.md) session
97
+ planned it, do not specify it again. Wait while `devrites-engine claim check
98
+ --workspace <child>` exits 3 (a live lookahead holds it), then set
99
+ `.devrites/ACTIVE` to the child and resume from its cursor at step 1. A
100
+ predecessor replan since its Vet blocks the child's readiness with
101
+ `DRV-GATE-READINESS-STALE`; route that to `/rite-vet` before Build.
102
+
96
103
  Spend accounting is durable in `state.md` cursors, not chat. Before invoking the
97
104
  continuation, ensure the current workspace's `sequence_workspaces_remaining` is
98
105
  set — absent, write `max_workspaces - 1` and `sequence_position: 1` first — and
@@ -12,6 +12,10 @@ phases. Never silently code against a known-wrong plan.
12
12
  - the design system / existing UX pattern contradicts the planned UI;
13
13
  - a missing user decision that affects product behavior surfaces.
14
14
 
15
+ A timing gate that fails with no code cause is a protocol or environment defect
16
+ ([performance.md § Performance gate protocol](../../devrites-lib/reference/standards/performance.md#performance-gate-protocol)),
17
+ never another wright round.
18
+
15
19
  ## Workflow
16
20
  ```
17
21
  1. STOP coding.
@@ -124,7 +124,8 @@ load a routed standard to discover required behavior, not to prescribe implement
124
124
  owned prerequisites. Keep a build checkpoint only for unavailable pre-code evidence or a
125
125
  mandatory action-time approval. **Completion:** no foreseeable human choice is deferred.
126
126
  5. **Create or update the workspace** + set `.devrites/ACTIVE` from
127
- [state-workspace](reference/state-workspace.md). If the slug already exists,
127
+ [state-workspace](reference/state-workspace.md); a `--lookahead` run
128
+ leaves `.devrites/ACTIVE` unchanged. If the slug already exists,
128
129
  update the existing workspace rather than overwrite it; preserve history and
129
130
  unrelated settled content. Write every required artifact and conditional
130
131
  annex exactly from [spec-template](reference/spec-template.md)
@@ -211,7 +211,9 @@ plan declares a root-authored executable workflow file, read
211
211
  `marker sweep:` line is recorded in `eng-review.md`; a kept hit blocks READY. Write phase/next step and emit one
212
212
  `Readiness inputs SHA-256` with
213
213
  `devrites-engine check readiness --emit-binding <slug>`; normal readiness check
214
- must pass. Record the per-input drift baseline alongside it:
214
+ must pass. A `sequence_lookahead: yes` workspace also records one
215
+ `Predecessor readiness: <predecessor> <digest>` line from the predecessor's
216
+ `--emit-binding` hex; readiness re-checks it. Record the per-input drift baseline alongside it:
215
217
  `devrites-engine check drift <slug> --record` — a later stale binding then
216
218
  names the exact artifact that moved instead of "something changed". An `ADVISORY
217
219
  proportion:` line names a slice whose proof outgrew its ACs: move its rows without a