specrails-core 3.8.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -59,6 +59,36 @@ which openspec && openspec --version
59
59
 
60
60
  {{TEST_RUNNER_CHECK}}
61
61
 
62
+ #### 5. Agent discovery
63
+
64
+ Scan the agents directory to determine which agents are installed:
65
+
66
+ ```bash
67
+ ls .claude/agents/sr-*.md 2>/dev/null | sed 's|.*/||;s|\.md$||' | sort
68
+ ```
69
+
70
+ Store the result as `AVAILABLE_AGENTS` (a list of agent IDs). The pipeline adapts dynamically to the installed agents:
71
+
72
+ | Agent | Role | Required? | Phase(s) affected |
73
+ |-------|------|-----------|-------------------|
74
+ | sr-architect | Architecture & design | **Core** (always present) | 3a |
75
+ | sr-developer | Full-stack implementation | **Core** (always present) | 3b |
76
+ | sr-reviewer | Generalist quality gate | **Core** (always present) | 4b |
77
+ | sr-merge-resolver | Merge conflict resolution | **Core** (always present) | 4a |
78
+ | sr-product-manager | Product exploration | Optional | 1 |
79
+ | sr-test-writer | Test generation | Optional | 3c |
80
+ | sr-doc-sync | Documentation sync | Optional | 3d |
81
+ | sr-frontend-developer | Frontend implementation | Optional | 3b (routing) |
82
+ | sr-backend-developer | Backend implementation | Optional | 3b (routing) |
83
+ | sr-frontend-reviewer | Frontend review | Optional | 4b |
84
+ | sr-backend-reviewer | Backend review | Optional | 4b |
85
+ | sr-security-reviewer | Security analysis | Optional | 4b |
86
+ | sr-performance-reviewer | Performance analysis | Optional | 4b |
87
+
88
+ **Gate rules** (applied throughout the pipeline):
89
+ - If an optional agent is NOT in `AVAILABLE_AGENTS`, **skip** that phase/sub-step silently and note `"<agent> not installed — skipping"`.
90
+ - Core agents are guaranteed to exist. If a core agent is missing, **STOP** and print: `[error] Core agent <name> not found. Run /specrails:enrich or reinstall.`
91
+
62
92
  ### Summary
63
93
 
64
94
  Print a setup report:
@@ -71,9 +101,10 @@ Print a setup report:
71
101
  | OpenSpec | ok | ... |
72
102
  | Dependencies | ok | ... |
73
103
  | Test runner | ok | ... |
104
+ | Agents | N installed | core: 4/4, optional: M |
74
105
  ```
75
106
 
76
- **Pass `TEST_CMD` (or equivalent) and `BACKLOG_AVAILABLE` forward** — all later phases must use these.
107
+ **Pass `TEST_CMD`, `BACKLOG_AVAILABLE`, and `AVAILABLE_AGENTS` forward** — all later phases must use these.
77
108
 
78
109
  ---
79
110
 
@@ -250,8 +281,8 @@ Write the initial state file:
250
281
  "phases": {
251
282
  "architect": "pending",
252
283
  "developer": "pending",
253
- "test-writer": "pending",
254
- "doc-sync": "pending",
284
+ "test-writer": "<'pending' if sr-test-writer ∈ AVAILABLE_AGENTS, else 'skipped'>",
285
+ "doc-sync": "<'pending' if sr-doc-sync ∈ AVAILABLE_AGENTS, else 'skipped'>",
255
286
  "reviewer": "pending",
256
287
  "ship": "pending",
257
288
  "ci": "pending"
@@ -296,7 +327,9 @@ If `PIPELINE_STATE_AVAILABLE=false`: skip all state updates silently.
296
327
 
297
328
  ## Phase 1: Explore (parallel)
298
329
 
299
- **Only runs if Phase 0 found no backlog issues AND user passed area names.**
330
+ **Only runs if Phase 0 found no backlog issues AND user passed area names AND `sr-product-manager` ∈ `AVAILABLE_AGENTS`.**
331
+
332
+ If `sr-product-manager` is not installed, skip Phase 1 and Phase 2 entirely. Print: `[phase-1] sr-product-manager not installed — skipping exploration. Proceeding with provided input.`
300
333
 
301
334
  For each area, launch a **sr-product-manager** agent (`subagent_type: sr-product-manager`, `run_in_background: true`).
302
335
 
@@ -470,21 +503,64 @@ Before launching any developer agent, run a trivial Bash command to confirm Bash
470
503
 
471
504
  #### Choosing the right developer agent
472
505
 
473
- For each feature, analyze the tasks' layer tags:
506
+ For each feature, read `openspec/changes/<name>/tasks.md` and classify every task by its layer tags and file references.
507
+
508
+ **Step 1 — Classify tasks into layers:**
474
509
 
475
- {{DEVELOPER_ROUTING_RULES}}
510
+ For each task, determine its layer from:
511
+ 1. **Explicit layer tags** in tasks.md (e.g., `[frontend]`, `[backend]`, `[core]`, `[infra]`, `[docs]`, etc.)
512
+ 2. **File references** under `**Files:**` entries — apply the same extension/path rules used in Phase 4b:
513
+ - Frontend: `.jsx`, `.tsx`, `.vue`, `.svelte`, `.css`, `.scss`, `.html`, or paths under `components/`, `pages/`, `views/`, `ui/`, `client/`, `frontend/`, `app/`, `public/`, `static/`, `assets/`
514
+ - Backend: `.py`, `.go`, `.java`, `.rb`, `.php`, `.rs`, `.cs`, `.sql`, or paths under `server/`, `api/`, `routes/`, `controllers/`, `services/`, `models/`, `db/`, `backend/`, `migrations/`
515
+ - Mixed/other: everything else (shell scripts, config files, markdown, YAML, etc.)
516
+
517
+ Produce three sets: `FRONTEND_TASKS`, `BACKEND_TASKS`, `OTHER_TASKS`.
518
+
519
+ **Step 2 — Route tasks to developer agents:**
520
+
521
+ Evaluate available developer agents in `AVAILABLE_AGENTS` and apply these rules in priority order:
522
+
523
+ | Condition | Agent(s) selected | Mode |
524
+ |-----------|-------------------|------|
525
+ | ALL tasks are frontend-only AND `sr-frontend-developer` ∈ `AVAILABLE_AGENTS` | **sr-frontend-developer** | Single agent for all tasks |
526
+ | ALL tasks are backend-only AND `sr-backend-developer` ∈ `AVAILABLE_AGENTS` | **sr-backend-developer** | Single agent for all tasks |
527
+ | Mix of frontend + backend tasks AND both layer-specific developers available | **sr-frontend-developer** for `FRONTEND_TASKS`, **sr-backend-developer** for `BACKEND_TASKS`, **sr-developer** for `OTHER_TASKS` | Parallel agents per layer |
528
+ | Frontend tasks exist AND `sr-frontend-developer` available, but no backend-specific developer | **sr-frontend-developer** for `FRONTEND_TASKS`, **sr-developer** for remaining | Parallel agents |
529
+ | Backend tasks exist AND `sr-backend-developer` available, but no frontend-specific developer | **sr-backend-developer** for `BACKEND_TASKS`, **sr-developer** for remaining | Parallel agents |
530
+ | No layer-specific developers available (fallback) | **sr-developer** | Single agent for all tasks |
531
+
532
+ Store the result as `DEVELOPER_ROUTING`: a map of `{agent_id: [task_list]}`.
533
+
534
+ **Step 3 — Print routing decision:**
535
+
536
+ ```
537
+ ## Developer Routing
538
+
539
+ | Agent | Tasks | Reason |
540
+ |-------|-------|--------|
541
+ | sr-frontend-developer | Task 1, Task 3 | Frontend-only tasks (React components) |
542
+ | sr-backend-developer | Task 2, Task 4 | Backend-only tasks (API endpoints) |
543
+ | sr-developer | Task 5 | Mixed layer (config + infra) |
544
+ ```
545
+
546
+ Also store `DEVELOPER_AGENTS_USED` (the set of developer agent IDs actually launched) — Phase 4b will use this for reviewer selection.
476
547
 
477
548
  #### Launch modes
478
549
 
479
- **If `SINGLE_MODE`**: Launch in the main repo, foreground.
550
+ For each entry in `DEVELOPER_ROUTING`, launch the assigned developer agent with its task subset.
551
+
552
+ **If `SINGLE_MODE` and only one agent in routing**: Launch in the main repo, foreground.
553
+ **If `SINGLE_MODE` but multiple agents in routing**: Launch agents sequentially in the main repo (one at a time, foreground), passing only their assigned tasks.
480
554
  **If multiple features**: Launch in isolated worktrees (`isolation: worktree`, `run_in_background: true`).
481
555
 
482
556
  Wait for all developers to complete.
483
557
 
484
- **Pipeline state:** update `developer` → `done`. Also update `implemented_files` in the state file with the complete list of files created or modified by the developer agent(s). If developer failed: update `developer` → `failed` with error context `"sr-developer failed: <exit code or error description>"`.
558
+ **Pipeline state:** update `developer` → `done`. Also update `implemented_files` in the state file with the complete list of files created or modified by the developer agent(s). If developer failed: update `developer` → `failed` with error context `"<agent-id> failed: <exit code or error description>"`.
485
559
 
486
560
  ## Phase 3c: Write Tests
487
561
 
562
+ **Guard:** If `sr-test-writer` ∉ `AVAILABLE_AGENTS`, skip this phase. Print: `[phase-3c] sr-test-writer not installed — skipping test generation.` Update pipeline state: `test-writer` → `skipped`. Proceed to Phase 3d.
563
+
488
564
  Launch a **sr-test-writer** agent for each feature immediately after its developer completes.
489
565
 
490
566
  Construct the agent invocation prompt to include:
@@ -519,6 +595,8 @@ If a test-writer agent fails or times out:
519
595
 
520
596
  ## Phase 3d: Doc Sync
521
597
 
598
+ **Guard:** If `sr-doc-sync` ∉ `AVAILABLE_AGENTS`, skip this phase. Print: `[phase-3d] sr-doc-sync not installed — skipping doc sync.` Update pipeline state: `doc-sync` → `skipped`. Proceed to Phase 4.
599
+
522
600
  Launch a **sr-doc-sync** agent for each feature after its tests are written.
523
601
 
524
602
  Construct the agent invocation prompt to include:
@@ -643,7 +721,9 @@ After all features are processed, print the preliminary report:
643
721
  - <file> (features: <a>, <b> — conflicting section: "<heading>")
644
722
  ```
645
723
 
646
- **Step 5a: Smart conflict resolution** (skip if `SINGLE_MODE=true` or `DRY_RUN=true`)
724
+ **Step 5a: Smart conflict resolution** (skip if `SINGLE_MODE=true` or `DRY_RUN=true` or `sr-merge-resolver` ∉ `AVAILABLE_AGENTS`)
725
+
726
+ If `sr-merge-resolver` is not installed, print: `[smart-merge] sr-merge-resolver not installed — skipping automatic resolution. Fix conflicts manually.` and skip to Step 5b.
647
727
 
648
728
  If `MERGE_REPORT.requires_resolution` is non-empty:
649
729
 
@@ -728,27 +808,43 @@ Set `BACKEND_FILES` = files matching backend rules.
728
808
 
729
809
  **Overlap rule:** a file may appear in both `FRONTEND_FILES` and `BACKEND_FILES` (e.g., a Next.js API route at `pages/api/`). Both reviewers will scan it independently.
730
810
 
731
- If `FRONTEND_FILES` is empty: set `FRONTEND_REVIEW_REPORT = "SKIPPED"` and skip frontend-reviewer launch. Note: "No frontend files detected."
732
- If `BACKEND_FILES` is empty: set `BACKEND_REVIEW_REPORT = "SKIPPED"` and skip backend-reviewer launch. Note: "No backend files detected."
811
+ #### Step 2: Determine which reviewers to launch
812
+
813
+ A layer reviewer is launched when **both** conditions are met:
814
+ 1. There are files to review for that layer (file classification) **OR** the corresponding layer developer was used in Phase 3b (`DEVELOPER_AGENTS_USED`)
815
+ 2. The reviewer agent is installed (`∈ AVAILABLE_AGENTS`)
816
+
817
+ | Reviewer | Launch condition | Skip reason |
818
+ |----------|-----------------|-------------|
819
+ | sr-frontend-reviewer | (`FRONTEND_FILES` non-empty OR `sr-frontend-developer` ∈ `DEVELOPER_AGENTS_USED`) AND installed | No frontend files + no frontend developer used, or not installed |
820
+ | sr-backend-reviewer | (`BACKEND_FILES` non-empty OR `sr-backend-developer` ∈ `DEVELOPER_AGENTS_USED`) AND installed | No backend files + no backend developer used, or not installed |
821
+ | sr-security-reviewer | Installed | Not installed |
822
+ | sr-performance-reviewer | Installed | Not installed |
823
+
824
+ If a reviewer is skipped, set its report variable to `"SKIPPED"` and note the reason.
733
825
 
734
- #### Step 2: Launch Layer Reviewers in Parallel
826
+ #### Step 3: Launch Layer Reviewers in Parallel
735
827
 
736
- Launch all applicable layer reviewers in parallel (`run_in_background: true`):
828
+ Launch all applicable layer reviewers in parallel (`run_in_background: true`).
737
829
 
738
- **sr-frontend-reviewer** (if `FRONTEND_FILES` is non-empty):
830
+ **sr-frontend-reviewer** (if applicable per Step 2):
739
831
  - Pass `FRONTEND_FILES_LIST`: the list of files in `FRONTEND_FILES`
740
832
  - Pass `PIPELINE_CONTEXT`: brief description of what was implemented
741
833
 
742
- **sr-backend-reviewer** (if `BACKEND_FILES` is non-empty):
834
+ **sr-backend-reviewer** (if applicable per Step 2):
743
835
  - Pass `BACKEND_FILES_LIST`: the list of files in `BACKEND_FILES`
744
836
  - Pass `PIPELINE_CONTEXT`: brief description of what was implemented
745
837
 
746
- **sr-security-reviewer** (always):
838
+ **sr-security-reviewer** (if applicable per Step 2):
747
839
  - Pass `MODIFIED_FILES_LIST`: the complete list of all files created or modified during this run
748
840
  - Pass `PIPELINE_CONTEXT`: brief description of what was implemented
749
841
  - Pass the exemptions config path: `.claude/security-exemptions.yaml`
750
842
 
751
- Wait for all launched layer reviewers to complete before proceeding to Step 3.
843
+ **sr-performance-reviewer** (if applicable per Step 2):
844
+ - Pass `MODIFIED_FILES_LIST`: the complete list of all files created or modified during this run
845
+ - Pass `PIPELINE_CONTEXT`: brief description of what was implemented
846
+
847
+ Wait for all launched layer reviewers to complete before proceeding to Step 4.
752
848
 
753
849
  Parse status lines from each completed reviewer:
754
850
  - `FRONTEND_REVIEW_STATUS: ISSUES_FOUND` or `CLEAN` → set `FRONTEND_STATUS`
@@ -757,7 +853,7 @@ Parse status lines from each completed reviewer:
757
853
 
758
854
  If a layer reviewer fails or times out: set the relevant report variable to `"ERROR: reviewer did not complete"` and continue.
759
855
 
760
- #### Step 3: Launch Generalist Reviewer
856
+ #### Step 4: Launch Generalist Reviewer
761
857
 
762
858
  Construct the generalist reviewer's invocation prompt with layer reports injected. Set each variable to the full output of the corresponding reviewer, or to the string `"SKIPPED"` if that reviewer was not launched:
763
859
 
@@ -49,6 +49,8 @@ Output ONLY the following structured markdown. Do not add any preamble or explan
49
49
 
50
50
  After generating the proposal, read `.specrails/backlog-config.json` to determine `BACKLOG_PROVIDER` and `BACKLOG_WRITE`.
51
51
 
52
+ If `.specrails/backlog-config.json` does not exist, default to `provider=local` and `write_access=true`. Initialize `.specrails/local-tickets.json` if it does not exist (empty store with `schema_version: "1.0"`, `revision: 0`, `next_id: 1`, `tickets: {}`).
53
+
52
54
  ### If provider=local — Create Local Ticket
53
55
 
54
56
  Create a local ticket from the proposal output:
@@ -50,8 +50,6 @@
50
50
  "models.preset": "string — balanced | budget | max",
51
51
  "models.defaults.model": "string — sonnet | opus | haiku (overrides preset)",
52
52
  "models.overrides": "Record<string, string> — per-agent model (highest priority)",
53
- "quick_context.product_description": "string — product description seed for VPC discovery",
54
- "quick_context.target_users": "string — target users seed for VPC discovery",
55
53
  "agent_teams": "boolean — install team-review and team-debug commands"
56
54
  }
57
55
  },
@@ -59,6 +59,36 @@ which openspec && openspec --version
59
59
 
60
60
  {{TEST_RUNNER_CHECK}}
61
61
 
62
+ #### 5. Agent discovery
63
+
64
+ Scan the agents directory to determine which agents are installed:
65
+
66
+ ```bash
67
+ ls .claude/agents/sr-*.md 2>/dev/null | sed 's|.*/||;s|\.md$||' | sort
68
+ ```
69
+
70
+ Store the result as `AVAILABLE_AGENTS` (a list of agent IDs). The pipeline adapts dynamically to the installed agents:
71
+
72
+ | Agent | Role | Required? | Phase(s) affected |
73
+ |-------|------|-----------|-------------------|
74
+ | sr-architect | Architecture & design | **Core** (always present) | 3a |
75
+ | sr-developer | Full-stack implementation | **Core** (always present) | 3b |
76
+ | sr-reviewer | Generalist quality gate | **Core** (always present) | 4b |
77
+ | sr-merge-resolver | Merge conflict resolution | **Core** (always present) | 4a |
78
+ | sr-product-manager | Product exploration | Optional | 1 |
79
+ | sr-test-writer | Test generation | Optional | 3c |
80
+ | sr-doc-sync | Documentation sync | Optional | 3d |
81
+ | sr-frontend-developer | Frontend implementation | Optional | 3b (routing) |
82
+ | sr-backend-developer | Backend implementation | Optional | 3b (routing) |
83
+ | sr-frontend-reviewer | Frontend review | Optional | 4b |
84
+ | sr-backend-reviewer | Backend review | Optional | 4b |
85
+ | sr-security-reviewer | Security analysis | Optional | 4b |
86
+ | sr-performance-reviewer | Performance analysis | Optional | 4b |
87
+
88
+ **Gate rules** (applied throughout the pipeline):
89
+ - If an optional agent is NOT in `AVAILABLE_AGENTS`, **skip** that phase/sub-step silently and note `"<agent> not installed — skipping"`.
90
+ - Core agents are guaranteed to exist. If a core agent is missing, **STOP** and print: `[error] Core agent <name> not found. Run /specrails:enrich or reinstall.`
91
+
62
92
  ### Summary
63
93
 
64
94
  Print a setup report:
@@ -71,9 +101,10 @@ Print a setup report:
71
101
  | OpenSpec | ok | ... |
72
102
  | Dependencies | ok | ... |
73
103
  | Test runner | ok | ... |
104
+ | Agents | N installed | core: 4/4, optional: M |
74
105
  ```
75
106
 
76
- **Pass `TEST_CMD` (or equivalent) and `BACKLOG_AVAILABLE` forward** — all later phases must use these.
107
+ **Pass `TEST_CMD`, `BACKLOG_AVAILABLE`, and `AVAILABLE_AGENTS` forward** — all later phases must use these.
77
108
 
78
109
  ---
79
110
 
@@ -213,8 +244,8 @@ Write the initial state file:
213
244
  "phases": {
214
245
  "architect": "pending",
215
246
  "developer": "pending",
216
- "test-writer": "pending",
217
- "doc-sync": "pending",
247
+ "test-writer": "<'pending' if sr-test-writer ∈ AVAILABLE_AGENTS, else 'skipped'>",
248
+ "doc-sync": "<'pending' if sr-doc-sync ∈ AVAILABLE_AGENTS, else 'skipped'>",
218
249
  "reviewer": "pending",
219
250
  "ship": "pending",
220
251
  "ci": "pending"
@@ -259,7 +290,9 @@ If `PIPELINE_STATE_AVAILABLE=false`: skip all state updates silently.
259
290
 
260
291
  ## Phase 1: Explore (parallel)
261
292
 
262
- **Only runs if Phase 0 found no backlog issues AND user passed area names.**
293
+ **Only runs if Phase 0 found no backlog issues AND user passed area names AND `sr-product-manager` ∈ `AVAILABLE_AGENTS`.**
294
+
295
+ If `sr-product-manager` is not installed, skip Phase 1 and Phase 2 entirely. Print: `[phase-1] sr-product-manager not installed — skipping exploration. Proceeding with provided input.`
263
296
 
264
297
  For each area, launch a **sr-product-manager** agent (`subagent_type: sr-product-manager`, `run_in_background: true`).
265
298
 
@@ -431,21 +464,64 @@ Before launching any developer agent, run a trivial Bash command to confirm Bash
431
464
 
432
465
  #### Choosing the right developer agent
433
466
 
434
- For each feature, analyze the tasks' layer tags:
467
+ For each feature, read `openspec/changes/<name>/tasks.md` and classify every task by its layer tags and file references.
468
+
469
+ **Step 1 — Classify tasks into layers:**
435
470
 
436
- {{DEVELOPER_ROUTING_RULES}}
471
+ For each task, determine its layer from:
472
+ 1. **Explicit layer tags** in tasks.md (e.g., `[frontend]`, `[backend]`, `[core]`, `[infra]`, `[docs]`, etc.)
473
+ 2. **File references** under `**Files:**` entries — apply the same extension/path rules used in Phase 4b:
474
+ - Frontend: `.jsx`, `.tsx`, `.vue`, `.svelte`, `.css`, `.scss`, `.html`, or paths under `components/`, `pages/`, `views/`, `ui/`, `client/`, `frontend/`, `app/`, `public/`, `static/`, `assets/`
475
+ - Backend: `.py`, `.go`, `.java`, `.rb`, `.php`, `.rs`, `.cs`, `.sql`, or paths under `server/`, `api/`, `routes/`, `controllers/`, `services/`, `models/`, `db/`, `backend/`, `migrations/`
476
+ - Mixed/other: everything else (shell scripts, config files, markdown, YAML, etc.)
477
+
478
+ Produce three sets: `FRONTEND_TASKS`, `BACKEND_TASKS`, `OTHER_TASKS`.
479
+
480
+ **Step 2 — Route tasks to developer agents:**
481
+
482
+ Evaluate available developer agents in `AVAILABLE_AGENTS` and apply these rules in priority order:
483
+
484
+ | Condition | Agent(s) selected | Mode |
485
+ |-----------|-------------------|------|
486
+ | ALL tasks are frontend-only AND `sr-frontend-developer` ∈ `AVAILABLE_AGENTS` | **sr-frontend-developer** | Single agent for all tasks |
487
+ | ALL tasks are backend-only AND `sr-backend-developer` ∈ `AVAILABLE_AGENTS` | **sr-backend-developer** | Single agent for all tasks |
488
+ | Mix of frontend + backend tasks AND both layer-specific developers available | **sr-frontend-developer** for `FRONTEND_TASKS`, **sr-backend-developer** for `BACKEND_TASKS`, **sr-developer** for `OTHER_TASKS` | Parallel agents per layer |
489
+ | Frontend tasks exist AND `sr-frontend-developer` available, but no backend-specific developer | **sr-frontend-developer** for `FRONTEND_TASKS`, **sr-developer** for remaining | Parallel agents |
490
+ | Backend tasks exist AND `sr-backend-developer` available, but no frontend-specific developer | **sr-backend-developer** for `BACKEND_TASKS`, **sr-developer** for remaining | Parallel agents |
491
+ | No layer-specific developers available (fallback) | **sr-developer** | Single agent for all tasks |
492
+
493
+ Store the result as `DEVELOPER_ROUTING`: a map of `{agent_id: [task_list]}`.
494
+
495
+ **Step 3 — Print routing decision:**
496
+
497
+ ```
498
+ ## Developer Routing
499
+
500
+ | Agent | Tasks | Reason |
501
+ |-------|-------|--------|
502
+ | sr-frontend-developer | Task 1, Task 3 | Frontend-only tasks (React components) |
503
+ | sr-backend-developer | Task 2, Task 4 | Backend-only tasks (API endpoints) |
504
+ | sr-developer | Task 5 | Mixed layer (config + infra) |
505
+ ```
506
+
507
+ Also store `DEVELOPER_AGENTS_USED` (the set of developer agent IDs actually launched) — Phase 4b will use this for reviewer selection.
437
508
 
438
509
  #### Launch modes
439
510
 
440
- **If `SINGLE_MODE`**: Launch in the main repo, foreground.
511
+ For each entry in `DEVELOPER_ROUTING`, launch the assigned developer agent with its task subset.
512
+
513
+ **If `SINGLE_MODE` and only one agent in routing**: Launch in the main repo, foreground.
514
+ **If `SINGLE_MODE` but multiple agents in routing**: Launch agents sequentially in the main repo (one at a time, foreground), passing only their assigned tasks.
441
515
  **If multiple features**: Launch in isolated worktrees (`isolation: worktree`, `run_in_background: true`).
442
516
 
443
517
  Wait for all developers to complete.
444
518
 
445
- **Pipeline state:** update `developer` → `done`. Also update `implemented_files` in the state file with the complete list of files created or modified by the developer agent(s). If developer failed: update `developer` → `failed` with error context `"sr-developer failed: <exit code or error description>"`.
519
+ **Pipeline state:** update `developer` → `done`. Also update `implemented_files` in the state file with the complete list of files created or modified by the developer agent(s). If developer failed: update `developer` → `failed` with error context `"<agent-id> failed: <exit code or error description>"`.
446
520
 
447
521
  ## Phase 3c: Write Tests
448
522
 
523
+ **Guard:** If `sr-test-writer` ∉ `AVAILABLE_AGENTS`, skip this phase. Print: `[phase-3c] sr-test-writer not installed — skipping test generation.` Update pipeline state: `test-writer` → `skipped`. Proceed to Phase 3d.
524
+
449
525
  Launch a **sr-test-writer** agent for each feature immediately after its developer completes.
450
526
 
451
527
  Construct the agent invocation prompt to include:
@@ -480,6 +556,8 @@ If a test-writer agent fails or times out:
480
556
 
481
557
  ## Phase 3d: Doc Sync
482
558
 
559
+ **Guard:** If `sr-doc-sync` ∉ `AVAILABLE_AGENTS`, skip this phase. Print: `[phase-3d] sr-doc-sync not installed — skipping doc sync.` Update pipeline state: `doc-sync` → `skipped`. Proceed to Phase 4.
560
+
483
561
  Launch a **sr-doc-sync** agent for each feature after its tests are written.
484
562
 
485
563
  Construct the agent invocation prompt to include:
@@ -604,7 +682,9 @@ After all features are processed, print the preliminary report:
604
682
  - <file> (features: <a>, <b> — conflicting section: "<heading>")
605
683
  ```
606
684
 
607
- **Step 5a: Smart conflict resolution** (skip if `SINGLE_MODE=true` or `DRY_RUN=true`)
685
+ **Step 5a: Smart conflict resolution** (skip if `SINGLE_MODE=true` or `DRY_RUN=true` or `sr-merge-resolver` ∉ `AVAILABLE_AGENTS`)
686
+
687
+ If `sr-merge-resolver` is not installed, print: `[smart-merge] sr-merge-resolver not installed — skipping automatic resolution. Fix conflicts manually.` and skip to Step 5b.
608
688
 
609
689
  If `MERGE_REPORT.requires_resolution` is non-empty:
610
690
 
@@ -689,27 +769,43 @@ Set `BACKEND_FILES` = files matching backend rules.
689
769
 
690
770
  **Overlap rule:** a file may appear in both `FRONTEND_FILES` and `BACKEND_FILES` (e.g., a Next.js API route at `pages/api/`). Both reviewers will scan it independently.
691
771
 
692
- If `FRONTEND_FILES` is empty: set `FRONTEND_REVIEW_REPORT = "SKIPPED"` and skip frontend-reviewer launch. Note: "No frontend files detected."
693
- If `BACKEND_FILES` is empty: set `BACKEND_REVIEW_REPORT = "SKIPPED"` and skip backend-reviewer launch. Note: "No backend files detected."
772
+ #### Step 2: Determine which reviewers to launch
773
+
774
+ A layer reviewer is launched when **both** conditions are met:
775
+ 1. There are files to review for that layer (file classification) **OR** the corresponding layer developer was used in Phase 3b (`DEVELOPER_AGENTS_USED`)
776
+ 2. The reviewer agent is installed (`∈ AVAILABLE_AGENTS`)
777
+
778
+ | Reviewer | Launch condition | Skip reason |
779
+ |----------|-----------------|-------------|
780
+ | sr-frontend-reviewer | (`FRONTEND_FILES` non-empty OR `sr-frontend-developer` ∈ `DEVELOPER_AGENTS_USED`) AND installed | No frontend files + no frontend developer used, or not installed |
781
+ | sr-backend-reviewer | (`BACKEND_FILES` non-empty OR `sr-backend-developer` ∈ `DEVELOPER_AGENTS_USED`) AND installed | No backend files + no backend developer used, or not installed |
782
+ | sr-security-reviewer | Installed | Not installed |
783
+ | sr-performance-reviewer | Installed | Not installed |
784
+
785
+ If a reviewer is skipped, set its report variable to `"SKIPPED"` and note the reason.
694
786
 
695
- #### Step 2: Launch Layer Reviewers in Parallel
787
+ #### Step 3: Launch Layer Reviewers in Parallel
696
788
 
697
- Launch all applicable layer reviewers in parallel (`run_in_background: true`):
789
+ Launch all applicable layer reviewers in parallel (`run_in_background: true`).
698
790
 
699
- **sr-frontend-reviewer** (if `FRONTEND_FILES` is non-empty):
791
+ **sr-frontend-reviewer** (if applicable per Step 2):
700
792
  - Pass `FRONTEND_FILES_LIST`: the list of files in `FRONTEND_FILES`
701
793
  - Pass `PIPELINE_CONTEXT`: brief description of what was implemented
702
794
 
703
- **sr-backend-reviewer** (if `BACKEND_FILES` is non-empty):
795
+ **sr-backend-reviewer** (if applicable per Step 2):
704
796
  - Pass `BACKEND_FILES_LIST`: the list of files in `BACKEND_FILES`
705
797
  - Pass `PIPELINE_CONTEXT`: brief description of what was implemented
706
798
 
707
- **sr-security-reviewer** (always):
799
+ **sr-security-reviewer** (if applicable per Step 2):
708
800
  - Pass `MODIFIED_FILES_LIST`: the complete list of all files created or modified during this run
709
801
  - Pass `PIPELINE_CONTEXT`: brief description of what was implemented
710
802
  - Pass the exemptions config path: `.claude/security-exemptions.yaml`
711
803
 
712
- Wait for all launched layer reviewers to complete before proceeding to Step 3.
804
+ **sr-performance-reviewer** (if applicable per Step 2):
805
+ - Pass `MODIFIED_FILES_LIST`: the complete list of all files created or modified during this run
806
+ - Pass `PIPELINE_CONTEXT`: brief description of what was implemented
807
+
808
+ Wait for all launched layer reviewers to complete before proceeding to Step 4.
713
809
 
714
810
  Parse status lines from each completed reviewer:
715
811
  - `FRONTEND_REVIEW_STATUS: ISSUES_FOUND` or `CLEAN` → set `FRONTEND_STATUS`
@@ -718,7 +814,7 @@ Parse status lines from each completed reviewer:
718
814
 
719
815
  If a layer reviewer fails or times out: set the relevant report variable to `"ERROR: reviewer did not complete"` and continue.
720
816
 
721
- #### Step 3: Launch Generalist Reviewer
817
+ #### Step 4: Launch Generalist Reviewer
722
818
 
723
819
  Construct the generalist reviewer's invocation prompt with layer reports injected. Set each variable to the full output of the corresponding reviewer, or to the string `"SKIPPED"` if that reviewer was not launched:
724
820
 
@@ -1,156 +0,0 @@
1
- ---
2
- name: openspec-apply-change
3
- description: Implement tasks from an OpenSpec change. Use when the user wants to start implementing, continue implementation, or work through tasks.
4
- license: MIT
5
- compatibility: Requires openspec CLI.
6
- metadata:
7
- author: openspec
8
- version: "1.0"
9
- generatedBy: "1.1.1"
10
- ---
11
-
12
- Implement tasks from an OpenSpec change.
13
-
14
- **Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
15
-
16
- **Steps**
17
-
18
- 1. **Select the change**
19
-
20
- If a name is provided, use it. Otherwise:
21
- - Infer from conversation context if the user mentioned a change
22
- - Auto-select if only one active change exists
23
- - If ambiguous, run `openspec list --json` to get available changes and use the **AskUserQuestion tool** to let the user select
24
-
25
- Always announce: "Using change: <name>" and how to override (e.g., `/opsx:apply <other>`).
26
-
27
- 2. **Check status to understand the schema**
28
- ```bash
29
- openspec status --change "<name>" --json
30
- ```
31
- Parse the JSON to understand:
32
- - `schemaName`: The workflow being used (e.g., "spec-driven")
33
- - Which artifact contains the tasks (typically "tasks" for spec-driven, check status for others)
34
-
35
- 3. **Get apply instructions**
36
-
37
- ```bash
38
- openspec instructions apply --change "<name>" --json
39
- ```
40
-
41
- This returns:
42
- - Context file paths (varies by schema - could be proposal/specs/design/tasks or spec/tests/implementation/docs)
43
- - Progress (total, complete, remaining)
44
- - Task list with status
45
- - Dynamic instruction based on current state
46
-
47
- **Handle states:**
48
- - If `state: "blocked"` (missing artifacts): show message, suggest using openspec-continue-change
49
- - If `state: "all_done"`: congratulate, suggest archive
50
- - Otherwise: proceed to implementation
51
-
52
- 4. **Read context files**
53
-
54
- Read the files listed in `contextFiles` from the apply instructions output.
55
- The files depend on the schema being used:
56
- - **spec-driven**: proposal, specs, design, tasks
57
- - Other schemas: follow the contextFiles from CLI output
58
-
59
- 5. **Show current progress**
60
-
61
- Display:
62
- - Schema being used
63
- - Progress: "N/M tasks complete"
64
- - Remaining tasks overview
65
- - Dynamic instruction from CLI
66
-
67
- 6. **Implement tasks (loop until done or blocked)**
68
-
69
- For each pending task:
70
- - Show which task is being worked on
71
- - Make the code changes required
72
- - Keep changes minimal and focused
73
- - Mark task complete in the tasks file: `- [ ]` → `- [x]`
74
- - Continue to next task
75
-
76
- **Pause if:**
77
- - Task is unclear → ask for clarification
78
- - Implementation reveals a design issue → suggest updating artifacts
79
- - Error or blocker encountered → report and wait for guidance
80
- - User interrupts
81
-
82
- 7. **On completion or pause, show status**
83
-
84
- Display:
85
- - Tasks completed this session
86
- - Overall progress: "N/M tasks complete"
87
- - If all done: suggest archive
88
- - If paused: explain why and wait for guidance
89
-
90
- **Output During Implementation**
91
-
92
- ```
93
- ## Implementing: <change-name> (schema: <schema-name>)
94
-
95
- Working on task 3/7: <task description>
96
- [...implementation happening...]
97
- ✓ Task complete
98
-
99
- Working on task 4/7: <task description>
100
- [...implementation happening...]
101
- ✓ Task complete
102
- ```
103
-
104
- **Output On Completion**
105
-
106
- ```
107
- ## Implementation Complete
108
-
109
- **Change:** <change-name>
110
- **Schema:** <schema-name>
111
- **Progress:** 7/7 tasks complete ✓
112
-
113
- ### Completed This Session
114
- - [x] Task 1
115
- - [x] Task 2
116
- ...
117
-
118
- All tasks complete! Ready to archive this change.
119
- ```
120
-
121
- **Output On Pause (Issue Encountered)**
122
-
123
- ```
124
- ## Implementation Paused
125
-
126
- **Change:** <change-name>
127
- **Schema:** <schema-name>
128
- **Progress:** 4/7 tasks complete
129
-
130
- ### Issue Encountered
131
- <description of the issue>
132
-
133
- **Options:**
134
- 1. <option 1>
135
- 2. <option 2>
136
- 3. Other approach
137
-
138
- What would you like to do?
139
- ```
140
-
141
- **Guardrails**
142
- - Keep going through tasks until done or blocked
143
- - Always read context files before starting (from the apply instructions output)
144
- - If task is ambiguous, pause and ask before implementing
145
- - If implementation reveals issues, pause and suggest artifact updates
146
- - Keep code changes minimal and scoped to each task
147
- - Update task checkbox immediately after completing each task
148
- - Pause on errors, blockers, or unclear requirements - don't guess
149
- - Use contextFiles from CLI output, don't assume specific file names
150
-
151
- **Fluid Workflow Integration**
152
-
153
- This skill supports the "actions on a change" model:
154
-
155
- - **Can be invoked anytime**: Before all artifacts are done (if tasks exist), after partial implementation, interleaved with other actions
156
- - **Allows artifact updates**: If implementation reveals design issues, suggest updating artifacts - not phase-locked, work fluidly