devrites 7.0.11 → 7.0.13

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.13](https://github.com/ViktorsBaikers/DevRites/compare/v7.0.12...v7.0.13) (2026-10-25)
6
+
7
+ ### Fixed
8
+
9
+ * **devrites:** recognize styled perturbation failures ([#171](https://github.com/ViktorsBaikers/DevRites/issues/171)) ([50207c0](https://github.com/ViktorsBaikers/DevRites/commit/50207c053feae0a5a851ec1dbd428cb5db1697e3))
10
+
11
+ ## [7.0.12](https://github.com/ViktorsBaikers/DevRites/compare/v7.0.11...v7.0.12) (2026-10-24)
12
+
13
+ ### Fixed
14
+
15
+ * **devrites:** resolve nested standard citation paths ([#170](https://github.com/ViktorsBaikers/DevRites/issues/170)) ([05dc684](https://github.com/ViktorsBaikers/DevRites/commit/05dc684564b2541c36db5e479ae464417dfc56d8))
16
+ * **no-release:** label writer contract reminder as advisory ([#169](https://github.com/ViktorsBaikers/DevRites/issues/169)) ([47f298e](https://github.com/ViktorsBaikers/DevRites/commit/47f298e977622587bacad8dfe72eeb159ce8a528))
17
+
5
18
  ## [7.0.11](https://github.com/ViktorsBaikers/DevRites/compare/v7.0.10...v7.0.11) (2026-10-24)
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.11`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v7.0.11): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
34
+ **Status:** [`v7.0.13`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v7.0.13): 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
 
@@ -217,14 +217,15 @@ func (a anchorer) breaks(cells []string) (status, detail string) {
217
217
  _, size := utf8.DecodeRuneInString(cited[open:])
218
218
  name, quote := cited[:open], cited[open+size:closing]
219
219
  var paths []string
220
- switch base := mdName(name); base {
221
- case "":
220
+ file := mdName(name)
221
+ switch base := filepath.Base(file); {
222
+ case file == "":
222
223
  paths = []string{filepath.Join(a.workspace, "spec.md"), filepath.Join(a.workspace, "decisions.md")}
223
- case "spec.md", "decisions.md":
224
+ case base == "spec.md" || base == "decisions.md":
224
225
  paths = []string{filepath.Join(a.workspace, base)}
225
226
  default:
226
- if skills, err := resolveSkillsRoot(a.root, a.skillsRoot); err == nil {
227
- paths = []string{filepath.Join(skills, "devrites-lib", "reference", "standards", base)}
227
+ if path := a.standardPath(file); path != "" {
228
+ paths = []string{path}
228
229
  }
229
230
  }
230
231
  var text []string
@@ -265,11 +266,46 @@ func (a anchorer) lines(rel string) ([]string, error) {
265
266
  return nil, fmt.Errorf("%s is not a file under the workspace or project", rel)
266
267
  }
267
268
 
268
- // mdName is the base name of the first .md file a breaks anchor names, or "".
269
+ func (a anchorer) standardPath(name string) string {
270
+ name = filepath.ToSlash(name)
271
+ if strings.Contains("/"+name+"/", "/../") || strings.ContainsRune(name, '\\') {
272
+ return ""
273
+ }
274
+ skills, err := resolveSkillsRoot(a.root, a.skillsRoot)
275
+ if err != nil {
276
+ return ""
277
+ }
278
+ standards, err := filepath.Abs(filepath.Join(skills, "devrites-lib", "reference", "standards"))
279
+ if err != nil {
280
+ return ""
281
+ }
282
+ full := name
283
+ if !filepath.IsAbs(full) {
284
+ full = filepath.Join(a.project, filepath.FromSlash(name))
285
+ }
286
+ if rel, err := filepath.Rel(standards, full); err != nil || !filepath.IsLocal(rel) {
287
+ if !filepath.IsLocal(name) {
288
+ return ""
289
+ }
290
+ full = filepath.Join(standards, filepath.FromSlash(name))
291
+ }
292
+ if !safepath.WithinResolved(full, standards) {
293
+ return ""
294
+ }
295
+ return full
296
+ }
297
+
298
+ // mdName is the first .md path a breaks anchor names, or "".
269
299
  func mdName(name string) string {
270
- for _, field := range strings.Fields(strings.ReplaceAll(name, "`", " ")) {
271
- if field = strings.TrimRight(field, ",;:"); strings.HasSuffix(field, ".md") {
272
- return filepath.Base(field)
300
+ for i, part := range strings.Split(name, "`") {
301
+ fields := strings.Fields(part)
302
+ if i%2 == 1 {
303
+ fields = []string{part}
304
+ }
305
+ for _, field := range fields {
306
+ if field = strings.TrimRight(field, ",;:"); strings.HasSuffix(field, ".md") {
307
+ return field
308
+ }
273
309
  }
274
310
  }
275
311
  return ""
@@ -773,7 +773,7 @@ func admitWrightRounds(root, slug string, f *dispatchFile, w *dispatchWave, revi
773
773
  }
774
774
  }
775
775
  if kind == "wright" {
776
- lines = append(lines, "dispatch: wright contract: name the writer-safe checks the wright runs (syntax/type/lint, unit and self-check suites, a narrow local smoke) and never forbid them; only artifact-producing, consumptive, or full canonical gates stay root-owned")
776
+ lines = append(lines, "dispatch: ADVISORY: wright contract reminder: name the writer-safe checks the wright runs (syntax/type/lint, unit and self-check suites, a narrow local smoke) and never forbid them; only artifact-producing, consumptive, or full canonical gates stay root-owned")
777
777
  }
778
778
  if len(overCap) == 0 {
779
779
  if review != "" {
@@ -44,6 +44,7 @@ const perturbOutputTail = 64 << 10
44
44
 
45
45
  var (
46
46
  perturbNameRE = regexp.MustCompile(`[^A-Za-z0-9._-]`)
47
+ perturbSGRRE = regexp.MustCompile(`\x1b\[[0-9;:]*m`)
47
48
  // perturbFailREs capture the failed test name from one runner FAIL line.
48
49
  perturbFailREs = []*regexp.Regexp{
49
50
  regexp.MustCompile(`^\s*--- FAIL: (\S+)`), // go test
@@ -335,8 +336,9 @@ func classifyPerturbRed(outcome acceptance.RunOutcome, expect string) (match str
335
336
  }
336
337
  for _, line := range strings.Split(outcome.Output, "\n") {
337
338
  line = strings.TrimRight(line, "\r")
339
+ plain := perturbSGRRE.ReplaceAllString(line, "")
338
340
  for _, re := range perturbFailREs {
339
- m := re.FindStringSubmatch(line)
341
+ m := re.FindStringSubmatch(plain)
340
342
  if m == nil {
341
343
  continue
342
344
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devrites",
3
- "version": "7.0.11",
3
+ "version": "7.0.13",
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",