substrate-ai 0.20.64 → 0.20.66

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.
Files changed (35) hide show
  1. package/dist/adapter-registry-BbVWH3Yv.js +4 -0
  2. package/dist/cli/index.js +172 -25
  3. package/dist/{decision-router-BA__VYIp.js → decision-router-DblHY8se.js} +1 -1
  4. package/dist/{decisions-4F91LrVD.js → decisions-DilHo99V.js} +2 -2
  5. package/dist/{dist-W2emvN3F.js → dist-K_RRWnBX.js} +2 -2
  6. package/dist/{errors-CKFu8YI9.js → errors-pSiZbn6e.js} +2 -2
  7. package/dist/{experimenter-BgpUcUaW.js → experimenter-DT9v2Pto.js} +1 -1
  8. package/dist/health-D6MKxV46.js +1715 -0
  9. package/dist/health-rGXaJvYJ.js +8 -0
  10. package/dist/index-c924O9mj.d.ts +1432 -0
  11. package/dist/index.d.ts +56 -735
  12. package/dist/index.js +2 -2
  13. package/dist/interactive-prompt-kzkG24Rn.js +183 -0
  14. package/dist/{health-DudlnqXd.js → manifest-read-g4zt3DXJ.js} +280 -2014
  15. package/dist/modules/interactive-prompt/index.d.ts +86 -0
  16. package/dist/modules/interactive-prompt/index.js +6 -0
  17. package/dist/recovery-engine-BKGBeBnW.js +281 -0
  18. package/dist/{routing-0ykvBl_4.js → routing-CzF0p6lI.js} +2 -2
  19. package/dist/{run-CCxsv-9M.js → run-7h2-DIjt.js} +282 -37
  20. package/dist/run-DB9P6m_P.js +14 -0
  21. package/dist/src/modules/decision-router/index.js +1 -1
  22. package/dist/src/modules/recovery-engine/index.d.ts +1101 -0
  23. package/dist/src/modules/recovery-engine/index.js +5 -0
  24. package/dist/{upgrade-OFeC_NIx.js → upgrade-DxzQ1nss.js} +3 -3
  25. package/dist/{upgrade-aW7GYL2F.js → upgrade-MP9XzrI6.js} +2 -2
  26. package/dist/version-manager-impl-GZDUBt0Q.js +4 -0
  27. package/dist/work-graph-repository-DZyJv5pV.js +265 -0
  28. package/package.json +1 -1
  29. package/dist/adapter-registry-k7ZX3Bz6.js +0 -4
  30. package/dist/health-CLNmnZiw.js +0 -6
  31. package/dist/run-ChxsPICN.js +0 -10
  32. package/dist/version-manager-impl-BCSf5E3j.js +0 -4
  33. /package/dist/{decisions-C0pz9Clx.js → decisions-CzSIEeGP.js} +0 -0
  34. /package/dist/{routing-CcBOCuC9.js → routing-DFxoKHDt.js} +0 -0
  35. /package/dist/{version-manager-impl-FH4TTnXm.js → version-manager-impl-qFBiO4Eh.js} +0 -0
@@ -1,8 +1,12 @@
1
- import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, FindingsInjector, RunManifest, RuntimeProbeListSchema, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectCycles, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, renderFindings, resolveGraphPath, resolveMainRepoRoot, runStaleVerificationRecovery, validateStoryKey } from "./health-DudlnqXd.js";
1
+ import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, validateStoryKey } from "./health-D6MKxV46.js";
2
2
  import { createLogger } from "./logger-KeHncl-f.js";
3
3
  import { TypedEventBusImpl, createEventBus, createTuiApp, isTuiCapable, printNonTtyWarning, sleep } from "./helpers-CElYrONe.js";
4
- import { ADVISORY_NOTES, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, IngestionServer, LogTurnAnalyzer, OPERATIONAL_FINDING, Recommender, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, callLLM, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-W2emvN3F.js";
5
- import { deriveExitCode, routeDecision } from "./decision-router-BA__VYIp.js";
4
+ import { ADVISORY_NOTES, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, IngestionServer, LogTurnAnalyzer, OPERATIONAL_FINDING, Recommender, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, callLLM, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-K_RRWnBX.js";
5
+ import { FindingsInjector, RunManifest, RuntimeProbeListSchema, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, renderFindings, resolveGraphPath, resolveMainRepoRoot, runAcTraceabilityCheck, runStaleVerificationRecovery } from "./manifest-read-g4zt3DXJ.js";
6
+ import { WorkGraphRepository, detectCycles } from "./work-graph-repository-DZyJv5pV.js";
7
+ import { deriveExitCode, routeDecision } from "./decision-router-DblHY8se.js";
8
+ import { runInteractivePrompt } from "./interactive-prompt-kzkG24Rn.js";
9
+ import { runRecoveryEngine } from "./recovery-engine-BKGBeBnW.js";
6
10
  import { basename, dirname, extname, join } from "path";
7
11
  import { access, readFile, readdir, stat } from "fs/promises";
8
12
  import { EventEmitter } from "node:events";
@@ -15,7 +19,7 @@ import path, { basename as basename$1, dirname as dirname$1, extname as extname$
15
19
  import { tmpdir } from "node:os";
16
20
  import { createHash, randomUUID } from "node:crypto";
17
21
  import { z } from "zod";
18
- import { access as access$1, lstat, mkdir as mkdir$1, readFile as readFile$1, readdir as readdir$1, readlink, realpath, rename, stat as stat$1, unlink, writeFile as writeFile$1 } from "node:fs/promises";
22
+ import { access as access$1, lstat, mkdir as mkdir$1, readFile as readFile$1, readdir as readdir$1, readlink, realpath, rename, stat as stat$1, unlink as unlink$1, writeFile as writeFile$1 } from "node:fs/promises";
19
23
  import { existsSync as existsSync$1, lstatSync, mkdirSync as mkdirSync$1, readFileSync as readFileSync$1, readdir as readdir$2, readdirSync as readdirSync$1, readlinkSync, realpathSync as realpathSync$1, unlinkSync as unlinkSync$1, writeFileSync as writeFileSync$1 } from "fs";
20
24
  import { promisify } from "node:util";
21
25
  import { fileURLToPath } from "node:url";
@@ -11309,7 +11313,8 @@ function assembleVerificationContext(opts) {
11309
11313
  storyContent: opts.storyContent,
11310
11314
  devStoryResult: opts.devStoryResult,
11311
11315
  outputTokenCount: opts.outputTokenCount,
11312
- sourceEpicContent: opts.sourceEpicContent
11316
+ sourceEpicContent: opts.sourceEpicContent,
11317
+ runId: opts.runId
11313
11318
  };
11314
11319
  }
11315
11320
  /**
@@ -12356,7 +12361,7 @@ function createImplementationOrchestrator(deps) {
12356
12361
  let _otlpEndpoint;
12357
12362
  let _probeAuthorEffectiveMode = "enabled";
12358
12363
  const verificationStore = new VerificationStore();
12359
- const verificationPipeline = createDefaultVerificationPipeline(toSdlcEventBus(eventBus));
12364
+ const verificationPipeline = createDefaultVerificationPipeline(toSdlcEventBus(eventBus), void 0);
12360
12365
  const _stateStoreCache = new Map();
12361
12366
  const _checkpoints = new Map();
12362
12367
  const MEMORY_PRESSURE_BACKOFF_MS = [
@@ -14330,13 +14335,35 @@ function createImplementationOrchestrator(deps) {
14330
14335
  const buildRouteResult = routeDecision("build-verification-failure", buildHaltPolicy);
14331
14336
  const buildRunId = config.pipelineRunId ?? "unknown";
14332
14337
  const buildReason = `build verification failed for story ${storyKey}`;
14333
- if (buildRouteResult.halt) eventBus.emit("decision:halt", {
14334
- runId: buildRunId,
14335
- decisionType: "build-verification-failure",
14336
- severity: buildRouteResult.severity,
14337
- reason: buildReason
14338
- });
14339
- else eventBus.emit("decision:autonomous", {
14338
+ if (buildRouteResult.halt) {
14339
+ eventBus.emit("decision:halt", {
14340
+ runId: buildRunId,
14341
+ decisionType: "build-verification-failure",
14342
+ severity: buildRouteResult.severity,
14343
+ reason: buildReason
14344
+ });
14345
+ await runInteractivePrompt({
14346
+ runId: buildRunId,
14347
+ decisionType: "build-verification-failure",
14348
+ severity: buildRouteResult.severity,
14349
+ summary: buildReason,
14350
+ defaultAction: buildRouteResult.defaultAction,
14351
+ choices: [
14352
+ "escalate-without-halt",
14353
+ "retry-with-custom-context",
14354
+ "propose-re-scope",
14355
+ "abort-run"
14356
+ ],
14357
+ onHaltSkipped: (payload) => {
14358
+ eventBus.emit("decision:halt-skipped-non-interactive", payload);
14359
+ }
14360
+ }).catch((err) => {
14361
+ logger$26.warn({
14362
+ err,
14363
+ storyKey
14364
+ }, "interactive prompt failed — continuing with default action");
14365
+ });
14366
+ } else eventBus.emit("decision:autonomous", {
14340
14367
  runId: buildRunId,
14341
14368
  decisionType: "build-verification-failure",
14342
14369
  severity: buildRouteResult.severity,
@@ -14436,23 +14463,173 @@ function createImplementationOrchestrator(deps) {
14436
14463
  storyContent: storyContentForVerification,
14437
14464
  devStoryResult: devStorySignals,
14438
14465
  outputTokenCount: devOutputTokenCount,
14439
- sourceEpicContent
14466
+ sourceEpicContent,
14467
+ runId: config.pipelineRunId
14440
14468
  });
14441
14469
  const verifSummary = await verificationPipeline.run(verifContext, "A");
14442
14470
  verificationStore.set(storyKey, verifSummary);
14443
14471
  await persistVerificationResult(storyKey, verifSummary, runManifest);
14444
14472
  if (verifSummary.status === "fail") {
14445
- updateStory(storyKey, {
14446
- phase: "VERIFICATION_FAILED",
14447
- completedAt: new Date().toISOString()
14448
- });
14449
- persistStoryState(storyKey, _stories.get(storyKey)).catch((err) => logger$26.warn({
14450
- err,
14451
- storyKey
14452
- }, "StateStore write failed after verification-failed"));
14453
- await writeStoryMetricsBestEffort(storyKey, "verification-failed", finalReviewCycles);
14454
- await persistState();
14455
- return "verification-failed";
14473
+ let shouldFallThroughToComplete = false;
14474
+ if (runManifest != null) {
14475
+ const failFindings = (verifSummary.checks ?? []).flatMap((c) => c.findings ?? []);
14476
+ const hasBuildFail = (verifSummary.checks ?? []).some((c) => (c.checkName === "build" || c.checkName === "typecheck") && c.status === "fail");
14477
+ const recoveryRootCause = hasBuildFail ? "build-failure" : "ac-missing-evidence";
14478
+ const recoveryBudget = {
14479
+ max: config.maxReviewCycles,
14480
+ remaining: Math.max(0, config.maxReviewCycles - finalReviewCycles)
14481
+ };
14482
+ const recoveryResult = await runRecoveryEngine({
14483
+ runId: config.pipelineRunId ?? storyKey,
14484
+ storyKey,
14485
+ failure: {
14486
+ rootCause: recoveryRootCause,
14487
+ findings: failFindings
14488
+ },
14489
+ budget: recoveryBudget,
14490
+ bus: toSdlcEventBus(eventBus),
14491
+ manifest: runManifest,
14492
+ adapter: db,
14493
+ engine: "linear"
14494
+ }).catch((recoveryErr) => {
14495
+ logger$26.warn({
14496
+ storyKey,
14497
+ err: recoveryErr instanceof Error ? recoveryErr.message : String(recoveryErr)
14498
+ }, "Recovery Engine invocation failed — falling through to VERIFICATION_FAILED (best-effort)");
14499
+ return null;
14500
+ });
14501
+ if (recoveryResult?.action === "halt-entire-run") {
14502
+ logger$26.error({
14503
+ storyKey,
14504
+ pendingProposalsCount: recoveryResult.pendingProposalsCount
14505
+ }, "Recovery Engine safety valve: halting entire run due to >= 5 pending proposals");
14506
+ _budgetExhausted = true;
14507
+ } else if (recoveryResult?.action === "retry") {
14508
+ logger$26.info({
14509
+ storyKey,
14510
+ attempt: recoveryResult.attempt,
14511
+ retryBudgetRemaining: recoveryResult.retryBudgetRemaining
14512
+ }, "Recovery Engine Tier A: re-dispatching dev-story with enriched prompt");
14513
+ try {
14514
+ incrementDispatches(storyKey);
14515
+ const retryDevResult = await runDevStory({
14516
+ db,
14517
+ pack,
14518
+ contextCompiler,
14519
+ dispatcher,
14520
+ projectRoot,
14521
+ tokenCeilings,
14522
+ otlpEndpoint: _otlpEndpoint,
14523
+ repoMapInjector,
14524
+ maxRepoMapTokens,
14525
+ agentId
14526
+ }, {
14527
+ storyKey,
14528
+ storyFilePath: storyFilePath ?? "",
14529
+ pipelineRunId: config.pipelineRunId,
14530
+ findingsPrompt: recoveryResult.enrichedPrompt
14531
+ });
14532
+ replaceDevStorySignals(retryDevResult);
14533
+ await persistDevStorySignals(storyKey, devStorySignals, runManifest);
14534
+ const retryVerifContext = assembleVerificationContext({
14535
+ storyKey,
14536
+ workingDir: projectRoot ?? process.cwd(),
14537
+ reviewResult: latestReviewSignals,
14538
+ storyContent: storyContentForVerification,
14539
+ devStoryResult: devStorySignals,
14540
+ outputTokenCount: devOutputTokenCount,
14541
+ sourceEpicContent,
14542
+ runId: config.pipelineRunId
14543
+ });
14544
+ const retryVerifSummary = await verificationPipeline.run(retryVerifContext, "A");
14545
+ verificationStore.set(storyKey, retryVerifSummary);
14546
+ await persistVerificationResult(storyKey, retryVerifSummary, runManifest);
14547
+ if (retryVerifSummary.status !== "fail") {
14548
+ logger$26.info({ storyKey }, "Recovery Engine Tier A retry succeeded — story proceeding to COMPLETE");
14549
+ shouldFallThroughToComplete = true;
14550
+ } else logger$26.warn({ storyKey }, "Recovery Engine Tier A retry still failed — falling through to VERIFICATION_FAILED");
14551
+ } catch (retryErr) {
14552
+ logger$26.warn({
14553
+ storyKey,
14554
+ err: retryErr instanceof Error ? retryErr.message : String(retryErr)
14555
+ }, "Recovery Engine Tier A re-dispatch threw — falling through to VERIFICATION_FAILED");
14556
+ }
14557
+ } else if (recoveryResult?.action === "propose") {
14558
+ logger$26.info({ storyKey }, "Recovery Engine Tier B: proposal appended — marking story ESCALATED for operator re-scope");
14559
+ updateStory(storyKey, {
14560
+ phase: "ESCALATED",
14561
+ completedAt: new Date().toISOString(),
14562
+ error: "recovery-engine-propose"
14563
+ });
14564
+ persistStoryState(storyKey, _stories.get(storyKey)).catch((err) => logger$26.warn({
14565
+ err,
14566
+ storyKey
14567
+ }, "StateStore write failed after recovery-propose"));
14568
+ await emitEscalation({
14569
+ storyKey,
14570
+ lastVerdict: "recovery-propose",
14571
+ reviewCycles: finalReviewCycles,
14572
+ issues: failFindings
14573
+ });
14574
+ await writeStoryMetricsBestEffort(storyKey, "escalated", finalReviewCycles);
14575
+ await persistState();
14576
+ return "verification-failed";
14577
+ } else if (recoveryResult?.action === "halt") {
14578
+ logger$26.warn({ storyKey }, "Recovery Engine Tier C: halt — invoking interactive prompt for operator decision");
14579
+ const haltRunId = config.pipelineRunId ?? storyKey;
14580
+ await runInteractivePrompt({
14581
+ runId: haltRunId,
14582
+ decisionType: "verification-failure",
14583
+ severity: "critical",
14584
+ summary: `Verification failed (Tier C halt) on story ${storyKey}: ${recoveryRootCause}`,
14585
+ defaultAction: "escalate",
14586
+ choices: [
14587
+ "escalate-without-halt",
14588
+ "propose-re-scope",
14589
+ "abort-run"
14590
+ ],
14591
+ onHaltSkipped: (haltPayload) => {
14592
+ eventBus.emit("decision:halt-skipped-non-interactive", haltPayload);
14593
+ }
14594
+ }).catch((err) => {
14595
+ logger$26.warn({
14596
+ err,
14597
+ storyKey
14598
+ }, "Recovery Engine Tier C: interactive prompt failed — escalating anyway");
14599
+ });
14600
+ updateStory(storyKey, {
14601
+ phase: "ESCALATED",
14602
+ completedAt: new Date().toISOString(),
14603
+ error: "recovery-engine-halt"
14604
+ });
14605
+ persistStoryState(storyKey, _stories.get(storyKey)).catch((err) => logger$26.warn({
14606
+ err,
14607
+ storyKey
14608
+ }, "StateStore write failed after recovery-halt"));
14609
+ await emitEscalation({
14610
+ storyKey,
14611
+ lastVerdict: "recovery-halt",
14612
+ reviewCycles: finalReviewCycles,
14613
+ issues: failFindings
14614
+ });
14615
+ await writeStoryMetricsBestEffort(storyKey, "escalated", finalReviewCycles);
14616
+ await persistState();
14617
+ return "verification-failed";
14618
+ }
14619
+ }
14620
+ if (!shouldFallThroughToComplete) {
14621
+ updateStory(storyKey, {
14622
+ phase: "VERIFICATION_FAILED",
14623
+ completedAt: new Date().toISOString()
14624
+ });
14625
+ persistStoryState(storyKey, _stories.get(storyKey)).catch((err) => logger$26.warn({
14626
+ err,
14627
+ storyKey
14628
+ }, "StateStore write failed after verification-failed"));
14629
+ await writeStoryMetricsBestEffort(storyKey, "verification-failed", finalReviewCycles);
14630
+ await persistState();
14631
+ return "verification-failed";
14632
+ }
14456
14633
  }
14457
14634
  }
14458
14635
  if (autoApprove !== void 0) eventBus.emit("story:auto-approved", {
@@ -15299,13 +15476,32 @@ function createImplementationOrchestrator(deps) {
15299
15476
  const routeResult = routeDecision("cost-ceiling-exhausted", haltPolicy);
15300
15477
  const runId = config.pipelineRunId ?? "unknown";
15301
15478
  const reason = `cost ceiling exceeded: ${result.cumulative.toFixed(4)} USD >= ${result.ceiling} USD`;
15302
- if (routeResult.halt) eventBus.emit("decision:halt", {
15303
- runId,
15304
- decisionType: "cost-ceiling-exhausted",
15305
- severity: routeResult.severity,
15306
- reason
15307
- });
15308
- else eventBus.emit("decision:autonomous", {
15479
+ if (routeResult.halt) {
15480
+ eventBus.emit("decision:halt", {
15481
+ runId,
15482
+ decisionType: "cost-ceiling-exhausted",
15483
+ severity: routeResult.severity,
15484
+ reason
15485
+ });
15486
+ await runInteractivePrompt({
15487
+ runId,
15488
+ decisionType: "cost-ceiling-exhausted",
15489
+ severity: routeResult.severity,
15490
+ summary: reason,
15491
+ defaultAction: routeResult.defaultAction,
15492
+ choices: [
15493
+ "skip-remaining",
15494
+ "retry-with-custom-context",
15495
+ "propose-re-scope",
15496
+ "abort-run"
15497
+ ],
15498
+ onHaltSkipped: (payload) => {
15499
+ eventBus.emit("decision:halt-skipped-non-interactive", payload);
15500
+ }
15501
+ }).catch((err) => {
15502
+ logger$26.warn({ err }, "interactive prompt failed during cost-ceiling halt — continuing with default action");
15503
+ });
15504
+ } else eventBus.emit("decision:autonomous", {
15309
15505
  runId,
15310
15506
  decisionType: "cost-ceiling-exhausted",
15311
15507
  severity: routeResult.severity,
@@ -43325,7 +43521,7 @@ async function writeRunState(projectDir, state) {
43325
43521
  async function clearRunState(projectDir) {
43326
43522
  const filePath = runStatePath(projectDir);
43327
43523
  try {
43328
- await unlink(filePath);
43524
+ await unlink$1(filePath);
43329
43525
  } catch (err) {
43330
43526
  if (err.code !== "ENOENT") throw err;
43331
43527
  }
@@ -44322,7 +44518,7 @@ function resolveProbeAuthorStateIntegrating(cliFlag) {
44322
44518
  * substrate run --non-interactive --halt-on none --events --output-format json
44323
44519
  */
44324
44520
  async function runRunAction(options) {
44325
- const { pack: packName, from: startPhase, stopAfter, concept: conceptArg, conceptFile, stories: storiesArg, concurrency, outputFormat, projectRoot, events: eventsFlag, verbose: verboseFlag, tui: tuiFlag, skipUx, research: researchFlag, skipResearch: skipResearchFlag, skipPreflight, skipVerification, epic: epicNumber, dryRun, maxReviewCycles = 2, engine, agent: agentId, registry: injectedRegistry, haltOn: haltOnOpt, costCeiling, probeAuthor, probeAuthorStateIntegrating: probeAuthorStateIntegratingFlag, nonInteractive } = options;
44521
+ const { pack: packName, from: startPhase, stopAfter, concept: conceptArg, conceptFile, stories: storiesArg, concurrency, outputFormat, projectRoot, events: eventsFlag, verbose: verboseFlag, tui: tuiFlag, skipUx, research: researchFlag, skipResearch: skipResearchFlag, skipPreflight, skipVerification, epic: epicNumber, dryRun, maxReviewCycles = 2, engine, agent: agentId, registry: injectedRegistry, haltOn: haltOnOpt, costCeiling, probeAuthor, probeAuthorStateIntegrating: probeAuthorStateIntegratingFlag, nonInteractive, verifyAc } = options;
44326
44522
  const haltOn = haltOnOpt;
44327
44523
  const VALID_PROBE_AUTHOR_MODES = [
44328
44524
  "enabled",
@@ -45248,6 +45444,54 @@ async function runRunAction(options) {
45248
45444
  });
45249
45445
  return derivedCode;
45250
45446
  }
45447
+ if (verifyAc === true) try {
45448
+ const runsDir = join(dbDir, "runs");
45449
+ const runManifestForAc = RunManifest.open(pipelineRun.id, runsDir);
45450
+ const manifestData = await runManifestForAc.read();
45451
+ const artifactsDir = join(dbRoot, "_bmad-output", "implementation-artifacts");
45452
+ const acResults = {};
45453
+ for (const [sk, state] of Object.entries(manifestData.per_story_state)) {
45454
+ const filesModified = state.dev_story_signals?.files_modified ?? [];
45455
+ let storyContent = "";
45456
+ try {
45457
+ const artifactFiles = await readdir(artifactsDir, { encoding: "utf-8" }).catch(() => []);
45458
+ const matchingFile = artifactFiles.find((f$1) => (f$1.startsWith(`${sk}-`) || f$1 === `${sk}.md`) && f$1.endsWith(".md"));
45459
+ if (matchingFile) storyContent = await readFile(join(artifactsDir, matchingFile), "utf-8");
45460
+ } catch {}
45461
+ try {
45462
+ const result = await runAcTraceabilityCheck({
45463
+ storyKey: sk,
45464
+ storyContent,
45465
+ filesModified
45466
+ });
45467
+ acResults[sk] = {
45468
+ matrix: result.matrix,
45469
+ confidence: result.confidence
45470
+ };
45471
+ } catch (acErr) {
45472
+ logger.debug({
45473
+ err: acErr,
45474
+ storyKey: sk
45475
+ }, "ac traceability check failed for story");
45476
+ }
45477
+ }
45478
+ if (outputFormat === "json" || ndjsonEmitter !== void 0) process.stdout.write(JSON.stringify({
45479
+ type: "pipeline:ac-traceability",
45480
+ ts: new Date().toISOString(),
45481
+ run_id: pipelineRun.id,
45482
+ ac_traceability: acResults
45483
+ }) + "\n");
45484
+ else {
45485
+ process.stdout.write("\n── AC Traceability (approximate) ──\n");
45486
+ for (const [sk, result] of Object.entries(acResults)) {
45487
+ const matrix = result.matrix;
45488
+ const matchCount = matrix.filter((r) => r.matched).length;
45489
+ process.stdout.write(` ${sk}: ${matchCount}/${matrix.length} ACs matched\n`);
45490
+ }
45491
+ }
45492
+ } catch (acRunErr) {
45493
+ logger.warn({ err: acRunErr }, "AC traceability post-run check failed (best-effort)");
45494
+ }
45251
45495
  return 0;
45252
45496
  } catch (err) {
45253
45497
  const msg = err instanceof Error ? err.message : String(err);
@@ -45743,7 +45987,7 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
45743
45987
  "",
45744
45988
  "--halt-on defaults to critical. Skipped halt decisions are recorded as",
45745
45989
  "decision:halt-skipped-non-interactive events in --non-interactive mode."
45746
- ].join("\n ")).action(async (opts) => {
45990
+ ].join("\n ")).option("--verify-ac", "Run AC-to-test traceability heuristic after the pipeline completes (Story 74-1)").action(async (opts) => {
45747
45991
  if (opts.helpAgent) {
45748
45992
  process.exitCode = await runHelpAgent();
45749
45993
  return;
@@ -45788,7 +46032,8 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
45788
46032
  costCeiling: opts.costCeiling,
45789
46033
  probeAuthor: opts.probeAuthor,
45790
46034
  probeAuthorStateIntegrating: opts.probeAuthorStateIntegrating,
45791
- nonInteractive: opts.nonInteractive
46035
+ nonInteractive: opts.nonInteractive,
46036
+ verifyAc: opts.verifyAc
45792
46037
  });
45793
46038
  if (opts.nonInteractive === true) process.exit(exitCode);
45794
46039
  process.exitCode = exitCode;
@@ -45797,4 +46042,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
45797
46042
 
45798
46043
  //#endregion
45799
46044
  export { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR$1 as GLOBSTAR, GitClient, GrammarLoader, Minimatch$1 as Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape$1 as escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, normalizeGraphSummaryToStatus, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runRunAction, runSolutioningPhase, unescape$1 as unescape, validateStopAfterFromConflict, wireNdjsonEmitter };
45800
- //# sourceMappingURL=run-CCxsv-9M.js.map
46045
+ //# sourceMappingURL=run-7h2-DIjt.js.map
@@ -0,0 +1,14 @@
1
+ import "./health-D6MKxV46.js";
2
+ import "./logger-KeHncl-f.js";
3
+ import "./helpers-CElYrONe.js";
4
+ import "./dist-K_RRWnBX.js";
5
+ import "./manifest-read-g4zt3DXJ.js";
6
+ import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, runRunAction, wireNdjsonEmitter } from "./run-7h2-DIjt.js";
7
+ import "./routing-DFxoKHDt.js";
8
+ import "./work-graph-repository-DZyJv5pV.js";
9
+ import "./decisions-CzSIEeGP.js";
10
+ import "./decision-router-DblHY8se.js";
11
+ import "./interactive-prompt-kzkG24Rn.js";
12
+ import "./recovery-engine-BKGBeBnW.js";
13
+
14
+ export { runRunAction };
@@ -1,3 +1,3 @@
1
- import { DECISION_SEVERITY_MAP, deriveExitCode, routeDecision } from "../../../decision-router-BA__VYIp.js";
1
+ import { DECISION_SEVERITY_MAP, deriveExitCode, routeDecision } from "../../../decision-router-DblHY8se.js";
2
2
 
3
3
  export { DECISION_SEVERITY_MAP, deriveExitCode, routeDecision };