@dzhechkov/harness-cli 0.3.244 → 0.3.246

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 CHANGED
@@ -9,7 +9,7 @@
9
9
  },
10
10
  {
11
11
  "path": "README.md",
12
- "sha256": "2471dcbdf8588a65410c17557f5ef331c4f8cc77923824728f64ebe7e33d84dc"
12
+ "sha256": "129ee8a3fc96a1edda2258d02cd6dc4b8df2ab766f3b03ddb38f1559f0c0d9b9"
13
13
  },
14
14
  {
15
15
  "path": "coverage/coverage-final.json",
@@ -41,15 +41,15 @@
41
41
  },
42
42
  {
43
43
  "path": "dist/cli.d.ts.map",
44
- "sha256": "2bb00d2f42334250ee57b4d0f88d92968cbe3f010ec8d75bb748c0ee6f8de0b8"
44
+ "sha256": "894d5779615292e57a6b5c204ebd04cef4b065e3fe4d8546c0f3dfbe0fb22529"
45
45
  },
46
46
  {
47
47
  "path": "dist/cli.js",
48
- "sha256": "d959d7623b68286e440e04f90ee3ae7af0166c1fe506f2cf7e6e9e317439409d"
48
+ "sha256": "aaaf1d89fb27f39c125c3404b37d57f9251fe62d7993f79df5696944ae8bddcf"
49
49
  },
50
50
  {
51
51
  "path": "dist/cli.js.map",
52
- "sha256": "68e0bbf621169f7bae350a5b723f9425969ab12b6f7dd98ce26bb06d32c77c92"
52
+ "sha256": "dfdfb4feeb07bf037194a1aa7da4f956e88da30ec8c1848fa2e989d82ed34a0b"
53
53
  },
54
54
  {
55
55
  "path": "dist/index.d.ts",
@@ -73,7 +73,7 @@
73
73
  },
74
74
  {
75
75
  "path": "package.json",
76
- "sha256": "ff01608759bb01a9bb83aa45cc4658182765d9fb4b2512f3a096b8ea55370eac"
76
+ "sha256": "139d06a7617876ef1f9a1c7408f993314f1c3415a7c95a4dc53d89dcf453d866"
77
77
  },
78
78
  {
79
79
  "path": "src/bin.ts",
@@ -81,7 +81,7 @@
81
81
  },
82
82
  {
83
83
  "path": "src/cli.ts",
84
- "sha256": "14a3db7155fcc858272439a55bc7a43a09c7f6fd7caa302e5a13c153fe1a6d16"
84
+ "sha256": "967efe0f790775d915f31665e270490794a8ca4bdbecd0844562edda2edf42d9"
85
85
  },
86
86
  {
87
87
  "path": "src/index.ts",
@@ -101,5 +101,5 @@
101
101
  }
102
102
  ]
103
103
  },
104
- "signature": "WQQaokaBe8iyzdWIE4vAORyCEzPbmF/WLd7uUazUGV6j9mL84mxjqC4NaVyKwWjD1+c+wawazid8gFVOqz07Bg=="
104
+ "signature": "pCBgoXGJzxdv5poRU5eOMtJoISDMnvSabiQOi+YCg1eWnD+txkaJWy1VeyoNZhPkuUAHAm6VfykoZ5K6Th6wDw=="
105
105
  }
package/README.md CHANGED
@@ -434,6 +434,36 @@ dz parity — codex (capabilities: shell, skills, mcp)
434
434
  **When to use:** before promising a workflow to a teammate on Cursor/Codex/Hermes; when choosing
435
435
  a target for a project; as the requirements input for porting a feature to more targets.
436
436
 
437
+ ### Does the learning loop actually pay? — `dz compounding`
438
+
439
+ dz's self-learning has collect, rank and apply legs — this command answers whether they COMPOUND,
440
+ honestly. Ported from rUv's darwin-mode with a deliberate split: the seeded statistics came over
441
+ verbatim (deterministic bootstrap, lower-95 promotion, and a minimum of 5 samples per arm — darwin's
442
+ own calibration measured a 33% false-discovery rate at n=3); darwin's measurement legs did NOT (they
443
+ score fixtures, not your data). The measurements here run over what your machine actually recorded:
444
+
445
+ ```
446
+ $ dz compounding
447
+ POOL PAYOFF: 154 lessons · 27 ever injected by the apply leg · 89 touched by any recall
448
+ write-only ratio (strict bar): 82%
449
+ GUARD TRAJECTORY (violations, first half vs second half of the audit span):
450
+ ↓ no-workspace-star: 31 → 0
451
+ ↓ readme-first: 49 → 4
452
+ COLD-VS-WARM REPLAY: 2 unique prompt event(s); 5 needed — queries are recorded as of 2026-07-28
453
+ INSTRUMENTATION: last apply-leg record … — live
454
+ ```
455
+
456
+ Three honesty rules are load-bearing:
457
+ - **a gate without enough data says INSUFFICIENT DATA** — never a verdict (the apply-leg log turned
458
+ out to have been silently dead for 19 days; "no data" is a finding, not a pass);
459
+ - **readiness is not a result** — the replay section says `ready`, never `promote`;
460
+ - **improvement is judged by RATE** (violations per audit), so a quiet afternoon cannot masquerade
461
+ as progress.
462
+
463
+ The prompt queries that make replay possible stay on your machine: `.dz/recall-usage.jsonl` is
464
+ git-ignored, entries are truncated at 200 chars and flagged when truncated (a prefix is not a prompt,
465
+ so flagged rows never count as replayable).
466
+
437
467
  ### Usage estimates you can act on — `dz usage`
438
468
 
439
469
  `dz usage` estimates how much of your Claude session (5h block) and week you have spent, from local
@@ -696,7 +726,7 @@ Get the whole set with `dz init --target claude-code --preset meta`, or pick one
696
726
 
697
727
  > **A skill and its npx toolkit are not duplicates — they're a graduation.** Several skills (e.g. `feature-adr`, `design-thinking`) exist BOTH as a skill inside a `dz` preset AND as a standalone `npx` package. The preset's SKILL.md is **fully functional on its own** (the whole methodology — modules + references — travels with it, and it auto-activates by description), and it's the only way to compile that capability to the **non-Claude platforms** (Codex/OpenCode/Hermes/OpenClaude) via `dz`. The npx package adds **project-level runtime governance** around the same skill: a slash command, governance rules, a context shard, and (for feature-adr) reward-learning + `/harvest`. So: pick the **skill/preset** for a working capability across platforms; pick the **npx toolkit** when you want it as a governed, command-driven fixture of one project.
698
728
 
699
- ## All Commands (58)
729
+ ## All Commands (59)
700
730
 
701
731
  ```
702
732
  dz setup --target <name> [--preset <name>] [--select id,id,...] [--skills-dir <dir>] [--memory agentdb] [--no-memory] [--no-hooks] [--install-driver] [--force]
@@ -753,6 +783,7 @@ dz bto-optimize --split|--plan|--select|--scope-check|--diff [--json] # determ
753
783
  dz discrimination-check --test <f[,f]> [--base <ref>] [--name <filter>] [--runner <cmd>] [--json] # §42 test-discrimination gate for feature-adr Step-8: run the ADR's property test in an isolated git worktree at pre-feature base — it MUST go red without the fix; a green is a false green (HIGH finding, advisory, never auto-aborts)
754
784
  dz delivery-check --slug <slug> [--context-only] [--findings <f.json>] [--strict] [--author <model>] [--json] # portable Step-10 Delivery Gate: the `manual` form that travels to every shell target — prints the 4-plane review brief (regressions ‖ security ‖ code-quality ‖ product-honesty) + artifact probes; --findings classifies a fed-back review into a fail-closed ready|blocked hand-off (only cross-validated BLOCKER/HIGH count) and writes features/<slug>/10_delivery_review.md; --strict exits 1 on blocked
755
785
  dz skills-verify [--dir <project>] [--expect a,b] [--static] [--strict] [--timeout <s>] [--json] # does .claude/skills/ actually REGISTER? --static = instant layout scan (CI-safe, no session): flags dirs that can never register; default also starts a real session and reads the authoritative system/init listing. exit 0 pass / 1 fail / 2 inconclusive — an unobservable registration is NEVER a pass
786
+ dz compounding [--project <dir>] [--json] # honest learning-loop payoff report: pool write-only ratio, guard repeat-violation trajectory (rate per audit-half), cold-vs-warm replay readiness over unique untruncated prompt events, apply-leg staleness — a gate without enough data says INSUFFICIENT_DATA, never a verdict
756
787
  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
757
788
  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
758
789
  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)
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;AAwRH,2EAA2E;AAC3E,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC;CAC5C;AAED,yFAAyF;AACzF,MAAM,MAAM,iBAAiB,GAAG,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KACvD;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AA20L9E,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,KAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAoJ5E"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA6RH,2EAA2E;AAC3E,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC;CAC5C;AAED,yFAAyF;AACzF,MAAM,MAAM,iBAAiB,GAAG,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KACvD;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAs6L9E,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,KAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAsJ5E"}
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ import { fileURLToPath } from 'node:url';
9
9
  import { execSync, spawn } from 'node:child_process';
10
10
  import { homedir, tmpdir } from 'node:os';
11
11
  import { createRequire } from 'node:module';
12
- import { createSkill, getSkillInfo, getWorkflow, isTargetName, listSkills, runDoctor, runInit, benchmarkSkill, benchmarkSkills, scanMcp, reconcileCapabilities, RECONCILE_BANNER, buildRegistry, discoverSkillPackDirs, checkUpstream, compareSkills, checkAllUpstream, sweepSkillDrift, syncCanonicalSkill, checkUpgrades, discoverPackages, discoverSourcePackages, fetchAllDownloads, filterByCategory, pretrain, recommend, generatePlugin, publishPackages, runSetup, runMigrate, searchRegistry, runSync, runVerify, runInitAgentsMd, runInitGeminiMd, TARGET_NAMES, buildParityMatrix, TARGET_CAPABILITIES, TARGET_SHORT_LABELS, WORKFLOW_NAMES, importEcc, recordPattern, resolveLearningBackend, storeStats, consolidateSessions, pruneNoisePatterns, lessonDeltaReport, removePatternsByIds, snapshotStore, recallHybrid, teachGuard, mirrorPatternsToVector, mirrorEntriesToVector, patternVectorEntry, readMemoryLearningConfig, promotePatterns, quarantineExpiryCandidates, pruneQuarantinePatterns, clearAgentdbQuarantine, vectorMirrorEnabled, vectorTierStatus, resolveVectorEngine, reindexVectorStore, harmonizeVectorStore, importRvfCheckpoint, statuslineData, writeFeatureAdrState, computeUsage, deriveUsageCalibration, normalizeClaudeUsageModelKey, readUsageLimits, claimCheck, summarize, queryBookKnowledge, loadStorePatternsSync, patternRecordId, loadStoreRecords, recordToPattern, bundleSkills, brainHome, listBrain, promoteProjectToBrain, updateBrainSource, queryBrain, groundPrompt, expandKu, reindexBrainVectors, buildPrimer, exportBrainSlice, importBrainSlice, registerKusToBrain, RECALL_USAGE_LOG_RELATIVE, RECALL_USAGE_LOG_MAX_BYTES, parseRecallUsageLog, buildRecallUsageReport, buildManifest, buildSbom, resolveTrustRoot, decideVerifyPolicy, generateSigningKeypair, evaluateGuard, resolveRules, auditRecord, guardExitCode, DEFAULT_RULES, decideProvenance, isInsideTree, signManifest, verifyManifest, listSignablePackFiles, assertKeyOutsideTree, decidePublishGate, collectPackageFacts, planReleaseGates, selectAffectedPackages, classifyGateExecutions, buildFailureIssue, buildReleaseNotes, releaseTagName, firstOutputLine, formatPublishError, MANIFEST_NAME, SBOM_NAME, buildArchitectureMap, renderMapHuman, findArchitectureDrift, renderDriftReport, scanWorkspacePackages, loadSubsystemManifest, loadProductVision, checkFeatureAgainstArchitecture, renderArchCheck, planProjectSkills, guidanceForStage, renderInjectionReport, analyzeCorpus, renderRakeReport, renderCriticSection, rakeAsLesson, rakeReward, DEFAULT_RAKE_THRESHOLDS, streamSessionEvents, findLatestTranscript, detectProcessRakes, buildRetro, renderRetro, retroLessonText, PROCESS_SIGNATURES, RETRO_DOMAIN, scanForSetup, buildSetupPlan, scaffoldFromSpec, renderScaffoldPreview, readExistingForScaffold, assembleChallengeContext, buildChallengeBrief, planDiscriminationCheck, classifyDiscrimination, pickAdversaryModel, CHALLENGE_QUESTIONS, loadOutcomes, renderOutcomes, statsForKey, selectAutoCost, recordProvisional, finalizeOutcome, COST_LADDER, splitScenarios, budgetPlan, selectWinner, proseScopeOk, renderProseDiff, readScenarioIds, DEFAULT_MAX_JUDGE_RUNS, collectDeliveryFacts, planDeliveryCheck, renderDeliveryBrief, classifyDelivery, isUsablePlaneResult, renderDeliveryReview, scanSkillsLayout, parseInitFacts, verifyRegistration, buildContentProbePrompt, classifyContentProbe, renderContentProbe, findNonRegistrableSkillDirs, registrationExitCode, renderRegistrationReport, } from '@dzhechkov/harness-core';
12
+ import { createSkill, getSkillInfo, getWorkflow, isTargetName, listSkills, runDoctor, runInit, benchmarkSkill, benchmarkSkills, scanMcp, reconcileCapabilities, RECONCILE_BANNER, buildRegistry, discoverSkillPackDirs, checkUpstream, compareSkills, checkAllUpstream, sweepSkillDrift, syncCanonicalSkill, checkUpgrades, discoverPackages, discoverSourcePackages, fetchAllDownloads, filterByCategory, pretrain, recommend, generatePlugin, publishPackages, runSetup, runMigrate, searchRegistry, runSync, runVerify, runInitAgentsMd, runInitGeminiMd, TARGET_NAMES, buildParityMatrix, TARGET_CAPABILITIES, TARGET_SHORT_LABELS, WORKFLOW_NAMES, importEcc, recordPattern, resolveLearningBackend, storeStats, consolidateSessions, pruneNoisePatterns, lessonDeltaReport, removePatternsByIds, snapshotStore, recallHybrid, teachGuard, mirrorPatternsToVector, mirrorEntriesToVector, patternVectorEntry, readMemoryLearningConfig, promotePatterns, quarantineExpiryCandidates, pruneQuarantinePatterns, clearAgentdbQuarantine, vectorMirrorEnabled, vectorTierStatus, resolveVectorEngine, reindexVectorStore, harmonizeVectorStore, importRvfCheckpoint, statuslineData, writeFeatureAdrState, computeUsage, deriveUsageCalibration, normalizeClaudeUsageModelKey, readUsageLimits, claimCheck, summarize, queryBookKnowledge, loadStorePatternsSync, patternRecordId, loadStoreRecords, recordToPattern, bundleSkills, brainHome, listBrain, promoteProjectToBrain, updateBrainSource, queryBrain, groundPrompt, expandKu, reindexBrainVectors, buildPrimer, exportBrainSlice, importBrainSlice, registerKusToBrain, RECALL_USAGE_LOG_RELATIVE, RECALL_USAGE_LOG_MAX_BYTES, parseRecallUsageLog, buildRecallUsageReport, buildManifest, buildSbom, resolveTrustRoot, decideVerifyPolicy, generateSigningKeypair, evaluateGuard, resolveRules, auditRecord, guardExitCode, DEFAULT_RULES, decideProvenance, isInsideTree, signManifest, verifyManifest, listSignablePackFiles, assertKeyOutsideTree, decidePublishGate, collectPackageFacts, planReleaseGates, selectAffectedPackages, classifyGateExecutions, buildFailureIssue, buildReleaseNotes, releaseTagName, firstOutputLine, formatPublishError, MANIFEST_NAME, SBOM_NAME, buildArchitectureMap, renderMapHuman, findArchitectureDrift, renderDriftReport, scanWorkspacePackages, loadSubsystemManifest, loadProductVision, checkFeatureAgainstArchitecture, renderArchCheck, planProjectSkills, guidanceForStage, renderInjectionReport, analyzeCorpus, renderRakeReport, renderCriticSection, rakeAsLesson, rakeReward, DEFAULT_RAKE_THRESHOLDS, streamSessionEvents, findLatestTranscript, detectProcessRakes, buildRetro, renderRetro, retroLessonText, PROCESS_SIGNATURES, RETRO_DOMAIN, scanForSetup, buildSetupPlan, scaffoldFromSpec, renderScaffoldPreview, readExistingForScaffold, assembleChallengeContext, buildChallengeBrief, planDiscriminationCheck, classifyDiscrimination, pickAdversaryModel, CHALLENGE_QUESTIONS, loadOutcomes, renderOutcomes, statsForKey, selectAutoCost, recordProvisional, finalizeOutcome, COST_LADDER, splitScenarios, budgetPlan, selectWinner, proseScopeOk, renderProseDiff, readScenarioIds, DEFAULT_MAX_JUDGE_RUNS, collectDeliveryFacts, planDeliveryCheck, renderDeliveryBrief, classifyDelivery, isUsablePlaneResult, renderDeliveryReview, scanSkillsLayout, parseInitFacts, verifyRegistration, buildContentProbePrompt, classifyContentProbe, renderContentProbe, findNonRegistrableSkillDirs, assembleCompoundingReport, renderCompoundingReport, readReinforcementState, readQuarantineState, registrationExitCode, renderRegistrationReport, } from '@dzhechkov/harness-core';
13
13
  import { getPreset, PRESET_NAMES } from '@dzhechkov/harness-presets';
14
14
  import { scanGitHub, analyzeRepo, generateReport, deepAnalyze, scanAllSources, ScoutMemory } from '@dzhechkov/scout';
15
15
  const USAGE = `dz - DZ cross-platform harness CLI
@@ -36,6 +36,7 @@ Usage:
36
36
  dz parity [--target <name>] [--json] (the honest feature×target map, COMPUTED from the capability model — which harness feature is full / manual / absent on each of the ${TARGET_NAMES.length} targets, and via which form)
37
37
  dz delivery-check --slug <slug> [--context-only] [--findings <f.json>] [--strict] [--author <model>] [--json] (portable Step-10 Delivery Gate: prints the 4-plane review brief + artifact probes; --findings classifies a fed-back review into a fail-closed ready|blocked hand-off and writes features/<slug>/10_delivery_review.md; --strict exits 1 on blocked)
38
38
  dz skills-verify [--dir <project>] [--expect a,b] [--static] [--strict] [--json] (does .claude/skills/ actually REGISTER? --static = instant layout scan for CI; default reads the authoritative system/init listing from a real session. exit 0 pass / 1 fail / 2 inconclusive — never a false pass)
39
+ dz compounding [--project <dir>] [--json] (honest learning-loop payoff report: pool write-only ratio, guard repeat-violation trajectory, cold-vs-warm replay readiness, instrumentation health — a gate without enough data says INSUFFICIENT_DATA, never a fake verdict)
39
40
  dz setup --target <name> [--preset <name>] [--select id,id,...] [--skills-dir <dir>] [--project <dir>] [--memory agentdb] [--no-memory] [--no-hooks] [--install-driver] [--force] [--enrich]
40
41
  dz teach "<pattern>" [--reward <0-1>] [--domain <name>] [--type rule|success-pattern|lesson-learned] [--project <dir>] [--no-mirror] (--project pins the learned store to <dir>/.dz, not the cwd — pin to a canonical brain)
41
42
  dz teach --from-json <file> [--project <dir>] [--no-mirror] (bulk-import a 'dz recall --all --json' export — share a learned store across machines)
@@ -5371,6 +5372,100 @@ function nameFor(t, outcome) {
5371
5372
  * --author <model> cosmetic: the reviewer to dispatch, printed alongside the brief
5372
5373
  * --json machine contract { planesChecked, planesSkipped, findings, handoff, artifact }
5373
5374
  */
5375
+ /**
5376
+ * `dz compounding` — does the learning loop actually PAY? (feature compounding, scout C2.)
5377
+ * Gathers the facts (store rows, apply-leg usage log, guard audit) and hands them to the PURE
5378
+ * report assembler. Gates without enough data say INSUFFICIENT_DATA — never a fake verdict.
5379
+ */
5380
+ function cmdCompounding(options, flags, cwd, write) {
5381
+ const json = flags.has('json');
5382
+ if (flags.has('help')) {
5383
+ write('dz compounding [--project <dir>] [--json] — honest learning-loop payoff report');
5384
+ write(' pool payoff (write-only ratio) · guard repeat-violation trajectory · cold-vs-warm replay readiness · instrumentation health');
5385
+ return 0;
5386
+ }
5387
+ for (const flag of flags) {
5388
+ if (!new Set(['json', 'help']).has(flag)) {
5389
+ write(json ? JSON.stringify({ error: `unknown option --${flag}`, exitCode: 1 }) : `dz compounding: unknown option --${flag}\n allowed: --project <dir>, --json`);
5390
+ return 1;
5391
+ }
5392
+ }
5393
+ for (const key of options.keys()) {
5394
+ if (key.startsWith('_positional_')) {
5395
+ write(json ? JSON.stringify({ error: `unexpected argument "${options.get(key)}"`, exitCode: 1 }) : `dz compounding: unexpected argument "${options.get(key)}"\n allowed: --project <dir>, --json`);
5396
+ return 1;
5397
+ }
5398
+ if (key !== 'project') {
5399
+ write(json ? JSON.stringify({ error: `unknown option --${key}`, exitCode: 1 }) : `dz compounding: unknown option --${key}\n allowed: --project <dir>, --json`);
5400
+ return 1;
5401
+ }
5402
+ }
5403
+ const root = resolve(cwd, options.get('project') ?? '.');
5404
+ // lessons — the store, with reinforcement + quarantine metadata
5405
+ const lessons = loadStoreRecords(root).map((r) => ({
5406
+ dzId: r.id,
5407
+ uses: readReinforcementState(r).uses,
5408
+ quarantined: readQuarantineState(r).quarantined,
5409
+ reward: typeof r.score === 'number' ? r.score : null,
5410
+ }));
5411
+ // apply-leg usage events (read records only; aggregate rows carry no query by construction)
5412
+ const usage = [];
5413
+ try {
5414
+ const text = readFileSync(join(root, '.dz', 'recall-usage.jsonl'), 'utf-8');
5415
+ for (const line of text.split('\n')) {
5416
+ if (line.trim() === '')
5417
+ continue;
5418
+ try {
5419
+ const o = JSON.parse(line);
5420
+ if (typeof o.dzId === 'string' && typeof o.ts === 'string' && o.kind !== 'aggregate') {
5421
+ usage.push({
5422
+ dzId: o.dzId,
5423
+ ts: o.ts,
5424
+ ...(typeof o.query === 'string' ? { query: o.query } : {}),
5425
+ ...(typeof o.runId === 'string' ? { runId: o.runId } : {}),
5426
+ });
5427
+ }
5428
+ }
5429
+ catch {
5430
+ /* one bad line must not kill the report */
5431
+ }
5432
+ }
5433
+ }
5434
+ catch {
5435
+ /* no log yet — the report says so */
5436
+ }
5437
+ // guard audit events
5438
+ const guard = [];
5439
+ try {
5440
+ const text = readFileSync(join(root, '.dz', 'guard-audit.jsonl'), 'utf-8');
5441
+ for (const line of text.split('\n')) {
5442
+ if (line.trim() === '')
5443
+ continue;
5444
+ try {
5445
+ const o = JSON.parse(line);
5446
+ if (typeof o.ts === 'string' && typeof o.verdict === 'string') {
5447
+ guard.push({
5448
+ ts: o.ts,
5449
+ verdict: o.verdict,
5450
+ rules: Array.isArray(o.violations) ? o.violations.map((v) => (typeof v?.rule === 'string' ? v.rule : '')).filter(Boolean) : [],
5451
+ });
5452
+ }
5453
+ }
5454
+ catch {
5455
+ /* skip */
5456
+ }
5457
+ }
5458
+ }
5459
+ catch {
5460
+ /* no audit yet */
5461
+ }
5462
+ const report = assembleCompoundingReport({ lessons, usage, guard, nowTs: new Date().toISOString() });
5463
+ if (json)
5464
+ write(JSON.stringify({ ...report, exitCode: 0 }, null, 2));
5465
+ else
5466
+ write(renderCompoundingReport(report));
5467
+ return 0;
5468
+ }
5374
5469
  /**
5375
5470
  * Env vars an INHERITED Claude session leaks into a child. Left in place, the probe can silently
5376
5471
  * read the parent's project instead of the target — the exact confound that made a hand-rolled
@@ -6161,6 +6256,8 @@ export async function runCli(argv, io = {}) {
6161
6256
  return cmdDeliveryCheck(options, flags, cwd, write);
6162
6257
  case 'skills-verify':
6163
6258
  return cmdSkillsVerify(options, flags, cwd, write);
6259
+ case 'compounding':
6260
+ return cmdCompounding(options, flags, cwd, write);
6164
6261
  case 'routing':
6165
6262
  return cmdRouting(options, flags, cwd, write);
6166
6263
  case 'bto-optimize':