@dzhechkov/harness-cli 0.3.222 → 0.3.224
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/README.md +62 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +126 -1
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
- package/src/cli.ts +131 -0
package/README.md
CHANGED
|
@@ -431,7 +431,7 @@ Get the whole set with `dz init --target claude-code --preset meta`, or pick one
|
|
|
431
431
|
|
|
432
432
|
> **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.
|
|
433
433
|
|
|
434
|
-
## All Commands (
|
|
434
|
+
## All Commands (50)
|
|
435
435
|
|
|
436
436
|
```
|
|
437
437
|
dz setup --target <name> [--preset <name>] [--select id,id,...] [--skills-dir <dir>] [--memory agentdb] [--no-memory] [--no-hooks] [--install-driver] [--force]
|
|
@@ -482,6 +482,8 @@ dz project-skills [--json] [--stages-json] # polymorphic feature-adr: resol
|
|
|
482
482
|
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)
|
|
483
483
|
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
|
|
484
484
|
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)
|
|
485
|
+
dz challenge --plan <plan.md> [--json] [--context-only] [--author <model>] # adversarial plan-gate (behind the `challenge-panel` skill): assemble a WIDE context pack (plan + vision + testing + map + degradations) + the fixed C1-C8 "break it" brief for a FRESH adversary (≠ plan author); advisory, never blocks
|
|
486
|
+
dz routing [--stage <s>] [--json] # inspect the learned cost-optimal routing store: what `args.models.<stage>='auto-cost'` believes per (stage, complexity-tier, model) — gated attempts/successes/rate (feeds feature-adr model selection)
|
|
485
487
|
dz publish [--filter <name>] [--bump-only] [--claim-check <off|warn|error>] (dry-run by default; pass --yes/--confirm to go live; claim-check gate defaults to warn — surfaces README claim findings, never blocks)
|
|
486
488
|
dz auto-canonicalize --source <github-url> --pack <skills-pack>
|
|
487
489
|
dz sync-upstream [--package <dir>] [--list] [--all]
|
|
@@ -1429,6 +1431,65 @@ retro: 2 recurring rake(s) to drill (from 6800 events):
|
|
|
1429
1431
|
First-seen rakes accrue silently; only **recurring** ones get a drill (no nagging on a one-off). The user gets the
|
|
1430
1432
|
drill, the agent gets the taught rule — from the same mistake, out of one shared `dz teach` store.
|
|
1431
1433
|
|
|
1434
|
+
### `dz challenge` — when you have an implementation plan and want it broken BEFORE you code
|
|
1435
|
+
|
|
1436
|
+
The cross-model QE at feature-adr Step 8 catches problems *after* the code is written. The most expensive plan
|
|
1437
|
+
mistakes — overengineering, silent decisions, cemented bad patterns, test-theater, unrealistic scope — cement at
|
|
1438
|
+
the plan stage, and the plan's author can't see their own gaps. `dz challenge` assembles the "round"; the
|
|
1439
|
+
`challenge-panel` skill fires it at a FRESH adversary that did **not** write the plan:
|
|
1440
|
+
```bash
|
|
1441
|
+
dz challenge --plan features/my-feature/06_implementation_plan.md # print the WIDE brief + C1-C8 + verdict schema
|
|
1442
|
+
dz challenge --plan features/my-feature/06_implementation_plan.md --context-only # just what the panel will read + the adversary to use
|
|
1443
|
+
dz challenge --plan features/my-feature/06_implementation_plan.md --author codex # who wrote the plan → prints the CROSS-family adversary
|
|
1444
|
+
```
|
|
1445
|
+
```
|
|
1446
|
+
challenge context for features/my-feature/06_implementation_plan.md:
|
|
1447
|
+
plan: ✓ 23752 chars
|
|
1448
|
+
vision: ✓ 2443 chars
|
|
1449
|
+
testing: ✗ (less calibration)
|
|
1450
|
+
map: ✓ 4470 chars
|
|
1451
|
+
degradations:✓ 719 chars
|
|
1452
|
+
→ adversary: codex — plan authored on claude (Claude) → Codex adversary (cross-family)
|
|
1453
|
+
```
|
|
1454
|
+
The panel asks a fixed owner-question set in "break it, don't confirm it" mode — **C1** arch-anti-cement (a
|
|
1455
|
+
deviation from a pattern in `architecture/degradations.md` is *not* flagged), **C2** prod-ready, **C3** test
|
|
1456
|
+
sufficiency + honesty (both under- and over-testing), **C4** overengineering, **C5** silent decisions, **C6**
|
|
1457
|
+
runtime consistency, **C7** scope, **C8** executability. Every P0/P1 finding is **cross-validated** by a second
|
|
1458
|
+
independent agent (theory is dropped), and the verdict is **advisory — it never auto-blocks**. Two invariants:
|
|
1459
|
+
the panel is never the plan's own author (cross-family adversary), and the context pack is WIDE (a narrow slice
|
|
1460
|
+
yields shallow findings). In the feature-adr pipeline this runs automatically at the L/XL plan checkpoint; ad-hoc,
|
|
1461
|
+
just say **"прогони challenge на этот план"** / **"challenge this plan"**. Scaffold the degradations registry with
|
|
1462
|
+
`dz feature-adr-setup --from-spec <spec with {"degradations":true}> --apply`.
|
|
1463
|
+
|
|
1464
|
+
### `dz routing` — when you want feature-adr to LEARN which model is worth paying for
|
|
1465
|
+
|
|
1466
|
+
feature-adr can route a stage to a fixed model (`args.models.code='opus'`), but you may not know which model is
|
|
1467
|
+
actually worth it. The **`auto-cost`** spec learns from real outcomes: it picks the **cheapest** model whose
|
|
1468
|
+
learned success-rate is **≥0.7** at `(stage, complexity-tier)`, and a model whose code later **fails the Step-8
|
|
1469
|
+
QE gate is down-ranked** (success is *passing the gate*, not "returned something"). Grounded in rUv's shipped
|
|
1470
|
+
`MetaHarnessRouter`. Turn it on per stage:
|
|
1471
|
+
```js
|
|
1472
|
+
Workflow({ scriptPath: '.claude/workflows/feature-adr.js',
|
|
1473
|
+
args: { slug, description, tier: 'L', models: { code: 'auto-cost', qe: 'auto-cost' } } })
|
|
1474
|
+
```
|
|
1475
|
+
```bash
|
|
1476
|
+
dz routing # the learned table — what auto-cost currently believes
|
|
1477
|
+
dz routing --stage code # just the code stage
|
|
1478
|
+
dz routing --json # raw store (.dz/routing-outcomes.json)
|
|
1479
|
+
```
|
|
1480
|
+
```
|
|
1481
|
+
Learned routing outcomes (what `auto-cost` currently believes):
|
|
1482
|
+
|
|
1483
|
+
## code
|
|
1484
|
+
L sonnet 100% (4/4 gated, 4 provisional)
|
|
1485
|
+
L opus 60% (3/5 gated)
|
|
1486
|
+
```
|
|
1487
|
+
Cold-start (no history) walks a cheapest-first chain and escalates on failure; once a model clears the bar it is
|
|
1488
|
+
chosen directly. Two invariants held hard: `auto-cost` on the **qe** stage only ever ranks the **cross-family of
|
|
1489
|
+
the coder** (a model never self-QEs), and the whole thing is **opt-in** — with no `auto-cost` spec anywhere the
|
|
1490
|
+
pipeline is byte-identical and the store is never touched. Layered under the usage-adaptive override (a session
|
|
1491
|
+
near its limit still switches to Codex first). Storage is a plain JSON file — zero native deps.
|
|
1492
|
+
|
|
1432
1493
|
## Recipes & FAQ
|
|
1433
1494
|
|
|
1434
1495
|
Scenario → exact command → how to verify → gotcha. **Three gotchas worth calling out up front:**
|
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;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkOH,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;CACzB;AAk8ID,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,KAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAoI5E"}
|
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
9
9
|
import { execSync } from 'node:child_process';
|
|
10
10
|
import { homedir } 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, WORKFLOW_NAMES, importEcc, recordPattern, resolveLearningBackend, storeStats, consolidateSessions, pruneNoisePatterns, lessonDeltaReport, removePatternsByIds, snapshotStore, recallHybrid, teachGuard, mirrorPatternsToVector, 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, decideProvenance, isInsideTree, signManifest, verifyManifest, assertKeyOutsideTree, decidePublishGate, 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, } 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, WORKFLOW_NAMES, importEcc, recordPattern, resolveLearningBackend, storeStats, consolidateSessions, pruneNoisePatterns, lessonDeltaReport, removePatternsByIds, snapshotStore, recallHybrid, teachGuard, mirrorPatternsToVector, 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, decideProvenance, isInsideTree, signManifest, verifyManifest, assertKeyOutsideTree, decidePublishGate, 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, pickAdversaryModel, CHALLENGE_QUESTIONS, loadOutcomes, renderOutcomes, statsForKey, selectAutoCost, recordProvisional, finalizeOutcome, COST_LADDER, } 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
|
|
@@ -4182,6 +4182,13 @@ function cmdFeatureAdrSetup(options, flags, cwd, write) {
|
|
|
4182
4182
|
if (f.action === 'unchanged')
|
|
4183
4183
|
continue; // never clobber
|
|
4184
4184
|
const abs = resolve(repoRoot, f.path);
|
|
4185
|
+
// Write-boundary augment-never-clobber guard (defense in depth): a 'create' must NEVER overwrite an
|
|
4186
|
+
// existing file, even if the plan (built from a caller-supplied `existing`) said create. 'augment' has
|
|
4187
|
+
// already union-merged the prior content, so overwriting there is the merged result, not a clobber.
|
|
4188
|
+
if (f.action === 'create' && existsSync(abs)) {
|
|
4189
|
+
write(` · skipped ${f.path} — already exists (not overwritten)`);
|
|
4190
|
+
continue;
|
|
4191
|
+
}
|
|
4185
4192
|
try {
|
|
4186
4193
|
mkdirSync(dirname(abs), { recursive: true });
|
|
4187
4194
|
writeFileSync(abs, f.content);
|
|
@@ -4195,6 +4202,120 @@ function cmdFeatureAdrSetup(options, flags, cwd, write) {
|
|
|
4195
4202
|
write(`\n↳ wrote ${wrote} file(s). Verify: dz project-skills + dz architecture --revise`);
|
|
4196
4203
|
return 0;
|
|
4197
4204
|
}
|
|
4205
|
+
/**
|
|
4206
|
+
* `dz challenge` — the deterministic "cartridge" behind the `challenge-panel` adversarial plan-gate (R6).
|
|
4207
|
+
* Assembles a WIDE context pack (plan + vision + testing + map + degradations) and prints the fixed C1-C8
|
|
4208
|
+
* "break it, don't confirm it" brief + the verdict schema. It runs NO LLM and writes nothing — the
|
|
4209
|
+
* `challenge-panel` SKILL fires the brief at a FRESH adversary (a model ≠ the plan author) + a mandatory
|
|
4210
|
+
* cross-validator. ADVISE, never block.
|
|
4211
|
+
* --plan <plan.md> the plan under review (required)
|
|
4212
|
+
* --json emit the assembled context + brief as JSON
|
|
4213
|
+
* --context-only just the assembled context summary (what the panel will read)
|
|
4214
|
+
* --author <model> the plan-author model → prints the cross-family adversary to dispatch (FR-4)
|
|
4215
|
+
*/
|
|
4216
|
+
function cmdChallenge(options, flags, cwd, write) {
|
|
4217
|
+
let repoRoot = cwd;
|
|
4218
|
+
try {
|
|
4219
|
+
repoRoot = execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8' }).trim() || cwd;
|
|
4220
|
+
}
|
|
4221
|
+
catch { /* not git */ }
|
|
4222
|
+
const planPath = options.get('plan');
|
|
4223
|
+
if (planPath === undefined) {
|
|
4224
|
+
write('dz challenge: pass --plan <plan.md> (the implementation plan to challenge).');
|
|
4225
|
+
return 1;
|
|
4226
|
+
}
|
|
4227
|
+
const ctx = assembleChallengeContext(repoRoot, planPath);
|
|
4228
|
+
if (ctx.plan === '') {
|
|
4229
|
+
write(`dz challenge: plan not found or empty: ${planPath}`);
|
|
4230
|
+
return 1;
|
|
4231
|
+
}
|
|
4232
|
+
const adversary = pickAdversaryModel(options.get('author') ?? 'claude');
|
|
4233
|
+
if (flags.has('json')) {
|
|
4234
|
+
write(JSON.stringify({ context: ctx, brief: buildChallengeBrief(ctx), adversary, questions: CHALLENGE_QUESTIONS }, null, 2));
|
|
4235
|
+
return 0;
|
|
4236
|
+
}
|
|
4237
|
+
if (flags.has('context-only')) {
|
|
4238
|
+
const has = (v) => (v === undefined ? '✗ (less calibration)' : `✓ ${v.length} chars`);
|
|
4239
|
+
write(`challenge context for ${planPath}:`);
|
|
4240
|
+
write(` plan: ✓ ${ctx.plan.length} chars`);
|
|
4241
|
+
write(` vision: ${has(ctx.vision)}`);
|
|
4242
|
+
write(` testing: ${has(ctx.testing)}`);
|
|
4243
|
+
write(` map: ${has(ctx.map)}`);
|
|
4244
|
+
write(` degradations:${has(ctx.degradations)}`);
|
|
4245
|
+
write(` → adversary: ${adversary.model} — ${adversary.note}`);
|
|
4246
|
+
return 0;
|
|
4247
|
+
}
|
|
4248
|
+
write(buildChallengeBrief(ctx));
|
|
4249
|
+
write(`\n── dispatch (panel ≠ plan author) ──\n${adversary.model}: ${adversary.note}`);
|
|
4250
|
+
return 0;
|
|
4251
|
+
}
|
|
4252
|
+
/**
|
|
4253
|
+
* `dz routing` — inspect the learned cost-optimal routing outcome store (feature learned-cost-routing). Shows
|
|
4254
|
+
* what `args.models[stage]='auto-cost'` currently believes per (stage, complexity-tier, model): gated
|
|
4255
|
+
* attempts / successes / rate. Read-only.
|
|
4256
|
+
* --stage <s> filter to one pipeline stage (code, qe, plan, …)
|
|
4257
|
+
* --json raw store JSON
|
|
4258
|
+
*/
|
|
4259
|
+
function cmdRouting(options, flags, cwd, write) {
|
|
4260
|
+
let repoRoot = cwd;
|
|
4261
|
+
try {
|
|
4262
|
+
repoRoot = execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8' }).trim() || cwd;
|
|
4263
|
+
}
|
|
4264
|
+
catch { /* not git */ }
|
|
4265
|
+
const stage = options.get('stage');
|
|
4266
|
+
const tier = options.get('tier');
|
|
4267
|
+
const model = options.get('model');
|
|
4268
|
+
// --select: resolve an `auto-cost` stage → the concrete model + escalate chain (the workflow shells out here
|
|
4269
|
+
// because it is sandboxed with no fs). --family restricts to the coder's cross-family (qe guard); --ladder is
|
|
4270
|
+
// the probe-filtered id set (account-specific Codex ids that answered).
|
|
4271
|
+
if (flags.has('select')) {
|
|
4272
|
+
if (!stage || !tier) {
|
|
4273
|
+
write('dz routing --select needs --stage and --tier');
|
|
4274
|
+
return 1;
|
|
4275
|
+
}
|
|
4276
|
+
const fam = options.get('family');
|
|
4277
|
+
const family = fam === 'claude' || fam === 'openai' ? fam : undefined;
|
|
4278
|
+
const ladderCsv = options.get('ladder');
|
|
4279
|
+
let ladder;
|
|
4280
|
+
if (ladderCsv !== undefined) {
|
|
4281
|
+
const ids = new Set(ladderCsv.split(',').map((s) => s.trim()).filter(Boolean));
|
|
4282
|
+
ladder = COST_LADDER.filter((r) => ids.has(r.id));
|
|
4283
|
+
}
|
|
4284
|
+
const statsFor = statsForKey(loadOutcomes(repoRoot), stage, tier);
|
|
4285
|
+
const pick = selectAutoCost(stage, tier, statsFor, { ...(family ? { family } : {}), ...(ladder ? { ladder } : {}) });
|
|
4286
|
+
write(JSON.stringify(pick));
|
|
4287
|
+
return 0;
|
|
4288
|
+
}
|
|
4289
|
+
// --record-provisional / --finalize: the two-phase outcome label. The workflow calls these at stage end
|
|
4290
|
+
// (provisional) and at the downstream gate (finalize, authoritative).
|
|
4291
|
+
if (flags.has('record-provisional')) {
|
|
4292
|
+
if (!stage || !tier || !model) {
|
|
4293
|
+
write('dz routing --record-provisional needs --stage --tier --model');
|
|
4294
|
+
return 1;
|
|
4295
|
+
}
|
|
4296
|
+
recordProvisional(repoRoot, stage, tier, model, flags.has('weak'));
|
|
4297
|
+
write(`recorded provisional: ${stage}/${tier}/${model}${flags.has('weak') ? ' (weak-credit)' : ''}`);
|
|
4298
|
+
return 0;
|
|
4299
|
+
}
|
|
4300
|
+
if (flags.has('finalize')) {
|
|
4301
|
+
if (!stage || !tier || !model) {
|
|
4302
|
+
write('dz routing --finalize needs --stage --tier --model --success <true|false>');
|
|
4303
|
+
return 1;
|
|
4304
|
+
}
|
|
4305
|
+
const success = options.get('success') === 'true';
|
|
4306
|
+
finalizeOutcome(repoRoot, stage, tier, model, success);
|
|
4307
|
+
write(`finalized: ${stage}/${tier}/${model} → ${success ? 'success' : 'FAILURE'}`);
|
|
4308
|
+
return 0;
|
|
4309
|
+
}
|
|
4310
|
+
// default / --json: inspect the learned table.
|
|
4311
|
+
const store = loadOutcomes(repoRoot);
|
|
4312
|
+
if (flags.has('json')) {
|
|
4313
|
+
write(JSON.stringify(store, null, 2));
|
|
4314
|
+
return 0;
|
|
4315
|
+
}
|
|
4316
|
+
write(renderOutcomes(store, stage));
|
|
4317
|
+
return 0;
|
|
4318
|
+
}
|
|
4198
4319
|
function cmdStats(cwd, write) {
|
|
4199
4320
|
const baseDir = join(cwd, 'packages', '@dzhechkov');
|
|
4200
4321
|
if (!existsSync(baseDir)) {
|
|
@@ -4452,6 +4573,10 @@ export async function runCli(argv, io = {}) {
|
|
|
4452
4573
|
return await cmdRetro(options, flags, cwd, write);
|
|
4453
4574
|
case 'feature-adr-setup':
|
|
4454
4575
|
return cmdFeatureAdrSetup(options, flags, cwd, write);
|
|
4576
|
+
case 'challenge':
|
|
4577
|
+
return cmdChallenge(options, flags, cwd, write);
|
|
4578
|
+
case 'routing':
|
|
4579
|
+
return cmdRouting(options, flags, cwd, write);
|
|
4455
4580
|
case 'dashboard':
|
|
4456
4581
|
return cmdDashboard(cwd, write);
|
|
4457
4582
|
case 'roam':
|