substrate-ai 0.19.2 → 0.19.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,9 +4,46 @@
4
4
 
5
5
  # Substrate
6
6
 
7
- Most multi-agent coding tools help you run AI sessions in parallel — but leave planning, quality control, and learning up to you. Substrate is different: it packages structured planning methodology, multi-agent parallel execution, automated code review cycles, and self-improvement into a single pipeline. Describe your project concept, and Substrate takes it from analysis through implementation and review coordinating multiple AI coding agents (Claude Code, Codex, Gemini CLI) across isolated worktree branches while a supervisor watches for stalls, auto-recovers, and after each run experiments with improvements to close the loop automatically.
7
+ Substrate is an autonomous software development pipeline, operated by your AI coding assistant. Install it, initialize your project, and tell Claude what to buildSubstrate handles the rest.
8
8
 
9
- Unlike API-based orchestrators, Substrate routes work through the CLI tools you already have installed, maximizing your existing AI subscriptions before falling back to pay-per-token billing. Runs are persistent and resumable with full cost visibility across every provider.
9
+ Most multi-agent coding tools help you run AI sessions in parallel but leave planning, quality control, and learning up to you. Substrate is different: it packages structured planning methodology, multi-agent parallel execution, automated code review cycles, and self-improvement into a single pipeline. Describe your project concept, and Substrate takes it from research through implementation and review — coordinating multiple AI coding agents across isolated worktree branches while a supervisor watches for stalls, auto-recovers, and experiments with improvements to close the loop.
10
+
11
+ ## How It Works
12
+
13
+ Substrate operates through a three-layer interaction model:
14
+
15
+ ```
16
+ ┌─────────────────────────────────────────────────────────────────┐
17
+ │ You │
18
+ │ "Implement stories 7-1 through 7-5" │
19
+ │ ↓ │
20
+ │ Your AI Assistant (Claude Code / Codex / Gemini) │
21
+ │ Invokes substrate CLI, parses structured events, reacts │
22
+ │ ↓ │
23
+ │ Substrate │
24
+ │ Dispatches work to worker agents in parallel worktrees │
25
+ │ Manages quality gates, review cycles, stall recovery │
26
+ └─────────────────────────────────────────────────────────────────┘
27
+ ```
28
+
29
+ **You talk to your AI assistant. Your assistant talks to Substrate. Substrate orchestrates everything.**
30
+
31
+ Here's what that looks like in practice:
32
+
33
+ ```
34
+ You: "Implement stories 7-1 through 7-5"
35
+
36
+ Claude Code: runs `substrate run --events --stories 7-1,7-2,7-3,7-4,7-5`
37
+
38
+ Substrate: dispatches 5 stories across 3 agents in parallel worktrees
39
+ → story 7-1: dev complete, code review: SHIP_IT ✓
40
+ → story 7-2: dev complete, code review: NEEDS_MINOR_FIXES → auto-fix → SHIP_IT ✓
41
+ → story 7-3: escalated (interface conflict) → Claude asks you what to do
42
+ → story 7-4: dev complete, code review: SHIP_IT ✓
43
+ → story 7-5: dev complete, code review: SHIP_IT ✓
44
+
45
+ Claude Code: "4 succeeded, 1 escalated — here's the interface conflict in 7-3..."
46
+ ```
10
47
 
11
48
  ## Prerequisites
12
49
 
@@ -19,115 +56,134 @@ Unlike API-based orchestrators, Substrate routes work through the CLI tools you
19
56
 
20
57
  ## Quick Start
21
58
 
22
- ### Install
23
-
24
- Install globally and initialize in your project:
59
+ ### Install and Initialize
25
60
 
26
61
  ```bash
27
62
  npm install -g substrate-ai
63
+ cd your-project
28
64
  substrate init
29
65
  ```
30
66
 
31
- Or as a project dependency:
67
+ This does three things:
68
+ 1. **Generates `.substrate/config.yaml`** — provider routing, concurrency, budgets
69
+ 2. **Injects a `## Substrate Pipeline` section into CLAUDE.md** — behavioral directives that teach your AI assistant how to operate the pipeline
70
+ 3. **Creates `.claude/commands/` slash commands** — `/substrate-run`, `/substrate-supervisor`, `/substrate-metrics`
32
71
 
33
- ```bash
34
- npm install substrate-ai
35
- npx substrate init
36
- ```
37
-
38
- This scaffolds CLAUDE.md with behavioral directives and generates `.claude/commands/` slash commands. Claude Code reads these on session start and knows how to operate the pipeline automatically.
72
+ ### Run From Your AI Assistant
39
73
 
40
- ### Use Substrate From Claude
41
-
42
- Start a Claude Code session in your project. Claude automatically sees the substrate instructions and slash commands. From there:
74
+ Start a Claude Code session in your project. Claude automatically reads the substrate instructions from CLAUDE.md and knows how to operate the pipeline. From there:
43
75
 
44
76
  - **"Run the substrate pipeline"** — Claude runs the full lifecycle from analysis through implementation
45
77
  - **"Run substrate for stories 7-1, 7-2, 7-3"** — Claude implements specific stories
46
78
  - **"/substrate-run"** — invoke the slash command directly for a guided pipeline run
47
- - **"/substrate-supervisor"** — launch the supervisor to monitor, recover stalls, and run experiments
48
79
 
49
80
  Claude parses structured events, handles escalations, offers to fix review issues, and summarizes results. You stay in control — Claude always asks before re-running failed stories or applying fixes.
50
81
 
51
82
  ### Monitor and Self-Improve
52
83
 
53
- While the pipeline runs (or after it finishes), tell Claude in the same or a separate session:
84
+ While the pipeline runs (or after it finishes):
54
85
 
55
- > "Run the substrate supervisor with experiments"
86
+ > "Run the substrate supervisor"
56
87
 
57
- The supervisor watches the pipeline, kills stalls, and auto-restarts. When the run completes, it analyzes what happened — bottlenecks, token waste, slow stories — then runs A/B experiments on prompts and config in isolated worktrees. Improvements get auto-PRed; regressions get discarded.
88
+ The supervisor watches the pipeline, kills stalls, and auto-restarts. When the run completes, it analyzes what happened — bottlenecks, token waste, slow stories — then optionally runs A/B experiments on prompts and config in isolated worktrees. Improvements get auto-PRed; regressions get discarded.
58
89
 
59
- Later, ask Claude to compare runs:
90
+ This is the full loop: **run → watch → analyze → experiment → improve.**
60
91
 
61
- > "Compare the last two substrate runs"
92
+ ### Run From the CLI Directly
62
93
 
63
- This is the full loop: run watch analyze → experiment → improve.
94
+ You can also run substrate directly from the terminal:
64
95
 
65
- ### Pick Up an Existing BMAD Project
96
+ ```bash
97
+ # Full pipeline with NDJSON event stream
98
+ substrate run --events
66
99
 
67
- Already have a project with BMAD artifacts (from vanilla BMAD, the Beads-based ai-toolkit, or any other tool)? Substrate can pick up the remaining implementation work from inside a Claude Code session.
100
+ # Specific stories
101
+ substrate run --events --stories 7-1,7-2,7-3
68
102
 
69
- **What Substrate needs from your project:**
103
+ # Human-readable progress output (default)
104
+ substrate run
105
+ ```
70
106
 
71
- | File | Required? | Purpose |
72
- |------|-----------|---------|
73
- | `_bmad-output/planning-artifacts/epics.md` | Yes | Parsed into per-epic context shards |
74
- | `_bmad-output/planning-artifacts/architecture.md` | Yes | Tech stack and constraints for agents |
75
- | `_bmad-output/implementation-artifacts/*.md` | Optional | Existing story files — Substrate skips create-story for any it finds |
76
- | `package.json` | Optional | Test framework detection |
107
+ ## The Pipeline
77
108
 
78
- After the same install + init from [Quick Start](#quick-start), start a Claude Code session and tell it what to do:
109
+ When you tell Substrate to build something, it runs through up to six phases auto-detecting which phase to start from based on what artifacts already exist:
79
110
 
80
- > "Run the substrate pipeline to implement the remaining stories."
111
+ ### Full Lifecycle (from concept)
81
112
 
82
- Claude reads the CLAUDE.md scaffold, discovers the substrate commands, and drives the pipeline implementing stories, handling code review cycles, and summarizing results. You stay in the loop for escalations and failed stories.
113
+ 1. **Research**technology stack research, keyword extraction (optional)
114
+ 2. **Analysis** — processes concept into structured product brief with problem statement, target users, core features
115
+ 3. **Planning** — breaks product brief into epics and stories
116
+ 4. **Solutioning** — technical architecture design with constraints, tech stack, design decisions
117
+ 5. **Implementation** — parallel story execution (see below)
118
+ 6. **Contract Verification** — post-sprint validation of cross-story interfaces
83
119
 
84
- Substrate reads one directory — `_bmad-output/` — and doesn't care which tool created it. It does not read `sprint-status.yaml` or `.beads/` — you decide what's left by choosing which story keys to pass.
120
+ ### Per-Story Implementation
85
121
 
86
- ## Supported Worker Agents
122
+ Each story flows through a quality-gated loop:
87
123
 
88
- Substrate dispatches work to CLI-based AI agents running as child processes. It never calls LLMs directly — all implementation, code review, and story generation is delegated to these worker agents.
124
+ ```
125
+ create-story → dev-story → build-verify → code-review
126
+
127
+ SHIP_IT → done ✓
128
+ NEEDS_MINOR_FIXES → auto-fix → code-review
129
+ NEEDS_MAJOR_REWORK → rework → code-review
130
+ max cycles exceeded → escalated ⚠
131
+ ```
89
132
 
90
- | Agent ID | CLI Tool | Billing |
91
- |----------|----------|---------|
92
- | `claude-code` | [Claude Code](https://docs.anthropic.com/en/docs/claude-code) | Subscription (Max) or API key |
93
- | `codex` | [Codex CLI](https://github.com/openai/codex) | Subscription (ChatGPT Plus/Pro) or API key |
94
- | `gemini` | Gemini CLI | Subscription or API key |
133
+ Stories run in parallel across your available agents, each in its own git worktree. Build verification catches compilation errors before code review. Zero-diff detection catches phantom completions. Interface change warnings flag potential cross-module impacts.
95
134
 
96
- All three agents are fully supported as worker targets. Substrate auto-discovers available agents and routes work based on adapter health checks and configuration.
135
+ ### Already Have Planning Artifacts?
97
136
 
98
- ## Pipeline Observability
137
+ If your project already has BMAD artifacts (from any tool), Substrate skips straight to implementation:
99
138
 
100
- Substrate provides multiple output modes for monitoring pipeline execution.
139
+ | File | Required? | Purpose |
140
+ |------|-----------|---------|
141
+ | `_bmad-output/planning-artifacts/epics.md` | Yes | Parsed into per-epic context shards |
142
+ | `_bmad-output/planning-artifacts/architecture.md` | Yes | Tech stack and constraints for agents |
143
+ | `_bmad-output/implementation-artifacts/*.md` | Optional | Existing story files — Substrate skips creation for any it finds |
101
144
 
102
- ### Human-Readable Progress (default)
145
+ ## AI Agent Integration
103
146
 
104
- `substrate run` displays compact, updating progress lines with color:
147
+ Substrate is designed to be operated by AI agents, not just humans. Three mechanisms teach agents how to interact with the pipeline at runtime:
105
148
 
106
- ```
107
- substrate run — 6 stories, concurrency 3
149
+ ### CLAUDE.md Scaffold
150
+
151
+ `substrate init` injects a `## Substrate Pipeline` section into your project's CLAUDE.md with:
152
+
153
+ - Instructions to run `--help-agent` on first use
154
+ - Event-driven interaction patterns (escalation handling, fix offers, confirmation requirements)
155
+ - Supervisor workflow guidance
156
+ - Version stamp for detecting stale instructions after upgrades
108
157
 
109
- [create] 7-1 creating story...
110
- [dev] 7-2 implementing...
111
- [review] 7-3 SHIP_IT (1 cycle)
112
- [fix] 7-4 fixing minor issues...
113
- [done] 7-5 SHIP_IT (2 cycles)
114
- [wait] 1-9 queued
158
+ The section is wrapped in `<!-- substrate:start/end -->` markers for idempotent updates. Re-running `init` updates the substrate section while preserving all other CLAUDE.md content.
115
159
 
116
- Pipeline complete: 5 succeeded, 0 failed, 1 escalated
160
+ ### Self-Describing CLI (`--help-agent`)
161
+
162
+ ```bash
163
+ substrate run --help-agent
117
164
  ```
118
165
 
119
- - **TTY mode**: ANSI cursor control for in-place line updates
120
- - **Non-TTY mode**: plain text, one line per update (CI-friendly)
121
- - Respects `NO_COLOR` environment variable
122
- - Pino JSON logs suppressed by default — use `--verbose` to restore them
166
+ Outputs a machine-optimized prompt fragment (<2000 tokens) that an AI agent can ingest as a system prompt. Generated from the same TypeScript type definitions as the event emitter, so documentation never drifts from implementation. Includes:
123
167
 
124
- ### NDJSON Event Protocol (`--events`)
168
+ - All available commands and flags with examples
169
+ - Capabilities manifest — installed version, available engines, configured providers, active features
170
+ - Complete event protocol schema
171
+ - Decision flowchart for handling each event type
172
+
173
+ ### Slash Commands
125
174
 
126
- For programmatic consumption, `--events` emits newline-delimited JSON events on stdout:
175
+ `substrate init` generates `.claude/commands/` slash commands:
176
+
177
+ - `/substrate-run` — Start or resume a pipeline run with structured events
178
+ - `/substrate-supervisor` — Launch the supervisor monitor with stall detection and auto-restart
179
+ - `/substrate-metrics` — Query run history, compare runs, and read analysis reports
180
+
181
+ ### NDJSON Event Protocol
182
+
183
+ With `--events`, Substrate emits newline-delimited JSON events on stdout for programmatic consumption:
127
184
 
128
185
  ```bash
129
186
  substrate run --events
130
- substrate run --events --stories 7-1,7-2
131
187
  ```
132
188
 
133
189
  Event types form a discriminated union on the `type` field:
@@ -137,15 +193,15 @@ Event types form a discriminated union on the `type` field:
137
193
  | `pipeline:start` | Pipeline begins — includes `run_id`, `stories[]`, `concurrency` |
138
194
  | `pipeline:complete` | Pipeline ends — includes `succeeded[]`, `failed[]`, `escalated[]` |
139
195
  | `story:phase` | Story transitions between phases (`create-story`, `dev-story`, `code-review`, `fix`) |
140
- | `story:done` | Story reaches terminal success state with `review_cycles` count |
141
- | `story:escalation` | Story escalated after exhausting review cycles — includes issue list with severities |
196
+ | `story:done` | Story reaches terminal state with `review_cycles` count |
197
+ | `story:escalation` | Story escalated — includes issue list with severities |
198
+ | `story:metrics` | Per-story wall-clock time, token counts, phase breakdown |
142
199
  | `story:warn` | Non-fatal warning (e.g., token ceiling truncation) |
143
- | `story:log` | Informational progress message |
144
- | `supervisor:*` | Supervisor lifecycle events — `kill`, `restart`, `abort`, `summary` |
145
- | `supervisor:analysis:*` | Post-run analysis events — `complete`, `error` |
146
- | `supervisor:experiment:*` | Experiment loop events — `start`, `skip`, `recommendations`, `complete`, `error` |
200
+ | `pipeline:heartbeat` | Periodic heartbeat with active/completed/queued dispatch counts |
201
+ | `supervisor:*` | Supervisor lifecycle — `poll`, `kill`, `restart`, `abort`, `summary` |
202
+ | `supervisor:experiment:*` | Experiment loop — `start`, `recommendations`, `complete`, `error` |
147
203
 
148
- All events carry a `ts` (ISO-8601 timestamp) field. The full TypeScript types are exported from the package:
204
+ All events carry a `ts` (ISO-8601 timestamp) field. Full TypeScript types are exported:
149
205
 
150
206
  ```typescript
151
207
  import type { PipelineEvent, StoryEscalationEvent } from 'substrate-ai'
@@ -158,129 +214,264 @@ if (event.type === 'story:escalation') {
158
214
  }
159
215
  ```
160
216
 
161
- ## AI Agent Integration
217
+ ## Supported Worker Agents
162
218
 
163
- Substrate is designed to be operated by AI agents, not just humans. Three mechanisms teach agents how to interact with the pipeline at runtime:
219
+ Substrate dispatches work to CLI-based AI agents running as child processes. It never calls LLMs directly all implementation, code review, and story generation is delegated to worker agents.
164
220
 
165
- ### Self-Describing CLI (`--help-agent`)
221
+ | Agent ID | CLI Tool | Billing |
222
+ |----------|----------|---------|
223
+ | `claude-code` | [Claude Code](https://docs.anthropic.com/en/docs/claude-code) | Subscription (Max) or API key |
224
+ | `codex` | [Codex CLI](https://github.com/openai/codex) | Subscription (ChatGPT Plus/Pro) or API key |
225
+ | `gemini` | Gemini CLI | Subscription or API key |
226
+
227
+ Substrate auto-discovers available agents at startup and routes work based on adapter health checks and your routing configuration. Unlike API-based orchestrators, Substrate routes work through the CLI tools you already have installed, maximizing your existing AI subscriptions before falling back to pay-per-token billing.
228
+
229
+ ## Observability and Self-Improvement
230
+
231
+ ### Pipeline Monitoring
166
232
 
167
233
  ```bash
168
- substrate run --help-agent
234
+ # Human-readable progress (default)
235
+ substrate run
236
+ # Shows compact, updating progress lines:
237
+ # [dev] 7-2 implementing...
238
+ # [review] 7-3 SHIP_IT (1 cycle)
239
+ # [done] 7-5 SHIP_IT (2 cycles)
240
+
241
+ # Real-time health check
242
+ substrate health --output-format json
243
+
244
+ # Poll status
245
+ substrate status --output-format json
169
246
  ```
170
247
 
171
- Outputs a machine-optimized markdown prompt fragment (<2000 tokens) that an AI agent can ingest as a system prompt. Generated from the same TypeScript type definitions as the event emitter, so documentation never drifts from implementation. Includes:
248
+ - **TTY mode**: ANSI cursor control for in-place line updates
249
+ - **Non-TTY mode**: plain text, one line per update (CI-friendly)
250
+ - Respects `NO_COLOR` environment variable
172
251
 
173
- - All available commands and flags with examples
174
- - Complete event protocol schema
175
- - Decision flowchart for handling each event type
176
- - Version stamp for detecting stale cached instructions
252
+ ### Supervisor
177
253
 
178
- ### CLAUDE.md Scaffold
254
+ The supervisor is a long-running monitor that watches pipeline health:
179
255
 
180
- `substrate init` injects a `## Substrate Pipeline` section into your project's CLAUDE.md with behavioral directives for Claude Code:
256
+ ```bash
257
+ substrate supervisor --output-format json
258
+ ```
181
259
 
182
- - Instructions to run `--help-agent` on first use
183
- - Event-driven interaction patterns (escalation handling, fix offers, confirmation requirements)
184
- - Supervisor workflow guidance (when to use `run` vs `supervisor` vs `supervisor --experiment`)
185
- - Section is wrapped in `<!-- substrate:start/end -->` markers for idempotent updates
186
- - Re-running `init` updates the substrate section while preserving all other CLAUDE.md content
260
+ - Detects stalled agents (configurable threshold)
261
+ - Kills stuck process trees and auto-restarts via `resume`
262
+ - Emits structured events for each action taken
187
263
 
188
- ### Slash Commands
264
+ ### Self-Improvement Loop
189
265
 
190
- `substrate init` also generates `.claude/commands/` slash commands that Claude Code can invoke directly:
266
+ ```bash
267
+ substrate supervisor --experiment --output-format json
268
+ ```
191
269
 
192
- - `/substrate-run` — Start or resume a pipeline run with structured events
193
- - `/substrate-supervisor` Launch the supervisor monitor with stall detection and auto-restart
194
- - `/substrate-metrics`Query run history, compare runs, and read analysis reports
270
+ After the pipeline completes, the supervisor:
271
+ 1. **Analyzes** the run identifies bottlenecks, token waste, slow stories
272
+ 2. **Generates recommendations** prompt tweaks, config changes, routing adjustments
273
+ 3. **Runs A/B experiments** — applies each recommendation in an isolated worktree, re-runs affected stories, compares metrics
274
+ 4. **Verdicts**: IMPROVED changes are kept, REGRESSED changes are discarded
275
+
276
+ ### Metrics and Cost Tracking
277
+
278
+ ```bash
279
+ # Historical run metrics
280
+ substrate metrics --output-format json
281
+
282
+ # Compare two runs side-by-side
283
+ substrate metrics --compare <run-a>,<run-b>
284
+
285
+ # Read analysis report
286
+ substrate metrics --analysis <run-id> --output-format json
287
+
288
+ # Cost breakdown
289
+ substrate cost --output-format json
290
+ ```
291
+
292
+ ## Software Factory (Advanced)
293
+
294
+ Beyond the linear SDLC pipeline, Substrate includes a graph-based execution engine and autonomous quality system:
295
+
296
+ ### Graph Engine
297
+
298
+ ```bash
299
+ substrate run --engine graph --events
300
+ ```
301
+
302
+ The graph engine reads pipeline topology from DOT files (Graphviz format), enabling:
303
+ - Conditional edges (retry loops, branching on review verdict)
304
+ - Parallel fan-out/fan-in with configurable join policies
305
+ - LLM-evaluated edge conditions
306
+ - Subgraph composition with depth guards
307
+ - Custom pipeline templates
308
+
309
+ ### Scenario-Based Validation
310
+
311
+ Instead of (or alongside) code review, define external test scenarios that the agent can't game:
312
+
313
+ ```bash
314
+ substrate factory scenarios list
315
+ substrate factory scenarios run
316
+ ```
195
317
 
196
- These commands encode the recommended invocation patterns so Claude uses the right flags without needing to memorize them.
318
+ - **Scenario Store**: SHA-256 manifests for integrity verification
319
+ - **Satisfaction Scoring**: weighted composite of scenario pass rate, performance, complexity
320
+ - **Convergence Loops**: iterate until satisfaction threshold met, with plateau detection and budget controls
197
321
 
198
- ## Commands
322
+ ### Quality Modes
199
323
 
200
- These commands are invoked by AI agents (Claude Code, Codex, Gemini CLI) during pipeline operation. You typically don't run them directly — you tell your agent what to do and it selects the right command.
324
+ Configure how stories are validated via `.substrate/config.yaml`:
325
+
326
+ | Mode | Description |
327
+ |------|-------------|
328
+ | `code-review` | Traditional — code review verdict drives the gate (default) |
329
+ | `dual-signal` | Both scenario satisfaction and code review required |
330
+ | `scenario-primary` | Satisfaction score is authoritative |
331
+ | `scenario-only` | Satisfaction only; code review skipped |
332
+
333
+ ### Digital Twins
334
+
335
+ Docker Compose-managed services for external validation environments:
336
+
337
+ ```bash
338
+ substrate factory twins up
339
+ substrate factory twins status
340
+ substrate factory twins down
341
+ ```
342
+
343
+ ## Configuration
344
+
345
+ Substrate reads configuration from `.substrate/config.yaml` in your project root. Run `substrate init` to generate defaults.
346
+
347
+ ### Key Configuration
348
+
349
+ ```yaml
350
+ config_format_version: '1'
351
+
352
+ global:
353
+ log_level: info
354
+ max_concurrent_tasks: 4 # Parallel story limit
355
+ budget_cap_usd: 0 # 0 = unlimited
356
+
357
+ providers:
358
+ claude:
359
+ enabled: true
360
+ max_concurrent: 2
361
+ rate_limit:
362
+ tokens: 220000
363
+ window_seconds: 18000
364
+
365
+ # Optional: per-workflow token limits
366
+ token_ceilings:
367
+ dev-story: 200000
368
+ code-review: 150000
369
+
370
+ # Optional: dispatch timeout overrides (ms)
371
+ dispatch_timeouts:
372
+ dev-story: 1800000 # 30 min
373
+ ```
374
+
375
+ ### Configuration Files
376
+
377
+ | File | Purpose |
378
+ |------|---------|
379
+ | `.substrate/config.yaml` | Provider routing, concurrency, budgets, quality mode |
380
+ | `.substrate/project-profile.yaml` | Auto-detected build system, language, test framework |
381
+ | `.substrate/routing-policy.yaml` | Task-to-provider routing rules |
382
+ | `CLAUDE.md` | Agent scaffold with substrate instructions |
383
+ | `.claude/commands/` | Slash commands for Claude Code |
384
+
385
+ ### Versioned State Backend (Optional)
386
+
387
+ Substrate supports [Dolt](https://www.dolthub.com/) for versioned pipeline state:
388
+
389
+ ```bash
390
+ substrate init --dolt
391
+ ```
392
+
393
+ This enables:
394
+ - `substrate diff <story>` — row-level state changes per story
395
+ - `substrate history` — commit log of pipeline state mutations
396
+ - OTEL observability persistence
397
+ - Context engineering repo-map storage
398
+
399
+ Without Dolt, everything works using plain SQLite.
400
+
401
+ ## CLI Command Reference
402
+
403
+ These commands are invoked by AI agents during pipeline operation. You typically don't run them directly — you tell your agent what to do and it selects the right command.
201
404
 
202
405
  ### Pipeline
203
406
 
204
407
  | Command | Description |
205
408
  |---------|-------------|
206
- | `substrate brainstorm` | Interactive multi-persona ideation session |
207
- | `substrate init` | Initialize config, methodology pack, CLAUDE.md scaffold, and slash commands |
208
409
  | `substrate run` | Run the full pipeline (analysis → implement) |
209
410
  | `substrate run --events` | Emit NDJSON event stream on stdout |
210
411
  | `substrate run --stories <keys>` | Run specific stories (e.g., `7-1,7-2`) |
211
412
  | `substrate run --from <phase>` | Start from a specific phase |
413
+ | `substrate run --engine graph` | Use the graph execution engine |
212
414
  | `substrate run --help-agent` | Print agent instruction prompt fragment and exit |
213
415
  | `substrate resume` | Resume an interrupted pipeline run |
214
416
  | `substrate status` | Show pipeline run status |
215
417
  | `substrate amend` | Run an amendment pipeline against a completed run |
418
+ | `substrate brainstorm` | Interactive multi-persona ideation session |
216
419
 
217
420
  ### Observability
218
421
 
219
422
  | Command | Description |
220
423
  |---------|-------------|
221
424
  | `substrate health` | Check pipeline health, stall detection, and process status |
222
- | `substrate supervisor` | Long-running monitor that kills stalled runs and auto-restarts |
223
- | `substrate supervisor --experiment` | Self-improvement loop: post-run analysis + A/B experiments |
425
+ | `substrate supervisor` | Long-running monitor with kill-and-restart recovery |
426
+ | `substrate supervisor --experiment` | Self-improvement: post-run analysis + A/B experiments |
224
427
  | `substrate metrics` | Historical pipeline run metrics |
225
428
  | `substrate metrics --compare <a,b>` | Side-by-side comparison of two runs |
226
429
  | `substrate metrics --analysis <run-id>` | Read the analysis report for a specific run |
227
430
  | `substrate monitor status` | View agent performance metrics |
228
- | `substrate monitor report` | Generate a detailed performance report |
229
- | `substrate monitor recommendations` | Display routing recommendations from performance data |
230
431
  | `substrate cost` | View cost and token usage summary |
231
432
 
232
- ### Export & Sharing
433
+ ### Export and Sharing
233
434
 
234
435
  | Command | Description |
235
436
  |---------|-------------|
236
- | `substrate export` | Export planning artifacts (product brief, PRD, architecture, epics) as markdown |
437
+ | `substrate export` | Export planning artifacts as markdown |
237
438
  | `substrate export --run-id <id>` | Export artifacts from a specific pipeline run |
238
- | `substrate export --output-dir <dir>` | Write to a custom directory (default: `_bmad-output/planning-artifacts/`) |
239
- | `substrate export --output-format json` | Emit JSON result to stdout for agent consumption |
439
+ | `substrate export --output-format json` | Emit JSON result for agent consumption |
240
440
 
241
441
  ### Worktree Management
242
442
 
243
443
  | Command | Description |
244
444
  |---------|-------------|
245
- | `substrate merge` | Detect conflicts and merge task worktree branches into the target branch |
246
- | `substrate worktrees` | List all active git worktrees and their associated tasks |
445
+ | `substrate merge` | Detect conflicts and merge worktree branches into target |
446
+ | `substrate worktrees` | List active git worktrees and their tasks |
247
447
 
248
448
  ### Setup
249
449
 
250
450
  | Command | Description |
251
451
  |---------|-------------|
452
+ | `substrate init` | Initialize config, CLAUDE.md scaffold, and slash commands |
252
453
  | `substrate adapters` | List and check available AI agent adapters |
253
454
  | `substrate config` | Show, set, export, or import configuration |
254
455
  | `substrate upgrade` | Check for updates and upgrade to the latest version |
255
- | `substrate --help` | Show all available commands |
256
-
257
- ## Configuration
258
-
259
- Substrate reads configuration from `.substrate/config.yaml` in your project root. Run `substrate init` to generate a default config.
260
456
 
261
457
  ## Development
262
458
 
263
459
  ```bash
264
- # Clone and install
265
460
  git clone https://github.com/johnplanow/substrate.git
266
461
  cd substrate
267
462
  npm install
268
-
269
- # Build
270
463
  npm run build
271
-
272
- # Run tests
273
464
  npm test
465
+ ```
274
466
 
275
- # Development mode (watch)
276
- npm run dev
277
-
278
- # Type check
279
- npm run typecheck
467
+ ### Monorepo Structure
280
468
 
281
- # Lint
282
- npm run lint
283
- ```
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 |
284
475
 
285
476
  ## License
286
477
 
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, EXPERIMENT_RESULT, 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, getSessionCostSummary, getSessionCostSummaryFiltered, getStoryMetricsForRun, getTokenUsageSummary, incrementRunRestarts, initSchema, initializeDolt, listRequirements, listRunMetrics, loadParentRunDecisions, supersedeDecision, tagRunAsBaseline, updatePipelineRun } from "../dist-Bm0qSZer.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, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-BOhSIujp.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, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runSolutioningPhase, validateStopAfterFromConflict } from "../run-Ch7k7HEu.js";
8
8
  import "../errors-BSpu7pIv.js";
9
9
  import "../routing-CcBOCuC9.js";
10
10
  import "../decisions-C0pz9Clx.js";
@@ -1605,6 +1605,26 @@ function buildStackAwareDevNotes(profile) {
1605
1605
  //#region src/cli/commands/init.ts
1606
1606
  const logger$15 = createLogger("init");
1607
1607
  const __dirname = dirname(new URL(import.meta.url).pathname);
1608
+ const SCAFFOLD_VERSION_REGEX = /<!-- substrate:version=([\d.]+) -->/;
1609
+ /**
1610
+ * Read the substrate package version from package.json at the given root.
1611
+ */
1612
+ function readSubstrateVersion(pkgRoot) {
1613
+ try {
1614
+ const pkg = JSON.parse(readFileSync$1(join(pkgRoot, "package.json"), "utf8"));
1615
+ return pkg.version ?? "0.0.0";
1616
+ } catch {
1617
+ return "0.0.0";
1618
+ }
1619
+ }
1620
+ /**
1621
+ * Extract the version stamped in an existing CLAUDE.md scaffold section.
1622
+ * Returns null if no version stamp found.
1623
+ */
1624
+ function extractScaffoldVersion(content) {
1625
+ const match = SCAFFOLD_VERSION_REGEX.exec(content);
1626
+ return match?.[1] ?? null;
1627
+ }
1608
1628
  const INIT_EXIT_SUCCESS = 0;
1609
1629
  const INIT_EXIT_ERROR = 1;
1610
1630
  const BMAD_FRAMEWORK_DIRS = [
@@ -1671,6 +1691,8 @@ async function scaffoldClaudeMd(projectRoot, profile) {
1671
1691
  logger$15.warn({ templatePath }, "CLAUDE.md substrate section template not found; skipping");
1672
1692
  return;
1673
1693
  }
1694
+ const substrateVersion = readSubstrateVersion(pkgRoot);
1695
+ sectionContent = sectionContent.replace("{{SUBSTRATE_VERSION}}", substrateVersion);
1674
1696
  if (!sectionContent.endsWith("\n")) sectionContent += "\n";
1675
1697
  const devNotesSection = buildStackAwareDevNotes(profile ?? null);
1676
1698
  let existingContent = "";
@@ -1684,8 +1706,11 @@ async function scaffoldClaudeMd(projectRoot, profile) {
1684
1706
  else newContent = sectionContent;
1685
1707
  else {
1686
1708
  let updatedExisting;
1687
- if (existingContent.includes(CLAUDE_MD_START_MARKER)) updatedExisting = existingContent.replace(new RegExp(`${CLAUDE_MD_START_MARKER.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[\\s\\S]*?${CLAUDE_MD_END_MARKER.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`), sectionContent.trimEnd());
1688
- else {
1709
+ if (existingContent.includes(CLAUDE_MD_START_MARKER)) {
1710
+ const existingVersion = extractScaffoldVersion(existingContent);
1711
+ if (existingVersion && existingVersion !== substrateVersion) process.stderr.write(`Updating CLAUDE.md substrate scaffold from v${existingVersion} → v${substrateVersion}\n`);
1712
+ updatedExisting = existingContent.replace(new RegExp(`${CLAUDE_MD_START_MARKER.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[\\s\\S]*?${CLAUDE_MD_END_MARKER.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`), sectionContent.trimEnd());
1713
+ } else {
1689
1714
  const separator = existingContent.endsWith("\n") ? "\n" : "\n\n";
1690
1715
  updatedExisting = existingContent + separator + sectionContent;
1691
1716
  }
@@ -4522,7 +4547,7 @@ async function runSupervisorAction(options, deps = {}) {
4522
4547
  await initSchema(expAdapter);
4523
4548
  const { runRunAction: runPipeline } = await import(
4524
4549
  /* @vite-ignore */
4525
- "../run-CCHb_JMl.js"
4550
+ "../run-d2qnKgPF.js"
4526
4551
  );
4527
4552
  const runStoryFn = async (opts) => {
4528
4553
  const exitCode = await runPipeline({
@@ -1,4 +1,5 @@
1
1
  <!-- substrate:start -->
2
+ <!-- substrate:version={{SUBSTRATE_VERSION}} -->
2
3
  ## Substrate Pipeline
3
4
 
4
5
  This project uses Substrate for automated implementation pipelines. **When the user asks you to implement, build, or run the pipeline — go straight to running substrate. Do NOT explore the codebase, read source files, or plan the implementation yourself.** Substrate orchestrates sub-agents that handle all of that.
@@ -18,8 +18,9 @@ import { existsSync as existsSync$1, lstatSync, mkdirSync as mkdirSync$1, readFi
18
18
  import { promisify } from "node:util";
19
19
  import { createRequire } from "node:module";
20
20
  import { fileURLToPath } from "node:url";
21
+ import { execFile as execFile$1, spawn as spawn$1 } from "child_process";
22
+ import { promisify as promisify$1 } from "util";
21
23
  import { createHash as createHash$1 } from "crypto";
22
- import { spawn as spawn$1 } from "child_process";
23
24
  import * as readline from "readline";
24
25
  import Stream from "node:stream";
25
26
  import { StringDecoder } from "node:string_decoder";
@@ -660,6 +661,7 @@ function createProgressRenderer(stream$1, isTTY) {
660
661
 
661
662
  //#endregion
662
663
  //#region src/cli/commands/help-agent.ts
664
+ const execFileAsync = promisify$1(execFile$1);
663
665
  /**
664
666
  * Metadata object mirroring all PipelineEvent discriminated union members.
665
667
  * This is the runtime source of truth for the --help-agent output.
@@ -1801,15 +1803,81 @@ Patterns for \`substrate supervisor --output-format json\` events:
1801
1803
  `;
1802
1804
  }
1803
1805
  /**
1806
+ * Generate the capabilities manifest section.
1807
+ */
1808
+ function generateCapabilitiesSection(caps) {
1809
+ const lines = ["## Capabilities", ""];
1810
+ lines.push(`Substrate version: ${caps.version}`);
1811
+ lines.push(`Engines: ${caps.engines.join(", ")}`);
1812
+ lines.push("");
1813
+ lines.push("Providers:");
1814
+ for (const p of caps.providers) lines.push(`- ${p.name}: ${p.available ? "available" : "not found"}`);
1815
+ lines.push("");
1816
+ lines.push(`Quality mode: ${caps.qualityMode}`);
1817
+ lines.push(`Factory features: ${caps.factoryEnabled ? "enabled" : "disabled"}`);
1818
+ lines.push(`Dolt (versioned state): ${caps.doltAvailable ? "available" : "not installed"}`);
1819
+ lines.push("");
1820
+ return lines.join("\n");
1821
+ }
1822
+ /**
1823
+ * Probe the local environment for capabilities.
1824
+ */
1825
+ async function probeCapabilities(version) {
1826
+ const providerChecks = [
1827
+ "claude",
1828
+ "codex",
1829
+ "gemini"
1830
+ ].map(async (name) => {
1831
+ try {
1832
+ await execFileAsync("which", [name]);
1833
+ return {
1834
+ name,
1835
+ available: true
1836
+ };
1837
+ } catch {
1838
+ return {
1839
+ name,
1840
+ available: false
1841
+ };
1842
+ }
1843
+ });
1844
+ const providers = await Promise.all(providerChecks);
1845
+ let doltAvailable = false;
1846
+ try {
1847
+ await execFileAsync("which", ["dolt"]);
1848
+ doltAvailable = true;
1849
+ } catch {}
1850
+ let qualityMode = "code-review";
1851
+ let factoryEnabled = false;
1852
+ try {
1853
+ const configPath = join(process.cwd(), ".substrate", "config.yaml");
1854
+ await access(configPath);
1855
+ const configText = await readFile(configPath, "utf-8");
1856
+ const qmMatch = /quality_mode:\s*['"]?(\S+?)['"]?\s*$/m.exec(configText);
1857
+ if (qmMatch) qualityMode = qmMatch[1];
1858
+ const factoryMatch = /^\s*factory:/m.exec(configText);
1859
+ if (factoryMatch) factoryEnabled = true;
1860
+ } catch {}
1861
+ return {
1862
+ version,
1863
+ engines: ["linear", "graph"],
1864
+ providers,
1865
+ factoryEnabled,
1866
+ qualityMode,
1867
+ doltAvailable
1868
+ };
1869
+ }
1870
+ /**
1804
1871
  * Generate the complete help-agent prompt fragment.
1805
1872
  */
1806
- function generateHelpAgentOutput(version, events = PIPELINE_EVENT_METADATA) {
1873
+ function generateHelpAgentOutput(version, events = PIPELINE_EVENT_METADATA, capabilities) {
1807
1874
  const lines = [];
1808
1875
  lines.push("# Substrate Pipeline — Agent Instructions");
1809
1876
  lines.push(`Version: ${version}`);
1810
1877
  lines.push("");
1811
1878
  lines.push("This document is a machine-optimized instruction fragment for AI agents operating the Substrate pipeline. Ingest it as a system prompt fragment to understand commands, event protocol, and interaction patterns.");
1812
1879
  lines.push("");
1880
+ if (capabilities) lines.push(generateCapabilitiesSection(capabilities));
1813
1881
  lines.push(generateCommandReferenceSection());
1814
1882
  lines.push(generateEventSchemaSection(events));
1815
1883
  lines.push(generateInteractionPatternsSection());
@@ -1820,7 +1888,8 @@ function generateHelpAgentOutput(version, events = PIPELINE_EVENT_METADATA) {
1820
1888
  */
1821
1889
  async function runHelpAgent() {
1822
1890
  const version = await resolvePackageVersion();
1823
- const output = generateHelpAgentOutput(version);
1891
+ const capabilities = await probeCapabilities(version);
1892
+ const output = generateHelpAgentOutput(version, PIPELINE_EVENT_METADATA, capabilities);
1824
1893
  process.stdout.write(output + "\n");
1825
1894
  return 0;
1826
1895
  }
@@ -14370,7 +14439,7 @@ async function runSteps(steps, deps, runId, phase, params) {
14370
14439
  prompt = prompt.replace(`{{${ref.placeholder}}}`, value);
14371
14440
  }
14372
14441
  const allDecisions = await getDecisionsByPhaseForRun(deps.db, runId, phase);
14373
- const budgetTokens = calculateDynamicBudget(4e3, allDecisions.length);
14442
+ const budgetTokens = calculateDynamicBudget(8e3, allDecisions.length);
14374
14443
  let estimatedTokens = Math.ceil(prompt.length / 4);
14375
14444
  if (estimatedTokens > budgetTokens) {
14376
14445
  const decisionRefs = step.context.filter((ref) => ref.source.startsWith("decision:"));
@@ -40787,4 +40856,4 @@ function registerRunCommand(program, _version = "0.0.0", projectRoot = process.c
40787
40856
 
40788
40857
  //#endregion
40789
40858
  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, registerFactoryCommand, registerRunCommand, registerScenariosCommand, resolveStoryKeys, runAnalysisPhase, runPlanningPhase, runRunAction, runSolutioningPhase, validateStopAfterFromConflict };
40790
- //# sourceMappingURL=run-BOhSIujp.js.map
40859
+ //# sourceMappingURL=run-Ch7k7HEu.js.map
@@ -2,7 +2,7 @@ import "./health-Cx2ZhRNT.js";
2
2
  import "./logger-KeHncl-f.js";
3
3
  import "./helpers-CElYrONe.js";
4
4
  import "./dist-Bm0qSZer.js";
5
- import { normalizeGraphSummaryToStatus, registerRunCommand, runRunAction } from "./run-BOhSIujp.js";
5
+ import { normalizeGraphSummaryToStatus, registerRunCommand, runRunAction } from "./run-Ch7k7HEu.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.19.2",
3
+ "version": "0.19.4",
4
4
  "description": "Substrate — multi-agent orchestration daemon for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",