devrites 6.1.5 → 6.2.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 (24) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/engine/help.go +1 -1
  4. package/engine/internal/lib/dispatch.go +12 -5
  5. package/engine/internal/lib/dispatch_contract.go +51 -0
  6. package/pack/.claude/skills/rite-build/SKILL.md +2 -2
  7. package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +3 -1
  8. package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +8 -4
  9. package/pack/generated/claude/skills/rite-build/SKILL.md +2 -2
  10. package/pack/generated/claude/skills/rite-build/reference/one-slice-cycle.md +3 -1
  11. package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +8 -4
  12. package/pack/generated/codex/skills/rite-build/SKILL.md +2 -2
  13. package/pack/generated/codex/skills/rite-build/reference/one-slice-cycle.md +3 -1
  14. package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +8 -4
  15. package/pack/generated/devin/skills/rite-build/SKILL.md +2 -2
  16. package/pack/generated/devin/skills/rite-build/reference/one-slice-cycle.md +3 -1
  17. package/pack/generated/devin/skills/rite-build/reference/wright-dispatch.md +8 -4
  18. package/pack/generated/omp/skills/rite-build/SKILL.md +2 -2
  19. package/pack/generated/omp/skills/rite-build/reference/one-slice-cycle.md +3 -1
  20. package/pack/generated/omp/skills/rite-build/reference/wright-dispatch.md +8 -4
  21. package/pack/generated/pi/skills/rite-build/SKILL.md +2 -2
  22. package/pack/generated/pi/skills/rite-build/reference/one-slice-cycle.md +3 -1
  23. package/pack/generated/pi/skills/rite-build/reference/wright-dispatch.md +8 -4
  24. package/package.json +1 -1
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
+ ## [6.2.0](https://github.com/ViktorsBaikers/DevRites/compare/v6.1.5...v6.2.0) (2026-10-16)
6
+
7
+ ### Added
8
+
9
+ * **devrites:** lint wright contracts at dispatch open ([#112](https://github.com/ViktorsBaikers/DevRites/issues/112)) ([391a931](https://github.com/ViktorsBaikers/DevRites/commit/391a9317dba9f00941ed29c48cc1f3f2ae8551c4))
10
+
5
11
  ## [6.1.5](https://github.com/ViktorsBaikers/DevRites/compare/v6.1.4...v6.1.5) (2026-10-16)
6
12
 
7
13
  ### Fixed
package/README.md CHANGED
@@ -31,7 +31,7 @@ history can't lose it. After you clear the conversation, switch hosts, or hand
31
31
  the feature to another engineer, the next session reads the same plan,
32
32
  decisions, and evidence before it continues.
33
33
 
34
- **Status:** [`v6.1.5`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v6.1.5): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
34
+ **Status:** [`v6.2.0`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v6.2.0): 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/engine/help.go CHANGED
@@ -58,7 +58,7 @@ const (
58
58
  metrics record <slug> --phase <p> --event <e> [--role r] [--bytes n] [--note s]
59
59
  metrics summary [slug] [--by-slice]
60
60
  `
61
- dispatchUsage = `usage: devrites-engine dispatch <slug> <open|start|seal|return|status|abandon> [--phase p] [--wave w] [--role r] [--handle h] [--reason s] [--slice SLICE-###] [--reslice-review <DRIFT-ID>]`
61
+ dispatchUsage = `usage: devrites-engine dispatch <slug> <open|start|seal|return|status|abandon> [--phase p] [--wave w] [--role r] [--handle h] [--reason s] [--slice SLICE-###] [--reslice-review <DRIFT-ID>] [--contract <file>]`
62
62
  claimUsageText = `usage: devrites-engine claim <add|release|list|check> ...
63
63
 
64
64
  claim add --session <id> [--ttl <minutes>] [--reason <s>] <path>...
@@ -21,9 +21,9 @@ import (
21
21
  // fan-out cannot silently degrade to serial (open -> every role started ->
22
22
  // seal -> returns -> complete). start/return also auto-record metrics events.
23
23
  //
24
- // devrites-engine dispatch <slug> <sub> [--phase p] [--wave w] [--role r] [--handle h] [--reason s] [--slice SLICE-###] [--reslice-review <DRIFT-ID>]
24
+ // devrites-engine dispatch <slug> <sub> [--phase p] [--wave w] [--role r] [--handle h] [--reason s] [--slice SLICE-###] [--reslice-review <DRIFT-ID>] [--contract <file>]
25
25
 
26
- const dispatchUsage = `usage: devrites-engine dispatch <slug> <open|start|seal|return|status|abandon> [--phase p] [--wave w] [--role r] [--handle h] [--reason s] [--slice SLICE-###] [--reslice-review <DRIFT-ID>]
26
+ const dispatchUsage = `usage: devrites-engine dispatch <slug> <open|start|seal|return|status|abandon> [--phase p] [--wave w] [--role r] [--handle h] [--reason s] [--slice SLICE-###] [--reslice-review <DRIFT-ID>] [--contract <file>]
27
27
 
28
28
  Wave barrier for parallel agent dispatch: seal fails until every declared
29
29
  role has a distinct handle; return fails before seal. status --wave exits
@@ -117,7 +117,7 @@ func nowStamp() string { return time.Now().UTC().Format(time.RFC3339) }
117
117
 
118
118
  // RunDispatch implements the dispatch wave state machine.
119
119
  func RunDispatch(root string, args []string, stdout, stderr io.Writer) int {
120
- var slug, sub, phase, wave, role, handle, reason, review string
120
+ var slug, sub, phase, wave, role, handle, reason, review, contract string
121
121
  var roles, sliceIDs []string
122
122
  var positional []string
123
123
  for i := 0; i < len(args); i++ {
@@ -138,6 +138,8 @@ func RunDispatch(root string, args []string, stdout, stderr io.Writer) int {
138
138
  sliceIDs = append(sliceIDs, value)
139
139
  case "--reslice-review":
140
140
  review = value
141
+ case "--contract":
142
+ contract = value
141
143
  default:
142
144
  if strings.HasPrefix(args[i], "-") {
143
145
  fmt.Fprintf(stderr, "dispatch: unknown flag %q\n", args[i])
@@ -161,7 +163,7 @@ func RunDispatch(root string, args []string, stdout, stderr io.Writer) int {
161
163
  // an update and strand the wave short of complete.
162
164
  code := 0
163
165
  if err := state.WithFeatureLock(root, slug, func() error {
164
- code = dispatchLocked(root, slug, sub, phase, wave, role, handle, reason, roles, sliceIDs, review, stdout, stderr)
166
+ code = dispatchLocked(root, slug, sub, phase, wave, role, handle, reason, roles, sliceIDs, review, contract, stdout, stderr)
165
167
  return nil
166
168
  }); err != nil {
167
169
  fmt.Fprintf(stderr, "dispatch: %v\n", err)
@@ -170,7 +172,7 @@ func RunDispatch(root string, args []string, stdout, stderr io.Writer) int {
170
172
  return code
171
173
  }
172
174
 
173
- func dispatchLocked(root, slug, sub, phase, wave, role, handle, reason string, roles, sliceIDs []string, review string, stdout, stderr io.Writer) int {
175
+ func dispatchLocked(root, slug, sub, phase, wave, role, handle, reason string, roles, sliceIDs []string, review, contract string, stdout, stderr io.Writer) int {
174
176
  f, path, err := loadDispatch(root, slug)
175
177
  if err != nil {
176
178
  fmt.Fprintf(stderr, "dispatch: %v\n", err)
@@ -209,6 +211,11 @@ func dispatchLocked(root, slug, sub, phase, wave, role, handle, reason string, r
209
211
  if code != 0 {
210
212
  return code
211
213
  }
214
+ if isBuildWrightWave(w) {
215
+ if err := lintWrightContract(contract); err != nil {
216
+ return fail("BLOCKED: %v", err)
217
+ }
218
+ }
212
219
  f.Waves[wave] = w
213
220
  if err := saveDispatch(path, f); err != nil {
214
221
  return fail("%v", err)
@@ -0,0 +1,51 @@
1
+ package lib
2
+
3
+ import (
4
+ "fmt"
5
+ "regexp"
6
+ "strings"
7
+ )
8
+
9
+ // maxContractBytes bounds a wright contract read; packets stay <= 64 KiB.
10
+ const maxContractBytes = 64 << 10
11
+
12
+ var (
13
+ // writerSafeLineRE is the contract line that names the checks the wright
14
+ // itself runs before returning.
15
+ writerSafeLineRE = regexp.MustCompile(`(?im)^[\s>*#-]*writer-safe checks\s*:\s*\S`)
16
+ // forbidExecutionRE catches contract text that leaves the wright blind:
17
+ // "skip tests", "no tests/build", "do not run any checks", "run nothing".
18
+ forbidExecutionRE = regexp.MustCompile(`(?i)\bskip(?:s|ping)?\s+(?:all\s+|the\s+)?(?:builds?|lint|tests?|testing|checks?|formatters?)\b` +
19
+ `|\bno\s+(?:leaf\s+)?(?:tests?|test\s+commands?|builds?|lint|execution|checks?)\b` +
20
+ `|\b(?:do\s+not|don't|never)\s+run\s+(?:any\s+)?(?:tests?|checks?|builds?|lint|commands?)\b` +
21
+ `|\brun\s+nothing\b`)
22
+ // allowedAfterRE marks a forbid match that is about not weakening tests,
23
+ // not about skipping their execution ("no tests weakened or deleted").
24
+ allowedAfterRE = regexp.MustCompile(`(?i)^[\s/,a-z-]{0,24}\b(?:weaken|delet|remov|disabl|skipp|xfail|loosen)`)
25
+ )
26
+
27
+ // lintWrightContract refuses a build wright contract that forbids the wright's
28
+ // own writer-safe verification or names none, so a blind round is rejected
29
+ // before launch rather than discovered after the wright returns.
30
+ func lintWrightContract(path string) error {
31
+ if path == "" {
32
+ return fmt.Errorf("a build wright wave needs --contract <file> holding the exact wright contract (with a `Writer-safe checks:` line)")
33
+ }
34
+ raw, err := readBoundedRegularFile(path, maxContractBytes)
35
+ if err != nil {
36
+ return fmt.Errorf("wright contract %s: %w", path, err)
37
+ }
38
+ for i, line := range strings.Split(string(raw), "\n") {
39
+ for _, loc := range forbidExecutionRE.FindAllStringIndex(line, -1) {
40
+ if allowedAfterRE.MatchString(line[loc[1]:]) {
41
+ continue
42
+ }
43
+ return fmt.Errorf("wright contract %s:%d forbids writer-safe execution (%q); the wright runs syntax/type/lint, unit and self-check suites and a narrow local smoke itself — list them under `Writer-safe checks:` and keep only artifact-producing, consumptive, or full canonical gates root-owned",
44
+ path, i+1, strings.TrimSpace(line[loc[0]:loc[1]]))
45
+ }
46
+ }
47
+ if !writerSafeLineRE.Match(raw) {
48
+ return fmt.Errorf("wright contract %s names no `Writer-safe checks:` line; list the syntax/type/lint, unit/self-check and narrow smoke commands the wright runs before returning", path)
49
+ }
50
+ return nil
51
+ }
@@ -29,8 +29,8 @@ Execute [`reference/phase-contract.md`](reference/phase-contract.md)
29
29
  [`reference/wright-dispatch.md`](reference/wright-dispatch.md).
30
30
  Every wright contract names the writer-safe checks the wright runs (syntax/type/lint,
31
31
  unit and self-check suites, a narrow local smoke) and never forbids them; only
32
- artifact-producing, consumptive, or full canonical gates stay root-owned.
33
- Prior contracts in `evidence.md` are not a template for this. **Failing case:** the
32
+ artifact-producing, consumptive, or full canonical gates stay root-owned;
33
+ `dispatch open --contract` refuses a contract that breaks this. Prior contracts in `evidence.md` are not a template for this. **Failing case:** the
34
34
  contract says "skip tests mid-flight; root runs them after return", and the wright
35
35
  returns three unit failures that a 20 s `go test` would have caught in-round.
36
36
 
@@ -23,7 +23,9 @@ DISPATCH → hand the slice contract to devrites-slice-wright (fresh context).
23
23
  (independent claims, fresh contexts); wright fixes stay serial — writers share files
24
24
  PROVE → root, concurrent with the reviews on the same frozen candidate:
25
25
  required build/browser/E2E (narrow self-check/smoke first, full gate only
26
- after it is green, long runs in the background), then returned-diff/path recheck; fail-on-red
26
+ after it is green, long runs in the background; cancel one still running once
27
+ review or proof sends the candidate back, keeping its partial output as
28
+ diagnostics), then returned-diff/path recheck; fail-on-red
27
29
  (red/gap → repair wright, then re-review and re-prove; do not commit yet)
28
30
  RECORD → orchestrator: after green verification, update state.md/evidence.md and
29
31
  upsert the authoritative candidate manifest from the actual scoped diff
@@ -94,10 +94,14 @@ claim add --session <id> <task-paths>`; retain its returned `<claim-id>`, then r
94
94
  live foreign session releases the retained claim and stops the dispatch, per
95
95
  [`agents.md`](../../devrites-lib/reference/standards/agents.md). `.devrites/**`
96
96
  is never a task path; see [Workflow Artifact admission](../../devrites-lib/reference/standards/workflow-artifacts.md).
97
- Ask the host
98
- for the exact writer in fresh context and wait. Track it through the
99
- launch barrier — `devrites-engine dispatch <slug> open --phase build --wave
100
- <slice-id> --role slice-wright --slice <SLICE-ID>`, then `start` with the host handle, `seal`, and
97
+ Write the exact contract, with its `Writer-safe checks:` line, to
98
+ `packets/<wave>.contract.md` and hand the wright that text verbatim. Ask the host
99
+ for the exact writer in fresh context; a repair round on the same slice whose
100
+ returned wright the host can still continue goes to that wright on its existing
101
+ handle instead, so it does not re-read the slice from scratch. Wait, and track it
102
+ through the launch barrier — `devrites-engine dispatch <slug> open --phase build --wave
103
+ <slice-id> --role slice-wright --slice <SLICE-ID> --contract <file>` (it refuses a
104
+ contract that forbids writer-safe checks or names none), then `start` with the host handle, `seal`, and
101
105
  `return` on completion (auto-records dispatch/return metrics). Every 5 wright
102
106
  rounds on one slice, `open` blocks for a reslice review: propose an
103
107
  acceptance-preserving split (`root_no_change_analysis` → `FOLD` per
@@ -29,8 +29,8 @@ Execute [`reference/phase-contract.md`](reference/phase-contract.md)
29
29
  [`reference/wright-dispatch.md`](reference/wright-dispatch.md).
30
30
  Every wright contract names the writer-safe checks the wright runs (syntax/type/lint,
31
31
  unit and self-check suites, a narrow local smoke) and never forbids them; only
32
- artifact-producing, consumptive, or full canonical gates stay root-owned.
33
- Prior contracts in `evidence.md` are not a template for this. **Failing case:** the
32
+ artifact-producing, consumptive, or full canonical gates stay root-owned;
33
+ `dispatch open --contract` refuses a contract that breaks this. Prior contracts in `evidence.md` are not a template for this. **Failing case:** the
34
34
  contract says "skip tests mid-flight; root runs them after return", and the wright
35
35
  returns three unit failures that a 20 s `go test` would have caught in-round.
36
36
 
@@ -23,7 +23,9 @@ DISPATCH → hand the slice contract to devrites-slice-wright (fresh context).
23
23
  (independent claims, fresh contexts); wright fixes stay serial — writers share files
24
24
  PROVE → root, concurrent with the reviews on the same frozen candidate:
25
25
  required build/browser/E2E (narrow self-check/smoke first, full gate only
26
- after it is green, long runs in the background), then returned-diff/path recheck; fail-on-red
26
+ after it is green, long runs in the background; cancel one still running once
27
+ review or proof sends the candidate back, keeping its partial output as
28
+ diagnostics), then returned-diff/path recheck; fail-on-red
27
29
  (red/gap → repair wright, then re-review and re-prove; do not commit yet)
28
30
  RECORD → orchestrator: after green verification, update state.md/evidence.md and
29
31
  upsert the authoritative candidate manifest from the actual scoped diff
@@ -94,10 +94,14 @@ claim add --session <id> <task-paths>`; retain its returned `<claim-id>`, then r
94
94
  live foreign session releases the retained claim and stops the dispatch, per
95
95
  [`agents.md`](../../devrites-lib/reference/standards/agents.md). `.devrites/**`
96
96
  is never a task path; see [Workflow Artifact admission](../../devrites-lib/reference/standards/workflow-artifacts.md).
97
- Ask the host
98
- for the exact writer in fresh context and wait. Track it through the
99
- launch barrier — `devrites-engine dispatch <slug> open --phase build --wave
100
- <slice-id> --role slice-wright --slice <SLICE-ID>`, then `start` with the host handle, `seal`, and
97
+ Write the exact contract, with its `Writer-safe checks:` line, to
98
+ `packets/<wave>.contract.md` and hand the wright that text verbatim. Ask the host
99
+ for the exact writer in fresh context; a repair round on the same slice whose
100
+ returned wright the host can still continue goes to that wright on its existing
101
+ handle instead, so it does not re-read the slice from scratch. Wait, and track it
102
+ through the launch barrier — `devrites-engine dispatch <slug> open --phase build --wave
103
+ <slice-id> --role slice-wright --slice <SLICE-ID> --contract <file>` (it refuses a
104
+ contract that forbids writer-safe checks or names none), then `start` with the host handle, `seal`, and
101
105
  `return` on completion (auto-records dispatch/return metrics). Every 5 wright
102
106
  rounds on one slice, `open` blocks for a reslice review: propose an
103
107
  acceptance-preserving split (`root_no_change_analysis` → `FOLD` per
@@ -29,8 +29,8 @@ Execute [`reference/phase-contract.md`](reference/phase-contract.md)
29
29
  [`reference/wright-dispatch.md`](reference/wright-dispatch.md).
30
30
  Every wright contract names the writer-safe checks the wright runs (syntax/type/lint,
31
31
  unit and self-check suites, a narrow local smoke) and never forbids them; only
32
- artifact-producing, consumptive, or full canonical gates stay root-owned.
33
- Prior contracts in `evidence.md` are not a template for this. **Failing case:** the
32
+ artifact-producing, consumptive, or full canonical gates stay root-owned;
33
+ `dispatch open --contract` refuses a contract that breaks this. Prior contracts in `evidence.md` are not a template for this. **Failing case:** the
34
34
  contract says "skip tests mid-flight; root runs them after return", and the wright
35
35
  returns three unit failures that a 20 s `go test` would have caught in-round.
36
36
 
@@ -23,7 +23,9 @@ DISPATCH → hand the slice contract to devrites-slice-wright (fresh context).
23
23
  (independent claims, fresh contexts); wright fixes stay serial — writers share files
24
24
  PROVE → root, concurrent with the reviews on the same frozen candidate:
25
25
  required build/browser/E2E (narrow self-check/smoke first, full gate only
26
- after it is green, long runs in the background), then returned-diff/path recheck; fail-on-red
26
+ after it is green, long runs in the background; cancel one still running once
27
+ review or proof sends the candidate back, keeping its partial output as
28
+ diagnostics), then returned-diff/path recheck; fail-on-red
27
29
  (red/gap → repair wright, then re-review and re-prove; do not commit yet)
28
30
  RECORD → orchestrator: after green verification, update state.md/evidence.md and
29
31
  upsert the authoritative candidate manifest from the actual scoped diff
@@ -94,10 +94,14 @@ claim add --session <id> <task-paths>`; retain its returned `<claim-id>`, then r
94
94
  live foreign session releases the retained claim and stops the dispatch, per
95
95
  [`agents.md`](../../devrites-lib/reference/standards/agents.md). `.devrites/**`
96
96
  is never a task path; see [Workflow Artifact admission](../../devrites-lib/reference/standards/workflow-artifacts.md).
97
- Ask the host
98
- for the exact writer in fresh context and wait. Track it through the
99
- launch barrier — `devrites-engine dispatch <slug> open --phase build --wave
100
- <slice-id> --role slice-wright --slice <SLICE-ID>`, then `start` with the host handle, `seal`, and
97
+ Write the exact contract, with its `Writer-safe checks:` line, to
98
+ `packets/<wave>.contract.md` and hand the wright that text verbatim. Ask the host
99
+ for the exact writer in fresh context; a repair round on the same slice whose
100
+ returned wright the host can still continue goes to that wright on its existing
101
+ handle instead, so it does not re-read the slice from scratch. Wait, and track it
102
+ through the launch barrier — `devrites-engine dispatch <slug> open --phase build --wave
103
+ <slice-id> --role slice-wright --slice <SLICE-ID> --contract <file>` (it refuses a
104
+ contract that forbids writer-safe checks or names none), then `start` with the host handle, `seal`, and
101
105
  `return` on completion (auto-records dispatch/return metrics). Every 5 wright
102
106
  rounds on one slice, `open` blocks for a reslice review: propose an
103
107
  acceptance-preserving split (`root_no_change_analysis` → `FOLD` per
@@ -28,8 +28,8 @@ Execute [`reference/phase-contract.md`](reference/phase-contract.md)
28
28
  [`reference/wright-dispatch.md`](reference/wright-dispatch.md).
29
29
  Every wright contract names the writer-safe checks the wright runs (syntax/type/lint,
30
30
  unit and self-check suites, a narrow local smoke) and never forbids them; only
31
- artifact-producing, consumptive, or full canonical gates stay root-owned.
32
- Prior contracts in `evidence.md` are not a template for this. **Failing case:** the
31
+ artifact-producing, consumptive, or full canonical gates stay root-owned;
32
+ `dispatch open --contract` refuses a contract that breaks this. Prior contracts in `evidence.md` are not a template for this. **Failing case:** the
33
33
  contract says "skip tests mid-flight; root runs them after return", and the wright
34
34
  returns three unit failures that a 20 s `go test` would have caught in-round.
35
35
 
@@ -23,7 +23,9 @@ DISPATCH → hand the slice contract to devrites-slice-wright (fresh context).
23
23
  (independent claims, fresh contexts); wright fixes stay serial — writers share files
24
24
  PROVE → root, concurrent with the reviews on the same frozen candidate:
25
25
  required build/browser/E2E (narrow self-check/smoke first, full gate only
26
- after it is green, long runs in the background), then returned-diff/path recheck; fail-on-red
26
+ after it is green, long runs in the background; cancel one still running once
27
+ review or proof sends the candidate back, keeping its partial output as
28
+ diagnostics), then returned-diff/path recheck; fail-on-red
27
29
  (red/gap → repair wright, then re-review and re-prove; do not commit yet)
28
30
  RECORD → orchestrator: after green verification, update state.md/evidence.md and
29
31
  upsert the authoritative candidate manifest from the actual scoped diff
@@ -94,10 +94,14 @@ claim add --session <id> <task-paths>`; retain its returned `<claim-id>`, then r
94
94
  live foreign session releases the retained claim and stops the dispatch, per
95
95
  [`agents.md`](../../devrites-lib/reference/standards/agents.md). `.devrites/**`
96
96
  is never a task path; see [Workflow Artifact admission](../../devrites-lib/reference/standards/workflow-artifacts.md).
97
- Ask the host
98
- for the exact writer in fresh context and wait. Track it through the
99
- launch barrier — `devrites-engine dispatch <slug> open --phase build --wave
100
- <slice-id> --role slice-wright --slice <SLICE-ID>`, then `start` with the host handle, `seal`, and
97
+ Write the exact contract, with its `Writer-safe checks:` line, to
98
+ `packets/<wave>.contract.md` and hand the wright that text verbatim. Ask the host
99
+ for the exact writer in fresh context; a repair round on the same slice whose
100
+ returned wright the host can still continue goes to that wright on its existing
101
+ handle instead, so it does not re-read the slice from scratch. Wait, and track it
102
+ through the launch barrier — `devrites-engine dispatch <slug> open --phase build --wave
103
+ <slice-id> --role slice-wright --slice <SLICE-ID> --contract <file>` (it refuses a
104
+ contract that forbids writer-safe checks or names none), then `start` with the host handle, `seal`, and
101
105
  `return` on completion (auto-records dispatch/return metrics). Every 5 wright
102
106
  rounds on one slice, `open` blocks for a reslice review: propose an
103
107
  acceptance-preserving split (`root_no_change_analysis` → `FOLD` per
@@ -29,8 +29,8 @@ Execute [`reference/phase-contract.md`](reference/phase-contract.md)
29
29
  [`reference/wright-dispatch.md`](reference/wright-dispatch.md).
30
30
  Every wright contract names the writer-safe checks the wright runs (syntax/type/lint,
31
31
  unit and self-check suites, a narrow local smoke) and never forbids them; only
32
- artifact-producing, consumptive, or full canonical gates stay root-owned.
33
- Prior contracts in `evidence.md` are not a template for this. **Failing case:** the
32
+ artifact-producing, consumptive, or full canonical gates stay root-owned;
33
+ `dispatch open --contract` refuses a contract that breaks this. Prior contracts in `evidence.md` are not a template for this. **Failing case:** the
34
34
  contract says "skip tests mid-flight; root runs them after return", and the wright
35
35
  returns three unit failures that a 20 s `go test` would have caught in-round.
36
36
 
@@ -23,7 +23,9 @@ DISPATCH → hand the slice contract to devrites-slice-wright (fresh context).
23
23
  (independent claims, fresh contexts); wright fixes stay serial — writers share files
24
24
  PROVE → root, concurrent with the reviews on the same frozen candidate:
25
25
  required build/browser/E2E (narrow self-check/smoke first, full gate only
26
- after it is green, long runs in the background), then returned-diff/path recheck; fail-on-red
26
+ after it is green, long runs in the background; cancel one still running once
27
+ review or proof sends the candidate back, keeping its partial output as
28
+ diagnostics), then returned-diff/path recheck; fail-on-red
27
29
  (red/gap → repair wright, then re-review and re-prove; do not commit yet)
28
30
  RECORD → orchestrator: after green verification, update state.md/evidence.md and
29
31
  upsert the authoritative candidate manifest from the actual scoped diff
@@ -94,10 +94,14 @@ claim add --session <id> <task-paths>`; retain its returned `<claim-id>`, then r
94
94
  live foreign session releases the retained claim and stops the dispatch, per
95
95
  [`agents.md`](skill://devrites-lib/reference/standards/agents.md). `.devrites/**`
96
96
  is never a task path; see [Workflow Artifact admission](skill://devrites-lib/reference/standards/workflow-artifacts.md).
97
- Ask the host
98
- for the exact writer in fresh context and wait. Track it through the
99
- launch barrier — `devrites-engine dispatch <slug> open --phase build --wave
100
- <slice-id> --role slice-wright --slice <SLICE-ID>`, then `start` with the host handle, `seal`, and
97
+ Write the exact contract, with its `Writer-safe checks:` line, to
98
+ `packets/<wave>.contract.md` and hand the wright that text verbatim. Ask the host
99
+ for the exact writer in fresh context; a repair round on the same slice whose
100
+ returned wright the host can still continue goes to that wright on its existing
101
+ handle instead, so it does not re-read the slice from scratch. Wait, and track it
102
+ through the launch barrier — `devrites-engine dispatch <slug> open --phase build --wave
103
+ <slice-id> --role slice-wright --slice <SLICE-ID> --contract <file>` (it refuses a
104
+ contract that forbids writer-safe checks or names none), then `start` with the host handle, `seal`, and
101
105
  `return` on completion (auto-records dispatch/return metrics). Every 5 wright
102
106
  rounds on one slice, `open` blocks for a reslice review: propose an
103
107
  acceptance-preserving split (`root_no_change_analysis` → `FOLD` per
@@ -29,8 +29,8 @@ Execute [`reference/phase-contract.md`](reference/phase-contract.md)
29
29
  [`reference/wright-dispatch.md`](reference/wright-dispatch.md).
30
30
  Every wright contract names the writer-safe checks the wright runs (syntax/type/lint,
31
31
  unit and self-check suites, a narrow local smoke) and never forbids them; only
32
- artifact-producing, consumptive, or full canonical gates stay root-owned.
33
- Prior contracts in `evidence.md` are not a template for this. **Failing case:** the
32
+ artifact-producing, consumptive, or full canonical gates stay root-owned;
33
+ `dispatch open --contract` refuses a contract that breaks this. Prior contracts in `evidence.md` are not a template for this. **Failing case:** the
34
34
  contract says "skip tests mid-flight; root runs them after return", and the wright
35
35
  returns three unit failures that a 20 s `go test` would have caught in-round.
36
36
 
@@ -23,7 +23,9 @@ DISPATCH → hand the slice contract to devrites-slice-wright (fresh context).
23
23
  (independent claims, fresh contexts); wright fixes stay serial — writers share files
24
24
  PROVE → root, concurrent with the reviews on the same frozen candidate:
25
25
  required build/browser/E2E (narrow self-check/smoke first, full gate only
26
- after it is green, long runs in the background), then returned-diff/path recheck; fail-on-red
26
+ after it is green, long runs in the background; cancel one still running once
27
+ review or proof sends the candidate back, keeping its partial output as
28
+ diagnostics), then returned-diff/path recheck; fail-on-red
27
29
  (red/gap → repair wright, then re-review and re-prove; do not commit yet)
28
30
  RECORD → orchestrator: after green verification, update state.md/evidence.md and
29
31
  upsert the authoritative candidate manifest from the actual scoped diff
@@ -94,10 +94,14 @@ claim add --session <id> <task-paths>`; retain its returned `<claim-id>`, then r
94
94
  live foreign session releases the retained claim and stops the dispatch, per
95
95
  [`agents.md`](../../devrites-lib/reference/standards/agents.md). `.devrites/**`
96
96
  is never a task path; see [Workflow Artifact admission](../../devrites-lib/reference/standards/workflow-artifacts.md).
97
- Ask the host
98
- for the exact writer in fresh context and wait. Track it through the
99
- launch barrier — `devrites-engine dispatch <slug> open --phase build --wave
100
- <slice-id> --role slice-wright --slice <SLICE-ID>`, then `start` with the host handle, `seal`, and
97
+ Write the exact contract, with its `Writer-safe checks:` line, to
98
+ `packets/<wave>.contract.md` and hand the wright that text verbatim. Ask the host
99
+ for the exact writer in fresh context; a repair round on the same slice whose
100
+ returned wright the host can still continue goes to that wright on its existing
101
+ handle instead, so it does not re-read the slice from scratch. Wait, and track it
102
+ through the launch barrier — `devrites-engine dispatch <slug> open --phase build --wave
103
+ <slice-id> --role slice-wright --slice <SLICE-ID> --contract <file>` (it refuses a
104
+ contract that forbids writer-safe checks or names none), then `start` with the host handle, `seal`, and
101
105
  `return` on completion (auto-records dispatch/return metrics). Every 5 wright
102
106
  rounds on one slice, `open` blocks for a reslice review: propose an
103
107
  acceptance-preserving split (`root_no_change_analysis` → `FOLD` per
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devrites",
3
- "version": "6.1.5",
3
+ "version": "6.2.0",
4
4
  "description": "DevRites: a disciplined senior-engineer workflow pack for Claude Code, Codex, omp, pi, and Devin CLI",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://github.com/ViktorsBaikers/DevRites#readme",