@dzhechkov/skills-feature-adr 1.5.13 → 1.5.15
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 +15 -11
- package/CHANGELOG.md +14 -0
- package/README.md +48 -1
- package/package.json +2 -2
- package/sbom.json +20 -10
- package/src/commands/init.js +38 -6
- package/templates/.claude/skills/feature-adr/SKILL.md +79 -1
- package/templates/.claude/skills/feature-adr/modules/06-implementation-plan.md +10 -0
- package/templates/.claude/skills/feature-adr/modules/07-code.md +29 -0
- package/templates/.claude/skills/feature-adr/modules/08-qe.md +35 -2
- package/templates/.claude/skills/feature-adr/scripts/build-coder-context.mjs +201 -0
- package/templates/.claude/skills/feature-adr/scripts/check-plan-completeness.mjs +210 -28
- package/templates/.claude/workflows/feature-adr.js +334 -39
package/.dz-manifest.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"files": [
|
|
6
6
|
{
|
|
7
7
|
"path": "CHANGELOG.md",
|
|
8
|
-
"sha256": "
|
|
8
|
+
"sha256": "26fa03f89862d03ebfc6447c866cb5d4dcbd5591ae4f8fb3a3ea08b6c586e19d"
|
|
9
9
|
},
|
|
10
10
|
{
|
|
11
11
|
"path": "LICENSE",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"path": "README.md",
|
|
16
|
-
"sha256": "
|
|
16
|
+
"sha256": "66f3b2cf7fdcf9efbf64c7d5cc36b34ffc82b151a9bc07e6fda5fc47d4fba72e"
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"path": "bin/cli.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
"path": "package.json",
|
|
28
|
-
"sha256": "
|
|
28
|
+
"sha256": "e74b1a22e0260a61a3ab37512366402c4e6231b85625028a86219ee3f5c21e12"
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
"path": "src/cli.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
"path": "src/commands/init.js",
|
|
40
|
-
"sha256": "
|
|
40
|
+
"sha256": "07ff9d955422979ea67aa5aa454c13303f5ae644efb32e5cc6f359a509638347"
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
"path": "src/commands/list.js",
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"path": "templates/.claude/skills/feature-adr/SKILL.md",
|
|
116
|
-
"sha256": "
|
|
116
|
+
"sha256": "28c265603481f976a52ea4c627e11194f3c0283801ea93d02cbb9f4248b43c68"
|
|
117
117
|
},
|
|
118
118
|
{
|
|
119
119
|
"path": "templates/.claude/skills/feature-adr/examples/sample-feature-output.md",
|
|
@@ -149,15 +149,15 @@
|
|
|
149
149
|
},
|
|
150
150
|
{
|
|
151
151
|
"path": "templates/.claude/skills/feature-adr/modules/06-implementation-plan.md",
|
|
152
|
-
"sha256": "
|
|
152
|
+
"sha256": "d7a2a4e56b24451da234b1ac4ef440ba9b0370617e1c0cde8ad5f3d575a53209"
|
|
153
153
|
},
|
|
154
154
|
{
|
|
155
155
|
"path": "templates/.claude/skills/feature-adr/modules/07-code.md",
|
|
156
|
-
"sha256": "
|
|
156
|
+
"sha256": "db79f8d026cc47edd1e5d2f30d0e1455c55c570dd022d549d440985a3e5940a5"
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
"path": "templates/.claude/skills/feature-adr/modules/08-qe.md",
|
|
160
|
-
"sha256": "
|
|
160
|
+
"sha256": "d7a967926feec9b0ec173ac7042ae3abd368644d8e1dba9a81a770794417fcb3"
|
|
161
161
|
},
|
|
162
162
|
{
|
|
163
163
|
"path": "templates/.claude/skills/feature-adr/modules/09-fleet-qe.md",
|
|
@@ -247,9 +247,13 @@
|
|
|
247
247
|
"path": "templates/.claude/skills/feature-adr/references/qe-checklist.md",
|
|
248
248
|
"sha256": "238d8896996dc53559f58b24aa7eca966cc8845c3b9dda6d982c717c657b91e4"
|
|
249
249
|
},
|
|
250
|
+
{
|
|
251
|
+
"path": "templates/.claude/skills/feature-adr/scripts/build-coder-context.mjs",
|
|
252
|
+
"sha256": "19c3991bfb5e88205c9ff6d4d44037c136a190581bab199d3928196e4616fe15"
|
|
253
|
+
},
|
|
250
254
|
{
|
|
251
255
|
"path": "templates/.claude/skills/feature-adr/scripts/check-plan-completeness.mjs",
|
|
252
|
-
"sha256": "
|
|
256
|
+
"sha256": "8b93949ce4f671d932c5389050db3a3e2750efcbed69681d69f392ccf4d2a168"
|
|
253
257
|
},
|
|
254
258
|
{
|
|
255
259
|
"path": "templates/.claude/skills/feature-adr/scripts/markdown-masker.mjs",
|
|
@@ -317,7 +321,7 @@
|
|
|
317
321
|
},
|
|
318
322
|
{
|
|
319
323
|
"path": "templates/.claude/workflows/feature-adr.js",
|
|
320
|
-
"sha256": "
|
|
324
|
+
"sha256": "7928cc90575eaef4f4626849f4490631676bc4ce6eb80e8f94c99d9e215bbd77"
|
|
321
325
|
},
|
|
322
326
|
{
|
|
323
327
|
"path": "templates/lib/memory-protocol.md",
|
|
@@ -329,5 +333,5 @@
|
|
|
329
333
|
}
|
|
330
334
|
]
|
|
331
335
|
},
|
|
332
|
-
"signature": "
|
|
336
|
+
"signature": "wSJpaUNRsFXAD5Ye7V5y8FPgcvrLDEq6peQpK/RadbFsD518KglZDn5GNzV4DJE6i+mkHbH9tIwr+HIYXKN4BA=="
|
|
333
337
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
### Fixed — `init --force` больше не стирает локальную правку молча
|
|
6
|
+
|
|
7
|
+
- Из трёх путей записи `init --force` был ЕДИНСТВЕННЫМ, который перезаписывал локально
|
|
8
|
+
изменённый файл без резервной копии и без строки в отчёте — при том, что баннер успеха
|
|
9
|
+
рекомендует именно эту команду. `update` сохраняет правку по трёхсторонней сверке,
|
|
10
|
+
`update --force` кладёт `.bak` с первого дня; расходился только `init --force`.
|
|
11
|
+
- Теперь `init --force` копирует изменённый файл в `<file>.bak` ПЕРЕД перезаписью и называет
|
|
12
|
+
его в отчёте. Копия делается только если байты ОТЛИЧАЮТСЯ от шаблона: `.bak`, совпадающий
|
|
13
|
+
с шаблоном, — чистый мусор. `--dry-run --force` называет будущую копию и ничего не пишет.
|
|
14
|
+
- Поведение самого `--force` не смягчено: файл по-прежнему перезаписывается, это его смысл.
|
|
15
|
+
Менялось только то, что правка перестала исчезать бесследно.
|
|
16
|
+
|
|
3
17
|
## [1.5.1] - 2026-08-21
|
|
4
18
|
|
|
5
19
|
### Changed — the Step-8 amendment gate is a COMMAND, and the durable writers are witnessed
|
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# @dzhechkov/skills-feature-adr
|
|
2
2
|
|
|
3
|
+
Current package version: `1.5.15`. <!-- dz:version -->
|
|
4
|
+
|
|
5
|
+
Site: https://aicoding.space · Source: https://github.com/djd1m/dz-harness/tree/main/packages/@dzhechkov/skills-feature-adr
|
|
6
|
+
|
|
3
7
|
**Spec-Driven Development pipeline for AI coding agents (Claude Code, Codex, …)**
|
|
4
8
|
|
|
5
9
|
An 11-step, complexity-routed pipeline that makes an AI coding agent build a feature the way a
|
|
@@ -37,6 +41,21 @@ npx @dzhechkov/skills-feature-adr init
|
|
|
37
41
|
|
|
38
42
|
After installation, open Claude Code in your project directory and use `/feature-adr`.
|
|
39
43
|
|
|
44
|
+
Plain usage guidance joins the existing stage writer to `usage --by-stage --project` with explicit FA/
|
|
45
|
+
Wf source selection and observed receipt IDs. It preserves unknown splits/prices, caller estimates and
|
|
46
|
+
separate conservation/inventory/source verification. No billing inference, new ledger or paid replay.
|
|
47
|
+
|
|
48
|
+
Plain Step 8 bridge guidance now passes current `--round`, `--round-run` and `--task` from the existing
|
|
49
|
+
round receipt with the execution `--project`. Explicit conflicts refuse before reviewer work; the
|
|
50
|
+
bridge's invocation `runId` stays distinct from pipeline identity. Native Workflow QE remains its own
|
|
51
|
+
review path. Historical window correlation is disclosed as lower assurance, without guessed identity.
|
|
52
|
+
|
|
53
|
+
Step 7 uses the installed `scripts/build-coder-context.mjs` helper to include literal requirements,
|
|
54
|
+
plan tasks and ADR Decision/Confirmation. Workflow reads current inputs before code checkpoint
|
|
55
|
+
lookup; plain coding runs the same helper and reads or embeds its successful `promptBlock`.
|
|
56
|
+
Missing required sections, invalid files and exceeded UTF-8 bounds refuse coding instead of trimming
|
|
57
|
+
the context. Existing decision recall and code-wrapper routing remain in place.
|
|
58
|
+
|
|
40
59
|
---
|
|
41
60
|
|
|
42
61
|
## What You Get
|
|
@@ -63,7 +82,9 @@ npx @dzhechkov/skills-feature-adr init # Install core components
|
|
|
63
82
|
npx @dzhechkov/skills-feature-adr init --with-learning # + reward learning
|
|
64
83
|
npx @dzhechkov/skills-feature-adr init --knowledge-extractor # + knowledge extractor
|
|
65
84
|
npx @dzhechkov/skills-feature-adr init --with-learning --knowledge-extractor # + both
|
|
66
|
-
npx @dzhechkov/skills-feature-adr init --force # Overwrite existing files
|
|
85
|
+
npx @dzhechkov/skills-feature-adr init --force # Overwrite existing files (a locally
|
|
86
|
+
# changed file is copied to <file>.bak first,
|
|
87
|
+
# and the copy is named in the report)
|
|
67
88
|
npx @dzhechkov/skills-feature-adr init --dry-run # Preview without making changes
|
|
68
89
|
npx @dzhechkov/skills-feature-adr update # Update to latest version
|
|
69
90
|
npx @dzhechkov/skills-feature-adr remove # Clean uninstall
|
|
@@ -106,6 +127,13 @@ ARCHITECTURE → IMPLEMENTATION → CODE → QE → FLEET QE
|
|
|
106
127
|
# Full protocols + 6 extra skills, up to 7 fleet QE agents
|
|
107
128
|
```
|
|
108
129
|
|
|
130
|
+
### Checkpoint reads have one source (v1.5.14)
|
|
131
|
+
|
|
132
|
+
`loadCheckpoints` in the bundled `feature-adr.js` now builds its read command with the checkpoints blob's own
|
|
133
|
+
`checkpointReadCmd(FDIR)` instead of a hand-written duplicate, so the helper with the speaking name is the one the pipeline
|
|
134
|
+
runs. Behaviour is unchanged: for directory names with spaces, quotes and missing directories the shell output is
|
|
135
|
+
byte-identical (proved against the old command). A wiring test fails if the duplicate is re-inlined.
|
|
136
|
+
|
|
109
137
|
### Advisory micro-recall at two decision points (v1.5.9, staged)
|
|
110
138
|
|
|
111
139
|
The workflow makes one bounded decision-local recall attempt immediately before the live Step 3
|
|
@@ -1354,3 +1382,22 @@ harness-core's `src/markdown-masker.ts`. It runs without a core build. Amendment
|
|
|
1354
1382
|
and K2 share the parser while retaining their existing unclosed-block and indentation policies.
|
|
1355
1383
|
The four-space indented-code gap remains open for amendment checks and K2; swarm briefs retain their
|
|
1356
1384
|
existing masking of indented code. Versions are unchanged in this staged change.
|
|
1385
|
+
|
|
1386
|
+
### Codex companion for feature-adr
|
|
1387
|
+
|
|
1388
|
+
`dz statusline --watch --project "/path/to/worktree" --brain "/path/to/shared-brain"
|
|
1389
|
+
--slug "feature-slug" --run-id "stable-run-id"` adds an explicitly launched adjacent terminal
|
|
1390
|
+
companion, including Plain runs. Until installed, invoke the worktree-built
|
|
1391
|
+
`node packages/@dzhechkov/harness-cli/dist/bin.js statusline --watch ...`. This extends the existing
|
|
1392
|
+
command inventory. Canonical feature-adr guidance supplies the quoted producer/observer recipe: record
|
|
1393
|
+
a stable run ID and actual tier at the START of each step, then `done` on real completion; recall/teach
|
|
1394
|
+
remain scoped to the shared brain. Project run state and brain counts are separate. One slug retains
|
|
1395
|
+
one latest run; report freshness is not process liveness and stage position is not passed gates.
|
|
1396
|
+
|
|
1397
|
+
The readonly companion requires a dedicated stdout TTY, uses serial 2-second refreshes (0.25–60
|
|
1398
|
+
allowed), sanitizes/clips text and handles resize. Below 40x8 it shows a size warning. Ctrl-C/SIGTERM
|
|
1399
|
+
exit 0; output failure 1; invalid/piped watch 2. Failed/absent counts and optional values are explicit;
|
|
1400
|
+
watch v1 ETA is unavailable and global source inventory omitted. No stdin/raw mode, models, logical
|
|
1401
|
+
store writes or automatic terminal/settings changes. Normal SQLite ephemeral WAL/SHM sidecars are
|
|
1402
|
+
permitted. One-shot Claude text/JSON/ETA remain unchanged. Codex native footer capability is not
|
|
1403
|
+
asserted; parity names manual `dz statusline --watch` access.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dzhechkov/skills-feature-adr",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.15",
|
|
4
4
|
"description": "Adaptive Feature Development skill pack for Claude Code — 11-step pipeline with Complexity Router (S/M/L/XL), ADR-driven architecture, 15 agentic-qe skills, multi-agent fleet QE. Supports --full-qe, --full-qe-extended, --with-learning, and --knowledge-extractor modes.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"skills-feature-adr": "./bin/cli.js"
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"url": "git+https://github.com/djd1m/dz-harness.git",
|
|
50
50
|
"directory": "packages/@dzhechkov/skills-feature-adr"
|
|
51
51
|
},
|
|
52
|
-
"homepage": "https://
|
|
52
|
+
"homepage": "https://aicoding.space",
|
|
53
53
|
"bugs": {
|
|
54
54
|
"url": "https://github.com/djd1m/dz-harness/issues"
|
|
55
55
|
},
|
package/sbom.json
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"hashes": [
|
|
16
16
|
{
|
|
17
17
|
"alg": "SHA-256",
|
|
18
|
-
"content": "
|
|
18
|
+
"content": "26fa03f89862d03ebfc6447c866cb5d4dcbd5591ae4f8fb3a3ea08b6c586e19d"
|
|
19
19
|
}
|
|
20
20
|
]
|
|
21
21
|
},
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"hashes": [
|
|
36
36
|
{
|
|
37
37
|
"alg": "SHA-256",
|
|
38
|
-
"content": "
|
|
38
|
+
"content": "66f3b2cf7fdcf9efbf64c7d5cc36b34ffc82b151a9bc07e6fda5fc47d4fba72e"
|
|
39
39
|
}
|
|
40
40
|
]
|
|
41
41
|
},
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
71
|
"name": "dz:canonical-json-sha256-v2",
|
|
72
|
-
"value": "
|
|
72
|
+
"value": "e74b1a22e0260a61a3ab37512366402c4e6231b85625028a86219ee3f5c21e12"
|
|
73
73
|
}
|
|
74
74
|
]
|
|
75
75
|
},
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"hashes": [
|
|
100
100
|
{
|
|
101
101
|
"alg": "SHA-256",
|
|
102
|
-
"content": "
|
|
102
|
+
"content": "07ff9d955422979ea67aa5aa454c13303f5ae644efb32e5cc6f359a509638347"
|
|
103
103
|
}
|
|
104
104
|
]
|
|
105
105
|
},
|
|
@@ -289,7 +289,7 @@
|
|
|
289
289
|
"hashes": [
|
|
290
290
|
{
|
|
291
291
|
"alg": "SHA-256",
|
|
292
|
-
"content": "
|
|
292
|
+
"content": "28c265603481f976a52ea4c627e11194f3c0283801ea93d02cbb9f4248b43c68"
|
|
293
293
|
}
|
|
294
294
|
]
|
|
295
295
|
},
|
|
@@ -379,7 +379,7 @@
|
|
|
379
379
|
"hashes": [
|
|
380
380
|
{
|
|
381
381
|
"alg": "SHA-256",
|
|
382
|
-
"content": "
|
|
382
|
+
"content": "d7a2a4e56b24451da234b1ac4ef440ba9b0370617e1c0cde8ad5f3d575a53209"
|
|
383
383
|
}
|
|
384
384
|
]
|
|
385
385
|
},
|
|
@@ -389,7 +389,7 @@
|
|
|
389
389
|
"hashes": [
|
|
390
390
|
{
|
|
391
391
|
"alg": "SHA-256",
|
|
392
|
-
"content": "
|
|
392
|
+
"content": "db79f8d026cc47edd1e5d2f30d0e1455c55c570dd022d549d440985a3e5940a5"
|
|
393
393
|
}
|
|
394
394
|
]
|
|
395
395
|
},
|
|
@@ -399,7 +399,7 @@
|
|
|
399
399
|
"hashes": [
|
|
400
400
|
{
|
|
401
401
|
"alg": "SHA-256",
|
|
402
|
-
"content": "
|
|
402
|
+
"content": "d7a967926feec9b0ec173ac7042ae3abd368644d8e1dba9a81a770794417fcb3"
|
|
403
403
|
}
|
|
404
404
|
]
|
|
405
405
|
},
|
|
@@ -623,13 +623,23 @@
|
|
|
623
623
|
}
|
|
624
624
|
]
|
|
625
625
|
},
|
|
626
|
+
{
|
|
627
|
+
"type": "file",
|
|
628
|
+
"name": "templates/.claude/skills/feature-adr/scripts/build-coder-context.mjs",
|
|
629
|
+
"hashes": [
|
|
630
|
+
{
|
|
631
|
+
"alg": "SHA-256",
|
|
632
|
+
"content": "19c3991bfb5e88205c9ff6d4d44037c136a190581bab199d3928196e4616fe15"
|
|
633
|
+
}
|
|
634
|
+
]
|
|
635
|
+
},
|
|
626
636
|
{
|
|
627
637
|
"type": "file",
|
|
628
638
|
"name": "templates/.claude/skills/feature-adr/scripts/check-plan-completeness.mjs",
|
|
629
639
|
"hashes": [
|
|
630
640
|
{
|
|
631
641
|
"alg": "SHA-256",
|
|
632
|
-
"content": "
|
|
642
|
+
"content": "8b93949ce4f671d932c5389050db3a3e2750efcbed69681d69f392ccf4d2a168"
|
|
633
643
|
}
|
|
634
644
|
]
|
|
635
645
|
},
|
|
@@ -799,7 +809,7 @@
|
|
|
799
809
|
"hashes": [
|
|
800
810
|
{
|
|
801
811
|
"alg": "SHA-256",
|
|
802
|
-
"content": "
|
|
812
|
+
"content": "7928cc90575eaef4f4626849f4490631676bc4ce6eb80e8f94c99d9e215bbd77"
|
|
803
813
|
}
|
|
804
814
|
]
|
|
805
815
|
},
|
package/src/commands/init.js
CHANGED
|
@@ -54,14 +54,15 @@ function showKeysariumIntegration(keysariumManifest) {
|
|
|
54
54
|
|
|
55
55
|
// Copies a component file-by-file with per-file overwrite protection:
|
|
56
56
|
// - destination missing -> write, record in `written`
|
|
57
|
-
// - destination exists + --force ->
|
|
57
|
+
// - destination exists + --force -> BACK UP to a .bak sibling if the bytes differ,
|
|
58
|
+
// then overwrite; record in `written` (+ `backedUp`)
|
|
58
59
|
// - destination exists, no --force -> do NOT write, record in `preserved`
|
|
59
60
|
// In dry-run mode nothing is written, but the same written/preserved
|
|
60
61
|
// classification is produced.
|
|
61
62
|
// Returns { missing, fileCount } where `missing` means the template source
|
|
62
63
|
// was absent on disk and `fileCount` is how many files the template provides.
|
|
63
64
|
function installComponent(key, comp, templatesDir, targetDir, opts) {
|
|
64
|
-
const { force, dryRun, written, preserved, hashes } = opts;
|
|
65
|
+
const { force, dryRun, written, preserved, backedUp, hashes } = opts;
|
|
65
66
|
const src = path.join(templatesDir, comp.src);
|
|
66
67
|
const destRoot = path.join(targetDir, comp.src);
|
|
67
68
|
|
|
@@ -89,12 +90,20 @@ function installComponent(key, comp, templatesDir, targetDir, opts) {
|
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
for (const entry of entries) {
|
|
92
|
-
|
|
93
|
+
const existed = fileExists(entry.destFile);
|
|
94
|
+
if (existed && !force) {
|
|
93
95
|
preserved.push(entry.rel);
|
|
94
96
|
continue;
|
|
95
97
|
}
|
|
98
|
+
// `update --force` has backed edits up to a `.bak` sibling since day one; `init --force` was
|
|
99
|
+
// the ONE path that overwrote silently — and the success banner recommends exactly that
|
|
100
|
+
// command, so a locally-edited workflow could vanish with no notice and no copy.
|
|
101
|
+
// Only DIFFERING bytes are backed up: a `.bak` identical to the template is pure litter.
|
|
102
|
+
const differs = existed && hashFile(entry.destFile) !== hashFile(entry.srcFile);
|
|
103
|
+
if (differs && backedUp) backedUp.push(entry.rel);
|
|
96
104
|
if (!dryRun) {
|
|
97
105
|
ensureDir(path.dirname(entry.destFile));
|
|
106
|
+
if (differs) fs.copyFileSync(entry.destFile, `${entry.destFile}.bak`);
|
|
98
107
|
fs.copyFileSync(entry.srcFile, entry.destFile);
|
|
99
108
|
// Record the SHA-256 of the TEMPLATE bytes we just installed (not the
|
|
100
109
|
// dest) as this file's baseline. This makes baseline == mine immediately
|
|
@@ -110,6 +119,23 @@ function installComponent(key, comp, templatesDir, targetDir, opts) {
|
|
|
110
119
|
return { missing: false, fileCount: entries.length };
|
|
111
120
|
}
|
|
112
121
|
|
|
122
|
+
// Print the block of locally-changed files that were (or would be) backed up before --force
|
|
123
|
+
// overwrote them. Silence here is what the field report caught: the operator had no way to learn
|
|
124
|
+
// that their edit was gone, let alone where the copy is.
|
|
125
|
+
function printBackedUpBlock(backedUp, dryRun) {
|
|
126
|
+
if (backedUp.length === 0) return;
|
|
127
|
+
const MAX_SHOWN = 10; // `printPreservedBlock` держит свою копию — она объявлена в его теле
|
|
128
|
+
console.log('');
|
|
129
|
+
const verb = dryRun ? 'would be backed up' : 'backed up';
|
|
130
|
+
warn(`${backedUp.length} locally-changed file(s) ${verb} to a .bak sibling before being overwritten:`);
|
|
131
|
+
for (const rel of backedUp.slice(0, MAX_SHOWN)) {
|
|
132
|
+
console.log(dim(` ${rel} -> ${rel}.bak`));
|
|
133
|
+
}
|
|
134
|
+
if (backedUp.length > MAX_SHOWN) {
|
|
135
|
+
console.log(dim(` …and ${backedUp.length - MAX_SHOWN} more`));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
113
139
|
// Print the block of pre-existing files that were (or would be) preserved
|
|
114
140
|
function printPreservedBlock(preserved, dryRun) {
|
|
115
141
|
console.log('');
|
|
@@ -233,6 +259,7 @@ async function run(options) {
|
|
|
233
259
|
const installedFiles = []; // files written (or would-write in dry-run)
|
|
234
260
|
const installedHashes = {}; // rel -> sha256 of the TEMPLATE bytes installed (baseline)
|
|
235
261
|
const preservedFiles = []; // pre-existing files NOT overwritten (no --force)
|
|
262
|
+
const backedUpFiles = []; // locally-changed files copied to .bak before --force overwrote them
|
|
236
263
|
const completedKeys = []; // component keys processed so far (for partial manifest)
|
|
237
264
|
const installedOptionalKeys = [];
|
|
238
265
|
let stepNum = 0;
|
|
@@ -246,7 +273,7 @@ async function run(options) {
|
|
|
246
273
|
|
|
247
274
|
installComponent(key, comp, templatesDir, targetDir, {
|
|
248
275
|
force, dryRun, written: installedFiles, preserved: preservedFiles,
|
|
249
|
-
hashes: installedHashes,
|
|
276
|
+
backedUp: backedUpFiles, hashes: installedHashes,
|
|
250
277
|
});
|
|
251
278
|
completedKeys.push(key);
|
|
252
279
|
}
|
|
@@ -262,7 +289,7 @@ async function run(options) {
|
|
|
262
289
|
|
|
263
290
|
const res = installComponent(key, comp, templatesDir, targetDir, {
|
|
264
291
|
force, dryRun, written: installedFiles, preserved: preservedFiles,
|
|
265
|
-
hashes: installedHashes,
|
|
292
|
+
backedUp: backedUpFiles, hashes: installedHashes,
|
|
266
293
|
});
|
|
267
294
|
if (!res.missing && res.fileCount > 0) {
|
|
268
295
|
installedOptionalKeys.push(key);
|
|
@@ -296,6 +323,10 @@ async function run(options) {
|
|
|
296
323
|
if (dryRun) {
|
|
297
324
|
console.log('');
|
|
298
325
|
info(`Dry run: ${installedFiles.length} file(s) would be written, ${preservedFiles.length} pre-existing file(s) would be preserved.`);
|
|
326
|
+
// Отчёт о копиях стоит СНАРУЖИ стража сохранённых: при --force сохранять нечего, список
|
|
327
|
+
// пуст, и внутри стража блок был бы недостижим ровно в том случае, ради которого написан.
|
|
328
|
+
// Пустой список функция отсекает сама.
|
|
329
|
+
printBackedUpBlock(backedUpFiles, true);
|
|
299
330
|
if (preservedFiles.length > 0) {
|
|
300
331
|
printPreservedBlock(preservedFiles, true);
|
|
301
332
|
}
|
|
@@ -318,10 +349,11 @@ async function run(options) {
|
|
|
318
349
|
process.exit(0);
|
|
319
350
|
}
|
|
320
351
|
|
|
352
|
+
printBackedUpBlock(backedUpFiles, false); // снаружи: при --force preservedFiles пуст
|
|
321
353
|
if (preservedFiles.length > 0) {
|
|
322
354
|
printPreservedBlock(preservedFiles, false);
|
|
323
|
-
console.log('');
|
|
324
355
|
}
|
|
356
|
+
if (preservedFiles.length > 0 || backedUpFiles.length > 0) console.log('');
|
|
325
357
|
|
|
326
358
|
// ── f) Write manifest ──────────────────────────────────────────────────
|
|
327
359
|
const pkgPath = path.resolve(__dirname, '../../package.json');
|
|
@@ -562,13 +562,91 @@ only the statusline:
|
|
|
562
562
|
|
|
563
563
|
**Record the panel at the START of every step, not only at Steps 0/8/9.** The panel shows the last step
|
|
564
564
|
that reported; a pipeline that reports three times per run shows a stale step for most of its life. Emit
|
|
565
|
-
`dz statusline --fa-record --slug <slug> --step "<Step N Name>" --recalled <n> --stored <n>` as the first
|
|
565
|
+
`dz statusline --fa-record --project "<worktree>" --slug "<slug>" --run-id "<stable-run-id>" --tier M --step "<Step N Name>" --recalled <n> --stored <n>` as the first
|
|
566
566
|
action of each step. The recall/teach counts only change at Steps 0/8/9; the *step label* changes at every
|
|
567
567
|
one of them.
|
|
568
568
|
|
|
569
569
|
*Honesty note:* the panel is live only insofar as the pipeline records state — it reflects what the
|
|
570
570
|
pipeline actually did with the loop (recalls that ran, stores that landed), not an aspirational count.
|
|
571
571
|
|
|
572
|
+
### Plain observed usage receipts
|
|
573
|
+
|
|
574
|
+
Use the existing witnessed writer for usage you actually observed. At a real stage boundary,
|
|
575
|
+
capture the execution project, stable run/task, verbatim stage, actual model/family/role, attempt,
|
|
576
|
+
tier/mode and source window/IDs available to this host. Missing fields remain null with their reason;
|
|
577
|
+
do not infer input/cache from total, price from a model family, or tokens from invocation budgets.
|
|
578
|
+
|
|
579
|
+
```bash
|
|
580
|
+
dz feature-adr-record --kind ledger --stage "$CURRENT_STAGE" --project "$EXECUTION_PROJECT" \
|
|
581
|
+
--row "$OBSERVED_STAGE_ROW_JSON" --rollout-id "$ACTUAL_SESSION_ID" --turn-id "$ACTUAL_TURN_ID" --json
|
|
582
|
+
dz usage --by-stage --project "$EXECUTION_PROJECT" --source fa-ledger --run "$STABLE_RUN_ID" --json
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
`OBSERVED_STAGE_ROW_JSON` is real host metadata: `runId`, `taskId`, `stage`, `model`, `family`, `role`,
|
|
586
|
+
`attempt`, `tier`, `mode`, `tokens`/dimensions when observed, and optional separate `estimate` with
|
|
587
|
+
tokens/costUsd/method/source/capturedAt. Omit selectors not known; window/cwd/model-only correlation
|
|
588
|
+
is labelled legacy-window and cannot claim exact source verification. Source roots can be named with
|
|
589
|
+
`--codex-sessions`. Exact IDs are validated against existing receipts; no new IDs or recall/teach occur.
|
|
590
|
+
The source receipt subset is captured once; later source append cannot enlarge the old row.
|
|
591
|
+
Captured payload integrity and every pricing-bearing dimension must match the original scoped source.
|
|
592
|
+
A reported monetary amount belongs to one observation, not each expanded token receipt. Preserve an
|
|
593
|
+
actual observation ID/scope/basis in optional `reportedCostObservation: { id, scope, basis }` within
|
|
594
|
+
`--row` when known; otherwise a captured source scope supplies a stable identity and unrelated money
|
|
595
|
+
attribution stays unavailable. Reimports of the same observation count once; conflicting amounts are
|
|
596
|
+
diagnosed. Missing money differs from zero. Exports must avoid every selected authoritative source,
|
|
597
|
+
including custom run directories and symlink aliases. Invalid Claude counters retain nulls/diagnostics;
|
|
598
|
+
a declared invalid total cannot derive a replacement, and accounting validity does not rewrite the
|
|
599
|
+
actual generation outcome.
|
|
600
|
+
|
|
601
|
+
For Wf, use `--source workflow-budget --run <id>` and optional `--run-dir <dir>` for its existing
|
|
602
|
+
budget/trace/state. Auto source collisions require an explicit source; joined Wf summary projections
|
|
603
|
+
never add another cost. Preserve reported total basis and cache/reasoning subsets. Wf budget.spent
|
|
604
|
+
counts dispatch units; native Workflow's existing budget delta is output-only. Neither is raw total.
|
|
605
|
+
|
|
606
|
+
Reports separate conservation, expected inventory and independent amount verification. Without
|
|
607
|
+
a same-scope witness, verified totals are null even when reported values conserve. Unknown rates or
|
|
608
|
+
split keep primary estimated USD null; static family estimates, provider-reported USD and caller
|
|
609
|
+
pre-run estimates are separate, never current exact prices or billed amounts. Billing remains unobserved.
|
|
610
|
+
|
|
611
|
+
### Codex companion terminal (Plain included)
|
|
612
|
+
|
|
613
|
+
Open an adjacent terminal or a manual tmux split and launch the observer explicitly. Codex does not
|
|
614
|
+
have a dz native command-provider footer. Keep the producer's project, slug and stable run ID equal to
|
|
615
|
+
the observer's; use the actual complexity tier at the START of every active step. Brain is the shared
|
|
616
|
+
learning store for recall/teach, while project is the worktree containing run slots and branch.
|
|
617
|
+
|
|
618
|
+
```bash
|
|
619
|
+
# Set these to your actual absolute paths. Use the worktree build until the change is installed.
|
|
620
|
+
PANEL_CLI="/path/to/worktree/packages/@dzhechkov/harness-cli/dist/bin.js"
|
|
621
|
+
PANEL_PROJECT="/path/to/worktree"
|
|
622
|
+
PANEL_BRAIN="/path/to/canonical-brain"
|
|
623
|
+
PANEL_SLUG="feature-slug"
|
|
624
|
+
PANEL_RUN="feature-20261002-1" # choose once per invocation, retain at every step
|
|
625
|
+
node "$PANEL_CLI" statusline --watch --project "$PANEL_PROJECT" --brain "$PANEL_BRAIN" \
|
|
626
|
+
--slug "$PANEL_SLUG" --run-id "$PANEL_RUN" --interval 2
|
|
627
|
+
# In the producer terminal, at the START of each real step (example: tier M):
|
|
628
|
+
node "$PANEL_CLI" statusline --fa-record --project "$PANEL_PROJECT" --slug "$PANEL_SLUG" \
|
|
629
|
+
--run-id "$PANEL_RUN" --tier M --step "Step 7 Code" --recalled 3 --stored 0
|
|
630
|
+
# Only after the run actually completes; this is not a claim that QE passed:
|
|
631
|
+
node "$PANEL_CLI" statusline --fa-record --project "$PANEL_PROJECT" --slug "$PANEL_SLUG" \
|
|
632
|
+
--run-id "$PANEL_RUN" --tier M --step "done" --recalled 3 --stored 0
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
Use `dz recall ... --project "$PANEL_BRAIN"` and `dz teach ... --project "$PANEL_BRAIN"` for actual
|
|
636
|
+
learning. Supply measured cumulative counters, not the example numbers. The observer counts its brain
|
|
637
|
+
source directly; the slot's producer pool is not a shared-brain inventory. One slug holds one latest
|
|
638
|
+
run, so a replacement makes an exact old selection missing. No selectors means visibly automatic
|
|
639
|
+
selection. Freshness measures producer-report age, not process liveness: fresh <30 minutes, stale
|
|
640
|
+
30–<90, expired >=90; completed remains completed. Stage position is not completed gates.
|
|
641
|
+
|
|
642
|
+
Watch v1 displays ETA unavailable, unknown optional values and unavailable failed/absent learning
|
|
643
|
+
sources, and omits ambiguous global source inventory. It uses escaped ASCII text, a dedicated stdout
|
|
644
|
+
TTY, 0.25–60 second intervals (default 2), and a size warning below 40 columns/8 rows. Ctrl-C/SIGTERM
|
|
645
|
+
exit 0; output failures exit 1; piped output and watch+JSON/install/record combinations exit 2.
|
|
646
|
+
Observation never reads stdin, runs models or writes logical store state. SQLite-managed ephemeral
|
|
647
|
+
WAL/SHM files are permitted; no application locks, repair or schema changes occur. One-shot Claude
|
|
648
|
+
statusline/JSON and its ETA keep their existing behavior. Do not start a terminal automatically.
|
|
649
|
+
|
|
572
650
|
### What changes with `--full-qe`
|
|
573
651
|
|
|
574
652
|
Full agentic-qe protocols for the same 9 core skills. No new agents, just deeper methodology.
|
|
@@ -235,6 +235,16 @@ C2 recognises JS/TS, pytest, Go, Rust, JVM and .NET test paths, extensible per p
|
|
|
235
235
|
|
|
236
236
|
Never proceed on a non-zero exit, and never treat empty output as a pass — the last line
|
|
237
237
|
(`K2 plan-completeness: PASS|FAIL|NOT-ESTABLISHED`) is the verdict, and its absence is not one.
|
|
238
|
+
|
|
239
|
+
**Where an id counts (the default since 2026-09-27, owner decision).** C1 and C8 read the plan's
|
|
240
|
+
TASK LINES only: a heading, a list item or a table row. An `ADR-<n>` or `FR-<n>` that appears only
|
|
241
|
+
in a prose paragraph, a fenced code block (the SPARC-GOAP ```yaml goal state included), an HTML
|
|
242
|
+
comment, the `## Amendments` section or the `EXPECTED_CODE_TARGETS:` block is a mention, not a task,
|
|
243
|
+
and the gate FAILs it with `(cited only outside task lines)`. Write the id on the FIRST line of the
|
|
244
|
+
task that implements it: a wrapped continuation line of a list item is not read either. Measured on the archive when the default changed: 56 of 102 plans that had
|
|
245
|
+
passed would fail this reader, so a plan written before that date may be red on a re-check — move
|
|
246
|
+
the citation onto a task line, or re-check that one plan with `--no-require-task-lines` and say so
|
|
247
|
+
in the checkpoint banner.
|
|
238
248
|
What it checks: C1 every ADR **decision** (a `# ADR-NNN` / `## ADR-NNN` heading INSIDE the file, not
|
|
239
249
|
just the filename prefix — a file with several headings owes several plan citations) has a plan task
|
|
240
250
|
citing it · C2 every ADR Confirmation test path is named in the plan · C3 the `EXPECTED_CODE_TARGETS:`
|
|
@@ -26,6 +26,35 @@ opus (complex code generation)
|
|
|
26
26
|
|
|
27
27
|
### 1. Pre-Implementation Checklist
|
|
28
28
|
|
|
29
|
+
### Current literal context (plain and delegated coding)
|
|
30
|
+
|
|
31
|
+
Before coding or delegating, run the installed helper beside this module. Set `CONTEXT_HELPER` to
|
|
32
|
+
the absolute `scripts/build-coder-context.mjs` path of the skill installation you are reading;
|
|
33
|
+
set `FEATURE_DIR` to the absolute target `features/<slug>` directory and use the actual tier:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
node "$CONTEXT_HELPER" "$FEATURE_DIR" --tier=M
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The command emits exactly one JSON envelope and exits 0 only for `status: "complete"`. On any
|
|
40
|
+
nonzero exit, unavailable/incomplete status, malformed JSON or required missing/empty section,
|
|
41
|
+
stop before coding and repair the named input. Never paste a partial result as complete. A missing
|
|
42
|
+
helper requires restoring this skill installation, not inventing a replacement block.
|
|
43
|
+
|
|
44
|
+
For every delegated coder assignment, paste the successful envelope's literal `promptBlock` into
|
|
45
|
+
the actual prompt, then append the existing advisory decision-recall block once. Keep the source
|
|
46
|
+
paths below for deeper reading. For single-agent in-session coding, read this generated block
|
|
47
|
+
directly before implementing. Requirements and plan are included in full; each ADR supplies its
|
|
48
|
+
Decision and Confirmation with source labels. M/L/XL require at least one ADR; S can have none.
|
|
49
|
+
|
|
50
|
+
The same canonical helper is used by the programmatic Workflow before code checkpoint lookup.
|
|
51
|
+
It fingerprints full current inputs and binds the prompt separately, so changed documents cannot
|
|
52
|
+
reuse old code. The plain mode boundary is an executable helper command plus these required
|
|
53
|
+
read/embedding instructions; there is no separately automated plain dispatcher. Pure/fixture tests
|
|
54
|
+
do not establish a live model relay's authenticity. Helper bounds are 64 documents, 256 KiB/file,
|
|
55
|
+
1 MiB read and 96 KiB UTF-8 for the entire labelled block; exceeded bounds refuse without trimming.
|
|
56
|
+
These are document limits, not a new limit on the existing coder wrapper's final prompt.
|
|
57
|
+
|
|
29
58
|
Before writing any code:
|
|
30
59
|
- [ ] Read existing similar implementations in codebase
|
|
31
60
|
- [ ] Identify naming conventions (files, classes, functions, variables)
|
|
@@ -23,6 +23,30 @@ sonnet (analytical evaluation)
|
|
|
23
23
|
|
|
24
24
|
## Protocol
|
|
25
25
|
|
|
26
|
+
### Bridge identity for plain Step 8
|
|
27
|
+
|
|
28
|
+
When the plain host invokes the existing Claude review bridge, take round number, pipeline run and
|
|
29
|
+
task from the current round receipt/state in the execution project. Pass the fields actually present:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
dz qe-bridge --family claude --slug "$FEATURE_SLUG" --project "$EXECUTION_PROJECT" \
|
|
33
|
+
--round "$CURRENT_ROUND" --round-run "$CURRENT_ROUND_RUN" --task "$CURRENT_TASK" \
|
|
34
|
+
--coder-family codex
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Do not mint missing identifiers or point `--project` at a separate learning brain. Explicit identity
|
|
38
|
+
must agree with one readable open round before any probe or review child; conflicts refuse with exit 2.
|
|
39
|
+
The bridge freezes that snapshot for the signoff. Signoff `roundRun` is the pipeline run; its existing
|
|
40
|
+
`runId` identifies the separate bridge invocation and audit filenames. No-flags standalone reviews
|
|
41
|
+
retain best-effort lookup and visibly unbound provenance when authority is absent or unavailable.
|
|
42
|
+
|
|
43
|
+
Round close validates every present identity field before selection. Full, partial and genuinely
|
|
44
|
+
identity-free window assurance appear as `round-run-task`, `partial-identity` and `legacy-window`.
|
|
45
|
+
Malformed or foreign claims cannot become a manual-close fallback. This contract governs the
|
|
46
|
+
existing plain bridge and control-review caller; native Workflow QE already runs its own review and
|
|
47
|
+
must not invoke a second bridge to manufacture this receipt. Local fake-child tests do not establish
|
|
48
|
+
a live Claude model roundtrip or secure every native Codex QE receipt.
|
|
49
|
+
|
|
26
50
|
### 1. Smoke Tests (All tiers)
|
|
27
51
|
|
|
28
52
|
```
|
|
@@ -205,7 +229,9 @@ list), grep for unfinished-stub markers: `TODO` / `FIXME` / `HACK` / `XXX` / `PL
|
|
|
205
229
|
file:line, UNLESS the line carries an inline `no-stubs: <reason>` waiver WITH a non-empty reason, or
|
|
206
230
|
`.dz/guard.json` `stubWaivers` lists the path WITH a reason. A REASONLESS waiver is itself a HIGH gap,
|
|
207
231
|
never an exemption. Cross-check mechanically: `dz guard check --op publish --json` runs the same scan
|
|
208
|
-
as the SOFT `no-stubs` rule over the working-tree diff.
|
|
232
|
+
as the SOFT `no-stubs` rule over the working-tree diff.
|
|
233
|
+
After the Step-7 code has landed, run `dz guard check --op code --json` and treat a HARD `block` verdict
|
|
234
|
+
as a HIGH finding naming the drifted file. When you QUOTE a marker in `08_qe_report.md`,
|
|
209
235
|
backtick it so the report itself scans clean (the claim-check forbidden-phrase convention). Record the
|
|
210
236
|
verdict in the ADR Fitness section.
|
|
211
237
|
|
|
@@ -311,6 +337,9 @@ Compile all findings into a structured report:
|
|
|
311
337
|
✅ READY FOR MERGE | ❌ NEEDS FIXES | ⚠️ CONDITIONAL APPROVAL
|
|
312
338
|
```
|
|
313
339
|
|
|
340
|
+
Settle a cross-family re-QE debt with `dz reqe --slug <s> --done --report <08b>`.
|
|
341
|
+
For `dz reqe --done`, exit 3 means the review settled but named BLOCKER/HIGH findings — stop and surface them to the owner.
|
|
342
|
+
|
|
314
343
|
### 7.1 Findings ledger (machine-readable)
|
|
315
344
|
|
|
316
345
|
Prose is for people; `dz score`/`dz recap` need a machine-readable surface too (qe-findings-record,
|
|
@@ -373,9 +402,13 @@ resume guard at all before this).
|
|
|
373
402
|
Otherwise — QE ran fresh in this pass — after `08_qe_report.md` is written and the grade is final, run:
|
|
374
403
|
|
|
375
404
|
```bash
|
|
376
|
-
dz feature-adr-record --kind ledger --stage qe --slug <slug> --row '<json>' --
|
|
405
|
+
dz feature-adr-record --kind ledger --stage qe --slug <slug> --row '<json>' --json
|
|
377
406
|
```
|
|
378
407
|
|
|
408
|
+
fix-round-1 (Codex r1 HIGH finding 4, ADR-001 D5): no `--auto` here. `--auto` is the trusted marker
|
|
409
|
+
of an AUTOMATED pipeline run and requires an experiment envelope that the manual path does not have;
|
|
410
|
+
this plain-mode row is written without it.
|
|
411
|
+
|
|
379
412
|
`<json>` carries the same fields the ultracode pipeline writes for this row: `reviewer` (the model
|
|
380
413
|
that reviewed, or `null` if unknown — never guessed), `reviewerFamily` (`claude`|`codex`|`null` when
|
|
381
414
|
the reviewer identity is not one of the two known families — never guessed as `claude`), `qeRole`
|