@dzhechkov/harness-cli 0.7.7 → 0.7.9

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": "3d621db3f7811b174ee46b19fa462316ef13679786a910ac64c65fb05bfd5ef7"
12
+ "sha256": "07e1f395043324fe72c1170406340df3ebdb1dbabde64d80dc8124269a0cb5a6"
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": "c7856b79fdf6683fe855268191805ed07b1c68f2ff7ac544d46ac3d93e4c94ef"
52
+ "sha256": "947a13984fe9e992098c4d7b63303b6048f30d7ff0f509b666022e1c8c67cd54"
53
53
  },
54
54
  {
55
55
  "path": "dist/cli.js",
56
- "sha256": "27741d68ac996a060df7161b49e372f68e31b990a406f0792c79c474ff17eeca"
56
+ "sha256": "d539a0084dced536df3edadd79bcce94d1cb7205d1e534922fd8a1ca37c7fc7d"
57
57
  },
58
58
  {
59
59
  "path": "dist/cli.js.map",
60
- "sha256": "bea844c256e8d947464a4690d2224e4f28d61f433d6e50e5fe26bed3b415ae26"
60
+ "sha256": "b3b37c4d27ea28e00da2f6d1bc438e22ebb48da8dec365e9f4128071647c3dd0"
61
61
  },
62
62
  {
63
63
  "path": "dist/core-compat.d.ts",
@@ -133,7 +133,7 @@
133
133
  },
134
134
  {
135
135
  "path": "package.json",
136
- "sha256": "b7c47af8811ca86ee8dd5d4d98cab76c4cceddaafbe09676141bacae92b69b9d"
136
+ "sha256": "98583e52265eb3951c2596f652f5046cc2044e5a4c12353ea1a380a037819778"
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": "d8288240b5420ddca2cabdb7b358c7c18ba59724defda951d0dbc61439b6fc4c"
148
+ "sha256": "e13c80580e477748ab072078f3b90e9301ad60b01106e228501f16bc753f994a"
149
149
  },
150
150
  {
151
151
  "path": "src/core-compat.ts",
@@ -165,5 +165,5 @@
165
165
  }
166
166
  ]
167
167
  },
168
- "signature": "OQCEpmIWKpZGhU/+x7WMKAFh0U4l40qE6AIVuUfTE5ACGVyVo5kon78Pw2MG2mNhf//gJwd+vAERs41vWR5rAw=="
168
+ "signature": "flR84d1UlTdgGlaECrwiCZX3wEr4dySuhKG7pAcgdw/VbUH4vG8zNRDx91OiHIcLCBN9OW1cdHAUsWTLwLAxBg=="
169
169
  }
package/README.md CHANGED
@@ -266,7 +266,7 @@ 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 77 commands (MEASURED — reproducer: `grep -c "^ case '" src/cli.ts`, the dispatch cases) mapped to a real workflow:
269
+ All 77 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
@@ -1770,7 +1770,7 @@ to witness — so a stage that did not happen can no longer be recorded, which t
1770
1770
 
1771
1771
  ## All Commands (77)
1772
1772
 
1773
- *(73 MEASURED — reproducer: `grep -c "^ case '" src/cli.ts`, the dispatch cases.)*
1773
+ *(77 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
1774
 
1775
1775
  ```
1776
1776
  dz setup --target <name> [--preset <name>] [--select id,id,...] [--skills-dir <dir>] [--memory agentdb] [--no-memory] [--no-hooks] [--install-driver] [--force]
@@ -1818,7 +1818,7 @@ dz registry [search <query>] [--category <cat>]
1818
1818
  dz benchmark <skill-dir> [--compare <dir>] [--all]
1819
1819
  dz mcp-scan [path] [--json] (static agent-permission audit; exit 0/1/2 = clean/medium/high)
1820
1820
  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
1821
+ 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
1822
  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
1823
  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
1824
  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)
@@ -3012,6 +3012,50 @@ Two surfaces:
3012
3012
  { "memory": { "learning": { "deltaRerank": true } } }
3013
3013
  ```
3014
3014
 
3015
+ ### Bandit payoff re-rank — "did this lesson ever actually help?"
3016
+
3017
+ Similarity answers *is this lesson **about** the topic*. SAFLA delta answers *is its payoff **rising***.
3018
+ Neither answers *has it ever **resolved** anything* — three lessons can all be about Codex while only one
3019
+ has ever closed a real defect. The bandit adds that axis: a Beta posterior per `(context, lesson)` fed by
3020
+ your **confirmations** (`dz teach --reinforce`), turned into a **bounded** re-rank term.
3021
+
3022
+ ```jsonc
3023
+ // .dz/config.json
3024
+ { "memory": { "learning": {
3025
+ "banditRerank": false, // arm the payoff term (default false)
3026
+ "banditExploration": false // allow unproven lessons a trial lift (default false)
3027
+ } } }
3028
+ ```
3029
+
3030
+ What arming each one costs, plainly:
3031
+
3032
+ - **`banditRerank`** — recall gains a payoff term capped at the same constant the reinforcement and
3033
+ SAFLA-delta terms use, so it reorders near-ties and can never overturn a decisive relevance gap.
3034
+ Similarity still decides WHICH lessons are candidates; the bandit only reorders WITHIN them, and it
3035
+ never adds a lesson similarity did not select. Deterministic (posterior mean, no sampling), so two
3036
+ identical queries give identical order. A lesson with no confirmations yet contributes exactly `0` —
3037
+ on day one the feature changes nothing, which is the deliberate price of refusing a random lift.
3038
+ - **`banditExploration`** — grants *unproven* lessons a bounded trial lift so they can accumulate
3039
+ evidence. This **weakens the view-does-not-promote posture** the store relies on, which is why it is a
3040
+ separate flag and ships off. Quarantined lessons are excluded from exploration in **every**
3041
+ configuration, and the auto-inject hook is untouched in all of them. `banditExploration` without
3042
+ `banditRerank` is a warned no-op.
3043
+
3044
+ An **exposure is not a reward**: merely seeing a lesson in a recall result is counted in its own channel
3045
+ and never moves the posterior. State lives in `.dz/lesson-bandit/state.json` behind a named lock, is pure
3046
+ derived data, and can be deleted at any time — you lose the learned posteriors, never a lesson.
3047
+
3048
+ ```bash
3049
+ dz recall "codex" --json # armed ⇒ a `{"bandit": …}` line on stderr: contextKey, armsConsidered
3050
+ # (the POST-cut list), quarantinedExcluded, unknownArms, moved, reason
3051
+ dz compounding # a bandit-health section: arms with measured payoff, reward events vs
3052
+ # exposure events, write errors, movedRate — INSUFFICIENT_DATA when empty
3053
+ ```
3054
+
3055
+ `moved` is the honest headline. `moved: 0` over many queries means the feature is armed and doing
3056
+ nothing — and none of these numbers claims the re-ranking is *better*: `moved` counts change, not
3057
+ improvement.
3058
+
3015
3059
  ### How to enable AgentDB
3016
3060
 
3017
3061
  ```bash
@@ -3118,12 +3162,18 @@ Drop an `architecture/project-skills.json` (no pipeline edits needed):
3118
3162
  "extra": [ { "skill": ".dz-skills/security-checklist/SKILL.md", "phase": "qe", "as": "guidance" } ] }
3119
3163
  ```
3120
3164
  ```bash
3121
- dz project-skills # who-injected report (which skill feeds which stage)
3122
- dz project-skills --json # the plan feature-adr Step 0 reads
3165
+ dz project-skills # who-injected report (which skill feeds which stage)
3166
+ dz project-skills --json # the plan feature-adr Step 0 reads
3167
+ dz project-skills --project /some/repo # read THAT repo's manifest, whatever your cwd is
3123
3168
  ```
3124
3169
  No manifest ⇒ a normal generic run (byte-identical). With one, feature-adr folds each skill into its stage as guidance
3125
3170
  (`product-vision`→design+QE, `critic`→QE, `brand`→code).
3126
3171
 
3172
+ `--project <dir>` names the root explicitly. Until harness-cli 0.7.9 the command read the manifest from **cwd only**,
3173
+ so a feature-adr run whose target repo is a separate checkout probed the wrong place, found nothing, and quietly fell
3174
+ back to a generic run — no error, just missing project guidance in every stage. Step 0 now probes the target repo first
3175
+ and falls back to the workspace, so a manifest is found wherever it actually lives.
3176
+
3127
3177
  ### `dz mr-rakes` — when you want to learn what mistakes this project keeps repeating
3128
3178
 
3129
3179
  Run it once you have a few reviews (feature-adr QE reports / MR reviews) to mine the **recurring** rakes:
@@ -4096,7 +4146,7 @@ npx @dzhechkov/p-replicator init
4096
4146
 
4097
4147
  ## Status
4098
4148
 
4099
- `v0.7.7` — **the observability pass, and one new verb.** `dz feature-adr-record --backfill` fills the
4149
+ `v0.7.8` — **the observability pass, one new verb, and a publisher that stops rewriting history.** `dz feature-adr-record --backfill` fills the
4100
4150
  run-cost ledger from the host's own workflow record — dry-run by default, `--yes` writes atomically.
4101
4151
  A derived number is MARKED (`filledFrom`/`filledBy`), a number you typed is never overwritten and any
4102
4152
  disagreement is reported, and every unfillable row comes back NAMED rather than silently skipped.
@@ -4111,12 +4161,17 @@ Ledger rows now carry a join key at all: the sandboxed workflow cannot know its
4111
4161
  unambiguous — and stamps it as `runIdSource: 'resolved-at-write'`, because a resolved id is an
4112
4162
  inference and not something the pipeline knew.
4113
4163
 
4164
+ `dz publish` stops relabelling old changelog entries. Keeping the README footer in lock-step with
4165
+ the bump was done by replacing every occurrence of the outgoing version, which rewrote the heading
4166
+ documenting what that release contained — four headings in one shipped README had collapsed onto one
4167
+ version. Entry-shaped lines are now left alone; footers and install examples still move.
4168
+
4114
4169
  `dz feature-adr-checkpoint` stamps the write instant, so "how long did this stage take" becomes
4115
4170
  answerable for every future run. `dz doctor` reports AQE store integrity from a log that had 1508
4116
4171
  rows and no readers. `dz score` gains an `observability-declared` discipline: does the architecture
4117
4172
  artifact say how anyone would know this feature works? Descriptive, never a gate.
4118
4173
 
4119
- `v0.7.7` — **`dz drift-check` and `dz sync-canonical` stop being a `.claude/skills` gate.** Skill-copy
4174
+ `v0.7.6` — **`dz drift-check` and `dz sync-canonical` stop being a `.claude/skills` gate.** Skill-copy
4120
4175
  discovery searched `packages/` plus one hardcoded install root, so the four other per-target install
4121
4176
  trees were ungated — measurably: this repo's own Codex install of `feature-adr` under `.agents/skills`
4122
4177
  drifted for a day while `dz sync-canonical feature-adr --check` reported "all 3 copies match
@@ -4130,7 +4185,7 @@ written by `dz init --enrich` is exempt from both the drift verdict and the heal
4130
4185
  cannot delete it. Also: `dz tg-post` gains `--max-per-day`, previously read by the code but
4131
4186
  unregistered.
4132
4187
 
4133
- `v0.7.7` — **the channel sender stops trusting itself.** `dz tg-post` could format-check, provenance-check
4188
+ `v0.7.6` — **the channel sender stops trusting itself.** `dz tg-post` could format-check, provenance-check
4134
4189
  and time-check a post and still publish it twice, or ten more times, or right through an operator who
4135
4190
  wanted everything stopped: nothing counted what had already gone out. It now runs three guards FAIL-CLOSED
4136
4191
  in a fixed order — a **stop-cord** file that halts even a perfect post before any cheaper check, **dedup**
@@ -4144,7 +4199,7 @@ and never inferred from its shape. Also: `dz challenge` is now discoverable from
4144
4199
  (it existed and was reachable only if you already knew the name), and the adversary it assembles is fed all
4145
4200
  five calibration documents rather than a subset.
4146
4201
 
4147
- `v0.7.7` — **a signature-only republish.** `0.7.0` shipped through `pnpm publish` rather than
4202
+ `v0.7.5` — **a signature-only republish.** `0.7.0` shipped through `pnpm publish` rather than
4148
4203
  `dz publish`, so the re-signing step was skipped and 17 of 497 files in the published core did not
4149
4204
  match their signed hashes — the content was correct, the manifest was ten hours stale. Nothing in
4150
4205
  the shipped behaviour changes between `0.7.0` and `0.7.7`; the integrity check stops reporting these
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -18,7 +18,7 @@ import { createSkill, getSkillInfo, listSkillsDetailed, formatSkillLoadFailures,
18
18
  // dz workflow run (feature dz-workflow-run): the pure scheduler + the dispatch adapters.
19
19
  TRACE_RUNID_RE, WF_RUN_OWNER_HOST, preflight, runWorkflow, makeClaudePDispatcher, makeCodexExecDispatcher, NamedLockTimeoutError, NamedLockCompromisedError, POLICY_SOURCES, detectPolicyDrift, hasPolicyFence, TARGET_NAMES, buildParityMatrix, downgradeForStaleEvidence, findStaleTranscriptEvidence, TARGET_CAPABILITIES, TARGET_SHORT_LABELS, WORKFLOW_TEMPLATES_RETIRED_MESSAGE, parsePlan, isParseErrors, validatePlan, normalizePlan, planDigest, toTraceProjection, renderPlan, mergeRender, lint, lintExitCode, LOOP_BLOBS, parseTrace, assembleTimeline, runInvariants, deriveAttestation, stampAttestation, corroborate, NOT_WITNESSED, renderTimelineHtml, 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, deriveCostLedger, planLedgerBackfill, listCostLedgerRuns, resolveLedgerRunId, AMBIGUOUS, stampCheckpointLine, LEDGER_FILL_SOURCE, renderCostLedger, verifyCostLedgerReport, writeCostLedgerJsonl, COST_LEDGER_SCOPE, deriveUsageCalibration, normalizeClaudeUsageModelKey, readUsageLimits, parseWeeklyResetAnchor, claimCheck, summarize, queryBookKnowledge, loadStorePatternsSync, patternRecordId, loadStoreRecords, recordToPattern, bundleSkills, brainHome, listBrain, bookKbPath, promoteProjectToBrain, updateBrainSource, queryBrain, groundPrompt, expandKu, reindexBrainVectors, buildPrimer, exportBrainSlice, importBrainSlice, registerKusToBrain, RECALL_USAGE_LOG_RELATIVE, RECALL_USAGE_LOG_MAX_BYTES, parseRecallUsageLog, buildRecallUsageReport, EVENT_CHAIN_TAIL_BYTES, EMPTY_LOG_TAIL, readTailInfo, appendChainedLines, verifyEventChainText, buildManifest, buildSbom, resolveTrustRoot, decideVerifyPolicy, generateSigningKeypair, evaluateGuard, resolveRules, auditRecord, guardExitCode, DEFAULT_RULES, parsePnpmLockImporters, scannableStubPath,
20
20
  // guard-promotion (feature guard-promotion, scout idea #1)
21
- assembleCandidates, renderPromotionReport, renderPromotionAdr, normalizePromotionState, nextPromotionState, globMatch, promotionAdrRelPath, DEFAULT_WINDOW_DAYS, DEFAULT_PERIODS, MAX_CONTENT_FETCHES, BUILTIN_COVERAGE, 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, classifyExecutionEvidence, pickAdversaryModel, CHALLENGE_QUESTIONS, loadOutcomes, renderOutcomes, statsForKey, selectAutoCost, recordProvisional, finalizeOutcome, harvestStageOutcomes, recommendModels, planFeed, GRADE_SUCCESS_FLOOR, COST_LADDER, splitScenarios, budgetPlan, selectWinner, proseScopeOk, renderProseDiff, readScenarioIds, DEFAULT_MAX_JUDGE_RUNS, collectDeliveryFacts, planDeliveryCheck, renderDeliveryBrief, classifyDelivery, isUsablePlaneResult, renderDeliveryReview, scanSkillsLayout, declaredPluginSurface, parseInitFacts, verifyRegistration, buildContentProbePrompt, classifyContentProbe, renderContentProbe, findNonRegistrableSkillDirs, assembleCompoundingReport,
21
+ assembleCandidates, renderPromotionReport, renderPromotionAdr, normalizePromotionState, nextPromotionState, globMatch, promotionAdrRelPath, DEFAULT_WINDOW_DAYS, DEFAULT_PERIODS, MAX_CONTENT_FETCHES, BUILTIN_COVERAGE, 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, classifyExecutionEvidence, pickAdversaryModel, CHALLENGE_QUESTIONS, loadOutcomes, renderOutcomes, statsForKey, selectAutoCost, recordProvisional, finalizeOutcome, harvestStageOutcomes, recommendModels, planFeed, GRADE_SUCCESS_FLOOR, COST_LADDER, splitScenarios, budgetPlan, selectWinner, proseScopeOk, renderProseDiff, readScenarioIds, DEFAULT_MAX_JUDGE_RUNS, collectDeliveryFacts, planDeliveryCheck, renderDeliveryBrief, classifyDelivery, isUsablePlaneResult, renderDeliveryReview, scanSkillsLayout, declaredPluginSurface, parseInitFacts, verifyRegistration, buildContentProbePrompt, classifyContentProbe, renderContentProbe, findNonRegistrableSkillDirs, assembleCompoundingReport, banditStats, narrowBanditReport, renderBanditHealth,
22
22
  // Cold-vs-warm EPOCH RUNNER (feature epoch-replay) — orchestrates + scores, never calls a model.
23
23
  replayableInstances, buildWorkOrder, buildJudgePrompts, unblindJudgments, verifyWorkOrder, isValidMargin, DIGEST_HONEST_SCOPE, scoreEpochReplay, generateMockOutcomes, renderEpochReplayResult, renderWorkOrderSummary, renderJudgePromptsSummary, WORK_ORDER_KIND, DEFAULT_MOCK_N, DEFAULT_MOCK_SEED, scoreRun, readQeGrade, recapWindow, decideHorizon, withinWindow, buildRecap, renderRecap, parseSourceManifest, tgPostHtmlIssues, tgVisibleLength, decideTgSend, TG_TEXT_LIMIT, countRecallEventsForRun, unknownFlagNotice, mirrorWriterExplanation, appendRecallUsage, closenessLine, anyAboveFloor, decideNameCheck, renderNameCheck, exportedNamesIn, dispatchedCommandsIn, decideSourceProvenance, renderSourceProvenance, REFUSED_HORIZONS, renderScorecard, renderCompoundingReport, readReinforcementState, readQuarantineState, registrationExitCode, renderRegistrationReport,
24
24
  // Smart Backlog (feature smart-backlog) — goal-directed idea pipeline over the Brain vector engine.
@@ -72,6 +72,11 @@ Usage:
72
72
  dz tg-post --draft <file.html> [--manifest <sources.json>] [--channel <@name|id>] [--send --yes] [--night] [--preview] [--json] (the sender for an APPROVED channel post, per the accepted genai-tweets-channel ADRs: HTML mode only — never MarkdownV2; link preview OFF by default (x.com previews in Telegram are broken); the 00:00-06:00 MSK quiet window refuses without an explicit --night. DEFAULT IS A DRY-RUN: it validates the draft (tag balance, allowed tags, bare &/<, the 4096 visible-character limit with the overshoot counted) and runs the provenance gate over --manifest IN-PROCESS — a draft with no manifest is refused as unchecked, and anything but ALLOWED refuses. A real send needs --send --yes, stating ADR-004's manual-publishing decision out loud each time. The token comes from TELEGRAM_BOT_TOKEN or telegram.tokenFile in .dz/config.json and is never printed. exit 0 sent or clean dry-run / 1 refused or Telegram error / 2 usage)
73
73
  dz name-check [--command <n>] [--module <basename>] [--export <a,b>] [--project <dir>] [--json] (is this name free, BEFORE a line of code? Scans workspace SOURCE — never dist, because a stale build answers 'free' confidently. Checks a dz command name against the dispatcher AND the help block, a module basename against every package's src/, and exported identifiers against every declaration in the workspace. exit 0 all free / 1 at least one taken, naming where / 2 nothing asked or the scan did not run — 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)
74
74
  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 names its source, and only a KNOWN kind that resolves safely is cleared. Repo paths go through 'git -C <root> check-ignore' over the RESOLVED path — a symlink into an ignored directory is REFUSED (git classifies the string and never dereferences, MEASURED), and the verdict does not change with your working directory. Store records must be named in the git-TRACKED provenance-public.json, so declaring one public is a reviewable commit rather than a field inside an ignored store. An undeclared kind is refused, 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. It proves what was CITED: it cannot see a paraphrase with no citation, nor confidential text pasted by hand into an allowed file)
75
+ dz project-skills [--project <dir>] [--json] [--stages-json] (polymorphic feature-adr: resolve architecture/project-skills.json — fixed roles product-vision/critic/brand/impl-bar plus an open extra[] — into per-stage guidance. READ-ONLY. --project names the root explicitly, so it works from any cwd; without it the manifest is read from the current repo. No manifest ⇒ a byte-identical generic run)
76
+ dz discrimination-check --slug <slug> [--base <ref>] [--json] (does the ADR's named test actually DISCRIMINATE? Re-runs it on a worktree at the pre-feature commit, where it MUST go red. A test that passes with the feature removed proves nothing; dz amendment-check proves the test exists, this proves it bites)
77
+ dz guard [check|promote|init] [--json] [--force] (HARD/SOFT repo rules — readme-first, lockfile-in-sync, claim tagging — run automatically as a pre-flight inside dz publish. HARD blocks, SOFT warns)
78
+ dz architecture [--check --slug <s> --desc <text>] [--project <dir>] [--revise] (the live product map + vision: --check is the soft Step-0 сверка of a new feature against them, reporting {signal,confidence} rather than blocking)
79
+ dz sbom [--pack <name>] [--out <file>] (CycloneDX software bill of materials for the workspace, or for one pack with --pack)
75
80
  dz amendment-check --slug <slug> | --feature-dir <dir> | --all [--json] (the deterministic Step-8 amendment gate: every AM-N 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. exit 0 pass/skip, 1 fail, 3 NOT-ESTABLISHED — a section that parsed ZERO rows is never a pass. --all is a CENSUS and always exits 0. Does NOT prove non-vacuity — that is dz discrimination-check)
76
81
  dz feature-adr-record --kind ledger|training-pair --stage <s> [--slug <s>] [--row|--pair <json>] [--mark <n>] [--once] [--json] (the witnessed writer for the run-cost ledger and training pairs: the payload arrives as an ARGUMENT, never as shell; a malformed or wrong-kind payload is REFUSED before any write; the timestamp is stamped before serialising; the append is verified by re-reading the tail. exit 0 written|duplicate|skipped, 2 refused, 3 not-verified — a record failure is never blocking)
77
82
  dz feature-adr-checkpoint (--slug <feature> | --feature-dir <abs>) --stage <s> --input-hash <h> --result <json> [--artifact a,b] [--json] (record a pipeline stage ONLY after measuring its artifacts on disk; refuses a null result, an absent artifact, or a stage that declares none — the subagent runs a COMMAND instead of hand-writing durable state)
@@ -3054,8 +3059,8 @@ async function cmdRecall(options, flags, cwd, write) {
3054
3059
  // second occurrence. Foreign stdout is routed to stderr for the duration of the engine call — our
3055
3060
  // own output is written after it returns.
3056
3061
  const result = asJson
3057
- ? await withForeignStdoutOnStderr(() => recallHybrid(projectRoot, query, { limit: fetchLimit, mode }))
3058
- : await recallHybrid(projectRoot, query, { limit: fetchLimit, mode });
3062
+ ? await withForeignStdoutOnStderr(() => recallHybrid(projectRoot, query, { limit: fetchLimit, mode, deferExposures: true, ...(wantedDomain !== undefined ? { domain: wantedDomain } : {}) }))
3063
+ : await recallHybrid(projectRoot, query, { limit: fetchLimit, mode, deferExposures: true, ...(wantedDomain !== undefined ? { domain: wantedDomain } : {}) });
3059
3064
  if (mode === 'semantic' && result.vectorEngine === 'none') {
3060
3065
  // --semantic is an explicit ask — degrading it silently would be dishonest (FR-3).
3061
3066
  const why = result.vectorReason ?? 'no vector engine available — run: dz setup --memory agentdb';
@@ -3086,6 +3091,22 @@ async function cmdRecall(options, flags, cwd, write) {
3086
3091
  // "foreign-domain lessons kept" about the pre-cut list while the printed list was
3087
3092
  // missing one. Count it and say so; the reader can act on it (raise --limit).
3088
3093
  const displaced = boost !== null ? countDisplacedByCut(result.hits, boost.hits, limit) : 0;
3094
+ // lesson-bandit-rerank FR-8/AC-11: the bandit block must describe the POST-cut list the reader
3095
+ // actually sees. `dz recall` over-fetches under --domain and truncates AGAIN here, so reporting
3096
+ // the core's own (already post-merge-cut) count would still describe a list one cut too early.
3097
+ // ABSENT while disarmed — its presence is what tells a reader the feature ran.
3098
+ const shownDzIds = hits.map((h) => patternRecordId(h.pattern));
3099
+ const banditBlock = result.bandit === undefined
3100
+ ? undefined
3101
+ : narrowBanditReport(result.bandit, shownDzIds);
3102
+ // Exposures were DEFERRED (`deferExposures: true`) precisely so this cut happens first: `dz recall`
3103
+ // over-fetches under --domain and truncates again here, and counting an over-fetched hit as "seen"
3104
+ // both inflates the health metrics and mislabels a candidate the reader never laid eyes on.
3105
+ result.commitExposures?.(shownDzIds);
3106
+ const renderBanditNote = (b) => ` ℹ bandit payoff: ${b.moved} of ${b.armsConsidered} shown hit(s) moved (ctx ${b.contextKey}` +
3107
+ `, ${b.unknownArms} with no measured payoff yet, ${b.quarantinedExcluded} quarantined excluded` +
3108
+ `${b.exploration ? `, exploration ON — ${b.explored} trial impression(s)` : ''}` +
3109
+ `${b.reason !== null ? `, state ${b.reason}` : ''})`;
3089
3110
  if (asJson) {
3090
3111
  // Portable contract UNCHANGED (I-7/AC-6): a plain PatternRecord[] — round-trips through
3091
3112
  // `dz teach --from-json` regardless of which backend ranked each hit.
@@ -3117,6 +3138,11 @@ async function cmdRecall(options, flags, cwd, write) {
3117
3138
  if (cutNoteJson !== '')
3118
3139
  process.stderr.write(`${cutNoteJson}\n`);
3119
3140
  }
3141
+ // STDERR, not stdout: `--json`'s stdout contract is a plain PatternRecord[] that round-trips
3142
+ // through `dz teach --from-json`, and wrapping it in an object to make room for one report
3143
+ // would break every existing consumer. The block travels beside the other honesty notes.
3144
+ if (banditBlock !== undefined)
3145
+ process.stderr.write(`${JSON.stringify({ bandit: banditBlock })}\n`);
3120
3146
  return semanticUnserved ? 1 : 0;
3121
3147
  }
3122
3148
  if (hits.length === 0) {
@@ -3216,6 +3242,12 @@ async function cmdRecall(options, flags, cwd, write) {
3216
3242
  // The loop stays VISIBLE (ADR D2): a quarantined hit is shown, marked, and explained.
3217
3243
  write(' ⚠q = quarantined (unproven hypothesis, rank damped) — confirm with dz teach --reinforce, or dz recall --promote <dzId> --apply');
3218
3244
  }
3245
+ if (banditBlock !== undefined) {
3246
+ // Say what the payoff term did — INCLUDING when it did nothing. `moved: 0` over many queries
3247
+ // means the feature is armed and inert, which is precisely the outcome nobody would notice
3248
+ // without this line.
3249
+ write(renderBanditNote(banditBlock));
3250
+ }
3219
3251
  if (boost !== null && shownDomain !== undefined) {
3220
3252
  // Say what the boost did — INCLUDING when it did nothing. A silent reorder would
3221
3253
  // let the reader believe the ranking was domain-aware when it had no match to work with.
@@ -7597,12 +7629,17 @@ async function cmdDownloads(cwd, write) {
7597
7629
  * The pure engine lives in harness-core; this is the thin I/O shell (scan disk + git, render).
7598
7630
  */
7599
7631
  function cmdArchitecture(options, flags, cwd, write) {
7600
- // Resolve repo root: prefer git toplevel, fall back to cwd (matches cmdRoam / cmdStats duality).
7601
- let repoRoot = cwd;
7632
+ // Resolve repo root: an explicit --project wins, then git toplevel, then cwd (matches cmdRoam /
7633
+ // cmdStats duality). The --project leg is the same fix as cmdProjectSkills got for field report
7634
+ // doc-25b, applied to its neighbour before it costs a second report: this command also reads an
7635
+ // `architecture/` tree, and on a feature-adr run against a target checkout the Step-0 product-vision
7636
+ // сверка silently no-ops for exactly that reason.
7637
+ const explicitRoot = (options.get('project') ?? '').trim();
7638
+ let repoRoot = explicitRoot !== '' ? resolve(cwd, explicitRoot) : cwd;
7602
7639
  try {
7603
- repoRoot = execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8' }).trim() || cwd;
7640
+ repoRoot = execSync('git rev-parse --show-toplevel', { cwd: repoRoot, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim() || repoRoot;
7604
7641
  }
7605
- catch { /* not a git repo — use cwd */ }
7642
+ catch { /* not a git repo — use the root as given */ }
7606
7643
  const manifest = loadSubsystemManifest(repoRoot);
7607
7644
  if (!manifest) {
7608
7645
  write('dz architecture: architecture/subsystems.manifest.json not found — run from the repo root.');
@@ -7640,12 +7677,22 @@ function cmdArchitecture(options, flags, cwd, write) {
7640
7677
  * --stages-json { hasManifest, design, code, qe, report } — ready to thread into prompts
7641
7678
  * No manifest ⇒ empty guidance strings ⇒ byte-identical run (FR-7).
7642
7679
  */
7643
- function cmdProjectSkills(flags, cwd, write) {
7644
- let repoRoot = cwd;
7680
+ function cmdProjectSkills(options, flags, cwd, write) {
7681
+ // `--project <dir>` names the root EXPLICITLY. Until 2026-08-25 this command took only `cwd`, so
7682
+ // the manifest was reachable exclusively from the workspace you happened to stand in — and because
7683
+ // the known-flag list is deliberately FLAT, `--project` passed validation on a command that never
7684
+ // read it: exit 0, no warning, no manifest. MEASURED that day: a feature-adr run against a target
7685
+ // repo probed with `cd REPO`, found nothing, and fell open to a generic run — the honest
7686
+ // `polymorphism:null` was recorded and not one project lens reached any stage.
7687
+ const explicitRoot = (options.get('project') ?? '').trim();
7688
+ let repoRoot = explicitRoot !== '' ? resolve(cwd, explicitRoot) : cwd;
7645
7689
  try {
7646
- repoRoot = execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8' }).trim() || cwd;
7690
+ // stderr is SWALLOWED: a non-repo directory is an ordinary case here, and letting git print
7691
+ // "fatal: not a git repository" onto the operator's terminal made a working command look broken.
7692
+ // The sibling cmdFeatureAdrSetup already redirects; this one did not.
7693
+ repoRoot = execSync('git rev-parse --show-toplevel', { cwd: repoRoot, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim() || repoRoot;
7647
7694
  }
7648
- catch { /* not a git repo — use cwd */ }
7695
+ catch { /* not a git repo — use the root as given */ }
7649
7696
  const plan = planProjectSkills(repoRoot);
7650
7697
  const hasManifest = plan.injections.length > 0 || plan.skipped.length > 0;
7651
7698
  if (flags.has('stages-json')) {
@@ -11772,10 +11819,15 @@ function cmdCompounding(options, flags, cwd, write) {
11772
11819
  }
11773
11820
  }
11774
11821
  const report = assembleCompoundingReport({ lessons, usage, guard, nowTs: new Date().toISOString(), evidenceLogs });
11822
+ // lesson-bandit-rerank §11: the payoff axis joins THIS report rather than growing a private
11823
+ // dashboard — the `rewardEvents : exposureEvents` row asks exactly the question this command
11824
+ // already asks of the reinforcement loop (is the apply leg alive, or is it a write-only log?).
11825
+ // Read-only, and INSUFFICIENT_DATA on an absent state file — never a fake verdict.
11826
+ const bandit = banditStats(root);
11775
11827
  if (json)
11776
- write(JSON.stringify({ ...report, exitCode: 0 }, null, 2));
11828
+ write(JSON.stringify({ ...report, bandit, exitCode: 0 }, null, 2));
11777
11829
  else
11778
- write(renderCompoundingReport(report));
11830
+ write(`${renderCompoundingReport(report)}\n\n${renderBanditHealth(bandit)}`);
11779
11831
  return 0;
11780
11832
  }
11781
11833
  // ── `dz epoch-replay` (feature epoch-replay) ────────────────────────────────────────────────────
@@ -13511,7 +13563,7 @@ export async function runCli(argv, io = {}) {
13511
13563
  case 'architecture':
13512
13564
  return cmdArchitecture(options, flags, cwd, write);
13513
13565
  case 'project-skills':
13514
- return cmdProjectSkills(flags, cwd, write);
13566
+ return cmdProjectSkills(options, flags, cwd, write);
13515
13567
  case 'mr-rakes':
13516
13568
  return await cmdMrRakes(options, flags, cwd, write);
13517
13569
  case 'retro':