substrate-ai 0.20.4 → 0.20.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { FileStateStore, RunManifest, SUBSTRATE_OWNED_SETTINGS_KEYS, SupervisorLock, VALID_PHASES, WorkGraphRepository, buildPipelineStatusOutput, createDatabaseAdapter, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveRunManifest } from "../health-
|
|
2
|
+
import { FileStateStore, RunManifest, SUBSTRATE_OWNED_SETTINGS_KEYS, SupervisorLock, VALID_PHASES, WorkGraphRepository, buildPipelineStatusOutput, createDatabaseAdapter, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveRunManifest } from "../health-DHLR9Iz1.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, 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-srr3BfCc.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-ofO9AWFc.js";
|
|
8
8
|
import "../errors-CSTQNabo.js";
|
|
9
9
|
import "../routing-CcBOCuC9.js";
|
|
10
10
|
import "../decisions-C0pz9Clx.js";
|
|
@@ -3665,7 +3665,7 @@ async function runStatusAction(options) {
|
|
|
3665
3665
|
logger$12.debug({ err }, "Work graph query failed, continuing without work graph data");
|
|
3666
3666
|
}
|
|
3667
3667
|
if (run === void 0) {
|
|
3668
|
-
const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-
|
|
3668
|
+
const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-CQTK6ltK.js");
|
|
3669
3669
|
const substrateDirPath = join(projectRoot, ".substrate");
|
|
3670
3670
|
const processInfo = inspectProcessTree$1({
|
|
3671
3671
|
projectRoot,
|
|
@@ -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-s6bRK0LF.js"
|
|
5195
5195
|
);
|
|
5196
5196
|
const runStoryFn = async (opts) => {
|
|
5197
5197
|
const exitCode = await runPipeline({
|
|
@@ -1,4 +1,4 @@
|
|
|
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-DHLR9Iz1.js";
|
|
2
2
|
import "./logger-KeHncl-f.js";
|
|
3
3
|
import "./dist-srr3BfCc.js";
|
|
4
4
|
import "./decisions-C0pz9Clx.js";
|
|
@@ -4,6 +4,7 @@ import { createRequire } from "module";
|
|
|
4
4
|
import { dirname, join } from "path";
|
|
5
5
|
import { readFile } from "fs/promises";
|
|
6
6
|
import { EventEmitter } from "node:events";
|
|
7
|
+
import { YAMLException, load } from "js-yaml";
|
|
7
8
|
import { existsSync, promises, readFileSync } from "node:fs";
|
|
8
9
|
import { spawn, spawnSync } from "node:child_process";
|
|
9
10
|
import { dirname as dirname$1, join as join$1, resolve as resolve$1 } from "node:path";
|
|
@@ -3259,7 +3260,7 @@ const MAX_OUTPUT_CHARS = 2e3;
|
|
|
3259
3260
|
/** Per-stream tail size cap for structured findings (story 55-1 convention). */
|
|
3260
3261
|
const TAIL_BYTES = 4 * 1024;
|
|
3261
3262
|
/** Return the last N bytes of a UTF-8 string, sliced by string length for simplicity. */
|
|
3262
|
-
function tail(text, bytes = TAIL_BYTES) {
|
|
3263
|
+
function tail$1(text, bytes = TAIL_BYTES) {
|
|
3263
3264
|
return text.length <= bytes ? text : text.slice(text.length - bytes);
|
|
3264
3265
|
}
|
|
3265
3266
|
/**
|
|
@@ -3351,8 +3352,8 @@ var BuildCheck = class {
|
|
|
3351
3352
|
severity: "error",
|
|
3352
3353
|
message: `command exceeded ${BUILD_CHECK_TIMEOUT_MS}ms`,
|
|
3353
3354
|
command: cmd,
|
|
3354
|
-
stdoutTail: tail(stdout),
|
|
3355
|
-
stderrTail: tail(stderr),
|
|
3355
|
+
stdoutTail: tail$1(stdout),
|
|
3356
|
+
stderrTail: tail$1(stderr),
|
|
3356
3357
|
durationMs: duration
|
|
3357
3358
|
}];
|
|
3358
3359
|
resolve$2({
|
|
@@ -3379,8 +3380,8 @@ var BuildCheck = class {
|
|
|
3379
3380
|
message: `build failed (exit ${code}): ${truncated}`,
|
|
3380
3381
|
command: cmd,
|
|
3381
3382
|
...code !== null ? { exitCode: code } : {},
|
|
3382
|
-
stdoutTail: tail(stdout),
|
|
3383
|
-
stderrTail: tail(stderr),
|
|
3383
|
+
stdoutTail: tail$1(stdout),
|
|
3384
|
+
stderrTail: tail$1(stderr),
|
|
3384
3385
|
durationMs: duration
|
|
3385
3386
|
}];
|
|
3386
3387
|
resolve$2({
|
|
@@ -3395,6 +3396,342 @@ var BuildCheck = class {
|
|
|
3395
3396
|
}
|
|
3396
3397
|
};
|
|
3397
3398
|
|
|
3399
|
+
//#endregion
|
|
3400
|
+
//#region packages/sdlc/dist/verification/probes/types.js
|
|
3401
|
+
/**
|
|
3402
|
+
* Execution sandbox for a runtime probe.
|
|
3403
|
+
*
|
|
3404
|
+
* - `host`: probe runs directly on the operator's machine. Explicit opt-in.
|
|
3405
|
+
* Cheapest; most dangerous. Authors choosing `host` acknowledge the probe
|
|
3406
|
+
* may touch host state (ports, systemd units, filesystem) and take
|
|
3407
|
+
* responsibility for cleanup.
|
|
3408
|
+
* - `twin`: probe runs inside an ephemeral sandbox brokered by the Digital
|
|
3409
|
+
* Twin subsystem (Epic 47). Twin integration is **deferred to Phase 3** —
|
|
3410
|
+
* probes with `sandbox: twin` currently emit a `probe-deferred` warn
|
|
3411
|
+
* finding rather than executing. Authors can declare twin-scoped probes
|
|
3412
|
+
* today and they will execute transparently once Phase 3 lands.
|
|
3413
|
+
*/
|
|
3414
|
+
const RuntimeProbeSandboxSchema = z.enum(["host", "twin"]);
|
|
3415
|
+
/**
|
|
3416
|
+
* Default per-probe timeout in milliseconds. Matches the existing
|
|
3417
|
+
* BuildCheck ceiling (60 s) — deliberate, so probe timeouts are bounded
|
|
3418
|
+
* by the same policy the pipeline already uses for long-running checks.
|
|
3419
|
+
*/
|
|
3420
|
+
const DEFAULT_PROBE_TIMEOUT_MS = 6e4;
|
|
3421
|
+
/** Hard upper bound on per-probe stdout/stderr retention (≤ 4 KiB — the
|
|
3422
|
+
* same convention as VerificationFinding.{stdoutTail,stderrTail}). */
|
|
3423
|
+
const PROBE_TAIL_BYTES = 4 * 1024;
|
|
3424
|
+
/**
|
|
3425
|
+
* Zod schema for one runtime probe declared in a story's
|
|
3426
|
+
* `## Runtime Probes` section.
|
|
3427
|
+
*
|
|
3428
|
+
* Required fields (`name`, `sandbox`, `command`) force authors to make
|
|
3429
|
+
* intent explicit — no silent defaults that could mask a miswritten probe.
|
|
3430
|
+
* Optional fields cover operational knobs with sensible fallbacks.
|
|
3431
|
+
*/
|
|
3432
|
+
const RuntimeProbeSchema = z.object({
|
|
3433
|
+
name: z.string().min(1, "probe name is required"),
|
|
3434
|
+
sandbox: RuntimeProbeSandboxSchema,
|
|
3435
|
+
command: z.string().min(1, "probe command is required"),
|
|
3436
|
+
timeout_ms: z.number().int().positive().optional(),
|
|
3437
|
+
description: z.string().optional()
|
|
3438
|
+
});
|
|
3439
|
+
/** Zod schema for the full list (wrapping the per-probe schema). */
|
|
3440
|
+
const RuntimeProbeListSchema = z.array(RuntimeProbeSchema);
|
|
3441
|
+
|
|
3442
|
+
//#endregion
|
|
3443
|
+
//#region packages/sdlc/dist/verification/probes/parser.js
|
|
3444
|
+
const SECTION_HEADING = /^##\s+Runtime\s+Probes\s*$/i;
|
|
3445
|
+
/**
|
|
3446
|
+
* Return the raw text of the story's `## Runtime Probes` section (excluding
|
|
3447
|
+
* the heading line itself), or `undefined` if the section is not present.
|
|
3448
|
+
*
|
|
3449
|
+
* The section ends at the next `##` heading or end-of-file. Sub-headings
|
|
3450
|
+
* (`###`, `####`) remain part of the section body.
|
|
3451
|
+
*/
|
|
3452
|
+
function extractRuntimeProbesSection(storyContent) {
|
|
3453
|
+
const lines = storyContent.split(/\r?\n/);
|
|
3454
|
+
const start = lines.findIndex((line) => SECTION_HEADING.test(line.trim()));
|
|
3455
|
+
if (start === -1) return void 0;
|
|
3456
|
+
let end = lines.length;
|
|
3457
|
+
for (let i = start + 1; i < lines.length; i += 1) if (/^##\s+\S/.test(lines[i] ?? "")) {
|
|
3458
|
+
end = i;
|
|
3459
|
+
break;
|
|
3460
|
+
}
|
|
3461
|
+
return lines.slice(start + 1, end).join("\n");
|
|
3462
|
+
}
|
|
3463
|
+
/**
|
|
3464
|
+
* Extract the body of the first ```yaml (or ```yml) fenced block in the
|
|
3465
|
+
* given section text. Returns `undefined` if no yaml fence is present.
|
|
3466
|
+
*
|
|
3467
|
+
* The opening fence is recognized case-insensitively and may carry an
|
|
3468
|
+
* arbitrary trailing info string (e.g. ```yaml title=...). The closing
|
|
3469
|
+
* fence is any line whose first non-whitespace run is exactly three
|
|
3470
|
+
* backticks.
|
|
3471
|
+
*/
|
|
3472
|
+
function extractYamlFence(section) {
|
|
3473
|
+
const lines = section.split(/\r?\n/);
|
|
3474
|
+
let inside = false;
|
|
3475
|
+
let collected;
|
|
3476
|
+
for (const line of lines) {
|
|
3477
|
+
if (!inside) {
|
|
3478
|
+
if (/^\s*```\s*(yaml|yml)\b/i.test(line)) {
|
|
3479
|
+
inside = true;
|
|
3480
|
+
collected = [];
|
|
3481
|
+
}
|
|
3482
|
+
continue;
|
|
3483
|
+
}
|
|
3484
|
+
if (/^\s*```\s*$/.test(line)) return (collected ?? []).join("\n");
|
|
3485
|
+
collected?.push(line);
|
|
3486
|
+
}
|
|
3487
|
+
return void 0;
|
|
3488
|
+
}
|
|
3489
|
+
/**
|
|
3490
|
+
* Parse the `## Runtime Probes` section of a story's markdown content.
|
|
3491
|
+
*
|
|
3492
|
+
* Outcomes:
|
|
3493
|
+
* - section missing → { kind: 'absent' }
|
|
3494
|
+
* - section present, no yaml fence → { kind: 'invalid' }
|
|
3495
|
+
* - section present, yaml fence malformed → { kind: 'invalid' }
|
|
3496
|
+
* - section present, yaml root is not a list → { kind: 'invalid' }
|
|
3497
|
+
* - section present, entry fails RuntimeProbeSchema → { kind: 'invalid' }
|
|
3498
|
+
* - section present, yaml valid, all entries valid → { kind: 'parsed' }
|
|
3499
|
+
*
|
|
3500
|
+
* Duplicate names within a single story are surfaced as `invalid` so that
|
|
3501
|
+
* finding messages can unambiguously reference a probe by name.
|
|
3502
|
+
*/
|
|
3503
|
+
function parseRuntimeProbes(storyContent) {
|
|
3504
|
+
const section = extractRuntimeProbesSection(storyContent);
|
|
3505
|
+
if (section === void 0) return { kind: "absent" };
|
|
3506
|
+
const yamlBody = extractYamlFence(section);
|
|
3507
|
+
if (yamlBody === void 0) return {
|
|
3508
|
+
kind: "invalid",
|
|
3509
|
+
error: "## Runtime Probes section is present but contains no terminated ```yaml fenced block"
|
|
3510
|
+
};
|
|
3511
|
+
let parsed;
|
|
3512
|
+
try {
|
|
3513
|
+
parsed = load(yamlBody) ?? [];
|
|
3514
|
+
} catch (err) {
|
|
3515
|
+
const detail = err instanceof YAMLException ? err.message : String(err);
|
|
3516
|
+
return {
|
|
3517
|
+
kind: "invalid",
|
|
3518
|
+
error: `YAML parse error: ${detail}`
|
|
3519
|
+
};
|
|
3520
|
+
}
|
|
3521
|
+
if (!Array.isArray(parsed)) return {
|
|
3522
|
+
kind: "invalid",
|
|
3523
|
+
error: `probe block root must be a YAML list; got ${typeof parsed}`
|
|
3524
|
+
};
|
|
3525
|
+
const validation = RuntimeProbeListSchema.safeParse(parsed);
|
|
3526
|
+
if (!validation.success) {
|
|
3527
|
+
const first = validation.error.issues[0];
|
|
3528
|
+
const path$1 = first?.path.join(".") ?? "";
|
|
3529
|
+
const message = first?.message ?? "schema validation failed";
|
|
3530
|
+
return {
|
|
3531
|
+
kind: "invalid",
|
|
3532
|
+
error: `probe list is malformed at ${path$1 || "<root>"}: ${message}`
|
|
3533
|
+
};
|
|
3534
|
+
}
|
|
3535
|
+
const probes = validation.data;
|
|
3536
|
+
const seen = new Set();
|
|
3537
|
+
for (const probe of probes) {
|
|
3538
|
+
if (seen.has(probe.name)) return {
|
|
3539
|
+
kind: "invalid",
|
|
3540
|
+
error: `duplicate probe name: ${probe.name}`
|
|
3541
|
+
};
|
|
3542
|
+
seen.add(probe.name);
|
|
3543
|
+
}
|
|
3544
|
+
return {
|
|
3545
|
+
kind: "parsed",
|
|
3546
|
+
probes
|
|
3547
|
+
};
|
|
3548
|
+
}
|
|
3549
|
+
|
|
3550
|
+
//#endregion
|
|
3551
|
+
//#region packages/sdlc/dist/verification/probes/executor.js
|
|
3552
|
+
/** Return the last N bytes of a UTF-8 string (sliced by length for simplicity). */
|
|
3553
|
+
function tail(text, bytes = PROBE_TAIL_BYTES) {
|
|
3554
|
+
return text.length <= bytes ? text : text.slice(text.length - bytes);
|
|
3555
|
+
}
|
|
3556
|
+
/**
|
|
3557
|
+
* Execute one probe on the host and return a structured ProbeResult.
|
|
3558
|
+
*
|
|
3559
|
+
* Behavior notes:
|
|
3560
|
+
* - The shell used is `/bin/sh -c '<probe.command>'` inside a detached
|
|
3561
|
+
* process group (so the entire tree is killed on timeout).
|
|
3562
|
+
* - stdout and stderr are captured independently; each is returned
|
|
3563
|
+
* tailed to PROBE_TAIL_BYTES (≤ 4 KiB) so published tarballs of the
|
|
3564
|
+
* run manifest stay small.
|
|
3565
|
+
* - Timeout defaults to `probe.timeout_ms ?? DEFAULT_PROBE_TIMEOUT_MS`
|
|
3566
|
+
* (60 s). When the timeout fires, the process group is SIGKILL'd and
|
|
3567
|
+
* the returned result has `outcome: 'timeout'`, `exitCode` undefined.
|
|
3568
|
+
* - Never throws. Spawn errors (e.g. exec format error) are returned as
|
|
3569
|
+
* `outcome: 'fail'` with exitCode -1 and the error message captured on
|
|
3570
|
+
* stderrTail, so the caller can emit a deterministic finding.
|
|
3571
|
+
*/
|
|
3572
|
+
function executeProbeOnHost(probe, options = {}) {
|
|
3573
|
+
const timeoutMs = probe.timeout_ms ?? DEFAULT_PROBE_TIMEOUT_MS;
|
|
3574
|
+
const cwd = options.cwd ?? process.cwd();
|
|
3575
|
+
const env = options.env ?? process.env;
|
|
3576
|
+
const start = Date.now();
|
|
3577
|
+
return new Promise((resolve$2) => {
|
|
3578
|
+
let stdout = "";
|
|
3579
|
+
let stderr = "";
|
|
3580
|
+
let settled = false;
|
|
3581
|
+
const child = spawn(probe.command, [], {
|
|
3582
|
+
cwd,
|
|
3583
|
+
env,
|
|
3584
|
+
detached: true,
|
|
3585
|
+
shell: true,
|
|
3586
|
+
stdio: [
|
|
3587
|
+
"ignore",
|
|
3588
|
+
"pipe",
|
|
3589
|
+
"pipe"
|
|
3590
|
+
]
|
|
3591
|
+
});
|
|
3592
|
+
const finalize = (result) => {
|
|
3593
|
+
if (settled) return;
|
|
3594
|
+
settled = true;
|
|
3595
|
+
resolve$2(result);
|
|
3596
|
+
};
|
|
3597
|
+
child.on("error", (err) => {
|
|
3598
|
+
finalize({
|
|
3599
|
+
outcome: "fail",
|
|
3600
|
+
command: probe.command,
|
|
3601
|
+
exitCode: -1,
|
|
3602
|
+
stdoutTail: tail(stdout),
|
|
3603
|
+
stderrTail: tail(stderr + (stderr.length > 0 && !stderr.endsWith("\n") ? "\n" : "") + `spawn error: ${err.message}\n`),
|
|
3604
|
+
durationMs: Date.now() - start
|
|
3605
|
+
});
|
|
3606
|
+
});
|
|
3607
|
+
child.stdout?.on("data", (chunk) => {
|
|
3608
|
+
stdout += chunk.toString();
|
|
3609
|
+
});
|
|
3610
|
+
child.stderr?.on("data", (chunk) => {
|
|
3611
|
+
stderr += chunk.toString();
|
|
3612
|
+
});
|
|
3613
|
+
const timeoutHandle = setTimeout(() => {
|
|
3614
|
+
try {
|
|
3615
|
+
if (child.pid !== void 0) process.kill(-child.pid, "SIGKILL");
|
|
3616
|
+
} catch {}
|
|
3617
|
+
finalize({
|
|
3618
|
+
outcome: "timeout",
|
|
3619
|
+
command: probe.command,
|
|
3620
|
+
stdoutTail: tail(stdout),
|
|
3621
|
+
stderrTail: tail(stderr),
|
|
3622
|
+
durationMs: Date.now() - start
|
|
3623
|
+
});
|
|
3624
|
+
}, timeoutMs);
|
|
3625
|
+
child.on("close", (code) => {
|
|
3626
|
+
clearTimeout(timeoutHandle);
|
|
3627
|
+
const duration = Date.now() - start;
|
|
3628
|
+
finalize({
|
|
3629
|
+
outcome: code === 0 ? "pass" : "fail",
|
|
3630
|
+
command: probe.command,
|
|
3631
|
+
...code !== null ? { exitCode: code } : {},
|
|
3632
|
+
stdoutTail: tail(stdout),
|
|
3633
|
+
stderrTail: tail(stderr),
|
|
3634
|
+
durationMs: duration
|
|
3635
|
+
});
|
|
3636
|
+
});
|
|
3637
|
+
});
|
|
3638
|
+
}
|
|
3639
|
+
|
|
3640
|
+
//#endregion
|
|
3641
|
+
//#region packages/sdlc/dist/verification/checks/runtime-probe-check.js
|
|
3642
|
+
const CATEGORY_PARSE = "runtime-probe-parse-error";
|
|
3643
|
+
const CATEGORY_SKIP = "runtime-probe-skip";
|
|
3644
|
+
const CATEGORY_DEFERRED = "runtime-probe-deferred";
|
|
3645
|
+
const CATEGORY_FAIL = "runtime-probe-fail";
|
|
3646
|
+
const CATEGORY_TIMEOUT = "runtime-probe-timeout";
|
|
3647
|
+
const defaultExecutors = { host: (probe) => executeProbeOnHost(probe, { cwd: process.cwd() }) };
|
|
3648
|
+
var RuntimeProbeCheck = class {
|
|
3649
|
+
name = "runtime-probes";
|
|
3650
|
+
tier = "A";
|
|
3651
|
+
_executors;
|
|
3652
|
+
constructor(executors) {
|
|
3653
|
+
this._executors = {
|
|
3654
|
+
...defaultExecutors,
|
|
3655
|
+
...executors ?? {}
|
|
3656
|
+
};
|
|
3657
|
+
}
|
|
3658
|
+
async run(context) {
|
|
3659
|
+
const start = Date.now();
|
|
3660
|
+
if (context.storyContent === void 0) {
|
|
3661
|
+
const findings$1 = [{
|
|
3662
|
+
category: CATEGORY_SKIP,
|
|
3663
|
+
severity: "warn",
|
|
3664
|
+
message: "story content unavailable — skipping runtime probe check"
|
|
3665
|
+
}];
|
|
3666
|
+
return {
|
|
3667
|
+
status: "warn",
|
|
3668
|
+
details: renderFindings(findings$1),
|
|
3669
|
+
duration_ms: Date.now() - start,
|
|
3670
|
+
findings: findings$1
|
|
3671
|
+
};
|
|
3672
|
+
}
|
|
3673
|
+
const parsed = parseRuntimeProbes(context.storyContent);
|
|
3674
|
+
if (parsed.kind === "absent") return {
|
|
3675
|
+
status: "pass",
|
|
3676
|
+
details: "runtime-probes: no ## Runtime Probes section declared — skipping",
|
|
3677
|
+
duration_ms: Date.now() - start,
|
|
3678
|
+
findings: []
|
|
3679
|
+
};
|
|
3680
|
+
if (parsed.kind === "invalid") {
|
|
3681
|
+
const findings$1 = [{
|
|
3682
|
+
category: CATEGORY_PARSE,
|
|
3683
|
+
severity: "error",
|
|
3684
|
+
message: parsed.error
|
|
3685
|
+
}];
|
|
3686
|
+
return {
|
|
3687
|
+
status: "fail",
|
|
3688
|
+
details: renderFindings(findings$1),
|
|
3689
|
+
duration_ms: Date.now() - start,
|
|
3690
|
+
findings: findings$1
|
|
3691
|
+
};
|
|
3692
|
+
}
|
|
3693
|
+
if (parsed.probes.length === 0) return {
|
|
3694
|
+
status: "pass",
|
|
3695
|
+
details: "runtime-probes: 0 probes declared — skipping",
|
|
3696
|
+
duration_ms: Date.now() - start,
|
|
3697
|
+
findings: []
|
|
3698
|
+
};
|
|
3699
|
+
const findings = [];
|
|
3700
|
+
for (const probe of parsed.probes) {
|
|
3701
|
+
if (probe.sandbox === "twin") {
|
|
3702
|
+
findings.push({
|
|
3703
|
+
category: CATEGORY_DEFERRED,
|
|
3704
|
+
severity: "warn",
|
|
3705
|
+
message: `probe "${probe.name}" uses sandbox=twin which is deferred until Phase 3 (Digital Twin integration); skipping`
|
|
3706
|
+
});
|
|
3707
|
+
continue;
|
|
3708
|
+
}
|
|
3709
|
+
const result = await this._executors.host(probe);
|
|
3710
|
+
if (result.outcome === "pass") continue;
|
|
3711
|
+
const category = result.outcome === "timeout" ? CATEGORY_TIMEOUT : CATEGORY_FAIL;
|
|
3712
|
+
const descriptor = probe.description ? ` (${probe.description})` : "";
|
|
3713
|
+
const message = result.outcome === "timeout" ? `probe "${probe.name}"${descriptor} timed out after ${result.durationMs}ms` : `probe "${probe.name}"${descriptor} failed with exit ${result.exitCode ?? "unknown"}`;
|
|
3714
|
+
findings.push({
|
|
3715
|
+
category,
|
|
3716
|
+
severity: "error",
|
|
3717
|
+
message,
|
|
3718
|
+
command: result.command,
|
|
3719
|
+
...result.exitCode !== void 0 ? { exitCode: result.exitCode } : {},
|
|
3720
|
+
stdoutTail: result.stdoutTail,
|
|
3721
|
+
stderrTail: result.stderrTail,
|
|
3722
|
+
durationMs: result.durationMs
|
|
3723
|
+
});
|
|
3724
|
+
}
|
|
3725
|
+
const status = findings.some((f) => f.severity === "error") ? "fail" : findings.some((f) => f.severity === "warn") ? "warn" : "pass";
|
|
3726
|
+
return {
|
|
3727
|
+
status,
|
|
3728
|
+
details: findings.length > 0 ? renderFindings(findings) : `runtime-probes: ${parsed.probes.length} probe(s) passed`,
|
|
3729
|
+
duration_ms: Date.now() - start,
|
|
3730
|
+
findings
|
|
3731
|
+
};
|
|
3732
|
+
}
|
|
3733
|
+
};
|
|
3734
|
+
|
|
3398
3735
|
//#endregion
|
|
3399
3736
|
//#region packages/sdlc/dist/verification/verification-pipeline.js
|
|
3400
3737
|
/**
|
|
@@ -3460,7 +3797,8 @@ var VerificationPipeline = class {
|
|
|
3460
3797
|
checkName: check.name,
|
|
3461
3798
|
status: runResult.status,
|
|
3462
3799
|
details: runResult.details,
|
|
3463
|
-
duration_ms: runResult.duration_ms
|
|
3800
|
+
duration_ms: runResult.duration_ms,
|
|
3801
|
+
...runResult.findings !== void 0 ? { findings: runResult.findings } : {}
|
|
3464
3802
|
};
|
|
3465
3803
|
} catch (err) {
|
|
3466
3804
|
const elapsed = Date.now() - checkStart;
|
|
@@ -3470,7 +3808,12 @@ var VerificationPipeline = class {
|
|
|
3470
3808
|
checkName: check.name,
|
|
3471
3809
|
status: "warn",
|
|
3472
3810
|
details: message,
|
|
3473
|
-
duration_ms: elapsed
|
|
3811
|
+
duration_ms: elapsed,
|
|
3812
|
+
findings: [{
|
|
3813
|
+
category: "check-exception",
|
|
3814
|
+
severity: "warn",
|
|
3815
|
+
message
|
|
3816
|
+
}]
|
|
3474
3817
|
};
|
|
3475
3818
|
}
|
|
3476
3819
|
checkResults.push(result);
|
|
@@ -3495,11 +3838,13 @@ var VerificationPipeline = class {
|
|
|
3495
3838
|
/**
|
|
3496
3839
|
* Create a VerificationPipeline pre-loaded with the canonical check set.
|
|
3497
3840
|
*
|
|
3498
|
-
* Canonical Tier A check order
|
|
3841
|
+
* Canonical Tier A check order:
|
|
3499
3842
|
* 1. PhantomReviewCheck — story 51-2 (runs first: unreviewed stories skipped)
|
|
3500
3843
|
* 2. TrivialOutputCheck — story 51-3
|
|
3501
3844
|
* 3. AcceptanceCriteriaEvidenceCheck
|
|
3502
3845
|
* 4. BuildCheck — story 51-4
|
|
3846
|
+
* 5. RuntimeProbeCheck — Epic 55 Phase 2: runtime behavior gate; runs last
|
|
3847
|
+
* in Tier A because probes may depend on built artifacts
|
|
3503
3848
|
*
|
|
3504
3849
|
* @param bus Typed event bus for verification events.
|
|
3505
3850
|
* @param config Optional config (used to forward threshold to TrivialOutputCheck).
|
|
@@ -3509,7 +3854,8 @@ function createDefaultVerificationPipeline(bus, config) {
|
|
|
3509
3854
|
new PhantomReviewCheck(),
|
|
3510
3855
|
new TrivialOutputCheck(config),
|
|
3511
3856
|
new AcceptanceCriteriaEvidenceCheck(),
|
|
3512
|
-
new BuildCheck()
|
|
3857
|
+
new BuildCheck(),
|
|
3858
|
+
new RuntimeProbeCheck()
|
|
3513
3859
|
];
|
|
3514
3860
|
return new VerificationPipeline(bus, checks);
|
|
3515
3861
|
}
|
|
@@ -4885,4 +5231,4 @@ function registerHealthCommand(program, _version = "0.0.0", projectRoot = proces
|
|
|
4885
5231
|
|
|
4886
5232
|
//#endregion
|
|
4887
5233
|
export { BMAD_BASELINE_TOKENS_FULL, DEFAULT_STALL_THRESHOLD_SECONDS, DoltMergeConflict, FileStateStore, FindingsInjector, RunManifest, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN$1 as STORY_KEY_PATTERN, SUBSTRATE_OWNED_SETTINGS_KEYS, SupervisorLock, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter$1 as createDatabaseAdapter, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, createStateStore, detectCycles, extractTargetFilesFromStoryContent, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, isOrchestratorProcessLine, parseDbTimestampAsUtc, registerHealthCommand, renderFindings, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveGraphPath, resolveMainRepoRoot, resolveRunManifest, runHealthAction, validateStoryKey };
|
|
4888
|
-
//# sourceMappingURL=health-
|
|
5234
|
+
//# sourceMappingURL=health-DHLR9Iz1.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, FindingsInjector, RunManifest, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectCycles, extractTargetFilesFromStoryContent, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, renderFindings, resolveGraphPath, resolveMainRepoRoot, validateStoryKey } from "./health-
|
|
1
|
+
import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, FindingsInjector, RunManifest, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectCycles, extractTargetFilesFromStoryContent, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, renderFindings, resolveGraphPath, resolveMainRepoRoot, validateStoryKey } from "./health-DHLR9Iz1.js";
|
|
2
2
|
import { createLogger } from "./logger-KeHncl-f.js";
|
|
3
3
|
import { TypedEventBusImpl, createEventBus, createTuiApp, isTuiCapable, printNonTtyWarning, sleep } from "./helpers-CElYrONe.js";
|
|
4
4
|
import { ADVISORY_NOTES, Categorizer, ConsumerAnalyzer, DEFAULT_GLOBAL_SETTINGS, DispatcherImpl, DoltClient, ESCALATION_DIAGNOSIS, EXPERIMENT_RESULT, EfficiencyScorer, IngestionServer, LogTurnAnalyzer, OPERATIONAL_FINDING, Recommender, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, STORY_METRICS, STORY_OUTCOME, SubstrateConfigSchema, TEST_EXPANSION_FINDING, TEST_PLAN, TelemetryNormalizer, TelemetryPipeline, TurnAnalyzer, addTokenUsage, aggregateTokenUsageForRun, aggregateTokenUsageForStory, callLLM, createConfigSystem, createDatabaseAdapter$1, createDecision, createPipelineRun, createRequirement, detectInterfaceChanges, getArtifactByTypeForRun, getArtifactsByRun, getDecisionsByCategory, getDecisionsByPhase, getDecisionsByPhaseForRun, getLatestRun, getPipelineRunById, getRunMetrics, getRunningPipelineRuns, getStoryMetricsForRun, getTokenUsageSummary, initSchema, listRequirements, loadModelRoutingConfig, registerArtifact, updatePipelineRun, updatePipelineRunConfig, upsertDecision, writeRunMetrics, writeStoryMetrics } from "./dist-srr3BfCc.js";
|
|
@@ -43840,4 +43840,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
|
|
|
43840
43840
|
|
|
43841
43841
|
//#endregion
|
|
43842
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 };
|
|
43843
|
-
//# sourceMappingURL=run-
|
|
43843
|
+
//# sourceMappingURL=run-ofO9AWFc.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import "./health-
|
|
1
|
+
import "./health-DHLR9Iz1.js";
|
|
2
2
|
import "./logger-KeHncl-f.js";
|
|
3
3
|
import "./helpers-CElYrONe.js";
|
|
4
4
|
import "./dist-srr3BfCc.js";
|
|
5
|
-
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-
|
|
5
|
+
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-ofO9AWFc.js";
|
|
6
6
|
import "./routing-CcBOCuC9.js";
|
|
7
7
|
import "./decisions-C0pz9Clx.js";
|
|
8
8
|
|