devrites 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/engine/internal/parallel/lease.go +12 -2
  4. package/engine/internal/parallel/ops.go +3 -3
  5. package/engine/internal/parallel/parallel_test.go +104 -0
  6. package/pack/.claude/skills/rite-build/SKILL.md +7 -5
  7. package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +7 -5
  8. package/pack/.claude/skills/rite-build/reference/parallel-batch.md +13 -7
  9. package/pack/.claude/skills/rite-build/reference/phase-contract.md +1 -0
  10. package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +1 -1
  11. package/pack/generated/claude/skills/rite-build/SKILL.md +7 -5
  12. package/pack/generated/claude/skills/rite-build/reference/one-slice-cycle.md +7 -5
  13. package/pack/generated/claude/skills/rite-build/reference/parallel-batch.md +13 -7
  14. package/pack/generated/claude/skills/rite-build/reference/phase-contract.md +1 -0
  15. package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +1 -1
  16. package/pack/generated/codex/skills/rite-build/SKILL.md +7 -5
  17. package/pack/generated/codex/skills/rite-build/reference/one-slice-cycle.md +7 -5
  18. package/pack/generated/codex/skills/rite-build/reference/parallel-batch.md +13 -7
  19. package/pack/generated/codex/skills/rite-build/reference/phase-contract.md +1 -0
  20. package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +1 -1
  21. package/pack/generated/omp/skills/rite-build/SKILL.md +7 -5
  22. package/pack/generated/omp/skills/rite-build/reference/one-slice-cycle.md +7 -5
  23. package/pack/generated/omp/skills/rite-build/reference/parallel-batch.md +13 -7
  24. package/pack/generated/omp/skills/rite-build/reference/phase-contract.md +1 -0
  25. package/pack/generated/omp/skills/rite-build/reference/wright-dispatch.md +1 -1
  26. package/package.json +3 -2
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to DevRites are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and DevRites adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Releases are generated automatically by [semantic-release](https://semantic-release.gitbook.io/) from Conventional Commits on `main`.
4
4
 
5
+ ## [5.1.0](https://github.com/ViktorsBaikers/DevRites/compare/v5.0.0...v5.1.0) (2026-09-10)
6
+
7
+ ### Added
8
+
9
+ * **skills:** raise /rite-build --parallel cap from 3 to 10 ([#60](https://github.com/ViktorsBaikers/DevRites/issues/60)) ([d88afa0](https://github.com/ViktorsBaikers/DevRites/commit/d88afa0af31eed421a1a5fdbff8eaf3f61b02bff))
10
+
5
11
  ## [5.0.0](https://github.com/ViktorsBaikers/DevRites/compare/v4.7.0...v5.0.0) (2026-09-06)
6
12
 
7
13
  ### ⚠ BREAKING CHANGES
package/README.md CHANGED
@@ -33,7 +33,7 @@ project-conventional push, tag, or PR action, and archive the workspace.
33
33
  Unattended runs may create local WIP checkpoint commits along the way, but they
34
34
  remain local unless Ship's disclosed plan includes an approved remote action.
35
35
 
36
- **Status:** [`v5.0.0`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v5.0.0): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
36
+ **Status:** [`v5.1.0`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v5.1.0): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
37
37
 
38
38
  This is the latest published release; `main` may contain unreleased work.
39
39
 
@@ -20,6 +20,9 @@ const (
20
20
  WrightGreen = "green"
21
21
  WrightRed = "red"
22
22
  WrightGap = "gap"
23
+
24
+ MinParallelSlices = 2
25
+ MaxParallelSlices = 10
23
26
  )
24
27
 
25
28
  var (
@@ -95,6 +98,13 @@ func validateSliceID(id string) error {
95
98
  return nil
96
99
  }
97
100
 
101
+ func checkParallelSliceCount(n int) error {
102
+ if n < MinParallelSlices || n > MaxParallelSlices {
103
+ return fmt.Errorf("parallel requires %d-%d slices (got %d)", MinParallelSlices, MaxParallelSlices, n)
104
+ }
105
+ return nil
106
+ }
107
+
98
108
  func ValidateLease(lease *Lease) error {
99
109
  if lease == nil {
100
110
  return fmt.Errorf("lease is nil")
@@ -113,8 +123,8 @@ func ValidateLease(lease *Lease) error {
113
123
  default:
114
124
  return fmt.Errorf("invalid lease status %q", lease.Status)
115
125
  }
116
- if len(lease.Slices) < 2 || len(lease.Slices) > 3 {
117
- return fmt.Errorf("lease must have 2 or 3 slices (got %d)", len(lease.Slices))
126
+ if err := checkParallelSliceCount(len(lease.Slices)); err != nil {
127
+ return err
118
128
  }
119
129
  if lease.N != len(lease.Slices) {
120
130
  return fmt.Errorf("lease n=%d does not match slices=%d", lease.N, len(lease.Slices))
@@ -29,7 +29,7 @@ type CreateOpts struct {
29
29
  Slices []SlicePaths
30
30
  }
31
31
 
32
- // Create path-disjoint-gates, creates <=3 worktrees from base, and writes a running lease.
32
+ // Create path-disjoint-gates, creates 2-10 worktrees from base, and writes a running lease.
33
33
  func Create(opts CreateOpts) (*Lease, error) {
34
34
  if err := validateSlug(opts.Slug); err != nil {
35
35
  return nil, err
@@ -37,8 +37,8 @@ func Create(opts CreateOpts) (*Lease, error) {
37
37
  if err := validateBatchID(opts.BatchID); err != nil {
38
38
  return nil, err
39
39
  }
40
- if len(opts.Slices) < 2 || len(opts.Slices) > 3 {
41
- return nil, fmt.Errorf("create requires 2 or 3 slices (got %d)", len(opts.Slices))
40
+ if err := checkParallelSliceCount(len(opts.Slices)); err != nil {
41
+ return nil, err
42
42
  }
43
43
  if _, err := CheckPathDisjoint(opts.Slices, opts.Root); err != nil {
44
44
  return nil, err
@@ -1,6 +1,7 @@
1
1
  package parallel
2
2
 
3
3
  import (
4
+ "fmt"
4
5
  "os"
5
6
  "os/exec"
6
7
  "path/filepath"
@@ -146,6 +147,109 @@ func TestCreateAbortCleanup(t *testing.T) {
146
147
  }
147
148
  }
148
149
 
150
+ func TestCreateAcceptsFourSlices(t *testing.T) {
151
+ t.Parallel()
152
+ repo, _ := setupRepo(t)
153
+ for _, name := range []string{"c.go", "d.go"} {
154
+ if err := os.WriteFile(filepath.Join(repo, "src", name), []byte("package main\n"), 0o644); err != nil {
155
+ t.Fatal(err)
156
+ }
157
+ }
158
+ gitOk(t, repo, "add", ".")
159
+ gitOk(t, repo, "commit", "-m", "more files")
160
+ base := gitOk(t, repo, "rev-parse", "HEAD")
161
+ lease, err := Create(CreateOpts{
162
+ Root: repo,
163
+ Slug: "demo-four",
164
+ BatchID: "batch4",
165
+ BaseSHA: base,
166
+ Slices: []SlicePaths{
167
+ {ID: "slice-a", Paths: []string{"src/a.go"}},
168
+ {ID: "slice-b", Paths: []string{"src/b.go"}},
169
+ {ID: "slice-c", Paths: []string{"src/c.go"}},
170
+ {ID: "slice-d", Paths: []string{"src/d.go"}},
171
+ },
172
+ })
173
+ if err != nil {
174
+ t.Fatal(err)
175
+ }
176
+ if lease.N != 4 || len(lease.Slices) != 4 {
177
+ t.Fatalf("want 4 slices, got n=%d slices=%d", lease.N, len(lease.Slices))
178
+ }
179
+ }
180
+
181
+ func TestCreateRefusesCountOutsideBounds(t *testing.T) {
182
+ t.Parallel()
183
+ repo, base := setupRepo(t)
184
+ _, err := Create(CreateOpts{
185
+ Root: repo,
186
+ Slug: "demo-one",
187
+ BatchID: "batch1",
188
+ BaseSHA: base,
189
+ Slices: []SlicePaths{{ID: "slice-a", Paths: []string{"src/a.go"}}},
190
+ })
191
+ if err == nil || !strings.Contains(err.Error(), "2-10 slices") {
192
+ t.Fatalf("expected 2-10 bound for N=1, got %v", err)
193
+ }
194
+
195
+ slices := make([]SlicePaths, MaxParallelSlices+1)
196
+ for i := range slices {
197
+ name := fmt.Sprintf("src/x%d.go", i)
198
+ if err := os.WriteFile(filepath.Join(repo, name), []byte("package main\n"), 0o644); err != nil {
199
+ t.Fatal(err)
200
+ }
201
+ slices[i] = SlicePaths{ID: fmt.Sprintf("s%d", i), Paths: []string{name}}
202
+ }
203
+ gitOk(t, repo, "add", ".")
204
+ gitOk(t, repo, "commit", "-m", "eleven")
205
+ base = gitOk(t, repo, "rev-parse", "HEAD")
206
+ _, err = Create(CreateOpts{
207
+ Root: repo,
208
+ Slug: "demo-eleven",
209
+ BatchID: "batch11",
210
+ BaseSHA: base,
211
+ Slices: slices,
212
+ })
213
+ if err == nil || !strings.Contains(err.Error(), "2-10 slices") {
214
+ t.Fatalf("expected 2-10 bound for N=11, got %v", err)
215
+ }
216
+ }
217
+
218
+ func TestValidateLeaseBounds(t *testing.T) {
219
+ t.Parallel()
220
+ ok := validTestLease(MaxParallelSlices)
221
+ if err := ValidateLease(ok); err != nil {
222
+ t.Fatalf("N=%d should validate: %v", MaxParallelSlices, err)
223
+ }
224
+ tooMany := validTestLease(MaxParallelSlices + 1)
225
+ if err := ValidateLease(tooMany); err == nil || !strings.Contains(err.Error(), "2-10 slices") {
226
+ t.Fatalf("N=%d should refuse, got %v", MaxParallelSlices+1, err)
227
+ }
228
+ }
229
+
230
+ func validTestLease(n int) *Lease {
231
+ slices := make([]LeaseSlice, n)
232
+ for i := range slices {
233
+ id := fmt.Sprintf("s%d", i)
234
+ slices[i] = LeaseSlice{
235
+ ID: id,
236
+ Paths: []string{fmt.Sprintf("src/%s.go", id)},
237
+ WorktreePath: "/tmp/" + id,
238
+ Branch: "devrites/parallel/x/batch/" + id,
239
+ WrightStatus: WrightPending,
240
+ }
241
+ }
242
+ return &Lease{
243
+ BatchID: "batch1",
244
+ CreatedAt: "2026-08-23T00:00:00Z",
245
+ BaseSHA: "abcdef1",
246
+ N: n,
247
+ Status: StatusRunning,
248
+ ControlPIDOrSession: "test",
249
+ Slices: slices,
250
+ }
251
+ }
252
+
149
253
  func TestCreateRefusesOverlap(t *testing.T) {
150
254
  repo, base := setupRepo(t)
151
255
  _, err := Create(CreateOpts{
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: rite-build
3
- description: Build the next approved vertical slice with evidence. HITL one-slice default; AFK may chain serially; opt-in `--parallel N` (2≤N≤3) for path-disjoint worktrees.
3
+ description: Build the next approved vertical slice with evidence. HITL one-slice default; AFK may chain serially; opt-in `--parallel N` (2≤N≤10) for path-disjoint worktrees.
4
4
  argument-hint: "[--parallel N] [slice number or name]"
5
5
  user-invocable: true
6
6
  ---
@@ -10,7 +10,7 @@ user-invocable: true
10
10
  Build and prove one slice. HITL stops; a later user invocation starts the next.
11
11
  Explicit `.devrites/AFK` alone lets the controlling root chain pending slices
12
12
  serially under green proof, caps, and pause rules. Every wright returns after one slice.
13
- **Opt-in:** `/rite-build --parallel N` (2≤N≤3; N=1≡serial) follows
13
+ **Opt-in:** `/rite-build --parallel N` (2≤N≤10; N=1≡serial) follows
14
14
  [`reference/parallel-batch.md`](reference/parallel-batch.md)
15
15
  ([`one-slice-cycle.md`](reference/one-slice-cycle.md)).
16
16
 
@@ -55,9 +55,11 @@ Wright applies anti-slop; root verifies returns and never patches source.
55
55
  <!-- workflow-artifact-adapter: {"module":"devrites-lib/reference/standards/workflow-artifacts.md","entry":"Vet-ready admitted bytes require root authorship outside product wright","action":"ROOT_TRANSACTION; root writes only admitted .devrites/** targets","return":"saved Build slice cursor; wright product allowlist unchanged"} -->
56
56
  ## `--parallel N` (opt-in)
57
57
 
58
- Omitted/`1` ≡ serial; `2`/`3` → path-disjoint fan-out when eligible; else hard refuse.
59
- All-green serial integrate; one red/gap aborts. AFK charges after integrate only.
60
- Running lease blocks another `/rite-build`. Details: `parallel-batch.md`.
58
+ Omitted/`1` ≡ serial; `2`–`10` → path-disjoint fan-out when eligible; else hard refuse.
59
+ All-green serial integrate; one red/gap aborts. Abort with agent-owned plan
60
+ gaps continues via Spec Drift Guard (plan repair + vet inline); do not emit a
61
+ human `Fix`. AFK charges after integrate only. Running lease blocks another
62
+ `/rite-build`. Details: `parallel-batch.md`.
61
63
 
62
64
  ## Execute and reply
63
65
 
@@ -3,7 +3,7 @@
3
3
  One wright dispatch builds one thin, proven slice. HITL stops; only explicit
4
4
  `.devrites/AFK` lets the controlling root chain another pending slice under the
5
5
  green-proof, cap, and pause rules. Each wright returns after exactly one slice.
6
- Opt-in fan-out: [`parallel-batch.md`](parallel-batch.md) (`--parallel N`); this is default.
6
+ This serial cycle is the default `/rite-build`. Opt-in fan-out: [`parallel-batch.md`](parallel-batch.md) (`--parallel N`).
7
7
 
8
8
  ## The cycle
9
9
 
@@ -38,8 +38,10 @@ you check yourself against: anything outside it is scope creep or a drift event.
38
38
 
39
39
  ## When the slice can't be completed cleanly
40
40
 
41
- - Discovered the plan is wrong → **Spec Drift Guard** (stop, record, classify, maybe
42
- ask, `/rite-plan` repair).
43
- - Slice is bigger than one cycle → stop and `/rite-plan reslice`.
44
- - Blocked on a failing dependency → record in `state.md`, `/rite-plan unblock`.
41
+ - Discovered the plan is wrong → **Spec Drift Guard** (record, classify;
42
+ agent-owned repair+vet inline; ask only for product/policy/irreversible-risk).
43
+ - Slice is bigger than one cycle → `/rite-plan reslice` inline when AC is
44
+ preserved; do not emit a human Fix.
45
+ - Blocked on a failing dependency → record in `state.md`, `/rite-plan unblock`
46
+ inline when the reroute is technical.
45
47
  Never power through by guessing.
@@ -7,12 +7,13 @@ Opt-in only. Default `/rite-build` stays [`one-slice-cycle.md`](one-slice-cycle.
7
7
  | Input | Behavior |
8
8
  | --- | --- |
9
9
  | omitted / `--parallel 1` | Serial one-slice |
10
- | `--parallel N` (**2≤N≤3**) | Parallel when eligible + host pass |
11
- | non-integer / `N≤0` / `N>3` | Hard refuse (no silent clamp) |
10
+ | `--parallel N` (**2≤N≤10**) | Parallel when eligible + host pass |
11
+ | non-integer / `N≤0` / `N>10` | Hard refuse (no silent clamp) |
12
12
 
13
13
  AFK caps `N` by remaining budget. Charge **only after successful integrate**
14
- (once per integrated green sibling). Abort / integrate-failed → **0**. Running
15
- lease blocks another `/rite-build`.
14
+ (once per integrated green sibling). Abort / integrate-failed → **0**. A
15
+ `running` lease blocks another `/rite-build`. Any present lease blocks
16
+ `parallel create` until cleanup.
16
17
 
17
18
  ## Path-disjoint
18
19
 
@@ -40,14 +41,19 @@ Lease: `batch_id`, `created_at`, `base_sha`, `n`,
40
41
 
41
42
  1. Orient/gate; parse N; select ≤N path-disjoint pending slices.
42
43
  2. Write lease; freeze `B=HEAD`; `parallel create` worktrees.
43
- 3. Dispatch ≤3 wrights in parallel (cwd=worktree; allowlist; prove `HEAD==B`).
44
- 4. Inspect + fail-on-red → `green|red|gap`.
44
+ 3. Dispatch ≤10 wrights in parallel (cwd=worktree; allowlist; prove `HEAD==B`).
45
+ 4. Inspect + fail-on-red → `green|red|gap`. Independent-review Critical is `gap`
46
+ even when targeted tests are green.
45
47
  5. Any red/gap → **abort** (no partial integrate). All green → serial integrate.
46
48
  6. Integrate: `transfer_commit` descends from `B`; `` `<base>..<transfer>` ``
47
49
  path-exact; apply in plan order. Conflict → reset to `B`, `integrate-failed`.
48
50
  7. Success: FF control; union `touched-files.md`; update state/evidence; AFK +1
49
51
  per integrated sibling; optional `check candidate`.
50
- 8. Cleanup: success removes worktrees/branches; abort keeps until acknowledged.
52
+ 8. Cleanup: success removes worktrees/branches. Abort keeps them as repair
53
+ inputs until the root consumes them: agent-owned plan gaps (AC unchanged)
54
+ follow [`spec-drift-guard.md`](spec-drift-guard.md) — `/rite-plan repair` then
55
+ `/rite-vet` inline, then cleanup and resume Build. Do not emit
56
+ `Fix: /rite-plan repair`. Product/policy/irreversible-risk still stops.
51
57
 
52
58
  ## Engine verbs
53
59
 
@@ -3,6 +3,7 @@
3
3
  See [`one-slice-cycle.md`](one-slice-cycle.md); candidate lifecycle is
4
4
  [`candidate-integrity.md`](../../devrites-lib/reference/candidate-integrity.md).
5
5
  Opt-in `--parallel N` uses [`parallel-batch.md`](parallel-batch.md) instead of steps 2–8.
6
+ Spec Drift Guard still applies on abort or plan-gap.
6
7
 
7
8
  1. **Orient and gate.** Read core, `.devrites/ACTIVE`, `state.md`, and required
8
9
  slice artifacts. Require `Implementation readiness: READY`, its current
@@ -36,7 +36,7 @@ Conflict, extra/missing commit, moved base, or cleanup failure is `gap`/STOP:
36
36
  preserve the worktree and commit. Without explicit reconciliation, use same-worktree serial.
37
37
  Parallel isolated-writer worktrees remain forbidden until this serial pilot measures
38
38
  transfer, conflict, proof, and review outcomes on both hosts; opt-in `/rite-build --parallel N`
39
- (2≤N≤3) path-disjoint fan-out is the only sanctioned parallel mode. Same-worktree multi-writer / root-emulated
39
+ (2≤N≤10) path-disjoint fan-out is the only sanctioned parallel mode. Same-worktree multi-writer / root-emulated
40
40
  worktrees stay forbidden.
41
41
 
42
42
  ## Prepare
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: rite-build
3
- description: Build the next approved vertical slice with evidence. HITL one-slice default; AFK may chain serially; opt-in `--parallel N` (2≤N≤3) for path-disjoint worktrees.
3
+ description: Build the next approved vertical slice with evidence. HITL one-slice default; AFK may chain serially; opt-in `--parallel N` (2≤N≤10) for path-disjoint worktrees.
4
4
  argument-hint: "[--parallel N] [slice number or name]"
5
5
  user-invocable: true
6
6
  ---
@@ -10,7 +10,7 @@ user-invocable: true
10
10
  Build and prove one slice. HITL stops; a later user invocation starts the next.
11
11
  Explicit `.devrites/AFK` alone lets the controlling root chain pending slices
12
12
  serially under green proof, caps, and pause rules. Every wright returns after one slice.
13
- **Opt-in:** `/rite-build --parallel N` (2≤N≤3; N=1≡serial) follows
13
+ **Opt-in:** `/rite-build --parallel N` (2≤N≤10; N=1≡serial) follows
14
14
  [`reference/parallel-batch.md`](reference/parallel-batch.md)
15
15
  ([`one-slice-cycle.md`](reference/one-slice-cycle.md)).
16
16
 
@@ -55,9 +55,11 @@ Wright applies anti-slop; root verifies returns and never patches source.
55
55
  <!-- workflow-artifact-adapter: {"module":"devrites-lib/reference/standards/workflow-artifacts.md","entry":"Vet-ready admitted bytes require root authorship outside product wright","action":"ROOT_TRANSACTION; root writes only admitted .devrites/** targets","return":"saved Build slice cursor; wright product allowlist unchanged"} -->
56
56
  ## `--parallel N` (opt-in)
57
57
 
58
- Omitted/`1` ≡ serial; `2`/`3` → path-disjoint fan-out when eligible; else hard refuse.
59
- All-green serial integrate; one red/gap aborts. AFK charges after integrate only.
60
- Running lease blocks another `/rite-build`. Details: `parallel-batch.md`.
58
+ Omitted/`1` ≡ serial; `2`–`10` → path-disjoint fan-out when eligible; else hard refuse.
59
+ All-green serial integrate; one red/gap aborts. Abort with agent-owned plan
60
+ gaps continues via Spec Drift Guard (plan repair + vet inline); do not emit a
61
+ human `Fix`. AFK charges after integrate only. Running lease blocks another
62
+ `/rite-build`. Details: `parallel-batch.md`.
61
63
 
62
64
  ## Execute and reply
63
65
 
@@ -3,7 +3,7 @@
3
3
  One wright dispatch builds one thin, proven slice. HITL stops; only explicit
4
4
  `.devrites/AFK` lets the controlling root chain another pending slice under the
5
5
  green-proof, cap, and pause rules. Each wright returns after exactly one slice.
6
- Opt-in fan-out: [`parallel-batch.md`](parallel-batch.md) (`--parallel N`); this is default.
6
+ This serial cycle is the default `/rite-build`. Opt-in fan-out: [`parallel-batch.md`](parallel-batch.md) (`--parallel N`).
7
7
 
8
8
  ## The cycle
9
9
 
@@ -38,8 +38,10 @@ you check yourself against: anything outside it is scope creep or a drift event.
38
38
 
39
39
  ## When the slice can't be completed cleanly
40
40
 
41
- - Discovered the plan is wrong → **Spec Drift Guard** (stop, record, classify, maybe
42
- ask, `/rite-plan` repair).
43
- - Slice is bigger than one cycle → stop and `/rite-plan reslice`.
44
- - Blocked on a failing dependency → record in `state.md`, `/rite-plan unblock`.
41
+ - Discovered the plan is wrong → **Spec Drift Guard** (record, classify;
42
+ agent-owned repair+vet inline; ask only for product/policy/irreversible-risk).
43
+ - Slice is bigger than one cycle → `/rite-plan reslice` inline when AC is
44
+ preserved; do not emit a human Fix.
45
+ - Blocked on a failing dependency → record in `state.md`, `/rite-plan unblock`
46
+ inline when the reroute is technical.
45
47
  Never power through by guessing.
@@ -7,12 +7,13 @@ Opt-in only. Default `/rite-build` stays [`one-slice-cycle.md`](one-slice-cycle.
7
7
  | Input | Behavior |
8
8
  | --- | --- |
9
9
  | omitted / `--parallel 1` | Serial one-slice |
10
- | `--parallel N` (**2≤N≤3**) | Parallel when eligible + host pass |
11
- | non-integer / `N≤0` / `N>3` | Hard refuse (no silent clamp) |
10
+ | `--parallel N` (**2≤N≤10**) | Parallel when eligible + host pass |
11
+ | non-integer / `N≤0` / `N>10` | Hard refuse (no silent clamp) |
12
12
 
13
13
  AFK caps `N` by remaining budget. Charge **only after successful integrate**
14
- (once per integrated green sibling). Abort / integrate-failed → **0**. Running
15
- lease blocks another `/rite-build`.
14
+ (once per integrated green sibling). Abort / integrate-failed → **0**. A
15
+ `running` lease blocks another `/rite-build`. Any present lease blocks
16
+ `parallel create` until cleanup.
16
17
 
17
18
  ## Path-disjoint
18
19
 
@@ -40,14 +41,19 @@ Lease: `batch_id`, `created_at`, `base_sha`, `n`,
40
41
 
41
42
  1. Orient/gate; parse N; select ≤N path-disjoint pending slices.
42
43
  2. Write lease; freeze `B=HEAD`; `parallel create` worktrees.
43
- 3. Dispatch ≤3 wrights in parallel (cwd=worktree; allowlist; prove `HEAD==B`).
44
- 4. Inspect + fail-on-red → `green|red|gap`.
44
+ 3. Dispatch ≤10 wrights in parallel (cwd=worktree; allowlist; prove `HEAD==B`).
45
+ 4. Inspect + fail-on-red → `green|red|gap`. Independent-review Critical is `gap`
46
+ even when targeted tests are green.
45
47
  5. Any red/gap → **abort** (no partial integrate). All green → serial integrate.
46
48
  6. Integrate: `transfer_commit` descends from `B`; `` `<base>..<transfer>` ``
47
49
  path-exact; apply in plan order. Conflict → reset to `B`, `integrate-failed`.
48
50
  7. Success: FF control; union `touched-files.md`; update state/evidence; AFK +1
49
51
  per integrated sibling; optional `check candidate`.
50
- 8. Cleanup: success removes worktrees/branches; abort keeps until acknowledged.
52
+ 8. Cleanup: success removes worktrees/branches. Abort keeps them as repair
53
+ inputs until the root consumes them: agent-owned plan gaps (AC unchanged)
54
+ follow [`spec-drift-guard.md`](spec-drift-guard.md) — `/rite-plan repair` then
55
+ `/rite-vet` inline, then cleanup and resume Build. Do not emit
56
+ `Fix: /rite-plan repair`. Product/policy/irreversible-risk still stops.
51
57
 
52
58
  ## Engine verbs
53
59
 
@@ -3,6 +3,7 @@
3
3
  See [`one-slice-cycle.md`](one-slice-cycle.md); candidate lifecycle is
4
4
  [`candidate-integrity.md`](../../devrites-lib/reference/candidate-integrity.md).
5
5
  Opt-in `--parallel N` uses [`parallel-batch.md`](parallel-batch.md) instead of steps 2–8.
6
+ Spec Drift Guard still applies on abort or plan-gap.
6
7
 
7
8
  1. **Orient and gate.** Read core, `.devrites/ACTIVE`, `state.md`, and required
8
9
  slice artifacts. Require `Implementation readiness: READY`, its current
@@ -36,7 +36,7 @@ Conflict, extra/missing commit, moved base, or cleanup failure is `gap`/STOP:
36
36
  preserve the worktree and commit. Without explicit reconciliation, use same-worktree serial.
37
37
  Parallel isolated-writer worktrees remain forbidden until this serial pilot measures
38
38
  transfer, conflict, proof, and review outcomes on both hosts; opt-in `/rite-build --parallel N`
39
- (2≤N≤3) path-disjoint fan-out is the only sanctioned parallel mode. Same-worktree multi-writer / root-emulated
39
+ (2≤N≤10) path-disjoint fan-out is the only sanctioned parallel mode. Same-worktree multi-writer / root-emulated
40
40
  worktrees stay forbidden.
41
41
 
42
42
  ## Prepare
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: rite-build
3
- description: Build the next approved vertical slice with evidence. HITL one-slice default; AFK may chain serially; opt-in `--parallel N` (2≤N≤3) for path-disjoint worktrees.
3
+ description: Build the next approved vertical slice with evidence. HITL one-slice default; AFK may chain serially; opt-in `--parallel N` (2≤N≤10) for path-disjoint worktrees.
4
4
  argument-hint: "[--parallel N] [slice number or name]"
5
5
  user-invocable: true
6
6
  ---
@@ -10,7 +10,7 @@ user-invocable: true
10
10
  Build and prove one slice. HITL stops; a later user invocation starts the next.
11
11
  Explicit `.devrites/AFK` alone lets the controlling root chain pending slices
12
12
  serially under green proof, caps, and pause rules. Every wright returns after one slice.
13
- **Opt-in:** `$rite-build --parallel N` (2≤N≤3; N=1≡serial) follows
13
+ **Opt-in:** `$rite-build --parallel N` (2≤N≤10; N=1≡serial) follows
14
14
  [`reference/parallel-batch.md`](reference/parallel-batch.md)
15
15
  ([`one-slice-cycle.md`](reference/one-slice-cycle.md)).
16
16
 
@@ -55,9 +55,11 @@ Wright applies anti-slop; root verifies returns and never patches source.
55
55
  <!-- workflow-artifact-adapter: {"module":"devrites-lib/reference/standards/workflow-artifacts.md","entry":"Vet-ready admitted bytes require root authorship outside product wright","action":"ROOT_TRANSACTION; root writes only admitted .devrites/** targets","return":"saved Build slice cursor; wright product allowlist unchanged"} -->
56
56
  ## `--parallel N` (opt-in)
57
57
 
58
- Omitted/`1` ≡ serial; `2`/`3` → path-disjoint fan-out when eligible; else hard refuse.
59
- All-green serial integrate; one red/gap aborts. AFK charges after integrate only.
60
- Running lease blocks another `$rite-build`. Details: `parallel-batch.md`.
58
+ Omitted/`1` ≡ serial; `2`–`10` → path-disjoint fan-out when eligible; else hard refuse.
59
+ All-green serial integrate; one red/gap aborts. Abort with agent-owned plan
60
+ gaps continues via Spec Drift Guard (plan repair + vet inline); do not emit a
61
+ human `Fix`. AFK charges after integrate only. Running lease blocks another
62
+ `$rite-build`. Details: `parallel-batch.md`.
61
63
 
62
64
  ## Execute and reply
63
65
 
@@ -3,7 +3,7 @@
3
3
  One wright dispatch builds one thin, proven slice. HITL stops; only explicit
4
4
  `.devrites/AFK` lets the controlling root chain another pending slice under the
5
5
  green-proof, cap, and pause rules. Each wright returns after exactly one slice.
6
- Opt-in fan-out: [`parallel-batch.md`](parallel-batch.md) (`--parallel N`); this is default.
6
+ This serial cycle is the default `$rite-build`. Opt-in fan-out: [`parallel-batch.md`](parallel-batch.md) (`--parallel N`).
7
7
 
8
8
  ## The cycle
9
9
 
@@ -38,8 +38,10 @@ you check yourself against: anything outside it is scope creep or a drift event.
38
38
 
39
39
  ## When the slice can't be completed cleanly
40
40
 
41
- - Discovered the plan is wrong → **Spec Drift Guard** (stop, record, classify, maybe
42
- ask, `$rite-plan` repair).
43
- - Slice is bigger than one cycle → stop and `$rite-plan reslice`.
44
- - Blocked on a failing dependency → record in `state.md`, `$rite-plan unblock`.
41
+ - Discovered the plan is wrong → **Spec Drift Guard** (record, classify;
42
+ agent-owned repair+vet inline; ask only for product/policy/irreversible-risk).
43
+ - Slice is bigger than one cycle → `$rite-plan reslice` inline when AC is
44
+ preserved; do not emit a human Fix.
45
+ - Blocked on a failing dependency → record in `state.md`, `$rite-plan unblock`
46
+ inline when the reroute is technical.
45
47
  Never power through by guessing.
@@ -7,12 +7,13 @@ Opt-in only. Default `$rite-build` stays [`one-slice-cycle.md`](one-slice-cycle.
7
7
  | Input | Behavior |
8
8
  | --- | --- |
9
9
  | omitted / `--parallel 1` | Serial one-slice |
10
- | `--parallel N` (**2≤N≤3**) | Parallel when eligible + host pass |
11
- | non-integer / `N≤0` / `N>3` | Hard refuse (no silent clamp) |
10
+ | `--parallel N` (**2≤N≤10**) | Parallel when eligible + host pass |
11
+ | non-integer / `N≤0` / `N>10` | Hard refuse (no silent clamp) |
12
12
 
13
13
  AFK caps `N` by remaining budget. Charge **only after successful integrate**
14
- (once per integrated green sibling). Abort / integrate-failed → **0**. Running
15
- lease blocks another `$rite-build`.
14
+ (once per integrated green sibling). Abort / integrate-failed → **0**. A
15
+ `running` lease blocks another `$rite-build`. Any present lease blocks
16
+ `parallel create` until cleanup.
16
17
 
17
18
  ## Path-disjoint
18
19
 
@@ -40,14 +41,19 @@ Lease: `batch_id`, `created_at`, `base_sha`, `n`,
40
41
 
41
42
  1. Orient/gate; parse N; select ≤N path-disjoint pending slices.
42
43
  2. Write lease; freeze `B=HEAD`; `parallel create` worktrees.
43
- 3. Dispatch ≤3 wrights in parallel (cwd=worktree; allowlist; prove `HEAD==B`).
44
- 4. Inspect + fail-on-red → `green|red|gap`.
44
+ 3. Dispatch ≤10 wrights in parallel (cwd=worktree; allowlist; prove `HEAD==B`).
45
+ 4. Inspect + fail-on-red → `green|red|gap`. Independent-review Critical is `gap`
46
+ even when targeted tests are green.
45
47
  5. Any red/gap → **abort** (no partial integrate). All green → serial integrate.
46
48
  6. Integrate: `transfer_commit` descends from `B`; `` `<base>..<transfer>` ``
47
49
  path-exact; apply in plan order. Conflict → reset to `B`, `integrate-failed`.
48
50
  7. Success: FF control; union `touched-files.md`; update state/evidence; AFK +1
49
51
  per integrated sibling; optional `check candidate`.
50
- 8. Cleanup: success removes worktrees/branches; abort keeps until acknowledged.
52
+ 8. Cleanup: success removes worktrees/branches. Abort keeps them as repair
53
+ inputs until the root consumes them: agent-owned plan gaps (AC unchanged)
54
+ follow [`spec-drift-guard.md`](spec-drift-guard.md) — `$rite-plan repair` then
55
+ `$rite-vet` inline, then cleanup and resume Build. Do not emit
56
+ `Fix: $rite-plan repair`. Product/policy/irreversible-risk still stops.
51
57
 
52
58
  ## Engine verbs
53
59
 
@@ -3,6 +3,7 @@
3
3
  See [`one-slice-cycle.md`](one-slice-cycle.md); candidate lifecycle is
4
4
  [`candidate-integrity.md`](../../devrites-lib/reference/candidate-integrity.md).
5
5
  Opt-in `--parallel N` uses [`parallel-batch.md`](parallel-batch.md) instead of steps 2–8.
6
+ Spec Drift Guard still applies on abort or plan-gap.
6
7
 
7
8
  1. **Orient and gate.** Read core, `.devrites/ACTIVE`, `state.md`, and required
8
9
  slice artifacts. Require `Implementation readiness: READY`, its current
@@ -36,7 +36,7 @@ Conflict, extra/missing commit, moved base, or cleanup failure is `gap`/STOP:
36
36
  preserve the worktree and commit. Without explicit reconciliation, use same-worktree serial.
37
37
  Parallel isolated-writer worktrees remain forbidden until this serial pilot measures
38
38
  transfer, conflict, proof, and review outcomes on both hosts; opt-in `$rite-build --parallel N`
39
- (2≤N≤3) path-disjoint fan-out is the only sanctioned parallel mode. Same-worktree multi-writer / root-emulated
39
+ (2≤N≤10) path-disjoint fan-out is the only sanctioned parallel mode. Same-worktree multi-writer / root-emulated
40
40
  worktrees stay forbidden.
41
41
 
42
42
  ## Prepare
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: rite-build
3
- description: Build the next approved vertical slice with evidence. HITL one-slice default; AFK may chain serially; opt-in `--parallel N` (2≤N≤3) for path-disjoint worktrees.
3
+ description: Build the next approved vertical slice with evidence. HITL one-slice default; AFK may chain serially; opt-in `--parallel N` (2≤N≤10) for path-disjoint worktrees.
4
4
  argument-hint: "[--parallel N] [slice number or name]"
5
5
  user-invocable: true
6
6
  ---
@@ -10,7 +10,7 @@ user-invocable: true
10
10
  Build and prove one slice. HITL stops; a later user invocation starts the next.
11
11
  Explicit `.devrites/AFK` alone lets the controlling root chain pending slices
12
12
  serially under green proof, caps, and pause rules. Every wright returns after one slice.
13
- **Opt-in:** `/rite-build --parallel N` (2≤N≤3; N=1≡serial) follows
13
+ **Opt-in:** `/rite-build --parallel N` (2≤N≤10; N=1≡serial) follows
14
14
  [`reference/parallel-batch.md`](reference/parallel-batch.md)
15
15
  ([`one-slice-cycle.md`](reference/one-slice-cycle.md)).
16
16
 
@@ -55,9 +55,11 @@ Wright applies anti-slop; root verifies returns and never patches source.
55
55
  <!-- workflow-artifact-adapter: {"module":"devrites-lib/reference/standards/workflow-artifacts.md","entry":"Vet-ready admitted bytes require root authorship outside product wright","action":"ROOT_TRANSACTION; root writes only admitted .devrites/** targets","return":"saved Build slice cursor; wright product allowlist unchanged"} -->
56
56
  ## `--parallel N` (opt-in)
57
57
 
58
- Omitted/`1` ≡ serial; `2`/`3` → path-disjoint fan-out when eligible; else hard refuse.
59
- All-green serial integrate; one red/gap aborts. AFK charges after integrate only.
60
- Running lease blocks another `/rite-build`. Details: `parallel-batch.md`.
58
+ Omitted/`1` ≡ serial; `2`–`10` → path-disjoint fan-out when eligible; else hard refuse.
59
+ All-green serial integrate; one red/gap aborts. Abort with agent-owned plan
60
+ gaps continues via Spec Drift Guard (plan repair + vet inline); do not emit a
61
+ human `Fix`. AFK charges after integrate only. Running lease blocks another
62
+ `/rite-build`. Details: `parallel-batch.md`.
61
63
 
62
64
  ## Execute and reply
63
65
 
@@ -3,7 +3,7 @@
3
3
  One wright dispatch builds one thin, proven slice. HITL stops; only explicit
4
4
  `.devrites/AFK` lets the controlling root chain another pending slice under the
5
5
  green-proof, cap, and pause rules. Each wright returns after exactly one slice.
6
- Opt-in fan-out: [`parallel-batch.md`](parallel-batch.md) (`--parallel N`); this is default.
6
+ This serial cycle is the default `/rite-build`. Opt-in fan-out: [`parallel-batch.md`](parallel-batch.md) (`--parallel N`).
7
7
 
8
8
  ## The cycle
9
9
 
@@ -38,8 +38,10 @@ you check yourself against: anything outside it is scope creep or a drift event.
38
38
 
39
39
  ## When the slice can't be completed cleanly
40
40
 
41
- - Discovered the plan is wrong → **Spec Drift Guard** (stop, record, classify, maybe
42
- ask, `/rite-plan` repair).
43
- - Slice is bigger than one cycle → stop and `/rite-plan reslice`.
44
- - Blocked on a failing dependency → record in `state.md`, `/rite-plan unblock`.
41
+ - Discovered the plan is wrong → **Spec Drift Guard** (record, classify;
42
+ agent-owned repair+vet inline; ask only for product/policy/irreversible-risk).
43
+ - Slice is bigger than one cycle → `/rite-plan reslice` inline when AC is
44
+ preserved; do not emit a human Fix.
45
+ - Blocked on a failing dependency → record in `state.md`, `/rite-plan unblock`
46
+ inline when the reroute is technical.
45
47
  Never power through by guessing.
@@ -7,12 +7,13 @@ Opt-in only. Default `/rite-build` stays [`one-slice-cycle.md`](one-slice-cycle.
7
7
  | Input | Behavior |
8
8
  | --- | --- |
9
9
  | omitted / `--parallel 1` | Serial one-slice |
10
- | `--parallel N` (**2≤N≤3**) | Parallel when eligible + host pass |
11
- | non-integer / `N≤0` / `N>3` | Hard refuse (no silent clamp) |
10
+ | `--parallel N` (**2≤N≤10**) | Parallel when eligible + host pass |
11
+ | non-integer / `N≤0` / `N>10` | Hard refuse (no silent clamp) |
12
12
 
13
13
  AFK caps `N` by remaining budget. Charge **only after successful integrate**
14
- (once per integrated green sibling). Abort / integrate-failed → **0**. Running
15
- lease blocks another `/rite-build`.
14
+ (once per integrated green sibling). Abort / integrate-failed → **0**. A
15
+ `running` lease blocks another `/rite-build`. Any present lease blocks
16
+ `parallel create` until cleanup.
16
17
 
17
18
  ## Path-disjoint
18
19
 
@@ -40,14 +41,19 @@ Lease: `batch_id`, `created_at`, `base_sha`, `n`,
40
41
 
41
42
  1. Orient/gate; parse N; select ≤N path-disjoint pending slices.
42
43
  2. Write lease; freeze `B=HEAD`; `parallel create` worktrees.
43
- 3. Dispatch ≤3 wrights in parallel (cwd=worktree; allowlist; prove `HEAD==B`).
44
- 4. Inspect + fail-on-red → `green|red|gap`.
44
+ 3. Dispatch ≤10 wrights in parallel (cwd=worktree; allowlist; prove `HEAD==B`).
45
+ 4. Inspect + fail-on-red → `green|red|gap`. Independent-review Critical is `gap`
46
+ even when targeted tests are green.
45
47
  5. Any red/gap → **abort** (no partial integrate). All green → serial integrate.
46
48
  6. Integrate: `transfer_commit` descends from `B`; `` `<base>..<transfer>` ``
47
49
  path-exact; apply in plan order. Conflict → reset to `B`, `integrate-failed`.
48
50
  7. Success: FF control; union `touched-files.md`; update state/evidence; AFK +1
49
51
  per integrated sibling; optional `check candidate`.
50
- 8. Cleanup: success removes worktrees/branches; abort keeps until acknowledged.
52
+ 8. Cleanup: success removes worktrees/branches. Abort keeps them as repair
53
+ inputs until the root consumes them: agent-owned plan gaps (AC unchanged)
54
+ follow [`spec-drift-guard.md`](spec-drift-guard.md) — `/rite-plan repair` then
55
+ `/rite-vet` inline, then cleanup and resume Build. Do not emit
56
+ `Fix: /rite-plan repair`. Product/policy/irreversible-risk still stops.
51
57
 
52
58
  ## Engine verbs
53
59
 
@@ -3,6 +3,7 @@
3
3
  See [`one-slice-cycle.md`](one-slice-cycle.md); candidate lifecycle is
4
4
  [`candidate-integrity.md`](../../devrites-lib/reference/candidate-integrity.md).
5
5
  Opt-in `--parallel N` uses [`parallel-batch.md`](parallel-batch.md) instead of steps 2–8.
6
+ Spec Drift Guard still applies on abort or plan-gap.
6
7
 
7
8
  1. **Orient and gate.** Read core, `.devrites/ACTIVE`, `state.md`, and required
8
9
  slice artifacts. Require `Implementation readiness: READY`, its current
@@ -36,7 +36,7 @@ Conflict, extra/missing commit, moved base, or cleanup failure is `gap`/STOP:
36
36
  preserve the worktree and commit. Without explicit reconciliation, use same-worktree serial.
37
37
  Parallel isolated-writer worktrees remain forbidden until this serial pilot measures
38
38
  transfer, conflict, proof, and review outcomes on both hosts; opt-in `/rite-build --parallel N`
39
- (2≤N≤3) path-disjoint fan-out is the only sanctioned parallel mode. Same-worktree multi-writer / root-emulated
39
+ (2≤N≤10) path-disjoint fan-out is the only sanctioned parallel mode. Same-worktree multi-writer / root-emulated
40
40
  worktrees stay forbidden.
41
41
 
42
42
  ## Prepare
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devrites",
3
- "version": "5.0.0",
3
+ "version": "5.1.0",
4
4
  "description": "DevRites: a disciplined senior-engineer workflow pack for Claude Code and Codex",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://github.com/ViktorsBaikers/DevRites#readme",
@@ -84,6 +84,7 @@
84
84
  "@semantic-release/npm": {
85
85
  "npm": "11.19.1"
86
86
  },
87
- "fast-uri": "3.1.6"
87
+ "fast-uri": "3.1.6",
88
+ "js-yaml": "4.3.2"
88
89
  }
89
90
  }