Display the product-driven backlog by reading issues/tickets from the configured backlog provider (read from .specrails/backlog-config.json). These are feature ideas generated through VPC-based product discovery — evaluated against user personas. Use /specrails:auto-propose-backlog-specs to generate new ideas.
-
Fetch all open product-driven backlog items:
If BACKLOG_PROVIDER=github:
gh issue list --label "product-driven-backlog" --state open --json number,title,body,labels --limit 100
If BACKLOG_PROVIDER=local: read .specrails/local-tickets.json and extract the tickets array.
-
Parse each issue/ticket to extract metadata from the body:
- Area: from
area:* label
- Persona Fit: from the body's Overview table — extract per-persona scores and total
- Effort: from the body's Overview table (High/Medium/Low)
- Description: from the body's "Feature Description" section
- User Story: from the body's "User Story" section
-
Parse prerequisites for each issue:
- Locate the row whose first cell matches
**Prerequisites** in the issue body's Overview table.
- If the cell value is
None, -, or empty: set prereqs = [] for this issue.
- Otherwise: extract all tokens matching
#\d+ from the cell and set prereqs = [<numbers>].
- If a prerequisite number does not appear in the fetched issue list, treat it as already satisfied (externally closed). Do not include it in the DAG.
-
Build dependency graph and detect cycles:
-
Compute safe implementation order (Kahn's topological sort):
-
Group by area.
-
Sort within each area by Total Persona Score (descending), then by Effort (Low > Medium > High) as tiebreaker.
-
Display as a formatted table per area, then propose the top 3 items from WAVE_1 (features with all prerequisites satisfied) for implementation. If fewer than 3 are in WAVE_1, show as many as available and add: "Note: Only {N} feature(s) are available to start immediately — remaining features have unmet prerequisites."
[If CYCLE_MEMBERS is non-empty, render the cycle warning block immediately before the first area table.]
Render each area table with the following format:
- Append
[blocked] to the issue title cell if in_degree[issue] > 0 and the issue is not in CYCLE_MEMBERS.
- Append
[cycle] to the issue title cell if the issue is in CYCLE_MEMBERS.
Prereqs cell: list prerequisite issue numbers as #N, #M, or — if none.
## Product-Driven Backlog
{N} open issues | Source: VPC-based product discovery
Personas: <read persona names and roles from .specrails/personas/*.md or .claude/agents/personas/*.md>
### {Area Name}
| # | Issue | <one column per persona> | Total | Effort | Prereqs |
|---|-------|<separators>|-------|--------|---------|
| 1 | #42 Feature name [blocked] | ... | X/<N*5> | Low | #12, #17 |
| 2 | #43 Other feature | ... | X/<N*5> | High | — |
(N = number of personas, max score = N * 5)
---
## Recommended Next Sprint (Top 3)
Ranked by VPC persona score / effort ratio:
| Priority | Issue | Area | <one column per persona> | Total | Effort | Rationale |
|----------|-------|------|<separators>|-------|--------|-----------|
### Selection criteria
- Cross-persona features (both 4+/5) prioritized over single-persona
- Low effort preferred over high effort at same score
- Critical pain relief weighted higher than gain creation
Run `/specrails:implement` to start implementing these items.
-
Render Safe Implementation Order section after the Recommended Next Sprint table:
---
## Safe Implementation Order
Features grouped by wave. All features in a wave can start in parallel.
Features in wave N must complete before wave N+1 begins.
| Wave | Issue | Title | Prereqs | Score | Effort |
|------|-------|-------|---------|-------|--------|
| 1 | #N | ... | — | X/<N*5> | Low |
| 2 | #M | ... | #N | X/<N*5> | Medium |
To implement in this order:
/specrails:batch-implement <issue-refs in wave order> --deps "<A> -> <B>, <C> -> <D>, ..."
[If no edges exist in the DAG, omit the --deps clause:]
/specrails:batch-implement <issue-refs>
[If CYCLE_MEMBERS is non-empty, append:]
Cycle members excluded from ordering: #A, #B
Fix the Prerequisites fields in these issues to include them.
Issue refs in the /specrails:batch-implement command are listed in wave order (wave 1 first, then wave 2, etc.), sorted by persona score within each wave. The --deps string is constructed from all edges in the DAG: "A -> B" for each edge, comma-separated. If the backlog has no dependencies at all (DAG has no edges), the section still renders showing all features in wave 1 and the --deps clause is omitted.
-
If no issues exist:
No product-driven backlog issues found. Run `/specrails:auto-propose-backlog-specs` to generate feature ideas.
-
[Orchestrator] After the product-analyst completes, write issue snapshots to .claude/backlog-cache.json.
Guard: If GH_AVAILABLE=false (from Phase 0 pre-flight), print [backlog-cache] Skipped — GH unavailable. and return. Do not attempt the write.
Fetch all open backlog issues in one call:
gh issue list --label "product-driven-backlog" --state open --json number,title,state,assignees,labels,body,updatedAt
For each issue in the result, build a snapshot object:
Merge strategy: If .claude/backlog-cache.json already exists and is valid JSON, read it and merge: new snapshot entries overwrite existing entries by issue number key; entries for issue numbers not in the current fetch are preserved (they may be needed by an in-progress /specrails:implement run). If the file does not exist or is malformed, create it fresh.
Write the merged result back to .claude/backlog-cache.json with:
schema_version: "1"
provider: "github"
last_updated: current ISO 8601 timestamp
written_by: "get-backlog-specs"
issues: the merged map keyed by string issue number
If the write fails (e.g., .claude/ directory does not exist): print [backlog-cache] Warning: could not write cache. Continuing. Do not abort.