substrate-ai 0.19.53 → 0.20.0
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/README.md
CHANGED
|
@@ -340,6 +340,33 @@ substrate factory twins status
|
|
|
340
340
|
substrate factory twins down
|
|
341
341
|
```
|
|
342
342
|
|
|
343
|
+
## Using as a Library
|
|
344
|
+
|
|
345
|
+
Substrate ships as a family of npm packages. Most users just want the CLI (`substrate-ai`); the scoped packages are for downstream projects that want to embed substrate pieces directly.
|
|
346
|
+
|
|
347
|
+
| Package | Use when you want... |
|
|
348
|
+
|---------|----------------------|
|
|
349
|
+
| `substrate-ai` | The full CLI — installed globally |
|
|
350
|
+
| `@substrate-ai/core` | Transport-agnostic primitives — event bus, adapters, cost tracker, telemetry, config schema |
|
|
351
|
+
| `@substrate-ai/sdlc` | SDLC orchestration — phase handlers, graph orchestrator, verification pipeline, learning loop |
|
|
352
|
+
| `@substrate-ai/factory` | Graph engine, scenario runner, convergence loop, digital twin helpers, LLM client |
|
|
353
|
+
|
|
354
|
+
All four packages release in lockstep on every `v*` tag push — pick a version and mix any combination:
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
npm install @substrate-ai/core @substrate-ai/factory
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
import { createEventBus } from '@substrate-ai/core'
|
|
362
|
+
import { parseGraph, createGraphExecutor } from '@substrate-ai/factory'
|
|
363
|
+
import { createSdlcEventBridge } from '@substrate-ai/sdlc'
|
|
364
|
+
|
|
365
|
+
// Compose these primitives in your own orchestrator.
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
TypeScript declaration files are bundled in each package. Published tarballs carry an npm provenance attestation you can verify with `npm audit signatures`.
|
|
369
|
+
|
|
343
370
|
## Configuration
|
|
344
371
|
|
|
345
372
|
Substrate reads configuration from `.substrate/config.yaml` in your project root. Run `substrate init` to generate defaults.
|
|
@@ -461,17 +488,11 @@ git clone https://github.com/johnplanow/substrate.git
|
|
|
461
488
|
cd substrate
|
|
462
489
|
npm install
|
|
463
490
|
npm run build
|
|
464
|
-
npm test
|
|
491
|
+
npm run test:fast # ~50s unit suite for iteration
|
|
492
|
+
npm test # full suite with coverage — run before merging
|
|
465
493
|
```
|
|
466
494
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
| Package | Purpose |
|
|
470
|
-
|---------|---------|
|
|
471
|
-
| `substrate-ai` | CLI entry point, pipeline orchestrators, methodology packs |
|
|
472
|
-
| `@substrate-ai/core` | Transport-agnostic infrastructure — adapters, dispatch, routing, persistence, telemetry |
|
|
473
|
-
| `@substrate-ai/sdlc` | SDLC graph orchestrator, DOT pipeline topology, event handlers |
|
|
474
|
-
| `@substrate-ai/factory` | Software factory — scenarios, convergence, direct API backend, digital twins |
|
|
495
|
+
The repo is an npm workspaces monorepo — see [Using as a Library](#using-as-a-library) for the four packages it publishes. Release mechanics live in `scripts/sync-workspace-versions.mjs` and `.github/workflows/publish.yml`: every `v*` tag push syncs the workspace package versions to the root, dry-runs all four tarballs, and publishes via npm OIDC trusted publishing.
|
|
475
496
|
|
|
476
497
|
## License
|
|
477
498
|
|
package/dist/cli/index.js
CHANGED
|
@@ -4,7 +4,7 @@ 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, IngestionServer, MonitorDatabaseImpl, OPERATIONAL_FINDING, PartialGlobalSettingsSchema, PartialProviderConfigSchema, ProvidersSchema, RoutingRecommender, STORY_METRICS, TelemetryConfigSchema, addTokenUsage, aggregateTokenUsageForRun, checkDoltInstalled, compareRunMetrics, createAmendmentRun, createConfigSystem, createDecision, createDoltClient, createPipelineRun, getActiveDecisions, getAllCostEntriesFiltered, getBaselineRunMetrics, getDecisionsByCategory, getDecisionsByPhaseForRun, getLatestCompletedRun, getLatestRun, getPipelineRunById, getPlanningCostTotal, getRetryableEscalations, getRunMetrics, getRunningPipelineRuns, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRunMetrics, loadParentRunDecisions, supersedeDecision, tagRunAsBaseline, updatePipelineRun } from "../dist-sNh9XQ6V.js";
|
|
6
6
|
import "../adapter-registry-DXLMTmfD.js";
|
|
7
|
-
import { 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, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-
|
|
7
|
+
import { 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, registerExportCommand, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-dCGeboq9.js";
|
|
8
8
|
import "../errors-RupuC-ES.js";
|
|
9
9
|
import "../routing-CcBOCuC9.js";
|
|
10
10
|
import "../decisions-C0pz9Clx.js";
|
|
@@ -5191,7 +5191,7 @@ async function runSupervisorAction(options, deps = {}) {
|
|
|
5191
5191
|
await initSchema(expAdapter);
|
|
5192
5192
|
const { runRunAction: runPipeline } = await import(
|
|
5193
5193
|
/* @vite-ignore */
|
|
5194
|
-
"../run-
|
|
5194
|
+
"../run-D41_ttBq.js"
|
|
5195
5195
|
);
|
|
5196
5196
|
const runStoryFn = async (opts) => {
|
|
5197
5197
|
const exitCode = await runPipeline({
|
|
@@ -2,7 +2,7 @@ import "./health-DrZiqv4h.js";
|
|
|
2
2
|
import "./logger-KeHncl-f.js";
|
|
3
3
|
import "./helpers-CElYrONe.js";
|
|
4
4
|
import "./dist-sNh9XQ6V.js";
|
|
5
|
-
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-
|
|
5
|
+
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-dCGeboq9.js";
|
|
6
6
|
import "./routing-CcBOCuC9.js";
|
|
7
7
|
import "./decisions-C0pz9Clx.js";
|
|
8
8
|
|
|
@@ -6501,6 +6501,142 @@ var TrivialOutputCheck = class {
|
|
|
6501
6501
|
}
|
|
6502
6502
|
};
|
|
6503
6503
|
|
|
6504
|
+
//#endregion
|
|
6505
|
+
//#region packages/sdlc/dist/verification/checks/acceptance-criteria-evidence-check.js
|
|
6506
|
+
/**
|
|
6507
|
+
* AcceptanceCriteriaEvidenceCheck.
|
|
6508
|
+
*
|
|
6509
|
+
* Tier A verification check that compares a story's declared acceptance
|
|
6510
|
+
* criteria against structured dev-story output. The check is intentionally
|
|
6511
|
+
* deterministic: no LLM calls, no shell commands, no repository inspection.
|
|
6512
|
+
*/
|
|
6513
|
+
const EXPLICIT_AC_REF = /\bAC\s*:?\s*#?\s*(\d+)\b/gi;
|
|
6514
|
+
const NUMBERED_CRITERION = /^\s*(?:[-*]\s*)?(?:\[[ xX]\]\s*)?(\d+)[.)]\s+\S/;
|
|
6515
|
+
function normalizeAcId(value) {
|
|
6516
|
+
const parsed = Number.parseInt(value, 10);
|
|
6517
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return void 0;
|
|
6518
|
+
return `AC${parsed}`;
|
|
6519
|
+
}
|
|
6520
|
+
function sortAcIds(ids) {
|
|
6521
|
+
return Array.from(ids).sort((a, b) => {
|
|
6522
|
+
const aNum = Number.parseInt(a.replace(/^AC/i, ""), 10);
|
|
6523
|
+
const bNum = Number.parseInt(b.replace(/^AC/i, ""), 10);
|
|
6524
|
+
return aNum - bNum;
|
|
6525
|
+
});
|
|
6526
|
+
}
|
|
6527
|
+
function addExplicitAcRefs(text, ids) {
|
|
6528
|
+
EXPLICIT_AC_REF.lastIndex = 0;
|
|
6529
|
+
let match$1;
|
|
6530
|
+
while ((match$1 = EXPLICIT_AC_REF.exec(text)) !== null) {
|
|
6531
|
+
const id = normalizeAcId(match$1[1] ?? "");
|
|
6532
|
+
if (id !== void 0) ids.add(id);
|
|
6533
|
+
}
|
|
6534
|
+
}
|
|
6535
|
+
function extractAcceptanceSection(storyContent) {
|
|
6536
|
+
const lines = storyContent.split(/\r?\n/);
|
|
6537
|
+
const start = lines.findIndex((line) => /^##\s+Acceptance Criteria\s*$/i.test(line.trim()));
|
|
6538
|
+
if (start === -1) return void 0;
|
|
6539
|
+
let end = lines.length;
|
|
6540
|
+
for (let i = start + 1; i < lines.length; i += 1) if (/^##\s+\S/.test(lines[i] ?? "")) {
|
|
6541
|
+
end = i;
|
|
6542
|
+
break;
|
|
6543
|
+
}
|
|
6544
|
+
return lines.slice(start + 1, end).join("\n");
|
|
6545
|
+
}
|
|
6546
|
+
/**
|
|
6547
|
+
* Extract normalized AC ids from story markdown.
|
|
6548
|
+
*
|
|
6549
|
+
* Supports the BMAD default format (`### AC1:`), explicit references such as
|
|
6550
|
+
* `AC: #1`, and plain numbered criteria inside the Acceptance Criteria section.
|
|
6551
|
+
*/
|
|
6552
|
+
function extractAcceptanceCriteriaIds(storyContent) {
|
|
6553
|
+
const ids = new Set();
|
|
6554
|
+
const acceptanceSection = extractAcceptanceSection(storyContent);
|
|
6555
|
+
const textToScan = acceptanceSection ?? storyContent;
|
|
6556
|
+
addExplicitAcRefs(textToScan, ids);
|
|
6557
|
+
if (acceptanceSection !== void 0) for (const line of acceptanceSection.split(/\r?\n/)) {
|
|
6558
|
+
const match$1 = line.match(NUMBERED_CRITERION);
|
|
6559
|
+
if (match$1?.[1] !== void 0) {
|
|
6560
|
+
const id = normalizeAcId(match$1[1]);
|
|
6561
|
+
if (id !== void 0) ids.add(id);
|
|
6562
|
+
}
|
|
6563
|
+
}
|
|
6564
|
+
return sortAcIds(ids);
|
|
6565
|
+
}
|
|
6566
|
+
function extractClaimedAcceptanceCriteriaIds(values) {
|
|
6567
|
+
const ids = new Set();
|
|
6568
|
+
for (const value of values ?? []) {
|
|
6569
|
+
addExplicitAcRefs(value, ids);
|
|
6570
|
+
const bareNumber = value.trim().match(/^#?(\d+)\b/);
|
|
6571
|
+
if (bareNumber?.[1] !== void 0) {
|
|
6572
|
+
const id = normalizeAcId(bareNumber[1]);
|
|
6573
|
+
if (id !== void 0) ids.add(id);
|
|
6574
|
+
}
|
|
6575
|
+
}
|
|
6576
|
+
return sortAcIds(ids);
|
|
6577
|
+
}
|
|
6578
|
+
function normalizeTestOutcome(value) {
|
|
6579
|
+
if (value === void 0) return void 0;
|
|
6580
|
+
return value.toLowerCase().includes("fail") ? "fail" : "pass";
|
|
6581
|
+
}
|
|
6582
|
+
function formatIds(ids) {
|
|
6583
|
+
return ids.join(", ");
|
|
6584
|
+
}
|
|
6585
|
+
var AcceptanceCriteriaEvidenceCheck = class {
|
|
6586
|
+
name = "acceptance-criteria-evidence";
|
|
6587
|
+
tier = "A";
|
|
6588
|
+
async run(context) {
|
|
6589
|
+
const start = Date.now();
|
|
6590
|
+
const storyContent = context.storyContent?.trim();
|
|
6591
|
+
if (!storyContent) return {
|
|
6592
|
+
status: "warn",
|
|
6593
|
+
details: "acceptance-criteria-evidence: story content unavailable - skipping AC evidence check",
|
|
6594
|
+
duration_ms: Date.now() - start
|
|
6595
|
+
};
|
|
6596
|
+
const expectedIds = extractAcceptanceCriteriaIds(storyContent);
|
|
6597
|
+
if (expectedIds.length === 0) return {
|
|
6598
|
+
status: "warn",
|
|
6599
|
+
details: "acceptance-criteria-evidence: no numbered acceptance criteria found in story",
|
|
6600
|
+
duration_ms: Date.now() - start
|
|
6601
|
+
};
|
|
6602
|
+
const devResult = context.devStoryResult;
|
|
6603
|
+
if (devResult === void 0) return {
|
|
6604
|
+
status: "warn",
|
|
6605
|
+
details: `acceptance-criteria-evidence: dev-story result unavailable for ${formatIds(expectedIds)}`,
|
|
6606
|
+
duration_ms: Date.now() - start
|
|
6607
|
+
};
|
|
6608
|
+
const acFailures = devResult.ac_failures ?? [];
|
|
6609
|
+
if (acFailures.length > 0) return {
|
|
6610
|
+
status: "fail",
|
|
6611
|
+
details: `acceptance-criteria-evidence: dev-story reported AC failures: ${acFailures.join("; ")}`,
|
|
6612
|
+
duration_ms: Date.now() - start
|
|
6613
|
+
};
|
|
6614
|
+
const testOutcome = normalizeTestOutcome(devResult.tests);
|
|
6615
|
+
if (testOutcome === "fail") return {
|
|
6616
|
+
status: "fail",
|
|
6617
|
+
details: "acceptance-criteria-evidence: dev-story reported failing tests",
|
|
6618
|
+
duration_ms: Date.now() - start
|
|
6619
|
+
};
|
|
6620
|
+
const claimedIds = new Set(extractClaimedAcceptanceCriteriaIds(devResult.ac_met));
|
|
6621
|
+
const missingIds = expectedIds.filter((id) => !claimedIds.has(id));
|
|
6622
|
+
if (missingIds.length > 0) return {
|
|
6623
|
+
status: "fail",
|
|
6624
|
+
details: `acceptance-criteria-evidence: missing dev-story AC evidence for ${formatIds(missingIds)}; expected ${formatIds(expectedIds)}, claimed ${formatIds(sortAcIds(claimedIds)) || "none"}`,
|
|
6625
|
+
duration_ms: Date.now() - start
|
|
6626
|
+
};
|
|
6627
|
+
if (testOutcome === void 0) return {
|
|
6628
|
+
status: "warn",
|
|
6629
|
+
details: `acceptance-criteria-evidence: AC evidence covers ${formatIds(expectedIds)} but test outcome is unavailable`,
|
|
6630
|
+
duration_ms: Date.now() - start
|
|
6631
|
+
};
|
|
6632
|
+
return {
|
|
6633
|
+
status: "pass",
|
|
6634
|
+
details: `acceptance-criteria-evidence: AC evidence covers ${formatIds(expectedIds)}; tests=${testOutcome}`,
|
|
6635
|
+
duration_ms: Date.now() - start
|
|
6636
|
+
};
|
|
6637
|
+
}
|
|
6638
|
+
};
|
|
6639
|
+
|
|
6504
6640
|
//#endregion
|
|
6505
6641
|
//#region packages/sdlc/dist/verification/checks/build-check.js
|
|
6506
6642
|
/** Hard timeout for the build command in milliseconds (FR-V11). */
|
|
@@ -6705,7 +6841,8 @@ var VerificationPipeline = class {
|
|
|
6705
6841
|
* Canonical Tier A check order (architecture section 3.5):
|
|
6706
6842
|
* 1. PhantomReviewCheck — story 51-2 (runs first: unreviewed stories skipped)
|
|
6707
6843
|
* 2. TrivialOutputCheck — story 51-3
|
|
6708
|
-
* 3.
|
|
6844
|
+
* 3. AcceptanceCriteriaEvidenceCheck
|
|
6845
|
+
* 4. BuildCheck — story 51-4
|
|
6709
6846
|
*
|
|
6710
6847
|
* @param bus Typed event bus for verification events.
|
|
6711
6848
|
* @param config Optional config (used to forward threshold to TrivialOutputCheck).
|
|
@@ -6714,6 +6851,7 @@ function createDefaultVerificationPipeline(bus, config) {
|
|
|
6714
6851
|
const checks = [
|
|
6715
6852
|
new PhantomReviewCheck(),
|
|
6716
6853
|
new TrivialOutputCheck(config),
|
|
6854
|
+
new AcceptanceCriteriaEvidenceCheck(),
|
|
6717
6855
|
new BuildCheck()
|
|
6718
6856
|
];
|
|
6719
6857
|
return new VerificationPipeline(bus, checks);
|
|
@@ -10764,6 +10902,8 @@ function assembleVerificationContext(opts) {
|
|
|
10764
10902
|
commitSha,
|
|
10765
10903
|
timeout: 6e4,
|
|
10766
10904
|
reviewResult: opts.reviewResult,
|
|
10905
|
+
storyContent: opts.storyContent,
|
|
10906
|
+
devStoryResult: opts.devStoryResult,
|
|
10767
10907
|
outputTokenCount: opts.outputTokenCount
|
|
10768
10908
|
};
|
|
10769
10909
|
}
|
|
@@ -12597,6 +12737,37 @@ function createImplementationOrchestrator(deps) {
|
|
|
12597
12737
|
const batchFileGroups = [];
|
|
12598
12738
|
let devStoryWasSuccess = false;
|
|
12599
12739
|
let devOutputTokenCount;
|
|
12740
|
+
let storyContentForVerification;
|
|
12741
|
+
let devStorySignals;
|
|
12742
|
+
const normalizeDevStorySignals = (result) => {
|
|
12743
|
+
if (result == null) return void 0;
|
|
12744
|
+
return {
|
|
12745
|
+
result: result.result,
|
|
12746
|
+
ac_met: result.ac_met ?? [],
|
|
12747
|
+
ac_failures: result.ac_failures ?? [],
|
|
12748
|
+
files_modified: result.files_modified ?? [],
|
|
12749
|
+
tests: result.tests
|
|
12750
|
+
};
|
|
12751
|
+
};
|
|
12752
|
+
const replaceDevStorySignals = (result) => {
|
|
12753
|
+
const normalized = normalizeDevStorySignals(result);
|
|
12754
|
+
if (normalized !== void 0) devStorySignals = normalized;
|
|
12755
|
+
};
|
|
12756
|
+
const mergeDevStorySignals = (result) => {
|
|
12757
|
+
const normalized = normalizeDevStorySignals(result);
|
|
12758
|
+
if (normalized === void 0) return;
|
|
12759
|
+
if (devStorySignals === void 0) {
|
|
12760
|
+
devStorySignals = normalized;
|
|
12761
|
+
return;
|
|
12762
|
+
}
|
|
12763
|
+
devStorySignals = {
|
|
12764
|
+
result: devStorySignals.result === "failed" || normalized.result === "failed" ? "failed" : normalized.result ?? devStorySignals.result,
|
|
12765
|
+
ac_met: Array.from(new Set([...devStorySignals.ac_met ?? [], ...normalized.ac_met ?? []])),
|
|
12766
|
+
ac_failures: Array.from(new Set([...devStorySignals.ac_failures ?? [], ...normalized.ac_failures ?? []])),
|
|
12767
|
+
files_modified: Array.from(new Set([...devStorySignals.files_modified ?? [], ...normalized.files_modified ?? []])),
|
|
12768
|
+
tests: devStorySignals.tests === "fail" || normalized.tests === "fail" ? "fail" : normalized.tests ?? devStorySignals.tests
|
|
12769
|
+
};
|
|
12770
|
+
};
|
|
12600
12771
|
let baselineHeadSha;
|
|
12601
12772
|
try {
|
|
12602
12773
|
baselineHeadSha = execSync("git rev-parse HEAD", {
|
|
@@ -12614,6 +12785,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
12614
12785
|
let storyContentForAnalysis = "";
|
|
12615
12786
|
try {
|
|
12616
12787
|
storyContentForAnalysis = await readFile$1(storyFilePath ?? "", "utf-8");
|
|
12788
|
+
storyContentForVerification = storyContentForAnalysis;
|
|
12617
12789
|
} catch (err) {
|
|
12618
12790
|
logger$24.error({
|
|
12619
12791
|
storyKey,
|
|
@@ -12681,6 +12853,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
12681
12853
|
}
|
|
12682
12854
|
const batchDurationMs = Date.now() - batchStartMs;
|
|
12683
12855
|
const batchFilesModified = batchResult.files_modified ?? [];
|
|
12856
|
+
mergeDevStorySignals(batchResult);
|
|
12684
12857
|
const batchMetrics = {
|
|
12685
12858
|
batchIndex: batch.batchIndex,
|
|
12686
12859
|
taskIds: batch.taskIds,
|
|
@@ -12950,6 +13123,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
12950
13123
|
return;
|
|
12951
13124
|
}
|
|
12952
13125
|
const retryParsed = checkpointRetryResult.parsed;
|
|
13126
|
+
replaceDevStorySignals(retryParsed);
|
|
12953
13127
|
devFilesModified = retryParsed?.files_modified ?? checkGitDiffFiles(projectRoot ?? process.cwd());
|
|
12954
13128
|
if (checkpointRetryResult.status === "completed" && retryParsed?.result === "success") devStoryWasSuccess = true;
|
|
12955
13129
|
else logger$24.warn({
|
|
@@ -12958,22 +13132,25 @@ function createImplementationOrchestrator(deps) {
|
|
|
12958
13132
|
}, "Checkpoint retry completed with failure — proceeding to code review");
|
|
12959
13133
|
checkpointHandled = true;
|
|
12960
13134
|
}
|
|
12961
|
-
if (!checkpointHandled)
|
|
12962
|
-
|
|
12963
|
-
|
|
12964
|
-
|
|
12965
|
-
error: devResult.error,
|
|
12966
|
-
filesModified: devFilesModified.length
|
|
12967
|
-
}, "Dev-story reported failure, proceeding to code review");
|
|
12968
|
-
if (!devResult.error?.startsWith("dispatch_timeout")) {
|
|
13135
|
+
if (!checkpointHandled) {
|
|
13136
|
+
replaceDevStorySignals(devResult);
|
|
13137
|
+
if (devResult.result === "success") devStoryWasSuccess = true;
|
|
13138
|
+
else {
|
|
12969
13139
|
logger$24.warn({
|
|
12970
13140
|
storyKey,
|
|
12971
|
-
error: devResult.error
|
|
12972
|
-
|
|
12973
|
-
|
|
12974
|
-
|
|
12975
|
-
|
|
12976
|
-
|
|
13141
|
+
error: devResult.error,
|
|
13142
|
+
filesModified: devFilesModified.length
|
|
13143
|
+
}, "Dev-story reported failure, proceeding to code review");
|
|
13144
|
+
if (!devResult.error?.startsWith("dispatch_timeout")) {
|
|
13145
|
+
logger$24.warn({
|
|
13146
|
+
storyKey,
|
|
13147
|
+
error: devResult.error
|
|
13148
|
+
}, "Agent process failure (non-timeout) — story will proceed to code review with partial work");
|
|
13149
|
+
eventBus.emit("orchestrator:story-warn", {
|
|
13150
|
+
storyKey,
|
|
13151
|
+
msg: "agent process failure (non-timeout)"
|
|
13152
|
+
});
|
|
13153
|
+
}
|
|
12977
13154
|
}
|
|
12978
13155
|
}
|
|
12979
13156
|
}
|
|
@@ -13551,6 +13728,8 @@ function createImplementationOrchestrator(deps) {
|
|
|
13551
13728
|
storyKey,
|
|
13552
13729
|
workingDir: projectRoot ?? process.cwd(),
|
|
13553
13730
|
reviewResult: latestReviewSignals,
|
|
13731
|
+
storyContent: storyContentForVerification,
|
|
13732
|
+
devStoryResult: devStorySignals,
|
|
13554
13733
|
outputTokenCount: devOutputTokenCount
|
|
13555
13734
|
});
|
|
13556
13735
|
const verifSummary = await verificationPipeline.run(verifContext, "A");
|
|
@@ -13791,6 +13970,37 @@ function createImplementationOrchestrator(deps) {
|
|
|
13791
13970
|
}, "Auto-approve fix dispatch failed — approving anyway (issues were minor)");
|
|
13792
13971
|
}
|
|
13793
13972
|
endPhase(storyKey, "code-review");
|
|
13973
|
+
if (config.skipVerification !== true) {
|
|
13974
|
+
const latestReviewSignals = reviewResult != null ? {
|
|
13975
|
+
dispatchFailed: reviewResult.dispatchFailed,
|
|
13976
|
+
error: reviewResult.error,
|
|
13977
|
+
rawOutput: reviewResult.rawOutput
|
|
13978
|
+
} : void 0;
|
|
13979
|
+
const verifContext = assembleVerificationContext({
|
|
13980
|
+
storyKey,
|
|
13981
|
+
workingDir: projectRoot ?? process.cwd(),
|
|
13982
|
+
reviewResult: latestReviewSignals,
|
|
13983
|
+
storyContent: storyContentForVerification,
|
|
13984
|
+
devStoryResult: devStorySignals,
|
|
13985
|
+
outputTokenCount: devOutputTokenCount
|
|
13986
|
+
});
|
|
13987
|
+
const verifSummary = await verificationPipeline.run(verifContext, "A");
|
|
13988
|
+
verificationStore.set(storyKey, verifSummary);
|
|
13989
|
+
persistVerificationResult(storyKey, verifSummary, runManifest);
|
|
13990
|
+
if (verifSummary.status === "fail") {
|
|
13991
|
+
updateStory(storyKey, {
|
|
13992
|
+
phase: "VERIFICATION_FAILED",
|
|
13993
|
+
completedAt: new Date().toISOString()
|
|
13994
|
+
});
|
|
13995
|
+
persistStoryState(storyKey, _stories.get(storyKey)).catch((err) => logger$24.warn({
|
|
13996
|
+
err,
|
|
13997
|
+
storyKey
|
|
13998
|
+
}, "StateStore write failed after verification-failed"));
|
|
13999
|
+
await writeStoryMetricsBestEffort(storyKey, "verification-failed", finalReviewCycles);
|
|
14000
|
+
await persistState();
|
|
14001
|
+
return;
|
|
14002
|
+
}
|
|
14003
|
+
}
|
|
13794
14004
|
eventBus.emit("story:auto-approved", {
|
|
13795
14005
|
storyKey,
|
|
13796
14006
|
verdict,
|
|
@@ -14038,6 +14248,7 @@ function createImplementationOrchestrator(deps) {
|
|
|
14038
14248
|
exitCode: fixResult.exitCode
|
|
14039
14249
|
}, "Fix dispatch failed");
|
|
14040
14250
|
}
|
|
14251
|
+
if (isMajorRework) replaceDevStorySignals(fixResult.parsed);
|
|
14041
14252
|
} catch (err) {
|
|
14042
14253
|
logger$24.warn({
|
|
14043
14254
|
storyKey,
|
|
@@ -43077,4 +43288,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
|
|
|
43077
43288
|
|
|
43078
43289
|
//#endregion
|
|
43079
43290
|
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 };
|
|
43080
|
-
//# sourceMappingURL=run-
|
|
43291
|
+
//# sourceMappingURL=run-dCGeboq9.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "substrate-ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Substrate — multi-agent orchestration daemon for AI coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -65,7 +65,8 @@
|
|
|
65
65
|
"typecheck": "tsc --noEmit",
|
|
66
66
|
"typecheck:gate": "tsc --noEmit -p tsconfig.typecheck.json",
|
|
67
67
|
"clean": "rm -rf dist",
|
|
68
|
-
"substrate:dev": "node dist/cli/index.js"
|
|
68
|
+
"substrate:dev": "node dist/cli/index.js",
|
|
69
|
+
"version:sync": "node scripts/sync-workspace-versions.mjs"
|
|
69
70
|
},
|
|
70
71
|
"dependencies": {
|
|
71
72
|
"bmad-method": "^6.2.2",
|