@dzhechkov/harness-cli 0.8.21 → 0.8.23
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 +16 -16
- package/README.md +519 -155
- package/dist/boolean-flags.d.ts.map +1 -1
- package/dist/boolean-flags.js +2 -0
- package/dist/boolean-flags.js.map +1 -1
- package/dist/cli.d.ts +74 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1654 -331
- package/dist/cli.js.map +1 -1
- package/dist/known-flags.d.ts.map +1 -1
- package/dist/known-flags.js +21 -0
- package/dist/known-flags.js.map +1 -1
- package/package.json +6 -5
- package/sbom.json +15 -15
- package/src/boolean-flags.ts +2 -0
- package/src/cli.ts +1778 -359
- package/src/known-flags.ts +21 -0
package/README.md
CHANGED
|
@@ -2,19 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
The **`dz`** CLI — the main entry point to the DZ Harness Hub. Install AI skills for **Claude Code, Codex, OpenCode, Hermes, OpenClaude, GitHub Copilot** from a single command.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Install in 30 seconds
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @dzhechkov/harness-cli
|
|
9
|
+
dz setup --target claude-code --preset devops
|
|
10
|
+
dz doctor
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
You do NOT need to clone any repository to use dz. Source is for contributors — see
|
|
14
|
+
[From source (contributors only)](#from-source-contributors-only) at the end of this README.
|
|
12
15
|
|
|
13
16
|
## Why dz?
|
|
14
17
|
|
|
15
18
|
> **`dz` is a package manager + cross-compiler for your AI agent harness.** Write a skill once in one canonical form; `dz` installs it into any agent's harness, holds it to a quality bar, and lets the harness learn over time.
|
|
16
19
|
|
|
17
|
-
**The problem.** You accumulate
|
|
20
|
+
**The problem.** You accumulate 260 skills (design-thinking, QE, devops, web3, MCP, academic…). Five pains follow:
|
|
18
21
|
|
|
19
22
|
1. **Every agent wants a different layout.** Claude Code reads `.claude/skills/`, Codex `.codex/`, OpenCode/Hermes/OpenClaude their own. Hand-maintaining N copies is sync hell.
|
|
20
23
|
2. **Skills arrive from many upstream repos** — they must be *canonicalized* (brought to one form) and kept in sync without losing provenance.
|
|
@@ -120,7 +123,7 @@ Re-running is safe (existing files are skipped unless `--force`). Targets: `clau
|
|
|
120
123
|
|
|
121
124
|
Don't see your tool below? Two fallbacks: if it reads `CLAUDE.md`/`.claude/` use `--target claude-code`;
|
|
122
125
|
otherwise `dz bundle --select <ids> --out <dir>` gives a portable tree of **raw `SKILL.md`** files you can
|
|
123
|
-
point any tool at (a skill is just Markdown). Dedicated targets are on the
|
|
126
|
+
point any tool at (a skill is just Markdown). Dedicated targets are on the roadmap (contributors — see `docs/target-expansion-research.md` in the source repo).
|
|
124
127
|
|
|
125
128
|
**✅ Shipped native targets** (each compiles to the tool's own layout):
|
|
126
129
|
|
|
@@ -287,7 +290,7 @@ you know exactly which file is at fault, and you know whose defect it is.
|
|
|
287
290
|
|
|
288
291
|
## User Journey — from install to mastery
|
|
289
292
|
|
|
290
|
-
All
|
|
293
|
+
All 92 commands (MEASURED — reproducer: `node --input-type=module -e "import('./dist/index.js').then(m=>console.log(m.DZ_COMMANDS.length))"` from this package; rendered help documents 93 unique top-level names — the 92 plus the built-in `help` — pinned NAME-FOR-NAME by `test/command-inventory-parity.test.ts`) mapped to a real workflow:
|
|
291
294
|
|
|
292
295
|
```
|
|
293
296
|
DISCOVER → INSTALL → USE → CREATE → MAINTAIN → SHARE
|
|
@@ -353,9 +356,9 @@ dz help # see all commands
|
|
|
353
356
|
dz pretrain # analyze project files → recommend by tech stack
|
|
354
357
|
dz recommend "build API and deploy to K8s" # keyword match → skills + toolkits
|
|
355
358
|
dz recommend "work on this project" # unmatched? → labels suggestions as PROJECT-STACK, not task-derived
|
|
356
|
-
dz stats #
|
|
359
|
+
dz stats # 58 packages, 260 skills, 10 targets, 14 presets
|
|
357
360
|
dz dashboard # visual panel — packages, adapters, skill packs
|
|
358
|
-
dz registry # browse all
|
|
361
|
+
dz registry # browse all 260 skills by category
|
|
359
362
|
dz registry search kubernetes # find specific skills
|
|
360
363
|
dz registry --category devops # filter by domain
|
|
361
364
|
dz downloads # npm weekly download stats
|
|
@@ -503,12 +506,36 @@ dz release # gates for the whole workspace;
|
|
|
503
506
|
dz publish --dry-run # preview
|
|
504
507
|
dz publish --filter skills-devops # publish specific package
|
|
505
508
|
dz publish # publish all changed packages
|
|
509
|
+
dz publish --yes --mirror-cmd "node scripts/publish-mirror.mjs" # live publish + required mirror receipt
|
|
510
|
+
dz publish --yes --no-mirror # explicit one-run mirror opt-out
|
|
506
511
|
|
|
507
512
|
# Export portable, self-contained skill bundles for a generic consumer (e.g. a LangGraph app):
|
|
508
513
|
dz bundle --preset news --out ./dist # → ./dist/skills/<id>/ (SKILL.md + references/scripts/assets)
|
|
509
514
|
dz bundle --select news-digest,goap-research-ed25519 --out ./dist
|
|
510
515
|
```
|
|
511
516
|
|
|
517
|
+
For a live sweep that publishes at least one package, `dz publish` can run a command-hook epilogue.
|
|
518
|
+
Set it for one invocation with `--mirror-cmd`, or persist the command in `.dz/config.json`:
|
|
519
|
+
|
|
520
|
+
```json
|
|
521
|
+
{
|
|
522
|
+
"publish": {
|
|
523
|
+
"mirrorCommand": "node scripts/publish-mirror.mjs"
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
The CLI exports `DZ_PUBLISHED=name@version,…` and appends `--expect name@version,… --json`. It marks
|
|
529
|
+
the mirror `confirmed` only when the command returns JSON containing the live-manifest receipt;
|
|
530
|
+
`unconfirmed`, `skipped`, and `not-configured` remain separate report states. If npm publication
|
|
531
|
+
failed, the command returns exit `1`. If npm publication landed but a configured mirror was not
|
|
532
|
+
confirmed, it returns exit `3` and prints a usable `re-run:` command. `--dry-run`, `--no-mirror`,
|
|
533
|
+
`--bump-only`, and a live sweep with zero published packages do not execute the hook. A malformed or
|
|
534
|
+
unreadable `.dz/config.json` leaves the mirror `not-configured`, returns the ordinary publish exit code,
|
|
535
|
+
and prints `⚠ mirror: .dz/config.json unreadable — …`; an explicit `--mirror-cmd` still takes precedence.
|
|
536
|
+
The repository wrapper prints human-readable output by default; `scripts/publish-mirror.mjs --json`
|
|
537
|
+
prints exactly one JSON document (the `dz publish` epilogue always selects this mode).
|
|
538
|
+
|
|
512
539
|
---
|
|
513
540
|
|
|
514
541
|
## Three Ways to Install Skills
|
|
@@ -997,17 +1024,15 @@ extracts you scope are what leaves the machine. RU: мост в обратную
|
|
|
997
1024
|
### Пересмотр после аварийного само-ревью — `dz reqe`
|
|
998
1025
|
|
|
999
1026
|
The feature-adr pipeline's cross-model guard says *the model that writes code must not review it*.
|
|
1000
|
-
|
|
1001
|
-
Step-8 QE both
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
`
|
|
1005
|
-
freed-up limits, and settlement is FAIL-CLOSED.
|
|
1027
|
+
Historical usage-switched runs could suspend that guard under provider-limit pressure: coder AND
|
|
1028
|
+
Step-8 QE both ran on Codex. The rule used to say "re-review manually after limits reset" — an
|
|
1029
|
+
instruction nobody remembers. `dz reqe` turns it into a **debt with a lifecycle**: the run records
|
|
1030
|
+
`features/<slug>/.fa-state/reqe-due.json`, `dz usage --json` carries the outstanding count as
|
|
1031
|
+
`reqeDue`, and settlement is FAIL-CLOSED.
|
|
1006
1032
|
|
|
1007
1033
|
```bash
|
|
1008
|
-
$ dz usage
|
|
1009
|
-
|
|
1010
|
-
re-QE due: 1 usage-switched run(s) kept same-family QE — run `dz reqe` for the cross-family pass
|
|
1034
|
+
$ dz usage --json
|
|
1035
|
+
{"sessionPct":null,"weeklyPct":null,"routing":"disabled-by-design","spend":{"days":[...],"total7d":{...},"byModel":{...}},"reqeDue":1}
|
|
1011
1036
|
|
|
1012
1037
|
$ dz reqe # the ledger
|
|
1013
1038
|
dz reqe — 1 unsettled re-QE debt(s):
|
|
@@ -1018,8 +1043,8 @@ $ dz reqe --slug add-x --done --report features/add-x/08b_reqe_report.md
|
|
|
1018
1043
|
dz reqe: debt settled: re-QE grade C (report …) — settlement appended to features/add-x/08_qe_report.md
|
|
1019
1044
|
```
|
|
1020
1045
|
|
|
1021
|
-
**When to use:** any time `dz usage`
|
|
1022
|
-
`reqeDue: true`. **Fail-closed settlement:** the report must exist, be non-trivial, and name exactly
|
|
1046
|
+
**When to use:** any time `dz usage --json` reports a positive `reqeDue`, or a feature-adr result
|
|
1047
|
+
carried `reqeDue: true`. **Fail-closed settlement:** the report must exist, be non-trivial, and name exactly
|
|
1023
1048
|
one line-anchored `GRADE` (the boilerplate phrase `GRADE A-F` does not count); the run's own
|
|
1024
1049
|
`08_qe_report.md` can never settle its own debt (real-path AND inode compared — a hard link doesn't
|
|
1025
1050
|
fool it); the settlement epilogue lands in `08_qe_report.md` and the due-file rotates to
|
|
@@ -1027,12 +1052,13 @@ fool it); the settlement epilogue lands in `08_qe_report.md` and the due-file ro
|
|
|
1027
1052
|
nothing re-runs QE automatically, and the validator proves the settlement is procedurally sound —
|
|
1028
1053
|
which model authored the report stays with the human running the brief. RU: гард «кодер не ревьюит
|
|
1029
1054
|
сам себя» осознанно снимается под лимитом; `dz reqe` превращает инструкцию «перепроверь потом»
|
|
1030
|
-
в долг на диске — виден в `dz usage`, гасится только настоящим кросс-семейным отчётом с грейдом.
|
|
1055
|
+
в долг на диске — виден как `reqeDue` в `dz usage --json`, гасится только настоящим кросс-семейным отчётом с грейдом.
|
|
1031
1056
|
|
|
1032
|
-
###
|
|
1057
|
+
### Spend you can inspect — `dz usage`
|
|
1033
1058
|
|
|
1034
|
-
`dz usage`
|
|
1035
|
-
|
|
1059
|
+
`dz usage` reports cost-weighted token spend from local Claude Code and subagent transcripts. It does
|
|
1060
|
+
not predict provider limits: there is no provider usage API, weekly resets are per-account, and
|
|
1061
|
+
ad-hoc resets make a local denominator non-measurable. Feature routing is therefore disabled by design.
|
|
1036
1062
|
|
|
1037
1063
|
Two things changed to make it mean something:
|
|
1038
1064
|
|
|
@@ -1042,20 +1068,44 @@ Two things changed to make it mean something:
|
|
|
1042
1068
|
1-hour TTL write, cache-read 0.1x, output 5x).
|
|
1043
1069
|
- **Subagent transcripts count.** `<session>/subagents/*.jsonl` carry real, non-duplicated usage and
|
|
1044
1070
|
were silently excluded.
|
|
1071
|
+
- **Symlinked project directories are scanned by real path, each real directory once.** Broken links
|
|
1072
|
+
and symlinks to files are skipped.
|
|
1045
1073
|
- **The walk is safe and bounded.** Only regular files are read, symlinked files and directory
|
|
1046
|
-
components
|
|
1047
|
-
|
|
1074
|
+
components cannot create duplicate walks or loops, and the file cap keeps the NEWEST transcripts
|
|
1075
|
+
so a long history cannot push current usage out of view.
|
|
1048
1076
|
|
|
1049
1077
|
```bash
|
|
1050
|
-
dz usage
|
|
1051
|
-
dz usage --json
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1078
|
+
dz usage # seven UTC days + seven-day total + model shares + today-by-model
|
|
1079
|
+
dz usage --json # sessionPct/weeklyPct stay null; spend carries days, total7d, byModel, daysByModel
|
|
1080
|
+
```
|
|
1081
|
+
|
|
1082
|
+
The compatibility keys `sessionPct` and `weeklyPct` remain present and always `null`, so existing
|
|
1083
|
+
feature-adr probes keep parsing the payload without treating a guess as a routing signal.
|
|
1084
|
+
|
|
1085
|
+
**What `unknown` means, and which window each block covers.** The "by model" table is a
|
|
1086
|
+
**seven-day window total** — it is the same seven days as the daily table above it, collapsed
|
|
1087
|
+
across models, never a per-day figure (a defect this project has hit before: a weekly figure read
|
|
1088
|
+
as a daily one). A model row named `unknown` is the aggregation's fallback bucket, literally
|
|
1089
|
+
`event.model ?? 'unknown'` in `spendReport` — it catches BOTH of the two ways an event can carry no
|
|
1090
|
+
usable model: an event with **no model field at all**, and one whose model string did not match
|
|
1091
|
+
any of the four known substrings (`fable`/`opus`/`sonnet`/`haiku`). (Fix-round-1, Codex review
|
|
1092
|
+
MEDIUM #3: an earlier revision of this paragraph said `unknown` was "not an event without a
|
|
1093
|
+
model" — the opposite of what the code does; corrected to name both causes.) MEASURED on this
|
|
1094
|
+
machine, the second cause dominates — almost entirely `<synthetic>` assistant-turn markers, not a
|
|
1095
|
+
parsing failure — and `unknown` is always shown, never hidden, because a hidden `unknown` row would
|
|
1096
|
+
make the visible rows undercount the real total. Both the "by model" table and the "today by model"
|
|
1097
|
+
block print a third column: the model's **share as a fraction 0..1** (two decimals), not a
|
|
1098
|
+
percentage — `by model` shares are of the **seven-day total**, `today by model` shares are of
|
|
1099
|
+
**today's own total**, and a complete breakdown's column sums to `1.00` in either block (never
|
|
1100
|
+
`100` — that would be the percentage form). The `--json` payload additionally carries
|
|
1101
|
+
`spend.daysByModel`: one entry per day (same dates as `spend.days`, same order) with that single
|
|
1102
|
+
day's `{model → weightedTokens}`, `unknown` included — read `daysByModel.at(-1)` for **today's**
|
|
1103
|
+
per-model spend, which the plain-text report prints as the `today (<date>) by model` block right
|
|
1104
|
+
after the seven-day "by model" table. The invariant this rests on — every model breakdown
|
|
1105
|
+
reconciles exactly with the totals it was sliced from — is `spendInvariantViolations()` in
|
|
1106
|
+
`harness-core` (relative tolerance `max(1e-6, 1e-9·max(|a|,|b|))`, and a `NaN`/`Infinity` sum is
|
|
1107
|
+
always a violation, never a silent pass), covered by a dedicated mutation-registry entry
|
|
1108
|
+
(`usage-days-by-model-invariant`).
|
|
1059
1109
|
|
|
1060
1110
|
### Where did the run's budget actually go? — `dz usage --by-stage`
|
|
1061
1111
|
|
|
@@ -1303,6 +1353,22 @@ Four rules the gate itself obeys — these are what distinguish it from a green-
|
|
|
1303
1353
|
undefended property lives in this repo's test suite, and the gate MUST fail on it — a gate that
|
|
1304
1354
|
cannot fail cannot pass.
|
|
1305
1355
|
|
|
1356
|
+
**Where the full output of a RED baseline/rebaseline line lives** (gate-stability, 2026-09-12,
|
|
1357
|
+
fix-round-1 2026-09-12): the bounded 3-line/20-line tail in the verdict is a teaser, and under a
|
|
1358
|
+
multi-entry `--only a,b` run it was measured to hand back an unrelated neighbour's stderr —
|
|
1359
|
+
undiagnosable. When the initial baseline or a per-entry/final rebaseline line comes back non-zero,
|
|
1360
|
+
the executor saves the FULL stdout+stderr to
|
|
1361
|
+
`<os.tmpdir()>/dz-mutgate-output/dz-mutgate-<entryId|baseline>-<phase>-<ISO-timestamp>.log` and the
|
|
1362
|
+
verdict text names the path (`; full output: <path>`); a green line writes nothing. Files older
|
|
1363
|
+
than 7 days in that directory are rotated away on the next write, and rotation only ever touches a
|
|
1364
|
+
name carrying BOTH our own `dz-mutgate-` prefix AND our exact ISO-timestamp shape — a foreign file
|
|
1365
|
+
(even one shaped like `service-baseline-backup.log`, which the pre-fix-round-1 pattern would have
|
|
1366
|
+
matched and deleted) is never touched. If the save itself fails (EACCES/ENOSPC/EROFS/a blocked
|
|
1367
|
+
output directory), the verdict says so instead of silently losing the diagnostic artifact
|
|
1368
|
+
(`; full output NOT saved: <error>`) — the gate's own exit code is never changed by a logging
|
|
1369
|
+
failure. Override the directory with `DZ_MUTGATE_OUTPUT_DIR` (used by this package's own tests to
|
|
1370
|
+
avoid touching the real tmpdir).
|
|
1371
|
+
|
|
1306
1372
|
When to reach for it: after a QE round names safety properties (seed the registry so they STAY
|
|
1307
1373
|
defended); in CI for a package whose protections have burned you before (`npm run test:mutation`);
|
|
1308
1374
|
and in feature-adr Step 8, where the QE reviewer runs it whenever the touched package has a
|
|
@@ -1425,15 +1491,16 @@ Each pack is an npm package — click through for the **full per-skill documenta
|
|
|
1425
1491
|
| [@dzhechkov/skills-academic](https://www.npmjs.com/package/@dzhechkov/skills-academic) | 5 | Thesis-defense toolkit — dissertation review, questions, doc-check, defense eval |
|
|
1426
1492
|
| [@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) |
|
|
1427
1493
|
| [@dzhechkov/skills-demo-publisher](https://github.com/djd1m/dz-harness/tree/main/packages/%40dzhechkov/skills-demo-publisher) | 1 | *dz-original, staged* — scenario-driven product recording → budgeted static HTML5 video site with Russian captions and fail-closed Pages delivery checks |
|
|
1428
|
-
| [@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 (
|
|
1429
|
-
| [@dzhechkov/skills-reverse-engineering](https://www.npmjs.com/package/@dzhechkov/skills-reverse-engineering) | 1 | *dz-original* — `reverse-engineering-unicorn`: company → launch playbook (+CJM) via 6-module QUICK/DEEP/VERIFIED pipeline; canonical home that resolved the keysarium↔p-replicator drift (
|
|
1430
|
-
| [@dzhechkov/skills-presentation-storyteller](https://www.npmjs.com/package/@dzhechkov/skills-presentation-storyteller) | 1 | *dz-original* — `presentation-storyteller`: selling deck + verified sources + slide-by-slide speaker script; referenced (not vendored) by reverse-engineering-unicorn's Post-M6 step (
|
|
1431
|
-
| [@dzhechkov/skills-website-cloner](https://www.npmjs.com/package/@dzhechkov/skills-website-cloner) | 1 | *imported (MIT)* — `clone-website`: live site → pixel-perfect Next.js clone (recon → specs → parallel build → visual QA); needs a browser-MCP + Next.js scaffold; referenced by p-replicator's `/replicate` (
|
|
1432
|
-
| [@dzhechkov/skills-pm](https://www.npmjs.com/package/@dzhechkov/skills-pm) | 18 | *imported (MIT)* — product-management toolkit: OST, RICE/ICE prioritization, product-strategy, pricing, OKRs, NSM/metrics/A-B/cohort, outcome-roadmap, stakeholder-map, sprint-plan, strategy-red-team, GTM/growth/beachhead, market-sizing; curated from phuryn/pm-skills (`dz init --preset pm`) (
|
|
1433
|
-
| [@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`) (
|
|
1434
|
-
| [@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`) (
|
|
1494
|
+
| [@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, contributors-only doc) |
|
|
1495
|
+
| [@dzhechkov/skills-reverse-engineering](https://www.npmjs.com/package/@dzhechkov/skills-reverse-engineering) | 1 | *dz-original* — `reverse-engineering-unicorn`: company → launch playbook (+CJM) via 6-module QUICK/DEEP/VERIFIED pipeline; canonical home that resolved the keysarium↔p-replicator drift (ADR-0001, contributors-only doc) |
|
|
1496
|
+
| [@dzhechkov/skills-presentation-storyteller](https://www.npmjs.com/package/@dzhechkov/skills-presentation-storyteller) | 1 | *dz-original* — `presentation-storyteller`: selling deck + verified sources + slide-by-slide speaker script; referenced (not vendored) by reverse-engineering-unicorn's Post-M6 step (ADR-0001, contributors-only doc) |
|
|
1497
|
+
| [@dzhechkov/skills-website-cloner](https://www.npmjs.com/package/@dzhechkov/skills-website-cloner) | 1 | *imported (MIT)* — `clone-website`: live site → pixel-perfect Next.js clone (recon → specs → parallel build → visual QA); needs a browser-MCP + Next.js scaffold; referenced by p-replicator's `/replicate` (ADR-0001, contributors-only doc) |
|
|
1498
|
+
| [@dzhechkov/skills-pm](https://www.npmjs.com/package/@dzhechkov/skills-pm) | 18 | *imported (MIT)* — product-management toolkit: OST, RICE/ICE prioritization, product-strategy, pricing, OKRs, NSM/metrics/A-B/cohort, outcome-roadmap, stakeholder-map, sprint-plan, strategy-red-team, GTM/growth/beachhead, market-sizing; curated from phuryn/pm-skills (`dz init --preset pm`) (ADR-0002, contributors-only doc) |
|
|
1499
|
+
| [@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, contributors-only doc) |
|
|
1500
|
+
| [@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, contributors-only doc) |
|
|
1435
1501
|
| [@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,…`) |
|
|
1436
1502
|
| [@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`) |
|
|
1503
|
+
| [@dzhechkov/skills-book-clean-code](https://www.npmjs.com/package/@dzhechkov/skills-book-clean-code) | 9 | *generated by the digitizer, CP5-published 2026-09-11* — «Чистый код» (Robert C. Martin, рус. пер.): intent/comment contract, source layout, function contracts, object/data ownership, error and boundary handling, test-suite feedback, legacy refactoring loop, architecture assembly, concurrency safety; ships `brain/clean-code.sqlite` (259 KU). Shingling IP gate 0 violations on the published bytes; trust tier 1. |
|
|
1437
1504
|
|
|
1438
1505
|
### Available Presets (14)
|
|
1439
1506
|
|
|
@@ -1947,10 +2014,10 @@ runs a command that MEASURES the declared artifacts itself. It refuses a null re
|
|
|
1947
2014
|
never recorded as done), an absent or partially-present artifact set, and a stage that declares nothing
|
|
1948
2015
|
to witness — so a stage that did not happen can no longer be recorded, which the old mechanism allowed.
|
|
1949
2016
|
|
|
1950
|
-
## All Commands (
|
|
2017
|
+
## All Commands (92)
|
|
1951
2018
|
|
|
1952
|
-
*(
|
|
1953
|
-
top-level names — the
|
|
2019
|
+
*(92 MEASURED from the bounded command inventory below; rendered `dz --help` exposes 93 unique
|
|
2020
|
+
top-level names — the 92 plus the built-in `help`, which prints USAGE before the dispatch switch and
|
|
1954
2021
|
is therefore documented without being a command. Both numbers are COMPUTED, never typed: the name
|
|
1955
2022
|
sets of this section, the root README, the docs site and `DZ_COMMANDS` are pinned to each other by
|
|
1956
2023
|
`test/command-inventory-parity.test.ts`.)*
|
|
@@ -1967,7 +2034,7 @@ dz teach --from-json <file> [--project <dir>] [--no-mirror] [--harmonize] # bu
|
|
|
1967
2034
|
dz consolidate [--sessions-dir <dir>] [--project <dir>] [--no-mirror]
|
|
1968
2035
|
dz recall "<query>" [--limit <N>] [--domain <name>] [--semantic | --no-semantic] [--full] [--project <dir>] # hybrid lexical+vector when the vector tier is enabled; --domain BOOSTS same-domain lessons (never filters)
|
|
1969
2036
|
dz recall --all [--json] [--stats] [--include-domain <name,…>] # export the learned store (held-out domains are withheld unless named), or inspect learning stats/top uses
|
|
1970
|
-
dz recall --books "<query>" [--book <slug>] # digitized-book KUs; --book narrows to one book
|
|
2037
|
+
dz recall --books "<query>" [--book <slug>] # digitized-book KUs; --book narrows to one book. Reads via a read-only opener (ADR-001, store-readonly-reads): works from a read-only-mounted store directory (falls back to a temporary copy) and no longer writes `-wal`/`-shm` on every invocation
|
|
1971
2038
|
dz vector status [--project <dir>] [--json] # semantic tier: engine availability, mirrored vs lexical counts, pending queue
|
|
1972
2039
|
dz vector reindex [--project <dir>] [--json] # re-embed learned vectors with the CONFIGURED model + stamp the manifest (snapshot first; atomic — a mid-way failure restores the store). Warns about task types it does not own (e.g. book-knowledge → run `dz brain reindex`)
|
|
1973
2040
|
dz vector export <path> [--project <dir>] # portable VECTOR form (.rvf checkpoint; needs the opt-in RVF engine)
|
|
@@ -1976,13 +2043,13 @@ dz vector harmonize [--apply] [--threshold <0..1>] [--json] # SEMANTIC me
|
|
|
1976
2043
|
dz teach --harmonize [--apply] [--threshold <0..1>] # alias of `dz vector harmonize`
|
|
1977
2044
|
dz statusline [--json] [--install] # compact Claude Code statusline: live self-learning pattern count + brain sources
|
|
1978
2045
|
dz store-guard [--status|--reset] [--yes] [--project <dir>] # inspect the monotonic external high-water mark; --reset is the only lowering path and requires confirmation or --yes
|
|
1979
|
-
dz usage [--json] [--project <dir>]
|
|
2046
|
+
dz usage [--json] [--project <dir>] # 7-day UTC spend from local Claude Code + subagent transcripts; provider-limit routing disabled by design
|
|
1980
2047
|
--by-stage [--run <id> | --slug <s>] [--epsilon <0..1>] [--write <file.jsonl>] [--json] # per-stage cost ledger for ONE feature-adr run + reconciliation invariant (BALANCED | DEFECT | INSUFFICIENT_DATA)
|
|
1981
2048
|
dz chain [--project <dir>] [--json] # verify EVERY hash-chained journal in one command; coverage is DERIVED from the CHAINED_JOURNALS registry, so a journal cannot be chained and checked by nobody; an ABSENT journal is NAMED, never omitted; exit 1 on broken/unreadable
|
|
1982
2049
|
dz claim-check [paths...] [--json] [--fail-on high|medium|none] [--project <dir>] # enforce the Integrity Rule: flag untagged/overstated accuracy claims; default scan = READMEs + features' 08_qe_report.md; exit 1 only at/above --fail-on (default high)
|
|
1983
2050
|
dz lint [paths...] [--json] [--config <file>] [--registry <file>] [--project <dir>] # advisory EN/RU prose-style lint; findings exit 0, incomplete input/policy exits 1, usage exits 2
|
|
1984
2051
|
dz brain list [--json] # the durable cross-project knowledge brain
|
|
1985
|
-
dz brain query "<q>" [--source <slug>] [--limit <N>] [--any] [--rerank] [--json] # cross-source recall (--any = OR match; --rerank reorders on-point first). Auto-broadens: if strict all-terms match yields 0 hits, it retries once as OR and labels the result "broadened" (text note + broadened:true in --json) instead of returning empty. Explicit --any is OR from the start (never labeled broadened).
|
|
2052
|
+
dz brain query "<q>" [--source <slug>] [--limit <N>] [--any] [--rerank] [--json] # cross-source recall (--any = OR match; --rerank reorders on-point first). Auto-broadens: if strict all-terms match yields 0 hits, it retries once as OR and labels the result "broadened" (text note + broadened:true in --json) instead of returning empty. Explicit --any is OR from the start (never labeled broadened). `dz brain query`/`dz brain ground` read via the same read-only opener as `dz recall --books` — see ADR-001, store-readonly-reads.
|
|
1986
2053
|
dz brain add [--source <slug>] [--project <dir>] [--from-slice <f>|--from-pack <p>|--from-kus <f> --slug <s> --kind <k> --license <spdx> [--override]] [--json] # grow the brain
|
|
1987
2054
|
dz brain ground "<prompt>" [--k <N>] [--source <slug>] [--text] [--budget <N>] [--full] # retrieve + emit grounding citations (hook entrypoint; silent if irrelevant); --budget N eager-inlines top-K KU content within ~N tokens (chars/4 approx); --full = --budget 8000
|
|
1988
2055
|
dz brain expand <kuId> [--source <slug>] [--json] # full-content lookup by kuId — the command the grounding directive names; prints name/problem/pages/book + FULL content (untruncated)
|
|
@@ -1990,6 +2057,8 @@ dz brain init [--project <dir>] [--k <N>] # opt-in: w
|
|
|
1990
2057
|
dz brain primer <slug> [--json] # print a source's capability card (histogram + top decision moments)
|
|
1991
2058
|
dz brain export --source <slug> --out <file> # write a portable per-book KB slice (ships inside the pack, §8.1)
|
|
1992
2059
|
dz brain update <slug> [--project <dir>] [--json] # non-destructive refresh: re-mirror a re-ingested source, evict stale corpus
|
|
2060
|
+
dz brain reindex [--json] # snapshot + re-embed the brain's book-KU vectors, stamp current model; ALSO rotates the brain's own pre-reindex snapshots on success (default keep 3)
|
|
2061
|
+
dz brain snapshots [--keep <N>] [--prune] [--json] [--project <dir>] # list (default) — or, with --prune, rotate — the brain's own `agentdb.db.pre-reindex-<ms>.bak` snapshot families; reaches the same rotation WITHOUT running a reindex
|
|
1993
2062
|
dz pretrain [--project <dir>]
|
|
1994
2063
|
dz recommend "<task description>" [--json] (RU/EN lexical topics; explicit task/project-stack/none provenance)
|
|
1995
2064
|
dz compose <preset1+preset2+...> [--target <name>]
|
|
@@ -2016,7 +2085,86 @@ dz discrimination-check --test <f[,f]> [--base <ref>] [--name <filter>] [--runne
|
|
|
2016
2085
|
dz amendment-check --slug <slug> | --feature-dir <dir> | --all [--json] (every AM-N / AM-CP-N amendment row must resolve to a test found INSIDE the file the row names; the PLAN is authoritative when it carries rows, and an ideation amendment the plan drops is a failure; --all is a census that always exits 0; exit 0 pass/skip, 1 fail, 3 NOT-ESTABLISHED — ZERO parsed rows may skip only when the whole first paragraph or heading suffix is exactly "None"/"N/A"/"нет", optionally with a full stop; an optional CommonMark closing # sequence is heading furniture, qualified text is refused, and AM-like content beside the declaration is NOT-ESTABLISHED)
|
|
2017
2086
|
dz contract-check --slug <s> [--json] (read-only retrospective feature contract gate: canonical AC-N + ADR Confirmation → CC-N; every item needs one artifact-anchored met|unmet|not-testable verdict; A/B with unmet is refused; exit 0 pass / 1 readable violation / 2 invalid invocation or unreadable/not-established artifacts)
|
|
2018
2087
|
dz journal add --kind decision|verdict|run|error|block "<text>" [--ref <trace>] [--at <ISO>] [--quote <file>] [--commit-quote]; show [--day|--week] [--at <date>] [--kind <kind>] [--json] # UTC day files, witnessed append; quotes local by default
|
|
2019
|
-
dz feature-adr-record --kind ledger|training-pair --stage <s> [--slug <s>] [--row|--pair <json>] [--mark <n>] [--once] [--json] (the witnessed writer: payload as an ARGUMENT never as shell, refused before any write,
|
|
2088
|
+
dz feature-adr-record --kind ledger|training-pair --stage <s> [--slug <s>] [--row|--pair <json>] [--run-id <id>] [--mark <n>] [--once] [--json] (the witnessed writer: payload as an ARGUMENT never as shell, refused before any write; for a ledger row `ts` is ALWAYS the real write instant (a payload `ts` survives as `payloadTs`, never lost); `--run-id` fills a MISSING `runId` — absent, null, empty, or non-string — and tags it `runIdSource:'cli-flag'`; `minutesSincePrev`/`minutesSource` on an auto ledger row measure against the previous row of the same run, reporting `unavailable` on no prior row OR a corrupt/non-object ledger line anywhere in between; new fields never reorder existing ones; append verified by re-reading the tail; exit 0 written|duplicate|skipped, 2 refused, 3 not-verified, never blocking)
|
|
2089
|
+
dz round open --slug <s> --round <n|auto> --topic "<topic>" [--run <id>] [--owner-pid <n> | --owner-run <runId>] [--force] | exec --slug <s> --round <n> --brief <file> [--log <file>] [--model gpt-5.6-sol] [--effort high] [--timeout-min 30] | close --slug <s> --round <n> --outcome shipped|refuted|blocked|abandoned (--lesson teach:<id>... | --no-new-knowledge "<reason>") [--no-cost] | status [--older-than <minutes>] -- every subcommand also takes [--state-root <dir>] (or DZ_ROUND_STATE_ROOT) # open records the parent process by default; --owner-pid records a process and --owner-run records a run-registry owner; live/stalled runs are live, finished/orphaned runs are dead, and unknown registry state stays unknown; open --force refuses a live or unknown owner
|
|
2090
|
+
|
|
2091
|
+
The round owner is the session shell (`process.ppid`) by default. Under `setsid`, or in a container
|
|
2092
|
+
where that parent is PID 1, pass `--owner-pid <pid>` for the real supervising process; otherwise PID 1
|
|
2093
|
+
can make an abandoned round appear permanently owned by a live process.
|
|
2094
|
+
|
|
2095
|
+
`--state-root <dir>` (or `DZ_ROUND_STATE_ROOT=<dir>`, flag wins when both are set) names where round
|
|
2096
|
+
state (`.dz/rounds/`) AND its ledger row live — every subcommand reads/writes under this root instead
|
|
2097
|
+
of cwd when it is given. **`--project` is unrelated and stays recall-only**: `open` only ever passes
|
|
2098
|
+
it to `dz recall` for lessons, round state itself has always lived in cwd (lesson `2ac30a70`), and
|
|
2099
|
+
`--state-root` is the flag that actually redirects that state. The value must be an absolute path —
|
|
2100
|
+
a relative one is refused with exit 2 before anything is written. Without the flag or the variable,
|
|
2101
|
+
behavior is unchanged (state in cwd, exactly as before this flag existed). `open` always prints the
|
|
2102
|
+
resolved root as `state root: <dir>` (text) / `stateRoot` (JSON), so a caller never has to assume it
|
|
2103
|
+
landed in cwd; `status` prints the same `stateRoot` in JSON always, and the `state root: <dir>` text
|
|
2104
|
+
line only when `--state-root`/`DZ_ROUND_STATE_ROOT` was actually given (its default-cwd text output
|
|
2105
|
+
is otherwise unchanged, byte-for-byte, from before this flag existed).
|
|
2106
|
+
|
|
2107
|
+
Every mutation of `.dz/rounds/<slug>-<round>.json` (`open`'s archive+write, `exec`'s owner-claim and
|
|
2108
|
+
owner-restore writes, `close`'s final reread+delete) runs under ONE named lock,
|
|
2109
|
+
`<stateRoot>/.dz/locks/round-state.lock` (`withNamedLockSync`, feature round-state-lock) — two `dz
|
|
2110
|
+
round` processes sharing a `--state-root` can no longer lose each other's update. Recall (`open`) and
|
|
2111
|
+
the run-cost ledger write (`close`) stay OUTSIDE the lock — they can be slow, and the lock must not be
|
|
2112
|
+
held across anything that isn't a short, synchronous read-modify-write. `open` rereads state again
|
|
2113
|
+
UNDER the lock right before writing: if recall ran for a while and a different process opened the
|
|
2114
|
+
same round in the meantime, `open` refuses instead of silently overwriting that process's state.
|
|
2115
|
+
`status` never takes the lock (read-only) and keeps working while it is held elsewhere. Two refusals,
|
|
2116
|
+
both observable, neither one leaves a state file half-written:
|
|
2117
|
+
- **`already-open`** — a different process's state appeared while `open` was recalling: exit 1,
|
|
2118
|
+
`круг уже открыт (pid …) — состояние не перезаписано`, `--json` carries `{"refused":"already-open",
|
|
2119
|
+
"pid": <n>}`. The ORIGINAL state (the other process's) is left on disk untouched.
|
|
2120
|
+
- **`lock-busy`** — the lock could not be acquired before its deadline (another process is still
|
|
2121
|
+
inside its own critical section): exit 1, `lock busy: …`, `--json` carries `{"refused":"lock-busy"}`.
|
|
2122
|
+
Nothing is written; for `close` specifically, the run-cost ledger row is written BEFORE this lock is
|
|
2123
|
+
ever attempted (see above), so a `close` that hits `lock-busy` on its final delete has already logged
|
|
2124
|
+
the outcome — only the round's own state file is left undeleted (retry `close` to finish it).
|
|
2125
|
+
|
|
2126
|
+
**Fix-round (identity beats pid, `stateId`).** Every state `open` writes carries a `stateId` (16
|
|
2127
|
+
random hex chars) — the token `exec`/`close` compare against, not pid: `process.ppid` coincides for
|
|
2128
|
+
two `dz` launched from the same shell, and every run-owned state carries pid 0, so pid alone could
|
|
2129
|
+
not tell a genuine race from an innocent coincidence.
|
|
2130
|
+
- `open`'s recheck-under-lock now refuses on ANY raw-byte change since the pre-recall snapshot
|
|
2131
|
+
(pid is diagnostic-only in the refusal text), except a vanished file — a round closed while `open`
|
|
2132
|
+
was recalling is not a race to refuse, it is the ordinary "no existing round" case, `--force` or not.
|
|
2133
|
+
- `exec`'s claim AND owner-restore sections both refuse — leaving the file untouched — when the state
|
|
2134
|
+
under the lock is gone (`круг закрыт во время exec, владелец не менялся`) or carries a DIFFERENT
|
|
2135
|
+
`stateId` (`состояние круга заменено (stateId …), возврат владельца пропущен`); neither section ever
|
|
2136
|
+
falls back to resurrecting or overwriting with a stale pre-lock snapshot. The owner-restore lock is
|
|
2137
|
+
retried up to 3 times at the same timeout before giving up; if it still cannot recover ownership, the
|
|
2138
|
+
round is left `ownerKind: 'exec'` and the command says so in prose (`владелец круга не восстановлен
|
|
2139
|
+
(ownerKind=exec остался): повторите dz round exec для этого круга, когда блокировка освободится`) —
|
|
2140
|
+
no new flag is added for this. `open` and `status` warn on their own when a round has been sitting at
|
|
2141
|
+
`ownerKind: 'exec'` for 10+ minutes, so a stuck claim is never silently left for someone to trip over.
|
|
2142
|
+
- `close`'s final delete deletes ONLY the state instance its own ledger row was written for (matched by
|
|
2143
|
+
`stateId`): a state that vanished under the lock is `круг уже закрыт (строка леджера записана)` (exit
|
|
2144
|
+
0 — the same round reaching its own success postcondition a different way, not a failure); a state
|
|
2145
|
+
replaced by a different `stateId` is `состояние заменено, не удалено` (exit 1, never deleted). A
|
|
2146
|
+
`close` that hits `lock-busy` on the delete step now says exactly what already happened:
|
|
2147
|
+
`строка леджера записана, состояние круга осталось открытым — повторите close`, `--json` carries
|
|
2148
|
+
`{"refused":"lock-busy","ledgerWritten":true}` — and the retry is idempotent: if the ledger already
|
|
2149
|
+
carries this attempt's row (same slug/round/closedAt), the retry does not append a second one.
|
|
2150
|
+
|
|
2151
|
+
`feature-adr` is one outer round, not one round per stage. Step 0 opens it with `--round auto` and
|
|
2152
|
+
`--run fa:<slug>` plus `--owner-run <runId>` when the run-registry start receipt supplies a non-empty
|
|
2153
|
+
id, so the run registry—not the short-lived command process—owns its liveness. If that best-effort
|
|
2154
|
+
registry write fails, the workflow omits `--owner-run`, logs the fallback explicitly, and keeps round
|
|
2155
|
+
tracking under the command's ordinary explicit owner. Step 8 maps the QE grade to the outcome and
|
|
2156
|
+
closes with `--no-cost`. The existing stage ledger commands remain byte-stable and remain the only
|
|
2157
|
+
cost source, so cadence/usage readers do not count the same minutes or tokens twice. A refused close
|
|
2158
|
+
is logged and returned as `roundClosed:false` without failing the feature run.
|
|
2159
|
+
|
|
2160
|
+
In round rows, `tokens: null` means tokens were not measured; an explicit `--tokens 0` remains zero.
|
|
2161
|
+
Automatic feature-adr stage rows keep total `tokens` null and record the measurable partial cost as
|
|
2162
|
+
`tokensOut`, with `tokensOutSource` naming `budget.spent` or `unavailable`.
|
|
2163
|
+
|
|
2164
|
+
When `args.dzBin` is supplied, feature-adr uses it without a selection/version agent call and logs
|
|
2165
|
+
version `not probed (dzBin given)`. With no `dzBin`, binary selection costs no more than **3 additional
|
|
2166
|
+
agent calls**: up to 2 `probeSessionCwd` attempts when the workspace is not yet known, plus 1 combined
|
|
2167
|
+
probe that both selects the workspace build or PATH fallback and prints the selected binary's version.
|
|
2020
2168
|
dz runs [--settle] [--stall-minutes N] [--json] [--project <dir>] (read the run registry: live / stalled / orphaned / inconclusive / finished)
|
|
2021
2169
|
dz runs-record --event started|heartbeat|finished [--run-id <id>] [--kind <kind>] [--slug <slug>] [--pid <pid|host>] [--parent-run-id <id>] [--outcome <text>] [--project <dir>] [--json] (append one run event)
|
|
2022
2170
|
dz runs-clean [--apply] [--retention-days N] [--project <dir>] [--json] (plan cleanup of old clean merged worktrees and dead/finished registry histories; apply explicitly)
|
|
@@ -2031,7 +2179,7 @@ dz epoch-replay --judge <filled-work-order.json> [--out <file>] [--json] # bli
|
|
|
2031
2179
|
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
|
|
2032
2180
|
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
|
|
2033
2181
|
dz recap [--day|--week|--month] [--at <ISO date>] [--refresh-publishes] [--project <dir>] [--json] # what was done over a window, from records only. `--refresh-publishes` fills the third-party publish-times cache first (the ONLY place this command touches the network — 51 packages in ~7s, batches of 8); the report itself always reads the cache, prints its AGE, and names any package the registry did not answer for: those are MISSING from the numbers, not zero. Deliveries carry the grade an independent review STATED — a report naming two different grades is reported AMBIGUOUS, never guessed; registry publishes come from a cache (51 packages cost 18.3s over the network, MEASURED — never inside a report); gate verdicts and knowledge reuse come from the local stores. --quarter/--half-year/--year are RECOGNISED and REFUSED with the real span in days: there is exactly ONE complete quarter and the longest record is 174 days, so a quarter-over-quarter comparison is arithmetically impossible and a year would be fabrication. Every section carries its own data-start date, and "the source was not read" never prints as a zero. Contaminated measures are NOT computed and the report says so: commit count (this project mandates a commit per logical change), lines changed (352 of 1318 commits are docs), token spend (self-declared an estimate, once wrong sixfold), learning-event volume (the curve tracks when hooks were installed), inventory counts (monotonic — they can only flatter), lesson count (54% of the pool has never been read). exit 0 reported / 2 refused
|
|
2034
|
-
dz cadence [--window day|week|month|quarter|halfyear|year] [--json] # the RHYTHM view of what shipped: graded-shipment counts bucketed by ISO week, npm-publish cadence (reads `dz recap`'s publish-times cache — run `dz recap --refresh-publishes` to warm it), guard repeat DECAY on the FIXED rule set (a rule joins only with pre-window history, so a newborn rule's zero is youth, not virtue — the no-stubs false-zero class excluded by construction), and recall reuse per week. A window deeper than 2× the record is REFUSED with the measured depth and the largest honest window named (a cadence from under two full windows is scale forgery). Sibling of `dz recap`: recap is the narrative what-was-done report over one window; cadence is the week-by-week rhythm across the window. exit 0 / 2 refused-window / 1 usage
|
|
2182
|
+
dz cadence [--window day|week|month|quarter|halfyear|year] [--json] # the RHYTHM view of what shipped: graded-shipment counts bucketed by ISO week, round/round-exec outcomes with every unfinished round named, packages/ commits in the window (`not measured` when git is unavailable), npm-publish cadence (reads `dz recap`'s publish-times cache — run `dz recap --refresh-publishes` to warm it), guard repeat DECAY on the FIXED rule set (a rule joins only with pre-window history, so a newborn rule's zero is youth, not virtue — the no-stubs false-zero class excluded by construction), and recall reuse per week. A window deeper than 2× the record is REFUSED with the measured depth and the largest honest window named (a cadence from under two full windows is scale forgery). Sibling of `dz recap`: recap is the narrative what-was-done report over one window; cadence is the week-by-week rhythm across the window. exit 0 / 2 refused-window / 1 usage
|
|
2035
2183
|
dz profile init | show | set <field> <value> | sync [--target claude] # WHO is being talked to. Per-USER store ~/.dz/profile.json (0600, never under a project root), delivered as a marked block in ~/.claude/CLAUDE.md so it loads in EVERY project on the machine, dz installed or not. Two axes: default register (pro | pro-lite | plain; RU aliases профи / профи лайт / просто) and named domains that move it — `deep` = full pro no scaffolding, `weak` = one plain sentence EVERY time unprompted, MANDATORY there. Three fixed rules ride along and the register cannot override them: an explanation is SELF-CONTAINED (every term glossed at first use in THIS passage), the register governs dialogue and owner-facing surfaces but NEVER ADRs / commits / QE reports / npm READMEs, and it changes FORM not FACTS. `show` always prints the store path and the profile's age; an unknown register value is REFUSED naming the accepted set, never silently defaulted; a hand-edited block is reported as drift and `sync` repairs it with a timestamped backup, foreign content preserved byte-for-byte. Redacted from training-pair capture (.dz/fa-training/ records the full prompt and is deliberately not gitignored)
|
|
2036
2184
|
dz qe-rounds (--slug <feature> | --feature-dir <abs>) [--ceiling <n>] [--project <dir>] [--json] # how many Step-8 review rounds has this feature ALREADY had? The rule "Max iterations: 3" lived only as a sentence in a prose module, so every restart of the agent forgot it — MEASURED, one real slug reached 38 graded rounds. Reads what `dz qe-bridge` already wrote (signoff-<runId>.json / failed-*.json under features/<slug>/.fa-state/qe-bridge) and writes NOTHING itself, so it answers for runs already past. A round is a runId, not a file; an attempt with no verdict is counted separately and never merged; ONE directory, never a union across checkouts. FAILS CLOSED: if any record cannot be counted the verdict is NOT ESTABLISHED, never a smaller number presented as the answer. exit 0 under the ceiling / 1 at-or-over — the owner decides, this never judges whether the rounds were warranted / 2 NOT ESTABLISHED, which is never "zero rounds"
|
|
2037
2185
|
dz restart-advisor --slug <feature> [--threshold C|D] [--rounds <n>] [--json] # manual, read-only advice over this feature's QE history. Defaults: threshold D, rounds 2. Reads only features/<slug>/.fa-state/checkpoints.jsonl and .dz/fa-training/<slug>/qe.jsonl; when both carry QE rounds they must normalize identically and are never unioned. RESTART_CODE_STAGE is a recommendation for the operator, not an action: autoAction is always false, and every firing result includes an explicit decision-log line. exit 0 established recommendation/no-recommendation / 2 invalid or not established / 1 unexpected runtime failure
|
|
@@ -2046,10 +2194,10 @@ dz backlog <sub> add "<idea>" | list | show <id> | goals [--validate] | roul
|
|
|
2046
2194
|
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
|
|
2047
2195
|
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
|
|
2048
2196
|
dz verify-pack --pack <dir> [--pubkey <path>] # signature check of a pack: fail-closed, and the trust root comes from the repo, never from the pack it is verifying
|
|
2049
|
-
dz guard check --op <publish|teach|consolidate|reindex> [--text <s>] [--json] [--force <reason>] # declarative constraint layer before self-mutating ops: HARD violation → block (exit 1), SOFT → warn; zero-config defaults, .dz/guard.json to customise; dz guard --init | dz guard log (append-only audit). dz publish runs it automatically (--no-guard "<reason>" = logged escape hatch)
|
|
2197
|
+
dz guard check --op <publish|teach|consolidate|reindex> [--text <s>] [--json] [--force <reason>] # declarative constraint layer before self-mutating ops: HARD violation → block (exit 1), SOFT → warn; zero-config defaults, .dz/guard.json to customise; dz guard --init | dz guard log (append-only audit). The built-in SOFT `rounds-traced` rule warns at 10 packages/ commits since the latest round receipt (or the ledger's first row when no round exists); a null git fact is `not measured`, and `.dz/config.json` `rounds.traced:false` is a named skip. dz publish runs it automatically (--no-guard "<reason>" = logged escape hatch)
|
|
2050
2198
|
dz guard promote [--dry-run | --apply] [--window-days <N>] [--periods <N>] [--json] # lesson → guard-rule promotion: ranks lessons by firings × cost, SHADOW-replays each candidate over real commits, and proposes a rule only after TWO consecutive wins AND two window-lengths of REAL elapsed time since first observation. Non-dry runs add bounded prospective funnel evidence to .dz/promotion-state.json without feeding the verdict; --dry-run remains write-free. --apply installs SOFT rules only; promotions/refusals remain under features/guard-promotion/promotions/
|
|
2051
2199
|
dz feature-adr-setup --guards [--loc-cap <n>] [--apply] # P3: scaffold DETERMINISTIC guard tests into the project — guards.config.json + a zero-dependency check.mjs runner (LOC cap, secret scan, frozen-file sha256 pins, waivers-with-reasons); wire `node architecture/guards/check.mjs` into CI
|
|
2052
|
-
dz publish [--filter <name>] [--bump-only] [--claim-check <off|warn|error>] (dry-run by default; pass --yes/--confirm to go live;
|
|
2200
|
+
dz publish [--filter <name>] [--bump-only] [--claim-check <off|warn|error>] [--mirror-cmd <cmd>|--no-mirror] (dry-run by default; pass --yes/--confirm to go live; a configured mirror must return a live receipt or the published run exits 3; config: publish.mirrorCommand)
|
|
2053
2201
|
dz parity [--target <name>] [--json] # honest feature×target map COMPUTED from the capability model — full / manual (via which form) / absent, per target
|
|
2054
2202
|
dz release [--filter <name>] [--affected] [--audit-dev] [--tag] [--publish] [--json] [--dry-run] [--no-issue] # VERIFIED release: 4 HARD gates in front of dz publish — package test suites, pnpm audit --prod >=high (--audit-dev widens), node --check of every dist/bin file (unbuilt package with a build script ⇒ MISSING_DIST fail), bin smoke-boot "node <bin> --help" (temp cwd + timeout); --affected narrows to git-touched packages (fail-open); any red gate STOPS the release (exit 1) + best-effort gh issue; green ⇒ re-sign reminder, then the ready dz publish command (never with --yes injected)
|
|
2055
2203
|
dz auto-canonicalize --source <github-url> --pack <skills-pack>
|
|
@@ -2076,7 +2224,7 @@ dz import-ecc [--local-path <dir>] [--select id,id,...] [--limit N] [--out
|
|
|
2076
2224
|
```
|
|
2077
2225
|
|
|
2078
2226
|
Built-in, not a command: `dz help` prints this same USAGE and is handled before the dispatch switch,
|
|
2079
|
-
so `dz --help` lists
|
|
2227
|
+
so `dz --help` lists 93 names while the canonical inventory above holds 92 (ADR-001 of feature
|
|
2080
2228
|
`command-count-triad`).
|
|
2081
2229
|
|
|
2082
2230
|
**Adding a command — the whole checklist, in order.** It replaces the seven-place folklore that used
|
|
@@ -2219,27 +2367,25 @@ echo "how do I handle replication lag?" | dz brain ground --budget 2000 # eage
|
|
|
2219
2367
|
|
|
2220
2368
|
### Live self-learning panel (`dz statusline`)
|
|
2221
2369
|
|
|
2222
|
-
The
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
store guard reads it as an integrity signal, and narrowing it would look like a store collapse.
|
|
2230
|
-
The JSON payload exposes these warnings as `patternMirror`; parity omits that field. Both surfaces
|
|
2231
|
-
carry the indicator — the combined panel helper and `dz statusline` itself.
|
|
2370
|
+
The panel always names the mirror: `mirror: N lessons (pending M)` when readable, or `mirror: absent` when it is not configured.
|
|
2371
|
+
Its JSON `mirror` section reports `{available, rows, lessons, pending, source:'agentdb'}`; `patternMirror` compares only mirrorable lexical lessons and reports class/noise exclusions.
|
|
2372
|
+
|
|
2373
|
+
A mirror that EXISTS but cannot be read remains a distinct degraded state (`mirror: unreadable ⚠`).
|
|
2374
|
+
Mirror lesson counts exclude backlog ideas and book units, while the lexical comparison also excludes
|
|
2375
|
+
class lessons and noise rejected by the writer. `vectorRows` remains the full physical count because
|
|
2376
|
+
the store guard consumes it as an integrity signal.
|
|
2232
2377
|
|
|
2233
2378
|
`dz statusline` renders a compact Claude Code statusline that surfaces dz's learning at a glance:
|
|
2234
2379
|
|
|
2235
2380
|
```
|
|
2236
|
-
🎓 dz: 12 (9 active · 3 quarantined)
|
|
2381
|
+
🎓 dz: 12 (9 active · 3 quarantined) · mirror: 11 lessons (pending 1) · 🧠 3 sources (223/315/60)
|
|
2237
2382
|
```
|
|
2238
2383
|
|
|
2239
|
-
The parenthesized split is read
|
|
2384
|
+
The parenthesized split is read from the primary lexical store; its JSON source is `lexical+mirror`
|
|
2385
|
+
when the mirror is readable and `lexical` otherwise. A row is quarantined exactly
|
|
2240
2386
|
when parsed metadata has `qStatus: "quarantined"`; historical fields do not count. The quarantine
|
|
2241
2387
|
fragment is omitted at zero, `⚠` appears at one third of the pool, and `⚠ tiers ΔN` reports a
|
|
2242
|
-
quarantine-label difference greater than five rows
|
|
2388
|
+
quarantine-label difference greater than five rows across the mirrorable populations. `M sources` is how many
|
|
2243
2389
|
brain sources (book-KBs / grounding stores) are wired, and the parenthesised list after it gives the
|
|
2244
2390
|
KU volume of EACH source in brain order — four sources of 300 units and four of three read
|
|
2245
2391
|
identically without it. The list is omitted (bare source count) when the volumes cannot be
|
|
@@ -2401,75 +2547,36 @@ the exact `dz store-guard --reset --project '<dir>'` command. `--status` and gua
|
|
|
2401
2547
|
selected lexical source; when both SQLite and JSONL exist they also name the ignored JSONL row count.
|
|
2402
2548
|
The snapshot helper supports both lexical formats.
|
|
2403
2549
|
|
|
2404
|
-
### Usage
|
|
2405
|
-
> **Pin the weekly reset to an ABSOLUTE instant.** `weeklyResetAnchor: "Wed 08:59"` is
|
|
2406
|
-
> server-timezone-relative — measured: the same moment lands a week apart under UTC vs `+03:00`, so
|
|
2407
|
-
> after a real account reset the counter can keep showing the OLD week for hours while printing the
|
|
2408
|
-
> "correct" clock time. Add your offset: `"Wed 08:59 +03:00"` in `.dz/config.json` — the boundary
|
|
2409
|
-
> then never moves with the machine's timezone, and `dz usage` prints the full anchor
|
|
2410
|
-
> (`resets Wed 08:59 +03:00`). Without an offset it warns on every run.
|
|
2550
|
+
### Usage spend (`dz usage`)
|
|
2411
2551
|
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
counts use the active fixed-length transcript block (`memory.usage.sessionBlockHours`, normally `5`).
|
|
2552
|
+
`dz usage` prints a READONLY, never-throw spend report over the last seven UTC calendar days,
|
|
2553
|
+
aggregated from local `~/.claude/projects/**/*.jsonl` Claude Code and subagent transcripts. Every day
|
|
2554
|
+
shows weighted tokens, raw input/output/cache-read/cache-write tokens, and event count; the report
|
|
2555
|
+
also carries a seven-day total and cost-weighted model shares.
|
|
2417
2556
|
|
|
2418
2557
|
```bash
|
|
2419
|
-
dz usage
|
|
2420
|
-
dz usage --json
|
|
2421
|
-
```
|
|
2422
|
-
|
|
2423
|
-
**Exit code is 0 ALWAYS** (even unconfigured/error → all-null JSON) — a probe must never distinguish
|
|
2424
|
-
"usage unknown" from "command failed" via a non-zero exit. Percentages are **ESTIMATES** from local
|
|
2425
|
-
transcripts; claude.ai/settings/usage is authoritative. They are `null` until you configure the
|
|
2426
|
-
plan-dependent limits in `.dz/config.json`:
|
|
2427
|
-
|
|
2428
|
-
```json
|
|
2429
|
-
{
|
|
2430
|
-
"memory": {
|
|
2431
|
-
"usage": {
|
|
2432
|
-
"sessionTokenLimit": 200000000,
|
|
2433
|
-
"weeklyTokenLimit": 1000000000,
|
|
2434
|
-
"weeklyResetAnchor": "Wed 08:59",
|
|
2435
|
-
"sessionBlockHours": 5,
|
|
2436
|
-
"weeklyTokenLimitByModel": { "fable": 500000000 }
|
|
2437
|
-
}
|
|
2438
|
-
}
|
|
2439
|
-
}
|
|
2558
|
+
dz usage
|
|
2559
|
+
dz usage --json
|
|
2440
2560
|
```
|
|
2441
2561
|
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
when it has at least one valid model limit (`fable`, `opus`, `sonnet`, or `haiku`), `weeklyPct` is the
|
|
2445
|
-
binding per-model percentage and `--json` adds:
|
|
2562
|
+
The weighting is input `1x`, five-minute cache write `1.25x`, one-hour cache write `2x`, cache read
|
|
2563
|
+
`0.1x`, and output `5x`. The JSON contract is:
|
|
2446
2564
|
|
|
2447
2565
|
```json
|
|
2448
2566
|
{
|
|
2449
|
-
"
|
|
2450
|
-
"
|
|
2567
|
+
"sessionPct": null,
|
|
2568
|
+
"weeklyPct": null,
|
|
2569
|
+
"routing": "disabled-by-design",
|
|
2570
|
+
"spend": { "days": [], "total7d": {}, "byModel": {} },
|
|
2571
|
+
"reqeDue": 0
|
|
2451
2572
|
}
|
|
2452
2573
|
```
|
|
2453
2574
|
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
```bash
|
|
2460
|
-
dz usage --calibrate --session 20 --weekly 50 --model fable=76 --project .
|
|
2461
|
-
```
|
|
2462
|
-
|
|
2463
|
-
It computes each limit as `currentTokens / (pct / 100)`, writes only `memory.usage` in
|
|
2464
|
-
`.dz/config.json`, and records `calibratedAt` plus `source: "claude.ai/settings/usage"`. Invalid
|
|
2465
|
-
percentages, unknown models, missing transcripts, and zero-token calibration requests are skipped with
|
|
2466
|
-
exit code `0`.
|
|
2467
|
-
|
|
2468
|
-
This feeds `/feature-adr`'s **usage-adaptive routing** — the pipeline probes `dz usage --json` at each
|
|
2469
|
-
phase boundary and pre-emptively routes the remaining stages to Codex when `sessionPct` or the binding
|
|
2470
|
-
`weeklyPct` crosses the threshold (default 70%). **Honest caveat:** at TRUE exhaustion even the Codex
|
|
2471
|
-
dispatch dies (`codex:codex-rescue` is a Claude wrapper), so the switch must happen BEFORE — the
|
|
2472
|
-
pre-emptive probe, not reactive detection, is the real defense.
|
|
2575
|
+
The percentage keys deliberately remain present and always `null` for the existing feature-adr probe.
|
|
2576
|
+
Provider limits are not measurable locally: there is no provider usage API, weekly resets are tied to
|
|
2577
|
+
an account, and ad-hoc resets invalidate a learned denominator. `--calibrate` was removed and returns
|
|
2578
|
+
exit `2` with that reason. Existing `.dz/config.json` limit fields are neither read for this report nor
|
|
2579
|
+
modified.
|
|
2473
2580
|
|
|
2474
2581
|
### Claim check (`dz claim-check`)
|
|
2475
2582
|
|
|
@@ -3391,6 +3498,102 @@ dz setup --target claude-code --preset devops --memory agentdb # AgentDB (vect
|
|
|
3391
3498
|
| **MCP tools** | 0 | pattern, reflexion, causal, skill, hierarchy (whatever the pinned `agentdb` build exposes — `dz` hardcodes no count) |
|
|
3392
3499
|
| **Dependencies** | None | agentdb (optional, via npx) |
|
|
3393
3500
|
|
|
3501
|
+
### The apply leg — `dz setup --memory agentdb` installs the whole loop, not two of three
|
|
3502
|
+
|
|
3503
|
+
Self-learning is a three-leg loop: **collect** (session hooks write into the store above),
|
|
3504
|
+
**rank** (`dz teach` / `dz recall` / `dz consolidate` score and retrieve), and **apply** (a
|
|
3505
|
+
`UserPromptSubmit` hook injects the top-ranked lessons back into your next prompt, automatically).
|
|
3506
|
+
Before this feature `dz setup` shipped the first two legs only — the apply leg's files existed
|
|
3507
|
+
solely in this repo's own `.claude/helpers/`, so every OTHER project that ran `dz setup --memory
|
|
3508
|
+
agentdb` got collection and ranking, but never automatic recall (MEASURED: a clean install wrote no
|
|
3509
|
+
`UserPromptSubmit` entry at all, on 0.8.10 and 0.8.23 alike, with or without `--memory agentdb`).
|
|
3510
|
+
|
|
3511
|
+
`dz setup --target claude-code --memory agentdb` now installs all three, additively (a repeat run
|
|
3512
|
+
changes nothing; a foreign hook you wrote yourself is left exactly where it is):
|
|
3513
|
+
|
|
3514
|
+
| What | Where | Purpose |
|
|
3515
|
+
|---|---|---|
|
|
3516
|
+
| `recall-hook.cjs` | `.claude/helpers/` | `UserPromptSubmit` hook — asks the embed daemon for relevant lessons, injects them as prompt context, silent when nothing clears the relevance floor |
|
|
3517
|
+
| `dz-embed-daemon.mjs` | `.claude/helpers/` | Resident embedding daemon behind a unix socket — keeps the ~1.5 s model-load cost off every single prompt |
|
|
3518
|
+
| `UserPromptSubmit` entry | `.claude/settings.json` | Runs the recall hook (`node ".../recall-hook.cjs" 2>/dev/null \|\| true` — a broken hook never blocks a prompt) |
|
|
3519
|
+
| `SessionStart` entry | `.claude/settings.json` | Spawns the embed daemon detached (`sh -c 'nohup node ".../dz-embed-daemon.mjs" ... & exit 0'`) |
|
|
3520
|
+
|
|
3521
|
+
The hook resolves your harness-core installation by an ABSOLUTE PATH baked in at `dz setup` time
|
|
3522
|
+
(the installation actually running the command), first in its candidate list — no more guessing at
|
|
3523
|
+
`/usr/lib/node_modules/...`, which silently failed on any other npm prefix (nvm, `/usr/local`, a
|
|
3524
|
+
global install elsewhere). Project-local candidates (`node_modules/`, a monorepo checkout) stay as
|
|
3525
|
+
fallbacks after it.
|
|
3526
|
+
|
|
3527
|
+
**On the jsonl backend** (no `--memory agentdb`) the step reports `skipped` with the reason named —
|
|
3528
|
+
the embed daemon needs agentdb's transitive `@huggingface/transformers`/`@xenova/transformers`
|
|
3529
|
+
dependency, which jsonl mode never installs. This is an honest boundary, not a missing feature: run
|
|
3530
|
+
`dz setup --memory agentdb` when you want the automatic apply leg.
|
|
3531
|
+
|
|
3532
|
+
**Memory footprint and idle lifecycle.** OWNER-MEASURED: the resident embed daemon holds ~1.0 GB
|
|
3533
|
+
RSS with only 7 patterns loaded — the multilingual embedding model dominates that number, not the
|
|
3534
|
+
pattern count, so it does not grow materially with a larger store. The recommended mental model is
|
|
3535
|
+
"spawns on session start, exits after 30 minutes idle" (`DZ_EMBED_IDLE_MS`, default
|
|
3536
|
+
`30 * 60 * 1000`) — not "runs forever": a machine that cannot spare ~1 GB resident for a background
|
|
3537
|
+
process should stay on the jsonl backend rather than tune the idle window down to zero, since `0`
|
|
3538
|
+
(or a negative/non-numeric value) now DISABLES the idle exit entirely (issue #10 defect 7) rather
|
|
3539
|
+
than exiting immediately — the daemon is meant to be reaped by inactivity, not pinned forever by a
|
|
3540
|
+
misconfigured knob. A value above Node's 32-bit `setTimeout` ceiling (2 147 483 647 ms, ~24.9 days)
|
|
3541
|
+
is clamped to that ceiling with a logged line (`idle clamp: <value> -> 2147483647 ms`) instead of
|
|
3542
|
+
silently wrapping to ~1 ms — the pre-fix bug that made a "30 days" idle setting exit in about a
|
|
3543
|
+
second.
|
|
3544
|
+
|
|
3545
|
+
**`dz doctor` and `dz parity` measure this, they don't declare it.** Both read the SAME
|
|
3546
|
+
`applyLegStatus(root)` function — a plain filesystem check (do the two files exist? does
|
|
3547
|
+
`settings.json` reference them?) — so neither can say "installed" about a project that only has the
|
|
3548
|
+
memory backend configured:
|
|
3549
|
+
|
|
3550
|
+
```bash
|
|
3551
|
+
dz setup --target claude-code --memory agentdb # installs all three legs
|
|
3552
|
+
dz doctor # apply-leg installed: ✓ (or a red row naming: dz setup --target claude-code --memory agentdb)
|
|
3553
|
+
dz parity --target claude-code # ✓ Self-learning: automatic apply-leg via UserPromptSubmit hook (auto recall)
|
|
3554
|
+
```
|
|
3555
|
+
|
|
3556
|
+
Without the apply leg installed, `dz doctor` prints a RED `apply-leg installed` check with the
|
|
3557
|
+
exact fix command, and `dz parity`'s `learning-apply` row for `claude-code` reads `◐ manual` with
|
|
3558
|
+
`not installed — run dz setup --target claude-code --memory agentdb` — never a silent `✓` read off
|
|
3559
|
+
a capability table that has never looked at your project.
|
|
3560
|
+
|
|
3561
|
+
#### Post-install verification (acceptance check, dz-harness-hub issue #10)
|
|
3562
|
+
|
|
3563
|
+
A live end-to-end check for a fresh `--memory agentdb` install — every line below is something the
|
|
3564
|
+
install must produce, not a smoke test of the CLI parsing its own flags:
|
|
3565
|
+
|
|
3566
|
+
```bash
|
|
3567
|
+
# 1. Install — all three legs, on a bare Node 20/22 host (no C toolchain required: AM-2 pins
|
|
3568
|
+
# better-sqlite3@^11, the range with a prebuilt binary for Node 20's ABI 115).
|
|
3569
|
+
dz setup --target claude-code --project . --memory agentdb
|
|
3570
|
+
|
|
3571
|
+
# 2. Both hook entries actually landed in settings.json.
|
|
3572
|
+
grep -c recall-hook.cjs .claude/settings.json # → 1
|
|
3573
|
+
grep -c dz-embed-daemon.mjs .claude/settings.json # → 1
|
|
3574
|
+
|
|
3575
|
+
# 3. The pinned dependency resolved to a version WITH a prebuilt binary.
|
|
3576
|
+
node -e "console.log(require('./node_modules/better-sqlite3/package.json').version)" # → 11.x
|
|
3577
|
+
|
|
3578
|
+
# 4. A lesson taught right after setup — before any session has ever ended — still mirrors
|
|
3579
|
+
# (AM-4: setup pre-creates an empty .dz/agentdb.db so this is never silent).
|
|
3580
|
+
dz teach "acceptance check lesson" --allow-cold-start # → "↳ mirrored to vector tier (agentdb)"
|
|
3581
|
+
|
|
3582
|
+
# 5. The embed daemon comes up (spawned by SessionStart; give it up to ~20s to load the model).
|
|
3583
|
+
timeout 20 sh -c 'until [ -S .dz/embed.sock ]; do sleep 1; done' && echo "daemon socket is up"
|
|
3584
|
+
|
|
3585
|
+
# 6. The recall hook actually injects context for a relevant prompt, and stays silent for one
|
|
3586
|
+
# that clears no relevance floor — never a hang, never a stray print on stdout.
|
|
3587
|
+
echo '{"prompt":"acceptance check lesson"}' | node .claude/helpers/recall-hook.cjs # → one line of JSON, hookSpecificOutput.additionalContext non-empty
|
|
3588
|
+
echo '{"prompt":"unrelated weather report"}' | node .claude/helpers/recall-hook.cjs # → empty stdout, exit 0
|
|
3589
|
+
|
|
3590
|
+
# 7. Doctor confirms the leg is alive, not merely installed.
|
|
3591
|
+
dz doctor # → "apply-leg alive (embed daemon): embed.sock present"
|
|
3592
|
+
```
|
|
3593
|
+
|
|
3594
|
+
Every step above is a REPRODUCER, not a claim: run it on a scratch project before trusting a `dz
|
|
3595
|
+
setup --memory agentdb` install on a new machine.
|
|
3596
|
+
|
|
3394
3597
|
### AgentDB self-learning algorithms
|
|
3395
3598
|
|
|
3396
3599
|
When using `--memory agentdb`, the following algorithms automatically tune search quality:
|
|
@@ -3731,8 +3934,8 @@ Learned routing outcomes (what `auto-cost` currently believes):
|
|
|
3731
3934
|
Cold-start (no history) walks a cheapest-first chain and escalates on failure; once a model clears the bar it is
|
|
3732
3935
|
chosen directly. Two invariants held hard: `auto-cost` on the **qe** stage only ever ranks the **cross-family of
|
|
3733
3936
|
the coder** (a model never self-QEs), and the whole thing is **opt-in** — with no `auto-cost` spec anywhere the
|
|
3734
|
-
pipeline is byte-identical and the store is never touched.
|
|
3735
|
-
|
|
3937
|
+
pipeline is byte-identical and the store is never touched. Provider-limit overrides are disabled by design;
|
|
3938
|
+
`auto-cost` decisions use only their own gated outcome history. Storage is a plain JSON file — zero native deps.
|
|
3736
3939
|
|
|
3737
3940
|
### `dz bto-optimize` — when you want to improve a skill WITHOUT gaming its own benchmark
|
|
3738
3941
|
|
|
@@ -3866,7 +4069,7 @@ invariants: HARD rules **block** the operation, SOFT rules warn. Zero config nee
|
|
|
3866
4069
|
cover the known rakes; `.dz/guard.json` (via `dz guard --init`) exists only if you want to tune a severity
|
|
3867
4070
|
or disable a rule.
|
|
3868
4071
|
```bash
|
|
3869
|
-
dz guard check --op publish # no-workspace-star · no-skill-drift · no-secrets · readme-consistency · readme-first · signature-fresh · skills-registrable · lockfile-in-sync · marketplace-parity · no-stubs · review-round · licence-hold
|
|
4072
|
+
dz guard check --op publish # no-workspace-star · no-skill-drift · no-secrets · readme-consistency · readme-first · signature-fresh · skills-registrable · lockfile-in-sync · marketplace-parity · no-stubs · review-round · rounds-closed · rounds-traced · licence-hold
|
|
3870
4073
|
dz guard check --op teach --text "the fix: export sk-abc..." # → BLOCK (exit 1): looks like a credential
|
|
3871
4074
|
dz guard log # append-only audit: every verdict + every forced override
|
|
3872
4075
|
```
|
|
@@ -4348,6 +4551,119 @@ stay in the previous embedding space until their own reindex runs) instead of le
|
|
|
4348
4551
|
Only models listed in `KNOWN_EMBED_DIMS` are accepted — the store's `vectorDim` is 384, so a 768-dim
|
|
4349
4552
|
model is rejected rather than silently writing mismatched vectors.
|
|
4350
4553
|
|
|
4554
|
+
#### Pre-reindex snapshots pile up — rotating them
|
|
4555
|
+
|
|
4556
|
+
Every `dz brain reindex` (and every `dz vector reindex`) copies the store to
|
|
4557
|
+
`<db>.pre-reindex-<ms>.bak` first, as an undo point. Nothing pruned those copies before this feature —
|
|
4558
|
+
13 snapshots / 50 MB accumulated on one real brain home before anyone noticed. Two ways to clear them:
|
|
4559
|
+
|
|
4560
|
+
```bash
|
|
4561
|
+
$ dz brain reindex
|
|
4562
|
+
dz brain reindex: re-embedded 812 KU vector(s) with Xenova/paraphrase-multilingual-MiniLM-L12-v2 (manifest v4)
|
|
4563
|
+
snapshot: /home/you/.dz/brain/agentdb.db.pre-reindex-1757754000000.bak
|
|
4564
|
+
↳ snapshots: kept 6, removed 8 (41.2 MB)
|
|
4565
|
+
```
|
|
4566
|
+
|
|
4567
|
+
`dz brain reindex` now rotates automatically after a SUCCESSFUL reindex, keeping the newest 3
|
|
4568
|
+
snapshot families by default (`opts.keepSnapshots`) — the family it just created is never removed,
|
|
4569
|
+
even at `keep=0`. A reindex that itself fails rotates nothing (the old snapshots may be the only
|
|
4570
|
+
working copy left).
|
|
4571
|
+
|
|
4572
|
+
When you cannot or do not want to run a reindex — e.g. a hub where reindexing itself is off-limits
|
|
4573
|
+
today, but old snapshots have piled up regardless — rotate directly:
|
|
4574
|
+
|
|
4575
|
+
```bash
|
|
4576
|
+
$ dz brain snapshots
|
|
4577
|
+
dz brain snapshots — 9 family(-ies) @ /home/you/.dz/brain/agentdb.db
|
|
4578
|
+
2026-09-01T08:00:00.000Z ms=1756713600000 2 file(s) 4.1 MB
|
|
4579
|
+
2026-09-05T08:00:00.000Z ms=1757059200000 2 file(s) 4.1 MB
|
|
4580
|
+
...
|
|
4581
|
+
(dry run — pass --prune to remove families older than --keep)
|
|
4582
|
+
|
|
4583
|
+
# The PROJECT store (.dz/agentdb.db, written by the vector-tier reindex) is addressed with --project:
|
|
4584
|
+
$ dz brain snapshots --project .
|
|
4585
|
+
dz brain snapshots — 13 family(-ies) @ /path/to/project/.dz/agentdb.db
|
|
4586
|
+
|
|
4587
|
+
$ dz brain snapshots --prune --keep 3
|
|
4588
|
+
dz brain snapshots: kept 6, removed 12 (37.1 MB)
|
|
4589
|
+
removed: agentdb.db.pre-reindex-1756713600000.bak, agentdb.db.pre-reindex-1756713600000.bak.embed-manifest.json, ...
|
|
4590
|
+
```
|
|
4591
|
+
|
|
4592
|
+
`dz brain snapshots` never touches anything but the brain's own strictly-named
|
|
4593
|
+
`agentdb.db.pre-reindex-<ms>.bak` family (a symlink or a differently-named neighbour is left alone);
|
|
4594
|
+
without `--prune` it only lists, and a bad `--keep` — negative, non-numeric, empty, or whitespace-
|
|
4595
|
+
padded (`--keep ' 2'`) — is refused with exit 2 rather than silently treated as 0 or 2.
|
|
4596
|
+
|
|
4597
|
+
**Fix-round hardenings (2026-09-13, after a Codex review found the earlier version could delete
|
|
4598
|
+
every snapshot on a bad `--keep`):**
|
|
4599
|
+
|
|
4600
|
+
- **10-minute grace period.** A family younger than 10 minutes is never removed, even past `--keep`
|
|
4601
|
+
— there is no flag to shorten or disable this; it protects a snapshot a DIFFERENT, still-running
|
|
4602
|
+
process just wrote from looking "old" to a `--prune` invoked moments later.
|
|
4603
|
+
- **Removal order inside a family: siblings first, `.bak` last, only if every sibling actually
|
|
4604
|
+
unlinked.** If a sibling (the manifest, `-shm`, `-wal`) fails to unlink, the `.bak` — the one file
|
|
4605
|
+
that alone still proves the snapshot existed — is left in place, and the family's `⚠ .bak
|
|
4606
|
+
preserved after a sibling failure` line names it.
|
|
4607
|
+
- **A scan error blocks the whole rotation, not just that one file.** If the brain directory itself
|
|
4608
|
+
cannot be listed (or a file's status cannot be read) for a reason other than "it does not exist",
|
|
4609
|
+
the command prints `⚠ scan error(s), nothing removed this call` and removes NOTHING — an
|
|
4610
|
+
incomplete file list is never a safe basis for "these are the old ones".
|
|
4611
|
+
|
|
4612
|
+
```bash
|
|
4613
|
+
$ dz brain snapshots --prune --keep 3
|
|
4614
|
+
dz brain snapshots: kept 6, removed 12 (37.1 MB)
|
|
4615
|
+
removed: agentdb.db.pre-reindex-1756713600000.bak, agentdb.db.pre-reindex-1756713600000.bak.embed-manifest.json, ...
|
|
4616
|
+
⚠ .bak preserved after a sibling failure in famil(y/ies): 1756713600000 # only printed if a sibling unlink failed
|
|
4617
|
+
⚠ scan error(s), nothing removed this call: readdir /home/you/.dz/brain: EACCES # only printed on a scan failure
|
|
4618
|
+
```
|
|
4619
|
+
|
|
4620
|
+
**Snapshot lock (agentdb-snapshot-lock, 2026-09-13).** `--prune` now takes the SAME advisory lock a
|
|
4621
|
+
concurrent `dz brain reindex`/`reindexAgentdbRows` uses (`<store dir>/.dz/locks/agentdb-snapshot.lock`)
|
|
4622
|
+
before it removes anything — a `rotate --keep 0` racing a live reindex used to be able to delete the
|
|
4623
|
+
undo point the reindex was still relying on; now it waits for the lock, or reports the timeout
|
|
4624
|
+
explicitly instead of silently succeeding on an empty rotation:
|
|
4625
|
+
|
|
4626
|
+
```bash
|
|
4627
|
+
$ dz brain snapshots --prune --keep 0 # a concurrent reindex is mid-flight and holds the lock
|
|
4628
|
+
dz brain snapshots: kept 0, removed 0 (0.0 MB)
|
|
4629
|
+
⚠ 1 error(s): lock busy: the lock at …/.dz/locks/agentdb-snapshot.lock stayed held for 10000ms — …
|
|
4630
|
+
$ echo $?
|
|
4631
|
+
1
|
|
4632
|
+
```
|
|
4633
|
+
|
|
4634
|
+
A family a LIVE reindex marker names (`<db>.reindex-inprogress.json`, written for the duration of
|
|
4635
|
+
that reindex, not just the moment the lock is held) also survives `--prune`, even at `--keep 0`; an
|
|
4636
|
+
EXPIRED marker (older than 60 minutes) is cleaned up and named honestly in a `note:` line rather than
|
|
4637
|
+
either protecting it forever or treating its removal as a scan error:
|
|
4638
|
+
|
|
4639
|
+
```bash
|
|
4640
|
+
$ dz brain snapshots --prune --keep 0
|
|
4641
|
+
dz brain snapshots: kept 2, removed 4 (12.3 MB)
|
|
4642
|
+
note: stale reindex marker (ms=1757754000000, startedAt=2026-09-13T01:00:00.000Z) ignored and removed
|
|
4643
|
+
```
|
|
4644
|
+
|
|
4645
|
+
If the marker could not actually be removed (e.g. a permission error), the note says so instead of
|
|
4646
|
+
silently claiming success: `"… ignored, removal failed: <err>"` — never `"… ignored and removed"` for
|
|
4647
|
+
a removal that did not happen.
|
|
4648
|
+
|
|
4649
|
+
**Marker ownership + a stuck rollback (fix-round, 2026-09-13).** The marker file is now written and
|
|
4650
|
+
removed with an ownership token: a `dz brain reindex` genuinely still in flight refuses a SECOND
|
|
4651
|
+
concurrent reindex of the same store outright (no snapshot for the refused attempt), and nothing but
|
|
4652
|
+
the owning reindex can clear its own marker. If a reindex fails and its rollback cannot re-acquire the
|
|
4653
|
+
snapshot lock (e.g. `--prune` or another reindex is mid-critical-section), the marker is deliberately
|
|
4654
|
+
LEFT IN PLACE rather than cleared — the reported error names both the snapshot and the marker path and
|
|
4655
|
+
says `requires manual recovery`:
|
|
4656
|
+
|
|
4657
|
+
```
|
|
4658
|
+
error: index failed: …; rollback failed: lock busy: …; snapshot at /home/you/.dz/brain/agentdb.db.pre-reindex-1757754000000.bak
|
|
4659
|
+
was not confirmed restored; marker at /home/you/.dz/brain/agentdb.db.reindex-inprogress.json is left
|
|
4660
|
+
in place — requires manual recovery
|
|
4661
|
+
```
|
|
4662
|
+
|
|
4663
|
+
Recovery is manual: inspect the named snapshot, restore it by hand if the store looks wrong, then
|
|
4664
|
+
delete the marker file. **The snapshot lock's own stale threshold is 5 minutes** — a base whose own
|
|
4665
|
+
snapshot genuinely takes longer needs external coordination, not a bigger default.
|
|
4666
|
+
|
|
4351
4667
|
**Before → after** (what changes when you enable it):
|
|
4352
4668
|
|
|
4353
4669
|
| | Before (lexical only) | After (hybrid vector tier) |
|
|
@@ -4713,23 +5029,19 @@ refusal as the honest answer.
|
|
|
4713
5029
|
|
|
4714
5030
|
## Status
|
|
4715
5031
|
|
|
4716
|
-
`harness-core v0.8.
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
`
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
`/tmp/.dz`. A planned fallback lock location was MEASURED unsound (two processes could hold two
|
|
4730
|
-
different locks for one root) and withdrawn before release — named locks stay `<root>/.dz/locks`, a
|
|
4731
|
-
pure function of the root. (6) `dz amendment-check` recognises the Russian challenge-panel placeholder
|
|
4732
|
-
as a stub.
|
|
5032
|
+
`harness-core v0.8.31` · `harness-cli v0.8.23` — **this release: the store guard tells "busy" from "broken",
|
|
5033
|
+
and a publish is not finished until the public mirror confirms it.** (1) The learning-store guard used to
|
|
5034
|
+
turn ANY read failure into `unreadable` and refuse the write; a neighbour holding the SQLite write lock
|
|
5035
|
+
(`SQLITE_BUSY`) or a store still being initialised (`no such table`) now gets bounded retries and, if still
|
|
5036
|
+
busy, the verdict `busy` = **NOT MEASURED** — the write proceeds under the store lock, the high-water mark
|
|
5037
|
+
is left untouched, and both the text panel and `dz statusline --json` say so from one verdict. MEASURED:
|
|
5038
|
+
eight barrier-synchronised `dz teach` writers from two worktrees no longer lose a lesson to a false
|
|
5039
|
+
refusal. (2) `dz publish` gained a mirror epilogue: after a live sweep lands at least one package it runs
|
|
5040
|
+
`publish.mirrorCommand` from `.dz/config.json` (or `--mirror-cmd`), passes the published versions, and reads
|
|
5041
|
+
a JSON receipt whose proof is the live raw `MIRROR-MANIFEST.json` carrying those versions. Publication
|
|
5042
|
+
errors stay exit `1`; packages published but the mirror NOT confirmed exit **`3`** with the exact `re-run:`
|
|
5043
|
+
command; dry runs, `--no-mirror`, `--bump-only` and zero-package sweeps never invoke the hook, and each of
|
|
5044
|
+
those states is named in the report. This is the first release published THROUGH that epilogue.
|
|
4733
5045
|
|
|
4734
5046
|
`dz guard check --op publish` now warns when either release line disagrees with the core/CLI package versions, and a registry-confirmed live core or CLI publish synchronizes the first such line in both release READMEs: each README is rewritten atomically; the pair is not one transaction (dry-run and bump-only never write them).
|
|
4735
5047
|
|
|
@@ -4740,7 +5052,7 @@ exports (`commandInventory`, `declaredCommands`, `dispatchedCommands`, `document
|
|
|
4740
5052
|
`stripNonCode`, `validateExceptionList`, `INTERNAL_ENTRY_POINTS`, `PSEUDO_COMMANDS`) — instead of a
|
|
4741
5053
|
fourth private regex and a fourth number. Four hidden commands (`mr-rakes`, `retro`,
|
|
4742
5054
|
`feature-adr-setup`, `bto-optimize`) gained USAGE lines, so `--help` changed; `help` is a documented
|
|
4743
|
-
pseudo-command, not a `case` label. **
|
|
5055
|
+
pseudo-command, not a `case` label. **92 canonical commands, 93 names in rendered `--help`** (the 92
|
|
4744
5056
|
plus the built-in `help`) — both COMPUTED from `cli.ts`, neither typed into a test. Three cross-family QE rounds closed
|
|
4745
5057
|
six parser defects the naive version had: four that INVENTED a command (regex literals with a lone
|
|
4746
5058
|
`}`, `case` labels in comments or templates, sub-verb labels from nested switches, ` dz <name>` lines
|
|
@@ -4760,6 +5072,43 @@ plan-route choice. Every failure is fail-open; versioned `.fa-state/decision-rec
|
|
|
4760
5072
|
receipt coverage and repeat-related outcomes derivable offline. The hypothesis is external `[SRC],
|
|
4761
5073
|
n=1`, books were silent on retrieval timing, and no runtime threshold gates a stage.
|
|
4762
5074
|
|
|
5075
|
+
`harness-core` / `harness-cli` — **staged, not published: `ts` and `minutesSincePrev` on the run-cost
|
|
5076
|
+
ledger.** The writer could not measure a stage's full duration (the workflow sandbox never calls
|
|
5077
|
+
`Date.now()`, for resume-safety) but it always knew the moment of each write and the run it belonged
|
|
5078
|
+
to — so every ledger row now also gets `ts` (the ISO instant it was recorded, next to `date`), and an
|
|
5079
|
+
`auto:true` row that carries a `runId` additionally gets `minutesSincePrev` (a number, one decimal
|
|
5080
|
+
digit, ≥ 0) plus `minutesSource: 'ledger-ts-delta'`, measured against the LAST row of the same run —
|
|
5081
|
+
found via `dz feature-adr-record --run-id <id>` or a `runId` already in the payload. When there is no
|
|
5082
|
+
prior row, or it carries no `ts`, the pair reads `minutesSincePrev: null` / `minutesSource:
|
|
5083
|
+
'unavailable'` rather than a guess. `minutes` itself is untouched and stays `null` on every auto row:
|
|
5084
|
+
a partial measurement gets its own named field and source, and is never folded into the field that
|
|
5085
|
+
implies the whole stage's duration was known. `dz cadence`'s round summary reads unaffected fixtures
|
|
5086
|
+
unchanged — the new fields are additive, never repositioning an existing key.
|
|
5087
|
+
|
|
5088
|
+
**Fix-round-1 (cross-family review, grade B → 5 findings closed), still staged, not published:**
|
|
5089
|
+
a Codex `gpt-5.6-sol` review of the above found five contract gaps, all closed by measurement:
|
|
5090
|
+
(1) the reverse scan for the previous row's `ts` used to skip PAST a torn or non-object ledger line
|
|
5091
|
+
and keep looking further back, so an OLDER row for the same `runId` could be returned while a newer
|
|
5092
|
+
one sat hidden behind the corrupt line; it now stops and reports `unavailable` — named
|
|
5093
|
+
`ledger-corrupt-line` — the instant it hits a line it cannot parse as an object, never a guess made
|
|
5094
|
+
by skipping past what it could not read. (2) `--run-id` filling a MISSING `runId` was already correct
|
|
5095
|
+
— "missing" means absent, `null`, `''`, or a non-string value, the same "missing when absent or
|
|
5096
|
+
blank" rule `runnerId` uses — but it was untested beyond the plain non-empty-string case and
|
|
5097
|
+
undocumented; both are fixed now, behavior unchanged. (3) when `--run-id` actually fills the gap, the
|
|
5098
|
+
row is now tagged `runIdSource: 'cli-flag'` — the same provenance discipline `resolved-at-write`
|
|
5099
|
+
already gets for the OTHER runId source (write-time auto-resolution) — and an existing non-empty
|
|
5100
|
+
`runIdSource` is left untouched. (4) a payload's own `ts` is no longer trusted for the delta: `ts` on
|
|
5101
|
+
a ledger row is now ALWAYS the actual write instant, and a caller-supplied one survives, renamed,
|
|
5102
|
+
as `payloadTs` — no data lost, just no longer the value the delta measures from. (5) object key order
|
|
5103
|
+
now matches the documented convention exactly: a `runnerId` this call itself stamps keeps its position
|
|
5104
|
+
ahead of `ts`/`minutesSincePrev`/`minutesSource`, which land strictly last regardless of which fields
|
|
5105
|
+
the incoming payload already carried. `test/run-records.test.ts` (48, +10) and
|
|
5106
|
+
`test/feature-adr-record-cli.test.ts` (22, +7) cover all five, plus fractional-minute rounding
|
|
5107
|
+
(2m30s → 2.5, 1m3s → 1.1) and a pinned negative-delta case; the `ledger-minutes-since-prev-measured`
|
|
5108
|
+
mutation-gate entry was RE-MEASURED at `failingCount: 3` (three of the new tests now discriminate the
|
|
5109
|
+
same mutation, up from one) and the registry updated to match — `dz mutation-gate --only
|
|
5110
|
+
ledger-minutes-since-prev-measured` verdict `PROVEN`, exit 0.
|
|
5111
|
+
|
|
4763
5112
|
`v0.8.8` — **staged, not published.** `dz init` now reports exactly one MCP and one hook outcome,
|
|
4764
5113
|
adds `integrations-verify`, content-bound authorization, explicit skills-only opt-out, and named
|
|
4765
5114
|
partial-failure exits; only receipt-proven live registration may be called emitted.
|
|
@@ -4890,7 +5239,7 @@ partial design). The compat floor is unchanged — this CLI uses no new core exp
|
|
|
4890
5239
|
|
|
4891
5240
|
**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".
|
|
4892
5241
|
|
|
4893
|
-
`v0.5.0` — published.
|
|
5242
|
+
`v0.5.0` — published. Claude Plugin packaging exists for contributors only (see [Claude Plugin](#claude-plugin) — a public marketplace install does not work today). Part of [DZ Harness Hub](https://github.com/djd1m/dz-harness).
|
|
4894
5243
|
|
|
4895
5244
|
New in 0.5.0 (feature `qe-bridge-claude`, cross-runtime leg 3/4): `dz qe-bridge --family claude`
|
|
4896
5245
|
runs an INDEPENDENT Claude reviewer from any host — a Codex session included — and lands a PARSED
|
|
@@ -4914,21 +5263,21 @@ Previously: the global `dz --version` / `-v` / `dz version` surface (one parseab
|
|
|
4914
5263
|
|
|
4915
5264
|
## Claude Plugin
|
|
4916
5265
|
|
|
4917
|
-
|
|
5266
|
+
Using the whole hub as a Claude Code plugin needs the source repo — this is a path for
|
|
5267
|
+
**contributors and plugin developers**, not something an `npm install -g` user needs (see
|
|
5268
|
+
Install above). A public marketplace install does **not** work today: `claude plugin marketplace add djd1m/dz-harness` fails with `Marketplace file not found` (MEASURED 2026-09-13, scratch probe) — the public mirror ships each package's `npm pack` contents only, never the root-level `.claude-plugin/marketplace.json`.
|
|
4918
5269
|
|
|
4919
5270
|
```bash
|
|
4920
|
-
#
|
|
4921
|
-
claude plugin marketplace add djd1m/dz-harness-hub
|
|
4922
|
-
claude plugin install dz-harness-hub@dz-harness-hub
|
|
4923
|
-
|
|
4924
|
-
# Or test locally:
|
|
5271
|
+
# From a cloned repo (contributors / plugin developers only):
|
|
4925
5272
|
claude --plugin-dir /path/to/dz-harness-hub
|
|
4926
5273
|
|
|
4927
5274
|
# Generate plugin manifest from current inventory:
|
|
4928
5275
|
dz plugin --version 0.3.86
|
|
4929
5276
|
```
|
|
4930
5277
|
|
|
4931
|
-
The `.claude-plugin/` directory contains `plugin.json` + `marketplace.json`
|
|
5278
|
+
The `.claude-plugin/` directory (source repo only) contains `plugin.json` + `marketplace.json`
|
|
5279
|
+
compatible with [pi-claude-marketplace](https://npm.im/pi-claude-marketplace) and
|
|
5280
|
+
[skill-hub](https://npm.im/@jasonwen/skill-hub).
|
|
4932
5281
|
|
|
4933
5282
|
## Related Projects
|
|
4934
5283
|
|
|
@@ -5010,3 +5359,18 @@ Core APIs: `settleDeadRuns` and `planRegistryArchive` are pure registry decision
|
|
|
5010
5359
|
`planWorktreeCleanup` accepts injected `WorktreeFact` values and returns remove/keep decisions;
|
|
5011
5360
|
`renderCleanupPlan` renders them. `worktreeRemovalsToApply` selects removals only when apply is true.
|
|
5012
5361
|
No process is terminated and no branch is deleted.
|
|
5362
|
+
|
|
5363
|
+
## From source (contributors only)
|
|
5364
|
+
|
|
5365
|
+
Everything below is for people building or testing `dz` itself — not for `npm install -g` users.
|
|
5366
|
+
The buildable source lives in the public mirror, [github.com/djd1m/dz-harness](https://github.com/djd1m/dz-harness) (each package's own npm-pack contents; the full monorepo, including this feature's design docs, stays in the private source repo).
|
|
5367
|
+
|
|
5368
|
+
### Test execution
|
|
5369
|
+
|
|
5370
|
+
`npx vitest run` uses two projects and returns one combined verdict: `parallel` runs the ordinary
|
|
5371
|
+
suites concurrently, while `serial` runs process-spawning and real-time suites one file at a time.
|
|
5372
|
+
The serial paths in `test/serial-suites.txt` are regenerated from
|
|
5373
|
+
`test/serial-suites-census.test.ts`, which scans test sources for synchronous and asynchronous
|
|
5374
|
+
process markers, including `execSync(` and `execFile(`, and fails when the list and census differ.
|
|
5375
|
+
CF-2 records uncommented explicit test budgets in each package's `test/budget-debt-ceiling.json`: growth fails with `file:line` findings; shrinkage passes and suggests a lower ceiling.
|
|
5376
|
+
The ceiling files live in `packages/@dzhechkov/harness-core/test/` and `packages/@dzhechkov/harness-cli/test/` and are lowered by hand: a ratchet on existing debt, not a migration that clears it in one shot.
|