substrate-ai 0.20.145 → 0.20.147

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.
@@ -0,0 +1,4 @@
1
+ import { AdapterRegistry } from "./dist-DT378h1M.js";
2
+ import "./adapter-registry-DIcrxjH8.js";
3
+
4
+ export { AdapterRegistry };
package/dist/cli/index.js CHANGED
@@ -1,20 +1,20 @@
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-muiK_xRZ.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-nQ_Txd5T.js";
3
3
  import { createLogger } from "../logger-KeHncl-f.js";
4
4
  import { createEventBus } from "../helpers-CElYrONe.js";
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, 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-DiNK6QOD.js";
6
- import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR, GitClient, GrammarLoader, Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createGitWorktreeManager, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runSolutioningPhase, unescape, validateStopAfterFromConflict } from "../run-DHPGxjlk.js";
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, 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-DT378h1M.js";
6
+ import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR, GitClient, GrammarLoader, Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createGitWorktreeManager, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runSolutioningPhase, unescape, validateStopAfterFromConflict } from "../run-BBVZdkEo.js";
7
7
  import "../adapter-registry-DIcrxjH8.js";
8
- import { RunManifest, SupervisorLock, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, parseRuntimeProbes, readCurrentRunId, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorByClass, rollupProbeAuthorMetrics, runAcTraceabilityCheck } from "../manifest-read-CX6KKQHX.js";
9
- import "../errors-B21JUhcc.js";
8
+ import { RunManifest, SupervisorLock, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, parseRuntimeProbes, readCurrentRunId, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorByClass, rollupProbeAuthorMetrics, runAcTraceabilityCheck } from "../manifest-read-DlWwZpfO.js";
9
+ import "../errors-BGE3kaH8.js";
10
10
  import "../routing-DFxoKHDt.js";
11
11
  import { WorkGraphRepository } from "../work-graph-repository-DZyJv5pV.js";
12
12
  import "../decisions-CzSIEeGP.js";
13
13
  import "../decision-router-BAPpON_C.js";
14
- import "../interactive-prompt-PgHUXA-A.js";
14
+ import "../interactive-prompt-xJ3K-IUQ.js";
15
15
  import "../recovery-engine-BKGBeBnW.js";
16
16
  import "../version-manager-impl-qFBiO4Eh.js";
17
- import { registerUpgradeCommand } from "../upgrade-DB7KzD9c.js";
17
+ import { registerUpgradeCommand } from "../upgrade-BVHnUYUd.js";
18
18
  import { Command } from "commander";
19
19
  import { fileURLToPath } from "url";
20
20
  import { dirname, join, resolve } from "path";
@@ -623,7 +623,12 @@ const SubstrateConfigSchema = z.object({
623
623
  default_agent: z.string().optional(),
624
624
  supervisor_poll_interval_seconds: z.number().int().positive().optional(),
625
625
  retry_budget: z.number().int().positive().optional(),
626
- epics_path: z.string().optional()
626
+ epics_path: z.string().optional(),
627
+ finalization: z.object({ mode: z.enum([
628
+ "merge",
629
+ "branch",
630
+ "pr"
631
+ ]).optional() }).strict().optional()
627
632
  }).strict();
628
633
  const PartialSubstrateConfigSchema = z.object({
629
634
  config_format_version: z.enum(["1"]).optional(),
@@ -642,7 +647,12 @@ const PartialSubstrateConfigSchema = z.object({
642
647
  default_agent: z.string().optional(),
643
648
  supervisor_poll_interval_seconds: z.number().int().positive().optional(),
644
649
  retry_budget: z.number().int().positive().optional(),
645
- epics_path: z.string().optional()
650
+ epics_path: z.string().optional(),
651
+ finalization: z.object({ mode: z.enum([
652
+ "merge",
653
+ "branch",
654
+ "pr"
655
+ ]).optional() }).strict().optional()
646
656
  }).strict();
647
657
 
648
658
  //#endregion
@@ -7052,7 +7062,7 @@ async function runStatusAction(options) {
7052
7062
  logger$15.debug({ err }, "Work graph query failed, continuing without work graph data");
7053
7063
  }
7054
7064
  if (run === void 0) {
7055
- const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-Dk6gHNDC.js");
7065
+ const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-BJoVPIyR.js");
7056
7066
  const substrateDirPath = join(projectRoot, ".substrate");
7057
7067
  const processInfo = inspectProcessTree$1({
7058
7068
  projectRoot,
@@ -8000,7 +8010,7 @@ function defaultSupervisorDeps() {
8000
8010
  if (cached === null) {
8001
8011
  const { AdapterRegistry: AR } = await import(
8002
8012
  /* @vite-ignore */
8003
- "../adapter-registry-qU0IkbbQ.js"
8013
+ "../adapter-registry-SL7-DtOW.js"
8004
8014
  );
8005
8015
  cached = new AR();
8006
8016
  await cached.discoverAndRegister();
@@ -8567,11 +8577,11 @@ async function runSupervisorAction(options, deps = {}) {
8567
8577
  try {
8568
8578
  const { createExperimenter } = await import(
8569
8579
  /* @vite-ignore */
8570
- "../experimenter-D55L011w.js"
8580
+ "../experimenter-COLnRT8i.js"
8571
8581
  );
8572
8582
  const { getLatestRun: getLatest } = await import(
8573
8583
  /* @vite-ignore */
8574
- "../decisions-Dvw5HhyM.js"
8584
+ "../decisions-qFnqErZ5.js"
8575
8585
  );
8576
8586
  const expAdapter = createDatabaseAdapter({
8577
8587
  backend: "auto",
@@ -8581,7 +8591,7 @@ async function runSupervisorAction(options, deps = {}) {
8581
8591
  await initSchema(expAdapter);
8582
8592
  const { runRunAction: runPipeline } = await import(
8583
8593
  /* @vite-ignore */
8584
- "../run-C0uq3ETL.js"
8594
+ "../run-D3mhgkIL.js"
8585
8595
  );
8586
8596
  const runStoryFn = async (opts) => {
8587
8597
  const exitCode = await runPipeline({
@@ -9106,7 +9116,7 @@ async function runMetricsAction(options) {
9106
9116
  const routingConfigPath = join(dbDir, "routing.yml");
9107
9117
  let routingConfig = null;
9108
9118
  if (existsSync$1(routingConfigPath)) try {
9109
- const { loadModelRoutingConfig } = await import("../routing-_PGfe_cD.js");
9119
+ const { loadModelRoutingConfig } = await import("../routing-Dz4GQta5.js");
9110
9120
  routingConfig = loadModelRoutingConfig(routingConfigPath);
9111
9121
  } catch {}
9112
9122
  if (routingConfig === null) routingConfig = {
@@ -12972,6 +12982,17 @@ function renderHuman(output, manifest) {
12972
12982
  ], COL_WIDTHS));
12973
12983
  }
12974
12984
  lines.push("");
12985
+ const unmerged = stories.filter((s) => s.finalization !== void 0 && s.finalization.mode !== "merge");
12986
+ if (unmerged.length > 0) {
12987
+ lines.push("Finalization (deliverable branches — NOT merged):");
12988
+ for (const s of unmerged) {
12989
+ const fz = s.finalization ?? {};
12990
+ const shaStr = fz.sha ? ` @ ${fz.sha.slice(0, 10)}` : "";
12991
+ const prStr = fz.mode === "pr" ? fz.pr_url ? ` PR: ${fz.pr_url}` : " PR: creation failed — degraded to branch" : "";
12992
+ lines.push(` ${s.story_key}: [${fz.mode ?? "?"}] ${fz.branch ?? "?"}${shaStr}${prStr}`);
12993
+ }
12994
+ lines.push("");
12995
+ }
12975
12996
  const lowOutputStories = stories.filter((s) => s.low_output_warning === true);
12976
12997
  if (lowOutputStories.length > 0) {
12977
12998
  lines.push(`⚠ ${lowOutputStories.length} story/stories produced fewer than ${LOW_OUTPUT_TOKEN_THRESHOLD} output tokens —`);
@@ -13104,7 +13125,8 @@ function assembleReport(runId, manifest, halts, storyOutputTokens) {
13104
13125
  verification_findings: findings,
13105
13126
  verification_ran: verificationRan,
13106
13127
  ...outputTokens !== void 0 ? { output_tokens: outputTokens } : {},
13107
- ...lowOutputWarning ? { low_output_warning: true } : {}
13128
+ ...lowOutputWarning ? { low_output_warning: true } : {},
13129
+ ...state.finalization !== void 0 ? { finalization: state.finalization } : {}
13108
13130
  };
13109
13131
  stories.push(storySummary);
13110
13132
  summary[outcome]++;
@@ -13420,8 +13442,8 @@ async function createProgram() {
13420
13442
  /** Fire-and-forget startup version check (story 8.3, AC3/AC5) */
13421
13443
  function checkForUpdatesInBackground(currentVersion) {
13422
13444
  if (process.env.SUBSTRATE_NO_UPDATE_CHECK === "1") return;
13423
- import("../upgrade-CTj4hi8J.js").then(async () => {
13424
- const { createVersionManager } = await import("../version-manager-impl-HJMonRJi.js");
13445
+ import("../upgrade-V0xYGkQs.js").then(async () => {
13446
+ const { createVersionManager } = await import("../version-manager-impl-BWqvme_f.js");
13425
13447
  const vm = createVersionManager();
13426
13448
  const result = await vm.checkForUpdates();
13427
13449
  if (result.updateAvailable) {
@@ -1,4 +1,4 @@
1
- import { addTokenUsage, createDecision, createPipelineRun, createRequirement, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunningPipelineRuns, getTokenUsageSummary, listRequirements, registerArtifact, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision } from "./dist-DiNK6QOD.js";
1
+ import { addTokenUsage, createDecision, createPipelineRun, createRequirement, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunningPipelineRuns, getTokenUsageSummary, listRequirements, registerArtifact, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision } from "./dist-DT378h1M.js";
2
2
  import "./decisions-CzSIEeGP.js";
3
3
 
4
4
  export { getLatestRun };
@@ -6251,7 +6251,12 @@ const SubstrateConfigSchema = z.object({
6251
6251
  budget: BudgetConfigSchema.optional(),
6252
6252
  telemetry: TelemetryConfigSchema.optional(),
6253
6253
  worktree: WorktreeConfigSchema.optional(),
6254
- trivialOutputThreshold: z.number().int().nonnegative().optional()
6254
+ trivialOutputThreshold: z.number().int().nonnegative().optional(),
6255
+ finalization: z.object({ mode: z.enum([
6256
+ "merge",
6257
+ "branch",
6258
+ "pr"
6259
+ ]).optional() }).strict().optional()
6255
6260
  }).passthrough();
6256
6261
  const PartialProviderConfigSchema = ProviderConfigSchema.partial();
6257
6262
  const PartialGlobalSettingsSchema = GlobalSettingsSchema.partial();
@@ -6268,7 +6273,12 @@ const PartialSubstrateConfigSchema = z.object({
6268
6273
  budget: BudgetConfigSchema.partial().optional(),
6269
6274
  telemetry: TelemetryConfigSchema.partial().optional(),
6270
6275
  worktree: WorktreeConfigSchema.partial().optional(),
6271
- trivialOutputThreshold: z.number().int().nonnegative().optional()
6276
+ trivialOutputThreshold: z.number().int().nonnegative().optional(),
6277
+ finalization: z.object({ mode: z.enum([
6278
+ "merge",
6279
+ "branch",
6280
+ "pr"
6281
+ ]).optional() }).strict().optional()
6272
6282
  }).passthrough();
6273
6283
 
6274
6284
  //#endregion
@@ -10414,6 +10424,121 @@ var GeminiCLIAdapter = class GeminiCLIAdapter {
10414
10424
  }
10415
10425
  };
10416
10426
 
10427
+ //#endregion
10428
+ //#region packages/core/dist/adapters/stub-adapter.js
10429
+ var StubAdapter = class {
10430
+ id = "stub";
10431
+ displayName = "Stub Agent (e2e harness)";
10432
+ adapterVersion = "1.0.0";
10433
+ async healthCheck() {
10434
+ if (process.env.SUBSTRATE_STUB_ADAPTER !== "1") return {
10435
+ healthy: false,
10436
+ error: "stub adapter is gated behind SUBSTRATE_STUB_ADAPTER=1 (e2e harness only)",
10437
+ supportsHeadless: true
10438
+ };
10439
+ const script = process.env.SUBSTRATE_STUB_SCRIPT;
10440
+ if (script === void 0 || script === "") return {
10441
+ healthy: false,
10442
+ error: "SUBSTRATE_STUB_SCRIPT must point at the scenario script",
10443
+ supportsHeadless: true
10444
+ };
10445
+ try {
10446
+ await access$1(script);
10447
+ } catch {
10448
+ return {
10449
+ healthy: false,
10450
+ error: `SUBSTRATE_STUB_SCRIPT not readable: ${script}`,
10451
+ supportsHeadless: true
10452
+ };
10453
+ }
10454
+ return {
10455
+ healthy: true,
10456
+ version: "stub-1.0.0",
10457
+ supportsHeadless: true
10458
+ };
10459
+ }
10460
+ buildCommand(prompt, options) {
10461
+ return {
10462
+ binary: process.execPath,
10463
+ args: [process.env.SUBSTRATE_STUB_SCRIPT ?? "/nonexistent-stub-script", options.taskType ?? "unknown"],
10464
+ env: {
10465
+ SUBSTRATE_STUB_SCENARIO: process.env.SUBSTRATE_STUB_SCENARIO ?? "success",
10466
+ SUBSTRATE_STUB_STORY_KEY: options.storyKey ?? ""
10467
+ },
10468
+ cwd: options.worktreePath,
10469
+ stdin: prompt
10470
+ };
10471
+ }
10472
+ buildPlanningCommand(_request, options) {
10473
+ return {
10474
+ binary: process.execPath,
10475
+ args: [process.env.SUBSTRATE_STUB_SCRIPT ?? "/nonexistent-stub-script", "planning"],
10476
+ env: { SUBSTRATE_STUB_SCENARIO: process.env.SUBSTRATE_STUB_SCENARIO ?? "success" },
10477
+ cwd: options.worktreePath,
10478
+ stdin: ""
10479
+ };
10480
+ }
10481
+ parseOutput(stdout, stderr, exitCode) {
10482
+ if (exitCode !== 0) return {
10483
+ success: false,
10484
+ output: stdout,
10485
+ error: stderr || `stub exited with code ${String(exitCode)}`,
10486
+ exitCode
10487
+ };
10488
+ return {
10489
+ success: true,
10490
+ output: stdout,
10491
+ exitCode
10492
+ };
10493
+ }
10494
+ parsePlanOutput(stdout, stderr, exitCode) {
10495
+ if (exitCode !== 0) return {
10496
+ success: false,
10497
+ tasks: [],
10498
+ error: stderr || `stub exited ${String(exitCode)}`
10499
+ };
10500
+ return {
10501
+ success: false,
10502
+ tasks: [],
10503
+ error: "stub adapter does not generate plans"
10504
+ };
10505
+ }
10506
+ estimateTokens(text) {
10507
+ const input = Math.ceil(text.length / 4);
10508
+ return {
10509
+ input,
10510
+ output: 0,
10511
+ total: input
10512
+ };
10513
+ }
10514
+ getCapabilities() {
10515
+ return {
10516
+ supportsJsonOutput: false,
10517
+ supportsStreaming: false,
10518
+ supportsSubscriptionBilling: true,
10519
+ supportsApiBilling: false,
10520
+ supportsPlanGeneration: false,
10521
+ maxContextTokens: 1e6,
10522
+ supportedTaskTypes: [
10523
+ "create-story",
10524
+ "dev-story",
10525
+ "code-review",
10526
+ "fix-story",
10527
+ "test-plan",
10528
+ "probe-author",
10529
+ "test-expansion"
10530
+ ],
10531
+ supportedLanguages: [
10532
+ "python",
10533
+ "typescript",
10534
+ "go"
10535
+ ],
10536
+ timeoutMultiplier: 1,
10537
+ defaultModel: "stub"
10538
+ };
10539
+ }
10540
+ };
10541
+
10417
10542
  //#endregion
10418
10543
  //#region packages/core/dist/adapters/adapter-registry.js
10419
10544
  /**
@@ -10468,6 +10593,7 @@ var AdapterRegistry = class {
10468
10593
  new CodexCLIAdapter(),
10469
10594
  new GeminiCLIAdapter()
10470
10595
  ];
10596
+ if (process.env.SUBSTRATE_STUB_ADAPTER === "1") builtInAdapters.push(new StubAdapter());
10471
10597
  const results = [];
10472
10598
  let registeredCount = 0;
10473
10599
  let failedCount = 0;
@@ -11520,4 +11646,4 @@ async function callLLM(params) {
11520
11646
 
11521
11647
  //#endregion
11522
11648
  export { ADVISORY_NOTES, AdapterRegistry, AdtError, BudgetConfigSchema, CLAUDE_AUTH_FAILURE_HINT, CODEX_SANDBOX_BLOCK_HINT, CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, Categorizer, ClaudeCodeAdapter, CodexCLIAdapter, ConfigError, ConfigIncompatibleFormatError, ConsumerAnalyzer, CostTrackerConfigSchema, DEFAULT_CONFIG, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, DoltNotInstalled, DoltQueryError, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, GeminiCLIAdapter, GlobalSettingsSchema, InMemoryDatabaseAdapter, IngestionServer, LEARNING_FINDING, LogTurnAnalyzer, ModelRoutingConfigSchema, MonitorDatabaseImpl, OPERATIONAL_FINDING, PartialGlobalSettingsSchema, PartialProviderConfigSchema, ProviderPolicySchema, ProvidersSchema, Recommender, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TASK_TYPE_PHASE_MAP, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryConfigSchema, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, VersionManagerImpl, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, callLLM, checkDoltInstalled, classifyVersionGap, compareRunMetrics, createAmendmentRun, createConfigSystem, createDatabaseAdapter as createDatabaseAdapter$1, createDecision, createExperimenter, createPipelineRun, createRequirement, createStderrLogger, createVersionManager, detectClaudeAuthFailure, detectCodexSandboxBlock, detectInterfaceChanges, determineVerdict, getActiveDecisions, getAllCostEntriesFiltered, getArtifactByTypeForRun, getArtifactsByRun, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getModelTier, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initWorkGraphSchema, initializeDolt, listRequirements, listRunMetrics, loadModelRoutingConfig, loadParentRunDecisions, registerArtifact, resolvePromptFile, supersedeDecision, swallowDebug, tagRunAsBaseline, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics };
11523
- //# sourceMappingURL=dist-DiNK6QOD.js.map
11649
+ //# sourceMappingURL=dist-DT378h1M.js.map
@@ -1,4 +1,4 @@
1
- import { AdtError } from "./dist-DiNK6QOD.js";
1
+ import { AdtError } from "./dist-DT378h1M.js";
2
2
 
3
3
  //#region src/core/errors.ts
4
4
  /** Error thrown when task configuration is invalid */
@@ -71,4 +71,4 @@ var TaskGraphIncompatibleFormatError = class extends AdtError {
71
71
 
72
72
  //#endregion
73
73
  export { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError };
74
- //# sourceMappingURL=errors-B21JUhcc.js.map
74
+ //# sourceMappingURL=errors-BGE3kaH8.js.map
@@ -1,3 +1,3 @@
1
- import { buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, createExperimenter, determineVerdict, resolvePromptFile } from "./dist-DiNK6QOD.js";
1
+ import { buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, createExperimenter, determineVerdict, resolvePromptFile } from "./dist-DT378h1M.js";
2
2
 
3
3
  export { createExperimenter };
@@ -1,7 +1,7 @@
1
- import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-muiK_xRZ.js";
1
+ import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-nQ_Txd5T.js";
2
2
  import "./logger-KeHncl-f.js";
3
- import "./dist-DiNK6QOD.js";
4
- import "./manifest-read-CX6KKQHX.js";
3
+ import "./dist-DT378h1M.js";
4
+ import "./manifest-read-DlWwZpfO.js";
5
5
  import "./work-graph-repository-DZyJv5pV.js";
6
6
  import "./decisions-CzSIEeGP.js";
7
7
 
@@ -1,6 +1,6 @@
1
1
  import { createLogger } from "./logger-KeHncl-f.js";
2
- import { DoltClient, DoltQueryError, createDatabaseAdapter$1 as createDatabaseAdapter, getLatestRun, getPipelineRunById, initSchema } from "./dist-DiNK6QOD.js";
3
- import { resolveMainRepoRoot, resolveRunManifest } from "./manifest-read-CX6KKQHX.js";
2
+ import { DoltClient, DoltQueryError, createDatabaseAdapter$1 as createDatabaseAdapter, getLatestRun, getPipelineRunById, initSchema } from "./dist-DT378h1M.js";
3
+ import { resolveMainRepoRoot, resolveRunManifest } from "./manifest-read-DlWwZpfO.js";
4
4
  import { createRequire } from "module";
5
5
  import { dirname, join } from "path";
6
6
  import { existsSync, readFileSync } from "node:fs";
@@ -1000,4 +1000,4 @@ function registerHealthCommand(program, _version = "0.0.0", projectRoot = proces
1000
1000
 
1001
1001
  //#endregion
1002
1002
  export { BMAD_BASELINE_TOKENS_FULL, DEFAULT_STALL_THRESHOLD_SECONDS, FileKvStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter$1 as createDatabaseAdapter, createDoltOperatorReader, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, isOrchestratorProcessLine, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, runHealthAction, validateStoryKey };
1003
- //# sourceMappingURL=health-muiK_xRZ.js.map
1003
+ //# sourceMappingURL=health-nQ_Txd5T.js.map
@@ -292,6 +292,13 @@ declare const SubstrateConfigSchema: z.ZodObject<{
292
292
  copy_files: z.ZodDefault<z.ZodArray<z.ZodString>>;
293
293
  }, z.core.$strict>>;
294
294
  trivialOutputThreshold: z.ZodOptional<z.ZodNumber>;
295
+ finalization: z.ZodOptional<z.ZodObject<{
296
+ mode: z.ZodOptional<z.ZodEnum<{
297
+ merge: "merge";
298
+ branch: "branch";
299
+ pr: "pr";
300
+ }>>;
301
+ }, z.core.$strict>>;
295
302
  }, z.core.$loose>;
296
303
  type SubstrateConfig = z.infer<typeof SubstrateConfigSchema>; //#endregion
297
304
  //#region packages/core/dist/events/core-events.d.ts
@@ -1584,4 +1591,4 @@ interface Recommendation {
1584
1591
 
1585
1592
  //#endregion
1586
1593
  export { AdapterDiscoveryResult, AdapterRegistry as AdapterRegistry$1, AdtError as AdtError$1, ClaudeCodeAdapter as ClaudeCodeAdapter$1, CodexCLIAdapter as CodexCLIAdapter$1, ConfigError as ConfigError$1, ConfigIncompatibleFormatError as ConfigIncompatibleFormatError$1, CoreEvents, DatabaseAdapter, DiscoveryReport, GeminiCLIAdapter as GeminiCLIAdapter$1, Recommendation, TypedEventBus };
1587
- //# sourceMappingURL=index-BqVBOAO0.d.ts.map
1594
+ //# sourceMappingURL=index-DaBYDiWn.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AdapterDiscoveryResult, AdapterRegistry$1 as AdapterRegistry, AdtError$1 as AdtError, ClaudeCodeAdapter$1 as ClaudeCodeAdapter, CodexCLIAdapter$1 as CodexCLIAdapter, ConfigError$1 as ConfigError, ConfigIncompatibleFormatError$1 as ConfigIncompatibleFormatError, DiscoveryReport, GeminiCLIAdapter$1 as GeminiCLIAdapter, Recommendation, TypedEventBus } from "./index-BqVBOAO0.js";
1
+ import { AdapterDiscoveryResult, AdapterRegistry$1 as AdapterRegistry, AdtError$1 as AdtError, ClaudeCodeAdapter$1 as ClaudeCodeAdapter, CodexCLIAdapter$1 as CodexCLIAdapter, ConfigError$1 as ConfigError, ConfigIncompatibleFormatError$1 as ConfigIncompatibleFormatError, DiscoveryReport, GeminiCLIAdapter$1 as GeminiCLIAdapter, Recommendation, TypedEventBus } from "./index-DaBYDiWn.js";
2
2
  import pino from "pino";
3
3
  import { z } from "zod";
4
4
  import { Readable, Writable } from "node:stream";
@@ -150,6 +150,59 @@ interface StoryDoneEvent {
150
150
  /** Number of review cycles completed */
151
151
  review_cycles: number;
152
152
  }
153
+ /**
154
+ * Emitted when a story's verified work has been committed on its branch
155
+ * (the `feat(story-…)` auto-commit). Fires in every finalization mode,
156
+ * BEFORE any integration step.
157
+ */
158
+ interface StoryCommittedEvent {
159
+ type: 'story:committed';
160
+ /** ISO-8601 timestamp generated at emit time */
161
+ ts: string;
162
+ /** Story key (e.g., "10-1") */
163
+ key: string;
164
+ /** Commit SHA of the deliverable commit */
165
+ sha: string;
166
+ /** Story branch the commit lives on (substrate/story-<key>) */
167
+ branch: string;
168
+ }
169
+ /**
170
+ * Emitted when a story branch was merged into the start branch.
171
+ * Only fires in `merge` finalization mode.
172
+ */
173
+ interface StoryMergedEvent {
174
+ type: 'story:merged';
175
+ /** ISO-8601 timestamp generated at emit time */
176
+ ts: string;
177
+ /** Story key (e.g., "10-1") */
178
+ key: string;
179
+ /** Commit SHA of the deliverable commit that was merged */
180
+ sha: string;
181
+ /** Story branch that was merged */
182
+ branch: string;
183
+ }
184
+ /**
185
+ * Emitted when a story's finalization completed, in every mode. For `merge`
186
+ * this follows story:merged; for `branch`/`pr` the branch itself is the
187
+ * deliverable and nothing was self-merged. A `pr`-mode event WITHOUT
188
+ * `pr_url` means PR creation failed and finalization degraded to branch
189
+ * semantics (the branch is intact locally).
190
+ */
191
+ interface StoryFinalizedEvent {
192
+ type: 'story:finalized';
193
+ /** ISO-8601 timestamp generated at emit time */
194
+ ts: string;
195
+ /** Story key (e.g., "10-1") */
196
+ key: string;
197
+ /** Finalization mode that was applied */
198
+ mode: 'merge' | 'branch' | 'pr';
199
+ /** Story branch carrying the deliverable */
200
+ branch: string;
201
+ /** Commit SHA of the deliverable commit */
202
+ sha: string;
203
+ /** PR URL (pr mode, only when gh pr create succeeded) */
204
+ pr_url?: string;
205
+ }
153
206
  /**
154
207
  * Emitted when the orchestrator auto-approves a story after exhausting
155
208
  * review cycles with only minor issues remaining. Provides transparency
@@ -783,7 +836,7 @@ interface PipelineMergeConflictDetectedEvent {
783
836
  * }
784
837
  * ```
785
838
  */
786
- type PipelineEvent = PipelineStartEvent | PipelineCompleteEvent | PipelinePreFlightFailureEvent | PipelineProfileStaleEvent | PipelineContractMismatchEvent | PipelineContractVerificationSummaryEvent | StoryPhaseEvent | StoryDoneEvent | StoryEscalationEvent | StoryWarnEvent | StoryLogEvent | PipelineHeartbeatEvent | StoryStallEvent | StoryZeroDiffEscalationEvent | StoryBuildVerificationFailedEvent | StoryBuildVerificationPassedEvent | StoryInterfaceChangeWarningEvent | StoryMetricsEvent | SupervisorPollEvent | SupervisorKillEvent | SupervisorRestartEvent | SupervisorAbortEvent | SupervisorSummaryEvent | SupervisorAnalysisCompleteEvent | SupervisorAnalysisErrorEvent | SupervisorExperimentStartEvent | SupervisorExperimentSkipEvent | SupervisorExperimentRecommendationsEvent | SupervisorExperimentCompleteEvent | SupervisorExperimentErrorEvent | RoutingModelSelectedEvent | PipelinePhaseStartEvent | PipelinePhaseCompleteEvent | StoryAutoApprovedEvent | VerificationCheckCompleteEvent | VerificationStoryCompleteEvent | CostWarningEvent | CostCeilingReachedEvent | DecisionHaltSkippedNonInteractiveEvent | PipelineMergeConflictDetectedEvent; //#endregion
839
+ type PipelineEvent = PipelineStartEvent | PipelineCompleteEvent | PipelinePreFlightFailureEvent | PipelineProfileStaleEvent | PipelineContractMismatchEvent | PipelineContractVerificationSummaryEvent | StoryPhaseEvent | StoryDoneEvent | StoryCommittedEvent | StoryMergedEvent | StoryFinalizedEvent | StoryEscalationEvent | StoryWarnEvent | StoryLogEvent | PipelineHeartbeatEvent | StoryStallEvent | StoryZeroDiffEscalationEvent | StoryBuildVerificationFailedEvent | StoryBuildVerificationPassedEvent | StoryInterfaceChangeWarningEvent | StoryMetricsEvent | SupervisorPollEvent | SupervisorKillEvent | SupervisorRestartEvent | SupervisorAbortEvent | SupervisorSummaryEvent | SupervisorAnalysisCompleteEvent | SupervisorAnalysisErrorEvent | SupervisorExperimentStartEvent | SupervisorExperimentSkipEvent | SupervisorExperimentRecommendationsEvent | SupervisorExperimentCompleteEvent | SupervisorExperimentErrorEvent | RoutingModelSelectedEvent | PipelinePhaseStartEvent | PipelinePhaseCompleteEvent | StoryAutoApprovedEvent | VerificationCheckCompleteEvent | VerificationStoryCompleteEvent | CostWarningEvent | CostCeilingReachedEvent | DecisionHaltSkippedNonInteractiveEvent | PipelineMergeConflictDetectedEvent; //#endregion
787
840
  //#region src/core/errors.d.ts
788
841
 
789
842
  /**
@@ -1015,6 +1068,13 @@ declare const SubstrateConfigSchema: z.ZodObject<{
1015
1068
  supervisor_poll_interval_seconds: z.ZodOptional<z.ZodNumber>;
1016
1069
  retry_budget: z.ZodOptional<z.ZodNumber>;
1017
1070
  epics_path: z.ZodOptional<z.ZodString>;
1071
+ finalization: z.ZodOptional<z.ZodObject<{
1072
+ mode: z.ZodOptional<z.ZodEnum<{
1073
+ merge: "merge";
1074
+ branch: "branch";
1075
+ pr: "pr";
1076
+ }>>;
1077
+ }, z.core.$strict>>;
1018
1078
  }, z.core.$strict>;
1019
1079
  type SubstrateConfig = z.infer<typeof SubstrateConfigSchema>;
1020
1080
 
@@ -1399,6 +1459,26 @@ interface OrchestratorEvents {
1399
1459
  storyKey: string;
1400
1460
  reviewCycles: number;
1401
1461
  };
1462
+ /** H3.2: substrate committed story work to its branch (deliverable feat commit) */
1463
+ 'orchestrator:story-committed': {
1464
+ storyKey: string;
1465
+ sha: string;
1466
+ branch: string;
1467
+ };
1468
+ /** H3.2: a story branch merged into the start branch */
1469
+ 'orchestrator:story-merged': {
1470
+ storyKey: string;
1471
+ sha: string;
1472
+ branch: string;
1473
+ };
1474
+ /** H3.2: terminal integration state for a verified story — never inferred from worktree presence again (field finding #14) */
1475
+ 'orchestrator:story-finalized': {
1476
+ storyKey: string;
1477
+ mode: 'merge' | 'branch' | 'pr';
1478
+ branch: string;
1479
+ sha: string;
1480
+ prUrl?: string;
1481
+ };
1402
1482
  /** A story has been escalated after exceeding max review cycles */
1403
1483
  'orchestrator:story-escalated': {
1404
1484
  storyKey: string;
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { childLogger, createLogger, logger } from "./logger-KeHncl-f.js";
2
2
  import { assertDefined, createEventBus, createTuiApp, deepClone, formatDuration, generateId, isPlainObject, isTuiCapable, printNonTtyWarning, sleep, withRetry } from "./helpers-CElYrONe.js";
3
- import { AdapterRegistry, AdtError, ClaudeCodeAdapter, CodexCLIAdapter, ConfigError, ConfigIncompatibleFormatError, GeminiCLIAdapter } from "./dist-DiNK6QOD.js";
3
+ import { AdapterRegistry, AdtError, ClaudeCodeAdapter, CodexCLIAdapter, ConfigError, ConfigIncompatibleFormatError, GeminiCLIAdapter } from "./dist-DT378h1M.js";
4
4
  import "./adapter-registry-DIcrxjH8.js";
5
- import { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError } from "./errors-B21JUhcc.js";
5
+ import { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError } from "./errors-BGE3kaH8.js";
6
6
 
7
7
  //#region src/core/di.ts
8
8
  /**
@@ -1,5 +1,5 @@
1
1
  import { createLogger } from "./logger-KeHncl-f.js";
2
- import { readCurrentRunId, resolveMainRepoRoot } from "./manifest-read-CX6KKQHX.js";
2
+ import { readCurrentRunId, resolveMainRepoRoot } from "./manifest-read-DlWwZpfO.js";
3
3
  import { join } from "node:path";
4
4
  import { mkdir, readFile, writeFile } from "node:fs/promises";
5
5
  import * as readline from "node:readline";
@@ -180,4 +180,4 @@ async function runInteractivePrompt(decisionContext) {
180
180
 
181
181
  //#endregion
182
182
  export { runInteractivePrompt };
183
- //# sourceMappingURL=interactive-prompt-PgHUXA-A.js.map
183
+ //# sourceMappingURL=interactive-prompt-xJ3K-IUQ.js.map
@@ -1,5 +1,5 @@
1
1
  import { createLogger } from "./logger-KeHncl-f.js";
2
- import { LEARNING_FINDING, createDecision, getDecisionsByCategory } from "./dist-DiNK6QOD.js";
2
+ import { LEARNING_FINDING, createDecision, getDecisionsByCategory } from "./dist-DT378h1M.js";
3
3
  import * as path$1 from "path";
4
4
  import { join } from "path";
5
5
  import { readFile } from "fs/promises";
@@ -5086,6 +5086,16 @@ const PerStoryStateSchema = z.object({
5086
5086
  commit_sha: z.string().optional(),
5087
5087
  baseline_sha: z.string().optional(),
5088
5088
  checkpoint_sha: z.string().optional(),
5089
+ finalization: z.object({
5090
+ mode: z.union([
5091
+ z.literal("merge"),
5092
+ z.literal("branch"),
5093
+ z.literal("pr")
5094
+ ]),
5095
+ branch: z.string().optional(),
5096
+ sha: z.string().optional(),
5097
+ pr_url: z.string().optional()
5098
+ }).optional(),
5089
5099
  story_file: z.string().optional(),
5090
5100
  story_file_input_path: z.string().optional(),
5091
5101
  story_file_sha256: z.string().optional(),
@@ -6290,4 +6300,4 @@ async function resolveRunManifest(dbRoot, runId) {
6290
6300
 
6291
6301
  //#endregion
6292
6302
  export { FindingsInjector, RunManifest, RuntimeProbeListSchema, SupervisorLock, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, parseRuntimeProbes, readCurrentRunId, renderFindings, resolveGraphPath, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorByClass, rollupProbeAuthorMetrics, runAcTraceabilityCheck, runStaleVerificationRecovery };
6293
- //# sourceMappingURL=manifest-read-CX6KKQHX.js.map
6303
+ //# sourceMappingURL=manifest-read-DlWwZpfO.js.map
@@ -1,6 +1,6 @@
1
1
  import "../../logger-KeHncl-f.js";
2
- import "../../dist-DiNK6QOD.js";
3
- import "../../manifest-read-CX6KKQHX.js";
4
- import { runInteractivePrompt } from "../../interactive-prompt-PgHUXA-A.js";
2
+ import "../../dist-DT378h1M.js";
3
+ import "../../manifest-read-DlWwZpfO.js";
4
+ import { runInteractivePrompt } from "../../interactive-prompt-xJ3K-IUQ.js";
5
5
 
6
6
  export { runInteractivePrompt };
@@ -1,4 +1,4 @@
1
- import { ModelRoutingConfigSchema, ProviderPolicySchema, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, TASK_TYPE_PHASE_MAP, getModelTier, loadModelRoutingConfig } from "./dist-DiNK6QOD.js";
1
+ import { ModelRoutingConfigSchema, ProviderPolicySchema, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, TASK_TYPE_PHASE_MAP, getModelTier, loadModelRoutingConfig } from "./dist-DT378h1M.js";
2
2
  import "./routing-DFxoKHDt.js";
3
3
 
4
4
  export { loadModelRoutingConfig };
@@ -1,11 +1,11 @@
1
- import { BMAD_BASELINE_TOKENS_FULL, FileKvStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, validateStoryKey } from "./health-muiK_xRZ.js";
1
+ import { BMAD_BASELINE_TOKENS_FULL, FileKvStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, validateStoryKey } from "./health-nQ_Txd5T.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, CLAUDE_AUTH_FAILURE_HINT, CODEX_SANDBOX_BLOCK_HINT, 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, classifyVersionGap, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, createStderrLogger, detectClaudeAuthFailure, detectCodexSandboxBlock, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, swallowDebug, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-DiNK6QOD.js";
5
- import { FindingsInjector, RunManifest, RuntimeProbeListSchema, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, parseRuntimeProbes, renderFindings, resolveGraphPath, resolveMainRepoRoot, runAcTraceabilityCheck, runStaleVerificationRecovery } from "./manifest-read-CX6KKQHX.js";
4
+ import { ADVISORY_NOTES, CLAUDE_AUTH_FAILURE_HINT, CODEX_SANDBOX_BLOCK_HINT, 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, classifyVersionGap, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, createStderrLogger, detectClaudeAuthFailure, detectCodexSandboxBlock, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, swallowDebug, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-DT378h1M.js";
5
+ import { FindingsInjector, RunManifest, RuntimeProbeListSchema, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, parseRuntimeProbes, renderFindings, resolveGraphPath, resolveMainRepoRoot, runAcTraceabilityCheck, runStaleVerificationRecovery } from "./manifest-read-DlWwZpfO.js";
6
6
  import { WorkGraphRepository, detectCycles } from "./work-graph-repository-DZyJv5pV.js";
7
7
  import { deriveExitCode, routeDecision } from "./decision-router-BAPpON_C.js";
8
- import { runInteractivePrompt } from "./interactive-prompt-PgHUXA-A.js";
8
+ import { runInteractivePrompt } from "./interactive-prompt-xJ3K-IUQ.js";
9
9
  import { runRecoveryEngine } from "./recovery-engine-BKGBeBnW.js";
10
10
  import { basename, dirname, extname, join } from "path";
11
11
  import { access, readFile, readdir, stat } from "fs/promises";
@@ -590,7 +590,8 @@ var GitWorktreeManagerImpl = class {
590
590
  }, "cleanupWorktree");
591
591
  if (opts?.force !== true) {
592
592
  const decision = await inspectWorktreeRemovalSafety(worktreePath, this._projectRoot, branchName);
593
- if (!decision.safe) throw new Error(`refusing to clean up worktree for "${taskId}": ${decision.reasons.join("; ")}.\nInspect first (git -C ${worktreePath} status; git log ${branchName} --oneline) or re-run with --force to discard.`);
593
+ const blockingReasons = opts?.keepBranch === true ? decision.reasons.filter((r) => r.includes("uncommitted")) : decision.reasons;
594
+ if (blockingReasons.length > 0) throw new Error(`refusing to clean up worktree for "${taskId}": ${blockingReasons.join("; ")}.\nInspect first (git -C ${worktreePath} status; git log ${branchName} --oneline) or re-run with --force to discard.`);
594
595
  }
595
596
  let worktreeExists = false;
596
597
  try {
@@ -611,7 +612,7 @@ var GitWorktreeManagerImpl = class {
611
612
  err
612
613
  }, "removeWorktree failed during cleanup");
613
614
  }
614
- try {
615
+ if (opts?.keepBranch !== true) try {
615
616
  await removeBranch(branchName, this._projectRoot);
616
617
  } catch (err) {
617
618
  this._logger.warn({
@@ -1616,6 +1617,98 @@ const PIPELINE_EVENT_METADATA = [
1616
1617
  }
1617
1618
  ]
1618
1619
  },
1620
+ {
1621
+ type: "story:committed",
1622
+ description: "Story deliverable committed on its branch (feat(story-…) auto-commit).",
1623
+ when: "Once per story after the auto-commit, before any integration step (all finalization modes).",
1624
+ fields: [
1625
+ {
1626
+ name: "ts",
1627
+ type: "string",
1628
+ description: "Timestamp."
1629
+ },
1630
+ {
1631
+ name: "key",
1632
+ type: "string",
1633
+ description: "Story key."
1634
+ },
1635
+ {
1636
+ name: "sha",
1637
+ type: "string",
1638
+ description: "Deliverable commit SHA."
1639
+ },
1640
+ {
1641
+ name: "branch",
1642
+ type: "string",
1643
+ description: "Story branch (substrate/story-<key>)."
1644
+ }
1645
+ ]
1646
+ },
1647
+ {
1648
+ type: "story:merged",
1649
+ description: "Story branch merged into the start branch.",
1650
+ when: "Once per story on merge success (merge finalization mode only).",
1651
+ fields: [
1652
+ {
1653
+ name: "ts",
1654
+ type: "string",
1655
+ description: "Timestamp."
1656
+ },
1657
+ {
1658
+ name: "key",
1659
+ type: "string",
1660
+ description: "Story key."
1661
+ },
1662
+ {
1663
+ name: "sha",
1664
+ type: "string",
1665
+ description: "Deliverable commit SHA that was merged."
1666
+ },
1667
+ {
1668
+ name: "branch",
1669
+ type: "string",
1670
+ description: "Story branch that was merged."
1671
+ }
1672
+ ]
1673
+ },
1674
+ {
1675
+ type: "story:finalized",
1676
+ description: "Story finalization completed. In branch/pr modes nothing self-merges — the branch is the deliverable. A pr-mode event without pr_url means PR creation failed and finalization degraded to branch semantics.",
1677
+ when: "Once per story after integration (every finalization mode).",
1678
+ fields: [
1679
+ {
1680
+ name: "ts",
1681
+ type: "string",
1682
+ description: "Timestamp."
1683
+ },
1684
+ {
1685
+ name: "key",
1686
+ type: "string",
1687
+ description: "Story key."
1688
+ },
1689
+ {
1690
+ name: "mode",
1691
+ type: "merge|branch|pr",
1692
+ description: "Finalization mode applied."
1693
+ },
1694
+ {
1695
+ name: "branch",
1696
+ type: "string",
1697
+ description: "Branch carrying the deliverable."
1698
+ },
1699
+ {
1700
+ name: "sha",
1701
+ type: "string",
1702
+ description: "Deliverable commit SHA."
1703
+ },
1704
+ {
1705
+ name: "pr_url",
1706
+ type: "string",
1707
+ description: "PR URL (pr mode, gh success only).",
1708
+ optional: true
1709
+ }
1710
+ ]
1711
+ },
1619
1712
  {
1620
1713
  type: "story:escalation",
1621
1714
  description: "Story escalated — either max review cycles exceeded or a precondition for SHIP_IT was not met.",
@@ -16170,6 +16263,23 @@ function createImplementationOrchestrator(deps) {
16170
16263
  let schemaValidationRetries = 0;
16171
16264
  let previousIterationWasMalformed = false;
16172
16265
  const MAX_SCHEMA_VALIDATION_RETRIES = 3;
16266
+ function recaptureChangedFiles(root) {
16267
+ const files = new Set();
16268
+ if (baselineHeadSha) try {
16269
+ execSync(`git diff --name-only ${baselineHeadSha}..HEAD`, {
16270
+ cwd: root,
16271
+ encoding: "utf-8",
16272
+ timeout: 5e3,
16273
+ stdio: [
16274
+ "ignore",
16275
+ "pipe",
16276
+ "pipe"
16277
+ ]
16278
+ }).split("\n").map((l) => l.trim()).filter((l) => l.length > 0).forEach((f$1) => files.add(f$1));
16279
+ } catch {}
16280
+ for (const f$1 of checkGitDiffFiles(root)) files.add(f$1);
16281
+ return [...files];
16282
+ }
16173
16283
  async function runVerificationAndComplete(args) {
16174
16284
  const { recordedVerdict, finalReviewCycles, reviewResult, autoApprove } = args;
16175
16285
  endPhase(storyKey, "code-review");
@@ -16285,6 +16395,8 @@ function createImplementationOrchestrator(deps) {
16285
16395
  devStoryResult: devStorySignals,
16286
16396
  outputTokenCount: devOutputTokenCount,
16287
16397
  sourceEpicContent,
16398
+ ...effectiveProjectRoot !== void 0 ? { changedFiles: recaptureChangedFiles(effectiveProjectRoot) } : {},
16399
+ ...modifiedTrackedFiles !== void 0 ? { modifiedTrackedFiles } : {},
16288
16400
  runId: config.pipelineRunId
16289
16401
  });
16290
16402
  const retryVerifSummary = await verificationPipeline.run(retryVerifContext, "A");
@@ -16453,6 +16565,7 @@ function createImplementationOrchestrator(deps) {
16453
16565
  return "completed";
16454
16566
  }
16455
16567
  async function finalizeStory(completedReviewCycles) {
16568
+ let storyDeliverableSha;
16456
16569
  if (!noWorktree && _worktreeManager !== void 0 && _orchestratorStartBranch !== void 0 && projectRoot !== void 0) {
16457
16570
  const branchName = `${BRANCH_PREFIX}${storyKey}`;
16458
16571
  if (effectiveProjectRoot !== void 0) {
@@ -16552,6 +16665,12 @@ function createImplementationOrchestrator(deps) {
16552
16665
  timeout: 5e3
16553
16666
  }).trim();
16554
16667
  } catch {}
16668
+ storyDeliverableSha = finalizeCommitSha;
16669
+ if (finalizeCommitSha) eventBus.emit("orchestrator:story-committed", {
16670
+ storyKey,
16671
+ sha: finalizeCommitSha,
16672
+ branch: branchName
16673
+ });
16555
16674
  if (runManifest !== null && finalizeCommitSha) {
16556
16675
  const statePatch = { commit_sha: finalizeCommitSha };
16557
16676
  if (storyFilePath !== void 0) try {
@@ -16626,6 +16745,70 @@ function createImplementationOrchestrator(deps) {
16626
16745
  err: gateErr instanceof Error ? gateErr.message : String(gateErr)
16627
16746
  }, "merge-to-main pre-flight verification failed — proceeding with merge phase");
16628
16747
  }
16748
+ const finalizationMode = config.finalizationMode ?? "merge";
16749
+ if (finalizationMode === "branch" || finalizationMode === "pr") {
16750
+ let prUrl;
16751
+ if (finalizationMode === "pr") try {
16752
+ execSync(`git push -u origin ${branchName}`, {
16753
+ cwd: projectRoot,
16754
+ stdio: [
16755
+ "ignore",
16756
+ "pipe",
16757
+ "pipe"
16758
+ ],
16759
+ timeout: 6e4
16760
+ });
16761
+ const shortSha = (storyDeliverableSha ?? "").slice(0, 10);
16762
+ const ghOutput = execSync(`gh pr create --head ${branchName} --title ${JSON.stringify(`story ${storyKey}: ${_capturedStoryTitle ?? "implementation"}`)} --body ${JSON.stringify(`Substrate story ${storyKey} (commit ${shortSha}). Verified by the Tier-A pipeline; see the run manifest for the full verification record.`)}`, {
16763
+ cwd: projectRoot,
16764
+ encoding: "utf-8",
16765
+ stdio: [
16766
+ "ignore",
16767
+ "pipe",
16768
+ "pipe"
16769
+ ],
16770
+ timeout: 6e4
16771
+ }).trim();
16772
+ prUrl = ghOutput === "" ? void 0 : ghOutput;
16773
+ } catch (prErr) {
16774
+ logger$27.warn({
16775
+ storyKey,
16776
+ branchName,
16777
+ err: prErr instanceof Error ? prErr.message.slice(0, 300) : String(prErr)
16778
+ }, "pr finalization: push/gh failed — degrading to branch mode (the branch is still the deliverable)");
16779
+ }
16780
+ try {
16781
+ await _worktreeManager.cleanupWorktree(storyKey, { keepBranch: true });
16782
+ } catch (cleanupErr) {
16783
+ logger$27.warn({
16784
+ storyKey,
16785
+ err: cleanupErr
16786
+ }, "worktree removal after branch/pr finalization failed (best-effort; branch intact)");
16787
+ }
16788
+ eventBus.emit("orchestrator:story-finalized", {
16789
+ storyKey,
16790
+ mode: finalizationMode,
16791
+ branch: branchName,
16792
+ sha: storyDeliverableSha ?? "",
16793
+ ...prUrl !== void 0 ? { prUrl } : {}
16794
+ });
16795
+ if (runManifest !== null) runManifest.patchStoryState(storyKey, { finalization: {
16796
+ mode: finalizationMode,
16797
+ branch: branchName,
16798
+ ...storyDeliverableSha ? { sha: storyDeliverableSha } : {},
16799
+ ...prUrl !== void 0 ? { pr_url: prUrl } : {}
16800
+ } }).catch((err) => logger$27.warn({
16801
+ err,
16802
+ storyKey
16803
+ }, "patchStoryState(finalization) failed — pipeline continues"));
16804
+ logger$27.info({
16805
+ storyKey,
16806
+ branchName,
16807
+ mode: finalizationMode,
16808
+ prUrl
16809
+ }, "story finalized without self-merge — branch is the deliverable");
16810
+ return "finalized";
16811
+ }
16629
16812
  logger$27.info({
16630
16813
  storyKey,
16631
16814
  branchName,
@@ -16685,6 +16868,25 @@ function createImplementationOrchestrator(deps) {
16685
16868
  storyKey,
16686
16869
  branchName
16687
16870
  }, "merge-to-main phase completed successfully");
16871
+ eventBus.emit("orchestrator:story-merged", {
16872
+ storyKey,
16873
+ sha: storyDeliverableSha ?? "",
16874
+ branch: branchName
16875
+ });
16876
+ eventBus.emit("orchestrator:story-finalized", {
16877
+ storyKey,
16878
+ mode: "merge",
16879
+ branch: branchName,
16880
+ sha: storyDeliverableSha ?? ""
16881
+ });
16882
+ if (runManifest !== null) runManifest.patchStoryState(storyKey, { finalization: {
16883
+ mode: "merge",
16884
+ branch: branchName,
16885
+ ...storyDeliverableSha ? { sha: storyDeliverableSha } : {}
16886
+ } }).catch((err) => logger$27.warn({
16887
+ err,
16888
+ storyKey
16889
+ }, "patchStoryState(finalization) failed — pipeline continues"));
16688
16890
  }
16689
16891
  return "finalized";
16690
16892
  }
@@ -46392,6 +46594,35 @@ function wireNdjsonEmitter(eventBus, ndjsonEmitter) {
46392
46594
  review_cycles: payload.reviewCycles
46393
46595
  });
46394
46596
  });
46597
+ eventBus.on("orchestrator:story-committed", (payload) => {
46598
+ ndjsonEmitter.emit({
46599
+ type: "story:committed",
46600
+ ts: new Date().toISOString(),
46601
+ key: payload.storyKey,
46602
+ sha: payload.sha,
46603
+ branch: payload.branch
46604
+ });
46605
+ });
46606
+ eventBus.on("orchestrator:story-merged", (payload) => {
46607
+ ndjsonEmitter.emit({
46608
+ type: "story:merged",
46609
+ ts: new Date().toISOString(),
46610
+ key: payload.storyKey,
46611
+ sha: payload.sha,
46612
+ branch: payload.branch
46613
+ });
46614
+ });
46615
+ eventBus.on("orchestrator:story-finalized", (payload) => {
46616
+ ndjsonEmitter.emit({
46617
+ type: "story:finalized",
46618
+ ts: new Date().toISOString(),
46619
+ key: payload.storyKey,
46620
+ mode: payload.mode,
46621
+ branch: payload.branch,
46622
+ sha: payload.sha,
46623
+ ...payload.prUrl !== void 0 ? { pr_url: payload.prUrl } : {}
46624
+ });
46625
+ });
46395
46626
  eventBus.on("orchestrator:story-escalated", (payload) => {
46396
46627
  const rawIssues = Array.isArray(payload.issues) ? payload.issues : [];
46397
46628
  const issues = rawIssues.map((issue) => {
@@ -46605,7 +46836,7 @@ function resolveProbeAuthorStateIntegrating(cliFlag) {
46605
46836
  * substrate run --non-interactive --halt-on none --events --output-format json
46606
46837
  */
46607
46838
  async function runRunAction(options) {
46608
- 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: explicitAgentId, registry: injectedRegistry, haltOn: haltOnOpt, costCeiling, probeAuthor, probeAuthorStateIntegrating: probeAuthorStateIntegratingFlag, nonInteractive, verifyAc, noWorktree } = options;
46839
+ 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: explicitAgentId, registry: injectedRegistry, haltOn: haltOnOpt, costCeiling, probeAuthor, probeAuthorStateIntegrating: probeAuthorStateIntegratingFlag, nonInteractive, verifyAc, noWorktree, finalization } = options;
46609
46840
  const haltOn = haltOnOpt;
46610
46841
  const VALID_PROBE_AUTHOR_MODES = [
46611
46842
  "enabled",
@@ -46721,6 +46952,7 @@ async function runRunAction(options) {
46721
46952
  let meshUrl;
46722
46953
  let meshProjectId;
46723
46954
  let configRetryBudget;
46955
+ let configFinalizationMode;
46724
46956
  let configWorktreeCopyFiles;
46725
46957
  try {
46726
46958
  const configSystem = createConfigSystem({ projectConfigDir: dbDir });
@@ -46747,6 +46979,7 @@ async function runRunAction(options) {
46747
46979
  meshProjectId = cfg.telemetry.projectId;
46748
46980
  }
46749
46981
  if (typeof cfg.retry_budget === "number") configRetryBudget = cfg.retry_budget;
46982
+ if (cfg.finalization?.mode !== void 0) configFinalizationMode = cfg.finalization.mode;
46750
46983
  if (Array.isArray(cfg.worktree?.copy_files) && cfg.worktree.copy_files.length > 0) {
46751
46984
  configWorktreeCopyFiles = [...cfg.worktree.copy_files];
46752
46985
  logger.info({ copyFiles: configWorktreeCopyFiles }, "Loaded worktree.copy_files from config");
@@ -46846,6 +47079,7 @@ async function runRunAction(options) {
46846
47079
  retryBudget: configRetryBudget ?? 2,
46847
47080
  agentId,
46848
47081
  ...noWorktree === true ? { noWorktree: true } : {},
47082
+ ...finalization !== void 0 ? { finalizationMode: finalization } : configFinalizationMode !== void 0 ? { finalizationMode: configFinalizationMode } : {},
46849
47083
  ...configWorktreeCopyFiles !== void 0 ? { worktreeCopyFiles: configWorktreeCopyFiles } : {}
46850
47084
  });
46851
47085
  let storyKeys = [...parsedStoryKeys];
@@ -47409,6 +47643,7 @@ async function runRunAction(options) {
47409
47643
  ...probeAuthor !== void 0 ? { probeAuthorMode: probeAuthor } : {},
47410
47644
  probeAuthorStateIntegrating: resolvedProbeAuthorStateIntegrating,
47411
47645
  ...noWorktree === true ? { noWorktree: true } : {},
47646
+ ...finalization !== void 0 ? { finalizationMode: finalization } : configFinalizationMode !== void 0 ? { finalizationMode: configFinalizationMode } : {},
47412
47647
  ...configWorktreeCopyFiles !== void 0 ? { worktreeCopyFiles: configWorktreeCopyFiles } : {}
47413
47648
  },
47414
47649
  projectRoot,
@@ -47632,7 +47867,7 @@ async function runRunAction(options) {
47632
47867
  }
47633
47868
  }
47634
47869
  async function runFullPipeline(options) {
47635
- const { packName, packPath, dbDir, dbPath, startPhase, stopAfter, concept, concurrency, outputFormat, projectRoot, events: eventsFlag, skipUx, research: researchFlag, skipResearch: skipResearchFlag, skipPreflight, skipVerification, maxReviewCycles = 2, retryBudget, registry: injectedRegistry, tokenCeilings, stories: explicitStories, telemetryEnabled: fullTelemetryEnabled, telemetryPort: fullTelemetryPort, agentId, meshUrl: fpMeshUrl, meshProjectId: fpMeshProjectId, engineType: fpEngineType, probeAuthor, probeAuthorStateIntegrating: fpProbeAuthorStateIntegrating, noWorktree, worktreeCopyFiles: fpWorktreeCopyFiles } = options;
47870
+ const { packName, packPath, dbDir, dbPath, startPhase, stopAfter, concept, concurrency, outputFormat, projectRoot, events: eventsFlag, skipUx, research: researchFlag, skipResearch: skipResearchFlag, skipPreflight, skipVerification, maxReviewCycles = 2, retryBudget, registry: injectedRegistry, tokenCeilings, stories: explicitStories, telemetryEnabled: fullTelemetryEnabled, telemetryPort: fullTelemetryPort, agentId, meshUrl: fpMeshUrl, meshProjectId: fpMeshProjectId, engineType: fpEngineType, probeAuthor, probeAuthorStateIntegrating: fpProbeAuthorStateIntegrating, noWorktree, worktreeCopyFiles: fpWorktreeCopyFiles, finalizationMode: fpFinalizationMode } = options;
47636
47871
  if (!existsSync$1(dbDir)) mkdirSync$1(dbDir, { recursive: true });
47637
47872
  let doltServerFull = null;
47638
47873
  try {
@@ -47942,6 +48177,7 @@ async function runFullPipeline(options) {
47942
48177
  ...probeAuthor !== void 0 ? { probeAuthorMode: probeAuthor } : {},
47943
48178
  ...fpProbeAuthorStateIntegrating !== void 0 ? { probeAuthorStateIntegrating: fpProbeAuthorStateIntegrating } : {},
47944
48179
  ...noWorktree === true ? { noWorktree: true } : {},
48180
+ ...fpFinalizationMode !== void 0 ? { finalizationMode: fpFinalizationMode } : {},
47945
48181
  ...fpWorktreeCopyFiles !== void 0 ? { worktreeCopyFiles: fpWorktreeCopyFiles } : {}
47946
48182
  },
47947
48183
  projectRoot,
@@ -48112,7 +48348,7 @@ async function runFullPipeline(options) {
48112
48348
  */
48113
48349
  async function emitPreDispatchVersionAdvisory(currentVersion) {
48114
48350
  if (process.env["SUBSTRATE_NO_UPDATE_CHECK"] === "1") return;
48115
- const { createVersionManager } = await import("./version-manager-impl-HJMonRJi.js");
48351
+ const { createVersionManager } = await import("./version-manager-impl-BWqvme_f.js");
48116
48352
  const vm = createVersionManager();
48117
48353
  const result = await vm.checkForUpdates(true);
48118
48354
  const gap = classifyVersionGap(currentVersion, result.latestVersion);
@@ -48152,7 +48388,7 @@ function registerRunCommand(program, version = "0.0.0", projectRoot = process.cw
48152
48388
  "",
48153
48389
  "--halt-on defaults to critical. Skipped halt decisions are recorded as",
48154
48390
  "decision:halt-skipped-non-interactive events in --non-interactive mode."
48155
- ].join("\n ")).option("--verify-ac", "Run AC-to-test traceability heuristic after the pipeline completes (Story 74-1)").option("--no-worktree", "Bypass per-story git worktrees (safety valve for submodules, bare repos, or large checkouts where parallel worktrees blow disk — not the recommended path)").action(async (opts) => {
48391
+ ].join("\n ")).option("--verify-ac", "Run AC-to-test traceability heuristic after the pipeline completes (Story 74-1)").option("--no-worktree", "Bypass per-story git worktrees (safety valve for submodules, bare repos, or large checkouts where parallel worktrees blow disk — not the recommended path)").option("--finalization <mode>", "H3.1: how verified stories integrate: 'merge' (default, local merge), 'branch' (never self-merge — the story branch is the deliverable), 'pr' (branch + push + gh pr create; degrades to branch on failure).").action(async (opts) => {
48156
48392
  if (opts.helpAgent) {
48157
48393
  process.exitCode = await runHelpAgent();
48158
48394
  return;
@@ -48170,6 +48406,15 @@ function registerRunCommand(program, version = "0.0.0", projectRoot = process.cw
48170
48406
  }
48171
48407
  fromPhase = opts.from;
48172
48408
  }
48409
+ if (opts.finalization !== void 0 && ![
48410
+ "merge",
48411
+ "branch",
48412
+ "pr"
48413
+ ].includes(String(opts.finalization))) {
48414
+ process.stderr.write(`Invalid --finalization "${String(opts.finalization)}" — expected merge | branch | pr\n`);
48415
+ process.exitCode = 2;
48416
+ return;
48417
+ }
48173
48418
  const exitCode = await runRunAction({
48174
48419
  pack: opts.pack,
48175
48420
  from: fromPhase,
@@ -48200,7 +48445,8 @@ function registerRunCommand(program, version = "0.0.0", projectRoot = process.cw
48200
48445
  probeAuthorStateIntegrating: opts.probeAuthorStateIntegrating,
48201
48446
  nonInteractive: opts.nonInteractive,
48202
48447
  verifyAc: opts.verifyAc,
48203
- noWorktree: opts.worktree === false || process.env["SUBSTRATE_NO_WORKTREE"] === "1"
48448
+ noWorktree: opts.worktree === false || process.env["SUBSTRATE_NO_WORKTREE"] === "1",
48449
+ finalization: opts.finalization
48204
48450
  });
48205
48451
  if (opts.nonInteractive === true) process.exit(exitCode);
48206
48452
  process.exitCode = exitCode;
@@ -48209,4 +48455,4 @@ function registerRunCommand(program, version = "0.0.0", projectRoot = process.cw
48209
48455
 
48210
48456
  //#endregion
48211
48457
  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, createGitWorktreeManager, 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 };
48212
- //# sourceMappingURL=run-DHPGxjlk.js.map
48458
+ //# sourceMappingURL=run-BBVZdkEo.js.map
@@ -1,14 +1,14 @@
1
- import "./health-muiK_xRZ.js";
1
+ import "./health-nQ_Txd5T.js";
2
2
  import "./logger-KeHncl-f.js";
3
3
  import "./helpers-CElYrONe.js";
4
- import "./dist-DiNK6QOD.js";
5
- import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, runRunAction, wireNdjsonEmitter } from "./run-DHPGxjlk.js";
6
- import "./manifest-read-CX6KKQHX.js";
4
+ import "./dist-DT378h1M.js";
5
+ import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, runRunAction, wireNdjsonEmitter } from "./run-BBVZdkEo.js";
6
+ import "./manifest-read-DlWwZpfO.js";
7
7
  import "./routing-DFxoKHDt.js";
8
8
  import "./work-graph-repository-DZyJv5pV.js";
9
9
  import "./decisions-CzSIEeGP.js";
10
10
  import "./decision-router-BAPpON_C.js";
11
- import "./interactive-prompt-PgHUXA-A.js";
11
+ import "./interactive-prompt-xJ3K-IUQ.js";
12
12
  import "./recovery-engine-BKGBeBnW.js";
13
13
 
14
14
  export { runRunAction };
@@ -1,4 +1,4 @@
1
- import { CoreEvents, DatabaseAdapter, TypedEventBus } from "../../../index-BqVBOAO0.js";
1
+ import { CoreEvents, DatabaseAdapter, TypedEventBus } from "../../../index-DaBYDiWn.js";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region packages/sdlc/dist/verification/findings.d.ts
@@ -583,6 +583,12 @@ declare const PerStoryStateSchema: z.ZodObject<{
583
583
  commit_sha: z.ZodOptional<z.ZodString>;
584
584
  baseline_sha: z.ZodOptional<z.ZodString>;
585
585
  checkpoint_sha: z.ZodOptional<z.ZodString>;
586
+ finalization: z.ZodOptional<z.ZodObject<{
587
+ mode: z.ZodUnion<readonly [z.ZodLiteral<"merge">, z.ZodLiteral<"branch">, z.ZodLiteral<"pr">]>;
588
+ branch: z.ZodOptional<z.ZodString>;
589
+ sha: z.ZodOptional<z.ZodString>;
590
+ pr_url: z.ZodOptional<z.ZodString>;
591
+ }, z.core.$strip>>;
586
592
  story_file: z.ZodOptional<z.ZodString>;
587
593
  story_file_input_path: z.ZodOptional<z.ZodString>;
588
594
  story_file_sha256: z.ZodOptional<z.ZodString>;
@@ -1,4 +1,4 @@
1
- import { createVersionManager } from "./dist-DiNK6QOD.js";
1
+ import { createVersionManager } from "./dist-DT378h1M.js";
2
2
  import { execSync, spawn } from "child_process";
3
3
  import * as readline from "readline";
4
4
 
@@ -123,4 +123,4 @@ function registerUpgradeCommand(program) {
123
123
 
124
124
  //#endregion
125
125
  export { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand };
126
- //# sourceMappingURL=upgrade-DB7KzD9c.js.map
126
+ //# sourceMappingURL=upgrade-BVHnUYUd.js.map
@@ -1,5 +1,5 @@
1
- import "./dist-DiNK6QOD.js";
1
+ import "./dist-DT378h1M.js";
2
2
  import "./version-manager-impl-qFBiO4Eh.js";
3
- import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-DB7KzD9c.js";
3
+ import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-BVHnUYUd.js";
4
4
 
5
5
  export { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand };
@@ -1,4 +1,4 @@
1
- import { VersionManagerImpl, createVersionManager } from "./dist-DiNK6QOD.js";
1
+ import { VersionManagerImpl, createVersionManager } from "./dist-DT378h1M.js";
2
2
  import "./version-manager-impl-qFBiO4Eh.js";
3
3
 
4
4
  export { createVersionManager };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "substrate-ai",
3
- "version": "0.20.145",
3
+ "version": "0.20.147",
4
4
  "description": "Substrate — multi-agent orchestration daemon for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,4 +0,0 @@
1
- import { AdapterRegistry } from "./dist-DiNK6QOD.js";
2
- import "./adapter-registry-DIcrxjH8.js";
3
-
4
- export { AdapterRegistry };