devrites 7.0.9 → 7.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  All notable changes to DevRites are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and DevRites adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Releases are generated automatically by [semantic-release](https://semantic-release.gitbook.io/) from Conventional Commits on `main`.
4
4
 
5
+ ## [7.0.11](https://github.com/ViktorsBaikers/DevRites/compare/v7.0.10...v7.0.11) (2026-10-24)
6
+
7
+ ### Fixed
8
+
9
+ * **deps:** restore dependency audits with bounded exceptions ([#168](https://github.com/ViktorsBaikers/DevRites/issues/168)) ([89b4aa7](https://github.com/ViktorsBaikers/DevRites/commit/89b4aa733d2395c09f979757cde094f57daca822))
10
+ * **devrites:** permit proof runner read-only inspection ([#167](https://github.com/ViktorsBaikers/DevRites/issues/167)) ([aa11b9e](https://github.com/ViktorsBaikers/DevRites/commit/aa11b9e889a67f11de943fa9d90bff9ed0fd6bf3))
11
+
12
+ ## [7.0.10](https://github.com/ViktorsBaikers/DevRites/compare/v7.0.9...v7.0.10) (2026-10-23)
13
+
14
+ ### Fixed
15
+
16
+ * **devrites:** apply-bundle refuses an unrunnable preflight row ([#166](https://github.com/ViktorsBaikers/DevRites/issues/166)) ([6bc06a4](https://github.com/ViktorsBaikers/DevRites/commit/6bc06a40530e3456b80883303e345fb25d45357a))
17
+
5
18
  ## [7.0.9](https://github.com/ViktorsBaikers/DevRites/compare/v7.0.8...v7.0.9) (2026-10-22)
6
19
 
7
20
  ### 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:** [`v7.0.9`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v7.0.9): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
34
+ **Status:** [`v7.0.11`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v7.0.11): 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
 
@@ -1,6 +1,7 @@
1
1
  package acceptance
2
2
 
3
3
  import (
4
+ "fmt"
4
5
  "path/filepath"
5
6
  "strings"
6
7
 
@@ -25,6 +26,9 @@ type PreflightRow struct {
25
26
  // RunAt is the optional `Run at` cell (`vet`, `pre-dispatch SLICE-###`,
26
27
  // `action`), whitespace-collapsed; "" when the row or table has none.
27
28
  RunAt string
29
+ // Width and HeaderWidth are the row's and its table header's cell counts;
30
+ // they differ when a bare `|` in a command splits the row.
31
+ Width, HeaderWidth int
28
32
  }
29
33
 
30
34
  // ApprovedCommands extracts the approved command surface of test-plan.md: the
@@ -56,7 +60,7 @@ func PreflightRows(testPlan []byte) (rows []PreflightRow, hasRunAt bool) {
56
60
  return nil, false
57
61
  }
58
62
  inSection := false
59
- commandCol, cwdCol, gateCol, expectedCol, runAtCol := -1, -1, -1, -1, -1
63
+ commandCol, cwdCol, gateCol, expectedCol, runAtCol, headerWidth := -1, -1, -1, -1, -1, 0
60
64
  for _, line := range strings.Split(string(structural), "\n") {
61
65
  trimmed := strings.TrimSpace(line)
62
66
  if strings.HasPrefix(trimmed, "##") {
@@ -77,6 +81,7 @@ func PreflightRows(testPlan []byte) (rows []PreflightRow, hasRunAt bool) {
77
81
  gateCol = columnIndex(cells, "gate")
78
82
  expectedCol = columnIndex(cells, "expected")
79
83
  runAtCol = columnIndex(cells, "run at")
84
+ headerWidth = len(cells)
80
85
  hasRunAt = hasRunAt || (commandCol >= 0 && runAtCol >= 0)
81
86
  continue
82
87
  }
@@ -87,7 +92,7 @@ func PreflightRows(testPlan []byte) (rows []PreflightRow, hasRunAt bool) {
87
92
  if command == "" {
88
93
  continue
89
94
  }
90
- row := PreflightRow{ApprovedCommand: ApprovedCommand{Command: command}}
95
+ row := PreflightRow{ApprovedCommand: ApprovedCommand{Command: command}, Width: len(cells), HeaderWidth: headerWidth}
91
96
  if cwdCol >= 0 && cwdCol < len(cells) {
92
97
  row.Cwd = normalizeApprovedCwd(cells[cwdCol])
93
98
  }
@@ -99,6 +104,30 @@ func PreflightRows(testPlan []byte) (rows []PreflightRow, hasRunAt bool) {
99
104
  return rows, hasRunAt
100
105
  }
101
106
 
107
+ // PreflightShapeProblems names each Build-entry preflight row that cannot run
108
+ // as written: a cell count that differs from its header (an unescaped `|`
109
+ // in the command, which must be written `\|`) or an invalid `Run at` value.
110
+ // `check preconditions` would otherwise find it only when Vet runs the row.
111
+ func PreflightShapeProblems(testPlan []byte) []string {
112
+ rows, _ := PreflightRows(testPlan)
113
+ var problems []string
114
+ for _, row := range rows {
115
+ name := valueOr(row.Gate, row.Command)
116
+ if row.Width != row.HeaderWidth {
117
+ problems = append(problems, fmt.Sprintf("preflight row %q has %d cells but its header has %d; escape each `|` in the command as `\\|`", name, row.Width, row.HeaderWidth))
118
+ } else if !ValidRunAt(row.RunAt) {
119
+ problems = append(problems, fmt.Sprintf("preflight row %q has invalid Run at %q (want vet, pre-dispatch SLICE-###, or action)", name, row.RunAt))
120
+ }
121
+ }
122
+ return problems
123
+ }
124
+
125
+ // ValidRunAt reports whether a `Run at` cell is empty or a known value.
126
+ func ValidRunAt(runAt string) bool {
127
+ lower := strings.ToLower(runAt)
128
+ return lower == "" || lower == "vet" || lower == "action" || preDispatchRunAtRE.MatchString(runAt)
129
+ }
130
+
102
131
  // cellText returns a cell's trimmed text without code backticks, "" when the
103
132
  // column is absent or the row is short.
104
133
  func cellText(cells []string, col int) string {
@@ -163,8 +163,7 @@ func runPreflightRows(root, slug, work, project, runAt string, rows []PreflightR
163
163
  doc := &Document{}
164
164
  var results []GateResult
165
165
  for _, row := range rows {
166
- lower := strings.ToLower(row.RunAt)
167
- if lower != "" && lower != "vet" && lower != "action" && !preDispatchRunAtRE.MatchString(row.RunAt) {
166
+ if !ValidRunAt(row.RunAt) {
168
167
  fmt.Fprintf(stdout, "row %s: invalid Run at %q (want vet, pre-dispatch SLICE-###, or action)\n", valueOr(row.Gate, row.Command), row.RunAt)
169
168
  failed = true
170
169
  continue
@@ -15,6 +15,7 @@ import (
15
15
  "sort"
16
16
  "strings"
17
17
 
18
+ "github.com/devrites/devrites/internal/acceptance"
18
19
  "github.com/devrites/devrites/internal/devritespaths"
19
20
  "github.com/devrites/devrites/internal/fsutil"
20
21
  "github.com/devrites/devrites/internal/state"
@@ -360,7 +361,8 @@ func applyHunks(base string, hunks []candidateHunk) (string, []string) {
360
361
 
361
362
  // checkBundleResult rejects an outcome the root would otherwise discover only
362
363
  // at Vet: a tracked ID that vanished from every touched file without being
363
- // listed in retired_ids, a new tasks.md graph problem, or a budgeted artifact
364
+ // listed in retired_ids, a new tasks.md graph problem, a new test-plan.md
365
+ // preflight row that cannot run as written, or a budgeted artifact
364
366
  // that grew into material overshoot without a covering
365
367
  // `Budget override: <=N lines; <reason>` line.
366
368
  func checkBundleResult(targets []*bundleTarget, retired map[string]bool) []string {
@@ -400,6 +402,17 @@ func checkBundleResult(targets []*bundleTarget, retired map[string]bool) []strin
400
402
  }
401
403
  }
402
404
  }
405
+ if name == "test-plan.md" && filepath.Dir(target.rel) == "." {
406
+ old := map[string]bool{}
407
+ for _, p := range acceptance.PreflightShapeProblems(target.before) {
408
+ old[p] = true
409
+ }
410
+ for _, p := range acceptance.PreflightShapeProblems(target.after) {
411
+ if !old[p] {
412
+ problems = append(problems, "test-plan.md: "+p)
413
+ }
414
+ }
415
+ }
403
416
  if filepath.Dir(target.rel) == "." && currentStatePlanning[name] &&
404
417
  len(datedHeadingRE.FindAllIndex(target.after, -1)) > len(datedHeadingRE.FindAllIndex(target.before, -1)) {
405
418
  problems = append(problems, target.rel+": adds a dated delta section; rewrite the owning clause in place (rationale to decisions.md, closed narrative to history/)")
@@ -60,7 +60,7 @@ and only the orchestrator-supplied changed paths.
60
60
  ## Rules
61
61
 
62
62
  - Read-only: do not edit source, tests, `.devrites/**`, Git state, or dependencies.
63
- - Execute no command or external write. Invoke no agent and fix nothing.
63
+ - Read-only local filesystem inspection and digest calculations are permitted. Execute no test, build, benchmark, gate, application or other effectful command; perform no external write. Invoke no agent and fix nothing.
64
64
  - Return a reproduction. Unavailable proof is `cannot_verify`, never pass.
65
65
 
66
66
  ## Output format
@@ -66,7 +66,7 @@ and only the orchestrator-supplied changed paths.
66
66
  ## Rules
67
67
 
68
68
  - Read-only: do not edit source, tests, `.devrites/**`, Git state, or dependencies.
69
- - Execute no command or external write. Invoke no agent and fix nothing.
69
+ - Read-only local filesystem inspection and digest calculations are permitted. Execute no test, build, benchmark, gate, application or other effectful command; perform no external write. Invoke no agent and fix nothing.
70
70
  - Return a reproduction. Unavailable proof is `cannot_verify`, never pass.
71
71
 
72
72
  ## Output format
@@ -64,7 +64,7 @@ and only the orchestrator-supplied changed paths.
64
64
  ## Rules
65
65
 
66
66
  - Read-only: do not edit source, tests, `.devrites/**`, Git state, or dependencies.
67
- - Execute no command or external write. Invoke no agent and fix nothing.
67
+ - Read-only local filesystem inspection and digest calculations are permitted. Execute no test, build, benchmark, gate, application or other effectful command; perform no external write. Invoke no agent and fix nothing.
68
68
  - Return a reproduction. Unavailable proof is `cannot_verify`, never pass.
69
69
 
70
70
  ## Output format
@@ -68,7 +68,7 @@ and only the orchestrator-supplied changed paths.
68
68
  ## Rules
69
69
 
70
70
  - Read-only: do not edit source, tests, `.devrites/**`, Git state, or dependencies.
71
- - Execute no command or external write. Invoke no agent and fix nothing.
71
+ - Read-only local filesystem inspection and digest calculations are permitted. Execute no test, build, benchmark, gate, application or other effectful command; perform no external write. Invoke no agent and fix nothing.
72
72
  - Return a reproduction. Unavailable proof is `cannot_verify`, never pass.
73
73
 
74
74
  ## Output format
@@ -65,7 +65,7 @@ and only the orchestrator-supplied changed paths.
65
65
  ## Rules
66
66
 
67
67
  - Read-only: do not edit source, tests, `.devrites/**`, Git state, or dependencies.
68
- - Execute no command or external write. Invoke no agent and fix nothing.
68
+ - Read-only local filesystem inspection and digest calculations are permitted. Execute no test, build, benchmark, gate, application or other effectful command; perform no external write. Invoke no agent and fix nothing.
69
69
  - Return a reproduction. Unavailable proof is `cannot_verify`, never pass.
70
70
 
71
71
  ## Output format
@@ -66,7 +66,7 @@ and only the orchestrator-supplied changed paths.
66
66
  ## Rules
67
67
 
68
68
  - Read-only: do not edit source, tests, `.devrites/**`, Git state, or dependencies.
69
- - Execute no command or external write. Invoke no agent and fix nothing.
69
+ - Read-only local filesystem inspection and digest calculations are permitted. Execute no test, build, benchmark, gate, application or other effectful command; perform no external write. Invoke no agent and fix nothing.
70
70
  - Return a reproduction. Unavailable proof is `cannot_verify`, never pass.
71
71
 
72
72
  ## Output format
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devrites",
3
- "version": "7.0.9",
3
+ "version": "7.0.11",
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",
@@ -92,7 +92,7 @@
92
92
  "@semantic-release/npm": {
93
93
  "npm": "11.21.1"
94
94
  },
95
- "fast-uri": "3.1.8",
95
+ "fast-uri": "3.1.9",
96
96
  "js-yaml": "4.3.2"
97
97
  }
98
98
  }