substrate-ai 0.20.2 → 0.20.4

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.
@@ -1,7 +1,7 @@
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-DrZiqv4h.js";
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-CB48LF0t.js";
2
2
  import { createLogger } from "./logger-KeHncl-f.js";
3
3
  import { TypedEventBusImpl, createEventBus, createTuiApp, isTuiCapable, printNonTtyWarning, sleep } from "./helpers-CElYrONe.js";
4
- import { ADVISORY_NOTES, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, IngestionServer, LogTurnAnalyzer, OPERATIONAL_FINDING, Recommender, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, callLLM, 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-sNh9XQ6V.js";
4
+ import { ADVISORY_NOTES, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, IngestionServer, LogTurnAnalyzer, OPERATIONAL_FINDING, Recommender, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, callLLM, 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";
5
5
  import { basename, dirname, extname, join } from "path";
6
6
  import { access, readFile, readdir, stat } from "fs/promises";
7
7
  import { EventEmitter } from "node:events";
@@ -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");
@@ -10568,20 +10096,18 @@ var AdapterTelemetryPersistence = class {
10568
10096
  async storeCategoryStats(storyKey, stats) {
10569
10097
  if (stats.length === 0) return;
10570
10098
  await this._adapter.transaction(async (adapter) => {
10571
- for (const stat$2 of stats) try {
10572
- await adapter.query(`INSERT INTO category_stats (
10573
- story_key, category, total_tokens, percentage, event_count,
10574
- avg_tokens_per_event, trend
10575
- ) VALUES (?, ?, ?, ?, ?, ?, ?)`, [
10576
- storyKey,
10577
- stat$2.category,
10578
- stat$2.totalTokens,
10579
- stat$2.percentage,
10580
- stat$2.eventCount,
10581
- stat$2.avgTokensPerEvent,
10582
- stat$2.trend
10583
- ]);
10584
- } catch {}
10099
+ for (const stat$2 of stats) await adapter.query(`INSERT IGNORE INTO category_stats (
10100
+ story_key, category, total_tokens, percentage, event_count,
10101
+ avg_tokens_per_event, trend
10102
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)`, [
10103
+ storyKey,
10104
+ stat$2.category,
10105
+ stat$2.totalTokens,
10106
+ stat$2.percentage,
10107
+ stat$2.eventCount,
10108
+ stat$2.avgTokensPerEvent,
10109
+ stat$2.trend
10110
+ ]);
10585
10111
  });
10586
10112
  logger$9.debug({
10587
10113
  storyKey,
@@ -10613,20 +10139,18 @@ var AdapterTelemetryPersistence = class {
10613
10139
  async storeConsumerStats(storyKey, consumers) {
10614
10140
  if (consumers.length === 0) return;
10615
10141
  await this._adapter.transaction(async (adapter) => {
10616
- for (const consumer of consumers) try {
10617
- await adapter.query(`INSERT INTO consumer_stats (
10618
- story_key, consumer_key, category, total_tokens, percentage,
10619
- event_count, top_invocations_json
10620
- ) VALUES (?, ?, ?, ?, ?, ?, ?)`, [
10621
- storyKey,
10622
- consumer.consumerKey,
10623
- consumer.category,
10624
- consumer.totalTokens,
10625
- consumer.percentage,
10626
- consumer.eventCount,
10627
- JSON.stringify(consumer.topInvocations)
10628
- ]);
10629
- } catch {}
10142
+ for (const consumer of consumers) await adapter.query(`INSERT IGNORE INTO consumer_stats (
10143
+ story_key, consumer_key, category, total_tokens, percentage,
10144
+ event_count, top_invocations_json
10145
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)`, [
10146
+ storyKey,
10147
+ consumer.consumerKey,
10148
+ consumer.category,
10149
+ consumer.totalTokens,
10150
+ consumer.percentage,
10151
+ consumer.eventCount,
10152
+ JSON.stringify(consumer.topInvocations)
10153
+ ]);
10630
10154
  });
10631
10155
  logger$9.debug({
10632
10156
  storyKey,
@@ -10956,6 +10480,29 @@ function persistVerificationResult(storyKey, summary, runManifest) {
10956
10480
  storyKey
10957
10481
  }, "manifest verification_result write failed — pipeline continues"));
10958
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
+ }
10959
10506
 
10960
10507
  //#endregion
10961
10508
  //#region src/modules/implementation-orchestrator/cost-governance.ts
@@ -13916,6 +13463,7 @@ function createImplementationOrchestrator(deps) {
13916
13463
  archConstraints = constraints.map((d) => `${d.key}: ${d.value}`).join("\n");
13917
13464
  } catch {}
13918
13465
  const targetedFilesContent = buildTargetedFilesContent(issueList);
13466
+ const verificationFindingsContent = renderVerificationFindingsForPrompt(verificationStore.get(storyKey));
13919
13467
  const sections = [
13920
13468
  {
13921
13469
  name: "story_content",
@@ -13936,6 +13484,11 @@ function createImplementationOrchestrator(deps) {
13936
13484
  name: "targeted_files",
13937
13485
  content: targetedFilesContent,
13938
13486
  priority: "important"
13487
+ }] : [],
13488
+ ...verificationFindingsContent ? [{
13489
+ name: "verification_findings",
13490
+ content: verificationFindingsContent,
13491
+ priority: "important"
13939
13492
  }] : []
13940
13493
  ];
13941
13494
  const assembled = assemblePrompt(fixTemplate, sections, 24e3);
@@ -14104,6 +13657,7 @@ function createImplementationOrchestrator(deps) {
14104
13657
  const findings = await getProjectFindings(db);
14105
13658
  if (findings !== "") priorFindingsContent = "Prior pipeline findings — avoid repeating these patterns:\n\n" + findings;
14106
13659
  } catch {}
13660
+ const verificationFindingsContent = renderVerificationFindingsForPrompt(verificationStore.get(storyKey));
14107
13661
  const sections = isMajorRework ? [
14108
13662
  {
14109
13663
  name: "story_content",
@@ -14129,7 +13683,12 @@ function createImplementationOrchestrator(deps) {
14129
13683
  name: "prior_findings",
14130
13684
  content: priorFindingsContent,
14131
13685
  priority: "optional"
14132
- }
13686
+ },
13687
+ ...verificationFindingsContent ? [{
13688
+ name: "verification_findings",
13689
+ content: verificationFindingsContent,
13690
+ priority: "important"
13691
+ }] : []
14133
13692
  ] : (() => {
14134
13693
  const targetedFilesContent = buildTargetedFilesContent(issueList);
14135
13694
  return [
@@ -14157,7 +13716,12 @@ function createImplementationOrchestrator(deps) {
14157
13716
  name: "prior_findings",
14158
13717
  content: priorFindingsContent,
14159
13718
  priority: "optional"
14160
- }
13719
+ },
13720
+ ...verificationFindingsContent ? [{
13721
+ name: "verification_findings",
13722
+ content: verificationFindingsContent,
13723
+ priority: "important"
13724
+ }] : []
14161
13725
  ];
14162
13726
  })();
14163
13727
  const assembled = assemblePrompt(fixTemplate, sections, 24e3);
@@ -44276,4 +43840,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
44276
43840
 
44277
43841
  //#endregion
44278
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 };
44279
- //# sourceMappingURL=run-CfYYoCH_.js.map
43843
+ //# sourceMappingURL=run-BHKqyFFM.js.map
@@ -1,8 +1,8 @@
1
- import "./health-DrZiqv4h.js";
1
+ import "./health-CB48LF0t.js";
2
2
  import "./logger-KeHncl-f.js";
3
3
  import "./helpers-CElYrONe.js";
4
- import "./dist-sNh9XQ6V.js";
5
- import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-CfYYoCH_.js";
4
+ import "./dist-srr3BfCc.js";
5
+ import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-BHKqyFFM.js";
6
6
  import "./routing-CcBOCuC9.js";
7
7
  import "./decisions-C0pz9Clx.js";
8
8
 
@@ -1,5 +1,5 @@
1
- import "./dist-sNh9XQ6V.js";
1
+ import "./dist-srr3BfCc.js";
2
2
  import "./version-manager-impl-BmOWu8ml.js";
3
- import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-DfbgFpt7.js";
3
+ import { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand } from "./upgrade-iTr8nbbE.js";
4
4
 
5
5
  export { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand };
@@ -1,4 +1,4 @@
1
- import { createVersionManager } from "./dist-sNh9XQ6V.js";
1
+ import { createVersionManager } from "./dist-srr3BfCc.js";
2
2
  import { execSync, spawn } from "child_process";
3
3
  import * as readline from "readline";
4
4
 
@@ -123,4 +123,4 @@ function registerUpgradeCommand(program) {
123
123
 
124
124
  //#endregion
125
125
  export { isGlobalInstall, registerUpgradeCommand, runUpgradeCommand };
126
- //# sourceMappingURL=upgrade-DfbgFpt7.js.map
126
+ //# sourceMappingURL=upgrade-iTr8nbbE.js.map