valent-pipeline 0.2.25 → 0.2.26

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "valent-pipeline",
3
- "version": "0.2.25",
3
+ "version": "0.2.26",
4
4
  "description": "v3 multi-agent AI pipeline for software development lifecycle",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,127 @@
1
+ # Claude Code Runtime Adapter
2
+
3
+ > **Provider:** Claude Code Agent Teams
4
+ > **Read by:** Lead agent when `runtime.provider` is `claude-code` in `pipeline-config.yaml`
5
+ > **Purpose:** Defines HOW to create teams, spawn agents, send signals, track tasks, and monitor liveness using Claude Code's native primitives.
6
+
7
+ ---
8
+
9
+ ## Initialization
10
+
11
+ Use `TeamCreate` to create a named team for inbox routing:
12
+
13
+ - **Epic runs** (`{is_epic_run}` is true): `TeamCreate("valent-{epic_id}")` (lowercased). The team persists across stories so Knowledge Agent stays alive. If the team already exists (continuing an epic), proceed without recreating.
14
+ - **Standalone runs**: `TeamCreate("valent-{story_id}")` (lowercased).
15
+
16
+ **Clean up stale team:** If `TeamCreate` fails with an "Already leading team" error, call `TeamDelete` first, then retry. This handles cases where a prior run crashed before teardown.
17
+
18
+ **NEVER** spawn pipeline agents as anonymous subagents. Every agent must be a named teammate on the team so it can send and receive inbox messages with other teammates.
19
+
20
+ ---
21
+
22
+ ## Task Registry
23
+
24
+ Use the shared task list API to create and track tasks:
25
+
26
+ 1. **Create tasks:** For each task in the resolved task graph, call `TaskCreate` with `subject`, `description`, and `activeForm` from the template.
27
+ 2. **Wire dependencies:** For each task with `blockedBy` refs, call `TaskUpdate` with `addBlockedBy` using the mapped real task IDs. If a `blockedBy` ref is in `skipped_refs`, omit it.
28
+ 3. **Maintain ref map:** Keep a `ref -> taskId` map (e.g., `{ reqs: "1", uxa: "2", ... }`) and a `skipped_refs` set.
29
+ 4. **Read task state:** Use `TaskList` and `TaskGet` to check task statuses during monitoring.
30
+ 5. **Update status:** Use `TaskUpdate` to mark tasks `in_progress` on agent spawn and `completed` on agent handoff.
31
+
32
+ ---
33
+
34
+ ## Agent Spawning
35
+
36
+ Use the `Agent` tool with `name` parameter to spawn named teammates onto the team. Set `run_in_background: true` so agents work autonomously.
37
+
38
+ ### Spawn Pattern
39
+
40
+ 1. Read the spawn template (a short ~15-line template from `.valent-pipeline/spawn-templates/`)
41
+ 2. Substitute all `{{variables}}` with resolved values from config and the task graph
42
+ 3. Pass the filled template as the Agent tool's `prompt` parameter
43
+ 4. Set `name` to the agent's name from the manifest (e.g., `"REQS"`, `"UXA"`, `"Knowledge"`)
44
+ 5. Set `run_in_background: true`
45
+ 6. Set `model` per the `models` section in `pipeline-config.yaml` (match agent name to tier)
46
+
47
+ **DO NOT read the agent's prompt files, step files, or templates yourself.** The spawn template tells the teammate to read its own prompt and steps. Your job is ONLY to substitute variables in the template and pass it to the Agent tool.
48
+
49
+ ### Templates
50
+
51
+ - `.valent-pipeline/spawn-templates/agent-spawn.template.md` — for all agents except Knowledge
52
+ - `.valent-pipeline/spawn-templates/knowledge-spawn.template.md` — for the Knowledge Agent
53
+
54
+ ### Wave-Based Spawning
55
+
56
+ | Wave | Spawn Trigger | Agents |
57
+ |------|---------------|--------|
58
+ | 1 | At kick-off | Knowledge, REQS, UXA, QA-A, READINESS |
59
+ | 2 | QA-A sends `[HANDOFF]` | BEND, FEND, DATA, MCP-DEV, LIBDEV, DOCGEN, IAC, CRITIC (each only if not skipped) |
60
+ | 3 | CRITIC task becomes `in_progress` | QA-B, PMCP (if ui profile) |
61
+ | 4 | JUDGE bug-review task becomes `in_progress` | (reserved) |
62
+
63
+ **Pattern:** Spawn the next wave when the current blocking agent starts work, so downstream agents are initialized and ready the moment the blocker finishes.
64
+
65
+ ### Knowledge Agent (Epic Mode)
66
+
67
+ If `{is_epic_run}` is true and a Knowledge teammate already exists in the current team, skip the spawn. Instead, send `SendMessage(to: "Knowledge")`: `[STORY-RESET] story_id={story_id}, pipeline_context={story_output_dir}/pipeline-context.md`. Wait for `[KNOWLEDGE-READY]` response.
68
+
69
+ ---
70
+
71
+ ## Signal Delivery
72
+
73
+ Use `SendMessage` for all inter-agent communication. Messages are delivered to named teammate inboxes.
74
+
75
+ ### Lead Outbound Messages
76
+
77
+ - `[SPAWN] Spawning {agent} for {story_id}. Role: {role}. Shared context: {story_output_dir}.`
78
+ - `[CHECK-IN] {agent}: task {task} has been in_progress for {minutes}min. Status?`
79
+ - `[REVIEW-READY] Story {story_id}` — sent to READINESS when a story reaches `readiness-review`
80
+ - `[TEARDOWN] Tearing down all teammates for {story_id}.`
81
+ - `shutdown_request` via SendMessage to each agent individually at teardown
82
+
83
+ ### Agent-to-Agent (Peer-to-Peer)
84
+
85
+ Agents use `SendMessage` directly for:
86
+ - `[HANDOFF]` — completion signal to Lead and/or downstream agent
87
+ - `[CRITIC-REJECTION]` — CRITIC to BEND/FEND, CC Lead
88
+ - `[BUG]` — QA-B to BEND/FEND, CC Lead
89
+ - `[KNOWLEDGE-QUERY]` / `[KNOWLEDGE-RESPONSE]` — any agent to/from Knowledge
90
+ - `[DESIGN-COUNCIL]` / `[DESIGN-COUNCIL-RESPONSE]` — structured deliberation between 2-3 agents
91
+ - `[BLOCKER]` / `[ESCALATION]` — agent to Lead
92
+
93
+ ---
94
+
95
+ ## Monitoring
96
+
97
+ ### Heartbeat Timer
98
+
99
+ At the start of Phase 2, create a `CronCreate` job that fires every 4 minutes. Each heartbeat triggers a liveness check: call `TaskList`, verify at least one non-Knowledge agent is `in_progress`. If uncompleted tasks exist but no agent is working, diagnose deadlock (stale blockers, missed unblocks, dead teammates) and act.
100
+
101
+ Create a separate 4-minute keep-alive ping for the Knowledge Agent to prevent prompt cache expiry.
102
+
103
+ ### Monitoring Loop
104
+
105
+ 1. Watch for task status changes (completed, blocked, failed)
106
+ 2. Watch for wave spawn triggers (QA-A completion, CRITIC start)
107
+ 3. Watch for inbox messages ([ESCALATION], [BLOCKER], [DESIGN-COUNCIL], [STATUS])
108
+ 4. Track rejection counts per agent for circuit breaker
109
+ 5. Track time-in-progress per task for stall detection (exempt: Knowledge Agent)
110
+ 6. On every phase transition, capture timestamp and update `phase-timing.md`
111
+
112
+ ### Stall Detection
113
+
114
+ When a task stays `in_progress` beyond `{stall_threshold_minutes}`:
115
+ 1. Send `[CHECK-IN]` message to the teammate via SendMessage
116
+ 2. If no response within reasonable time, classify per Headless Escalation Protocol
117
+
118
+ ---
119
+
120
+ ## Teardown
121
+
122
+ 1. Send `shutdown_request` via `SendMessage` to each teammate individually (not broadcast)
123
+ 2. Wait for each agent to write final state to its handoff file
124
+ 3. Delete heartbeat and keep-alive cron jobs via `CronDelete`
125
+ 4. Call `TeamDelete` to destroy the team and all inboxes
126
+ 5. Write `story-report.md`
127
+ 6. Commit and push to story branch
@@ -0,0 +1,49 @@
1
+ # Valent Pipeline — Codex Agent Instructions
2
+
3
+ > This file provides pipeline-wide rules for all agents running under OpenAI Codex.
4
+ > It is the Codex equivalent of project-level CLAUDE.md instructions.
5
+
6
+ ## Communication Standard
7
+
8
+ All output follows the V3 Distilled Communication Standard:
9
+ - Write for machine consumption, not human readability
10
+ - Structured data (YAML, lists, key-value) over prose paragraphs
11
+ - Facts and decisions only — no filler sentences
12
+ - Section headers as semantic labels
13
+ - Explicit cross-references using file paths and section anchors
14
+
15
+ Full reference: `.valent-pipeline/docs/communication-standard.md`
16
+
17
+ ## Output Format
18
+
19
+ Every handoff document must include:
20
+ 1. **YAML frontmatter** — agent, story, status, stepsCompleted, pendingSteps, lastCheckpoint, inputsRead, outputsWritten, blockers
21
+ 2. **Orchestrator Summary** — Agent, Story, Verdict (pass/fail/needs-review), State transition, Files created/modified, Flags
22
+
23
+ Full schema: `.valent-pipeline/docs/communication-standard.md#3` and `#4`
24
+
25
+ ## Shared Context
26
+
27
+ At startup, every agent reads:
28
+ 1. Its core prompt from `.valent-pipeline/prompts/{agent}.md`
29
+ 2. Shared context from `{story_output_dir}/pipeline-context.md`
30
+ 3. Step files at the point of execution (not before)
31
+
32
+ ## File Conventions
33
+
34
+ - Write all output to `{story_output_dir}/`
35
+ - Use the appropriate template from `.valent-pipeline/templates/`
36
+ - Cross-reference files by path and section anchor: `file.md#section`
37
+ - Never reference implicit shared context — everything must be explicit
38
+
39
+ ## Signal Delivery
40
+
41
+ In Codex mode, thread completion IS your handoff signal. Write your output files with the orchestrator summary verdict, then complete. Lead reads your verdict from the handoff file and routes accordingly.
42
+
43
+ Do NOT attempt to use `SendMessage` or inbox messaging — these are Claude Code primitives not available in Codex.
44
+
45
+ ## Knowledge Queries
46
+
47
+ If you need knowledge context, check `{story_output_dir}/pipeline-context.md` for the knowledge mode:
48
+ - If `knowledge-context.md` exists in the story output dir, read it directly
49
+ - Otherwise, write your query to `{story_output_dir}/knowledge-queries/{your_name}-{n}.md` and note "pending knowledge query" in your handoff. Lead will relay the response.
@@ -0,0 +1,256 @@
1
+ # Codex Runtime Adapter
2
+
3
+ > **Provider:** OpenAI Codex (CLI and Cloud)
4
+ > **Read by:** Lead agent when `runtime.provider` is `codex` in `pipeline-config.yaml`
5
+ > **Purpose:** Defines HOW to spawn agent threads, coordinate via steering, track tasks via file-based registry, and manage thread lifecycle using Codex's native primitives.
6
+
7
+ ---
8
+
9
+ ## Initialization
10
+
11
+ No team API call needed. Ensure the story output directory exists:
12
+
13
+ ```
14
+ mkdir -p {story_output_dir}/
15
+ ```
16
+
17
+ No `signals/` or `inbox/` directories needed. Codex thread management handles coordination natively:
18
+ - Agent completion is detected by thread state
19
+ - Parent-to-child communication uses steering (follow-up instructions to running threads)
20
+ - Child-to-parent communication is via thread completion + handoff file verdict
21
+
22
+ ---
23
+
24
+ ## Task Registry
25
+
26
+ Write `{story_output_dir}/task-registry.yaml` from the resolved task graph:
27
+
28
+ ```yaml
29
+ tasks:
30
+ reqs:
31
+ status: pending # pending | in_progress | completed | blocked
32
+ agent: REQS
33
+ blocked_by: []
34
+ started_at: null
35
+ completed_at: null
36
+ uxa:
37
+ status: pending
38
+ agent: UXA
39
+ blocked_by: [reqs]
40
+ started_at: null
41
+ completed_at: null
42
+ # ... all tasks from task graph, filtered by project type and testing profiles
43
+ ```
44
+
45
+ **Update protocol:**
46
+ - Before spawning an agent: set its task status to `in_progress`, write `started_at`
47
+ - After agent thread completes: set status to `completed`, write `completed_at`, check if downstream tasks are unblocked
48
+ - Read the registry to determine next actions (replaces `TaskList`/`TaskGet`)
49
+
50
+ **Lead is the sole writer.** Agents never modify `task-registry.yaml`.
51
+
52
+ ---
53
+
54
+ ## Agent Spawning
55
+
56
+ Codex subagents run as **persistent threads**. Threads stay alive until explicitly closed. Lead spawns threads, steers them with follow-up instructions, and closes them at teardown.
57
+
58
+ ### Agent Type Classification
59
+
60
+ | Agent | Type | Rationale |
61
+ |-------|------|-----------|
62
+ | REQS | explorer | Reads story inputs + codebase for context, produces spec only |
63
+ | UXA | worker | Translates specs, may scaffold component stubs |
64
+ | QA-A | explorer | Reads all specs + codebase patterns, produces test spec only |
65
+ | READINESS | explorer | Reads all spec artifacts, produces review only |
66
+ | BEND | worker | Writes production code + tests, runs builds |
67
+ | FEND | worker | Writes UI code + tests, runs builds |
68
+ | IAC | worker | Writes infrastructure code |
69
+ | CRITIC | explorer | Multi-pass code review — reads everything, writes review doc only |
70
+ | QA-B | worker | Runs test suites, writes bug reports, may modify test files |
71
+ | JUDGE | explorer | Reads all artifacts, produces ship/reject verdict only |
72
+ | Knowledge | default | Reactive service — reads knowledge base, writes responses |
73
+
74
+ ### Sandbox Mode Per Agent
75
+
76
+ | Agent | Sandbox Mode | Notes |
77
+ |-------|-------------|-------|
78
+ | REQS, UXA, READINESS | `workspace-write` | Read files, write handoff docs |
79
+ | QA-A | `workspace-write` | Read files, write test spec |
80
+ | BEND, FEND, IAC | `workspace-write` | Read/write files, run shell (npm install, build, git). Network enabled for deps. |
81
+ | CRITIC, JUDGE | `read-only` | Only reads code. Override `writable_roots` for story output dir. |
82
+ | QA-B | `workspace-write` | Run test suites, start local servers. Network enabled, `allow_local_binding: true`. |
83
+ | PMCP | `workspace-write` | Run Playwright MCP. Network enabled, `allow_local_binding: true`. |
84
+ | Knowledge | `workspace-write` | Read knowledge files, write responses |
85
+
86
+ ### Sequential Phases (Wave 1)
87
+
88
+ Spawn threads one at a time. Each reads predecessor output from disk.
89
+
90
+ ```
91
+ Lead spawns REQS thread → REQS writes reqs-brief.md → completes
92
+ Lead reads handoff file verdict, updates task-registry.yaml
93
+ Lead spawns UXA thread → UXA reads reqs-brief.md, writes uxa-spec.md → completes
94
+ ...
95
+ Lead spawns READINESS thread → reviews specs → completes
96
+ ```
97
+
98
+ ### Parallel Phases (Wave 2)
99
+
100
+ Spawn BEND, FEND, IAC as parallel threads. All read from approved specs on disk.
101
+
102
+ ```
103
+ Lead spawns [BEND, FEND, IAC] as parallel threads
104
+ All three read from qa-test-spec.md + readiness-review.md on disk
105
+ All three write separate output files
106
+ Lead waits for all threads to complete
107
+ Lead updates task-registry.yaml for all three
108
+ Lead spawns CRITIC thread
109
+ ```
110
+
111
+ ### Wave Spawn Triggers
112
+
113
+ Same as Claude Code — spawn next wave when current blocking agent starts:
114
+
115
+ | Wave | Trigger | Agents |
116
+ |------|---------|--------|
117
+ | 1 | At kick-off | Knowledge, REQS, UXA, QA-A, READINESS |
118
+ | 2 | QA-A completes (READINESS approved) | BEND, FEND, IAC, CRITIC (each only if not skipped) |
119
+ | 3 | CRITIC starts | QA-B, PMCP (if ui profile) |
120
+ | 4 | JUDGE bug-review starts | (reserved) |
121
+
122
+ ### Spawn Template
123
+
124
+ Each agent receives a prompt built from `.valent-pipeline/spawn-templates/agent-spawn.template.md` (same template as Claude Code, without SendMessage instructions). The template tells the agent to:
125
+ 1. Read its core prompt
126
+ 2. Read shared context
127
+ 3. Execute steps
128
+ 4. Write output files to `{story_output_dir}/`
129
+ 5. Complete (Lead manages thread lifecycle)
130
+
131
+ ---
132
+
133
+ ## Rejection Loop (Steering, Not Re-Spawning)
134
+
135
+ Because threads persist, rejection loops use steering instead of re-spawning:
136
+
137
+ ```
138
+ Lead spawns CRITIC thread → CRITIC writes critic-review.md → completes with verdict
139
+ If verdict == rejection:
140
+ Lead steers BEND thread with follow-up: "CRITIC rejected. See critic-review.md#finding-1. Fix."
141
+ BEND fixes in-place → completes
142
+ Lead steers CRITIC thread: "BEND pushed fixes. Re-review."
143
+ CRITIC re-reviews → completes
144
+ Loop until approved or circuit breaker
145
+ ```
146
+
147
+ This preserves agent context from the initial implementation — no re-loading of codebase or specs.
148
+
149
+ If a thread was already closed (crash, timeout), Lead spawns a new thread with recovery context from handoff frontmatter.
150
+
151
+ ---
152
+
153
+ ## Knowledge Agent
154
+
155
+ ### Option A: Persistent Thread via Steering (Default for CLI)
156
+
157
+ Lead spawns Knowledge thread at story start. Knowledge loads correction directives, curated knowledge, and ChromaDB/SQLite sources, then signals ready.
158
+
159
+ When another agent needs knowledge:
160
+ 1. Agent writes query to `{story_output_dir}/knowledge-queries/{agent}-{n}.md`
161
+ 2. Agent completes its current step and notes "pending knowledge query" in handoff
162
+ 3. Lead steers Knowledge thread: "Answer query in `knowledge-queries/{agent}-{n}.md`"
163
+ 4. Knowledge writes response to `{story_output_dir}/knowledge-responses/{agent}-{n}.md`
164
+ 5. Lead steers the requesting agent: "Knowledge response ready at `knowledge-responses/{agent}-{n}.md`"
165
+
166
+ Hub-and-spoke: Lead relays between agents and Knowledge. No direct agent-to-Knowledge channel.
167
+
168
+ ### Option B: Pre-Computed Context File (Default for Cloud)
169
+
170
+ Lead spawns a one-shot Knowledge thread that:
171
+ 1. Reads ALL correction directives and ALL curated knowledge entries
172
+ 2. Produces `{story_output_dir}/knowledge-context.md` — compiled reference
173
+ 3. Completes
174
+
175
+ All downstream agents read `knowledge-context.md` directly. Zero relay overhead.
176
+
177
+ ### Option C: MCP Tool (Advanced)
178
+
179
+ Configure knowledge retrieval as an MCP tool in `.codex/config.toml`:
180
+ ```toml
181
+ [mcp.knowledge]
182
+ type = "stdio"
183
+ command = "node"
184
+ args = [".valent-pipeline/scripts/knowledge-mcp-server.js"]
185
+ ```
186
+
187
+ Agents call the knowledge tool directly. No relay through Lead.
188
+
189
+ ---
190
+
191
+ ## Signal Delivery
192
+
193
+ ### Agent → Lead (completion/verdict)
194
+
195
+ Thread completion IS the signal. When a thread completes, Lead reads the handoff file's YAML frontmatter (`status`) and orchestrator summary (`verdict`) to determine routing:
196
+ - `verdict: pass` → advance downstream task, update task-registry
197
+ - `verdict: fail` → route rejection per re-entry map
198
+ - `verdict: needs-review` → escalate per Headless Escalation Protocol
199
+
200
+ No signal files needed. Lead reads the handoff artifact directly.
201
+
202
+ ### Lead → Agent (instructions, rejection context, steering)
203
+
204
+ Two channels:
205
+ - **At spawn:** Initial prompt via spawn template.
206
+ - **Mid-execution:** Steering via follow-up instructions to running thread. Used for rejection rework, knowledge query relay, and course correction.
207
+
208
+ ### Agent → Agent (peer communication)
209
+
210
+ Not supported natively. Hub-and-spoke only. Two patterns:
211
+
212
+ **File-based (for data):** Agent writes to `{story_output_dir}/` and the consuming agent reads it when spawned or steered. This is how handoff documents already work.
213
+
214
+ **Lead relay (for coordination):** Lead reads output from one thread, steers another thread with the relevant information. Used for Design Council deliberation and Knowledge Agent query relay.
215
+
216
+ ---
217
+
218
+ ## Monitoring
219
+
220
+ Lead drives execution as an orchestration loop, managing threads directly:
221
+
222
+ ```
223
+ while tasks remain:
224
+ next_batch = get_unblocked_tasks(task_registry)
225
+ if parallel_safe(next_batch):
226
+ spawn all as parallel threads, wait for all to complete
227
+ else:
228
+ spawn sequentially, wait for each
229
+ update task_registry
230
+ check circuit breaker thresholds
231
+ if rejection: steer agent threads for rework (see Rejection Loop)
232
+ ```
233
+
234
+ ### Stall Detection
235
+
236
+ Lead can inspect running threads via `/agent` or by checking `job_max_runtime_seconds` timeout. If a thread exceeds the timeout, Codex kills it and Lead handles the timeout as a stall — spawn a replacement thread with recovery context from handoff frontmatter.
237
+
238
+ No heartbeat cron needed — Lead observes thread state directly.
239
+
240
+ ### Thread Budget
241
+
242
+ `max_threads` defaults to 6 (configurable via `runtime.codex.max_concurrent_agents`). Lead's own thread does NOT count against this limit.
243
+
244
+ **Strategy:** Close completed spec agent threads (REQS, UXA, QA-A, READINESS) before spawning Wave 2 to free slots. For rejection loops, if slots are tight, close dev threads and re-spawn with recovery context.
245
+
246
+ If `max_threads` is hit, Codex queues excess spawns. Pipeline degrades to sequential execution — slower but not broken.
247
+
248
+ ---
249
+
250
+ ## Teardown
251
+
252
+ Close all agent threads and clean up:
253
+ 1. Close all completed agent threads (ask Codex to close each thread)
254
+ 2. Stop any still-running threads (Knowledge Agent if using Option A)
255
+ 3. Write `story-report.md`
256
+ 4. Commit and push to story branch
@@ -95,6 +95,23 @@ export function validateConfig(config) {
95
95
  }
96
96
  }
97
97
 
98
+ // Runtime section (optional — provider adapter configuration)
99
+ if (config.runtime) {
100
+ const validProviders = ['claude-code', 'codex'];
101
+ if (config.runtime.provider && !validProviders.includes(config.runtime.provider)) {
102
+ errors.push(`Invalid runtime.provider: "${config.runtime.provider}". Must be one of: ${validProviders.join(', ')}`);
103
+ }
104
+ if (config.runtime.codex) {
105
+ if (config.runtime.codex.max_concurrent_agents !== undefined && typeof config.runtime.codex.max_concurrent_agents !== 'number') {
106
+ errors.push(`runtime.codex.max_concurrent_agents must be a number, got: ${typeof config.runtime.codex.max_concurrent_agents}`);
107
+ }
108
+ const validSandboxModes = ['read-only', 'workspace-write', 'danger-full-access'];
109
+ if (config.runtime.codex.sandbox_mode && !validSandboxModes.includes(config.runtime.codex.sandbox_mode)) {
110
+ errors.push(`Invalid runtime.codex.sandbox_mode: "${config.runtime.codex.sandbox_mode}". Must be one of: ${validSandboxModes.join(', ')}`);
111
+ }
112
+ }
113
+ }
114
+
98
115
  if (config.knowledge?.mode === 'sqlite' && !config.knowledge?.sqlite_db_path) {
99
116
  errors.push('knowledge.sqlite_db_path is required when knowledge.mode is "sqlite"');
100
117
  }
@@ -168,4 +185,18 @@ export const defaults = {
168
185
  auto_reprioritize: true,
169
186
  auto_generate_gap_stories: false,
170
187
  },
188
+ runtime: {
189
+ provider: 'claude-code',
190
+ codex: {
191
+ max_concurrent_agents: 6,
192
+ sandbox_mode: 'workspace-write',
193
+ model_map: {},
194
+ cloud: {
195
+ git_remote: 'origin',
196
+ internet_allowlist: [],
197
+ setup_script: '.codex/setup.sh',
198
+ commit_prefix: 'pipeline',
199
+ },
200
+ },
201
+ },
171
202
  };