@dzhechkov/harness-cli 0.4.6 → 0.5.1
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 +125 -21
- package/LICENSE +21 -0
- package/README.md +501 -30
- package/dist/bin.d.ts +10 -0
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +45 -12
- package/dist/bin.js.map +1 -1
- package/dist/cli.d.ts +110 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2206 -195
- package/dist/cli.js.map +1 -1
- package/dist/core-compat.d.ts +106 -0
- package/dist/core-compat.d.ts.map +1 -0
- package/dist/core-compat.js +252 -0
- package/dist/core-compat.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
- package/sbom.json +280 -20
- package/src/bin.ts +43 -12
- package/src/cli.ts +2315 -184
- package/src/core-compat.ts +240 -0
- package/src/index.ts +4 -0
package/README.md
CHANGED
|
@@ -125,6 +125,140 @@ point any tool at (a skill is just Markdown). Dedicated targets are on the [road
|
|
|
125
125
|
**❌ No target applies:** `nemoclaw` (NVIDIA agent-safety runtime — not a code editor, no rules file) ·
|
|
126
126
|
`v0` (UI-only, no repo file). *(`pi` is a real coder but reads `AGENTS.md` → covered by `agents-md`.)*
|
|
127
127
|
|
|
128
|
+
#### `--target` aliases and did-you-mean
|
|
129
|
+
|
|
130
|
+
`--target claude` used to be rejected outright — the canonical name is `claude-code`, and the error
|
|
131
|
+
just re-printed the list. All **eight** `--target`-taking commands (`init`, `verify`, `install`,
|
|
132
|
+
`compose`, `setup`, `upgrade`, `parity`, `feature-adr-setup`) now resolve the value first.
|
|
133
|
+
|
|
134
|
+
*(This sentence used to say "every" and name only seven: `dz parity` was missed, and shipped the
|
|
135
|
+
original defect verbatim. It is now checked rather than promised — `test/target-alias-cli.test.ts`
|
|
136
|
+
asserts that no command reads `--target` without reaching the resolver, and that every command whose
|
|
137
|
+
`--help` advertises `--target` appears in the per-command sweep.)*
|
|
138
|
+
|
|
139
|
+
**Accepted aliases** (a table, so adding one is a data edit):
|
|
140
|
+
|
|
141
|
+
| You type | You get | Why it is a row |
|
|
142
|
+
|----------|---------|-----------------|
|
|
143
|
+
| `claude` · `cc` | `claude-code` | the tool's everyday name |
|
|
144
|
+
| `agents` | `agents-md` | the everyday name of the `AGENTS.md` target |
|
|
145
|
+
| `gpt` · `openai` | `codex` | the vendor name, not the CLI's |
|
|
146
|
+
|
|
147
|
+
Case, padding and separators are handled **without** a row: `CLAUDE`, `Claude_Code`, `claudecode`
|
|
148
|
+
and ` claude-code ` all resolve to `claude-code`; `agentsmd` and `agents.md` resolve to `agents-md`.
|
|
149
|
+
|
|
150
|
+
**A typo is SUGGESTED, never silently accepted** — installing to the wrong target on a guess is worse
|
|
151
|
+
than one round-trip:
|
|
152
|
+
|
|
153
|
+
```console
|
|
154
|
+
$ dz init --target clade-code --preset devops > out.txt # the refusal is on STDERR
|
|
155
|
+
dz init: unknown --target "clade-code" — did you mean "claude-code"?
|
|
156
|
+
--target must be one of: agents-md, claude-code, codex, copilot, cursor, gemini, hermes, openclaude, opencode, windsurf
|
|
157
|
+
$ echo $?
|
|
158
|
+
1
|
|
159
|
+
$ wc -c out.txt
|
|
160
|
+
0 out.txt # stdout stays a clean data channel, even on a refusal
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Both lines go to stderr** — the refusal, like the alias note below, is diagnosis, not data. `dz
|
|
164
|
+
parity --target <bad> --json` likewise writes its structured error to stderr and leaves stdout empty,
|
|
165
|
+
so `| jq` is never handed a diagnostic.
|
|
166
|
+
|
|
167
|
+
An ambiguous prefix gets no guess at all (`--target co` could be `codex` or `copilot`), and neither
|
|
168
|
+
does nonsense (`--target totally-bogus` prints the plain list). When an alias IS accepted, the
|
|
169
|
+
substitution is announced **on stderr**, so piped stdout stays machine-readable:
|
|
170
|
+
|
|
171
|
+
```console
|
|
172
|
+
$ dz init --target claude --preset devops > installed.txt
|
|
173
|
+
dz init: --target "claude" → claude-code (alias)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**When this matters:** you are following a blog post or a teammate's snippet that says `--target claude`.
|
|
177
|
+
It now works, and you are told what it resolved to.
|
|
178
|
+
|
|
179
|
+
### `dz list` — one broken skill never hides the rest
|
|
180
|
+
|
|
181
|
+
`dz list` used to abort on the FIRST unparseable `SKILL.md`: exit 1, an error naming neither the file
|
|
182
|
+
nor a count, and every other skill in the tree invisible. A pack you installed could blank your whole
|
|
183
|
+
listing. Now the loadable skills are listed on **stdout** and the unloadable ones are named on
|
|
184
|
+
**stderr**:
|
|
185
|
+
|
|
186
|
+
```console
|
|
187
|
+
$ dz list --skills-dir .claude/skills
|
|
188
|
+
105 skill(s) in /home/you/proj/.claude/skills:
|
|
189
|
+
|
|
190
|
+
api-design Designs REST and GraphQL APIs with OpenAPI specs…
|
|
191
|
+
…103 more…
|
|
192
|
+
test-writer Writes focused unit and integration tests…
|
|
193
|
+
$ echo $?
|
|
194
|
+
1
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
…with the diagnosis kept out of the data:
|
|
198
|
+
|
|
199
|
+
```console
|
|
200
|
+
$ dz list --skills-dir .claude/skills 2>/dev/null # stdout only — clean, pipeable
|
|
201
|
+
105 skill(s) in …
|
|
202
|
+
|
|
203
|
+
$ dz list --skills-dir .claude/skills 1>/dev/null # stderr only — the actionable part
|
|
204
|
+
dz list: 105 listed, 1 skipped in /home/you/proj/.claude/skills
|
|
205
|
+
⚠ 1 skill(s) skipped (unparseable SKILL.md):
|
|
206
|
+
/home/you/proj/.claude/skills/broken-one/SKILL.md
|
|
207
|
+
SKILL.md must begin with a "---" frontmatter fence
|
|
208
|
+
(line 1: "# Broken One")
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
The full contract:
|
|
212
|
+
|
|
213
|
+
| valid skills | skipped | stdout | stderr | exit |
|
|
214
|
+
|--------------|---------|--------|--------|------|
|
|
215
|
+
| >0 | 0 | the listing | *empty* | 0 |
|
|
216
|
+
| >0 | >0 | the listing of the valid ones | named summary | 1 |
|
|
217
|
+
| 0 | >0 | *nothing* | named summary (`0 listed, N skipped`) | 1 |
|
|
218
|
+
| 0 | 0 | *nothing* | `dz list: no skills found in <dir>` | 1 |
|
|
219
|
+
|
|
220
|
+
`dz init`, `dz install` and `dz sync` behave the same way — the good skills are installed, the bad ones
|
|
221
|
+
are named, and the command exits 1.
|
|
222
|
+
|
|
223
|
+
**Two failure kinds, two headers, two subjects.** A skill that will not PARSE and a skill that will not
|
|
224
|
+
WRITE are different accusations, so `dz init` reports them separately:
|
|
225
|
+
|
|
226
|
+
```console
|
|
227
|
+
$ dz init --target claude-code --skills-dir ./skills --project ./proj
|
|
228
|
+
dz init --target claude-code: 1 skill(s), 1 file(s) written, 0 skipped
|
|
229
|
+
dz init: 1 installed, 1 failed to write # ← stderr
|
|
230
|
+
✗ 1 skill(s) failed to install (compile/write error):
|
|
231
|
+
alpha
|
|
232
|
+
EEXIST: file already exists, mkdir './proj/.claude/skills/alpha'
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
The header names the **target**, not `alpha/SKILL.md` — which is perfectly valid. (It used to print
|
|
236
|
+
`⚠ 1 skill(s) skipped (unparseable SKILL.md)` and quote `line 1: "---"`, a valid frontmatter fence, as
|
|
237
|
+
its evidence: a failure that names the wrong artifact is worse than an anonymous one.)
|
|
238
|
+
|
|
239
|
+
`dz install` renders the offending path **relative to the package**
|
|
240
|
+
and says so explicitly, because a `node_modules/**` path is not something you can act on:
|
|
241
|
+
|
|
242
|
+
```console
|
|
243
|
+
$ dz install @someone/skills-pack
|
|
244
|
+
dz install @someone/skills-pack: 12 skill(s), 24 file(s) written, 0 skipped
|
|
245
|
+
dz install: @someone/skills-pack ships 1 unparseable skill(s) —
|
|
246
|
+
⚠ 1 skill(s) skipped (unparseable SKILL.md):
|
|
247
|
+
skills/broken-one/SKILL.md
|
|
248
|
+
SKILL.md must begin with a "---" frontmatter fence
|
|
249
|
+
This is a defect in the package, not in your project.
|
|
250
|
+
Workaround: npx -y @someone/skills-pack init
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**When this matters:** a package you installed shipped a broken skill — you still see everything else,
|
|
254
|
+
you know exactly which file is at fault, and you know whose defect it is.
|
|
255
|
+
|
|
256
|
+
> **`dz` requires `@dzhechkov/harness-core >= 0.4.7`.** If you ever see
|
|
257
|
+
> `dz: needs @dzhechkov/harness-core >= 0.4.7, found 0.4.1`, a stale core was reused from a cache:
|
|
258
|
+
> `rm -rf ~/.npm/_npx && npx @dzhechkov/harness-cli@latest --version`. That named message replaced a
|
|
259
|
+
> bare `SyntaxError: … does not provide an export named 'GRADE_SUCCESS_FLOOR'` that used to kill even
|
|
260
|
+
> `dz --version`.
|
|
261
|
+
|
|
128
262
|
> **"Nothing installs" / "no skills found"?** Update the CLI:
|
|
129
263
|
> `cd /tmp && npm i -g @dzhechkov/harness-cli@latest`. Older global installs couldn't locate their
|
|
130
264
|
> own bundled packs outside the monorepo — now fixed, so `dz registry`/`dz init`/`dz setup` work
|
|
@@ -132,7 +266,7 @@ point any tool at (a skill is just Markdown). Dedicated targets are on the [road
|
|
|
132
266
|
|
|
133
267
|
## User Journey — from install to mastery
|
|
134
268
|
|
|
135
|
-
All
|
|
269
|
+
All 67 commands (MEASURED — reproducer: `grep -c "^ case '" src/cli.ts`, the dispatch cases) mapped to a real workflow:
|
|
136
270
|
|
|
137
271
|
```
|
|
138
272
|
DISCOVER → INSTALL → USE → CREATE → MAINTAIN → SHARE
|
|
@@ -280,7 +414,7 @@ dz bundle --select news-digest,goap-research-ed25519 --out ./dist
|
|
|
280
414
|
dz init --target claude-code --select design-thinking
|
|
281
415
|
|
|
282
416
|
# Curated set by topic (recommended):
|
|
283
|
-
dz setup --target claude-code --preset meta #
|
|
417
|
+
dz setup --target claude-code --preset meta # 20 development skills + self-learning
|
|
284
418
|
|
|
285
419
|
# Full toolkit with orchestrated pipeline:
|
|
286
420
|
npx @dzhechkov/keysarium init # 7-phase research + commands + memory
|
|
@@ -605,6 +739,82 @@ ever enter a work order.
|
|
|
605
739
|
**When to use:** after `dz compounding` reports the replay as READY; before claiming that recall
|
|
606
740
|
"works"; and any time you want the claim re-checked as the corpus grows.
|
|
607
741
|
|
|
742
|
+
### Обратный мост QE: Claude-ревьюер из Codex-сессии — `dz qe-bridge`
|
|
743
|
+
|
|
744
|
+
The cross-family rule ("the family that writes the code must not review it") was enforceable in one
|
|
745
|
+
direction only. When **Codex hosts** the run there is no Claude agent plane to dispatch from — and
|
|
746
|
+
`dz reqe`'s brief admits it: for a claude review family it prints `null` where the codex branch
|
|
747
|
+
prints a ready command. `dz qe-bridge` is that missing vehicle: a plain-shell command that probes a
|
|
748
|
+
Claude model, sends a Step-8-shaped brief over SCOPED extracts, and PARSES the verdict.
|
|
749
|
+
|
|
750
|
+
```bash
|
|
751
|
+
# MEASURED 2026-08-19 on this repo — reproducer: the exact command below, reviewing a real shipped feature
|
|
752
|
+
$ dz qe-bridge --family claude --slug wave1-scorer-negation --coder-family codex --model opus
|
|
753
|
+
dz qe-bridge: GRADE C from claude/opus — 7 finding(s) in 343s
|
|
754
|
+
report: features/wave1-scorer-negation/08b_reqe_report.md
|
|
755
|
+
signoff: features/wave1-scorer-negation/.fa-state/qe-bridge/signoff-2026-08-19T18-48-45-545Z.json
|
|
756
|
+
settle: dz reqe --slug wave1-scorer-negation --done --report features/wave1-scorer-negation/08b_reqe_report.md
|
|
757
|
+
the bridge REPORTS (any grade exits 0); gating stays with dz reqe and the host pipeline.
|
|
758
|
+
|
|
759
|
+
# the same command with a binary that cannot answer — a failed call, and NO report to settle with
|
|
760
|
+
$ DZ_QE_BRIDGE_CLAUDE_BIN=/bin/false dz qe-bridge --family claude --slug wave1-scorer-negation --coder-family codex
|
|
761
|
+
dz qe-bridge: FAILED — probe-failed
|
|
762
|
+
no candidate model answered the liveness probe — opus: exit 1, no `OK` in 0 chars of stdout; sonnet: exit 1, …; haiku: exit 1, …
|
|
763
|
+
record: features/wave1-scorer-negation/.fa-state/qe-bridge/failed-2026-08-19T18-48-52-931Z.json
|
|
764
|
+
no report was written — an unparseable or absent review is never a passing one.
|
|
765
|
+
|
|
766
|
+
# with a debt on record, the report settles it through the untouched fail-closed path
|
|
767
|
+
$ dz reqe --slug add-x --done --report features/add-x/08b_reqe_report.md
|
|
768
|
+
dz reqe: debt settled: re-QE grade C (report …) — settlement appended to features/add-x/08_qe_report.md
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
**When to use:** you are hosting a run outside Claude Code (Codex, CI, a plain terminal), you have
|
|
772
|
+
just written code, and the independent reviewer must be the OTHER family. Also: whenever `dz reqe`
|
|
773
|
+
lists a debt whose coder family is `openai`.
|
|
774
|
+
|
|
775
|
+
**The reviewer runs isolated.** Both calls (probe and review) run from an EMPTY temporary directory
|
|
776
|
+
with `--safe-mode --strict-mcp-config --tools '' --no-session-persistence`, and the verdict is read
|
|
777
|
+
from the `--output-format json` **result envelope**. Why: customization output lands on the same
|
|
778
|
+
stdout — MEASURED on this machine, a session-start plugin prints a banner ahead of the model's
|
|
779
|
+
answer — so a crafted hook could otherwise print a complete grade-A signoff and a stream parser
|
|
780
|
+
would believe it (reproducer: `features/qe-bridge-claude/07_code_changes/mutants/c1-forgery-repro.mjs`).
|
|
781
|
+
Residue, stated: `--safe-mode` leaves ADMIN-MANAGED policy settings in force, and no flag proves
|
|
782
|
+
which binary answered.
|
|
783
|
+
|
|
784
|
+
**What makes the grade valid.** Three channels must EXIST and AGREE, each read **LAST-anchored**,
|
|
785
|
+
and the marker must be the FINAL content of the answer:
|
|
786
|
+
the terminal `QE-BRIDGE-SIGNOFF grade=<A-F> findings=<n>` line, the last fenced `qe-bridge-signoff`
|
|
787
|
+
JSON block, and the report's own line-anchored `GRADE:` line. Repo content flows into the prompt and
|
|
788
|
+
comes back quoted, so a planted earlier verdict must lose — and it does (there is a test whose
|
|
789
|
+
fixture plants `grade=A` early and requires the genuine trailing `grade=D` to win). Extracts are
|
|
790
|
+
DEFANGED on the way in, so quoted content can never mint a verdict. Empty, gradeless, marker-only or
|
|
791
|
+
self-contradicting output is a **named failure** — one of 17 closed reasons (`envelope-unparseable`,
|
|
792
|
+
`marker-not-terminal`, `findings-count-mismatch`, `grade-mismatch`, `ambiguous-grade`,
|
|
793
|
+
`audit-write-failed`, `report-write-failed`, … ; closed BOTH ways — every one is produced by a real
|
|
794
|
+
run in the suite and leaves a record) — with an audit record under
|
|
795
|
+
`features/<slug>/.fa-state/qe-bridge/` and the raw stdout beside it, never `findings: []`. Finding
|
|
796
|
+
numbers are the reviewer's: a missing, non-positive or duplicated `n` fails the call instead of being
|
|
797
|
+
renumbered, and a marker whose `findings=<n>` disagrees with the block is `findings-count-mismatch`.
|
|
798
|
+
|
|
799
|
+
**The record is auditable, not just a conclusion.** Every run writes a `runId`, the resolved
|
|
800
|
+
executable plus `binOverride` (true whenever `DZ_QE_BRIDGE_CLAUDE_BIN` was used — the documented TEST
|
|
801
|
+
SEAM; there is no `--claude-bin` flag), the prompt sha256, the byte offsets at which each channel was
|
|
802
|
+
found, the `requestedOut` path and `reportWritten: true|false` — so "no report was written" is a
|
|
803
|
+
stated fact rather than an inference from an absent file. Records and reports are written `0600` in a
|
|
804
|
+
`0700` directory, through `O_EXCL`, with realpath containment that refuses a symlinked parent — and
|
|
805
|
+
the state directory itself is contained the same way, before anything is created in it. The audit
|
|
806
|
+
trail is written BEFORE the report and corrected after it, so `reportWritten` can only ever
|
|
807
|
+
understate; if the trail cannot be written at all, the run FAILS (`audit-write-failed`) rather than
|
|
808
|
+
shipping a verdict nobody can re-derive.
|
|
809
|
+
|
|
810
|
+
**Exit codes:** `0` a signoff was parsed (ANY grade — a grade F still exits 0: the bridge reports, it
|
|
811
|
+
does not gate), `1` a named failure, `2` a usage error. **Honest limits:** it proves the call was
|
|
812
|
+
procedurally sound (a live model was probed, a scoped brief was sent, a self-consistent verdict came
|
|
813
|
+
back); it cannot prove which model authored the text, and it cannot classify your secrets — the
|
|
814
|
+
extracts you scope are what leaves the machine. RU: мост в обратную сторону — из Codex-сессии
|
|
815
|
+
позвать независимого Claude-ревьюера и получить РАЗОБРАННЫЙ вердикт; пустой или безоценочный ответ —
|
|
816
|
+
это названная ошибка, а не «чисто».
|
|
817
|
+
|
|
608
818
|
### Пересмотр после аварийного само-ревью — `dz reqe`
|
|
609
819
|
|
|
610
820
|
The feature-adr pipeline's cross-model guard says *the model that writes code must not review it*.
|
|
@@ -1015,7 +1225,7 @@ green: re-sign reminder (`dz sign …` — the publish signature gate is refuse-
|
|
|
1015
1225
|
before a multi-package npm release, or whenever a broken dist/bin must be impossible to ship; keep plain
|
|
1016
1226
|
`dz publish` for routine pushes. `dz publish` itself is byte-identical whether or not release exists.
|
|
1017
1227
|
|
|
1018
|
-
### Skill Packs (
|
|
1228
|
+
### Skill Packs (18 packs · 189 skills)
|
|
1019
1229
|
|
|
1020
1230
|
Each pack is an npm package — click through for the **full per-skill documentation** (what each skill does + how to trigger it). Install a whole pack with `dz install <pkg>`, or pick skills with `dz init --select` / a `--preset`.
|
|
1021
1231
|
|
|
@@ -1027,7 +1237,7 @@ Each pack is an npm package — click through for the **full per-skill documenta
|
|
|
1027
1237
|
| [@dzhechkov/skills-qe](https://www.npmjs.com/package/@dzhechkov/skills-qe) | 20 | Quality engineering — test-gen, coverage, chaos, defect intelligence, QCSD swarms |
|
|
1028
1238
|
| [@dzhechkov/skills-reasoning](https://www.npmjs.com/package/@dzhechkov/skills-reasoning) | 4 | Generic reasoning & code-quality — investigate (root-cause), solid (SOLID/TDD), karpathy-guidelines, agents-md-creator |
|
|
1029
1239
|
| [@dzhechkov/skills-ecc](https://www.npmjs.com/package/@dzhechkov/skills-ecc) | 20 | Claude-Code engineering craft — agent architecture, autonomous loops, framework patterns |
|
|
1030
|
-
| [@dzhechkov/skills-meta](https://www.npmjs.com/package/@dzhechkov/skills-meta) |
|
|
1240
|
+
| [@dzhechkov/skills-meta](https://www.npmjs.com/package/@dzhechkov/skills-meta) | 20 | Dev-process meta skills — explore, feature-adr, design-thinking, audit, skill-advisor, loop-plan-author, decision-mockups (vendored mirror of `@dzhechkov/skills-decision-mockups`) |
|
|
1031
1241
|
| [@dzhechkov/skills-academic](https://www.npmjs.com/package/@dzhechkov/skills-academic) | 5 | Thesis-defense toolkit — dissertation review, questions, doc-check, defense eval |
|
|
1032
1242
|
| [@dzhechkov/skills-news](https://www.npmjs.com/package/@dzhechkov/skills-news) | 3 | *dz-original* — news digests (`news-digest`) + delta watches (`news-monitor`) + bundled `goap-research-ed25519` verified-research backend (mandatory) |
|
|
1033
1243
|
| [@dzhechkov/skills-idea2prd](https://www.npmjs.com/package/@dzhechkov/skills-idea2prd) | 1 | *dz-original* — `idea2prd-manual`: idea/problem → PRD+ADR+DDD+C4+Pseudocode+Tests+Completion (9 checkpoints); bundles the analyst trio as a sources.json-tracked vendor ([ADR-0001](https://github.com/djd1m/dz-harness-hub/blob/main/docs/adr/0001-skill-canonicalization-and-dependency-model.md)) |
|
|
@@ -1038,12 +1248,13 @@ Each pack is an npm package — click through for the **full per-skill documenta
|
|
|
1038
1248
|
| [@dzhechkov/skills-taste](https://www.npmjs.com/package/@dzhechkov/skills-taste) | 1 | *imported (MIT)* — `design-taste-frontend`: anti-slop landing/portfolio/redesign framework (dials + pre-flight + GSAP skeletons); complements frontend-design (`dz init --select design-taste-frontend`) ([ADR-0002](https://github.com/djd1m/dz-harness-hub/blob/main/docs/adr/0002-product-and-design-expansion.md)) |
|
|
1039
1249
|
| [@dzhechkov/skills-book-digitizer](https://www.npmjs.com/package/@dzhechkov/skills-book-digitizer) | 8 | *dz-original* — book → installable methodology pack: `digitize-book` (orchestrator) + ingest/extract/distill/pack/kb-index + `book-brain-register` (CP6 promote → cross-project brain) + `source-brain-ingest` (repo sibling). Verified provenance, IP-safe, resumable (`dz init --select digitize-book`) ([ADR-001](https://github.com/djd1m/dz-harness-hub/blob/main/features/book-knowledge-digitizer/03_adr/001-book-to-skillpack-pipeline.md)) |
|
|
1040
1250
|
| [@dzhechkov/skills-12factor](https://www.npmjs.com/package/@dzhechkov/skills-12factor) | 12 | *generated by the digitizer, CC BY 4.0* — The Twelve-Factor App distilled into 12 decision-moment skills (one per factor). The first PUBLIC digitized-book pack; paraphrased (shingling-gated), routing-gated (every factor carries triggers), attributed (`NOTICE`) (`dz init --select 12factor-config-in-environment,…`) |
|
|
1251
|
+
| [@dzhechkov/skills-book-ai-apps](https://www.npmjs.com/package/@dzhechkov/skills-book-ai-apps) | 17 | *generated by the digitizer, CP5-published* — «Building Applications with AI Agents» (Albada, рус. пер.) distilled into 17 decision-moment skills across the whole agent-building arc: agent-fit & model choice, single-vs-multi, orchestration, tool design, knowledge & memory, context engineering, evaluation, probabilistic behaviour checks, release gates, improvement loops, drift, human-in-the-loop, agent UX, governance, security. Ships our page-anchored Knowledge Units, NOT the book text — shingling-gated at 0 uncited verbatim runs >=8 words; publication is the recorded CP5 owner decision; `trust_tier 1` (routing-gated, not human-reviewed) Since 0.2.2 it also ships `brain/ai-apps.sqlite`, the 223-KU knowledge slice: `dz brain add --from-pack @dzhechkov/skills-book-ai-apps` loads it into your `~/.dz/brain`, then `dz brain query --source ai-apps` answers in any project (`dz install @dzhechkov/skills-book-ai-apps --target claude-code`) |
|
|
1041
1252
|
|
|
1042
1253
|
### Available Presets (14)
|
|
1043
1254
|
|
|
1044
1255
|
| Preset | Skills | Description |
|
|
1045
1256
|
|--------|--------|-------------|
|
|
1046
|
-
| `meta` |
|
|
1257
|
+
| `meta` | 20 | Development process (explore, goap-research, problem-solver, design-thinking, feature-adr, knowledge-extractor, understand-anything-bridge, agentshield-scan, adversarial-verifier, skill-advisor, audit, loop-plan-author, decision-mockups) |
|
|
1047
1258
|
| `qe-engineer` | 20 | Quality engineering (test-gen, coverage, chaos, defect, ...) |
|
|
1048
1259
|
| `bto` | 1 | Build-Benchmark-Test-Optimize pipeline |
|
|
1049
1260
|
| `health` | 8 | Medical AI (diagnostics, drugs, labs, clinical decisions) |
|
|
@@ -1073,6 +1284,7 @@ Get the whole set with `dz init --target claude-code --preset meta`, or pick one
|
|
|
1073
1284
|
| `reflection-loop` | Standalone critique → revise cycle (≤3 rounds) for code, text, architecture or research | `/reflection-loop` · "critique this" / "review and improve" |
|
|
1074
1285
|
| `structured-reasoning` | Picks the reasoning strategy (Tree-of-Thought / CoT / compression) and checks the conclusion follows | "reason about…" / "explore options" / "compare approaches" |
|
|
1075
1286
|
| `skill-crystallizer` | Auto-creates skills from execution traces, combines skills, and repairs broken ones | "create skill from this" / "combine skills" / "fix skill" |
|
|
1287
|
+
| `decision-mockups` | Owner-facing DECISION PAGE — plain-language write-up + browser-frame before/after mockups + clickable option forks + a copy-answers export you paste back into the chat (a one-option fork is deleted as fake, and a deterministic G0–G14 gate blocks the page if it is not) | "объясни понятным языком" / "что сделано, польза, риски, из чего выбираем" / "покажи владельцу развилки и собери решения" / "оформи артефактом" |
|
|
1076
1288
|
|
|
1077
1289
|
### Standalone Packages (install via npx, no dz CLI needed)
|
|
1078
1290
|
|
|
@@ -1093,7 +1305,7 @@ Get the whole set with `dz init --target claude-code --preset meta`, or pick one
|
|
|
1093
1305
|
|
|
1094
1306
|
> **A skill and its npx toolkit are not duplicates — they're a graduation.** Several skills (e.g. `feature-adr`, `design-thinking`) exist BOTH as a skill inside a `dz` preset AND as a standalone `npx` package. The preset's SKILL.md is **fully functional on its own** (the whole methodology — modules + references — travels with it, and it auto-activates by description), and it's the only way to compile that capability to the **non-Claude platforms** (Codex/OpenCode/Hermes/OpenClaude) via `dz`. The npx package adds **project-level runtime governance** around the same skill: a slash command, governance rules, a context shard, and (for feature-adr) reward-learning + `/harvest`. So: pick the **skill/preset** for a working capability across platforms; pick the **npx toolkit** when you want it as a governed, command-driven fixture of one project.
|
|
1095
1307
|
|
|
1096
|
-
## Design custom Workflow loops (`workflow` · `workflow-lint` · `workflow-trace`)
|
|
1308
|
+
## Design custom Workflow loops (`workflow` · `workflow run` · `workflow-lint` · `workflow-trace`)
|
|
1097
1309
|
|
|
1098
1310
|
Custom loops used to be born by copy-pasting a 1470-line workflow script; nothing deterministic
|
|
1099
1311
|
checked the copy. The loop-designer meta-factory replaces that: a versioned typed plan
|
|
@@ -1131,15 +1343,36 @@ rules honestly report `inconclusive` there, never a silent green). `dz workflow
|
|
|
1131
1343
|
self-checks the shared-subsystem blob registry (checkpoints, model-resolver, trace, …) that the
|
|
1132
1344
|
generator injects verbatim — edit the canonical TS in harness-core, regenerate, never the copies.
|
|
1133
1345
|
|
|
1134
|
-
**Scope, stated plainly: `dz` AUTHORS, GATES
|
|
1135
|
-
|
|
1136
|
-
host's `Workflow({scriptPath})`
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1346
|
+
**Scope, stated plainly (and NARROWED since `dz workflow run` shipped): `dz` AUTHORS, GATES, READS
|
|
1347
|
+
and now RUNS loops — but it never runs a RENDERED SCRIPT.** Step 5 above is still not a `dz`
|
|
1348
|
+
command: executing the generated script belongs to the Claude Code host's `Workflow({scriptPath})`
|
|
1349
|
+
runtime, which owns the agent dispatch that script calls into. What `dz workflow run` executes is
|
|
1350
|
+
the PLAN (see "Run a plan WITHOUT the Claude host" below) — a second, independent enactor that
|
|
1351
|
+
dispatches to `codex exec` / `claude -p` and writes the SAME trace shape. So a claim on this page is
|
|
1352
|
+
about the plan, the generated script, the lint verdict, and a run's own trace file — the two hosts
|
|
1353
|
+
are compared through the same reader, never assumed equivalent. `dz workflow-trace` reads what
|
|
1354
|
+
EITHER host wrote (`trace.jsonl`, seq-ordered by the loop's own counter); with no run there is
|
|
1355
|
+
nothing to read, and it says so rather than inventing a timeline.
|
|
1356
|
+
|
|
1357
|
+
**Who writes the trace, and how far the cross-host claim actually reaches (MEASURED 2026-08-20).**
|
|
1358
|
+
The two enactors do not attest their runs the same way, and the difference is load-bearing:
|
|
1359
|
+
|
|
1360
|
+
| Enactor | Who appends `trace.jsonl` | Evidentiary weight |
|
|
1361
|
+
|---|---|---|
|
|
1362
|
+
| `dz workflow run` (Codex **or** Claude family) | the `dz` process itself, `appendFileSync` in `cli.ts` | **instrument-written** |
|
|
1363
|
+
| the rendered script under the Claude host's `Workflow({scriptPath})` | an AGENT the script asks to run the flush command (`loop-render.ts`) | **agent-attested** |
|
|
1364
|
+
|
|
1365
|
+
The host runtime's own records cannot substitute for the second row. `journal.jsonl` carries four
|
|
1366
|
+
fields (`type`, `key`, `agentId`, `result`) — no `seq`, no `ts`, so it can order nothing; the
|
|
1367
|
+
per-agent `agent-*.jsonl` transcripts do carry `timestamp` and `uuid`/`parentUuid`, so they can
|
|
1368
|
+
order AGENT runs — but a join, a gate redo and a typed pause are steps of the loop, not agents, and
|
|
1369
|
+
leave no record there at all.
|
|
1370
|
+
|
|
1371
|
+
Consequently the cross-host structural equivalence proved by the committed fixture (`pkg-audit-1`)
|
|
1372
|
+
covers a bounded fanout, an all-activated join, a dep chain and a gate. It does **not** cover the
|
|
1373
|
+
gate redo route, the typed terminal route, the typed pause or the file deliverable: those four are
|
|
1374
|
+
what `discrimination.plan.json` adds, and no capture of them exists yet. Read every equivalence
|
|
1375
|
+
statement here as scoped to the first list.
|
|
1143
1376
|
|
|
1144
1377
|
### Build a loop for YOUR scenario — the end-to-end use case (a real one)
|
|
1145
1378
|
|
|
@@ -1306,6 +1539,97 @@ edit loop converges. What it cannot do is run the result: the generated script c
|
|
|
1306
1539
|
`agent()`/`parallel()` sandbox, which only the Claude Code Workflow runtime provides. A green lint
|
|
1307
1540
|
from Codex + a run under Claude Code is a legitimate two-agent split.
|
|
1308
1541
|
|
|
1542
|
+
### Run a plan WITHOUT the Claude host (`dz workflow run`)
|
|
1543
|
+
|
|
1544
|
+
Everything above renders a plan into a script that only Claude Code's `Workflow({scriptPath})`
|
|
1545
|
+
runtime can execute. `dz workflow run` is the other half: it **interprets the plan itself**, from a
|
|
1546
|
+
plain shell, dispatching each step to `codex exec` or an isolated `claude -p`.
|
|
1547
|
+
|
|
1548
|
+
**When to use which** — one sentence each:
|
|
1549
|
+
|
|
1550
|
+
| | use it when |
|
|
1551
|
+
|---|---|
|
|
1552
|
+
| `workflow render` + `Workflow({scriptPath})` | you are already inside Claude Code and want the loop to run in that session, with its agents and its context |
|
|
1553
|
+
| `dz workflow run` | you are in a shell, in CI, or on a box with no Claude Code session — and you want the same plan enacted with a trace the same reader can read |
|
|
1554
|
+
|
|
1555
|
+
It interprets the PLAN, never the rendered script (a rendered script is a Claude-host artifact; a
|
|
1556
|
+
second enactor reading it would be reading someone else's implementation). Same `loop-plan/1`, same
|
|
1557
|
+
gate grammar, same join policies, same failure classes — those decisions live in ONE module both
|
|
1558
|
+
enactors consume, not in two lookalike copies.
|
|
1559
|
+
|
|
1560
|
+
```bash
|
|
1561
|
+
dz workflow run audit.plan.json --run-id pkg-audit-2 --coder-family claude
|
|
1562
|
+
# → dz workflow run: completed (pkg-audit-2) — trace at .dz/loop-trace/pkg-audit-2/trace.jsonl
|
|
1563
|
+
# → {"schema":"wf-run-result/1","runId":"pkg-audit-2","status":"completed","exitCode":0}
|
|
1564
|
+
|
|
1565
|
+
# the run wrote into the addressing the reader already uses, so nothing new is needed to read it:
|
|
1566
|
+
dz workflow-trace --run pkg-audit-2 --invariants audit.plan.json
|
|
1567
|
+
# → INVARIANT PASS seq-monotonic: seq unique and contiguous 1..12 (12 events)
|
|
1568
|
+
# → INVARIANT PASS dispatch-settle-pairing: every dispatch has exactly one settle
|
|
1569
|
+
# → INVARIANT PASS join-coverage:fan: every dispatched branch settled; …
|
|
1570
|
+
```
|
|
1571
|
+
|
|
1572
|
+
**Exit codes — `run` and `workflow-lint` have DIFFERENT tables. Both, side by side:**
|
|
1573
|
+
|
|
1574
|
+
| | 0 | 1 | 2 | 3 | 75 |
|
|
1575
|
+
|---|---|---|---|---|---|
|
|
1576
|
+
| `dz workflow run` | completed | failed (named reason) | usage / invalid plan | — | **typed pause** |
|
|
1577
|
+
| `dz workflow-lint` | clean | findings | — | inconclusive | — |
|
|
1578
|
+
|
|
1579
|
+
`75` is `EX_TEMPFAIL` ("try again later"), and it is deliberately **not** `3`: `3` collides with
|
|
1580
|
+
lint's inconclusive and reads ignorable, while a pause strands work that is genuinely resumable.
|
|
1581
|
+
On a pause the **last stdout line** is a `wf-pause-envelope/1` JSON object; a FAILURE emits none —
|
|
1582
|
+
so a wrapper distinguishes the two from stdout and the exit code alone, without parsing prose.
|
|
1583
|
+
|
|
1584
|
+
**Pause and resume** (a `kind: 'pause'` step, or the budget ceiling):
|
|
1585
|
+
|
|
1586
|
+
```bash
|
|
1587
|
+
dz workflow run release.plan.json --run-id rel-7
|
|
1588
|
+
# → dz workflow run: PAUSED (AWAITING_APPROVAL) — resume with: dz workflow run release.plan.json --resume rel-7 --arg approve=<value>
|
|
1589
|
+
# → {"schema":"wf-pause-envelope/1","runId":"rel-7","exitCode":75,"pauseState":"AWAITING_APPROVAL", …}
|
|
1590
|
+
echo $? # 75
|
|
1591
|
+
|
|
1592
|
+
dz workflow run release.plan.json --resume rel-7 --arg approve=yes
|
|
1593
|
+
# → dz workflow run: completed (rel-7) — …
|
|
1594
|
+
```
|
|
1595
|
+
|
|
1596
|
+
A resume never re-spends work: the cursor comes from checkpoint lines plus artifact probes, and a
|
|
1597
|
+
STALE-INPUT mismatch (plan digest, exec fingerprint, or the run-args hash) refuses to resume at all —
|
|
1598
|
+
there is no override, because the checkpoints describe a different run. Extending a ceiling is the
|
|
1599
|
+
one thing that is not an identity change: `--budget-extra` and `--wall-clock-extra` are recorded and
|
|
1600
|
+
capped, never silent.
|
|
1601
|
+
|
|
1602
|
+
**Budget.** Every boundary reserves its worst case BEFORE it dispatches, so a region that will not
|
|
1603
|
+
fit pauses in front of the region rather than halfway through it. `budget.jsonl` gets one
|
|
1604
|
+
`wf-budget-1` row per dispatch (plus probe rows, which never decrement the ceiling).
|
|
1605
|
+
|
|
1606
|
+
**Cross-model safety.** A step marked `x-role: "qe"` that resolves to the same family as
|
|
1607
|
+
`--coder-family` is REFUSED: the family that wrote the code may not review it. `--allow-same-family-qe`
|
|
1608
|
+
proceeds, and writes a real re-QE debt that `dz reqe` surfaces — a suspension you can see, not a
|
|
1609
|
+
comment nobody reads.
|
|
1610
|
+
|
|
1611
|
+
#### Honest limits — three divergences from the Claude host, named rather than discovered
|
|
1612
|
+
|
|
1613
|
+
1. **dz-side settle events carry no `wallTime`.** The Claude host stamps it shell-side during its
|
|
1614
|
+
flush; the shared emitter accepts none, and stamping it afterwards would mean editing lines that
|
|
1615
|
+
were already validated — exactly what the buffer discipline forbids. Per-dispatch wall clock
|
|
1616
|
+
lives in `budget.jsonl` instead. `wallTime` was always diagnostic-only (never an operand of an
|
|
1617
|
+
invariant), so no verdict changes.
|
|
1618
|
+
2. **The runner checkpoints every top-level stage unconditionally**, whatever `plan.checkpointing`
|
|
1619
|
+
says. Its resume cursor is BUILT from those lines, so making them optional would make resume
|
|
1620
|
+
optional. `plan.checkpointing` remains what it always was: the Claude-host opt-in.
|
|
1621
|
+
3. **A gate `terminal:` route ends the run by plan design, and leaves the trace INCOMPLETE.** This is
|
|
1622
|
+
parity with the rendered script, whose top-level terminal `return` skips the epilogue that writes
|
|
1623
|
+
`run.closed`. The run exits 0 (the plan declared this ending; the Workflow host completes too) and
|
|
1624
|
+
the ledger row names the route — but `dz workflow-trace` will report the trace as incomplete and
|
|
1625
|
+
downgrade window-truncated invariants to `inconclusive`. That is correct: nothing proves the
|
|
1626
|
+
un-run steps would have passed.
|
|
1627
|
+
|
|
1628
|
+
**Deferred, and said so:** budget rows do not appear in the `dz workflow-trace` timeline yet. The
|
|
1629
|
+
condition for adding them was zero reader change for Claude-host runs, and it is not met — a
|
|
1630
|
+
Claude-host run has no `budget.jsonl`, so the timeline would grow a section that is empty for half
|
|
1631
|
+
its inputs. `budget.jsonl` is readable by eye and by the recommender in the meantime.
|
|
1632
|
+
|
|
1309
1633
|
### Move a run's telemetry to another machine (`workflow-trace export` / `import`)
|
|
1310
1634
|
|
|
1311
1635
|
A run leaves traces on the machine that produced it. `export` puts one run's telemetry into a single
|
|
@@ -1376,9 +1700,9 @@ only at their documented scopes (plan + step), and `fanouts[].registry` items mu
|
|
|
1376
1700
|
ItemKey domain the trace plane enforces — `trace.emit` can never decide whether a valid plan runs.
|
|
1377
1701
|
Deferred options are on the loop-designer roadmap.
|
|
1378
1702
|
|
|
1379
|
-
## All Commands (
|
|
1703
|
+
## All Commands (69)
|
|
1380
1704
|
|
|
1381
|
-
*(
|
|
1705
|
+
*(69 MEASURED — reproducer: `grep -c "^ case '" src/cli.ts`, the dispatch cases.)*
|
|
1382
1706
|
|
|
1383
1707
|
```
|
|
1384
1708
|
dz setup --target <name> [--preset <name>] [--select id,id,...] [--skills-dir <dir>] [--memory agentdb] [--no-memory] [--no-hooks] [--install-driver] [--force]
|
|
@@ -1433,7 +1757,7 @@ dz feature-adr-setup [--plan] [--from-spec <f>] [--apply] # guided project onb
|
|
|
1433
1757
|
dz challenge --plan <plan.md> [--json] [--context-only] [--author <model>] # adversarial plan-gate (behind the `challenge-panel` skill): assemble a WIDE context pack (plan + vision + testing + map + degradations) + the fixed C1-C8 "break it" brief for a FRESH adversary (≠ plan author); advisory, never blocks
|
|
1434
1758
|
dz routing [--stage <s>] [--json] # inspect the learned cost-optimal routing store: what `args.models.<stage>='auto-cost'` believes per (stage, complexity-tier, model) — gated attempts/successes/rate (feeds feature-adr model selection)
|
|
1435
1759
|
dz bto-optimize --split|--plan|--select|--scope-check|--diff [--json] # deterministic engine behind /bto-optimize: hold-out split + hard-capped budget + no-regress-on-holdout winner selection (defeats judge-gaming); prose-only, diff-confirmed, never auto-writes
|
|
1436
|
-
dz discrimination-check --test <f[,f]> [--base <ref>] [--name <filter>] [--runner <cmd>] [--json] # §42 test-discrimination gate for feature-adr Step-8: run the ADR's property test in an isolated git worktree at pre-feature base — it MUST go red without the fix
|
|
1760
|
+
dz discrimination-check --test <f[,f]> [--base <ref>] [--name <filter>] [--runner <cmd>] [--timeout <ms>] [--json] # §42 test-discrimination gate for feature-adr Step-8: run the ADR's property test in an isolated git worktree at pre-feature base — it MUST go red without the fix. SEVEN verdicts, each gated on EXECUTION evidence: DISCRIMINATES · DISCRIMINATES_VIA_ERROR · NON_DISCRIMINATING (false green) · TEST_FILE_ABSENT · LOAD_ERROR_AT_BOTH_REVS · FAILS_AT_TIP · CANNOT_ISOLATE (+ typed reason). Advisory, never auto-aborts
|
|
1437
1761
|
dz mutation-gate [--package <dir>] [--registry <file>] [--test-cmd "<cmd>"] [--only <id[,id]>] [--timeout <ms>] [--rebaseline per-entry|final] [--keep-scratch] [--json] # the mutation gate: for each NAMED protection in a declarative registry, copy the package to a scratch dir (shadow-repo layout, node_modules symlinked, git-initialized), verify the baseline is green, apply the entry's exact {find, replace} mutation, run the suite, REQUIRE red, restore — and require the red to be ATTRIBUTABLE to the protection: a mutated file that no longer parses is MUTATION_UNPARSEABLE, a failing count far above the entry's bound (maxFailing, default from observed) is OVER_FAILING, and a restored tree that does not reproduce green makes the entry INCONCLUSIVE (flaky suite). A mutation that does not apply, a green suite, or an inconclusive run is a FAILURE — never a skip. exit 0 all proven / 1 gate failed / 2 setup error
|
|
1438
1762
|
dz delivery-check --slug <slug> [--context-only] [--findings <f.json>] [--strict] [--author <model>] [--json] # portable Step-10 Delivery Gate: the `manual` form that travels to every shell target — prints the 4-plane review brief (regressions ‖ security ‖ code-quality ‖ product-honesty) + artifact probes; --findings classifies a fed-back review into a fail-closed ready|blocked hand-off (only cross-validated BLOCKER/HIGH count) and writes features/<slug>/10_delivery_review.md; --strict exits 1 on blocked
|
|
1439
1763
|
dz skills-verify [--dir <project>] [--expect a,b] [--static] [--strict] [--timeout <s>] [--json] # does .claude/skills/ actually REGISTER? --static = instant layout scan (CI-safe, no session): flags dirs that can never register; default also starts a real session and reads the authoritative system/init listing. exit 0 pass / 1 fail / 2 inconclusive — an unobservable registration is NEVER a pass
|
|
@@ -1444,6 +1768,7 @@ dz epoch-replay --judge <filled-work-order.json> [--out <file>] [--json] # bli
|
|
|
1444
1768
|
dz epoch-replay --score <judgments.json> --work-order <file> [--slice <name>] [--json] # un-blind against the VERIFIED pre-registered assignment; ONE paired binomial over DECISIVE pairs (ties excluded, reported) → SUPPORTED only when the lift interval (2p−1) lies entirely above zero; FALSIFIED only on harm or a passed non-superiority test (lift upper bound below the margin PRE-REGISTERED in the work order, default 0.05, at 10+ decisive pairs); else INCONCLUSIVE (min 5 decisive pairs). Refuses a forged work order, a --margin flag, or duplicate judgement ids; the verdict is data, not an exit code
|
|
1445
1769
|
dz score --slug <feature> [--project <dir>] [--json] # process scorecard for ONE feature-adr run, from its artifacts: ADR confirmation, discrimination proof, cross-model QE grade, live verification, README-first, learning loop, amendments — DESCRIPTIVE-ONLY (a low score exits 0); evidence lines are shown so the reader judges the heuristics
|
|
1446
1770
|
dz reqe [--slug <feature> [--done --report <f>]] [--project <dir>] [--json] # the re-QE debt ledger: a usage-switched feature-adr run whose Step-8 QE ran on the coder's OWN family (cross-model guard suspended, FR-2.9) records a debt; list debts (also surfaced by dz usage), print the cross-family review brief, settle FAIL-CLOSED against an existing GRADED report (the run's own 08_qe_report.md — even hard-linked — can never settle its own debt); settlement lands in 08_qe_report.md, evidence rotates to reqe-settled.json
|
|
1771
|
+
dz qe-bridge --family claude --slug <feature> [--coder-family codex|claude] [--model <id>] [--files a,b] [--out <f>] [--timeout <s>] [--allow-same-family] [--json] # the REVERSE QE bridge (Codex-hosted → Claude reviewer): the reviewer runs ISOLATED (an empty temp cwd + --safe-mode --strict-mcp-config --tools '' --no-session-persistence, so no CLAUDE.md/skills/plugins/hooks/MCP load) and its verdict is read from the --output-format json RESULT ENVELOPE, so text a customization printed onto the same stdout can never become a signoff. Probes the model first; sends SCOPED extracts under a loud 200k-char ceiling; the grade must agree across three LAST-anchored channels AND the marker must be the final content — empty/gradeless/mismatched/miscounted output is a named failure with an audit record under features/<slug>/.fa-state/qe-bridge/, never a clean review. exit 0 signoff parsed (ANY grade — it reports, it does not gate) / 1 named failure / 2 usage. DZ_QE_BRIDGE_CLAUDE_BIN is a TEST SEAM (recorded as binOverride:true)
|
|
1447
1772
|
dz backlog <sub> add "<idea>" | list | show <id> | goals [--validate] | roulette [--seed n] [--commit <id>] | ship <id…> | drop <id…> | reopen <id…> | enrich <id> | jira <id> | harmonize [--apply] # brain-backed idea backlog: capture an idea → semantic dedup against past ideas/features via the REUSED agentdb vector engine (two-signal: bounded-excerpt cosine DUPLICATE≥0.92 corroborated by shared subject vocabulary — a register-only 0.94 is demoted to RELATED, a length-only re-capture is caught as a subset duplicate; absorbed texts kept in absorbed.jsonl) + GoalMap alignment ("map+compass") → weighted seeded roulette picks one to work on → enrich STAGES an idea2prd hand-off → jira writes an auditable outbox via a configurable MCP adapter seam (jira-mcp|copilot-mcp|none). No 2nd vector store; without agentdb it degrades to exact-text dedup (honest)
|
|
1448
1773
|
dz sign --init --out <path> | --pack <dir> --key <path> # --init: generate the Ed25519 keypair (private OUTSIDE the repo, prints the public key for keys/dz.pub); else sign a pack's manifest + CycloneDX SBOM
|
|
1449
1774
|
dz sbom --pack <dir> [--out <file>] # emit the CycloneDX 1.5 SBOM for a pack standalone (file-level bill of materials); print to stdout or write to a file
|
|
@@ -1456,9 +1781,12 @@ dz release [--filter <name>] [--affected] [--audit-dev] [--tag] [--pub
|
|
|
1456
1781
|
dz auto-canonicalize --source <github-url> --pack <skills-pack>
|
|
1457
1782
|
dz sync-upstream [--package <dir>] [--list] [--all]
|
|
1458
1783
|
dz drift-check [--all] [--json] [--project <dir>] # CI gate: exit 1 on NEW shared-skill drift (baseline: .dz/drift-allowlist.json; --all incl .claude dogfood)
|
|
1784
|
+
dz agents-sync [--check] [--json] [--project <dir>] # sync anchored bearing rules into the root AGENTS.md policy fence; exit 0 sync / 1 drift / 3 inconclusive
|
|
1785
|
+
dz hooks-sync --target codex [--check] [--verify|--no-verify] [--project <dir>] [--remove] [--json] # install + ARM the dz veto/recall hooks in $CODEX_HOME/hooks.json and PROVE they fire with a live veto probe; exit 0 armed+trusted+verified / 1 not armed / 3 inconclusive (incl. --no-verify)
|
|
1459
1786
|
dz sync-canonical <skill> [--check] [--from <dir>] [--auto] [--project <dir>] # heal every copy from skills-meta/<skill> or --from; no canonical + --check = compare copies to each other (exit 1 on drift); no canonical + write = refuse unless --auto (LOUD, picks most-complete copy); --check writes nothing
|
|
1460
1787
|
dz scout [--topics <list>] [--since <date>] [--deep] [--output <file>] [--diff] [--report]
|
|
1461
1788
|
dz workflow init --name <n> [--pattern pipeline|barrier|fanout|gate] [--o <plan.json>] | validate <plan.json> [--json] | render <plan.json> --o <script.js> [--check] [--force] | blobs [--check] # loop-plan/1 authoring (the ADR-005 templates are retired)
|
|
1789
|
+
dz workflow run <plan.json> [--run-id <id>] [--resume <runId>] [--arg k=v]... [--coder-family codex|claude] [--default-family codex|claude] [--budget <n>] [--max-wall-clock <s>] [--stage-timeout <s>] [--budget-extra <n>] [--wall-clock-extra <s>] [--run-dir <dir>] [--allow-same-family-qe] [--json] # INTERPRET the plan without the Claude host; exit 0/1/2/75 (75 = typed pause)
|
|
1462
1790
|
dz workflow-lint <script.js> [--plan <plan.json>] [--require-plan|--legacy] [--json] # 18-rule deterministic gate; exit 0/1/3 — inconclusive is never a pass
|
|
1463
1791
|
dz workflow-trace <runDir|--slug <s>|--run <id>> [--invariants <plan.json>] [--html <out.html>] [--json] # timeline + SEQ invariant runner over the loop's own trace.jsonl
|
|
1464
1792
|
dz workflow-trace export <run> --o <file> [--include-pairs --yes] [--strict] # one run's telemetry as ONE movable file
|
|
@@ -1477,8 +1805,8 @@ dz help
|
|
|
1477
1805
|
## Global: `dz --version` / `-v` / `dz version`
|
|
1478
1806
|
|
|
1479
1807
|
```bash
|
|
1480
|
-
dz --version # 0.4.
|
|
1481
|
-
dz --version --json # {"name":"dz","version":"0.4.
|
|
1808
|
+
dz --version # 0.4.8
|
|
1809
|
+
dz --version --json # {"name":"dz","version":"0.4.8","node":"v22.22.0","schemas":{"loopPlan":"loop-plan/1"}}
|
|
1482
1810
|
```
|
|
1483
1811
|
|
|
1484
1812
|
One line, exit 0. Unresolvable ⇒ the literal `unknown` and exit **1** — never a fabricated number,
|
|
@@ -2083,6 +2411,96 @@ dz sync-upstream --package packages/@dzhechkov/skills-devops # check one packag
|
|
|
2083
2411
|
|
|
2084
2412
|
Discovers all skill packs with `sources.json`, fetches SKILL.md from origin repos, reports which skills have upstream changes.
|
|
2085
2413
|
|
|
2414
|
+
### dz agents-sync — Codex starts with the repository's bearing rules
|
|
2415
|
+
|
|
2416
|
+
Use this after changing an anchored policy clause in `CLAUDE.md` or `.claude/rules/*.md`, and run
|
|
2417
|
+
the check form in CI. It updates only the `dz:policies` fence in the root `AGENTS.md`; authored
|
|
2418
|
+
content and the independent `dz:skills` fence remain untouched.
|
|
2419
|
+
|
|
2420
|
+
```console
|
|
2421
|
+
$ dz agents-sync
|
|
2422
|
+
dz agents-sync: wrote — 9 policy section(s), 8097 bytes (24.71% of 32768)
|
|
2423
|
+
|
|
2424
|
+
$ dz agents-sync --check
|
|
2425
|
+
dz agents-sync: in sync — 9 policy section(s), 8097 bytes (24.71% of 32768)
|
|
2426
|
+
```
|
|
2427
|
+
|
|
2428
|
+
Exit codes are **0** for synchronized, **1** for drift and **3** when fixed source evidence is
|
|
2429
|
+
missing or unreadable. `--check` never writes. Each section carries a 12-hex hash recomputed from
|
|
2430
|
+
its source anchor; this proves synchronization only — not that Codex read or obeyed the rule. The
|
|
2431
|
+
separate cold-start acceptance probe establishes runtime visibility.
|
|
2432
|
+
|
|
2433
|
+
### dz hooks-sync — Codex runs the same veto and recall hooks Claude Code does
|
|
2434
|
+
|
|
2435
|
+
**When to use it.** Once per machine, after `npm i -g @dzhechkov/harness-cli`, if you drive Codex as
|
|
2436
|
+
well as Claude Code. It installs two hooks into the **user-global** `$CODEX_HOME/hooks.json`
|
|
2437
|
+
(default `~/.codex/hooks.json`) and **arms** them — Codex hooks are trust-gated, and an untrusted
|
|
2438
|
+
entry is silently never run. Re-run it after a dz upgrade; it is byte-idempotent, so an unchanged
|
|
2439
|
+
install rewrites nothing and the hook keeps its trust.
|
|
2440
|
+
|
|
2441
|
+
```console
|
|
2442
|
+
$ dz hooks-sync --target codex
|
|
2443
|
+
dz hooks-sync: codex hooks installed and ARMED (trust: trusted) — VERIFIED by a live veto probe — ready
|
|
2444
|
+
|
|
2445
|
+
$ dz hooks-sync --target codex --check # read-only, and it re-proves the guard fires
|
|
2446
|
+
dz hooks-sync: codex hooks installed and ARMED (trust: trusted) — VERIFIED by a live veto probe — ready
|
|
2447
|
+
|
|
2448
|
+
$ dz hooks-sync --target codex --no-verify # skips the probe — and can never say "ready"
|
|
2449
|
+
dz hooks-sync: installed+trusted, NOT verified — ARMED = NO (trust: trusted, executable: true, verify: not verified (no live probe ran))
|
|
2450
|
+
|
|
2451
|
+
$ dz hooks-sync --target codex --remove
|
|
2452
|
+
dz hooks-sync: removed 2 managed entr(ies) from /root/.codex/hooks.json
|
|
2453
|
+
```
|
|
2454
|
+
|
|
2455
|
+
**"ready" means a command was actually blocked, in this run.** By default `dz hooks-sync` runs a
|
|
2456
|
+
LIVE, nonce-scoped veto probe through `codex exec` in a hermetic workspace: it asks Codex to run one
|
|
2457
|
+
forbidden command and requires BOTH halves of the evidence — dz's `DZ-VETO:` marker in the
|
|
2458
|
+
transcript AND the absence of the command's side effect. `--dangerously-bypass-hook-trust` is never
|
|
2459
|
+
passed, because a bypassed run proves the helper body works and nothing about the installed state.
|
|
2460
|
+
Anything else — a silent transcript, a dead invocation, a timeout, a version mismatch — is
|
|
2461
|
+
**inconclusive**, never ready. `--no-verify` skips the probe and is reported as unverified;
|
|
2462
|
+
`--project <dir>` runs the probe in a project that has already opted into `"shellVeto": "block"`
|
|
2463
|
+
instead of the hermetic workspace.
|
|
2464
|
+
|
|
2465
|
+
Exit codes are **0** for armed **and** trusted **and** verified, **1** for not-armed / drift / a
|
|
2466
|
+
refusal, and **3** when the answer is inconclusive (including "no `codex` binary on PATH", where dz
|
|
2467
|
+
writes **nothing**, and `--no-verify`, where nothing was measured). `--check` writes nothing and is
|
|
2468
|
+
**silent** in a home that never opted in.
|
|
2469
|
+
|
|
2470
|
+
**`dz setup --target codex` and `dz init --target codex` deliver these hooks too**, verify them the
|
|
2471
|
+
same way, and report a failure without aborting the rest of the command. Pass `--no-hooks` for
|
|
2472
|
+
skills only.
|
|
2473
|
+
|
|
2474
|
+
**What the two hooks do.**
|
|
2475
|
+
|
|
2476
|
+
| Hook | Event | Behaviour |
|
|
2477
|
+
|---|---|---|
|
|
2478
|
+
| `dz-codex-veto.cjs` | `PreToolUse` | judges the shell command against one rule, `ssh-explicit-auth-weakening` |
|
|
2479
|
+
| `dz-codex-recall.cjs` | `UserPromptSubmit` | injects matching learned lessons and records the use with `runtime: "codex"` |
|
|
2480
|
+
|
|
2481
|
+
**The veto WARNS by default and never blocks.** A hit prints `DZ-VETO-WARN:` and exits 0. Enforcement
|
|
2482
|
+
is opt-in **per project**:
|
|
2483
|
+
|
|
2484
|
+
```console
|
|
2485
|
+
$ cat .dz/config.json
|
|
2486
|
+
{"hooks": {"shellVeto": "block"}} # off | warn (default) | block
|
|
2487
|
+
```
|
|
2488
|
+
|
|
2489
|
+
Only then does a hit exit 2 and stop the command. The rule fires only on tokens by which the command
|
|
2490
|
+
*explicitly* asks for weaker ssh authentication — `sshpass`, `-o PasswordAuthentication=yes`,
|
|
2491
|
+
`-o PubkeyAuthentication=no`, `-o PreferredAuthentications=…password…`. A bare `ssh myhost` whose
|
|
2492
|
+
identity comes from `~/.ssh/config` or `ssh-agent` is **allowed**: this guard is user-global, so a
|
|
2493
|
+
rule that blocks the normal secure case is not a guard, it is an outage.
|
|
2494
|
+
|
|
2495
|
+
**Radius.** Both helpers are INERT outside an opted-in dz project — the activation marker is a `.dz`
|
|
2496
|
+
directory, not `.git`. In a plain git checkout they take no decision, print nothing, and create
|
|
2497
|
+
nothing.
|
|
2498
|
+
|
|
2499
|
+
**Removal is conservative.** `--remove` deletes only entries whose command hash is recorded in dz's
|
|
2500
|
+
own manifest. An entry that merely *looks* like dz's is kept and reported — dz never deletes what it
|
|
2501
|
+
cannot prove it wrote. Foreign entries are preserved byte-for-byte by every operation, and a
|
|
2502
|
+
`hooks.json.bak-<ISO>` copy (newest 3 kept) is taken before each modifying write.
|
|
2503
|
+
|
|
2086
2504
|
### dz drift-check / dz sync-canonical — intra-monorepo skill-drift guard
|
|
2087
2505
|
|
|
2088
2506
|
**What.** The same skill is physically duplicated across many packages (`packages/@dzhechkov/*/<skill>/` + `.claude/skills/<skill>/`). These two commands make that duplication safe:
|
|
@@ -2365,7 +2783,7 @@ dz pretrain # detects stack, recommends pres
|
|
|
2365
2783
|
dz recommend "work on this Node.js API" # suggests skills + toolkits
|
|
2366
2784
|
|
|
2367
2785
|
# 2. Install skills (choose your level)
|
|
2368
|
-
dz setup --target claude-code --preset meta --memory agentdb #
|
|
2786
|
+
dz setup --target claude-code --preset meta --memory agentdb # 20 skills (includes feature-adr)
|
|
2369
2787
|
dz setup --target claude-code --preset qe-engineer # + 20 QE skills
|
|
2370
2788
|
|
|
2371
2789
|
# Want the full feature-adr toolkit with /feature-adr command + governance?
|
|
@@ -2756,23 +3174,56 @@ feature-adr Step-8 asserts the ADR's load-bearing safety property **has** a test
|
|
|
2756
3174
|
false green — it may never exercise the property, so it would stay green even if the property regressed. The
|
|
2757
3175
|
`§42` gate (learned from rUv's `cve-bench/evaluate.mjs`) proves the test **discriminates**: it runs the property
|
|
2758
3176
|
test in a throwaway git worktree at the pre-feature base (no fix) and requires it to go **red**.
|
|
3177
|
+
|
|
3178
|
+
**Use it when** you are about to accept "the property has a test" as evidence — in Step-8 QE, in a review of
|
|
3179
|
+
someone else's fix, or before trusting a regression test you did not write. Run it against `HEAD` while your
|
|
3180
|
+
change is still uncommitted; that is what makes `HEAD` the pre-feature base.
|
|
3181
|
+
|
|
2759
3182
|
```bash
|
|
2760
3183
|
# the Step-7 feature diff is uncommitted mid-pipeline, so HEAD is the pre-feature base
|
|
2761
3184
|
dz discrimination-check --test packages/x/test/auth-property.test.ts --base HEAD --json
|
|
3185
|
+
|
|
3186
|
+
# human output, a longer suite, and a runner that is not vitest
|
|
3187
|
+
dz discrimination-check --test packages/x/test/auth-property.test.ts \
|
|
3188
|
+
--base HEAD --runner "node --test" --timeout 600000
|
|
2762
3189
|
```
|
|
2763
3190
|
```
|
|
2764
3191
|
discrimination-check @ HEAD — verdict: NON_DISCRIMINATING
|
|
2765
3192
|
✗ packages/x/test/auth-property.test.ts: NON_DISCRIMINATING
|
|
3193
|
+
measurementValid: true · primaryAction: strengthen-test
|
|
2766
3194
|
|
|
2767
3195
|
[high] non-discriminating property test (false green)
|
|
2768
|
-
1 property test(s) PASS at pre-feature base — they do not exercise the ADR safety
|
|
3196
|
+
1 property test(s) PASS at pre-feature base WITH execution evidence — they do not exercise the ADR safety
|
|
3197
|
+
property and would stay green if the fix regressed … Action: strengthen-test. (Advisory — the pipeline
|
|
3198
|
+
continues; the owner decides.)
|
|
2769
3199
|
```
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
3200
|
+
|
|
3201
|
+
**Every verdict is gated on EXECUTION evidence.** The gate reads the runner's own output shape (vitest /
|
|
3202
|
+
node --test) and requires it to demonstrate that the *named* test actually ran. An outcome nobody can prove
|
|
3203
|
+
degrades loudly instead of minting trust — MEASURED before this change, `--runner false` (a command that
|
|
3204
|
+
executes nothing and prints nothing) returned `DISCRIMINATES`; it now returns `CANNOT_ISOLATE` with
|
|
3205
|
+
reason `unrecognised-runner-output`.
|
|
3206
|
+
|
|
3207
|
+
| Verdict | Means | ✓/✗ | Action |
|
|
3208
|
+
|---|---|---|---|
|
|
3209
|
+
| `DISCRIMINATES` | assertion-red at base, execution-evidenced | ✓ | none |
|
|
3210
|
+
| `DISCRIMINATES_VIA_ERROR` | evidenced load error at base **and** an evidenced pass at TIP | ✓ | none (inference — note it) |
|
|
3211
|
+
| `NON_DISCRIMINATING` | evidenced pass at base — a proven false green | ✗ | `strengthen-test` |
|
|
3212
|
+
| `TEST_FILE_ABSENT` | the named check is not a regular file (stat+isFile, before any worktree) | ✗ | `create-missing-test` |
|
|
3213
|
+
| `LOAD_ERROR_AT_BOTH_REVS` | could not execute at EITHER rev — zero signal | ✗ | `fix-runner-invocation` |
|
|
3214
|
+
| `FAILS_AT_TIP` | the feature's own test is red **with** the feature present | ✗ | `fix-red-feature-test` |
|
|
3215
|
+
| `CANNOT_ISOLATE` | no established observation; the row carries a typed `reason` | ✗ | `map-a-test` / `fix-runner-invocation` |
|
|
3216
|
+
|
|
3217
|
+
`--json` carries the full reading: `perTest[]` (verdict + `reason`), the per-run `evidence` rows, `findings[]`
|
|
3218
|
+
(**one per distinct non-clean verdict** — the scalar `aggregate` can only name the worst), `measurementValid`
|
|
3219
|
+
(`true | false | 'partial'` — did the instrument measure at all), `primaryAction`, and `tipTree` (the live
|
|
3220
|
+
tree's HEAD + dirty-file count when a tip control ran). The singular `finding` is a **deprecated** alias for
|
|
3221
|
+
`findings[0]`; read `findings[]`. `--timeout <ms>` (default 300000) bounds each run — a timed-out run is
|
|
3222
|
+
`CANNOT_ISOLATE` reason `timeout`, never a pass.
|
|
3223
|
+
|
|
3224
|
+
It **never auto-aborts** (dz's rule: a false gate kills trust) — exit 0 on any verdict, exit 2 only on a
|
|
3225
|
+
usage/setup error. Base ref, paths, name filter, and runner are all injection-checked, and the worktree is
|
|
3226
|
+
always removed. Step-8 runs this on the ADR Confirmation's `Required automated check` automatically.
|
|
2776
3227
|
|
|
2777
3228
|
### `dz guard` — when a self-mutating operation should be refused, not regretted
|
|
2778
3229
|
|
|
@@ -3506,9 +3957,29 @@ npx @dzhechkov/p-replicator init
|
|
|
3506
3957
|
|
|
3507
3958
|
## Status
|
|
3508
3959
|
|
|
3509
|
-
`v0.
|
|
3960
|
+
`v0.5.1` — **published 2026-08-20**. Ships `dz workflow run`, the portable plan enactor: it INTERPRETS a `loop-plan/1` plan instead of executing a rendered script, dispatching to `codex exec` or an isolated `claude -p`, exit 0/1/2/75 (75 = a typed pause whose last stdout line is a `wf-pause-envelope/1`). Requires `@dzhechkov/harness-core >= 0.5.1` (the compat guard refuses below it by name). See "Who writes the trace" above for the stated scope of the cross-host equivalence claim — it is narrower than "the two hosts agree".
|
|
3961
|
+
|
|
3962
|
+
`v0.5.0` — published. Also available as [Claude Plugin](#claude-plugin). Part of [DZ Harness Hub](https://github.com/djd1m/dz-harness-hub).
|
|
3963
|
+
|
|
3964
|
+
New in 0.5.0 (feature `qe-bridge-claude`, cross-runtime leg 3/4): `dz qe-bridge --family claude`
|
|
3965
|
+
runs an INDEPENDENT Claude reviewer from any host — a Codex session included — and lands a PARSED
|
|
3966
|
+
signoff whose grade must agree across three LAST-anchored channels; an empty or gradeless answer is
|
|
3967
|
+
a named failure with a forensic record, never a clean review. `withNamedLockSync` generalises the
|
|
3968
|
+
store lock and now guards the `$CODEX_HOME/hooks.json` read-merge-write, so two dz processes can no
|
|
3969
|
+
longer lose each other's hook entries.
|
|
3970
|
+
|
|
3971
|
+
Also in 0.4.8 (feature `crossrt-1-agents-md`): `dz agents-sync` ports the fixed registry of bearing
|
|
3972
|
+
rules into an early root-`AGENTS.md` fence, `--check` exposes source drift to CI, and both surfaces
|
|
3973
|
+
report the measured Codex project-doc byte budget. A live cold-start probe, not file presence,
|
|
3974
|
+
remains the runtime acceptance gate.
|
|
3975
|
+
|
|
3976
|
+
New in this change (feature `dz-cli-defects`, slice A — three defects confirmed by RUNNING the CLI, then fixed):
|
|
3977
|
+
|
|
3978
|
+
- **`dz list` skips and collects** — one unparseable `SKILL.md` no longer hides the rest; the broken files are named on stderr and the exit code stays 1. Same for `dz init` / `dz install` / `dz sync`. [Details](#dz-list--one-broken-skill-never-hides-the-rest)
|
|
3979
|
+
- **`--target` aliases + did-you-mean** — `--target claude` (and `cc`, `agents`, `gpt`/`openai`) resolve; typos are suggested, never silently accepted. [Details](#--target-aliases-and-did-you-mean)
|
|
3980
|
+
- **A named refusal instead of a `SyntaxError`** — `dz` now requires `@dzhechkov/harness-core >= 0.4.7` (was `^0.4.0`, which npm could legally resolve to a core too old to link) and says so in words, before anything is imported.
|
|
3510
3981
|
|
|
3511
|
-
|
|
3982
|
+
Previously: the global `dz --version` / `-v` / `dz version` surface (one parseable line), and `dz skills-verify --plugin-dir` / `--expect-commands` so slash-command registration is gate-visible. Both exist for `@dzhechkov/loop-designer-plugin`, which requires `dz` in `^0.4`, verifies it at run time, and falls back to `npx -y @dzhechkov/harness-cli@^0.4` when the `dz` on PATH is stale, unparseable or missing.
|
|
3512
3983
|
|
|
3513
3984
|
## Claude Plugin
|
|
3514
3985
|
|