@dzhechkov/harness-cli 0.3.243 → 0.3.245

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": "5f4e31653970ef6970b6d87c862a1c6ac1f2da92c3f4f913b4be4155284db1f4"
12
+ "sha256": "8be358264886041e22508990afe5d9b395f9fc4248dd46a9cee7a2cf6cd4429e"
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": "e26250419d70ec922def52f25f63000b658eec8203b29a2135edad1be98f8d5d"
76
+ "sha256": "af2086ded1d37777464e520760fc7c25435bd0c96808e7555f0144f2cd4863af"
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": "gGmbCW5Q8VH8CPNbUxHMrZBTxa6wqihi7F0bfUw+dyfN09I/hBQJZzhkautvL4TeFLGJGxkzzXVvpBqjoLHEAw=="
104
+ "signature": "Ittm2O/b8yBu3Iu5RFRkiEnj8nTDq3a9G5mS8k94mXHmqrmNOJiUqUTk4YtZO7jZ1nyKQP7sCYwUmC5MZq5rBQ=="
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
@@ -447,6 +477,9 @@ Two things changed to make it mean something:
447
477
  1-hour TTL write, cache-read 0.1x, output 5x).
448
478
  - **Subagent transcripts count.** `<session>/subagents/*.jsonl` carry real, non-duplicated usage and
449
479
  were silently excluded.
480
+ - **The walk is safe and bounded.** Only regular files are read, symlinked files and directory
481
+ components are skipped (a FIFO used to block it, a symlink used to be followed), and the file cap
482
+ keeps the NEWEST transcripts so a long history cannot push current usage out of view.
450
483
 
451
484
  ```bash
452
485
  dz usage # session ~13% (resets 10:24) · week ~15% (resets 08:59) · estimated
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':