specrails-core 3.5.1 → 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/commands/setup.md +20 -20
- package/docs/migration-guide.md +2 -2
- 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 +20 -20
- package/templates/skills/sr-auto-propose-backlog-specs/SKILL.md +3 -3
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",
|
|
@@ -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.
|
|
@@ -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/migration-guide.md
CHANGED
|
@@ -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/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",
|
|
@@ -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.
|
|
@@ -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
|
|