substrate-ai 0.21.16 → 0.21.18

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/dist/cli/index.js CHANGED
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
- import { FileKvStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createDatabaseAdapter, createDoltOperatorReader, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion } from "../health-CI8pIygU.js";
2
+ import { FileKvStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createDatabaseAdapter, createDoltOperatorReader, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion } from "../health-Bu5nYB6q.js";
3
3
  import { createLogger } from "../logger-KeHncl-f.js";
4
4
  import { createEventBus } from "../helpers-CElYrONe.js";
5
5
  import { AdapterRegistry, BudgetConfigSchema, CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, ConfigError, CostTrackerConfigSchema, DEFAULT_CONFIG, DoltClient, DoltNotInstalled, GlobalSettingsSchema, InMemoryDatabaseAdapter, IngestionServer, MonitorDatabaseImpl, OPERATIONAL_FINDING, PartialGlobalSettingsSchema, PartialProviderConfigSchema, ProvidersSchema, RoutingRecommender, STORY_METRICS, TelemetryConfigSchema, addTokenUsage, aggregateTokenUsageForRun, checkDoltInstalled, compareRunMetrics, createAmendmentRun, createConfigSystem, createDecision, createGitWorktreeManager, createPipelineRun, createStderrLogger, getActiveDecisions, getAllCostEntriesFiltered, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initWorkGraphSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, swallowDebug, tagRunAsBaseline, updatePipelineRun } from "../dist-BZGqn-XQ.js";
6
6
  import "../adapter-registry-DXLMTmfD.js";
7
- import { ACCEPTANCE_CONTRACT_PROFILE_PATH, JOURNEY_CANDIDATE_PATH, JOURNEY_DEFERRALS_PATH, JOURNEY_REGISTRY_PATH, RunManifest, SupervisorLock, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, checkRegistryStaleness, clearGateDemotion, computePrecision, computeRecall, demoteGate, diffJourneySets, isProjectContainedPath, loadAcceptanceContractFromTrustedTree, loadJourneyRegistryFromFile, loadJourneyRegistryFromTrustedTree, parseAcceptanceContract, parseJourneyCandidate, parseJourneyDeferrals, parseJourneyRegistry, parseRuntimeProbes, ratifyCandidate, readAcceptanceMetrics, readCurrentRunId, readGateState, readTrustedFileContent, recordCanary, recordOverride, renderRegistryDiff, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorByClass, rollupProbeAuthorMetrics, runAcTraceabilityCheck, runCanary } from "../manifest-read-3cF8yP3_.js";
8
- import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR, GitClient, GrammarLoader, Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runSolutioningPhase, unescape, validateStopAfterFromConflict } from "../run-BeYZ5L6d.js";
7
+ import { ACCEPTANCE_CONTRACT_PROFILE_PATH, JOURNEY_CANDIDATE_PATH, JOURNEY_DEFERRALS_PATH, JOURNEY_REGISTRY_PATH, RunManifest, SupervisorLock, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, checkRegistryStaleness, clearGateDemotion, computePrecision, computeRecall, demoteGate, diffJourneySets, isProjectContainedPath, loadAcceptanceContractFromTrustedTree, loadJourneyRegistryFromFile, loadJourneyRegistryFromTrustedTree, parseAcceptanceContract, parseJourneyCandidate, parseJourneyDeferrals, parseJourneyRegistry, parseRuntimeProbes, ratifyCandidate, readAcceptanceMetrics, readCurrentRunId, readGateState, readTrustedFileContent, recordCanary, recordOverride, renderRegistryDiff, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorByClass, rollupProbeAuthorMetrics, runAcTraceabilityCheck, runCanary } from "../manifest-read-leQdHLyo.js";
8
+ import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR, GitClient, GrammarLoader, Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runSolutioningPhase, unescape, validateStopAfterFromConflict } from "../run-BXP4F8a2.js";
9
9
  import "../errors-xSeGw6pf.js";
10
- import { AcceptanceDeriveResultSchema, assemblePrompt, getTokenCeiling, runAcceptanceJudge } from "../acceptance-judge-lAv5EvYA.js";
10
+ import { AcceptanceCompletenessResultSchema, AcceptanceDeriveResultSchema, assemblePrompt, getTokenCeiling, runAcceptanceJudge } from "../acceptance-judge-COyOxhQ2.js";
11
11
  import "../routing-DZT5PN3N.js";
12
12
  import { WorkGraphRepository } from "../work-graph-repository-4cKsf8Lf.js";
13
13
  import "../decisions-BAaxpVD0.js";
14
14
  import "../decision-router-Dyby0fUf.js";
15
- import "../interactive-prompt-BWdH9Lb9.js";
15
+ import "../interactive-prompt-BbeQO4mm.js";
16
16
  import "../recovery-engine-dtLHyV4M.js";
17
17
  import "../version-manager-impl-DMTw551Q.js";
18
18
  import { registerUpgradeCommand } from "../upgrade-CNGc12AV.js";
@@ -47,14 +47,14 @@ var RecommendationEngine = class {
47
47
  _filters;
48
48
  _historyDays;
49
49
  _logger;
50
- constructor(monitorDb, config = {}, logger$20) {
50
+ constructor(monitorDb, config = {}, logger$21) {
51
51
  this._monitorDb = monitorDb;
52
52
  this._filters = {
53
53
  threshold_percentage: config.recommendation_threshold_percentage ?? 5,
54
54
  min_sample_size: config.min_sample_size ?? 10
55
55
  };
56
56
  this._historyDays = config.recommendation_history_days ?? 90;
57
- this._logger = logger$20 ?? createStderrLogger("monitor:recommendation-engine");
57
+ this._logger = logger$21 ?? createStderrLogger("monitor:recommendation-engine");
58
58
  }
59
59
  generateRecommendations() {
60
60
  const sinceDate = new Date(Date.now() - this._historyDays * 24 * 60 * 60 * 1e3).toISOString();
@@ -1312,7 +1312,7 @@ function buildStackAwareDevNotes(profile) {
1312
1312
 
1313
1313
  //#endregion
1314
1314
  //#region src/cli/commands/init.ts
1315
- const logger$19 = createLogger("init");
1315
+ const logger$20 = createLogger("init");
1316
1316
  const __dirname = dirname(new URL(import.meta.url).pathname);
1317
1317
  const SCAFFOLD_VERSION_REGEX = /<!-- substrate:version=([\d.]+) -->/;
1318
1318
  /**
@@ -1353,7 +1353,7 @@ async function scaffoldBmadFramework(projectRoot, force, outputFormat) {
1353
1353
  const version = resolveBmadMethodVersion();
1354
1354
  if (force && bmadExists) process.stderr.write(`Warning: Replacing existing _bmad/ framework with bmad-method@${version}\n`);
1355
1355
  process.stdout.write(`Scaffolding BMAD framework from bmad-method@${version}\n`);
1356
- logger$19.info({
1356
+ logger$20.info({
1357
1357
  version,
1358
1358
  dest: bmadDest
1359
1359
  }, "Scaffolding BMAD framework");
@@ -1363,7 +1363,7 @@ async function scaffoldBmadFramework(projectRoot, force, outputFormat) {
1363
1363
  const destDir = join(bmadDest, dir);
1364
1364
  mkdirSync$1(destDir, { recursive: true });
1365
1365
  cpSync(srcDir, destDir, { recursive: true });
1366
- logger$19.info({
1366
+ logger$20.info({
1367
1367
  dir,
1368
1368
  dest: destDir
1369
1369
  }, "Scaffolded BMAD framework directory");
@@ -1382,7 +1382,7 @@ async function scaffoldBmadFramework(projectRoot, force, outputFormat) {
1382
1382
  "document_output_language: English"
1383
1383
  ].join("\n") + "\n";
1384
1384
  await writeFile(configFile, configStub, "utf8");
1385
- logger$19.info({ configFile }, "Generated _bmad/_config/config.yaml stub");
1385
+ logger$20.info({ configFile }, "Generated _bmad/_config/config.yaml stub");
1386
1386
  }
1387
1387
  }
1388
1388
  const CLAUDE_MD_START_MARKER = "<!-- substrate:start -->";
@@ -1397,7 +1397,7 @@ async function scaffoldClaudeMd(projectRoot, profile) {
1397
1397
  try {
1398
1398
  sectionContent = await readFile(templatePath, "utf8");
1399
1399
  } catch {
1400
- logger$19.warn({ templatePath }, "CLAUDE.md substrate section template not found; skipping");
1400
+ logger$20.warn({ templatePath }, "CLAUDE.md substrate section template not found; skipping");
1401
1401
  return;
1402
1402
  }
1403
1403
  const substrateVersion = readSubstrateVersion(pkgRoot);
@@ -1433,7 +1433,7 @@ async function scaffoldClaudeMd(projectRoot, profile) {
1433
1433
  else newContent = updatedExisting;
1434
1434
  }
1435
1435
  await writeFile(claudeMdPath, newContent, "utf8");
1436
- logger$19.info({ claudeMdPath }, "Wrote substrate section to CLAUDE.md");
1436
+ logger$20.info({ claudeMdPath }, "Wrote substrate section to CLAUDE.md");
1437
1437
  }
1438
1438
  async function scaffoldAgentsMd(projectRoot, profile) {
1439
1439
  const agentsMdPath = join(projectRoot, "AGENTS.md");
@@ -1445,7 +1445,7 @@ async function scaffoldAgentsMd(projectRoot, profile) {
1445
1445
  try {
1446
1446
  sectionContent = await readFile(templatePath, "utf8");
1447
1447
  } catch {
1448
- logger$19.warn({ templatePath }, "AGENTS.md substrate section template not found; skipping");
1448
+ logger$20.warn({ templatePath }, "AGENTS.md substrate section template not found; skipping");
1449
1449
  return;
1450
1450
  }
1451
1451
  const substrateVersion = readSubstrateVersion(pkgRoot);
@@ -1466,7 +1466,7 @@ async function scaffoldAgentsMd(projectRoot, profile) {
1466
1466
  newContent = existingContent + separator + sectionContent;
1467
1467
  }
1468
1468
  await writeFile(agentsMdPath, newContent, "utf8");
1469
- logger$19.info({ agentsMdPath }, "Wrote substrate section to AGENTS.md");
1469
+ logger$20.info({ agentsMdPath }, "Wrote substrate section to AGENTS.md");
1470
1470
  }
1471
1471
  async function scaffoldGeminiMd(projectRoot, profile) {
1472
1472
  const geminiMdPath = join(projectRoot, "GEMINI.md");
@@ -1478,7 +1478,7 @@ async function scaffoldGeminiMd(projectRoot, profile) {
1478
1478
  try {
1479
1479
  sectionContent = await readFile(templatePath, "utf8");
1480
1480
  } catch {
1481
- logger$19.warn({ templatePath }, "GEMINI.md substrate section template not found; skipping");
1481
+ logger$20.warn({ templatePath }, "GEMINI.md substrate section template not found; skipping");
1482
1482
  return;
1483
1483
  }
1484
1484
  const substrateVersion = readSubstrateVersion(pkgRoot);
@@ -1499,7 +1499,7 @@ async function scaffoldGeminiMd(projectRoot, profile) {
1499
1499
  newContent = existingContent + separator + sectionContent;
1500
1500
  }
1501
1501
  await writeFile(geminiMdPath, newContent, "utf8");
1502
- logger$19.info({ geminiMdPath }, "Wrote substrate section to GEMINI.md");
1502
+ logger$20.info({ geminiMdPath }, "Wrote substrate section to GEMINI.md");
1503
1503
  }
1504
1504
  async function scaffoldStatuslineScript(projectRoot) {
1505
1505
  const pkgRoot = findPackageRoot(__dirname);
@@ -1510,7 +1510,7 @@ async function scaffoldStatuslineScript(projectRoot) {
1510
1510
  try {
1511
1511
  content = await readFile(templatePath, "utf8");
1512
1512
  } catch {
1513
- logger$19.warn({ templatePath }, "statusline.sh template not found; skipping");
1513
+ logger$20.warn({ templatePath }, "statusline.sh template not found; skipping");
1514
1514
  return;
1515
1515
  }
1516
1516
  const claudeDir = join(projectRoot, ".claude");
@@ -1518,7 +1518,7 @@ async function scaffoldStatuslineScript(projectRoot) {
1518
1518
  mkdirSync$1(claudeDir, { recursive: true });
1519
1519
  await writeFile(statuslinePath, content, "utf8");
1520
1520
  chmodSync(statuslinePath, 493);
1521
- logger$19.info({ statuslinePath }, "Wrote .claude/statusline.sh");
1521
+ logger$20.info({ statuslinePath }, "Wrote .claude/statusline.sh");
1522
1522
  }
1523
1523
  async function scaffoldClaudeSettings(projectRoot) {
1524
1524
  const claudeDir = join(projectRoot, ".claude");
@@ -1534,7 +1534,7 @@ async function scaffoldClaudeSettings(projectRoot) {
1534
1534
  if (!merged["$schema"]) merged["$schema"] = "https://json.schemastore.org/claude-code-settings.json";
1535
1535
  mkdirSync$1(claudeDir, { recursive: true });
1536
1536
  await writeFile(settingsPath, JSON.stringify(merged, null, 2) + "\n", "utf8");
1537
- logger$19.info({ settingsPath }, "Wrote substrate settings to .claude/settings.json");
1537
+ logger$20.info({ settingsPath }, "Wrote substrate settings to .claude/settings.json");
1538
1538
  }
1539
1539
  /**
1540
1540
  * H5.2 (field finding #2): write substrate's own slash commands
@@ -1553,7 +1553,7 @@ function scaffoldSubstrateSlashCommands(projectRoot) {
1553
1553
  let templatesDir = join(pkgRoot, "dist", "cli", "templates", "claude-commands");
1554
1554
  if (!existsSync$1(templatesDir)) templatesDir = join(pkgRoot, "src", "cli", "templates", "claude-commands");
1555
1555
  if (!existsSync$1(templatesDir)) {
1556
- logger$19.warn({ templatesDir }, "substrate slash-command templates not found; skipping");
1556
+ logger$20.warn({ templatesDir }, "substrate slash-command templates not found; skipping");
1557
1557
  return 0;
1558
1558
  }
1559
1559
  const commandsDir = join(projectRoot, ".claude", "commands");
@@ -1565,19 +1565,19 @@ function scaffoldSubstrateSlashCommands(projectRoot) {
1565
1565
  writeFileSync$1(join(commandsDir, file), readFileSync$1(join(templatesDir, file), "utf8"));
1566
1566
  written += 1;
1567
1567
  } catch (err) {
1568
- logger$19.warn({
1568
+ logger$20.warn({
1569
1569
  file,
1570
1570
  err
1571
1571
  }, "failed to write substrate slash command (init continues)");
1572
1572
  }
1573
1573
  }
1574
- logger$19.info({
1574
+ logger$20.info({
1575
1575
  written,
1576
1576
  commandsDir
1577
1577
  }, "Scaffolded substrate slash commands");
1578
1578
  return written;
1579
1579
  } catch (err) {
1580
- logger$19.warn({ err }, "scaffoldSubstrateSlashCommands failed; init continues");
1580
+ logger$20.warn({ err }, "scaffoldSubstrateSlashCommands failed; init continues");
1581
1581
  return 0;
1582
1582
  }
1583
1583
  }
@@ -1651,7 +1651,7 @@ async function compileBmadAgents(bmadDir) {
1651
1651
  writeFileSync$1(mdPath, result.xml, "utf-8");
1652
1652
  compiled++;
1653
1653
  } catch (compileErr) {
1654
- logger$19.debug({
1654
+ logger$20.debug({
1655
1655
  err: compileErr,
1656
1656
  file
1657
1657
  }, "Failed to compile agent YAML");
@@ -1798,9 +1798,9 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
1798
1798
  const _require = createRequire(join(__dirname, "synthetic.js"));
1799
1799
  try {
1800
1800
  const compiledCount = await compileBmadAgents(bmadDir);
1801
- if (compiledCount > 0) logger$19.info({ compiledCount }, "Compiled agent YAML files to MD");
1801
+ if (compiledCount > 0) logger$20.info({ compiledCount }, "Compiled agent YAML files to MD");
1802
1802
  } catch (compileErr) {
1803
- logger$19.warn({ err: compileErr }, "Agent compilation failed; agent commands may be incomplete");
1803
+ logger$20.warn({ err: compileErr }, "Agent compilation failed; agent commands may be incomplete");
1804
1804
  }
1805
1805
  const resolveExport = (mod, name) => {
1806
1806
  if (typeof mod[name] === "function") return mod[name];
@@ -1814,7 +1814,7 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
1814
1814
  const manifestGenPath = join(installerLibPath, "core", "manifest-generator.js");
1815
1815
  const pathUtilsPath = join(installerLibPath, "ide", "shared", "path-utils.js");
1816
1816
  if (!existsSync$1(agentGenPath)) {
1817
- logger$19.info("bmad-method generators not available (requires bmad-method with agent/workflow/task-tool generators)");
1817
+ logger$20.info("bmad-method generators not available (requires bmad-method with agent/workflow/task-tool generators)");
1818
1818
  return;
1819
1819
  }
1820
1820
  const agentMod = _require(agentGenPath);
@@ -1824,11 +1824,11 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
1824
1824
  if (existsSync$1(workflowGenPath)) {
1825
1825
  const workflowMod = _require(workflowGenPath);
1826
1826
  WorkflowCommandGenerator = resolveExport(workflowMod, "WorkflowCommandGenerator");
1827
- } else logger$19.info("bmad-method workflow-command-generator not available; will try skill-based installation");
1827
+ } else logger$20.info("bmad-method workflow-command-generator not available; will try skill-based installation");
1828
1828
  if (existsSync$1(taskToolGenPath)) {
1829
1829
  const taskToolMod = _require(taskToolGenPath);
1830
1830
  TaskToolCommandGenerator = resolveExport(taskToolMod, "TaskToolCommandGenerator");
1831
- } else logger$19.info("bmad-method task-tool-command-generator not available; will try skill-based installation");
1831
+ } else logger$20.info("bmad-method task-tool-command-generator not available; will try skill-based installation");
1832
1832
  let ManifestGenerator = null;
1833
1833
  if (existsSync$1(manifestGenPath)) {
1834
1834
  const manifestMod = _require(manifestGenPath);
@@ -1860,7 +1860,7 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
1860
1860
  const manifestGen = new ManifestGenerator();
1861
1861
  await manifestGen.generateManifests(bmadDir, allModules, [], { ides: ["claude-code"] });
1862
1862
  } catch (manifestErr) {
1863
- logger$19.warn({ err: manifestErr }, "ManifestGenerator failed; workflow/task commands may be incomplete");
1863
+ logger$20.warn({ err: manifestErr }, "ManifestGenerator failed; workflow/task commands may be incomplete");
1864
1864
  }
1865
1865
  const commandsDir = join(projectRoot, ".claude", "commands");
1866
1866
  mkdirSync$1(commandsDir, { recursive: true });
@@ -1888,7 +1888,7 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
1888
1888
  const total = agentCount + workflowCount + taskToolCount + skillCount;
1889
1889
  if (outputFormat !== "json") if (skillCount > 0) process.stdout.write(`Generated ${String(total)} Claude Code commands (${String(agentCount)} agents, ${String(skillCount)} skills)\n`);
1890
1890
  else process.stdout.write(`Generated ${String(total)} Claude Code commands (${String(agentCount)} agents, ${String(workflowCount)} workflows, ${String(taskToolCount)} tasks/tools)\n`);
1891
- logger$19.info({
1891
+ logger$20.info({
1892
1892
  agentCount,
1893
1893
  workflowCount,
1894
1894
  taskToolCount,
@@ -1899,7 +1899,7 @@ async function scaffoldClaudeCommands(projectRoot, outputFormat) {
1899
1899
  } catch (err) {
1900
1900
  const msg = err instanceof Error ? err.message : String(err);
1901
1901
  if (outputFormat !== "json") process.stderr.write(`Warning: .claude/commands/ generation failed: ${msg}\n`);
1902
- logger$19.warn({ err }, "scaffoldClaudeCommands failed; init continues");
1902
+ logger$20.warn({ err }, "scaffoldClaudeCommands failed; init continues");
1903
1903
  }
1904
1904
  }
1905
1905
  /**
@@ -1928,7 +1928,7 @@ function syncCommandsAsPrompts(commandsDir, promptsDir, ownershipPrefixes, nameP
1928
1928
  unlinkSync$1(join(promptsDir, entry.name));
1929
1929
  }
1930
1930
  } catch (err) {
1931
- logger$19.debug({
1931
+ logger$20.debug({
1932
1932
  err,
1933
1933
  promptsDir
1934
1934
  }, "Failed to prune stale prompts");
@@ -1971,7 +1971,7 @@ function syncSkillsToTarget(srcSkillsDir, destSkillsDir, ownershipPrefixes, name
1971
1971
  });
1972
1972
  }
1973
1973
  } catch (err) {
1974
- logger$19.debug({
1974
+ logger$20.debug({
1975
1975
  err,
1976
1976
  destSkillsDir
1977
1977
  }, "Failed to prune stale skills");
@@ -1997,7 +1997,7 @@ function syncSkillsToTarget(srcSkillsDir, destSkillsDir, ownershipPrefixes, name
1997
1997
  op: stage,
1998
1998
  err: msg
1999
1999
  });
2000
- logger$19.warn({
2000
+ logger$20.warn({
2001
2001
  skill: entry.name,
2002
2002
  dest,
2003
2003
  stage,
@@ -2007,7 +2007,7 @@ function syncSkillsToTarget(srcSkillsDir, destSkillsDir, ownershipPrefixes, name
2007
2007
  }
2008
2008
  if (failures.length > 0 && count === 0) {
2009
2009
  const first = failures[0];
2010
- logger$19.warn({
2010
+ logger$20.warn({
2011
2011
  destSkillsDir,
2012
2012
  attempted: failures.length,
2013
2013
  dominantStage: first.op,
@@ -2034,7 +2034,7 @@ const PROJECT_OWNERSHIP_PREFIXES = ["bmad-", "substrate-"];
2034
2034
  function scaffoldCodexProject(projectRoot, outputFormat) {
2035
2035
  if (process.env["SUBSTRATE_NO_CODEX_SCAFFOLD"] === "1") {
2036
2036
  if (outputFormat !== "json") process.stdout.write(" Skipping .codex/ scaffolding (SUBSTRATE_NO_CODEX_SCAFFOLD=1)\n");
2037
- logger$19.debug("SUBSTRATE_NO_CODEX_SCAFFOLD=1 — skipping .codex/ scaffolding");
2037
+ logger$20.debug("SUBSTRATE_NO_CODEX_SCAFFOLD=1 — skipping .codex/ scaffolding");
2038
2038
  return;
2039
2039
  }
2040
2040
  const claudeCommandsDir = join(projectRoot, ".claude", "commands");
@@ -2047,16 +2047,16 @@ function scaffoldCodexProject(projectRoot, outputFormat) {
2047
2047
  const skillCount = syncSkillsToTarget(claudeSkillsDir, codexSkillsDir, PROJECT_OWNERSHIP_PREFIXES, "");
2048
2048
  const total = promptCount + skillCount;
2049
2049
  if (outputFormat !== "json" && total > 0) process.stdout.write(`Generated ${String(total)} Codex artifacts (${String(promptCount)} prompts, ${String(skillCount)} skills)\n`);
2050
- if (total > 0) logger$19.info({
2050
+ if (total > 0) logger$20.info({
2051
2051
  promptCount,
2052
2052
  skillCount,
2053
2053
  codexDir
2054
2054
  }, "Generated .codex/");
2055
- else logger$19.debug({ codexDir }, "No Codex artifacts generated; source Claude content not found");
2055
+ else logger$20.debug({ codexDir }, "No Codex artifacts generated; source Claude content not found");
2056
2056
  } catch (err) {
2057
2057
  const msg = err instanceof Error ? err.message : String(err);
2058
2058
  if (outputFormat !== "json") process.stderr.write(`Warning: .codex/ generation failed: ${msg}\n`);
2059
- logger$19.warn({ err }, "scaffoldCodexProject failed; init continues");
2059
+ logger$20.warn({ err }, "scaffoldCodexProject failed; init continues");
2060
2060
  }
2061
2061
  }
2062
2062
  /**
@@ -2074,7 +2074,7 @@ function scaffoldCodexProject(projectRoot, outputFormat) {
2074
2074
  function scaffoldCodexUser(projectRoot, homeDir, outputFormat) {
2075
2075
  if (process.env["SUBSTRATE_NO_CODEX_SCAFFOLD"] === "1") {
2076
2076
  if (outputFormat !== "json") process.stdout.write(" Skipping ~/.codex/ scaffolding (SUBSTRATE_NO_CODEX_SCAFFOLD=1)\n");
2077
- logger$19.debug("SUBSTRATE_NO_CODEX_SCAFFOLD=1 — skipping ~/.codex/ scaffolding");
2077
+ logger$20.debug("SUBSTRATE_NO_CODEX_SCAFFOLD=1 — skipping ~/.codex/ scaffolding");
2078
2078
  return;
2079
2079
  }
2080
2080
  const claudeCommandsDir = join(projectRoot, ".claude", "commands");
@@ -2087,16 +2087,16 @@ function scaffoldCodexUser(projectRoot, homeDir, outputFormat) {
2087
2087
  const skillCount = syncSkillsToTarget(claudeSkillsDir, userSkillsDir, ["substrate-"], "substrate-");
2088
2088
  const total = promptCount + skillCount;
2089
2089
  if (outputFormat !== "json" && total > 0) process.stdout.write(`Installed ${String(total)} Codex artifacts to ${userCodexDir} (${String(promptCount)} prompts, ${String(skillCount)} skills)\n`);
2090
- if (total > 0) logger$19.info({
2090
+ if (total > 0) logger$20.info({
2091
2091
  promptCount,
2092
2092
  skillCount,
2093
2093
  userCodexDir
2094
2094
  }, "Installed user-scope Codex content");
2095
- else logger$19.debug({ userCodexDir }, "No user-scope Codex content installed; source Claude content not found");
2095
+ else logger$20.debug({ userCodexDir }, "No user-scope Codex content installed; source Claude content not found");
2096
2096
  } catch (err) {
2097
2097
  const msg = err instanceof Error ? err.message : String(err);
2098
2098
  if (outputFormat !== "json") process.stderr.write(`Warning: user-scope Codex install failed: ${msg}\n`);
2099
- logger$19.warn({ err }, "scaffoldCodexUser failed; init continues");
2099
+ logger$20.warn({ err }, "scaffoldCodexUser failed; init continues");
2100
2100
  }
2101
2101
  }
2102
2102
  const PROVIDER_DEFAULTS = DEFAULT_CONFIG.providers;
@@ -2217,7 +2217,7 @@ async function runInitAction(options) {
2217
2217
  discoveryReport = await registry.discoverAndRegister();
2218
2218
  } catch (err) {
2219
2219
  const message = err instanceof Error ? err.message : String(err);
2220
- logger$19.error({ err }, "Adapter discovery failed");
2220
+ logger$20.error({ err }, "Adapter discovery failed");
2221
2221
  if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, `Adapter discovery failed: ${message}`) + "\n");
2222
2222
  else process.stderr.write(` Error: adapter discovery failed — ${message}\n`);
2223
2223
  return INIT_EXIT_ERROR;
@@ -2266,7 +2266,7 @@ async function runInitAction(options) {
2266
2266
  try {
2267
2267
  detectedProfile = await detectProjectProfile(dbRoot);
2268
2268
  } catch (err) {
2269
- logger$19.warn({ err }, "Project profile detection failed; skipping");
2269
+ logger$20.warn({ err }, "Project profile detection failed; skipping");
2270
2270
  }
2271
2271
  if (detectedProfile === null) {
2272
2272
  if (outputFormat !== "json") process.stdout.write(" No project stack detected. Create .substrate/project-profile.yaml manually to enable polyglot support.\n");
@@ -2300,12 +2300,12 @@ async function runInitAction(options) {
2300
2300
  return INIT_EXIT_ERROR;
2301
2301
  }
2302
2302
  if (force && existsSync$1(localManifest)) {
2303
- logger$19.info({ pack: packName }, "Replacing existing pack with bundled version");
2303
+ logger$20.info({ pack: packName }, "Replacing existing pack with bundled version");
2304
2304
  process.stderr.write(`Warning: Replacing existing pack '${packName}' with bundled version\n`);
2305
2305
  }
2306
2306
  mkdirSync$1(dirname(packPath), { recursive: true });
2307
2307
  cpSync(bundledPackPath, packPath, { recursive: true });
2308
- logger$19.info({
2308
+ logger$20.info({
2309
2309
  pack: packName,
2310
2310
  dest: packPath
2311
2311
  }, "Scaffolded methodology pack");
@@ -2347,10 +2347,10 @@ async function runInitAction(options) {
2347
2347
  const { content, changed } = computeSubstrateGitignore(existing);
2348
2348
  if (changed) {
2349
2349
  writeFileSync$1(gitignorePath, content);
2350
- logger$19.info("Updated .gitignore: track only .substrate/config.yaml");
2350
+ logger$20.info("Updated .gitignore: track only .substrate/config.yaml");
2351
2351
  }
2352
2352
  } catch (err) {
2353
- logger$19.debug({ err }, "Could not update .gitignore (non-fatal)");
2353
+ logger$20.debug({ err }, "Could not update .gitignore (non-fatal)");
2354
2354
  }
2355
2355
  const doltMode = options.doltMode ?? "auto";
2356
2356
  let doltInitialized = false;
@@ -2364,7 +2364,7 @@ async function runInitAction(options) {
2364
2364
  process.stderr.write(`${err.message}\n`);
2365
2365
  return INIT_EXIT_ERROR;
2366
2366
  }
2367
- logger$19.debug("Dolt not installed, skipping auto-init");
2367
+ logger$20.debug("Dolt not installed, skipping auto-init");
2368
2368
  } else {
2369
2369
  const msg = err instanceof Error ? err.message : String(err);
2370
2370
  if (doltMode === "force") {
@@ -2374,7 +2374,7 @@ async function runInitAction(options) {
2374
2374
  process.stderr.write(`⚠ Dolt state store initialization failed: ${msg}\n Pipeline metrics, cost tracking, and health monitoring will not persist.\n Fix the issue and re-run: substrate init --dolt\n`);
2375
2375
  }
2376
2376
  }
2377
- else logger$19.debug("Dolt step was skipped (--no-dolt)");
2377
+ else logger$20.debug("Dolt step was skipped (--no-dolt)");
2378
2378
  const successMsg = `Pack '${packName}' and database initialized successfully at ${dbPath}`;
2379
2379
  if (outputFormat === "json") process.stdout.write(formatOutput({
2380
2380
  pack: packName,
@@ -2412,7 +2412,7 @@ async function runInitAction(options) {
2412
2412
  const msg = err instanceof Error ? err.message : String(err);
2413
2413
  if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
2414
2414
  else process.stderr.write(`Error: ${msg}\n`);
2415
- logger$19.error({ err }, "init failed");
2415
+ logger$20.error({ err }, "init failed");
2416
2416
  return INIT_EXIT_ERROR;
2417
2417
  }
2418
2418
  }
@@ -2436,7 +2436,7 @@ function registerInitCommand(program, _version, registry) {
2436
2436
 
2437
2437
  //#endregion
2438
2438
  //#region src/cli/commands/config.ts
2439
- const logger$18 = createLogger("config-cmd");
2439
+ const logger$19 = createLogger("config-cmd");
2440
2440
  const CONFIG_EXIT_SUCCESS = 0;
2441
2441
  const CONFIG_EXIT_ERROR = 1;
2442
2442
  const CONFIG_EXIT_INVALID = 2;
@@ -2462,7 +2462,7 @@ async function runConfigShow(opts = {}) {
2462
2462
  return CONFIG_EXIT_INVALID;
2463
2463
  }
2464
2464
  const message = err instanceof Error ? err.message : String(err);
2465
- logger$18.error({ err }, "Failed to load configuration");
2465
+ logger$19.error({ err }, "Failed to load configuration");
2466
2466
  process.stderr.write(` Error loading configuration: ${message}\n`);
2467
2467
  return CONFIG_EXIT_ERROR;
2468
2468
  }
@@ -2536,7 +2536,7 @@ async function runConfigExport(opts = {}) {
2536
2536
  return CONFIG_EXIT_INVALID;
2537
2537
  }
2538
2538
  const message = err instanceof Error ? err.message : String(err);
2539
- logger$18.error({ err }, "Failed to load configuration");
2539
+ logger$19.error({ err }, "Failed to load configuration");
2540
2540
  process.stderr.write(`Error loading configuration: ${message}\n`);
2541
2541
  return CONFIG_EXIT_ERROR;
2542
2542
  }
@@ -6456,7 +6456,7 @@ async function detectManifestDriftAgainstWorkingTree(manifest, projectRoot) {
6456
6456
 
6457
6457
  //#endregion
6458
6458
  //#region src/cli/commands/resume.ts
6459
- const logger$17 = createLogger("resume-cmd");
6459
+ const logger$18 = createLogger("resume-cmd");
6460
6460
  /**
6461
6461
  * Format a human-readable duration from an ISO-8601 timestamp to "now".
6462
6462
  */
@@ -6526,7 +6526,7 @@ async function runResumeAction(options) {
6526
6526
  return 1;
6527
6527
  }
6528
6528
  } catch (driftErr) {
6529
- logger$17.debug({ err: driftErr }, "manifest drift check failed — proceeding with resume");
6529
+ logger$18.debug({ err: driftErr }, "manifest drift check failed — proceeding with resume");
6530
6530
  }
6531
6531
  }
6532
6532
  const doltDir = join(dbRoot, ".substrate", "state", ".dolt");
@@ -6596,15 +6596,15 @@ async function runResumeAction(options) {
6596
6596
  const manifestStories = manifestData.cli_flags["stories"] ?? manifestData.story_scope;
6597
6597
  if (Array.isArray(manifestStories) && manifestStories.length > 0) {
6598
6598
  scopedStories = manifestStories;
6599
- logger$17.debug({
6599
+ logger$18.debug({
6600
6600
  runId,
6601
6601
  stories: scopedStories
6602
6602
  }, "resume scope loaded from manifest");
6603
6603
  }
6604
6604
  } catch {
6605
- logger$17.debug({ runId }, "manifest read failed in resume — using legacy config_json scope");
6605
+ logger$18.debug({ runId }, "manifest read failed in resume — using legacy config_json scope");
6606
6606
  }
6607
- else logger$17.debug({ runId }, "Run manifest not found for scope preservation — using legacy config_json scope");
6607
+ else logger$18.debug({ runId }, "Run manifest not found for scope preservation — using legacy config_json scope");
6608
6608
  }
6609
6609
  return runFullPipelineFromPhase({
6610
6610
  packName,
@@ -6627,7 +6627,7 @@ async function runResumeAction(options) {
6627
6627
  const msg = err instanceof Error ? err.message : String(err);
6628
6628
  if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
6629
6629
  else process.stderr.write(`Error: ${msg}\n`);
6630
- logger$17.error({ err }, "auto resume failed");
6630
+ logger$18.error({ err }, "auto resume failed");
6631
6631
  return 1;
6632
6632
  } finally {
6633
6633
  try {
@@ -6667,7 +6667,8 @@ async function runFullPipelineFromPhase(options) {
6667
6667
  pack,
6668
6668
  contextCompiler,
6669
6669
  dispatcher,
6670
- agentId
6670
+ agentId,
6671
+ eventBus
6671
6672
  };
6672
6673
  const agentAdapter = agentId != null ? injectedRegistry.get(agentId) : void 0;
6673
6674
  const adapterDefaultCycles = agentAdapter?.getCapabilities?.()?.defaultMaxReviewCycles;
@@ -6880,11 +6881,11 @@ async function runFullPipelineFromPhase(options) {
6880
6881
  output_tokens: output,
6881
6882
  cost_usd: costUsd
6882
6883
  }).catch((err) => {
6883
- logger$17.warn({ err }, "Failed to record token usage");
6884
+ logger$18.warn({ err }, "Failed to record token usage");
6884
6885
  });
6885
6886
  }
6886
6887
  } catch (err) {
6887
- logger$17.warn({ err }, "Failed to record token usage");
6888
+ logger$18.warn({ err }, "Failed to record token usage");
6888
6889
  }
6889
6890
  });
6890
6891
  const storyKeys = await resolveStoryKeys(adapter, projectRoot, {
@@ -6953,7 +6954,7 @@ async function runFullPipelineFromPhase(options) {
6953
6954
  const msg = err instanceof Error ? err.message : String(err);
6954
6955
  if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
6955
6956
  else process.stderr.write(`Error: ${msg}\n`);
6956
- logger$17.error({ err }, "pipeline from phase failed");
6957
+ logger$18.error({ err }, "pipeline from phase failed");
6957
6958
  return 1;
6958
6959
  } finally {
6959
6960
  try {
@@ -6983,7 +6984,7 @@ function registerResumeCommand(program, _version = "0.0.0", projectRoot = proces
6983
6984
 
6984
6985
  //#endregion
6985
6986
  //#region src/cli/commands/status.ts
6986
- const logger$16 = createLogger("status-cmd");
6987
+ const logger$17 = createLogger("status-cmd");
6987
6988
  /**
6988
6989
  * Map a manifest per-story status string to the appropriate WorkGraphCounts bucket.
6989
6990
  * Unknown strings are treated as `inProgress` (safe default).
@@ -7095,9 +7096,9 @@ async function runStatusAction(options) {
7095
7096
  const manifestData = await resolvedManifest.read();
7096
7097
  manifestPerStoryState = manifestData.per_story_state;
7097
7098
  workGraph = buildWorkGraphFromManifest(manifestData.per_story_state);
7098
- logger$16.debug({ runId: run?.id }, "status: workGraph built from manifest per_story_state");
7099
+ logger$17.debug({ runId: run?.id }, "status: workGraph built from manifest per_story_state");
7099
7100
  } catch {
7100
- logger$16.debug({ runId: run?.id }, "status: manifest read failed — falling back to wg_stories");
7101
+ logger$17.debug({ runId: run?.id }, "status: manifest read failed — falling back to wg_stories");
7101
7102
  }
7102
7103
  if (workGraph === void 0) try {
7103
7104
  const wgRepo = new WorkGraphRepository(adapter);
@@ -7134,10 +7135,10 @@ async function runStatusAction(options) {
7134
7135
  };
7135
7136
  }
7136
7137
  } catch (err) {
7137
- logger$16.debug({ err }, "Work graph query failed, continuing without work graph data");
7138
+ logger$17.debug({ err }, "Work graph query failed, continuing without work graph data");
7138
7139
  }
7139
7140
  if (run === void 0) {
7140
- const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-C1m6-7WH.js");
7141
+ const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-4VCoTtz_.js");
7141
7142
  const substrateDirPath = join(projectRoot, ".substrate");
7142
7143
  const processInfo = inspectProcessTree$1({
7143
7144
  projectRoot,
@@ -7296,7 +7297,7 @@ async function runStatusAction(options) {
7296
7297
  const msg = err instanceof Error ? err.message : String(err);
7297
7298
  if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
7298
7299
  else process.stderr.write(`Error: ${msg}\n`);
7299
- logger$16.error({ err }, "status action failed");
7300
+ logger$17.error({ err }, "status action failed");
7300
7301
  return 1;
7301
7302
  } finally {
7302
7303
  try {
@@ -7640,7 +7641,7 @@ Analyze thoroughly and return ONLY the JSON array with no additional text.`;
7640
7641
 
7641
7642
  //#endregion
7642
7643
  //#region src/cli/commands/amend.ts
7643
- const logger$15 = createLogger("amend-cmd");
7644
+ const logger$16 = createLogger("amend-cmd");
7644
7645
  /**
7645
7646
  * Detect and apply supersessions after a phase completes in an amendment run.
7646
7647
  *
@@ -7671,7 +7672,7 @@ async function runPostPhaseSupersessionDetection(adapter, amendmentRunId, curren
7671
7672
  });
7672
7673
  } catch (err) {
7673
7674
  const msg = err instanceof Error ? err.message : String(err);
7674
- logger$15.warn({
7675
+ logger$16.warn({
7675
7676
  err,
7676
7677
  originalId: parentMatch.id,
7677
7678
  supersedingId: newDec.id
@@ -7779,7 +7780,8 @@ async function runAmendAction(options) {
7779
7780
  pack,
7780
7781
  contextCompiler,
7781
7782
  dispatcher,
7782
- agentId
7783
+ agentId,
7784
+ eventBus
7783
7785
  };
7784
7786
  const phaseOrder = [
7785
7787
  "analysis",
@@ -7808,7 +7810,7 @@ async function runAmendAction(options) {
7808
7810
  for (let i = startIdx; i < phaseOrder.length; i++) {
7809
7811
  const currentPhase = phaseOrder[i];
7810
7812
  const amendmentContext = handler.loadContextForPhase(currentPhase);
7811
- logger$15.info({
7813
+ logger$16.info({
7812
7814
  phase: currentPhase,
7813
7815
  amendmentContextLen: amendmentContext.length
7814
7816
  }, "Amendment context loaded for phase");
@@ -7929,7 +7931,7 @@ async function runAmendAction(options) {
7929
7931
  } catch (err) {
7930
7932
  const msg = err instanceof Error ? err.message : String(err);
7931
7933
  process.stderr.write(`Error: ${msg}\n`);
7932
- logger$15.error({ err }, "amend failed");
7934
+ logger$16.error({ err }, "amend failed");
7933
7935
  return 1;
7934
7936
  } finally {
7935
7937
  try {
@@ -8666,7 +8668,7 @@ async function runSupervisorAction(options, deps = {}) {
8666
8668
  await initSchema(expAdapter);
8667
8669
  const { runRunAction: runPipeline } = await import(
8668
8670
  /* @vite-ignore */
8669
- "../run-NlTM7HwK.js"
8671
+ "../run-CTfGK9yU.js"
8670
8672
  );
8671
8673
  const runStoryFn = async (opts) => {
8672
8674
  const exitCode = await runPipeline({
@@ -8916,7 +8918,7 @@ function registerSupervisorCommand(program, _version = "0.0.0", projectRoot = pr
8916
8918
 
8917
8919
  //#endregion
8918
8920
  //#region src/cli/commands/metrics.ts
8919
- const logger$14 = createLogger("metrics-cmd");
8921
+ const logger$15 = createLogger("metrics-cmd");
8920
8922
  async function openTelemetryAdapter(basePath) {
8921
8923
  try {
8922
8924
  const adapter = createDatabaseAdapter({
@@ -9275,7 +9277,7 @@ async function runMetricsAction(options) {
9275
9277
  }
9276
9278
  }
9277
9279
  } catch (err) {
9278
- logger$14.debug({ err }, "getScenarioResultsForRun failed");
9280
+ logger$15.debug({ err }, "getScenarioResultsForRun failed");
9279
9281
  }
9280
9282
  if (rows.length === 0) {
9281
9283
  const msg = `No factory run found with id: ${run}`;
@@ -9311,7 +9313,7 @@ async function runMetricsAction(options) {
9311
9313
  }
9312
9314
  }
9313
9315
  } catch (err) {
9314
- logger$14.debug({ err }, "getTwinRunsForRun failed — twin_runs table may not exist yet");
9316
+ logger$15.debug({ err }, "getTwinRunsForRun failed — twin_runs table may not exist yet");
9315
9317
  }
9316
9318
  }
9317
9319
  return 0;
@@ -9321,7 +9323,7 @@ async function runMetricsAction(options) {
9321
9323
  try {
9322
9324
  factoryRuns$1 = await getFactoryRunSummaries(adapter, limit);
9323
9325
  } catch (err) {
9324
- logger$14.debug({ err }, "getFactoryRunSummaries failed in factory-only mode");
9326
+ logger$15.debug({ err }, "getFactoryRunSummaries failed in factory-only mode");
9325
9327
  }
9326
9328
  if (outputFormat === "json") process.stdout.write(formatOutput({ graph_runs: factoryRuns$1 }, "json", true) + "\n");
9327
9329
  else if (factoryRuns$1.length === 0) process.stdout.write("No factory runs recorded yet.\n");
@@ -9424,7 +9426,7 @@ async function runMetricsAction(options) {
9424
9426
  try {
9425
9427
  factoryRuns = await getFactoryRunSummaries(adapter, limit);
9426
9428
  } catch (err) {
9427
- logger$14.debug({ err }, "getFactoryRunSummaries failed — table may not exist in older databases");
9429
+ logger$15.debug({ err }, "getFactoryRunSummaries failed — table may not exist in older databases");
9428
9430
  }
9429
9431
  if (outputFormat === "json") {
9430
9432
  const runsWithBreakdown = runs.map((run$1) => ({
@@ -9510,7 +9512,7 @@ async function runMetricsAction(options) {
9510
9512
  const msg = err instanceof Error ? err.message : String(err);
9511
9513
  if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
9512
9514
  else process.stderr.write(`Error: ${msg}\n`);
9513
- logger$14.error({ err }, "metrics action failed");
9515
+ logger$15.error({ err }, "metrics action failed");
9514
9516
  return 1;
9515
9517
  } finally {
9516
9518
  try {
@@ -9566,7 +9568,7 @@ function registerMetricsCommand(program, _version = "0.0.0", projectRoot = proce
9566
9568
  function getLatestSessionId(_adapter) {
9567
9569
  return null;
9568
9570
  }
9569
- const logger$13 = createLogger("cost-cmd");
9571
+ const logger$14 = createLogger("cost-cmd");
9570
9572
  const COST_EXIT_SUCCESS = 0;
9571
9573
  const COST_EXIT_ERROR = 1;
9572
9574
  /**
@@ -9810,7 +9812,7 @@ async function runCostAction(options) {
9810
9812
  } catch (err) {
9811
9813
  const message = err instanceof Error ? err.message : String(err);
9812
9814
  process.stderr.write(`Error: ${message}\n`);
9813
- logger$13.error({ err }, "runCostAction failed");
9815
+ logger$14.error({ err }, "runCostAction failed");
9814
9816
  return COST_EXIT_ERROR;
9815
9817
  } finally {
9816
9818
  if (adapter !== null) try {
@@ -9844,7 +9846,7 @@ function registerCostCommand(program, version = "0.0.0", projectRoot = process.c
9844
9846
 
9845
9847
  //#endregion
9846
9848
  //#region src/cli/commands/monitor.ts
9847
- const logger$12 = createLogger("monitor-cmd");
9849
+ const logger$13 = createLogger("monitor-cmd");
9848
9850
  const MONITOR_EXIT_SUCCESS = 0;
9849
9851
  const MONITOR_EXIT_ERROR = 1;
9850
9852
  /**
@@ -10047,7 +10049,7 @@ async function runMonitorReportAction(options) {
10047
10049
  } catch (err) {
10048
10050
  const message = err instanceof Error ? err.message : String(err);
10049
10051
  process.stderr.write(`Error: ${message}\n`);
10050
- logger$12.error({ err }, "runMonitorReportAction failed");
10052
+ logger$13.error({ err }, "runMonitorReportAction failed");
10051
10053
  return MONITOR_EXIT_ERROR;
10052
10054
  } finally {
10053
10055
  if (monitorDb !== null) try {
@@ -10109,7 +10111,7 @@ async function runMonitorStatusAction(options) {
10109
10111
  } catch (err) {
10110
10112
  const message = err instanceof Error ? err.message : String(err);
10111
10113
  process.stderr.write(`Error: ${message}\n`);
10112
- logger$12.error({ err }, "runMonitorStatusAction failed");
10114
+ logger$13.error({ err }, "runMonitorStatusAction failed");
10113
10115
  return MONITOR_EXIT_ERROR;
10114
10116
  } finally {
10115
10117
  if (monitorDb !== null) try {
@@ -10144,7 +10146,7 @@ async function runMonitorResetAction(options) {
10144
10146
  } catch (err) {
10145
10147
  const message = err instanceof Error ? err.message : String(err);
10146
10148
  process.stderr.write(`Error: ${message}\n`);
10147
- logger$12.error({ err }, "runMonitorResetAction failed");
10149
+ logger$13.error({ err }, "runMonitorResetAction failed");
10148
10150
  return MONITOR_EXIT_ERROR;
10149
10151
  } finally {
10150
10152
  if (monitorDb !== null) try {
@@ -10192,7 +10194,7 @@ async function runMonitorRecommendationsAction(options) {
10192
10194
  } catch (err) {
10193
10195
  const message = err instanceof Error ? err.message : String(err);
10194
10196
  process.stderr.write(`Error: ${message}\n`);
10195
- logger$12.error({ err }, "runMonitorRecommendationsAction failed");
10197
+ logger$13.error({ err }, "runMonitorRecommendationsAction failed");
10196
10198
  return MONITOR_EXIT_ERROR;
10197
10199
  } finally {
10198
10200
  if (monitorDb !== null) try {
@@ -10270,7 +10272,7 @@ function registerMonitorCommand(program, version = "0.0.0", projectRoot = proces
10270
10272
 
10271
10273
  //#endregion
10272
10274
  //#region src/cli/commands/merge.ts
10273
- const logger$11 = createLogger("merge-cmd");
10275
+ const logger$12 = createLogger("merge-cmd");
10274
10276
  const MERGE_EXIT_SUCCESS = 0;
10275
10277
  const MERGE_EXIT_CONFLICT = 1;
10276
10278
  const MERGE_EXIT_ERROR = 2;
@@ -10308,7 +10310,7 @@ async function mergeTask(taskId, targetBranch, projectRoot) {
10308
10310
  projectRoot
10309
10311
  });
10310
10312
  try {
10311
- logger$11.info({
10313
+ logger$12.info({
10312
10314
  taskId,
10313
10315
  targetBranch
10314
10316
  }, "Running conflict detection...");
@@ -10330,7 +10332,7 @@ async function mergeTask(taskId, targetBranch, projectRoot) {
10330
10332
  } catch (err) {
10331
10333
  const message = err instanceof Error ? err.message : String(err);
10332
10334
  console.error(`Error merging task "${taskId}": ${message}`);
10333
- logger$11.error({
10335
+ logger$12.error({
10334
10336
  taskId,
10335
10337
  err
10336
10338
  }, "merge --task failed");
@@ -10384,7 +10386,7 @@ async function mergeAll(targetBranch, projectRoot, taskIds) {
10384
10386
  error: message
10385
10387
  });
10386
10388
  console.log(` Error for task "${taskId}": ${message}`);
10387
- logger$11.error({
10389
+ logger$12.error({
10388
10390
  taskId,
10389
10391
  err
10390
10392
  }, "merge --all: task failed");
@@ -10437,7 +10439,7 @@ function registerMergeCommand(program, projectRoot = process.cwd()) {
10437
10439
 
10438
10440
  //#endregion
10439
10441
  //#region src/cli/commands/worktrees.ts
10440
- const logger$10 = createLogger("worktrees-cmd");
10442
+ const logger$11 = createLogger("worktrees-cmd");
10441
10443
  const WORKTREES_EXIT_SUCCESS = 0;
10442
10444
  const WORKTREES_EXIT_ERROR = 1;
10443
10445
  /** Valid task statuses for filtering */
@@ -10564,7 +10566,7 @@ async function listWorktreesAction(options) {
10564
10566
  try {
10565
10567
  worktreeInfos = await manager.listWorktrees();
10566
10568
  } catch (err) {
10567
- logger$10.error({ err }, "Failed to list worktrees");
10569
+ logger$11.error({ err }, "Failed to list worktrees");
10568
10570
  const message = err instanceof Error ? err.message : String(err);
10569
10571
  process.stderr.write(`Error listing worktrees: ${message}\n`);
10570
10572
  return WORKTREES_EXIT_ERROR;
@@ -10591,7 +10593,7 @@ async function listWorktreesAction(options) {
10591
10593
  } catch (err) {
10592
10594
  const message = err instanceof Error ? err.message : String(err);
10593
10595
  process.stderr.write(`Error: ${message}\n`);
10594
- logger$10.error({ err }, "listWorktreesAction failed");
10596
+ logger$11.error({ err }, "listWorktreesAction failed");
10595
10597
  return WORKTREES_EXIT_ERROR;
10596
10598
  }
10597
10599
  }
@@ -10620,7 +10622,7 @@ async function cleanupWorktreesAction(options) {
10620
10622
  } catch (err) {
10621
10623
  const message = err instanceof Error ? err.message : String(err);
10622
10624
  process.stderr.write(`Error cleaning up worktree for task "${taskId}": ${message}\n`);
10623
- logger$10.error({
10625
+ logger$11.error({
10624
10626
  err,
10625
10627
  taskId
10626
10628
  }, "cleanupWorktreesAction (single) failed");
@@ -10634,13 +10636,13 @@ async function cleanupWorktreesAction(options) {
10634
10636
  } catch (err) {
10635
10637
  const message = err instanceof Error ? err.message : String(err);
10636
10638
  process.stderr.write(`Error during bulk cleanup: ${message}\n`);
10637
- logger$10.error({ err }, "cleanupWorktreesAction (bulk) failed");
10639
+ logger$11.error({ err }, "cleanupWorktreesAction (bulk) failed");
10638
10640
  return WORKTREES_EXIT_ERROR;
10639
10641
  }
10640
10642
  } catch (err) {
10641
10643
  const message = err instanceof Error ? err.message : String(err);
10642
10644
  process.stderr.write(`Error: ${message}\n`);
10643
- logger$10.error({ err }, "cleanupWorktreesAction failed");
10645
+ logger$11.error({ err }, "cleanupWorktreesAction failed");
10644
10646
  return WORKTREES_EXIT_ERROR;
10645
10647
  }
10646
10648
  }
@@ -10691,7 +10693,7 @@ function registerWorktreesCommand(program, version = "0.0.0", projectRoot = proc
10691
10693
 
10692
10694
  //#endregion
10693
10695
  //#region src/cli/commands/brainstorm.ts
10694
- const logger$9 = createLogger("brainstorm-cmd");
10696
+ const logger$10 = createLogger("brainstorm-cmd");
10695
10697
  /**
10696
10698
  * Detect whether the project has existing planning artifacts that indicate
10697
10699
  * this is an amendment session (vs. a brand-new project brainstorm).
@@ -10737,13 +10739,13 @@ async function loadAmendmentContextDocuments(projectRoot) {
10737
10739
  try {
10738
10740
  brief = await readFile(briefPath, "utf-8");
10739
10741
  } catch {
10740
- logger$9.warn({ briefPath }, "product-brief.md not found — continuing without brief context");
10742
+ logger$10.warn({ briefPath }, "product-brief.md not found — continuing without brief context");
10741
10743
  process.stderr.write(`Warning: product-brief.md not found at ${briefPath}\n`);
10742
10744
  }
10743
10745
  try {
10744
10746
  prd = await readFile(prdPath, "utf-8");
10745
10747
  } catch {
10746
- logger$9.warn({ prdPath }, "requirements.md not found — continuing without PRD context");
10748
+ logger$10.warn({ prdPath }, "requirements.md not found — continuing without PRD context");
10747
10749
  process.stderr.write(`Warning: requirements.md not found at ${prdPath}\n`);
10748
10750
  }
10749
10751
  return {
@@ -10952,7 +10954,7 @@ async function dispatchToPersonas(userPrompt, context, llmDispatch) {
10952
10954
  }
10953
10955
  ];
10954
10956
  const defaultDispatch = async (prompt, personaName) => {
10955
- logger$9.debug({
10957
+ logger$10.debug({
10956
10958
  personaName,
10957
10959
  promptLength: prompt.length
10958
10960
  }, "Dispatching to persona (stub mode)");
@@ -10969,7 +10971,7 @@ async function dispatchToPersonas(userPrompt, context, llmDispatch) {
10969
10971
  };
10970
10972
  } catch (err) {
10971
10973
  const msg = err instanceof Error ? err.message : String(err);
10972
- logger$9.error({
10974
+ logger$10.error({
10973
10975
  err,
10974
10976
  personaName: persona.name
10975
10977
  }, "Persona dispatch failed");
@@ -11121,7 +11123,7 @@ async function runBrainstormSession(options, llmDispatch, rlInterface) {
11121
11123
  }
11122
11124
  });
11123
11125
  rl.on("error", (err) => {
11124
- logger$9.error({ err }, "readline error");
11126
+ logger$10.error({ err }, "readline error");
11125
11127
  if (!sessionEnded) endSession(false);
11126
11128
  });
11127
11129
  });
@@ -11162,7 +11164,7 @@ function registerBrainstormCommand(program, _version = "0.0.0", projectRoot = pr
11162
11164
 
11163
11165
  //#endregion
11164
11166
  //#region src/cli/commands/retry-escalated.ts
11165
- const logger$8 = createLogger("retry-escalated-cmd");
11167
+ const logger$9 = createLogger("retry-escalated-cmd");
11166
11168
  async function runRetryEscalatedAction(options) {
11167
11169
  const { runId, dryRun, force, outputFormat, projectRoot, concurrency, pack: packName, registry: injectedRegistry, agent: agentId, events: eventsFlag } = options;
11168
11170
  const dbRoot = await resolveMainRepoRoot(projectRoot);
@@ -11203,7 +11205,7 @@ async function runRetryEscalatedAction(options) {
11203
11205
  process.stdout.write(`[INFO] ${storyKey}: Context ceiling set to ${contextCeiling} tokens due to prior context spike pattern.\n`);
11204
11206
  }
11205
11207
  } catch (err) {
11206
- logger$8.warn({
11208
+ logger$9.warn({
11207
11209
  err,
11208
11210
  storyKey
11209
11211
  }, "Failed to read efficiency profile — skipping gate");
@@ -11365,11 +11367,11 @@ async function runRetryEscalatedAction(options) {
11365
11367
  output_tokens: output,
11366
11368
  cost_usd: costUsd
11367
11369
  }).catch((err) => {
11368
- logger$8.warn({ err }, "Failed to record token usage");
11370
+ logger$9.warn({ err }, "Failed to record token usage");
11369
11371
  });
11370
11372
  }
11371
11373
  } catch (err) {
11372
- logger$8.warn({ err }, "Failed to record token usage");
11374
+ logger$9.warn({ err }, "Failed to record token usage");
11373
11375
  }
11374
11376
  });
11375
11377
  if (outputFormat === "human") {
@@ -11398,7 +11400,7 @@ async function runRetryEscalatedAction(options) {
11398
11400
  const msg = err instanceof Error ? err.message : String(err);
11399
11401
  if (outputFormat === "json") process.stdout.write(formatOutput(null, "json", false, msg) + "\n");
11400
11402
  else process.stderr.write(`Error: ${msg}\n`);
11401
- logger$8.error({ err }, "retry-escalated failed");
11403
+ logger$9.error({ err }, "retry-escalated failed");
11402
11404
  return 1;
11403
11405
  } finally {
11404
11406
  try {
@@ -11431,7 +11433,7 @@ function registerRetryEscalatedCommand(program, _version = "0.0.0", projectRoot
11431
11433
 
11432
11434
  //#endregion
11433
11435
  //#region src/cli/commands/cancel.ts
11434
- const logger$7 = createLogger("cancel-cmd");
11436
+ const logger$8 = createLogger("cancel-cmd");
11435
11437
  async function runCancelAction(options) {
11436
11438
  const { outputFormat, projectRoot, force } = options;
11437
11439
  const dbRoot = await resolveMainRepoRoot(projectRoot);
@@ -11470,7 +11472,7 @@ async function runCancelAction(options) {
11470
11472
  }
11471
11473
  } catch (err) {
11472
11474
  const msg = err instanceof Error ? err.message : String(err);
11473
- logger$7.warn({
11475
+ logger$8.warn({
11474
11476
  pid,
11475
11477
  err: msg
11476
11478
  }, "Failed to kill orchestrator");
@@ -11500,7 +11502,7 @@ async function runCancelAction(options) {
11500
11502
  await adapter.close();
11501
11503
  }
11502
11504
  } catch (err) {
11503
- logger$7.warn({ err }, "Could not update pipeline run status (non-fatal)");
11505
+ logger$8.warn({ err }, "Could not update pipeline run status (non-fatal)");
11504
11506
  }
11505
11507
  if (outputFormat === "json") process.stdout.write(formatOutput({
11506
11508
  cancelled: true,
@@ -11653,7 +11655,7 @@ function emitDiff(diff, ctx) {
11653
11655
 
11654
11656
  //#endregion
11655
11657
  //#region src/cli/commands/probe-author.ts
11656
- const logger$6 = createLogger("cli:probe-author");
11658
+ const logger$7 = createLogger("cli:probe-author");
11657
11659
  /**
11658
11660
  * A minimum-viable logger that routes everything to stderr. Used by the
11659
11661
  * subcommand to keep stdout reserved for the JSON result payload.
@@ -11722,7 +11724,7 @@ async function runProbeAuthorDispatch(opts, projectRoot, registry) {
11722
11724
  logger: stderrLogger
11723
11725
  });
11724
11726
  const workingDir = opts.workingDir !== void 0 ? resolve$1(opts.workingDir) : resolve$1(storyFilePath, "..");
11725
- logger$6.info({
11727
+ logger$7.info({
11726
11728
  storyKey: opts.storyKey,
11727
11729
  storyFile: storyFilePath,
11728
11730
  epicFile: epicFilePath,
@@ -11944,7 +11946,7 @@ function registerHistoryCommand(program) {
11944
11946
 
11945
11947
  //#endregion
11946
11948
  //#region src/cli/commands/repo-map.ts
11947
- const logger$5 = createLogger("cli:repo-map");
11949
+ const logger$6 = createLogger("cli:repo-map");
11948
11950
  /** Validate that a symbol name contains only safe identifier characters. */
11949
11951
  function isValidSymbolName(name) {
11950
11952
  return /^[a-zA-Z0-9_]+$/.test(name);
@@ -11979,15 +11981,15 @@ function registerRepoMapCommand(program) {
11979
11981
  const colRows = await doltClient.query(`SHOW COLUMNS FROM repo_map_symbols LIKE 'dependencies'`);
11980
11982
  if (colRows.length === 0) {
11981
11983
  await doltClient.query(`ALTER TABLE repo_map_symbols ADD COLUMN dependencies JSON`);
11982
- logger$5.info("Applied migration: added dependencies column to repo_map_symbols");
11984
+ logger$6.info("Applied migration: added dependencies column to repo_map_symbols");
11983
11985
  }
11984
11986
  } catch {
11985
- logger$5.debug("Skipping repo_map_symbols migration: table not yet created");
11987
+ logger$6.debug("Skipping repo_map_symbols migration: table not yet created");
11986
11988
  }
11987
- const symbolRepo = new DoltSymbolRepository(doltClient, logger$5);
11989
+ const symbolRepo = new DoltSymbolRepository(doltClient, logger$6);
11988
11990
  const metaRepo = new DoltRepoMapMetaRepository(doltClient);
11989
- const repoMapModule = new RepoMapModule(metaRepo, logger$5);
11990
- const queryEngine = new RepoMapQueryEngine(symbolRepo, logger$5);
11991
+ const repoMapModule = new RepoMapModule(metaRepo, logger$6);
11992
+ const queryEngine = new RepoMapQueryEngine(symbolRepo, logger$6);
11991
11993
  if (options.show === true || !options.update && !options.query && !options.dryRun) {
11992
11994
  const meta = await metaRepo.getMeta();
11993
11995
  const staleResult = await repoMapModule.checkStaleness();
@@ -12013,9 +12015,9 @@ function registerRepoMapCommand(program) {
12013
12015
  return;
12014
12016
  }
12015
12017
  if (options.update === true) {
12016
- logger$5.info("repo-map --update: triggering incremental update");
12017
- const gitClient = new GitClient(logger$5);
12018
- const grammarLoader = new GrammarLoader(logger$5);
12018
+ logger$6.info("repo-map --update: triggering incremental update");
12019
+ const gitClient = new GitClient(logger$6);
12020
+ const grammarLoader = new GrammarLoader(logger$6);
12019
12021
  if (grammarLoader.getGrammar(".ts") === null) {
12020
12022
  const msg = "tree-sitter grammars not installed. Run `npm install tree-sitter tree-sitter-typescript tree-sitter-javascript tree-sitter-python` in the substrate installation directory.";
12021
12023
  if (options.outputFormat === "json") console.log(JSON.stringify({
@@ -12026,15 +12028,15 @@ function registerRepoMapCommand(program) {
12026
12028
  process.exitCode = 1;
12027
12029
  return;
12028
12030
  }
12029
- const parser = new SymbolParser(grammarLoader, logger$5);
12030
- const storage = new RepoMapStorage(symbolRepo, metaRepo, gitClient, logger$5);
12031
+ const parser = new SymbolParser(grammarLoader, logger$6);
12032
+ const storage = new RepoMapStorage(symbolRepo, metaRepo, gitClient, logger$6);
12031
12033
  let updateWarning;
12032
12034
  try {
12033
12035
  await storage.incrementalUpdate(dbRoot, parser);
12034
12036
  } catch (err) {
12035
12037
  if (err instanceof AppError && err.code === ERR_REPO_MAP_STORAGE_WRITE) {
12036
12038
  updateWarning = err.message;
12037
- logger$5.warn({ err }, "repo-map --update: storage write error (partial update)");
12039
+ logger$6.warn({ err }, "repo-map --update: storage write error (partial update)");
12038
12040
  } else throw err;
12039
12041
  }
12040
12042
  const meta = await metaRepo.getMeta();
@@ -12054,7 +12056,7 @@ function registerRepoMapCommand(program) {
12054
12056
  return;
12055
12057
  }
12056
12058
  if (options.query !== void 0) {
12057
- logger$5.debug({ symbol: options.query }, "repo-map --query");
12059
+ logger$6.debug({ symbol: options.query }, "repo-map --query");
12058
12060
  const result = await queryEngine.query({
12059
12061
  symbols: [options.query],
12060
12062
  maxTokens: 4e3
@@ -12076,7 +12078,7 @@ function registerRepoMapCommand(program) {
12076
12078
  process.exitCode = 1;
12077
12079
  return;
12078
12080
  }
12079
- const injector = new RepoMapInjector(queryEngine, logger$5);
12081
+ const injector = new RepoMapInjector(queryEngine, logger$6);
12080
12082
  const injectionResult = await injector.buildContext(storyContent, 2e3);
12081
12083
  console.log(JSON.stringify({
12082
12084
  text: injectionResult.text,
@@ -12090,7 +12092,7 @@ function registerRepoMapCommand(program) {
12090
12092
 
12091
12093
  //#endregion
12092
12094
  //#region src/cli/commands/routing.ts
12093
- const logger$4 = createLogger("cli:routing");
12095
+ const logger$5 = createLogger("cli:routing");
12094
12096
  function registerRoutingCommand(program) {
12095
12097
  program.command("routing").description("Show routing configuration and auto-tune history").option("--history", "Show the routing auto-tune log (model changes applied)").option("--output-format <format>", "Output format: text or json", "text").action(async (options) => {
12096
12098
  const dbRoot = await resolveMainRepoRoot(process.cwd());
@@ -12098,7 +12100,7 @@ function registerRoutingCommand(program) {
12098
12100
  try {
12099
12101
  await store.initialize();
12100
12102
  if (options.history === true) {
12101
- logger$4.debug("routing --history: fetching tune log");
12103
+ logger$5.debug("routing --history: fetching tune log");
12102
12104
  const raw$1 = await store.getMetric("global", "routing_tune_log");
12103
12105
  let entries = [];
12104
12106
  if (Array.isArray(raw$1)) entries = raw$1.sort((a, b) => b.appliedAt.localeCompare(a.appliedAt));
@@ -12393,7 +12395,7 @@ function registerFactoryCommand$1(program) {
12393
12395
 
12394
12396
  //#endregion
12395
12397
  //#region src/cli/commands/reconcile-from-disk.ts
12396
- const logger$3 = createLogger("reconcile-from-disk");
12398
+ const logger$4 = createLogger("reconcile-from-disk");
12397
12399
  /**
12398
12400
  * The reconcile write (obs_2026-05-26_031). Keyed on `story_key` ALONE —
12399
12401
  * `wg_stories` has no `run_id` column (cols: story_key, epic, title, status,
@@ -12465,7 +12467,7 @@ async function readRunEntry(dbRoot, resolvedRunId) {
12465
12467
  stories
12466
12468
  };
12467
12469
  } catch {
12468
- logger$3.debug({ runId: resolvedRunId }, "failed to read individual run manifest");
12470
+ logger$4.debug({ runId: resolvedRunId }, "failed to read individual run manifest");
12469
12471
  return null;
12470
12472
  }
12471
12473
  }
@@ -12600,7 +12602,7 @@ async function runReconcileFromDiskAction(options) {
12600
12602
  const latestRun = await getLatestRun(probeAdapter);
12601
12603
  if (latestRun?.id) resolvedRunId = latestRun.id;
12602
12604
  } catch {
12603
- logger$3.debug("Dolt fallback failed during run-id resolution");
12605
+ logger$4.debug("Dolt fallback failed during run-id resolution");
12604
12606
  } finally {
12605
12607
  await probeAdapter.close().catch(swallowDebug("reconcile-probe-close"));
12606
12608
  }
@@ -12681,7 +12683,7 @@ async function runReconcileFromDiskAction(options) {
12681
12683
  stdoutTail: failedGateResult?.stdoutTail,
12682
12684
  durationMs: durationMs$1
12683
12685
  });
12684
- logger$3.info({
12686
+ logger$4.info({
12685
12687
  runId: resolvedRunId,
12686
12688
  failedGate: failedGateName,
12687
12689
  exitCode: failedGateResult?.exitCode
@@ -12739,7 +12741,7 @@ async function runReconcileFromDiskAction(options) {
12739
12741
  record.storyKey
12740
12742
  ]);
12741
12743
  });
12742
- logger$3.info({
12744
+ logger$4.info({
12743
12745
  runId: resolvedRunId,
12744
12746
  affectedStories: reconcilableRecords.map((r) => r.storyKey)
12745
12747
  }, "reconcile-from-disk: Dolt update complete");
@@ -12794,7 +12796,7 @@ function registerReconcileFromDiskCommand(program, _version = "0.0.0", projectRo
12794
12796
 
12795
12797
  //#endregion
12796
12798
  //#region src/cli/commands/report.ts
12797
- const logger$2 = createLogger("report");
12799
+ const logger$3 = createLogger("report");
12798
12800
  /**
12799
12801
  * v0.20.110: Minimum output_tokens for a verified/recovered story to be
12800
12802
  * trusted as having actually produced work. Below this, the story is flagged
@@ -12949,7 +12951,7 @@ async function readNotificationsForRun(runId, dbRoot) {
12949
12951
  const parsed = JSON.parse(raw);
12950
12952
  notifications.push(parsed);
12951
12953
  } catch (err) {
12952
- if (err.code !== "ENOENT") logger$2.warn({
12954
+ if (err.code !== "ENOENT") logger$3.warn({
12953
12955
  err,
12954
12956
  filePath
12955
12957
  }, "failed to read notification file — skipping");
@@ -12958,7 +12960,7 @@ async function readNotificationsForRun(runId, dbRoot) {
12958
12960
  try {
12959
12961
  await unlink(filePath);
12960
12962
  } catch (err) {
12961
- if (err.code !== "ENOENT") logger$2.warn({
12963
+ if (err.code !== "ENOENT") logger$3.warn({
12962
12964
  err,
12963
12965
  filePath
12964
12966
  }, "failed to delete notification file — continuing");
@@ -13291,7 +13293,7 @@ async function resolveLatestRunId(dbRoot) {
13291
13293
  const latest = await getLatestRun(probeAdapter);
13292
13294
  return latest?.id ?? null;
13293
13295
  } catch {
13294
- logger$2.debug("Dolt fallback failed during run-id resolution");
13296
+ logger$3.debug("Dolt fallback failed during run-id resolution");
13295
13297
  return null;
13296
13298
  } finally {
13297
13299
  await probeAdapter.close().catch(swallowDebug("report-probe-close"));
@@ -13302,7 +13304,7 @@ async function runReportAction(options) {
13302
13304
  const effectiveProjectRoot = process.env["SUBSTRATE_PROJECT_ROOT"] ?? projectRoot;
13303
13305
  const dbRoot = _dbRoot ?? await resolveMainRepoRoot(effectiveProjectRoot);
13304
13306
  const runsDir = join(dbRoot, ".substrate", "runs");
13305
- logger$2.debug({
13307
+ logger$3.debug({
13306
13308
  runArg,
13307
13309
  effectiveProjectRoot,
13308
13310
  dbRoot
@@ -13317,7 +13319,7 @@ async function runReportAction(options) {
13317
13319
  const data = await canonical.manifest.read();
13318
13320
  manifest = data;
13319
13321
  } catch {
13320
- logger$2.debug({ runId: resolvedRunId }, "canonical manifest read failed — using raw shim");
13322
+ logger$3.debug({ runId: resolvedRunId }, "canonical manifest read failed — using raw shim");
13321
13323
  }
13322
13324
  if (!manifest) manifest = await readRawManifest(runsDir, resolvedRunId);
13323
13325
  } else {
@@ -13328,7 +13330,7 @@ async function runReportAction(options) {
13328
13330
  const data = await canonical.manifest.read();
13329
13331
  manifest = data;
13330
13332
  } catch {
13331
- logger$2.debug({ runId: canonical.runId }, "canonical manifest read failed — using raw shim");
13333
+ logger$3.debug({ runId: canonical.runId }, "canonical manifest read failed — using raw shim");
13332
13334
  manifest = null;
13333
13335
  }
13334
13336
  }
@@ -13340,7 +13342,7 @@ async function runReportAction(options) {
13340
13342
  const data = await reread.manifest.read();
13341
13343
  manifest = data;
13342
13344
  } catch {
13343
- logger$2.debug({ runId: resolvedRunId }, "manifest read failed after Dolt resolution");
13345
+ logger$3.debug({ runId: resolvedRunId }, "manifest read failed after Dolt resolution");
13344
13346
  }
13345
13347
  if (!manifest) manifest = await readRawManifest(runsDir, resolvedRunId);
13346
13348
  }
@@ -13369,18 +13371,18 @@ async function runReportAction(options) {
13369
13371
  const state = manifest.per_story_state[row.story_key];
13370
13372
  if (state && !state.completed_at && row.completed_at) state.completed_at = row.completed_at;
13371
13373
  }
13372
- logger$2.debug({ storyCount: rows.length }, "Dolt wg_stories enrichment applied");
13374
+ logger$3.debug({ storyCount: rows.length }, "Dolt wg_stories enrichment applied");
13373
13375
  }
13374
13376
  } catch (err) {
13375
- logger$2.debug({ err }, "Dolt enrichment unavailable — using manifest-only data (degraded mode)");
13377
+ logger$3.debug({ err }, "Dolt enrichment unavailable — using manifest-only data (degraded mode)");
13376
13378
  } finally {
13377
13379
  if (doltClient !== null) await doltClient.close().catch((err) => {
13378
- logger$2.debug({ err }, "DoltClient.close() failed — non-fatal");
13380
+ logger$3.debug({ err }, "DoltClient.close() failed — non-fatal");
13379
13381
  });
13380
13382
  }
13381
13383
  }
13382
13384
  const halts = await readNotificationsForRun(resolvedRunId, dbRoot).catch((err) => {
13383
- logger$2.debug({ err }, "notification read failed — continuing without halt data");
13385
+ logger$3.debug({ err }, "notification read failed — continuing without halt data");
13384
13386
  return [];
13385
13387
  });
13386
13388
  const storyOutputTokens = new Map();
@@ -13393,7 +13395,7 @@ async function runReportAction(options) {
13393
13395
  const storyMetricsRows = await getStoryMetricsForRun(metricsAdapter, resolvedRunId);
13394
13396
  for (const row of storyMetricsRows) if (typeof row.output_tokens === "number") storyOutputTokens.set(row.story_key, row.output_tokens);
13395
13397
  } catch (err) {
13396
- logger$2.debug({ err }, "story_metrics read failed — low-output flagging unavailable");
13398
+ logger$3.debug({ err }, "story_metrics read failed — low-output flagging unavailable");
13397
13399
  } finally {
13398
13400
  await metricsAdapter.close().catch(swallowDebug("report-metrics-close"));
13399
13401
  }
@@ -13407,7 +13409,7 @@ async function runReportAction(options) {
13407
13409
  const rmData = await rmForAc.read();
13408
13410
  acPerStoryState = rmData.per_story_state;
13409
13411
  } catch {
13410
- logger$2.debug({ runId: resolvedRunId }, "RunManifest.read() for --verify-ac failed — using raw manifest fallback");
13412
+ logger$3.debug({ runId: resolvedRunId }, "RunManifest.read() for --verify-ac failed — using raw manifest fallback");
13411
13413
  }
13412
13414
  const storyEntries = Object.entries(acPerStoryState);
13413
13415
  for (const [storyKey, state] of storyEntries) {
@@ -13429,7 +13431,7 @@ async function runReportAction(options) {
13429
13431
  confidence: result.confidence
13430
13432
  };
13431
13433
  } catch (err) {
13432
- logger$2.debug({
13434
+ logger$3.debug({
13433
13435
  err,
13434
13436
  storyKey
13435
13437
  }, "ac traceability check failed for story (skipping)");
@@ -13464,9 +13466,9 @@ function registerReportCommand(program, _version = "0.0.0", projectRoot = proces
13464
13466
 
13465
13467
  //#endregion
13466
13468
  //#region src/modules/compiled-workflows/acceptance-derive.ts
13467
- const logger$1 = createLogger("compiled-workflows:acceptance-derive");
13469
+ const logger$2 = createLogger("compiled-workflows:acceptance-derive");
13468
13470
  /** Cap on injected source-document content (chars) — PRDs can be book-length. */
13469
- const SOURCE_CONTENT_CAP = 12e4;
13471
+ const SOURCE_CONTENT_CAP$1 = 12e4;
13470
13472
  /** Shape problems the schema can't express: duplicate ids, id/end-state prefix drift. */
13471
13473
  function validateDerivedJourneys(journeys) {
13472
13474
  if (journeys.length === 0) return "derive produced zero journeys — a PRD with no identifiable user journeys should be reported via result: failed with an error, not an empty success";
@@ -13493,7 +13495,7 @@ async function runAcceptanceDerive(deps, params) {
13493
13495
  }
13494
13496
  };
13495
13497
  }
13496
- const truncated = prdContent.length > SOURCE_CONTENT_CAP;
13498
+ const truncated = prdContent.length > SOURCE_CONTENT_CAP$1;
13497
13499
  const buildPrompt = (correctivePreamble) => {
13498
13500
  const { prompt } = assemblePrompt(template, [
13499
13501
  {
@@ -13503,7 +13505,7 @@ async function runAcceptanceDerive(deps, params) {
13503
13505
  },
13504
13506
  {
13505
13507
  name: "source_content",
13506
- content: (truncated ? `(truncated to first ${String(SOURCE_CONTENT_CAP)} chars)\n` : "") + prdContent.slice(0, SOURCE_CONTENT_CAP),
13508
+ content: (truncated ? `(truncated to first ${String(SOURCE_CONTENT_CAP$1)} chars)\n` : "") + prdContent.slice(0, SOURCE_CONTENT_CAP$1),
13507
13509
  priority: "required"
13508
13510
  },
13509
13511
  {
@@ -13556,7 +13558,7 @@ async function runAcceptanceDerive(deps, params) {
13556
13558
  const parsed = AcceptanceDeriveResultSchema.safeParse(dispatchResult.parsed);
13557
13559
  if (!parsed.success) {
13558
13560
  lastProblem = `output failed schema validation (${parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ").slice(0, 500)})`;
13559
- logger$1.warn({
13561
+ logger$2.warn({
13560
13562
  prdRelPath,
13561
13563
  attempt,
13562
13564
  lastProblem
@@ -13572,14 +13574,14 @@ async function runAcceptanceDerive(deps, params) {
13572
13574
  const shapeProblem = validateDerivedJourneys(parsed.data.journeys);
13573
13575
  if (shapeProblem !== void 0) {
13574
13576
  lastProblem = shapeProblem;
13575
- logger$1.warn({
13577
+ logger$2.warn({
13576
13578
  prdRelPath,
13577
13579
  attempt,
13578
13580
  shapeProblem
13579
13581
  }, "RP1.1: derived journeys malformed");
13580
13582
  continue;
13581
13583
  }
13582
- logger$1.info({
13584
+ logger$2.info({
13583
13585
  prdRelPath,
13584
13586
  journeys: parsed.data.journeys.map((j) => `${j.id}[${j.criticality}]`)
13585
13587
  }, "RP1.1: derive candidates accepted");
@@ -13597,6 +13599,159 @@ async function runAcceptanceDerive(deps, params) {
13597
13599
  };
13598
13600
  }
13599
13601
 
13602
+ //#endregion
13603
+ //#region src/modules/compiled-workflows/acceptance-completeness.ts
13604
+ const logger$1 = createLogger("compiled-workflows:acceptance-completeness");
13605
+ const SOURCE_CONTENT_CAP = 12e4;
13606
+ function normalizeForGrounding(s) {
13607
+ return s.replace(/\s+/g, " ").trim().toLowerCase();
13608
+ }
13609
+ /**
13610
+ * Validate claims against the registry and the PRD (deterministic, no LLM):
13611
+ * - registered claims must cite a real journey id
13612
+ * - excluded claims must cite a real exclusion candidate
13613
+ * - every prd_span must ground in the document (≥0.6 substantive-token
13614
+ * overlap — the judge's F7-calibrated threshold; verbatim quotes of a
13615
+ * 120k-char document ground trivially, fabrications don't)
13616
+ */
13617
+ function validateCompletenessClaims(claims, registry, prdContent) {
13618
+ const registered = new Set(registry.journeys.map((j) => j.id));
13619
+ const excluded = new Set((registry.provenance?.excluded ?? []).map((e) => e.candidate));
13620
+ const haystack = ` ${normalizeForGrounding(prdContent)} `;
13621
+ for (const claim of claims) {
13622
+ if (claim.disposition === "registered") {
13623
+ if (claim.registry_ref === void 0 || !registered.has(claim.registry_ref)) return `claim "${claim.description}" says registered but cites no real registry id (got ${JSON.stringify(claim.registry_ref)})`;
13624
+ }
13625
+ if (claim.disposition === "excluded") {
13626
+ if (claim.registry_ref === void 0 || !excluded.has(claim.registry_ref)) return `claim "${claim.description}" says excluded but cites no real exclusion candidate (got ${JSON.stringify(claim.registry_ref)})`;
13627
+ }
13628
+ const tokens = normalizeForGrounding(claim.prd_span).split(" ").map((t) => t.replace(/[^a-z0-9]/g, "")).filter((t) => t.length >= 4);
13629
+ if (tokens.length < 2) return `claim "${claim.description}" cites too thin a prd_span ("${claim.prd_span}") — quote a substantive span of the document`;
13630
+ const present = tokens.filter((t) => haystack.includes(t)).length;
13631
+ if (present / tokens.length < .6) return `claim "${claim.description}" prd_span does not appear in the document (only ${String(present)}/${String(tokens.length)} tokens present — fabricated citation?)`;
13632
+ }
13633
+ return void 0;
13634
+ }
13635
+ function renderRegistryForPrompt(registry) {
13636
+ const journeys = registry.journeys.map((j) => `- id: ${j.id}\n title: ${j.title}\n criticality: ${j.criticality}`).join("\n");
13637
+ const excluded = (registry.provenance?.excluded ?? []).map((e) => `- candidate: ${e.candidate}\n reason: ${e.reason}`).join("\n");
13638
+ return `Registered journeys (version ${String(registry.version)}):\n${journeys || "(none)"}\n\nOperator-excluded candidates:\n${excluded || "(none)"}`;
13639
+ }
13640
+ async function runCompletenessCheck(deps, params) {
13641
+ const { prdRelPath, prdContent, registry } = params;
13642
+ let template;
13643
+ try {
13644
+ template = await deps.pack.getPrompt("acceptance-completeness");
13645
+ } catch (err) {
13646
+ return {
13647
+ result: "failed",
13648
+ error: `Failed to retrieve acceptance-completeness prompt: ${err instanceof Error ? err.message : String(err)}`,
13649
+ tokenUsage: {
13650
+ input: 0,
13651
+ output: 0
13652
+ }
13653
+ };
13654
+ }
13655
+ const truncated = prdContent.length > SOURCE_CONTENT_CAP;
13656
+ const buildPrompt = (correctivePreamble) => {
13657
+ const { prompt } = assemblePrompt(template, [
13658
+ {
13659
+ name: "source_path",
13660
+ content: prdRelPath,
13661
+ priority: "required"
13662
+ },
13663
+ {
13664
+ name: "source_content",
13665
+ content: (truncated ? `(truncated to first ${String(SOURCE_CONTENT_CAP)} chars)\n` : "") + prdContent.slice(0, SOURCE_CONTENT_CAP),
13666
+ priority: "required"
13667
+ },
13668
+ {
13669
+ name: "registry_summary",
13670
+ content: renderRegistryForPrompt(registry),
13671
+ priority: "required"
13672
+ }
13673
+ ], getTokenCeiling("acceptance-completeness", deps.tokenCeilings).ceiling);
13674
+ return correctivePreamble !== void 0 ? `${correctivePreamble}\n\n${prompt}` : prompt;
13675
+ };
13676
+ let totalTokens = {
13677
+ input: 0,
13678
+ output: 0
13679
+ };
13680
+ let lastProblem = "unknown";
13681
+ for (let attempt = 0; attempt < 2; attempt++) {
13682
+ const prompt = attempt === 0 ? buildPrompt() : buildPrompt(`PREVIOUS ATTEMPT REJECTED: ${lastProblem}. Emit ONLY the YAML block per the Output Contract — every claim with a VERBATIM prd_span; registered/excluded claims must cite real registry_ref values.`);
13683
+ const handle = deps.dispatcher.dispatch({
13684
+ prompt,
13685
+ agent: deps.agentId ?? "claude-code",
13686
+ taskType: "acceptance-completeness",
13687
+ outputSchema: AcceptanceCompletenessResultSchema,
13688
+ maxTurns: 30,
13689
+ ...deps.otlpEndpoint !== void 0 ? { otlpEndpoint: deps.otlpEndpoint } : {}
13690
+ });
13691
+ let dispatchResult;
13692
+ try {
13693
+ dispatchResult = await handle.result;
13694
+ } catch (err) {
13695
+ return {
13696
+ result: "failed",
13697
+ error: `Dispatch error: ${err instanceof Error ? err.message : String(err)}`,
13698
+ tokenUsage: totalTokens
13699
+ };
13700
+ }
13701
+ totalTokens = {
13702
+ input: totalTokens.input + dispatchResult.tokenEstimate.input,
13703
+ output: totalTokens.output + dispatchResult.tokenEstimate.output
13704
+ };
13705
+ if (dispatchResult.status === "failed" || dispatchResult.status === "timeout") return {
13706
+ result: "failed",
13707
+ error: `Dispatch status: ${dispatchResult.status}. ${dispatchResult.parseError ?? ""}`.trim(),
13708
+ tokenUsage: totalTokens
13709
+ };
13710
+ const parsed = AcceptanceCompletenessResultSchema.safeParse(dispatchResult.parsed);
13711
+ if (!parsed.success) {
13712
+ lastProblem = `output failed schema validation (${parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ").slice(0, 500)})`;
13713
+ logger$1.warn({
13714
+ prdRelPath,
13715
+ attempt,
13716
+ lastProblem
13717
+ }, "RP3.2: completeness output invalid");
13718
+ continue;
13719
+ }
13720
+ if (parsed.data.result === "failed") return {
13721
+ result: "failed",
13722
+ error: "acceptance-completeness-refused",
13723
+ details: parsed.data.error ?? "checker reported failure without a reason",
13724
+ tokenUsage: totalTokens
13725
+ };
13726
+ const problem = validateCompletenessClaims(parsed.data.claims, registry, prdContent);
13727
+ if (problem !== void 0) {
13728
+ lastProblem = problem;
13729
+ logger$1.warn({
13730
+ prdRelPath,
13731
+ attempt,
13732
+ problem
13733
+ }, "RP3.2: completeness claims failed validation");
13734
+ continue;
13735
+ }
13736
+ logger$1.info({
13737
+ prdRelPath,
13738
+ claims: parsed.data.claims.length,
13739
+ undispositioned: parsed.data.claims.filter((c) => c.disposition === "undispositioned").length
13740
+ }, "RP3.2: completeness claims accepted");
13741
+ return {
13742
+ result: "success",
13743
+ claims: parsed.data.claims,
13744
+ tokenUsage: totalTokens
13745
+ };
13746
+ }
13747
+ return {
13748
+ result: "failed",
13749
+ error: "acceptance-completeness-invalid",
13750
+ details: `checker produced invalid output twice — last problem: ${lastProblem}`,
13751
+ tokenUsage: totalTokens
13752
+ };
13753
+ }
13754
+
13600
13755
  //#endregion
13601
13756
  //#region src/cli/commands/acceptance.ts
13602
13757
  const ACCEPTANCE_EXIT_SUCCESS = 0;
@@ -13649,7 +13804,7 @@ async function listFilesRecursive(root, base = root) {
13649
13804
  }
13650
13805
  function registerAcceptanceCommand(program, version, registry) {
13651
13806
  const acceptanceCmd = program.command("acceptance").description("Acceptance Gate — journey registry tools (the missing sprint demo)");
13652
- acceptanceCmd.command("validate").description(`Lint ${JOURNEY_REGISTRY_PATH} with actionable, pathed errors`).option("--ref <ref>", "validate the COMMITTED registry at a git ref (trusted-tree read) instead of the working tree").option("--output-format <format>", "Output format: text (default) or json", "text").action(async (opts) => {
13807
+ acceptanceCmd.command("validate").description(`Lint ${JOURNEY_REGISTRY_PATH} with actionable, pathed errors`).option("--ref <ref>", "validate the COMMITTED registry at a git ref (trusted-tree read) instead of the working tree").option("--against-prd [path]", "RP3.2: run the completeness checker agent — every PRD journey must be registered or excluded (advisory findings; defaults to provenance.derived_from)").option("--agent <id>", "agent adapter id for --against-prd", "claude-code").option("--pack <name>", "methodology pack carrying the completeness prompt", "bmad").option("--output-format <format>", "Output format: text (default) or json", "text").action(async (opts) => {
13653
13808
  const projectRoot = process.cwd();
13654
13809
  const source = opts.ref !== void 0 ? `committed @ ${opts.ref}` : "working tree";
13655
13810
  const result = opts.ref !== void 0 ? await loadJourneyRegistryFromTrustedTree(projectRoot, opts.ref) : await loadJourneyRegistryFromFile(projectRoot);
@@ -13675,6 +13830,82 @@ function registerAcceptanceCommand(program, version, registry) {
13675
13830
  }
13676
13831
  staleness = checkRegistryStaleness(result.registry, sourceContent);
13677
13832
  }
13833
+ let completeness;
13834
+ if (opts.againstPrd !== void 0 && opts.againstPrd !== false) if (result.status !== "ok") completeness = {
13835
+ status: "failed",
13836
+ error: "registry must validate before a completeness check"
13837
+ };
13838
+ else if (registry === void 0) completeness = {
13839
+ status: "failed",
13840
+ error: "adapter registry unavailable in this invocation context"
13841
+ };
13842
+ else {
13843
+ const prdRel = typeof opts.againstPrd === "string" ? opts.againstPrd : result.registry.provenance?.derived_from;
13844
+ if (prdRel === void 0) completeness = {
13845
+ status: "failed",
13846
+ error: "no PRD path — pass --against-prd <path> or ratify with provenance first"
13847
+ };
13848
+ else if (!isProjectContainedPath(prdRel)) completeness = {
13849
+ status: "failed",
13850
+ error: `PRD path "${prdRel}" resolves outside the project`
13851
+ };
13852
+ else {
13853
+ let prdContent;
13854
+ try {
13855
+ prdContent = await readFile$1(join$1(projectRoot, prdRel), "utf-8");
13856
+ } catch (err) {
13857
+ completeness = {
13858
+ status: "failed",
13859
+ error: `cannot read PRD at ${prdRel}: ${String(err)}`
13860
+ };
13861
+ }
13862
+ if (prdContent !== void 0) {
13863
+ if (process.env.LOG_LEVEL === void 0) process.env.LOG_LEVEL = "silent";
13864
+ const eventBus = createEventBus();
13865
+ const adapter = new InMemoryDatabaseAdapter();
13866
+ const packLoader = createPackLoader();
13867
+ try {
13868
+ const pack = await packLoader.load(join$1(projectRoot, "packs", opts.pack));
13869
+ const contextCompiler = createContextCompiler({ db: adapter });
13870
+ const dispatcher = createDispatcher({
13871
+ eventBus,
13872
+ adapterRegistry: registry,
13873
+ logger: {
13874
+ debug: () => {},
13875
+ info: () => {},
13876
+ warn: () => {},
13877
+ error: () => {}
13878
+ }
13879
+ });
13880
+ process.stderr.write(`completeness check against ${prdRel} (real agent dispatch — may take a few minutes)…\n`);
13881
+ const check = await runCompletenessCheck({
13882
+ db: adapter,
13883
+ pack,
13884
+ contextCompiler,
13885
+ dispatcher,
13886
+ agentId: opts.agent
13887
+ }, {
13888
+ prdRelPath: prdRel,
13889
+ prdContent,
13890
+ registry: result.registry
13891
+ });
13892
+ await dispatcher.shutdown();
13893
+ completeness = check.result === "success" && check.claims !== void 0 ? {
13894
+ status: "ran",
13895
+ claims: check.claims
13896
+ } : {
13897
+ status: "failed",
13898
+ error: `${check.error ?? "unknown"}${check.details !== void 0 ? `: ${check.details}` : ""}`
13899
+ };
13900
+ } catch (err) {
13901
+ completeness = {
13902
+ status: "failed",
13903
+ error: `failed to load pack '${opts.pack}': ${String(err)}`
13904
+ };
13905
+ }
13906
+ }
13907
+ }
13908
+ }
13678
13909
  if (opts.outputFormat === "json") {
13679
13910
  const output = buildJsonOutput("substrate acceptance validate", {
13680
13911
  source,
@@ -13683,7 +13914,8 @@ function registerAcceptanceCommand(program, version, registry) {
13683
13914
  provenance: {
13684
13915
  status: result.status === "ok" && result.registry.provenance !== void 0 ? "present" : "absent",
13685
13916
  ...staleness !== void 0 ? { staleness: staleness.status } : {}
13686
- }
13917
+ },
13918
+ ...completeness !== void 0 ? { completeness } : {}
13687
13919
  }, version);
13688
13920
  process.stdout.write(JSON.stringify(output, null, 2) + "\n");
13689
13921
  process.exit(result.status === "ok" ? ACCEPTANCE_EXIT_SUCCESS : ACCEPTANCE_EXIT_ERROR);
@@ -13712,6 +13944,13 @@ function registerAcceptanceCommand(program, version, registry) {
13712
13944
  for (const issue of contract.issues) process.stdout.write(` ${issue.path}: ${issue.message}\n`);
13713
13945
  } else if (contract.status === "absent") process.stdout.write(`contract: ABSENT — no acceptance: block in ${ACCEPTANCE_CONTRACT_PROFILE_PATH}. Claimed journeys can never be walked (acceptance-unrunnable in blocking mode).
13714
13946
  `);
13947
+ if (completeness !== void 0) if (completeness.status === "failed") process.stdout.write(`completeness: CHECK FAILED — ${completeness.error}\n`);
13948
+ else {
13949
+ const undispositioned = completeness.claims.filter((c) => c.disposition === "undispositioned");
13950
+ process.stdout.write(`completeness: ${String(completeness.claims.length)} journey-shaped claim(s) in the PRD — ${String(completeness.claims.filter((c) => c.disposition === "registered").length)} registered, ${String(completeness.claims.filter((c) => c.disposition === "excluded").length)} excluded, ${String(undispositioned.length)} UNDISPOSITIONED\n`);
13951
+ for (const c of completeness.claims) if (c.disposition === "undispositioned") process.stdout.write(` journey-undispositioned (advisory): "${c.description}"\n PRD span: "${c.prd_span}"\n resolve: register it (derive + ratify) or exclude it with a reason (ratify --exclude)\n`);
13952
+ else process.stdout.write(` ${c.disposition}: "${c.description}" → ${c.registry_ref ?? ""}\n`);
13953
+ }
13715
13954
  process.exit(exitCode);
13716
13955
  });
13717
13956
  acceptanceCmd.command("defer <journeyId>").description("Record an operator deferral for a journey — the coverage audit reports it `deferred` instead of unclaimed/unwalked. Writes to the working tree; COMMIT the file for the audit (trusted tree) to honor it.").requiredOption("--reason <text>", "why this journey is deferred (the operator ack is the point)").action(async (journeyId, opts) => {
@@ -14094,7 +14333,7 @@ function registerAcceptanceCommand(program, version, registry) {
14094
14333
  process.exit(ACCEPTANCE_EXIT_ERROR);
14095
14334
  return;
14096
14335
  }
14097
- const { runAcceptanceJudge: runAcceptanceJudge$1 } = await import("../acceptance-judge-D5Iba2D_.js");
14336
+ const { runAcceptanceJudge: runAcceptanceJudge$1 } = await import("../acceptance-judge-BStwKVzD.js");
14098
14337
  const eventBus = createEventBus();
14099
14338
  const adapter = new InMemoryDatabaseAdapter();
14100
14339
  const packLoader = createPackLoader();