@dzhechkov/keysarium 1.5.40 → 1.5.41

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/.dz-manifest.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "files": [
6
6
  {
7
7
  "path": "README.md",
8
- "sha256": "676f962e26cf674631c11f1593d533fa1e9c4cdee7e1d7786f7727fc1412366a"
8
+ "sha256": "55a9e601a7028333e77dd2ee0f8eec201f053cd970deb8f58ecfa7cf06987cf4"
9
9
  },
10
10
  {
11
11
  "path": "README.ru.md",
@@ -17,7 +17,7 @@
17
17
  },
18
18
  {
19
19
  "path": "package.json",
20
- "sha256": "7b17d0b5b5a60c3ee74d7d93358040a1353c828a962df2530ba74dc982309089"
20
+ "sha256": "9371c3fe3922382a7871224941fb0bae838dfcbeb750bd55a662e4c27a1e1af7"
21
21
  },
22
22
  {
23
23
  "path": "src/cli.js",
@@ -381,7 +381,7 @@
381
381
  },
382
382
  {
383
383
  "path": "templates/.claude/skills/feature-adr/modules/06-implementation-plan.md",
384
- "sha256": "3903e2694ad47782914b35869bbf19c5f0803b6dafdcfb629df343a5ff00d1b9"
384
+ "sha256": "b3efdfa1d44f4c51ff46551b5827066955c1f0bfee212d371ac1e2fb1c99980f"
385
385
  },
386
386
  {
387
387
  "path": "templates/.claude/skills/feature-adr/modules/07-code.md",
@@ -481,7 +481,7 @@
481
481
  },
482
482
  {
483
483
  "path": "templates/.claude/skills/feature-adr/scripts/check-plan-completeness.mjs",
484
- "sha256": "5cef77e68c58f163be64516013fb90866ef7201e415dc8888cc21a0f4d92b7d8"
484
+ "sha256": "eddf116620050e80b88497ace026fb8e0a12986f94f216181480c7daa0e08be4"
485
485
  },
486
486
  {
487
487
  "path": "templates/.claude/skills/frontend-design/LICENSE.txt",
@@ -985,5 +985,5 @@
985
985
  }
986
986
  ]
987
987
  },
988
- "signature": "HqvQFasiKkM8l4ksIkFcAGUHMtxvogzo9q7bO3Km4i2EQPoxwyWo6Z85GftW6HRLA+L75kTNPWpMU5avuxmJBA=="
988
+ "signature": "AXc5drN9RLQVp4PK9QbjYylVG4nQruSrJQZV4KPQ2JY3/Xif4oZzOxlUOQ1JA5+HRppGUvGnnMtTN8c35rDkDw=="
989
989
  }
package/README.md CHANGED
@@ -419,6 +419,12 @@ deliberately excluded — "skeleton first" is nonsense there.
419
419
 
420
420
  ## Status
421
421
 
422
+ `1.5.41` — refreshes the bundled `feature-adr` gate script with the C6 amendment-integrity fix (each
423
+ amendment scoped to its own block; closes a false refusal on markers below the old three-line window
424
+ AND a false pass where a testless amendment borrowed its neighbour's marker). No keysarium behaviour
425
+ changes. See `@dzhechkov/skills-feature-adr@1.5.3`.
426
+
427
+
422
428
  `1.5.38` — a fix to the bundled `feature-adr` gate script in `templates/`, no pipeline change.
423
429
 
424
430
  The bundled K2 plan-completeness gate now tells an **ABSENT** `00_complexity_assessment.md` from a
@@ -427,5 +433,5 @@ carrying no acid table is an honest SKIP. Both used to report as a clean skip, s
427
433
  silently switched itself off whenever Step 0 wrote nothing — MEASURED 2026-08-21, 66 of 199 features
428
434
  carried that file and the last four in a row did not.
429
435
 
430
- `1.5.40` — the bundled `feature-adr` Step-8 module now describes the amendment gate as the command
436
+ `1.5.41` — the bundled `feature-adr` Step-8 module now describes the amendment gate as the command
431
437
  `dz amendment-check` instead of a judgement the reviewer is asked to make. Text only; no pipeline change.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dzhechkov/keysarium",
3
- "version": "1.5.40",
3
+ "version": "1.5.41",
4
4
  "description": "AI Case Research Toolkit for Claude Code — full 7-phase pipeline with feature-adr, dream cycles, background workers, multi-platform support, reward learning, and Cloud.ru AI Factory mapping (--ai-factory flag)",
5
5
  "main": "src/cli.js",
6
6
  "bin": {
package/sbom.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "hashes": [
16
16
  {
17
17
  "alg": "SHA-256",
18
- "content": "676f962e26cf674631c11f1593d533fa1e9c4cdee7e1d7786f7727fc1412366a"
18
+ "content": "55a9e601a7028333e77dd2ee0f8eec201f053cd970deb8f58ecfa7cf06987cf4"
19
19
  }
20
20
  ]
21
21
  },
@@ -45,7 +45,7 @@
45
45
  "hashes": [
46
46
  {
47
47
  "alg": "SHA-256",
48
- "content": "7b17d0b5b5a60c3ee74d7d93358040a1353c828a962df2530ba74dc982309089"
48
+ "content": "9371c3fe3922382a7871224941fb0bae838dfcbeb750bd55a662e4c27a1e1af7"
49
49
  }
50
50
  ]
51
51
  },
@@ -955,7 +955,7 @@
955
955
  "hashes": [
956
956
  {
957
957
  "alg": "SHA-256",
958
- "content": "3903e2694ad47782914b35869bbf19c5f0803b6dafdcfb629df343a5ff00d1b9"
958
+ "content": "b3efdfa1d44f4c51ff46551b5827066955c1f0bfee212d371ac1e2fb1c99980f"
959
959
  }
960
960
  ]
961
961
  },
@@ -1205,7 +1205,7 @@
1205
1205
  "hashes": [
1206
1206
  {
1207
1207
  "alg": "SHA-256",
1208
- "content": "5cef77e68c58f163be64516013fb90866ef7201e415dc8888cc21a0f4d92b7d8"
1208
+ "content": "eddf116620050e80b88497ace026fb8e0a12986f94f216181480c7daa0e08be4"
1209
1209
  }
1210
1210
  ]
1211
1211
  },
@@ -185,6 +185,11 @@ Create `features/<slug>/06_implementation_plan.md` with:
185
185
  - `## Amendments` — every correction folded into this plan (a Step-3.5 CONDITIONAL condition, a
186
186
  challenge-panel confirmed finding, a user checkpoint steer) as a fixed-shape row:
187
187
  `AM-N (source): <change>. Confirmation: <property> → test `test_name` (fails if reverted).`
188
+ The row is MACHINE-READ by the K2 C6 gate: the `→ test \`name\`` marker (or `superseded by AM-N`)
189
+ must sit inside that amendment's OWN block — anywhere between its `AM-N` line and the line where
190
+ the NEXT `AM-N` begins. Multi-line amendments are fine; what is NOT fine is putting a marker after
191
+ the following amendment has already started, because it then belongs to that one. A bare range
192
+ like `AM-1..AM-4` never opens a row.
188
193
  A safeguard amendment's named test must prove it TRIGGERS on a real input, not merely that its code
189
194
  path exists. Step 8 verifies every named test exists and is non-vacuous (`dz discrimination-check`).
190
195
 
@@ -327,13 +327,36 @@ else for (const t of acidTokens) if (!new RegExp(`\\b${t.replace(/[.*+?^${}()|[\
327
327
  }
328
328
  }
329
329
  if (sectionStart >= 0) {
330
- for (const lnRaw of amSection.split('\n')) {
331
- const ln = lnRaw.trim();
332
- const am = /^(?:[-*|]\s*)?\*{0,2}(AM-(?:CP-)?\d+)\*{0,2}\b/.exec(ln);
333
- if (!am) continue;
334
- const hasTest = /\u2192\s*test\b|->\s*test\b/.test(ln) || /\u2192\s*test\b|->\s*test\b/.test(amSection.slice(amSection.indexOf(lnRaw)).split('\n').slice(0, 3).join('\n'));
335
- const superseded = /superseded by AM-(?:CP-)?\d+/i.test(ln);
336
- if (!hasTest && !superseded) failures.push(`C6: ${am[1]} carries neither \`\u2192 test <name>\` nor \`superseded by AM-N\` — an amendment without a confirmation is a wish, and a retracted one must say its successor`);
330
+ // Each amendment's confirmation is looked for in ITS OWN BLOCK: from its definition line to the
331
+ // line where the NEXT amendment begins. Three defects die with the old three-line window
332
+ // (MEASURED 2026-08-25 against the 142-plan corpus — 292 C6 failures before, 33 after, and ZERO
333
+ // rows newly caught that pass today):
334
+ // • FALSE REFUSAL — a marker on the `Confirmation:` line 4+ lines down was invisible, so plans
335
+ // that DID name their test were rejected (7 per run, twice in one day, on a user's machine).
336
+ // • FALSE PASS — the window is three LINES, not one amendment, so `- AM-1 testless` followed by
337
+ // `- AM-2 … -> test x` PASSED: AM-1 borrowed its neighbour's marker. That is the safety half,
338
+ // and it is why the boundary is the next DEFINITION rather than a blank line — a blank line
339
+ // does not separate adjacent bullet rows.
340
+ // • A substring seek (`amSection.indexOf(lnRaw)`) let a duplicated line read someone else's
341
+ // window. Indices remove that hazard for free.
342
+ // The boundary is not invented: parseAmendments() in harness-core/src/amendment-trace.ts has used
343
+ // the same next-definition bound all along, so this also ends a divergence between two checkers.
344
+ const secLines = amSection.split('\n');
345
+ // The bullet stays OPTIONAL: requiring it drops 104 of the corpus's 347 real AM rows out of the
346
+ // check entirely (MEASURED). The `(?!\s*\.)` guard is what refuses a wrapped `AM-1..AM-4;`
347
+ // range preamble, which used to open a phantom amendment and double-count AM-1 — it costs 0 rows.
348
+ const DEF = /^(?:[-*|]\s*)?\*{0,2}(AM-(?:CP-)?\d+)\*{0,2}\b(?!\s*\.)/;
349
+ // `tests?` — the two-id form `-> tests \`a\` and \`b\`` is corpus-canonical and is what
350
+ // amendment-trace.ts parses; matching only the singular turned two currently-green rows red.
351
+ const MARK = /\u2192\s*tests?\b|->\s*tests?\b/;
352
+ const defs = [];
353
+ secLines.forEach((l, i) => { const m = DEF.exec(l.trim()); if (m) defs.push({ i, id: m[1] }); });
354
+ for (let k = 0; k < defs.length; k++) {
355
+ const to = k + 1 < defs.length ? defs[k + 1].i : secLines.length;
356
+ const block = secLines.slice(defs[k].i, to).join('\n');
357
+ const hasTest = MARK.test(block);
358
+ const superseded = /superseded by AM-(?:CP-)?\d+/i.test(block);
359
+ if (!hasTest && !superseded) failures.push(`C6: ${defs[k].id} carries neither \`\u2192 test <name>\` nor \`superseded by AM-N\` — an amendment without a confirmation is a wish, and a retracted one must say its successor`);
337
360
  }
338
361
  }
339
362
  }