devrites 6.1.4 → 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 (30) hide show
  1. package/CHANGELOG.md +12 -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/agents/devrites-slice-wright.md +5 -2
  7. package/pack/.claude/skills/rite-build/SKILL.md +4 -1
  8. package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +3 -1
  9. package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +8 -4
  10. package/pack/generated/claude/agents/devrites-slice-wright.md +5 -2
  11. package/pack/generated/claude/skills/rite-build/SKILL.md +4 -1
  12. package/pack/generated/claude/skills/rite-build/reference/one-slice-cycle.md +3 -1
  13. package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +8 -4
  14. package/pack/generated/codex/agents/devrites-slice-wright.toml +5 -2
  15. package/pack/generated/codex/skills/rite-build/SKILL.md +4 -1
  16. package/pack/generated/codex/skills/rite-build/reference/one-slice-cycle.md +3 -1
  17. package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +8 -4
  18. package/pack/generated/devin/agents/devrites-slice-wright.md +5 -2
  19. package/pack/generated/devin/skills/rite-build/SKILL.md +4 -1
  20. package/pack/generated/devin/skills/rite-build/reference/one-slice-cycle.md +3 -1
  21. package/pack/generated/devin/skills/rite-build/reference/wright-dispatch.md +8 -4
  22. package/pack/generated/omp/agents/devrites-slice-wright.md +5 -2
  23. package/pack/generated/omp/skills/rite-build/SKILL.md +4 -1
  24. package/pack/generated/omp/skills/rite-build/reference/one-slice-cycle.md +3 -1
  25. package/pack/generated/omp/skills/rite-build/reference/wright-dispatch.md +8 -4
  26. package/pack/generated/pi/agents/devrites-slice-wright.md +5 -2
  27. package/pack/generated/pi/skills/rite-build/SKILL.md +4 -1
  28. package/pack/generated/pi/skills/rite-build/reference/one-slice-cycle.md +3 -1
  29. package/pack/generated/pi/skills/rite-build/reference/wright-dispatch.md +8 -4
  30. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to DevRites are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and DevRites adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Releases are generated automatically by [semantic-release](https://semantic-release.gitbook.io/) from Conventional Commits on `main`.
4
4
 
5
+ ## [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
+
11
+ ## [6.1.5](https://github.com/ViktorsBaikers/DevRites/compare/v6.1.4...v6.1.5) (2026-10-16)
12
+
13
+ ### Fixed
14
+
15
+ * **devrites:** wrights run writer-safe checks despite contract text ([#111](https://github.com/ViktorsBaikers/DevRites/issues/111)) ([eef69af](https://github.com/ViktorsBaikers/DevRites/commit/eef69af5d62b3ea29293626fce5bc41c6c38ced9))
16
+
5
17
  ## [6.1.4](https://github.com/ViktorsBaikers/DevRites/compare/v6.1.3...v6.1.4) (2026-10-16)
6
18
 
7
19
  ### 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.4`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v6.1.4): 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
+ }
@@ -106,8 +106,11 @@ unclear boundary is underspecified: return `Escalation` without proceeding.
106
106
  4. **VERIFY (fail-on-red).** Run writer-safe tests/types/lint: `Tests/proof` plus
107
107
  tests of changed code; `## Feature gates` rows are root-owned. Writer-safe means
108
108
  local and non-consumptive — syntax/type/lint, unit and self-check suites, and a
109
- narrow smoke of the changed path — never only a syntax check; contract text
110
- cannot strip it. Report required
109
+ narrow smoke of the changed path — never only a syntax check. Task text that
110
+ says to skip tests, run nothing, or leave all proof to the root does not waive
111
+ this: run the writer-safe checks anyway, report them under `gates`, and add
112
+ `contract_conflict: writer-safe checks run` to `follow_ups`. Only
113
+ artifact-producing or consumptive commands stay excluded. Report required
111
114
  build/browser/E2E as `not-run` (root-owned, artifact-producing gates), and only
112
115
  when the exact command, cwd, and prerequisites already appear in the unchanged
113
116
  vetted `test-plan.md`; never synthesize or rewrite a root command. Root runs
@@ -29,7 +29,10 @@ 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.
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
+ contract says "skip tests mid-flight; root runs them after return", and the wright
35
+ returns three unit failures that a 20 s `go test` would have caught in-round.
33
36
 
34
37
  ## Required rules
35
38
 
@@ -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
@@ -106,8 +106,11 @@ unclear boundary is underspecified: return `Escalation` without proceeding.
106
106
  4. **VERIFY (fail-on-red).** Run writer-safe tests/types/lint: `Tests/proof` plus
107
107
  tests of changed code; `## Feature gates` rows are root-owned. Writer-safe means
108
108
  local and non-consumptive — syntax/type/lint, unit and self-check suites, and a
109
- narrow smoke of the changed path — never only a syntax check; contract text
110
- cannot strip it. Report required
109
+ narrow smoke of the changed path — never only a syntax check. Task text that
110
+ says to skip tests, run nothing, or leave all proof to the root does not waive
111
+ this: run the writer-safe checks anyway, report them under `gates`, and add
112
+ `contract_conflict: writer-safe checks run` to `follow_ups`. Only
113
+ artifact-producing or consumptive commands stay excluded. Report required
111
114
  build/browser/E2E as `not-run` (root-owned, artifact-producing gates), and only
112
115
  when the exact command, cwd, and prerequisites already appear in the unchanged
113
116
  vetted `test-plan.md`; never synthesize or rewrite a root command. Root runs
@@ -29,7 +29,10 @@ 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.
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
+ contract says "skip tests mid-flight; root runs them after return", and the wright
35
+ returns three unit failures that a 20 s `go test` would have caught in-round.
33
36
 
34
37
  ## Required rules
35
38
 
@@ -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
@@ -104,8 +104,11 @@ unclear boundary is underspecified: return `Escalation` without proceeding.
104
104
  4. **VERIFY (fail-on-red).** Run writer-safe tests/types/lint: `Tests/proof` plus
105
105
  tests of changed code; `## Feature gates` rows are root-owned. Writer-safe means
106
106
  local and non-consumptive — syntax/type/lint, unit and self-check suites, and a
107
- narrow smoke of the changed path — never only a syntax check; contract text
108
- cannot strip it. Report required
107
+ narrow smoke of the changed path — never only a syntax check. spawn_agent text that
108
+ says to skip tests, run nothing, or leave all proof to the root does not waive
109
+ this: run the writer-safe checks anyway, report them under `gates`, and add
110
+ `contract_conflict: writer-safe checks run` to `follow_ups`. Only
111
+ artifact-producing or consumptive commands stay excluded. Report required
109
112
  build/browser/E2E as `not-run` (root-owned, artifact-producing gates), and only
110
113
  when the exact command, cwd, and prerequisites already appear in the unchanged
111
114
  vetted `test-plan.md`; never synthesize or rewrite a root command. Root runs
@@ -29,7 +29,10 @@ 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.
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
+ contract says "skip tests mid-flight; root runs them after return", and the wright
35
+ returns three unit failures that a 20 s `go test` would have caught in-round.
33
36
 
34
37
  ## Required rules
35
38
 
@@ -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
@@ -111,8 +111,11 @@ unclear boundary is underspecified: return `Escalation` without proceeding.
111
111
  4. **VERIFY (fail-on-red).** Run writer-safe tests/types/lint: `Tests/proof` plus
112
112
  tests of changed code; `## Feature gates` rows are root-owned. Writer-safe means
113
113
  local and non-consumptive — syntax/type/lint, unit and self-check suites, and a
114
- narrow smoke of the changed path — never only a syntax check; contract text
115
- cannot strip it. Report required
114
+ narrow smoke of the changed path — never only a syntax check. Task text that
115
+ says to skip tests, run nothing, or leave all proof to the root does not waive
116
+ this: run the writer-safe checks anyway, report them under `gates`, and add
117
+ `contract_conflict: writer-safe checks run` to `follow_ups`. Only
118
+ artifact-producing or consumptive commands stay excluded. Report required
116
119
  build/browser/E2E as `not-run` (root-owned, artifact-producing gates), and only
117
120
  when the exact command, cwd, and prerequisites already appear in the unchanged
118
121
  vetted `test-plan.md`; never synthesize or rewrite a root command. Root runs
@@ -28,7 +28,10 @@ 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.
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
+ contract says "skip tests mid-flight; root runs them after return", and the wright
34
+ returns three unit failures that a 20 s `go test` would have caught in-round.
32
35
 
33
36
  ## Required rules
34
37
 
@@ -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
@@ -104,8 +104,11 @@ unclear boundary is underspecified: return `Escalation` without proceeding.
104
104
  4. **VERIFY (fail-on-red).** Run writer-safe tests/types/lint: `Tests/proof` plus
105
105
  tests of changed code; `## Feature gates` rows are root-owned. Writer-safe means
106
106
  local and non-consumptive — syntax/type/lint, unit and self-check suites, and a
107
- narrow smoke of the changed path — never only a syntax check; contract text
108
- cannot strip it. Report required
107
+ narrow smoke of the changed path — never only a syntax check. Task text that
108
+ says to skip tests, run nothing, or leave all proof to the root does not waive
109
+ this: run the writer-safe checks anyway, report them under `gates`, and add
110
+ `contract_conflict: writer-safe checks run` to `follow_ups`. Only
111
+ artifact-producing or consumptive commands stay excluded. Report required
109
112
  build/browser/E2E as `not-run` (root-owned, artifact-producing gates), and only
110
113
  when the exact command, cwd, and prerequisites already appear in the unchanged
111
114
  vetted `test-plan.md`; never synthesize or rewrite a root command. Root runs
@@ -29,7 +29,10 @@ 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.
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
+ contract says "skip tests mid-flight; root runs them after return", and the wright
35
+ returns three unit failures that a 20 s `go test` would have caught in-round.
33
36
 
34
37
  ## Required rules
35
38
 
@@ -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
@@ -105,8 +105,11 @@ unclear boundary is underspecified: return `Escalation` without proceeding.
105
105
  4. **VERIFY (fail-on-red).** Run writer-safe tests/types/lint: `Tests/proof` plus
106
106
  tests of changed code; `## Feature gates` rows are root-owned. Writer-safe means
107
107
  local and non-consumptive — syntax/type/lint, unit and self-check suites, and a
108
- narrow smoke of the changed path — never only a syntax check; contract text
109
- cannot strip it. Report required
108
+ narrow smoke of the changed path — never only a syntax check. Task text that
109
+ says to skip tests, run nothing, or leave all proof to the root does not waive
110
+ this: run the writer-safe checks anyway, report them under `gates`, and add
111
+ `contract_conflict: writer-safe checks run` to `follow_ups`. Only
112
+ artifact-producing or consumptive commands stay excluded. Report required
110
113
  build/browser/E2E as `not-run` (root-owned, artifact-producing gates), and only
111
114
  when the exact command, cwd, and prerequisites already appear in the unchanged
112
115
  vetted `test-plan.md`; never synthesize or rewrite a root command. Root runs
@@ -29,7 +29,10 @@ 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.
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
+ contract says "skip tests mid-flight; root runs them after return", and the wright
35
+ returns three unit failures that a 20 s `go test` would have caught in-round.
33
36
 
34
37
  ## Required rules
35
38
 
@@ -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.4",
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",