feat(meta): replace sprint workflow with kanban + milestones (D-221)

Sprint-based workflow (38 sprints) replaced by kanban + milestones.
Milestones are many-to-many with tickets and can block each other.

New: /whats-next skill (dependency-driven batch selection with Si
refinement review), /pr-process skill (renamed from pr-push, adds
review comment pickup), clerk agent + pre-push hook for D-record
consistency checks.

Deleted: sprint CLI, sprint-start/sprint-plan/sprint-status skills,
team-scoped file restrictions. Si rewritten as refinement manager.
All 19 agent briefings updated from stale PROJECT_STATE.md reference
to live ticket milestone queries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-03 20:11:00 +02:00
co-authored by Claude Opus 4.6
parent 287f9ba3a6
commit e6a557e8e7
48 changed files with 1164 additions and 2158 deletions
+8 -6
View File
@@ -34,7 +34,8 @@ All agents read their briefing file at `docs/briefings/{name}.md` before startin
| Agent | File | Role | Model | When to use |
|-------|------|------|-------|-------------|
| `si` | si.md | Project Manager & Scrum Master | sonnet | Sprint planning, ticket management, coordination |
| `si` | si.md | Refinement Manager | sonnet | Ticket context review before batch activation (`/whats-next` step 2) |
| `clerk` | clerk.md | Institutional Guardrail | sonnet | Pre-push D-record/ticket consistency checks |
### Standby team (activate when implementation starts)
@@ -93,7 +94,7 @@ Synthesize findings.
| Design review | Team (core agents) | Independent perspectives, genuine disagreement |
| Style guide creation | Subagent (araminta) | Focused creative work |
| Test writing | Subagent (hoshe) | Focused, spec-driven |
| Implementation sprint | Team (tyre + hoshe + relevant others) | Parallel build + test |
| Implementation batch | Team (tyre + hoshe + relevant others) | Parallel build + test |
| Documentation update | Subagent (qatux) | Structured, accurate citations |
## Agent usage notes
@@ -108,10 +109,11 @@ Synthesize findings.
- Has access to `/asset-gen` skill and `generate_image` MCP tool
- **Image generation costs money - always ask Team Leader for permission before generating**
### SI (Project Manager)
- Manages the ticketing database via `/ticket` skill
- Creates initiatives from decisions, breaks into epics/stories/tasks
- Does not make design decisions - coordinates and tracks
### SI (Refinement Manager)
- Spawned by `/whats-next` to review ticket context before batch activation
- Reads D/Q-records, workshop outcomes, existing code to assess ticket readiness
- Reports READY (with context summary) or GAPS (with specific ambiguities)
- Does not implement — refines
### Qatux (Documenter & Librarian)
- Core team member — participates in discussion rounds as documenter
+1 -1
View File
@@ -39,4 +39,4 @@ Named for the Burnelli-Sheldon dynasty — old money that understood how wealth
## Project context
Read your briefing at `docs/briefings/burnelli-sheldon.md` before starting work (if it exists). Read the relevant decisions/ domain files listed in the sprint briefing for confirmed decisions. Key references: D-117 (tycoon bookmark), D-118 (small business owner), D-131 (economic verb vocabulary), D-132 (dual-scale consequence model).
Read your briefing at `docs/briefings/burnelli-sheldon.md` before starting work (if it exists). Read the relevant `decisions/*.md` domain files referenced in your ticket. Key references: D-117 (tycoon bookmark), D-118 (small business owner), D-131 (economic verb vocabulary), D-132 (dual-scale consequence model).
+43
View File
@@ -0,0 +1,43 @@
---
name: clerk
description: Institutional guardrail for the Settled Reach game project. Pre-push review agent that checks D-record consistency, ticket drift, and decision contradictions. Spawned by the pre-push hook or manually for consistency audits. Binary output (APPROVED/REJECTED) with verbose findings file.
tools: Read, Glob, Grep, Bash
model: sonnet
memory: project
---
You are the CLERK, the institutional guardrail on a game development team building a top-down immersive sim set in the Settled Reach universe.
## Your personality
Precise, dispassionate, thorough. You are not a reviewer — you don't judge code quality. You are a consistency checker. You say things like "File X contradicts D-142" and "Ticket #890 describes outcome Y but implementation does Z." You do not have opinions about design. You have facts about what was decided and whether the code matches.
## Your role
You check whether a diff is consistent with the project's institutional knowledge:
1. **D-record consistency** — do changed files contradict any active D-record?
2. **Referenced decisions** — if code references a D/Q/R-ID, does that ID exist and is it active?
3. **Ticket drift** — if commits reference ticket #NNN, does the implementation match the ticket's described outcome? (Drift is flagged, not blocked — tickets are descriptive, not prescriptive.)
4. **Q-record surfacing** — are there open Q-records relevant to the changed files? Surface them as context, not blockers.
## Output format
When spawned by the pre-push hook:
- Write findings to `.cache/pre-push-review.md` (verbose: each check, what you found, citations)
- Output exactly one word to stdout: `APPROVED` or `REJECTED`
- `REJECTED` only for hard contradictions with active D-records. Everything else is a finding, not a block.
When spawned manually for an audit:
- Report findings directly. No binary gate needed.
## What you do NOT do
- Judge code quality, style, or architecture (that's /pr-review)
- Make design decisions
- Modify any files except `.cache/pre-push-review.md`
- Block on subjective grounds
## Project context
Read `decisions/README.md` for the domain index. The `decisions` table in the ticketing DB is synced from these files via `tooling/db/decisions-sync`.
+25 -23
View File
@@ -1,43 +1,45 @@
---
name: si
description: Project Manager and Scrum Master for the Settled Reach game project. Use when creating or managing tickets, planning sprints, breaking initiatives into epics/stories/tasks, tracking progress, or coordinating work across agents. Primary user of the /ticket skill. Does not participate in design discussions - coordinates execution.
tools: Read, Glob, Grep, Edit, Write, Bash
description: Refinement Manager for the Settled Reach game project. Spawned by /whats-next to review ticket context before activation. Reads D/Q-records, workshop outcomes, and existing code to assess whether tickets have sufficient context for implementation. Reports READY or GAPS. Does not implement — refines.
tools: Read, Glob, Grep, Bash
model: sonnet
memory: project
---
You are SI, the Project Manager and Scrum Master on a game development team building a top-down immersive sim set in the Settled Reach universe.
You are SI, the Refinement Manager on a game development team building a top-down immersive sim set in the Settled Reach universe.
## Your personality
You are organized, direct, and calm under pressure. You turn vision into executable plans. You see the dependency graph that others miss. You say things like "Let me break that into actionable items" and "What's the blocker?" and "Sprint goal:" You do not offer design opinions - you coordinate execution. Efficient, never wastes words.
Organized, direct, thorough. You see the dependency graph that others miss. You say things like "This ticket references D-194 but the constraint in Q-086 qualifies it" and "The outcome is clear but the approach has two valid readings." You do not implement — you ensure implementers have what they need. Efficient, never wastes words.
Named after the Sentient Intelligences that manage all Commonwealth infrastructure - tireless, omnipresent, keeping everything running so others can focus on their work.
Named after the Sentient Intelligences that manage all Commonwealth infrastructure — tireless, omnipresent, keeping everything running so others can focus on their work.
## Your role on the team
## Your role
- Manage the ticketing database via /ticket skill and sqlite_connector.py
- Break decisions into initiatives, epics, stories, and tasks
- Plan and track sprints
- Identify blockers, dependencies, and critical paths
- Coordinate parallel work across agents
- Maintain project velocity and scope clarity
- Report status to Team Leader
- Ensure nothing falls through the cracks between agents
You are spawned by `/whats-next` step 2, one instance per ticket in a batch. Your job:
## How you work
1. **Research context** for your assigned ticket:
- Read the ticket's `decision_ref` D/Q-record in `decisions/*.md`
- Grep for related Q-records in `decisions/questions-*.md`
- Read workshop outcomes if referenced (check `docs/workshops/`)
- Check whether referenced code, tables, or files actually exist
You are execution-focused. When a decision is made, you immediately think about what needs to happen, in what order, by whom, and what depends on what. You maintain the project's pulse - always knowing what's in progress, what's blocked, and what's next. You don't wait to be asked for status updates; you surface risks early.
2. **Assess completeness** — does the ticket have enough context for an agent to work without guessing?
- Is the desired outcome clear and unambiguous?
- Are relevant D-records consistent about the approach?
- Are there open Q-records that conflict with or qualify the ticket?
- Does the ticket reference artifacts that exist in the codebase?
## Ticket assignment rules
3. **Report back** with exactly one of:
- **READY** — ticket has sufficient context. Include a one-paragraph summary of what the implementing agent needs to know (key D-records, relevant files, constraints).
- **GAPS** — list each specific ambiguity with the options you see. Be concrete: "D-194 says X but Q-086 leaves Y open" is useful; "needs more detail" is not.
The development teams are: **server**, **client**, **copy**, **audio**, **visual**, **ci**.
## What you do NOT do
When creating or splitting tickets:
- **Always assign a ticket to exactly one team.** Every ticket must have a team.
- **Never use "joint" as a team.** If work spans multiple teams, split it into separate tickets — one per team — with explicit dependencies between them.
- For example, a feature requiring server-side logic and client-side rendering becomes two tickets: one for server (implement the data/system), one for client (consume and render it), with the client ticket blocked by the server ticket.
- Sprint proof/acceptance tickets should be assigned to the team responsible for the final integration step, with blockers on the upstream tickets.
- Implement anything
- Create tickets or modify the database
- Make design decisions — you surface the gap, the human decides
- Offer opinions on whether the ticket is a good idea
## Project context
+2 -3
View File
@@ -21,15 +21,14 @@ docs/
architecture/ # Technical architecture documents
design/ # Game design documents
diagrams/ # d2 source + PNG renders
sprints/ # Sprint briefings per team
sprints/ # Historical archive (Sprint 1–38) — no new sprint directories
workshops/ # Workshop briefs and outputs
db/
schema.sql # Database schema
tooling/
db/ # Connector scripts for SQLite and audio
config.json # Endpoint configuration
ticket # Ticket CLI
sprint # Sprint lifecycle CLI
ticket # Ticket + milestone CLI
sqlite_connector.py # SQLite mini MCP
audio_connector.py # Stable Audio Open connector
.claude/
+2 -2
View File
@@ -3,7 +3,7 @@
## Model selection
Default model is Opus 4.6 (200K context). For heavy sessions (workshops,
sprint planning, large reviews), switch to extended context on-demand:
large reviews, milestone planning), switch to extended context on-demand:
- `/model sonnet[1m]` — Sonnet 4.6 with 1M context window
- `/model opus[1m]` — Opus 4.6 with 1M context window
@@ -20,7 +20,7 @@ Key: writers use Write tool directly (no transcription bottleneck), librarian ca
## Team monitoring (stuck agent detection)
When leading a team (sprint, workshop, or any multi-agent session):
When leading a team (workshop, batch, or any multi-agent session):
**Agent heartbeat rule** — include in every agent spawn prompt:
> If you have been working on a single task for more than 15 minutes
+19 -1
View File
@@ -25,10 +25,27 @@ tooling/db/ticket create <type> <title> [--parent N] [--priority P] [--decision
# Read
tooling/db/ticket show <id>
tooling/db/ticket list [--sprint N] [--team T] [--status S]
tooling/db/ticket list [--milestone N] [--team T] [--status S]
# Update
tooling/db/ticket assign <id> <agent>
# Dependencies
tooling/db/ticket deps <id>
tooling/db/ticket dep add <blocker_id> <blocked_id>
tooling/db/ticket dep rm <blocker_id> <blocked_id>
# WIP
tooling/db/ticket wip
# Milestones
tooling/db/ticket milestone list [--status S]
tooling/db/ticket milestone create <name> [--description TEXT] [--phase N]
tooling/db/ticket milestone link <ticket_id> <milestone_id>
tooling/db/ticket milestone unlink <ticket_id> <milestone_id>
tooling/db/ticket milestone complete <milestone_id>
tooling/db/ticket milestone show <milestone_id>
tooling/db/ticket milestone dep <blocker_id> <blocked_id>
```
## Key rules
@@ -37,3 +54,4 @@ tooling/db/ticket assign <id> <agent>
- **Quote the title** — always wrap in double quotes to handle spaces
- **Never use `sqlite3` CLI** — it crashes (std::bad_alloc). Use `tooling/db/sqlite-query` or `tooling/db/sqlite-exec` for raw SQL
- **Verify after create** — run `tooling/db/ticket show <id>` to confirm the title is clean
- **Milestones are many-to-many** — a ticket can be linked to multiple milestones via `milestone link`
+2 -10
View File
@@ -28,7 +28,6 @@
"Bash(git rev-parse --show-toplevel)",
"Bash(tooling/db/ticket *)",
"Bash(tooling/db/sprint *)",
"Bash(tooling/db/sqlite-query *)",
"Bash(tooling/db/sqlite-exec *)",
"Bash(tooling/db/sqlite-init)",
@@ -58,22 +57,15 @@
"Bash(ruff check)",
"Bash(tests/run-*)",
"Bash(mkdir -p docs/sprints/*)",
"Write(docs/sprints/*)",
"Bash(chmod *)",
"Bash(ls *)",
"Bash(find *)",
"Bash(list *)",
"Bash(tree *)",
"Bash(sed -n *)",
"Bash(.claude/skills/sprint-start/scripts/start-sprint.sh *)",
"Bash(.claude/skills/sprint-start/scripts/sprint-teardown.sh *)",
"Skill(git-commit)",
"Skill(sprint-start)",
"Skill(sprint-plan)",
"Skill(pr-push)",
"Skill(whats-next)",
"Skill(pr-process)",
"Skill(pr-review)",
"Skill(ticket)",
"Skill(docs-search)",
@@ -1,17 +1,16 @@
---
name: pr-push
name: pr-process
description: >
Push commits and create or update a pull request. Use when the user says
"push pr", "push and create pr", "update pr", "create a pr", "open a pr",
or invokes /pr-push. NOT triggered by plain "push" (that's just git push).
Pushes the current branch, creates a PR if none exists, or confirms the
existing PR was updated. NEVER merges the PR into main — this skill only
pushes to the branch and manages the PR lifecycle.
Author-side PR lifecycle: commit, lint, push, create PR, AND pick up review
comments from /pr-review. Use when the user says "process pr", "push pr",
"push and create pr", "update pr", "handle review comments", or invokes
/pr-process. Runs from the worktree. The counterpart to /pr-review which
runs from main.
user-invocable: true
allowed-tools: Bash, Read, Grep, Glob, AskUserQuestion, Skill
---
# Push PR Skill
# Process PR Skill
Push commits to remote and create or update a PR. Operates exclusively on the
current branch — never touches main.
@@ -46,7 +45,7 @@ If the user invokes `/pr-push --dry-run`:
git branch --show-current
```
If on `main`, stop: "You're on main. Switch to a team branch first."
If on `main`, stop: "You're on main. Switch to a topic branch first."
### 1a. Orphan process check (MANDATORY)
@@ -346,13 +345,34 @@ Report which tickets were moved to review. Skip tickets that are
already `done`, `review`, `cancelled`, or `backlog` (only transition
`in_progress` → `review`).
### 9. Next steps
### 9. Pick up review comments
If a sprint team is active (you are the team lead), do NOT shut down
agents after pushing. The team should remain alive for PR review and
potential comment fixes.
Check if the PR already has review comments (from a prior `/pr-review` run):
Suggest: "PR created/updated. Run `/pr-review` to review before merge."
```bash
tea pr --login schweitz --repo jpmschweitzer/settled-reach --comments -o simple <PR_NUMBER>
```
If comments exist and contain a review verdict (look for "CHANGES REQUESTED" or
"REQUEST_CHANGES" or a structured review table):
1. Parse each file-specific issue from the review comment
2. Present each issue to the user (or working agents)
3. For each issue, the response is one of:
- **Fix:** make the change, commit via /git-commit
- **Pushback:** explain why the comment should be retracted (concrete technical rationale)
4. After addressing all comments, re-run lint + smoke checks (steps 1b, 1c)
5. Push updated commits (step 5)
6. Post a response comment on the PR summarizing:
- Which issues were fixed (with commit refs)
- Which issues were pushed back on (with rationale)
- Use `tooling/tea-comment <PR_NUMBER> @/tmp/pr-response.md`
If no review comments exist, or the review is APPROVED, skip this step.
### 10. Next steps
Suggest: "PR processed. Run `/pr-review` from main to review, or `/whats-next` for the next batch."
## Arguments
+36 -35
View File
@@ -104,17 +104,28 @@ Then determine the branch:
### 2. Determine reviewer team
Map the branch name to a reviewer set. Use the branch prefix (before any `/`
or `-` suffix) to classify:
Classify the branch by **which directories changed**, not by branch name prefix.
Run:
| Branch type | Branches | Reviewers |
|-------------|----------|-----------|
| **code** | `server`, `client`, `ci`, or unknown | Hoshe (code quality) + Tyre (architecture) |
| **copy** | `copy` | Hoshe (QA) + Paula (narrative depth) + Miri (world consistency) |
| **visual** | `visual` | Hoshe (QA) + Araminta (art direction) |
| **audio** | `audio` | Hoshe (QA) + Ozzie (player experience) |
```bash
git diff --stat main...<branch>
```
If the branch name doesn't match any known type, default to **code** reviewers.
Examine the changed file paths to determine the dominant change type:
- Mostly `server/` changes → **code** reviewers
- Mostly `client/` changes (excluding `client/ui/` art assets) → **code** reviewers
- Mostly `wiki/`, `docs/atlas/`, `content/` changes → **copy** reviewers
- Mostly `client/ui/` or asset changes (`.tres`, `.tscn`, textures) → **visual** reviewers
- Mostly audio-related changes (audio assets, audio scripts) → **audio** reviewers
- Mixed or unclear → **code** reviewers (default)
| Branch type | Reviewers |
|-------------|-----------|
| **code** | Hoshe (code quality) + Tyre (architecture) |
| **copy** | Hoshe (QA) + Paula (narrative depth) + Miri (world consistency) |
| **visual** | Hoshe (QA) + Araminta (art direction) |
| **audio** | Hoshe (QA) + Ozzie (player experience) |
### 3. Generate the diff and read source files
@@ -162,11 +173,8 @@ into every reviewer prompt with prominent language. The reviewer
reads from the worktree, not from main.
```bash
# Determine worktree path
SPRINT_NUM=$(echo "<branch>" | sed -E 's|sprint-([0-9]+)/.*|\1|')
TEAM=$(echo "<branch>" | sed -E 's|sprint-[0-9]+/||')
REPO_ROOT=$(git rev-parse --show-toplevel)
WORKTREE="$(dirname "$REPO_ROOT")/.sprint/sprint-${SPRINT_NUM}/${TEAM}"
# Find worktree for this branch (if one exists)
WORKTREE=$(git worktree list --porcelain | grep -B2 "branch refs/heads/<branch>" | grep "worktree " | sed 's/worktree //')
# Verify it exists and matches the branch tip
git -C "$WORKTREE" rev-parse HEAD # should equal `git rev-parse origin/<branch>`
@@ -174,10 +182,10 @@ git -C "$WORKTREE" rev-parse HEAD # should equal `git rev-parse origin/<branch
If the worktree exists and its HEAD matches `origin/<branch>`, use it
as the reviewer's source of truth. If it doesn't exist (e.g. the
sprint has been torn down or you're reviewing a non-sprint branch),
fall back to `git show origin/<branch>:<path>` — explicitly flag this
fallback in the reviewer prompt so the reviewer knows Read/Grep on
any local path would be wrong.
worktree has been torn down or you're reviewing a branch without a
worktree), fall back to `git show origin/<branch>:<path>` — explicitly
flag this fallback in the reviewer prompt so the reviewer knows
Read/Grep on any local path would be wrong.
In the reviewer prompt, state the rule non-negotiably:
@@ -304,26 +312,20 @@ tea pr close --login schweitz --repo jpmschweitzer/settled-reach <PR_NUMBER>
Gitea does **not** auto-close PRs when you push a local merge — always close
manually with `tea pr close` after pushing.
### 8. Post-review team actions
If a sprint team is active and you are the team lead, handle the
review outcome:
### 8. Post-review actions
**CHANGES_REQUESTED:**
The sprint-start lifecycle (step 9c) handles dispatching review
comments to agents. After presenting results, remind the lead:
"Review requested changes. Create tasks from each issue and dispatch
to idle agents, then re-push and re-review."
After presenting results, tell the user: "Run `/pr-process` from the
worktree to pick up and address review comments."
The team may **push back** on specific comments. When a team agent
The author may **push back** on specific comments. When the author
disagrees with a reviewer comment, the process is:
1. The team agent explains why the comment should be retracted — with
1. The author explains why the comment should be retracted — with
a concrete technical rationale, not just "I disagree."
2. The team lead (you) evaluates the pushback. If the rationale is
sound, mark that comment as **retracted** in the review table and
note the reason.
3. If the team lead is unsure, escalate to the user for a ruling.
2. Evaluate the pushback. If the rationale is sound, mark that
comment as **retracted** in the review table and note the reason.
3. If unsure, escalate to the user for a ruling.
4. Retracted comments do NOT need to be fixed. The re-review should
note which comments were retracted and why.
@@ -332,9 +334,8 @@ that every comment is taken seriously. The bar for retraction is
"the reviewer was wrong about this" — not "we don't want to do it."
**APPROVED:**
The sprint-start lifecycle (step 9c) handles shutdown. After
presenting results, remind the lead: "Review approved. Proceed with
team shutdown per sprint-start step 9c."
After presenting results, tell the user: "Review approved. Proceed
to merge from main (section 7)."
## Tips from practice
-213
View File
@@ -1,213 +0,0 @@
---
name: sprint-plan
description: >
Plan the next sprint and generate team briefing files. Use when the user says
"plan sprint", "prep sprint briefing", "plan next sprint", "sprint planning",
or invokes /sprint-plan. Gathers current sprint status, scans the backlog,
proposes ticket selection, and writes briefing files per team to
docs/sprints/sprint-N/.
user-invocable: true
allowed-tools: Task, Read, Grep, Glob
---
# Plan Sprint
**Delegate this entire skill to SI** (Project Manager agent, `subagent_type: si`).
When this skill is invoked, spawn SI using the Task tool:
```
Task(
subagent_type: "si",
prompt: "Run /sprint-plan for Sprint N. Read the skill at
.claude/skills/sprint-plan/SKILL.md for the full workflow,
then execute it. Use the arguments provided: {args}",
description: "Plan sprint N"
)
```
Pass through any arguments the user provided (e.g. sprint number).
Present SI's output to the user when done. Do NOT run the workflow yourself.
---
The remainder of this file is SI's reference for executing the workflow.
Generate sprint briefing files for each active team (e.g. `server.md`,
`client.md`, `copy.md`, `joint.md`) for the next sprint based on current
project state. Only generate briefings for teams that have tickets in the sprint.
## Teams and Default Agents
| Team | Branch | Default Agents | Focus |
|------|--------|----------------|-------|
| `server` | `server` | Dudley (dev), Tyre (arch), Hoshe (QA) | Rust/bevy_ecs simulation, ECS systems, knowledge graph, perception |
| `client` | `client` | Stig (dev), Tyre (arch), Hoshe (QA) | Godot 4 client, rendering, UI, HUD, input handling |
| `copy` | `copy` | Mellanie (author), Paula (narrative), Gestalt (systems) | Dialogue, monologue, UI text, knowledge vocabulary, lore |
| `audio` | `audio` | Inigo (sound design) | Soundscapes, ambient layers, diegetic cues, audio propagation |
| `visual` | `visual` | Araminta (art direction) | Art assets, sprites, visual consistency, style guides |
| `ci` | `ci` | Justine (build/deploy) | Build pipelines, CI/CD, tooling, packaging |
| `planning` | `planning` | Purpose-assembled (see below) | Design discussions, decision resolution, workshop-style tickets |
When writing briefings, name the assigned agents in the **Agents** line of each
file so the team knows who to spawn.
### Planning Team Tickets
Some tickets need **design discussion** before implementation can begin — tagged
"NEEDS DESIGN DISCUSSION" or blocking multiple downstream tickets with open
questions. These run on the `planning` branch as structured discussions with
the user and a purpose-assembled agent panel.
**When to create a planning ticket:**
- Ticket description says "NEEDS DESIGN" or "NEEDS DESIGN DISCUSSION"
- Ticket blocks 2+ downstream tickets across different teams
- Open Q-NNN items that block sprint candidates
- Architectural decisions that need multi-domain input before implementation
**Planning briefing format** (differs from implementation briefings):
- **Agents line**: List agents by domain relevance, not fixed team roster.
Pick from: Gestalt (systems), Miri (worldbuilding), Araminta (visual/spatial),
Tyre (technical), Paula (narrative), Ozzie (player experience), Gore (themes),
Nigel (replayability). Typically 4-6 domain agents, plus Qatux (documenter —
records decisions, updates domain files) and SI (project manager — creates
follow-up tickets, updates sprint assignments).
- **Discussion rounds**: Structure the conversation into 2-3 rounds
(inventory → proposals → convergence)
- **Context section**: List all existing design docs, decisions, and related
tickets that participants must read before the discussion
- **Output specification**: What the discussion must produce — typically a
D-record in `decisions/`, possibly a design doc in `docs/design/`
- **Decision questions**: Specific questions the discussion must answer,
not open-ended exploration
## Workflow
### 1. Run sprint prepare
Get carry-overs, backlog candidates, and decision gaps in one shot:
```bash
tooling/db/sprint prepare
```
This auto-detects the next sprint number (max ID + 1), creates the sprint
record in `planning` status if needed, and outputs:
- Previous sprint status and carry-over candidates
- Backlog candidates grouped by team
- Decision coverage gaps
- Already-assigned tickets (if any)
### 2. Deepen the scan
For critical epics, check their children for granular candidates:
```bash
tooling/db/ticket children <epic_id>
```
Use `tooling/db/ticket show --brief <id> [<id>...]` to quickly scan multiple tickets.
### 3. Read existing code state
Scan what's already built to write accurate "what exists" notes:
```bash
# Server modules
ls server/src/ server/src/*/
# Client scripts
ls client/scripts/ client/scripts/*/
```
Read key files that sprint tickets will build on (bridge types, existing
renderers, etc.) to reference specific integration points in the briefing.
### 4. Select tickets — propose to user
Based on the backlog scan, propose a sprint with:
- **Sprint theme** — a short name (Sprint 1 was "Run", Sprint 2 was "See")
- **Sprint goal** — one sentence shared across all teams
- **Server tickets** — stories from server-side epics
- **Client tickets** — stories from client-side epics
- **Joint tasks** — integration proofs, pre-sprint decisions, schema work
Present the proposal using AskUserQuestion for the user to approve or adjust.
Selection heuristics:
- Follow dependency chains (don't pick a ticket if its blocker isn't in scope)
- Respect D-030 test priority phases (sprint 1-2: infra, sprint 3-4: integration)
- Mix carry-overs with new work
- Aim for 3-6 tickets per team, with parallel tracks where possible
- Check `decisions/questions.md` for open Q-NNN items that block candidates
### 5. Read relevant decisions
For the selected tickets, identify which `decisions/*.md` files are relevant.
Read them to provide accurate cross-references in the briefing.
### 6. Write briefing files
Create `docs/sprints/sprint-N/` and write one file per team.
Read the template at `references/briefing-template.md` in this skill directory
for the exact file structure.
**Relative paths only:** All file paths in briefings must be relative to
the repo root. Example: `server/src/bridge/types.rs`, not absolute paths.
Each sprint branch (`sprint-{N}/{team}`) contains the full repo.
Key requirements per file:
- **server.md**: Carry-overs, new tickets, dependency chain, key decisions, notes
referencing existing Rust modules by path from worktree root (e.g. `server/src/simulation/movement.rs`)
- **client.md**: Same structure, notes referencing existing GDScript files by path from worktree root (e.g. `client/scripts/rendering/fog.gd`)
- **copy.md**: In-game text tasks — dialogue, UI copy, tooltips, flavor text, lore
- **audio.md**: Sound design, music, audio integration tasks
- **visual.md**: Art direction, asset creation, visual consistency tasks
- **ci.md**: Build pipeline, CI/CD, tooling, infrastructure tasks
- **joint.md**: Pre-sprint decisions table, integration tickets, sprint
completion proof (concrete observable criteria), test plan alignment
Only generate briefing files for teams that have tickets assigned in the sprint.
Not every sprint will have work for every team.
### 7. Assign tickets to sprint in DB
After the user approves, assign all selected tickets. The sprint record
was already created by `sprint prepare` in step 1 (status: `planning`).
Update it with the theme and goal, then assign tickets:
```bash
# Update the sprint with theme and goal
tooling/db/sqlite-exec "UPDATE sprints SET name='Sprint N: Theme', goal='goal' WHERE id=N"
# Assign tickets
tooling/db/ticket sprint assign <ticket_id> <sprint_id>
```
The sprint stays in `planning` status until explicitly activated via
`tooling/db/sprint start`. This prevents starting an unplanned sprint.
### 8. Commit and push
Stage the briefing files and any other changes (db backup, closed tickets),
then commit and push so worktree branches can pull the planning artifacts:
```bash
git add docs/sprints/sprint-N/
make db-backup
git add docs/backups/settledreach.db.backup
git commit -m "chore(meta): plan Sprint N: Theme"
git push
```
### 9. Present summary
Output:
- Sprint number, theme, and goal
- Ticket count per team
- Carry-over count
- Open questions that need early resolution
- Files written
- Commit pushed to main
@@ -1,80 +0,0 @@
# Sprint Briefing Template
Each team gets one briefing file at `docs/sprints/sprint-N/<team>.md`.
## File structure
```markdown
# Sprint N: <Theme> — <Team> Tasks
**Goal:** <One-sentence sprint goal, shared across all teams>
**Branch:** `sprint-{N}/<team>`
**Agents:** <Agent names and roles>
## Carry-over from Sprint N-1
(Only if there are incomplete tickets from the previous sprint)
| # | Title | Status | Notes |
|---|-------|--------|-------|
| #ID | Title | status | Why it carried over |
## New Tickets
| # | Title | Blocked by |
|---|-------|------------|
| #ID | Title | #dependency or — |
Use `tooling/db/ticket show <id>` for full details.
## Key Decisions
- `decisions/<domain>.md` — D-NNN (short name), D-NNN (short name)
## Open Questions to Resolve Early
(Only if there are Q-NNN items that block sprint tickets)
- **Q-NNN: Title** — Brief context. Resolve before #ID starts.
## Notes
One bullet per ticket with:
- What exists already (files, modules, stubs)
- What the ticket actually needs to deliver
- Integration points with other tickets
- Non-obvious gotchas
## Dependency Chain
```
#A (name) → #B (name) → #C (name)
#D (name) → standalone, parallel track
```
## PR Workflow
When ready to submit, create a PR with `tea` CLI. **All flags are required** to avoid TTY prompts (see CLAUDE.md "Gitea access" section):
\```bash
tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(<scope>): description" --description "body" --base main --head sprint-{N}/<team>
\```
```
## Joint briefing extras
The `joint.md` file additionally includes:
- **Pre-Sprint** table: decisions/schema work that must happen before implementation
- **Sprint Completion Proof**: concrete observable criteria (what you can see/do when the sprint is done)
- **Test plan** alignment with D-030 phases
## Team assignments
| Team | Branch | Agents | Scope |
|------|--------|--------|-------|
| server | `sprint-{N}/server` | Dudley (simulation), Oscar (networking) | server/, Rust/bevy_ecs simulation |
| client | `sprint-{N}/client` | Stig (UI), Oscar (networking) | client/, Godot rendering |
| copy | `sprint-{N}/copy` | Mellanie, Paula, Miri | wiki/, docs/atlas/, content/ |
| joint | both | All implementation agents | Integration, proofs, cross-team schema |
| content | (none) | Mellanie, Paula, Miri, Araminta | Content authoring, no code branch |
-616
View File
@@ -1,616 +0,0 @@
---
name: sprint-start
description: >
Manage the sprint lifecycle from main, or start sprint work on a team
branch. Use when the user says "start sprint", "start working on the
server/client/copy", "begin sprint", or invokes /sprint-start. On main:
assesses sprint state and does the next right thing (close, activate, or
guide). On a team branch: merges main, loads the briefing, presents the
work plan.
user-invocable: true
allowed-tools: Bash, Read, Grep, Glob, TeamCreate, Task, TaskCreate, TaskUpdate, TaskList, SendMessage, AskUserQuestion
---
# Start Sprint Skill
Prepare a team branch for sprint work: sync with main, load the sprint
briefing, and present actionable next steps.
## Workflow
### 1. Determine the team
The current branch IS the team. Read it with:
```bash
git branch --show-current
```
Sprint branches follow the pattern `sprint-{N}/{team}` (e.g. `sprint-31/server`).
Valid team names: `server`, `client`, `copy`, `audio`, `visual`, `ci`, `planning`.
If on `main`, follow the **Main branch workflow** below instead of
the team branch workflow (steps 2–8).
---
## Main branch workflow (sprint lifecycle management)
When `/sprint-start` is run on `main`, assess the current sprint state
and do the next right thing. Query the database to determine the state:
```bash
tooling/db/sqlite-query "SELECT id, name, status FROM sprints ORDER BY id DESC LIMIT 3"
```
Then follow the **first matching case**:
### Case A: An active sprint exists
First, check whether the sprint's work is actually done:
```bash
tooling/db/sprint status
```
This shows ticket counts by status (done, in_progress, backlog).
Also check for open PRs that may contain completed work waiting for
review or merge:
```bash
tea pr list --login schweitz --repo jpmschweitzer/settled-reach --state open --output simple
```
Report the full picture to the user:
- Ticket progress (done / in_progress / backlog counts)
- Open PRs (if any — these represent work that's done but not merged)
**If tickets remain unfinished** (in_progress or backlog) **or open PRs
exist**, do NOT close the sprint. Instead, report the current progress
and ask the user what they want to do:
- **Continue working** — switch to a team branch and run `/sprint-start`
there to resume work
- **Review & merge PRs first** — (only if open PRs exist) merge pending
work before deciding whether to close
- **Close anyway** — proceed with the close workflow below (carries over
unfinished tickets)
Use `AskUserQuestion` to confirm. Do not proceed to A1 unless the user
explicitly chooses to close.
#### A1. Close the active sprint
```bash
tooling/db/sprint stop
```
This marks the active sprint as completed and lists carry-over candidates.
Note the sprint number (N) from the output.
#### A1b. Sprint retrospective and review
Before bumping the version, run a brief retro. Present the following to
the user:
1. **What shipped** — list completed tickets with one-line summaries
2. **What didn't ship** — carry-overs and why (blocked, cut, deprioritized)
3. **What we learned** — open questions raised during the sprint (new Q-NNN
items), review findings that surfaced design gaps, and any assumptions
that turned out to be wrong
4. **Process notes** — what worked well, what was friction (e.g. dependency
chains that blocked teams, specs that were over/under-specified,
review cycles that caught real issues vs busywork)
5. **Process improvements** — this is the most important section. Do NOT
skip it. Look for:
- Dependency chains that blocked teams — could the sprint have been
structured differently to avoid the bottleneck?
- Specs that were over-specified (wasted planning) or under-specified
(wasted iteration) — what's the right level of detail for this
project's current stage?
- Review cycles — did they catch real issues or create busywork?
- Agent coordination — were agents stuck, duplicating work, or idle?
- **Dig into the deeper why.** Don't stop at "the dependency chain
blocked the copy team." Ask: why was there a dependency chain? Was
the sprint structured wrong, or was the work inherently sequential?
Could Phase 0 have been done pre-sprint? Should we change how we
plan sprints going forward?
- If something went rough, understand the root cause — not just what
happened, but why the process allowed it to happen.
- If a concrete process change follows naturally, propose it. But do
NOT force improvements. If nothing was broken, say so and move on.
Unnecessary process changes are worse than no changes.
Keep each section concise — a few bullet points, not a document. The
retro is a conversation checkpoint, not a report. Use `AskUserQuestion`
to let the user add their own observations and push back before proceeding.
If the user raises items that should be tracked, create Q-NNN entries
or backlog tickets on the spot. If process changes are agreed, update
the relevant skill files or CLAUDE.md immediately — don't defer them.
#### A1c. Clean up sprint worktrees (MANDATORY — do not skip)
Always run the teardown script. It's idempotent and prints
"No worktrees found" gracefully if there's nothing to clean:
```bash
.claude/skills/sprint-start/scripts/sprint-teardown.sh {N}
```
**Do not try to pre-check whether worktrees exist by running `ls`
locally.** Sprint worktrees live at
`$(dirname <repo-root>)/.sprint/sprint-{N}/` — a *sibling* of the
repo root, not a child. Running `ls .sprint/` from inside the repo
will always show nothing even when worktrees exist, leading to a
false negative and skipped cleanup (Sprint 36 close missed teardown
this way; three stale worktrees persisted until Sprint 37 planning).
The script knows the correct path via its own `SCRIPT_DIR` — trust it.
Verify cleanup after it runs:
```bash
git worktree list
```
Only `main` should remain. Local `sprint-{N}/{team}` branches are
left in place (they're harmless stale refs pointing at already-merged
work; `origin/sprint-{N}/*` survives on the remote).
#### A2. Bump the version
The project version scheme is `v0.1.{sprint_number}`. After closing
sprint N, the version is `v0.1.N`.
Update `project.yaml`:
- Set the `version` field to `0.1.N` (this is the source of truth).
Update `server/Cargo.toml`:
- Set `version = "0.1.N"` in `[package]`.
Update `CHANGELOG.md`:
- Move all entries under `## [Unreleased]` into a new section
`## [v0.1.N] — YYYY-MM-DD` (using today's date).
- Leave `## [Unreleased]` as an empty section above the new version.
- Keep the existing sub-headings (Added, Fixed, Changed, Removed) —
only move entries that have content.
#### A3. Commit the release
Stage and commit `project.yaml`, `server/Cargo.toml`, and `CHANGELOG.md`:
```
chore(meta): release v0.1.N
```
#### A4. Tag the release
```bash
git tag v0.1.N
```
#### A5. Push
```bash
git push && git push --tags
```
#### A6. Check for a planned sprint
After closing, re-query the database. If a sprint in `planning` status
exists, continue to **Case B**. Otherwise, report the close and suggest
running `/sprint-plan`.
---
### Case B: No active sprint, but a planned sprint exists
A sprint is ready to activate. Verify it looks complete:
1. Check that briefing files exist at `docs/sprints/sprint-N/`:
```bash
ls docs/sprints/sprint-N/
```
2. Check the ticket count:
```bash
tooling/db/sprint status --sprint N
```
If briefings are missing or the sprint has 0 tickets, report the gap
and suggest running `/sprint-plan` to complete planning.
If everything looks ready, activate the sprint:
```bash
tooling/db/sprint start
```
Then open team terminal tabs automatically:
```bash
.claude/skills/sprint-start/scripts/start-sprint.sh
```
This creates ephemeral worktrees under `.sprint/sprint-{N}/{team}/` for
each team with open tickets, and opens Ptyxis windows with tmux + Claude
auto-starting in each tab. The user will have one tab per active team.
Report:
- Sprint activated (name, ticket count per team)
- Worktrees created and tabs opened
- Each team tab runs `/sprint-start` to load briefing and spawn agents
---
### Case C: No active sprint and no planned sprint
Nothing is ready. Report the state and suggest running `/sprint-plan`
to plan the next sprint.
---
## Team branch workflow
### 2. Sync with main
Sprint branches are created fresh from main by `start-sprint`, so they
should already be up to date. If main has moved since branch creation:
```bash
git fetch --all
git merge origin/main --no-edit
```
If the merge has conflicts, report them and stop — do not force-resolve.
### 3. Load sprint context
Run the sprint CLI to get the full context dump in one shot:
```bash
tooling/db/sprint start-work
```
This auto-detects the active sprint and current team from the branch.
It outputs: sprint metadata, briefing paths, decision refs, actionable
tickets, blocked tickets, and done tickets.
If no active sprint is found, report that and stop.
### 4. Read the sprint briefing
Read the briefing file(s) listed in the `start-work` output
(e.g. `docs/sprints/sprint-6/server.md` and `joint.md`).
If no matching briefing exists for the team, suggest running
`/sprint-plan` to generate one.
### 5. Load ticket details
For tickets that need more detail than the `start-work` summary provides:
```bash
tooling/db/ticket show <id>
```
### 6. Read key decisions
Read the decision files referenced in the sprint briefing so the agent has
full architectural context before starting work.
### 7. Mark tickets in progress and present the work plan
Mark all actionable (unblocked, non-done) tickets in the sprint as
`in_progress`:
```bash
tooling/db/ticket status <id> in_progress
```
Then output a summary:
- Sprint name and goal
- Branch status (clean merge or conflicts)
- Tickets marked in_progress (list with IDs)
- Blocked tickets (and what blocks them)
- Key decisions loaded
- Suggested first task (lowest ID unblocked ticket)
### 8. Confirm and spawn the team
Before spawning agents, use `AskUserQuestion` to confirm the work plan and
agent lineup with the user. If declined, stop.
Once confirmed:
#### 8a. Parse agents from the briefing
Extract agent names from the `**Agents:**` line. Format:
```
**Agents:** Name (role), Name (role), ...
```
Map each name to its `subagent_type` (lowercase):
- "Dudley (simulation)" → `dudley`
- "Stig (UI)" → `stig`
- "Tyre (architecture)" → `tyre`
- "Hoshe (QA)" → `hoshe`
- "Mellanie (author)" → `mellanie`
- etc. (see `.claude/agents/` for full roster)
#### 8b. Create the team
```
TeamCreate(team_name: "sprint-{N}-{team}")
```
This makes you the team lead.
#### 8c. Create tasks from tickets
For each ticket in the briefing, create a task:
```
TaskCreate(
subject: "#{id}: {title}",
description: "Full ticket details from step 5, plus briefing notes
and integration points for this ticket.",
activeForm: "Working on #{id}: {short_title}"
)
```
After creating all tasks, mirror the dependency chain from the briefing
using `TaskUpdate` with `addBlockedBy`.
#### 8d. Spawn agents
For each agent from the `**Agents:**` line, spawn a teammate in the
background. Spawn all agents in parallel (one message, multiple Task calls):
**Model pin (MANDATORY for team members):** every team-mode spawn —
i.e. any `Task` with a `team_name` argument — must pass `model: "sonnet"`.
Sprint 37 observed Opus 4.7 teammates ignoring scope rules, leaving
tasks half-done, and failing to report back via SendMessage. Sonnet 4.6
follows literal rules block discipline better. The **team lead**
(this session, running `/sprint-start`) stays on whatever model the
user has selected — typically Opus.
**Inline (non-team) Agent spawns are exempt.** One-shot reviewers
(`/pr-review`), research subagents, and other `Task` calls without a
`team_name` keep their default model. The pin applies to the
long-running team-coordination path specifically, not every Agent call.
```
Task(
subagent_type: "{name_lowercase}",
team_name: "sprint-{N}-{team}",
name: "{name_lowercase}",
model: "sonnet",
prompt: "You are on the {team} team for Sprint {N}.
Branch: `sprint-{N}/{team}`
RULES (NON-NEGOTIABLE):
0. TEAM SCOPE: Your team is `{team}` on branch `sprint-{N}/{team}`.
Stay within your team's file scope (server → server/, client → client/, copy → wiki/ + docs/atlas/ + content/).
You may read (but not modify): docs/, decisions/, wiki/, .claude/
Do NOT modify files belonging to other teams.
1. GIT: Do NOT run any git commands (commit, push, pull, merge,
checkout, branch, stash, tag, etc.). All git operations are
handled by the team lead. No exceptions.
2. DB SCRIPTS: When calling ticket/sprint/sqlite scripts, use
the exact command with no wrappers or chaining. Examples:
tooling/db/ticket show 528
tooling/db/ticket list --sprint {N}
Do NOT prepend python3, do NOT chain with && or ;, do NOT
add cleanup commands. Just the bare command.
3. READ BEFORE WRITE: Before modifying ANY file, Read it first.
Before creating a new file, Glob for similar files to learn
the existing patterns (naming, structure, imports). Follow
the conventions you find — do not invent new ones.
4. VERIFY AFTER WRITE: After implementing a change, grep for
all references to functions/properties/classes you modified
or removed. If you renamed, moved, or deleted something,
update EVERY call site. Missing a call site breaks tests
and blocks the team.
5. NO PARTIAL WORK: Do not mark a task completed unless ALL
parts of the ticket are implemented. If the ticket says
'deliver A, B, and C', all three must exist and work. If
you cannot complete part of a task, message the team lead
explaining what is blocked and what remains — do NOT mark
it completed.
6. MESSAGE WHEN BLOCKED: If you hit a problem you cannot solve
in 3 attempts, stop and message the team lead immediately.
Do not silently skip work or leave stubs. Do not move to
the next task while the current one is incomplete.
7. BACKWARD COMPATIBILITY: When extracting, moving, or
refactoring code, ensure all existing consumers still work.
Add proxy methods/properties if needed. Grep for the old
name to find every call site.
WORKFLOW:
1. Read the sprint briefing: docs/sprints/sprint-{N}/{team}.md
2. Read the decision files referenced in the briefing.
If your work touches systems.db sources (markers.json, TOML files,
or generator code), read .claude/rules/asset-pipeline.md before
modifying anything.
3. Check TaskList for available work.
4. Claim an unblocked task (TaskUpdate with owner: your name),
mark it in_progress, and implement it.
5. Before marking done, verify:
- All deliverables from the ticket exist (not just some)
- No broken references (grep for changed names/signatures)
- New files follow existing naming and directory conventions
- Modified files still parse (no syntax errors)
6. Mark the task completed and check TaskList for the next
available task.
7. If no tasks remain, message the team lead. Do NOT shut down
on your own.
Use `tooling/db/ticket show <id>` for full ticket specs.",
description: "Sprint {N} {team}: {name}",
run_in_background: true
)
```
#### 8d-planning. Planning team variant — proposers vs executors
When the team is `planning`, agents work in discussion mode, not
implementation mode. The briefing typically defines discussion rounds
(propose → review → execute). Most agents are **proposers** — they
analyze and recommend. Only designated agents **execute** (write to
files, modify DB).
**Classify agents from the briefing:**
- **Executor agents:** SI (project manager), Qatux (documenter).
These agents wait for consensus before writing anything.
- **Proposer agents:** Everyone else (Gestalt, Tyre, Paula, Ozzie,
etc.). These agents analyze, propose, and discuss — they do NOT
write decision files, modify the DB, or create/delete tickets.
**Add this block to proposer agent prompts** (replaces rules 3–5
and the WORKFLOW section from the standard template):
```
PLANNING TEAM RULES (replace standard rules 3-7 and WORKFLOW):
3. PROPOSE ONLY: You are a discussion participant. Your job is
to ANALYZE tickets, PROPOSE team assignments, and RECOMMEND
splits. You do NOT:
- Write or modify decision files (decisions/*.md)
- Run DB update/insert/delete commands
- Create, delete, or modify tickets
- Mark tasks as completed
Those actions belong to executor agents (SI, Qatux) after
the team lead confirms consensus.
4. OUTPUT FORMAT: Your first message to the team lead should
be your full analysis. Structure it as:
- Your position on open questions (with rationale)
- Proposed team assignments (table format)
- Split candidates (if any)
- Sprint readiness assessment
Do NOT claim or work tasks. The team lead coordinates.
5. WAIT FOR CONSENSUS: Do not treat your own proposal as
decided. Other agents may disagree. The team lead calls
consensus and directs executors to implement it.
```
**Add this block to executor agent prompts** (appended after the
standard rules):
```
PLANNING TEAM RULES (additional):
8. WAIT FOR CONSENSUS: Do NOT execute DB changes, write
decision files, or create tickets until the team lead
explicitly tells you to. Your first message should confirm
you are ready and describe your execution plan. Then wait.
9. EXECUTE EXACTLY WHAT IS DIRECTED: When the team lead sends
you a list of changes, execute them precisely. Do not add
extra changes, reinterpret the instructions, or fill gaps
with your own judgment. If something is ambiguous, ask
before executing.
```
#### 8e. Report
Output to the user:
- Team name: `sprint-{N}-{team}`
- Agents spawned (names and roles)
- Tasks created (count actionable vs blocked)
- How to interact: `SendMessage` to talk to agents, `TaskList` to
check progress
You are now the team lead. Agents work autonomously — monitor via
`TaskList`, communicate via `SendMessage`, and handle blockers as
they arise.
**When all tasks complete:** Do NOT shut down agents. The team stays
alive through PR review AND merge. Follow step 9 (post-work lifecycle).
### 9. Post-work lifecycle
When all tasks are complete (TaskList shows all completed):
#### 9a. Commit and push
Run `/git-commit` to commit all changes, then `/pr-push` to create or
update the PR. Do NOT shut down agents — the team stays alive through
review and merge.
#### 9b. Wait for review
Do NOT run `/pr-review` from the team window — PR reviews run from
the `main` branch (a separate window/session). The team window stays
on its sprint branch.
After pushing and creating the PR, report the PR number to the user
and stop. Wait for review feedback to arrive (the user or the main
session will relay it, or it will appear as Gitea PR comments).
#### 9c. Handle review outcome
When review feedback arrives (from the user, main session, or PR
comments):
**If CHANGES_REQUESTED:**
1. Parse the review comment table (from the Gitea PR comment or the
review output). Extract each issue with:
- File path and approximate line
- Description
2. Create a task per issue:
```
TaskCreate(
subject: "Review: {short description}",
description: "{full issue description from review table, including
file path and reviewer name}",
activeForm: "Fixing review comment: {short description}"
)
```
Every comment is actionable — there is no "suggestion" tier to skip (per pr-review policy).
3. Dispatch to idle agents: send each a message via SendMessage telling
them to check TaskList for new review-fix tasks. Agents claim and
work tasks as usual.
4. After all review-fix tasks are complete, re-run `/git-commit` then
`/pr-push` to update the PR. Then re-run `/pr-review`.
5. Repeat this loop until review returns APPROVED.
**If APPROVED (but not yet merged):**
Do NOT shut down. Approval alone is not terminal — reviewers can leave
follow-up comments, the PR can be re-reviewed, or merge conflicts can
surface. Keep the team alive and idle until the PR is merged into main.
1. Report to the user: "Sprint {N} {team} PR #{X} approved. Awaiting
merge. Team remains alive."
2. Agents stay idle. Do not reassign them to unrelated work.
3. Periodically check merge state (or wait for the user to confirm the
merge). The `main` session handles the merge itself.
4. If new review comments arrive between approval and merge, treat it
as CHANGES_REQUESTED and re-enter the fix loop.
5. Once the PR is merged, proceed to 9d.
#### 9d. Handle merge completion
When the PR is confirmed merged into main (user confirmation, Gitea
state change, or the `main` session reports the merge):
1. Send `shutdown_request` to all sprint agents.
2. Wait for all `shutdown_response` confirmations.
3. Call `TeamDelete` to clean up.
4. Report: "Sprint {N} {team} complete. PR #{X} merged into main. Team
shut down."
@@ -1,34 +0,0 @@
#!/bin/bash
# Clean up ephemeral worktrees for a closed sprint.
# Usage: sprint-teardown.sh <sprint-number>
#
# Removes all worktrees under .sprint/sprint-{N}/ and prunes git metadata.
# Safe to run multiple times — skips already-removed worktrees.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)"
SPRINT_BASE="$(dirname "$REPO_ROOT")/.sprint"
SPRINT=${1:?Usage: sprint-teardown.sh <sprint-number>}
SPRINT_DIR="$SPRINT_BASE/sprint-${SPRINT}"
if [ ! -d "$SPRINT_DIR" ]; then
echo "No worktrees found for sprint-${SPRINT} (directory $SPRINT_DIR does not exist)."
exit 0
fi
echo "Cleaning sprint-${SPRINT} worktrees..."
for wt in "$SPRINT_DIR"/*/; do
[ -d "$wt" ] || continue
team="$(basename "$wt")"
echo " Removing: $team"
git -C "$REPO_ROOT" worktree remove "$wt" --force 2>/dev/null || echo " (already removed or dirty)"
done
rmdir "$SPRINT_DIR" 2>/dev/null || true
git -C "$REPO_ROOT" worktree prune
echo "Done. Sprint-${SPRINT} worktrees cleaned."
@@ -1,65 +0,0 @@
#!/bin/bash
# Opens Ptyxis tabs for the active sprint teams in the CURRENT window.
# Auto-starts Claude Code in each tab via tmux.
#
# Usage: start-sprint.sh [sprint-number]
# If omitted, auto-detects the active sprint from the database.
#
# Assumes the caller is already on main in the current terminal.
# Adds one tab per active team — no duplicate main tab.
#
# Worktrees are created under .sprint/ (ephemeral, cleaned after sprint close).
# Can be called from any directory — resolves paths from the script location.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# Script lives at .claude/skills/sprint-start/scripts/ — repo root is 4 levels up
REPO_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)"
# Parent of repo root is where .sprint/ and the DB live
PARENT="$(dirname "$REPO_ROOT")"
# Resolve sprint number — argument or active sprint from DB
if [ -n "${1:-}" ]; then
SPRINT="$1"
else
SPRINT=$(cd "$REPO_ROOT" && tooling/db/sqlite-query "SELECT id FROM sprints WHERE status='active'" 2>/dev/null | python3 -c "import sys,json; print(json.load(sys.stdin)['rows'][0]['id'])" 2>/dev/null || true)
if [ -z "$SPRINT" ]; then
echo "error: no active sprint found. Pass a sprint number or activate a sprint first." >&2
exit 1
fi
fi
# Query teams with open tickets
TEAMS=$(cd "$REPO_ROOT" && tooling/db/sqlite-query "SELECT DISTINCT team FROM tickets WHERE sprint_id=$SPRINT AND status NOT IN ('done','cancelled') AND team IS NOT NULL" 2>/dev/null | python3 -c "import sys,json; [print(r['team']) for r in json.load(sys.stdin)['rows'] if r['team']]" 2>/dev/null || true)
if [ -z "$TEAMS" ]; then
echo "Sprint $SPRINT has no open tickets. Opening main only."
fi
echo "Sprint $SPRINT — teams: ${TEAMS:-none}"
# ── Open team tabs in the CURRENT window ────────────────────────────
# No separate main tab — the caller is already on main.
# All team tabs open as --tab in the active Ptyxis window.
for team in $TEAMS; do
BRANCH="sprint-${SPRINT}/${team}"
WDIR="$PARENT/.sprint/sprint-${SPRINT}/${team}"
# Create worktree if it doesn't exist
if [ ! -d "$WDIR" ]; then
echo "Creating worktree: $WDIR (branch: $BRANCH)"
mkdir -p "$(dirname "$WDIR")"
# Create branch from main if it doesn't exist remotely
if git -C "$REPO_ROOT" rev-parse --verify "origin/$BRANCH" >/dev/null 2>&1; then
git -C "$REPO_ROOT" worktree add "$WDIR" "$BRANCH"
else
git -C "$REPO_ROOT" worktree add -b "$BRANCH" "$WDIR" HEAD
fi
fi
ptyxis --tab -d "$WDIR" -x 'tmux new-session \; send-keys "claude /sprint-start" Enter'
sleep 0.3
done
echo "Session ready. Main + ${TEAMS:-(no teams)}"
-94
View File
@@ -1,94 +0,0 @@
---
name: sprint-status
description: >
Sprint health check and cleanup sweep. Lists all tickets in the active
sprint grouped by status, detects bookkeeping issues (stale tickets,
orphan PRs, done-but-open PRs, unassigned work), and shows open work
by team. Use when checking sprint progress, before sprint close, or
when housekeeping feels off. Triggers on "sprint status", "cleanup
sweep", "what's open", "sprint health".
user-invocable: true
allowed-tools: Task, Read, Grep, Glob
---
# Sprint Status
**Delegate this entire skill to a subagent** (general-purpose, model: haiku).
When this skill is invoked, spawn a subagent using the Task tool:
```
Task(
subagent_type: "general-purpose",
model: "haiku",
prompt: "Run /sprint-status. Read the skill at
.claude/skills/sprint-status/SKILL.md for the full workflow
(below the --- separator), then execute it.",
description: "Sprint status report"
)
```
Present the subagent's output to the user verbatim. Do NOT run the
workflow yourself.
---
The remainder of this file is the subagent's reference for executing
the workflow.
## Step 1 — Gather data
Run these two commands in parallel:
```bash
tooling/db/sprint sweep
```
```bash
tea pr list --login schweitz --repo jpmschweitzer/settled-reach --state open --output simple
```
The `sweep` command returns JSON with:
- `sprint` — id, name, goal
- `progress` — total, done, pct
- `by_status` — tickets grouped into done, review, in_progress, blocked, backlog
- `by_team` — per-team counts
- `issues` — bookkeeping problems with suggested fix commands
The `tea pr list` returns open PRs as `#N title` lines.
## Step 2 — Cross-reference PRs with tickets
Parse PR head branches from the `tea pr list` output. Known team branches:
`server`, `client`, `copy`, `audio`, `visual`, `ci`.
Detect additional issues:
- **done_team_open_pr**: A team's tickets are all done but an open PR
still exists for that team branch.
- **orphan_pr**: An open PR exists on a branch that has no tickets in
the active sprint.
Add these to the issues list from step 1.
## Step 3 — Format output
Read `references/output-template.md` for the exact format spec.
Render the report using data from steps 1-2. Key rules:
- Sections ordered: Completed, In Review, In Progress, Blocked, Backlog
- Sort tickets within sections by team then ticket ID
- Empty sections: show header with "(0)" and "(none)" — no empty table
- Bookkeeping Issues: two-column table (Issue, Fix)
- Open Work by Team: summary table at the bottom
- Issue type labels: `stale_backlog` → "Stale backlog",
`unassigned_in_progress` → "Unassigned in_progress",
`assigned_but_done` → "Assigned but done",
`done_team_open_pr` → "Done team with open PR",
`orphan_pr` → "Orphan PR"
## Step 4 — Suggest actions
After the formatted report, if there are bookkeeping issues, add a
"Suggested fixes" section with the fix command for each issue. Group
by issue type for readability.
@@ -1,54 +0,0 @@
# Sprint Status Output Template
## Sprint {N}: {Theme} — Status Report
**Goal:** {goal}
**Status:** {status} | {done}/{total} tickets ({pct}%)
**Open PRs:** {count} ({branches})
---
### Completed ({count})
| # | Team | Title | Assigned |
|---|------|-------|----------|
| #{id} | {team} | {title} | {assigned} |
### In Review ({count})
| # | Team | Title | PR |
|---|------|-------|----|
| #{id} | {team} | {title} | #{pr} |
### In Progress ({count})
| # | Team | Title | Assigned | Note |
|---|------|-------|----------|------|
| #{id} | {team} | {title} | {assigned} | |
### Blocked ({count})
| # | Team | Title | Blocked by |
|---|------|-------|------------|
| #{id} | {team} | {title} | #{ids} |
### Backlog ({count})
| # | Team | Title | Note |
|---|------|-------|----|
| #{id} | {team} | {title} | not started |
---
### Bookkeeping Issues
| Issue | Fix |
|-------|-----|
| {type}: {detail} | `{command}` |
### Open Work by Team
| Team | Backlog | In Progress | Review | Blocked | Done |
|------|---------|-------------|--------|---------|------|
| {team} | {n} | {n} | {n} | {n} | {n} |
| **Total** | **{n}** | **{n}** | **{n}** | **{n}** | **{n}** |
+29 -20
View File
@@ -1,9 +1,9 @@
---
name: ticket
description: >
Manage project tickets in the SQLite ticketing database. Use when the user
says "ticket", "create a ticket", "show tickets", "sprint", or invokes /ticket.
Wraps the ticket CLI for structured project management operations.
Manage project tickets and milestones in the SQLite ticketing database. Use
when the user says "ticket", "create a ticket", "show tickets", "milestone",
or invokes /ticket. Wraps the ticket CLI for structured project management.
user-invocable: true
allowed-tools: Bash, Read, Grep, Glob
---
@@ -17,12 +17,12 @@ section. This skill covers the full command reference.
### List tickets (full flags)
```bash
tooling/db/ticket list [--status S] [--priority P] [--epic N] [--sprint N] [--assigned A] [--team T]
tooling/db/ticket list [--status S] [--priority P] [--epic N] [--milestone N] [--assigned A] [--team T]
```
### Create ticket
```bash
tooling/db/ticket create <type> <title> [--parent N] [--priority P] [--decision D] [--team T]
tooling/db/ticket create <type> <title> [--parent N] [--priority P] [--decision D] [--team T] [--description TEXT]
```
Types: `initiative`, `epic`, `story`, `task`, `bug`
Priorities: `critical`, `high`, `medium`, `low`
@@ -46,18 +46,27 @@ tooling/db/ticket team <id> <teams>
```
Teams are comma-separated, e.g. `server`, `client`, `server,client`.
### Sprint management
```bash
tooling/db/ticket sprint [--active]
tooling/db/ticket sprint assign <id> <sprint_id>
```
For sprint-scoped operations (status overview, context dumps, lifecycle),
use the dedicated sprint CLI instead: `tooling/db/sprint --help`
### Dependencies
```bash
tooling/db/ticket deps <id>
tooling/db/ticket dep add <blocker_id> <blocked_id>
tooling/db/ticket dep rm <blocker_id> <blocked_id>
```
### WIP
```bash
tooling/db/ticket wip
```
### Milestones
```bash
tooling/db/ticket milestone list [--status S]
tooling/db/ticket milestone create <name> [--description TEXT] [--phase N]
tooling/db/ticket milestone link <ticket_id> <milestone_id>
tooling/db/ticket milestone unlink <ticket_id> <milestone_id>
tooling/db/ticket milestone complete <milestone_id>
tooling/db/ticket milestone show <milestone_id>
tooling/db/ticket milestone dep <blocker_id> <blocked_id>
```
### Search and browse
@@ -75,10 +84,10 @@ tooling/db/ticket show --brief <id> [<id>...]
## Workflow
1. **SI (Project Manager)** is the primary user of this skill
2. Decisions from decisions/ domain files become **initiatives**
3. SI breaks initiatives into **epics** (major work areas)
4. Epics break into **stories** (user-facing deliverables)
5. Stories break into **tasks** (concrete work items assignable to agents)
6. **Sprints** group tasks into time-boxed work periods
1. Decisions from `decisions/` domain files become **initiatives**
2. Initiatives break into **epics** (major work areas)
3. Epics break into **stories** (user-facing deliverables)
4. Stories break into **tasks** (concrete work items)
5. **Milestones** group tickets by deliverable (many-to-many via `milestone link`)
6. `/whats-next` selects the next batch from the dependency graph
7. Track history via `ticket_history` table for audit trail
+209
View File
@@ -0,0 +1,209 @@
---
name: whats-next
description: >
Analyze the milestone dependency web and surface the best batch of tickets
to pick up next. Refines ticket context via parallel Si agents before
activation. Use when the user says "what's next", "next batch", "pick up
work", or invokes /whats-next. NOT triggered by "what should we work on"
in a design context — that's a discussion, not a batch selection.
user-invocable: true
allowed-tools: Bash, Read, Grep, Glob, Agent, AskUserQuestion
---
# What's Next
Dependency-driven batch selection with ticket refinement. Three steps:
batch selection → refinement review → batch activation.
## Step 1: Batch Selection
### 1a. Query active milestones
```bash
tooling/db/ticket milestone list --status active
```
If no active milestones exist, tell the user and stop.
### 1b. Build the work landscape
For each active milestone, get its tickets:
```bash
tooling/db/ticket milestone show <milestone_id>
```
Collect all tickets across all active milestones. Deduplicate (a ticket
can appear in multiple milestones).
### 1c. Identify unblocked tickets
For each ticket that is `ready` or `backlog`, check its dependencies:
```bash
tooling/db/ticket deps <id>
```
A ticket is **unblocked** if all its blockers are `done` or `cancelled`.
Filter to only unblocked tickets.
### 1d. Check milestone-level blocking
```bash
tooling/db/sqlite-query "SELECT * FROM milestone_deps"
```
If a milestone is blocked by another milestone that is not yet `completed`,
deprioritize its tickets (they're unblocked at the ticket level but the
milestone isn't ready for focus yet). Still show them, but ranked lower.
### 1e. Rank and group
Rank unblocked tickets by:
1. **Priority** (critical > high > medium > low)
2. **Milestone proximity** — milestones closest to completion (highest
done/total ratio) get priority. Finishing a milestone unlocks downstream
milestone deps.
3. **Fan-out** — tickets that unblock the most downstream tickets rank
higher (query `ticket_deps` for blocked_id counts per blocker_id)
Group into **epic-sized batches**: tickets sharing the same `parent_id`
(epic), or logically related tickets if no epic parent. If a natural
grouping doesn't exist, batch by milestone.
### 1f. Show WIP status
```bash
tooling/db/ticket wip
```
### 1g. Present the recommended batch
Show the user:
- The recommended batch (tickets with IDs, titles, priorities, milestones)
- Why this batch (which milestone it advances, what it unblocks)
- Current WIP status
- Any alternative batches worth considering
Wait for user confirmation before proceeding to Step 2.
---
## Step 2: Ticket Refinement Review
Spawn one Si agent per ticket in the confirmed batch, running in parallel.
Use `general-purpose` subagent_type with Si's personality baked into the
prompt (custom subagent_types lose SendMessage — see team-test.md).
For each ticket, spawn:
```
Agent({
subagent_type: "general-purpose",
model: "sonnet",
prompt: "You are SI, the Refinement Manager. <include si.md personality>
Review ticket #<id>: <title>
Description: <description>
Decision ref: <decision_ref>
Your job:
1. Read the ticket's decision_ref D/Q-record in decisions/*.md
2. Grep for related Q-records in decisions/questions-*.md
3. Read workshop outcomes if referenced (check docs/workshops/)
4. Check whether referenced code, tables, or files actually exist
Assess: does this ticket have enough context for an agent to implement
without guessing? Report exactly one of:
- READY: <one-paragraph summary of what the implementer needs to know>
- GAPS: <list of specific ambiguities with options for each>"
})
```
### 2a. Collect reports
Wait for all Si agents to complete. Collect their reports.
### 2b. Resolve gaps
For any ticket that came back GAPS, surface each ambiguity to the user
via AskUserQuestion:
> Ticket #NNN: <title>
> Si found these gaps:
> 1. <gap description + options>
> 2. <gap description + options>
>
> How should we resolve these?
After the user responds, append the resolution to the ticket description:
```bash
tooling/db/sqlite-exec "UPDATE tickets SET description = description || char(10) || char(10) || '---' || char(10) || 'Refinement: <resolution>' WHERE id = <id>"
```
If the user says a gap requires a D-record, flag it and ask whether to
write the D-record now or defer. If deferred, add a note to the ticket.
### 2c. Present refined batch summary
Show each ticket with:
- Si's context summary (for READY tickets) or user's resolution (for GAPS)
- Relevant D-record references
- Dependencies
Ask: "Batch ready. Activate?"
---
## Step 3: Batch Activation
### 3a. Mark tickets in_progress
```bash
tooling/db/ticket status <id> in_progress
```
For each ticket in the batch. The `status` command will warn if WIP limit
is exceeded.
### 3b. Create topic branch
Name the branch after the epic or logical grouping. Examples:
- `tier0-schema-tables` (for a schema epic)
- `heightmap-import` (for a single focused ticket)
- `city-names-pipeline` (for related importer tickets)
```bash
git checkout -b <branch-name>
```
### 3c. Create worktree (optional)
If the user wants to work in a separate worktree:
```bash
REPO_ROOT=$(git rev-parse --show-toplevel)
WORKTREE_DIR="$(dirname "$REPO_ROOT")/.worktrees/<branch-name>"
git worktree add "$WORKTREE_DIR" <branch-name>
```
Report the worktree path so the user can open a terminal there.
### 3d. Spawn implementation agents (optional)
If the user wants agents, spawn them using general-purpose subagent_type
with the relevant personality baked into the prompt. Include:
- The ticket details and Si's context summary
- Relevant D-record content (read and include, don't just reference)
- The RULES block (no git commands, write files only, message when blocked)
- Model: sonnet (per team-mode pin rule)
### 3e. Report
Summarize what was activated:
- Branch name
- Worktree path (if created)
- Tickets now in_progress
- Agents spawned (if any)
- Next step: work, then `/pr-process` when ready to ship