@dzhechkov/harness-cli 0.7.8 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dz-manifest.json +12 -12
- package/README.md +155 -21
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +704 -73
- package/dist/cli.js.map +1 -1
- package/dist/known-flags.d.ts.map +1 -1
- package/dist/known-flags.js +2 -0
- package/dist/known-flags.js.map +1 -1
- package/package.json +18 -18
- package/sbom.json +16 -12
- package/src/cli.ts +704 -68
- package/src/known-flags.ts +2 -0
package/.dz-manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest": {
|
|
3
|
-
"version":
|
|
3
|
+
"version": 3,
|
|
4
4
|
"pack": "harness-cli",
|
|
5
5
|
"files": [
|
|
6
6
|
{
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
{
|
|
11
11
|
"path": "README.md",
|
|
12
|
-
"sha256": "
|
|
12
|
+
"sha256": "346b65ccfd61e78f8988622475fe0389248cad80f3347eb1cd83656ff6a7dc1c"
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"path": "dist/bin.d.ts",
|
|
@@ -49,15 +49,15 @@
|
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
"path": "dist/cli.d.ts.map",
|
|
52
|
-
"sha256": "
|
|
52
|
+
"sha256": "890a0f9a6650d531045820ecd5501c26e69178f3123d54c6ff2afae8fd339348"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"path": "dist/cli.js",
|
|
56
|
-
"sha256": "
|
|
56
|
+
"sha256": "c4cd799f718714e3c1cf835e7f5f6e533e819dd7348e04a5134fe62fe09efdbb"
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
59
|
"path": "dist/cli.js.map",
|
|
60
|
-
"sha256": "
|
|
60
|
+
"sha256": "af1ec69d7191440d499321ffb7f0ab3fc77749422b0cca233f8af2b3fb69315e"
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
"path": "dist/core-compat.d.ts",
|
|
@@ -113,15 +113,15 @@
|
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"path": "dist/known-flags.d.ts.map",
|
|
116
|
-
"sha256": "
|
|
116
|
+
"sha256": "e142475e7ead4abd8773d6e83bc3a1ebd693ef2c5a3418e2ad896ab9711cff51"
|
|
117
117
|
},
|
|
118
118
|
{
|
|
119
119
|
"path": "dist/known-flags.js",
|
|
120
|
-
"sha256": "
|
|
120
|
+
"sha256": "302026471c90d6f6e99374b3735933bdae6dbcd0fd405fdac0950f6a161b575d"
|
|
121
121
|
},
|
|
122
122
|
{
|
|
123
123
|
"path": "dist/known-flags.js.map",
|
|
124
|
-
"sha256": "
|
|
124
|
+
"sha256": "87e001a15b8203a3ccc6dcaf12b5a2270217972109f3e357238a02f232fbfe28"
|
|
125
125
|
},
|
|
126
126
|
{
|
|
127
127
|
"path": "keys/README.md",
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
135
|
"path": "package.json",
|
|
136
|
-
"sha256": "
|
|
136
|
+
"sha256": "8ee638e6241900c1da48901ea5b1e763044986d11459314fd0296f9e7c9ce169"
|
|
137
137
|
},
|
|
138
138
|
{
|
|
139
139
|
"path": "src/bin.ts",
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
},
|
|
146
146
|
{
|
|
147
147
|
"path": "src/cli.ts",
|
|
148
|
-
"sha256": "
|
|
148
|
+
"sha256": "3c0c9e454344058a7802ec54eb3aaaea0ec8fed72f6c10038ea2fdb6d2ed3a3a"
|
|
149
149
|
},
|
|
150
150
|
{
|
|
151
151
|
"path": "src/core-compat.ts",
|
|
@@ -161,9 +161,9 @@
|
|
|
161
161
|
},
|
|
162
162
|
{
|
|
163
163
|
"path": "src/known-flags.ts",
|
|
164
|
-
"sha256": "
|
|
164
|
+
"sha256": "4a3f93b484a5a0d89baefdb68aa85b92d5c630e48774e6ee302078fce065e60f"
|
|
165
165
|
}
|
|
166
166
|
]
|
|
167
167
|
},
|
|
168
|
-
"signature": "
|
|
168
|
+
"signature": "qnB7A5EXO4tlWiQK4Vrc+4OYP/3QeR0JSwZaXuTdONL6IyjqNGE0CHiNXelA0z1EkLcFre02G96zq33an+rgDg=="
|
|
169
169
|
}
|
package/README.md
CHANGED
|
@@ -266,12 +266,63 @@ you know exactly which file is at fault, and you know whose defect it is.
|
|
|
266
266
|
|
|
267
267
|
## User Journey — from install to mastery
|
|
268
268
|
|
|
269
|
-
All
|
|
269
|
+
All 79 commands (MEASURED — reproducer: `grep -c "^ case '" packages/@dzhechkov/harness-cli/src/cli.ts`, the dispatch cases — which is also what the bounded `## All Commands` list enumerates) mapped to a real workflow:
|
|
270
270
|
|
|
271
271
|
```
|
|
272
272
|
DISCOVER → INSTALL → USE → CREATE → MAINTAIN → SHARE
|
|
273
273
|
```
|
|
274
274
|
|
|
275
|
+
### `dz profile` — say once who you are, and stop being explained the wrong things
|
|
276
|
+
|
|
277
|
+
The failure this closes is measured, not hypothetical. On 2026-08-28 an OS pipe buffer was explained
|
|
278
|
+
to this repository's owner across three paragraphs of kernel mechanics — he holds a **CCIE**, and
|
|
279
|
+
*"tail drop on a full queue with no backpressure signal"* would have landed in one line. In the same
|
|
280
|
+
session `ADR` and `vitest worker` went by unexplained, in a domain where he had said plainly he is not
|
|
281
|
+
a professional. Neither failure was ignorance. Both were not knowing who was listening.
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
dz profile init
|
|
285
|
+
# 1/5 Dialogue language (ru, en, …) [ru]: ru
|
|
286
|
+
# 2/5 Default register — pro / pro-lite / plain (профи / профи лайт / просто) [pro-lite]: профи лайт
|
|
287
|
+
# 3/5 Назовите 2–4 области, где вам НЕ нужно пояснять термины … : networking (CCIE; NSX), cloud architecture
|
|
288
|
+
# 4/5 Где наоборот — терминам нужна одна поясняющая фраза? : software architecture, testing internals
|
|
289
|
+
# 5/5 Do you teach — must explanations be re-tellable? y/n [y]: y
|
|
290
|
+
#
|
|
291
|
+
# wrote ~/.dz/profile.json (0600) — register pro-lite (профи лайт), language ru, teaches yes
|
|
292
|
+
# deep: networking (CCIE; NSX), cloud-architecture · weak: software-architecture, testing-internals
|
|
293
|
+
# synced block into ~/.claude/CLAUDE.md
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
That block now loads in **every project on the machine**, including projects where dz is not installed
|
|
297
|
+
— because `~/.claude/CLAUDE.md` is read by the runtime itself, not by a hook.
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
dz profile show # store path, age in days, drift verdict, the rendered block
|
|
301
|
+
dz profile set weak add build-toolchains
|
|
302
|
+
dz profile set register профи # RU aliases accepted; stored as the neutral `pro`
|
|
303
|
+
dz profile sync # after a hand-edit: repairs the block, timestamped backup, foreign content untouched
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**When to use it:** once, at onboarding — and again whenever you correct the register twice in one
|
|
307
|
+
session, which is the signal the profile is wrong rather than the moment to absorb it silently.
|
|
308
|
+
|
|
309
|
+
**What it deliberately does not do.** It never changes the FACTS — numbers, caveats, risks and bad
|
|
310
|
+
results survive every register, or "simpler please" becomes a hole in the honesty rules. It never
|
|
311
|
+
touches artifacts written for future readers: ADRs, commit messages, code comments, QE reports and npm
|
|
312
|
+
READMEs keep their own conventions, because their audience is not the current operator. And it is
|
|
313
|
+
redacted from training-pair capture, because `.dz/fa-training/` records the full prompt and is
|
|
314
|
+
deliberately not gitignored — without that, "never write personal data into a project" would be
|
|
315
|
+
defeated one path over.
|
|
316
|
+
|
|
317
|
+
**What no test can prove.** That the explanation actually landed is a judgement only the reader makes.
|
|
318
|
+
The acceptance step is human by design and recorded as such
|
|
319
|
+
(`features/operator-profile/08_acceptance_cf7.md`): the same passage rendered at two registers, and
|
|
320
|
+
the owner says which one works. That run found a real defect — a term glossed in one breath and
|
|
321
|
+
another assumed in the next — and produced the rule the block now carries: **an explanation is
|
|
322
|
+
self-contained; every term gets its gloss at first use in THIS passage, because the earlier text has
|
|
323
|
+
scrolled away and a new session never had it.**
|
|
324
|
+
|
|
325
|
+
|
|
275
326
|
### Phase 1: Discover (what's available?)
|
|
276
327
|
|
|
277
328
|
```bash
|
|
@@ -281,9 +332,7 @@ dz help # see all commands
|
|
|
281
332
|
dz pretrain # analyze project files → recommend by tech stack
|
|
282
333
|
dz recommend "build API and deploy to K8s" # keyword match → skills + toolkits
|
|
283
334
|
dz recommend "work on this project" # generic? → auto-runs pretrain → recommends by stack
|
|
284
|
-
dz stats # 54 packages,
|
|
285
|
-
# NB: the preset figure is stats' own, and it UNDER-reports — the registry has 14
|
|
286
|
-
# (reasoning, news and pm are missing from stats). Backlog 6e6ae88d7f7660f6.
|
|
335
|
+
dz stats # 54 packages, 201 skills, 10 targets, 14 presets
|
|
287
336
|
dz dashboard # visual panel — packages, adapters, skill packs
|
|
288
337
|
dz registry # browse all 179 skills by category
|
|
289
338
|
dz registry search kubernetes # find specific skills
|
|
@@ -298,7 +347,7 @@ dz downloads # npm weekly download stats
|
|
|
298
347
|
dz setup --target claude-code --preset devops # pretrain + hooks + memory + installs the preset skills
|
|
299
348
|
|
|
300
349
|
# With AgentDB vector memory (semantic search + self-learning):
|
|
301
|
-
dz setup --target claude-code --preset devops --memory agentdb #
|
|
350
|
+
dz setup --target claude-code --preset devops --memory agentdb # vector memory + agentdb MCP server
|
|
302
351
|
|
|
303
352
|
# Or just install skills (no learning):
|
|
304
353
|
dz init --target claude-code --preset devops # 30 DevOps skills
|
|
@@ -443,9 +492,9 @@ dz sign --init --out ~/.dz/keys/dz.key
|
|
|
443
492
|
# Sign a pack. The private key MUST live outside the repo — dz refuses otherwise.
|
|
444
493
|
dz sign --pack packages/@dzhechkov/skills-qe --key ~/.dz/keys/dz.key
|
|
445
494
|
|
|
446
|
-
# Verify. The public key comes from the REPO (keys/dz.pub), never from the pack
|
|
447
|
-
# whoever replaced the
|
|
448
|
-
dz verify-pack --pack
|
|
495
|
+
# Verify an unpacked artifact. The public key comes from the REPO (keys/dz.pub), never from the pack:
|
|
496
|
+
# whoever replaced the artifact would have replaced a key shipped inside it.
|
|
497
|
+
dz verify-pack --pack ./unpacked-tarball/package # exit 0 = artifact unmodified
|
|
449
498
|
dz verify-pack --pack ./downloaded-pack --pubkey keys/dz.pub # explicit trust root
|
|
450
499
|
|
|
451
500
|
# The SBOM on its own (CycloneDX 1.5, a file-level bill of materials for the pack):
|
|
@@ -453,9 +502,24 @@ dz sbom --pack packages/@dzhechkov/skills-qe # print to stdout
|
|
|
453
502
|
dz sbom --pack packages/@dzhechkov/skills-qe --out sbom.json # write to a file
|
|
454
503
|
```
|
|
455
504
|
|
|
456
|
-
A single flipped byte, a deleted file, or an **added** file
|
|
457
|
-
|
|
458
|
-
|
|
505
|
+
A single flipped byte, a deleted file, or an **added** file inside the authenticated npm shipment set
|
|
506
|
+
fails verification and names the path. Directory segments `node_modules`, `.git`, `.agentic-qe`, and
|
|
507
|
+
`.dz` are unsigned local/dependency/VCS state by design and are absent from both manifest and SBOM; an OK
|
|
508
|
+
verdict makes no claim about bytes placed there. A symlink smuggled anywhere else still fails loudly.
|
|
509
|
+
`sbom.json` is required even though it is not self-hashed: after the signature is valid, `verify-pack`
|
|
510
|
+
derives the canonical CycloneDX bytes from the signed manifest and rejects a missing, malformed, duplicated,
|
|
511
|
+
renamed, re-hashed, or metadata-modified SBOM. This keeps the trust chain acyclic without leaving the SBOM
|
|
512
|
+
as unauthenticated decoration.
|
|
513
|
+
CycloneDX `SHA-256` fields describe raw bytes only. Because packers may reorder ordinary
|
|
514
|
+
`package.json` metadata, format v3 publishes its semantic canonical digest through explicit
|
|
515
|
+
`dz:canonical-json-sha256-v2` and `dz:digest-basis=package-json-ordered-conditions-v2` properties.
|
|
516
|
+
Canonicalisation still sorts packer-noise keys, but preserves every object key order under `exports`,
|
|
517
|
+
`imports`, and `typesVersions`; changing first-match condition order therefore changes the signed digest.
|
|
518
|
+
Current/v3 signing and verification refuse malformed, duplicate-key, or precision-losing JSON.
|
|
519
|
+
Verification retains compatibility-only readers for existing v1/v2 manifests; new evidence emits v3.
|
|
520
|
+
`dz sign` hashes the pnpm tarball because pnpm rewrites `package.json` and may synthesize or omit files;
|
|
521
|
+
the authoring tree is therefore not the signed object. `dz publish` rebuilds and verifies that exact
|
|
522
|
+
artifact, while direct `verify-pack` is for an already unpacked artifact or installed package.
|
|
459
523
|
Re-sign after ANY pack change (the manifest hashes `package.json` too) — sign is the LAST step before publish. Every degenerate input (no manifest, empty file list, empty signature, no public key)
|
|
460
524
|
fails **closed** — absence never reads as success. `dz doctor` **and** `dz drift-check` run this check
|
|
461
525
|
over the installed packs: a **tampered** pack is fatal (blocks); an **unsigned** pack or a missing trust
|
|
@@ -1768,16 +1832,16 @@ runs a command that MEASURES the declared artifacts itself. It refuses a null re
|
|
|
1768
1832
|
never recorded as done), an absent or partially-present artifact set, and a stage that declares nothing
|
|
1769
1833
|
to witness — so a stage that did not happen can no longer be recorded, which the old mechanism allowed.
|
|
1770
1834
|
|
|
1771
|
-
## All Commands (
|
|
1835
|
+
## All Commands (79)
|
|
1772
1836
|
|
|
1773
|
-
*(
|
|
1837
|
+
*(79 MEASURED — reproducer: `grep -c "^ case '" packages/@dzhechkov/harness-cli/src/cli.ts`, the dispatch cases — which is also what the bounded `## All Commands` list enumerates.)*
|
|
1774
1838
|
|
|
1775
1839
|
```
|
|
1776
1840
|
dz setup --target <name> [--preset <name>] [--select id,id,...] [--skills-dir <dir>] [--memory agentdb] [--no-memory] [--no-hooks] [--install-driver] [--force]
|
|
1777
1841
|
dz init --target <name> [--preset <name>] [--select id,id,...] [--force]
|
|
1778
1842
|
dz install <npm-pkg> [--target <name>] [--project <dir>] [--force]
|
|
1779
1843
|
dz bundle [--preset <name> | --select id,...] [--out <dir>] [--skills-dir <dir>] [--force]
|
|
1780
|
-
dz teach "<pattern>" [--reward <0-1>] [--domain <name>] [--type rule|success-pattern|lesson-learned] [--project <dir>] [--no-mirror] [--guard] # --project pins the learned store to <dir>/.dz (not the cwd) — pin to a canonical brain
|
|
1844
|
+
dz teach "<pattern>" [--reward <0-1>] [--domain <name>] [--type rule|success-pattern|lesson-learned] [--project <dir>] [--to project|global] [--no-mirror] [--guard] # --project pins the learned store to <dir>/.dz (not the cwd) — pin to a canonical brain; --to picks WHICH store (global = ~/.dz, shared across projects). Session default: export DZ_LEARN=global. Project default: .dz/config.json -> learning.teachTo. An unknown value is REFUSED, never defaulted. Every write prints the path AND what chose it.
|
|
1781
1845
|
dz teach --reinforce "<dzId-or-exact-text>" [--project <dir>] # bump an existing learned pattern instead of writing a near-duplicate
|
|
1782
1846
|
dz teach --from-json <file> [--project <dir>] [--no-mirror] [--harmonize] # bulk-import a `dz recall --all --json` export; prints a harmonize dry-run advisory
|
|
1783
1847
|
dz consolidate [--sessions-dir <dir>] [--project <dir>] [--no-mirror]
|
|
@@ -1818,7 +1882,7 @@ dz registry [search <query>] [--category <cat>]
|
|
|
1818
1882
|
dz benchmark <skill-dir> [--compare <dir>] [--all]
|
|
1819
1883
|
dz mcp-scan [path] [--json] (static agent-permission audit; exit 0/1/2 = clean/medium/high)
|
|
1820
1884
|
dz architecture [--json] [--revise] [--check --slug <s> --desc "<text>" [--cmd a,b] [--subsystem <id>]] # product map (subsystems = the README jobs + foundation/arsenal/ops); --revise = drift check (exit 1); --check = forward-looking сverka of a proposed feature vs map+vision (exit 2 on a hard-stop dup)
|
|
1821
|
-
dz project-skills [--json] [--stages-json] # polymorphic feature-adr: resolve architecture/project-skills.json (fixed roles product-vision/critic/brand/impl-bar + open extra[]) into per-stage guidance; absent = generic run (byte-identical); feature-adr Step 0 reads it
|
|
1885
|
+
dz project-skills [--json] [--stages-json] [--project <dir>] # polymorphic feature-adr: resolve architecture/project-skills.json (fixed roles product-vision/critic/brand/impl-bar + open extra[]) into per-stage guidance; absent = generic run (byte-identical); feature-adr Step 0 reads it
|
|
1822
1886
|
dz mr-rakes [--json] [--candidate N --confirmed N] [--teach] [--gen-critic <path> [--apply]] # mine review artifacts (features' QE reports + REVIEW files) for RECURRING mistakes; anti-noise (≥2/≥3 distinct sources); close into dz teach + a project-critic skill (R2 critic role)
|
|
1823
1887
|
dz retro [transcript] [--json] [--threshold N] [--no-teach] [--install-hook] # per-session retro: mine the current session for recurring PROCESS rakes (claimed-done-without-verify, committed-without-verify, n-fix-cycles, ignored-correction), drill the user (socratic + checklist) AND teach the agent — co-learning via the dz teach store
|
|
1824
1888
|
dz feature-adr-setup [--plan] [--from-spec <f>] [--apply] # guided project onboarding engine (behind the `configure-feature-adr` skill): --plan shows which docs exist/missing; --from-spec scaffolds vision/map/testing/project-skills (propose; --apply writes; augment-never-clobber)
|
|
@@ -1839,6 +1903,8 @@ dz epoch-replay --score <judgments.json> --work-order <file> [--slice <name>] [-
|
|
|
1839
1903
|
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
|
|
1840
1904
|
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
|
|
1841
1905
|
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
|
|
1906
|
+
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)
|
|
1907
|
+
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"
|
|
1842
1908
|
dz provenance-check --manifest <sources.json> [--project <dir>] [--json] # nothing goes out citing a source that may not leave this machine. Checks PROVENANCE, not words: every claim in a draft names its source, and a source is cleared only when it is a KNOWN kind that resolves safely. Repo paths are classified by `git -C <root> check-ignore` over the RESOLVED path — so a symlink into an ignored directory is refused, not cleared (MEASURED: git classifies the string and never dereferences), and the verdict does not change with your working directory. Store records need naming in the git-TRACKED `provenance-public.json`, so declaring one public is a reviewable commit rather than a field inside an ignored store. Anything else is refused: an undeclared kind is never inferred from the path's shape. exit 0 allowed / 1 blocked / 3 NOT ESTABLISHED — an empty manifest, an unreadable one, or an oracle that did not run is never a pass. **What it cannot do, said on the passing path too:** it proves what was CITED. It cannot see a paraphrase with no citation, nor confidential text pasted by hand into an allowed file. Read the draft.
|
|
1843
1909
|
dz name-check [--command <n>] [--module <basename>] [--export <a,b>] [--project <dir>] [--json] # is this name free, BEFORE a line of code? Twice in one day a collision broke the build outright — `dz retro` was already a command, `decideProvenance` already an export — and both were answerable in advance. Scans workspace SOURCE and never `dist`, because a stale build answers 'free' confidently (MEASURED: half an hour of convincing live runs against a previous build while tsc was red). Checks a command name against the dispatcher AND the help block, a module basename against every package's src/, and exported identifiers against every declaration — naming the DECLARING file, not the barrel. exit 0 all free / 1 at least one taken / 2 nothing asked or the scan read nothing — an empty sweep is never a clean bill. **Honest limit, printed on the passing path:** it reads declarations, so a re-export under a different name stays the build's job.
|
|
1844
1910
|
dz tg-post --draft <file.html> [--manifest <sources.json>] [--channel <@name>] [--send --yes] [--night] [--max-per-day <n>] [--json] # the sender for an APPROVED genai-tweets-channel post, held to the channel's own accepted ADRs: HTML mode only (never MarkdownV2 — 18 escapes against 3, one miss is a 400); link preview OFF by default (x.com previews in Telegram are broken since 2022); the 00:00-06:00 MSK quiet window refuses without an explicit --night. THE DEFAULT RUN IS A DRY-RUN: tag balance and allowed-tag checks, bare &/< detection, the 4096 visible-character limit with the overshoot counted — every issue named in one pass, not just the first. The provenance gate runs IN-PROCESS over --manifest, and a draft with no manifest is refused as unchecked when a send is asked. A real send needs --send AND --yes — ADR-004's standing order that publishing stays manual, stated out loud each time. Three autopublish guards run FAIL-CLOSED, in a fixed order: the **stop-cord** (`.dz/tg-post/HALT` exists ⇒ nothing publishes, checked FIRST so no bug in a later gate can route around it), **dedup** by the sha256 of the post's VISIBLE text (what the reader sees, not the bytes — a whitespace-different draft is the same post), and the **daily limit** (10 by default, `--max-per-day <n>` to change it), counted over the trailing 24h. The journal is two-phase: a `pending` row is written BEFORE the network call and a `sent` row after Telegram accepts, so a crash between the two is caught by dedup on the next run instead of double-publishing; only `sent` rows eat the daily ceiling. An UNREADABLE journal REFUSES — an unreadable counter does not prove the ceiling is unreached. The provenance gate also clears `kind: url`: a well-formed http(s) URL is public by construction so there is nothing local to protect, while a `file://`, a bare path or a non-URL is refused, never inferred. The bot token (TELEGRAM_BOT_TOKEN or telegram.tokenFile) is never printed, and the gates run BEFORE any secret is read. exit 0 sent or clean dry-run / 1 refused / 2 usage
|
|
@@ -2962,7 +3028,7 @@ dz setup --target claude-code --preset devops --memory agentdb # AgentDB (vect
|
|
|
2962
3028
|
| Capability | JSONL (default) | AgentDB (`--memory agentdb`) |
|
|
2963
3029
|
|------------|----------------|------------------------------|
|
|
2964
3030
|
| **Session tracking** | Append-only JSONL log | **Real rows in the shared `.dz/agentdb.db`** (`dz_session_events` telemetry, written by session hooks) |
|
|
2965
|
-
| **Pattern storage** | `dz teach` → patterns.jsonl | `dz teach` (lexical) +
|
|
3031
|
+
| **Pattern storage** | `dz teach` → patterns.jsonl | `dz teach` (lexical) + session-hook writes → `.dz/agentdb.db`; `agentdb_pattern_store` → `.dz/agentdb-mcp.db` (separate stores — see below) |
|
|
2966
3032
|
| **Search** | Keyword (grep) | **Semantic** (HNSW nearest-neighbor, cosine similarity) |
|
|
2967
3033
|
| **Retrieval** | Sequential scan | **O(log n)** approximate nearest neighbor |
|
|
2968
3034
|
| **Self-learning** | Frequency-based | **9 RL algorithms** + Thompson Sampling bandit |
|
|
@@ -2972,7 +3038,7 @@ dz setup --target claude-code --preset devops --memory agentdb # AgentDB (vect
|
|
|
2972
3038
|
| **Skill composition** | Manual (presets) | **Bandit-picked** skill chains (A→B→C) |
|
|
2973
3039
|
| **Audit trail** | No | **Cryptographic attestation log** |
|
|
2974
3040
|
| **Size** | ~0 KB | 4.6 MB (agentdb) |
|
|
2975
|
-
| **MCP tools** | 0 |
|
|
3041
|
+
| **MCP tools** | 0 | pattern, reflexion, causal, skill, hierarchy (whatever the pinned `agentdb` build exposes — `dz` hardcodes no count) |
|
|
2976
3042
|
| **Dependencies** | None | agentdb (optional, via npx) |
|
|
2977
3043
|
|
|
2978
3044
|
### AgentDB self-learning algorithms
|
|
@@ -3012,6 +3078,50 @@ Two surfaces:
|
|
|
3012
3078
|
{ "memory": { "learning": { "deltaRerank": true } } }
|
|
3013
3079
|
```
|
|
3014
3080
|
|
|
3081
|
+
### Bandit payoff re-rank — "did this lesson ever actually help?"
|
|
3082
|
+
|
|
3083
|
+
Similarity answers *is this lesson **about** the topic*. SAFLA delta answers *is its payoff **rising***.
|
|
3084
|
+
Neither answers *has it ever **resolved** anything* — three lessons can all be about Codex while only one
|
|
3085
|
+
has ever closed a real defect. The bandit adds that axis: a Beta posterior per `(context, lesson)` fed by
|
|
3086
|
+
your **confirmations** (`dz teach --reinforce`), turned into a **bounded** re-rank term.
|
|
3087
|
+
|
|
3088
|
+
```jsonc
|
|
3089
|
+
// .dz/config.json
|
|
3090
|
+
{ "memory": { "learning": {
|
|
3091
|
+
"banditRerank": false, // arm the payoff term (default false)
|
|
3092
|
+
"banditExploration": false // allow unproven lessons a trial lift (default false)
|
|
3093
|
+
} } }
|
|
3094
|
+
```
|
|
3095
|
+
|
|
3096
|
+
What arming each one costs, plainly:
|
|
3097
|
+
|
|
3098
|
+
- **`banditRerank`** — recall gains a payoff term capped at the same constant the reinforcement and
|
|
3099
|
+
SAFLA-delta terms use, so it reorders near-ties and can never overturn a decisive relevance gap.
|
|
3100
|
+
Similarity still decides WHICH lessons are candidates; the bandit only reorders WITHIN them, and it
|
|
3101
|
+
never adds a lesson similarity did not select. Deterministic (posterior mean, no sampling), so two
|
|
3102
|
+
identical queries give identical order. A lesson with no confirmations yet contributes exactly `0` —
|
|
3103
|
+
on day one the feature changes nothing, which is the deliberate price of refusing a random lift.
|
|
3104
|
+
- **`banditExploration`** — grants *unproven* lessons a bounded trial lift so they can accumulate
|
|
3105
|
+
evidence. This **weakens the view-does-not-promote posture** the store relies on, which is why it is a
|
|
3106
|
+
separate flag and ships off. Quarantined lessons are excluded from exploration in **every**
|
|
3107
|
+
configuration, and the auto-inject hook is untouched in all of them. `banditExploration` without
|
|
3108
|
+
`banditRerank` is a warned no-op.
|
|
3109
|
+
|
|
3110
|
+
An **exposure is not a reward**: merely seeing a lesson in a recall result is counted in its own channel
|
|
3111
|
+
and never moves the posterior. State lives in `.dz/lesson-bandit/state.json` behind a named lock, is pure
|
|
3112
|
+
derived data, and can be deleted at any time — you lose the learned posteriors, never a lesson.
|
|
3113
|
+
|
|
3114
|
+
```bash
|
|
3115
|
+
dz recall "codex" --json # armed ⇒ a `{"bandit": …}` line on stderr: contextKey, armsConsidered
|
|
3116
|
+
# (the POST-cut list), quarantinedExcluded, unknownArms, moved, reason
|
|
3117
|
+
dz compounding # a bandit-health section: arms with measured payoff, reward events vs
|
|
3118
|
+
# exposure events, write errors, movedRate — INSUFFICIENT_DATA when empty
|
|
3119
|
+
```
|
|
3120
|
+
|
|
3121
|
+
`moved` is the honest headline. `moved: 0` over many queries means the feature is armed and doing
|
|
3122
|
+
nothing — and none of these numbers claims the re-ranking is *better*: `moved` counts change, not
|
|
3123
|
+
improvement.
|
|
3124
|
+
|
|
3015
3125
|
### How to enable AgentDB
|
|
3016
3126
|
|
|
3017
3127
|
```bash
|
|
@@ -3019,9 +3129,11 @@ Two surfaces:
|
|
|
3019
3129
|
dz setup --target claude-code --preset devops --memory agentdb
|
|
3020
3130
|
```
|
|
3021
3131
|
|
|
3022
|
-
This installs `agentdb` + `better-sqlite3` locally (prebuilt, no build tools), writes `.dz/agentdb-writer.mjs`, registers the agentdb MCP server (
|
|
3132
|
+
This installs `agentdb` + `better-sqlite3` locally (prebuilt, no build tools), writes `.dz/agentdb-writer.mjs`, registers the agentdb MCP server in `.mcp.json` **pinned to the exact installed version (never `@latest`) with `AGENTDB_PATH` = `.dz/agentdb-mcp.db`**, and configures session hooks. The agent can immediately use `agentdb_pattern_store`, `agentdb_reflexion_recall`, etc.
|
|
3023
3133
|
|
|
3024
|
-
**
|
|
3134
|
+
**Two stores, never one file.** The session hooks write into `.dz/agentdb.db`; the MCP server reads and writes `.dz/agentdb-mcp.db`. This split is deliberate: the hook writer opens SQLite natively via better-sqlite3, while the MCP server silently falls back to **sql.js** when better-sqlite3 has no usable binary for your Node version — and sql.js persists by rewriting the **whole file** from memory, discarding pages the other engine just committed. Measured in the dz repo on 2026-07-09 under exactly that arrangement: of 20 samples, **5 were zero bytes and 4 were torn**. So `dz setup` refuses to point both at one file, `dz doctor` reports a shared store as `agentdb store separation: ok:false`, and a pre-existing shared-store install is re-pointed on your next plain `dz setup --memory agentdb` (no `--force` needed). The rows already written by the MCP server into the old shared file are **not** copied into the new store — copying out of a file two engines may have torn would launder unknown bytes; the MCP store starts empty.
|
|
3135
|
+
|
|
3136
|
+
**Session hooks make real writes into the writer's own store.** On every session start/end the hook runs the generated writer, which inserts a **metadata-only telemetry row** into the `dz_session_events` table of `.dz/agentdb.db`. Deliberately *not* an embedding write: markers carry no semantic content, so they stay out of the HNSW index and cost ~milliseconds (no model load, nothing blocks your session). Real learnings enter the vector index in-session via `agentdb_pattern_store` / `agentdb_reflexion_store`, in `.dz/agentdb-mcp.db`. If `better-sqlite3` isn't installed yet, the writer degrades to an honestly-labelled `.dz/sessions.jsonl` line and self-heals once the deps exist. *(Restart Claude Code after setup so the MCP server + hooks load.)*
|
|
3025
3137
|
|
|
3026
3138
|
| Command | When to use |
|
|
3027
3139
|
|---------|-------------|
|
|
@@ -3118,12 +3230,18 @@ Drop an `architecture/project-skills.json` (no pipeline edits needed):
|
|
|
3118
3230
|
"extra": [ { "skill": ".dz-skills/security-checklist/SKILL.md", "phase": "qe", "as": "guidance" } ] }
|
|
3119
3231
|
```
|
|
3120
3232
|
```bash
|
|
3121
|
-
dz project-skills
|
|
3122
|
-
dz project-skills --json
|
|
3233
|
+
dz project-skills # who-injected report (which skill feeds which stage)
|
|
3234
|
+
dz project-skills --json # the plan feature-adr Step 0 reads
|
|
3235
|
+
dz project-skills --project /some/repo # read THAT repo's manifest, whatever your cwd is
|
|
3123
3236
|
```
|
|
3124
3237
|
No manifest ⇒ a normal generic run (byte-identical). With one, feature-adr folds each skill into its stage as guidance
|
|
3125
3238
|
(`product-vision`→design+QE, `critic`→QE, `brand`→code).
|
|
3126
3239
|
|
|
3240
|
+
`--project <dir>` names the root explicitly. Until harness-cli 0.7.9 the command read the manifest from **cwd only**,
|
|
3241
|
+
so a feature-adr run whose target repo is a separate checkout probed the wrong place, found nothing, and quietly fell
|
|
3242
|
+
back to a generic run — no error, just missing project guidance in every stage. Step 0 now probes the target repo first
|
|
3243
|
+
and falls back to the workspace, so a manifest is found wherever it actually lives.
|
|
3244
|
+
|
|
3127
3245
|
### `dz mr-rakes` — when you want to learn what mistakes this project keeps repeating
|
|
3128
3246
|
|
|
3129
3247
|
Run it once you have a few reviews (feature-adr QE reports / MR reviews) to mine the **recurring** rakes:
|
|
@@ -4096,6 +4214,22 @@ npx @dzhechkov/p-replicator init
|
|
|
4096
4214
|
|
|
4097
4215
|
## Status
|
|
4098
4216
|
|
|
4217
|
+
`v0.8.1` — **`dz profile` (the 79th command), hardened by four cross-family review rounds until one came back clean.** Say once who you
|
|
4218
|
+
are — register, language, deep and weak domains — and every Claude session on the machine loads it from a marked block in
|
|
4219
|
+
`~/.claude/CLAUDE.md`; the store lives at `~/.dz/profile.json` (0600, never inside a project, redacted from training-pair capture).
|
|
4220
|
+
The review ladder did what it exists to do, each round finding a hole in the previous round's fix: a marker literal could enter the
|
|
4221
|
+
profile through `set` and poison every later sync (refused at the one validation seam all write paths cross); the CLI echoed
|
|
4222
|
+
`language: <value>` BEFORE a refused write exited 2 — a success-looking confirmation of a mutation never applied (echo now deferred
|
|
4223
|
+
until the write lands); the validation boundary itself could throw (`JSON.stringify(2n)` is a TypeError) through the documented
|
|
4224
|
+
never-throws contract of `syncProfileBlock` (the validator is now total); and the catch path formatting the thrown value could throw
|
|
4225
|
+
too — conversion hooks run on the thrown value, so a hostile getter throwing `Object.create(null)` blew up the catch itself (coercion
|
|
4226
|
+
now sits under its own try with a fixed fallback). Round 8 reviewed the final state and returned no findings, executing the tests
|
|
4227
|
+
(22/22, MEASURED — reproducer `npx vitest run test/profile.test.ts` in `packages/@dzhechkov/harness-core`) and typecheck itself.
|
|
4228
|
+
Release gates: tests / syntax / smoke green across 54 packages (MEASURED — reproducer `dz release --filter harness`, verdict
|
|
4229
|
+
2026-08-28: tests 32 passed, syntax 215 passed, smoke 19 passed); the audit gate is red on advisories
|
|
4230
|
+
that live ONLY in workspace dev tooling — the published pair's runtime deps are workspace siblings plus `proper-lockfile` and `yaml`,
|
|
4231
|
+
none affected — taken through the gate's own documented fallback with the scoping fix filed.
|
|
4232
|
+
|
|
4099
4233
|
`v0.7.8` — **the observability pass, one new verb, and a publisher that stops rewriting history.** `dz feature-adr-record --backfill` fills the
|
|
4100
4234
|
run-cost ledger from the host's own workflow record — dry-run by default, `--yes` writes atomically.
|
|
4101
4235
|
A derived number is MARKED (`filledFrom`/`filledBy`), a number you typed is never overwritten and any
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAoC,KAAK,EAAa,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAK3G,OAAO,EA4CL,iBAAiB,EAmBjB,KAAK,oBAAoB,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|