substrate-ai 0.20.3 → 0.20.5
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 +4 -4
- package/dist/{health-Cs2x975P.js → health-CQTK6ltK.js} +1 -1
- package/dist/{health-BfeoutPu.js → health-DHLR9Iz1.js} +981 -3
- package/dist/{run-8UnjRlkK.js → run-ofO9AWFc.js} +44 -476
- package/dist/{run-COw1z5NJ.js → run-s6bRK0LF.js} +2 -2
- package/package.json +1 -1
- package/packs/bmad/prompts/fix-story.md +3 -0
- package/packs/bmad/prompts/rework-story.md +3 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, FindingsInjector, RunManifest, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectCycles, extractTargetFilesFromStoryContent, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, resolveGraphPath, resolveMainRepoRoot, validateStoryKey } from "./health-
|
|
1
|
+
import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, FindingsInjector, RunManifest, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectCycles, extractTargetFilesFromStoryContent, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, renderFindings, resolveGraphPath, resolveMainRepoRoot, validateStoryKey } from "./health-DHLR9Iz1.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, 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, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-srr3BfCc.js";
|
|
@@ -6386,478 +6386,6 @@ async function runGitCommand(args, cwd, logLabel) {
|
|
|
6386
6386
|
});
|
|
6387
6387
|
}
|
|
6388
6388
|
|
|
6389
|
-
//#endregion
|
|
6390
|
-
//#region packages/sdlc/dist/verification/checks/phantom-review-check.js
|
|
6391
|
-
/**
|
|
6392
|
-
* PhantomReviewCheck — Story 51-2.
|
|
6393
|
-
*
|
|
6394
|
-
* Tier A verification check that detects when a code review dispatch failed
|
|
6395
|
-
* but was recorded as a passing verdict. Stories that were never actually
|
|
6396
|
-
* reviewed should not be counted as verified.
|
|
6397
|
-
*
|
|
6398
|
-
* Architecture constraints (FR-V9):
|
|
6399
|
-
* - No LLM calls.
|
|
6400
|
-
* - No shell invocations — pure static signal inspection over VerificationContext fields.
|
|
6401
|
-
* - Runs first in Tier A (before TrivialOutputCheck, before BuildCheck).
|
|
6402
|
-
*/
|
|
6403
|
-
/**
|
|
6404
|
-
* Detects phantom reviews — dispatches that failed or produced no output but
|
|
6405
|
-
* were recorded as passing verdicts.
|
|
6406
|
-
*
|
|
6407
|
-
* AC1: dispatch failed (non-zero exit, timeout, crash) → fail
|
|
6408
|
-
* AC2: empty or null rawOutput → fail
|
|
6409
|
-
* AC3: schema_validation_failed error → fail
|
|
6410
|
-
* AC5: valid review (non-empty rawOutput, no dispatchFailed) → pass
|
|
6411
|
-
* AC6: name='phantom-review', tier='A'
|
|
6412
|
-
*/
|
|
6413
|
-
var PhantomReviewCheck = class {
|
|
6414
|
-
name = "phantom-review";
|
|
6415
|
-
tier = "A";
|
|
6416
|
-
async run(context) {
|
|
6417
|
-
const start = Date.now();
|
|
6418
|
-
const review = context.reviewResult;
|
|
6419
|
-
if (!review) return {
|
|
6420
|
-
status: "pass",
|
|
6421
|
-
details: "phantom-review: no review result in context — skipping check",
|
|
6422
|
-
duration_ms: Date.now() - start
|
|
6423
|
-
};
|
|
6424
|
-
if (review.dispatchFailed === true) {
|
|
6425
|
-
const reason = review.error === "schema_validation_failed" ? "schema validation failed" : `dispatch failed${review.error ? ` — ${review.error}` : ""}`;
|
|
6426
|
-
return {
|
|
6427
|
-
status: "fail",
|
|
6428
|
-
details: `phantom-review: ${reason}`,
|
|
6429
|
-
duration_ms: Date.now() - start
|
|
6430
|
-
};
|
|
6431
|
-
}
|
|
6432
|
-
if (review.rawOutput !== void 0 && review.rawOutput.trim().length === 0) return {
|
|
6433
|
-
status: "fail",
|
|
6434
|
-
details: "phantom-review: empty review output",
|
|
6435
|
-
duration_ms: Date.now() - start
|
|
6436
|
-
};
|
|
6437
|
-
return {
|
|
6438
|
-
status: "pass",
|
|
6439
|
-
details: "phantom-review: review output is valid",
|
|
6440
|
-
duration_ms: Date.now() - start
|
|
6441
|
-
};
|
|
6442
|
-
}
|
|
6443
|
-
};
|
|
6444
|
-
|
|
6445
|
-
//#endregion
|
|
6446
|
-
//#region packages/sdlc/dist/verification/checks/trivial-output-check.js
|
|
6447
|
-
/**
|
|
6448
|
-
* TrivialOutputCheck — Story 51-3.
|
|
6449
|
-
*
|
|
6450
|
-
* Tier A verification check that flags story dispatches which produced
|
|
6451
|
-
* fewer output tokens than the configured threshold. A very low output
|
|
6452
|
-
* token count is a strong signal that the agent exited early (e.g. hit a
|
|
6453
|
-
* maxTurns limit, encountered a fatal error, or did no real work).
|
|
6454
|
-
*
|
|
6455
|
-
* Architecture constraints (DC-6, FR-V9):
|
|
6456
|
-
* - No LLM calls.
|
|
6457
|
-
* - No shell invocations — pure in-process computation.
|
|
6458
|
-
* - Runs in Tier A: before BuildCheck, after PhantomReviewCheck.
|
|
6459
|
-
*/
|
|
6460
|
-
/**
|
|
6461
|
-
* Default minimum output-token count a story must produce to be
|
|
6462
|
-
* considered non-trivial. Configurable via trivialOutputThreshold config field.
|
|
6463
|
-
*/
|
|
6464
|
-
const DEFAULT_TRIVIAL_OUTPUT_THRESHOLD = 100;
|
|
6465
|
-
/**
|
|
6466
|
-
* Checks that a completed story dispatch produced at least `threshold` output
|
|
6467
|
-
* tokens. Dispatches that produced fewer tokens are flagged as failures with
|
|
6468
|
-
* an actionable suggestion to re-run with increased maxTurns.
|
|
6469
|
-
*
|
|
6470
|
-
* AC1: fail when outputTokenCount < threshold.
|
|
6471
|
-
* AC2: details string includes "Re-run with increased maxTurns".
|
|
6472
|
-
* AC3: pass when outputTokenCount >= threshold.
|
|
6473
|
-
* AC4: threshold is configurable via trivialOutputThreshold config field.
|
|
6474
|
-
* AC5: warn (not fail) when outputTokenCount is undefined.
|
|
6475
|
-
* AC6: implements VerificationCheck with name='trivial-output', tier='A'.
|
|
6476
|
-
*/
|
|
6477
|
-
var TrivialOutputCheck = class {
|
|
6478
|
-
name = "trivial-output";
|
|
6479
|
-
tier = "A";
|
|
6480
|
-
threshold;
|
|
6481
|
-
constructor(config) {
|
|
6482
|
-
this.threshold = config?.trivialOutputThreshold ?? DEFAULT_TRIVIAL_OUTPUT_THRESHOLD;
|
|
6483
|
-
}
|
|
6484
|
-
async run(context) {
|
|
6485
|
-
const start = Date.now();
|
|
6486
|
-
if (context.outputTokenCount === void 0) return {
|
|
6487
|
-
status: "warn",
|
|
6488
|
-
details: "trivial-output: output token count unavailable — skipping check",
|
|
6489
|
-
duration_ms: Date.now() - start
|
|
6490
|
-
};
|
|
6491
|
-
const count = context.outputTokenCount;
|
|
6492
|
-
if (count < this.threshold) return {
|
|
6493
|
-
status: "fail",
|
|
6494
|
-
details: `trivial-output: output token count ${count} is below threshold ${this.threshold} — Re-run with increased maxTurns`,
|
|
6495
|
-
duration_ms: Date.now() - start
|
|
6496
|
-
};
|
|
6497
|
-
return {
|
|
6498
|
-
status: "pass",
|
|
6499
|
-
details: `output token count ${count} meets threshold ${this.threshold}`,
|
|
6500
|
-
duration_ms: Date.now() - start
|
|
6501
|
-
};
|
|
6502
|
-
}
|
|
6503
|
-
};
|
|
6504
|
-
|
|
6505
|
-
//#endregion
|
|
6506
|
-
//#region packages/sdlc/dist/verification/checks/acceptance-criteria-evidence-check.js
|
|
6507
|
-
/**
|
|
6508
|
-
* AcceptanceCriteriaEvidenceCheck.
|
|
6509
|
-
*
|
|
6510
|
-
* Tier A verification check that compares a story's declared acceptance
|
|
6511
|
-
* criteria against structured dev-story output. The check is intentionally
|
|
6512
|
-
* deterministic: no LLM calls, no shell commands, no repository inspection.
|
|
6513
|
-
*/
|
|
6514
|
-
const EXPLICIT_AC_REF = /\bAC\s*:?\s*#?\s*(\d+)\b/gi;
|
|
6515
|
-
const NUMBERED_CRITERION = /^\s*(?:[-*]\s*)?(?:\[[ xX]\]\s*)?(\d+)[.)]\s+\S/;
|
|
6516
|
-
function normalizeAcId(value) {
|
|
6517
|
-
const parsed = Number.parseInt(value, 10);
|
|
6518
|
-
if (!Number.isFinite(parsed) || parsed <= 0) return void 0;
|
|
6519
|
-
return `AC${parsed}`;
|
|
6520
|
-
}
|
|
6521
|
-
function sortAcIds(ids) {
|
|
6522
|
-
return Array.from(ids).sort((a, b) => {
|
|
6523
|
-
const aNum = Number.parseInt(a.replace(/^AC/i, ""), 10);
|
|
6524
|
-
const bNum = Number.parseInt(b.replace(/^AC/i, ""), 10);
|
|
6525
|
-
return aNum - bNum;
|
|
6526
|
-
});
|
|
6527
|
-
}
|
|
6528
|
-
function addExplicitAcRefs(text, ids) {
|
|
6529
|
-
EXPLICIT_AC_REF.lastIndex = 0;
|
|
6530
|
-
let match$2;
|
|
6531
|
-
while ((match$2 = EXPLICIT_AC_REF.exec(text)) !== null) {
|
|
6532
|
-
const id = normalizeAcId(match$2[1] ?? "");
|
|
6533
|
-
if (id !== void 0) ids.add(id);
|
|
6534
|
-
}
|
|
6535
|
-
}
|
|
6536
|
-
function extractAcceptanceSection(storyContent) {
|
|
6537
|
-
const lines = storyContent.split(/\r?\n/);
|
|
6538
|
-
const start = lines.findIndex((line) => /^##\s+Acceptance Criteria\s*$/i.test(line.trim()));
|
|
6539
|
-
if (start === -1) return void 0;
|
|
6540
|
-
let end = lines.length;
|
|
6541
|
-
for (let i = start + 1; i < lines.length; i += 1) if (/^##\s+\S/.test(lines[i] ?? "")) {
|
|
6542
|
-
end = i;
|
|
6543
|
-
break;
|
|
6544
|
-
}
|
|
6545
|
-
return lines.slice(start + 1, end).join("\n");
|
|
6546
|
-
}
|
|
6547
|
-
/**
|
|
6548
|
-
* Extract normalized AC ids from story markdown.
|
|
6549
|
-
*
|
|
6550
|
-
* Supports the BMAD default format (`### AC1:`), explicit references such as
|
|
6551
|
-
* `AC: #1`, and plain numbered criteria inside the Acceptance Criteria section.
|
|
6552
|
-
*/
|
|
6553
|
-
function extractAcceptanceCriteriaIds(storyContent) {
|
|
6554
|
-
const ids = new Set();
|
|
6555
|
-
const acceptanceSection = extractAcceptanceSection(storyContent);
|
|
6556
|
-
const textToScan = acceptanceSection ?? storyContent;
|
|
6557
|
-
addExplicitAcRefs(textToScan, ids);
|
|
6558
|
-
if (acceptanceSection !== void 0) for (const line of acceptanceSection.split(/\r?\n/)) {
|
|
6559
|
-
const match$2 = line.match(NUMBERED_CRITERION);
|
|
6560
|
-
if (match$2?.[1] !== void 0) {
|
|
6561
|
-
const id = normalizeAcId(match$2[1]);
|
|
6562
|
-
if (id !== void 0) ids.add(id);
|
|
6563
|
-
}
|
|
6564
|
-
}
|
|
6565
|
-
return sortAcIds(ids);
|
|
6566
|
-
}
|
|
6567
|
-
function extractClaimedAcceptanceCriteriaIds(values) {
|
|
6568
|
-
const ids = new Set();
|
|
6569
|
-
for (const value of values ?? []) {
|
|
6570
|
-
addExplicitAcRefs(value, ids);
|
|
6571
|
-
const bareNumber = value.trim().match(/^#?(\d+)\b/);
|
|
6572
|
-
if (bareNumber?.[1] !== void 0) {
|
|
6573
|
-
const id = normalizeAcId(bareNumber[1]);
|
|
6574
|
-
if (id !== void 0) ids.add(id);
|
|
6575
|
-
}
|
|
6576
|
-
}
|
|
6577
|
-
return sortAcIds(ids);
|
|
6578
|
-
}
|
|
6579
|
-
function normalizeTestOutcome(value) {
|
|
6580
|
-
if (value === void 0) return void 0;
|
|
6581
|
-
return value.toLowerCase().includes("fail") ? "fail" : "pass";
|
|
6582
|
-
}
|
|
6583
|
-
function formatIds(ids) {
|
|
6584
|
-
return ids.join(", ");
|
|
6585
|
-
}
|
|
6586
|
-
var AcceptanceCriteriaEvidenceCheck = class {
|
|
6587
|
-
name = "acceptance-criteria-evidence";
|
|
6588
|
-
tier = "A";
|
|
6589
|
-
async run(context) {
|
|
6590
|
-
const start = Date.now();
|
|
6591
|
-
const storyContent = context.storyContent?.trim();
|
|
6592
|
-
if (!storyContent) return {
|
|
6593
|
-
status: "warn",
|
|
6594
|
-
details: "acceptance-criteria-evidence: story content unavailable - skipping AC evidence check",
|
|
6595
|
-
duration_ms: Date.now() - start
|
|
6596
|
-
};
|
|
6597
|
-
const expectedIds = extractAcceptanceCriteriaIds(storyContent);
|
|
6598
|
-
if (expectedIds.length === 0) return {
|
|
6599
|
-
status: "warn",
|
|
6600
|
-
details: "acceptance-criteria-evidence: no numbered acceptance criteria found in story",
|
|
6601
|
-
duration_ms: Date.now() - start
|
|
6602
|
-
};
|
|
6603
|
-
const devResult = context.devStoryResult;
|
|
6604
|
-
if (devResult === void 0) return {
|
|
6605
|
-
status: "warn",
|
|
6606
|
-
details: `acceptance-criteria-evidence: dev-story result unavailable for ${formatIds(expectedIds)}`,
|
|
6607
|
-
duration_ms: Date.now() - start
|
|
6608
|
-
};
|
|
6609
|
-
const acFailures = devResult.ac_failures ?? [];
|
|
6610
|
-
if (acFailures.length > 0) return {
|
|
6611
|
-
status: "fail",
|
|
6612
|
-
details: `acceptance-criteria-evidence: dev-story reported AC failures: ${acFailures.join("; ")}`,
|
|
6613
|
-
duration_ms: Date.now() - start
|
|
6614
|
-
};
|
|
6615
|
-
const testOutcome = normalizeTestOutcome(devResult.tests);
|
|
6616
|
-
if (testOutcome === "fail") return {
|
|
6617
|
-
status: "fail",
|
|
6618
|
-
details: "acceptance-criteria-evidence: dev-story reported failing tests",
|
|
6619
|
-
duration_ms: Date.now() - start
|
|
6620
|
-
};
|
|
6621
|
-
const claimedIds = new Set(extractClaimedAcceptanceCriteriaIds(devResult.ac_met));
|
|
6622
|
-
const missingIds = expectedIds.filter((id) => !claimedIds.has(id));
|
|
6623
|
-
if (missingIds.length > 0) return {
|
|
6624
|
-
status: "fail",
|
|
6625
|
-
details: `acceptance-criteria-evidence: missing dev-story AC evidence for ${formatIds(missingIds)}; expected ${formatIds(expectedIds)}, claimed ${formatIds(sortAcIds(claimedIds)) || "none"}`,
|
|
6626
|
-
duration_ms: Date.now() - start
|
|
6627
|
-
};
|
|
6628
|
-
if (testOutcome === void 0) return {
|
|
6629
|
-
status: "warn",
|
|
6630
|
-
details: `acceptance-criteria-evidence: AC evidence covers ${formatIds(expectedIds)} but test outcome is unavailable`,
|
|
6631
|
-
duration_ms: Date.now() - start
|
|
6632
|
-
};
|
|
6633
|
-
return {
|
|
6634
|
-
status: "pass",
|
|
6635
|
-
details: `acceptance-criteria-evidence: AC evidence covers ${formatIds(expectedIds)}; tests=${testOutcome}`,
|
|
6636
|
-
duration_ms: Date.now() - start
|
|
6637
|
-
};
|
|
6638
|
-
}
|
|
6639
|
-
};
|
|
6640
|
-
|
|
6641
|
-
//#endregion
|
|
6642
|
-
//#region packages/sdlc/dist/verification/checks/build-check.js
|
|
6643
|
-
/** Hard timeout for the build command in milliseconds (FR-V11). */
|
|
6644
|
-
const BUILD_CHECK_TIMEOUT_MS = 6e4;
|
|
6645
|
-
/** Maximum characters to include in details string from build output. */
|
|
6646
|
-
const MAX_OUTPUT_CHARS = 2e3;
|
|
6647
|
-
/**
|
|
6648
|
-
* Detect the build command for a project based on files present in `workingDir`.
|
|
6649
|
-
*
|
|
6650
|
-
* Returns an empty string when no recognized build system is found, which
|
|
6651
|
-
* causes BuildCheck to return a 'warn' result without blocking the pipeline.
|
|
6652
|
-
*
|
|
6653
|
-
* NOTE: Do NOT import from src/modules/agent-dispatch/dispatcher-impl.ts —
|
|
6654
|
-
* that would create a circular dependency from packages/sdlc/ → monolith src/.
|
|
6655
|
-
* This function inlines the detection logic independently.
|
|
6656
|
-
*/
|
|
6657
|
-
function detectBuildCommand(workingDir) {
|
|
6658
|
-
if (existsSync(join$1(workingDir, "turbo.json"))) return "turbo build";
|
|
6659
|
-
if (existsSync(join$1(workingDir, "pnpm-lock.yaml"))) return "pnpm run build";
|
|
6660
|
-
if (existsSync(join$1(workingDir, "yarn.lock"))) return "yarn build";
|
|
6661
|
-
if (existsSync(join$1(workingDir, "bun.lockb"))) return "bun run build";
|
|
6662
|
-
if (existsSync(join$1(workingDir, "package.json"))) return "npm run build";
|
|
6663
|
-
const nonNodeMarkers = [
|
|
6664
|
-
"pyproject.toml",
|
|
6665
|
-
"poetry.lock",
|
|
6666
|
-
"setup.py",
|
|
6667
|
-
"Cargo.toml",
|
|
6668
|
-
"go.mod"
|
|
6669
|
-
];
|
|
6670
|
-
for (const marker of nonNodeMarkers) if (existsSync(join$1(workingDir, marker))) return "";
|
|
6671
|
-
return "";
|
|
6672
|
-
}
|
|
6673
|
-
/**
|
|
6674
|
-
* Runs the project's build command and returns pass/warn/fail based on exit code.
|
|
6675
|
-
*
|
|
6676
|
-
* AC1: exit code 0 → pass
|
|
6677
|
-
* AC2: non-zero exit code → fail with truncated output in details
|
|
6678
|
-
* AC3: timeout → kill process group, return fail with timeout message
|
|
6679
|
-
* AC4: no recognized build system → warn without blocking
|
|
6680
|
-
* AC5: explicit buildCommand override respected; empty string → warn (skip)
|
|
6681
|
-
* AC6: name === 'build', tier === 'A'
|
|
6682
|
-
*/
|
|
6683
|
-
var BuildCheck = class {
|
|
6684
|
-
name = "build";
|
|
6685
|
-
tier = "A";
|
|
6686
|
-
async run(context) {
|
|
6687
|
-
const start = Date.now();
|
|
6688
|
-
const cmd = context.buildCommand !== void 0 ? context.buildCommand : detectBuildCommand(context.workingDir);
|
|
6689
|
-
if (cmd === "") return {
|
|
6690
|
-
status: "warn",
|
|
6691
|
-
details: `build-skip: no build command detected for project at ${context.workingDir}`,
|
|
6692
|
-
duration_ms: Date.now() - start
|
|
6693
|
-
};
|
|
6694
|
-
return new Promise((resolve$6) => {
|
|
6695
|
-
const child = spawn(cmd, [], {
|
|
6696
|
-
cwd: context.workingDir,
|
|
6697
|
-
detached: true,
|
|
6698
|
-
shell: true,
|
|
6699
|
-
stdio: [
|
|
6700
|
-
"ignore",
|
|
6701
|
-
"pipe",
|
|
6702
|
-
"pipe"
|
|
6703
|
-
]
|
|
6704
|
-
});
|
|
6705
|
-
let output = "";
|
|
6706
|
-
child.stdout?.on("data", (chunk) => {
|
|
6707
|
-
output += chunk.toString();
|
|
6708
|
-
});
|
|
6709
|
-
child.stderr?.on("data", (chunk) => {
|
|
6710
|
-
output += chunk.toString();
|
|
6711
|
-
});
|
|
6712
|
-
const timeoutHandle = setTimeout(() => {
|
|
6713
|
-
try {
|
|
6714
|
-
process.kill(-child.pid, "SIGKILL");
|
|
6715
|
-
} catch {}
|
|
6716
|
-
resolve$6({
|
|
6717
|
-
status: "fail",
|
|
6718
|
-
details: `build-timeout: command exceeded ${BUILD_CHECK_TIMEOUT_MS}ms`,
|
|
6719
|
-
duration_ms: Date.now() - start
|
|
6720
|
-
});
|
|
6721
|
-
}, BUILD_CHECK_TIMEOUT_MS);
|
|
6722
|
-
child.on("close", (code) => {
|
|
6723
|
-
clearTimeout(timeoutHandle);
|
|
6724
|
-
if (code === 0) resolve$6({
|
|
6725
|
-
status: "pass",
|
|
6726
|
-
details: "build passed",
|
|
6727
|
-
duration_ms: Date.now() - start
|
|
6728
|
-
});
|
|
6729
|
-
else {
|
|
6730
|
-
const truncated = output.length > MAX_OUTPUT_CHARS ? output.slice(0, MAX_OUTPUT_CHARS) + "... (truncated)" : output;
|
|
6731
|
-
resolve$6({
|
|
6732
|
-
status: "fail",
|
|
6733
|
-
details: `build failed (exit ${code}): ${truncated}`,
|
|
6734
|
-
duration_ms: Date.now() - start
|
|
6735
|
-
});
|
|
6736
|
-
}
|
|
6737
|
-
});
|
|
6738
|
-
});
|
|
6739
|
-
}
|
|
6740
|
-
};
|
|
6741
|
-
|
|
6742
|
-
//#endregion
|
|
6743
|
-
//#region packages/sdlc/dist/verification/verification-pipeline.js
|
|
6744
|
-
/**
|
|
6745
|
-
* Compute the worst-case aggregate status across a list of check results.
|
|
6746
|
-
* Precedence: fail > warn > pass.
|
|
6747
|
-
*/
|
|
6748
|
-
function aggregateStatus(checks) {
|
|
6749
|
-
let result = "pass";
|
|
6750
|
-
for (const c of checks) {
|
|
6751
|
-
if (c.status === "fail") return "fail";
|
|
6752
|
-
if (c.status === "warn") result = "warn";
|
|
6753
|
-
}
|
|
6754
|
-
return result;
|
|
6755
|
-
}
|
|
6756
|
-
/**
|
|
6757
|
-
* Runs an ordered chain of VerificationCheck implementations after each story dispatch.
|
|
6758
|
-
*
|
|
6759
|
-
* Checks are stored in registration order. When `run()` is called with `tier: 'A'`
|
|
6760
|
-
* only Tier A checks execute; when called with `tier: 'B'` only Tier B checks execute.
|
|
6761
|
-
* (Story 51-5 will invoke both tiers at the appropriate orchestration points.)
|
|
6762
|
-
*/
|
|
6763
|
-
var VerificationPipeline = class {
|
|
6764
|
-
_bus;
|
|
6765
|
-
_checks = [];
|
|
6766
|
-
/**
|
|
6767
|
-
* @param bus Typed event bus for emitting verification events.
|
|
6768
|
-
* @param checks Optional initial list of checks to register at construction time.
|
|
6769
|
-
*/
|
|
6770
|
-
constructor(bus, checks = []) {
|
|
6771
|
-
this._bus = bus;
|
|
6772
|
-
for (const check of checks) this.register(check);
|
|
6773
|
-
}
|
|
6774
|
-
/**
|
|
6775
|
-
* Register a VerificationCheck.
|
|
6776
|
-
*
|
|
6777
|
-
* Checks are stored in insertion order within their tier.
|
|
6778
|
-
* Tier A checks always run before Tier B checks regardless of registration order.
|
|
6779
|
-
*/
|
|
6780
|
-
register(check) {
|
|
6781
|
-
this._checks.push(check);
|
|
6782
|
-
}
|
|
6783
|
-
/**
|
|
6784
|
-
* Execute all checks matching the specified tier sequentially.
|
|
6785
|
-
*
|
|
6786
|
-
* AC2: Tier A checks execute in registration order.
|
|
6787
|
-
* AC4: Results are aggregated into a VerificationSummary.
|
|
6788
|
-
* AC5: verification:check-complete and verification:story-complete events are emitted.
|
|
6789
|
-
* AC6: Unhandled exceptions are caught and recorded as warn.
|
|
6790
|
-
*
|
|
6791
|
-
* @param context Verification context for the story being verified.
|
|
6792
|
-
* @param tier Which tier of checks to execute ('A' | 'B'). Defaults to 'A'.
|
|
6793
|
-
*/
|
|
6794
|
-
async run(context, tier = "A") {
|
|
6795
|
-
const pipelineStart = Date.now();
|
|
6796
|
-
const checks = this._checks.filter((c) => c.tier === tier);
|
|
6797
|
-
const checkResults = [];
|
|
6798
|
-
for (const check of checks) {
|
|
6799
|
-
const checkStart = Date.now();
|
|
6800
|
-
let result;
|
|
6801
|
-
try {
|
|
6802
|
-
const runResult = await check.run(context);
|
|
6803
|
-
result = {
|
|
6804
|
-
checkName: check.name,
|
|
6805
|
-
status: runResult.status,
|
|
6806
|
-
details: runResult.details,
|
|
6807
|
-
duration_ms: runResult.duration_ms
|
|
6808
|
-
};
|
|
6809
|
-
} catch (err) {
|
|
6810
|
-
const elapsed = Date.now() - checkStart;
|
|
6811
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
6812
|
-
process.stderr.write(`[verification-pipeline] check "${check.name}" threw an unhandled exception: ${message}\n`);
|
|
6813
|
-
result = {
|
|
6814
|
-
checkName: check.name,
|
|
6815
|
-
status: "warn",
|
|
6816
|
-
details: message,
|
|
6817
|
-
duration_ms: elapsed
|
|
6818
|
-
};
|
|
6819
|
-
}
|
|
6820
|
-
checkResults.push(result);
|
|
6821
|
-
this._bus.emit("verification:check-complete", {
|
|
6822
|
-
storyKey: context.storyKey,
|
|
6823
|
-
checkName: result.checkName,
|
|
6824
|
-
status: result.status,
|
|
6825
|
-
details: result.details,
|
|
6826
|
-
duration_ms: result.duration_ms
|
|
6827
|
-
});
|
|
6828
|
-
}
|
|
6829
|
-
const summary = {
|
|
6830
|
-
storyKey: context.storyKey,
|
|
6831
|
-
checks: checkResults,
|
|
6832
|
-
status: aggregateStatus(checkResults),
|
|
6833
|
-
duration_ms: Date.now() - pipelineStart
|
|
6834
|
-
};
|
|
6835
|
-
this._bus.emit("verification:story-complete", summary);
|
|
6836
|
-
return summary;
|
|
6837
|
-
}
|
|
6838
|
-
};
|
|
6839
|
-
/**
|
|
6840
|
-
* Create a VerificationPipeline pre-loaded with the canonical check set.
|
|
6841
|
-
*
|
|
6842
|
-
* Canonical Tier A check order (architecture section 3.5):
|
|
6843
|
-
* 1. PhantomReviewCheck — story 51-2 (runs first: unreviewed stories skipped)
|
|
6844
|
-
* 2. TrivialOutputCheck — story 51-3
|
|
6845
|
-
* 3. AcceptanceCriteriaEvidenceCheck
|
|
6846
|
-
* 4. BuildCheck — story 51-4
|
|
6847
|
-
*
|
|
6848
|
-
* @param bus Typed event bus for verification events.
|
|
6849
|
-
* @param config Optional config (used to forward threshold to TrivialOutputCheck).
|
|
6850
|
-
*/
|
|
6851
|
-
function createDefaultVerificationPipeline(bus, config) {
|
|
6852
|
-
const checks = [
|
|
6853
|
-
new PhantomReviewCheck(),
|
|
6854
|
-
new TrivialOutputCheck(config),
|
|
6855
|
-
new AcceptanceCriteriaEvidenceCheck(),
|
|
6856
|
-
new BuildCheck()
|
|
6857
|
-
];
|
|
6858
|
-
return new VerificationPipeline(bus, checks);
|
|
6859
|
-
}
|
|
6860
|
-
|
|
6861
6389
|
//#endregion
|
|
6862
6390
|
//#region src/modules/compiled-workflows/story-complexity.ts
|
|
6863
6391
|
const logger$16 = createLogger("compiled-workflows:story-complexity");
|
|
@@ -10952,6 +10480,29 @@ function persistVerificationResult(storyKey, summary, runManifest) {
|
|
|
10952
10480
|
storyKey
|
|
10953
10481
|
}, "manifest verification_result write failed — pipeline continues"));
|
|
10954
10482
|
}
|
|
10483
|
+
/**
|
|
10484
|
+
* Flatten every finding from a VerificationSummary's checks into a single
|
|
10485
|
+
* prompt-ready string. Returns '' when the summary is undefined, contains
|
|
10486
|
+
* no checks, or every check emits zero findings (e.g. every check passed).
|
|
10487
|
+
*
|
|
10488
|
+
* The output is intended for direct injection into retry/rework/fix
|
|
10489
|
+
* prompt templates via a `{{verification_findings}}` section — kept
|
|
10490
|
+
* human-readable and minimal. Each finding is rendered as a single
|
|
10491
|
+
* `ERROR [category] message` / `WARN [...]` / `INFO [...]` line via the
|
|
10492
|
+
* renderFindings helper from the verification module; lines are grouped
|
|
10493
|
+
* by check name for readability.
|
|
10494
|
+
*/
|
|
10495
|
+
function renderVerificationFindingsForPrompt(summary) {
|
|
10496
|
+
if (!summary) return "";
|
|
10497
|
+
const blocks = [];
|
|
10498
|
+
for (const check of summary.checks) {
|
|
10499
|
+
const findings = check.findings ?? [];
|
|
10500
|
+
if (findings.length === 0) continue;
|
|
10501
|
+
const rendered = renderFindings(findings);
|
|
10502
|
+
blocks.push(`- ${check.checkName}:\n${rendered.replace(/^/gm, " ")}`);
|
|
10503
|
+
}
|
|
10504
|
+
return blocks.join("\n");
|
|
10505
|
+
}
|
|
10955
10506
|
|
|
10956
10507
|
//#endregion
|
|
10957
10508
|
//#region src/modules/implementation-orchestrator/cost-governance.ts
|
|
@@ -13912,6 +13463,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
13912
13463
|
archConstraints = constraints.map((d) => `${d.key}: ${d.value}`).join("\n");
|
|
13913
13464
|
} catch {}
|
|
13914
13465
|
const targetedFilesContent = buildTargetedFilesContent(issueList);
|
|
13466
|
+
const verificationFindingsContent = renderVerificationFindingsForPrompt(verificationStore.get(storyKey));
|
|
13915
13467
|
const sections = [
|
|
13916
13468
|
{
|
|
13917
13469
|
name: "story_content",
|
|
@@ -13932,6 +13484,11 @@ function createImplementationOrchestrator(deps) {
|
|
|
13932
13484
|
name: "targeted_files",
|
|
13933
13485
|
content: targetedFilesContent,
|
|
13934
13486
|
priority: "important"
|
|
13487
|
+
}] : [],
|
|
13488
|
+
...verificationFindingsContent ? [{
|
|
13489
|
+
name: "verification_findings",
|
|
13490
|
+
content: verificationFindingsContent,
|
|
13491
|
+
priority: "important"
|
|
13935
13492
|
}] : []
|
|
13936
13493
|
];
|
|
13937
13494
|
const assembled = assemblePrompt(fixTemplate, sections, 24e3);
|
|
@@ -14100,6 +13657,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14100
13657
|
const findings = await getProjectFindings(db);
|
|
14101
13658
|
if (findings !== "") priorFindingsContent = "Prior pipeline findings — avoid repeating these patterns:\n\n" + findings;
|
|
14102
13659
|
} catch {}
|
|
13660
|
+
const verificationFindingsContent = renderVerificationFindingsForPrompt(verificationStore.get(storyKey));
|
|
14103
13661
|
const sections = isMajorRework ? [
|
|
14104
13662
|
{
|
|
14105
13663
|
name: "story_content",
|
|
@@ -14125,7 +13683,12 @@ function createImplementationOrchestrator(deps) {
|
|
|
14125
13683
|
name: "prior_findings",
|
|
14126
13684
|
content: priorFindingsContent,
|
|
14127
13685
|
priority: "optional"
|
|
14128
|
-
}
|
|
13686
|
+
},
|
|
13687
|
+
...verificationFindingsContent ? [{
|
|
13688
|
+
name: "verification_findings",
|
|
13689
|
+
content: verificationFindingsContent,
|
|
13690
|
+
priority: "important"
|
|
13691
|
+
}] : []
|
|
14129
13692
|
] : (() => {
|
|
14130
13693
|
const targetedFilesContent = buildTargetedFilesContent(issueList);
|
|
14131
13694
|
return [
|
|
@@ -14153,7 +13716,12 @@ function createImplementationOrchestrator(deps) {
|
|
|
14153
13716
|
name: "prior_findings",
|
|
14154
13717
|
content: priorFindingsContent,
|
|
14155
13718
|
priority: "optional"
|
|
14156
|
-
}
|
|
13719
|
+
},
|
|
13720
|
+
...verificationFindingsContent ? [{
|
|
13721
|
+
name: "verification_findings",
|
|
13722
|
+
content: verificationFindingsContent,
|
|
13723
|
+
priority: "important"
|
|
13724
|
+
}] : []
|
|
14157
13725
|
];
|
|
14158
13726
|
})();
|
|
14159
13727
|
const assembled = assemblePrompt(fixTemplate, sections, 24e3);
|
|
@@ -44272,4 +43840,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
|
|
|
44272
43840
|
|
|
44273
43841
|
//#endregion
|
|
44274
43842
|
export { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GitClient, GrammarLoader, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, normalizeGraphSummaryToStatus, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveMaxReviewCycles, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict, wireNdjsonEmitter };
|
|
44275
|
-
//# sourceMappingURL=run-
|
|
43843
|
+
//# sourceMappingURL=run-ofO9AWFc.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "./health-
|
|
1
|
+
import "./health-DHLR9Iz1.js";
|
|
2
2
|
import "./logger-KeHncl-f.js";
|
|
3
3
|
import "./helpers-CElYrONe.js";
|
|
4
4
|
import "./dist-srr3BfCc.js";
|
|
5
|
-
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-
|
|
5
|
+
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-ofO9AWFc.js";
|
|
6
6
|
import "./routing-CcBOCuC9.js";
|
|
7
7
|
import "./decisions-C0pz9Clx.js";
|
|
8
8
|
|
package/package.json
CHANGED