substrate-ai 0.20.93 → 0.20.95

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-C_NE40jY.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 { FileStateStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createDatabaseAdapter, createDoltOperatorReader, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion } from "../health-dWYa13k4.js";
2
+ import { FileStateStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createDatabaseAdapter, createDoltOperatorReader, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion } from "../health-CzZ2Ki-b.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, createDoltClient, createPipelineRun, getActiveDecisions, getAllCostEntriesFiltered, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, swallowDebug, tagRunAsBaseline, updatePipelineRun } from "../dist-l0pA6zZF.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-BXRwQRst.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, createDoltClient, createPipelineRun, getActiveDecisions, getAllCostEntriesFiltered, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, swallowDebug, tagRunAsBaseline, updatePipelineRun } from "../dist-C_NE40jY.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-COnbF6By.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-CSmDEOWH.js";
9
- import "../errors-DZuD2tVU.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-BSsjVG96.js";
9
+ import "../errors-D531Z8FW.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-DblHY8se.js";
14
- import "../interactive-prompt-DY-PFko-.js";
14
+ import "../interactive-prompt-DF-PL5ia.js";
15
15
  import "../recovery-engine-BKGBeBnW.js";
16
16
  import "../version-manager-impl-qFBiO4Eh.js";
17
- import { registerUpgradeCommand } from "../upgrade-BP0P3qr9.js";
17
+ import { registerUpgradeCommand } from "../upgrade-C1KzAZQE.js";
18
18
  import { Command } from "commander";
19
19
  import { fileURLToPath } from "url";
20
20
  import { dirname, join, resolve } from "path";
@@ -2109,10 +2109,7 @@ async function runInitAction(options) {
2109
2109
  let doltInitialized = false;
2110
2110
  if (doltMode !== "skip") try {
2111
2111
  if (doltMode === "auto") await checkDoltInstalled();
2112
- await initializeDolt({
2113
- projectRoot,
2114
- schemaPath: fileURLToPath$1(new URL("../schema.sql", import.meta.url))
2115
- });
2112
+ await initializeDolt({ projectRoot });
2116
2113
  doltInitialized = true;
2117
2114
  } catch (err) {
2118
2115
  if (err instanceof DoltNotInstalled) {
@@ -6890,7 +6887,7 @@ async function runStatusAction(options) {
6890
6887
  logger$15.debug({ err }, "Work graph query failed, continuing without work graph data");
6891
6888
  }
6892
6889
  if (run === void 0) {
6893
- const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-CgY9akax.js");
6890
+ const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-C0bSSccV.js");
6894
6891
  const substrateDirPath = join(projectRoot, ".substrate");
6895
6892
  const processInfo = inspectProcessTree$1({
6896
6893
  projectRoot,
@@ -7838,7 +7835,7 @@ function defaultSupervisorDeps() {
7838
7835
  if (cached === null) {
7839
7836
  const { AdapterRegistry: AR } = await import(
7840
7837
  /* @vite-ignore */
7841
- "../adapter-registry-BZ0cVi8C.js"
7838
+ "../adapter-registry-Bvox1eRm.js"
7842
7839
  );
7843
7840
  cached = new AR();
7844
7841
  await cached.discoverAndRegister();
@@ -8405,11 +8402,11 @@ async function runSupervisorAction(options, deps = {}) {
8405
8402
  try {
8406
8403
  const { createExperimenter } = await import(
8407
8404
  /* @vite-ignore */
8408
- "../experimenter-GfhQpMis.js"
8405
+ "../experimenter-Cg2fBeVq.js"
8409
8406
  );
8410
8407
  const { getLatestRun: getLatest } = await import(
8411
8408
  /* @vite-ignore */
8412
- "../decisions-CsNAM-T-.js"
8409
+ "../decisions-CNe9RlcE.js"
8413
8410
  );
8414
8411
  const expAdapter = createDatabaseAdapter({
8415
8412
  backend: "auto",
@@ -8419,7 +8416,7 @@ async function runSupervisorAction(options, deps = {}) {
8419
8416
  await initSchema(expAdapter);
8420
8417
  const { runRunAction: runPipeline } = await import(
8421
8418
  /* @vite-ignore */
8422
- "../run-DPQ4DT5Q.js"
8419
+ "../run-Bmrjp1QI.js"
8423
8420
  );
8424
8421
  const runStoryFn = async (opts) => {
8425
8422
  const exitCode = await runPipeline({
@@ -8947,7 +8944,7 @@ async function runMetricsAction(options) {
8947
8944
  const routingConfigPath = join(dbDir, "routing.yml");
8948
8945
  let routingConfig = null;
8949
8946
  if (existsSync$1(routingConfigPath)) try {
8950
- const { loadModelRoutingConfig } = await import("../routing-CD5PGDLe.js");
8947
+ const { loadModelRoutingConfig } = await import("../routing-Cptl6Ali.js");
8951
8948
  routingConfig = loadModelRoutingConfig(routingConfigPath);
8952
8949
  } catch {}
8953
8950
  if (routingConfig === null) routingConfig = {
@@ -13321,8 +13318,8 @@ async function createProgram() {
13321
13318
  /** Fire-and-forget startup version check (story 8.3, AC3/AC5) */
13322
13319
  function checkForUpdatesInBackground(currentVersion) {
13323
13320
  if (process.env.SUBSTRATE_NO_UPDATE_CHECK === "1") return;
13324
- import("../upgrade-DCDe5u0P.js").then(async () => {
13325
- const { createVersionManager } = await import("../version-manager-impl-B8MpvZQz.js");
13321
+ import("../upgrade--vRnNB3V.js").then(async () => {
13322
+ const { createVersionManager } = await import("../version-manager-impl-9J_JCJPu.js");
13326
13323
  const vm = createVersionManager();
13327
13324
  const result = await vm.checkForUpdates();
13328
13325
  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-l0pA6zZF.js";
1
+ import { addTokenUsage, createDecision, createPipelineRun, createRequirement, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunningPipelineRuns, getTokenUsageSummary, listRequirements, registerArtifact, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision } from "./dist-C_NE40jY.js";
2
2
  import "./decisions-CzSIEeGP.js";
3
3
 
4
4
  export { getLatestRun };
@@ -3103,6 +3103,142 @@ async function initSchema(adapter) {
3103
3103
  applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
3104
3104
  )
3105
3105
  `);
3106
+ await adapter.exec(`
3107
+ CREATE TABLE IF NOT EXISTS stories (
3108
+ story_key VARCHAR(100) NOT NULL,
3109
+ sprint VARCHAR(50),
3110
+ status VARCHAR(30) NOT NULL DEFAULT 'PENDING',
3111
+ phase VARCHAR(30) NOT NULL DEFAULT 'PENDING',
3112
+ ac_results JSON,
3113
+ error_message TEXT,
3114
+ created_at DATETIME,
3115
+ updated_at DATETIME,
3116
+ completed_at DATETIME,
3117
+ PRIMARY KEY (story_key)
3118
+ )
3119
+ `);
3120
+ await adapter.exec(`
3121
+ CREATE TABLE IF NOT EXISTS contracts (
3122
+ story_key VARCHAR(100) NOT NULL,
3123
+ name VARCHAR(200) NOT NULL,
3124
+ direction VARCHAR(20) NOT NULL,
3125
+ schema_path VARCHAR(500),
3126
+ transport VARCHAR(200),
3127
+ recorded_at DATETIME,
3128
+ PRIMARY KEY (story_key, name, direction)
3129
+ )
3130
+ `);
3131
+ await adapter.exec(`
3132
+ CREATE TABLE IF NOT EXISTS metrics (
3133
+ story_key VARCHAR(100) NOT NULL,
3134
+ task_type VARCHAR(100) NOT NULL,
3135
+ recorded_at DATETIME NOT NULL,
3136
+ model VARCHAR(100),
3137
+ tokens_in BIGINT NOT NULL DEFAULT 0,
3138
+ tokens_out BIGINT NOT NULL DEFAULT 0,
3139
+ cache_read_tokens BIGINT NOT NULL DEFAULT 0,
3140
+ cost_usd DECIMAL(10,6) NOT NULL DEFAULT 0,
3141
+ wall_clock_ms BIGINT NOT NULL DEFAULT 0,
3142
+ review_cycles INT NOT NULL DEFAULT 0,
3143
+ stall_count INT NOT NULL DEFAULT 0,
3144
+ result VARCHAR(30),
3145
+ PRIMARY KEY (story_key, task_type, recorded_at)
3146
+ )
3147
+ `);
3148
+ await adapter.exec(`
3149
+ CREATE TABLE IF NOT EXISTS dispatch_log (
3150
+ story_key VARCHAR(100) NOT NULL,
3151
+ dispatched_at DATETIME NOT NULL,
3152
+ branch VARCHAR(200),
3153
+ worker_id VARCHAR(100),
3154
+ result VARCHAR(30),
3155
+ PRIMARY KEY (story_key, dispatched_at)
3156
+ )
3157
+ `);
3158
+ await adapter.exec(`
3159
+ CREATE TABLE IF NOT EXISTS build_results (
3160
+ story_key VARCHAR(100) NOT NULL,
3161
+ timestamp DATETIME NOT NULL,
3162
+ command VARCHAR(500),
3163
+ exit_code INT,
3164
+ stdout_hash VARCHAR(64),
3165
+ PRIMARY KEY (story_key, timestamp)
3166
+ )
3167
+ `);
3168
+ await adapter.exec(`
3169
+ CREATE TABLE IF NOT EXISTS review_verdicts (
3170
+ story_key VARCHAR(100) NOT NULL,
3171
+ timestamp DATETIME NOT NULL,
3172
+ verdict VARCHAR(30),
3173
+ issues_count INT NOT NULL DEFAULT 0,
3174
+ notes TEXT,
3175
+ PRIMARY KEY (story_key, timestamp)
3176
+ )
3177
+ `);
3178
+ await adapter.exec(`
3179
+ CREATE TABLE IF NOT EXISTS _schema_version (
3180
+ version INT NOT NULL,
3181
+ applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
3182
+ description VARCHAR(500),
3183
+ PRIMARY KEY (version)
3184
+ )
3185
+ `);
3186
+ try {
3187
+ await adapter.exec(`INSERT IGNORE INTO _schema_version (version, description) VALUES (1, 'Initial substrate state schema')`);
3188
+ } catch {}
3189
+ try {
3190
+ await adapter.exec(`INSERT IGNORE INTO _schema_version (version, description) VALUES (2, 'Add turn_analysis table (Epic 27-4)')`);
3191
+ } catch {}
3192
+ try {
3193
+ await adapter.exec(`INSERT IGNORE INTO _schema_version (version, description) VALUES (3, 'Add category_stats and consumer_stats tables (Epic 27-5)')`);
3194
+ } catch {}
3195
+ try {
3196
+ await adapter.exec(`INSERT IGNORE INTO _schema_version (version, description) VALUES (4, 'Add recommendations table (Epic 27-7)')`);
3197
+ } catch {}
3198
+ try {
3199
+ await adapter.exec(`INSERT IGNORE INTO _schema_version (version, description) VALUES (5, 'Add repo_map_symbols and repo_map_meta tables (Epic 28-2)')`);
3200
+ } catch {}
3201
+ try {
3202
+ await adapter.exec(`INSERT IGNORE INTO _schema_version (version, description) VALUES (6, 'Add dependencies JSON column to repo_map_symbols (Epic 28-3)')`);
3203
+ } catch {}
3204
+ try {
3205
+ await adapter.exec(`INSERT IGNORE INTO _schema_version (version, description) VALUES (7, 'Add wg_stories, story_dependencies tables and ready_stories view (Epic 31-1)')`);
3206
+ } catch {}
3207
+ try {
3208
+ await adapter.exec(`INSERT IGNORE INTO _schema_version (version, description) VALUES (8, 'Add task_type, phase, dispatch_id columns to turn_analysis (Story 30-1)')`);
3209
+ } catch {}
3210
+ try {
3211
+ await adapter.exec(`INSERT IGNORE INTO _schema_version (version, description) VALUES (9, 'Add dispatch_id, task_type, phase columns to efficiency_scores (Story 30-3)')`);
3212
+ } catch {}
3213
+ await adapter.exec(`
3214
+ CREATE TABLE IF NOT EXISTS repo_map_symbols (
3215
+ id BIGINT AUTO_INCREMENT NOT NULL,
3216
+ file_path VARCHAR(1000) NOT NULL,
3217
+ symbol_name VARCHAR(500) NOT NULL,
3218
+ symbol_kind VARCHAR(20) NOT NULL,
3219
+ signature TEXT,
3220
+ line_number INT NOT NULL DEFAULT 0,
3221
+ exported TINYINT(1) NOT NULL DEFAULT 0,
3222
+ file_hash VARCHAR(64) NOT NULL,
3223
+ dependencies JSON,
3224
+ PRIMARY KEY (id)
3225
+ )
3226
+ `);
3227
+ await adapter.exec("CREATE INDEX IF NOT EXISTS idx_repo_map_symbols_file ON repo_map_symbols (file_path)");
3228
+ await adapter.exec("CREATE INDEX IF NOT EXISTS idx_repo_map_symbols_kind ON repo_map_symbols (symbol_kind)");
3229
+ await adapter.exec(`
3230
+ CREATE TABLE IF NOT EXISTS repo_map_meta (
3231
+ id INT NOT NULL DEFAULT 1,
3232
+ commit_sha VARCHAR(64),
3233
+ updated_at DATETIME,
3234
+ file_count INT NOT NULL DEFAULT 0,
3235
+ PRIMARY KEY (id)
3236
+ )
3237
+ `);
3238
+ await adapter.exec("CREATE INDEX IF NOT EXISTS idx_efficiency_story ON efficiency_scores (story_key, timestamp DESC)");
3239
+ await adapter.exec("CREATE INDEX IF NOT EXISTS idx_recommendations_story ON recommendations (story_key, severity)");
3240
+ await adapter.exec("CREATE INDEX IF NOT EXISTS idx_category_stats_story ON category_stats (story_key, total_tokens)");
3241
+ await adapter.exec("CREATE INDEX IF NOT EXISTS idx_consumer_stats_story ON consumer_stats (story_key, total_tokens)");
3106
3242
  }
3107
3243
 
3108
3244
  //#endregion
@@ -5032,17 +5168,21 @@ async function runDoltConfigSet(key, value) {
5032
5168
  * Initialize a Dolt repository for Substrate state storage.
5033
5169
  *
5034
5170
  * This function is idempotent: running it a second time on an already-
5035
- * initialized repository is safe — `dolt init` is skipped, existing tables
5036
- * are not re-created (IF NOT EXISTS guards), and the schema version row is
5037
- * not duplicated (INSERT IGNORE).
5171
+ * initialized repository is safe — `dolt init` is skipped, and the initial
5172
+ * empty-repo commit is not re-created.
5173
+ *
5174
+ * Post-Ship-3 (2026-05): no DDL is applied here. The runtime `initSchema()`
5175
+ * call on first `substrate run` creates all tables idempotently via
5176
+ * `CREATE TABLE IF NOT EXISTS` + try/catch `ALTER ADD COLUMN`. Existing
5177
+ * repos auto-migrate transparently; fresh repos pay one extra `substrate run`
5178
+ * invocation before tables exist.
5038
5179
  *
5039
- * @param config - Initialization configuration. `schemaPath` is required.
5180
+ * @param config - Initialization configuration.
5040
5181
  * @throws {DoltNotInstalled} If the `dolt` binary is not in PATH.
5041
5182
  * @throws {DoltInitError} If any Dolt CLI command fails.
5042
5183
  */
5043
5184
  async function initializeDolt(config) {
5044
5185
  const statePath = config.statePath ?? join$1(config.projectRoot, ".substrate", "state");
5045
- const schemaPath = config.schemaPath;
5046
5186
  await checkDoltInstalled();
5047
5187
  await mkdir$1(statePath, { recursive: true });
5048
5188
  await ensureDoltIdentity();
@@ -5055,11 +5195,6 @@ async function initializeDolt(config) {
5055
5195
  doltDirExists = false;
5056
5196
  }
5057
5197
  if (!doltDirExists) await runDoltCommand(["init"], statePath);
5058
- await runDoltCommand([
5059
- "sql",
5060
- "-f",
5061
- schemaPath
5062
- ], statePath);
5063
5198
  let hasCommits = false;
5064
5199
  try {
5065
5200
  await runDoltCommand(["log", "--oneline"], statePath);
@@ -5071,8 +5206,9 @@ async function initializeDolt(config) {
5071
5206
  await runDoltCommand(["add", "-A"], statePath);
5072
5207
  await runDoltCommand([
5073
5208
  "commit",
5209
+ "--allow-empty",
5074
5210
  "-m",
5075
- "Initialize substrate state schema v1"
5211
+ "Initialize substrate state repo"
5076
5212
  ], statePath);
5077
5213
  }
5078
5214
  }
@@ -11155,4 +11291,4 @@ async function callLLM(params) {
11155
11291
 
11156
11292
  //#endregion
11157
11293
  export { ADVISORY_NOTES, AdapterRegistry, AdtError, BudgetConfigSchema, 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, createDoltClient, createExperimenter, createPipelineRun, createRequirement, createVersionManager, detectInterfaceChanges, determineVerdict, getActiveDecisions, getAllCostEntriesFiltered, getArtifactByTypeForRun, getArtifactsByRun, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getModelTier, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRequirements, listRunMetrics, loadModelRoutingConfig, loadParentRunDecisions, registerArtifact, resolvePromptFile, supersedeDecision, swallowDebug, tagRunAsBaseline, updateDecision, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics };
11158
- //# sourceMappingURL=dist-l0pA6zZF.js.map
11294
+ //# sourceMappingURL=dist-C_NE40jY.js.map
@@ -1,4 +1,4 @@
1
- import { AdtError } from "./dist-l0pA6zZF.js";
1
+ import { AdtError } from "./dist-C_NE40jY.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-DZuD2tVU.js.map
74
+ //# sourceMappingURL=errors-D531Z8FW.js.map
@@ -1,3 +1,3 @@
1
- import { buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, createExperimenter, determineVerdict, resolvePromptFile } from "./dist-l0pA6zZF.js";
1
+ import { buildAuditLogEntry, buildBranchName, buildModificationDirective, buildPRBody, buildWorktreePath, createExperimenter, determineVerdict, resolvePromptFile } from "./dist-C_NE40jY.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-dWYa13k4.js";
1
+ import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-CzZ2Ki-b.js";
2
2
  import "./logger-KeHncl-f.js";
3
- import "./dist-l0pA6zZF.js";
4
- import "./manifest-read-CSmDEOWH.js";
3
+ import "./dist-C_NE40jY.js";
4
+ import "./manifest-read-BSsjVG96.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-l0pA6zZF.js";
3
- import { resolveMainRepoRoot, resolveRunManifest } from "./manifest-read-CSmDEOWH.js";
2
+ import { DoltClient, DoltQueryError, createDatabaseAdapter$1 as createDatabaseAdapter, getLatestRun, getPipelineRunById, initSchema } from "./dist-C_NE40jY.js";
3
+ import { resolveMainRepoRoot, resolveRunManifest } from "./manifest-read-BSsjVG96.js";
4
4
  import { createRequire } from "module";
5
5
  import { dirname, join } from "path";
6
6
  import { existsSync, readFileSync } from "node:fs";
@@ -1231,4 +1231,4 @@ function registerHealthCommand(program, _version = "0.0.0", projectRoot = proces
1231
1231
 
1232
1232
  //#endregion
1233
1233
  export { BMAD_BASELINE_TOKENS_FULL, DEFAULT_STALL_THRESHOLD_SECONDS, DoltMergeConflict, FileStateStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN$1 as STORY_KEY_PATTERN, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter$1 as createDatabaseAdapter, createDoltOperatorReader, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, isOrchestratorProcessLine, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, runHealthAction, validateStoryKey };
1234
- //# sourceMappingURL=health-dWYa13k4.js.map
1234
+ //# sourceMappingURL=health-CzZ2Ki-b.js.map
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-l0pA6zZF.js";
3
+ import { AdapterRegistry, AdtError, ClaudeCodeAdapter, CodexCLIAdapter, ConfigError, ConfigIncompatibleFormatError, GeminiCLIAdapter } from "./dist-C_NE40jY.js";
4
4
  import "./adapter-registry-DIcrxjH8.js";
5
- import { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError } from "./errors-DZuD2tVU.js";
5
+ import { BudgetExceededError, GitError, RecoveryError, TaskConfigError, TaskGraphCycleError, TaskGraphError, TaskGraphIncompatibleFormatError, WorkerError, WorkerNotFoundError } from "./errors-D531Z8FW.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-CSmDEOWH.js";
2
+ import { readCurrentRunId, resolveMainRepoRoot } from "./manifest-read-BSsjVG96.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-DY-PFko-.js.map
183
+ //# sourceMappingURL=interactive-prompt-DF-PL5ia.js.map
@@ -1,5 +1,5 @@
1
1
  import { createLogger } from "./logger-KeHncl-f.js";
2
- import { LEARNING_FINDING, createDecision, getDecisionsByCategory } from "./dist-l0pA6zZF.js";
2
+ import { LEARNING_FINDING, createDecision, getDecisionsByCategory } from "./dist-C_NE40jY.js";
3
3
  import * as path$1 from "path";
4
4
  import { join } from "path";
5
5
  import { readFile } from "fs/promises";
@@ -5845,4 +5845,4 @@ async function resolveRunManifest(dbRoot, runId) {
5845
5845
 
5846
5846
  //#endregion
5847
5847
  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 };
5848
- //# sourceMappingURL=manifest-read-CSmDEOWH.js.map
5848
+ //# sourceMappingURL=manifest-read-BSsjVG96.js.map
@@ -1,6 +1,6 @@
1
1
  import "../../logger-KeHncl-f.js";
2
- import "../../dist-l0pA6zZF.js";
3
- import "../../manifest-read-CSmDEOWH.js";
4
- import { runInteractivePrompt } from "../../interactive-prompt-DY-PFko-.js";
2
+ import "../../dist-C_NE40jY.js";
3
+ import "../../manifest-read-BSsjVG96.js";
4
+ import { runInteractivePrompt } from "../../interactive-prompt-DF-PL5ia.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-l0pA6zZF.js";
1
+ import { ModelRoutingConfigSchema, ProviderPolicySchema, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, TASK_TYPE_PHASE_MAP, getModelTier, loadModelRoutingConfig } from "./dist-C_NE40jY.js";
2
2
  import "./routing-DFxoKHDt.js";
3
3
 
4
4
  export { loadModelRoutingConfig };
@@ -1,14 +1,14 @@
1
- import "./health-dWYa13k4.js";
1
+ import "./health-CzZ2Ki-b.js";
2
2
  import "./logger-KeHncl-f.js";
3
3
  import "./helpers-CElYrONe.js";
4
- import "./dist-l0pA6zZF.js";
5
- import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, runRunAction, wireNdjsonEmitter } from "./run-BXRwQRst.js";
6
- import "./manifest-read-CSmDEOWH.js";
4
+ import "./dist-C_NE40jY.js";
5
+ import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, runRunAction, wireNdjsonEmitter } from "./run-COnbF6By.js";
6
+ import "./manifest-read-BSsjVG96.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-DblHY8se.js";
11
- import "./interactive-prompt-DY-PFko-.js";
11
+ import "./interactive-prompt-DF-PL5ia.js";
12
12
  import "./recovery-engine-BKGBeBnW.js";
13
13
 
14
14
  export { runRunAction };
@@ -1,11 +1,11 @@
1
- import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, validateStoryKey } from "./health-dWYa13k4.js";
1
+ import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, validateStoryKey } from "./health-CzZ2Ki-b.js";
2
2
  import { createLogger } from "./logger-KeHncl-f.js";
3
3
  import { TypedEventBusImpl, createEventBus, createTuiApp, isTuiCapable, printNonTtyWarning, sleep } from "./helpers-CElYrONe.js";
4
- import { ADVISORY_NOTES, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, IngestionServer, LogTurnAnalyzer, OPERATIONAL_FINDING, Recommender, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, callLLM, classifyVersionGap, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, swallowDebug, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-l0pA6zZF.js";
5
- import { FindingsInjector, RunManifest, RuntimeProbeListSchema, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, renderFindings, resolveGraphPath, resolveMainRepoRoot, runAcTraceabilityCheck, runStaleVerificationRecovery } from "./manifest-read-CSmDEOWH.js";
4
+ import { ADVISORY_NOTES, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, IngestionServer, LogTurnAnalyzer, OPERATIONAL_FINDING, Recommender, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, callLLM, classifyVersionGap, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, swallowDebug, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-C_NE40jY.js";
5
+ import { FindingsInjector, RunManifest, RuntimeProbeListSchema, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, renderFindings, resolveGraphPath, resolveMainRepoRoot, runAcTraceabilityCheck, runStaleVerificationRecovery } from "./manifest-read-BSsjVG96.js";
6
6
  import { WorkGraphRepository, detectCycles } from "./work-graph-repository-DZyJv5pV.js";
7
7
  import { deriveExitCode, routeDecision } from "./decision-router-DblHY8se.js";
8
- import { runInteractivePrompt } from "./interactive-prompt-DY-PFko-.js";
8
+ import { runInteractivePrompt } from "./interactive-prompt-DF-PL5ia.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";
@@ -11679,127 +11679,6 @@ var AdapterTelemetryPersistence = class {
11679
11679
  constructor(adapter) {
11680
11680
  this._adapter = adapter;
11681
11681
  }
11682
- /**
11683
- * Apply the telemetry schema DDL to the database.
11684
- * Idempotent — uses CREATE TABLE IF NOT EXISTS.
11685
- */
11686
- async initSchema() {
11687
- await this._adapter.exec(`
11688
- CREATE TABLE IF NOT EXISTS turn_analysis (
11689
- story_key VARCHAR(64) NOT NULL,
11690
- span_id VARCHAR(128) NOT NULL,
11691
- turn_number INTEGER NOT NULL,
11692
- name VARCHAR(255) NOT NULL DEFAULT '',
11693
- timestamp BIGINT NOT NULL DEFAULT 0,
11694
- source VARCHAR(32) NOT NULL DEFAULT '',
11695
- model VARCHAR(64),
11696
- input_tokens INTEGER NOT NULL DEFAULT 0,
11697
- output_tokens INTEGER NOT NULL DEFAULT 0,
11698
- cache_read_tokens INTEGER NOT NULL DEFAULT 0,
11699
- fresh_tokens INTEGER NOT NULL DEFAULT 0,
11700
- cache_hit_rate DOUBLE NOT NULL DEFAULT 0,
11701
- cost_usd DOUBLE NOT NULL DEFAULT 0,
11702
- duration_ms INTEGER NOT NULL DEFAULT 0,
11703
- context_size INTEGER NOT NULL DEFAULT 0,
11704
- context_delta INTEGER NOT NULL DEFAULT 0,
11705
- tool_name VARCHAR(128),
11706
- is_context_spike BOOLEAN NOT NULL DEFAULT 0,
11707
- child_spans_json TEXT NOT NULL DEFAULT '[]',
11708
- task_type VARCHAR(64),
11709
- phase VARCHAR(64),
11710
- dispatch_id VARCHAR(64),
11711
- PRIMARY KEY (story_key, span_id)
11712
- )
11713
- `);
11714
- await this._adapter.exec(`
11715
- CREATE INDEX IF NOT EXISTS idx_turn_analysis_story
11716
- ON turn_analysis (story_key, turn_number)
11717
- `);
11718
- await this._adapter.exec(`
11719
- CREATE TABLE IF NOT EXISTS efficiency_scores (
11720
- story_key VARCHAR(64) NOT NULL,
11721
- timestamp BIGINT NOT NULL,
11722
- composite_score INTEGER NOT NULL DEFAULT 0,
11723
- cache_hit_sub_score DOUBLE NOT NULL DEFAULT 0,
11724
- io_ratio_sub_score DOUBLE NOT NULL DEFAULT 0,
11725
- context_management_sub_score DOUBLE NOT NULL DEFAULT 0,
11726
- avg_cache_hit_rate DOUBLE NOT NULL DEFAULT 0,
11727
- avg_io_ratio DOUBLE NOT NULL DEFAULT 0,
11728
- context_spike_count INTEGER NOT NULL DEFAULT 0,
11729
- total_turns INTEGER NOT NULL DEFAULT 0,
11730
- per_model_json TEXT NOT NULL DEFAULT '[]',
11731
- per_source_json TEXT NOT NULL DEFAULT '[]',
11732
- token_density_sub_score DOUBLE NOT NULL DEFAULT 0,
11733
- cold_start_turns_excluded INTEGER NOT NULL DEFAULT 0,
11734
- dispatch_id TEXT,
11735
- task_type TEXT,
11736
- phase TEXT,
11737
- PRIMARY KEY (story_key, timestamp)
11738
- )
11739
- `);
11740
- await this._adapter.exec(`
11741
- CREATE INDEX IF NOT EXISTS idx_efficiency_story
11742
- ON efficiency_scores (story_key, timestamp DESC)
11743
- `);
11744
- try {
11745
- await this._adapter.exec(`ALTER TABLE efficiency_scores ADD COLUMN token_density_sub_score DOUBLE NOT NULL DEFAULT 0`);
11746
- } catch {}
11747
- try {
11748
- await this._adapter.exec(`ALTER TABLE efficiency_scores ADD COLUMN cold_start_turns_excluded INTEGER NOT NULL DEFAULT 0`);
11749
- } catch {}
11750
- await this._adapter.exec(`
11751
- CREATE TABLE IF NOT EXISTS recommendations (
11752
- id VARCHAR(16) NOT NULL,
11753
- story_key VARCHAR(64) NOT NULL,
11754
- sprint_id VARCHAR(64),
11755
- rule_id VARCHAR(64) NOT NULL,
11756
- severity VARCHAR(16) NOT NULL,
11757
- title TEXT NOT NULL,
11758
- description TEXT NOT NULL,
11759
- potential_savings_tokens INTEGER,
11760
- potential_savings_usd DOUBLE,
11761
- action_target TEXT,
11762
- generated_at VARCHAR(32) NOT NULL,
11763
- PRIMARY KEY (id)
11764
- )
11765
- `);
11766
- await this._adapter.exec(`
11767
- CREATE INDEX IF NOT EXISTS idx_recommendations_story
11768
- ON recommendations (story_key, severity)
11769
- `);
11770
- await this._adapter.exec(`
11771
- CREATE TABLE IF NOT EXISTS category_stats (
11772
- story_key VARCHAR(100) NOT NULL,
11773
- category VARCHAR(30) NOT NULL,
11774
- total_tokens BIGINT NOT NULL DEFAULT 0,
11775
- percentage DECIMAL(6,3) NOT NULL DEFAULT 0,
11776
- event_count INTEGER NOT NULL DEFAULT 0,
11777
- avg_tokens_per_event DECIMAL(12,2) NOT NULL DEFAULT 0,
11778
- trend VARCHAR(10) NOT NULL DEFAULT 'stable',
11779
- PRIMARY KEY (story_key, category)
11780
- )
11781
- `);
11782
- await this._adapter.exec(`
11783
- CREATE INDEX IF NOT EXISTS idx_category_stats_story
11784
- ON category_stats (story_key, total_tokens)
11785
- `);
11786
- await this._adapter.exec(`
11787
- CREATE TABLE IF NOT EXISTS consumer_stats (
11788
- story_key VARCHAR(100) NOT NULL,
11789
- consumer_key VARCHAR(300) NOT NULL,
11790
- category VARCHAR(30) NOT NULL,
11791
- total_tokens BIGINT NOT NULL DEFAULT 0,
11792
- percentage DECIMAL(6,3) NOT NULL DEFAULT 0,
11793
- event_count INTEGER NOT NULL DEFAULT 0,
11794
- top_invocations_json TEXT,
11795
- PRIMARY KEY (story_key, consumer_key)
11796
- )
11797
- `);
11798
- await this._adapter.exec(`
11799
- CREATE INDEX IF NOT EXISTS idx_consumer_stats_story
11800
- ON consumer_stats (story_key, total_tokens)
11801
- `);
11802
- }
11803
11682
  async storeTurnAnalysis(storyKey, turns) {
11804
11683
  if (turns.length === 0) return;
11805
11684
  await this._adapter.transaction(async (adapter) => {
@@ -12152,22 +12031,18 @@ var AdapterTelemetryPersistence = class {
12152
12031
  * Concrete DatabaseAdapter-backed telemetry persistence.
12153
12032
  *
12154
12033
  * Accepts a DatabaseAdapter and delegates all operations to
12155
- * AdapterTelemetryPersistence. Provides schema initialization via initSchema().
12034
+ * AdapterTelemetryPersistence.
12156
12035
  *
12157
- * Accepts a DatabaseAdapter and uses it for all persistence operations.
12036
+ * Schema initialization is the responsibility of the main `initSchema()` in
12037
+ * packages/core/src/persistence/schema.ts. Callers MUST call it before
12038
+ * constructing TelemetryPersistence (Ship 4 / v0.20.95: removed the redundant
12039
+ * telemetry-only DDL that lived here).
12158
12040
  */
12159
12041
  var TelemetryPersistence = class {
12160
12042
  _impl;
12161
12043
  constructor(adapter) {
12162
12044
  this._impl = new AdapterTelemetryPersistence(adapter);
12163
12045
  }
12164
- /**
12165
- * Apply the telemetry schema DDL to the database.
12166
- * Idempotent — uses CREATE TABLE IF NOT EXISTS.
12167
- */
12168
- async initSchema() {
12169
- await this._impl.initSchema();
12170
- }
12171
12046
  async storeTurnAnalysis(storyKey, turns) {
12172
12047
  return this._impl.storeTurnAnalysis(storyKey, turns);
12173
12048
  }
@@ -46038,7 +45913,6 @@ async function runRunAction(options) {
46038
45913
  return 1;
46039
45914
  }
46040
45915
  const telemetryPersistence = telemetryEnabled ? new AdapterTelemetryPersistence(adapter) : void 0;
46041
- if (telemetryPersistence !== void 0) await telemetryPersistence.initSchema();
46042
45916
  const packLoader = createPackLoader();
46043
45917
  let pack;
46044
45918
  try {
@@ -47078,7 +46952,6 @@ async function runFullPipeline(options) {
47078
46952
  });
47079
46953
  }
47080
46954
  const fpTelemetryPersistence = fullTelemetryEnabled ? new AdapterTelemetryPersistence(adapter) : void 0;
47081
- if (fpTelemetryPersistence !== void 0) await fpTelemetryPersistence.initSchema();
47082
46955
  const orchestrator = createImplementationOrchestrator({
47083
46956
  db: adapter,
47084
46957
  pack,
@@ -47264,7 +47137,7 @@ async function runFullPipeline(options) {
47264
47137
  */
47265
47138
  async function emitPreDispatchVersionAdvisory(currentVersion) {
47266
47139
  if (process.env["SUBSTRATE_NO_UPDATE_CHECK"] === "1") return;
47267
- const { createVersionManager } = await import("./version-manager-impl-B8MpvZQz.js");
47140
+ const { createVersionManager } = await import("./version-manager-impl-9J_JCJPu.js");
47268
47141
  const vm = createVersionManager();
47269
47142
  const result = await vm.checkForUpdates(true);
47270
47143
  const gap = classifyVersionGap(currentVersion, result.latestVersion);
@@ -47361,4 +47234,4 @@ function registerRunCommand(program, version = "0.0.0", projectRoot = process.cw
47361
47234
 
47362
47235
  //#endregion
47363
47236
  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 };
47364
- //# sourceMappingURL=run-BXRwQRst.js.map
47237
+ //# sourceMappingURL=run-COnbF6By.js.map
@@ -1,5 +1,5 @@
1
- import "./dist-l0pA6zZF.js";
1
+ import "./dist-C_NE40jY.js";
2
2
  import "./version-manager-impl-qFBiO4Eh.js";
3
- import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-BP0P3qr9.js";
3
+ import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-C1KzAZQE.js";
4
4
 
5
5
  export { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand };
@@ -1,4 +1,4 @@
1
- import { createVersionManager } from "./dist-l0pA6zZF.js";
1
+ import { createVersionManager } from "./dist-C_NE40jY.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-BP0P3qr9.js.map
126
+ //# sourceMappingURL=upgrade-C1KzAZQE.js.map
@@ -1,4 +1,4 @@
1
- import { VersionManagerImpl, createVersionManager } from "./dist-l0pA6zZF.js";
1
+ import { VersionManagerImpl, createVersionManager } from "./dist-C_NE40jY.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.93",
3
+ "version": "0.20.95",
4
4
  "description": "Substrate — multi-agent orchestration daemon for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -41,7 +41,6 @@
41
41
  "dist/**/*.js",
42
42
  "dist/**/*.d.ts",
43
43
  "dist/**/*.json",
44
- "dist/**/*.sql",
45
44
  "dist/**/*.dot",
46
45
  "dist/cli/templates",
47
46
  "packs",
@@ -50,7 +49,7 @@
50
49
  "scripts": {
51
50
  "agent-memory:bootstrap": "node scripts/bootstrap-agent-memory.mjs",
52
51
  "build": "tsc --build packages/core packages/sdlc packages/factory && tsdown",
53
- "postbuild": "cp -r src/cli/templates dist/cli/templates && cp src/modules/state/schema.sql dist/schema.sql && mkdir -p dist/graphs && cp packages/sdlc/graphs/sdlc-pipeline.dot dist/graphs/ && printf '#!/usr/bin/env node\\n// Wrapper so probes can invoke as dist/cli.mjs (Story 71-1).\\n// Redirect argv[1] so isMainModule detection in cli/index.js fires correctly.\\nprocess.argv[1] = new URL(\"./cli/index.js\", import.meta.url).pathname;\\nawait import(\"./cli/index.js\");\\n' > dist/cli.mjs",
52
+ "postbuild": "cp -r src/cli/templates dist/cli/templates && mkdir -p dist/graphs && cp packages/sdlc/graphs/sdlc-pipeline.dot dist/graphs/ && printf '#!/usr/bin/env node\\n// Wrapper so probes can invoke as dist/cli.mjs (Story 71-1).\\n// Redirect argv[1] so isMainModule detection in cli/index.js fires correctly.\\nprocess.argv[1] = new URL(\"./cli/index.js\", import.meta.url).pathname;\\nawait import(\"./cli/index.js\");\\n' > dist/cli.mjs",
54
53
  "check:circular": "dpdm --no-warning --exit-code circular:1 packages/core/src/index.ts packages/sdlc/src/index.ts packages/factory/src/index.ts",
55
54
  "dev": "tsx watch src/cli/index.ts",
56
55
  "test": "vitest run --coverage",
@@ -1,4 +0,0 @@
1
- import { AdapterRegistry } from "./dist-l0pA6zZF.js";
2
- import "./adapter-registry-DIcrxjH8.js";
3
-
4
- export { AdapterRegistry };
package/dist/schema.sql DELETED
@@ -1,328 +0,0 @@
1
- -- Substrate State Schema v1
2
- -- Dolt-compatible DDL: composite natural business-key primary keys,
3
- -- DATETIME columns to avoid timezone-dependent merge conflicts.
4
-
5
- -- ---------------------------------------------------------------------------
6
- -- stories
7
- -- ---------------------------------------------------------------------------
8
- CREATE TABLE IF NOT EXISTS stories (
9
- story_key VARCHAR(100) NOT NULL,
10
- sprint VARCHAR(50),
11
- status VARCHAR(30) NOT NULL DEFAULT 'PENDING',
12
- phase VARCHAR(30) NOT NULL DEFAULT 'PENDING',
13
- ac_results JSON,
14
- error_message TEXT,
15
- created_at DATETIME,
16
- updated_at DATETIME,
17
- completed_at DATETIME,
18
- PRIMARY KEY (story_key)
19
- );
20
-
21
- -- ---------------------------------------------------------------------------
22
- -- contracts
23
- -- ---------------------------------------------------------------------------
24
- CREATE TABLE IF NOT EXISTS contracts (
25
- story_key VARCHAR(100) NOT NULL,
26
- name VARCHAR(200) NOT NULL,
27
- direction VARCHAR(20) NOT NULL,
28
- schema_path VARCHAR(500),
29
- transport VARCHAR(200),
30
- recorded_at DATETIME,
31
- PRIMARY KEY (story_key, name, direction)
32
- );
33
-
34
- -- ---------------------------------------------------------------------------
35
- -- metrics
36
- -- ---------------------------------------------------------------------------
37
- CREATE TABLE IF NOT EXISTS metrics (
38
- story_key VARCHAR(100) NOT NULL,
39
- task_type VARCHAR(100) NOT NULL,
40
- recorded_at DATETIME NOT NULL,
41
- model VARCHAR(100),
42
- tokens_in BIGINT NOT NULL DEFAULT 0,
43
- tokens_out BIGINT NOT NULL DEFAULT 0,
44
- cache_read_tokens BIGINT NOT NULL DEFAULT 0,
45
- cost_usd DECIMAL(10,6) NOT NULL DEFAULT 0,
46
- wall_clock_ms BIGINT NOT NULL DEFAULT 0,
47
- review_cycles INT NOT NULL DEFAULT 0,
48
- stall_count INT NOT NULL DEFAULT 0,
49
- result VARCHAR(30),
50
- PRIMARY KEY (story_key, task_type, recorded_at)
51
- );
52
-
53
- -- ---------------------------------------------------------------------------
54
- -- dispatch_log
55
- -- ---------------------------------------------------------------------------
56
- CREATE TABLE IF NOT EXISTS dispatch_log (
57
- story_key VARCHAR(100) NOT NULL,
58
- dispatched_at DATETIME NOT NULL,
59
- branch VARCHAR(200),
60
- worker_id VARCHAR(100),
61
- result VARCHAR(30),
62
- PRIMARY KEY (story_key, dispatched_at)
63
- );
64
-
65
- -- ---------------------------------------------------------------------------
66
- -- build_results
67
- -- ---------------------------------------------------------------------------
68
- CREATE TABLE IF NOT EXISTS build_results (
69
- story_key VARCHAR(100) NOT NULL,
70
- timestamp DATETIME NOT NULL,
71
- command VARCHAR(500),
72
- exit_code INT,
73
- stdout_hash VARCHAR(64),
74
- PRIMARY KEY (story_key, timestamp)
75
- );
76
-
77
- -- ---------------------------------------------------------------------------
78
- -- review_verdicts
79
- -- ---------------------------------------------------------------------------
80
- CREATE TABLE IF NOT EXISTS review_verdicts (
81
- story_key VARCHAR(100) NOT NULL,
82
- timestamp DATETIME NOT NULL,
83
- verdict VARCHAR(30),
84
- issues_count INT NOT NULL DEFAULT 0,
85
- notes TEXT,
86
- PRIMARY KEY (story_key, timestamp)
87
- );
88
-
89
- -- ---------------------------------------------------------------------------
90
- -- _schema_version
91
- -- ---------------------------------------------------------------------------
92
- CREATE TABLE IF NOT EXISTS _schema_version (
93
- version INT NOT NULL,
94
- applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
95
- description VARCHAR(500),
96
- PRIMARY KEY (version)
97
- );
98
-
99
- -- Seed schema version (idempotent via INSERT IGNORE)
100
- INSERT IGNORE INTO _schema_version (version, description) VALUES (1, 'Initial substrate state schema');
101
-
102
- -- ---------------------------------------------------------------------------
103
- -- turn_analysis (story 27-4)
104
- -- ---------------------------------------------------------------------------
105
- CREATE TABLE IF NOT EXISTS turn_analysis (
106
- story_key VARCHAR(64) NOT NULL,
107
- span_id VARCHAR(128) NOT NULL,
108
- turn_number INTEGER NOT NULL,
109
- name VARCHAR(255) NOT NULL DEFAULT '',
110
- timestamp BIGINT NOT NULL DEFAULT 0,
111
- source VARCHAR(32) NOT NULL DEFAULT '',
112
- model VARCHAR(64),
113
- input_tokens INTEGER NOT NULL DEFAULT 0,
114
- output_tokens INTEGER NOT NULL DEFAULT 0,
115
- cache_read_tokens INTEGER NOT NULL DEFAULT 0,
116
- fresh_tokens INTEGER NOT NULL DEFAULT 0,
117
- cache_hit_rate DOUBLE NOT NULL DEFAULT 0,
118
- cost_usd DOUBLE NOT NULL DEFAULT 0,
119
- duration_ms INTEGER NOT NULL DEFAULT 0,
120
- context_size INTEGER NOT NULL DEFAULT 0,
121
- context_delta INTEGER NOT NULL DEFAULT 0,
122
- tool_name VARCHAR(128),
123
- is_context_spike BOOLEAN NOT NULL DEFAULT 0,
124
- child_spans_json TEXT NOT NULL DEFAULT '[]',
125
- task_type VARCHAR(64),
126
- phase VARCHAR(64),
127
- dispatch_id VARCHAR(64),
128
- PRIMARY KEY (story_key, span_id)
129
- );
130
-
131
- CREATE INDEX IF NOT EXISTS idx_turn_analysis_story ON turn_analysis (story_key, turn_number);
132
-
133
- INSERT IGNORE INTO _schema_version (version, description) VALUES (2, 'Add turn_analysis table (Epic 27-4)');
134
-
135
- -- ---------------------------------------------------------------------------
136
- -- efficiency_scores
137
- -- ---------------------------------------------------------------------------
138
- CREATE TABLE IF NOT EXISTS efficiency_scores (
139
- story_key VARCHAR(64) NOT NULL,
140
- timestamp BIGINT NOT NULL,
141
- composite_score INTEGER NOT NULL DEFAULT 0,
142
- cache_hit_sub_score DOUBLE NOT NULL DEFAULT 0,
143
- io_ratio_sub_score DOUBLE NOT NULL DEFAULT 0,
144
- context_management_sub_score DOUBLE NOT NULL DEFAULT 0,
145
- token_density_sub_score DOUBLE NOT NULL DEFAULT 0,
146
- cold_start_turns_excluded INTEGER NOT NULL DEFAULT 0,
147
- avg_cache_hit_rate DOUBLE NOT NULL DEFAULT 0,
148
- avg_io_ratio DOUBLE NOT NULL DEFAULT 0,
149
- context_spike_count INTEGER NOT NULL DEFAULT 0,
150
- total_turns INTEGER NOT NULL DEFAULT 0,
151
- per_model_json TEXT NOT NULL DEFAULT '[]',
152
- per_source_json TEXT NOT NULL DEFAULT '[]',
153
- dispatch_id TEXT,
154
- task_type TEXT,
155
- phase TEXT,
156
- PRIMARY KEY (story_key, timestamp)
157
- );
158
-
159
- CREATE INDEX IF NOT EXISTS idx_efficiency_story ON efficiency_scores (story_key, timestamp DESC);
160
-
161
- -- ---------------------------------------------------------------------------
162
- -- recommendations (story 27-7)
163
- -- ---------------------------------------------------------------------------
164
- CREATE TABLE IF NOT EXISTS recommendations (
165
- id VARCHAR(16) NOT NULL,
166
- story_key VARCHAR(64) NOT NULL,
167
- sprint_id VARCHAR(64),
168
- rule_id VARCHAR(64) NOT NULL,
169
- severity VARCHAR(16) NOT NULL,
170
- title TEXT NOT NULL,
171
- description TEXT NOT NULL,
172
- potential_savings_tokens INTEGER,
173
- potential_savings_usd DOUBLE,
174
- action_target TEXT,
175
- generated_at VARCHAR(32) NOT NULL,
176
- PRIMARY KEY (id)
177
- );
178
- CREATE INDEX IF NOT EXISTS idx_recommendations_story ON recommendations (story_key, severity);
179
-
180
- -- ---------------------------------------------------------------------------
181
- -- category_stats (story 27-5)
182
- -- ---------------------------------------------------------------------------
183
- CREATE TABLE IF NOT EXISTS category_stats (
184
- story_key VARCHAR(100) NOT NULL,
185
- category VARCHAR(30) NOT NULL,
186
- total_tokens BIGINT NOT NULL DEFAULT 0,
187
- percentage DECIMAL(6,3) NOT NULL DEFAULT 0,
188
- event_count INTEGER NOT NULL DEFAULT 0,
189
- avg_tokens_per_event DECIMAL(12,2) NOT NULL DEFAULT 0,
190
- trend VARCHAR(10) NOT NULL DEFAULT 'stable',
191
- PRIMARY KEY (story_key, category)
192
- );
193
-
194
- CREATE INDEX IF NOT EXISTS idx_category_stats_story ON category_stats (story_key, total_tokens);
195
-
196
- -- ---------------------------------------------------------------------------
197
- -- consumer_stats (story 27-5)
198
- -- ---------------------------------------------------------------------------
199
- CREATE TABLE IF NOT EXISTS consumer_stats (
200
- story_key VARCHAR(100) NOT NULL,
201
- consumer_key VARCHAR(300) NOT NULL,
202
- category VARCHAR(30) NOT NULL,
203
- total_tokens BIGINT NOT NULL DEFAULT 0,
204
- percentage DECIMAL(6,3) NOT NULL DEFAULT 0,
205
- event_count INTEGER NOT NULL DEFAULT 0,
206
- top_invocations_json TEXT,
207
- PRIMARY KEY (story_key, consumer_key)
208
- );
209
-
210
- CREATE INDEX IF NOT EXISTS idx_consumer_stats_story ON consumer_stats (story_key, total_tokens);
211
-
212
- INSERT IGNORE INTO _schema_version (version, description) VALUES (3, 'Add category_stats and consumer_stats tables (Epic 27-5)');
213
- INSERT IGNORE INTO _schema_version (version, description) VALUES (4, 'Add recommendations table (Epic 27-7)');
214
-
215
- -- ---------------------------------------------------------------------------
216
- -- repo_map_symbols (story 28-2 / Epic 28)
217
- -- ---------------------------------------------------------------------------
218
- CREATE TABLE IF NOT EXISTS repo_map_symbols (
219
- id BIGINT AUTO_INCREMENT NOT NULL,
220
- file_path VARCHAR(1000) NOT NULL,
221
- symbol_name VARCHAR(500) NOT NULL,
222
- symbol_kind VARCHAR(20) NOT NULL,
223
- signature TEXT,
224
- line_number INT NOT NULL DEFAULT 0,
225
- exported TINYINT(1) NOT NULL DEFAULT 0,
226
- file_hash VARCHAR(64) NOT NULL,
227
- dependencies JSON,
228
- PRIMARY KEY (id)
229
- );
230
-
231
- CREATE INDEX IF NOT EXISTS idx_repo_map_symbols_file ON repo_map_symbols (file_path);
232
- CREATE INDEX IF NOT EXISTS idx_repo_map_symbols_kind ON repo_map_symbols (symbol_kind);
233
-
234
- -- ---------------------------------------------------------------------------
235
- -- repo_map_meta (story 28-2 / Epic 28)
236
- -- ---------------------------------------------------------------------------
237
- CREATE TABLE IF NOT EXISTS repo_map_meta (
238
- id INT NOT NULL DEFAULT 1,
239
- commit_sha VARCHAR(64),
240
- updated_at DATETIME,
241
- file_count INT NOT NULL DEFAULT 0,
242
- PRIMARY KEY (id)
243
- );
244
-
245
- INSERT IGNORE INTO _schema_version (version, description) VALUES (5, 'Add repo_map_symbols and repo_map_meta tables (Epic 28-2)');
246
- INSERT IGNORE INTO _schema_version (version, description) VALUES (6, 'Add dependencies JSON column to repo_map_symbols (Epic 28-3)');
247
-
248
- -- ---------------------------------------------------------------------------
249
- -- wg_stories (Epic 31-1) — planning-level work graph story nodes
250
- -- ---------------------------------------------------------------------------
251
- CREATE TABLE IF NOT EXISTS wg_stories (
252
- story_key VARCHAR(20) NOT NULL,
253
- epic VARCHAR(20) NOT NULL,
254
- title VARCHAR(255),
255
- status VARCHAR(30) NOT NULL DEFAULT 'planned',
256
- spec_path VARCHAR(500),
257
- created_at DATETIME,
258
- updated_at DATETIME,
259
- completed_at DATETIME,
260
- PRIMARY KEY (story_key)
261
- );
262
-
263
- CREATE INDEX IF NOT EXISTS idx_wg_stories_epic ON wg_stories (epic);
264
-
265
- -- ---------------------------------------------------------------------------
266
- -- story_dependencies (Epic 31-1) — directed dependency edges
267
- -- ---------------------------------------------------------------------------
268
- CREATE TABLE IF NOT EXISTS story_dependencies (
269
- story_key VARCHAR(50) NOT NULL,
270
- depends_on VARCHAR(50) NOT NULL,
271
- dependency_type VARCHAR(50) NOT NULL DEFAULT 'blocks',
272
- source VARCHAR(50) NOT NULL DEFAULT 'explicit',
273
- created_at DATETIME,
274
- PRIMARY KEY (story_key, depends_on)
275
- );
276
-
277
- -- Migration: add created_at to story_dependencies (added in v0.12.0)
278
- SET @_sd_created_at_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'story_dependencies' AND COLUMN_NAME = 'created_at');
279
- SET @_sql = IF(@_sd_created_at_exists = 0, 'ALTER TABLE story_dependencies ADD COLUMN created_at DATETIME DEFAULT NULL', 'SELECT 1');
280
- PREPARE _add_col FROM @_sql; EXECUTE _add_col; DEALLOCATE PREPARE _add_col;
281
-
282
- -- ---------------------------------------------------------------------------
283
- -- ready_stories view (Epic 31-1)
284
- -- ---------------------------------------------------------------------------
285
- CREATE OR REPLACE VIEW ready_stories AS
286
- SELECT s.* FROM wg_stories s
287
- WHERE s.status IN ('planned', 'ready')
288
- AND NOT EXISTS (
289
- SELECT 1 FROM story_dependencies d
290
- JOIN wg_stories dep ON dep.story_key = d.depends_on
291
- WHERE d.story_key = s.story_key
292
- AND d.dependency_type = 'blocks'
293
- AND dep.status <> 'complete'
294
- );
295
-
296
- INSERT IGNORE INTO _schema_version (version, description) VALUES (7, 'Add wg_stories, story_dependencies tables and ready_stories view (Epic 31-1)');
297
- INSERT IGNORE INTO _schema_version (version, description) VALUES (8, 'Add task_type, phase, dispatch_id columns to turn_analysis (Story 30-1)');
298
-
299
- -- Migration: add dispatch context columns to turn_analysis for existing repos (Story 30-1)
300
- -- Uses INFORMATION_SCHEMA guard for Dolt/MySQL compatibility (ADD COLUMN IF NOT EXISTS not standard MySQL)
301
- -- For fresh repos the columns are already declared in CREATE TABLE IF NOT EXISTS above, so these
302
- -- INFORMATION_SCHEMA checks will find count > 0 and emit 'SELECT 1' (no-op).
303
- SET @_task_type_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'turn_analysis' AND COLUMN_NAME = 'task_type');
304
- SET @_sql = IF(@_task_type_exists = 0, 'ALTER TABLE turn_analysis ADD COLUMN task_type VARCHAR(64)', 'SELECT 1');
305
- PREPARE _add_col FROM @_sql; EXECUTE _add_col; DEALLOCATE PREPARE _add_col;
306
-
307
- SET @_phase_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'turn_analysis' AND COLUMN_NAME = 'phase');
308
- SET @_sql = IF(@_phase_exists = 0, 'ALTER TABLE turn_analysis ADD COLUMN phase VARCHAR(64)', 'SELECT 1');
309
- PREPARE _add_col FROM @_sql; EXECUTE _add_col; DEALLOCATE PREPARE _add_col;
310
-
311
- SET @_dispatch_id_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'turn_analysis' AND COLUMN_NAME = 'dispatch_id');
312
- SET @_sql = IF(@_dispatch_id_exists = 0, 'ALTER TABLE turn_analysis ADD COLUMN dispatch_id VARCHAR(64)', 'SELECT 1');
313
- PREPARE _add_col FROM @_sql; EXECUTE _add_col; DEALLOCATE PREPARE _add_col;
314
-
315
- INSERT IGNORE INTO _schema_version (version, description) VALUES (9, 'Add dispatch_id, task_type, phase columns to efficiency_scores (Story 30-3)');
316
-
317
- -- Migration: add dispatch context columns to efficiency_scores for existing repos (Story 30-3)
318
- SET @_eff_dispatch_id_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'efficiency_scores' AND COLUMN_NAME = 'dispatch_id');
319
- SET @_sql = IF(@_eff_dispatch_id_exists = 0, 'ALTER TABLE efficiency_scores ADD COLUMN dispatch_id TEXT', 'SELECT 1');
320
- PREPARE _add_col FROM @_sql; EXECUTE _add_col; DEALLOCATE PREPARE _add_col;
321
-
322
- SET @_eff_task_type_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'efficiency_scores' AND COLUMN_NAME = 'task_type');
323
- SET @_sql = IF(@_eff_task_type_exists = 0, 'ALTER TABLE efficiency_scores ADD COLUMN task_type TEXT', 'SELECT 1');
324
- PREPARE _add_col FROM @_sql; EXECUTE _add_col; DEALLOCATE PREPARE _add_col;
325
-
326
- SET @_eff_phase_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'efficiency_scores' AND COLUMN_NAME = 'phase');
327
- SET @_sql = IF(@_eff_phase_exists = 0, 'ALTER TABLE efficiency_scores ADD COLUMN phase TEXT', 'SELECT 1');
328
- PREPARE _add_col FROM @_sql; EXECUTE _add_col; DEALLOCATE PREPARE _add_col;