@dzhechkov/keysarium 1.5.38 → 1.5.40
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 +6 -26
- package/README.md +3 -0
- package/package.json +3 -2
- package/sbom.json +5 -55
- package/templates/.claude/skills/feature-adr/SKILL.md +24 -0
- package/templates/.claude/skills/feature-adr/modules/08-qe.md +26 -12
- package/templates/.claude/skills/feature-adr/scripts/check-plan-completeness.mjs +62 -0
package/.dz-manifest.json
CHANGED
|
@@ -3,17 +3,9 @@
|
|
|
3
3
|
"version": 1,
|
|
4
4
|
"pack": "keysarium",
|
|
5
5
|
"files": [
|
|
6
|
-
{
|
|
7
|
-
"path": ".npmignore",
|
|
8
|
-
"sha256": "9317ffe4ed40056088019932546f9c61314dc12771936facac6c1a223850ba1a"
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
"path": "CHANGELOG.md",
|
|
12
|
-
"sha256": "8dc44c1a37773e4e3694b762bb4299a6a44b3d12cf9a82ef090a64a981dc15df"
|
|
13
|
-
},
|
|
14
6
|
{
|
|
15
7
|
"path": "README.md",
|
|
16
|
-
"sha256": "
|
|
8
|
+
"sha256": "676f962e26cf674631c11f1593d533fa1e9c4cdee7e1d7786f7727fc1412366a"
|
|
17
9
|
},
|
|
18
10
|
{
|
|
19
11
|
"path": "README.ru.md",
|
|
@@ -23,21 +15,9 @@
|
|
|
23
15
|
"path": "bin/cli.js",
|
|
24
16
|
"sha256": "a210174d6b63d053f7744757972d31acb0f4d9c59f8dacff7b62872a19ebd31a"
|
|
25
17
|
},
|
|
26
|
-
{
|
|
27
|
-
"path": "install.sh",
|
|
28
|
-
"sha256": "9631575645f93ca8a65aa2f346da7253cd6ffa6394e36c13a2bf0d7eb605387f"
|
|
29
|
-
},
|
|
30
18
|
{
|
|
31
19
|
"path": "package.json",
|
|
32
|
-
"sha256": "
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"path": "scripts/sync-templates.js",
|
|
36
|
-
"sha256": "2dbbe71d5454c5be20c4460330b7b3ec77dc78d498d99d7226fe474ed2fd1101"
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"path": "sources.json",
|
|
40
|
-
"sha256": "e36d98d8438c8ef9bc872843aeabc087c8b7a9fc52ed5a50568d28306d26b876"
|
|
20
|
+
"sha256": "7b17d0b5b5a60c3ee74d7d93358040a1353c828a962df2530ba74dc982309089"
|
|
41
21
|
},
|
|
42
22
|
{
|
|
43
23
|
"path": "src/cli.js",
|
|
@@ -365,7 +345,7 @@
|
|
|
365
345
|
},
|
|
366
346
|
{
|
|
367
347
|
"path": "templates/.claude/skills/feature-adr/SKILL.md",
|
|
368
|
-
"sha256": "
|
|
348
|
+
"sha256": "67eb730c815e6b8f9b9b61084c67ceb85440548f00b21f52187d16e81e3d7af8"
|
|
369
349
|
},
|
|
370
350
|
{
|
|
371
351
|
"path": "templates/.claude/skills/feature-adr/examples/sample-feature-output.md",
|
|
@@ -409,7 +389,7 @@
|
|
|
409
389
|
},
|
|
410
390
|
{
|
|
411
391
|
"path": "templates/.claude/skills/feature-adr/modules/08-qe.md",
|
|
412
|
-
"sha256": "
|
|
392
|
+
"sha256": "bd5b5809142c12fa1378de446b68027a0c342a7a91ad17e4fb3395ca8f6a8508"
|
|
413
393
|
},
|
|
414
394
|
{
|
|
415
395
|
"path": "templates/.claude/skills/feature-adr/modules/09-fleet-qe.md",
|
|
@@ -501,7 +481,7 @@
|
|
|
501
481
|
},
|
|
502
482
|
{
|
|
503
483
|
"path": "templates/.claude/skills/feature-adr/scripts/check-plan-completeness.mjs",
|
|
504
|
-
"sha256": "
|
|
484
|
+
"sha256": "5cef77e68c58f163be64516013fb90866ef7201e415dc8888cc21a0f4d92b7d8"
|
|
505
485
|
},
|
|
506
486
|
{
|
|
507
487
|
"path": "templates/.claude/skills/frontend-design/LICENSE.txt",
|
|
@@ -1005,5 +985,5 @@
|
|
|
1005
985
|
}
|
|
1006
986
|
]
|
|
1007
987
|
},
|
|
1008
|
-
"signature": "
|
|
988
|
+
"signature": "HqvQFasiKkM8l4ksIkFcAGUHMtxvogzo9q7bO3Km4i2EQPoxwyWo6Z85GftW6HRLA+L75kTNPWpMU5avuxmJBA=="
|
|
1009
989
|
}
|
package/README.md
CHANGED
|
@@ -426,3 +426,6 @@ deliberate skip: a missing file is a WARNING that names the missing artifact, wh
|
|
|
426
426
|
carrying no acid table is an honest SKIP. Both used to report as a clean skip, so the acid check
|
|
427
427
|
silently switched itself off whenever Step 0 wrote nothing — MEASURED 2026-08-21, 66 of 199 features
|
|
428
428
|
carried that file and the last four in a row did not.
|
|
429
|
+
|
|
430
|
+
`1.5.40` — the bundled `feature-adr` Step-8 module now describes the amendment gate as the command
|
|
431
|
+
`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.
|
|
3
|
+
"version": "1.5.40",
|
|
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": {
|
|
@@ -51,5 +51,6 @@
|
|
|
51
51
|
},
|
|
52
52
|
"publishConfig": {
|
|
53
53
|
"access": "public"
|
|
54
|
-
}
|
|
54
|
+
},
|
|
55
|
+
"scripts": {}
|
|
55
56
|
}
|
package/sbom.json
CHANGED
|
@@ -9,33 +9,13 @@
|
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
11
|
"components": [
|
|
12
|
-
{
|
|
13
|
-
"type": "file",
|
|
14
|
-
"name": ".npmignore",
|
|
15
|
-
"hashes": [
|
|
16
|
-
{
|
|
17
|
-
"alg": "SHA-256",
|
|
18
|
-
"content": "9317ffe4ed40056088019932546f9c61314dc12771936facac6c1a223850ba1a"
|
|
19
|
-
}
|
|
20
|
-
]
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
"type": "file",
|
|
24
|
-
"name": "CHANGELOG.md",
|
|
25
|
-
"hashes": [
|
|
26
|
-
{
|
|
27
|
-
"alg": "SHA-256",
|
|
28
|
-
"content": "8dc44c1a37773e4e3694b762bb4299a6a44b3d12cf9a82ef090a64a981dc15df"
|
|
29
|
-
}
|
|
30
|
-
]
|
|
31
|
-
},
|
|
32
12
|
{
|
|
33
13
|
"type": "file",
|
|
34
14
|
"name": "README.md",
|
|
35
15
|
"hashes": [
|
|
36
16
|
{
|
|
37
17
|
"alg": "SHA-256",
|
|
38
|
-
"content": "
|
|
18
|
+
"content": "676f962e26cf674631c11f1593d533fa1e9c4cdee7e1d7786f7727fc1412366a"
|
|
39
19
|
}
|
|
40
20
|
]
|
|
41
21
|
},
|
|
@@ -59,43 +39,13 @@
|
|
|
59
39
|
}
|
|
60
40
|
]
|
|
61
41
|
},
|
|
62
|
-
{
|
|
63
|
-
"type": "file",
|
|
64
|
-
"name": "install.sh",
|
|
65
|
-
"hashes": [
|
|
66
|
-
{
|
|
67
|
-
"alg": "SHA-256",
|
|
68
|
-
"content": "9631575645f93ca8a65aa2f346da7253cd6ffa6394e36c13a2bf0d7eb605387f"
|
|
69
|
-
}
|
|
70
|
-
]
|
|
71
|
-
},
|
|
72
42
|
{
|
|
73
43
|
"type": "file",
|
|
74
44
|
"name": "package.json",
|
|
75
45
|
"hashes": [
|
|
76
46
|
{
|
|
77
47
|
"alg": "SHA-256",
|
|
78
|
-
"content": "
|
|
79
|
-
}
|
|
80
|
-
]
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
"type": "file",
|
|
84
|
-
"name": "scripts/sync-templates.js",
|
|
85
|
-
"hashes": [
|
|
86
|
-
{
|
|
87
|
-
"alg": "SHA-256",
|
|
88
|
-
"content": "2dbbe71d5454c5be20c4460330b7b3ec77dc78d498d99d7226fe474ed2fd1101"
|
|
89
|
-
}
|
|
90
|
-
]
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
"type": "file",
|
|
94
|
-
"name": "sources.json",
|
|
95
|
-
"hashes": [
|
|
96
|
-
{
|
|
97
|
-
"alg": "SHA-256",
|
|
98
|
-
"content": "e36d98d8438c8ef9bc872843aeabc087c8b7a9fc52ed5a50568d28306d26b876"
|
|
48
|
+
"content": "7b17d0b5b5a60c3ee74d7d93358040a1353c828a962df2530ba74dc982309089"
|
|
99
49
|
}
|
|
100
50
|
]
|
|
101
51
|
},
|
|
@@ -915,7 +865,7 @@
|
|
|
915
865
|
"hashes": [
|
|
916
866
|
{
|
|
917
867
|
"alg": "SHA-256",
|
|
918
|
-
"content": "
|
|
868
|
+
"content": "67eb730c815e6b8f9b9b61084c67ceb85440548f00b21f52187d16e81e3d7af8"
|
|
919
869
|
}
|
|
920
870
|
]
|
|
921
871
|
},
|
|
@@ -1025,7 +975,7 @@
|
|
|
1025
975
|
"hashes": [
|
|
1026
976
|
{
|
|
1027
977
|
"alg": "SHA-256",
|
|
1028
|
-
"content": "
|
|
978
|
+
"content": "bd5b5809142c12fa1378de446b68027a0c342a7a91ad17e4fb3395ca8f6a8508"
|
|
1029
979
|
}
|
|
1030
980
|
]
|
|
1031
981
|
},
|
|
@@ -1255,7 +1205,7 @@
|
|
|
1255
1205
|
"hashes": [
|
|
1256
1206
|
{
|
|
1257
1207
|
"alg": "SHA-256",
|
|
1258
|
-
"content": "
|
|
1208
|
+
"content": "5cef77e68c58f163be64516013fb90866ef7201e415dc8888cc21a0f4d92b7d8"
|
|
1259
1209
|
}
|
|
1260
1210
|
]
|
|
1261
1211
|
},
|
|
@@ -100,6 +100,9 @@ ROUTER → REQUIREMENTS → RESEARCH → ADR → QCSD SWARM
|
|
|
100
100
|
SPARC-GOAP PLAN
|
|
101
101
|
(all)
|
|
102
102
|
│
|
|
103
|
+
K1 NAME-AVAILABILITY GATE
|
|
104
|
+
(every new command/module/export)
|
|
105
|
+
│
|
|
103
106
|
K2 PLAN-COMPLETENESS GATE
|
|
104
107
|
(all — exit 0 or Step 7 waits)
|
|
105
108
|
│
|
|
@@ -147,6 +150,27 @@ Step | S | M | L | XL | Model | Agentic QE Skill
|
|
|
147
150
|
10 Delivery Gate (OPT-IN) | o | o | o | o | cross-family of coder | 4 planes: regressions ‖ security ‖ code-quality ‖ product-honesty (o = runs only when explicitly requested; absent ⇒ byte-identical) |
|
|
148
151
|
```
|
|
149
152
|
|
|
153
|
+
### K1 name-availability gate (Step-6/7 boundary, MANDATORY, every new name)
|
|
154
|
+
|
|
155
|
+
Before Step 7 writes a line, every NEW name the plan introduces is checked:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
dz name-check --command <cmd> --module <basename> --export <a,b,c>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
`exit 0` → proceed · `exit 1` → rename in the plan first · `exit 2` → NOT ESTABLISHED (the sweep
|
|
162
|
+
found nothing of that kind — fix the invocation, never read it as free).
|
|
163
|
+
|
|
164
|
+
**Why this is a gate and not advice.** Twice on 2026-08-23/24 a collision broke the build outright —
|
|
165
|
+
`dz retro` was already a command and its star re-export clash stopped the CLI from importing at all;
|
|
166
|
+
`decideProvenance` was already an export. Both were answerable before any code. The check costs one
|
|
167
|
+
command; the miss costs a rename across every artifact of the feature. An agent's intention to
|
|
168
|
+
remember is layer 4 on the cost-of-detection ladder, and this line exists because that layer failed
|
|
169
|
+
twice in one day.
|
|
170
|
+
|
|
171
|
+
The check reads workspace SOURCE, never `dist` — a stale build answers "free" confidently. Its honest
|
|
172
|
+
limit is printed on the passing path: a re-export under a different name stays the build's job.
|
|
173
|
+
|
|
150
174
|
### K2 plan-completeness gate (Step-6/7 boundary, MANDATORY, all tiers)
|
|
151
175
|
|
|
152
176
|
Step 7 does not start until the plan passes a SCRIPT — not a reviewer's impression:
|
|
@@ -160,18 +160,32 @@ The Confirmation-to-test link is load-bearing. If absent, grade no better than C
|
|
|
160
160
|
|
|
161
161
|
### 3b. Amendment Gate (P2 — amendments inherit the Confirmation discipline)
|
|
162
162
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
163
|
+
**Do not judge this yourself — RUN the check.** Resolution of every `AM-N` row to a real test is a
|
|
164
|
+
deterministic question, and a deterministic question must not live in prose (cost-of-detection ladder).
|
|
165
|
+
It used to live here, and `features/qe-scoped-review` shipped with five named amendment test ids of
|
|
166
|
+
which none existed, while its plan recorded `## Amendments: None`.
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
dz amendment-check --slug <feature-slug> --json # or --feature-dir <abs path>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
| Outcome | Exit | What it means for the gate |
|
|
173
|
+
|---|---|---|
|
|
174
|
+
| `pass` | 0 | every row resolves to a test found inside the file the row names |
|
|
175
|
+
| `skip` | 0 | no `## Amendments` section — an absence, stated, never a silent pass |
|
|
176
|
+
| `fail` | 1 | a HIGH gap: quote every reason verbatim into the QE report |
|
|
177
|
+
| `not-established` | 3 | the grammar matched nothing, or the inputs were unreadable — **never a pass** |
|
|
178
|
+
|
|
179
|
+
Empty stdout, a crash, or a missing `dz` is `not-established`, not a clean gate.
|
|
180
|
+
|
|
181
|
+
**What the command does NOT prove:** that a resolved test discriminates. Vacuity stays yours, in the
|
|
182
|
+
SAME `dz discrimination-check --test <f1,f2,...> --base HEAD --json` run as the ADR property test — an
|
|
183
|
+
amendment test that stays green at pre-feature base proves nothing about its amendment. A **safeguard**
|
|
184
|
+
amendment additionally needs its test to prove the safeguard FIRES on a real input: a structurally-dead
|
|
185
|
+
safeguard passes an existence check and never fires in production.
|
|
186
|
+
|
|
187
|
+
This closes the distance between "we caught the design flaw" (challenge-panel/QCSD) and "we proved the
|
|
188
|
+
fix works".
|
|
175
189
|
|
|
176
190
|
### 3c. I/O-on-pure-path + fixture-swap hunt (P5)
|
|
177
191
|
|
|
@@ -292,6 +292,68 @@ if (acidArg) {
|
|
|
292
292
|
} else if (acidTokens.length === 0) skips.push('C4: no acid corpus declared (no --acid, no `| A<n> |` table in 00_complexity_assessment.md) — acid-naming check SKIPPED');
|
|
293
293
|
else for (const t of acidTokens) if (!new RegExp(`\\b${t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'i').test(plan)) failures.push(`C4: acid token "${safe(t)}" (from ${acidSource}) not named in the plan`);
|
|
294
294
|
|
|
295
|
+
// ── C6 amendment integrity (backlog 72b89e14, seams б/в/г) ──────────────────────────────────────
|
|
296
|
+
// The measured shape: AM-rows living OUTSIDE `## Amendments` were invisible to every gate; four
|
|
297
|
+
// amendments named no test at all; a retracted amendment (AM-23 cancelling AM-20) left the old one
|
|
298
|
+
// standing. One deterministic check for all three: every AM-token belongs to the section, and every
|
|
299
|
+
// AM row in the section carries `→ test ...` OR an explicit `superseded by AM-N`.
|
|
300
|
+
{
|
|
301
|
+
// Line-scan, not regex-over-document: \Z is Python, and $-lookahead under /m matches every
|
|
302
|
+
// line end — a section with no FOLLOWING heading silently failed to parse (caught by the
|
|
303
|
+
// fixture the moment the tests ran).
|
|
304
|
+
const planLines = plan.split('\n');
|
|
305
|
+
let sectionStart = -1, sectionEnd = -1, cursor = 0;
|
|
306
|
+
for (const pl of planLines) {
|
|
307
|
+
if (sectionStart < 0 && /^##\s*Amendments\s*$/.test(pl)) sectionStart = cursor + pl.length + 1;
|
|
308
|
+
else if (sectionStart >= 0 && sectionEnd < 0 && /^##\s/.test(pl)) sectionEnd = cursor;
|
|
309
|
+
cursor += pl.length + 1;
|
|
310
|
+
}
|
|
311
|
+
if (sectionStart >= 0 && sectionEnd < 0) sectionEnd = plan.length;
|
|
312
|
+
const amSection = sectionStart >= 0 ? plan.slice(sectionStart, sectionEnd) : '';
|
|
313
|
+
// Only a DEFINITION-shaped line counts as a stray: a list item opening with the AM token.
|
|
314
|
+
// A mid-prose REFERENCE («per 01_requirements.md (AM-1..AM-6)», «(AM-1: the clause stays
|
|
315
|
+
// dropped)») cites an amendment defined in ANOTHER artifact and is legitimate — the first cut
|
|
316
|
+
// failed the real wave1 corpus on exactly that (caught by the standing acid test).
|
|
317
|
+
{
|
|
318
|
+
let cursor2 = 0;
|
|
319
|
+
for (const pl of planLines) {
|
|
320
|
+
const isDef = /^\s*(?:[-*|]\s*)\*{0,2}AM-(?:CP-)?\d+\b/.test(pl);
|
|
321
|
+
const inSection = sectionStart >= 0 && cursor2 >= sectionStart && cursor2 < sectionEnd;
|
|
322
|
+
if (isDef && !inSection) {
|
|
323
|
+
const tok = (/AM-(?:CP-)?\d+/.exec(pl) || ['AM-?'])[0];
|
|
324
|
+
failures.push(`C6: ${tok} is DEFINED outside the \`## Amendments\` section (line: "${pl.trim().slice(0, 80)}") — an amendment outside the section is invisible to every downstream reader`);
|
|
325
|
+
}
|
|
326
|
+
cursor2 += pl.length + 1;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
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`);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// ── C7 ADR↔plan command-name drift (seam д) — WARN, deliberately never FAIL ─────────────────────
|
|
342
|
+
// The measured incident: the ADR said `dz policy-sync`, the plan said `dz agents-sync` (and even
|
|
343
|
+
// carried a test that the OTHER alias must not exist) — whichever file the coder opened first won.
|
|
344
|
+
// Deterministically provable is only the SET DIFFERENCE, not which side is right, so this warns
|
|
345
|
+
// with both sides named and never blocks.
|
|
346
|
+
{
|
|
347
|
+
const adrAll = adrFiles.map((f) => { try { return readFileSync(join(adrDir, f), 'utf-8'); } catch { return ''; } }).join('\n');
|
|
348
|
+
const cmds = (t) => new Set([...t.matchAll(/`dz ([a-z][a-z0-9-]+)`/g)].map((m) => m[1]));
|
|
349
|
+
const inAdr = cmds(adrAll); const inPlan = cmds(plan);
|
|
350
|
+
const onlyAdr = [...inAdr].filter((c) => !inPlan.has(c));
|
|
351
|
+
const onlyPlan = [...inPlan].filter((c) => !inAdr.has(c));
|
|
352
|
+
if (adrAll !== '' && onlyAdr.length > 0 && onlyPlan.length > 0) {
|
|
353
|
+
warnings.push(`C7: ADR and plan cite DIFFERENT dz commands — ADR-only: ${onlyAdr.join(', ')}; plan-only: ${onlyPlan.join(', ')} — if these name the SAME thing, one of the two files is lying to the coder (seam д)`);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
295
357
|
// C5 — Inputs read line
|
|
296
358
|
if (!/Inputs read:/i.test(plan)) warnings.push('C5: no "Inputs read:" line (wave-2 seam, WARN only)');
|
|
297
359
|
else for (const need of ['03_adr','05_architecture']) if (!plan.includes(need)) warnings.push(`C5: Inputs read line missing ${need}`);
|