devrites 7.0.0 → 7.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +1 -1
- package/docs/command-map.md +1 -1
- package/docs/usage.md +7 -2
- package/engine/internal/gate/gate.go +7 -0
- package/engine/internal/gate/predecessor.go +67 -0
- package/engine/internal/lib/claims.go +57 -7
- package/engine/internal/lib/resolve.go +11 -2
- package/pack/.claude/skills/devrites-lib/reference/standards/performance.md +14 -0
- package/pack/.claude/skills/rite-autocomplete/SKILL.md +7 -3
- package/pack/.claude/skills/rite-autocomplete/reference/lookahead.md +50 -0
- package/pack/.claude/skills/rite-autocomplete/reference/loop.md +7 -0
- package/pack/.claude/skills/rite-build/reference/spec-drift-guard.md +4 -0
- package/pack/.claude/skills/rite-spec/SKILL.md +2 -1
- package/pack/.claude/skills/rite-vet/SKILL.md +3 -1
- package/pack/generated/claude/skills/devrites-lib/reference/standards/performance.md +14 -0
- package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +7 -3
- package/pack/generated/claude/skills/rite-autocomplete/reference/lookahead.md +50 -0
- package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +7 -0
- package/pack/generated/claude/skills/rite-build/reference/spec-drift-guard.md +4 -0
- package/pack/generated/claude/skills/rite-spec/SKILL.md +2 -1
- package/pack/generated/claude/skills/rite-vet/SKILL.md +3 -1
- package/pack/generated/codex/skills/devrites-lib/reference/standards/performance.md +14 -0
- package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-autocomplete/reference/lookahead.md +50 -0
- package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +7 -0
- package/pack/generated/codex/skills/rite-build/reference/spec-drift-guard.md +4 -0
- package/pack/generated/codex/skills/rite-spec/SKILL.md +2 -1
- package/pack/generated/codex/skills/rite-vet/SKILL.md +3 -1
- package/pack/generated/devin/skills/devrites-lib/reference/standards/performance.md +14 -0
- package/pack/generated/devin/skills/rite-autocomplete/SKILL.md +7 -3
- package/pack/generated/devin/skills/rite-autocomplete/reference/lookahead.md +50 -0
- package/pack/generated/devin/skills/rite-autocomplete/reference/loop.md +7 -0
- package/pack/generated/devin/skills/rite-build/reference/spec-drift-guard.md +4 -0
- package/pack/generated/devin/skills/rite-spec/SKILL.md +2 -1
- package/pack/generated/devin/skills/rite-vet/SKILL.md +3 -1
- package/pack/generated/omp/commands/rite-autocomplete.md +1 -1
- package/pack/generated/omp/skills/devrites-lib/reference/standards/performance.md +14 -0
- package/pack/generated/omp/skills/rite-autocomplete/SKILL.md +7 -3
- package/pack/generated/omp/skills/rite-autocomplete/reference/lookahead.md +50 -0
- package/pack/generated/omp/skills/rite-autocomplete/reference/loop.md +7 -0
- package/pack/generated/omp/skills/rite-build/reference/spec-drift-guard.md +4 -0
- package/pack/generated/omp/skills/rite-spec/SKILL.md +2 -1
- package/pack/generated/omp/skills/rite-vet/SKILL.md +3 -1
- package/pack/generated/pi/prompts/rite-autocomplete.md +1 -1
- package/pack/generated/pi/skills/devrites-lib/reference/standards/performance.md +14 -0
- package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +7 -3
- package/pack/generated/pi/skills/rite-autocomplete/reference/lookahead.md +50 -0
- package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +7 -0
- package/pack/generated/pi/skills/rite-build/reference/spec-drift-guard.md +4 -0
- package/pack/generated/pi/skills/rite-spec/SKILL.md +2 -1
- package/pack/generated/pi/skills/rite-vet/SKILL.md +3 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to DevRites are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and DevRites adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Releases are generated automatically by [semantic-release](https://semantic-release.gitbook.io/) from Conventional Commits on `main`.
|
|
4
4
|
|
|
5
|
+
## [7.0.2](https://github.com/ViktorsBaikers/DevRites/compare/v7.0.1...v7.0.2) (2026-10-20)
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
* **devrites:** resume a workspace whose cursor holds the question ([#152](https://github.com/ViktorsBaikers/DevRites/issues/152)) ([de489b6](https://github.com/ViktorsBaikers/DevRites/commit/de489b6c9bd6a4d50b55060e4f46e1a7161607d0))
|
|
10
|
+
|
|
11
|
+
## [7.0.1](https://github.com/ViktorsBaikers/DevRites/compare/v7.0.0...v7.0.1) (2026-10-20)
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
* **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))
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
* **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))
|
|
20
|
+
|
|
5
21
|
## [7.0.0](https://github.com/ViktorsBaikers/DevRites/compare/v6.10.0...v7.0.0) (2026-10-20)
|
|
6
22
|
|
|
7
23
|
### ⚠ 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.
|
|
34
|
+
**Status:** [`v7.0.2`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v7.0.2): 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
|
|
package/docs/command-map.md
CHANGED
|
@@ -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 :=
|
|
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 :=
|
|
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 :=
|
|
521
|
+
paths, err := claimTargets(raw, workspaces)
|
|
472
522
|
if err != nil {
|
|
473
523
|
fmt.Fprintf(stderr, "claim: %v\n", err)
|
|
474
524
|
return 2
|
|
@@ -351,7 +351,7 @@ var (
|
|
|
351
351
|
)
|
|
352
352
|
|
|
353
353
|
// clearAwaiting resumes the workflow after a question is resolved: when state.md's
|
|
354
|
-
// "Awaiting human" block references qid, it drops that block, flips Status back to
|
|
354
|
+
// "Awaiting human" block or cursor question_id references qid, it drops that block, flips Status back to
|
|
355
355
|
// running, clears the Next step, and appends a Log entry. It is a no-op when the
|
|
356
356
|
// workspace is not waiting on this question.
|
|
357
357
|
func clearAwaiting(sfile, qid string) error {
|
|
@@ -386,8 +386,14 @@ func clearAwaiting(sfile, qid string) error {
|
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
388
|
waitingOn, _ := state.CursorField(awaitingLines, state.CursorQuestionID)
|
|
389
|
+
cursorWaits := false
|
|
389
390
|
if waitingOn != qid {
|
|
390
|
-
|
|
391
|
+
// `state set question_id=<qid>` records the wait in the cursor table
|
|
392
|
+
// instead of an Awaiting human block.
|
|
393
|
+
if cursorQID, _ := state.CursorField(lines, state.CursorQuestionID); cursorQID != qid {
|
|
394
|
+
return nil
|
|
395
|
+
}
|
|
396
|
+
cursorWaits = true
|
|
391
397
|
}
|
|
392
398
|
|
|
393
399
|
// Rewrite: drop the awaiting block, reset Status/Next step, log the resolution.
|
|
@@ -424,6 +430,9 @@ func clearAwaiting(sfile, qid string) error {
|
|
|
424
430
|
if inLog && !logAppended {
|
|
425
431
|
out = append(out, fmt.Sprintf("- %s %s: resolved %s", ts, resumePolicy.Target, qid))
|
|
426
432
|
}
|
|
433
|
+
if cursorWaits {
|
|
434
|
+
out = state.DeleteCursorField(out, state.CursorQuestionID)
|
|
435
|
+
}
|
|
427
436
|
out, _ = state.SetCursorField(out, state.CursorStatus, "running")
|
|
428
437
|
out, _ = state.SetCursorField(out, state.CursorNextAction, "(resume: `"+resumeCommand.Both()+"` to continue the workflow)")
|
|
429
438
|
if err := fsutil.WriteFileAtomic(sfile, joinRecords(out), 0o644); err != nil {
|
|
@@ -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`,
|
|
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)
|
|
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.
|
|
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`,
|
|
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.
|