substrate-ai 0.21.6 → 0.21.7
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/cli/index.js +6 -6
- package/dist/{health-HpFVnRU0.js → health-B1UtVXWb.js} +2 -2
- package/dist/{health-Chn5HCft.js → health-CmY5G4PV.js} +2 -2
- package/dist/{interactive-prompt-j4H9HnfF.js → interactive-prompt-CELNI8nZ.js} +2 -2
- package/dist/{manifest-read-D7HcgX21.js → manifest-read-Ce5Y-iNu.js} +273 -2
- package/dist/modules/interactive-prompt/index.js +2 -2
- package/dist/{run-BrltNj0g.js → run-BCrwTBDr.js} +4 -4
- package/dist/{run-BbBSwrqC.js → run-DsjRvAd4.js} +817 -504
- package/package.json +1 -1
|
@@ -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-B1UtVXWb.js";
|
|
2
2
|
import { createLogger } from "./logger-KeHncl-f.js";
|
|
3
3
|
import { TypedEventBusImpl, createEventBus, createTuiApp, isTuiCapable, printNonTtyWarning, sleep } from "./helpers-CElYrONe.js";
|
|
4
4
|
import { ADVISORY_NOTES, BRANCH_PREFIX, 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, createGitWorktreeManager, createPipelineRun, createRequirement, 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-DeyV_vqU.js";
|
|
5
|
-
import { ACCEPTANCE_CONTRACT_PROFILE_PATH, FindingsInjector, JOURNEY_DEFERRALS_PATH, RunManifest, RuntimeProbeListSchema, applyConfigToGraph, computeJourneyCoverage, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, loadAcceptanceContractFromTrustedTree, loadJourneyDeferralsFromTrustedTree, loadJourneyRegistryFromTrustedTree, parseRuntimeProbes, parseStoryFrontmatter, renderFindings, resolveGraphPath, resolveMainRepoRoot, runAcTraceabilityCheck, runStaleVerificationRecovery, summarizeCoverage } from "./manifest-read-
|
|
5
|
+
import { ACCEPTANCE_CONTRACT_PROFILE_PATH, FindingsInjector, JOURNEY_DEFERRALS_PATH, RunManifest, RuntimeProbeListSchema, applyConfigToGraph, computeJourneyCoverage, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, loadAcceptanceContractFromTrustedTree, loadJourneyDeferralsFromTrustedTree, loadJourneyRegistryFromTrustedTree, parseRuntimeProbes, parseStoryFrontmatter, renderFindings, renderSurface, renderVerdictHtml, resolveGraphPath, resolveMainRepoRoot, runAcTraceabilityCheck, runStaleVerificationRecovery, summarizeCoverage } from "./manifest-read-Ce5Y-iNu.js";
|
|
6
6
|
import { WorkGraphRepository, detectCycles } from "./work-graph-repository-DZyJv5pV.js";
|
|
7
7
|
import { deriveExitCode, routeDecision } from "./decision-router-BAPpON_C.js";
|
|
8
|
-
import { runInteractivePrompt } from "./interactive-prompt-
|
|
8
|
+
import { runInteractivePrompt } from "./interactive-prompt-CELNI8nZ.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";
|
|
@@ -17,7 +17,7 @@ import { accessSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathS
|
|
|
17
17
|
import { exec, execFile, execFileSync, execSync, spawn } from "node:child_process";
|
|
18
18
|
import * as path$2 from "node:path";
|
|
19
19
|
import path, { basename as basename$1, dirname as dirname$1, extname as extname$1, isAbsolute, join as join$1, posix, relative, resolve as resolve$1, win32 } from "node:path";
|
|
20
|
-
import { tmpdir } from "node:os";
|
|
20
|
+
import { homedir, tmpdir } from "node:os";
|
|
21
21
|
import { createHash, randomUUID } from "node:crypto";
|
|
22
22
|
import { z } from "zod";
|
|
23
23
|
import { access as access$1, lstat, mkdir as mkdir$1, readFile as readFile$1, readdir as readdir$1, readlink, realpath, rename, stat as stat$1, unlink as unlink$1, writeFile as writeFile$1 } from "node:fs/promises";
|
|
@@ -2476,7 +2476,7 @@ async function runHelpAgent() {
|
|
|
2476
2476
|
|
|
2477
2477
|
//#endregion
|
|
2478
2478
|
//#region src/persistence/dolt-server.ts
|
|
2479
|
-
const logger$
|
|
2479
|
+
const logger$27 = createLogger("dolt-server");
|
|
2480
2480
|
/**
|
|
2481
2481
|
* Start a dolt sql-server for the given project, if Dolt is available and no
|
|
2482
2482
|
* server is already running (socket already exists).
|
|
@@ -2493,7 +2493,7 @@ async function startDoltServer(projectRoot) {
|
|
|
2493
2493
|
if (!existsSync(join$1(stateDir, ".dolt"))) return null;
|
|
2494
2494
|
try {
|
|
2495
2495
|
await access$1(socketPath);
|
|
2496
|
-
logger$
|
|
2496
|
+
logger$27.debug("Dolt socket already exists at %s — using existing server", socketPath);
|
|
2497
2497
|
return null;
|
|
2498
2498
|
} catch {}
|
|
2499
2499
|
try {
|
|
@@ -2502,10 +2502,10 @@ async function startDoltServer(projectRoot) {
|
|
|
2502
2502
|
stdio: "pipe"
|
|
2503
2503
|
});
|
|
2504
2504
|
} catch {
|
|
2505
|
-
logger$
|
|
2505
|
+
logger$27.debug("dolt binary not on PATH — cannot start server");
|
|
2506
2506
|
return null;
|
|
2507
2507
|
}
|
|
2508
|
-
logger$
|
|
2508
|
+
logger$27.debug("Starting dolt sql-server at %s", socketPath);
|
|
2509
2509
|
let proc$1;
|
|
2510
2510
|
try {
|
|
2511
2511
|
proc$1 = spawn("dolt", [
|
|
@@ -2526,26 +2526,26 @@ async function startDoltServer(projectRoot) {
|
|
|
2526
2526
|
detached: false
|
|
2527
2527
|
});
|
|
2528
2528
|
} catch (err) {
|
|
2529
|
-
logger$
|
|
2529
|
+
logger$27.debug("Failed to spawn dolt sql-server: %s", err instanceof Error ? err.message : String(err));
|
|
2530
2530
|
return null;
|
|
2531
2531
|
}
|
|
2532
2532
|
let failed = false;
|
|
2533
2533
|
proc$1.on("error", (err) => {
|
|
2534
|
-
logger$
|
|
2534
|
+
logger$27.debug("dolt sql-server error: %s", err.message);
|
|
2535
2535
|
failed = true;
|
|
2536
2536
|
});
|
|
2537
2537
|
proc$1.on("exit", (code) => {
|
|
2538
|
-
if (code !== null && code !== 0) logger$
|
|
2538
|
+
if (code !== null && code !== 0) logger$27.debug("dolt sql-server exited with code %d", code);
|
|
2539
2539
|
});
|
|
2540
2540
|
proc$1.stderr?.on("data", (chunk) => {
|
|
2541
2541
|
const line = chunk.toString().trim();
|
|
2542
|
-
if (line) logger$
|
|
2542
|
+
if (line) logger$27.debug("dolt-server: %s", line);
|
|
2543
2543
|
});
|
|
2544
2544
|
const deadline = Date.now() + 5e3;
|
|
2545
2545
|
while (Date.now() < deadline && !failed) try {
|
|
2546
2546
|
await access$1(socketPath);
|
|
2547
2547
|
const pid = proc$1.pid ?? 0;
|
|
2548
|
-
logger$
|
|
2548
|
+
logger$27.info("Auto-started dolt sql-server (pid=%d, socket=%s)", pid, socketPath);
|
|
2549
2549
|
let stopped = false;
|
|
2550
2550
|
return {
|
|
2551
2551
|
pid,
|
|
@@ -2553,14 +2553,14 @@ async function startDoltServer(projectRoot) {
|
|
|
2553
2553
|
stop: () => {
|
|
2554
2554
|
if (stopped) return;
|
|
2555
2555
|
stopped = true;
|
|
2556
|
-
logger$
|
|
2556
|
+
logger$27.debug("Stopping dolt sql-server (pid=%d)", pid);
|
|
2557
2557
|
proc$1.kill("SIGTERM");
|
|
2558
2558
|
}
|
|
2559
2559
|
};
|
|
2560
2560
|
} catch {
|
|
2561
2561
|
await new Promise((resolve$6) => setTimeout(resolve$6, 100));
|
|
2562
2562
|
}
|
|
2563
|
-
logger$
|
|
2563
|
+
logger$27.debug("dolt sql-server did not start within 5s — killing");
|
|
2564
2564
|
proc$1.kill("SIGTERM");
|
|
2565
2565
|
return null;
|
|
2566
2566
|
}
|
|
@@ -2630,7 +2630,7 @@ function truncateToTokens(text, maxTokens) {
|
|
|
2630
2630
|
|
|
2631
2631
|
//#endregion
|
|
2632
2632
|
//#region src/modules/context-compiler/context-compiler-impl.ts
|
|
2633
|
-
const logger$
|
|
2633
|
+
const logger$26 = createLogger("context-compiler");
|
|
2634
2634
|
/**
|
|
2635
2635
|
* Fraction of the original token budget that must remain (after required +
|
|
2636
2636
|
* important sections) before an optional section is included.
|
|
@@ -2691,7 +2691,7 @@ var ContextCompilerImpl = class {
|
|
|
2691
2691
|
}
|
|
2692
2692
|
_applyExclusionFilter(text, sectionName) {
|
|
2693
2693
|
for (const excludedPath of this._excludedPaths) if (text.includes(excludedPath)) {
|
|
2694
|
-
logger$
|
|
2694
|
+
logger$26.warn({
|
|
2695
2695
|
sectionName,
|
|
2696
2696
|
excludedPath
|
|
2697
2697
|
}, "ContextCompiler: section excluded — contains path from exclusion list");
|
|
@@ -2749,7 +2749,7 @@ var ContextCompilerImpl = class {
|
|
|
2749
2749
|
includedParts.push(truncated);
|
|
2750
2750
|
remainingBudget -= truncatedTokens;
|
|
2751
2751
|
anyTruncated = true;
|
|
2752
|
-
logger$
|
|
2752
|
+
logger$26.warn({
|
|
2753
2753
|
section: section.name,
|
|
2754
2754
|
originalTokens: tokens,
|
|
2755
2755
|
budgetTokens: truncatedTokens
|
|
@@ -2763,7 +2763,7 @@ var ContextCompilerImpl = class {
|
|
|
2763
2763
|
});
|
|
2764
2764
|
} else {
|
|
2765
2765
|
anyTruncated = true;
|
|
2766
|
-
logger$
|
|
2766
|
+
logger$26.warn({
|
|
2767
2767
|
section: section.name,
|
|
2768
2768
|
tokens
|
|
2769
2769
|
}, "Context compiler: omitted \"important\" section — no budget remaining");
|
|
@@ -2790,7 +2790,7 @@ var ContextCompilerImpl = class {
|
|
|
2790
2790
|
} else {
|
|
2791
2791
|
if (tokens > 0) {
|
|
2792
2792
|
anyTruncated = true;
|
|
2793
|
-
logger$
|
|
2793
|
+
logger$26.warn({
|
|
2794
2794
|
section: section.name,
|
|
2795
2795
|
tokens,
|
|
2796
2796
|
budgetFractionRemaining: budgetFractionRemaining.toFixed(2)
|
|
@@ -2884,8 +2884,8 @@ var GrammarLoader = class {
|
|
|
2884
2884
|
_extensionMap;
|
|
2885
2885
|
_cache = new Map();
|
|
2886
2886
|
_unavailable = false;
|
|
2887
|
-
constructor(logger$
|
|
2888
|
-
this._logger = logger$
|
|
2887
|
+
constructor(logger$28) {
|
|
2888
|
+
this._logger = logger$28;
|
|
2889
2889
|
this._extensionMap = new Map([
|
|
2890
2890
|
[".ts", "tree-sitter-typescript/typescript"],
|
|
2891
2891
|
[".tsx", "tree-sitter-typescript/tsx"],
|
|
@@ -2971,9 +2971,9 @@ const ERR_REPO_MAP_GIT_FAILED = "ERR_REPO_MAP_GIT_FAILED";
|
|
|
2971
2971
|
var SymbolParser = class {
|
|
2972
2972
|
_grammarLoader;
|
|
2973
2973
|
_logger;
|
|
2974
|
-
constructor(grammarLoader, logger$
|
|
2974
|
+
constructor(grammarLoader, logger$28) {
|
|
2975
2975
|
this._grammarLoader = grammarLoader;
|
|
2976
|
-
this._logger = logger$
|
|
2976
|
+
this._logger = logger$28;
|
|
2977
2977
|
}
|
|
2978
2978
|
async parseFile(filePath) {
|
|
2979
2979
|
const ext$2 = extname$1(filePath);
|
|
@@ -3118,9 +3118,9 @@ async function computeFileHash(filePath) {
|
|
|
3118
3118
|
var DoltSymbolRepository = class {
|
|
3119
3119
|
_client;
|
|
3120
3120
|
_logger;
|
|
3121
|
-
constructor(client, logger$
|
|
3121
|
+
constructor(client, logger$28) {
|
|
3122
3122
|
this._client = client;
|
|
3123
|
-
this._logger = logger$
|
|
3123
|
+
this._logger = logger$28;
|
|
3124
3124
|
}
|
|
3125
3125
|
/**
|
|
3126
3126
|
* Atomically replace all symbols for filePath.
|
|
@@ -3326,11 +3326,11 @@ var RepoMapStorage = class {
|
|
|
3326
3326
|
_metaRepo;
|
|
3327
3327
|
_gitClient;
|
|
3328
3328
|
_logger;
|
|
3329
|
-
constructor(symbolRepo, metaRepo, gitClient, logger$
|
|
3329
|
+
constructor(symbolRepo, metaRepo, gitClient, logger$28) {
|
|
3330
3330
|
this._symbolRepo = symbolRepo;
|
|
3331
3331
|
this._metaRepo = metaRepo;
|
|
3332
3332
|
this._gitClient = gitClient;
|
|
3333
|
-
this._logger = logger$
|
|
3333
|
+
this._logger = logger$28;
|
|
3334
3334
|
}
|
|
3335
3335
|
/**
|
|
3336
3336
|
* Returns true if the file's current content hash differs from the stored hash.
|
|
@@ -3447,8 +3447,8 @@ function runGit(args, cwd) {
|
|
|
3447
3447
|
*/
|
|
3448
3448
|
var GitClient = class {
|
|
3449
3449
|
_logger;
|
|
3450
|
-
constructor(logger$
|
|
3451
|
-
this._logger = logger$
|
|
3450
|
+
constructor(logger$28) {
|
|
3451
|
+
this._logger = logger$28;
|
|
3452
3452
|
}
|
|
3453
3453
|
/**
|
|
3454
3454
|
* Returns the current HEAD commit SHA.
|
|
@@ -4804,9 +4804,9 @@ var RepoMapQueryEngine = class {
|
|
|
4804
4804
|
repo;
|
|
4805
4805
|
logger;
|
|
4806
4806
|
telemetry;
|
|
4807
|
-
constructor(repo, logger$
|
|
4807
|
+
constructor(repo, logger$28, telemetry) {
|
|
4808
4808
|
this.repo = repo;
|
|
4809
|
-
this.logger = logger$
|
|
4809
|
+
this.logger = logger$28;
|
|
4810
4810
|
this.telemetry = telemetry;
|
|
4811
4811
|
}
|
|
4812
4812
|
async query(q) {
|
|
@@ -5026,9 +5026,9 @@ var RepoMapFormatter = class {
|
|
|
5026
5026
|
var RepoMapTelemetry = class {
|
|
5027
5027
|
_telemetry;
|
|
5028
5028
|
_logger;
|
|
5029
|
-
constructor(telemetry, logger$
|
|
5029
|
+
constructor(telemetry, logger$28) {
|
|
5030
5030
|
this._telemetry = telemetry;
|
|
5031
|
-
this._logger = logger$
|
|
5031
|
+
this._logger = logger$28;
|
|
5032
5032
|
}
|
|
5033
5033
|
/**
|
|
5034
5034
|
* Emit a `repo_map.query` span.
|
|
@@ -5053,9 +5053,9 @@ var RepoMapTelemetry = class {
|
|
|
5053
5053
|
var RepoMapModule = class {
|
|
5054
5054
|
_metaRepo;
|
|
5055
5055
|
_logger;
|
|
5056
|
-
constructor(metaRepo, logger$
|
|
5056
|
+
constructor(metaRepo, logger$28) {
|
|
5057
5057
|
this._metaRepo = metaRepo;
|
|
5058
|
-
this._logger = logger$
|
|
5058
|
+
this._logger = logger$28;
|
|
5059
5059
|
}
|
|
5060
5060
|
/**
|
|
5061
5061
|
* Check whether the stored repo-map is stale relative to the current HEAD commit.
|
|
@@ -5099,9 +5099,9 @@ var RepoMapModule = class {
|
|
|
5099
5099
|
var RepoMapInjector = class {
|
|
5100
5100
|
_queryEngine;
|
|
5101
5101
|
_logger;
|
|
5102
|
-
constructor(queryEngine, logger$
|
|
5102
|
+
constructor(queryEngine, logger$28) {
|
|
5103
5103
|
this._queryEngine = queryEngine;
|
|
5104
|
-
this._logger = logger$
|
|
5104
|
+
this._logger = logger$28;
|
|
5105
5105
|
}
|
|
5106
5106
|
/**
|
|
5107
5107
|
* Build repo-map context by extracting file references from the story content,
|
|
@@ -5183,7 +5183,7 @@ const DEFAULT_TIMEOUTS = {
|
|
|
5183
5183
|
|
|
5184
5184
|
//#endregion
|
|
5185
5185
|
//#region src/modules/agent-dispatch/dispatcher-impl.ts
|
|
5186
|
-
const logger$
|
|
5186
|
+
const logger$25 = createLogger("agent-dispatch");
|
|
5187
5187
|
/**
|
|
5188
5188
|
* Create a new Dispatcher instance.
|
|
5189
5189
|
*
|
|
@@ -5327,7 +5327,7 @@ function runBuildVerification(options) {
|
|
|
5327
5327
|
let cmd;
|
|
5328
5328
|
if (verifyCommand === void 0) {
|
|
5329
5329
|
const detection = detectPackageManager(projectRoot);
|
|
5330
|
-
logger$
|
|
5330
|
+
logger$25.info({
|
|
5331
5331
|
packageManager: detection.packageManager,
|
|
5332
5332
|
lockfile: detection.lockfile,
|
|
5333
5333
|
resolvedCommand: detection.command
|
|
@@ -5339,7 +5339,7 @@ function runBuildVerification(options) {
|
|
|
5339
5339
|
const filters = deriveTurboFilters(changedFiles, projectRoot);
|
|
5340
5340
|
if (filters.length > 0) {
|
|
5341
5341
|
cmd = `${cmd} ${filters.join(" ")}`;
|
|
5342
|
-
logger$
|
|
5342
|
+
logger$25.info({
|
|
5343
5343
|
filters,
|
|
5344
5344
|
originalCmd: options.verifyCommand ?? "(auto-detected)"
|
|
5345
5345
|
}, "Build verification: scoped turbo build to affected packages");
|
|
@@ -5382,7 +5382,7 @@ function runBuildVerification(options) {
|
|
|
5382
5382
|
};
|
|
5383
5383
|
const missingScriptPattern = /Missing script[:\s]|No script found|Command "build" not found/i;
|
|
5384
5384
|
if (missingScriptPattern.test(combinedOutput)) {
|
|
5385
|
-
logger$
|
|
5385
|
+
logger$25.warn("Build script not found — skipping pre-flight (greenfield repo)");
|
|
5386
5386
|
return {
|
|
5387
5387
|
status: "skipped",
|
|
5388
5388
|
exitCode,
|
|
@@ -5392,7 +5392,7 @@ function runBuildVerification(options) {
|
|
|
5392
5392
|
}
|
|
5393
5393
|
const pep668Pattern = /externally-managed-environment|This environment is externally managed/i;
|
|
5394
5394
|
if (pep668Pattern.test(combinedOutput)) {
|
|
5395
|
-
logger$
|
|
5395
|
+
logger$25.warn("PEP 668: pip blocked by externally-managed-environment — skipping pre-flight. Create a .venv to resolve.");
|
|
5396
5396
|
return {
|
|
5397
5397
|
status: "skipped",
|
|
5398
5398
|
exitCode,
|
|
@@ -5402,7 +5402,7 @@ function runBuildVerification(options) {
|
|
|
5402
5402
|
}
|
|
5403
5403
|
const pythonEnvNotProvisionedPattern = /\bpython3?:?\s*command not found|command not found:\s*python3?\b|\bpip3?:?\s*command not found|No module named pip\b/i;
|
|
5404
5404
|
if (pythonEnvNotProvisionedPattern.test(combinedOutput)) {
|
|
5405
|
-
logger$
|
|
5405
|
+
logger$25.warn("Python environment not provisioned (interpreter or pip missing) — skipping build pre-flight. Provide a venv (or a project-profile buildCommand that activates one) to verify Python packages.");
|
|
5406
5406
|
return {
|
|
5407
5407
|
status: "skipped",
|
|
5408
5408
|
exitCode,
|
|
@@ -5625,7 +5625,7 @@ function pickRecommendation(distribution, profile, totalIssues, reviewCycles, la
|
|
|
5625
5625
|
|
|
5626
5626
|
//#endregion
|
|
5627
5627
|
//#region src/modules/implementation-orchestrator/project-findings.ts
|
|
5628
|
-
const logger$
|
|
5628
|
+
const logger$24 = createLogger("project-findings");
|
|
5629
5629
|
/** Maximum character length for the findings summary */
|
|
5630
5630
|
const MAX_CHARS = 2e3;
|
|
5631
5631
|
/**
|
|
@@ -5698,7 +5698,7 @@ async function getProjectFindings(db) {
|
|
|
5698
5698
|
if (summary.length > MAX_CHARS) summary = summary.slice(0, MAX_CHARS - 3) + "...";
|
|
5699
5699
|
return summary;
|
|
5700
5700
|
} catch (err) {
|
|
5701
|
-
logger$
|
|
5701
|
+
logger$24.warn({ err }, "Failed to query project findings (graceful fallback)");
|
|
5702
5702
|
return "";
|
|
5703
5703
|
}
|
|
5704
5704
|
}
|
|
@@ -5721,7 +5721,7 @@ function extractRecurringPatterns(outcomes) {
|
|
|
5721
5721
|
|
|
5722
5722
|
//#endregion
|
|
5723
5723
|
//#region src/modules/compiled-workflows/prompt-assembler.ts
|
|
5724
|
-
const logger$
|
|
5724
|
+
const logger$23 = createLogger("compiled-workflows:prompt-assembler");
|
|
5725
5725
|
/**
|
|
5726
5726
|
* Assemble a final prompt from a template and sections map.
|
|
5727
5727
|
*
|
|
@@ -5746,7 +5746,7 @@ function assemblePrompt(template, sections, tokenCeiling = 2200) {
|
|
|
5746
5746
|
tokenCount,
|
|
5747
5747
|
truncated: false
|
|
5748
5748
|
};
|
|
5749
|
-
logger$
|
|
5749
|
+
logger$23.warn({
|
|
5750
5750
|
tokenCount,
|
|
5751
5751
|
ceiling: tokenCeiling
|
|
5752
5752
|
}, "Prompt exceeds token ceiling — truncating optional sections");
|
|
@@ -5762,10 +5762,10 @@ function assemblePrompt(template, sections, tokenCeiling = 2200) {
|
|
|
5762
5762
|
const targetSectionTokens = Math.max(0, currentSectionTokens - overBy);
|
|
5763
5763
|
if (targetSectionTokens === 0) {
|
|
5764
5764
|
contentMap[section.name] = "";
|
|
5765
|
-
logger$
|
|
5765
|
+
logger$23.warn({ sectionName: section.name }, "Section eliminated to fit token budget");
|
|
5766
5766
|
} else {
|
|
5767
5767
|
contentMap[section.name] = truncateToTokens(section.content, targetSectionTokens);
|
|
5768
|
-
logger$
|
|
5768
|
+
logger$23.warn({
|
|
5769
5769
|
sectionName: section.name,
|
|
5770
5770
|
targetSectionTokens
|
|
5771
5771
|
}, "Section truncated to fit token budget");
|
|
@@ -5776,7 +5776,7 @@ function assemblePrompt(template, sections, tokenCeiling = 2200) {
|
|
|
5776
5776
|
}
|
|
5777
5777
|
if (tokenCount <= tokenCeiling) break;
|
|
5778
5778
|
}
|
|
5779
|
-
if (tokenCount > tokenCeiling) logger$
|
|
5779
|
+
if (tokenCount > tokenCeiling) logger$23.warn({
|
|
5780
5780
|
tokenCount,
|
|
5781
5781
|
ceiling: tokenCeiling
|
|
5782
5782
|
}, "Required sections alone exceed token ceiling — returning over-budget prompt");
|
|
@@ -6206,7 +6206,7 @@ function getTokenCeiling(workflowType, tokenCeilings) {
|
|
|
6206
6206
|
|
|
6207
6207
|
//#endregion
|
|
6208
6208
|
//#region src/modules/compiled-workflows/create-story.ts
|
|
6209
|
-
const logger$
|
|
6209
|
+
const logger$22 = createLogger("compiled-workflows:create-story");
|
|
6210
6210
|
/**
|
|
6211
6211
|
* Compute a hex SHA-256 of the normalized source AC section text.
|
|
6212
6212
|
*
|
|
@@ -6241,13 +6241,13 @@ function hashSourceAcSection(section) {
|
|
|
6241
6241
|
*/
|
|
6242
6242
|
async function runCreateStory(deps, params) {
|
|
6243
6243
|
const { epicId, storyKey, pipelineRunId, source_ac_hash, priorDriftFeedback } = params;
|
|
6244
|
-
logger$
|
|
6244
|
+
logger$22.debug({
|
|
6245
6245
|
epicId,
|
|
6246
6246
|
storyKey,
|
|
6247
6247
|
pipelineRunId
|
|
6248
6248
|
}, "Starting create-story workflow");
|
|
6249
6249
|
const { ceiling: TOKEN_CEILING, source: tokenCeilingSource } = getTokenCeiling("create-story", deps.tokenCeilings);
|
|
6250
|
-
logger$
|
|
6250
|
+
logger$22.info({
|
|
6251
6251
|
workflow: "create-story",
|
|
6252
6252
|
ceiling: TOKEN_CEILING,
|
|
6253
6253
|
source: tokenCeilingSource
|
|
@@ -6257,7 +6257,7 @@ async function runCreateStory(deps, params) {
|
|
|
6257
6257
|
template = await deps.pack.getPrompt("create-story");
|
|
6258
6258
|
} catch (err) {
|
|
6259
6259
|
const error = err instanceof Error ? err.message : String(err);
|
|
6260
|
-
logger$
|
|
6260
|
+
logger$22.error({ error }, "Failed to retrieve create-story prompt template");
|
|
6261
6261
|
return {
|
|
6262
6262
|
result: "failed",
|
|
6263
6263
|
error: `Failed to retrieve prompt template: ${error}`,
|
|
@@ -6274,7 +6274,7 @@ async function runCreateStory(deps, params) {
|
|
|
6274
6274
|
const storySection = extractStorySection(epicShardContent, storyKey);
|
|
6275
6275
|
if (storySection !== null) {
|
|
6276
6276
|
const computedHash = hashSourceAcSection(storySection);
|
|
6277
|
-
if (source_ac_hash !== void 0 && source_ac_hash !== computedHash) logger$
|
|
6277
|
+
if (source_ac_hash !== void 0 && source_ac_hash !== computedHash) logger$22.debug({
|
|
6278
6278
|
storyKey,
|
|
6279
6279
|
suppliedHash: source_ac_hash,
|
|
6280
6280
|
computedHash
|
|
@@ -6289,7 +6289,7 @@ async function runCreateStory(deps, params) {
|
|
|
6289
6289
|
const storyDef = storyDecisions.find((d) => d.category === "stories" && d.key === storyKey);
|
|
6290
6290
|
if (storyDef) {
|
|
6291
6291
|
storyDefinitionContent = storyDef.value;
|
|
6292
|
-
logger$
|
|
6292
|
+
logger$22.debug({ storyKey }, "Injected story definition from solutioning decisions");
|
|
6293
6293
|
}
|
|
6294
6294
|
} catch {}
|
|
6295
6295
|
const archConstraintsContent = await getArchConstraints$3(deps);
|
|
@@ -6299,11 +6299,11 @@ async function runCreateStory(deps, params) {
|
|
|
6299
6299
|
if (trustedRoot !== void 0) {
|
|
6300
6300
|
const registryLoad = await loadJourneyRegistryFromTrustedTree(trustedRoot);
|
|
6301
6301
|
if (registryLoad.status === "ok" && registryLoad.registry.journeys.length > 0) journeyRegistry = registryLoad.registry;
|
|
6302
|
-
else if (registryLoad.status === "invalid") logger$
|
|
6302
|
+
else if (registryLoad.status === "invalid") logger$22.warn({
|
|
6303
6303
|
storyKey,
|
|
6304
6304
|
issues: registryLoad.issues
|
|
6305
6305
|
}, "A0.2: journey registry present but invalid — stories will be untagged (registry validity is escalated at epic close)");
|
|
6306
|
-
else if (registryLoad.status === "error") logger$
|
|
6306
|
+
else if (registryLoad.status === "error") logger$22.warn({
|
|
6307
6307
|
storyKey,
|
|
6308
6308
|
error: registryLoad.message
|
|
6309
6309
|
}, "A0.2: journey registry read failed — stories will be untagged");
|
|
@@ -6364,7 +6364,7 @@ async function runCreateStory(deps, params) {
|
|
|
6364
6364
|
priority: "optional"
|
|
6365
6365
|
}]
|
|
6366
6366
|
], TOKEN_CEILING);
|
|
6367
|
-
logger$
|
|
6367
|
+
logger$22.debug({
|
|
6368
6368
|
tokenCount,
|
|
6369
6369
|
truncated,
|
|
6370
6370
|
tokenCeiling: TOKEN_CEILING
|
|
@@ -6384,7 +6384,7 @@ async function runCreateStory(deps, params) {
|
|
|
6384
6384
|
dispatchResult = await handle.result;
|
|
6385
6385
|
} catch (err) {
|
|
6386
6386
|
const error = err instanceof Error ? err.message : String(err);
|
|
6387
|
-
logger$
|
|
6387
|
+
logger$22.error({
|
|
6388
6388
|
epicId,
|
|
6389
6389
|
storyKey,
|
|
6390
6390
|
error
|
|
@@ -6405,7 +6405,7 @@ async function runCreateStory(deps, params) {
|
|
|
6405
6405
|
if (dispatchResult.status === "failed") {
|
|
6406
6406
|
const errorMsg = dispatchResult.parseError ?? `Dispatch failed with exit code ${dispatchResult.exitCode}`;
|
|
6407
6407
|
const stderrDetail = dispatchResult.output ? ` Output: ${dispatchResult.output}` : "";
|
|
6408
|
-
logger$
|
|
6408
|
+
logger$22.warn({
|
|
6409
6409
|
epicId,
|
|
6410
6410
|
storyKey,
|
|
6411
6411
|
exitCode: dispatchResult.exitCode,
|
|
@@ -6418,7 +6418,7 @@ async function runCreateStory(deps, params) {
|
|
|
6418
6418
|
};
|
|
6419
6419
|
}
|
|
6420
6420
|
if (dispatchResult.status === "timeout") {
|
|
6421
|
-
logger$
|
|
6421
|
+
logger$22.warn({
|
|
6422
6422
|
epicId,
|
|
6423
6423
|
storyKey
|
|
6424
6424
|
}, "Create-story dispatch timed out");
|
|
@@ -6433,7 +6433,7 @@ async function runCreateStory(deps, params) {
|
|
|
6433
6433
|
const rawSnippet = dispatchResult.output ? dispatchResult.output.slice(0, 1e3) : "(empty)";
|
|
6434
6434
|
const authSignature = detectClaudeAuthFailure(dispatchResult.output);
|
|
6435
6435
|
if (authSignature !== null) {
|
|
6436
|
-
logger$
|
|
6436
|
+
logger$22.error({
|
|
6437
6437
|
epicId,
|
|
6438
6438
|
storyKey,
|
|
6439
6439
|
authSignature,
|
|
@@ -6446,7 +6446,7 @@ async function runCreateStory(deps, params) {
|
|
|
6446
6446
|
tokenUsage
|
|
6447
6447
|
};
|
|
6448
6448
|
}
|
|
6449
|
-
logger$
|
|
6449
|
+
logger$22.warn({
|
|
6450
6450
|
epicId,
|
|
6451
6451
|
storyKey,
|
|
6452
6452
|
details,
|
|
@@ -6462,7 +6462,7 @@ async function runCreateStory(deps, params) {
|
|
|
6462
6462
|
const parseResult = CreateStoryResultSchema.safeParse(dispatchResult.parsed);
|
|
6463
6463
|
if (!parseResult.success) {
|
|
6464
6464
|
const details = parseResult.error.message;
|
|
6465
|
-
logger$
|
|
6465
|
+
logger$22.warn({
|
|
6466
6466
|
epicId,
|
|
6467
6467
|
storyKey,
|
|
6468
6468
|
details
|
|
@@ -6489,7 +6489,7 @@ async function runCreateStory(deps, params) {
|
|
|
6489
6489
|
const unknown = taggedJourneys.filter((id) => !knownIds.has(id));
|
|
6490
6490
|
if (unknown.length > 0) {
|
|
6491
6491
|
const details = `story artifact declares unknown journey id(s): ${unknown.join(", ")} — registry v${String(journeyRegistry.version)} defines: ${[...knownIds].join(", ")}`;
|
|
6492
|
-
logger$
|
|
6492
|
+
logger$22.warn({
|
|
6493
6493
|
epicId,
|
|
6494
6494
|
storyKey,
|
|
6495
6495
|
unknown
|
|
@@ -6502,7 +6502,7 @@ async function runCreateStory(deps, params) {
|
|
|
6502
6502
|
};
|
|
6503
6503
|
}
|
|
6504
6504
|
if (taggedJourneys.length > 0) {
|
|
6505
|
-
logger$
|
|
6505
|
+
logger$22.info({
|
|
6506
6506
|
epicId,
|
|
6507
6507
|
storyKey,
|
|
6508
6508
|
journeys: taggedJourneys
|
|
@@ -6511,7 +6511,7 @@ async function runCreateStory(deps, params) {
|
|
|
6511
6511
|
}
|
|
6512
6512
|
}
|
|
6513
6513
|
}
|
|
6514
|
-
logger$
|
|
6514
|
+
logger$22.info({
|
|
6515
6515
|
epicId,
|
|
6516
6516
|
storyKey,
|
|
6517
6517
|
storyFile: parsed.story_file,
|
|
@@ -6541,7 +6541,7 @@ async function getImplementationDecisions(deps, pipelineRunId) {
|
|
|
6541
6541
|
}
|
|
6542
6542
|
return await getDecisionsByPhase(deps.db, "implementation");
|
|
6543
6543
|
} catch (err) {
|
|
6544
|
-
logger$
|
|
6544
|
+
logger$22.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve implementation decisions");
|
|
6545
6545
|
return [];
|
|
6546
6546
|
}
|
|
6547
6547
|
}
|
|
@@ -6839,7 +6839,7 @@ function getEpicShard(decisions, epicId, projectRoot, storyKey) {
|
|
|
6839
6839
|
if (storyKey) {
|
|
6840
6840
|
const perStoryShard = decisions.find((d) => d.category === "epic-shard" && d.key === storyKey);
|
|
6841
6841
|
if (perStoryShard?.value) {
|
|
6842
|
-
logger$
|
|
6842
|
+
logger$22.debug({
|
|
6843
6843
|
epicId,
|
|
6844
6844
|
storyKey
|
|
6845
6845
|
}, "Found per-story epic shard (direct lookup)");
|
|
@@ -6851,13 +6851,13 @@ function getEpicShard(decisions, epicId, projectRoot, storyKey) {
|
|
|
6851
6851
|
if (shardContent && storyKey) {
|
|
6852
6852
|
const storySection = extractStorySection(shardContent, storyKey);
|
|
6853
6853
|
if (storySection) {
|
|
6854
|
-
logger$
|
|
6854
|
+
logger$22.debug({
|
|
6855
6855
|
epicId,
|
|
6856
6856
|
storyKey
|
|
6857
6857
|
}, "Extracted per-story section from epic shard (pre-37-0 fallback)");
|
|
6858
6858
|
return storySection;
|
|
6859
6859
|
}
|
|
6860
|
-
logger$
|
|
6860
|
+
logger$22.info({
|
|
6861
6861
|
epicId,
|
|
6862
6862
|
storyKey
|
|
6863
6863
|
}, "Story section absent in decisions-store shard — attempting file-based fallback before returning stale shard");
|
|
@@ -6865,11 +6865,11 @@ function getEpicShard(decisions, epicId, projectRoot, storyKey) {
|
|
|
6865
6865
|
if (projectRoot) {
|
|
6866
6866
|
const fallback = readEpicShardFromFile(projectRoot, epicId, storyKey);
|
|
6867
6867
|
if (fallback) {
|
|
6868
|
-
logger$
|
|
6868
|
+
logger$22.info({ epicId }, "Using file-based fallback for epic shard");
|
|
6869
6869
|
if (storyKey) {
|
|
6870
6870
|
const storySection = extractStorySection(fallback, storyKey);
|
|
6871
6871
|
if (storySection) {
|
|
6872
|
-
logger$
|
|
6872
|
+
logger$22.debug({
|
|
6873
6873
|
epicId,
|
|
6874
6874
|
storyKey
|
|
6875
6875
|
}, "Extracted per-story section from file-based epic shard");
|
|
@@ -6882,7 +6882,7 @@ function getEpicShard(decisions, epicId, projectRoot, storyKey) {
|
|
|
6882
6882
|
if (shardContent) return shardContent;
|
|
6883
6883
|
return "";
|
|
6884
6884
|
} catch (err) {
|
|
6885
|
-
logger$
|
|
6885
|
+
logger$22.warn({
|
|
6886
6886
|
epicId,
|
|
6887
6887
|
error: err instanceof Error ? err.message : String(err)
|
|
6888
6888
|
}, "Failed to retrieve epic shard");
|
|
@@ -6899,7 +6899,7 @@ function getPrevDevNotes(decisions, epicId) {
|
|
|
6899
6899
|
if (devNotes.length === 0) return "";
|
|
6900
6900
|
return devNotes[devNotes.length - 1].value;
|
|
6901
6901
|
} catch (err) {
|
|
6902
|
-
logger$
|
|
6902
|
+
logger$22.warn({
|
|
6903
6903
|
epicId,
|
|
6904
6904
|
error: err instanceof Error ? err.message : String(err)
|
|
6905
6905
|
}, "Failed to retrieve prev dev notes");
|
|
@@ -6932,7 +6932,7 @@ async function getArchConstraints$3(deps) {
|
|
|
6932
6932
|
const truncatedBody = body.length > 300 ? body.slice(0, 297) + "..." : body;
|
|
6933
6933
|
return `${header}\n${truncatedBody}`;
|
|
6934
6934
|
}).join("\n\n");
|
|
6935
|
-
logger$
|
|
6935
|
+
logger$22.info({
|
|
6936
6936
|
fullLength: full.length,
|
|
6937
6937
|
summarizedLength: summarized.length,
|
|
6938
6938
|
decisions: constraints.length
|
|
@@ -6943,13 +6943,13 @@ async function getArchConstraints$3(deps) {
|
|
|
6943
6943
|
if (archRoot) {
|
|
6944
6944
|
const fallback = readArchConstraintsFromFile(archRoot);
|
|
6945
6945
|
if (fallback) {
|
|
6946
|
-
logger$
|
|
6946
|
+
logger$22.info("Using file-based fallback for architecture constraints (decisions table empty)");
|
|
6947
6947
|
return fallback.length > ARCH_CONSTRAINT_MAX_CHARS ? fallback.slice(0, ARCH_CONSTRAINT_MAX_CHARS) + "\n\n[truncated for token budget]" : fallback;
|
|
6948
6948
|
}
|
|
6949
6949
|
}
|
|
6950
6950
|
return "";
|
|
6951
6951
|
} catch (err) {
|
|
6952
|
-
logger$
|
|
6952
|
+
logger$22.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve architecture constraints");
|
|
6953
6953
|
return "";
|
|
6954
6954
|
}
|
|
6955
6955
|
}
|
|
@@ -7013,7 +7013,7 @@ function readEpicShardFromFile(projectRoot, epicId, storyKey) {
|
|
|
7013
7013
|
}
|
|
7014
7014
|
return "";
|
|
7015
7015
|
} catch (err) {
|
|
7016
|
-
logger$
|
|
7016
|
+
logger$22.warn({
|
|
7017
7017
|
epicId,
|
|
7018
7018
|
error: err instanceof Error ? err.message : String(err)
|
|
7019
7019
|
}, "File-based epic shard fallback failed");
|
|
@@ -7036,7 +7036,7 @@ function readArchConstraintsFromFile(projectRoot) {
|
|
|
7036
7036
|
const content = readFileSync(archPath, "utf-8");
|
|
7037
7037
|
return content.slice(0, 1500);
|
|
7038
7038
|
} catch (err) {
|
|
7039
|
-
logger$
|
|
7039
|
+
logger$22.warn({ error: err instanceof Error ? err.message : String(err) }, "File-based architecture fallback failed");
|
|
7040
7040
|
return "";
|
|
7041
7041
|
}
|
|
7042
7042
|
}
|
|
@@ -7049,7 +7049,7 @@ async function getStoryTemplate(deps) {
|
|
|
7049
7049
|
try {
|
|
7050
7050
|
return await deps.pack.getTemplate("story");
|
|
7051
7051
|
} catch (err) {
|
|
7052
|
-
logger$
|
|
7052
|
+
logger$22.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve story template from pack");
|
|
7053
7053
|
return "";
|
|
7054
7054
|
}
|
|
7055
7055
|
}
|
|
@@ -7086,7 +7086,7 @@ async function isValidStoryFile(filePath) {
|
|
|
7086
7086
|
|
|
7087
7087
|
//#endregion
|
|
7088
7088
|
//#region src/modules/compiled-workflows/git-helpers.ts
|
|
7089
|
-
const logger$
|
|
7089
|
+
const logger$21 = createLogger("compiled-workflows:git-helpers");
|
|
7090
7090
|
/**
|
|
7091
7091
|
* Commit the agent's working-tree output for a dev-story dispatch.
|
|
7092
7092
|
*
|
|
@@ -7130,7 +7130,7 @@ async function commitDevStoryOutput(storyKey, storyTitle, filesModified, working
|
|
|
7130
7130
|
const abs = isAbsolute(p) ? p : resolve$1(workingDir, p);
|
|
7131
7131
|
const rel = relative(workingDir, abs);
|
|
7132
7132
|
if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) {
|
|
7133
|
-
logger$
|
|
7133
|
+
logger$21.debug({
|
|
7134
7134
|
path: p,
|
|
7135
7135
|
abs,
|
|
7136
7136
|
workingDir
|
|
@@ -7139,7 +7139,7 @@ async function commitDevStoryOutput(storyKey, storyTitle, filesModified, working
|
|
|
7139
7139
|
}
|
|
7140
7140
|
const segments = rel.replace(/\\/g, "/").split("/");
|
|
7141
7141
|
if (segments.some((s$1) => COMMIT_DENY_SEGMENTS.includes(s$1))) {
|
|
7142
|
-
logger$
|
|
7142
|
+
logger$21.warn({
|
|
7143
7143
|
path: rel,
|
|
7144
7144
|
storyKey
|
|
7145
7145
|
}, "commitDevStoryOutput: denylisted dependency/artifact path excluded from substrate commit");
|
|
@@ -7224,12 +7224,12 @@ async function commitDevStoryOutput(storyKey, storyTitle, filesModified, working
|
|
|
7224
7224
|
timeout: 5e3
|
|
7225
7225
|
}).trim();
|
|
7226
7226
|
} catch (err) {
|
|
7227
|
-
logger$
|
|
7227
|
+
logger$21.warn({
|
|
7228
7228
|
storyKey,
|
|
7229
7229
|
err
|
|
7230
7230
|
}, "commitDevStoryOutput: commit succeeded but rev-parse HEAD failed");
|
|
7231
7231
|
}
|
|
7232
|
-
logger$
|
|
7232
|
+
logger$21.info({
|
|
7233
7233
|
storyKey,
|
|
7234
7234
|
sha,
|
|
7235
7235
|
fileCount: insideWorktree.length
|
|
@@ -7333,7 +7333,7 @@ async function checkpointStoryWorktree(storyKey, reason, workingDir) {
|
|
|
7333
7333
|
timeout: 5e3
|
|
7334
7334
|
}).trim();
|
|
7335
7335
|
} catch {}
|
|
7336
|
-
logger$
|
|
7336
|
+
logger$21.info({
|
|
7337
7337
|
storyKey,
|
|
7338
7338
|
sha,
|
|
7339
7339
|
reason: cleanReason
|
|
@@ -7379,7 +7379,7 @@ function hasCommits(cwd) {
|
|
|
7379
7379
|
*/
|
|
7380
7380
|
async function getGitDiffSummary(workingDirectory = process.cwd()) {
|
|
7381
7381
|
if (!hasCommits(workingDirectory)) {
|
|
7382
|
-
logger$
|
|
7382
|
+
logger$21.debug({ cwd: workingDirectory }, "No commits in repo — returning empty diff");
|
|
7383
7383
|
return "";
|
|
7384
7384
|
}
|
|
7385
7385
|
return runGitCommand(["diff", "HEAD"], workingDirectory, "git-diff-summary");
|
|
@@ -7396,7 +7396,7 @@ async function getGitDiffSummary(workingDirectory = process.cwd()) {
|
|
|
7396
7396
|
*/
|
|
7397
7397
|
async function getGitDiffStatSummary(workingDirectory = process.cwd()) {
|
|
7398
7398
|
if (!hasCommits(workingDirectory)) {
|
|
7399
|
-
logger$
|
|
7399
|
+
logger$21.debug({ cwd: workingDirectory }, "No commits in repo — returning empty stat");
|
|
7400
7400
|
return "";
|
|
7401
7401
|
}
|
|
7402
7402
|
return runGitCommand([
|
|
@@ -7445,7 +7445,7 @@ async function getGitDiffStatBetweenCommits(baseCommit, endCommit = "HEAD", work
|
|
|
7445
7445
|
async function getGitDiffForFiles(files, workingDirectory = process.cwd()) {
|
|
7446
7446
|
if (files.length === 0) return "";
|
|
7447
7447
|
if (!hasCommits(workingDirectory)) {
|
|
7448
|
-
logger$
|
|
7448
|
+
logger$21.debug({ cwd: workingDirectory }, "No commits in repo — returning empty diff for files");
|
|
7449
7449
|
return "";
|
|
7450
7450
|
}
|
|
7451
7451
|
await stageIntentToAdd(files, workingDirectory);
|
|
@@ -7472,7 +7472,7 @@ async function getGitDiffForFiles(files, workingDirectory = process.cwd()) {
|
|
|
7472
7472
|
async function getGitDiffStatForFiles(files, workingDirectory = process.cwd()) {
|
|
7473
7473
|
if (files.length === 0) return "";
|
|
7474
7474
|
if (!hasCommits(workingDirectory)) {
|
|
7475
|
-
logger$
|
|
7475
|
+
logger$21.debug({ cwd: workingDirectory }, "No commits in repo — returning empty stat for files");
|
|
7476
7476
|
return "";
|
|
7477
7477
|
}
|
|
7478
7478
|
return runGitCommand([
|
|
@@ -7521,7 +7521,7 @@ async function stageIntentToAdd(files, workingDirectory) {
|
|
|
7521
7521
|
if (files.length === 0) return;
|
|
7522
7522
|
const existing = files.filter((f$1) => {
|
|
7523
7523
|
const exists = existsSync(f$1);
|
|
7524
|
-
if (!exists) logger$
|
|
7524
|
+
if (!exists) logger$21.debug({ file: f$1 }, "Skipping nonexistent file in stageIntentToAdd");
|
|
7525
7525
|
return exists;
|
|
7526
7526
|
});
|
|
7527
7527
|
if (existing.length === 0) return;
|
|
@@ -7550,7 +7550,7 @@ async function stageIntentToAdd(files, workingDirectory) {
|
|
|
7550
7550
|
async function recoverStoryFileFromBranch(storyFilePath, workingDirectory) {
|
|
7551
7551
|
const rel = relative(workingDirectory, resolve$1(workingDirectory, storyFilePath));
|
|
7552
7552
|
if (rel.startsWith("..")) {
|
|
7553
|
-
logger$
|
|
7553
|
+
logger$21.warn({
|
|
7554
7554
|
storyFilePath,
|
|
7555
7555
|
workingDirectory
|
|
7556
7556
|
}, "recoverStoryFileFromBranch: path outside the worktree — not recoverable");
|
|
@@ -7562,9 +7562,9 @@ async function recoverStoryFileFromBranch(storyFilePath, workingDirectory) {
|
|
|
7562
7562
|
const abs = resolve$1(workingDirectory, rel);
|
|
7563
7563
|
await mkdir$1(dirname$1(abs), { recursive: true });
|
|
7564
7564
|
await writeFile$1(abs, content, "utf-8");
|
|
7565
|
-
logger$
|
|
7565
|
+
logger$21.warn({ storyFilePath: abs }, "H5.5: story file restored to the working tree from branch HEAD");
|
|
7566
7566
|
} catch (writeErr) {
|
|
7567
|
-
logger$
|
|
7567
|
+
logger$21.warn({
|
|
7568
7568
|
storyFilePath,
|
|
7569
7569
|
err: writeErr
|
|
7570
7570
|
}, "H5.5: recovered story content but could not restore the file (continuing with in-memory content)");
|
|
@@ -7590,7 +7590,7 @@ async function runGitCommand(args, cwd, logLabel) {
|
|
|
7590
7590
|
stderr += chunk.toString("utf-8");
|
|
7591
7591
|
});
|
|
7592
7592
|
proc$1.on("error", (err) => {
|
|
7593
|
-
logger$
|
|
7593
|
+
logger$21.warn({
|
|
7594
7594
|
label: logLabel,
|
|
7595
7595
|
cwd,
|
|
7596
7596
|
error: err.message
|
|
@@ -7599,7 +7599,7 @@ async function runGitCommand(args, cwd, logLabel) {
|
|
|
7599
7599
|
});
|
|
7600
7600
|
proc$1.on("close", (code) => {
|
|
7601
7601
|
if (code !== 0) {
|
|
7602
|
-
logger$
|
|
7602
|
+
logger$21.warn({
|
|
7603
7603
|
label: logLabel,
|
|
7604
7604
|
cwd,
|
|
7605
7605
|
code,
|
|
@@ -7615,7 +7615,7 @@ async function runGitCommand(args, cwd, logLabel) {
|
|
|
7615
7615
|
|
|
7616
7616
|
//#endregion
|
|
7617
7617
|
//#region src/modules/compiled-workflows/story-complexity.ts
|
|
7618
|
-
const logger$
|
|
7618
|
+
const logger$20 = createLogger("compiled-workflows:story-complexity");
|
|
7619
7619
|
/**
|
|
7620
7620
|
* Compute a complexity score from story markdown content.
|
|
7621
7621
|
*
|
|
@@ -7667,7 +7667,7 @@ function resolveFixStoryMaxTurns(complexityScore) {
|
|
|
7667
7667
|
* @param resolvedMaxTurns - Turn limit resolved for this dispatch
|
|
7668
7668
|
*/
|
|
7669
7669
|
function logComplexityResult(storyKey, complexity, resolvedMaxTurns) {
|
|
7670
|
-
logger$
|
|
7670
|
+
logger$20.info({
|
|
7671
7671
|
storyKey,
|
|
7672
7672
|
taskCount: complexity.taskCount,
|
|
7673
7673
|
subtaskCount: complexity.subtaskCount,
|
|
@@ -7940,7 +7940,7 @@ function resolveInstallCommand(projectRoot) {
|
|
|
7940
7940
|
|
|
7941
7941
|
//#endregion
|
|
7942
7942
|
//#region src/modules/compiled-workflows/dev-story.ts
|
|
7943
|
-
const logger$
|
|
7943
|
+
const logger$19 = createLogger("compiled-workflows:dev-story");
|
|
7944
7944
|
/** Default timeout for dev-story dispatches in milliseconds (30 min) */
|
|
7945
7945
|
const DEFAULT_TIMEOUT_MS$2 = 18e5;
|
|
7946
7946
|
/**
|
|
@@ -7952,12 +7952,12 @@ const DEFAULT_TIMEOUT_MS$2 = 18e5;
|
|
|
7952
7952
|
*/
|
|
7953
7953
|
async function runDevStory(deps, params) {
|
|
7954
7954
|
const { storyKey, storyFilePath, taskScope, priorFiles, findingsPrompt: handlerFindingsPrompt } = params;
|
|
7955
|
-
logger$
|
|
7955
|
+
logger$19.info({
|
|
7956
7956
|
storyKey,
|
|
7957
7957
|
storyFilePath
|
|
7958
7958
|
}, "Starting compiled dev-story workflow");
|
|
7959
7959
|
const { ceiling: TOKEN_CEILING, source: tokenCeilingSource } = getTokenCeiling("dev-story", deps.tokenCeilings);
|
|
7960
|
-
logger$
|
|
7960
|
+
logger$19.info({
|
|
7961
7961
|
workflow: "dev-story",
|
|
7962
7962
|
ceiling: TOKEN_CEILING,
|
|
7963
7963
|
source: tokenCeilingSource
|
|
@@ -8000,10 +8000,10 @@ async function runDevStory(deps, params) {
|
|
|
8000
8000
|
let template;
|
|
8001
8001
|
try {
|
|
8002
8002
|
template = await deps.pack.getPrompt("dev-story");
|
|
8003
|
-
logger$
|
|
8003
|
+
logger$19.debug({ storyKey }, "Retrieved dev-story prompt template from pack");
|
|
8004
8004
|
} catch (err) {
|
|
8005
8005
|
const error = err instanceof Error ? err.message : String(err);
|
|
8006
|
-
logger$
|
|
8006
|
+
logger$19.error({
|
|
8007
8007
|
storyKey,
|
|
8008
8008
|
error
|
|
8009
8009
|
}, "Failed to retrieve dev-story prompt template");
|
|
@@ -8015,20 +8015,20 @@ async function runDevStory(deps, params) {
|
|
|
8015
8015
|
} catch (err) {
|
|
8016
8016
|
const recovered = await recoverStoryFileFromBranch(storyFilePath, deps.projectRoot ?? process.cwd());
|
|
8017
8017
|
if (recovered !== void 0) {
|
|
8018
|
-
logger$
|
|
8018
|
+
logger$19.warn({
|
|
8019
8019
|
storyKey,
|
|
8020
8020
|
storyFilePath
|
|
8021
8021
|
}, "story file missing from working tree — recovered from branch HEAD (H5.5)");
|
|
8022
8022
|
storyContent = recovered;
|
|
8023
8023
|
} else if (err.code === "ENOENT") {
|
|
8024
|
-
logger$
|
|
8024
|
+
logger$19.error({
|
|
8025
8025
|
storyKey,
|
|
8026
8026
|
storyFilePath
|
|
8027
8027
|
}, "Story file not found");
|
|
8028
8028
|
return makeFailureResult("story_file_not_found");
|
|
8029
8029
|
} else {
|
|
8030
8030
|
const error = err instanceof Error ? err.message : String(err);
|
|
8031
|
-
logger$
|
|
8031
|
+
logger$19.error({
|
|
8032
8032
|
storyKey,
|
|
8033
8033
|
storyFilePath,
|
|
8034
8034
|
error
|
|
@@ -8037,7 +8037,7 @@ async function runDevStory(deps, params) {
|
|
|
8037
8037
|
}
|
|
8038
8038
|
}
|
|
8039
8039
|
if (storyContent.trim().length === 0) {
|
|
8040
|
-
logger$
|
|
8040
|
+
logger$19.error({
|
|
8041
8041
|
storyKey,
|
|
8042
8042
|
storyFilePath
|
|
8043
8043
|
}, "Story file is empty");
|
|
@@ -8045,7 +8045,7 @@ async function runDevStory(deps, params) {
|
|
|
8045
8045
|
}
|
|
8046
8046
|
const staleStatus = detectDeprecatedStatusField(storyContent);
|
|
8047
8047
|
if (staleStatus !== null) {
|
|
8048
|
-
logger$
|
|
8048
|
+
logger$19.warn({
|
|
8049
8049
|
storyFilePath,
|
|
8050
8050
|
staleStatus
|
|
8051
8051
|
}, "Story spec contains deprecated Status field — stripped before dispatch (status is managed by Dolt work graph)");
|
|
@@ -8060,17 +8060,17 @@ async function runDevStory(deps, params) {
|
|
|
8060
8060
|
const testPatternDecisions = solutioningDecisions.filter((d) => d.category === "test-patterns");
|
|
8061
8061
|
if (testPatternDecisions.length > 0) {
|
|
8062
8062
|
testPatternsContent = "## Test Patterns\n" + testPatternDecisions.map((d) => `- ${d.key}: ${d.value}`).join("\n");
|
|
8063
|
-
logger$
|
|
8063
|
+
logger$19.debug({
|
|
8064
8064
|
storyKey,
|
|
8065
8065
|
count: testPatternDecisions.length
|
|
8066
8066
|
}, "Loaded test patterns from decision store");
|
|
8067
8067
|
} else {
|
|
8068
8068
|
testPatternsContent = resolveDefaultTestPatterns(deps.projectRoot);
|
|
8069
|
-
logger$
|
|
8069
|
+
logger$19.debug({ storyKey }, "No test-pattern decisions — using stack-aware defaults");
|
|
8070
8070
|
}
|
|
8071
8071
|
} catch (err) {
|
|
8072
8072
|
const error = err instanceof Error ? err.message : String(err);
|
|
8073
|
-
logger$
|
|
8073
|
+
logger$19.warn({
|
|
8074
8074
|
storyKey,
|
|
8075
8075
|
error
|
|
8076
8076
|
}, "Failed to load test patterns — using defaults");
|
|
@@ -8084,7 +8084,7 @@ async function runDevStory(deps, params) {
|
|
|
8084
8084
|
if (deps.repoMapInjector !== void 0) {
|
|
8085
8085
|
const injection = await deps.repoMapInjector.buildContext(storyContent, deps.maxRepoMapTokens ?? 2e3);
|
|
8086
8086
|
repoContextContent = injection.text;
|
|
8087
|
-
logger$
|
|
8087
|
+
logger$19.info({
|
|
8088
8088
|
storyKey,
|
|
8089
8089
|
repoMapTokens: Math.ceil(injection.text.length / 4),
|
|
8090
8090
|
symbolCount: injection.symbolCount,
|
|
@@ -8094,7 +8094,7 @@ async function runDevStory(deps, params) {
|
|
|
8094
8094
|
let priorFindingsContent = "";
|
|
8095
8095
|
if (handlerFindingsPrompt !== void 0 && handlerFindingsPrompt.length > 0) {
|
|
8096
8096
|
priorFindingsContent = handlerFindingsPrompt;
|
|
8097
|
-
logger$
|
|
8097
|
+
logger$19.debug({
|
|
8098
8098
|
storyKey,
|
|
8099
8099
|
findingsLen: handlerFindingsPrompt.length
|
|
8100
8100
|
}, "Using pre-computed findings from handler (Story 53-8 AC2)");
|
|
@@ -8106,7 +8106,7 @@ async function runDevStory(deps, params) {
|
|
|
8106
8106
|
});
|
|
8107
8107
|
if (findings.length > 0) {
|
|
8108
8108
|
priorFindingsContent = findings;
|
|
8109
|
-
logger$
|
|
8109
|
+
logger$19.debug({
|
|
8110
8110
|
storyKey,
|
|
8111
8111
|
findingsLen: findings.length
|
|
8112
8112
|
}, "Injecting relevance-scored findings into dev-story prompt");
|
|
@@ -8126,7 +8126,7 @@ async function runDevStory(deps, params) {
|
|
|
8126
8126
|
if (plan.test_categories && plan.test_categories.length > 0) parts.push(`\n### Categories: ${plan.test_categories.join(", ")}`);
|
|
8127
8127
|
if (plan.coverage_notes) parts.push(`\n### Coverage Notes\n${plan.coverage_notes}`);
|
|
8128
8128
|
testPlanContent = parts.join("\n");
|
|
8129
|
-
logger$
|
|
8129
|
+
logger$19.debug({ storyKey }, "Injecting test plan into dev-story prompt");
|
|
8130
8130
|
}
|
|
8131
8131
|
} catch {}
|
|
8132
8132
|
const sections = [
|
|
@@ -8187,7 +8187,7 @@ async function runDevStory(deps, params) {
|
|
|
8187
8187
|
}
|
|
8188
8188
|
];
|
|
8189
8189
|
const { prompt, tokenCount, truncated } = assemblePrompt(template, sections, TOKEN_CEILING);
|
|
8190
|
-
logger$
|
|
8190
|
+
logger$19.info({
|
|
8191
8191
|
storyKey,
|
|
8192
8192
|
tokenCount,
|
|
8193
8193
|
ceiling: TOKEN_CEILING,
|
|
@@ -8211,7 +8211,7 @@ async function runDevStory(deps, params) {
|
|
|
8211
8211
|
dispatchResult = await handle.result;
|
|
8212
8212
|
} catch (err) {
|
|
8213
8213
|
const error = err instanceof Error ? err.message : String(err);
|
|
8214
|
-
logger$
|
|
8214
|
+
logger$19.error({
|
|
8215
8215
|
storyKey,
|
|
8216
8216
|
error
|
|
8217
8217
|
}, "Dispatch threw an unexpected error");
|
|
@@ -8222,11 +8222,11 @@ async function runDevStory(deps, params) {
|
|
|
8222
8222
|
output: dispatchResult.tokenEstimate.output
|
|
8223
8223
|
};
|
|
8224
8224
|
if (dispatchResult.status === "timeout") {
|
|
8225
|
-
logger$
|
|
8225
|
+
logger$19.error({
|
|
8226
8226
|
storyKey,
|
|
8227
8227
|
durationMs: dispatchResult.durationMs
|
|
8228
8228
|
}, "Dev-story dispatch timed out");
|
|
8229
|
-
if (dispatchResult.output.length > 0) logger$
|
|
8229
|
+
if (dispatchResult.output.length > 0) logger$19.info({
|
|
8230
8230
|
storyKey,
|
|
8231
8231
|
partialOutput: dispatchResult.output.slice(0, 500)
|
|
8232
8232
|
}, "Partial output before timeout");
|
|
@@ -8236,12 +8236,12 @@ async function runDevStory(deps, params) {
|
|
|
8236
8236
|
};
|
|
8237
8237
|
}
|
|
8238
8238
|
if (dispatchResult.status === "failed" || dispatchResult.exitCode !== 0) {
|
|
8239
|
-
logger$
|
|
8239
|
+
logger$19.error({
|
|
8240
8240
|
storyKey,
|
|
8241
8241
|
exitCode: dispatchResult.exitCode,
|
|
8242
8242
|
status: dispatchResult.status
|
|
8243
8243
|
}, "Dev-story dispatch failed");
|
|
8244
|
-
if (dispatchResult.output.length > 0) logger$
|
|
8244
|
+
if (dispatchResult.output.length > 0) logger$19.info({
|
|
8245
8245
|
storyKey,
|
|
8246
8246
|
partialOutput: dispatchResult.output.slice(0, 500)
|
|
8247
8247
|
}, "Partial output from failed dispatch");
|
|
@@ -8253,7 +8253,7 @@ async function runDevStory(deps, params) {
|
|
|
8253
8253
|
if (dispatchResult.parseError !== null || dispatchResult.parsed === null) {
|
|
8254
8254
|
const details = dispatchResult.parseError ?? "parsed result was null";
|
|
8255
8255
|
const rawSnippet = dispatchResult.output ? dispatchResult.output.slice(0, 1e3) : "(empty)";
|
|
8256
|
-
logger$
|
|
8256
|
+
logger$19.error({
|
|
8257
8257
|
storyKey,
|
|
8258
8258
|
parseError: details,
|
|
8259
8259
|
rawOutputSnippet: rawSnippet
|
|
@@ -8261,12 +8261,12 @@ async function runDevStory(deps, params) {
|
|
|
8261
8261
|
let filesModified = [];
|
|
8262
8262
|
try {
|
|
8263
8263
|
filesModified = await getGitChangedFiles(deps.projectRoot ?? process.cwd());
|
|
8264
|
-
if (filesModified.length > 0) logger$
|
|
8264
|
+
if (filesModified.length > 0) logger$19.info({
|
|
8265
8265
|
storyKey,
|
|
8266
8266
|
fileCount: filesModified.length
|
|
8267
8267
|
}, "Recovered files_modified from git status (YAML fallback)");
|
|
8268
8268
|
} catch (err) {
|
|
8269
|
-
logger$
|
|
8269
|
+
logger$19.warn({
|
|
8270
8270
|
storyKey,
|
|
8271
8271
|
error: err instanceof Error ? err.message : String(err)
|
|
8272
8272
|
}, "Failed to recover files_modified from git");
|
|
@@ -8283,7 +8283,7 @@ async function runDevStory(deps, params) {
|
|
|
8283
8283
|
};
|
|
8284
8284
|
}
|
|
8285
8285
|
const parsed = dispatchResult.parsed;
|
|
8286
|
-
logger$
|
|
8286
|
+
logger$19.info({
|
|
8287
8287
|
storyKey,
|
|
8288
8288
|
result: parsed.result,
|
|
8289
8289
|
acMet: parsed.ac_met.length
|
|
@@ -8697,7 +8697,7 @@ function resolvesIntoExpected(modifiedFilePath, relativePath, expectedFiles) {
|
|
|
8697
8697
|
|
|
8698
8698
|
//#endregion
|
|
8699
8699
|
//#region src/modules/compiled-workflows/code-review.ts
|
|
8700
|
-
const logger$
|
|
8700
|
+
const logger$18 = createLogger("compiled-workflows:code-review");
|
|
8701
8701
|
/**
|
|
8702
8702
|
* Default fallback result when dispatch fails or times out.
|
|
8703
8703
|
* Uses NEEDS_MINOR_FIXES (not NEEDS_MAJOR_REWORK) so a parse/schema failure
|
|
@@ -8772,14 +8772,14 @@ async function countTestMetrics(filesModified, cwd) {
|
|
|
8772
8772
|
async function runCodeReview(deps, params) {
|
|
8773
8773
|
const { storyKey, storyFilePath, workingDirectory, pipelineRunId, filesModified, previousIssues, buildPassed, baselineCommit } = params;
|
|
8774
8774
|
const cwd = workingDirectory ?? process.cwd();
|
|
8775
|
-
logger$
|
|
8775
|
+
logger$18.debug({
|
|
8776
8776
|
storyKey,
|
|
8777
8777
|
storyFilePath,
|
|
8778
8778
|
cwd,
|
|
8779
8779
|
pipelineRunId
|
|
8780
8780
|
}, "Starting code-review workflow");
|
|
8781
8781
|
const { ceiling: TOKEN_CEILING, source: tokenCeilingSource } = getTokenCeiling("code-review", deps.tokenCeilings);
|
|
8782
|
-
logger$
|
|
8782
|
+
logger$18.info({
|
|
8783
8783
|
workflow: "code-review",
|
|
8784
8784
|
ceiling: TOKEN_CEILING,
|
|
8785
8785
|
source: tokenCeilingSource
|
|
@@ -8789,7 +8789,7 @@ async function runCodeReview(deps, params) {
|
|
|
8789
8789
|
template = await deps.pack.getPrompt("code-review");
|
|
8790
8790
|
} catch (err) {
|
|
8791
8791
|
const error = err instanceof Error ? err.message : String(err);
|
|
8792
|
-
logger$
|
|
8792
|
+
logger$18.error({ error }, "Failed to retrieve code-review prompt template");
|
|
8793
8793
|
return defaultFailResult(`Failed to retrieve prompt template: ${error}`, {
|
|
8794
8794
|
input: 0,
|
|
8795
8795
|
output: 0
|
|
@@ -8802,10 +8802,10 @@ async function runCodeReview(deps, params) {
|
|
|
8802
8802
|
const error = err instanceof Error ? err.message : String(err);
|
|
8803
8803
|
const recovered = await recoverStoryFileFromBranch(storyFilePath, cwd);
|
|
8804
8804
|
if (recovered !== void 0) {
|
|
8805
|
-
logger$
|
|
8805
|
+
logger$18.warn({ storyFilePath }, "story file missing from working tree — recovered from branch HEAD (H5.5)");
|
|
8806
8806
|
storyContent = recovered;
|
|
8807
8807
|
} else {
|
|
8808
|
-
logger$
|
|
8808
|
+
logger$18.error({
|
|
8809
8809
|
storyFilePath,
|
|
8810
8810
|
error
|
|
8811
8811
|
}, "Failed to read story file (absent from working tree AND branch HEAD)");
|
|
@@ -8826,12 +8826,12 @@ async function runCodeReview(deps, params) {
|
|
|
8826
8826
|
const scopedTotal = nonDiffTokens + countTokens(scopedDiff);
|
|
8827
8827
|
if (scopedTotal <= TOKEN_CEILING) {
|
|
8828
8828
|
gitDiffContent = scopedDiff;
|
|
8829
|
-
logger$
|
|
8829
|
+
logger$18.debug({
|
|
8830
8830
|
fileCount: filesModified.length,
|
|
8831
8831
|
tokenCount: scopedTotal
|
|
8832
8832
|
}, "Using scoped file diff");
|
|
8833
8833
|
} else {
|
|
8834
|
-
logger$
|
|
8834
|
+
logger$18.warn({
|
|
8835
8835
|
estimatedTotal: scopedTotal,
|
|
8836
8836
|
ceiling: TOKEN_CEILING,
|
|
8837
8837
|
fileCount: filesModified.length
|
|
@@ -8845,7 +8845,7 @@ async function runCodeReview(deps, params) {
|
|
|
8845
8845
|
const fullTotal = nonDiffTokens + countTokens(fullDiff);
|
|
8846
8846
|
if (fullTotal <= TOKEN_CEILING) gitDiffContent = fullDiff;
|
|
8847
8847
|
else {
|
|
8848
|
-
logger$
|
|
8848
|
+
logger$18.warn({
|
|
8849
8849
|
estimatedTotal: fullTotal,
|
|
8850
8850
|
ceiling: TOKEN_CEILING
|
|
8851
8851
|
}, "Full git diff would exceed token ceiling — using stat-only summary");
|
|
@@ -8853,7 +8853,7 @@ async function runCodeReview(deps, params) {
|
|
|
8853
8853
|
}
|
|
8854
8854
|
}
|
|
8855
8855
|
if (gitDiffContent.trim().length === 0 && baselineCommit) {
|
|
8856
|
-
logger$
|
|
8856
|
+
logger$18.info({
|
|
8857
8857
|
storyKey,
|
|
8858
8858
|
baselineCommit
|
|
8859
8859
|
}, "Working tree diff empty — diffing against baseline commit");
|
|
@@ -8861,7 +8861,7 @@ async function runCodeReview(deps, params) {
|
|
|
8861
8861
|
const commitTotal = nonDiffTokens + countTokens(commitDiff);
|
|
8862
8862
|
if (commitDiff.trim().length > 0) if (commitTotal <= TOKEN_CEILING) gitDiffContent = commitDiff;
|
|
8863
8863
|
else {
|
|
8864
|
-
logger$
|
|
8864
|
+
logger$18.warn({
|
|
8865
8865
|
estimatedTotal: commitTotal,
|
|
8866
8866
|
ceiling: TOKEN_CEILING
|
|
8867
8867
|
}, "Baseline..HEAD diff exceeds token ceiling — using stat-only summary");
|
|
@@ -8869,7 +8869,7 @@ async function runCodeReview(deps, params) {
|
|
|
8869
8869
|
}
|
|
8870
8870
|
}
|
|
8871
8871
|
if (gitDiffContent.trim().length === 0) {
|
|
8872
|
-
logger$
|
|
8872
|
+
logger$18.info({ storyKey }, "Empty git diff — skipping review with SHIP_IT");
|
|
8873
8873
|
return {
|
|
8874
8874
|
verdict: "SHIP_IT",
|
|
8875
8875
|
issues: 0,
|
|
@@ -8885,7 +8885,7 @@ async function runCodeReview(deps, params) {
|
|
|
8885
8885
|
if (deps.repoMapInjector !== void 0) {
|
|
8886
8886
|
const injection = await deps.repoMapInjector.buildContext(storyContent, deps.maxRepoMapTokens ?? 2e3);
|
|
8887
8887
|
repoContextContent = injection.text;
|
|
8888
|
-
logger$
|
|
8888
|
+
logger$18.info({
|
|
8889
8889
|
storyKey,
|
|
8890
8890
|
repoMapTokens: Math.ceil(injection.text.length / 4),
|
|
8891
8891
|
symbolCount: injection.symbolCount,
|
|
@@ -8905,17 +8905,17 @@ async function runCodeReview(deps, params) {
|
|
|
8905
8905
|
const findings = await getProjectFindings(deps.db);
|
|
8906
8906
|
if (findings.length > 0) {
|
|
8907
8907
|
priorFindingsContent = "Previous reviews found these recurring patterns — pay special attention:\n\n" + findings;
|
|
8908
|
-
logger$
|
|
8908
|
+
logger$18.debug({
|
|
8909
8909
|
storyKey,
|
|
8910
8910
|
findingsLen: findings.length
|
|
8911
8911
|
}, "Injecting prior findings into code-review prompt");
|
|
8912
8912
|
}
|
|
8913
8913
|
} catch {}
|
|
8914
8914
|
const testMetricsContent = await countTestMetrics(filesModified, cwd);
|
|
8915
|
-
if (testMetricsContent) logger$
|
|
8915
|
+
if (testMetricsContent) logger$18.debug({ storyKey }, "Injecting verified test-count metrics into code-review context");
|
|
8916
8916
|
const fileDiffs = gitDiffContent ? parseDiffByFile(gitDiffContent) : void 0;
|
|
8917
8917
|
const scopeAnalysisContent = storyContent && filesModified ? ScopeGuardrail.buildAnalysis(storyContent, filesModified, fileDiffs) : "";
|
|
8918
|
-
if (scopeAnalysisContent) logger$
|
|
8918
|
+
if (scopeAnalysisContent) logger$18.debug({ storyKey }, "Scope analysis detected out-of-scope files");
|
|
8919
8919
|
const buildStatusPrefix = buildPassed === true ? "BUILD STATUS: PASSED — code compiles and passes build verification. Focus on logic correctness, style, and acceptance criteria rather than compilation errors.\n\n" : "";
|
|
8920
8920
|
const sections = [
|
|
8921
8921
|
{
|
|
@@ -8960,11 +8960,11 @@ async function runCodeReview(deps, params) {
|
|
|
8960
8960
|
}
|
|
8961
8961
|
];
|
|
8962
8962
|
const assembleResult = assemblePrompt(template, sections, TOKEN_CEILING);
|
|
8963
|
-
if (assembleResult.truncated) logger$
|
|
8963
|
+
if (assembleResult.truncated) logger$18.warn({
|
|
8964
8964
|
storyKey,
|
|
8965
8965
|
tokenCount: assembleResult.tokenCount
|
|
8966
8966
|
}, "Code-review prompt truncated to fit token ceiling");
|
|
8967
|
-
logger$
|
|
8967
|
+
logger$18.debug({
|
|
8968
8968
|
storyKey,
|
|
8969
8969
|
tokenCount: assembleResult.tokenCount,
|
|
8970
8970
|
truncated: assembleResult.truncated
|
|
@@ -8985,7 +8985,7 @@ async function runCodeReview(deps, params) {
|
|
|
8985
8985
|
dispatchResult = await handle.result;
|
|
8986
8986
|
} catch (err) {
|
|
8987
8987
|
const error = err instanceof Error ? err.message : String(err);
|
|
8988
|
-
logger$
|
|
8988
|
+
logger$18.error({
|
|
8989
8989
|
storyKey,
|
|
8990
8990
|
error
|
|
8991
8991
|
}, "Code-review dispatch threw unexpected error");
|
|
@@ -9001,7 +9001,7 @@ async function runCodeReview(deps, params) {
|
|
|
9001
9001
|
const rawOutput = dispatchResult.output ?? void 0;
|
|
9002
9002
|
if (dispatchResult.status === "failed") {
|
|
9003
9003
|
const errorMsg = `Dispatch status: failed. Exit code: ${dispatchResult.exitCode}. ${dispatchResult.parseError ?? ""} ${dispatchResult.output ? `Stderr: ${dispatchResult.output}` : ""}`.trim();
|
|
9004
|
-
logger$
|
|
9004
|
+
logger$18.warn({
|
|
9005
9005
|
storyKey,
|
|
9006
9006
|
exitCode: dispatchResult.exitCode
|
|
9007
9007
|
}, "Code-review dispatch failed");
|
|
@@ -9011,7 +9011,7 @@ async function runCodeReview(deps, params) {
|
|
|
9011
9011
|
};
|
|
9012
9012
|
}
|
|
9013
9013
|
if (dispatchResult.status === "timeout") {
|
|
9014
|
-
logger$
|
|
9014
|
+
logger$18.warn({ storyKey }, "Code-review dispatch timed out");
|
|
9015
9015
|
return {
|
|
9016
9016
|
...defaultFailResult("Dispatch status: timeout. The agent did not complete within the allowed time.", tokenUsage),
|
|
9017
9017
|
rawOutput
|
|
@@ -9019,7 +9019,7 @@ async function runCodeReview(deps, params) {
|
|
|
9019
9019
|
}
|
|
9020
9020
|
if (dispatchResult.parsed === null) {
|
|
9021
9021
|
const details = dispatchResult.parseError ?? "No YAML block found in output";
|
|
9022
|
-
logger$
|
|
9022
|
+
logger$18.warn({
|
|
9023
9023
|
storyKey,
|
|
9024
9024
|
details
|
|
9025
9025
|
}, "Code-review output schema validation failed");
|
|
@@ -9037,7 +9037,7 @@ async function runCodeReview(deps, params) {
|
|
|
9037
9037
|
const parseResult = CodeReviewResultSchema.safeParse(dispatchResult.parsed);
|
|
9038
9038
|
if (!parseResult.success) {
|
|
9039
9039
|
const details = parseResult.error.message;
|
|
9040
|
-
logger$
|
|
9040
|
+
logger$18.warn({
|
|
9041
9041
|
storyKey,
|
|
9042
9042
|
details
|
|
9043
9043
|
}, "Code-review output failed schema validation");
|
|
@@ -9053,13 +9053,13 @@ async function runCodeReview(deps, params) {
|
|
|
9053
9053
|
};
|
|
9054
9054
|
}
|
|
9055
9055
|
const parsed = parseResult.data;
|
|
9056
|
-
if (parsed.agentVerdict !== parsed.verdict) logger$
|
|
9056
|
+
if (parsed.agentVerdict !== parsed.verdict) logger$18.info({
|
|
9057
9057
|
storyKey,
|
|
9058
9058
|
agentVerdict: parsed.agentVerdict,
|
|
9059
9059
|
pipelineVerdict: parsed.verdict,
|
|
9060
9060
|
issues: parsed.issues
|
|
9061
9061
|
}, "Pipeline overrode agent verdict based on issue severities");
|
|
9062
|
-
logger$
|
|
9062
|
+
logger$18.info({
|
|
9063
9063
|
storyKey,
|
|
9064
9064
|
verdict: parsed.verdict,
|
|
9065
9065
|
issues: parsed.issues
|
|
@@ -9085,14 +9085,14 @@ async function getArchConstraints$2(deps) {
|
|
|
9085
9085
|
if (constraints.length === 0) return "";
|
|
9086
9086
|
return constraints.map((d) => `${d.key}: ${d.value}`).join("\n");
|
|
9087
9087
|
} catch (err) {
|
|
9088
|
-
logger$
|
|
9088
|
+
logger$18.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve architecture constraints");
|
|
9089
9089
|
return "";
|
|
9090
9090
|
}
|
|
9091
9091
|
}
|
|
9092
9092
|
|
|
9093
9093
|
//#endregion
|
|
9094
9094
|
//#region src/modules/compiled-workflows/merge-to-main.ts
|
|
9095
|
-
const logger$
|
|
9095
|
+
const logger$17 = createLogger("compiled-workflows:merge-to-main");
|
|
9096
9096
|
/**
|
|
9097
9097
|
* Execute the merge-to-main phase: merge the story branch into the base branch.
|
|
9098
9098
|
*
|
|
@@ -9112,7 +9112,7 @@ const logger$16 = createLogger("compiled-workflows:merge-to-main");
|
|
|
9112
9112
|
async function runMergeToMain(params) {
|
|
9113
9113
|
const { storyKey, branchName, startBranch, worktreeManager, eventBus, projectRoot } = params;
|
|
9114
9114
|
const mergeStrategy = params.mergeStrategy ?? "ff-only";
|
|
9115
|
-
logger$
|
|
9115
|
+
logger$17.info({
|
|
9116
9116
|
storyKey,
|
|
9117
9117
|
branchName,
|
|
9118
9118
|
startBranch,
|
|
@@ -9120,7 +9120,7 @@ async function runMergeToMain(params) {
|
|
|
9120
9120
|
}, "Starting merge-to-main phase");
|
|
9121
9121
|
const dirtiedFiles = listParentDirtyIntersection(branchName, startBranch, projectRoot);
|
|
9122
9122
|
if (dirtiedFiles.length > 0) {
|
|
9123
|
-
logger$
|
|
9123
|
+
logger$17.warn({
|
|
9124
9124
|
storyKey,
|
|
9125
9125
|
branchName,
|
|
9126
9126
|
dirtiedFiles
|
|
@@ -9133,7 +9133,7 @@ async function runMergeToMain(params) {
|
|
|
9133
9133
|
}
|
|
9134
9134
|
const ffSuccess = tryFfMerge(branchName, projectRoot);
|
|
9135
9135
|
if (ffSuccess) {
|
|
9136
|
-
logger$
|
|
9136
|
+
logger$17.info({
|
|
9137
9137
|
storyKey,
|
|
9138
9138
|
branchName
|
|
9139
9139
|
}, "Fast-forward merge succeeded");
|
|
@@ -9141,7 +9141,7 @@ async function runMergeToMain(params) {
|
|
|
9141
9141
|
return { success: true };
|
|
9142
9142
|
}
|
|
9143
9143
|
if (mergeStrategy === "ff-only") {
|
|
9144
|
-
logger$
|
|
9144
|
+
logger$17.warn({
|
|
9145
9145
|
storyKey,
|
|
9146
9146
|
branchName,
|
|
9147
9147
|
startBranch
|
|
@@ -9151,13 +9151,13 @@ async function runMergeToMain(params) {
|
|
|
9151
9151
|
reason: "ff-only-merge-not-possible"
|
|
9152
9152
|
};
|
|
9153
9153
|
}
|
|
9154
|
-
logger$
|
|
9154
|
+
logger$17.info({
|
|
9155
9155
|
storyKey,
|
|
9156
9156
|
branchName
|
|
9157
9157
|
}, "Fast-forward merge failed — attempting 3-way merge");
|
|
9158
9158
|
const threeWayResult = tryThreeWayMerge(branchName, projectRoot);
|
|
9159
9159
|
if (threeWayResult.success) {
|
|
9160
|
-
logger$
|
|
9160
|
+
logger$17.info({
|
|
9161
9161
|
storyKey,
|
|
9162
9162
|
branchName
|
|
9163
9163
|
}, "3-way merge succeeded");
|
|
@@ -9165,7 +9165,7 @@ async function runMergeToMain(params) {
|
|
|
9165
9165
|
return { success: true };
|
|
9166
9166
|
}
|
|
9167
9167
|
const { conflictingFiles } = threeWayResult;
|
|
9168
|
-
logger$
|
|
9168
|
+
logger$17.warn({
|
|
9169
9169
|
storyKey,
|
|
9170
9170
|
branchName,
|
|
9171
9171
|
conflictingFiles
|
|
@@ -9218,7 +9218,7 @@ function listParentDirtyIntersection(branchName, startBranch, projectRoot) {
|
|
|
9218
9218
|
});
|
|
9219
9219
|
return diffOut.split("\n").filter((f$1) => f$1.trim().length > 0).filter((f$1) => dirty.has(f$1));
|
|
9220
9220
|
} catch (err) {
|
|
9221
|
-
logger$
|
|
9221
|
+
logger$17.warn({ err }, "parent-clean precondition check failed (best-effort) — proceeding to merge");
|
|
9222
9222
|
return [];
|
|
9223
9223
|
}
|
|
9224
9224
|
}
|
|
@@ -9295,7 +9295,7 @@ function tryThreeWayMerge(branchName, projectRoot) {
|
|
|
9295
9295
|
});
|
|
9296
9296
|
conflictingFiles = diffOutput.trim().split("\n").filter((line) => line.length > 0);
|
|
9297
9297
|
} catch (diffErr) {
|
|
9298
|
-
logger$
|
|
9298
|
+
logger$17.warn({ err: diffErr }, "Failed to list conflicting files (best-effort)");
|
|
9299
9299
|
}
|
|
9300
9300
|
try {
|
|
9301
9301
|
execFileSync("git", ["merge", "--abort"], {
|
|
@@ -9307,7 +9307,7 @@ function tryThreeWayMerge(branchName, projectRoot) {
|
|
|
9307
9307
|
]
|
|
9308
9308
|
});
|
|
9309
9309
|
} catch (abortErr) {
|
|
9310
|
-
logger$
|
|
9310
|
+
logger$17.warn({ err: abortErr }, "Failed to abort merge (best-effort)");
|
|
9311
9311
|
}
|
|
9312
9312
|
return {
|
|
9313
9313
|
success: false,
|
|
@@ -9329,12 +9329,12 @@ function tryThreeWayMerge(branchName, projectRoot) {
|
|
|
9329
9329
|
async function cleanupAfterSuccessfulMerge(storyKey, branchName, worktreeManager, _projectRoot) {
|
|
9330
9330
|
try {
|
|
9331
9331
|
await worktreeManager.cleanupWorktree(storyKey);
|
|
9332
|
-
logger$
|
|
9332
|
+
logger$17.info({
|
|
9333
9333
|
storyKey,
|
|
9334
9334
|
branchName
|
|
9335
9335
|
}, "Worktree + branch removed after successful merge");
|
|
9336
9336
|
} catch (worktreeErr) {
|
|
9337
|
-
logger$
|
|
9337
|
+
logger$17.warn({
|
|
9338
9338
|
storyKey,
|
|
9339
9339
|
err: worktreeErr
|
|
9340
9340
|
}, "Failed to remove worktree (best-effort)");
|
|
@@ -9363,7 +9363,7 @@ function createMergeQueue() {
|
|
|
9363
9363
|
|
|
9364
9364
|
//#endregion
|
|
9365
9365
|
//#region src/modules/compiled-workflows/test-plan.ts
|
|
9366
|
-
const logger$
|
|
9366
|
+
const logger$16 = createLogger("compiled-workflows:test-plan");
|
|
9367
9367
|
/** Default timeout for test-plan dispatches in milliseconds (5 min — lightweight call) */
|
|
9368
9368
|
const DEFAULT_TIMEOUT_MS$1 = 3e5;
|
|
9369
9369
|
/**
|
|
@@ -9375,12 +9375,12 @@ const DEFAULT_TIMEOUT_MS$1 = 3e5;
|
|
|
9375
9375
|
*/
|
|
9376
9376
|
async function runTestPlan(deps, params) {
|
|
9377
9377
|
const { storyKey, storyFilePath, pipelineRunId } = params;
|
|
9378
|
-
logger$
|
|
9378
|
+
logger$16.info({
|
|
9379
9379
|
storyKey,
|
|
9380
9380
|
storyFilePath
|
|
9381
9381
|
}, "Starting compiled test-plan workflow");
|
|
9382
9382
|
const { ceiling: TOKEN_CEILING, source: tokenCeilingSource } = getTokenCeiling("test-plan", deps.tokenCeilings);
|
|
9383
|
-
logger$
|
|
9383
|
+
logger$16.info({
|
|
9384
9384
|
workflow: "test-plan",
|
|
9385
9385
|
ceiling: TOKEN_CEILING,
|
|
9386
9386
|
source: tokenCeilingSource
|
|
@@ -9388,10 +9388,10 @@ async function runTestPlan(deps, params) {
|
|
|
9388
9388
|
let template;
|
|
9389
9389
|
try {
|
|
9390
9390
|
template = await deps.pack.getPrompt("test-plan");
|
|
9391
|
-
logger$
|
|
9391
|
+
logger$16.debug({ storyKey }, "Retrieved test-plan prompt template from pack");
|
|
9392
9392
|
} catch (err) {
|
|
9393
9393
|
const error = err instanceof Error ? err.message : String(err);
|
|
9394
|
-
logger$
|
|
9394
|
+
logger$16.warn({
|
|
9395
9395
|
storyKey,
|
|
9396
9396
|
error
|
|
9397
9397
|
}, "Failed to retrieve test-plan prompt template");
|
|
@@ -9402,14 +9402,14 @@ async function runTestPlan(deps, params) {
|
|
|
9402
9402
|
storyContent = await readFile$1(storyFilePath, "utf-8");
|
|
9403
9403
|
} catch (err) {
|
|
9404
9404
|
if (err.code === "ENOENT") {
|
|
9405
|
-
logger$
|
|
9405
|
+
logger$16.warn({
|
|
9406
9406
|
storyKey,
|
|
9407
9407
|
storyFilePath
|
|
9408
9408
|
}, "Story file not found for test planning");
|
|
9409
9409
|
return makeTestPlanFailureResult("story_file_not_found");
|
|
9410
9410
|
}
|
|
9411
9411
|
const error = err instanceof Error ? err.message : String(err);
|
|
9412
|
-
logger$
|
|
9412
|
+
logger$16.warn({
|
|
9413
9413
|
storyKey,
|
|
9414
9414
|
storyFilePath,
|
|
9415
9415
|
error
|
|
@@ -9423,13 +9423,13 @@ async function runTestPlan(deps, params) {
|
|
|
9423
9423
|
const testPatternDecisions = solutioningDecisions.filter((d) => d.category === "test-patterns");
|
|
9424
9424
|
if (testPatternDecisions.length > 0) {
|
|
9425
9425
|
testPatternsContent = "## Test Patterns\n" + testPatternDecisions.map((d) => `- ${d.key}: ${d.value}`).join("\n");
|
|
9426
|
-
logger$
|
|
9426
|
+
logger$16.debug({
|
|
9427
9427
|
storyKey,
|
|
9428
9428
|
count: testPatternDecisions.length
|
|
9429
9429
|
}, "Loaded test patterns from decision store");
|
|
9430
9430
|
} else {
|
|
9431
9431
|
testPatternsContent = resolveDefaultTestPatterns(deps.projectRoot);
|
|
9432
|
-
logger$
|
|
9432
|
+
logger$16.debug({ storyKey }, "No test-pattern decisions — using stack-aware defaults");
|
|
9433
9433
|
}
|
|
9434
9434
|
} catch {
|
|
9435
9435
|
testPatternsContent = resolveDefaultTestPatterns(deps.projectRoot);
|
|
@@ -9451,7 +9451,7 @@ async function runTestPlan(deps, params) {
|
|
|
9451
9451
|
priority: "optional"
|
|
9452
9452
|
}
|
|
9453
9453
|
], TOKEN_CEILING);
|
|
9454
|
-
logger$
|
|
9454
|
+
logger$16.info({
|
|
9455
9455
|
storyKey,
|
|
9456
9456
|
tokenCount,
|
|
9457
9457
|
ceiling: TOKEN_CEILING,
|
|
@@ -9472,7 +9472,7 @@ async function runTestPlan(deps, params) {
|
|
|
9472
9472
|
dispatchResult = await handle.result;
|
|
9473
9473
|
} catch (err) {
|
|
9474
9474
|
const error = err instanceof Error ? err.message : String(err);
|
|
9475
|
-
logger$
|
|
9475
|
+
logger$16.warn({
|
|
9476
9476
|
storyKey,
|
|
9477
9477
|
error
|
|
9478
9478
|
}, "Test-plan dispatch threw an unexpected error");
|
|
@@ -9483,7 +9483,7 @@ async function runTestPlan(deps, params) {
|
|
|
9483
9483
|
output: dispatchResult.tokenEstimate.output
|
|
9484
9484
|
};
|
|
9485
9485
|
if (dispatchResult.status === "timeout") {
|
|
9486
|
-
logger$
|
|
9486
|
+
logger$16.warn({
|
|
9487
9487
|
storyKey,
|
|
9488
9488
|
durationMs: dispatchResult.durationMs
|
|
9489
9489
|
}, "Test-plan dispatch timed out");
|
|
@@ -9493,7 +9493,7 @@ async function runTestPlan(deps, params) {
|
|
|
9493
9493
|
};
|
|
9494
9494
|
}
|
|
9495
9495
|
if (dispatchResult.status === "failed" || dispatchResult.exitCode !== 0) {
|
|
9496
|
-
logger$
|
|
9496
|
+
logger$16.warn({
|
|
9497
9497
|
storyKey,
|
|
9498
9498
|
exitCode: dispatchResult.exitCode,
|
|
9499
9499
|
status: dispatchResult.status
|
|
@@ -9505,7 +9505,7 @@ async function runTestPlan(deps, params) {
|
|
|
9505
9505
|
}
|
|
9506
9506
|
if (dispatchResult.parseError !== null || dispatchResult.parsed === null) {
|
|
9507
9507
|
const details = dispatchResult.parseError ?? "parsed result was null";
|
|
9508
|
-
logger$
|
|
9508
|
+
logger$16.warn({
|
|
9509
9509
|
storyKey,
|
|
9510
9510
|
parseError: details
|
|
9511
9511
|
}, "Test-plan YAML schema validation failed");
|
|
@@ -9528,19 +9528,19 @@ async function runTestPlan(deps, params) {
|
|
|
9528
9528
|
}),
|
|
9529
9529
|
rationale: `Test plan for ${storyKey}: ${parsed.test_files.length} test files, categories: ${parsed.test_categories.join(", ")}`
|
|
9530
9530
|
});
|
|
9531
|
-
logger$
|
|
9531
|
+
logger$16.info({
|
|
9532
9532
|
storyKey,
|
|
9533
9533
|
fileCount: parsed.test_files.length,
|
|
9534
9534
|
categories: parsed.test_categories
|
|
9535
9535
|
}, "Test plan stored in decision store");
|
|
9536
9536
|
} catch (err) {
|
|
9537
9537
|
const error = err instanceof Error ? err.message : String(err);
|
|
9538
|
-
logger$
|
|
9538
|
+
logger$16.warn({
|
|
9539
9539
|
storyKey,
|
|
9540
9540
|
error
|
|
9541
9541
|
}, "Failed to store test plan in decision store — proceeding anyway");
|
|
9542
9542
|
}
|
|
9543
|
-
logger$
|
|
9543
|
+
logger$16.info({
|
|
9544
9544
|
storyKey,
|
|
9545
9545
|
result: parsed.result
|
|
9546
9546
|
}, "Test-plan workflow completed");
|
|
@@ -9580,14 +9580,14 @@ async function getArchConstraints$1(deps) {
|
|
|
9580
9580
|
if (constraints.length === 0) return "";
|
|
9581
9581
|
return constraints.map((d) => `${d.key}: ${d.value}`).join("\n");
|
|
9582
9582
|
} catch (err) {
|
|
9583
|
-
logger$
|
|
9583
|
+
logger$16.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve architecture constraints for test-plan — proceeding without them");
|
|
9584
9584
|
return "";
|
|
9585
9585
|
}
|
|
9586
9586
|
}
|
|
9587
9587
|
|
|
9588
9588
|
//#endregion
|
|
9589
9589
|
//#region src/modules/implementation-orchestrator/probe-author-integration.ts
|
|
9590
|
-
const logger$
|
|
9590
|
+
const logger$15 = createLogger("implementation-orchestrator:probe-author");
|
|
9591
9591
|
/**
|
|
9592
9592
|
* Default timeout for probe-author dispatches (10 min).
|
|
9593
9593
|
* obs_2026-05-04_023 layer 2: raised from 300_000 → 600_000 after Story
|
|
@@ -9638,7 +9638,7 @@ async function runProbeAuthor(deps, params) {
|
|
|
9638
9638
|
};
|
|
9639
9639
|
const stateIntegratingActive = stateIntegratingEnabled !== false;
|
|
9640
9640
|
if (bypassGates !== true && !detectsEventDrivenAC(epicContent) && !(stateIntegratingActive && detectsStateIntegratingAC(epicContent))) {
|
|
9641
|
-
logger$
|
|
9641
|
+
logger$15.debug({ storyKey }, "probe-author: source AC neither event-driven nor state-integrating — skipping");
|
|
9642
9642
|
emitEvent?.("probe-author:skipped", {
|
|
9643
9643
|
storyKey,
|
|
9644
9644
|
runId: pipelineRunId,
|
|
@@ -9650,7 +9650,7 @@ async function runProbeAuthor(deps, params) {
|
|
|
9650
9650
|
try {
|
|
9651
9651
|
storyContent = await readFile$1(storyFilePath, "utf-8");
|
|
9652
9652
|
if (bypassGates !== true && /^## Runtime Probes/m.test(storyContent)) {
|
|
9653
|
-
logger$
|
|
9653
|
+
logger$15.info({ storyKey }, "probe-author: story artifact already has ## Runtime Probes — skipping");
|
|
9654
9654
|
emitEvent?.("probe-author:skipped", {
|
|
9655
9655
|
storyKey,
|
|
9656
9656
|
runId: pipelineRunId,
|
|
@@ -9660,7 +9660,7 @@ async function runProbeAuthor(deps, params) {
|
|
|
9660
9660
|
}
|
|
9661
9661
|
} catch (err) {
|
|
9662
9662
|
const error = err instanceof Error ? err.message : String(err);
|
|
9663
|
-
logger$
|
|
9663
|
+
logger$15.warn({
|
|
9664
9664
|
storyKey,
|
|
9665
9665
|
error
|
|
9666
9666
|
}, "probe-author: failed to read story file — falling through");
|
|
@@ -9675,10 +9675,10 @@ async function runProbeAuthor(deps, params) {
|
|
|
9675
9675
|
let template;
|
|
9676
9676
|
try {
|
|
9677
9677
|
template = await deps.pack.getPrompt("probe-author");
|
|
9678
|
-
logger$
|
|
9678
|
+
logger$15.debug({ storyKey }, "probe-author: retrieved prompt template");
|
|
9679
9679
|
} catch (err) {
|
|
9680
9680
|
const error = err instanceof Error ? err.message : String(err);
|
|
9681
|
-
logger$
|
|
9681
|
+
logger$15.warn({
|
|
9682
9682
|
storyKey,
|
|
9683
9683
|
error
|
|
9684
9684
|
}, "probe-author: failed to get prompt template — falling through");
|
|
@@ -9713,13 +9713,13 @@ async function runProbeAuthor(deps, params) {
|
|
|
9713
9713
|
};
|
|
9714
9714
|
let dispatchResult;
|
|
9715
9715
|
try {
|
|
9716
|
-
logger$
|
|
9716
|
+
logger$15.info({ storyKey }, "probe-author: dispatching probe-author agent");
|
|
9717
9717
|
dispatchResult = await doDispatch(basePrompt, DEFAULT_TIMEOUT_MS);
|
|
9718
9718
|
tokenUsage.input += dispatchResult.tokenEstimate.input;
|
|
9719
9719
|
tokenUsage.output += dispatchResult.tokenEstimate.output;
|
|
9720
9720
|
} catch (err) {
|
|
9721
9721
|
const error = err instanceof Error ? err.message : String(err);
|
|
9722
|
-
logger$
|
|
9722
|
+
logger$15.warn({
|
|
9723
9723
|
storyKey,
|
|
9724
9724
|
error
|
|
9725
9725
|
}, "probe-author: dispatch error — falling through to dev-story");
|
|
@@ -9732,7 +9732,7 @@ async function runProbeAuthor(deps, params) {
|
|
|
9732
9732
|
}
|
|
9733
9733
|
if (dispatchResult.status === "timeout") {
|
|
9734
9734
|
const elapsedMs = Date.now() - start;
|
|
9735
|
-
logger$
|
|
9735
|
+
logger$15.warn({
|
|
9736
9736
|
storyKey,
|
|
9737
9737
|
elapsedMs
|
|
9738
9738
|
}, "probe-author: dispatch timed out — retrying with 1.5× timeout");
|
|
@@ -9746,13 +9746,13 @@ async function runProbeAuthor(deps, params) {
|
|
|
9746
9746
|
tokenUsage.input += retryResult.tokenEstimate.input;
|
|
9747
9747
|
tokenUsage.output += retryResult.tokenEstimate.output;
|
|
9748
9748
|
if (retryResult.status === "timeout") {
|
|
9749
|
-
logger$
|
|
9749
|
+
logger$15.warn({ storyKey }, "probe-author: retry also timed out — falling through to dev-story");
|
|
9750
9750
|
return makeFailedResult("dispatch_timeout", tokenUsage, start);
|
|
9751
9751
|
}
|
|
9752
9752
|
dispatchResult = retryResult;
|
|
9753
9753
|
} catch (retryErr) {
|
|
9754
9754
|
const error = retryErr instanceof Error ? retryErr.message : String(retryErr);
|
|
9755
|
-
logger$
|
|
9755
|
+
logger$15.warn({
|
|
9756
9756
|
storyKey,
|
|
9757
9757
|
error
|
|
9758
9758
|
}, "probe-author: retry dispatch error — falling through to dev-story");
|
|
@@ -9761,7 +9761,7 @@ async function runProbeAuthor(deps, params) {
|
|
|
9761
9761
|
}
|
|
9762
9762
|
if (dispatchResult.status === "failed" || dispatchResult.exitCode !== 0) {
|
|
9763
9763
|
const error = `dispatch_failed with exit_code=${dispatchResult.exitCode}`;
|
|
9764
|
-
logger$
|
|
9764
|
+
logger$15.warn({ storyKey }, `probe-author: ${error} — falling through to dev-story`);
|
|
9765
9765
|
emitEvent?.("probe-author:dispatch-error", {
|
|
9766
9766
|
storyKey,
|
|
9767
9767
|
runId: pipelineRunId,
|
|
@@ -9772,7 +9772,7 @@ async function runProbeAuthor(deps, params) {
|
|
|
9772
9772
|
if (dispatchResult.parseError !== null || dispatchResult.parsed === null) {
|
|
9773
9773
|
const parseError = dispatchResult.parseError ?? "parsed result was null";
|
|
9774
9774
|
const rawOutputSnippet = dispatchResult.output.slice(0, 500);
|
|
9775
|
-
logger$
|
|
9775
|
+
logger$15.warn({
|
|
9776
9776
|
storyKey,
|
|
9777
9777
|
parseError,
|
|
9778
9778
|
rawOutputSnippet
|
|
@@ -9789,13 +9789,13 @@ async function runProbeAuthor(deps, params) {
|
|
|
9789
9789
|
tokenUsage.input += retryResult.tokenEstimate.input;
|
|
9790
9790
|
tokenUsage.output += retryResult.tokenEstimate.output;
|
|
9791
9791
|
if (retryResult.parseError !== null || retryResult.parsed === null) {
|
|
9792
|
-
logger$
|
|
9792
|
+
logger$15.warn({ storyKey }, "probe-author: retry still produced invalid YAML — falling through");
|
|
9793
9793
|
return makeFailedResult("invalid_yaml_after_retry", tokenUsage, start);
|
|
9794
9794
|
}
|
|
9795
9795
|
dispatchResult = retryResult;
|
|
9796
9796
|
} catch (retryErr) {
|
|
9797
9797
|
const error = retryErr instanceof Error ? retryErr.message : String(retryErr);
|
|
9798
|
-
logger$
|
|
9798
|
+
logger$15.warn({
|
|
9799
9799
|
storyKey,
|
|
9800
9800
|
error
|
|
9801
9801
|
}, "probe-author: retry error after invalid YAML — falling through");
|
|
@@ -9806,7 +9806,7 @@ async function runProbeAuthor(deps, params) {
|
|
|
9806
9806
|
const probeValidation = RuntimeProbeListSchema.safeParse(parsedOutput.probes);
|
|
9807
9807
|
if (!probeValidation.success) {
|
|
9808
9808
|
const validationError = probeValidation.error.message;
|
|
9809
|
-
logger$
|
|
9809
|
+
logger$15.warn({
|
|
9810
9810
|
storyKey,
|
|
9811
9811
|
validationError
|
|
9812
9812
|
}, "probe-author: probes failed RuntimeProbeListSchema — falling through");
|
|
@@ -9822,7 +9822,7 @@ async function runProbeAuthor(deps, params) {
|
|
|
9822
9822
|
probesParsedCount: probes.length
|
|
9823
9823
|
});
|
|
9824
9824
|
if (probes.length === 0) {
|
|
9825
|
-
logger$
|
|
9825
|
+
logger$15.info({ storyKey }, "probe-author: authored empty probes list — no probes needed");
|
|
9826
9826
|
emitEvent?.("probe-author:no-probes-authored", {
|
|
9827
9827
|
storyKey,
|
|
9828
9828
|
runId: pipelineRunId
|
|
@@ -9837,7 +9837,7 @@ async function runProbeAuthor(deps, params) {
|
|
|
9837
9837
|
try {
|
|
9838
9838
|
const refreshedContent = await readFile$1(storyFilePath, "utf-8");
|
|
9839
9839
|
if (/^## Runtime Probes/m.test(refreshedContent)) {
|
|
9840
|
-
logger$
|
|
9840
|
+
logger$15.info({ storyKey }, "probe-author: ## Runtime Probes section appeared after dispatch — skipping append (idempotent)");
|
|
9841
9841
|
const dispatchDurationMs$1 = Date.now() - start;
|
|
9842
9842
|
emitEvent?.("probe-author:dispatched", {
|
|
9843
9843
|
storyKey,
|
|
@@ -9856,7 +9856,7 @@ async function runProbeAuthor(deps, params) {
|
|
|
9856
9856
|
const tmpPath = join$1(targetDir, `.probe-author-${Date.now()}.tmp.md`);
|
|
9857
9857
|
await writeFile$1(tmpPath, newContent, "utf-8");
|
|
9858
9858
|
await rename(tmpPath, storyFilePath);
|
|
9859
|
-
logger$
|
|
9859
|
+
logger$15.info({
|
|
9860
9860
|
storyKey,
|
|
9861
9861
|
probesCount: probes.length
|
|
9862
9862
|
}, "probe-author: appended ## Runtime Probes section");
|
|
@@ -9868,7 +9868,7 @@ async function runProbeAuthor(deps, params) {
|
|
|
9868
9868
|
});
|
|
9869
9869
|
} catch (err) {
|
|
9870
9870
|
const error = err instanceof Error ? err.message : String(err);
|
|
9871
|
-
logger$
|
|
9871
|
+
logger$15.warn({
|
|
9872
9872
|
storyKey,
|
|
9873
9873
|
error
|
|
9874
9874
|
}, "probe-author: failed to append probes — falling through to dev-story");
|
|
@@ -9890,7 +9890,7 @@ async function runProbeAuthor(deps, params) {
|
|
|
9890
9890
|
costUsd,
|
|
9891
9891
|
triggered_by: triggerClass ?? "event-driven"
|
|
9892
9892
|
});
|
|
9893
|
-
logger$
|
|
9893
|
+
logger$15.info({
|
|
9894
9894
|
storyKey,
|
|
9895
9895
|
probesAuthoredCount: probes.length
|
|
9896
9896
|
}, "probe-author: phase complete");
|
|
@@ -9925,7 +9925,7 @@ function estimateDispatchCost$1(input, output) {
|
|
|
9925
9925
|
|
|
9926
9926
|
//#endregion
|
|
9927
9927
|
//#region src/modules/compiled-workflows/test-expansion.ts
|
|
9928
|
-
const logger$
|
|
9928
|
+
const logger$14 = createLogger("compiled-workflows:test-expansion");
|
|
9929
9929
|
function defaultFallbackResult(error, tokenUsage) {
|
|
9930
9930
|
return {
|
|
9931
9931
|
expansion_priority: "low",
|
|
@@ -9955,14 +9955,14 @@ function defaultFallbackResult(error, tokenUsage) {
|
|
|
9955
9955
|
async function runTestExpansion(deps, params) {
|
|
9956
9956
|
const { storyKey, storyFilePath, pipelineRunId, filesModified, workingDirectory } = params;
|
|
9957
9957
|
const cwd = workingDirectory ?? process.cwd();
|
|
9958
|
-
logger$
|
|
9958
|
+
logger$14.debug({
|
|
9959
9959
|
storyKey,
|
|
9960
9960
|
storyFilePath,
|
|
9961
9961
|
cwd,
|
|
9962
9962
|
pipelineRunId
|
|
9963
9963
|
}, "Starting test-expansion workflow");
|
|
9964
9964
|
const { ceiling: TOKEN_CEILING, source: tokenCeilingSource } = getTokenCeiling("test-expansion", deps.tokenCeilings);
|
|
9965
|
-
logger$
|
|
9965
|
+
logger$14.info({
|
|
9966
9966
|
workflow: "test-expansion",
|
|
9967
9967
|
ceiling: TOKEN_CEILING,
|
|
9968
9968
|
source: tokenCeilingSource
|
|
@@ -9972,7 +9972,7 @@ async function runTestExpansion(deps, params) {
|
|
|
9972
9972
|
template = await deps.pack.getPrompt("test-expansion");
|
|
9973
9973
|
} catch (err) {
|
|
9974
9974
|
const error = err instanceof Error ? err.message : String(err);
|
|
9975
|
-
logger$
|
|
9975
|
+
logger$14.warn({ error }, "Failed to retrieve test-expansion prompt template");
|
|
9976
9976
|
return defaultFallbackResult(`Failed to retrieve prompt template: ${error}`, {
|
|
9977
9977
|
input: 0,
|
|
9978
9978
|
output: 0
|
|
@@ -9983,7 +9983,7 @@ async function runTestExpansion(deps, params) {
|
|
|
9983
9983
|
storyContent = await readFile$1(storyFilePath, "utf-8");
|
|
9984
9984
|
} catch (err) {
|
|
9985
9985
|
const error = err instanceof Error ? err.message : String(err);
|
|
9986
|
-
logger$
|
|
9986
|
+
logger$14.warn({
|
|
9987
9987
|
storyFilePath,
|
|
9988
9988
|
error
|
|
9989
9989
|
}, "Failed to read story file");
|
|
@@ -9999,13 +9999,13 @@ async function runTestExpansion(deps, params) {
|
|
|
9999
9999
|
const testPatternDecisions = solutioningDecisions.filter((d) => d.category === "test-patterns");
|
|
10000
10000
|
if (testPatternDecisions.length > 0) {
|
|
10001
10001
|
testPatternsContent = "## Test Patterns\n" + testPatternDecisions.map((d) => `- ${d.key}: ${d.value}`).join("\n");
|
|
10002
|
-
logger$
|
|
10002
|
+
logger$14.debug({
|
|
10003
10003
|
storyKey,
|
|
10004
10004
|
count: testPatternDecisions.length
|
|
10005
10005
|
}, "Loaded test patterns from decision store");
|
|
10006
10006
|
} else {
|
|
10007
10007
|
testPatternsContent = resolveDefaultTestPatterns(deps.projectRoot);
|
|
10008
|
-
logger$
|
|
10008
|
+
logger$14.debug({ storyKey }, "No test-pattern decisions — using stack-aware defaults");
|
|
10009
10009
|
}
|
|
10010
10010
|
} catch {
|
|
10011
10011
|
testPatternsContent = resolveDefaultTestPatterns(deps.projectRoot);
|
|
@@ -10020,12 +10020,12 @@ async function runTestExpansion(deps, params) {
|
|
|
10020
10020
|
const scopedTotal = nonDiffTokens + countTokens(scopedDiff);
|
|
10021
10021
|
if (scopedTotal <= TOKEN_CEILING) {
|
|
10022
10022
|
gitDiffContent = scopedDiff;
|
|
10023
|
-
logger$
|
|
10023
|
+
logger$14.debug({
|
|
10024
10024
|
fileCount: filesModified.length,
|
|
10025
10025
|
tokenCount: scopedTotal
|
|
10026
10026
|
}, "Using scoped file diff");
|
|
10027
10027
|
} else {
|
|
10028
|
-
logger$
|
|
10028
|
+
logger$14.warn({
|
|
10029
10029
|
estimatedTotal: scopedTotal,
|
|
10030
10030
|
ceiling: TOKEN_CEILING,
|
|
10031
10031
|
fileCount: filesModified.length
|
|
@@ -10033,7 +10033,7 @@ async function runTestExpansion(deps, params) {
|
|
|
10033
10033
|
gitDiffContent = await getGitDiffStatForFiles(filesModified, cwd);
|
|
10034
10034
|
}
|
|
10035
10035
|
} catch (err) {
|
|
10036
|
-
logger$
|
|
10036
|
+
logger$14.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to get git diff — proceeding with empty diff");
|
|
10037
10037
|
}
|
|
10038
10038
|
const sections = [
|
|
10039
10039
|
{
|
|
@@ -10058,11 +10058,11 @@ async function runTestExpansion(deps, params) {
|
|
|
10058
10058
|
}
|
|
10059
10059
|
];
|
|
10060
10060
|
const assembleResult = assemblePrompt(template, sections, TOKEN_CEILING);
|
|
10061
|
-
if (assembleResult.truncated) logger$
|
|
10061
|
+
if (assembleResult.truncated) logger$14.warn({
|
|
10062
10062
|
storyKey,
|
|
10063
10063
|
tokenCount: assembleResult.tokenCount
|
|
10064
10064
|
}, "Test-expansion prompt truncated to fit token ceiling");
|
|
10065
|
-
logger$
|
|
10065
|
+
logger$14.debug({
|
|
10066
10066
|
storyKey,
|
|
10067
10067
|
tokenCount: assembleResult.tokenCount,
|
|
10068
10068
|
truncated: assembleResult.truncated
|
|
@@ -10082,7 +10082,7 @@ async function runTestExpansion(deps, params) {
|
|
|
10082
10082
|
dispatchResult = await handle.result;
|
|
10083
10083
|
} catch (err) {
|
|
10084
10084
|
const error = err instanceof Error ? err.message : String(err);
|
|
10085
|
-
logger$
|
|
10085
|
+
logger$14.warn({
|
|
10086
10086
|
storyKey,
|
|
10087
10087
|
error
|
|
10088
10088
|
}, "Test-expansion dispatch threw unexpected error");
|
|
@@ -10097,19 +10097,19 @@ async function runTestExpansion(deps, params) {
|
|
|
10097
10097
|
};
|
|
10098
10098
|
if (dispatchResult.status === "failed") {
|
|
10099
10099
|
const errorMsg = `Dispatch status: failed. Exit code: ${dispatchResult.exitCode}. ${dispatchResult.parseError ?? ""}`.trim();
|
|
10100
|
-
logger$
|
|
10100
|
+
logger$14.warn({
|
|
10101
10101
|
storyKey,
|
|
10102
10102
|
exitCode: dispatchResult.exitCode
|
|
10103
10103
|
}, "Test-expansion dispatch failed");
|
|
10104
10104
|
return defaultFallbackResult(errorMsg, tokenUsage);
|
|
10105
10105
|
}
|
|
10106
10106
|
if (dispatchResult.status === "timeout") {
|
|
10107
|
-
logger$
|
|
10107
|
+
logger$14.warn({ storyKey }, "Test-expansion dispatch timed out");
|
|
10108
10108
|
return defaultFallbackResult("Dispatch status: timeout. The agent did not complete within the allowed time.", tokenUsage);
|
|
10109
10109
|
}
|
|
10110
10110
|
if (dispatchResult.parsed === null) {
|
|
10111
10111
|
const details = dispatchResult.parseError ?? "No YAML block found in output";
|
|
10112
|
-
logger$
|
|
10112
|
+
logger$14.warn({
|
|
10113
10113
|
storyKey,
|
|
10114
10114
|
details
|
|
10115
10115
|
}, "Test-expansion output has no parseable YAML");
|
|
@@ -10118,14 +10118,14 @@ async function runTestExpansion(deps, params) {
|
|
|
10118
10118
|
const parseResult = TestExpansionResultSchema.safeParse(dispatchResult.parsed);
|
|
10119
10119
|
if (!parseResult.success) {
|
|
10120
10120
|
const details = parseResult.error.message;
|
|
10121
|
-
logger$
|
|
10121
|
+
logger$14.warn({
|
|
10122
10122
|
storyKey,
|
|
10123
10123
|
details
|
|
10124
10124
|
}, "Test-expansion output failed schema validation");
|
|
10125
10125
|
return defaultFallbackResult(`schema_validation_failed: ${details}`, tokenUsage);
|
|
10126
10126
|
}
|
|
10127
10127
|
const parsed = parseResult.data;
|
|
10128
|
-
logger$
|
|
10128
|
+
logger$14.info({
|
|
10129
10129
|
storyKey,
|
|
10130
10130
|
expansion_priority: parsed.expansion_priority,
|
|
10131
10131
|
coverage_gaps: parsed.coverage_gaps.length,
|
|
@@ -10150,14 +10150,14 @@ async function getArchConstraints(deps) {
|
|
|
10150
10150
|
if (constraints.length === 0) return "";
|
|
10151
10151
|
return constraints.map((d) => `${d.key}: ${d.value}`).join("\n");
|
|
10152
10152
|
} catch (err) {
|
|
10153
|
-
logger$
|
|
10153
|
+
logger$14.warn({ error: err instanceof Error ? err.message : String(err) }, "Failed to retrieve architecture constraints");
|
|
10154
10154
|
return "";
|
|
10155
10155
|
}
|
|
10156
10156
|
}
|
|
10157
10157
|
|
|
10158
10158
|
//#endregion
|
|
10159
10159
|
//#region src/modules/compiled-workflows/probe-author.ts
|
|
10160
|
-
const logger$
|
|
10160
|
+
const logger$13 = createLogger("compiled-workflows:probe-author");
|
|
10161
10161
|
/**
|
|
10162
10162
|
* Default initial timeout: 10 min. Override via SUBSTRATE_PROBE_AUTHOR_TIMEOUT_MS (ms).
|
|
10163
10163
|
* Story 65-7: raised from 300 s to 600 s to reduce infra-timeout false negatives.
|
|
@@ -10607,7 +10607,7 @@ function detectConflictGroupsWithContracts(storyKeys, config, declarations) {
|
|
|
10607
10607
|
|
|
10608
10608
|
//#endregion
|
|
10609
10609
|
//#region src/modules/implementation-orchestrator/seed-methodology-context.ts
|
|
10610
|
-
const logger$
|
|
10610
|
+
const logger$12 = createLogger("implementation-orchestrator:seed");
|
|
10611
10611
|
/** Max chars for the architecture summary seeded into decisions */
|
|
10612
10612
|
const MAX_ARCH_CHARS = 6e3;
|
|
10613
10613
|
/** Max chars per epic-shard decision value (per-story or per-epic fallback) */
|
|
@@ -10641,12 +10641,12 @@ async function seedMethodologyContext(db, projectRoot) {
|
|
|
10641
10641
|
const testCount = await seedTestPatterns(db, projectRoot);
|
|
10642
10642
|
if (testCount === -1) result.skippedCategories.push("test-patterns");
|
|
10643
10643
|
else result.decisionsCreated += testCount;
|
|
10644
|
-
logger$
|
|
10644
|
+
logger$12.info({
|
|
10645
10645
|
decisionsCreated: result.decisionsCreated,
|
|
10646
10646
|
skippedCategories: result.skippedCategories
|
|
10647
10647
|
}, "Methodology context seeding complete");
|
|
10648
10648
|
} catch (err) {
|
|
10649
|
-
logger$
|
|
10649
|
+
logger$12.warn({ error: err instanceof Error ? err.message : String(err) }, "Methodology context seeding failed (non-fatal)");
|
|
10650
10650
|
}
|
|
10651
10651
|
return result;
|
|
10652
10652
|
}
|
|
@@ -10690,7 +10690,7 @@ async function seedArchitecture(db, projectRoot) {
|
|
|
10690
10690
|
});
|
|
10691
10691
|
count = 1;
|
|
10692
10692
|
}
|
|
10693
|
-
logger$
|
|
10693
|
+
logger$12.debug({ count }, "Seeded architecture decisions");
|
|
10694
10694
|
return count;
|
|
10695
10695
|
}
|
|
10696
10696
|
/**
|
|
@@ -10714,11 +10714,11 @@ async function seedEpicShards(db, projectRoot) {
|
|
|
10714
10714
|
const storedHashDecision = implementationDecisions.find((d) => d.category === "epic-shard-hash" && d.key === "epics-file");
|
|
10715
10715
|
const storedHash = storedHashDecision?.value;
|
|
10716
10716
|
if (storedHash === currentHash) {
|
|
10717
|
-
logger$
|
|
10717
|
+
logger$12.debug({ hash: currentHash }, "Epic shards up-to-date (hash unchanged) — skipping re-seed");
|
|
10718
10718
|
return -1;
|
|
10719
10719
|
}
|
|
10720
10720
|
if (implementationDecisions.some((d) => d.category === "epic-shard")) {
|
|
10721
|
-
logger$
|
|
10721
|
+
logger$12.debug({
|
|
10722
10722
|
storedHash,
|
|
10723
10723
|
currentHash
|
|
10724
10724
|
}, "Epics file changed — deleting stale epic-shard decisions");
|
|
@@ -10730,7 +10730,7 @@ async function seedEpicShards(db, projectRoot) {
|
|
|
10730
10730
|
for (const shard of shards) {
|
|
10731
10731
|
const subsections = parseStorySubsections(shard.epicId, shard.content);
|
|
10732
10732
|
for (const subsection of subsections) {
|
|
10733
|
-
if (subsection.content.length > MAX_EPIC_SHARD_CHARS) logger$
|
|
10733
|
+
if (subsection.content.length > MAX_EPIC_SHARD_CHARS) logger$12.warn({
|
|
10734
10734
|
epicId: shard.epicId,
|
|
10735
10735
|
storyKey: subsection.key,
|
|
10736
10736
|
originalLength: subsection.content.length,
|
|
@@ -10738,7 +10738,7 @@ async function seedEpicShards(db, projectRoot) {
|
|
|
10738
10738
|
droppedChars: subsection.content.length - MAX_EPIC_SHARD_CHARS
|
|
10739
10739
|
}, `Epic shard for ${subsection.key} exceeded ${MAX_EPIC_SHARD_CHARS}-char cap and was truncated; tail content lost from decisions store. Consider splitting the story or raising MAX_EPIC_SHARD_CHARS.`);
|
|
10740
10740
|
if (seenKeys.has(subsection.key)) {
|
|
10741
|
-
logger$
|
|
10741
|
+
logger$12.warn({
|
|
10742
10742
|
epicId: shard.epicId,
|
|
10743
10743
|
storyKey: subsection.key,
|
|
10744
10744
|
droppedContentLength: subsection.content.length
|
|
@@ -10766,7 +10766,7 @@ async function seedEpicShards(db, projectRoot) {
|
|
|
10766
10766
|
value: currentHash,
|
|
10767
10767
|
rationale: "SHA-256 hash of epics file content for change detection"
|
|
10768
10768
|
});
|
|
10769
|
-
logger$
|
|
10769
|
+
logger$12.debug({
|
|
10770
10770
|
count,
|
|
10771
10771
|
hash: currentHash
|
|
10772
10772
|
}, "Seeded epic shard decisions");
|
|
@@ -10790,7 +10790,7 @@ async function seedTestPatterns(db, projectRoot) {
|
|
|
10790
10790
|
value: patterns.slice(0, MAX_TEST_PATTERNS_CHARS),
|
|
10791
10791
|
rationale: "Detected from project configuration at orchestrator startup"
|
|
10792
10792
|
});
|
|
10793
|
-
logger$
|
|
10793
|
+
logger$12.debug("Seeded test patterns decision");
|
|
10794
10794
|
return 1;
|
|
10795
10795
|
}
|
|
10796
10796
|
/**
|
|
@@ -11280,7 +11280,7 @@ function findArtifact(projectRoot, candidates) {
|
|
|
11280
11280
|
|
|
11281
11281
|
//#endregion
|
|
11282
11282
|
//#region src/modules/implementation-orchestrator/package-snapshot.ts
|
|
11283
|
-
const logger$
|
|
11283
|
+
const logger$11 = createLogger("package-snapshot");
|
|
11284
11284
|
/**
|
|
11285
11285
|
* Discover all package.json paths in a workspace monorepo.
|
|
11286
11286
|
* Checks the `workspaces` field in root package.json,
|
|
@@ -11372,7 +11372,7 @@ function restorePackageSnapshot(snapshot, options) {
|
|
|
11372
11372
|
writeFileSync(filePath, content, "utf-8");
|
|
11373
11373
|
filesRestored++;
|
|
11374
11374
|
} catch (err) {
|
|
11375
|
-
logger$
|
|
11375
|
+
logger$11.warn({
|
|
11376
11376
|
filePath,
|
|
11377
11377
|
err
|
|
11378
11378
|
}, "Failed to restore file from snapshot");
|
|
@@ -11383,7 +11383,7 @@ function restorePackageSnapshot(snapshot, options) {
|
|
|
11383
11383
|
encoding: "utf-8",
|
|
11384
11384
|
stdio: "pipe"
|
|
11385
11385
|
});
|
|
11386
|
-
logger$
|
|
11386
|
+
logger$11.info({
|
|
11387
11387
|
filesRestored,
|
|
11388
11388
|
installCommand: snapshot.installCommand
|
|
11389
11389
|
}, "Package snapshot restored successfully");
|
|
@@ -11394,7 +11394,7 @@ function restorePackageSnapshot(snapshot, options) {
|
|
|
11394
11394
|
};
|
|
11395
11395
|
} catch (err) {
|
|
11396
11396
|
const exitCode = err.status ?? 1;
|
|
11397
|
-
logger$
|
|
11397
|
+
logger$11.warn({
|
|
11398
11398
|
filesRestored,
|
|
11399
11399
|
exitCode,
|
|
11400
11400
|
err
|
|
@@ -11743,7 +11743,7 @@ const RecommendationSchema = z.object({
|
|
|
11743
11743
|
|
|
11744
11744
|
//#endregion
|
|
11745
11745
|
//#region src/modules/telemetry/adapter-persistence.ts
|
|
11746
|
-
const logger$
|
|
11746
|
+
const logger$10 = createLogger("telemetry:adapter-persistence");
|
|
11747
11747
|
/**
|
|
11748
11748
|
* Concrete DatabaseAdapter-backed telemetry persistence.
|
|
11749
11749
|
*
|
|
@@ -11797,7 +11797,7 @@ var AdapterTelemetryPersistence = class {
|
|
|
11797
11797
|
]);
|
|
11798
11798
|
}
|
|
11799
11799
|
});
|
|
11800
|
-
logger$
|
|
11800
|
+
logger$10.debug({
|
|
11801
11801
|
storyKey,
|
|
11802
11802
|
count: turns.length
|
|
11803
11803
|
}, "Stored turn analysis");
|
|
@@ -11869,7 +11869,7 @@ var AdapterTelemetryPersistence = class {
|
|
|
11869
11869
|
score.taskType ?? null,
|
|
11870
11870
|
score.phase ?? null
|
|
11871
11871
|
]);
|
|
11872
|
-
logger$
|
|
11872
|
+
logger$10.debug({
|
|
11873
11873
|
storyKey: score.storyKey,
|
|
11874
11874
|
compositeScore: score.compositeScore
|
|
11875
11875
|
}, "Stored efficiency score");
|
|
@@ -11937,7 +11937,7 @@ var AdapterTelemetryPersistence = class {
|
|
|
11937
11937
|
]);
|
|
11938
11938
|
}
|
|
11939
11939
|
});
|
|
11940
|
-
logger$
|
|
11940
|
+
logger$10.debug({
|
|
11941
11941
|
storyKey,
|
|
11942
11942
|
count: recs.length
|
|
11943
11943
|
}, "Saved recommendations");
|
|
@@ -12014,7 +12014,7 @@ var AdapterTelemetryPersistence = class {
|
|
|
12014
12014
|
stat$2.trend
|
|
12015
12015
|
]);
|
|
12016
12016
|
});
|
|
12017
|
-
logger$
|
|
12017
|
+
logger$10.debug({
|
|
12018
12018
|
storyKey,
|
|
12019
12019
|
count: stats.length
|
|
12020
12020
|
}, "Stored category stats");
|
|
@@ -12057,7 +12057,7 @@ var AdapterTelemetryPersistence = class {
|
|
|
12057
12057
|
JSON.stringify(consumer.topInvocations)
|
|
12058
12058
|
]);
|
|
12059
12059
|
});
|
|
12060
|
-
logger$
|
|
12060
|
+
logger$10.debug({
|
|
12061
12061
|
storyKey,
|
|
12062
12062
|
count: consumers.length
|
|
12063
12063
|
}, "Stored consumer stats");
|
|
@@ -12089,14 +12089,14 @@ var AdapterTelemetryPersistence = class {
|
|
|
12089
12089
|
await adapter.query("DELETE FROM category_stats WHERE story_key = ?", [storyKey]);
|
|
12090
12090
|
await adapter.query("DELETE FROM consumer_stats WHERE story_key = ?", [storyKey]);
|
|
12091
12091
|
});
|
|
12092
|
-
logger$
|
|
12092
|
+
logger$10.debug({ storyKey }, "Purged stale telemetry data for story");
|
|
12093
12093
|
}
|
|
12094
12094
|
/**
|
|
12095
12095
|
* Record a named span with arbitrary attributes.
|
|
12096
12096
|
* Currently logs the span at debug level; no DB persistence.
|
|
12097
12097
|
*/
|
|
12098
12098
|
recordSpan(span) {
|
|
12099
|
-
logger$
|
|
12099
|
+
logger$10.debug({ span }, "recordSpan");
|
|
12100
12100
|
}
|
|
12101
12101
|
};
|
|
12102
12102
|
|
|
@@ -12171,7 +12171,7 @@ var TelemetryPersistence = class {
|
|
|
12171
12171
|
|
|
12172
12172
|
//#endregion
|
|
12173
12173
|
//#region src/modules/telemetry/telemetry-advisor.ts
|
|
12174
|
-
const logger$
|
|
12174
|
+
const logger$9 = createLogger("telemetry-advisor");
|
|
12175
12175
|
/**
|
|
12176
12176
|
* Reads telemetry efficiency data to support retry gate decisions.
|
|
12177
12177
|
*/
|
|
@@ -12193,7 +12193,7 @@ var TelemetryAdvisor = class {
|
|
|
12193
12193
|
try {
|
|
12194
12194
|
const score = await this._persistence.getEfficiencyScore(storyKey);
|
|
12195
12195
|
if (score === null) {
|
|
12196
|
-
logger$
|
|
12196
|
+
logger$9.debug({ storyKey }, "No efficiency score found for story");
|
|
12197
12197
|
return null;
|
|
12198
12198
|
}
|
|
12199
12199
|
return {
|
|
@@ -12208,7 +12208,7 @@ var TelemetryAdvisor = class {
|
|
|
12208
12208
|
coldStartTurnsExcluded: score.coldStartTurnsExcluded ?? 0
|
|
12209
12209
|
};
|
|
12210
12210
|
} catch (err) {
|
|
12211
|
-
logger$
|
|
12211
|
+
logger$9.warn({
|
|
12212
12212
|
err,
|
|
12213
12213
|
storyKey
|
|
12214
12214
|
}, "Failed to retrieve efficiency score");
|
|
@@ -12245,7 +12245,7 @@ var TelemetryAdvisor = class {
|
|
|
12245
12245
|
merged.sort((a, b) => (severityOrder[a.severity] ?? 3) - (severityOrder[b.severity] ?? 3));
|
|
12246
12246
|
return merged;
|
|
12247
12247
|
} catch (err) {
|
|
12248
|
-
logger$
|
|
12248
|
+
logger$9.warn({ err }, "Failed to retrieve recommendations for run — returning empty");
|
|
12249
12249
|
return [];
|
|
12250
12250
|
}
|
|
12251
12251
|
}
|
|
@@ -12275,7 +12275,7 @@ var TelemetryAdvisor = class {
|
|
|
12275
12275
|
const lines = actionable.map((r) => `OPTIMIZATION (${r.severity}): ${r.title}. ${r.description}`);
|
|
12276
12276
|
const full = lines.join("\n");
|
|
12277
12277
|
if (full.length <= MAX_CHARS$1) {
|
|
12278
|
-
logger$
|
|
12278
|
+
logger$9.debug({
|
|
12279
12279
|
count: actionable.length,
|
|
12280
12280
|
chars: full.length
|
|
12281
12281
|
}, "Formatting optimization directives");
|
|
@@ -12283,7 +12283,7 @@ var TelemetryAdvisor = class {
|
|
|
12283
12283
|
}
|
|
12284
12284
|
const cutAt = full.lastIndexOf(" ", MAX_CHARS$1);
|
|
12285
12285
|
const truncated = (cutAt > 0 ? full.slice(0, cutAt) : full.slice(0, MAX_CHARS$1)) + "…";
|
|
12286
|
-
logger$
|
|
12286
|
+
logger$9.debug({
|
|
12287
12287
|
count: actionable.length,
|
|
12288
12288
|
chars: truncated.length
|
|
12289
12289
|
}, "Optimization directives truncated to budget");
|
|
@@ -12297,6 +12297,171 @@ function createTelemetryAdvisor(deps) {
|
|
|
12297
12297
|
return new TelemetryAdvisor(deps);
|
|
12298
12298
|
}
|
|
12299
12299
|
|
|
12300
|
+
//#endregion
|
|
12301
|
+
//#region src/modules/compiled-workflows/acceptance-judge.ts
|
|
12302
|
+
const logger$8 = createLogger("compiled-workflows:acceptance-judge");
|
|
12303
|
+
/** Cap per-artifact content injected into the prompt (chars). */
|
|
12304
|
+
const ARTIFACT_CONTENT_CAP = 16e3;
|
|
12305
|
+
function renderEndStates(journey) {
|
|
12306
|
+
return journey.end_states.map((es) => `- id: ${es.id}\n given: ${es.given}\n walk: ${es.walk}\n then: ${es.then}`).join("\n");
|
|
12307
|
+
}
|
|
12308
|
+
async function renderArtifactContents(artifactsDir, artifacts) {
|
|
12309
|
+
const blocks = [];
|
|
12310
|
+
for (const rel of artifacts) {
|
|
12311
|
+
let content;
|
|
12312
|
+
try {
|
|
12313
|
+
content = await readFile$1(join$1(artifactsDir, rel), "utf-8");
|
|
12314
|
+
} catch {
|
|
12315
|
+
blocks.push(`--- ${rel} ---\n(unreadable or binary — judge from the other artifacts)`);
|
|
12316
|
+
continue;
|
|
12317
|
+
}
|
|
12318
|
+
const truncated = content.length > ARTIFACT_CONTENT_CAP;
|
|
12319
|
+
blocks.push(`--- ${rel}${truncated ? ` (truncated to first ${String(ARTIFACT_CONTENT_CAP)} chars)` : ""} ---\n` + content.slice(0, ARTIFACT_CONTENT_CAP));
|
|
12320
|
+
}
|
|
12321
|
+
return blocks.join("\n\n");
|
|
12322
|
+
}
|
|
12323
|
+
/** Validate verdict completeness: every end-state exactly once, no unknown ids. */
|
|
12324
|
+
function validateVerdictCoverage(journey, verdicts) {
|
|
12325
|
+
const expected = new Set(journey.end_states.map((es) => es.id));
|
|
12326
|
+
const seen = new Set();
|
|
12327
|
+
for (const v of verdicts) {
|
|
12328
|
+
if (!expected.has(v.end_state_id)) return `verdict for unknown end-state id "${v.end_state_id}"`;
|
|
12329
|
+
if (seen.has(v.end_state_id)) return `duplicate verdict for end-state "${v.end_state_id}"`;
|
|
12330
|
+
seen.add(v.end_state_id);
|
|
12331
|
+
}
|
|
12332
|
+
const missing = [...expected].filter((id) => !seen.has(id));
|
|
12333
|
+
if (missing.length > 0) return `missing verdict(s) for end-state(s): ${missing.join(", ")}`;
|
|
12334
|
+
return void 0;
|
|
12335
|
+
}
|
|
12336
|
+
async function runAcceptanceJudge(deps, params) {
|
|
12337
|
+
const { journey, artifactsDir, artifacts, storyKey } = params;
|
|
12338
|
+
let template;
|
|
12339
|
+
try {
|
|
12340
|
+
template = await deps.pack.getPrompt("acceptance-judge");
|
|
12341
|
+
} catch (err) {
|
|
12342
|
+
return {
|
|
12343
|
+
result: "failed",
|
|
12344
|
+
error: `Failed to retrieve acceptance-judge prompt: ${err instanceof Error ? err.message : String(err)}`,
|
|
12345
|
+
tokenUsage: {
|
|
12346
|
+
input: 0,
|
|
12347
|
+
output: 0
|
|
12348
|
+
}
|
|
12349
|
+
};
|
|
12350
|
+
}
|
|
12351
|
+
const artifactContents = await renderArtifactContents(artifactsDir, artifacts);
|
|
12352
|
+
const buildPrompt = (correctivePreamble) => {
|
|
12353
|
+
const { prompt } = assemblePrompt(template, [
|
|
12354
|
+
{
|
|
12355
|
+
name: "journey_id",
|
|
12356
|
+
content: journey.id,
|
|
12357
|
+
priority: "required"
|
|
12358
|
+
},
|
|
12359
|
+
{
|
|
12360
|
+
name: "journey_title",
|
|
12361
|
+
content: journey.title,
|
|
12362
|
+
priority: "required"
|
|
12363
|
+
},
|
|
12364
|
+
{
|
|
12365
|
+
name: "end_states",
|
|
12366
|
+
content: renderEndStates(journey),
|
|
12367
|
+
priority: "required"
|
|
12368
|
+
},
|
|
12369
|
+
{
|
|
12370
|
+
name: "artifact_manifest",
|
|
12371
|
+
content: artifacts.length > 0 ? artifacts.map((a) => `- ${a}`).join("\n") : "(no artifacts)",
|
|
12372
|
+
priority: "required"
|
|
12373
|
+
},
|
|
12374
|
+
{
|
|
12375
|
+
name: "artifact_contents",
|
|
12376
|
+
content: artifactContents,
|
|
12377
|
+
priority: "required"
|
|
12378
|
+
}
|
|
12379
|
+
], getTokenCeiling("acceptance-judge", deps.tokenCeilings).ceiling);
|
|
12380
|
+
return correctivePreamble !== void 0 ? `${correctivePreamble}\n\n${prompt}` : prompt;
|
|
12381
|
+
};
|
|
12382
|
+
let totalTokens = {
|
|
12383
|
+
input: 0,
|
|
12384
|
+
output: 0
|
|
12385
|
+
};
|
|
12386
|
+
let lastProblem = "unknown";
|
|
12387
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
12388
|
+
const prompt = attempt === 0 ? buildPrompt() : buildPrompt(`PREVIOUS ATTEMPT REJECTED: ${lastProblem}. Emit ONLY the YAML block per the Output Contract — every end-state exactly once, every verdict with evidence {artifact, excerpt}.`);
|
|
12389
|
+
const handle = deps.dispatcher.dispatch({
|
|
12390
|
+
prompt,
|
|
12391
|
+
agent: deps.agentId ?? "claude-code",
|
|
12392
|
+
taskType: "acceptance-judge",
|
|
12393
|
+
outputSchema: AcceptanceJudgeResultSchema,
|
|
12394
|
+
maxTurns: 20,
|
|
12395
|
+
workingDirectory: artifactsDir,
|
|
12396
|
+
...deps.otlpEndpoint !== void 0 ? { otlpEndpoint: deps.otlpEndpoint } : {},
|
|
12397
|
+
...storyKey !== void 0 ? { storyKey } : {}
|
|
12398
|
+
});
|
|
12399
|
+
let dispatchResult;
|
|
12400
|
+
try {
|
|
12401
|
+
dispatchResult = await handle.result;
|
|
12402
|
+
} catch (err) {
|
|
12403
|
+
return {
|
|
12404
|
+
result: "failed",
|
|
12405
|
+
error: `Dispatch error: ${err instanceof Error ? err.message : String(err)}`,
|
|
12406
|
+
tokenUsage: totalTokens
|
|
12407
|
+
};
|
|
12408
|
+
}
|
|
12409
|
+
totalTokens = {
|
|
12410
|
+
input: totalTokens.input + dispatchResult.tokenEstimate.input,
|
|
12411
|
+
output: totalTokens.output + dispatchResult.tokenEstimate.output
|
|
12412
|
+
};
|
|
12413
|
+
if (dispatchResult.status === "failed" || dispatchResult.status === "timeout") return {
|
|
12414
|
+
result: "failed",
|
|
12415
|
+
error: `Dispatch status: ${dispatchResult.status}. ${dispatchResult.parseError ?? ""}`.trim(),
|
|
12416
|
+
tokenUsage: totalTokens
|
|
12417
|
+
};
|
|
12418
|
+
const parsed = AcceptanceJudgeResultSchema.safeParse(dispatchResult.parsed);
|
|
12419
|
+
if (!parsed.success) {
|
|
12420
|
+
lastProblem = `output failed schema validation (${parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ").slice(0, 500)})`;
|
|
12421
|
+
logger$8.warn({
|
|
12422
|
+
journeyId: journey.id,
|
|
12423
|
+
storyKey,
|
|
12424
|
+
attempt,
|
|
12425
|
+
lastProblem
|
|
12426
|
+
}, "A2.1: judge output invalid");
|
|
12427
|
+
continue;
|
|
12428
|
+
}
|
|
12429
|
+
if (parsed.data.result === "failed") return {
|
|
12430
|
+
result: "failed",
|
|
12431
|
+
error: "acceptance-judge-refused",
|
|
12432
|
+
details: parsed.data.error ?? "judge reported failure without a reason",
|
|
12433
|
+
tokenUsage: totalTokens
|
|
12434
|
+
};
|
|
12435
|
+
const coverageProblem = validateVerdictCoverage(journey, parsed.data.verdicts);
|
|
12436
|
+
if (coverageProblem !== void 0) {
|
|
12437
|
+
lastProblem = coverageProblem;
|
|
12438
|
+
logger$8.warn({
|
|
12439
|
+
journeyId: journey.id,
|
|
12440
|
+
storyKey,
|
|
12441
|
+
attempt,
|
|
12442
|
+
coverageProblem
|
|
12443
|
+
}, "A2.1: judge verdicts incomplete");
|
|
12444
|
+
continue;
|
|
12445
|
+
}
|
|
12446
|
+
logger$8.info({
|
|
12447
|
+
journeyId: journey.id,
|
|
12448
|
+
storyKey,
|
|
12449
|
+
verdicts: parsed.data.verdicts.map((v) => `${v.end_state_id}=${v.verdict}`)
|
|
12450
|
+
}, "A2.1: acceptance judge verdicts accepted");
|
|
12451
|
+
return {
|
|
12452
|
+
result: "success",
|
|
12453
|
+
verdicts: parsed.data.verdicts,
|
|
12454
|
+
tokenUsage: totalTokens
|
|
12455
|
+
};
|
|
12456
|
+
}
|
|
12457
|
+
return {
|
|
12458
|
+
result: "failed",
|
|
12459
|
+
error: "acceptance-judge-invalid",
|
|
12460
|
+
details: `judge produced invalid output twice — last problem: ${lastProblem}`,
|
|
12461
|
+
tokenUsage: totalTokens
|
|
12462
|
+
};
|
|
12463
|
+
}
|
|
12464
|
+
|
|
12300
12465
|
//#endregion
|
|
12301
12466
|
//#region src/modules/implementation-orchestrator/verification-integration.ts
|
|
12302
12467
|
const _logger = createLogger("verification-integration");
|
|
@@ -13602,7 +13767,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
13602
13767
|
projectRoot,
|
|
13603
13768
|
...config.worktreeCopyFiles !== void 0 ? { copyFiles: config.worktreeCopyFiles } : {}
|
|
13604
13769
|
}) : void 0);
|
|
13605
|
-
const logger$
|
|
13770
|
+
const logger$28 = createLogger("implementation-orchestrator");
|
|
13606
13771
|
const telemetryAdvisor = db !== void 0 ? createTelemetryAdvisor({ db }) : void 0;
|
|
13607
13772
|
const wgRepo = new WorkGraphRepository(db);
|
|
13608
13773
|
const _wgInProgressWritten = new Set();
|
|
@@ -13709,7 +13874,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
13709
13874
|
const existingCount = storyState?.retry_count ?? 0;
|
|
13710
13875
|
_storyRetryCount.set(storyKey, existingCount);
|
|
13711
13876
|
} catch (err) {
|
|
13712
|
-
logger$
|
|
13877
|
+
logger$28.warn({
|
|
13713
13878
|
err,
|
|
13714
13879
|
storyKey
|
|
13715
13880
|
}, "initRetryCount: failed to read manifest — starting at 0");
|
|
@@ -13723,7 +13888,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
13723
13888
|
const current = _storyRetryCount.get(storyKey) ?? 0;
|
|
13724
13889
|
const next = current + 1;
|
|
13725
13890
|
_storyRetryCount.set(storyKey, next);
|
|
13726
|
-
if (runManifest !== null && runManifest !== void 0) runManifest.patchStoryState(storyKey, { retry_count: next }).catch((err) => logger$
|
|
13891
|
+
if (runManifest !== null && runManifest !== void 0) runManifest.patchStoryState(storyKey, { retry_count: next }).catch((err) => logger$28.warn({
|
|
13727
13892
|
err,
|
|
13728
13893
|
storyKey
|
|
13729
13894
|
}, "patchStoryState(retry_count) failed — pipeline continues"));
|
|
@@ -13736,7 +13901,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
13736
13901
|
const nowMs = Date.now();
|
|
13737
13902
|
for (const [phase, startMs] of starts) {
|
|
13738
13903
|
const endMs = ends?.get(phase);
|
|
13739
|
-
if (endMs === void 0) logger$
|
|
13904
|
+
if (endMs === void 0) logger$28.warn({
|
|
13740
13905
|
storyKey,
|
|
13741
13906
|
phase
|
|
13742
13907
|
}, "Phase has no end time — story may have errored mid-phase. Duration capped to now() and may be inflated.");
|
|
@@ -13753,7 +13918,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
13753
13918
|
const wallClockSeconds = startedAt ? Math.round((new Date(completedAt).getTime() - new Date(startedAt).getTime()) / 1e3) : 0;
|
|
13754
13919
|
const wallClockMs = startedAt ? new Date(completedAt).getTime() - new Date(startedAt).getTime() : 0;
|
|
13755
13920
|
const tokenAgg = await aggregateTokenUsageForStory(db, config.pipelineRunId, storyKey);
|
|
13756
|
-
if (runManifest !== null) runManifest.patchStoryState(storyKey, { cost_usd: tokenAgg.cost }).catch((err) => logger$
|
|
13921
|
+
if (runManifest !== null) runManifest.patchStoryState(storyKey, { cost_usd: tokenAgg.cost }).catch((err) => logger$28.warn({
|
|
13757
13922
|
err,
|
|
13758
13923
|
storyKey
|
|
13759
13924
|
}, "patchStoryState(cost_usd) failed — pipeline continues"));
|
|
@@ -13792,7 +13957,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
13792
13957
|
rationale: `Story ${storyKey} completed with result=${result} in ${wallClockSeconds}s. Tokens: ${tokenAgg.input}+${tokenAgg.output}. Review cycles: ${reviewCycles}.`
|
|
13793
13958
|
});
|
|
13794
13959
|
} catch (decisionErr) {
|
|
13795
|
-
logger$
|
|
13960
|
+
logger$28.warn({
|
|
13796
13961
|
err: decisionErr,
|
|
13797
13962
|
storyKey
|
|
13798
13963
|
}, "Failed to write story-metrics decision (best-effort)");
|
|
@@ -13871,7 +14036,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
13871
14036
|
const LOW_OUTPUT_TOKEN_THRESHOLD = 100;
|
|
13872
14037
|
const unverified = tokenAgg.output < LOW_OUTPUT_TOKEN_THRESHOLD;
|
|
13873
14038
|
if (unverified) {
|
|
13874
|
-
logger$
|
|
14039
|
+
logger$28.warn({
|
|
13875
14040
|
storyKey,
|
|
13876
14041
|
outputTokens: tokenAgg.output,
|
|
13877
14042
|
threshold: LOW_OUTPUT_TOKEN_THRESHOLD
|
|
@@ -13895,13 +14060,13 @@ function createImplementationOrchestrator(deps) {
|
|
|
13895
14060
|
...unverified ? { unverified: true } : {}
|
|
13896
14061
|
});
|
|
13897
14062
|
} catch (emitErr) {
|
|
13898
|
-
logger$
|
|
14063
|
+
logger$28.warn({
|
|
13899
14064
|
err: emitErr,
|
|
13900
14065
|
storyKey
|
|
13901
14066
|
}, "Failed to emit story:metrics event (best-effort)");
|
|
13902
14067
|
}
|
|
13903
14068
|
} catch (err) {
|
|
13904
|
-
logger$
|
|
14069
|
+
logger$28.warn({
|
|
13905
14070
|
err,
|
|
13906
14071
|
storyKey
|
|
13907
14072
|
}, "Failed to write story metrics (best-effort)");
|
|
@@ -13930,7 +14095,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
13930
14095
|
rationale: `Story ${storyKey} ${outcome} after ${reviewCycles} review cycle(s).`
|
|
13931
14096
|
});
|
|
13932
14097
|
} catch (err) {
|
|
13933
|
-
logger$
|
|
14098
|
+
logger$28.warn({
|
|
13934
14099
|
err,
|
|
13935
14100
|
storyKey
|
|
13936
14101
|
}, "Failed to write story-outcome decision (best-effort)");
|
|
@@ -13945,15 +14110,15 @@ function createImplementationOrchestrator(deps) {
|
|
|
13945
14110
|
if (escalationWorktree !== void 0) {
|
|
13946
14111
|
const cp = await checkpointStoryWorktree(payload.storyKey, `escalation: ${payload.escalationReason ?? payload.lastVerdict}`, escalationWorktree);
|
|
13947
14112
|
if (cp.status === "committed") {
|
|
13948
|
-
logger$
|
|
14113
|
+
logger$28.info({
|
|
13949
14114
|
storyKey: payload.storyKey,
|
|
13950
14115
|
sha: cp.sha
|
|
13951
14116
|
}, "escalation checkpoint: uncommitted worktree state preserved on story branch");
|
|
13952
|
-
if (runManifest !== null && cp.sha) runManifest.patchStoryState(payload.storyKey, { checkpoint_sha: cp.sha }).catch((err) => logger$
|
|
14117
|
+
if (runManifest !== null && cp.sha) runManifest.patchStoryState(payload.storyKey, { checkpoint_sha: cp.sha }).catch((err) => logger$28.warn({
|
|
13953
14118
|
err,
|
|
13954
14119
|
storyKey: payload.storyKey
|
|
13955
14120
|
}, "patchStoryState(checkpoint_sha, escalation) failed — pipeline continues"));
|
|
13956
|
-
} else if (cp.status === "failed") logger$
|
|
14121
|
+
} else if (cp.status === "failed") logger$28.warn({
|
|
13957
14122
|
storyKey: payload.storyKey,
|
|
13958
14123
|
stderr: cp.stderr.slice(0, 500)
|
|
13959
14124
|
}, "escalation checkpoint failed — worktree state remains uncommitted (inspect before any cleanup)");
|
|
@@ -13967,7 +14132,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
13967
14132
|
storyKey: payload.storyKey,
|
|
13968
14133
|
msg: leakMsg
|
|
13969
14134
|
});
|
|
13970
|
-
logger$
|
|
14135
|
+
logger$28.warn({
|
|
13971
14136
|
storyKey: payload.storyKey,
|
|
13972
14137
|
leakedFileCount: leakedFiles.length
|
|
13973
14138
|
}, "escalation parent-tree leak detected");
|
|
@@ -13984,7 +14149,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
13984
14149
|
runManifest.patchStoryState(payload.storyKey, {
|
|
13985
14150
|
escalation_reason: escalationReason,
|
|
13986
14151
|
...escalationDetail !== void 0 ? { escalation_detail: escalationDetail } : {}
|
|
13987
|
-
}).catch((err) => logger$
|
|
14152
|
+
}).catch((err) => logger$28.warn({
|
|
13988
14153
|
err,
|
|
13989
14154
|
storyKey: payload.storyKey
|
|
13990
14155
|
}, "patchStoryState(escalation_reason/detail) failed — pipeline continues"));
|
|
@@ -14011,7 +14176,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14011
14176
|
rationale: `Escalation diagnosis for ${payload.storyKey}: ${diagnosis.recommendedAction} — ${diagnosis.rationale}`
|
|
14012
14177
|
});
|
|
14013
14178
|
} catch (err) {
|
|
14014
|
-
logger$
|
|
14179
|
+
logger$28.warn({
|
|
14015
14180
|
err,
|
|
14016
14181
|
storyKey: payload.storyKey
|
|
14017
14182
|
}, "Failed to persist escalation diagnosis (best-effort)");
|
|
@@ -14060,7 +14225,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14060
14225
|
...updates
|
|
14061
14226
|
};
|
|
14062
14227
|
const opts = targetStatus === "complete" || targetStatus === "escalated" ? { completedAt: fullUpdated.completedAt } : void 0;
|
|
14063
|
-
wgRepo.updateStoryStatus(storyKey, targetStatus, opts).catch((err) => logger$
|
|
14228
|
+
wgRepo.updateStoryStatus(storyKey, targetStatus, opts).catch((err) => logger$28.warn({
|
|
14064
14229
|
err,
|
|
14065
14230
|
storyKey
|
|
14066
14231
|
}, "wg_stories status update failed (best-effort)"));
|
|
@@ -14076,7 +14241,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14076
14241
|
status: "dispatched",
|
|
14077
14242
|
phase: String(updates.phase),
|
|
14078
14243
|
started_at: fullUpdated.startedAt ?? new Date().toISOString()
|
|
14079
|
-
}).catch((err) => logger$
|
|
14244
|
+
}).catch((err) => logger$28.warn({
|
|
14080
14245
|
err,
|
|
14081
14246
|
storyKey
|
|
14082
14247
|
}, "patchStoryState(dispatched) failed — pipeline continues"));
|
|
@@ -14088,13 +14253,13 @@ function createImplementationOrchestrator(deps) {
|
|
|
14088
14253
|
completed_at: fullUpdated.completedAt ?? new Date().toISOString(),
|
|
14089
14254
|
review_cycles: fullUpdated.reviewCycles ?? 0,
|
|
14090
14255
|
dispatches: _storyDispatches.get(storyKey) ?? 0
|
|
14091
|
-
}).catch((err) => logger$
|
|
14256
|
+
}).catch((err) => logger$28.warn({
|
|
14092
14257
|
err,
|
|
14093
14258
|
storyKey
|
|
14094
14259
|
}, `patchStoryState(${manifestStatus}) failed — pipeline continues`));
|
|
14095
14260
|
} else {
|
|
14096
14261
|
const intermediatePhase = updates.phase;
|
|
14097
|
-
runManifest.patchStoryState(storyKey, { phase: String(intermediatePhase) }).catch((err) => logger$
|
|
14262
|
+
runManifest.patchStoryState(storyKey, { phase: String(intermediatePhase) }).catch((err) => logger$28.warn({
|
|
14098
14263
|
err,
|
|
14099
14264
|
storyKey,
|
|
14100
14265
|
phase: intermediatePhase
|
|
@@ -14113,13 +14278,111 @@ function createImplementationOrchestrator(deps) {
|
|
|
14113
14278
|
token_usage_json: serialized
|
|
14114
14279
|
});
|
|
14115
14280
|
} catch (err) {
|
|
14116
|
-
logger$
|
|
14281
|
+
logger$28.warn({ err }, "Failed to persist orchestrator state");
|
|
14117
14282
|
}
|
|
14118
14283
|
}
|
|
14119
14284
|
function recordProgress() {
|
|
14120
14285
|
_lastProgressTs = Date.now();
|
|
14121
14286
|
_stalledStories.clear();
|
|
14122
14287
|
}
|
|
14288
|
+
const _journeyVerdicts = new Map();
|
|
14289
|
+
/** External artifacts base: ~/.substrate/acceptance/<name>-<hash8>/<run>/ (H4.2 symmetry). */
|
|
14290
|
+
function acceptanceArtifactsBase() {
|
|
14291
|
+
const root = projectRoot ?? process.cwd();
|
|
14292
|
+
const hash = createHash("sha256").update(resolve$1(root)).digest("hex").slice(0, 8);
|
|
14293
|
+
return join$1(homedir(), ".substrate", "acceptance", `${basename$1(root)}-${hash}`, config.pipelineRunId ?? "adhoc");
|
|
14294
|
+
}
|
|
14295
|
+
async function runAcceptanceStage(storyKey, worktreeDir) {
|
|
14296
|
+
const mode = config.acceptanceMode ?? "advisory";
|
|
14297
|
+
if (mode === "off" || projectRoot === void 0) return;
|
|
14298
|
+
const journeyIds = _stories.get(storyKey)?.journeys ?? [];
|
|
14299
|
+
if (journeyIds.length === 0) return;
|
|
14300
|
+
const registryLoad = await loadJourneyRegistryFromTrustedTree(projectRoot);
|
|
14301
|
+
if (registryLoad.status !== "ok") return;
|
|
14302
|
+
const contractLoad = await loadAcceptanceContractFromTrustedTree(projectRoot);
|
|
14303
|
+
if (contractLoad.status !== "ok") {
|
|
14304
|
+
logger$28.warn({
|
|
14305
|
+
storyKey,
|
|
14306
|
+
status: contractLoad.status
|
|
14307
|
+
}, "A2.3: no usable acceptance contract — claimed journeys stay unwalked (acceptance-unrunnable at audit)");
|
|
14308
|
+
return;
|
|
14309
|
+
}
|
|
14310
|
+
const contract = contractLoad.contract;
|
|
14311
|
+
eventBus.emit("orchestrator:acceptance-started", {
|
|
14312
|
+
storyKey,
|
|
14313
|
+
journeys: journeyIds
|
|
14314
|
+
});
|
|
14315
|
+
for (const journeyId of journeyIds) {
|
|
14316
|
+
const journey = registryLoad.registry.journeys.find((j$1) => j$1.id === journeyId);
|
|
14317
|
+
if (journey === void 0) continue;
|
|
14318
|
+
const journeyDir = join$1(acceptanceArtifactsBase(), storyKey, journeyId);
|
|
14319
|
+
const artifacts = [];
|
|
14320
|
+
let renderFailed = false;
|
|
14321
|
+
for (const surface of journey.surfaces) {
|
|
14322
|
+
if (surface === "web") continue;
|
|
14323
|
+
const res = await renderSurface({
|
|
14324
|
+
surface,
|
|
14325
|
+
contract,
|
|
14326
|
+
workingDirectory: worktreeDir,
|
|
14327
|
+
artifactsDir: join$1(journeyDir, surface)
|
|
14328
|
+
});
|
|
14329
|
+
eventBus.emit("orchestrator:acceptance-rendered", {
|
|
14330
|
+
storyKey,
|
|
14331
|
+
surface,
|
|
14332
|
+
status: res.status,
|
|
14333
|
+
artifactsDir: res.artifactsDir,
|
|
14334
|
+
artifacts: res.artifacts,
|
|
14335
|
+
...res.error !== void 0 ? { error: res.error } : {}
|
|
14336
|
+
});
|
|
14337
|
+
if (res.status === "failed") {
|
|
14338
|
+
renderFailed = true;
|
|
14339
|
+
logger$28.warn({
|
|
14340
|
+
storyKey,
|
|
14341
|
+
journeyId,
|
|
14342
|
+
surface,
|
|
14343
|
+
error: res.error,
|
|
14344
|
+
exitCode: res.exitCode,
|
|
14345
|
+
stderrTail: res.stderrTail?.slice(0, 500)
|
|
14346
|
+
}, "A2.3: surface render failed — journey stays unwalked");
|
|
14347
|
+
} else artifacts.push(...res.artifacts.map((a) => join$1(surface, a)));
|
|
14348
|
+
}
|
|
14349
|
+
if (renderFailed || artifacts.length === 0) continue;
|
|
14350
|
+
const judge = await runAcceptanceJudge({
|
|
14351
|
+
db,
|
|
14352
|
+
pack,
|
|
14353
|
+
contextCompiler,
|
|
14354
|
+
dispatcher,
|
|
14355
|
+
projectRoot: journeyDir,
|
|
14356
|
+
parentProjectRoot: projectRoot,
|
|
14357
|
+
tokenCeilings,
|
|
14358
|
+
otlpEndpoint: _otlpEndpoint,
|
|
14359
|
+
agentId
|
|
14360
|
+
}, {
|
|
14361
|
+
journey,
|
|
14362
|
+
artifactsDir: journeyDir,
|
|
14363
|
+
artifacts,
|
|
14364
|
+
storyKey
|
|
14365
|
+
});
|
|
14366
|
+
if (judge.result === "success" && judge.verdicts !== void 0) {
|
|
14367
|
+
_journeyVerdicts.set(journeyId, judge.verdicts);
|
|
14368
|
+
eventBus.emit("orchestrator:acceptance-verdict", {
|
|
14369
|
+
storyKey,
|
|
14370
|
+
journeyId,
|
|
14371
|
+
verdicts: judge.verdicts.map((v) => ({
|
|
14372
|
+
end_state_id: v.end_state_id,
|
|
14373
|
+
verdict: v.verdict,
|
|
14374
|
+
artifact: v.evidence.artifact,
|
|
14375
|
+
excerpt: v.evidence.excerpt
|
|
14376
|
+
}))
|
|
14377
|
+
});
|
|
14378
|
+
} else logger$28.warn({
|
|
14379
|
+
storyKey,
|
|
14380
|
+
journeyId,
|
|
14381
|
+
error: judge.error,
|
|
14382
|
+
details: judge.details
|
|
14383
|
+
}, "A2.3: judge failed — journey stays unwalked");
|
|
14384
|
+
}
|
|
14385
|
+
}
|
|
14123
14386
|
async function auditJourneyCoverage(scope, opts) {
|
|
14124
14387
|
const mode = config.acceptanceMode ?? "advisory";
|
|
14125
14388
|
if (mode === "off" || projectRoot === void 0) return void 0;
|
|
@@ -14130,26 +14393,30 @@ function createImplementationOrchestrator(deps) {
|
|
|
14130
14393
|
unrunnable: "journey registry is INVALID: " + registryLoad.issues.map((i) => `${i.path}: ${i.message}`).join("; ") + " — fix it (substrate acceptance validate) or the audit cannot run"
|
|
14131
14394
|
};
|
|
14132
14395
|
if (registryLoad.status !== "ok") {
|
|
14133
|
-
logger$
|
|
14396
|
+
logger$28.warn({ detail: registryLoad.message }, "A0.3: journey registry read failed — coverage audit skipped (environmental)");
|
|
14134
14397
|
return void 0;
|
|
14135
14398
|
}
|
|
14136
14399
|
let unrunnable;
|
|
14137
14400
|
const contractLoad = await loadAcceptanceContractFromTrustedTree(projectRoot);
|
|
14138
14401
|
if (contractLoad.status === "absent") unrunnable = `journey registry exists but the committed project profile has no acceptance: contract block (${ACCEPTANCE_CONTRACT_PROFILE_PATH}) — claimed journeys can never be walked. Declare render commands per surface.`;
|
|
14139
14402
|
else if (contractLoad.status === "invalid") unrunnable = "acceptance: contract block is INVALID: " + contractLoad.issues.map((i) => `${i.path}: ${i.message}`).join("; ");
|
|
14140
|
-
else if (contractLoad.status === "error") logger$
|
|
14403
|
+
else if (contractLoad.status === "error") logger$28.warn({ detail: contractLoad.message }, "A1.1: acceptance contract read failed (environmental) — treating as absent for this audit");
|
|
14141
14404
|
const deferralsLoad = await loadJourneyDeferralsFromTrustedTree(projectRoot);
|
|
14142
|
-
if (deferralsLoad.status !== "ok") logger$
|
|
14405
|
+
if (deferralsLoad.status !== "ok") logger$28.warn({ detail: deferralsLoad.status === "invalid" ? deferralsLoad.issues : deferralsLoad.message }, `A0.3: ${JOURNEY_DEFERRALS_PATH} unreadable/invalid — treating as no deferrals`);
|
|
14143
14406
|
const deferredJourneyIds = deferralsLoad.status === "ok" ? deferralsLoad.deferrals.map((d) => d.journey) : [];
|
|
14144
14407
|
const claims = [];
|
|
14145
14408
|
for (const [key, st] of _stories.entries()) for (const journeyId of st.journeys ?? []) claims.push({
|
|
14146
14409
|
journeyId,
|
|
14147
14410
|
storyKey: key
|
|
14148
14411
|
});
|
|
14412
|
+
const verdicts = [..._journeyVerdicts.entries()].map(([journeyId, vs]) => ({
|
|
14413
|
+
journeyId,
|
|
14414
|
+
verdict: vs.every((v) => v.verdict === "PASS") ? "pass" : "fail"
|
|
14415
|
+
}));
|
|
14149
14416
|
const entries = computeJourneyCoverage({
|
|
14150
14417
|
registry: registryLoad.registry,
|
|
14151
14418
|
claims,
|
|
14152
|
-
verdicts
|
|
14419
|
+
verdicts,
|
|
14153
14420
|
deferredJourneyIds,
|
|
14154
14421
|
scope
|
|
14155
14422
|
});
|
|
@@ -14160,8 +14427,46 @@ function createImplementationOrchestrator(deps) {
|
|
|
14160
14427
|
entries,
|
|
14161
14428
|
summary: summarizeCoverage(entries)
|
|
14162
14429
|
});
|
|
14163
|
-
if (unrunnable !== void 0) logger$
|
|
14164
|
-
if (opts?.persist === true
|
|
14430
|
+
if (unrunnable !== void 0) logger$28.warn({ scope: scopeLabel }, `A1.1: acceptance gate unrunnable — ${unrunnable}`);
|
|
14431
|
+
if (opts?.persist === true) {
|
|
14432
|
+
const entriesWithVerdicts = entries.map((e) => {
|
|
14433
|
+
const vs = _journeyVerdicts.get(e.journeyId);
|
|
14434
|
+
return vs !== void 0 ? {
|
|
14435
|
+
...e,
|
|
14436
|
+
verdicts: vs.map((v) => ({
|
|
14437
|
+
end_state_id: v.end_state_id,
|
|
14438
|
+
verdict: v.verdict,
|
|
14439
|
+
artifact: v.evidence.artifact,
|
|
14440
|
+
excerpt: v.evidence.excerpt
|
|
14441
|
+
}))
|
|
14442
|
+
} : e;
|
|
14443
|
+
});
|
|
14444
|
+
let reportPath;
|
|
14445
|
+
try {
|
|
14446
|
+
const html = renderVerdictHtml({
|
|
14447
|
+
scope: `${config.pipelineRunId ?? "run"} ${scopeLabel}`,
|
|
14448
|
+
generatedAt: new Date().toISOString(),
|
|
14449
|
+
journeys: entriesWithVerdicts.map((e) => ({
|
|
14450
|
+
journeyId: e.journeyId,
|
|
14451
|
+
title: e.title,
|
|
14452
|
+
criticality: e.criticality,
|
|
14453
|
+
state: e.state,
|
|
14454
|
+
ownerStories: e.ownerStories,
|
|
14455
|
+
verdicts: e.verdicts ?? []
|
|
14456
|
+
}))
|
|
14457
|
+
});
|
|
14458
|
+
reportPath = join$1(acceptanceArtifactsBase(), "acceptance-verdicts.html");
|
|
14459
|
+
mkdirSync(dirname$1(reportPath), { recursive: true });
|
|
14460
|
+
writeFileSync(reportPath, html, "utf-8");
|
|
14461
|
+
} catch (err) {
|
|
14462
|
+
logger$28.warn({ err }, "A2.2: verdict artifact write failed (best-effort)");
|
|
14463
|
+
reportPath = void 0;
|
|
14464
|
+
}
|
|
14465
|
+
if (runManifest !== null) await runManifest.update({
|
|
14466
|
+
journeys: entriesWithVerdicts,
|
|
14467
|
+
...reportPath !== void 0 ? { acceptance_report_path: reportPath } : {}
|
|
14468
|
+
}).catch((err) => logger$28.warn({ err }, "A0.3: manifest journeys ledger write failed — pipeline continues"));
|
|
14469
|
+
}
|
|
14165
14470
|
return unrunnable !== void 0 ? {
|
|
14166
14471
|
entries,
|
|
14167
14472
|
unrunnable
|
|
@@ -14208,7 +14513,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14208
14513
|
...Object.keys(perStoryState).length > 0 ? { perStoryState } : {}
|
|
14209
14514
|
});
|
|
14210
14515
|
if (config.pipelineRunId !== void 0) updatePipelineRun(db, config.pipelineRunId, { current_phase: "implementation" }).catch((err) => {
|
|
14211
|
-
logger$
|
|
14516
|
+
logger$28.debug({ err }, "Heartbeat: failed to touch updated_at (non-fatal)");
|
|
14212
14517
|
});
|
|
14213
14518
|
const elapsed = Date.now() - _lastProgressTs;
|
|
14214
14519
|
let childPids = [];
|
|
@@ -14230,7 +14535,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14230
14535
|
}
|
|
14231
14536
|
if (childActive) {
|
|
14232
14537
|
_lastProgressTs = Date.now();
|
|
14233
|
-
logger$
|
|
14538
|
+
logger$28.debug({
|
|
14234
14539
|
storyKey: key,
|
|
14235
14540
|
phase: s$1.phase,
|
|
14236
14541
|
childPids
|
|
@@ -14239,7 +14544,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14239
14544
|
}
|
|
14240
14545
|
_stalledStories.add(key);
|
|
14241
14546
|
_storiesWithStall.add(key);
|
|
14242
|
-
logger$
|
|
14547
|
+
logger$28.warn({
|
|
14243
14548
|
storyKey: key,
|
|
14244
14549
|
phase: s$1.phase,
|
|
14245
14550
|
elapsedMs: elapsed,
|
|
@@ -14284,7 +14589,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14284
14589
|
for (let attempt = 0; attempt < MEMORY_PRESSURE_BACKOFF_MS.length; attempt++) {
|
|
14285
14590
|
const memState = dispatcher.getMemoryState();
|
|
14286
14591
|
if (!memState.isPressured) return true;
|
|
14287
|
-
logger$
|
|
14592
|
+
logger$28.warn({
|
|
14288
14593
|
storyKey,
|
|
14289
14594
|
freeMB: memState.freeMB,
|
|
14290
14595
|
thresholdMB: memState.thresholdMB,
|
|
@@ -14304,12 +14609,12 @@ function createImplementationOrchestrator(deps) {
|
|
|
14304
14609
|
* exhausted retries the story is ESCALATED.
|
|
14305
14610
|
*/
|
|
14306
14611
|
async function processStory(storyKey, storyOptions) {
|
|
14307
|
-
logger$
|
|
14612
|
+
logger$28.info({ storyKey }, "Processing story");
|
|
14308
14613
|
await initRetryCount(storyKey);
|
|
14309
14614
|
{
|
|
14310
14615
|
const memoryOk = await checkMemoryPressure(storyKey);
|
|
14311
14616
|
if (!memoryOk) {
|
|
14312
|
-
logger$
|
|
14617
|
+
logger$28.warn({ storyKey }, "Memory pressure exhausted — escalating story without dispatch");
|
|
14313
14618
|
const memPressureState = {
|
|
14314
14619
|
phase: "ESCALATED",
|
|
14315
14620
|
reviewCycles: 0,
|
|
@@ -14353,7 +14658,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14353
14658
|
if (match$2) {
|
|
14354
14659
|
const candidatePath = join$1(artifactsDir, match$2);
|
|
14355
14660
|
const validation = await isValidStoryFile(candidatePath);
|
|
14356
|
-
if (!validation.valid) logger$
|
|
14661
|
+
if (!validation.valid) logger$28.warn({
|
|
14357
14662
|
storyKey,
|
|
14358
14663
|
storyFilePath: candidatePath,
|
|
14359
14664
|
reason: validation.reason
|
|
@@ -14378,7 +14683,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14378
14683
|
storedHash,
|
|
14379
14684
|
currentHash
|
|
14380
14685
|
});
|
|
14381
|
-
logger$
|
|
14686
|
+
logger$28.info({
|
|
14382
14687
|
storyKey,
|
|
14383
14688
|
storedHash,
|
|
14384
14689
|
currentHash
|
|
@@ -14389,7 +14694,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14389
14694
|
} catch {}
|
|
14390
14695
|
if (!isDrift) {
|
|
14391
14696
|
storyFilePath = candidatePath;
|
|
14392
|
-
logger$
|
|
14697
|
+
logger$28.info({
|
|
14393
14698
|
storyKey,
|
|
14394
14699
|
storyFilePath
|
|
14395
14700
|
}, "Found existing story file — skipping create-story");
|
|
@@ -14414,12 +14719,12 @@ function createImplementationOrchestrator(deps) {
|
|
|
14414
14719
|
const staleName = match$2.replace(/\.md$/, `.stale-${ts}.md`);
|
|
14415
14720
|
const stalePath = join$1(artifactsDir, staleName);
|
|
14416
14721
|
renameSync(candidatePath, stalePath);
|
|
14417
|
-
logger$
|
|
14722
|
+
logger$28.info({
|
|
14418
14723
|
storyKey,
|
|
14419
14724
|
staleName
|
|
14420
14725
|
}, `[orchestrator] story ${storyKey}: renamed drifted artifact to ${staleName} before re-dispatch`);
|
|
14421
14726
|
} catch (renameErr) {
|
|
14422
|
-
logger$
|
|
14727
|
+
logger$28.warn({
|
|
14423
14728
|
storyKey,
|
|
14424
14729
|
err: renameErr
|
|
14425
14730
|
}, "Failed to rename stale artifact before create-story re-dispatch; relying on 58-9d fraud-guard");
|
|
@@ -14428,7 +14733,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14428
14733
|
}
|
|
14429
14734
|
} catch {}
|
|
14430
14735
|
if (storyFilePath === void 0 && effectiveProjectRoot && isImplicitlyCovered(storyKey, effectiveProjectRoot)) {
|
|
14431
|
-
logger$
|
|
14736
|
+
logger$28.info({ storyKey }, `Story ${storyKey} appears implicitly covered — all expected new files already exist. Skipping create-story.`);
|
|
14432
14737
|
endPhase(storyKey, "create-story");
|
|
14433
14738
|
eventBus.emit("orchestrator:story-phase-complete", {
|
|
14434
14739
|
storyKey,
|
|
@@ -14483,7 +14788,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14483
14788
|
output_tokens: createResult.tokenUsage.output,
|
|
14484
14789
|
cost_usd: estimateDispatchCost(createResult.tokenUsage.input, createResult.tokenUsage.output),
|
|
14485
14790
|
metadata: JSON.stringify({ storyKey })
|
|
14486
|
-
})).catch((tokenErr) => logger$
|
|
14791
|
+
})).catch((tokenErr) => logger$28.warn({
|
|
14487
14792
|
storyKey,
|
|
14488
14793
|
err: tokenErr
|
|
14489
14794
|
}, "Failed to record create-story token usage"));
|
|
@@ -14491,7 +14796,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14491
14796
|
if (createResult.result === "failed") {
|
|
14492
14797
|
const errMsg = createResult.error ?? "create-story failed";
|
|
14493
14798
|
const stderrSnippet = errMsg.includes("--- stderr ---") ? errMsg.slice(errMsg.indexOf("--- stderr ---") + 15, errMsg.indexOf("--- stderr ---") + 515) : errMsg.slice(0, 500);
|
|
14494
|
-
logger$
|
|
14799
|
+
logger$28.error({
|
|
14495
14800
|
storyKey,
|
|
14496
14801
|
stderrSnippet
|
|
14497
14802
|
}, `Create-story failed: ${stderrSnippet.split("\n")[0]}`);
|
|
@@ -14562,7 +14867,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14562
14867
|
const outsideWorktree = relToWorktree.startsWith("..") || isAbsolute(relToWorktree);
|
|
14563
14868
|
if (outsideWorktree) {
|
|
14564
14869
|
const errMsg = `create-story wrote its artifact OUTSIDE the story worktree: ${createResult.story_file} (resolved: ${resolvedStoryFile}) (worktree: ${effectiveProjectRoot}). The agent escaped its working directory — this is the parent/home-directory write-leak class (field finding #15). The stray file was NOT adopted; inspect and remove it.`;
|
|
14565
|
-
logger$
|
|
14870
|
+
logger$28.error({
|
|
14566
14871
|
storyKey,
|
|
14567
14872
|
storyFile: createResult.story_file,
|
|
14568
14873
|
worktree: effectiveProjectRoot
|
|
@@ -14590,7 +14895,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14590
14895
|
let claimedPath = createResult.story_file;
|
|
14591
14896
|
if (claimedPath.startsWith(escapedExpectedDir)) {
|
|
14592
14897
|
claimedPath = claimedPath.replace("/\\_bmad-output/", "/_bmad-output/");
|
|
14593
|
-
logger$
|
|
14898
|
+
logger$28.warn({
|
|
14594
14899
|
storyKey,
|
|
14595
14900
|
originalClaim: createResult.story_file,
|
|
14596
14901
|
normalizedClaim: claimedPath
|
|
@@ -14608,7 +14913,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14608
14913
|
if (escapedVariant !== claimedPath && existsSync(escapedVariant)) try {
|
|
14609
14914
|
renameSync(escapedVariant, claimedPath);
|
|
14610
14915
|
actualPath = claimedPath;
|
|
14611
|
-
logger$
|
|
14916
|
+
logger$28.warn({
|
|
14612
14917
|
storyKey,
|
|
14613
14918
|
escapedVariant,
|
|
14614
14919
|
canonicalPath: claimedPath
|
|
@@ -14619,7 +14924,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14619
14924
|
});
|
|
14620
14925
|
} catch (renameErr) {
|
|
14621
14926
|
actualPath = escapedVariant;
|
|
14622
|
-
logger$
|
|
14927
|
+
logger$28.warn({
|
|
14623
14928
|
storyKey,
|
|
14624
14929
|
escapedVariant,
|
|
14625
14930
|
canonicalPath: claimedPath,
|
|
@@ -14634,7 +14939,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14634
14939
|
if (actualPath === null) {
|
|
14635
14940
|
const outputTokens = createResult.tokenUsage?.output ?? 0;
|
|
14636
14941
|
const errMsg = `create-story claimed success (story_file: ${createResult.story_file}) but the file does not exist on disk (output tokens: ${outputTokens})`;
|
|
14637
|
-
logger$
|
|
14942
|
+
logger$28.error({
|
|
14638
14943
|
storyKey,
|
|
14639
14944
|
claimedPath: createResult.story_file,
|
|
14640
14945
|
outputTokens
|
|
@@ -14662,7 +14967,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14662
14967
|
const mtimeISO = new Date(claimedStat.mtimeMs).toISOString();
|
|
14663
14968
|
const dispatchStartISO = new Date(dispatchStartMs).toISOString();
|
|
14664
14969
|
const errMsg = `create-story claimed success but did not rewrite ${actualPath} during this dispatch (file mtime ${mtimeISO} predates dispatch start ${dispatchStartISO}; output tokens: ${outputTokens})`;
|
|
14665
|
-
logger$
|
|
14970
|
+
logger$28.error({
|
|
14666
14971
|
storyKey,
|
|
14667
14972
|
claimedPath: actualPath,
|
|
14668
14973
|
mtimeISO,
|
|
@@ -14685,7 +14990,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14685
14990
|
return;
|
|
14686
14991
|
}
|
|
14687
14992
|
} catch (verifyErr) {
|
|
14688
|
-
logger$
|
|
14993
|
+
logger$28.warn({
|
|
14689
14994
|
storyKey,
|
|
14690
14995
|
err: verifyErr
|
|
14691
14996
|
}, "create-story post-dispatch file verification threw; proceeding with claimed path");
|
|
@@ -14694,7 +14999,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14694
14999
|
storyFilePath = createResult.story_file;
|
|
14695
15000
|
if (createResult.journeys !== void 0 && createResult.journeys.length > 0) {
|
|
14696
15001
|
updateStory(storyKey, { journeys: createResult.journeys });
|
|
14697
|
-
if (runManifest !== null) runManifest.patchStoryState(storyKey, { journeys: createResult.journeys }).catch((err) => logger$
|
|
15002
|
+
if (runManifest !== null) runManifest.patchStoryState(storyKey, { journeys: createResult.journeys }).catch((err) => logger$28.warn({
|
|
14698
15003
|
err,
|
|
14699
15004
|
storyKey
|
|
14700
15005
|
}, "A0.3: patchStoryState(journeys) failed — pipeline continues"));
|
|
@@ -14716,7 +15021,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14716
15021
|
const overlap = computeTitleOverlap(expectedTitle, createResult.story_title);
|
|
14717
15022
|
if (overlap < TITLE_OVERLAP_WARNING_THRESHOLD) {
|
|
14718
15023
|
const msg = `Story title mismatch: expected "${expectedTitle}" but got "${createResult.story_title}" (word overlap: ${Math.round(overlap * 100)}%). This may indicate the create-story agent received truncated context.`;
|
|
14719
|
-
logger$
|
|
15024
|
+
logger$28.warn({
|
|
14720
15025
|
storyKey,
|
|
14721
15026
|
expectedTitle,
|
|
14722
15027
|
generatedTitle: createResult.story_title,
|
|
@@ -14726,7 +15031,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14726
15031
|
storyKey,
|
|
14727
15032
|
msg
|
|
14728
15033
|
});
|
|
14729
|
-
} else logger$
|
|
15034
|
+
} else logger$28.debug({
|
|
14730
15035
|
storyKey,
|
|
14731
15036
|
expectedTitle,
|
|
14732
15037
|
generatedTitle: createResult.story_title,
|
|
@@ -14735,7 +15040,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14735
15040
|
}
|
|
14736
15041
|
}
|
|
14737
15042
|
} catch (titleValidationErr) {
|
|
14738
|
-
logger$
|
|
15043
|
+
logger$28.debug({
|
|
14739
15044
|
storyKey,
|
|
14740
15045
|
err: titleValidationErr
|
|
14741
15046
|
}, "Story title validation skipped due to error");
|
|
@@ -14776,7 +15081,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14776
15081
|
const pathDrift = pathFidelity?.drift ?? 0;
|
|
14777
15082
|
const clauseDrift = clauseFidelity.drift;
|
|
14778
15083
|
const overallDrift = Math.max(pathDrift, clauseDrift);
|
|
14779
|
-
logger$
|
|
15084
|
+
logger$28.debug({
|
|
14780
15085
|
storyKey,
|
|
14781
15086
|
pathDrift,
|
|
14782
15087
|
clauseDrift,
|
|
@@ -14798,7 +15103,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14798
15103
|
if (pathMissing.length > 0) reasons.push(`${pathMissing.length} named path(s) missing`);
|
|
14799
15104
|
if (numericMismatches.length > 0) reasons.push(`${numericMismatches.length} numeric quantifier mismatch(es) (e.g., "${numericMismatches[0].noun}" source=${numericMismatches[0].sourceCount} rendered=${numericMismatches[0].renderedCount})`);
|
|
14800
15105
|
if (clauseFidelity.clauseRatio < .7) reasons.push(`clause shortfall (rendered ${clauseFidelity.renderedClauseCount}/${clauseFidelity.sourceClauseCount} = ${Math.round(clauseFidelity.clauseRatio * 100)}%)`);
|
|
14801
|
-
logger$
|
|
15106
|
+
logger$28.warn({
|
|
14802
15107
|
storyKey,
|
|
14803
15108
|
pathDrift,
|
|
14804
15109
|
clauseDrift,
|
|
@@ -14841,7 +15146,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14841
15146
|
storyFilePath = void 0;
|
|
14842
15147
|
continue;
|
|
14843
15148
|
} catch (renameErr) {
|
|
14844
|
-
logger$
|
|
15149
|
+
logger$28.warn({
|
|
14845
15150
|
storyKey,
|
|
14846
15151
|
err: renameErr,
|
|
14847
15152
|
stalePath
|
|
@@ -14855,7 +15160,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14855
15160
|
if (numericMismatches.length > 0) reasons.push(`numeric mismatches: ${numericMismatches.map((m) => `${m.noun} (source=${m.sourceCount}, rendered=${m.renderedCount})`).join("; ")}`);
|
|
14856
15161
|
if (clauseFidelity.clauseRatio < .7) reasons.push(`clause shortfall: source=${clauseFidelity.sourceClauseCount}, rendered=${clauseFidelity.renderedClauseCount}`);
|
|
14857
15162
|
const errMsg = `create-story output drifted from source AC after ${MAX_FIDELITY_RETRIES} retries; ` + reasons.join("; ");
|
|
14858
|
-
logger$
|
|
15163
|
+
logger$28.error({
|
|
14859
15164
|
storyKey,
|
|
14860
15165
|
pathDrift,
|
|
14861
15166
|
clauseDrift,
|
|
@@ -14882,7 +15187,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14882
15187
|
}
|
|
14883
15188
|
}
|
|
14884
15189
|
} catch (fidelityErr) {
|
|
14885
|
-
logger$
|
|
15190
|
+
logger$28.warn({
|
|
14886
15191
|
storyKey,
|
|
14887
15192
|
err: fidelityErr
|
|
14888
15193
|
}, "fidelity gate threw; proceeding without retry");
|
|
@@ -14894,7 +15199,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14894
15199
|
probeRetries++;
|
|
14895
15200
|
const stalePath = storyFilePath.replace(/\.md$/, `.stale-probe-${Date.now()}.md`);
|
|
14896
15201
|
renameSync(storyFilePath, stalePath);
|
|
14897
|
-
logger$
|
|
15202
|
+
logger$28.warn({
|
|
14898
15203
|
storyKey,
|
|
14899
15204
|
error: probeParse.error,
|
|
14900
15205
|
retries: probeRetries,
|
|
@@ -14919,7 +15224,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14919
15224
|
continue;
|
|
14920
15225
|
}
|
|
14921
15226
|
} catch (probeGateErr) {
|
|
14922
|
-
logger$
|
|
15227
|
+
logger$28.warn({
|
|
14923
15228
|
storyKey,
|
|
14924
15229
|
err: probeGateErr
|
|
14925
15230
|
}, "probe-validity gate threw; proceeding without retry (verification backstop)");
|
|
@@ -14942,14 +15247,14 @@ function createImplementationOrchestrator(deps) {
|
|
|
14942
15247
|
...contract.transport !== void 0 ? { transport: contract.transport } : {}
|
|
14943
15248
|
})
|
|
14944
15249
|
});
|
|
14945
|
-
logger$
|
|
15250
|
+
logger$28.info({
|
|
14946
15251
|
storyKey,
|
|
14947
15252
|
contractCount: contracts.length,
|
|
14948
15253
|
contracts
|
|
14949
15254
|
}, "Stored interface contract declarations");
|
|
14950
15255
|
}
|
|
14951
15256
|
} catch (err) {
|
|
14952
|
-
logger$
|
|
15257
|
+
logger$28.warn({
|
|
14953
15258
|
storyKey,
|
|
14954
15259
|
error: err instanceof Error ? err.message : String(err)
|
|
14955
15260
|
}, "Failed to parse interface contracts — continuing without contract declarations");
|
|
@@ -14967,7 +15272,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14967
15272
|
const isStateIntegrating = stateIntegratingEnabled && detectsStateIntegratingAC(probeAuthorEpicContent);
|
|
14968
15273
|
if (isEventDriven || isStateIntegrating) {
|
|
14969
15274
|
const triggerClass = isEventDriven && isStateIntegrating ? "both" : isStateIntegrating ? "state-integrating" : "event-driven";
|
|
14970
|
-
if (runManifest !== null && runManifest !== void 0) runManifest.patchStoryState(storyKey, { probe_author_triggered_by: triggerClass }).catch((err) => logger$
|
|
15275
|
+
if (runManifest !== null && runManifest !== void 0) runManifest.patchStoryState(storyKey, { probe_author_triggered_by: triggerClass }).catch((err) => logger$28.warn({
|
|
14971
15276
|
err,
|
|
14972
15277
|
storyKey
|
|
14973
15278
|
}, "patchStoryState(probe_author_triggered_by) failed — pipeline continues"));
|
|
@@ -15002,7 +15307,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15002
15307
|
});
|
|
15003
15308
|
}
|
|
15004
15309
|
});
|
|
15005
|
-
logger$
|
|
15310
|
+
logger$28.info({
|
|
15006
15311
|
storyKey,
|
|
15007
15312
|
result: probeAuthorResult.result,
|
|
15008
15313
|
probesAuthoredCount: probeAuthorResult.probesAuthoredCount
|
|
@@ -15014,14 +15319,14 @@ function createImplementationOrchestrator(deps) {
|
|
|
15014
15319
|
output_tokens: probeAuthorResult.tokenUsage.output,
|
|
15015
15320
|
cost_usd: estimateDispatchCost(probeAuthorResult.tokenUsage.input, probeAuthorResult.tokenUsage.output),
|
|
15016
15321
|
metadata: JSON.stringify({ storyKey })
|
|
15017
|
-
})).catch((tokenErr) => logger$
|
|
15322
|
+
})).catch((tokenErr) => logger$28.warn({
|
|
15018
15323
|
storyKey,
|
|
15019
15324
|
err: tokenErr
|
|
15020
15325
|
}, "Failed to record probe-author token usage"));
|
|
15021
|
-
} else logger$
|
|
15022
|
-
} else logger$
|
|
15326
|
+
} else logger$28.debug({ storyKey }, "probe-author: story artifact already has ## Runtime Probes — skipping gate");
|
|
15327
|
+
} else logger$28.debug({ storyKey }, "probe-author: source AC not event-driven — skipping gate");
|
|
15023
15328
|
} catch (probeAuthorErr) {
|
|
15024
|
-
logger$
|
|
15329
|
+
logger$28.warn({
|
|
15025
15330
|
storyKey,
|
|
15026
15331
|
err: probeAuthorErr
|
|
15027
15332
|
}, "probe-author gate threw unexpectedly; proceeding to test-plan without authored probes");
|
|
@@ -15051,10 +15356,10 @@ function createImplementationOrchestrator(deps) {
|
|
|
15051
15356
|
});
|
|
15052
15357
|
testPlanPhaseResult = testPlanResult.result;
|
|
15053
15358
|
testPlanTokenUsage = testPlanResult.tokenUsage;
|
|
15054
|
-
if (testPlanResult.result === "success") logger$
|
|
15055
|
-
else logger$
|
|
15359
|
+
if (testPlanResult.result === "success") logger$28.info({ storyKey }, "Test plan generated successfully");
|
|
15360
|
+
else logger$28.warn({ storyKey }, "Test planning returned failed result — proceeding to dev-story without test plan");
|
|
15056
15361
|
} catch (err) {
|
|
15057
|
-
logger$
|
|
15362
|
+
logger$28.warn({
|
|
15058
15363
|
storyKey,
|
|
15059
15364
|
err
|
|
15060
15365
|
}, "Test planning failed — proceeding to dev-story without test plan");
|
|
@@ -15067,7 +15372,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15067
15372
|
output_tokens: testPlanTokenUsage.output,
|
|
15068
15373
|
cost_usd: estimateDispatchCost(testPlanTokenUsage.input, testPlanTokenUsage.output),
|
|
15069
15374
|
metadata: JSON.stringify({ storyKey })
|
|
15070
|
-
})).catch((tokenErr) => logger$
|
|
15375
|
+
})).catch((tokenErr) => logger$28.warn({
|
|
15071
15376
|
storyKey,
|
|
15072
15377
|
err: tokenErr
|
|
15073
15378
|
}, "Failed to record test-plan token usage"));
|
|
@@ -15130,7 +15435,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15130
15435
|
]
|
|
15131
15436
|
}).trim();
|
|
15132
15437
|
} catch {}
|
|
15133
|
-
if (baselineHeadSha !== void 0 && runManifest !== null) runManifest.patchStoryState(storyKey, { baseline_sha: baselineHeadSha }).catch((err) => logger$
|
|
15438
|
+
if (baselineHeadSha !== void 0 && runManifest !== null) runManifest.patchStoryState(storyKey, { baseline_sha: baselineHeadSha }).catch((err) => logger$28.warn({
|
|
15134
15439
|
err,
|
|
15135
15440
|
storyKey
|
|
15136
15441
|
}, "patchStoryState(baseline_sha) failed — pipeline continues"));
|
|
@@ -15140,7 +15445,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15140
15445
|
storyContentForAnalysis = await readFile$1(storyFilePath ?? "", "utf-8");
|
|
15141
15446
|
storyContentForVerification = storyContentForAnalysis;
|
|
15142
15447
|
} catch (err) {
|
|
15143
|
-
logger$
|
|
15448
|
+
logger$28.error({
|
|
15144
15449
|
storyKey,
|
|
15145
15450
|
storyFilePath,
|
|
15146
15451
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -15148,7 +15453,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15148
15453
|
}
|
|
15149
15454
|
const analysis = analyzeStoryComplexity(storyContentForAnalysis);
|
|
15150
15455
|
const batches = planTaskBatches(analysis);
|
|
15151
|
-
logger$
|
|
15456
|
+
logger$28.info({
|
|
15152
15457
|
storyKey,
|
|
15153
15458
|
estimatedScope: analysis.estimatedScope,
|
|
15154
15459
|
batchCount: batches.length,
|
|
@@ -15166,7 +15471,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15166
15471
|
if (_state !== "RUNNING") break;
|
|
15167
15472
|
const taskScope = batch.taskIds.map((id, i) => `T${id}: ${batch.taskTitles[i] ?? ""}`).join("\n");
|
|
15168
15473
|
const priorFiles = allFilesModified.size > 0 ? Array.from(allFilesModified) : void 0;
|
|
15169
|
-
logger$
|
|
15474
|
+
logger$28.info({
|
|
15170
15475
|
storyKey,
|
|
15171
15476
|
batchIndex: batch.batchIndex,
|
|
15172
15477
|
taskCount: batch.taskIds.length
|
|
@@ -15198,7 +15503,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15198
15503
|
});
|
|
15199
15504
|
} catch (batchErr) {
|
|
15200
15505
|
const errMsg = batchErr instanceof Error ? batchErr.message : String(batchErr);
|
|
15201
|
-
logger$
|
|
15506
|
+
logger$28.warn({
|
|
15202
15507
|
storyKey,
|
|
15203
15508
|
batchIndex: batch.batchIndex,
|
|
15204
15509
|
error: errMsg
|
|
@@ -15220,7 +15525,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15220
15525
|
filesModified: batchFilesModified,
|
|
15221
15526
|
result: batchResult.result === "success" ? "success" : "failed"
|
|
15222
15527
|
};
|
|
15223
|
-
logger$
|
|
15528
|
+
logger$28.info(batchMetrics, "Batch dev-story metrics");
|
|
15224
15529
|
for (const f$1 of batchFilesModified) allFilesModified.add(f$1);
|
|
15225
15530
|
if (batchFilesModified.length > 0) batchFileGroups.push({
|
|
15226
15531
|
batchIndex: batch.batchIndex,
|
|
@@ -15239,13 +15544,13 @@ function createImplementationOrchestrator(deps) {
|
|
|
15239
15544
|
durationMs: batchDurationMs,
|
|
15240
15545
|
result: batchMetrics.result
|
|
15241
15546
|
})
|
|
15242
|
-
})).catch((tokenErr) => logger$
|
|
15547
|
+
})).catch((tokenErr) => logger$28.warn({
|
|
15243
15548
|
storyKey,
|
|
15244
15549
|
batchIndex: batch.batchIndex,
|
|
15245
15550
|
err: tokenErr
|
|
15246
15551
|
}, "Failed to record batch token usage"));
|
|
15247
15552
|
if (batchResult.tokenUsage?.output !== void 0) devOutputTokenCount = (devOutputTokenCount ?? 0) + batchResult.tokenUsage.output;
|
|
15248
|
-
if (batchResult.result === "failed") logger$
|
|
15553
|
+
if (batchResult.result === "failed") logger$28.warn({
|
|
15249
15554
|
storyKey,
|
|
15250
15555
|
batchIndex: batch.batchIndex,
|
|
15251
15556
|
error: batchResult.error
|
|
@@ -15290,7 +15595,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15290
15595
|
output_tokens: devResult.tokenUsage.output,
|
|
15291
15596
|
cost_usd: estimateDispatchCost(devResult.tokenUsage.input, devResult.tokenUsage.output),
|
|
15292
15597
|
metadata: JSON.stringify({ storyKey })
|
|
15293
|
-
})).catch((tokenErr) => logger$
|
|
15598
|
+
})).catch((tokenErr) => logger$28.warn({
|
|
15294
15599
|
storyKey,
|
|
15295
15600
|
err: tokenErr
|
|
15296
15601
|
}, "Failed to record dev-story token usage"));
|
|
@@ -15305,7 +15610,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15305
15610
|
endPhase(storyKey, "dev-story", devStoryModel);
|
|
15306
15611
|
const timeoutFiles = checkGitDiffFiles(effectiveProjectRoot ?? process.cwd());
|
|
15307
15612
|
if (timeoutFiles.length === 0) {
|
|
15308
|
-
logger$
|
|
15613
|
+
logger$28.warn({ storyKey }, "Dev-story timeout with zero modified files — escalating immediately (no checkpoint)");
|
|
15309
15614
|
updateStory(storyKey, {
|
|
15310
15615
|
phase: "ESCALATED",
|
|
15311
15616
|
error: "timeout-no-files",
|
|
@@ -15321,7 +15626,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15321
15626
|
await persistState();
|
|
15322
15627
|
return;
|
|
15323
15628
|
}
|
|
15324
|
-
logger$
|
|
15629
|
+
logger$28.info({
|
|
15325
15630
|
storyKey,
|
|
15326
15631
|
filesCount: timeoutFiles.length
|
|
15327
15632
|
}, "Dev-story timeout with partial files — capturing checkpoint");
|
|
@@ -15338,7 +15643,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15338
15643
|
]
|
|
15339
15644
|
}).trim();
|
|
15340
15645
|
} catch (diffErr) {
|
|
15341
|
-
logger$
|
|
15646
|
+
logger$28.warn({
|
|
15342
15647
|
storyKey,
|
|
15343
15648
|
error: diffErr instanceof Error ? diffErr.message : String(diffErr)
|
|
15344
15649
|
}, "Failed to capture git diff for checkpoint — proceeding with empty diff");
|
|
@@ -15412,9 +15717,9 @@ function createImplementationOrchestrator(deps) {
|
|
|
15412
15717
|
checkpointRetryPrompt = assembled.prompt;
|
|
15413
15718
|
} catch {
|
|
15414
15719
|
checkpointRetryPrompt = `Continue story ${storyKey} from checkpoint. Your prior attempt timed out. Do not redo completed work.`;
|
|
15415
|
-
logger$
|
|
15720
|
+
logger$28.warn({ storyKey }, "Failed to assemble checkpoint retry prompt — using fallback");
|
|
15416
15721
|
}
|
|
15417
|
-
logger$
|
|
15722
|
+
logger$28.info({
|
|
15418
15723
|
storyKey,
|
|
15419
15724
|
filesCount: checkpointData.filesModified.length
|
|
15420
15725
|
}, "Dispatching checkpoint retry for timed-out story");
|
|
@@ -15444,7 +15749,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15444
15749
|
outcome: checkpointRetryResult.status === "timeout" ? "escalated" : "retried",
|
|
15445
15750
|
cost_usd: 0,
|
|
15446
15751
|
timestamp: new Date().toISOString()
|
|
15447
|
-
}).catch((err) => logger$
|
|
15752
|
+
}).catch((err) => logger$28.warn({
|
|
15448
15753
|
err,
|
|
15449
15754
|
storyKey
|
|
15450
15755
|
}, "appendRecoveryEntry(checkpoint-retry) failed — pipeline continues"));
|
|
@@ -15457,7 +15762,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15457
15762
|
} : void 0 }
|
|
15458
15763
|
});
|
|
15459
15764
|
if (checkpointRetryResult.status === "timeout") {
|
|
15460
|
-
logger$
|
|
15765
|
+
logger$28.warn({ storyKey }, "Checkpoint retry dispatch timed out — escalating story");
|
|
15461
15766
|
updateStory(storyKey, {
|
|
15462
15767
|
phase: "ESCALATED",
|
|
15463
15768
|
error: "checkpoint-retry-timeout",
|
|
@@ -15477,7 +15782,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15477
15782
|
replaceDevStorySignals(retryParsed);
|
|
15478
15783
|
devFilesModified = retryParsed?.files_modified ?? checkGitDiffFiles(effectiveProjectRoot ?? process.cwd());
|
|
15479
15784
|
if (checkpointRetryResult.status === "completed" && retryParsed?.result === "success") devStoryWasSuccess = true;
|
|
15480
|
-
else logger$
|
|
15785
|
+
else logger$28.warn({
|
|
15481
15786
|
storyKey,
|
|
15482
15787
|
status: checkpointRetryResult.status
|
|
15483
15788
|
}, "Checkpoint retry completed with failure — proceeding to code review");
|
|
@@ -15487,13 +15792,13 @@ function createImplementationOrchestrator(deps) {
|
|
|
15487
15792
|
replaceDevStorySignals(devResult);
|
|
15488
15793
|
if (devResult.result === "success") devStoryWasSuccess = true;
|
|
15489
15794
|
else {
|
|
15490
|
-
logger$
|
|
15795
|
+
logger$28.warn({
|
|
15491
15796
|
storyKey,
|
|
15492
15797
|
error: devResult.error,
|
|
15493
15798
|
filesModified: devFilesModified.length
|
|
15494
15799
|
}, "Dev-story reported failure, proceeding to code review");
|
|
15495
15800
|
if (!devResult.error?.startsWith("dispatch_timeout")) {
|
|
15496
|
-
logger$
|
|
15801
|
+
logger$28.warn({
|
|
15497
15802
|
storyKey,
|
|
15498
15803
|
error: devResult.error
|
|
15499
15804
|
}, "Agent process failure (non-timeout) — story will proceed to code review with partial work");
|
|
@@ -15574,7 +15879,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15574
15879
|
}).trim();
|
|
15575
15880
|
if (committedFiles.length > 0) gitDiffFiles = committedFiles.split("\n").filter(Boolean);
|
|
15576
15881
|
} catch {}
|
|
15577
|
-
logger$
|
|
15882
|
+
logger$28.info({
|
|
15578
15883
|
storyKey,
|
|
15579
15884
|
baselineHeadSha,
|
|
15580
15885
|
committedFileCount: gitDiffFiles?.length ?? 0
|
|
@@ -15582,7 +15887,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15582
15887
|
} else {
|
|
15583
15888
|
const outsideWorktreeFiles = detectWorkOutsideWorktree(effectiveProjectRoot, projectRoot, checkGitDiffFiles);
|
|
15584
15889
|
const misrouted = outsideWorktreeFiles.length > 0;
|
|
15585
|
-
logger$
|
|
15890
|
+
logger$28.warn({
|
|
15586
15891
|
storyKey,
|
|
15587
15892
|
misrouteSuspected: misrouted,
|
|
15588
15893
|
outsideWorktreeFileCount: outsideWorktreeFiles.length
|
|
@@ -15658,7 +15963,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15658
15963
|
}
|
|
15659
15964
|
}
|
|
15660
15965
|
if (implClassification.hasImplementation && implAddedLines === 0) {
|
|
15661
|
-
logger$
|
|
15966
|
+
logger$28.warn({
|
|
15662
15967
|
storyKey,
|
|
15663
15968
|
changed: gitDiffFiles.slice(0, 10)
|
|
15664
15969
|
}, "dev-story reported success but its implementation files added zero non-whitespace lines (empty stub / whitespace-only / pure deletion) — escalating no-implementation");
|
|
@@ -15680,7 +15985,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15680
15985
|
return;
|
|
15681
15986
|
}
|
|
15682
15987
|
if (!implClassification.hasImplementation) {
|
|
15683
|
-
logger$
|
|
15988
|
+
logger$28.warn({
|
|
15684
15989
|
storyKey,
|
|
15685
15990
|
artifactFiles: implClassification.artifactOnly.slice(0, 10)
|
|
15686
15991
|
}, "dev-story reported success but the diff contains only pipeline artifacts — no implementation was produced");
|
|
@@ -15709,24 +16014,24 @@ function createImplementationOrchestrator(deps) {
|
|
|
15709
16014
|
if (dirtyNow.length > 0) if (devStoryWasSuccess) {
|
|
15710
16015
|
const earlyCommit = await commitDevStoryOutput(storyKey, _capturedStoryTitle, dirtyNow, effectiveProjectRoot);
|
|
15711
16016
|
if (earlyCommit.status === "committed") {
|
|
15712
|
-
logger$
|
|
16017
|
+
logger$28.info({
|
|
15713
16018
|
storyKey,
|
|
15714
16019
|
sha: earlyCommit.sha,
|
|
15715
16020
|
fileCount: earlyCommit.filesStaged.length
|
|
15716
16021
|
}, "commit-first: dev-story output committed to story branch");
|
|
15717
|
-
if (runManifest !== null && earlyCommit.sha) runManifest.patchStoryState(storyKey, { commit_sha: earlyCommit.sha }).catch((err) => logger$
|
|
16022
|
+
if (runManifest !== null && earlyCommit.sha) runManifest.patchStoryState(storyKey, { commit_sha: earlyCommit.sha }).catch((err) => logger$28.warn({
|
|
15718
16023
|
err,
|
|
15719
16024
|
storyKey
|
|
15720
16025
|
}, "patchStoryState(commit_sha, commit-first) failed — pipeline continues"));
|
|
15721
16026
|
} else if (earlyCommit.status === "failed") {
|
|
15722
16027
|
_devOutputCommitHookFailure = earlyCommit.stderr;
|
|
15723
16028
|
const cp = await checkpointStoryWorktree(storyKey, "dev-story output (deliverable commit rejected by hooks)", effectiveProjectRoot);
|
|
15724
|
-
logger$
|
|
16029
|
+
logger$28.warn({
|
|
15725
16030
|
storyKey,
|
|
15726
16031
|
checkpoint: cp.status,
|
|
15727
16032
|
hookStderr: earlyCommit.stderr.slice(0, 500)
|
|
15728
16033
|
}, "commit-first: hooks rejected feat commit — work preserved as wip checkpoint");
|
|
15729
|
-
if (cp.status === "committed" && runManifest !== null && cp.sha) runManifest.patchStoryState(storyKey, { checkpoint_sha: cp.sha }).catch((err) => logger$
|
|
16034
|
+
if (cp.status === "committed" && runManifest !== null && cp.sha) runManifest.patchStoryState(storyKey, { checkpoint_sha: cp.sha }).catch((err) => logger$28.warn({
|
|
15730
16035
|
err,
|
|
15731
16036
|
storyKey
|
|
15732
16037
|
}, "patchStoryState(checkpoint_sha) failed — pipeline continues"));
|
|
@@ -15734,11 +16039,11 @@ function createImplementationOrchestrator(deps) {
|
|
|
15734
16039
|
} else {
|
|
15735
16040
|
const cp = await checkpointStoryWorktree(storyKey, "dev-story partial output", effectiveProjectRoot);
|
|
15736
16041
|
if (cp.status === "committed") {
|
|
15737
|
-
logger$
|
|
16042
|
+
logger$28.info({
|
|
15738
16043
|
storyKey,
|
|
15739
16044
|
sha: cp.sha
|
|
15740
16045
|
}, "commit-first: partial dev-story output checkpointed");
|
|
15741
|
-
if (runManifest !== null && cp.sha) runManifest.patchStoryState(storyKey, { checkpoint_sha: cp.sha }).catch((err) => logger$
|
|
16046
|
+
if (runManifest !== null && cp.sha) runManifest.patchStoryState(storyKey, { checkpoint_sha: cp.sha }).catch((err) => logger$28.warn({
|
|
15742
16047
|
err,
|
|
15743
16048
|
storyKey
|
|
15744
16049
|
}, "patchStoryState(checkpoint_sha) failed — pipeline continues"));
|
|
@@ -15772,10 +16077,10 @@ function createImplementationOrchestrator(deps) {
|
|
|
15772
16077
|
"pipe"
|
|
15773
16078
|
]
|
|
15774
16079
|
});
|
|
15775
|
-
logger$
|
|
16080
|
+
logger$28.info({ storyKey }, "Secondary typecheck (tsc --noEmit) passed");
|
|
15776
16081
|
} catch (tscErr) {
|
|
15777
16082
|
const tscOutput = tscErr instanceof Error && "stdout" in tscErr ? String(tscErr.stdout ?? "").slice(0, 2e3) : "";
|
|
15778
|
-
logger$
|
|
16083
|
+
logger$28.warn({
|
|
15779
16084
|
storyKey,
|
|
15780
16085
|
tscOutput
|
|
15781
16086
|
}, "Secondary typecheck (tsc --noEmit) failed — treating as build failure");
|
|
@@ -15790,7 +16095,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15790
16095
|
if (buildVerifyResult.status === "passed") {
|
|
15791
16096
|
_buildPassed = true;
|
|
15792
16097
|
eventBus.emit("story:build-verification-passed", { storyKey });
|
|
15793
|
-
logger$
|
|
16098
|
+
logger$28.info({ storyKey }, "Build verification passed");
|
|
15794
16099
|
} else if (buildVerifyResult.status === "failed" || buildVerifyResult.status === "timeout") {
|
|
15795
16100
|
const truncatedOutput = (buildVerifyResult.output ?? "").slice(0, 2e3);
|
|
15796
16101
|
const reason = buildVerifyResult.reason ?? "build-verification-failed";
|
|
@@ -15799,7 +16104,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15799
16104
|
const resolvedRoot = effectiveProjectRoot ?? process.cwd();
|
|
15800
16105
|
const hasChanges = detectPackageChanges(_packageSnapshot, resolvedRoot);
|
|
15801
16106
|
if (hasChanges) {
|
|
15802
|
-
logger$
|
|
16107
|
+
logger$28.warn({ storyKey }, "Package files changed since snapshot — restoring to prevent cascade");
|
|
15803
16108
|
const restoreResult = restorePackageSnapshot(_packageSnapshot, { projectRoot: resolvedRoot });
|
|
15804
16109
|
if (restoreResult.restored) {
|
|
15805
16110
|
const retryAfterRestore = runBuildVerification({
|
|
@@ -15812,11 +16117,11 @@ function createImplementationOrchestrator(deps) {
|
|
|
15812
16117
|
retryPassed = true;
|
|
15813
16118
|
_buildPassed = true;
|
|
15814
16119
|
eventBus.emit("story:build-verification-passed", { storyKey });
|
|
15815
|
-
logger$
|
|
16120
|
+
logger$28.warn({
|
|
15816
16121
|
storyKey,
|
|
15817
16122
|
filesRestored: restoreResult.filesRestored
|
|
15818
16123
|
}, "Build passed after package snapshot restore — cross-story pollution detected and cleaned");
|
|
15819
|
-
} else logger$
|
|
16124
|
+
} else logger$28.warn({
|
|
15820
16125
|
storyKey,
|
|
15821
16126
|
filesRestored: restoreResult.filesRestored
|
|
15822
16127
|
}, "Build still fails after snapshot restore — story has its own build errors");
|
|
@@ -15828,7 +16133,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15828
16133
|
if (missingPkgMatch && buildVerifyResult.status !== "timeout") {
|
|
15829
16134
|
const missingPkg = missingPkgMatch[1].replace(/^(@[^/]+\/[^/]+)\/.*$/, "$1").replace(/^([^@][^/]*)\/.*$/, "$1");
|
|
15830
16135
|
const resolvedRoot = effectiveProjectRoot ?? process.cwd();
|
|
15831
|
-
logger$
|
|
16136
|
+
logger$28.warn({
|
|
15832
16137
|
storyKey,
|
|
15833
16138
|
missingPkg
|
|
15834
16139
|
}, "Build-fix retry: detected missing npm package — attempting npm install");
|
|
@@ -15839,7 +16144,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15839
16144
|
encoding: "utf-8",
|
|
15840
16145
|
stdio: "pipe"
|
|
15841
16146
|
});
|
|
15842
|
-
logger$
|
|
16147
|
+
logger$28.warn({
|
|
15843
16148
|
storyKey,
|
|
15844
16149
|
missingPkg
|
|
15845
16150
|
}, "Build-fix retry: npm install succeeded — retrying build verification");
|
|
@@ -15853,18 +16158,18 @@ function createImplementationOrchestrator(deps) {
|
|
|
15853
16158
|
retryPassed = true;
|
|
15854
16159
|
_buildPassed = true;
|
|
15855
16160
|
eventBus.emit("story:build-verification-passed", { storyKey });
|
|
15856
|
-
logger$
|
|
16161
|
+
logger$28.warn({
|
|
15857
16162
|
storyKey,
|
|
15858
16163
|
missingPkg
|
|
15859
16164
|
}, "Build-fix retry: build verification passed after installing missing package");
|
|
15860
|
-
} else logger$
|
|
16165
|
+
} else logger$28.warn({
|
|
15861
16166
|
storyKey,
|
|
15862
16167
|
missingPkg,
|
|
15863
16168
|
retryStatus: retryResult.status
|
|
15864
16169
|
}, "Build-fix retry: build still fails after installing missing package — escalating");
|
|
15865
16170
|
} catch (installErr) {
|
|
15866
16171
|
const installMsg = installErr instanceof Error ? installErr.message : String(installErr);
|
|
15867
|
-
logger$
|
|
16172
|
+
logger$28.warn({
|
|
15868
16173
|
storyKey,
|
|
15869
16174
|
missingPkg,
|
|
15870
16175
|
error: installMsg
|
|
@@ -15874,7 +16179,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15874
16179
|
if (!retryPassed) {
|
|
15875
16180
|
let buildFixPassed = false;
|
|
15876
16181
|
if (buildVerifyResult.status === "failed" && storyFilePath !== void 0) try {
|
|
15877
|
-
logger$
|
|
16182
|
+
logger$28.info({ storyKey }, "Dispatching build-fix agent");
|
|
15878
16183
|
startPhase(storyKey, "build-fix");
|
|
15879
16184
|
const storyContent = await readFile$1(storyFilePath, "utf-8");
|
|
15880
16185
|
let buildFixTemplate;
|
|
@@ -15911,11 +16216,11 @@ function createImplementationOrchestrator(deps) {
|
|
|
15911
16216
|
buildFixPassed = true;
|
|
15912
16217
|
_buildPassed = true;
|
|
15913
16218
|
eventBus.emit("story:build-verification-passed", { storyKey });
|
|
15914
|
-
logger$
|
|
15915
|
-
} else logger$
|
|
16219
|
+
logger$28.info({ storyKey }, "Build passed after build-fix dispatch");
|
|
16220
|
+
} else logger$28.warn({ storyKey }, "Build still fails after build-fix dispatch — escalating");
|
|
15916
16221
|
} catch (fixErr) {
|
|
15917
16222
|
const fixMsg = fixErr instanceof Error ? fixErr.message : String(fixErr);
|
|
15918
|
-
logger$
|
|
16223
|
+
logger$28.warn({
|
|
15919
16224
|
storyKey,
|
|
15920
16225
|
error: fixMsg
|
|
15921
16226
|
}, "Build-fix dispatch failed — escalating");
|
|
@@ -15952,7 +16257,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15952
16257
|
eventBus.emit("decision:halt-skipped-non-interactive", payload);
|
|
15953
16258
|
}
|
|
15954
16259
|
}).catch((err) => {
|
|
15955
|
-
logger$
|
|
16260
|
+
logger$28.warn({
|
|
15956
16261
|
err,
|
|
15957
16262
|
storyKey
|
|
15958
16263
|
}, "interactive prompt failed — continuing with default action");
|
|
@@ -15969,7 +16274,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
15969
16274
|
exitCode: buildVerifyResult.exitCode ?? 1,
|
|
15970
16275
|
output: truncatedOutput
|
|
15971
16276
|
});
|
|
15972
|
-
logger$
|
|
16277
|
+
logger$28.warn({
|
|
15973
16278
|
storyKey,
|
|
15974
16279
|
reason,
|
|
15975
16280
|
exitCode: buildVerifyResult.exitCode,
|
|
@@ -16003,7 +16308,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16003
16308
|
storyKey
|
|
16004
16309
|
});
|
|
16005
16310
|
if (icResult.potentiallyAffectedTests.length > 0) {
|
|
16006
|
-
logger$
|
|
16311
|
+
logger$28.warn({
|
|
16007
16312
|
storyKey,
|
|
16008
16313
|
modifiedInterfaces: icResult.modifiedInterfaces,
|
|
16009
16314
|
potentiallyAffectedTests: icResult.potentiallyAffectedTests
|
|
@@ -16106,14 +16411,14 @@ function createImplementationOrchestrator(deps) {
|
|
|
16106
16411
|
adapter: db,
|
|
16107
16412
|
engine: "linear"
|
|
16108
16413
|
}).catch((recoveryErr) => {
|
|
16109
|
-
logger$
|
|
16414
|
+
logger$28.warn({
|
|
16110
16415
|
storyKey,
|
|
16111
16416
|
err: recoveryErr instanceof Error ? recoveryErr.message : String(recoveryErr)
|
|
16112
16417
|
}, "Recovery Engine invocation failed — falling through to VERIFICATION_FAILED (best-effort)");
|
|
16113
16418
|
return null;
|
|
16114
16419
|
});
|
|
16115
16420
|
if (recoveryResult?.action === "halt-entire-run") {
|
|
16116
|
-
logger$
|
|
16421
|
+
logger$28.error({
|
|
16117
16422
|
storyKey,
|
|
16118
16423
|
pendingProposalsCount: recoveryResult.pendingProposalsCount
|
|
16119
16424
|
}, "Recovery Engine safety valve: halting entire run due to >= 5 pending proposals");
|
|
@@ -16125,13 +16430,13 @@ function createImplementationOrchestrator(deps) {
|
|
|
16125
16430
|
outcome: "escalated",
|
|
16126
16431
|
cost_usd: 0,
|
|
16127
16432
|
timestamp: new Date().toISOString()
|
|
16128
|
-
}).catch((err) => logger$
|
|
16433
|
+
}).catch((err) => logger$28.warn({
|
|
16129
16434
|
err,
|
|
16130
16435
|
storyKey
|
|
16131
16436
|
}, "appendRecoveryEntry(halt-entire-run) failed — pipeline continues"));
|
|
16132
16437
|
_budgetExhausted = true;
|
|
16133
16438
|
} else if (recoveryResult?.action === "retry") {
|
|
16134
|
-
logger$
|
|
16439
|
+
logger$28.info({
|
|
16135
16440
|
storyKey,
|
|
16136
16441
|
attempt: recoveryResult.attempt,
|
|
16137
16442
|
retryBudgetRemaining: recoveryResult.retryBudgetRemaining
|
|
@@ -16183,22 +16488,22 @@ function createImplementationOrchestrator(deps) {
|
|
|
16183
16488
|
outcome: tierARecovered ? "recovered" : "retried",
|
|
16184
16489
|
cost_usd: 0,
|
|
16185
16490
|
timestamp: new Date().toISOString()
|
|
16186
|
-
}).catch((err) => logger$
|
|
16491
|
+
}).catch((err) => logger$28.warn({
|
|
16187
16492
|
err,
|
|
16188
16493
|
storyKey
|
|
16189
16494
|
}, "appendRecoveryEntry(tier-a) failed — pipeline continues"));
|
|
16190
16495
|
if (tierARecovered) {
|
|
16191
|
-
logger$
|
|
16496
|
+
logger$28.info({ storyKey }, "Recovery Engine Tier A retry succeeded — story proceeding to COMPLETE");
|
|
16192
16497
|
shouldFallThroughToComplete = true;
|
|
16193
|
-
} else logger$
|
|
16498
|
+
} else logger$28.warn({ storyKey }, "Recovery Engine Tier A retry still failed — falling through to VERIFICATION_FAILED");
|
|
16194
16499
|
} catch (retryErr) {
|
|
16195
|
-
logger$
|
|
16500
|
+
logger$28.warn({
|
|
16196
16501
|
storyKey,
|
|
16197
16502
|
err: retryErr instanceof Error ? retryErr.message : String(retryErr)
|
|
16198
16503
|
}, "Recovery Engine Tier A re-dispatch threw — falling through to VERIFICATION_FAILED");
|
|
16199
16504
|
}
|
|
16200
16505
|
} else if (recoveryResult?.action === "propose") {
|
|
16201
|
-
logger$
|
|
16506
|
+
logger$28.info({ storyKey }, "Recovery Engine Tier B: proposal appended — marking story ESCALATED for operator re-scope");
|
|
16202
16507
|
if (runManifest) runManifest.appendRecoveryEntry({
|
|
16203
16508
|
story_key: storyKey,
|
|
16204
16509
|
attempt_number: finalReviewCycles + 1,
|
|
@@ -16207,7 +16512,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16207
16512
|
outcome: "escalated",
|
|
16208
16513
|
cost_usd: 0,
|
|
16209
16514
|
timestamp: new Date().toISOString()
|
|
16210
|
-
}).catch((err) => logger$
|
|
16515
|
+
}).catch((err) => logger$28.warn({
|
|
16211
16516
|
err,
|
|
16212
16517
|
storyKey
|
|
16213
16518
|
}, "appendRecoveryEntry(tier-b) failed — pipeline continues"));
|
|
@@ -16227,7 +16532,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16227
16532
|
await persistState();
|
|
16228
16533
|
return "verification-failed";
|
|
16229
16534
|
} else if (recoveryResult?.action === "halt") {
|
|
16230
|
-
logger$
|
|
16535
|
+
logger$28.warn({ storyKey }, "Recovery Engine Tier C: halt — invoking interactive prompt for operator decision");
|
|
16231
16536
|
const haltRunId = config.pipelineRunId ?? storyKey;
|
|
16232
16537
|
await runInteractivePrompt({
|
|
16233
16538
|
runId: haltRunId,
|
|
@@ -16244,7 +16549,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16244
16549
|
eventBus.emit("decision:halt-skipped-non-interactive", haltPayload);
|
|
16245
16550
|
}
|
|
16246
16551
|
}).catch((err) => {
|
|
16247
|
-
logger$
|
|
16552
|
+
logger$28.warn({
|
|
16248
16553
|
err,
|
|
16249
16554
|
storyKey
|
|
16250
16555
|
}, "Recovery Engine Tier C: interactive prompt failed — escalating anyway");
|
|
@@ -16257,7 +16562,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16257
16562
|
outcome: "escalated",
|
|
16258
16563
|
cost_usd: 0,
|
|
16259
16564
|
timestamp: new Date().toISOString()
|
|
16260
|
-
}).catch((err) => logger$
|
|
16565
|
+
}).catch((err) => logger$28.warn({
|
|
16261
16566
|
err,
|
|
16262
16567
|
storyKey
|
|
16263
16568
|
}, "appendRecoveryEntry(tier-c) failed — pipeline continues"));
|
|
@@ -16282,11 +16587,11 @@ function createImplementationOrchestrator(deps) {
|
|
|
16282
16587
|
if (effectiveProjectRoot !== void 0 && effectiveProjectRoot !== projectRoot) {
|
|
16283
16588
|
const cp = await checkpointStoryWorktree(storyKey, `verification-failed: ${verificationFailReason ?? "tier-a-fail"}`, effectiveProjectRoot);
|
|
16284
16589
|
if (cp.status === "committed") {
|
|
16285
|
-
logger$
|
|
16590
|
+
logger$28.info({
|
|
16286
16591
|
storyKey,
|
|
16287
16592
|
sha: cp.sha
|
|
16288
16593
|
}, "verification-failed checkpoint: uncommitted worktree state preserved on story branch");
|
|
16289
|
-
if (runManifest !== null && cp.sha) runManifest.patchStoryState(storyKey, { checkpoint_sha: cp.sha }).catch((err) => logger$
|
|
16594
|
+
if (runManifest !== null && cp.sha) runManifest.patchStoryState(storyKey, { checkpoint_sha: cp.sha }).catch((err) => logger$28.warn({
|
|
16290
16595
|
err,
|
|
16291
16596
|
storyKey
|
|
16292
16597
|
}, "patchStoryState(checkpoint_sha, verification-failed) failed — pipeline continues"));
|
|
@@ -16296,7 +16601,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16296
16601
|
phase: "VERIFICATION_FAILED",
|
|
16297
16602
|
completedAt: new Date().toISOString()
|
|
16298
16603
|
});
|
|
16299
|
-
if (runManifest !== null) runManifest.patchStoryState(storyKey, { escalation_reason: verificationFailReason }).catch((err) => logger$
|
|
16604
|
+
if (runManifest !== null) runManifest.patchStoryState(storyKey, { escalation_reason: verificationFailReason }).catch((err) => logger$28.warn({
|
|
16300
16605
|
err,
|
|
16301
16606
|
storyKey
|
|
16302
16607
|
}, "patchStoryState(escalation_reason, verification-failed) failed — pipeline continues"));
|
|
@@ -16322,7 +16627,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16322
16627
|
if (autoApprove?.downgradeLastVerdict !== void 0) completeUpdate.lastVerdict = autoApprove.downgradeLastVerdict;
|
|
16323
16628
|
updateStory(storyKey, completeUpdate);
|
|
16324
16629
|
if (config.skipVerification !== true && runManifest != null) Promise.resolve().then(() => runManifest.read()).then((manifest) => {
|
|
16325
|
-
if (manifest?.per_story_state?.[storyKey]?.verification_result == null) logger$
|
|
16630
|
+
if (manifest?.per_story_state?.[storyKey]?.verification_result == null) logger$28.warn({
|
|
16326
16631
|
storyKey,
|
|
16327
16632
|
category: "verification-result-missing"
|
|
16328
16633
|
}, "post-COMPLETE invariant: verification_result absent in manifest");
|
|
@@ -16345,7 +16650,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16345
16650
|
const commitResult = await commitDevStoryOutput(storyKey, _capturedStoryTitle, dirty, effectiveProjectRoot);
|
|
16346
16651
|
if (commitResult.status === "no-changes") {
|
|
16347
16652
|
if (_devOutputCommitHookFailure !== void 0) {
|
|
16348
|
-
logger$
|
|
16653
|
+
logger$28.error({
|
|
16349
16654
|
storyKey,
|
|
16350
16655
|
stderr: _devOutputCommitHookFailure
|
|
16351
16656
|
}, "deliverable commit was rejected by hooks at dev-story end and was never resolved — escalating");
|
|
@@ -16378,7 +16683,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16378
16683
|
branchAdvancedSinceBaseline = headNow !== baselineHeadSha;
|
|
16379
16684
|
} catch {}
|
|
16380
16685
|
if (!branchAdvancedSinceBaseline) {
|
|
16381
|
-
logger$
|
|
16686
|
+
logger$28.warn({
|
|
16382
16687
|
storyKey,
|
|
16383
16688
|
reason: commitResult.reason
|
|
16384
16689
|
}, "dev-story produced no committable changes — escalating instead of running merge-to-main on an unchanged branch");
|
|
@@ -16396,10 +16701,10 @@ function createImplementationOrchestrator(deps) {
|
|
|
16396
16701
|
await persistState();
|
|
16397
16702
|
return "terminal";
|
|
16398
16703
|
}
|
|
16399
|
-
logger$
|
|
16704
|
+
logger$28.info({ storyKey }, "working tree clean at finalize but branch already advanced (commit-first) — proceeding to merge");
|
|
16400
16705
|
}
|
|
16401
16706
|
if (commitResult.status === "failed") {
|
|
16402
|
-
logger$
|
|
16707
|
+
logger$28.error({
|
|
16403
16708
|
storyKey,
|
|
16404
16709
|
stderr: commitResult.stderr
|
|
16405
16710
|
}, "substrate auto-commit failed — escalating story");
|
|
@@ -16420,7 +16725,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16420
16725
|
let finalizeCommitSha;
|
|
16421
16726
|
if (commitResult.status === "committed") {
|
|
16422
16727
|
finalizeCommitSha = commitResult.sha || void 0;
|
|
16423
|
-
logger$
|
|
16728
|
+
logger$28.info({
|
|
16424
16729
|
storyKey,
|
|
16425
16730
|
sha: commitResult.sha,
|
|
16426
16731
|
fileCount: commitResult.filesStaged.length
|
|
@@ -16448,7 +16753,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16448
16753
|
if (storyFilePath !== void 0) try {
|
|
16449
16754
|
Object.assign(statePatch, captureReconstructionInput(storyFilePath, storyKey, runManifest.baseDir, runManifest.runId, effectiveProjectRoot));
|
|
16450
16755
|
} catch (inputErr) {
|
|
16451
|
-
logger$
|
|
16756
|
+
logger$28.warn({
|
|
16452
16757
|
err: inputErr,
|
|
16453
16758
|
storyKey
|
|
16454
16759
|
}, "reconstruction phase-input capture failed — pipeline continues (commit_sha still recorded)");
|
|
@@ -16458,12 +16763,12 @@ function createImplementationOrchestrator(deps) {
|
|
|
16458
16763
|
if (dispatchTelemetry.total_turns !== void 0) statePatch.total_turns = dispatchTelemetry.total_turns;
|
|
16459
16764
|
if (dispatchTelemetry.total_tokens !== void 0) statePatch.total_tokens = dispatchTelemetry.total_tokens;
|
|
16460
16765
|
} catch (telemetryErr) {
|
|
16461
|
-
logger$
|
|
16766
|
+
logger$28.warn({
|
|
16462
16767
|
err: telemetryErr,
|
|
16463
16768
|
storyKey
|
|
16464
16769
|
}, "aggregateStoryDispatchTelemetry failed — pipeline continues (commit_sha still recorded)");
|
|
16465
16770
|
}
|
|
16466
|
-
runManifest.patchStoryState(storyKey, statePatch).catch((err) => logger$
|
|
16771
|
+
runManifest.patchStoryState(storyKey, statePatch).catch((err) => logger$28.warn({
|
|
16467
16772
|
err,
|
|
16468
16773
|
storyKey
|
|
16469
16774
|
}, "patchStoryState(commit_sha/phase-input/telemetry) failed — pipeline continues"));
|
|
@@ -16491,7 +16796,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16491
16796
|
timeout: 5e3
|
|
16492
16797
|
}).trim();
|
|
16493
16798
|
if (branchSha === startSha) {
|
|
16494
|
-
logger$
|
|
16799
|
+
logger$28.warn({
|
|
16495
16800
|
storyKey,
|
|
16496
16801
|
branchSha,
|
|
16497
16802
|
startSha,
|
|
@@ -16512,7 +16817,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16512
16817
|
return "terminal";
|
|
16513
16818
|
}
|
|
16514
16819
|
} catch (gateErr) {
|
|
16515
|
-
logger$
|
|
16820
|
+
logger$28.warn({
|
|
16516
16821
|
storyKey,
|
|
16517
16822
|
err: gateErr instanceof Error ? gateErr.message : String(gateErr)
|
|
16518
16823
|
}, "merge-to-main pre-flight verification failed — proceeding with merge phase");
|
|
@@ -16530,7 +16835,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16530
16835
|
const artifactSet = new Set(artifactOnly.map(norm));
|
|
16531
16836
|
const undisclosed = mergedFiles.map(norm).filter((f$1) => !artifactSet.has(f$1) && !disclosed.has(f$1));
|
|
16532
16837
|
if (undisclosed.length > 0) {
|
|
16533
|
-
logger$
|
|
16838
|
+
logger$28.error({
|
|
16534
16839
|
storyKey,
|
|
16535
16840
|
undisclosed,
|
|
16536
16841
|
disclosed: [...disclosed]
|
|
@@ -16550,6 +16855,14 @@ function createImplementationOrchestrator(deps) {
|
|
|
16550
16855
|
return "terminal";
|
|
16551
16856
|
}
|
|
16552
16857
|
}
|
|
16858
|
+
try {
|
|
16859
|
+
await runAcceptanceStage(storyKey, effectiveProjectRoot ?? projectRoot ?? process.cwd());
|
|
16860
|
+
} catch (stageErr) {
|
|
16861
|
+
logger$28.warn({
|
|
16862
|
+
storyKey,
|
|
16863
|
+
err: stageErr
|
|
16864
|
+
}, "A2.3: acceptance stage threw (best-effort) — claimed journeys stay unwalked");
|
|
16865
|
+
}
|
|
16553
16866
|
const finalizationMode = config.finalizationMode ?? "merge";
|
|
16554
16867
|
{
|
|
16555
16868
|
const acceptanceModeCfg = config.acceptanceMode ?? "advisory";
|
|
@@ -16567,7 +16880,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16567
16880
|
if (audit?.unrunnable !== void 0) issueLines.push(audit.unrunnable);
|
|
16568
16881
|
if (acceptanceModeCfg === "blocking") {
|
|
16569
16882
|
const verdict = violations.some((v) => v.state === "unclaimed") ? "journey-unclaimed" : audit?.unrunnable !== void 0 ? "acceptance-unrunnable" : "journey-unwalked";
|
|
16570
|
-
logger$
|
|
16883
|
+
logger$28.error({
|
|
16571
16884
|
storyKey,
|
|
16572
16885
|
epicId: epicIdA,
|
|
16573
16886
|
verdict,
|
|
@@ -16591,7 +16904,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16591
16904
|
await persistState();
|
|
16592
16905
|
return "terminal";
|
|
16593
16906
|
}
|
|
16594
|
-
logger$
|
|
16907
|
+
logger$28.warn({
|
|
16595
16908
|
storyKey,
|
|
16596
16909
|
epicId: epicIdA,
|
|
16597
16910
|
violations: issueLines
|
|
@@ -16607,7 +16920,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16607
16920
|
const TERMINAL_PHASES = ["COMPLETE", "ESCALATED"];
|
|
16608
16921
|
const isLastOfEpic = [..._stories.entries()].filter(([key]) => key !== storyKey && epicOf(key) === epicId).every(([, st]) => TERMINAL_PHASES.includes(st.phase));
|
|
16609
16922
|
if (isLastOfEpic) {
|
|
16610
|
-
logger$
|
|
16923
|
+
logger$28.info({
|
|
16611
16924
|
storyKey,
|
|
16612
16925
|
epicId,
|
|
16613
16926
|
epicGateCommand
|
|
@@ -16632,7 +16945,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16632
16945
|
gateOutput = `${e.stdout ?? ""}${e.stderr ?? ""}`.trim() || (e.message ?? String(gateCmdErr));
|
|
16633
16946
|
}
|
|
16634
16947
|
if (!gatePassed) {
|
|
16635
|
-
logger$
|
|
16948
|
+
logger$28.error({
|
|
16636
16949
|
storyKey,
|
|
16637
16950
|
epicId,
|
|
16638
16951
|
output: gateOutput.slice(0, 500)
|
|
@@ -16651,7 +16964,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16651
16964
|
await persistState();
|
|
16652
16965
|
return "terminal";
|
|
16653
16966
|
}
|
|
16654
|
-
logger$
|
|
16967
|
+
logger$28.info({
|
|
16655
16968
|
storyKey,
|
|
16656
16969
|
epicId
|
|
16657
16970
|
}, "H3.4: epic gate passed");
|
|
@@ -16696,7 +17009,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16696
17009
|
}).trim();
|
|
16697
17010
|
prUrl = ghOutput === "" ? void 0 : ghOutput;
|
|
16698
17011
|
} catch (prErr) {
|
|
16699
|
-
logger$
|
|
17012
|
+
logger$28.warn({
|
|
16700
17013
|
storyKey,
|
|
16701
17014
|
branchName,
|
|
16702
17015
|
err: prErr instanceof Error ? prErr.message.slice(0, 300) : String(prErr)
|
|
@@ -16705,7 +17018,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16705
17018
|
try {
|
|
16706
17019
|
await _worktreeManager.cleanupWorktree(storyKey, { keepBranch: true });
|
|
16707
17020
|
} catch (cleanupErr) {
|
|
16708
|
-
logger$
|
|
17021
|
+
logger$28.warn({
|
|
16709
17022
|
storyKey,
|
|
16710
17023
|
err: cleanupErr
|
|
16711
17024
|
}, "worktree removal after branch/pr finalization failed (best-effort; branch intact)");
|
|
@@ -16722,11 +17035,11 @@ function createImplementationOrchestrator(deps) {
|
|
|
16722
17035
|
branch: branchName,
|
|
16723
17036
|
...storyDeliverableSha ? { sha: storyDeliverableSha } : {},
|
|
16724
17037
|
...prUrl !== void 0 ? { pr_url: prUrl } : {}
|
|
16725
|
-
} }).catch((err) => logger$
|
|
17038
|
+
} }).catch((err) => logger$28.warn({
|
|
16726
17039
|
err,
|
|
16727
17040
|
storyKey
|
|
16728
17041
|
}, "patchStoryState(finalization) failed — pipeline continues"));
|
|
16729
|
-
logger$
|
|
17042
|
+
logger$28.info({
|
|
16730
17043
|
storyKey,
|
|
16731
17044
|
branchName,
|
|
16732
17045
|
mode: finalizationMode,
|
|
@@ -16734,7 +17047,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16734
17047
|
}, "story finalized without self-merge — branch is the deliverable");
|
|
16735
17048
|
return "finalized";
|
|
16736
17049
|
}
|
|
16737
|
-
logger$
|
|
17050
|
+
logger$28.info({
|
|
16738
17051
|
storyKey,
|
|
16739
17052
|
branchName,
|
|
16740
17053
|
startBranch: _orchestratorStartBranch
|
|
@@ -16752,7 +17065,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16752
17065
|
});
|
|
16753
17066
|
} catch (mergeErr) {
|
|
16754
17067
|
const errMsg = mergeErr instanceof Error ? mergeErr.message : String(mergeErr);
|
|
16755
|
-
logger$
|
|
17068
|
+
logger$28.error({
|
|
16756
17069
|
storyKey,
|
|
16757
17070
|
err: mergeErr
|
|
16758
17071
|
}, "merge-to-main phase threw unexpectedly — escalating story");
|
|
@@ -16776,7 +17089,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16776
17089
|
if (failReason === "parent-tree-dirtied-by-run") issues.push(`parent working tree has uncommitted changes to ${mergeResult.dirtiedFiles?.length ?? 0} file(s) the story also modified: ${(mergeResult.dirtiedFiles ?? []).join(", ")} — merging would entangle unreviewed parent edits with verified story content. Commit or stash the parent changes, then merge ${branchName} manually.`);
|
|
16777
17090
|
else if (failReason === "ff-only-merge-not-possible") issues.push(`${_orchestratorStartBranch ?? "the start branch"} moved since ${branchName} was created and merge_strategy is ff-only — substrate will not synthesize a merge commit. Set finalization.merge_strategy: three-way (required for concurrent multi-story runs) or integrate the branch manually.`);
|
|
16778
17091
|
else issues.push(`merge conflict in ${mergeResult.conflictingFiles?.length ?? 0} file(s): ${(mergeResult.conflictingFiles ?? []).join(", ")}`);
|
|
16779
|
-
logger$
|
|
17092
|
+
logger$28.warn({
|
|
16780
17093
|
storyKey,
|
|
16781
17094
|
branchName,
|
|
16782
17095
|
reason: failReason,
|
|
@@ -16797,7 +17110,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16797
17110
|
await persistState();
|
|
16798
17111
|
return "terminal";
|
|
16799
17112
|
}
|
|
16800
|
-
logger$
|
|
17113
|
+
logger$28.info({
|
|
16801
17114
|
storyKey,
|
|
16802
17115
|
branchName
|
|
16803
17116
|
}, "merge-to-main phase completed successfully");
|
|
@@ -16816,7 +17129,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16816
17129
|
mode: "merge",
|
|
16817
17130
|
branch: branchName,
|
|
16818
17131
|
...storyDeliverableSha ? { sha: storyDeliverableSha } : {}
|
|
16819
|
-
} }).catch((err) => logger$
|
|
17132
|
+
} }).catch((err) => logger$28.warn({
|
|
16820
17133
|
err,
|
|
16821
17134
|
storyKey
|
|
16822
17135
|
}, "patchStoryState(finalization) failed — pipeline continues"));
|
|
@@ -16878,7 +17191,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16878
17191
|
"NEEDS_MAJOR_REWORK": 2
|
|
16879
17192
|
};
|
|
16880
17193
|
for (const group of batchFileGroups) {
|
|
16881
|
-
logger$
|
|
17194
|
+
logger$28.info({
|
|
16882
17195
|
storyKey,
|
|
16883
17196
|
batchIndex: group.batchIndex,
|
|
16884
17197
|
fileCount: group.files.length
|
|
@@ -16924,7 +17237,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16924
17237
|
rawOutput: lastRawOutput,
|
|
16925
17238
|
tokenUsage: aggregateTokens
|
|
16926
17239
|
};
|
|
16927
|
-
logger$
|
|
17240
|
+
logger$28.info({
|
|
16928
17241
|
storyKey,
|
|
16929
17242
|
batchCount: batchFileGroups.length,
|
|
16930
17243
|
verdict: worstVerdict,
|
|
@@ -16968,7 +17281,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16968
17281
|
storyKey,
|
|
16969
17282
|
reviewCycle: reviewCycles
|
|
16970
17283
|
})
|
|
16971
|
-
})).catch((tokenErr) => logger$
|
|
17284
|
+
})).catch((tokenErr) => logger$28.warn({
|
|
16972
17285
|
storyKey,
|
|
16973
17286
|
err: tokenErr
|
|
16974
17287
|
}, "Failed to record code-review token usage"));
|
|
@@ -16986,7 +17299,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16986
17299
|
...reviewResult.details !== void 0 ? { details: reviewResult.details } : {}
|
|
16987
17300
|
});
|
|
16988
17301
|
if (schemaValidationRetries <= MAX_SCHEMA_VALIDATION_RETRIES) {
|
|
16989
|
-
logger$
|
|
17302
|
+
logger$28.warn({
|
|
16990
17303
|
storyKey,
|
|
16991
17304
|
reviewCycles,
|
|
16992
17305
|
attempt: schemaValidationRetries,
|
|
@@ -16995,7 +17308,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
16995
17308
|
previousIterationWasMalformed = true;
|
|
16996
17309
|
continue;
|
|
16997
17310
|
}
|
|
16998
|
-
logger$
|
|
17311
|
+
logger$28.warn({
|
|
16999
17312
|
storyKey,
|
|
17000
17313
|
reviewCycles,
|
|
17001
17314
|
schemaValidationRetries
|
|
@@ -17018,7 +17331,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17018
17331
|
}
|
|
17019
17332
|
if (isPhantomReview && !timeoutRetried) {
|
|
17020
17333
|
timeoutRetried = true;
|
|
17021
|
-
logger$
|
|
17334
|
+
logger$28.warn({
|
|
17022
17335
|
storyKey,
|
|
17023
17336
|
reviewCycles,
|
|
17024
17337
|
error: reviewResult.error
|
|
@@ -17048,7 +17361,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17048
17361
|
}
|
|
17049
17362
|
const isStoryFileMissing = (reviewResult.error ?? "").includes("story-file-missing");
|
|
17050
17363
|
const escalationReason = isStoryFileMissing ? "story-file-missing" : "consecutive-review-timeouts";
|
|
17051
|
-
logger$
|
|
17364
|
+
logger$28.warn({
|
|
17052
17365
|
storyKey,
|
|
17053
17366
|
reviewCycles,
|
|
17054
17367
|
error: reviewResult.error,
|
|
@@ -17073,7 +17386,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17073
17386
|
verdict = reviewResult.verdict;
|
|
17074
17387
|
issueList = reviewResult.issue_list ?? [];
|
|
17075
17388
|
if (verdict === "NEEDS_MAJOR_REWORK" && reviewCycles > 0 && previousIssueList.length > 0 && issueList.length < previousIssueList.length) {
|
|
17076
|
-
logger$
|
|
17389
|
+
logger$28.info({
|
|
17077
17390
|
storyKey,
|
|
17078
17391
|
originalVerdict: verdict,
|
|
17079
17392
|
issuesBefore: previousIssueList.length,
|
|
@@ -17102,7 +17415,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17102
17415
|
await persistState();
|
|
17103
17416
|
if (runManifest !== null) {
|
|
17104
17417
|
const persistedVerdict = reviewResult.agentVerdict ?? verdict;
|
|
17105
|
-
runManifest.patchStoryState(storyKey, { verdict: persistedVerdict }).catch((err) => logger$
|
|
17418
|
+
runManifest.patchStoryState(storyKey, { verdict: persistedVerdict }).catch((err) => logger$28.warn({
|
|
17106
17419
|
err,
|
|
17107
17420
|
storyKey
|
|
17108
17421
|
}, "patchStoryState(verdict) failed — pipeline continues"));
|
|
@@ -17116,7 +17429,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17116
17429
|
if (_decomposition !== void 0) parts.push(`decomposed: ${_decomposition.batchCount} batches`);
|
|
17117
17430
|
parts.push(`${fileCount} files`);
|
|
17118
17431
|
parts.push(`${totalTokensK} tokens`);
|
|
17119
|
-
logger$
|
|
17432
|
+
logger$28.info({
|
|
17120
17433
|
storyKey,
|
|
17121
17434
|
verdict,
|
|
17122
17435
|
agentVerdict: reviewResult.agentVerdict
|
|
@@ -17179,9 +17492,9 @@ function createImplementationOrchestrator(deps) {
|
|
|
17179
17492
|
}),
|
|
17180
17493
|
rationale: `Advisory notes from LGTM_WITH_NOTES review of ${storyKey}`
|
|
17181
17494
|
});
|
|
17182
|
-
logger$
|
|
17495
|
+
logger$28.info({ storyKey }, "Advisory notes persisted to decision store");
|
|
17183
17496
|
} catch (advisoryErr) {
|
|
17184
|
-
logger$
|
|
17497
|
+
logger$28.warn({
|
|
17185
17498
|
storyKey,
|
|
17186
17499
|
error: advisoryErr instanceof Error ? advisoryErr.message : String(advisoryErr)
|
|
17187
17500
|
}, "Failed to persist advisory notes (best-effort)");
|
|
@@ -17189,27 +17502,27 @@ function createImplementationOrchestrator(deps) {
|
|
|
17189
17502
|
if (telemetryPersistence !== void 0) try {
|
|
17190
17503
|
const turns = await telemetryPersistence.getTurnAnalysis(storyKey);
|
|
17191
17504
|
if (turns.length > 0) {
|
|
17192
|
-
const scorer = new EfficiencyScorer(logger$
|
|
17505
|
+
const scorer = new EfficiencyScorer(logger$28);
|
|
17193
17506
|
const effScore = scorer.score(storyKey, turns);
|
|
17194
17507
|
await telemetryPersistence.storeEfficiencyScore(effScore);
|
|
17195
|
-
logger$
|
|
17508
|
+
logger$28.info({
|
|
17196
17509
|
storyKey,
|
|
17197
17510
|
compositeScore: effScore.compositeScore,
|
|
17198
17511
|
modelCount: effScore.perModelBreakdown.length
|
|
17199
17512
|
}, "Efficiency score computed and persisted");
|
|
17200
|
-
} else logger$
|
|
17513
|
+
} else logger$28.debug({ storyKey }, "No turn analysis data available — skipping efficiency scoring");
|
|
17201
17514
|
} catch (effErr) {
|
|
17202
|
-
logger$
|
|
17515
|
+
logger$28.warn({
|
|
17203
17516
|
storyKey,
|
|
17204
17517
|
error: effErr instanceof Error ? effErr.message : String(effErr)
|
|
17205
17518
|
}, "Efficiency scoring failed — story verdict unchanged");
|
|
17206
17519
|
}
|
|
17207
17520
|
if (telemetryPersistence !== void 0) try {
|
|
17208
17521
|
const turns = await telemetryPersistence.getTurnAnalysis(storyKey);
|
|
17209
|
-
if (turns.length === 0) logger$
|
|
17522
|
+
if (turns.length === 0) logger$28.debug({ storyKey }, "No turn analysis data for telemetry categorization — skipping");
|
|
17210
17523
|
else {
|
|
17211
|
-
const categorizer = new Categorizer(logger$
|
|
17212
|
-
const consumerAnalyzer = new ConsumerAnalyzer(categorizer, logger$
|
|
17524
|
+
const categorizer = new Categorizer(logger$28);
|
|
17525
|
+
const consumerAnalyzer = new ConsumerAnalyzer(categorizer, logger$28);
|
|
17213
17526
|
const categoryStats = categorizer.computeCategoryStatsFromTurns(turns);
|
|
17214
17527
|
const consumerStats = consumerAnalyzer.analyzeFromTurns(turns);
|
|
17215
17528
|
await telemetryPersistence.storeCategoryStats(storyKey, categoryStats);
|
|
@@ -17217,7 +17530,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17217
17530
|
const growingCount = categoryStats.filter((c) => c.trend === "growing").length;
|
|
17218
17531
|
const topCategory = categoryStats[0]?.category ?? "none";
|
|
17219
17532
|
const topConsumer = consumerStats[0]?.consumerKey ?? "none";
|
|
17220
|
-
logger$
|
|
17533
|
+
logger$28.info({
|
|
17221
17534
|
storyKey,
|
|
17222
17535
|
topCategory,
|
|
17223
17536
|
topConsumer,
|
|
@@ -17225,7 +17538,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17225
17538
|
}, "Semantic categorization and consumer analysis complete");
|
|
17226
17539
|
}
|
|
17227
17540
|
} catch (catErr) {
|
|
17228
|
-
logger$
|
|
17541
|
+
logger$28.warn({
|
|
17229
17542
|
storyKey,
|
|
17230
17543
|
error: catErr instanceof Error ? catErr.message : String(catErr)
|
|
17231
17544
|
}, "Semantic categorization failed — story verdict unchanged");
|
|
@@ -17248,7 +17561,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17248
17561
|
filesModified: devFilesModified,
|
|
17249
17562
|
workingDirectory: effectiveProjectRoot
|
|
17250
17563
|
});
|
|
17251
|
-
logger$
|
|
17564
|
+
logger$28.debug({
|
|
17252
17565
|
storyKey,
|
|
17253
17566
|
expansion_priority: expansionResult.expansion_priority,
|
|
17254
17567
|
coverage_gaps: expansionResult.coverage_gaps.length
|
|
@@ -17261,7 +17574,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17261
17574
|
value: JSON.stringify(expansionResult)
|
|
17262
17575
|
});
|
|
17263
17576
|
} catch (expansionErr) {
|
|
17264
|
-
logger$
|
|
17577
|
+
logger$28.warn({
|
|
17265
17578
|
storyKey,
|
|
17266
17579
|
error: expansionErr instanceof Error ? expansionErr.message : String(expansionErr)
|
|
17267
17580
|
}, "Test expansion failed — story verdict unchanged");
|
|
@@ -17290,7 +17603,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17290
17603
|
await persistState();
|
|
17291
17604
|
return;
|
|
17292
17605
|
}
|
|
17293
|
-
logger$
|
|
17606
|
+
logger$28.info({
|
|
17294
17607
|
storyKey,
|
|
17295
17608
|
reviewCycles: finalReviewCycles,
|
|
17296
17609
|
issueCount: issueList.length
|
|
@@ -17356,7 +17669,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17356
17669
|
fixPrompt = assembled.prompt;
|
|
17357
17670
|
} catch {
|
|
17358
17671
|
fixPrompt = `Fix story ${storyKey}: verdict=${verdict}, minor fixes needed`;
|
|
17359
|
-
logger$
|
|
17672
|
+
logger$28.warn({ storyKey }, "Failed to assemble auto-approve fix prompt, using fallback");
|
|
17360
17673
|
}
|
|
17361
17674
|
const handle = dispatcher.dispatch({
|
|
17362
17675
|
prompt: fixPrompt,
|
|
@@ -17381,9 +17694,9 @@ function createImplementationOrchestrator(deps) {
|
|
|
17381
17694
|
output: fixResult.tokenEstimate.output
|
|
17382
17695
|
} : void 0 }
|
|
17383
17696
|
});
|
|
17384
|
-
if (fixResult.status === "timeout") logger$
|
|
17697
|
+
if (fixResult.status === "timeout") logger$28.warn({ storyKey }, "Auto-approve fix timed out — approving anyway (issues were minor)");
|
|
17385
17698
|
} catch (err) {
|
|
17386
|
-
logger$
|
|
17699
|
+
logger$28.warn({
|
|
17387
17700
|
storyKey,
|
|
17388
17701
|
err
|
|
17389
17702
|
}, "Auto-approve fix dispatch failed — approving anyway (issues were minor)");
|
|
@@ -17412,7 +17725,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17412
17725
|
outcome: "retried",
|
|
17413
17726
|
cost_usd: 0,
|
|
17414
17727
|
timestamp: new Date().toISOString()
|
|
17415
|
-
}).catch((err) => logger$
|
|
17728
|
+
}).catch((err) => logger$28.warn({
|
|
17416
17729
|
err,
|
|
17417
17730
|
storyKey
|
|
17418
17731
|
}, "appendRecoveryEntry failed — pipeline continues"));
|
|
@@ -17552,7 +17865,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17552
17865
|
fixPrompt = assembled.prompt;
|
|
17553
17866
|
} catch {
|
|
17554
17867
|
fixPrompt = `Fix story ${storyKey}: verdict=${verdict}, taskType=${taskType}`;
|
|
17555
|
-
logger$
|
|
17868
|
+
logger$28.warn({
|
|
17556
17869
|
storyKey,
|
|
17557
17870
|
taskType
|
|
17558
17871
|
}, "Failed to assemble fix prompt, using fallback");
|
|
@@ -17596,7 +17909,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17596
17909
|
if (taskType === "minor-fixes") {
|
|
17597
17910
|
const finalReviewCycles = reviewCycles + 1;
|
|
17598
17911
|
const downgradedVerdict = "LGTM_WITH_NOTES";
|
|
17599
|
-
logger$
|
|
17912
|
+
logger$28.warn({
|
|
17600
17913
|
storyKey,
|
|
17601
17914
|
reviewCycles: finalReviewCycles,
|
|
17602
17915
|
issueCount: issueList.length
|
|
@@ -17616,7 +17929,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17616
17929
|
keepReviewing = false;
|
|
17617
17930
|
return;
|
|
17618
17931
|
}
|
|
17619
|
-
logger$
|
|
17932
|
+
logger$28.warn({
|
|
17620
17933
|
storyKey,
|
|
17621
17934
|
taskType
|
|
17622
17935
|
}, "Fix dispatch timed out — escalating story");
|
|
@@ -17638,7 +17951,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17638
17951
|
}
|
|
17639
17952
|
if (fixResult.status === "failed") {
|
|
17640
17953
|
if (isMajorRework) {
|
|
17641
|
-
logger$
|
|
17954
|
+
logger$28.warn({
|
|
17642
17955
|
storyKey,
|
|
17643
17956
|
exitCode: fixResult.exitCode
|
|
17644
17957
|
}, "Major rework dispatch failed — escalating story");
|
|
@@ -17658,7 +17971,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17658
17971
|
await persistState();
|
|
17659
17972
|
return;
|
|
17660
17973
|
}
|
|
17661
|
-
logger$
|
|
17974
|
+
logger$28.warn({
|
|
17662
17975
|
storyKey,
|
|
17663
17976
|
taskType,
|
|
17664
17977
|
exitCode: fixResult.exitCode
|
|
@@ -17666,7 +17979,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17666
17979
|
}
|
|
17667
17980
|
if (isMajorRework) replaceDevStorySignals(fixResult.parsed);
|
|
17668
17981
|
} catch (err) {
|
|
17669
|
-
logger$
|
|
17982
|
+
logger$28.warn({
|
|
17670
17983
|
storyKey,
|
|
17671
17984
|
taskType,
|
|
17672
17985
|
err
|
|
@@ -17735,7 +18048,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17735
18048
|
eventBus.emit("decision:halt-skipped-non-interactive", payload);
|
|
17736
18049
|
}
|
|
17737
18050
|
}).catch((err) => {
|
|
17738
|
-
logger$
|
|
18051
|
+
logger$28.warn({ err }, "interactive prompt failed during auth-failure halt — halting anyway");
|
|
17739
18052
|
});
|
|
17740
18053
|
for (const [key, state] of _stories) if (state.phase === "PENDING" && key !== triggeredStoryKey) {
|
|
17741
18054
|
updateStory(key, {
|
|
@@ -17748,7 +18061,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17748
18061
|
escalation_reason: "auth-failure-halt"
|
|
17749
18062
|
}).catch(() => {});
|
|
17750
18063
|
}
|
|
17751
|
-
logger$
|
|
18064
|
+
logger$28.error({
|
|
17752
18065
|
runId,
|
|
17753
18066
|
triggeredStoryKey,
|
|
17754
18067
|
matchedSignature
|
|
@@ -17782,7 +18095,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17782
18095
|
eventBus.emit("decision:halt-skipped-non-interactive", payload);
|
|
17783
18096
|
}
|
|
17784
18097
|
}).catch((err) => {
|
|
17785
|
-
logger$
|
|
18098
|
+
logger$28.warn({ err }, "interactive prompt failed during cost-ceiling halt — continuing with default action");
|
|
17786
18099
|
});
|
|
17787
18100
|
} else eventBus.emit("decision:autonomous", {
|
|
17788
18101
|
runId,
|
|
@@ -17810,7 +18123,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17810
18123
|
severity: routeResult.severity
|
|
17811
18124
|
});
|
|
17812
18125
|
_budgetExhausted = true;
|
|
17813
|
-
logger$
|
|
18126
|
+
logger$28.warn({
|
|
17814
18127
|
skipped: allSkipped.length,
|
|
17815
18128
|
cumulative: result.cumulative,
|
|
17816
18129
|
ceiling: result.ceiling,
|
|
@@ -17829,7 +18142,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17829
18142
|
const completedStoryKeys = [];
|
|
17830
18143
|
for (const storyKey of group) {
|
|
17831
18144
|
if (_shutdownRequested) {
|
|
17832
|
-
logger$
|
|
18145
|
+
logger$28.info({ storyKey }, "shutdown requested — skipping dispatch");
|
|
17833
18146
|
return;
|
|
17834
18147
|
}
|
|
17835
18148
|
if (runManifest !== null && runManifest !== void 0) try {
|
|
@@ -17852,7 +18165,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17852
18165
|
}
|
|
17853
18166
|
}
|
|
17854
18167
|
} catch (err) {
|
|
17855
|
-
logger$
|
|
18168
|
+
logger$28.debug({ err }, "Cost ceiling check failed — proceeding without enforcement");
|
|
17856
18169
|
}
|
|
17857
18170
|
let optimizationDirectives;
|
|
17858
18171
|
if (telemetryAdvisor !== void 0 && completedStoryKeys.length > 0) try {
|
|
@@ -17860,13 +18173,13 @@ function createImplementationOrchestrator(deps) {
|
|
|
17860
18173
|
const directives = telemetryAdvisor.formatOptimizationDirectives(recs);
|
|
17861
18174
|
if (directives.length > 0) {
|
|
17862
18175
|
optimizationDirectives = directives;
|
|
17863
|
-
logger$
|
|
18176
|
+
logger$28.debug({
|
|
17864
18177
|
storyKey,
|
|
17865
18178
|
directiveCount: recs.filter((r) => r.severity !== "info").length
|
|
17866
18179
|
}, "Optimization directives ready for dispatch");
|
|
17867
18180
|
}
|
|
17868
18181
|
} catch (err) {
|
|
17869
|
-
logger$
|
|
18182
|
+
logger$28.debug({
|
|
17870
18183
|
err,
|
|
17871
18184
|
storyKey
|
|
17872
18185
|
}, "Failed to fetch optimization directives — proceeding without");
|
|
@@ -17990,7 +18303,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
17990
18303
|
recommendedAction: "serialize"
|
|
17991
18304
|
});
|
|
17992
18305
|
} catch {}
|
|
17993
|
-
logger$
|
|
18306
|
+
logger$28.info({
|
|
17994
18307
|
storyKeys: evt.storyKeys,
|
|
17995
18308
|
collisionPaths: evt.collisionPaths
|
|
17996
18309
|
}, "Cross-story file collision detected — serializing affected groups to prevent race conditions");
|
|
@@ -18003,7 +18316,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
18003
18316
|
mergedGroupMap.set(root2, [...existing, ...group]);
|
|
18004
18317
|
}
|
|
18005
18318
|
const result = [...mergedGroupMap.values()];
|
|
18006
|
-
logger$
|
|
18319
|
+
logger$28.info({
|
|
18007
18320
|
originalGroupCount: batchGroups.length,
|
|
18008
18321
|
mergedGroupCount: result.length,
|
|
18009
18322
|
collisionCount
|
|
@@ -18047,7 +18360,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
18047
18360
|
async function shutdownGracefully(reason, signal) {
|
|
18048
18361
|
if (_shutdownRequested) return;
|
|
18049
18362
|
_shutdownRequested = true;
|
|
18050
|
-
logger$
|
|
18363
|
+
logger$28.info({
|
|
18051
18364
|
reason,
|
|
18052
18365
|
signal
|
|
18053
18366
|
}, "Graceful shutdown initiated — stopping new dispatches");
|
|
@@ -18057,8 +18370,8 @@ function createImplementationOrchestrator(deps) {
|
|
|
18057
18370
|
run_status: "stopped",
|
|
18058
18371
|
stopped_reason: reason,
|
|
18059
18372
|
stopped_at: new Date().toISOString()
|
|
18060
|
-
}).catch((err) => logger$
|
|
18061
|
-
if (config.pipelineRunId !== void 0) await updatePipelineRun(db, config.pipelineRunId, { status: "stopped" }).catch((err) => logger$
|
|
18373
|
+
}).catch((err) => logger$28.warn({ err }, "patchRunStatus failed during shutdown (best-effort)"));
|
|
18374
|
+
if (config.pipelineRunId !== void 0) await updatePipelineRun(db, config.pipelineRunId, { status: "stopped" }).catch((err) => logger$28.warn({ err }, "updatePipelineRun(stopped) failed during shutdown (best-effort)"));
|
|
18062
18375
|
const activePhases = [
|
|
18063
18376
|
"PENDING",
|
|
18064
18377
|
"IN_STORY_CREATION",
|
|
@@ -18069,7 +18382,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
18069
18382
|
"CHECKPOINT"
|
|
18070
18383
|
];
|
|
18071
18384
|
const cancellations = [];
|
|
18072
|
-
for (const [storyKey, state] of _stories.entries()) if (activePhases.includes(state.phase)) cancellations.push(wgRepo.updateStoryStatus(storyKey, "cancelled").catch((err) => logger$
|
|
18385
|
+
for (const [storyKey, state] of _stories.entries()) if (activePhases.includes(state.phase)) cancellations.push(wgRepo.updateStoryStatus(storyKey, "cancelled").catch((err) => logger$28.warn({
|
|
18073
18386
|
err,
|
|
18074
18387
|
storyKey
|
|
18075
18388
|
}, "wg_stories → cancelled failed during shutdown (best-effort)")));
|
|
@@ -18078,11 +18391,11 @@ function createImplementationOrchestrator(deps) {
|
|
|
18078
18391
|
}
|
|
18079
18392
|
async function run(storyKeys) {
|
|
18080
18393
|
if (_state === "RUNNING" || _state === "PAUSED") {
|
|
18081
|
-
logger$
|
|
18394
|
+
logger$28.warn({ state: _state }, "run() called while orchestrator is already running or paused — ignoring");
|
|
18082
18395
|
return getStatus();
|
|
18083
18396
|
}
|
|
18084
18397
|
if (_state === "COMPLETE") {
|
|
18085
|
-
logger$
|
|
18398
|
+
logger$28.warn({ state: _state }, "run() called on a COMPLETE orchestrator — ignoring");
|
|
18086
18399
|
return getStatus();
|
|
18087
18400
|
}
|
|
18088
18401
|
_state = "RUNNING";
|
|
@@ -18097,15 +18410,15 @@ function createImplementationOrchestrator(deps) {
|
|
|
18097
18410
|
"pipe"
|
|
18098
18411
|
]
|
|
18099
18412
|
}).trim();
|
|
18100
|
-
logger$
|
|
18413
|
+
logger$28.info({ orchestratorStartBranch: _orchestratorStartBranch }, "Captured orchestrator start branch for merge-to-main");
|
|
18101
18414
|
} catch (branchErr) {
|
|
18102
18415
|
if (config.noWorktree !== true) {
|
|
18103
|
-
logger$
|
|
18416
|
+
logger$28.error({ err: branchErr }, "FATAL: failed to capture the orchestrator start branch (git rev-parse --abbrev-ref HEAD). Worktree finalization cannot work without it. Fix git in the project root or re-run with --no-worktree.");
|
|
18104
18417
|
_state = "FAILED";
|
|
18105
18418
|
_completedAt = new Date().toISOString();
|
|
18106
18419
|
return getStatus();
|
|
18107
18420
|
}
|
|
18108
|
-
logger$
|
|
18421
|
+
logger$28.warn({ err: branchErr }, "Failed to capture orchestrator start branch — merge-to-main will skip worktree integration (--no-worktree run)");
|
|
18109
18422
|
}
|
|
18110
18423
|
for (const key of storyKeys) {
|
|
18111
18424
|
const pendingState = {
|
|
@@ -18148,13 +18461,13 @@ function createImplementationOrchestrator(deps) {
|
|
|
18148
18461
|
await persistState();
|
|
18149
18462
|
recordProgress();
|
|
18150
18463
|
if (config.enableHeartbeat) startHeartbeat();
|
|
18151
|
-
if (_orchestratorStartBranch !== void 0 && runManifest !== null) runManifest.patchRunStatus({ orchestrator_start_branch: _orchestratorStartBranch }).catch((err) => logger$
|
|
18464
|
+
if (_orchestratorStartBranch !== void 0 && runManifest !== null) runManifest.patchRunStatus({ orchestrator_start_branch: _orchestratorStartBranch }).catch((err) => logger$28.warn({ err }, "Failed to persist orchestrator_start_branch to manifest (best-effort)"));
|
|
18152
18465
|
const _startupTimings = {};
|
|
18153
18466
|
if (projectRoot !== void 0) {
|
|
18154
18467
|
const seedStart = Date.now();
|
|
18155
18468
|
const seedResult = await seedMethodologyContext(db, projectRoot);
|
|
18156
18469
|
_startupTimings.seedMethodologyMs = Date.now() - seedStart;
|
|
18157
|
-
if (seedResult.decisionsCreated > 0) logger$
|
|
18470
|
+
if (seedResult.decisionsCreated > 0) logger$28.info({
|
|
18158
18471
|
decisionsCreated: seedResult.decisionsCreated,
|
|
18159
18472
|
skippedCategories: seedResult.skippedCategories,
|
|
18160
18473
|
durationMs: _startupTimings.seedMethodologyMs
|
|
@@ -18164,12 +18477,12 @@ function createImplementationOrchestrator(deps) {
|
|
|
18164
18477
|
const ingestStart = Date.now();
|
|
18165
18478
|
try {
|
|
18166
18479
|
const ingestResult = await autoIngestEpicsDependencies(db, projectRoot);
|
|
18167
|
-
if (ingestResult.storiesIngested > 0 || ingestResult.dependenciesIngested > 0) logger$
|
|
18480
|
+
if (ingestResult.storiesIngested > 0 || ingestResult.dependenciesIngested > 0) logger$28.info({
|
|
18168
18481
|
...ingestResult,
|
|
18169
18482
|
durationMs: Date.now() - ingestStart
|
|
18170
18483
|
}, "Auto-ingested stories and dependencies from epics document");
|
|
18171
18484
|
} catch (err) {
|
|
18172
|
-
logger$
|
|
18485
|
+
logger$28.debug({ err }, "Auto-ingest from epics document skipped — work graph may be unavailable");
|
|
18173
18486
|
}
|
|
18174
18487
|
}
|
|
18175
18488
|
const sigtermHandler = () => {
|
|
@@ -18183,7 +18496,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
18183
18496
|
try {
|
|
18184
18497
|
if (ingestionServer !== void 0) {
|
|
18185
18498
|
if (telemetryPersistence !== void 0) try {
|
|
18186
|
-
const pipelineLogger = logger$
|
|
18499
|
+
const pipelineLogger = logger$28;
|
|
18187
18500
|
const telemetryPipeline = new TelemetryPipeline({
|
|
18188
18501
|
normalizer: new TelemetryNormalizer(pipelineLogger),
|
|
18189
18502
|
turnAnalyzer: new TurnAnalyzer(pipelineLogger),
|
|
@@ -18195,14 +18508,14 @@ function createImplementationOrchestrator(deps) {
|
|
|
18195
18508
|
persistence: telemetryPersistence
|
|
18196
18509
|
});
|
|
18197
18510
|
ingestionServer.setPipeline(telemetryPipeline);
|
|
18198
|
-
logger$
|
|
18511
|
+
logger$28.info("TelemetryPipeline wired to IngestionServer");
|
|
18199
18512
|
} catch (pipelineErr) {
|
|
18200
|
-
logger$
|
|
18513
|
+
logger$28.warn({ err: pipelineErr }, "Failed to create TelemetryPipeline — continuing without analysis pipeline");
|
|
18201
18514
|
}
|
|
18202
|
-
await ingestionServer.start().catch((err) => logger$
|
|
18515
|
+
await ingestionServer.start().catch((err) => logger$28.warn({ err }, "IngestionServer.start() failed — continuing without telemetry (best-effort)"));
|
|
18203
18516
|
try {
|
|
18204
18517
|
_otlpEndpoint = ingestionServer.getOtlpEnvVars().OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
18205
|
-
logger$
|
|
18518
|
+
logger$28.info({ otlpEndpoint: _otlpEndpoint }, "OTLP telemetry ingestion active");
|
|
18206
18519
|
} catch {}
|
|
18207
18520
|
}
|
|
18208
18521
|
const interfaceContractDecisions = await getDecisionsByCategory(db, "interface-contract");
|
|
@@ -18228,12 +18541,12 @@ function createImplementationOrchestrator(deps) {
|
|
|
18228
18541
|
const conflictDetectStart = Date.now();
|
|
18229
18542
|
const { batches, edges: contractEdges } = detectConflictGroupsWithContracts(storyKeys, { moduleMap: pack.manifest.conflictGroups }, contractDeclarations);
|
|
18230
18543
|
_startupTimings.conflictDetectMs = Date.now() - conflictDetectStart;
|
|
18231
|
-
if (contractEdges.length > 0) logger$
|
|
18544
|
+
if (contractEdges.length > 0) logger$28.info({
|
|
18232
18545
|
contractEdges,
|
|
18233
18546
|
edgeCount: contractEdges.length
|
|
18234
18547
|
}, "Contract dependency edges detected — applying contract-aware dispatch ordering");
|
|
18235
|
-
wgRepo.addContractDependencies(contractEdges).catch((err) => logger$
|
|
18236
|
-
logger$
|
|
18548
|
+
wgRepo.addContractDependencies(contractEdges).catch((err) => logger$28.warn({ err }, "contract dep persistence failed (best-effort)"));
|
|
18549
|
+
logger$28.info({
|
|
18237
18550
|
storyCount: storyKeys.length,
|
|
18238
18551
|
groupCount: batches.reduce((sum, b) => sum + b.length, 0),
|
|
18239
18552
|
batchCount: batches.length,
|
|
@@ -18243,7 +18556,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
18243
18556
|
groups: batch.map((g) => g.join(","))
|
|
18244
18557
|
}))
|
|
18245
18558
|
}, "Orchestrator starting");
|
|
18246
|
-
logger$
|
|
18559
|
+
logger$28.info({
|
|
18247
18560
|
storyCount: storyKeys.length,
|
|
18248
18561
|
conflictGroups: batches.length,
|
|
18249
18562
|
maxConcurrency: config.maxConcurrency
|
|
@@ -18264,7 +18577,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
18264
18577
|
exitCode,
|
|
18265
18578
|
output: truncatedOutput
|
|
18266
18579
|
});
|
|
18267
|
-
logger$
|
|
18580
|
+
logger$28.error({
|
|
18268
18581
|
exitCode,
|
|
18269
18582
|
reason: preFlightResult.reason
|
|
18270
18583
|
}, "Pre-flight build check failed — aborting pipeline before any story dispatch");
|
|
@@ -18273,19 +18586,19 @@ function createImplementationOrchestrator(deps) {
|
|
|
18273
18586
|
await persistState();
|
|
18274
18587
|
return getStatus();
|
|
18275
18588
|
}
|
|
18276
|
-
if (preFlightResult.status !== "skipped") logger$
|
|
18589
|
+
if (preFlightResult.status !== "skipped") logger$28.info("Pre-flight build check passed");
|
|
18277
18590
|
}
|
|
18278
|
-
logger$
|
|
18591
|
+
logger$28.info(_startupTimings, "Orchestrator startup timings (ms)");
|
|
18279
18592
|
const totalGroups = batches.reduce((sum, b) => sum + b.length, 0);
|
|
18280
18593
|
const actualConcurrency = Math.min(config.maxConcurrency, totalGroups);
|
|
18281
18594
|
if (actualConcurrency > 1 && projectRoot !== void 0) try {
|
|
18282
18595
|
_packageSnapshot = capturePackageSnapshot({ projectRoot });
|
|
18283
|
-
logger$
|
|
18596
|
+
logger$28.info({
|
|
18284
18597
|
fileCount: _packageSnapshot.files.size,
|
|
18285
18598
|
installCommand: _packageSnapshot.installCommand
|
|
18286
18599
|
}, "Package snapshot captured for concurrent story protection");
|
|
18287
18600
|
} catch (snapErr) {
|
|
18288
|
-
logger$
|
|
18601
|
+
logger$28.warn({ err: snapErr }, "Failed to capture package snapshot — continuing without protection");
|
|
18289
18602
|
}
|
|
18290
18603
|
try {
|
|
18291
18604
|
for (const rawBatchGroups of batches) {
|
|
@@ -18310,14 +18623,14 @@ function createImplementationOrchestrator(deps) {
|
|
|
18310
18623
|
manifest: runManifest,
|
|
18311
18624
|
adapter: db
|
|
18312
18625
|
});
|
|
18313
|
-
if (!recoveryResult.noStale) logger$
|
|
18626
|
+
if (!recoveryResult.noStale) logger$28.info({
|
|
18314
18627
|
recovered: recoveryResult.recovered,
|
|
18315
18628
|
stillFailed: recoveryResult.stillFailed,
|
|
18316
18629
|
recoveredCount: recoveryResult.recovered.length,
|
|
18317
18630
|
stillFailedCount: recoveryResult.stillFailed.length
|
|
18318
18631
|
}, "Cross-story race recovery complete");
|
|
18319
18632
|
} catch (recoveryErr) {
|
|
18320
|
-
logger$
|
|
18633
|
+
logger$28.warn({ err: recoveryErr }, "Cross-story race recovery failed (non-fatal) — pipeline continues");
|
|
18321
18634
|
}
|
|
18322
18635
|
}
|
|
18323
18636
|
}
|
|
@@ -18326,7 +18639,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
18326
18639
|
_state = "FAILED";
|
|
18327
18640
|
_completedAt = new Date().toISOString();
|
|
18328
18641
|
await persistState();
|
|
18329
|
-
logger$
|
|
18642
|
+
logger$28.error({ err }, "Orchestrator failed with unhandled error");
|
|
18330
18643
|
return getStatus();
|
|
18331
18644
|
}
|
|
18332
18645
|
stopHeartbeat();
|
|
@@ -18336,7 +18649,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
18336
18649
|
const totalDeclarations = contractDeclarations.length;
|
|
18337
18650
|
const currentSprintDeclarations = contractDeclarations.filter((d) => storyKeys.includes(d.storyKey));
|
|
18338
18651
|
const stalePruned = totalDeclarations - currentSprintDeclarations.length;
|
|
18339
|
-
if (stalePruned > 0) logger$
|
|
18652
|
+
if (stalePruned > 0) logger$28.info({
|
|
18340
18653
|
stalePruned,
|
|
18341
18654
|
remaining: currentSprintDeclarations.length
|
|
18342
18655
|
}, "Pruned stale contract declarations from previous epics");
|
|
@@ -18350,11 +18663,11 @@ function createImplementationOrchestrator(deps) {
|
|
|
18350
18663
|
contractName: mismatch.contractName,
|
|
18351
18664
|
mismatchDescription: mismatch.mismatchDescription
|
|
18352
18665
|
});
|
|
18353
|
-
logger$
|
|
18666
|
+
logger$28.warn({
|
|
18354
18667
|
mismatchCount: mismatches.length,
|
|
18355
18668
|
mismatches
|
|
18356
18669
|
}, "Post-sprint contract verification found mismatches — manual review required");
|
|
18357
|
-
} else if (currentSprintDeclarations.length > 0) logger$
|
|
18670
|
+
} else if (currentSprintDeclarations.length > 0) logger$28.info("Post-sprint contract verification passed — all declared contracts satisfied");
|
|
18358
18671
|
eventBus.emit("pipeline:contract-verification-summary", {
|
|
18359
18672
|
verified: currentSprintDeclarations.length,
|
|
18360
18673
|
stalePruned,
|
|
@@ -18362,7 +18675,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
18362
18675
|
verdict: mismatches.length === 0 ? "pass" : "fail"
|
|
18363
18676
|
});
|
|
18364
18677
|
} catch (err) {
|
|
18365
|
-
logger$
|
|
18678
|
+
logger$28.error({ err }, "Post-sprint contract verification threw an error — skipping");
|
|
18366
18679
|
}
|
|
18367
18680
|
if (projectRoot !== void 0) try {
|
|
18368
18681
|
const indicators = checkProfileStaleness(projectRoot);
|
|
@@ -18372,15 +18685,15 @@ function createImplementationOrchestrator(deps) {
|
|
|
18372
18685
|
message,
|
|
18373
18686
|
indicators
|
|
18374
18687
|
});
|
|
18375
|
-
logger$
|
|
18688
|
+
logger$28.warn({ indicators }, message);
|
|
18376
18689
|
}
|
|
18377
18690
|
} catch (err) {
|
|
18378
|
-
logger$
|
|
18691
|
+
logger$28.debug({ err }, "Profile staleness check failed (best-effort)");
|
|
18379
18692
|
}
|
|
18380
18693
|
try {
|
|
18381
18694
|
await auditJourneyCoverage({ final: true }, { persist: true });
|
|
18382
18695
|
} catch (err) {
|
|
18383
|
-
logger$
|
|
18696
|
+
logger$28.warn({ err }, "A0.3: run-end coverage sweep failed (best-effort)");
|
|
18384
18697
|
}
|
|
18385
18698
|
let completed = 0;
|
|
18386
18699
|
let escalated = 0;
|
|
@@ -18399,7 +18712,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
18399
18712
|
} finally {
|
|
18400
18713
|
process.off("SIGTERM", sigtermHandler);
|
|
18401
18714
|
process.off("SIGINT", sigintHandler);
|
|
18402
|
-
if (ingestionServer !== void 0) await ingestionServer.stop().catch((err) => logger$
|
|
18715
|
+
if (ingestionServer !== void 0) await ingestionServer.stop().catch((err) => logger$28.warn({ err }, "IngestionServer.stop() failed (best-effort)"));
|
|
18403
18716
|
}
|
|
18404
18717
|
}
|
|
18405
18718
|
function pause() {
|
|
@@ -18408,7 +18721,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
18408
18721
|
_pauseGate = createPauseGate();
|
|
18409
18722
|
_state = "PAUSED";
|
|
18410
18723
|
eventBus.emit("orchestrator:paused", {});
|
|
18411
|
-
logger$
|
|
18724
|
+
logger$28.info("Orchestrator paused");
|
|
18412
18725
|
}
|
|
18413
18726
|
function resume() {
|
|
18414
18727
|
if (_state !== "PAUSED") return;
|
|
@@ -18419,7 +18732,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
18419
18732
|
}
|
|
18420
18733
|
_state = "RUNNING";
|
|
18421
18734
|
eventBus.emit("orchestrator:resumed", {});
|
|
18422
|
-
logger$
|
|
18735
|
+
logger$28.info("Orchestrator resumed");
|
|
18423
18736
|
}
|
|
18424
18737
|
return {
|
|
18425
18738
|
run,
|
|
@@ -35511,16 +35824,16 @@ var require_ajv = __commonJS({ "node_modules/ajv/lib/ajv.js"(exports, module) {
|
|
|
35511
35824
|
return metaOpts;
|
|
35512
35825
|
}
|
|
35513
35826
|
function setLogger(self) {
|
|
35514
|
-
var logger$
|
|
35515
|
-
if (logger$
|
|
35827
|
+
var logger$28 = self._opts.logger;
|
|
35828
|
+
if (logger$28 === false) self.logger = {
|
|
35516
35829
|
log: noop,
|
|
35517
35830
|
warn: noop,
|
|
35518
35831
|
error: noop
|
|
35519
35832
|
};
|
|
35520
35833
|
else {
|
|
35521
|
-
if (logger$
|
|
35522
|
-
if (!(typeof logger$
|
|
35523
|
-
self.logger = logger$
|
|
35834
|
+
if (logger$28 === void 0) logger$28 = console;
|
|
35835
|
+
if (!(typeof logger$28 == "object" && logger$28.log && logger$28.warn && logger$28.error)) throw new Error("logger must implement log, warn and error methods");
|
|
35836
|
+
self.logger = logger$28;
|
|
35524
35837
|
}
|
|
35525
35838
|
}
|
|
35526
35839
|
function noop() {}
|
|
@@ -48515,4 +48828,4 @@ function registerRunCommand(program, version = "0.0.0", projectRoot = process.cw
|
|
|
48515
48828
|
|
|
48516
48829
|
//#endregion
|
|
48517
48830
|
export { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR$1 as GLOBSTAR, GitClient, GrammarLoader, Minimatch$1 as Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape$1 as escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, normalizeGraphSummaryToStatus, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runRunAction, runSolutioningPhase, unescape$1 as unescape, validateStopAfterFromConflict, wireNdjsonEmitter };
|
|
48518
|
-
//# sourceMappingURL=run-
|
|
48831
|
+
//# sourceMappingURL=run-DsjRvAd4.js.map
|