specrails-core 3.5.0 → 3.5.2
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 +1 -1
- package/commands/setup.md +23 -23
- package/docs/installation.md +1 -1
- package/docs/local-tickets.md +4 -4
- package/docs/migration-guide.md +4 -4
- package/docs/workflows.md +1 -1
- package/package.json +1 -1
- package/templates/commands/specrails/auto-propose-backlog-specs.md +4 -4
- package/templates/commands/specrails/get-backlog-specs.md +1 -1
- package/templates/commands/specrails/implement.md +5 -5
- package/templates/commands/specrails/propose-spec.md +1 -1
- package/templates/commands/specrails/setup.md +23 -23
- package/templates/skills/sr-auto-propose-backlog-specs/SKILL.md +3 -3
package/README.md
CHANGED
|
@@ -196,7 +196,7 @@ AI product discovery using your personas. Evaluates ideas, creates tickets (loca
|
|
|
196
196
|
|
|
197
197
|
specrails-core ships with a built-in ticket system — no GitHub account or external tools required.
|
|
198
198
|
|
|
199
|
-
Tickets live in `.
|
|
199
|
+
Tickets live in `.specrails/local-tickets.json` alongside your code. They're plain JSON and git-friendly.
|
|
200
200
|
|
|
201
201
|
**Local tickets are the default.** The `/specrails:setup` wizard defaults to local tickets and skips GitHub/JIRA credential setup unless you opt in.
|
|
202
202
|
|
package/commands/setup.md
CHANGED
|
@@ -59,7 +59,7 @@ Read the following files to understand the current installation state:
|
|
|
59
59
|
Command template files include `implement.md`, `batch-implement.md`, `compat-check.md`, `refactor-recommender.md`, `why.md`, `get-backlog-specs.md`, `auto-propose-backlog-specs.md`.
|
|
60
60
|
If this directory does not exist, skip command template checking for this update.
|
|
61
61
|
|
|
62
|
-
6. Read
|
|
62
|
+
6. Read `.specrails/backlog-config.json` if it exists — contains stored provider configuration needed for command placeholder substitution.
|
|
63
63
|
|
|
64
64
|
### Phase U2: Quick Codebase Re-Analysis
|
|
65
65
|
|
|
@@ -178,7 +178,7 @@ For each command in the "changed commands" list from Phase U3:
|
|
|
178
178
|
1. Read the NEW template:
|
|
179
179
|
- If `cli_provider == "claude"`: from `$SPECRAILS_DIR/setup-templates/commands/specrails/<name>.md`
|
|
180
180
|
- If `cli_provider == "codex"`: from `$SPECRAILS_DIR/setup-templates/skills/sr-<name>/SKILL.md`
|
|
181
|
-
2. Read stored backlog configuration from
|
|
181
|
+
2. Read stored backlog configuration from `.specrails/backlog-config.json` (if it exists) to resolve provider-specific placeholders:
|
|
182
182
|
- `BACKLOG_PROVIDER` → `provider` field (`github`, `jira`, or `none`)
|
|
183
183
|
- `BACKLOG_WRITE` → `write_access` field
|
|
184
184
|
- `JIRA_BASE_URL` → `jira_base_url` field
|
|
@@ -424,8 +424,8 @@ Core commands (always install if missing):
|
|
|
424
424
|
- `auto-propose-backlog-specs.md`
|
|
425
425
|
|
|
426
426
|
**Initialize local ticket storage** (backlog provider defaults to `local`):
|
|
427
|
-
1. Copy `templates/local-tickets-schema.json` to
|
|
428
|
-
2. Write
|
|
427
|
+
1. Copy `templates/local-tickets-schema.json` to `.specrails/local-tickets.json` and set `last_updated` to the current ISO-8601 timestamp. Skip if the file already exists.
|
|
428
|
+
2. Write `.specrails/backlog-config.json` (skip if already exists):
|
|
429
429
|
```json
|
|
430
430
|
{
|
|
431
431
|
"provider": "local",
|
|
@@ -699,7 +699,7 @@ Ask the user how they want to manage their product backlog. Default is local —
|
|
|
699
699
|
Use local ticket management or connect an external provider?
|
|
700
700
|
|
|
701
701
|
1. **Local tickets** (default, recommended) — lightweight JSON-based ticket management built into the project.
|
|
702
|
-
No external tools or accounts required. Tickets stored in `.
|
|
702
|
+
No external tools or accounts required. Tickets stored in `.specrails/local-tickets.json`, version-controlled and diffable.
|
|
703
703
|
2. **External provider** — connect GitHub Issues, JIRA, or disable backlog commands
|
|
704
704
|
```
|
|
705
705
|
|
|
@@ -713,7 +713,7 @@ If the user selects **2**: display the secondary menu:
|
|
|
713
713
|
Which external provider?
|
|
714
714
|
|
|
715
715
|
1. **Local tickets** (recommended) — lightweight JSON-based ticket management built into the project.
|
|
716
|
-
No external tools required. Tickets stored in `.
|
|
716
|
+
No external tools required. Tickets stored in `.specrails/local-tickets.json`, version-controlled and diffable.
|
|
717
717
|
2. **GitHub Issues** — uses `gh` CLI to read/create issues with labels and VPC scores
|
|
718
718
|
3. **JIRA** — uses JIRA CLI or REST API to read/create tickets in a JIRA project
|
|
719
719
|
4. **None** — skip backlog commands (you can still use /implement with text descriptions)
|
|
@@ -725,10 +725,10 @@ Wait for the user's choice. Set `BACKLOG_PROVIDER` to `local`, `github`, `jira`,
|
|
|
725
725
|
|
|
726
726
|
No external tools or credentials required. Initialize the storage file:
|
|
727
727
|
|
|
728
|
-
1. Copy `templates/local-tickets-schema.json` to
|
|
728
|
+
1. Copy `templates/local-tickets-schema.json` to `.specrails/local-tickets.json`
|
|
729
729
|
2. Set `last_updated` to the current ISO-8601 timestamp
|
|
730
730
|
|
|
731
|
-
Store configuration in
|
|
731
|
+
Store configuration in `.specrails/backlog-config.json`:
|
|
732
732
|
```json
|
|
733
733
|
{
|
|
734
734
|
"provider": "local",
|
|
@@ -774,13 +774,13 @@ Local tickets are always read-write — there is no "read only" mode since the f
|
|
|
774
774
|
|
|
775
775
|
The `revision` counter in the JSON root enables optimistic concurrency — increment it on **every** write. The lock file prevents concurrent corruption:
|
|
776
776
|
|
|
777
|
-
1. **Acquire lock:** Check for
|
|
777
|
+
1. **Acquire lock:** Check for `.specrails/local-tickets.json.lock`
|
|
778
778
|
- If the file exists and its `timestamp` is less than 30 seconds old: wait 500ms and retry (max 5 attempts before aborting with an error)
|
|
779
779
|
- If the file exists and its `timestamp` is 30+ seconds old (stale): delete it and proceed
|
|
780
780
|
- If no lock file exists: proceed immediately
|
|
781
|
-
2. **Create lock file:** Write `{"agent": "<agent-name-or-process>", "timestamp": "<ISO-8601>"}` to
|
|
781
|
+
2. **Create lock file:** Write `{"agent": "<agent-name-or-process>", "timestamp": "<ISO-8601>"}` to `.specrails/local-tickets.json.lock`
|
|
782
782
|
3. **Minimal lock window:** Read the JSON → modify in memory → write back → release
|
|
783
|
-
4. **Release lock:** Delete
|
|
783
|
+
4. **Release lock:** Delete `.specrails/local-tickets.json.lock`
|
|
784
784
|
5. **Always increment `revision`** by 1 and update `last_updated` on every successful write
|
|
785
785
|
|
|
786
786
|
The hub server uses `proper-lockfile` (or equivalent) to honor the same protocol via the `.lock` file path.
|
|
@@ -895,7 +895,7 @@ Ask:
|
|
|
895
895
|
|
|
896
896
|
Set `EPIC_LINK_FIELD` to `parent` or `customfield_10014`. Default: `parent`.
|
|
897
897
|
|
|
898
|
-
Store the full configuration in `.
|
|
898
|
+
Store the full configuration in `.specrails/backlog-config.json`:
|
|
899
899
|
```json
|
|
900
900
|
{
|
|
901
901
|
"provider": "jira",
|
|
@@ -1147,22 +1147,22 @@ When adapting `auto-propose-backlog-specs.md` and `get-backlog-specs.md`, substi
|
|
|
1147
1147
|
|
|
1148
1148
|
#### Local Tickets (`BACKLOG_PROVIDER=local`)
|
|
1149
1149
|
|
|
1150
|
-
For the local provider, backlog placeholders resolve to **inline file-operation instructions** embedded in the generated command markdown — not shell commands. Agents execute these by reading/writing
|
|
1150
|
+
For the local provider, backlog placeholders resolve to **inline file-operation instructions** embedded in the generated command markdown — not shell commands. Agents execute these by reading/writing `.specrails/local-tickets.json` directly using their file tools.
|
|
1151
1151
|
|
|
1152
1152
|
All write operations must follow the **advisory file locking protocol** defined in Phase 3.2. Always increment `revision` and update `last_updated` on every write.
|
|
1153
1153
|
|
|
1154
1154
|
| Placeholder | Substituted value |
|
|
1155
1155
|
|-------------|-------------------|
|
|
1156
1156
|
| `{{BACKLOG_PROVIDER_NAME}}` | `Local Tickets` |
|
|
1157
|
-
| `{{BACKLOG_PREFLIGHT}}` | `[[ -f "
|
|
1158
|
-
| `{{BACKLOG_FETCH_CMD}}` | Read
|
|
1159
|
-
| `{{BACKLOG_FETCH_ALL_CMD}}` | Read
|
|
1160
|
-
| `{{BACKLOG_FETCH_CLOSED_CMD}}` | Read
|
|
1161
|
-
| `{{BACKLOG_VIEW_CMD}}` | Read
|
|
1162
|
-
| `{{BACKLOG_CREATE_CMD}}` | Write to
|
|
1163
|
-
| `{{BACKLOG_UPDATE_CMD}}` | Write to
|
|
1164
|
-
| `{{BACKLOG_DELETE_CMD}}` | Write to
|
|
1165
|
-
| `{{BACKLOG_COMMENT_CMD}}` | Write to
|
|
1157
|
+
| `{{BACKLOG_PREFLIGHT}}` | `[[ -f ".specrails/local-tickets.json" ]] && echo "Local tickets storage: OK" \|\| echo "WARNING: .specrails/local-tickets.json not found — run /specrails:setup to initialize"` |
|
|
1158
|
+
| `{{BACKLOG_FETCH_CMD}}` | Read `.specrails/local-tickets.json`. Parse the `tickets` map and return all entries where `status` is `"todo"` or `"in_progress"`. |
|
|
1159
|
+
| `{{BACKLOG_FETCH_ALL_CMD}}` | Read `.specrails/local-tickets.json`. Parse the `tickets` map and return all entries regardless of status. |
|
|
1160
|
+
| `{{BACKLOG_FETCH_CLOSED_CMD}}` | Read `.specrails/local-tickets.json`. Parse the `tickets` map and return all entries where `status` is `"done"` or `"cancelled"`. |
|
|
1161
|
+
| `{{BACKLOG_VIEW_CMD}}` | Read `.specrails/local-tickets.json`. Parse JSON and return the full ticket object at `tickets["{id}"]`, or an error if not found. |
|
|
1162
|
+
| `{{BACKLOG_CREATE_CMD}}` | Write to `.specrails/local-tickets.json` using the advisory locking protocol: acquire lock → read file → set `id = next_id`, increment `next_id`, set all ticket fields, set `created_at` and `updated_at` to now, bump `revision`, update `last_updated` → write → release lock. |
|
|
1163
|
+
| `{{BACKLOG_UPDATE_CMD}}` | Write to `.specrails/local-tickets.json` using the advisory locking protocol: acquire lock → read file → update fields in `tickets["{id}"]`, set `updated_at` to now, bump `revision`, update `last_updated` → write → release lock. |
|
|
1164
|
+
| `{{BACKLOG_DELETE_CMD}}` | Write to `.specrails/local-tickets.json` using the advisory locking protocol: acquire lock → read file → delete `tickets["{id}"]`, bump `revision`, update `last_updated` → write → release lock. |
|
|
1165
|
+
| `{{BACKLOG_COMMENT_CMD}}` | Write to `.specrails/local-tickets.json` using the advisory locking protocol: acquire lock → read file → append `{"author": "<agent-name>", "body": "<comment>", "created_at": "<ISO-8601>"}` to `tickets["{id}"].comments` (create the array if absent), set `updated_at` to now, bump `revision`, update `last_updated` → write → release lock. |
|
|
1166
1166
|
| `{{BACKLOG_PARTIAL_COMMENT_CMD}}` | Same as `{{BACKLOG_COMMENT_CMD}}` but append `{"author": "<agent-name>", "body": "<comment>", "type": "progress", "created_at": "<ISO-8601>"}`. |
|
|
1167
1167
|
| `{{BACKLOG_INIT_LABELS_CMD}}` | No label initialization required. Local tickets use freeform label strings. Standard label conventions: `area:frontend`, `area:backend`, `area:api`, `effort:low`, `effort:medium`, `effort:high`. |
|
|
1168
1168
|
|
|
@@ -1183,7 +1183,7 @@ All write operations must follow the **advisory file locking protocol** defined
|
|
|
1183
1183
|
- Issue view: `jira issue view {key}` or REST API
|
|
1184
1184
|
- VPC scores stored in the issue description body (same markdown format, parsed from description)
|
|
1185
1185
|
- Pre-flight check: `jira me` or test API connectivity
|
|
1186
|
-
- Store JIRA config in
|
|
1186
|
+
- Store JIRA config in `.specrails/backlog-config.json`:
|
|
1187
1187
|
```json
|
|
1188
1188
|
{
|
|
1189
1189
|
"provider": "jira",
|
package/docs/installation.md
CHANGED
|
@@ -231,7 +231,7 @@ The quick path — three questions, sensible defaults, done in under a minute.
|
|
|
231
231
|
|------|--------|
|
|
232
232
|
| Core agents | sr-architect, sr-developer, sr-reviewer, sr-product-manager |
|
|
233
233
|
| All workflow commands | `/specrails:implement`, `/specrails:get-backlog-specs`, and 14 more |
|
|
234
|
-
| Backlog storage | Local tickets (`.
|
|
234
|
+
| Backlog storage | Local tickets (`.specrails/local-tickets.json`) — no GitHub or JIRA required |
|
|
235
235
|
| CLAUDE.md | Project-level context for agents |
|
|
236
236
|
|
|
237
237
|
You can run the full wizard later to deepen configuration: personas, stack analysis, layer-specific conventions.
|
package/docs/local-tickets.md
CHANGED
|
@@ -6,7 +6,7 @@ specrails-core ships with a built-in, file-based ticket management system. It is
|
|
|
6
6
|
|
|
7
7
|
## Overview
|
|
8
8
|
|
|
9
|
-
Tickets live in `.
|
|
9
|
+
Tickets live in `.specrails/local-tickets.json` at your project root. Because it's a plain JSON file, tickets are:
|
|
10
10
|
|
|
11
11
|
- **Version-controlled** — tracked by git, diffable in PRs
|
|
12
12
|
- **Offline-first** — no network calls, no rate limits
|
|
@@ -18,7 +18,7 @@ The file is read and written by specrails-core during command execution.
|
|
|
18
18
|
|
|
19
19
|
## Storage format
|
|
20
20
|
|
|
21
|
-
`.
|
|
21
|
+
`.specrails/local-tickets.json`:
|
|
22
22
|
|
|
23
23
|
```json
|
|
24
24
|
{
|
|
@@ -99,7 +99,7 @@ Use local ticket management or connect an external provider?
|
|
|
99
99
|
2. External provider — connect GitHub Issues, JIRA, or disable backlog commands
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
Pressing **Enter** or selecting **1** initializes `.
|
|
102
|
+
Pressing **Enter** or selecting **1** initializes `.specrails/local-tickets.json` with an empty ticket store and writes `.specrails/backlog-config.json`:
|
|
103
103
|
|
|
104
104
|
```json
|
|
105
105
|
{
|
|
@@ -123,7 +123,7 @@ Multiple agents can modify `local-tickets.json` simultaneously. The system uses
|
|
|
123
123
|
|
|
124
124
|
### Advisory file lock
|
|
125
125
|
|
|
126
|
-
Before every write, the agent creates `.
|
|
126
|
+
Before every write, the agent creates `.specrails/local-tickets.json.lock`:
|
|
127
127
|
|
|
128
128
|
```json
|
|
129
129
|
{
|
package/docs/migration-guide.md
CHANGED
|
@@ -22,7 +22,7 @@ Switching is optional. GitHub Issues and JIRA remain fully supported. Local tick
|
|
|
22
22
|
|
|
23
23
|
## Step 1: Switch the provider
|
|
24
24
|
|
|
25
|
-
Edit `.
|
|
25
|
+
Edit `.specrails/backlog-config.json` in your project root:
|
|
26
26
|
|
|
27
27
|
```json
|
|
28
28
|
{
|
|
@@ -42,7 +42,7 @@ Then initialize the ticket store if it doesn't exist yet:
|
|
|
42
42
|
Or create the file manually:
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
|
-
cat > .
|
|
45
|
+
cat > .specrails/local-tickets.json << 'EOF'
|
|
46
46
|
{
|
|
47
47
|
"schema_version": "1.0",
|
|
48
48
|
"revision": 0,
|
|
@@ -93,7 +93,7 @@ To do a dry run (preview without writing):
|
|
|
93
93
|
|
|
94
94
|
### From JIRA
|
|
95
95
|
|
|
96
|
-
Use the `sr:migrate-from-jira` command (requires `jira` CLI or REST API credentials in `.
|
|
96
|
+
Use the `sr:migrate-from-jira` command (requires `jira` CLI or REST API credentials in `.specrails/backlog-config.json`):
|
|
97
97
|
|
|
98
98
|
```bash
|
|
99
99
|
# Inside Claude Code
|
|
@@ -133,7 +133,7 @@ The `--update` flag regenerates only the backlog commands (`get-backlog-specs`,
|
|
|
133
133
|
|
|
134
134
|
To revert to GitHub Issues:
|
|
135
135
|
|
|
136
|
-
1. Edit `.specrails/config.yaml` (or `.
|
|
136
|
+
1. Edit `.specrails/config.yaml` (or `.specrails/backlog-config.json` for scaffold installs) and set `provider: github`
|
|
137
137
|
2. Re-run `/specrails:setup --update` to regenerate commands
|
|
138
138
|
3. Your `local-tickets.json` is preserved — switch back any time
|
|
139
139
|
|
package/docs/workflows.md
CHANGED
|
@@ -126,7 +126,7 @@ View your prioritized product backlog, ranked by VPC fit and effort.
|
|
|
126
126
|
|
|
127
127
|
### What it shows
|
|
128
128
|
|
|
129
|
-
The Product Analyst reads your backlog (local tickets in `.
|
|
129
|
+
The Product Analyst reads your backlog (local tickets in `.specrails/local-tickets.json` by default, or GitHub Issues labeled `product-driven-backlog` if configured) and produces:
|
|
130
130
|
|
|
131
131
|
- **Backlog table** per area — sorted by Total Persona Score
|
|
132
132
|
- **Top 3 recommendations** — ranked by VPC score / effort ratio, filtered to Wave 1 of the safe implementation order
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specrails-core",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.2",
|
|
4
4
|
"description": "AI agent workflow system for Claude Code — installs 12 specialized agents, orchestration commands, and persona-driven product discovery into any repository",
|
|
5
5
|
"bin": {
|
|
6
6
|
"specrails-core": "bin/specrails-core.js"
|
|
@@ -67,7 +67,7 @@ After the Explore agent completes:
|
|
|
67
67
|
|
|
68
68
|
1. **Display** results to the user.
|
|
69
69
|
|
|
70
|
-
2. Read `.
|
|
70
|
+
2. Read `.specrails/backlog-config.json` and extract:
|
|
71
71
|
- `BACKLOG_PROVIDER` (`local`, `github`, `jira`, or `none`)
|
|
72
72
|
- `BACKLOG_WRITE` (from `write_access`)
|
|
73
73
|
|
|
@@ -100,7 +100,7 @@ After the Explore agent completes:
|
|
|
100
100
|
|
|
101
101
|
### If provider=local — Sync to Local Tickets
|
|
102
102
|
|
|
103
|
-
Local tickets are always read-write. Sync directly to
|
|
103
|
+
Local tickets are always read-write. Sync directly to `.specrails/local-tickets.json`.
|
|
104
104
|
|
|
105
105
|
3. **Fetch existing local tickets** to avoid duplicates:
|
|
106
106
|
```
|
|
@@ -196,7 +196,7 @@ Local tickets are always read-write. Sync directly to `$SPECRAILS_DIR/local-tick
|
|
|
196
196
|
|
|
197
197
|
### If provider=jira and BACKLOG_WRITE=true — Sync to JIRA
|
|
198
198
|
|
|
199
|
-
Read from `.
|
|
199
|
+
Read from `.specrails/backlog-config.json`:
|
|
200
200
|
- `JIRA_BASE_URL`, `JIRA_PROJECT_KEY`, `AUTH_METHOD`
|
|
201
201
|
- `PROJECT_LABEL` (may be empty string)
|
|
202
202
|
- `EPIC_MAPPING` (object mapping area name → JIRA epic key)
|
|
@@ -262,7 +262,7 @@ For each unique area:
|
|
|
262
262
|
If `PROJECT_LABEL` is non-empty, add it to the `labels` array.
|
|
263
263
|
Set `EPIC_MAPPING[area] = <returned key>`.
|
|
264
264
|
|
|
265
|
-
After all areas are processed: write the updated `EPIC_MAPPING` back to `.
|
|
265
|
+
After all areas are processed: write the updated `EPIC_MAPPING` back to `.specrails/backlog-config.json`.
|
|
266
266
|
|
|
267
267
|
#### Step E: Create Story tickets
|
|
268
268
|
|
|
@@ -163,7 +163,7 @@ The product-analyst receives this prompt:
|
|
|
163
163
|
|
|
164
164
|
#### If provider=local — Cache from Local Tickets
|
|
165
165
|
|
|
166
|
-
Read
|
|
166
|
+
Read `.specrails/local-tickets.json` and parse the `tickets` map. For each ticket with `"product-driven-backlog"` in its `labels` array and `status` not `"cancelled"`, build a snapshot object:
|
|
167
167
|
- `number`: ticket `id` (integer)
|
|
168
168
|
- `title`: ticket `title` string
|
|
169
169
|
- `state`: map ticket `status` — `"done"` or `"cancelled"` → `"closed"`, otherwise → `"open"`
|
|
@@ -26,11 +26,11 @@ Check the environment variable `CLAUDE_CODE_ENTRYPOINT`. If it contains `remote_
|
|
|
26
26
|
|
|
27
27
|
#### 1. Backlog provider availability
|
|
28
28
|
|
|
29
|
-
Read `.
|
|
29
|
+
Read `.specrails/backlog-config.json` and extract `BACKLOG_PROVIDER`.
|
|
30
30
|
|
|
31
31
|
**If `BACKLOG_PROVIDER=local`:**
|
|
32
32
|
```bash
|
|
33
|
-
[[ -f "
|
|
33
|
+
[[ -f ".specrails/local-tickets.json" ]] && echo "Local tickets storage: OK" || echo "WARNING: local-tickets.json not found"
|
|
34
34
|
```
|
|
35
35
|
- Set `LOCAL_TICKETS_AVAILABLE=true/false` based on file existence.
|
|
36
36
|
- Set `GH_AVAILABLE=false` (GitHub CLI not needed for local provider).
|
|
@@ -132,7 +132,7 @@ After fetching issue refs, capture a baseline snapshot for conflict detection.
|
|
|
132
132
|
|
|
133
133
|
##### If `BACKLOG_PROVIDER=local` and input mode was issue numbers:
|
|
134
134
|
|
|
135
|
-
For each resolved ticket ID, read
|
|
135
|
+
For each resolved ticket ID, read `.specrails/local-tickets.json` and extract the ticket object at `tickets["{id}"]`.
|
|
136
136
|
|
|
137
137
|
Build a snapshot object for each ticket:
|
|
138
138
|
- `number`: ticket `id` (integer)
|
|
@@ -314,7 +314,7 @@ Pick the single idea with the best impact/effort ratio from each exploration. Pr
|
|
|
314
314
|
|
|
315
315
|
Otherwise, re-fetch each issue in scope and diff against the Phase 0 snapshot:
|
|
316
316
|
|
|
317
|
-
**If `BACKLOG_PROVIDER=local`:** For each ticket ID in `ISSUE_REFS`, read
|
|
317
|
+
**If `BACKLOG_PROVIDER=local`:** For each ticket ID in `ISSUE_REFS`, read `.specrails/local-tickets.json` and extract the ticket at `tickets["{id}"]`. If the ticket does not exist (deleted): treat as a CRITICAL conflict — field `"state"`, was `<cached state>`, now `"deleted"`. Otherwise, reconstruct a current snapshot using the same mapping as the Phase 0 local snapshot.
|
|
318
318
|
|
|
319
319
|
**If `BACKLOG_PROVIDER=github`:** For each issue number in `ISSUE_REFS`:
|
|
320
320
|
|
|
@@ -897,7 +897,7 @@ This check is independent of Phase 3a.0. Even if the user chose to continue thro
|
|
|
897
897
|
|
|
898
898
|
Re-fetch each issue in `ISSUE_REFS` and diff against `.claude/backlog-cache.json` using the same algorithm as Phase 3a.0:
|
|
899
899
|
|
|
900
|
-
**If `BACKLOG_PROVIDER=local`:** Read
|
|
900
|
+
**If `BACKLOG_PROVIDER=local`:** Read `.specrails/local-tickets.json` and extract each ticket by ID.
|
|
901
901
|
|
|
902
902
|
**If `BACKLOG_PROVIDER=github`:**
|
|
903
903
|
```bash
|
|
@@ -47,7 +47,7 @@ Output ONLY the following structured markdown. Do not add any preamble or explan
|
|
|
47
47
|
|
|
48
48
|
## Backlog Sync
|
|
49
49
|
|
|
50
|
-
After generating the proposal, read `.
|
|
50
|
+
After generating the proposal, read `.specrails/backlog-config.json` to determine `BACKLOG_PROVIDER` and `BACKLOG_WRITE`.
|
|
51
51
|
|
|
52
52
|
### If provider=local — Create Local Ticket
|
|
53
53
|
|
|
@@ -59,7 +59,7 @@ Read the following files to understand the current installation state:
|
|
|
59
59
|
Command template files include `implement.md`, `batch-implement.md`, `compat-check.md`, `refactor-recommender.md`, `why.md`, `get-backlog-specs.md`, `auto-propose-backlog-specs.md`.
|
|
60
60
|
If this directory does not exist, skip command template checking for this update.
|
|
61
61
|
|
|
62
|
-
6. Read
|
|
62
|
+
6. Read `.specrails/backlog-config.json` if it exists — contains stored provider configuration needed for command placeholder substitution.
|
|
63
63
|
|
|
64
64
|
### Phase U2: Quick Codebase Re-Analysis
|
|
65
65
|
|
|
@@ -178,7 +178,7 @@ For each command in the "changed commands" list from Phase U3:
|
|
|
178
178
|
1. Read the NEW template:
|
|
179
179
|
- If `cli_provider == "claude"`: from `$SPECRAILS_DIR/setup-templates/commands/specrails/<name>.md`
|
|
180
180
|
- If `cli_provider == "codex"`: from `$SPECRAILS_DIR/setup-templates/skills/sr-<name>/SKILL.md`
|
|
181
|
-
2. Read stored backlog configuration from
|
|
181
|
+
2. Read stored backlog configuration from `.specrails/backlog-config.json` (if it exists) to resolve provider-specific placeholders:
|
|
182
182
|
- `BACKLOG_PROVIDER` → `provider` field (`github`, `jira`, or `none`)
|
|
183
183
|
- `BACKLOG_WRITE` → `write_access` field
|
|
184
184
|
- `JIRA_BASE_URL` → `jira_base_url` field
|
|
@@ -424,8 +424,8 @@ Core commands (always install if missing):
|
|
|
424
424
|
- `auto-propose-backlog-specs.md`
|
|
425
425
|
|
|
426
426
|
**Initialize local ticket storage** (backlog provider defaults to `local`):
|
|
427
|
-
1. Copy `templates/local-tickets-schema.json` to
|
|
428
|
-
2. Write
|
|
427
|
+
1. Copy `templates/local-tickets-schema.json` to `.specrails/local-tickets.json` and set `last_updated` to the current ISO-8601 timestamp. Skip if the file already exists.
|
|
428
|
+
2. Write `.specrails/backlog-config.json` (skip if already exists):
|
|
429
429
|
```json
|
|
430
430
|
{
|
|
431
431
|
"provider": "local",
|
|
@@ -699,7 +699,7 @@ Ask the user how they want to manage their product backlog. Default is local —
|
|
|
699
699
|
Use local ticket management or connect an external provider?
|
|
700
700
|
|
|
701
701
|
1. **Local tickets** (default, recommended) — lightweight JSON-based ticket management built into the project.
|
|
702
|
-
No external tools or accounts required. Tickets stored in `.
|
|
702
|
+
No external tools or accounts required. Tickets stored in `.specrails/local-tickets.json`, version-controlled and diffable.
|
|
703
703
|
2. **External provider** — connect GitHub Issues, JIRA, or disable backlog commands
|
|
704
704
|
```
|
|
705
705
|
|
|
@@ -713,7 +713,7 @@ If the user selects **2**: display the secondary menu:
|
|
|
713
713
|
Which external provider?
|
|
714
714
|
|
|
715
715
|
1. **Local tickets** (recommended) — lightweight JSON-based ticket management built into the project.
|
|
716
|
-
No external tools required. Tickets stored in `.
|
|
716
|
+
No external tools required. Tickets stored in `.specrails/local-tickets.json`, version-controlled and diffable.
|
|
717
717
|
2. **GitHub Issues** — uses `gh` CLI to read/create issues with labels and VPC scores
|
|
718
718
|
3. **JIRA** — uses JIRA CLI or REST API to read/create tickets in a JIRA project
|
|
719
719
|
4. **None** — skip backlog commands (you can still use /implement with text descriptions)
|
|
@@ -725,10 +725,10 @@ Wait for the user's choice. Set `BACKLOG_PROVIDER` to `local`, `github`, `jira`,
|
|
|
725
725
|
|
|
726
726
|
No external tools or credentials required. Initialize the storage file:
|
|
727
727
|
|
|
728
|
-
1. Copy `templates/local-tickets-schema.json` to
|
|
728
|
+
1. Copy `templates/local-tickets-schema.json` to `.specrails/local-tickets.json`
|
|
729
729
|
2. Set `last_updated` to the current ISO-8601 timestamp
|
|
730
730
|
|
|
731
|
-
Store configuration in
|
|
731
|
+
Store configuration in `.specrails/backlog-config.json`:
|
|
732
732
|
```json
|
|
733
733
|
{
|
|
734
734
|
"provider": "local",
|
|
@@ -774,13 +774,13 @@ Local tickets are always read-write — there is no "read only" mode since the f
|
|
|
774
774
|
|
|
775
775
|
The `revision` counter in the JSON root enables optimistic concurrency — increment it on **every** write. The lock file prevents concurrent corruption:
|
|
776
776
|
|
|
777
|
-
1. **Acquire lock:** Check for
|
|
777
|
+
1. **Acquire lock:** Check for `.specrails/local-tickets.json.lock`
|
|
778
778
|
- If the file exists and its `timestamp` is less than 30 seconds old: wait 500ms and retry (max 5 attempts before aborting with an error)
|
|
779
779
|
- If the file exists and its `timestamp` is 30+ seconds old (stale): delete it and proceed
|
|
780
780
|
- If no lock file exists: proceed immediately
|
|
781
|
-
2. **Create lock file:** Write `{"agent": "<agent-name-or-process>", "timestamp": "<ISO-8601>"}` to
|
|
781
|
+
2. **Create lock file:** Write `{"agent": "<agent-name-or-process>", "timestamp": "<ISO-8601>"}` to `.specrails/local-tickets.json.lock`
|
|
782
782
|
3. **Minimal lock window:** Read the JSON → modify in memory → write back → release
|
|
783
|
-
4. **Release lock:** Delete
|
|
783
|
+
4. **Release lock:** Delete `.specrails/local-tickets.json.lock`
|
|
784
784
|
5. **Always increment `revision`** by 1 and update `last_updated` on every successful write
|
|
785
785
|
|
|
786
786
|
The hub server uses `proper-lockfile` (or equivalent) to honor the same protocol via the `.lock` file path.
|
|
@@ -895,7 +895,7 @@ Ask:
|
|
|
895
895
|
|
|
896
896
|
Set `EPIC_LINK_FIELD` to `parent` or `customfield_10014`. Default: `parent`.
|
|
897
897
|
|
|
898
|
-
Store the full configuration in `.
|
|
898
|
+
Store the full configuration in `.specrails/backlog-config.json`:
|
|
899
899
|
```json
|
|
900
900
|
{
|
|
901
901
|
"provider": "jira",
|
|
@@ -1147,22 +1147,22 @@ When adapting `auto-propose-backlog-specs.md` and `get-backlog-specs.md`, substi
|
|
|
1147
1147
|
|
|
1148
1148
|
#### Local Tickets (`BACKLOG_PROVIDER=local`)
|
|
1149
1149
|
|
|
1150
|
-
For the local provider, backlog placeholders resolve to **inline file-operation instructions** embedded in the generated command markdown — not shell commands. Agents execute these by reading/writing
|
|
1150
|
+
For the local provider, backlog placeholders resolve to **inline file-operation instructions** embedded in the generated command markdown — not shell commands. Agents execute these by reading/writing `.specrails/local-tickets.json` directly using their file tools.
|
|
1151
1151
|
|
|
1152
1152
|
All write operations must follow the **advisory file locking protocol** defined in Phase 3.2. Always increment `revision` and update `last_updated` on every write.
|
|
1153
1153
|
|
|
1154
1154
|
| Placeholder | Substituted value |
|
|
1155
1155
|
|-------------|-------------------|
|
|
1156
1156
|
| `{{BACKLOG_PROVIDER_NAME}}` | `Local Tickets` |
|
|
1157
|
-
| `{{BACKLOG_PREFLIGHT}}` | `[[ -f "
|
|
1158
|
-
| `{{BACKLOG_FETCH_CMD}}` | Read
|
|
1159
|
-
| `{{BACKLOG_FETCH_ALL_CMD}}` | Read
|
|
1160
|
-
| `{{BACKLOG_FETCH_CLOSED_CMD}}` | Read
|
|
1161
|
-
| `{{BACKLOG_VIEW_CMD}}` | Read
|
|
1162
|
-
| `{{BACKLOG_CREATE_CMD}}` | Write to
|
|
1163
|
-
| `{{BACKLOG_UPDATE_CMD}}` | Write to
|
|
1164
|
-
| `{{BACKLOG_DELETE_CMD}}` | Write to
|
|
1165
|
-
| `{{BACKLOG_COMMENT_CMD}}` | Write to
|
|
1157
|
+
| `{{BACKLOG_PREFLIGHT}}` | `[[ -f ".specrails/local-tickets.json" ]] && echo "Local tickets storage: OK" \|\| echo "WARNING: .specrails/local-tickets.json not found — run /specrails:setup to initialize"` |
|
|
1158
|
+
| `{{BACKLOG_FETCH_CMD}}` | Read `.specrails/local-tickets.json`. Parse the `tickets` map and return all entries where `status` is `"todo"` or `"in_progress"`. |
|
|
1159
|
+
| `{{BACKLOG_FETCH_ALL_CMD}}` | Read `.specrails/local-tickets.json`. Parse the `tickets` map and return all entries regardless of status. |
|
|
1160
|
+
| `{{BACKLOG_FETCH_CLOSED_CMD}}` | Read `.specrails/local-tickets.json`. Parse the `tickets` map and return all entries where `status` is `"done"` or `"cancelled"`. |
|
|
1161
|
+
| `{{BACKLOG_VIEW_CMD}}` | Read `.specrails/local-tickets.json`. Parse JSON and return the full ticket object at `tickets["{id}"]`, or an error if not found. |
|
|
1162
|
+
| `{{BACKLOG_CREATE_CMD}}` | Write to `.specrails/local-tickets.json` using the advisory locking protocol: acquire lock → read file → set `id = next_id`, increment `next_id`, set all ticket fields, set `created_at` and `updated_at` to now, bump `revision`, update `last_updated` → write → release lock. |
|
|
1163
|
+
| `{{BACKLOG_UPDATE_CMD}}` | Write to `.specrails/local-tickets.json` using the advisory locking protocol: acquire lock → read file → update fields in `tickets["{id}"]`, set `updated_at` to now, bump `revision`, update `last_updated` → write → release lock. |
|
|
1164
|
+
| `{{BACKLOG_DELETE_CMD}}` | Write to `.specrails/local-tickets.json` using the advisory locking protocol: acquire lock → read file → delete `tickets["{id}"]`, bump `revision`, update `last_updated` → write → release lock. |
|
|
1165
|
+
| `{{BACKLOG_COMMENT_CMD}}` | Write to `.specrails/local-tickets.json` using the advisory locking protocol: acquire lock → read file → append `{"author": "<agent-name>", "body": "<comment>", "created_at": "<ISO-8601>"}` to `tickets["{id}"].comments` (create the array if absent), set `updated_at` to now, bump `revision`, update `last_updated` → write → release lock. |
|
|
1166
1166
|
| `{{BACKLOG_PARTIAL_COMMENT_CMD}}` | Same as `{{BACKLOG_COMMENT_CMD}}` but append `{"author": "<agent-name>", "body": "<comment>", "type": "progress", "created_at": "<ISO-8601>"}`. |
|
|
1167
1167
|
| `{{BACKLOG_INIT_LABELS_CMD}}` | No label initialization required. Local tickets use freeform label strings. Standard label conventions: `area:frontend`, `area:backend`, `area:api`, `effort:low`, `effort:medium`, `effort:high`. |
|
|
1168
1168
|
|
|
@@ -1183,7 +1183,7 @@ All write operations must follow the **advisory file locking protocol** defined
|
|
|
1183
1183
|
- Issue view: `jira issue view {key}` or REST API
|
|
1184
1184
|
- VPC scores stored in the issue description body (same markdown format, parsed from description)
|
|
1185
1185
|
- Pre-flight check: `jira me` or test API connectivity
|
|
1186
|
-
- Store JIRA config in
|
|
1186
|
+
- Store JIRA config in `.specrails/backlog-config.json`:
|
|
1187
1187
|
```json
|
|
1188
1188
|
{
|
|
1189
1189
|
"provider": "jira",
|
|
@@ -70,7 +70,7 @@ After the Explore agent completes:
|
|
|
70
70
|
|
|
71
71
|
1. **Display** results to the user.
|
|
72
72
|
|
|
73
|
-
2. Read `.
|
|
73
|
+
2. Read `.specrails/backlog-config.json` and extract:
|
|
74
74
|
- `BACKLOG_PROVIDER` (`github`, `jira`, or `none`)
|
|
75
75
|
- `BACKLOG_WRITE` (from `write_access`)
|
|
76
76
|
|
|
@@ -159,7 +159,7 @@ After the Explore agent completes:
|
|
|
159
159
|
|
|
160
160
|
### If provider=jira and BACKLOG_WRITE=true — Sync to JIRA
|
|
161
161
|
|
|
162
|
-
Read from `.
|
|
162
|
+
Read from `.specrails/backlog-config.json`:
|
|
163
163
|
- `JIRA_BASE_URL`, `JIRA_PROJECT_KEY`, `AUTH_METHOD`
|
|
164
164
|
- `PROJECT_LABEL` (may be empty string)
|
|
165
165
|
- `EPIC_MAPPING` (object mapping area name → JIRA epic key)
|
|
@@ -225,7 +225,7 @@ For each unique area:
|
|
|
225
225
|
If `PROJECT_LABEL` is non-empty, add it to the `labels` array.
|
|
226
226
|
Set `EPIC_MAPPING[area] = <returned key>`.
|
|
227
227
|
|
|
228
|
-
After all areas are processed: write the updated `EPIC_MAPPING` back to `.
|
|
228
|
+
After all areas are processed: write the updated `EPIC_MAPPING` back to `.specrails/backlog-config.json`.
|
|
229
229
|
|
|
230
230
|
#### Step E: Create Story tickets
|
|
231
231
|
|