substrate-ai 0.20.42 → 0.20.44

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, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, buildPipelineStatusOutput, createDatabaseAdapter, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, parseRuntimeProbes, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorMetrics } from "../health-BmEu3n9Z.js";
2
+ import { FileStateStore, RunManifest, SUBSTRATE_OWNED_SETTINGS_KEYS, SupervisorLock, VALID_PHASES, WorkGraphRepository, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, aggregateProbeAuthorMetrics, buildPipelineStatusOutput, createDatabaseAdapter, createStateStore, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, parseDbTimestampAsUtc, parseRuntimeProbes, registerHealthCommand, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorMetrics } from "../health-BZ1WtrLT.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, 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-VcMmfo2w.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, runProbeAuthor, runSolutioningPhase, validateStopAfterFromConflict } from "../run-DnwsCYYA.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, runProbeAuthor, runSolutioningPhase, validateStopAfterFromConflict } from "../run-CEVH9qJy.js";
8
8
  import "../errors-CogpxBUg.js";
9
9
  import "../routing-CcBOCuC9.js";
10
10
  import "../decisions-C0pz9Clx.js";
@@ -3667,7 +3667,7 @@ async function runStatusAction(options) {
3667
3667
  logger$13.debug({ err }, "Work graph query failed, continuing without work graph data");
3668
3668
  }
3669
3669
  if (run === void 0) {
3670
- const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-CAV-PNE4.js");
3670
+ const { inspectProcessTree: inspectProcessTree$1 } = await import("../health-CP3c3Imm.js");
3671
3671
  const substrateDirPath = join(projectRoot, ".substrate");
3672
3672
  const processInfo = inspectProcessTree$1({
3673
3673
  projectRoot,
@@ -5204,7 +5204,7 @@ async function runSupervisorAction(options, deps = {}) {
5204
5204
  await initSchema(expAdapter);
5205
5205
  const { runRunAction: runPipeline } = await import(
5206
5206
  /* @vite-ignore */
5207
- "../run-CXTAvjCK.js"
5207
+ "../run-DRElMHQ7.js"
5208
5208
  );
5209
5209
  const runStoryFn = async (opts) => {
5210
5210
  const exitCode = await runPipeline({
@@ -3994,6 +3994,53 @@ function executeProbeOnHost(probe, options = {}) {
3994
3994
  });
3995
3995
  }
3996
3996
 
3997
+ //#endregion
3998
+ //#region packages/sdlc/dist/run-model/story-artifact-schema.js
3999
+ /**
4000
+ * Open string enum for external-state dependency categories.
4001
+ * Suggested values: subprocess, filesystem, git, database, network,
4002
+ * registry, os. Open string so novel names don't cause silent skips.
4003
+ */
4004
+ const ExternalStateDependencySchema = z.string();
4005
+ const StoryFrontmatterSchema = z.object({ external_state_dependencies: z.array(ExternalStateDependencySchema).optional().default([]) });
4006
+ /**
4007
+ * Parse the optional YAML frontmatter block from a story artifact.
4008
+ *
4009
+ * Frontmatter must appear at the very start of the file, delimited by
4010
+ * `---\n` lines:
4011
+ *
4012
+ * ```
4013
+ * ---
4014
+ * external_state_dependencies:
4015
+ * - subprocess
4016
+ * - git
4017
+ * ---
4018
+ * # Story Title
4019
+ * ...
4020
+ * ```
4021
+ *
4022
+ * Returns `StoryFrontmatterSchema.parse({})` (i.e. `{ external_state_dependencies: [] }`)
4023
+ * on any of:
4024
+ * - No frontmatter block present
4025
+ * - Frontmatter YAML is malformed
4026
+ * - Frontmatter fields fail Zod validation
4027
+ *
4028
+ * This preserves backward-compatibility: stories without a frontmatter
4029
+ * block (i.e. every story created before Epic 64) continue to pass the
4030
+ * external-state-dependencies gate because the empty array is the "no
4031
+ * dependencies declared" default.
4032
+ */
4033
+ function parseStoryFrontmatter(content) {
4034
+ const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n/.exec(content);
4035
+ if (!match) return StoryFrontmatterSchema.parse({});
4036
+ try {
4037
+ const raw = load(match[1] ?? "");
4038
+ return StoryFrontmatterSchema.parse(raw ?? {});
4039
+ } catch {
4040
+ return StoryFrontmatterSchema.parse({});
4041
+ }
4042
+ }
4043
+
3997
4044
  //#endregion
3998
4045
  //#region packages/sdlc/dist/verification/checks/runtime-probe-check.js
3999
4046
  const CATEGORY_PARSE = "runtime-probe-parse-error";
@@ -4034,6 +4081,15 @@ const CATEGORY_ERROR_RESPONSE = "runtime-probe-error-response";
4034
4081
  */
4035
4082
  const CATEGORY_MISSING_TRIGGER = "runtime-probe-missing-production-trigger";
4036
4083
  /**
4084
+ * Story 64-2: story declares `external_state_dependencies` in its frontmatter
4085
+ * but has no `## Runtime Probes` section. The machine-readable declaration
4086
+ * confirms the author knows the story interacts with external state, so the
4087
+ * missing probes section is a hard gate — not just advisory.
4088
+ * Distinct from `runtime-probe-missing-production-trigger` (which fires when
4089
+ * probes are present but don't invoke a production trigger for event-driven ACs).
4090
+ */
4091
+ const CATEGORY_MISSING_PROBES_DECLARED = "runtime-probe-missing-declared-probes";
4092
+ /**
4037
4093
  * Source-AC keywords that signal an event-driven implementation. Word-boundary
4038
4094
  * matched, case-insensitive. When any of these appears in source AC text AND
4039
4095
  * no probe's command invokes a known production trigger, the check emits a
@@ -4112,12 +4168,28 @@ var RuntimeProbeCheck = class {
4112
4168
  };
4113
4169
  }
4114
4170
  const parsed = parseRuntimeProbes(context.storyContent);
4115
- if (parsed.kind === "absent") return {
4116
- status: "pass",
4117
- details: "runtime-probes: no ## Runtime Probes section declared — skipping",
4118
- duration_ms: Date.now() - start,
4119
- findings: []
4120
- };
4171
+ if (parsed.kind === "absent") {
4172
+ const frontmatter = parseStoryFrontmatter(context.storyContent);
4173
+ if (frontmatter.external_state_dependencies.length > 0) {
4174
+ const findings$1 = [{
4175
+ category: CATEGORY_MISSING_PROBES_DECLARED,
4176
+ severity: "error",
4177
+ message: "story declares external_state_dependencies but has no `## Runtime Probes` section — probes required per obs_2026-05-01_017."
4178
+ }];
4179
+ return {
4180
+ status: "fail",
4181
+ details: renderFindings(findings$1),
4182
+ duration_ms: Date.now() - start,
4183
+ findings: findings$1
4184
+ };
4185
+ }
4186
+ return {
4187
+ status: "pass",
4188
+ details: "runtime-probes: no ## Runtime Probes section declared — skipping",
4189
+ duration_ms: Date.now() - start,
4190
+ findings: []
4191
+ };
4192
+ }
4121
4193
  if (parsed.kind === "invalid") {
4122
4194
  const findings$1 = [{
4123
4195
  category: CATEGORY_PARSE,
@@ -6628,4 +6700,4 @@ function registerHealthCommand(program, _version = "0.0.0", projectRoot = proces
6628
6700
 
6629
6701
  //#endregion
6630
6702
  export { BMAD_BASELINE_TOKENS_FULL, DEFAULT_STALL_THRESHOLD_SECONDS, DoltMergeConflict, FileStateStore, FindingsInjector, RunManifest, RuntimeProbeListSchema, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN$1 as STORY_KEY_PATTERN, SUBSTRATE_OWNED_SETTINGS_KEYS, SupervisorLock, VALID_PHASES, WorkGraphRepository, ZERO_FINDINGS_BY_AUTHOR, ZERO_FINDING_COUNTS, ZERO_PROBE_AUTHOR_METRICS, __commonJS, __require, __toESM, aggregateProbeAuthorMetrics, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter$1 as createDatabaseAdapter, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, createStateStore, detectCycles, detectsEventDrivenAC, extractTargetFilesFromStoryContent, findPackageRoot, formatOutput, formatPipelineStatusHuman, formatPipelineSummary, formatTokenTelemetry, getAllDescendantPids, getAutoHealthData, getSubstrateDefaultSettings, inspectProcessTree, isOrchestratorProcessLine, parseDbTimestampAsUtc, parseRuntimeProbes, registerHealthCommand, renderFindings, resolveBmadMethodSrcPath, resolveBmadMethodVersion, resolveGraphPath, resolveMainRepoRoot, resolveRunManifest, rollupFindingCounts, rollupFindingsByAuthor, rollupProbeAuthorMetrics, runHealthAction, validateStoryKey };
6631
- //# sourceMappingURL=health-BmEu3n9Z.js.map
6703
+ //# sourceMappingURL=health-BZ1WtrLT.js.map
@@ -1,4 +1,4 @@
1
- import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-BmEu3n9Z.js";
1
+ import { DEFAULT_STALL_THRESHOLD_SECONDS, getAllDescendantPids, getAutoHealthData, inspectProcessTree, isOrchestratorProcessLine, registerHealthCommand, runHealthAction } from "./health-BZ1WtrLT.js";
2
2
  import "./logger-KeHncl-f.js";
3
3
  import "./dist-VcMmfo2w.js";
4
4
  import "./decisions-C0pz9Clx.js";
@@ -1,4 +1,4 @@
1
- import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, FindingsInjector, RunManifest, RuntimeProbeListSchema, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectCycles, detectsEventDrivenAC, extractTargetFilesFromStoryContent, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, renderFindings, resolveGraphPath, resolveMainRepoRoot, validateStoryKey } from "./health-BmEu3n9Z.js";
1
+ import { BMAD_BASELINE_TOKENS_FULL, DoltMergeConflict, FileStateStore, FindingsInjector, RunManifest, RuntimeProbeListSchema, STOP_AFTER_VALID_PHASES, STORY_KEY_PATTERN, VALID_PHASES, WorkGraphRepository, __commonJS, __require, __toESM, applyConfigToGraph, buildPipelineStatusOutput, createDatabaseAdapter, createDefaultVerificationPipeline, createGraphOrchestrator, createSdlcCodeReviewHandler, createSdlcCreateStoryHandler, createSdlcDevStoryHandler, createSdlcPhaseHandler, detectCycles, detectsEventDrivenAC, extractTargetFilesFromStoryContent, formatOutput, formatPipelineSummary, formatTokenTelemetry, inspectProcessTree, parseDbTimestampAsUtc, renderFindings, resolveGraphPath, resolveMainRepoRoot, validateStoryKey } from "./health-BZ1WtrLT.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-VcMmfo2w.js";
@@ -45175,4 +45175,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
45175
45175
 
45176
45176
  //#endregion
45177
45177
  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, runProbeAuthor, runRunAction, runSolutioningPhase, validateStopAfterFromConflict, wireNdjsonEmitter };
45178
- //# sourceMappingURL=run-DnwsCYYA.js.map
45178
+ //# sourceMappingURL=run-CEVH9qJy.js.map
@@ -1,8 +1,8 @@
1
- import "./health-BmEu3n9Z.js";
1
+ import "./health-BZ1WtrLT.js";
2
2
  import "./logger-KeHncl-f.js";
3
3
  import "./helpers-CElYrONe.js";
4
4
  import "./dist-VcMmfo2w.js";
5
- import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-DnwsCYYA.js";
5
+ import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, runRunAction, wireNdjsonEmitter } from "./run-CEVH9qJy.js";
6
6
  import "./routing-CcBOCuC9.js";
7
7
  import "./decisions-C0pz9Clx.js";
8
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "substrate-ai",
3
- "version": "0.20.42",
3
+ "version": "0.20.44",
4
4
  "description": "Substrate — multi-agent orchestration daemon for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -108,12 +108,53 @@ Use this exact format for each item:
108
108
 
109
109
  **Behavioral signals (runtime-dependent even when the artifact ships as TypeScript / JavaScript / Python source):** the AC describes the implementation invoking a **subprocess** (`execSync`, `spawn`, `child_process`), reading or writing the **filesystem outside test tmpdirs** (`fs.read*`, `fs.write*`, `path.join(homedir(), ...)`), running **git operations** (`git log`, `git push`, `git merge`), querying a **database** (Dolt, mysql, sqlite, postgres), making **network requests** (`fetch`, `axios`, `http.get`), or scanning a **registry / configuration source** ("queries the registry", "scans the fleet").
110
110
 
111
- If **either** the artifact-shape signal **or** the behavioral signal fires, add a `## Runtime Probes` section. Each probe is a short shell command whose exit status answers "does this artifact actually work against real state?".
111
+ **Architectural-level signals (the same external-state interactions described at higher abstraction levels — runtime-dependent identically):** the AC names a **named external dependency** (service, package, agent, skill, mesh, registry, queue, outbox, store, daemon, etc.) AND describes any **interaction verb** (queries, publishes, consumes, calls, writes to, reads from, subscribes to, registers with, delegates to, reaches for, persists to). Phrase patterns to recognize as the architectural-level equivalents of the code-API enumeration above:
112
+
113
+ - `queries <service-or-skill>` (network / database) — e.g., "queries agent-mesh's `query-reports` skill", "queries the Dolt registry"
114
+ - `publishes <X> via <package>['s component]` (network / filesystem) — e.g., "publishes `MorningBriefing` via packages/mesh-agent's outbox"
115
+ - `consumes <skill> from <agent>` / `subscribes to <event>` (network) — e.g., "consumes the `vision` skill", "subscribes to mesh telemetry"
116
+ - `via <package>'s [outbox | client | skill | inbox | queue]` (network / filesystem) — names a peer-package surface as the integration point
117
+ - `graceful degradation when <service> unreachable` / `falls back when <X> down` (network) — implies the AC expects a real network round-trip in the happy path
118
+ - `writes to / reads from the <named-store>` (database / filesystem) — store-shaped naming (mesh outbox, briefings table, vault, etc.)
119
+
120
+ The decision rule is identical to the code-API patterns above: **if the AC names a named external dependency that the implementation must interact with, the story IS runtime-dependent** regardless of whether the AC mentions specific code APIs (`fetch`, `execSync`, etc.). Map each architectural-level interaction to the matching `external_state_dependencies` category (mesh/skill/registry queries → `network`; outbox writes → `filesystem` or `network` depending on transport; etc.).
121
+
122
+ Strata Story 2-7 ("jarvis morning briefing consumes agent-mesh query-reports") shipped without probes under v0.20.43 because its ACs used architectural-level phrasing ("queries agent-mesh's skill", "publishes via outbox") that didn't match the code-API patterns; this paragraph closes that gap. See observation `obs_2026-05-01_017` reopen entry dated `2026-05-02T23:05:00Z`.
123
+
124
+ If **any** of the artifact-shape, code-API, or architectural-level signals fires, add a `## Runtime Probes` section. Each probe is a short shell command whose exit status answers "does this artifact actually work against real state?".
112
125
 
113
126
  **Omit the `## Runtime Probes` section ONLY for purely-algorithmic modules**: pure-function transforms (parse, format, sort, score, calculate), type-only refactors, documentation edits, build or tsconfig changes, and unit-test-only stories. A TypeScript module that runs `execSync('git log')`, reads `~/.config/...`, queries Dolt, or fetches from a network endpoint is RUNTIME-DEPENDENT regardless of its `.ts` extension; **do not omit probes for it**.
114
127
 
115
128
  Strata Story 2-4 ("morning briefing generator", v0.20.41) shipped two architectural defects through every substrate verification gate — `git log` ran with `cwd=fleetRoot` (a parent of N repos, not a single repo); commit attribution used substring match — because mocked unit tests passed and no `## Runtime Probes` section was authored. The prior prompt guidance had told agents to omit probes for "TypeScript code + tests" without checking whether that code interacts with external state. See observation `obs_2026-05-01_017`.
116
129
 
130
+ ### Frontmatter declaration for external-state dependencies
131
+
132
+ When you author a `## Runtime Probes` section, also populate the `external_state_dependencies` YAML frontmatter field at the **top of the story file** (before the `# Story Title` line). This is the machine-readable declaration that pairs with the operational `## Runtime Probes` section. The verification pipeline reads this field: when it is non-empty and no `## Runtime Probes` section is present, verification escalates to `error` severity and hard-gates SHIP_IT — the machine-readable declaration is proof the author knew external state was involved and left the probes section out intentionally or accidentally.
133
+
134
+ Example frontmatter (place at the very top of the story file, before `# Story Title`):
135
+
136
+ ```text
137
+ ---
138
+ external_state_dependencies:
139
+ - subprocess
140
+ - filesystem
141
+ ---
142
+ ```
143
+
144
+ Suggested values (use as many as apply):
145
+
146
+ | Value | Covers |
147
+ |---|---|
148
+ | `subprocess` | `execSync`, `spawn`, `child_process.*` calls |
149
+ | `filesystem` | `fs.read*` / `fs.write*` against host paths outside test tmpdirs |
150
+ | `git` | `git log`, `git push`, `git merge`, or any git operation |
151
+ | `database` | Dolt, sqlite, mysql, postgres queries |
152
+ | `network` | `fetch`, `axios`, `http.get`, any outbound HTTP/socket call |
153
+ | `registry` | npm/package registry scans, fleet-config reads |
154
+ | `os` | System-level state not covered by the above (env vars, `/proc`, sysctl) |
155
+
156
+ **Omit the field (or leave it empty) only for purely-algorithmic modules** where you also omit `## Runtime Probes` — parse/format/sort/score/calculate transforms, type-only refactors, documentation edits, build-config changes, and unit-test-only stories.
157
+
117
158
  ### Probe YAML shape
118
159
 
119
160
  Declare probes as a YAML list inside a single fenced `yaml` block directly under the `## Runtime Probes` heading. Each entry has this shape: