substrate-ai 0.20.138 → 0.20.141
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter-registry-qU0IkbbQ.js +4 -0
- package/dist/cli/index.js +41 -37
- package/dist/{decision-router-DblHY8se.js → decision-router-BAPpON_C.js} +4 -2
- package/dist/{decisions-fBdZmqOK.js → decisions-Dvw5HhyM.js} +1 -1
- package/dist/{dist-DnvGvKLu.js → dist-DiNK6QOD.js} +104 -17
- package/dist/{errors-i3s5sshZ.js → errors-B21JUhcc.js} +2 -2
- package/dist/{experimenter-DU2Cv51N.js → experimenter-D55L011w.js} +1 -1
- package/dist/{health-2Kfa00-H.js → health-BQRsVP6s.js} +3 -3
- package/dist/{health-Caa24SFM.js → health-Cm-pA1mZ.js} +3 -3
- package/dist/{index-BJEANS9i.d.ts → index-BqVBOAO0.d.ts} +25 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/{interactive-prompt-B91mG5v4.js → interactive-prompt-CgerI5Y6.js} +2 -2
- package/dist/{manifest-read-DJFbGhSd.js → manifest-read-Doh2Ion5.js} +17 -3
- package/dist/modules/interactive-prompt/index.js +3 -3
- package/dist/{routing-DFIBY9Yk.js → routing-_PGfe_cD.js} +1 -1
- package/dist/{run-Ppco-3HT.js → run-BHRkyn_H.js} +6 -6
- package/dist/{run-Dbwlb4Md.js → run-CRvusFIv.js} +674 -183
- package/dist/src/modules/decision-router/index.d.ts +1 -1
- package/dist/src/modules/decision-router/index.js +1 -1
- package/dist/src/modules/recovery-engine/index.d.ts +9 -1
- package/dist/{upgrade-CnIsoLpT.js → upgrade-CTj4hi8J.js} +2 -2
- package/dist/{upgrade-yULZIAAW.js → upgrade-DB7KzD9c.js} +2 -2
- package/dist/{version-manager-impl-C7ZhqLX3.js → version-manager-impl-HJMonRJi.js} +1 -1
- package/package.json +3 -3
- package/packs/bmad/prompts/probe-author.md +17 -0
- package/dist/adapter-registry-Bpa7ESBV.js +0 -4
|
@@ -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-
|
|
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-BQRsVP6s.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, 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, 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-
|
|
5
|
-
import { FindingsInjector, RunManifest, RuntimeProbeListSchema, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, parseRuntimeProbes, renderFindings, resolveGraphPath, resolveMainRepoRoot, runAcTraceabilityCheck, runStaleVerificationRecovery } from "./manifest-read-
|
|
4
|
+
import { ADVISORY_NOTES, CLAUDE_AUTH_FAILURE_HINT, CODEX_SANDBOX_BLOCK_HINT, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, IngestionServer, LogTurnAnalyzer, OPERATIONAL_FINDING, Recommender, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, callLLM, classifyVersionGap, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, createStderrLogger, detectClaudeAuthFailure, detectCodexSandboxBlock, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, swallowDebug, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-DiNK6QOD.js";
|
|
5
|
+
import { FindingsInjector, RunManifest, RuntimeProbeListSchema, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, parseRuntimeProbes, renderFindings, resolveGraphPath, resolveMainRepoRoot, runAcTraceabilityCheck, runStaleVerificationRecovery } from "./manifest-read-Doh2Ion5.js";
|
|
6
6
|
import { WorkGraphRepository, detectCycles } from "./work-graph-repository-DZyJv5pV.js";
|
|
7
|
-
import { deriveExitCode, routeDecision } from "./decision-router-
|
|
8
|
-
import { runInteractivePrompt } from "./interactive-prompt-
|
|
7
|
+
import { deriveExitCode, routeDecision } from "./decision-router-BAPpON_C.js";
|
|
8
|
+
import { runInteractivePrompt } from "./interactive-prompt-CgerI5Y6.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";
|
|
@@ -159,6 +159,66 @@ function decideWorktreeReclaim(hasUncommittedChanges, commitsAhead, baseBranch)
|
|
|
159
159
|
};
|
|
160
160
|
return { safe: true };
|
|
161
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Decide whether removing a story worktree AND deleting its branch is safe
|
|
164
|
+
* (H0.3, field findings #17/#19). Unsafe when:
|
|
165
|
+
* - the worktree has uncommitted changes (removal destroys the only copy), or
|
|
166
|
+
* - the branch carries commits not reachable from the project's current HEAD
|
|
167
|
+
* (branch -D destroys them — this is where H0.1's wip checkpoints live), or
|
|
168
|
+
* - either state could not be determined (negative unmergedCommits).
|
|
169
|
+
*
|
|
170
|
+
* Pure + exported for testing (mirrors decideWorktreeReclaim; the git I/O that
|
|
171
|
+
* produces the inputs lives in inspectWorktreeRemovalSafety).
|
|
172
|
+
*/
|
|
173
|
+
function decideWorktreeRemoval(hasUncommittedChanges, uncommittedFiles, unmergedCommits, branchName) {
|
|
174
|
+
const reasons = [];
|
|
175
|
+
if (hasUncommittedChanges) {
|
|
176
|
+
const preview = uncommittedFiles.slice(0, 10).join(", ");
|
|
177
|
+
const more = uncommittedFiles.length > 10 ? ` (+${String(uncommittedFiles.length - 10)} more)` : "";
|
|
178
|
+
reasons.push(`the worktree has ${String(uncommittedFiles.length)} uncommitted change(s) that removal would destroy` + (preview.length > 0 ? `: ${preview}${more}` : ""));
|
|
179
|
+
}
|
|
180
|
+
if (unmergedCommits > 0) reasons.push(`branch ${branchName} carries ${String(unmergedCommits)} commit(s) not reachable from the current HEAD — deleting the branch would destroy them`);
|
|
181
|
+
if (unmergedCommits < 0) reasons.push("the branch state could not be verified as safe to discard");
|
|
182
|
+
return {
|
|
183
|
+
safe: reasons.length === 0,
|
|
184
|
+
reasons
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Gather the inputs for `decideWorktreeRemoval` from git. Thin I/O wrapper:
|
|
189
|
+
* - `git status --porcelain` inside the worktree (skipped when the directory
|
|
190
|
+
* is missing — nothing on disk to lose)
|
|
191
|
+
* - `git rev-list --count HEAD..<branch>` in the project root (commits the
|
|
192
|
+
* branch has that the current checkout does not; 0 when the branch is
|
|
193
|
+
* merged or absent, -1 when the count could not be determined)
|
|
194
|
+
*/
|
|
195
|
+
async function inspectWorktreeRemovalSafety(worktreePath, projectRoot, branchName) {
|
|
196
|
+
let hasUncommittedChanges = false;
|
|
197
|
+
let uncommittedFiles = [];
|
|
198
|
+
const worktreeOnDisk = await access$1(worktreePath).then(() => true).catch(() => false);
|
|
199
|
+
if (worktreeOnDisk) {
|
|
200
|
+
const statusResult = await spawnGit(["status", "--porcelain"], { cwd: worktreePath });
|
|
201
|
+
if (statusResult.code === 0) {
|
|
202
|
+
uncommittedFiles = statusResult.stdout.split("\n").filter((line) => line.trim().length > 0).map((line) => line.slice(3).trim());
|
|
203
|
+
hasUncommittedChanges = uncommittedFiles.length > 0;
|
|
204
|
+
} else return decideWorktreeRemoval(false, [], -1, branchName);
|
|
205
|
+
}
|
|
206
|
+
const branchExists = (await spawnGit([
|
|
207
|
+
"rev-parse",
|
|
208
|
+
"--verify",
|
|
209
|
+
branchName
|
|
210
|
+
], { cwd: projectRoot })).code === 0;
|
|
211
|
+
let unmergedCommits = 0;
|
|
212
|
+
if (branchExists) {
|
|
213
|
+
const aheadResult = await spawnGit([
|
|
214
|
+
"rev-list",
|
|
215
|
+
"--count",
|
|
216
|
+
`HEAD..${branchName}`
|
|
217
|
+
], { cwd: projectRoot });
|
|
218
|
+
unmergedCommits = aheadResult.code === 0 ? Number.parseInt(aheadResult.stdout.trim(), 10) || 0 : -1;
|
|
219
|
+
}
|
|
220
|
+
return decideWorktreeRemoval(hasUncommittedChanges, uncommittedFiles, unmergedCommits, branchName);
|
|
221
|
+
}
|
|
162
222
|
async function createWorktree(projectRoot, taskId, branchName, baseBranch, copyFiles = []) {
|
|
163
223
|
const worktreePath = path$5.join(projectRoot, ".substrate-worktrees", taskId);
|
|
164
224
|
const worktreeExists = await access$1(worktreePath).then(() => true).catch((err) => {
|
|
@@ -518,14 +578,19 @@ var GitWorktreeManagerImpl = class {
|
|
|
518
578
|
}, "Worktree created");
|
|
519
579
|
return info;
|
|
520
580
|
}
|
|
521
|
-
async cleanupWorktree(taskId) {
|
|
581
|
+
async cleanupWorktree(taskId, opts) {
|
|
522
582
|
const branchName = BRANCH_PREFIX + taskId;
|
|
523
583
|
const worktreePath = this.getWorktreePath(taskId);
|
|
524
584
|
this._logger.debug({
|
|
525
585
|
taskId,
|
|
526
586
|
branchName,
|
|
527
|
-
worktreePath
|
|
587
|
+
worktreePath,
|
|
588
|
+
force: opts?.force === true
|
|
528
589
|
}, "cleanupWorktree");
|
|
590
|
+
if (opts?.force !== true) {
|
|
591
|
+
const decision = await inspectWorktreeRemovalSafety(worktreePath, this._projectRoot, branchName);
|
|
592
|
+
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
|
+
}
|
|
529
594
|
let worktreeExists = false;
|
|
530
595
|
try {
|
|
531
596
|
await access$1(worktreePath);
|
|
@@ -563,12 +628,28 @@ var GitWorktreeManagerImpl = class {
|
|
|
563
628
|
branchName
|
|
564
629
|
}, "Worktree cleaned up");
|
|
565
630
|
}
|
|
566
|
-
async cleanupAllWorktrees() {
|
|
567
|
-
this._logger.debug({
|
|
631
|
+
async cleanupAllWorktrees(opts) {
|
|
632
|
+
this._logger.debug({
|
|
633
|
+
projectRoot: this._projectRoot,
|
|
634
|
+
force: opts?.force === true
|
|
635
|
+
}, "cleanupAllWorktrees");
|
|
568
636
|
const orphanedPaths = await getOrphanedWorktrees(this._projectRoot, this._baseDirectory);
|
|
569
637
|
let cleaned = 0;
|
|
570
638
|
for (const worktreePath of orphanedPaths) {
|
|
571
639
|
const taskId = path$4.basename(worktreePath);
|
|
640
|
+
const branchGuardName = BRANCH_PREFIX + taskId;
|
|
641
|
+
const decision = opts?.force === true ? {
|
|
642
|
+
safe: true,
|
|
643
|
+
reasons: []
|
|
644
|
+
} : await inspectWorktreeRemovalSafety(worktreePath, this._projectRoot, branchGuardName);
|
|
645
|
+
if (!decision.safe) {
|
|
646
|
+
this._logger.warn({
|
|
647
|
+
taskId,
|
|
648
|
+
worktreePath,
|
|
649
|
+
reasons: decision.reasons
|
|
650
|
+
}, "cleanupAllWorktrees: preserving worktree — removal would destroy work (use `substrate worktrees cleanup --force` to discard)");
|
|
651
|
+
continue;
|
|
652
|
+
}
|
|
572
653
|
let worktreeRemoved = false;
|
|
573
654
|
try {
|
|
574
655
|
await removeWorktree(worktreePath, this._projectRoot);
|
|
@@ -6813,6 +6894,21 @@ async function runCreateStory(deps, params) {
|
|
|
6813
6894
|
if (dispatchResult.parsed === null) {
|
|
6814
6895
|
const details = dispatchResult.parseError ?? "No YAML block found in output";
|
|
6815
6896
|
const rawSnippet = dispatchResult.output ? dispatchResult.output.slice(0, 1e3) : "(empty)";
|
|
6897
|
+
const authSignature = detectClaudeAuthFailure(dispatchResult.output);
|
|
6898
|
+
if (authSignature !== null) {
|
|
6899
|
+
logger$21.error({
|
|
6900
|
+
epicId,
|
|
6901
|
+
storyKey,
|
|
6902
|
+
authSignature,
|
|
6903
|
+
rawOutputSnippet: rawSnippet
|
|
6904
|
+
}, "Create-story dispatch died on authentication");
|
|
6905
|
+
return {
|
|
6906
|
+
result: "failed",
|
|
6907
|
+
error: "auth-failure",
|
|
6908
|
+
details: `Claude CLI authentication failure (matched: "${authSignature}"). Agent output: ${rawSnippet}`,
|
|
6909
|
+
tokenUsage
|
|
6910
|
+
};
|
|
6911
|
+
}
|
|
6816
6912
|
logger$21.warn({
|
|
6817
6913
|
epicId,
|
|
6818
6914
|
storyKey,
|
|
@@ -7549,6 +7645,104 @@ async function commitDevStoryOutput(storyKey, storyTitle, filesModified, working
|
|
|
7549
7645
|
};
|
|
7550
7646
|
}
|
|
7551
7647
|
/**
|
|
7648
|
+
* Commit the worktree's dirty state as a recovery checkpoint (H0.1, field
|
|
7649
|
+
* finding #17): on every failure path the story branch — not the worktree's
|
|
7650
|
+
* working tree — must be the durable copy of the agent's work. Before this,
|
|
7651
|
+
* a verification-failed or escalated story left its only copy as uncommitted
|
|
7652
|
+
* files, and any `git worktree remove --force` (operator cleanup, orphan
|
|
7653
|
+
* sweep) destroyed it permanently.
|
|
7654
|
+
*
|
|
7655
|
+
* Semantics differ from `commitDevStoryOutput` deliberately:
|
|
7656
|
+
* - Stages EVERYTHING dirty (`git add -A`; .gitignore still applies) — a
|
|
7657
|
+
* checkpoint must not guess which files matter.
|
|
7658
|
+
* - Bypasses hooks (`--no-verify`): this is a recovery snapshot, not a
|
|
7659
|
+
* deliverable. Deliverable `feat(story-…)` commits keep hooks; wip
|
|
7660
|
+
* checkpoints never merge on their own — `reconcile-from-disk` and the
|
|
7661
|
+
* operator decide what to do with them.
|
|
7662
|
+
* - Message prefix `wip(story-<key>):` so tooling can tell checkpoints from
|
|
7663
|
+
* deliverables (reconcile-from-disk greps both, prefers feat).
|
|
7664
|
+
*
|
|
7665
|
+
* Never throws; all failure modes return a structured status.
|
|
7666
|
+
*/
|
|
7667
|
+
async function checkpointStoryWorktree(storyKey, reason, workingDir) {
|
|
7668
|
+
if (!existsSync(workingDir)) return { status: "no-changes" };
|
|
7669
|
+
try {
|
|
7670
|
+
execSync("git add -A", {
|
|
7671
|
+
cwd: workingDir,
|
|
7672
|
+
stdio: [
|
|
7673
|
+
"ignore",
|
|
7674
|
+
"pipe",
|
|
7675
|
+
"pipe"
|
|
7676
|
+
],
|
|
7677
|
+
timeout: 3e4
|
|
7678
|
+
});
|
|
7679
|
+
} catch (err) {
|
|
7680
|
+
const stderr = err instanceof Error && "stderr" in err ? String(err.stderr ?? err.message) : err instanceof Error ? err.message : String(err);
|
|
7681
|
+
return {
|
|
7682
|
+
status: "failed",
|
|
7683
|
+
stderr: `git add -A failed: ${stderr}`
|
|
7684
|
+
};
|
|
7685
|
+
}
|
|
7686
|
+
const cachedCheck = spawn("git", [
|
|
7687
|
+
"diff",
|
|
7688
|
+
"--cached",
|
|
7689
|
+
"--quiet"
|
|
7690
|
+
], {
|
|
7691
|
+
cwd: workingDir,
|
|
7692
|
+
stdio: [
|
|
7693
|
+
"ignore",
|
|
7694
|
+
"pipe",
|
|
7695
|
+
"pipe"
|
|
7696
|
+
]
|
|
7697
|
+
});
|
|
7698
|
+
const cachedStatus = await new Promise((res) => {
|
|
7699
|
+
cachedCheck.on("close", (code) => res(code ?? 0));
|
|
7700
|
+
cachedCheck.on("error", () => res(0));
|
|
7701
|
+
});
|
|
7702
|
+
if (cachedStatus === 0) return { status: "no-changes" };
|
|
7703
|
+
const cleanReason = (reason.split("\n")[0] ?? "checkpoint").split("").filter((ch) => ch.charCodeAt(0) >= 32).join("").slice(0, 100);
|
|
7704
|
+
const message = `wip(story-${storyKey}): ${cleanReason}`;
|
|
7705
|
+
try {
|
|
7706
|
+
execSync(`git commit --no-verify -m ${JSON.stringify(message)}`, {
|
|
7707
|
+
cwd: workingDir,
|
|
7708
|
+
stdio: [
|
|
7709
|
+
"ignore",
|
|
7710
|
+
"pipe",
|
|
7711
|
+
"pipe"
|
|
7712
|
+
],
|
|
7713
|
+
timeout: 6e4
|
|
7714
|
+
});
|
|
7715
|
+
} catch (err) {
|
|
7716
|
+
const stderr = err instanceof Error && "stderr" in err ? String(err.stderr ?? err.message) : err instanceof Error ? err.message : String(err);
|
|
7717
|
+
return {
|
|
7718
|
+
status: "failed",
|
|
7719
|
+
stderr: `git commit --no-verify failed: ${stderr}`
|
|
7720
|
+
};
|
|
7721
|
+
}
|
|
7722
|
+
let sha = "";
|
|
7723
|
+
try {
|
|
7724
|
+
sha = execSync("git rev-parse HEAD", {
|
|
7725
|
+
cwd: workingDir,
|
|
7726
|
+
encoding: "utf-8",
|
|
7727
|
+
stdio: [
|
|
7728
|
+
"ignore",
|
|
7729
|
+
"pipe",
|
|
7730
|
+
"pipe"
|
|
7731
|
+
],
|
|
7732
|
+
timeout: 5e3
|
|
7733
|
+
}).trim();
|
|
7734
|
+
} catch {}
|
|
7735
|
+
logger$20.info({
|
|
7736
|
+
storyKey,
|
|
7737
|
+
sha,
|
|
7738
|
+
reason: cleanReason
|
|
7739
|
+
}, "checkpointStoryWorktree: committed recovery checkpoint");
|
|
7740
|
+
return {
|
|
7741
|
+
status: "committed",
|
|
7742
|
+
sha
|
|
7743
|
+
};
|
|
7744
|
+
}
|
|
7745
|
+
/**
|
|
7552
7746
|
* Check whether the repo at `cwd` has at least one commit (HEAD resolves).
|
|
7553
7747
|
* Returns false for fresh repos with no commits, avoiding `fatal: bad revision 'HEAD'`.
|
|
7554
7748
|
* Synchronous (execSync) to keep it simple — this is a fast local check.
|
|
@@ -12562,6 +12756,48 @@ var CostGovernanceChecker = class {
|
|
|
12562
12756
|
}
|
|
12563
12757
|
};
|
|
12564
12758
|
|
|
12759
|
+
//#endregion
|
|
12760
|
+
//#region src/modules/implementation-orchestrator/dispatch-telemetry-aggregation.ts
|
|
12761
|
+
/**
|
|
12762
|
+
* Aggregates turn counts and token usage across an array of dispatch records.
|
|
12763
|
+
*
|
|
12764
|
+
* Returns an object with `total_turns` and/or `total_tokens` populated only
|
|
12765
|
+
* when at least one record carries the corresponding telemetry:
|
|
12766
|
+
* - If NO record has `turns` data → `total_turns` is absent.
|
|
12767
|
+
* - If NO record has `tokens` data → `total_tokens` is absent.
|
|
12768
|
+
* - If SOME records have turns/tokens and some don't, the available data is
|
|
12769
|
+
* summed; records without the field do not contribute zero.
|
|
12770
|
+
*
|
|
12771
|
+
* Absence MUST NOT be treated as zero by consumers — use `?? null` at call
|
|
12772
|
+
* sites per the `PerStoryState.total_turns` / `total_tokens` semantics.
|
|
12773
|
+
*
|
|
12774
|
+
* @param dispatchRecords - Array of per-dispatch records for one story.
|
|
12775
|
+
* Pass `_storyAgents.get(storyKey) ?? []` from the orchestrator. In the
|
|
12776
|
+
* current implementation those records don't carry token/turn data, so
|
|
12777
|
+
* the result is `{}` — this is the documented known gap.
|
|
12778
|
+
* @returns Partial telemetry aggregate: `{}` when no data, populated when present.
|
|
12779
|
+
*/
|
|
12780
|
+
function aggregateStoryDispatchTelemetry(dispatchRecords) {
|
|
12781
|
+
if (dispatchRecords.length === 0) return {};
|
|
12782
|
+
let turnsSum;
|
|
12783
|
+
let tokensInput;
|
|
12784
|
+
let tokensOutput;
|
|
12785
|
+
for (const record of dispatchRecords) {
|
|
12786
|
+
if (record.turns !== void 0) turnsSum = (turnsSum ?? 0) + record.turns;
|
|
12787
|
+
if (record.tokens !== void 0) {
|
|
12788
|
+
tokensInput = (tokensInput ?? 0) + record.tokens.input;
|
|
12789
|
+
tokensOutput = (tokensOutput ?? 0) + record.tokens.output;
|
|
12790
|
+
}
|
|
12791
|
+
}
|
|
12792
|
+
const result = {};
|
|
12793
|
+
if (turnsSum !== void 0) result.total_turns = turnsSum;
|
|
12794
|
+
if (tokensInput !== void 0 && tokensOutput !== void 0) result.total_tokens = {
|
|
12795
|
+
input: tokensInput,
|
|
12796
|
+
output: tokensOutput
|
|
12797
|
+
};
|
|
12798
|
+
return result;
|
|
12799
|
+
}
|
|
12800
|
+
|
|
12565
12801
|
//#endregion
|
|
12566
12802
|
//#region src/modules/work-graph/epic-ingester.ts
|
|
12567
12803
|
var EpicIngester = class {
|
|
@@ -13545,6 +13781,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
13545
13781
|
const _phaseEndMs = new Map();
|
|
13546
13782
|
const _storyDispatches = new Map();
|
|
13547
13783
|
const _storyAgents = new Map();
|
|
13784
|
+
const _storyWorktrees = new Map();
|
|
13548
13785
|
const _storyRetryCount = new Map();
|
|
13549
13786
|
let _completedDispatches = 0;
|
|
13550
13787
|
let _maxConcurrentActual = 0;
|
|
@@ -13554,6 +13791,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
13554
13791
|
const _costChecker = new CostGovernanceChecker();
|
|
13555
13792
|
let _costWarningEmitted = false;
|
|
13556
13793
|
let _budgetExhausted = false;
|
|
13794
|
+
let _authFailureHalted = false;
|
|
13557
13795
|
let _shutdownRequested = false;
|
|
13558
13796
|
let _inFlightCount = 0;
|
|
13559
13797
|
let _drainResolve = null;
|
|
@@ -13860,6 +14098,38 @@ function createImplementationOrchestrator(deps) {
|
|
|
13860
14098
|
* diagnosis to the decision store (Story 22-3).
|
|
13861
14099
|
*/
|
|
13862
14100
|
async function emitEscalation(payload) {
|
|
14101
|
+
const escalationWorktree = _storyWorktrees.get(payload.storyKey);
|
|
14102
|
+
if (escalationWorktree !== void 0) {
|
|
14103
|
+
const cp = await checkpointStoryWorktree(payload.storyKey, `escalation: ${payload.escalationReason ?? payload.lastVerdict}`, escalationWorktree);
|
|
14104
|
+
if (cp.status === "committed") {
|
|
14105
|
+
logger$27.info({
|
|
14106
|
+
storyKey: payload.storyKey,
|
|
14107
|
+
sha: cp.sha
|
|
14108
|
+
}, "escalation checkpoint: uncommitted worktree state preserved on story branch");
|
|
14109
|
+
if (runManifest !== null && cp.sha) runManifest.patchStoryState(payload.storyKey, { checkpoint_sha: cp.sha }).catch((err) => logger$27.warn({
|
|
14110
|
+
err,
|
|
14111
|
+
storyKey: payload.storyKey
|
|
14112
|
+
}, "patchStoryState(checkpoint_sha, escalation) failed — pipeline continues"));
|
|
14113
|
+
} else if (cp.status === "failed") logger$27.warn({
|
|
14114
|
+
storyKey: payload.storyKey,
|
|
14115
|
+
stderr: cp.stderr.slice(0, 500)
|
|
14116
|
+
}, "escalation checkpoint failed — worktree state remains uncommitted (inspect before any cleanup)");
|
|
14117
|
+
}
|
|
14118
|
+
if (escalationWorktree !== void 0 && projectRoot !== void 0) {
|
|
14119
|
+
const leakedFiles = detectWorkOutsideWorktree(escalationWorktree, projectRoot, checkGitDiffFiles);
|
|
14120
|
+
if (leakedFiles.length > 0) {
|
|
14121
|
+
const leakMsg = `PARENT-TREE LEAK: the MAIN checkout at ${projectRoot} carries ${String(leakedFiles.length)} uncommitted change(s) during this story's escalation (e.g. ${leakedFiles.slice(0, 10).join(", ")}). Story output may have landed OUTSIDE the worktree — inspect \`git -C ${projectRoot} status\` BEFORE any cleanup; reconcile-from-disk inspects the branch, not main, and will not see these files.`;
|
|
14122
|
+
payload.issues = [...payload.issues, leakMsg];
|
|
14123
|
+
eventBus.emit("orchestrator:story-warn", {
|
|
14124
|
+
storyKey: payload.storyKey,
|
|
14125
|
+
msg: leakMsg
|
|
14126
|
+
});
|
|
14127
|
+
logger$27.warn({
|
|
14128
|
+
storyKey: payload.storyKey,
|
|
14129
|
+
leakedFileCount: leakedFiles.length
|
|
14130
|
+
}, "escalation parent-tree leak detected");
|
|
14131
|
+
}
|
|
14132
|
+
}
|
|
13863
14133
|
const diagnosis = generateEscalationDiagnosis(payload.issues, payload.reviewCycles, payload.lastVerdict);
|
|
13864
14134
|
eventBus.emit("orchestrator:story-escalated", {
|
|
13865
14135
|
...payload,
|
|
@@ -14173,6 +14443,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14173
14443
|
if (!noWorktree && _worktreeManager !== void 0 && projectRoot !== void 0) {
|
|
14174
14444
|
const wt = await _worktreeManager.createWorktree(storyKey);
|
|
14175
14445
|
effectiveProjectRoot = wt.worktreePath;
|
|
14446
|
+
_storyWorktrees.set(storyKey, wt.worktreePath);
|
|
14176
14447
|
}
|
|
14177
14448
|
let _capturedStoryTitle;
|
|
14178
14449
|
await waitIfPaused();
|
|
@@ -14335,6 +14606,20 @@ function createImplementationOrchestrator(deps) {
|
|
|
14335
14606
|
completedAt: new Date().toISOString()
|
|
14336
14607
|
});
|
|
14337
14608
|
await writeStoryMetricsBestEffort(storyKey, "failed", 0);
|
|
14609
|
+
const authSignature = createResult.error === "auth-failure" ? createResult.details ?? "auth-failure" : detectClaudeAuthFailure(errMsg);
|
|
14610
|
+
if (authSignature !== null) {
|
|
14611
|
+
const authDetail = createResult.details ?? errMsg;
|
|
14612
|
+
await emitEscalation({
|
|
14613
|
+
storyKey,
|
|
14614
|
+
lastVerdict: "auth-failure",
|
|
14615
|
+
reviewCycles: 0,
|
|
14616
|
+
issues: [authDetail, CLAUDE_AUTH_FAILURE_HINT],
|
|
14617
|
+
escalationReason: "auth-failure"
|
|
14618
|
+
});
|
|
14619
|
+
await triggerAuthFailureHalt(storyKey, authSignature.slice(0, 200));
|
|
14620
|
+
await persistState();
|
|
14621
|
+
return;
|
|
14622
|
+
}
|
|
14338
14623
|
const codexHint = detectCodexSandboxBlock(errMsg);
|
|
14339
14624
|
await emitEscalation({
|
|
14340
14625
|
storyKey,
|
|
@@ -14902,6 +15187,10 @@ function createImplementationOrchestrator(deps) {
|
|
|
14902
15187
|
]
|
|
14903
15188
|
}).trim();
|
|
14904
15189
|
} catch {}
|
|
15190
|
+
if (baselineHeadSha !== void 0 && runManifest !== null) runManifest.patchStoryState(storyKey, { baseline_sha: baselineHeadSha }).catch((err) => logger$27.warn({
|
|
15191
|
+
err,
|
|
15192
|
+
storyKey
|
|
15193
|
+
}, "patchStoryState(baseline_sha) failed — pipeline continues"));
|
|
14905
15194
|
try {
|
|
14906
15195
|
let storyContentForAnalysis = "";
|
|
14907
15196
|
try {
|
|
@@ -15282,6 +15571,19 @@ function createImplementationOrchestrator(deps) {
|
|
|
15282
15571
|
completedAt: new Date().toISOString()
|
|
15283
15572
|
});
|
|
15284
15573
|
await writeStoryMetricsBestEffort(storyKey, "failed", 0);
|
|
15574
|
+
const devAuthSignature = detectClaudeAuthFailure(errMsg);
|
|
15575
|
+
if (devAuthSignature !== null) {
|
|
15576
|
+
await emitEscalation({
|
|
15577
|
+
storyKey,
|
|
15578
|
+
lastVerdict: "auth-failure",
|
|
15579
|
+
reviewCycles: 0,
|
|
15580
|
+
issues: [errMsg, CLAUDE_AUTH_FAILURE_HINT],
|
|
15581
|
+
escalationReason: "auth-failure"
|
|
15582
|
+
});
|
|
15583
|
+
await triggerAuthFailureHalt(storyKey, devAuthSignature);
|
|
15584
|
+
await persistState();
|
|
15585
|
+
return;
|
|
15586
|
+
}
|
|
15285
15587
|
await emitEscalation({
|
|
15286
15588
|
storyKey,
|
|
15287
15589
|
lastVerdict: "dev-story-exception",
|
|
@@ -15360,6 +15662,49 @@ function createImplementationOrchestrator(deps) {
|
|
|
15360
15662
|
}
|
|
15361
15663
|
}
|
|
15362
15664
|
}
|
|
15665
|
+
let _devOutputCommitHookFailure;
|
|
15666
|
+
const _commitFirstEligible = !noWorktree && _worktreeManager !== void 0 && effectiveProjectRoot !== void 0 && effectiveProjectRoot !== projectRoot;
|
|
15667
|
+
if (_commitFirstEligible && effectiveProjectRoot !== void 0) {
|
|
15668
|
+
const dirtyNow = await getGitChangedFiles(effectiveProjectRoot);
|
|
15669
|
+
if (dirtyNow.length > 0) if (devStoryWasSuccess) {
|
|
15670
|
+
const earlyCommit = await commitDevStoryOutput(storyKey, _capturedStoryTitle, dirtyNow, effectiveProjectRoot);
|
|
15671
|
+
if (earlyCommit.status === "committed") {
|
|
15672
|
+
logger$27.info({
|
|
15673
|
+
storyKey,
|
|
15674
|
+
sha: earlyCommit.sha,
|
|
15675
|
+
fileCount: earlyCommit.filesStaged.length
|
|
15676
|
+
}, "commit-first: dev-story output committed to story branch");
|
|
15677
|
+
if (runManifest !== null && earlyCommit.sha) runManifest.patchStoryState(storyKey, { commit_sha: earlyCommit.sha }).catch((err) => logger$27.warn({
|
|
15678
|
+
err,
|
|
15679
|
+
storyKey
|
|
15680
|
+
}, "patchStoryState(commit_sha, commit-first) failed — pipeline continues"));
|
|
15681
|
+
} else if (earlyCommit.status === "failed") {
|
|
15682
|
+
_devOutputCommitHookFailure = earlyCommit.stderr;
|
|
15683
|
+
const cp = await checkpointStoryWorktree(storyKey, "dev-story output (deliverable commit rejected by hooks)", effectiveProjectRoot);
|
|
15684
|
+
logger$27.warn({
|
|
15685
|
+
storyKey,
|
|
15686
|
+
checkpoint: cp.status,
|
|
15687
|
+
hookStderr: earlyCommit.stderr.slice(0, 500)
|
|
15688
|
+
}, "commit-first: hooks rejected feat commit — work preserved as wip checkpoint");
|
|
15689
|
+
if (cp.status === "committed" && runManifest !== null && cp.sha) runManifest.patchStoryState(storyKey, { checkpoint_sha: cp.sha }).catch((err) => logger$27.warn({
|
|
15690
|
+
err,
|
|
15691
|
+
storyKey
|
|
15692
|
+
}, "patchStoryState(checkpoint_sha) failed — pipeline continues"));
|
|
15693
|
+
}
|
|
15694
|
+
} else {
|
|
15695
|
+
const cp = await checkpointStoryWorktree(storyKey, "dev-story partial output", effectiveProjectRoot);
|
|
15696
|
+
if (cp.status === "committed") {
|
|
15697
|
+
logger$27.info({
|
|
15698
|
+
storyKey,
|
|
15699
|
+
sha: cp.sha
|
|
15700
|
+
}, "commit-first: partial dev-story output checkpointed");
|
|
15701
|
+
if (runManifest !== null && cp.sha) runManifest.patchStoryState(storyKey, { checkpoint_sha: cp.sha }).catch((err) => logger$27.warn({
|
|
15702
|
+
err,
|
|
15703
|
+
storyKey
|
|
15704
|
+
}, "patchStoryState(checkpoint_sha) failed — pipeline continues"));
|
|
15705
|
+
}
|
|
15706
|
+
}
|
|
15707
|
+
}
|
|
15363
15708
|
endPhase(storyKey, "dev-story", devStoryModel);
|
|
15364
15709
|
let _buildPassed = false;
|
|
15365
15710
|
{
|
|
@@ -15871,6 +16216,19 @@ function createImplementationOrchestrator(deps) {
|
|
|
15871
16216
|
}
|
|
15872
16217
|
}
|
|
15873
16218
|
if (!shouldFallThroughToComplete) {
|
|
16219
|
+
if (effectiveProjectRoot !== void 0 && effectiveProjectRoot !== projectRoot) {
|
|
16220
|
+
const cp = await checkpointStoryWorktree(storyKey, `verification-failed: ${verificationFailReason ?? "tier-a-fail"}`, effectiveProjectRoot);
|
|
16221
|
+
if (cp.status === "committed") {
|
|
16222
|
+
logger$27.info({
|
|
16223
|
+
storyKey,
|
|
16224
|
+
sha: cp.sha
|
|
16225
|
+
}, "verification-failed checkpoint: uncommitted worktree state preserved on story branch");
|
|
16226
|
+
if (runManifest !== null && cp.sha) runManifest.patchStoryState(storyKey, { checkpoint_sha: cp.sha }).catch((err) => logger$27.warn({
|
|
16227
|
+
err,
|
|
16228
|
+
storyKey
|
|
16229
|
+
}, "patchStoryState(checkpoint_sha, verification-failed) failed — pipeline continues"));
|
|
16230
|
+
}
|
|
16231
|
+
}
|
|
15874
16232
|
updateStory(storyKey, {
|
|
15875
16233
|
phase: "VERIFICATION_FAILED",
|
|
15876
16234
|
completedAt: new Date().toISOString()
|
|
@@ -15915,6 +16273,242 @@ function createImplementationOrchestrator(deps) {
|
|
|
15915
16273
|
await persistState();
|
|
15916
16274
|
return "completed";
|
|
15917
16275
|
}
|
|
16276
|
+
async function finalizeStory(completedReviewCycles) {
|
|
16277
|
+
if (!noWorktree && _worktreeManager !== void 0 && _orchestratorStartBranch !== void 0 && projectRoot !== void 0) {
|
|
16278
|
+
const branchName = `${BRANCH_PREFIX}${storyKey}`;
|
|
16279
|
+
if (effectiveProjectRoot !== void 0) {
|
|
16280
|
+
const dirty = await getGitChangedFiles(effectiveProjectRoot);
|
|
16281
|
+
const commitResult = await commitDevStoryOutput(storyKey, _capturedStoryTitle, dirty, effectiveProjectRoot);
|
|
16282
|
+
if (commitResult.status === "no-changes") {
|
|
16283
|
+
if (_devOutputCommitHookFailure !== void 0) {
|
|
16284
|
+
logger$27.error({
|
|
16285
|
+
storyKey,
|
|
16286
|
+
stderr: _devOutputCommitHookFailure
|
|
16287
|
+
}, "deliverable commit was rejected by hooks at dev-story end and was never resolved — escalating");
|
|
16288
|
+
updateStory(storyKey, {
|
|
16289
|
+
phase: "ESCALATED",
|
|
16290
|
+
error: "dev-story-commit-failed",
|
|
16291
|
+
completedAt: new Date().toISOString()
|
|
16292
|
+
});
|
|
16293
|
+
await emitEscalation({
|
|
16294
|
+
storyKey,
|
|
16295
|
+
lastVerdict: "dev-story-commit-failed",
|
|
16296
|
+
reviewCycles: completedReviewCycles,
|
|
16297
|
+
issues: [`substrate auto-commit was rejected by pre-commit hooks at dev-story end and the rejection was never resolved: ${_devOutputCommitHookFailure}`, "The work IS preserved as a wip(story-…) checkpoint on the story branch (hooks bypassed) — it was deliberately not merged."]
|
|
16298
|
+
});
|
|
16299
|
+
await persistState();
|
|
16300
|
+
return "terminal";
|
|
16301
|
+
}
|
|
16302
|
+
let branchAdvancedSinceBaseline = false;
|
|
16303
|
+
if (baselineHeadSha) try {
|
|
16304
|
+
const headNow = execSync("git rev-parse HEAD", {
|
|
16305
|
+
cwd: effectiveProjectRoot,
|
|
16306
|
+
encoding: "utf-8",
|
|
16307
|
+
stdio: [
|
|
16308
|
+
"ignore",
|
|
16309
|
+
"pipe",
|
|
16310
|
+
"pipe"
|
|
16311
|
+
],
|
|
16312
|
+
timeout: 5e3
|
|
16313
|
+
}).trim();
|
|
16314
|
+
branchAdvancedSinceBaseline = headNow !== baselineHeadSha;
|
|
16315
|
+
} catch {}
|
|
16316
|
+
if (!branchAdvancedSinceBaseline) {
|
|
16317
|
+
logger$27.warn({
|
|
16318
|
+
storyKey,
|
|
16319
|
+
reason: commitResult.reason
|
|
16320
|
+
}, "dev-story produced no committable changes — escalating instead of running merge-to-main on an unchanged branch");
|
|
16321
|
+
updateStory(storyKey, {
|
|
16322
|
+
phase: "ESCALATED",
|
|
16323
|
+
error: `dev-story-no-commit: ${commitResult.reason}`,
|
|
16324
|
+
completedAt: new Date().toISOString()
|
|
16325
|
+
});
|
|
16326
|
+
await emitEscalation({
|
|
16327
|
+
storyKey,
|
|
16328
|
+
lastVerdict: "dev-story-no-commit",
|
|
16329
|
+
reviewCycles: completedReviewCycles,
|
|
16330
|
+
issues: [`dev-story phase reached SHIP_IT but produced no committable changes (reason: ${commitResult.reason})`]
|
|
16331
|
+
});
|
|
16332
|
+
await persistState();
|
|
16333
|
+
return "terminal";
|
|
16334
|
+
}
|
|
16335
|
+
logger$27.info({ storyKey }, "working tree clean at finalize but branch already advanced (commit-first) — proceeding to merge");
|
|
16336
|
+
}
|
|
16337
|
+
if (commitResult.status === "failed") {
|
|
16338
|
+
logger$27.error({
|
|
16339
|
+
storyKey,
|
|
16340
|
+
stderr: commitResult.stderr
|
|
16341
|
+
}, "substrate auto-commit failed — escalating story");
|
|
16342
|
+
updateStory(storyKey, {
|
|
16343
|
+
phase: "ESCALATED",
|
|
16344
|
+
error: "dev-story-commit-failed",
|
|
16345
|
+
completedAt: new Date().toISOString()
|
|
16346
|
+
});
|
|
16347
|
+
await emitEscalation({
|
|
16348
|
+
storyKey,
|
|
16349
|
+
lastVerdict: "dev-story-commit-failed",
|
|
16350
|
+
reviewCycles: completedReviewCycles,
|
|
16351
|
+
issues: [`substrate auto-commit failed: ${commitResult.stderr}`]
|
|
16352
|
+
});
|
|
16353
|
+
await persistState();
|
|
16354
|
+
return "terminal";
|
|
16355
|
+
}
|
|
16356
|
+
let finalizeCommitSha;
|
|
16357
|
+
if (commitResult.status === "committed") {
|
|
16358
|
+
finalizeCommitSha = commitResult.sha || void 0;
|
|
16359
|
+
logger$27.info({
|
|
16360
|
+
storyKey,
|
|
16361
|
+
sha: commitResult.sha,
|
|
16362
|
+
fileCount: commitResult.filesStaged.length
|
|
16363
|
+
}, "substrate auto-committed dev-story output before merge-to-main");
|
|
16364
|
+
} else try {
|
|
16365
|
+
finalizeCommitSha = execSync("git rev-parse HEAD", {
|
|
16366
|
+
cwd: effectiveProjectRoot,
|
|
16367
|
+
encoding: "utf-8",
|
|
16368
|
+
stdio: [
|
|
16369
|
+
"ignore",
|
|
16370
|
+
"pipe",
|
|
16371
|
+
"pipe"
|
|
16372
|
+
],
|
|
16373
|
+
timeout: 5e3
|
|
16374
|
+
}).trim();
|
|
16375
|
+
} catch {}
|
|
16376
|
+
if (runManifest !== null && finalizeCommitSha) {
|
|
16377
|
+
const statePatch = { commit_sha: finalizeCommitSha };
|
|
16378
|
+
if (storyFilePath !== void 0) try {
|
|
16379
|
+
Object.assign(statePatch, captureReconstructionInput(storyFilePath, storyKey, runManifest.baseDir, runManifest.runId, effectiveProjectRoot));
|
|
16380
|
+
} catch (inputErr) {
|
|
16381
|
+
logger$27.warn({
|
|
16382
|
+
err: inputErr,
|
|
16383
|
+
storyKey
|
|
16384
|
+
}, "reconstruction phase-input capture failed — pipeline continues (commit_sha still recorded)");
|
|
16385
|
+
}
|
|
16386
|
+
try {
|
|
16387
|
+
const dispatchTelemetry = aggregateStoryDispatchTelemetry(_storyAgents.get(storyKey) ?? []);
|
|
16388
|
+
if (dispatchTelemetry.total_turns !== void 0) statePatch.total_turns = dispatchTelemetry.total_turns;
|
|
16389
|
+
if (dispatchTelemetry.total_tokens !== void 0) statePatch.total_tokens = dispatchTelemetry.total_tokens;
|
|
16390
|
+
} catch (telemetryErr) {
|
|
16391
|
+
logger$27.warn({
|
|
16392
|
+
err: telemetryErr,
|
|
16393
|
+
storyKey
|
|
16394
|
+
}, "aggregateStoryDispatchTelemetry failed — pipeline continues (commit_sha still recorded)");
|
|
16395
|
+
}
|
|
16396
|
+
runManifest.patchStoryState(storyKey, statePatch).catch((err) => logger$27.warn({
|
|
16397
|
+
err,
|
|
16398
|
+
storyKey
|
|
16399
|
+
}, "patchStoryState(commit_sha/phase-input/telemetry) failed — pipeline continues"));
|
|
16400
|
+
}
|
|
16401
|
+
}
|
|
16402
|
+
try {
|
|
16403
|
+
const branchSha = execSync(`git rev-parse ${branchName}`, {
|
|
16404
|
+
cwd: effectiveProjectRoot ?? projectRoot,
|
|
16405
|
+
encoding: "utf-8",
|
|
16406
|
+
stdio: [
|
|
16407
|
+
"ignore",
|
|
16408
|
+
"pipe",
|
|
16409
|
+
"pipe"
|
|
16410
|
+
],
|
|
16411
|
+
timeout: 5e3
|
|
16412
|
+
}).trim();
|
|
16413
|
+
const startSha = execSync(`git rev-parse ${_orchestratorStartBranch}`, {
|
|
16414
|
+
cwd: projectRoot,
|
|
16415
|
+
encoding: "utf-8",
|
|
16416
|
+
stdio: [
|
|
16417
|
+
"ignore",
|
|
16418
|
+
"pipe",
|
|
16419
|
+
"pipe"
|
|
16420
|
+
],
|
|
16421
|
+
timeout: 5e3
|
|
16422
|
+
}).trim();
|
|
16423
|
+
if (branchSha === startSha) {
|
|
16424
|
+
logger$27.warn({
|
|
16425
|
+
storyKey,
|
|
16426
|
+
branchSha,
|
|
16427
|
+
startSha,
|
|
16428
|
+
branchName
|
|
16429
|
+
}, "merge-to-main gate: branch did not advance from start commit — escalating instead of running a no-op merge");
|
|
16430
|
+
updateStory(storyKey, {
|
|
16431
|
+
phase: "ESCALATED",
|
|
16432
|
+
error: "dev-story-no-commit",
|
|
16433
|
+
completedAt: new Date().toISOString()
|
|
16434
|
+
});
|
|
16435
|
+
await emitEscalation({
|
|
16436
|
+
storyKey,
|
|
16437
|
+
lastVerdict: "dev-story-no-commit",
|
|
16438
|
+
reviewCycles: completedReviewCycles,
|
|
16439
|
+
issues: [`branch ${branchName} did not advance past start commit ${startSha} — merge-to-main would be a no-op`]
|
|
16440
|
+
});
|
|
16441
|
+
await persistState();
|
|
16442
|
+
return "terminal";
|
|
16443
|
+
}
|
|
16444
|
+
} catch (gateErr) {
|
|
16445
|
+
logger$27.warn({
|
|
16446
|
+
storyKey,
|
|
16447
|
+
err: gateErr instanceof Error ? gateErr.message : String(gateErr)
|
|
16448
|
+
}, "merge-to-main pre-flight verification failed — proceeding with merge phase");
|
|
16449
|
+
}
|
|
16450
|
+
logger$27.info({
|
|
16451
|
+
storyKey,
|
|
16452
|
+
branchName,
|
|
16453
|
+
startBranch: _orchestratorStartBranch
|
|
16454
|
+
}, "Invoking merge-to-main phase");
|
|
16455
|
+
let mergeResult;
|
|
16456
|
+
try {
|
|
16457
|
+
mergeResult = await enqueueMerge({
|
|
16458
|
+
storyKey,
|
|
16459
|
+
branchName,
|
|
16460
|
+
startBranch: _orchestratorStartBranch,
|
|
16461
|
+
worktreeManager: _worktreeManager,
|
|
16462
|
+
eventBus,
|
|
16463
|
+
projectRoot
|
|
16464
|
+
});
|
|
16465
|
+
} catch (mergeErr) {
|
|
16466
|
+
const errMsg = mergeErr instanceof Error ? mergeErr.message : String(mergeErr);
|
|
16467
|
+
logger$27.error({
|
|
16468
|
+
storyKey,
|
|
16469
|
+
err: mergeErr
|
|
16470
|
+
}, "merge-to-main phase threw unexpectedly — escalating story");
|
|
16471
|
+
updateStory(storyKey, {
|
|
16472
|
+
phase: "ESCALATED",
|
|
16473
|
+
error: `merge-to-main-error: ${errMsg}`,
|
|
16474
|
+
completedAt: new Date().toISOString()
|
|
16475
|
+
});
|
|
16476
|
+
await emitEscalation({
|
|
16477
|
+
storyKey,
|
|
16478
|
+
lastVerdict: "merge-to-main-error",
|
|
16479
|
+
reviewCycles: completedReviewCycles,
|
|
16480
|
+
issues: [`merge-to-main phase threw: ${errMsg}`]
|
|
16481
|
+
});
|
|
16482
|
+
await persistState();
|
|
16483
|
+
return "terminal";
|
|
16484
|
+
}
|
|
16485
|
+
if (!mergeResult.success) {
|
|
16486
|
+
logger$27.warn({
|
|
16487
|
+
storyKey,
|
|
16488
|
+
branchName,
|
|
16489
|
+
conflictingFiles: mergeResult.conflictingFiles
|
|
16490
|
+
}, "merge-to-main conflict — escalating story with merge-conflict-detected");
|
|
16491
|
+
updateStory(storyKey, {
|
|
16492
|
+
phase: "ESCALATED",
|
|
16493
|
+
error: "merge-conflict-detected",
|
|
16494
|
+
completedAt: new Date().toISOString()
|
|
16495
|
+
});
|
|
16496
|
+
await emitEscalation({
|
|
16497
|
+
storyKey,
|
|
16498
|
+
lastVerdict: "merge-conflict-detected",
|
|
16499
|
+
reviewCycles: completedReviewCycles,
|
|
16500
|
+
issues: [`merge conflict in ${mergeResult.conflictingFiles?.length ?? 0} file(s): ${(mergeResult.conflictingFiles ?? []).join(", ")}`]
|
|
16501
|
+
});
|
|
16502
|
+
await persistState();
|
|
16503
|
+
return "terminal";
|
|
16504
|
+
}
|
|
16505
|
+
logger$27.info({
|
|
16506
|
+
storyKey,
|
|
16507
|
+
branchName
|
|
16508
|
+
}, "merge-to-main phase completed successfully");
|
|
16509
|
+
}
|
|
16510
|
+
return "finalized";
|
|
16511
|
+
}
|
|
15918
16512
|
while (keepReviewing) {
|
|
15919
16513
|
await waitIfPaused();
|
|
15920
16514
|
if (_state !== "RUNNING") return;
|
|
@@ -16169,6 +16763,13 @@ function createImplementationOrchestrator(deps) {
|
|
|
16169
16763
|
} catch {}
|
|
16170
16764
|
updateStory(storyKey, { lastVerdict: verdict });
|
|
16171
16765
|
await persistState();
|
|
16766
|
+
if (runManifest !== null) {
|
|
16767
|
+
const persistedVerdict = reviewResult.agentVerdict ?? verdict;
|
|
16768
|
+
runManifest.patchStoryState(storyKey, { verdict: persistedVerdict }).catch((err) => logger$27.warn({
|
|
16769
|
+
err,
|
|
16770
|
+
storyKey
|
|
16771
|
+
}, "patchStoryState(verdict) failed — pipeline continues"));
|
|
16772
|
+
}
|
|
16172
16773
|
{
|
|
16173
16774
|
const totalTokens = reviewResult.tokenUsage ? reviewResult.tokenUsage.input + reviewResult.tokenUsage.output : 0;
|
|
16174
16775
|
const totalTokensK = totalTokens > 0 ? `${Math.round(totalTokens / 1e3)}K` : "0";
|
|
@@ -16309,178 +16910,8 @@ function createImplementationOrchestrator(deps) {
|
|
|
16309
16910
|
error: expansionErr instanceof Error ? expansionErr.message : String(expansionErr)
|
|
16310
16911
|
}, "Test expansion failed — story verdict unchanged");
|
|
16311
16912
|
}
|
|
16312
|
-
|
|
16313
|
-
|
|
16314
|
-
if (effectiveProjectRoot !== void 0) {
|
|
16315
|
-
const dirty = await getGitChangedFiles(effectiveProjectRoot);
|
|
16316
|
-
const commitResult = await commitDevStoryOutput(storyKey, _capturedStoryTitle, dirty, effectiveProjectRoot);
|
|
16317
|
-
if (commitResult.status === "no-changes") {
|
|
16318
|
-
logger$27.warn({
|
|
16319
|
-
storyKey,
|
|
16320
|
-
reason: commitResult.reason
|
|
16321
|
-
}, "dev-story produced no committable changes — escalating instead of running merge-to-main on an unchanged branch");
|
|
16322
|
-
updateStory(storyKey, {
|
|
16323
|
-
phase: "ESCALATED",
|
|
16324
|
-
error: `dev-story-no-commit: ${commitResult.reason}`,
|
|
16325
|
-
completedAt: new Date().toISOString()
|
|
16326
|
-
});
|
|
16327
|
-
await emitEscalation({
|
|
16328
|
-
storyKey,
|
|
16329
|
-
lastVerdict: "dev-story-no-commit",
|
|
16330
|
-
reviewCycles: completedReviewCycles,
|
|
16331
|
-
issues: [`dev-story phase reached SHIP_IT but produced no committable changes (reason: ${commitResult.reason})`]
|
|
16332
|
-
});
|
|
16333
|
-
await persistState();
|
|
16334
|
-
return;
|
|
16335
|
-
}
|
|
16336
|
-
if (commitResult.status === "failed") {
|
|
16337
|
-
logger$27.error({
|
|
16338
|
-
storyKey,
|
|
16339
|
-
stderr: commitResult.stderr
|
|
16340
|
-
}, "substrate auto-commit failed — escalating story");
|
|
16341
|
-
updateStory(storyKey, {
|
|
16342
|
-
phase: "ESCALATED",
|
|
16343
|
-
error: "dev-story-commit-failed",
|
|
16344
|
-
completedAt: new Date().toISOString()
|
|
16345
|
-
});
|
|
16346
|
-
await emitEscalation({
|
|
16347
|
-
storyKey,
|
|
16348
|
-
lastVerdict: "dev-story-commit-failed",
|
|
16349
|
-
reviewCycles: completedReviewCycles,
|
|
16350
|
-
issues: [`substrate auto-commit failed: ${commitResult.stderr}`]
|
|
16351
|
-
});
|
|
16352
|
-
await persistState();
|
|
16353
|
-
return;
|
|
16354
|
-
}
|
|
16355
|
-
logger$27.info({
|
|
16356
|
-
storyKey,
|
|
16357
|
-
sha: commitResult.sha,
|
|
16358
|
-
fileCount: commitResult.filesStaged.length
|
|
16359
|
-
}, "substrate auto-committed dev-story output before merge-to-main");
|
|
16360
|
-
if (runManifest !== null && commitResult.sha) {
|
|
16361
|
-
const statePatch = { commit_sha: commitResult.sha };
|
|
16362
|
-
if (storyFilePath !== void 0) try {
|
|
16363
|
-
Object.assign(statePatch, captureReconstructionInput(storyFilePath, storyKey, runManifest.baseDir, runManifest.runId, effectiveProjectRoot));
|
|
16364
|
-
} catch (inputErr) {
|
|
16365
|
-
logger$27.warn({
|
|
16366
|
-
err: inputErr,
|
|
16367
|
-
storyKey
|
|
16368
|
-
}, "reconstruction phase-input capture failed — pipeline continues (commit_sha still recorded)");
|
|
16369
|
-
}
|
|
16370
|
-
runManifest.patchStoryState(storyKey, statePatch).catch((err) => logger$27.warn({
|
|
16371
|
-
err,
|
|
16372
|
-
storyKey
|
|
16373
|
-
}, "patchStoryState(commit_sha/phase-input) failed — pipeline continues"));
|
|
16374
|
-
}
|
|
16375
|
-
}
|
|
16376
|
-
try {
|
|
16377
|
-
const branchSha = execSync(`git rev-parse ${branchName}`, {
|
|
16378
|
-
cwd: effectiveProjectRoot ?? projectRoot,
|
|
16379
|
-
encoding: "utf-8",
|
|
16380
|
-
stdio: [
|
|
16381
|
-
"ignore",
|
|
16382
|
-
"pipe",
|
|
16383
|
-
"pipe"
|
|
16384
|
-
],
|
|
16385
|
-
timeout: 5e3
|
|
16386
|
-
}).trim();
|
|
16387
|
-
const startSha = execSync(`git rev-parse ${_orchestratorStartBranch}`, {
|
|
16388
|
-
cwd: projectRoot,
|
|
16389
|
-
encoding: "utf-8",
|
|
16390
|
-
stdio: [
|
|
16391
|
-
"ignore",
|
|
16392
|
-
"pipe",
|
|
16393
|
-
"pipe"
|
|
16394
|
-
],
|
|
16395
|
-
timeout: 5e3
|
|
16396
|
-
}).trim();
|
|
16397
|
-
if (branchSha === startSha) {
|
|
16398
|
-
logger$27.warn({
|
|
16399
|
-
storyKey,
|
|
16400
|
-
branchSha,
|
|
16401
|
-
startSha,
|
|
16402
|
-
branchName
|
|
16403
|
-
}, "merge-to-main gate: branch did not advance from start commit — escalating instead of running a no-op merge");
|
|
16404
|
-
updateStory(storyKey, {
|
|
16405
|
-
phase: "ESCALATED",
|
|
16406
|
-
error: "dev-story-no-commit",
|
|
16407
|
-
completedAt: new Date().toISOString()
|
|
16408
|
-
});
|
|
16409
|
-
await emitEscalation({
|
|
16410
|
-
storyKey,
|
|
16411
|
-
lastVerdict: "dev-story-no-commit",
|
|
16412
|
-
reviewCycles: completedReviewCycles,
|
|
16413
|
-
issues: [`branch ${branchName} did not advance past start commit ${startSha} — merge-to-main would be a no-op`]
|
|
16414
|
-
});
|
|
16415
|
-
await persistState();
|
|
16416
|
-
return;
|
|
16417
|
-
}
|
|
16418
|
-
} catch (gateErr) {
|
|
16419
|
-
logger$27.warn({
|
|
16420
|
-
storyKey,
|
|
16421
|
-
err: gateErr instanceof Error ? gateErr.message : String(gateErr)
|
|
16422
|
-
}, "merge-to-main pre-flight verification failed — proceeding with merge phase");
|
|
16423
|
-
}
|
|
16424
|
-
logger$27.info({
|
|
16425
|
-
storyKey,
|
|
16426
|
-
branchName,
|
|
16427
|
-
startBranch: _orchestratorStartBranch
|
|
16428
|
-
}, "Invoking merge-to-main phase");
|
|
16429
|
-
let mergeResult;
|
|
16430
|
-
try {
|
|
16431
|
-
mergeResult = await enqueueMerge({
|
|
16432
|
-
storyKey,
|
|
16433
|
-
branchName,
|
|
16434
|
-
startBranch: _orchestratorStartBranch,
|
|
16435
|
-
worktreeManager: _worktreeManager,
|
|
16436
|
-
eventBus,
|
|
16437
|
-
projectRoot
|
|
16438
|
-
});
|
|
16439
|
-
} catch (mergeErr) {
|
|
16440
|
-
const errMsg = mergeErr instanceof Error ? mergeErr.message : String(mergeErr);
|
|
16441
|
-
logger$27.error({
|
|
16442
|
-
storyKey,
|
|
16443
|
-
err: mergeErr
|
|
16444
|
-
}, "merge-to-main phase threw unexpectedly — escalating story");
|
|
16445
|
-
updateStory(storyKey, {
|
|
16446
|
-
phase: "ESCALATED",
|
|
16447
|
-
error: `merge-to-main-error: ${errMsg}`,
|
|
16448
|
-
completedAt: new Date().toISOString()
|
|
16449
|
-
});
|
|
16450
|
-
await emitEscalation({
|
|
16451
|
-
storyKey,
|
|
16452
|
-
lastVerdict: "merge-to-main-error",
|
|
16453
|
-
reviewCycles: completedReviewCycles,
|
|
16454
|
-
issues: [`merge-to-main phase threw: ${errMsg}`]
|
|
16455
|
-
});
|
|
16456
|
-
await persistState();
|
|
16457
|
-
return;
|
|
16458
|
-
}
|
|
16459
|
-
if (!mergeResult.success) {
|
|
16460
|
-
logger$27.warn({
|
|
16461
|
-
storyKey,
|
|
16462
|
-
branchName,
|
|
16463
|
-
conflictingFiles: mergeResult.conflictingFiles
|
|
16464
|
-
}, "merge-to-main conflict — escalating story with merge-conflict-detected");
|
|
16465
|
-
updateStory(storyKey, {
|
|
16466
|
-
phase: "ESCALATED",
|
|
16467
|
-
error: "merge-conflict-detected",
|
|
16468
|
-
completedAt: new Date().toISOString()
|
|
16469
|
-
});
|
|
16470
|
-
await emitEscalation({
|
|
16471
|
-
storyKey,
|
|
16472
|
-
lastVerdict: "merge-conflict-detected",
|
|
16473
|
-
reviewCycles: completedReviewCycles,
|
|
16474
|
-
issues: [`merge conflict in ${mergeResult.conflictingFiles?.length ?? 0} file(s): ${(mergeResult.conflictingFiles ?? []).join(", ")}`]
|
|
16475
|
-
});
|
|
16476
|
-
await persistState();
|
|
16477
|
-
return;
|
|
16478
|
-
}
|
|
16479
|
-
logger$27.info({
|
|
16480
|
-
storyKey,
|
|
16481
|
-
branchName
|
|
16482
|
-
}, "merge-to-main phase completed successfully");
|
|
16483
|
-
}
|
|
16913
|
+
const finalizeOutcome = await finalizeStory(completedReviewCycles);
|
|
16914
|
+
if (finalizeOutcome === "terminal") return;
|
|
16484
16915
|
keepReviewing = false;
|
|
16485
16916
|
return;
|
|
16486
16917
|
}
|
|
@@ -16607,6 +17038,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16607
17038
|
}
|
|
16608
17039
|
});
|
|
16609
17040
|
if (outcome === "verification-failed") return;
|
|
17041
|
+
if (await finalizeStory(finalReviewCycles) === "terminal") return;
|
|
16610
17042
|
keepReviewing = false;
|
|
16611
17043
|
return;
|
|
16612
17044
|
}
|
|
@@ -16816,6 +17248,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16816
17248
|
}
|
|
16817
17249
|
});
|
|
16818
17250
|
if (outcome === "verification-failed") return;
|
|
17251
|
+
if (await finalizeStory(finalReviewCycles) === "terminal") return;
|
|
16819
17252
|
keepReviewing = false;
|
|
16820
17253
|
return;
|
|
16821
17254
|
}
|
|
@@ -16899,6 +17332,64 @@ function createImplementationOrchestrator(deps) {
|
|
|
16899
17332
|
* @param result - The ceiling check result
|
|
16900
17333
|
* @param manifest - The current run manifest data
|
|
16901
17334
|
*/
|
|
17335
|
+
/**
|
|
17336
|
+
* H0.4 (field finding #10): halt the entire run when a dispatch dies on
|
|
17337
|
+
* authentication. Auth failures are environmental, not story-specific —
|
|
17338
|
+
* every subsequent dispatch fails identically, so continuing burns the
|
|
17339
|
+
* whole batch (the field run lost ~25 minutes and two runs to this).
|
|
17340
|
+
* Mirrors handleCeilingExceeded: routes through the Decision Router
|
|
17341
|
+
* (severity fatal → halts under every --halt-on policy), sweeps PENDING
|
|
17342
|
+
* stories to ESCALATED with a named reason, and reuses _budgetExhausted
|
|
17343
|
+
* to stop the dispatch loop.
|
|
17344
|
+
*/
|
|
17345
|
+
async function triggerAuthFailureHalt(triggeredStoryKey, matchedSignature) {
|
|
17346
|
+
if (_authFailureHalted) return;
|
|
17347
|
+
_authFailureHalted = true;
|
|
17348
|
+
_budgetExhausted = true;
|
|
17349
|
+
const runId = config.pipelineRunId ?? "unknown";
|
|
17350
|
+
const reason = `agent authentication failure on story ${triggeredStoryKey} (matched: "${matchedSignature}") — all subsequent dispatches would fail identically`;
|
|
17351
|
+
let haltPolicy = "critical";
|
|
17352
|
+
if (runManifest !== null) try {
|
|
17353
|
+
const manifest = await runManifest.read();
|
|
17354
|
+
haltPolicy = manifest.cli_flags.halt_on ?? "critical";
|
|
17355
|
+
} catch {}
|
|
17356
|
+
const routeResult = routeDecision("auth-failure", haltPolicy);
|
|
17357
|
+
eventBus.emit("decision:halt", {
|
|
17358
|
+
runId,
|
|
17359
|
+
decisionType: "auth-failure",
|
|
17360
|
+
severity: routeResult.severity,
|
|
17361
|
+
reason
|
|
17362
|
+
});
|
|
17363
|
+
await runInteractivePrompt({
|
|
17364
|
+
runId,
|
|
17365
|
+
decisionType: "auth-failure",
|
|
17366
|
+
severity: routeResult.severity,
|
|
17367
|
+
summary: reason,
|
|
17368
|
+
defaultAction: routeResult.defaultAction,
|
|
17369
|
+
choices: ["abort-run"],
|
|
17370
|
+
onHaltSkipped: (payload) => {
|
|
17371
|
+
eventBus.emit("decision:halt-skipped-non-interactive", payload);
|
|
17372
|
+
}
|
|
17373
|
+
}).catch((err) => {
|
|
17374
|
+
logger$27.warn({ err }, "interactive prompt failed during auth-failure halt — halting anyway");
|
|
17375
|
+
});
|
|
17376
|
+
for (const [key, state] of _stories) if (state.phase === "PENDING" && key !== triggeredStoryKey) {
|
|
17377
|
+
updateStory(key, {
|
|
17378
|
+
phase: "ESCALATED",
|
|
17379
|
+
error: "auth-failure-halt",
|
|
17380
|
+
completedAt: new Date().toISOString()
|
|
17381
|
+
});
|
|
17382
|
+
if (runManifest !== null && runManifest !== void 0) runManifest.patchStoryState(key, {
|
|
17383
|
+
status: "escalated",
|
|
17384
|
+
escalation_reason: "auth-failure-halt"
|
|
17385
|
+
}).catch(() => {});
|
|
17386
|
+
}
|
|
17387
|
+
logger$27.error({
|
|
17388
|
+
runId,
|
|
17389
|
+
triggeredStoryKey,
|
|
17390
|
+
matchedSignature
|
|
17391
|
+
}, "RUN HALTED: agent authentication failure — fix credentials and re-run");
|
|
17392
|
+
}
|
|
16902
17393
|
async function handleCeilingExceeded(triggeredStoryKey, remainingInGroup, result, manifest) {
|
|
16903
17394
|
const haltPolicy = manifest.cli_flags.halt_on ?? "critical";
|
|
16904
17395
|
const routeResult = routeDecision("cost-ceiling-exhausted", haltPolicy);
|
|
@@ -47442,7 +47933,7 @@ async function runFullPipeline(options) {
|
|
|
47442
47933
|
*/
|
|
47443
47934
|
async function emitPreDispatchVersionAdvisory(currentVersion) {
|
|
47444
47935
|
if (process.env["SUBSTRATE_NO_UPDATE_CHECK"] === "1") return;
|
|
47445
|
-
const { createVersionManager } = await import("./version-manager-impl-
|
|
47936
|
+
const { createVersionManager } = await import("./version-manager-impl-HJMonRJi.js");
|
|
47446
47937
|
const vm = createVersionManager();
|
|
47447
47938
|
const result = await vm.checkForUpdates(true);
|
|
47448
47939
|
const gap = classifyVersionGap(currentVersion, result.latestVersion);
|
|
@@ -47539,4 +48030,4 @@ function registerRunCommand(program, version = "0.0.0", projectRoot = process.cw
|
|
|
47539
48030
|
|
|
47540
48031
|
//#endregion
|
|
47541
48032
|
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 };
|
|
47542
|
-
//# sourceMappingURL=run-
|
|
48033
|
+
//# sourceMappingURL=run-CRvusFIv.js.map
|