substrate-ai 0.20.143 → 0.20.145
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-CoxLvCcT.js → health-Dk6gHNDC.js} +2 -2
- package/dist/{health-FUl73R5F.js → health-muiK_xRZ.js} +2 -2
- package/dist/{interactive-prompt-CtO5Tm6u.js → interactive-prompt-PgHUXA-A.js} +2 -2
- package/dist/{manifest-read-BkijWyWk.js → manifest-read-CX6KKQHX.js} +218 -3
- package/dist/modules/interactive-prompt/index.js +2 -2
- package/dist/{run-DRwOPt3k.js → run-C0uq3ETL.js} +4 -4
- package/dist/{run-B2duge-W.js → run-DHPGxjlk.js} +92 -4
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { FileKvStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createDatabaseAdapter, createDoltOperatorReader, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion } from "../health-
|
|
2
|
+
import { FileKvStore, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, buildPipelineStatusOutput, createDatabaseAdapter, createDoltOperatorReader, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion } from "../health-muiK_xRZ.js";
|
|
3
3
|
import { createLogger } from "../logger-KeHncl-f.js";
|
|
4
4
|
import { createEventBus } from "../helpers-CElYrONe.js";
|
|
5
5
|
import { AdapterRegistry, BudgetConfigSchema, CURRENT_CONFIG_FORMAT_VERSION, CURRENT_TASK_GRAPH_VERSION, ConfigError, CostTrackerConfigSchema, DEFAULT_CONFIG, DoltClient, DoltNotInstalled, GlobalSettingsSchema, InMemoryDatabaseAdapter, IngestionServer, MonitorDatabaseImpl, OPERATIONAL_FINDING, PartialGlobalSettingsSchema, PartialProviderConfigSchema, ProvidersSchema, RoutingRecommender, STORY_METRICS, TelemetryConfigSchema, addTokenUsage, aggregateTokenUsageForRun, checkDoltInstalled, compareRunMetrics, createAmendmentRun, createConfigSystem, createDecision, createPipelineRun, createStderrLogger, getActiveDecisions, getAllCostEntriesFiltered, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initWorkGraphSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, swallowDebug, tagRunAsBaseline, updatePipelineRun } from "../dist-DiNK6QOD.js";
|
|
6
|
-
import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR, GitClient, GrammarLoader, Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createGitWorktreeManager, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runSolutioningPhase, unescape, validateStopAfterFromConflict } from "../run-
|
|
6
|
+
import { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR, GitClient, GrammarLoader, Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createGitWorktreeManager, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runSolutioningPhase, unescape, validateStopAfterFromConflict } from "../run-DHPGxjlk.js";
|
|
7
7
|
import "../adapter-registry-DIcrxjH8.js";
|
|
8
|
-
import { RunManifest, SupervisorLock, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, parseRuntimeProbes, readCurrentRunId, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorByClass, rollupProbeAuthorMetrics, runAcTraceabilityCheck } from "../manifest-read-
|
|
8
|
+
import { RunManifest, SupervisorLock, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, parseRuntimeProbes, readCurrentRunId, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorByClass, rollupProbeAuthorMetrics, runAcTraceabilityCheck } from "../manifest-read-CX6KKQHX.js";
|
|
9
9
|
import "../errors-B21JUhcc.js";
|
|
10
10
|
import "../routing-DFxoKHDt.js";
|
|
11
11
|
import { WorkGraphRepository } from "../work-graph-repository-DZyJv5pV.js";
|
|
12
12
|
import "../decisions-CzSIEeGP.js";
|
|
13
13
|
import "../decision-router-BAPpON_C.js";
|
|
14
|
-
import "../interactive-prompt-
|
|
14
|
+
import "../interactive-prompt-PgHUXA-A.js";
|
|
15
15
|
import "../recovery-engine-BKGBeBnW.js";
|
|
16
16
|
import "../version-manager-impl-qFBiO4Eh.js";
|
|
17
17
|
import { registerUpgradeCommand } from "../upgrade-DB7KzD9c.js";
|
|
@@ -7052,7 +7052,7 @@ async function runStatusAction(options) {
|
|
|
7052
7052
|
logger$15.debug({ err }, "Work graph query failed, continuing without work graph data");
|
|
7053
7053
|
}
|
|
7054
7054
|
if (run === void 0) {
|
|
7055
|
-
const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-
|
|
7055
|
+
const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-Dk6gHNDC.js");
|
|
7056
7056
|
const substrateDirPath = join(projectRoot, ".substrate");
|
|
7057
7057
|
const processInfo = inspectProcessTree$1({
|
|
7058
7058
|
projectRoot,
|
|
@@ -8581,7 +8581,7 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
8581
8581
|
await initSchema(expAdapter);
|
|
8582
8582
|
const { runRunAction: runPipeline } = await import(
|
|
8583
8583
|
/* @vite-ignore */
|
|
8584
|
-
"../run-
|
|
8584
|
+
"../run-C0uq3ETL.js"
|
|
8585
8585
|
);
|
|
8586
8586
|
const runStoryFn = async (opts) => {
|
|
8587
8587
|
const exitCode = await runPipeline({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-
|
|
1
|
+
import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-muiK_xRZ.js";
|
|
2
2
|
import "./logger-KeHncl-f.js";
|
|
3
3
|
import "./dist-DiNK6QOD.js";
|
|
4
|
-
import "./manifest-read-
|
|
4
|
+
import "./manifest-read-CX6KKQHX.js";
|
|
5
5
|
import "./work-graph-repository-DZyJv5pV.js";
|
|
6
6
|
import "./decisions-CzSIEeGP.js";
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createLogger } from "./logger-KeHncl-f.js";
|
|
2
2
|
import { DoltClient, DoltQueryError, createDatabaseAdapter$1 as createDatabaseAdapter, getLatestRun, getPipelineRunById, initSchema } from "./dist-DiNK6QOD.js";
|
|
3
|
-
import { resolveMainRepoRoot, resolveRunManifest } from "./manifest-read-
|
|
3
|
+
import { resolveMainRepoRoot, resolveRunManifest } from "./manifest-read-CX6KKQHX.js";
|
|
4
4
|
import { createRequire } from "module";
|
|
5
5
|
import { dirname, join } from "path";
|
|
6
6
|
import { existsSync, readFileSync } from "node:fs";
|
|
@@ -1000,4 +1000,4 @@ function registerHealthCommand(program, _version = "0.0.0", projectRoot = proces
|
|
|
1000
1000
|
|
|
1001
1001
|
//#endregion
|
|
1002
1002
|
export { BMAD_BASELINE_TOKENS_FULL, DEFAULT_STALL_THRESHOLD_SECONDS, FileKvStore, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, SUBSTRATE_OWNED_SETTINGS_KEYS, VALID_PHASES, __commonJS, __require, __toESM, buildPipelineStatusOutput, createDatabaseAdapter$1 as createDatabaseAdapter, createDoltOperatorReader, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, isOrchestratorProcessLine, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, runHealthAction, validateStoryKey };
|
|
1003
|
-
//# sourceMappingURL=health-
|
|
1003
|
+
//# sourceMappingURL=health-muiK_xRZ.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createLogger } from "./logger-KeHncl-f.js";
|
|
2
|
-
import { readCurrentRunId, resolveMainRepoRoot } from "./manifest-read-
|
|
2
|
+
import { readCurrentRunId, resolveMainRepoRoot } from "./manifest-read-CX6KKQHX.js";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
5
5
|
import * as readline from "node:readline";
|
|
@@ -180,4 +180,4 @@ async function runInteractivePrompt(decisionContext) {
|
|
|
180
180
|
|
|
181
181
|
//#endregion
|
|
182
182
|
export { runInteractivePrompt };
|
|
183
|
-
//# sourceMappingURL=interactive-prompt-
|
|
183
|
+
//# sourceMappingURL=interactive-prompt-PgHUXA-A.js.map
|
|
@@ -1737,6 +1737,16 @@ function extractAcceptanceCriteriaIds(storyContent) {
|
|
|
1737
1737
|
if (id !== void 0) ids.add(id);
|
|
1738
1738
|
}
|
|
1739
1739
|
}
|
|
1740
|
+
if (ids.size === 0) {
|
|
1741
|
+
const lines = acceptanceSection.split(/\r?\n/);
|
|
1742
|
+
const scenarioHeadings = lines.filter((l) => /^\s*(?:#+\s*)?(?:\*\*)?Scenario\b/i.test(l)).length;
|
|
1743
|
+
let scenarioCount = scenarioHeadings;
|
|
1744
|
+
if (scenarioCount === 0) scenarioCount = lines.filter((l) => /^\s*(?:\*\*)?Given\b/i.test(l)).length;
|
|
1745
|
+
for (let i = 1; i <= scenarioCount; i++) {
|
|
1746
|
+
const id = normalizeAcId(String(i));
|
|
1747
|
+
if (id !== void 0) ids.add(id);
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1740
1750
|
}
|
|
1741
1751
|
return sortAcIds(ids);
|
|
1742
1752
|
}
|
|
@@ -1783,7 +1793,7 @@ var AcceptanceCriteriaEvidenceCheck = class {
|
|
|
1783
1793
|
const findings = [{
|
|
1784
1794
|
category: "ac-context-missing",
|
|
1785
1795
|
severity: "warn",
|
|
1786
|
-
message: "no
|
|
1796
|
+
message: "no acceptance criteria could be extracted from the story (numbered, AC-ref, bullet, and Gherkin scenario forms all matched nothing) — AC-EVIDENCE ENFORCEMENT IS SKIPPED for this story. If the story genuinely has ACs, their format is unrecognized; number them (1. / AC1) or use Given/When/Then scenarios."
|
|
1787
1797
|
}];
|
|
1788
1798
|
return {
|
|
1789
1799
|
status: "warn",
|
|
@@ -2345,6 +2355,11 @@ var TestSuiteCheck = class {
|
|
|
2345
2355
|
stderrTail: tail$1(stderr),
|
|
2346
2356
|
durationMs: duration
|
|
2347
2357
|
}];
|
|
2358
|
+
if (context.devStoryResult?.tests === "pass") findings.push({
|
|
2359
|
+
category: "tests-claim-mismatch",
|
|
2360
|
+
severity: "error",
|
|
2361
|
+
message: `dev-story self-reported tests: pass, but the real suite failed (exit ${String(code)}) — the claim is contradicted by ground truth`
|
|
2362
|
+
});
|
|
2348
2363
|
resolve$2({
|
|
2349
2364
|
status: "fail",
|
|
2350
2365
|
details: renderFindings(findings),
|
|
@@ -2357,6 +2372,204 @@ var TestSuiteCheck = class {
|
|
|
2357
2372
|
}
|
|
2358
2373
|
};
|
|
2359
2374
|
|
|
2375
|
+
//#endregion
|
|
2376
|
+
//#region packages/sdlc/dist/verification/checks/contamination-check.js
|
|
2377
|
+
/** Map of language → source extensions used for foreign-language detection. */
|
|
2378
|
+
const LANGUAGE_EXTENSIONS = {
|
|
2379
|
+
typescript: [
|
|
2380
|
+
".ts",
|
|
2381
|
+
".tsx",
|
|
2382
|
+
".mts",
|
|
2383
|
+
".cts"
|
|
2384
|
+
],
|
|
2385
|
+
javascript: [
|
|
2386
|
+
".js",
|
|
2387
|
+
".jsx",
|
|
2388
|
+
".mjs",
|
|
2389
|
+
".cjs"
|
|
2390
|
+
],
|
|
2391
|
+
python: [".py"],
|
|
2392
|
+
go: [".go"],
|
|
2393
|
+
rust: [".rs"],
|
|
2394
|
+
java: [".java"],
|
|
2395
|
+
kotlin: [".kt", ".kts"]
|
|
2396
|
+
};
|
|
2397
|
+
/** JS-family toolchain manifests whose appearance flips build detection. */
|
|
2398
|
+
const JS_TOOLCHAIN_MANIFESTS = [
|
|
2399
|
+
"package.json",
|
|
2400
|
+
"tsconfig.json",
|
|
2401
|
+
"package-lock.json",
|
|
2402
|
+
"pnpm-lock.yaml",
|
|
2403
|
+
"yarn.lock",
|
|
2404
|
+
"bun.lockb",
|
|
2405
|
+
"vite.config.ts",
|
|
2406
|
+
"vite.config.js"
|
|
2407
|
+
];
|
|
2408
|
+
/** Droppings that must never appear in a story diff, regardless of language. */
|
|
2409
|
+
const ALWAYS_DENY_SEGMENTS = [
|
|
2410
|
+
"node_modules",
|
|
2411
|
+
".venv",
|
|
2412
|
+
"__pycache__"
|
|
2413
|
+
];
|
|
2414
|
+
/**
|
|
2415
|
+
* Collect every `language: <x>` declaration in the profile (single-project
|
|
2416
|
+
* `project.language` plus monorepo `packages[].language`). Line-based parse —
|
|
2417
|
+
* no yaml dependency. Returns [] when the profile is absent/unreadable.
|
|
2418
|
+
*/
|
|
2419
|
+
function readProfileLanguages(workingDir) {
|
|
2420
|
+
const profilePath = join$1(workingDir, ".substrate", "project-profile.yaml");
|
|
2421
|
+
if (!existsSync(profilePath)) return [];
|
|
2422
|
+
try {
|
|
2423
|
+
const content = readFileSync(profilePath, "utf-8");
|
|
2424
|
+
const langs = new Set();
|
|
2425
|
+
for (const m of content.matchAll(/^\s*(?:-\s+)?language:\s*['"]?([a-z]+)['"]?\s*$/gm)) if (m[1] !== void 0) langs.add(m[1]);
|
|
2426
|
+
return [...langs];
|
|
2427
|
+
} catch {
|
|
2428
|
+
return [];
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
/** Language of a file per LANGUAGE_EXTENSIONS, or undefined for neutral files. */
|
|
2432
|
+
function fileLanguage(file) {
|
|
2433
|
+
const lower = file.toLowerCase();
|
|
2434
|
+
for (const [lang, exts] of Object.entries(LANGUAGE_EXTENSIONS)) if (exts.some((e) => lower.endsWith(e))) return lang;
|
|
2435
|
+
return void 0;
|
|
2436
|
+
}
|
|
2437
|
+
/**
|
|
2438
|
+
* Pure classification of a changed-file list against the project's declared
|
|
2439
|
+
* languages. Exported for unit testing.
|
|
2440
|
+
*/
|
|
2441
|
+
function classifyContamination(changedFiles, allowedLanguages) {
|
|
2442
|
+
const allowJs = allowedLanguages.includes("typescript") || allowedLanguages.includes("javascript");
|
|
2443
|
+
const foreignSourceFiles = [];
|
|
2444
|
+
const foreignToolchainManifests = [];
|
|
2445
|
+
const droppings = [];
|
|
2446
|
+
for (const raw of changedFiles) {
|
|
2447
|
+
const file = raw.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
2448
|
+
const segments = file.split("/");
|
|
2449
|
+
if (segments.some((s) => ALWAYS_DENY_SEGMENTS.includes(s))) {
|
|
2450
|
+
droppings.push(file);
|
|
2451
|
+
continue;
|
|
2452
|
+
}
|
|
2453
|
+
if (!allowJs && segments.includes("dist")) {
|
|
2454
|
+
droppings.push(file);
|
|
2455
|
+
continue;
|
|
2456
|
+
}
|
|
2457
|
+
const base = segments[segments.length - 1] ?? "";
|
|
2458
|
+
if (!allowJs && JS_TOOLCHAIN_MANIFESTS.includes(base)) {
|
|
2459
|
+
foreignToolchainManifests.push(file);
|
|
2460
|
+
continue;
|
|
2461
|
+
}
|
|
2462
|
+
const lang = fileLanguage(file);
|
|
2463
|
+
if (lang !== void 0 && !allowedLanguages.includes(lang)) {
|
|
2464
|
+
if (allowJs && (lang === "typescript" || lang === "javascript")) continue;
|
|
2465
|
+
foreignSourceFiles.push({
|
|
2466
|
+
file,
|
|
2467
|
+
language: lang
|
|
2468
|
+
});
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
return {
|
|
2472
|
+
foreignSourceFiles,
|
|
2473
|
+
foreignToolchainManifests,
|
|
2474
|
+
droppings
|
|
2475
|
+
};
|
|
2476
|
+
}
|
|
2477
|
+
var ContaminationCheck = class {
|
|
2478
|
+
name = "scope-contamination";
|
|
2479
|
+
tier = "A";
|
|
2480
|
+
async run(context) {
|
|
2481
|
+
const start = Date.now();
|
|
2482
|
+
const changedFiles = context.changedFiles ?? [];
|
|
2483
|
+
if (changedFiles.length === 0) return {
|
|
2484
|
+
status: "pass",
|
|
2485
|
+
details: "no changed files to inspect",
|
|
2486
|
+
duration_ms: Date.now() - start,
|
|
2487
|
+
findings: []
|
|
2488
|
+
};
|
|
2489
|
+
const allowedLanguages = readProfileLanguages(context.workingDir);
|
|
2490
|
+
if (allowedLanguages.length === 0) {
|
|
2491
|
+
const findings$1 = [{
|
|
2492
|
+
category: "contamination-skip",
|
|
2493
|
+
severity: "warn",
|
|
2494
|
+
message: `no project profile with declared languages at ${context.workingDir} — cannot check for foreign-toolchain contamination (run substrate init to generate one)`
|
|
2495
|
+
}];
|
|
2496
|
+
return {
|
|
2497
|
+
status: "warn",
|
|
2498
|
+
details: renderFindings(findings$1),
|
|
2499
|
+
duration_ms: Date.now() - start,
|
|
2500
|
+
findings: findings$1
|
|
2501
|
+
};
|
|
2502
|
+
}
|
|
2503
|
+
const verdict = classifyContamination(changedFiles, allowedLanguages);
|
|
2504
|
+
const findings = [];
|
|
2505
|
+
if (verdict.droppings.length > 0) findings.push({
|
|
2506
|
+
category: "contamination-droppings",
|
|
2507
|
+
severity: "error",
|
|
2508
|
+
message: `story diff contains build/dependency droppings that must never be committed: ${verdict.droppings.slice(0, 10).join(", ")}` + (verdict.droppings.length > 10 ? ` (+${String(verdict.droppings.length - 10)} more)` : "")
|
|
2509
|
+
});
|
|
2510
|
+
if (verdict.foreignToolchainManifests.length > 0) findings.push({
|
|
2511
|
+
category: "contamination-toolchain",
|
|
2512
|
+
severity: "error",
|
|
2513
|
+
message: `story introduces a JS toolchain on a ${allowedLanguages.join("/")} project: ${verdict.foreignToolchainManifests.join(", ")}. This is the exact trigger that flips build detection to npm and masks real story outcomes (field finding #12).`
|
|
2514
|
+
});
|
|
2515
|
+
if (verdict.foreignSourceFiles.length > 0) findings.push({
|
|
2516
|
+
category: "contamination-language",
|
|
2517
|
+
severity: "error",
|
|
2518
|
+
message: `story writes source files in language(s) the project does not use (declared: ${allowedLanguages.join(", ")}): ` + verdict.foreignSourceFiles.slice(0, 10).map((f) => `${f.file} [${f.language}]`).join(", ")
|
|
2519
|
+
});
|
|
2520
|
+
if (findings.length === 0) return {
|
|
2521
|
+
status: "pass",
|
|
2522
|
+
details: `no contamination across ${String(changedFiles.length)} changed file(s)`,
|
|
2523
|
+
duration_ms: Date.now() - start,
|
|
2524
|
+
findings: []
|
|
2525
|
+
};
|
|
2526
|
+
return {
|
|
2527
|
+
status: "fail",
|
|
2528
|
+
details: renderFindings(findings),
|
|
2529
|
+
duration_ms: Date.now() - start,
|
|
2530
|
+
findings
|
|
2531
|
+
};
|
|
2532
|
+
}
|
|
2533
|
+
};
|
|
2534
|
+
|
|
2535
|
+
//#endregion
|
|
2536
|
+
//#region packages/sdlc/dist/verification/checks/test-mutation-check.js
|
|
2537
|
+
/** Heuristic: is this path a test file? Covers the JS/TS/Python/Go idioms. */
|
|
2538
|
+
function isTestPath(file) {
|
|
2539
|
+
const norm = file.replace(/\\/g, "/").toLowerCase();
|
|
2540
|
+
const base = norm.split("/").pop() ?? "";
|
|
2541
|
+
if (/(^|\/)(__tests__|tests?)\//.test(norm)) return true;
|
|
2542
|
+
if (/\.(test|spec)\.[a-z]+$/.test(base)) return true;
|
|
2543
|
+
if (/^test_.*\.py$/.test(base) || /_test\.(py|go)$/.test(base)) return true;
|
|
2544
|
+
return false;
|
|
2545
|
+
}
|
|
2546
|
+
var TestMutationCheck = class {
|
|
2547
|
+
name = "test-mutation";
|
|
2548
|
+
tier = "A";
|
|
2549
|
+
async run(context) {
|
|
2550
|
+
const start = Date.now();
|
|
2551
|
+
const modified = context.modifiedTrackedFiles ?? [];
|
|
2552
|
+
const mutatedTests = modified.filter(isTestPath);
|
|
2553
|
+
if (mutatedTests.length === 0) return {
|
|
2554
|
+
status: "pass",
|
|
2555
|
+
details: "no pre-existing test files were modified",
|
|
2556
|
+
duration_ms: Date.now() - start,
|
|
2557
|
+
findings: []
|
|
2558
|
+
};
|
|
2559
|
+
const findings = [{
|
|
2560
|
+
category: "test-mutation",
|
|
2561
|
+
severity: "warn",
|
|
2562
|
+
message: `story MODIFIED ${String(mutatedTests.length)} pre-existing test file(s): ${mutatedTests.slice(0, 10).join(", ")}` + (mutatedTests.length > 10 ? ` (+${String(mutatedTests.length - 10)} more)` : "") + ". Editing existing tests to satisfy a suite is the measured reward-hack pattern — review whether these edits weaken assertions the story was supposed to satisfy."
|
|
2563
|
+
}];
|
|
2564
|
+
return {
|
|
2565
|
+
status: "warn",
|
|
2566
|
+
details: renderFindings(findings),
|
|
2567
|
+
duration_ms: Date.now() - start,
|
|
2568
|
+
findings
|
|
2569
|
+
};
|
|
2570
|
+
}
|
|
2571
|
+
};
|
|
2572
|
+
|
|
2360
2573
|
//#endregion
|
|
2361
2574
|
//#region packages/sdlc/dist/verification/probes/types.js
|
|
2362
2575
|
/**
|
|
@@ -3846,7 +4059,7 @@ var SourceAcFidelityCheck = class {
|
|
|
3846
4059
|
}
|
|
3847
4060
|
}
|
|
3848
4061
|
const existsInCode = pathSatisfiedByCode(context.workingDir, clause.text);
|
|
3849
|
-
const modifiedFiles = context.devStoryResult?.files_modified ?? [];
|
|
4062
|
+
const modifiedFiles = context.changedFiles !== void 0 && context.changedFiles.length > 0 ? context.changedFiles : context.devStoryResult?.files_modified ?? [];
|
|
3850
4063
|
const referencedByStory = pathReferencedInModifiedFiles(context.workingDir, clause.text, modifiedFiles);
|
|
3851
4064
|
let severity;
|
|
3852
4065
|
let driftMessage;
|
|
@@ -4292,6 +4505,8 @@ function createDefaultVerificationPipeline(bus, config) {
|
|
|
4292
4505
|
new AcceptanceCriteriaEvidenceCheck(),
|
|
4293
4506
|
new BuildCheck(),
|
|
4294
4507
|
new TestSuiteCheck(),
|
|
4508
|
+
new ContaminationCheck(),
|
|
4509
|
+
new TestMutationCheck(),
|
|
4295
4510
|
new RuntimeProbeCheck(),
|
|
4296
4511
|
new SourceAcFidelityCheck(),
|
|
4297
4512
|
new SourceAcShelloutCheck(),
|
|
@@ -6075,4 +6290,4 @@ async function resolveRunManifest(dbRoot, runId) {
|
|
|
6075
6290
|
|
|
6076
6291
|
//#endregion
|
|
6077
6292
|
export { FindingsInjector, RunManifest, RuntimeProbeListSchema, SupervisorLock, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, parseRuntimeProbes, readCurrentRunId, renderFindings, resolveGraphPath, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorByClass, rollupProbeAuthorMetrics, runAcTraceabilityCheck, runStaleVerificationRecovery };
|
|
6078
|
-
//# sourceMappingURL=manifest-read-
|
|
6293
|
+
//# sourceMappingURL=manifest-read-CX6KKQHX.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "../../logger-KeHncl-f.js";
|
|
2
2
|
import "../../dist-DiNK6QOD.js";
|
|
3
|
-
import "../../manifest-read-
|
|
4
|
-
import { runInteractivePrompt } from "../../interactive-prompt-
|
|
3
|
+
import "../../manifest-read-CX6KKQHX.js";
|
|
4
|
+
import { runInteractivePrompt } from "../../interactive-prompt-PgHUXA-A.js";
|
|
5
5
|
|
|
6
6
|
export { runInteractivePrompt };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import "./health-
|
|
1
|
+
import "./health-muiK_xRZ.js";
|
|
2
2
|
import "./logger-KeHncl-f.js";
|
|
3
3
|
import "./helpers-CElYrONe.js";
|
|
4
4
|
import "./dist-DiNK6QOD.js";
|
|
5
|
-
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, runRunAction, wireNdjsonEmitter } from "./run-
|
|
6
|
-
import "./manifest-read-
|
|
5
|
+
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, runRunAction, wireNdjsonEmitter } from "./run-DHPGxjlk.js";
|
|
6
|
+
import "./manifest-read-CX6KKQHX.js";
|
|
7
7
|
import "./routing-DFxoKHDt.js";
|
|
8
8
|
import "./work-graph-repository-DZyJv5pV.js";
|
|
9
9
|
import "./decisions-CzSIEeGP.js";
|
|
10
10
|
import "./decision-router-BAPpON_C.js";
|
|
11
|
-
import "./interactive-prompt-
|
|
11
|
+
import "./interactive-prompt-PgHUXA-A.js";
|
|
12
12
|
import "./recovery-engine-BKGBeBnW.js";
|
|
13
13
|
|
|
14
14
|
export { runRunAction };
|
|
@@ -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-muiK_xRZ.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, CLAUDE_AUTH_FAILURE_HINT, CODEX_SANDBOX_BLOCK_HINT, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, IngestionServer, LogTurnAnalyzer, OPERATIONAL_FINDING, Recommender, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, callLLM, classifyVersionGap, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, createStderrLogger, detectClaudeAuthFailure, detectCodexSandboxBlock, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, swallowDebug, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-DiNK6QOD.js";
|
|
5
|
-
import { FindingsInjector, RunManifest, RuntimeProbeListSchema, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, parseRuntimeProbes, renderFindings, resolveGraphPath, resolveMainRepoRoot, runAcTraceabilityCheck, runStaleVerificationRecovery } from "./manifest-read-
|
|
5
|
+
import { FindingsInjector, RunManifest, RuntimeProbeListSchema, applyConfigToGraph, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectsEventDrivenAC, detectsStateIntegratingAC, extractTargetFilesFromStoryContent, parseRuntimeProbes, renderFindings, resolveGraphPath, resolveMainRepoRoot, runAcTraceabilityCheck, runStaleVerificationRecovery } from "./manifest-read-CX6KKQHX.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-PgHUXA-A.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";
|
|
@@ -5999,6 +5999,43 @@ function runBuildVerification(options) {
|
|
|
5999
5999
|
* @param workingDir - Directory to run git commands in (defaults to process.cwd())
|
|
6000
6000
|
* @returns Array of changed file paths; empty when nothing changed
|
|
6001
6001
|
*/
|
|
6002
|
+
/**
|
|
6003
|
+
* H1.7 (hardening program): the PRE-EXISTING files this story modified or
|
|
6004
|
+
* deleted — the tracked-diff portion of the working-tree change (unstaged
|
|
6005
|
+
* HEAD diff + staged), deliberately EXCLUDING untracked/new files. A tracked
|
|
6006
|
+
* file in this list existed before the dispatch; new tests the story wrote
|
|
6007
|
+
* never appear here. Feeds the reward-hack tripwire (agents editing existing
|
|
6008
|
+
* tests to go green — the measured exploit pattern).
|
|
6009
|
+
*/
|
|
6010
|
+
function checkGitModifiedTrackedFiles(workingDir = process.cwd()) {
|
|
6011
|
+
const results = new Set();
|
|
6012
|
+
try {
|
|
6013
|
+
execSync("git rev-parse --verify HEAD", {
|
|
6014
|
+
cwd: workingDir,
|
|
6015
|
+
stdio: [
|
|
6016
|
+
"ignore",
|
|
6017
|
+
"pipe",
|
|
6018
|
+
"pipe"
|
|
6019
|
+
],
|
|
6020
|
+
timeout: 3e3
|
|
6021
|
+
});
|
|
6022
|
+
} catch {
|
|
6023
|
+
return [];
|
|
6024
|
+
}
|
|
6025
|
+
for (const args of ["git diff --name-only HEAD", "git diff --cached --name-only"]) try {
|
|
6026
|
+
execSync(args, {
|
|
6027
|
+
cwd: workingDir,
|
|
6028
|
+
encoding: "utf-8",
|
|
6029
|
+
timeout: 5e3,
|
|
6030
|
+
stdio: [
|
|
6031
|
+
"ignore",
|
|
6032
|
+
"pipe",
|
|
6033
|
+
"pipe"
|
|
6034
|
+
]
|
|
6035
|
+
}).split("\n").map((l) => l.trim()).filter((l) => l.length > 0).forEach((f$1) => results.add(f$1));
|
|
6036
|
+
} catch {}
|
|
6037
|
+
return [...results];
|
|
6038
|
+
}
|
|
6002
6039
|
function checkGitDiffFiles(workingDir = process.cwd()) {
|
|
6003
6040
|
const results = new Set();
|
|
6004
6041
|
let repoHasCommits = true;
|
|
@@ -7542,6 +7579,12 @@ const logger$20 = createLogger("compiled-workflows:git-helpers");
|
|
|
7542
7579
|
* @returns Structured result for the orchestrator to inspect
|
|
7543
7580
|
*/
|
|
7544
7581
|
async function commitDevStoryOutput(storyKey, storyTitle, filesModified, workingDir) {
|
|
7582
|
+
const COMMIT_DENY_SEGMENTS = [
|
|
7583
|
+
"node_modules",
|
|
7584
|
+
".venv",
|
|
7585
|
+
"__pycache__",
|
|
7586
|
+
".substrate-worktrees"
|
|
7587
|
+
];
|
|
7545
7588
|
const insideWorktree = [];
|
|
7546
7589
|
for (const p of filesModified) {
|
|
7547
7590
|
const abs = isAbsolute(p) ? p : resolve$1(workingDir, p);
|
|
@@ -7554,6 +7597,14 @@ async function commitDevStoryOutput(storyKey, storyTitle, filesModified, working
|
|
|
7554
7597
|
}, "commitDevStoryOutput: filtered out path outside worktree");
|
|
7555
7598
|
continue;
|
|
7556
7599
|
}
|
|
7600
|
+
const segments = rel.replace(/\\/g, "/").split("/");
|
|
7601
|
+
if (segments.some((s$1) => COMMIT_DENY_SEGMENTS.includes(s$1))) {
|
|
7602
|
+
logger$20.warn({
|
|
7603
|
+
path: rel,
|
|
7604
|
+
storyKey
|
|
7605
|
+
}, "commitDevStoryOutput: denylisted dependency/artifact path excluded from substrate commit");
|
|
7606
|
+
continue;
|
|
7607
|
+
}
|
|
7557
7608
|
insideWorktree.push(rel);
|
|
7558
7609
|
}
|
|
7559
7610
|
if (insideWorktree.length === 0) return {
|
|
@@ -12619,6 +12670,8 @@ function assembleVerificationContext(opts) {
|
|
|
12619
12670
|
outputTokenCount: opts.outputTokenCount,
|
|
12620
12671
|
sourceEpicContent: opts.sourceEpicContent,
|
|
12621
12672
|
runId: opts.runId,
|
|
12673
|
+
...opts.changedFiles !== void 0 ? { changedFiles: opts.changedFiles } : {},
|
|
12674
|
+
...opts.modifiedTrackedFiles !== void 0 ? { modifiedTrackedFiles: opts.modifiedTrackedFiles } : {},
|
|
12622
12675
|
...profileBuildCommand !== void 0 ? { buildCommand: profileBuildCommand } : {},
|
|
12623
12676
|
...profileTestCommand !== void 0 ? { testCommand: profileTestCommand } : {}
|
|
12624
12677
|
};
|
|
@@ -14714,6 +14767,33 @@ function createImplementationOrchestrator(deps) {
|
|
|
14714
14767
|
await persistState();
|
|
14715
14768
|
return;
|
|
14716
14769
|
}
|
|
14770
|
+
if (effectiveProjectRoot !== void 0 && effectiveProjectRoot !== projectRoot && isAbsolute(createResult.story_file)) {
|
|
14771
|
+
const relToWorktree = relative(effectiveProjectRoot, createResult.story_file);
|
|
14772
|
+
const outsideWorktree = relToWorktree.startsWith("..") || isAbsolute(relToWorktree);
|
|
14773
|
+
if (outsideWorktree) {
|
|
14774
|
+
const errMsg = `create-story wrote its artifact OUTSIDE the story worktree: ${createResult.story_file} (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.`;
|
|
14775
|
+
logger$27.error({
|
|
14776
|
+
storyKey,
|
|
14777
|
+
storyFile: createResult.story_file,
|
|
14778
|
+
worktree: effectiveProjectRoot
|
|
14779
|
+
}, "create-story artifact outside worktree — escalating");
|
|
14780
|
+
updateStory(storyKey, {
|
|
14781
|
+
phase: "ESCALATED",
|
|
14782
|
+
error: "create-story-outside-project",
|
|
14783
|
+
completedAt: new Date().toISOString()
|
|
14784
|
+
});
|
|
14785
|
+
await writeStoryMetricsBestEffort(storyKey, "escalated", 0);
|
|
14786
|
+
await emitEscalation({
|
|
14787
|
+
storyKey,
|
|
14788
|
+
lastVerdict: "create-story-outside-project",
|
|
14789
|
+
reviewCycles: 0,
|
|
14790
|
+
issues: [errMsg],
|
|
14791
|
+
escalationReason: "create-story-outside-project"
|
|
14792
|
+
});
|
|
14793
|
+
await persistState();
|
|
14794
|
+
return;
|
|
14795
|
+
}
|
|
14796
|
+
}
|
|
14717
14797
|
if (effectiveProjectRoot !== void 0) {
|
|
14718
14798
|
const expectedArtifactsDir = join$1(effectiveProjectRoot, "_bmad-output", "implementation-artifacts");
|
|
14719
14799
|
const escapedExpectedDir = expectedArtifactsDir.replace("/_bmad-output/", "/\\_bmad-output/");
|
|
@@ -15660,8 +15740,14 @@ function createImplementationOrchestrator(deps) {
|
|
|
15660
15740
|
return;
|
|
15661
15741
|
}
|
|
15662
15742
|
let gitDiffFiles;
|
|
15743
|
+
let modifiedTrackedFiles;
|
|
15663
15744
|
if (devStoryWasSuccess) {
|
|
15664
15745
|
gitDiffFiles = checkGitDiffFiles(effectiveProjectRoot ?? process.cwd());
|
|
15746
|
+
try {
|
|
15747
|
+
modifiedTrackedFiles = checkGitModifiedTrackedFiles(effectiveProjectRoot ?? process.cwd());
|
|
15748
|
+
} catch {
|
|
15749
|
+
modifiedTrackedFiles = void 0;
|
|
15750
|
+
}
|
|
15665
15751
|
if (gitDiffFiles.length === 0) {
|
|
15666
15752
|
let hasNewCommits = false;
|
|
15667
15753
|
if (baselineHeadSha) try {
|
|
@@ -16109,6 +16195,8 @@ function createImplementationOrchestrator(deps) {
|
|
|
16109
16195
|
devStoryResult: devStorySignals,
|
|
16110
16196
|
outputTokenCount: devOutputTokenCount,
|
|
16111
16197
|
sourceEpicContent,
|
|
16198
|
+
...gitDiffFiles !== void 0 ? { changedFiles: gitDiffFiles } : {},
|
|
16199
|
+
...modifiedTrackedFiles !== void 0 ? { modifiedTrackedFiles } : {},
|
|
16112
16200
|
runId: config.pipelineRunId
|
|
16113
16201
|
});
|
|
16114
16202
|
const verifSummary = await verificationPipeline.run(verifContext, "A");
|
|
@@ -48121,4 +48209,4 @@ function registerRunCommand(program, version = "0.0.0", projectRoot = process.cw
|
|
|
48121
48209
|
|
|
48122
48210
|
//#endregion
|
|
48123
48211
|
export { AdapterTelemetryPersistence, AppError, DoltRepoMapMetaRepository, DoltSymbolRepository, ERR_REPO_MAP_STORAGE_WRITE, EpicIngester, GLOBSTAR$1 as GLOBSTAR, GitClient, GrammarLoader, Minimatch$1 as Minimatch, Minipass, RepoMapInjector, RepoMapModule, RepoMapQueryEngine, RepoMapStorage, SymbolParser, createContextCompiler, createDispatcher, createEventEmitter, createGitWorktreeManager, createImplementationOrchestrator, createPackLoader, createPhaseOrchestrator, createStopAfterGate, createTelemetryAdvisor, escape$1 as escape, formatPhaseCompletionSummary, getFactoryRunSummaries, getScenarioResultsForRun, getTwinRunsForRun, listGraphRuns, normalizeGraphSummaryToStatus, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runProbeAuthor, runRunAction, runSolutioningPhase, unescape$1 as unescape, validateStopAfterFromConflict, wireNdjsonEmitter };
|
|
48124
|
-
//# sourceMappingURL=run-
|
|
48212
|
+
//# sourceMappingURL=run-DHPGxjlk.js.map
|