substrate-ai 0.20.146 → 0.20.148

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-CZk5SeSt.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-eGHKiGlU.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-Aqc5cghP.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-D2mJXElX.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-BhoAW6dJ.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-CZk5SeSt.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-B9DV9sro.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-7kyDfQAK.js";
9
- import "../errors-CIBnPmzQ.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-D6NAZgt8.js";
9
+ import "../errors-_tbIg6Cv.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-opOBwMDU.js";
14
+ import "../interactive-prompt-BLkX0iE_.js";
15
15
  import "../recovery-engine-BKGBeBnW.js";
16
16
  import "../version-manager-impl-qFBiO4Eh.js";
17
- import { registerUpgradeCommand } from "../upgrade-Djo0dJak.js";
17
+ import { registerUpgradeCommand } from "../upgrade-BEfZJU4K.js";
18
18
  import { Command } from "commander";
19
19
  import { fileURLToPath } from "url";
20
20
  import { dirname, join, resolve } from "path";
@@ -623,7 +623,16 @@ 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({
628
+ mode: z.enum([
629
+ "merge",
630
+ "branch",
631
+ "pr"
632
+ ]).optional(),
633
+ merge_strategy: z.enum(["ff-only", "three-way"]).optional(),
634
+ epic_gate_command: z.string().optional()
635
+ }).strict().optional()
627
636
  }).strict();
628
637
  const PartialSubstrateConfigSchema = z.object({
629
638
  config_format_version: z.enum(["1"]).optional(),
@@ -642,7 +651,16 @@ const PartialSubstrateConfigSchema = z.object({
642
651
  default_agent: z.string().optional(),
643
652
  supervisor_poll_interval_seconds: z.number().int().positive().optional(),
644
653
  retry_budget: z.number().int().positive().optional(),
645
- epics_path: z.string().optional()
654
+ epics_path: z.string().optional(),
655
+ finalization: z.object({
656
+ mode: z.enum([
657
+ "merge",
658
+ "branch",
659
+ "pr"
660
+ ]).optional(),
661
+ merge_strategy: z.enum(["ff-only", "three-way"]).optional(),
662
+ epic_gate_command: z.string().optional()
663
+ }).strict().optional()
646
664
  }).strict();
647
665
 
648
666
  //#endregion
@@ -7052,7 +7070,7 @@ async function runStatusAction(options) {
7052
7070
  logger$15.debug({ err }, "Work graph query failed, continuing without work graph data");
7053
7071
  }
7054
7072
  if (run === void 0) {
7055
- const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-RQmFEmIC.js");
7073
+ const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-Cm0aQCQL.js");
7056
7074
  const substrateDirPath = join(projectRoot, ".substrate");
7057
7075
  const processInfo = inspectProcessTree$1({
7058
7076
  projectRoot,
@@ -8000,7 +8018,7 @@ function defaultSupervisorDeps() {
8000
8018
  if (cached === null) {
8001
8019
  const { AdapterRegistry: AR } = await import(
8002
8020
  /* @vite-ignore */
8003
- "../adapter-registry-BPwWmPjJ.js"
8021
+ "../adapter-registry-hLwwiJGM.js"
8004
8022
  );
8005
8023
  cached = new AR();
8006
8024
  await cached.discoverAndRegister();
@@ -8567,11 +8585,11 @@ async function runSupervisorAction(options, deps = {}) {
8567
8585
  try {
8568
8586
  const { createExperimenter } = await import(
8569
8587
  /* @vite-ignore */
8570
- "../experimenter-BZ17IbjW.js"
8588
+ "../experimenter-RnaEiLUD.js"
8571
8589
  );
8572
8590
  const { getLatestRun: getLatest } = await import(
8573
8591
  /* @vite-ignore */
8574
- "../decisions-D_HEApFV.js"
8592
+ "../decisions-DSDqOEN4.js"
8575
8593
  );
8576
8594
  const expAdapter = createDatabaseAdapter({
8577
8595
  backend: "auto",
@@ -8581,7 +8599,7 @@ async function runSupervisorAction(options, deps = {}) {
8581
8599
  await initSchema(expAdapter);
8582
8600
  const { runRunAction: runPipeline } = await import(
8583
8601
  /* @vite-ignore */
8584
- "../run-CJHnHg3o.js"
8602
+ "../run-BX-__EJm.js"
8585
8603
  );
8586
8604
  const runStoryFn = async (opts) => {
8587
8605
  const exitCode = await runPipeline({
@@ -9106,7 +9124,7 @@ async function runMetricsAction(options) {
9106
9124
  const routingConfigPath = join(dbDir, "routing.yml");
9107
9125
  let routingConfig = null;
9108
9126
  if (existsSync$1(routingConfigPath)) try {
9109
- const { loadModelRoutingConfig } = await import("../routing-CLVK4nBN.js");
9127
+ const { loadModelRoutingConfig } = await import("../routing-QBUaShFv.js");
9110
9128
  routingConfig = loadModelRoutingConfig(routingConfigPath);
9111
9129
  } catch {}
9112
9130
  if (routingConfig === null) routingConfig = {
@@ -12972,6 +12990,17 @@ function renderHuman(output, manifest) {
12972
12990
  ], COL_WIDTHS));
12973
12991
  }
12974
12992
  lines.push("");
12993
+ const unmerged = stories.filter((s) => s.finalization !== void 0 && s.finalization.mode !== "merge");
12994
+ if (unmerged.length > 0) {
12995
+ lines.push("Finalization (deliverable branches — NOT merged):");
12996
+ for (const s of unmerged) {
12997
+ const fz = s.finalization ?? {};
12998
+ const shaStr = fz.sha ? ` @ ${fz.sha.slice(0, 10)}` : "";
12999
+ const prStr = fz.mode === "pr" ? fz.pr_url ? ` PR: ${fz.pr_url}` : " PR: creation failed — degraded to branch" : "";
13000
+ lines.push(` ${s.story_key}: [${fz.mode ?? "?"}] ${fz.branch ?? "?"}${shaStr}${prStr}`);
13001
+ }
13002
+ lines.push("");
13003
+ }
12975
13004
  const lowOutputStories = stories.filter((s) => s.low_output_warning === true);
12976
13005
  if (lowOutputStories.length > 0) {
12977
13006
  lines.push(`⚠ ${lowOutputStories.length} story/stories produced fewer than ${LOW_OUTPUT_TOKEN_THRESHOLD} output tokens —`);
@@ -13104,7 +13133,8 @@ function assembleReport(runId, manifest, halts, storyOutputTokens) {
13104
13133
  verification_findings: findings,
13105
13134
  verification_ran: verificationRan,
13106
13135
  ...outputTokens !== void 0 ? { output_tokens: outputTokens } : {},
13107
- ...lowOutputWarning ? { low_output_warning: true } : {}
13136
+ ...lowOutputWarning ? { low_output_warning: true } : {},
13137
+ ...state.finalization !== void 0 ? { finalization: state.finalization } : {}
13108
13138
  };
13109
13139
  stories.push(storySummary);
13110
13140
  summary[outcome]++;
@@ -13420,8 +13450,8 @@ async function createProgram() {
13420
13450
  /** Fire-and-forget startup version check (story 8.3, AC3/AC5) */
13421
13451
  function checkForUpdatesInBackground(currentVersion) {
13422
13452
  if (process.env.SUBSTRATE_NO_UPDATE_CHECK === "1") return;
13423
- import("../upgrade-DnB0p8b5.js").then(async () => {
13424
- const { createVersionManager } = await import("../version-manager-impl-CKsauG6T.js");
13453
+ import("../upgrade-emlrK3YW.js").then(async () => {
13454
+ const { createVersionManager } = await import("../version-manager-impl-_x1n4xZk.js");
13425
13455
  const vm = createVersionManager();
13426
13456
  const result = await vm.checkForUpdates();
13427
13457
  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-D2mJXElX.js";
1
+ import { addTokenUsage, createDecision, createPipelineRun, createRequirement, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunningPipelineRuns, getTokenUsageSummary, listRequirements, registerArtifact, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision } from "./dist-CZk5SeSt.js";
2
2
  import "./decisions-CzSIEeGP.js";
3
3
 
4
4
  export { getLatestRun };
@@ -6251,7 +6251,16 @@ 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({
6256
+ mode: z.enum([
6257
+ "merge",
6258
+ "branch",
6259
+ "pr"
6260
+ ]).optional(),
6261
+ merge_strategy: z.enum(["ff-only", "three-way"]).optional(),
6262
+ epic_gate_command: z.string().optional()
6263
+ }).strict().optional()
6255
6264
  }).passthrough();
6256
6265
  const PartialProviderConfigSchema = ProviderConfigSchema.partial();
6257
6266
  const PartialGlobalSettingsSchema = GlobalSettingsSchema.partial();
@@ -6268,7 +6277,16 @@ const PartialSubstrateConfigSchema = z.object({
6268
6277
  budget: BudgetConfigSchema.partial().optional(),
6269
6278
  telemetry: TelemetryConfigSchema.partial().optional(),
6270
6279
  worktree: WorktreeConfigSchema.partial().optional(),
6271
- trivialOutputThreshold: z.number().int().nonnegative().optional()
6280
+ trivialOutputThreshold: z.number().int().nonnegative().optional(),
6281
+ finalization: z.object({
6282
+ mode: z.enum([
6283
+ "merge",
6284
+ "branch",
6285
+ "pr"
6286
+ ]).optional(),
6287
+ merge_strategy: z.enum(["ff-only", "three-way"]).optional(),
6288
+ epic_gate_command: z.string().optional()
6289
+ }).strict().optional()
6272
6290
  }).passthrough();
6273
6291
 
6274
6292
  //#endregion
@@ -11636,4 +11654,4 @@ async function callLLM(params) {
11636
11654
 
11637
11655
  //#endregion
11638
11656
  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 };
11639
- //# sourceMappingURL=dist-D2mJXElX.js.map
11657
+ //# sourceMappingURL=dist-CZk5SeSt.js.map
@@ -1,4 +1,4 @@
1
- import { AdtError } from "./dist-D2mJXElX.js";
1
+ import { AdtError } from "./dist-CZk5SeSt.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-CIBnPmzQ.js.map
74
+ //# sourceMappingURL=errors-_tbIg6Cv.js.map
@@ -1,3 +1,3 @@
1
- import { buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, createExperimenter, determineVerdict, resolvePromptFile } from "./dist-D2mJXElX.js";
1
+ import { buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, createExperimenter, determineVerdict, resolvePromptFile } from "./dist-CZk5SeSt.js";
2
2
 
3
3
  export { createExperimenter };
@@ -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-D2mJXElX.js";
3
- import { resolveMainRepoRoot, resolveRunManifest } from "./manifest-read-7kyDfQAK.js";
2
+ import { DoltClient, DoltQueryError, createDatabaseAdapter$1 as createDatabaseAdapter, getLatestRun, getPipelineRunById, initSchema } from "./dist-CZk5SeSt.js";
3
+ import { resolveMainRepoRoot, resolveRunManifest } from "./manifest-read-D6NAZgt8.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-eGHKiGlU.js.map
1003
+ //# sourceMappingURL=health-Aqc5cghP.js.map
@@ -1,7 +1,7 @@
1
- import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-eGHKiGlU.js";
1
+ import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-Aqc5cghP.js";
2
2
  import "./logger-KeHncl-f.js";
3
- import "./dist-D2mJXElX.js";
4
- import "./manifest-read-7kyDfQAK.js";
3
+ import "./dist-CZk5SeSt.js";
4
+ import "./manifest-read-D6NAZgt8.js";
5
5
  import "./work-graph-repository-DZyJv5pV.js";
6
6
  import "./decisions-CzSIEeGP.js";
7
7
 
@@ -292,6 +292,18 @@ 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
+ merge_strategy: z.ZodOptional<z.ZodEnum<{
302
+ "ff-only": "ff-only";
303
+ "three-way": "three-way";
304
+ }>>;
305
+ epic_gate_command: z.ZodOptional<z.ZodString>;
306
+ }, z.core.$strict>>;
295
307
  }, z.core.$loose>;
296
308
  type SubstrateConfig = z.infer<typeof SubstrateConfigSchema>; //#endregion
297
309
  //#region packages/core/dist/events/core-events.d.ts
@@ -1584,4 +1596,4 @@ interface Recommendation {
1584
1596
 
1585
1597
  //#endregion
1586
1598
  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
1599
+ //# sourceMappingURL=index-CvNLhgKV.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-CvNLhgKV.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,18 @@ 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
+ merge_strategy: z.ZodOptional<z.ZodEnum<{
1078
+ "ff-only": "ff-only";
1079
+ "three-way": "three-way";
1080
+ }>>;
1081
+ epic_gate_command: z.ZodOptional<z.ZodString>;
1082
+ }, z.core.$strict>>;
1018
1083
  }, z.core.$strict>;
1019
1084
  type SubstrateConfig = z.infer<typeof SubstrateConfigSchema>;
1020
1085
 
@@ -1399,6 +1464,26 @@ interface OrchestratorEvents {
1399
1464
  storyKey: string;
1400
1465
  reviewCycles: number;
1401
1466
  };
1467
+ /** H3.2: substrate committed story work to its branch (deliverable feat commit) */
1468
+ 'orchestrator:story-committed': {
1469
+ storyKey: string;
1470
+ sha: string;
1471
+ branch: string;
1472
+ };
1473
+ /** H3.2: a story branch merged into the start branch */
1474
+ 'orchestrator:story-merged': {
1475
+ storyKey: string;
1476
+ sha: string;
1477
+ branch: string;
1478
+ };
1479
+ /** H3.2: terminal integration state for a verified story — never inferred from worktree presence again (field finding #14) */
1480
+ 'orchestrator:story-finalized': {
1481
+ storyKey: string;
1482
+ mode: 'merge' | 'branch' | 'pr';
1483
+ branch: string;
1484
+ sha: string;
1485
+ prUrl?: string;
1486
+ };
1402
1487
  /** A story has been escalated after exceeding max review cycles */
1403
1488
  'orchestrator:story-escalated': {
1404
1489
  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-D2mJXElX.js";
3
+ import { AdapterRegistry, AdtError, ClaudeCodeAdapter, CodexCLIAdapter, ConfigError, ConfigIncompatibleFormatError, GeminiCLIAdapter } from "./dist-CZk5SeSt.js";
4
4
  import "./adapter-registry-DIcrxjH8.js";
5
- import { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError } from "./errors-CIBnPmzQ.js";
5
+ import { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError } from "./errors-_tbIg6Cv.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-7kyDfQAK.js";
2
+ import { readCurrentRunId, resolveMainRepoRoot } from "./manifest-read-D6NAZgt8.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-opOBwMDU.js.map
183
+ //# sourceMappingURL=interactive-prompt-BLkX0iE_.js.map
@@ -1,5 +1,5 @@
1
1
  import { createLogger } from "./logger-KeHncl-f.js";
2
- import { LEARNING_FINDING, createDecision, getDecisionsByCategory } from "./dist-D2mJXElX.js";
2
+ import { LEARNING_FINDING, createDecision, getDecisionsByCategory } from "./dist-CZk5SeSt.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-7kyDfQAK.js.map
6303
+ //# sourceMappingURL=manifest-read-D6NAZgt8.js.map
@@ -1,6 +1,6 @@
1
1
  import "../../logger-KeHncl-f.js";
2
- import "../../dist-D2mJXElX.js";
3
- import "../../manifest-read-7kyDfQAK.js";
4
- import { runInteractivePrompt } from "../../interactive-prompt-opOBwMDU.js";
2
+ import "../../dist-CZk5SeSt.js";
3
+ import "../../manifest-read-D6NAZgt8.js";
4
+ import { runInteractivePrompt } from "../../interactive-prompt-BLkX0iE_.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-D2mJXElX.js";
1
+ import { ModelRoutingConfigSchema, ProviderPolicySchema, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, TASK_TYPE_PHASE_MAP, getModelTier, loadModelRoutingConfig } from "./dist-CZk5SeSt.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-eGHKiGlU.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-Aqc5cghP.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-D2mJXElX.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-7kyDfQAK.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-CZk5SeSt.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-D6NAZgt8.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-opOBwMDU.js";
8
+ import { runInteractivePrompt } from "./interactive-prompt-BLkX0iE_.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.",
@@ -9513,11 +9606,26 @@ const logger$16 = createLogger("compiled-workflows:merge-to-main");
9513
9606
  */
9514
9607
  async function runMergeToMain(params) {
9515
9608
  const { storyKey, branchName, startBranch, worktreeManager, eventBus, projectRoot } = params;
9609
+ const mergeStrategy = params.mergeStrategy ?? "ff-only";
9516
9610
  logger$16.info({
9517
9611
  storyKey,
9518
9612
  branchName,
9519
- startBranch
9613
+ startBranch,
9614
+ mergeStrategy
9520
9615
  }, "Starting merge-to-main phase");
9616
+ const dirtiedFiles = listParentDirtyIntersection(branchName, startBranch, projectRoot);
9617
+ if (dirtiedFiles.length > 0) {
9618
+ logger$16.warn({
9619
+ storyKey,
9620
+ branchName,
9621
+ dirtiedFiles
9622
+ }, "parent working tree has uncommitted changes to files in the story diff — refusing to merge");
9623
+ return {
9624
+ success: false,
9625
+ reason: "parent-tree-dirtied-by-run",
9626
+ dirtiedFiles
9627
+ };
9628
+ }
9521
9629
  const ffSuccess = tryFfMerge(branchName, projectRoot);
9522
9630
  if (ffSuccess) {
9523
9631
  logger$16.info({
@@ -9527,6 +9635,17 @@ async function runMergeToMain(params) {
9527
9635
  await cleanupAfterSuccessfulMerge(storyKey, branchName, worktreeManager, projectRoot);
9528
9636
  return { success: true };
9529
9637
  }
9638
+ if (mergeStrategy === "ff-only") {
9639
+ logger$16.warn({
9640
+ storyKey,
9641
+ branchName,
9642
+ startBranch
9643
+ }, "fast-forward not possible (base moved since the story branched) and merge_strategy is ff-only — refusing 3-way merge. Set finalization.merge_strategy: three-way to allow it (required for concurrent multi-story runs), or integrate the branch manually.");
9644
+ return {
9645
+ success: false,
9646
+ reason: "ff-only-merge-not-possible"
9647
+ };
9648
+ }
9530
9649
  logger$16.info({
9531
9650
  storyKey,
9532
9651
  branchName
@@ -9558,6 +9677,47 @@ async function runMergeToMain(params) {
9558
9677
  };
9559
9678
  }
9560
9679
  /**
9680
+ * H3.3 (AC1): files that are both dirty in the parent working tree and part of
9681
+ * the story branch's diff against the start branch. Best-effort: if either
9682
+ * git query fails, returns [] (the merge itself will surface genuine issues).
9683
+ */
9684
+ function listParentDirtyIntersection(branchName, startBranch, projectRoot) {
9685
+ try {
9686
+ const statusOut = execFileSync("git", ["status", "--porcelain"], {
9687
+ cwd: projectRoot,
9688
+ encoding: "utf-8",
9689
+ stdio: [
9690
+ "ignore",
9691
+ "pipe",
9692
+ "pipe"
9693
+ ]
9694
+ });
9695
+ const dirty = new Set(statusOut.split("\n").filter((line) => line.trim().length > 0).map((line) => {
9696
+ const body = line.slice(3).trim();
9697
+ const arrow = body.indexOf(" -> ");
9698
+ return arrow === -1 ? body : body.slice(arrow + 4);
9699
+ }));
9700
+ if (dirty.size === 0) return [];
9701
+ const diffOut = execFileSync("git", [
9702
+ "diff",
9703
+ "--name-only",
9704
+ `${startBranch}...${branchName}`
9705
+ ], {
9706
+ cwd: projectRoot,
9707
+ encoding: "utf-8",
9708
+ stdio: [
9709
+ "ignore",
9710
+ "pipe",
9711
+ "pipe"
9712
+ ]
9713
+ });
9714
+ return diffOut.split("\n").filter((f$1) => f$1.trim().length > 0).filter((f$1) => dirty.has(f$1));
9715
+ } catch (err) {
9716
+ logger$16.warn({ err }, "parent-clean precondition check failed (best-effort) — proceeding to merge");
9717
+ return [];
9718
+ }
9719
+ }
9720
+ /**
9561
9721
  * Attempt a fast-forward merge of `branchName` into the current branch.
9562
9722
  *
9563
9723
  * @param branchName - Branch to merge
@@ -16472,6 +16632,7 @@ function createImplementationOrchestrator(deps) {
16472
16632
  return "completed";
16473
16633
  }
16474
16634
  async function finalizeStory(completedReviewCycles) {
16635
+ let storyDeliverableSha;
16475
16636
  if (!noWorktree && _worktreeManager !== void 0 && _orchestratorStartBranch !== void 0 && projectRoot !== void 0) {
16476
16637
  const branchName = `${BRANCH_PREFIX}${storyKey}`;
16477
16638
  if (effectiveProjectRoot !== void 0) {
@@ -16571,6 +16732,12 @@ function createImplementationOrchestrator(deps) {
16571
16732
  timeout: 5e3
16572
16733
  }).trim();
16573
16734
  } catch {}
16735
+ storyDeliverableSha = finalizeCommitSha;
16736
+ if (finalizeCommitSha) eventBus.emit("orchestrator:story-committed", {
16737
+ storyKey,
16738
+ sha: finalizeCommitSha,
16739
+ branch: branchName
16740
+ });
16574
16741
  if (runManifest !== null && finalizeCommitSha) {
16575
16742
  const statePatch = { commit_sha: finalizeCommitSha };
16576
16743
  if (storyFilePath !== void 0) try {
@@ -16645,6 +16812,127 @@ function createImplementationOrchestrator(deps) {
16645
16812
  err: gateErr instanceof Error ? gateErr.message : String(gateErr)
16646
16813
  }, "merge-to-main pre-flight verification failed — proceeding with merge phase");
16647
16814
  }
16815
+ const finalizationMode = config.finalizationMode ?? "merge";
16816
+ const epicGateCommand = config.epicGateCommand;
16817
+ if (epicGateCommand !== void 0 && epicGateCommand.trim() !== "" && finalizationMode !== "branch") {
16818
+ const epicOf = (key) => key.includes("-") ? key.slice(0, key.lastIndexOf("-")) : key;
16819
+ const epicId = epicOf(storyKey);
16820
+ const TERMINAL_PHASES = ["COMPLETE", "ESCALATED"];
16821
+ const isLastOfEpic = [..._stories.entries()].filter(([key]) => key !== storyKey && epicOf(key) === epicId).every(([, st]) => TERMINAL_PHASES.includes(st.phase));
16822
+ if (isLastOfEpic) {
16823
+ logger$27.info({
16824
+ storyKey,
16825
+ epicId,
16826
+ epicGateCommand
16827
+ }, "H3.4: last story of epic — running epic gate command");
16828
+ let gateOutput = "";
16829
+ let gatePassed = false;
16830
+ try {
16831
+ gateOutput = execSync(epicGateCommand, {
16832
+ cwd: projectRoot,
16833
+ encoding: "utf-8",
16834
+ stdio: [
16835
+ "ignore",
16836
+ "pipe",
16837
+ "pipe"
16838
+ ],
16839
+ timeout: 6e5,
16840
+ maxBuffer: 10 * 1024 * 1024
16841
+ });
16842
+ gatePassed = true;
16843
+ } catch (gateCmdErr) {
16844
+ const e = gateCmdErr;
16845
+ gateOutput = `${e.stdout ?? ""}${e.stderr ?? ""}`.trim() || (e.message ?? String(gateCmdErr));
16846
+ }
16847
+ if (!gatePassed) {
16848
+ logger$27.error({
16849
+ storyKey,
16850
+ epicId,
16851
+ output: gateOutput.slice(0, 500)
16852
+ }, "H3.4: epic gate command failed — halting finalization; branch preserved");
16853
+ updateStory(storyKey, {
16854
+ phase: "ESCALATED",
16855
+ error: "epic-gate-failed",
16856
+ completedAt: new Date().toISOString()
16857
+ });
16858
+ await emitEscalation({
16859
+ storyKey,
16860
+ lastVerdict: "epic-gate-failed",
16861
+ reviewCycles: completedReviewCycles,
16862
+ issues: [`epic gate command failed for epic ${epicId} (last story ${storyKey}): \`${epicGateCommand}\`\noutput (truncated):\n${gateOutput.slice(0, 4e3)}`]
16863
+ });
16864
+ await persistState();
16865
+ return "terminal";
16866
+ }
16867
+ logger$27.info({
16868
+ storyKey,
16869
+ epicId
16870
+ }, "H3.4: epic gate passed");
16871
+ }
16872
+ }
16873
+ if (finalizationMode === "branch" || finalizationMode === "pr") {
16874
+ let prUrl;
16875
+ if (finalizationMode === "pr") try {
16876
+ execSync(`git push -u origin ${branchName}`, {
16877
+ cwd: projectRoot,
16878
+ stdio: [
16879
+ "ignore",
16880
+ "pipe",
16881
+ "pipe"
16882
+ ],
16883
+ timeout: 6e4
16884
+ });
16885
+ const shortSha = (storyDeliverableSha ?? "").slice(0, 10);
16886
+ 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.`)}`, {
16887
+ cwd: projectRoot,
16888
+ encoding: "utf-8",
16889
+ stdio: [
16890
+ "ignore",
16891
+ "pipe",
16892
+ "pipe"
16893
+ ],
16894
+ timeout: 6e4
16895
+ }).trim();
16896
+ prUrl = ghOutput === "" ? void 0 : ghOutput;
16897
+ } catch (prErr) {
16898
+ logger$27.warn({
16899
+ storyKey,
16900
+ branchName,
16901
+ err: prErr instanceof Error ? prErr.message.slice(0, 300) : String(prErr)
16902
+ }, "pr finalization: push/gh failed — degrading to branch mode (the branch is still the deliverable)");
16903
+ }
16904
+ try {
16905
+ await _worktreeManager.cleanupWorktree(storyKey, { keepBranch: true });
16906
+ } catch (cleanupErr) {
16907
+ logger$27.warn({
16908
+ storyKey,
16909
+ err: cleanupErr
16910
+ }, "worktree removal after branch/pr finalization failed (best-effort; branch intact)");
16911
+ }
16912
+ eventBus.emit("orchestrator:story-finalized", {
16913
+ storyKey,
16914
+ mode: finalizationMode,
16915
+ branch: branchName,
16916
+ sha: storyDeliverableSha ?? "",
16917
+ ...prUrl !== void 0 ? { prUrl } : {}
16918
+ });
16919
+ if (runManifest !== null) runManifest.patchStoryState(storyKey, { finalization: {
16920
+ mode: finalizationMode,
16921
+ branch: branchName,
16922
+ ...storyDeliverableSha ? { sha: storyDeliverableSha } : {},
16923
+ ...prUrl !== void 0 ? { pr_url: prUrl } : {}
16924
+ } }).catch((err) => logger$27.warn({
16925
+ err,
16926
+ storyKey
16927
+ }, "patchStoryState(finalization) failed — pipeline continues"));
16928
+ logger$27.info({
16929
+ storyKey,
16930
+ branchName,
16931
+ mode: finalizationMode,
16932
+ prUrl
16933
+ }, "story finalized without self-merge — branch is the deliverable");
16934
+ return "finalized";
16935
+ }
16648
16936
  logger$27.info({
16649
16937
  storyKey,
16650
16938
  branchName,
@@ -16658,7 +16946,8 @@ function createImplementationOrchestrator(deps) {
16658
16946
  startBranch: _orchestratorStartBranch,
16659
16947
  worktreeManager: _worktreeManager,
16660
16948
  eventBus,
16661
- projectRoot
16949
+ projectRoot,
16950
+ mergeStrategy: config.mergeStrategy ?? "ff-only"
16662
16951
  });
16663
16952
  } catch (mergeErr) {
16664
16953
  const errMsg = mergeErr instanceof Error ? mergeErr.message : String(mergeErr);
@@ -16681,21 +16970,28 @@ function createImplementationOrchestrator(deps) {
16681
16970
  return "terminal";
16682
16971
  }
16683
16972
  if (!mergeResult.success) {
16973
+ const failReason = mergeResult.reason ?? "merge-conflict-detected";
16974
+ const issues = [];
16975
+ if (failReason === "parent-tree-dirtied-by-run") issues.push(`parent working tree has uncommitted changes to ${mergeResult.dirtiedFiles?.length ?? 0} file(s) the story also modified: ${(mergeResult.dirtiedFiles ?? []).join(", ")} — merging would entangle unreviewed parent edits with verified story content. Commit or stash the parent changes, then merge ${branchName} manually.`);
16976
+ else if (failReason === "ff-only-merge-not-possible") issues.push(`${_orchestratorStartBranch ?? "the start branch"} moved since ${branchName} was created and merge_strategy is ff-only — substrate will not synthesize a merge commit. Set finalization.merge_strategy: three-way (required for concurrent multi-story runs) or integrate the branch manually.`);
16977
+ else issues.push(`merge conflict in ${mergeResult.conflictingFiles?.length ?? 0} file(s): ${(mergeResult.conflictingFiles ?? []).join(", ")}`);
16684
16978
  logger$27.warn({
16685
16979
  storyKey,
16686
16980
  branchName,
16687
- conflictingFiles: mergeResult.conflictingFiles
16688
- }, "merge-to-main conflict — escalating story with merge-conflict-detected");
16981
+ reason: failReason,
16982
+ conflictingFiles: mergeResult.conflictingFiles,
16983
+ dirtiedFiles: mergeResult.dirtiedFiles
16984
+ }, `merge-to-main failed — escalating story with ${failReason}`);
16689
16985
  updateStory(storyKey, {
16690
16986
  phase: "ESCALATED",
16691
- error: "merge-conflict-detected",
16987
+ error: failReason,
16692
16988
  completedAt: new Date().toISOString()
16693
16989
  });
16694
16990
  await emitEscalation({
16695
16991
  storyKey,
16696
- lastVerdict: "merge-conflict-detected",
16992
+ lastVerdict: failReason,
16697
16993
  reviewCycles: completedReviewCycles,
16698
- issues: [`merge conflict in ${mergeResult.conflictingFiles?.length ?? 0} file(s): ${(mergeResult.conflictingFiles ?? []).join(", ")}`]
16994
+ issues
16699
16995
  });
16700
16996
  await persistState();
16701
16997
  return "terminal";
@@ -16704,6 +17000,25 @@ function createImplementationOrchestrator(deps) {
16704
17000
  storyKey,
16705
17001
  branchName
16706
17002
  }, "merge-to-main phase completed successfully");
17003
+ eventBus.emit("orchestrator:story-merged", {
17004
+ storyKey,
17005
+ sha: storyDeliverableSha ?? "",
17006
+ branch: branchName
17007
+ });
17008
+ eventBus.emit("orchestrator:story-finalized", {
17009
+ storyKey,
17010
+ mode: "merge",
17011
+ branch: branchName,
17012
+ sha: storyDeliverableSha ?? ""
17013
+ });
17014
+ if (runManifest !== null) runManifest.patchStoryState(storyKey, { finalization: {
17015
+ mode: "merge",
17016
+ branch: branchName,
17017
+ ...storyDeliverableSha ? { sha: storyDeliverableSha } : {}
17018
+ } }).catch((err) => logger$27.warn({
17019
+ err,
17020
+ storyKey
17021
+ }, "patchStoryState(finalization) failed — pipeline continues"));
16707
17022
  }
16708
17023
  return "finalized";
16709
17024
  }
@@ -17933,7 +18248,13 @@ function createImplementationOrchestrator(deps) {
17933
18248
  }).trim();
17934
18249
  logger$27.info({ orchestratorStartBranch: _orchestratorStartBranch }, "Captured orchestrator start branch for merge-to-main");
17935
18250
  } catch (branchErr) {
17936
- logger$27.warn({ err: branchErr }, "Failed to capture orchestrator start branch — merge-to-main will skip worktree integration");
18251
+ if (config.noWorktree !== true) {
18252
+ logger$27.error({ err: branchErr }, "FATAL: failed to capture the orchestrator start branch (git rev-parse --abbrev-ref HEAD). Worktree finalization cannot work without it. Fix git in the project root or re-run with --no-worktree.");
18253
+ _state = "FAILED";
18254
+ _completedAt = new Date().toISOString();
18255
+ return getStatus();
18256
+ }
18257
+ logger$27.warn({ err: branchErr }, "Failed to capture orchestrator start branch — merge-to-main will skip worktree integration (--no-worktree run)");
17937
18258
  }
17938
18259
  for (const key of storyKeys) {
17939
18260
  const pendingState = {
@@ -46411,6 +46732,35 @@ function wireNdjsonEmitter(eventBus, ndjsonEmitter) {
46411
46732
  review_cycles: payload.reviewCycles
46412
46733
  });
46413
46734
  });
46735
+ eventBus.on("orchestrator:story-committed", (payload) => {
46736
+ ndjsonEmitter.emit({
46737
+ type: "story:committed",
46738
+ ts: new Date().toISOString(),
46739
+ key: payload.storyKey,
46740
+ sha: payload.sha,
46741
+ branch: payload.branch
46742
+ });
46743
+ });
46744
+ eventBus.on("orchestrator:story-merged", (payload) => {
46745
+ ndjsonEmitter.emit({
46746
+ type: "story:merged",
46747
+ ts: new Date().toISOString(),
46748
+ key: payload.storyKey,
46749
+ sha: payload.sha,
46750
+ branch: payload.branch
46751
+ });
46752
+ });
46753
+ eventBus.on("orchestrator:story-finalized", (payload) => {
46754
+ ndjsonEmitter.emit({
46755
+ type: "story:finalized",
46756
+ ts: new Date().toISOString(),
46757
+ key: payload.storyKey,
46758
+ mode: payload.mode,
46759
+ branch: payload.branch,
46760
+ sha: payload.sha,
46761
+ ...payload.prUrl !== void 0 ? { pr_url: payload.prUrl } : {}
46762
+ });
46763
+ });
46414
46764
  eventBus.on("orchestrator:story-escalated", (payload) => {
46415
46765
  const rawIssues = Array.isArray(payload.issues) ? payload.issues : [];
46416
46766
  const issues = rawIssues.map((issue) => {
@@ -46624,7 +46974,7 @@ function resolveProbeAuthorStateIntegrating(cliFlag) {
46624
46974
  * substrate run --non-interactive --halt-on none --events --output-format json
46625
46975
  */
46626
46976
  async function runRunAction(options) {
46627
- 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;
46977
+ 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;
46628
46978
  const haltOn = haltOnOpt;
46629
46979
  const VALID_PROBE_AUTHOR_MODES = [
46630
46980
  "enabled",
@@ -46740,6 +47090,9 @@ async function runRunAction(options) {
46740
47090
  let meshUrl;
46741
47091
  let meshProjectId;
46742
47092
  let configRetryBudget;
47093
+ let configFinalizationMode;
47094
+ let configMergeStrategy;
47095
+ let configEpicGateCommand;
46743
47096
  let configWorktreeCopyFiles;
46744
47097
  try {
46745
47098
  const configSystem = createConfigSystem({ projectConfigDir: dbDir });
@@ -46766,6 +47119,9 @@ async function runRunAction(options) {
46766
47119
  meshProjectId = cfg.telemetry.projectId;
46767
47120
  }
46768
47121
  if (typeof cfg.retry_budget === "number") configRetryBudget = cfg.retry_budget;
47122
+ if (cfg.finalization?.mode !== void 0) configFinalizationMode = cfg.finalization.mode;
47123
+ if (cfg.finalization?.merge_strategy !== void 0) configMergeStrategy = cfg.finalization.merge_strategy;
47124
+ if (cfg.finalization?.epic_gate_command !== void 0) configEpicGateCommand = cfg.finalization.epic_gate_command;
46769
47125
  if (Array.isArray(cfg.worktree?.copy_files) && cfg.worktree.copy_files.length > 0) {
46770
47126
  configWorktreeCopyFiles = [...cfg.worktree.copy_files];
46771
47127
  logger.info({ copyFiles: configWorktreeCopyFiles }, "Loaded worktree.copy_files from config");
@@ -46865,6 +47221,9 @@ async function runRunAction(options) {
46865
47221
  retryBudget: configRetryBudget ?? 2,
46866
47222
  agentId,
46867
47223
  ...noWorktree === true ? { noWorktree: true } : {},
47224
+ ...finalization !== void 0 ? { finalizationMode: finalization } : configFinalizationMode !== void 0 ? { finalizationMode: configFinalizationMode } : {},
47225
+ ...configMergeStrategy !== void 0 ? { mergeStrategy: configMergeStrategy } : {},
47226
+ ...configEpicGateCommand !== void 0 ? { epicGateCommand: configEpicGateCommand } : {},
46868
47227
  ...configWorktreeCopyFiles !== void 0 ? { worktreeCopyFiles: configWorktreeCopyFiles } : {}
46869
47228
  });
46870
47229
  let storyKeys = [...parsedStoryKeys];
@@ -47428,6 +47787,9 @@ async function runRunAction(options) {
47428
47787
  ...probeAuthor !== void 0 ? { probeAuthorMode: probeAuthor } : {},
47429
47788
  probeAuthorStateIntegrating: resolvedProbeAuthorStateIntegrating,
47430
47789
  ...noWorktree === true ? { noWorktree: true } : {},
47790
+ ...finalization !== void 0 ? { finalizationMode: finalization } : configFinalizationMode !== void 0 ? { finalizationMode: configFinalizationMode } : {},
47791
+ ...configMergeStrategy !== void 0 ? { mergeStrategy: configMergeStrategy } : {},
47792
+ ...configEpicGateCommand !== void 0 ? { epicGateCommand: configEpicGateCommand } : {},
47431
47793
  ...configWorktreeCopyFiles !== void 0 ? { worktreeCopyFiles: configWorktreeCopyFiles } : {}
47432
47794
  },
47433
47795
  projectRoot,
@@ -47651,7 +48013,7 @@ async function runRunAction(options) {
47651
48013
  }
47652
48014
  }
47653
48015
  async function runFullPipeline(options) {
47654
- 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;
48016
+ 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, mergeStrategy: fpMergeStrategy, epicGateCommand: fpEpicGateCommand } = options;
47655
48017
  if (!existsSync$1(dbDir)) mkdirSync$1(dbDir, { recursive: true });
47656
48018
  let doltServerFull = null;
47657
48019
  try {
@@ -47961,6 +48323,9 @@ async function runFullPipeline(options) {
47961
48323
  ...probeAuthor !== void 0 ? { probeAuthorMode: probeAuthor } : {},
47962
48324
  ...fpProbeAuthorStateIntegrating !== void 0 ? { probeAuthorStateIntegrating: fpProbeAuthorStateIntegrating } : {},
47963
48325
  ...noWorktree === true ? { noWorktree: true } : {},
48326
+ ...fpFinalizationMode !== void 0 ? { finalizationMode: fpFinalizationMode } : {},
48327
+ ...fpMergeStrategy !== void 0 ? { mergeStrategy: fpMergeStrategy } : {},
48328
+ ...fpEpicGateCommand !== void 0 ? { epicGateCommand: fpEpicGateCommand } : {},
47964
48329
  ...fpWorktreeCopyFiles !== void 0 ? { worktreeCopyFiles: fpWorktreeCopyFiles } : {}
47965
48330
  },
47966
48331
  projectRoot,
@@ -48131,7 +48496,7 @@ async function runFullPipeline(options) {
48131
48496
  */
48132
48497
  async function emitPreDispatchVersionAdvisory(currentVersion) {
48133
48498
  if (process.env["SUBSTRATE_NO_UPDATE_CHECK"] === "1") return;
48134
- const { createVersionManager } = await import("./version-manager-impl-CKsauG6T.js");
48499
+ const { createVersionManager } = await import("./version-manager-impl-_x1n4xZk.js");
48135
48500
  const vm = createVersionManager();
48136
48501
  const result = await vm.checkForUpdates(true);
48137
48502
  const gap = classifyVersionGap(currentVersion, result.latestVersion);
@@ -48171,7 +48536,7 @@ function registerRunCommand(program, version = "0.0.0", projectRoot = process.cw
48171
48536
  "",
48172
48537
  "--halt-on defaults to critical. Skipped halt decisions are recorded as",
48173
48538
  "decision:halt-skipped-non-interactive events in --non-interactive mode."
48174
- ].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) => {
48539
+ ].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) => {
48175
48540
  if (opts.helpAgent) {
48176
48541
  process.exitCode = await runHelpAgent();
48177
48542
  return;
@@ -48189,6 +48554,15 @@ function registerRunCommand(program, version = "0.0.0", projectRoot = process.cw
48189
48554
  }
48190
48555
  fromPhase = opts.from;
48191
48556
  }
48557
+ if (opts.finalization !== void 0 && ![
48558
+ "merge",
48559
+ "branch",
48560
+ "pr"
48561
+ ].includes(String(opts.finalization))) {
48562
+ process.stderr.write(`Invalid --finalization "${String(opts.finalization)}" — expected merge | branch | pr\n`);
48563
+ process.exitCode = 2;
48564
+ return;
48565
+ }
48192
48566
  const exitCode = await runRunAction({
48193
48567
  pack: opts.pack,
48194
48568
  from: fromPhase,
@@ -48219,7 +48593,8 @@ function registerRunCommand(program, version = "0.0.0", projectRoot = process.cw
48219
48593
  probeAuthorStateIntegrating: opts.probeAuthorStateIntegrating,
48220
48594
  nonInteractive: opts.nonInteractive,
48221
48595
  verifyAc: opts.verifyAc,
48222
- noWorktree: opts.worktree === false || process.env["SUBSTRATE_NO_WORKTREE"] === "1"
48596
+ noWorktree: opts.worktree === false || process.env["SUBSTRATE_NO_WORKTREE"] === "1",
48597
+ finalization: opts.finalization
48223
48598
  });
48224
48599
  if (opts.nonInteractive === true) process.exit(exitCode);
48225
48600
  process.exitCode = exitCode;
@@ -48228,4 +48603,4 @@ function registerRunCommand(program, version = "0.0.0", projectRoot = process.cw
48228
48603
 
48229
48604
  //#endregion
48230
48605
  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 };
48231
- //# sourceMappingURL=run-BhoAW6dJ.js.map
48606
+ //# sourceMappingURL=run-B9DV9sro.js.map
@@ -1,14 +1,14 @@
1
- import "./health-eGHKiGlU.js";
1
+ import "./health-Aqc5cghP.js";
2
2
  import "./logger-KeHncl-f.js";
3
3
  import "./helpers-CElYrONe.js";
4
- import "./dist-D2mJXElX.js";
5
- import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, runRunAction, wireNdjsonEmitter } from "./run-BhoAW6dJ.js";
6
- import "./manifest-read-7kyDfQAK.js";
4
+ import "./dist-CZk5SeSt.js";
5
+ import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, runRunAction, wireNdjsonEmitter } from "./run-B9DV9sro.js";
6
+ import "./manifest-read-D6NAZgt8.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-opOBwMDU.js";
11
+ import "./interactive-prompt-BLkX0iE_.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-CvNLhgKV.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-D2mJXElX.js";
1
+ import { createVersionManager } from "./dist-CZk5SeSt.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-Djo0dJak.js.map
126
+ //# sourceMappingURL=upgrade-BEfZJU4K.js.map
@@ -1,5 +1,5 @@
1
- import "./dist-D2mJXElX.js";
1
+ import "./dist-CZk5SeSt.js";
2
2
  import "./version-manager-impl-qFBiO4Eh.js";
3
- import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-Djo0dJak.js";
3
+ import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-BEfZJU4K.js";
4
4
 
5
5
  export { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand };
@@ -1,4 +1,4 @@
1
- import { VersionManagerImpl, createVersionManager } from "./dist-D2mJXElX.js";
1
+ import { VersionManagerImpl, createVersionManager } from "./dist-CZk5SeSt.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.146",
3
+ "version": "0.20.148",
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-D2mJXElX.js";
2
- import "./adapter-registry-DIcrxjH8.js";
3
-
4
- export { AdapterRegistry };