specrails-core 4.8.1 → 4.9.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.
- package/bin/specrails-core.mjs +5 -1
- package/bin/tui-installer.mjs +87 -65
- package/dist/installer/cli.js +46 -6
- package/dist/installer/cli.js.map +1 -1
- package/dist/installer/commands/doctor.js +14 -5
- package/dist/installer/commands/doctor.js.map +1 -1
- package/dist/installer/commands/framework.js +134 -0
- package/dist/installer/commands/framework.js.map +1 -0
- package/dist/installer/commands/init.js +107 -32
- package/dist/installer/commands/init.js.map +1 -1
- package/dist/installer/commands/update.js +60 -34
- package/dist/installer/commands/update.js.map +1 -1
- package/dist/installer/phases/scaffold.js +592 -67
- package/dist/installer/phases/scaffold.js.map +1 -1
- package/dist/installer/util/fs.js +143 -1
- package/dist/installer/util/fs.js.map +1 -1
- package/dist/installer/util/registry.js +339 -0
- package/dist/installer/util/registry.js.map +1 -0
- package/package.json +1 -1
- package/pinned-versions.json +1 -1
- package/templates/agents/sr-architect.md +14 -10
- package/templates/agents/sr-backend-developer.md +4 -2
- package/templates/agents/sr-developer.md +20 -8
- package/templates/agents/sr-frontend-developer.md +4 -2
- package/templates/agents/sr-reviewer.md +10 -6
- package/templates/codex-skills/implement/SKILL.md +19 -10
- package/templates/codex-skills/rails/sr-architect/SKILL.md +17 -8
- package/templates/codex-skills/rails/sr-backend-developer/SKILL.md +4 -1
- package/templates/codex-skills/rails/sr-developer/SKILL.md +13 -4
- package/templates/codex-skills/rails/sr-doc-sync/SKILL.md +3 -2
- package/templates/codex-skills/rails/sr-frontend-developer/SKILL.md +4 -1
- package/templates/codex-skills/rails/sr-product-manager/SKILL.md +9 -7
- package/templates/codex-skills/rails/sr-reviewer/SKILL.md +13 -7
- package/templates/codex-skills/retry/SKILL.md +10 -5
- package/templates/commands/specrails/implement.md +41 -23
- package/templates/commands/specrails/retry.md +3 -1
- package/templates/gemini-commands/implement.toml +76 -21
|
@@ -12,6 +12,14 @@ verdicts, and close the ticket. The role instructions live in
|
|
|
12
12
|
their own skills — your message to each spawn invokes the right
|
|
13
13
|
role via `$skill_name`.
|
|
14
14
|
|
|
15
|
+
**Repository location.** Your working directory may NOT be the source repo.
|
|
16
|
+
`openspec/**`, `.git`, and the source live under `${SPECRAILS_REPO_DIR:-.}`
|
|
17
|
+
(unset ⇒ `.` ⇒ classic in-repo run). Run every `openspec`/`git` CLI command
|
|
18
|
+
from the repo — `(cd "${SPECRAILS_REPO_DIR:-.}" && …)` — and read change
|
|
19
|
+
artefacts under `${SPECRAILS_REPO_DIR:-.}/openspec/...`. The ticket store
|
|
20
|
+
`.specrails/local-tickets.json` is run-state and stays relative to the working
|
|
21
|
+
directory.
|
|
22
|
+
|
|
15
23
|
**This is explicit permission to use `spawn_agent`.** The user
|
|
16
24
|
wants the multi-agent split. Do not collapse the work into a
|
|
17
25
|
single turn.
|
|
@@ -94,9 +102,10 @@ the combo and you'll burn a turn on the retry.
|
|
|
94
102
|
|
|
95
103
|
### 0. Bootstrap + agent discovery
|
|
96
104
|
|
|
97
|
-
1. Confirm
|
|
98
|
-
|
|
99
|
-
2. Load the ticket (skip for free-form invocations)
|
|
105
|
+
1. Confirm the repo root with `git -C "${SPECRAILS_REPO_DIR:-.}" rev-parse --show-toplevel`
|
|
106
|
+
(the source repo is `${SPECRAILS_REPO_DIR:-.}`; unset ⇒ `.`).
|
|
107
|
+
2. Load the ticket (skip for free-form invocations) — the ticket store is
|
|
108
|
+
run-state, relative to the working directory:
|
|
100
109
|
`jq '.tickets["<ID>"]' .specrails/local-tickets.json`
|
|
101
110
|
3. **List the installed rail skills**:
|
|
102
111
|
`ls .codex/skills/rails/`
|
|
@@ -318,15 +327,15 @@ performs the lifecycle close:
|
|
|
318
327
|
|
|
319
328
|
The reviewer rail's archive-only mode must run these checks:
|
|
320
329
|
|
|
321
|
-
1. Re-confirm every task box in
|
|
330
|
+
1. Re-confirm every task box in `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/tasks.md`
|
|
322
331
|
is ticked (`- [x]`) and the change validates:
|
|
323
|
-
`openspec validate "<slug>" --strict`.
|
|
324
|
-
2. Archive it: `openspec archive "<slug>" -y` — this updates the
|
|
325
|
-
main specs and moves the change to
|
|
332
|
+
`(cd "${SPECRAILS_REPO_DIR:-.}" && openspec validate "<slug>" --strict)`.
|
|
333
|
+
2. Archive it: `(cd "${SPECRAILS_REPO_DIR:-.}" && openspec archive "<slug>" -y)` — this updates the
|
|
334
|
+
main specs and moves the change to `${SPECRAILS_REPO_DIR:-.}/openspec/changes/archive/`.
|
|
326
335
|
3. **Verify the archive landed — do NOT assume success.** Confirm
|
|
327
|
-
|
|
328
|
-
(`ls -d openspec/changes/archive/*<slug>* 2>/dev/null`) AND that
|
|
329
|
-
|
|
336
|
+
`${SPECRAILS_REPO_DIR:-.}/openspec/changes/archive/` now contains the slug
|
|
337
|
+
(`ls -d "${SPECRAILS_REPO_DIR:-.}"/openspec/changes/archive/*<slug>* 2>/dev/null`) AND that
|
|
338
|
+
`${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/` is gone. If the archive directory is
|
|
330
339
|
absent, archiving FAILED.
|
|
331
340
|
4. If `openspec validate`, `openspec archive`, or the step-3
|
|
332
341
|
verification fails: do NOT mark the ticket `done`. Treat the run
|
|
@@ -10,10 +10,17 @@ orchestrator already loaded the ticket and surveyed the repo before
|
|
|
10
10
|
spawning you. Your turn is short, focused, and ends with TWO
|
|
11
11
|
written artefacts: an OpenSpec change package and a plan artefact.
|
|
12
12
|
|
|
13
|
+
**Repository location.** `openspec/**`, `.git`, and the source live under
|
|
14
|
+
`${SPECRAILS_REPO_DIR:-.}` (unset ⇒ `.` ⇒ classic in-repo run). Run every
|
|
15
|
+
`openspec` CLI command from the repo — `(cd "${SPECRAILS_REPO_DIR:-.}" && openspec …)`
|
|
16
|
+
— and read/write change artefacts under `${SPECRAILS_REPO_DIR:-.}/openspec/...`.
|
|
17
|
+
Your plan artefact under `.specrails/agent-memory/` is run-state and stays
|
|
18
|
+
relative to the working directory.
|
|
19
|
+
|
|
13
20
|
## Your scope
|
|
14
21
|
|
|
15
22
|
You **plan**. You do not write production code. You do not edit
|
|
16
|
-
source files outside
|
|
23
|
+
source files outside `${SPECRAILS_REPO_DIR:-.}/openspec/` and `.specrails/agent-memory/`.
|
|
17
24
|
|
|
18
25
|
## What you produce
|
|
19
26
|
|
|
@@ -25,15 +32,15 @@ scaffolding so the change is registered with a workflow schema and
|
|
|
25
32
|
stays trackable by `openspec status`. Run:
|
|
26
33
|
|
|
27
34
|
```
|
|
28
|
-
openspec new change "<slug>" --schema spec-driven
|
|
35
|
+
(cd "${SPECRAILS_REPO_DIR:-.}" && openspec new change "<slug>" --schema spec-driven)
|
|
29
36
|
```
|
|
30
37
|
|
|
31
38
|
where `<slug>` is a kebab-case derivation of the ticket title
|
|
32
39
|
(e.g. ticket "Build a Playable Tetris Game" → `add-tetris-game`).
|
|
33
|
-
This creates
|
|
40
|
+
This creates `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/.openspec.yaml`.
|
|
34
41
|
|
|
35
42
|
- If the command fails because OpenSpec isn't initialised in this
|
|
36
|
-
repo, run `openspec init . --tools codex --force` once, then
|
|
43
|
+
repo, run `(cd "${SPECRAILS_REPO_DIR:-.}" && openspec init . --tools codex --force)` once, then
|
|
37
44
|
re-run `openspec new change …`.
|
|
38
45
|
- If the change directory already exists from a prior run,
|
|
39
46
|
**reuse** it (idempotent) — skip the `new change` call.
|
|
@@ -44,10 +51,10 @@ tasks). Check the order and what's still outstanding at any time
|
|
|
44
51
|
with:
|
|
45
52
|
|
|
46
53
|
```
|
|
47
|
-
openspec status --change "<slug>" --json
|
|
54
|
+
(cd "${SPECRAILS_REPO_DIR:-.}" && openspec status --change "<slug>" --json)
|
|
48
55
|
```
|
|
49
56
|
|
|
50
|
-
Write these four artefacts into
|
|
57
|
+
Write these four artefacts into `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/`:
|
|
51
58
|
|
|
52
59
|
**`proposal.md`** — the change's executive summary:
|
|
53
60
|
|
|
@@ -256,9 +263,11 @@ on the touched files as a fallback.>
|
|
|
256
263
|
When BOTH the OpenSpec change package and the plan artefact are
|
|
257
264
|
written:
|
|
258
265
|
|
|
259
|
-
1. **Validate the change with the OpenSpec CLI** (mandatory)
|
|
266
|
+
1. **Validate the change with the OpenSpec CLI** (mandatory). The
|
|
267
|
+
OpenSpec project root is `${SPECRAILS_REPO_DIR:-.}` (the repo),
|
|
268
|
+
NOT the workspace cwd — so run it scoped to the repo:
|
|
260
269
|
```
|
|
261
|
-
openspec validate "<slug>"
|
|
270
|
+
(cd "${SPECRAILS_REPO_DIR:-.}" && openspec validate "<slug>")
|
|
262
271
|
```
|
|
263
272
|
If validation reports structural errors, fix the offending
|
|
264
273
|
artefact and re-run until it passes. Do not hand off a change
|
|
@@ -15,8 +15,11 @@ for changes that are neither, `$sr-developer`.
|
|
|
15
15
|
## Your scope
|
|
16
16
|
|
|
17
17
|
Same TDD contract as `$sr-developer` — read the architect's
|
|
18
|
-
plan, walk
|
|
18
|
+
plan, walk `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/tasks.md` in order, write
|
|
19
19
|
the failing test first, then production code, re-run, tick.
|
|
20
|
+
(openspec + the source files named in `tasks.md` live under
|
|
21
|
+
`${SPECRAILS_REPO_DIR:-.}` — unset ⇒ `.` ⇒ classic in-repo run; edit each
|
|
22
|
+
source file as `${SPECRAILS_REPO_DIR:-.}/<path>`.)
|
|
20
23
|
|
|
21
24
|
What's different: you bias the test surface toward integration
|
|
22
25
|
and contract correctness, not isolated unit happy paths.
|
|
@@ -5,6 +5,15 @@ license: MIT
|
|
|
5
5
|
compatibility: "Codex-native. Designed to run as a full-history sub-agent fork of the implement orchestrator."
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
**Repository location.** Your working directory may NOT be the source
|
|
9
|
+
repo. `openspec/**` and the source files named in `tasks.md` (repo-relative
|
|
10
|
+
paths like `src/foo.ts`) live under `${SPECRAILS_REPO_DIR:-.}` — unset ⇒ `.`
|
|
11
|
+
⇒ byte-identical to a classic in-repo run. Read openspec from
|
|
12
|
+
`${SPECRAILS_REPO_DIR:-.}/openspec/...` and edit every source file as
|
|
13
|
+
`${SPECRAILS_REPO_DIR:-.}/<path>`. Run-state you write (`.specrails/agent-memory/`)
|
|
14
|
+
stays relative to the working directory; `.specrails/local-tickets.json` is
|
|
15
|
+
likewise relative (and owned by the orchestrator — you never write it).
|
|
16
|
+
|
|
8
17
|
You are the **developer** in the specrails implement pipeline. The
|
|
9
18
|
architect produced an OpenSpec change package (proposal + design +
|
|
10
19
|
tasks + spec deltas) and a plan artefact. Your job is to **apply**
|
|
@@ -27,14 +36,14 @@ note it in your reply — do not block on the architect.
|
|
|
27
36
|
1. **Read the inputs**, in this order:
|
|
28
37
|
- `<plan-path>` (the architect's plan artefact under
|
|
29
38
|
`.specrails/agent-memory/explanations/`).
|
|
30
|
-
-
|
|
31
|
-
-
|
|
39
|
+
- `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/proposal.md` — the why + what.
|
|
40
|
+
- `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/design.md` — the deep design.
|
|
32
41
|
Read **every section**, especially "Architecture", "Data
|
|
33
42
|
shapes", "State & lifecycle", "Public API / surface",
|
|
34
43
|
"Trade-offs" (so you know what NOT to revisit), and "Open
|
|
35
44
|
questions".
|
|
36
|
-
-
|
|
37
|
-
-
|
|
45
|
+
- `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/tasks.md` — your execution checklist.
|
|
46
|
+
- `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/specs/<cap>/spec.md` — the
|
|
38
47
|
behavioural contracts the tests must encode.
|
|
39
48
|
|
|
40
49
|
**About design.md's "Open questions" section** — if the
|
|
@@ -29,8 +29,9 @@ Two ways:
|
|
|
29
29
|
specrails-managed:start -->` … `<!--
|
|
30
30
|
specrails-managed:end -->` block. Outside that block
|
|
31
31
|
is user-authored; don't touch it.
|
|
32
|
-
-
|
|
33
|
-
-
|
|
32
|
+
- `${SPECRAILS_REPO_DIR:-.}/docs/` (any markdown files; repo-resident — unset
|
|
33
|
+
`SPECRAILS_REPO_DIR` ⇒ `.` ⇒ classic in-repo run).
|
|
34
|
+
- `${SPECRAILS_REPO_DIR:-.}/openspec/specs/<capability>/spec.md` (capabilities
|
|
34
35
|
documentation — drift here is the most serious; this
|
|
35
36
|
is the contract).
|
|
36
37
|
- Inline JSDoc / TSDoc / Python docstrings on exported
|
|
@@ -15,9 +15,12 @@ instead.
|
|
|
15
15
|
## Your scope
|
|
16
16
|
|
|
17
17
|
Same TDD contract as `$sr-developer` — read the architect's
|
|
18
|
-
plan, walk
|
|
18
|
+
plan, walk `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/tasks.md` in order, write
|
|
19
19
|
the failing test first, then the production code, then re-run.
|
|
20
20
|
Tick boxes only after observing the expected runner state.
|
|
21
|
+
(openspec + the source files named in `tasks.md` live under
|
|
22
|
+
`${SPECRAILS_REPO_DIR:-.}` — unset ⇒ `.` ⇒ classic in-repo run; edit each
|
|
23
|
+
source file as `${SPECRAILS_REPO_DIR:-.}/<path>`.)
|
|
21
24
|
|
|
22
25
|
What's different: you bias the test surface toward UI.
|
|
23
26
|
|
|
@@ -25,14 +25,16 @@ Two ways:
|
|
|
25
25
|
|
|
26
26
|
### 1. Read the existing artefacts
|
|
27
27
|
|
|
28
|
-
- `
|
|
29
|
-
-
|
|
28
|
+
(Repo-resident reads live under `${SPECRAILS_REPO_DIR:-.}` — unset ⇒ `.` ⇒
|
|
29
|
+
classic in-repo run.)
|
|
30
|
+
- `${SPECRAILS_REPO_DIR:-.}/README.md` (project intent and surface).
|
|
31
|
+
- `${SPECRAILS_REPO_DIR:-.}/openspec/specs/` (existing specs — what the product
|
|
30
32
|
contract is today).
|
|
31
|
-
- `.specrails/local-tickets.json` (existing backlog —
|
|
32
|
-
don't propose duplicates).
|
|
33
|
-
- A representative slice of the source code (5-10 files
|
|
34
|
-
drawn from the relevant theme).
|
|
35
|
-
- The desktop app's own
|
|
33
|
+
- `.specrails/local-tickets.json` (existing backlog — run-state, relative to
|
|
34
|
+
the working directory — don't propose duplicates).
|
|
35
|
+
- A representative slice of the source code (5-10 files under
|
|
36
|
+
`${SPECRAILS_REPO_DIR:-.}`, drawn from the relevant theme).
|
|
37
|
+
- The desktop app's own `${SPECRAILS_REPO_DIR:-.}/openspec/specs/` if relevant
|
|
36
38
|
(cross-component changes).
|
|
37
39
|
|
|
38
40
|
### 2. Identify gaps
|
|
@@ -11,6 +11,12 @@ implemented it. Your job is to validate the **whole** implementation
|
|
|
11
11
|
against ALL the artefacts the architect left, not just spot-check
|
|
12
12
|
the code. You emit a structured verdict and never touch the code.
|
|
13
13
|
|
|
14
|
+
**Repository location.** `openspec/**`, `.git`, and the source live under
|
|
15
|
+
`${SPECRAILS_REPO_DIR:-.}` (unset ⇒ `.` ⇒ classic in-repo run). Read change
|
|
16
|
+
artefacts from `${SPECRAILS_REPO_DIR:-.}/openspec/...`, and run every `openspec`
|
|
17
|
+
CLI, `git`, build, and test command from the repo —
|
|
18
|
+
`(cd "${SPECRAILS_REPO_DIR:-.}" && …)`.
|
|
19
|
+
|
|
14
20
|
## Your scope
|
|
15
21
|
|
|
16
22
|
You **validate**. You read every artefact, you re-run every check,
|
|
@@ -23,12 +29,12 @@ the completed OpenSpec change with the `openspec` CLI.
|
|
|
23
29
|
|
|
24
30
|
### 1. Validate the OpenSpec change package
|
|
25
31
|
|
|
26
|
-
Load
|
|
32
|
+
Load `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/` (the orchestrator gave you the
|
|
27
33
|
slug). **Run the OpenSpec validator first** — it is the canonical
|
|
28
34
|
structural check and is mandatory:
|
|
29
35
|
|
|
30
36
|
```
|
|
31
|
-
openspec validate "<slug>" --strict --json
|
|
37
|
+
(cd "${SPECRAILS_REPO_DIR:-.}" && openspec validate "<slug>" --strict --json)
|
|
32
38
|
```
|
|
33
39
|
|
|
34
40
|
A non-empty error list is a blocker finding: record each under
|
|
@@ -200,13 +206,13 @@ orchestrator has aggregated all reviewer verdicts. Therefore:
|
|
|
200
206
|
When archiving is authorized and the verdict is clean, run these exact
|
|
201
207
|
checks in order:
|
|
202
208
|
|
|
203
|
-
1. Re-run `openspec validate "<slug>" --strict`.
|
|
204
|
-
2. Read
|
|
209
|
+
1. Re-run `(cd "${SPECRAILS_REPO_DIR:-.}" && openspec validate "<slug>" --strict)`.
|
|
210
|
+
2. Read `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/tasks.md` and search for unchecked
|
|
205
211
|
tasks (`- [ ]`). If any remain, do not archive; change the verdict to
|
|
206
212
|
`fix needed: OpenSpec tasks remain unchecked`.
|
|
207
|
-
3. Run `openspec archive "<slug>" -y`.
|
|
208
|
-
4. Verify the archive landed: confirm
|
|
209
|
-
and
|
|
213
|
+
3. Run `(cd "${SPECRAILS_REPO_DIR:-.}" && openspec archive "<slug>" -y)`.
|
|
214
|
+
4. Verify the archive landed: confirm `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/` is gone
|
|
215
|
+
and `${SPECRAILS_REPO_DIR:-.}/openspec/changes/archive/` contains a directory whose name
|
|
210
216
|
includes `<slug>`.
|
|
211
217
|
|
|
212
218
|
If validation, archive, or verification fails, do not report `clean`.
|
|
@@ -13,9 +13,14 @@ You are NOT a separate pipeline. You inspect what `$implement`
|
|
|
13
13
|
left behind, summarise the current state, and re-invoke
|
|
14
14
|
`$implement` with a hint about what's already in place. The
|
|
15
15
|
implement skill is idempotent — architect reuses an existing
|
|
16
|
-
|
|
16
|
+
`${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/`, developer detects ticked tasks and
|
|
17
17
|
already-correct files, reviewer re-validates from scratch.
|
|
18
18
|
|
|
19
|
+
**Repository location.** `openspec/**` and `.git` live under
|
|
20
|
+
`${SPECRAILS_REPO_DIR:-.}` (unset ⇒ `.` ⇒ classic in-repo run); inspect change
|
|
21
|
+
artefacts there. The ticket store and `.specrails/agent-memory/` are run-state,
|
|
22
|
+
relative to the working directory.
|
|
23
|
+
|
|
19
24
|
## How the user invokes you
|
|
20
25
|
|
|
21
26
|
- `$retry #N` — retry the implement run for ticket `N`.
|
|
@@ -25,8 +30,8 @@ already-correct files, reviewer re-validates from scratch.
|
|
|
25
30
|
|
|
26
31
|
### 0. Locate the prior run's artefacts
|
|
27
32
|
|
|
28
|
-
1. Confirm
|
|
29
|
-
2. Load the ticket:
|
|
33
|
+
1. Confirm the repo root with `git -C "${SPECRAILS_REPO_DIR:-.}" rev-parse --show-toplevel`.
|
|
34
|
+
2. Load the ticket (run-state, relative to the working directory):
|
|
30
35
|
`jq '.tickets["<ID>"]' .specrails/local-tickets.json`. If
|
|
31
36
|
the ticket doesn't exist, stop and report.
|
|
32
37
|
3. Inspect what's already on disk for this ticket:
|
|
@@ -34,11 +39,11 @@ already-correct files, reviewer re-validates from scratch.
|
|
|
34
39
|
`.specrails/agent-memory/explanations/` named
|
|
35
40
|
`*-architect-ticket-<ID>.md`. List the latest.
|
|
36
41
|
- **OpenSpec change package**: any
|
|
37
|
-
|
|
42
|
+
`${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/` whose proposal.md mentions
|
|
38
43
|
the ticket title or whose tasks.md has tasks scoped to
|
|
39
44
|
the ticket. Find the slug.
|
|
40
45
|
- **tasks.md progress**: count `[x]` vs `[ ]` boxes in
|
|
41
|
-
|
|
46
|
+
`${SPECRAILS_REPO_DIR:-.}/openspec/changes/<slug>/tasks.md`.
|
|
42
47
|
- **Reviewer verdict**: latest matching
|
|
43
48
|
`*-reviewer-ticket-<ID>.confidence-score.json`. Read
|
|
44
49
|
the issues list and overall score.
|
|
@@ -14,6 +14,20 @@ Full OpenSpec lifecycle with specialized agents: architect designs, developer im
|
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
+
## Repository location (read first)
|
|
18
|
+
|
|
19
|
+
Your working directory may NOT be the user's source repository. **Repo-resident** things — the source code, `openspec/**`, `.git`, and the GitHub remote — live under **`${SPECRAILS_REPO_DIR:-.}`**. The spawner sets `SPECRAILS_REPO_DIR` to the repo path; **when it is unset it defaults to `.` (the current directory), making every command below byte-identical to a classic in-repo run.**
|
|
20
|
+
|
|
21
|
+
Rules used throughout this pipeline:
|
|
22
|
+
- **openspec reads/writes** → `${SPECRAILS_REPO_DIR:-.}/openspec/...`
|
|
23
|
+
- **git commands** → `git -C "${SPECRAILS_REPO_DIR:-.}" ...`
|
|
24
|
+
- **`gh` commands** (issue/PR — they need the repo's remote) → run them from the repo: `(cd "${SPECRAILS_REPO_DIR:-.}" && gh ...)`
|
|
25
|
+
- **worktree merge-back** → the merge *target* side (the main working tree) is `${SPECRAILS_REPO_DIR:-.}/<file>`
|
|
26
|
+
|
|
27
|
+
**Run-state stays with the working directory** (NOT the repo): `.claude/pipeline-state/`, `.claude/agent-memory/`, `.claude/backlog-cache.json`, and the dry-run cache `.claude/.dry-run/` are all written relative to the current directory. **Profile/agent files** (`.claude/agents/sr-*.md`) are likewise resolved relative to the current directory — do NOT prefix them with `${SPECRAILS_REPO_DIR:-.}`.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
17
31
|
## Phase -1: Environment Setup (cloud pre-flight)
|
|
18
32
|
|
|
19
33
|
**This phase runs BEFORE anything else.** Detect if we're in a cloud/remote environment and ensure all required tools are available.
|
|
@@ -353,7 +367,7 @@ If the write fails: print `[backlog-cache] Warning: could not write cache. Confl
|
|
|
353
367
|
For each resolved issue number, run:
|
|
354
368
|
|
|
355
369
|
```bash
|
|
356
|
-
gh issue view {number} --json number,title,state,assignees,labels,body,updatedAt
|
|
370
|
+
(cd "${SPECRAILS_REPO_DIR:-.}" && gh issue view {number} --json number,title,state,assignees,labels,body,updatedAt)
|
|
357
371
|
```
|
|
358
372
|
|
|
359
373
|
Build a snapshot object for each issue:
|
|
@@ -502,7 +516,7 @@ Otherwise, re-fetch each issue in scope and diff against the Phase 0 snapshot:
|
|
|
502
516
|
**If `BACKLOG_PROVIDER=github`:** For each issue number in `ISSUE_REFS`:
|
|
503
517
|
|
|
504
518
|
```bash
|
|
505
|
-
gh issue view {number} --json number,title,state,assignees,labels,body,updatedAt
|
|
519
|
+
(cd "${SPECRAILS_REPO_DIR:-.}" && gh issue view {number} --json number,title,state,assignees,labels,body,updatedAt)
|
|
506
520
|
```
|
|
507
521
|
|
|
508
522
|
If the `gh` command returns non-zero (issue deleted or inaccessible): treat as a CRITICAL conflict — field `"state"`, was `<cached state>`, now `"deleted"`.
|
|
@@ -558,7 +572,7 @@ For `body_sha` rows in the table, display only the first 8 characters of each SH
|
|
|
558
572
|
|
|
559
573
|
For each chosen idea, launch an **sr-architect** agent (`subagent_type: sr-architect`, `run_in_background: true`).
|
|
560
574
|
|
|
561
|
-
Each architect creates OpenSpec artifacts in
|
|
575
|
+
Each architect creates OpenSpec artifacts in `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<name>/`.
|
|
562
576
|
|
|
563
577
|
Each agent's prompt should include:
|
|
564
578
|
- Description of the feature
|
|
@@ -574,7 +588,7 @@ After all architect agents complete, before launching any developer agent:
|
|
|
574
588
|
|
|
575
589
|
#### Step 1: Extract file references
|
|
576
590
|
|
|
577
|
-
For each
|
|
591
|
+
For each `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<name>/tasks.md`, extract all paths listed under `**Files:**` entries (both `Create:` and `Modify:` lines). Normalize paths: strip leading `./`.
|
|
578
592
|
|
|
579
593
|
#### Step 2: Build the shared-file registry
|
|
580
594
|
|
|
@@ -653,7 +667,7 @@ Before launching any developer agent, run a trivial Bash command to confirm Bash
|
|
|
653
667
|
|
|
654
668
|
#### Choosing the right developer agent
|
|
655
669
|
|
|
656
|
-
For each feature, read
|
|
670
|
+
For each feature, read `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<name>/tasks.md` and classify every task by its layer tags and file references.
|
|
657
671
|
|
|
658
672
|
**Step 1 — Classify tasks into layers:**
|
|
659
673
|
|
|
@@ -857,6 +871,8 @@ If a doc-sync agent fails or times out:
|
|
|
857
871
|
|
|
858
872
|
#### Merge Algorithm
|
|
859
873
|
|
|
874
|
+
The merge **target** (the main repo working tree where merged files land) is `<target>` = **`${SPECRAILS_REPO_DIR:-.}`**. Every `<target>/<file>` below therefore resolves to `${SPECRAILS_REPO_DIR:-.}/<file>` so merged code lands in the real repo, not the working directory. (`<worktree-path>` is an absolute git-worktree path supplied by the runtime; `git -C <worktree-path>` already targets it directly.)
|
|
875
|
+
|
|
860
876
|
Process features in `MERGE_ORDER` sequence. For each feature:
|
|
861
877
|
|
|
862
878
|
**Step 1: Identify changed files**
|
|
@@ -871,7 +887,7 @@ Split into `exclusive_files` (only this feature modifies them) and `shared_files
|
|
|
871
887
|
|
|
872
888
|
Copy directly from worktree to target:
|
|
873
889
|
```bash
|
|
874
|
-
cp <worktree-path>/<file>
|
|
890
|
+
cp <worktree-path>/<file> "${SPECRAILS_REPO_DIR:-.}"/<file>
|
|
875
891
|
```
|
|
876
892
|
Log: `Copied (exclusive): <file>`
|
|
877
893
|
|
|
@@ -880,7 +896,7 @@ Log: `Copied (exclusive): <file>`
|
|
|
880
896
|
For each shared file, choose strategy by file type:
|
|
881
897
|
|
|
882
898
|
**Strategy A — Markdown section-aware merge** (`.md` files):
|
|
883
|
-
1. Read base: current content of
|
|
899
|
+
1. Read base: current content of `${SPECRAILS_REPO_DIR:-.}/<file>` (the merge target).
|
|
884
900
|
2. Read incoming: `<worktree-path>/<file>`.
|
|
885
901
|
3. Parse both into sections using `##` heading boundaries (heading line + all content until next `##` or EOF).
|
|
886
902
|
4. Build section maps: `{heading_text: content}` for base and incoming.
|
|
@@ -897,7 +913,7 @@ For each shared file, choose strategy by file type:
|
|
|
897
913
|
>>>>>>> base
|
|
898
914
|
```
|
|
899
915
|
Log: `CONFLICT: <file> — section "<heading>" requires manual resolution.`
|
|
900
|
-
6. Write merged result to
|
|
916
|
+
6. Write merged result to `${SPECRAILS_REPO_DIR:-.}/<file>` (the merge target).
|
|
901
917
|
|
|
902
918
|
**Strategy B — Unified diff sequential apply** (all other file types):
|
|
903
919
|
1. Generate incoming diff against original `main`:
|
|
@@ -906,7 +922,7 @@ For each shared file, choose strategy by file type:
|
|
|
906
922
|
```
|
|
907
923
|
2. Apply to current target:
|
|
908
924
|
```bash
|
|
909
|
-
patch --forward --fuzz=3
|
|
925
|
+
patch --forward --fuzz=3 "${SPECRAILS_REPO_DIR:-.}"/<file> < <diff>
|
|
910
926
|
```
|
|
911
927
|
3. If `patch` succeeds: log `Merged (diff-apply): <file>`.
|
|
912
928
|
4. If `patch` fails: insert conflict markers around rejected hunks. Log: `CONFLICT: <file> — N hunks rejected.`
|
|
@@ -949,7 +965,7 @@ If `MERGE_REPORT.requires_resolution` is non-empty:
|
|
|
949
965
|
|
|
950
966
|
Build `CONTEXT_BUNDLES` from the features in `MERGE_ORDER`:
|
|
951
967
|
```
|
|
952
|
-
{ "<feature-a>": "openspec/changes/<feature-a>/context-bundle.md", "<feature-b>": "openspec/changes/<feature-b>/context-bundle.md" }
|
|
968
|
+
{ "<feature-a>": "${SPECRAILS_REPO_DIR:-.}/openspec/changes/<feature-a>/context-bundle.md", "<feature-b>": "${SPECRAILS_REPO_DIR:-.}/openspec/changes/<feature-b>/context-bundle.md" }
|
|
953
969
|
```
|
|
954
970
|
|
|
955
971
|
Load merge resolver config from `.claude/merge-resolver-config.json` if it exists. Extract `confidence_threshold` (default: 70) and `mode` (default: `auto`).
|
|
@@ -959,7 +975,7 @@ Construct the `sr-merge-resolver` agent prompt with:
|
|
|
959
975
|
- `CONTEXT_BUNDLES`: the map above
|
|
960
976
|
- `CONFIDENCE_THRESHOLD`: from config or default (70)
|
|
961
977
|
- `RESOLUTION_MODE`: from config or default (`auto`)
|
|
962
|
-
- `REPORT_PATH`:
|
|
978
|
+
- `REPORT_PATH`: `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<first-feature-in-MERGE_ORDER>/merge-resolution-report.md`
|
|
963
979
|
|
|
964
980
|
Launch the **sr-merge-resolver** agent (`subagent_type: sr-merge-resolver`, foreground, `run_in_background: false`). Wait for it to complete.
|
|
965
981
|
|
|
@@ -1107,7 +1123,7 @@ After the generalist reviewer agent completes, evaluate the confidence score bef
|
|
|
1107
1123
|
|
|
1108
1124
|
#### Step 1 — Read score file
|
|
1109
1125
|
|
|
1110
|
-
Path:
|
|
1126
|
+
Path: `${SPECRAILS_REPO_DIR:-.}/openspec/changes/<name>/confidence-score.json`
|
|
1111
1127
|
|
|
1112
1128
|
- If the file does not exist:
|
|
1113
1129
|
- Set `CONFIDENCE_STATUS=MISSING`
|
|
@@ -1213,7 +1229,7 @@ Re-fetch each issue in `ISSUE_REFS` and diff against `.claude/backlog-cache.json
|
|
|
1213
1229
|
|
|
1214
1230
|
**If `BACKLOG_PROVIDER=github`:**
|
|
1215
1231
|
```bash
|
|
1216
|
-
gh issue view {number} --json number,title,state,assignees,labels,body,updatedAt
|
|
1232
|
+
(cd "${SPECRAILS_REPO_DIR:-.}" && gh issue view {number} --json number,title,state,assignees,labels,body,updatedAt)
|
|
1217
1233
|
```
|
|
1218
1234
|
|
|
1219
1235
|
If the cache file is missing or malformed JSON at this point: log `[conflict-check] Warning: cache file missing or unreadable. Skipping diff for this run.` and proceed to Phase 4c (treat as clean).
|
|
@@ -1270,13 +1286,15 @@ This phase respects the `GIT_AUTO` and `BACKLOG_WRITE` settings from configurati
|
|
|
1270
1286
|
|
|
1271
1287
|
#### If `GIT_AUTO=true` (automatic shipping)
|
|
1272
1288
|
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1289
|
+
All git operations run against the repo via `git -C "${SPECRAILS_REPO_DIR:-.}"`, and `gh` runs from inside the repo so it can detect the remote.
|
|
1290
|
+
|
|
1291
|
+
1. Create branch from `main`: `git -C "${SPECRAILS_REPO_DIR:-.}" checkout -b feat/<descriptive-name>`
|
|
1292
|
+
2. One commit per feature with descriptive messages (`git -C "${SPECRAILS_REPO_DIR:-.}" add … && git -C "${SPECRAILS_REPO_DIR:-.}" commit -m …`)
|
|
1293
|
+
3. If the reviewer modified files, create an additional commit: `git -C "${SPECRAILS_REPO_DIR:-.}" commit -m "fix: resolve CI issues (reviewer)"`
|
|
1294
|
+
4. Push with `-u` flag: `git -C "${SPECRAILS_REPO_DIR:-.}" push -u origin <branch-name>`
|
|
1295
|
+
5. Create PR (if GitHub CLI is available), running it from the repo:
|
|
1278
1296
|
```bash
|
|
1279
|
-
{{PR_CREATE_CMD}}
|
|
1297
|
+
(cd "${SPECRAILS_REPO_DIR:-.}" && {{PR_CREATE_CMD}})
|
|
1280
1298
|
```
|
|
1281
1299
|
If `gh` is not authenticated, print a compare URL for manual PR creation.
|
|
1282
1300
|
|
|
@@ -1293,9 +1311,9 @@ All implementation is complete and CI checks pass.
|
|
|
1293
1311
|
- [list all modified/created files per feature]
|
|
1294
1312
|
|
|
1295
1313
|
### Suggested Next Steps
|
|
1296
|
-
1. Review the changes: `git diff`
|
|
1297
|
-
2. Create a branch: `git checkout -b feat/<name>`
|
|
1298
|
-
3. Stage and commit: `git add <files> && git commit -m "feat: ..."`
|
|
1314
|
+
1. Review the changes: `git -C "${SPECRAILS_REPO_DIR:-.}" diff`
|
|
1315
|
+
2. Create a branch: `git -C "${SPECRAILS_REPO_DIR:-.}" checkout -b feat/<name>`
|
|
1316
|
+
3. Stage and commit: `git -C "${SPECRAILS_REPO_DIR:-.}" add <files> && git -C "${SPECRAILS_REPO_DIR:-.}" commit -m "feat: ..."`
|
|
1299
1317
|
4. Push and create PR manually
|
|
1300
1318
|
```
|
|
1301
1319
|
|
|
@@ -1307,7 +1325,7 @@ All implementation is complete and CI checks pass.
|
|
|
1307
1325
|
{{BACKLOG_COMMENT_CMD}}
|
|
1308
1326
|
```
|
|
1309
1327
|
- **Local:** Update the ticket status to `"done"` using `{{BACKLOG_UPDATE_CMD}}` and add a comment: `"Implemented in PR #XX. All acceptance criteria met."` via `{{BACKLOG_COMMENT_CMD}}`. Local tickets are closed directly — there is no auto-close-on-merge mechanism.
|
|
1310
|
-
- **GitHub:** `gh issue comment {number} --body "Implemented in PR #XX. All acceptance criteria met."` — do NOT close the issue explicitly. Use `Closes #N` in the PR body so GitHub auto-closes on merge.
|
|
1328
|
+
- **GitHub:** `(cd "${SPECRAILS_REPO_DIR:-.}" && gh issue comment {number} --body "Implemented in PR #XX. All acceptance criteria met.")` — do NOT close the issue explicitly. Use `Closes #N` in the PR body so GitHub auto-closes on merge.
|
|
1311
1329
|
- **JIRA:** `jira issue comment {key} --message "Implemented in PR #XX. All acceptance criteria met."`
|
|
1312
1330
|
- For GitHub/JIRA: ensure the PR body includes `Closes #N` for each fully resolved issue (auto-closes on merge)
|
|
1313
1331
|
- For partially resolved issues/tickets: add a comment noting progress:
|
|
@@ -19,6 +19,8 @@ Resume a failed `/specrails:implement` run for **{{PROJECT_NAME}}**. Reads pipel
|
|
|
19
19
|
|
|
20
20
|
**MANDATORY: Follow this pipeline exactly. Do NOT skip phases or re-run phases that already succeeded. Read all context from the pipeline state file — do not rely on memory. Do not re-implement anything yourself; delegate to the same agents used by `/specrails:implement`.**
|
|
21
21
|
|
|
22
|
+
**Repository location.** Your working directory may NOT be the user's source repository. Repo-resident things — `openspec/**`, source, `.git`, the GitHub remote — live under **`${SPECRAILS_REPO_DIR:-.}`** (set by the spawner; unset ⇒ `.` ⇒ byte-identical to a classic in-repo run). The pipeline-state file itself is **run-state**, read from `.claude/pipeline-state/` relative to the working directory — do NOT prefix it. The `openspec_artifacts` value stored in that file is a repo-relative path (`openspec/changes/<name>/`); prefix it with `${SPECRAILS_REPO_DIR:-.}/` when you read those files on disk. All git/PR operations are delegated to `/specrails:implement` Phase 4c, which already runs them against the repo.
|
|
23
|
+
|
|
22
24
|
**Input:** $ARGUMENTS — accepted forms:
|
|
23
25
|
|
|
24
26
|
1. `<feature-name>` — kebab-case feature name matching a `.claude/pipeline-state/<feature-name>.json` file
|
|
@@ -214,7 +216,7 @@ Wait for all architects to complete.
|
|
|
214
216
|
Before launching, verify architect artifacts exist:
|
|
215
217
|
|
|
216
218
|
```bash
|
|
217
|
-
ls
|
|
219
|
+
ls "${SPECRAILS_REPO_DIR:-.}/<OPENSPEC_ARTIFACTS>tasks.md" "${SPECRAILS_REPO_DIR:-.}/<OPENSPEC_ARTIFACTS>context-bundle.md"
|
|
218
220
|
```
|
|
219
221
|
|
|
220
222
|
If missing and `RESUME_PHASE=developer`: print:
|