diff --git a/.claude/settings.json b/.claude/settings.json index 0f478d80d..93838af11 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,7 +1,8 @@ { "autoMemoryDirectory": "/home/jeroenschweitzer/Projects/settled-reach/.memory", "env": { - "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1" + "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1", + "SR_DB_PATH": "/var/home/jeroenschweitzer/Projects/settled-reach/settledreach.db" }, "teammateMode": "in-process", "permissions": { @@ -65,7 +66,6 @@ "Bash(sed -n *)", "Skill(git-commit)", - "Skill(worktree-update)", "Skill(sprint-start)", "Skill(sprint-plan)", "Skill(pr-push)", diff --git a/.claude/skills/pr-review/SKILL.md b/.claude/skills/pr-review/SKILL.md index c989854c4..ab34e5481 100644 --- a/.claude/skills/pr-review/SKILL.md +++ b/.claude/skills/pr-review/SKILL.md @@ -16,16 +16,15 @@ on the branch type. All reviewers must approve for a clean review. ## Workflow -### 0. Branch guard — MUST be run by a Claude instance in the `main` worktree +### 0. Branch guard — MUST be run from the `main` branch ```bash git branch --show-current ``` If the current branch is **not `main`**, stop immediately and tell the user: -"PR reviews must be run by a Claude instance in the `main` worktree." -Do NOT proceed with the review. Do NOT work around this by reading files -from another worktree — the review agent itself must be running in main. +"PR reviews must be run from the `main` branch." +Do NOT proceed with the review. Stop and wait for the user to invoke `/pr-review` from main. ### 0b. Verify runtime smoke test was performed @@ -99,39 +98,24 @@ Three-dot diff with pathspec exclusions is unreliable. Instead, either: For large diffs (>1000 lines of source), provide **source files** rather than raw diff to reviewers — cleaner context, better reviews. -**IMPORTANT — use team directory paths for ALL agents.** Each team branch -is checked out in its own directory at: +**Reviewer agents read source files via `git show`.** Sprint branches +use the naming pattern `sprint-{N}/{team}`. To read a file from the +branch being reviewed: -``` -/var/mnt/data/projects/settled-reach// +```bash +git show origin/: ``` -For example, the `copy` team directory is at: -``` -/var/mnt/data/projects/settled-reach/copy/content/dialogue/... +For example: +```bash +git show origin/sprint-31/server:server/src/bin/atlas.rs ``` -**All reviewer agents** (regardless of Bash access) should read source files -from the team directory using the Read tool. This is more reliable than -`git show origin/:` because: -- All agents have Read access (no Bash dependency) -- Files are always the actual branch checkout (no stale cache) -- No risk of accidentally reading from main's working directory +If the sprint branch has an active worktree (under `.sprint/`), reviewers +can also use the Read tool with the worktree path. But `git show` is +the reliable default — it works whether or not a worktree exists. -When constructing reviewer prompts, tell agents to read files from the -team directory. Example instruction for agents: - -``` -Read the changed files from the team directory. The branch is checked -out at: /var/mnt/data/projects/settled-reach// - -For example, to read `content/dialogue/the-terminal/kael-davan.yaml`, -use: /var/mnt/data/projects/settled-reach//content/dialogue/the-terminal/kael-davan.yaml -``` - -Also tell agents to read relevant `decisions/*.md` files from the same -directory (they're identical to main, but using the team directory path -keeps agents grounded in the correct location). +Also tell agents to read relevant `decisions/*.md` files for context. ### 4. Spawn reviewers in parallel diff --git a/.claude/skills/pr-review/references/reviewer-profiles.md b/.claude/skills/pr-review/references/reviewer-profiles.md index 760b3ad2f..9442e2f77 100644 --- a/.claude/skills/pr-review/references/reviewer-profiles.md +++ b/.claude/skills/pr-review/references/reviewer-profiles.md @@ -2,17 +2,12 @@ Use `model: sonnet` for all reviewers — sufficient for review, saves cost. -**All reviewer agents read from team directories.** Each team branch is -checked out in its own directory at: -`/var/mnt/data/projects/settled-reach//` - -Tell every reviewer agent to read source files from the team directory -using the Read tool. Include the directory path and a list of changed -files in every prompt. Do NOT rely on `git show` or paste file contents — -agents can read directly from the directory. - -Note: cross-directory reading is only permitted for review agents spawned -from the `main` team. Team agents must stay within their own directory. +**Reviewer agents read source files via `git show` or from sprint +worktrees.** Sprint branches use `sprint-{N}/{team}` naming. Include +the branch name and a list of changed files in every prompt. The +default approach is `git show origin/:`. If an active +worktree exists under `.sprint/`, agents can also use the Read tool +with the worktree path. ## Code reviews (`server`, `client`, `ci`) diff --git a/.claude/skills/sprint-plan/SKILL.md b/.claude/skills/sprint-plan/SKILL.md index 767e76dc3..5c2cacb6d 100644 --- a/.claude/skills/sprint-plan/SKILL.md +++ b/.claude/skills/sprint-plan/SKILL.md @@ -154,12 +154,9 @@ 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. -**IMPORTANT — relative paths only:** Each team works in its own directory -containing the full repo (`server/`, `client/`, `docs/`, etc.). All file -paths in briefings must be relative to the working directory. Example: -`server/src/bridge/types.rs`, not `/absolute/path/to/server/src/...` or -paths that navigate outside (`../sibling-dir/...`). -Agents must stay within their team's working directory. +**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 diff --git a/.claude/skills/sprint-plan/references/briefing-template.md b/.claude/skills/sprint-plan/references/briefing-template.md index 34adf6320..f2a6d8c94 100644 --- a/.claude/skills/sprint-plan/references/briefing-template.md +++ b/.claude/skills/sprint-plan/references/briefing-template.md @@ -9,7 +9,7 @@ Each team gets one briefing file at `docs/sprints/sprint-N/.md`. **Goal:** -**Branch:** `` +**Branch:** `sprint-{N}/` **Agents:** ## Carry-over from Sprint N-1 @@ -57,7 +57,7 @@ One bullet per ticket with: 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(): description" --description "body" --base main --head +tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(): description" --description "body" --base main --head sprint-{N}/ \``` ``` @@ -73,7 +73,8 @@ The `joint.md` file additionally includes: | Team | Branch | Agents | Scope | |------|--------|--------|-------| -| server | `server` | Dudley (simulation), Oscar (networking) | Rust/bevy_ecs simulation | -| client | `client` | Stig (UI), Oscar (networking) | Godot client rendering | +| 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 | diff --git a/.claude/skills/sprint-start/SKILL.md b/.claude/skills/sprint-start/SKILL.md index b7ba98eec..a28b500cc 100644 --- a/.claude/skills/sprint-start/SKILL.md +++ b/.claude/skills/sprint-start/SKILL.md @@ -25,8 +25,8 @@ The current branch IS the team. Read it with: git branch --show-current ``` -Valid team branches: `server`, `client`, `copy`, `audio`, `visual`, `ci`, -`planning`. +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). @@ -130,6 +130,18 @@ 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 + +Remove ephemeral worktrees for the closed sprint. Run the teardown script: + +```bash +.claude/skills/sprint-start/scripts/sprint-teardown.sh {N} +``` + +This removes all worktrees under `.sprint/sprint-{N}/` and prunes git +metadata. Safe to skip if the sprint didn't use ephemeral worktrees +(e.g. legacy persistent worktree setup). + #### A2. Bump the version The project version scheme is `v0.1.{sprint_number}`. After closing @@ -200,7 +212,7 @@ tooling/db/sprint start Then report: - Sprint activated (name, ticket count per team) - Remind the user to switch to a team branch and run `/sprint-start` - there (or `cd` into the relevant worktree) + there (or run `start-sprint` to open team tabs) --- @@ -215,6 +227,9 @@ to plan the next sprint. ### 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 @@ -329,14 +344,14 @@ Task( team_name: "sprint-{N}-{team}", name: "{name_lowercase}", prompt: "You are on the {team} team for Sprint {N}. - Branch: `{team}` + Branch: `sprint-{N}/{team}` RULES (NON-NEGOTIABLE): - 0. TEAM BOUNDARY: Your team is `{team}` ($WORKTREE_TEAM). Stay - within the current working directory. Do NOT navigate to - parent or sibling directories. Do NOT follow .git pointers - to other directories. + 0. TEAM SCOPE: Your team is `{team}` on branch `sprint-{N}/{team}`. + You may modify files in: {team_scope_dirs} + 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 diff --git a/.claude/skills/sprint-start/scripts/sprint-teardown.sh b/.claude/skills/sprint-start/scripts/sprint-teardown.sh new file mode 100755 index 000000000..bd7d74201 --- /dev/null +++ b/.claude/skills/sprint-start/scripts/sprint-teardown.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# Clean up ephemeral worktrees for a closed sprint. +# Usage: sprint-teardown.sh +# +# 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_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." diff --git a/.claude/skills/worktree-update/SKILL.md b/.claude/skills/worktree-update/SKILL.md deleted file mode 100644 index 085797484..000000000 --- a/.claude/skills/worktree-update/SKILL.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -name: worktree-update -description: > - Sync worktree branches with main. Use when the user says "update worktrees", - "sync branches", "merge main", "worktree update", or invokes /worktree-update. - When on main: shows which worktree branches are ahead and lets the user pick - which to merge into main (flags branches with open PRs). When on a non-main - branch: merges main into the current branch. All operations are non-destructive. -user-invocable: true -allowed-tools: Bash, Read, AskUserQuestion ---- - -# Worktree Update Skill - -Sync worktree branches safely. Direction depends on the current branch. - -## Safety Rules (NON-NEGOTIABLE) - -- **Never force-push, reset --hard, rebase, or delete branches.** -- **Never use `--no-verify` or skip hooks.** -- **Always use `--no-edit` on merges** to avoid interactive editor prompts. -- **Stop on merge conflicts** — report them and let the user decide. Never - auto-resolve or abort a conflicted merge without asking. -- **Fetch before comparing** — always `git fetch --all` first so commit - comparisons are accurate. -- **Dry-run first on main** — show the user exactly what will happen before - merging anything into main. - -## Workflow - -### 1. Detect current branch - -```bash -git branch --show-current -``` - -Branch determines the mode: `main` → outbound sync, anything else → inbound sync. - -### 2a. On `main` — merge worktree branches into main - -#### Fetch and compare - -```bash -git fetch --all -``` - -Discover all worktree branches (excluding `main` itself): - -```bash -git worktree list | grep -v '\[main\]' | sed 's/.*\[//;s/\]//' -``` - -For each worktree branch, check if it has commits ahead of main: - -```bash -git rev-list --count main..origin/ -``` - -Skip branches with 0 commits ahead. For branches that ARE ahead, collect: -- Branch name -- Number of commits ahead -- One-line log of those commits: `git log --oneline main..` - -#### Check for open PRs - -```bash -tea pr list --login schweitz --repo jpmschweitzer/settled-reach --state open --output simple -``` - -Cross-reference open PR head branches with the ahead-of-main branches. - -#### Present results - -Show a summary table of branches ahead of main. For each branch, indicate: -- `[PR]` if it has an open pull request — warn that it should go through - normal review channels (use `/pr-review` instead) -- Commit count and summary - -Use `AskUserQuestion` to let the user pick which branches to merge. -Exclude PR-flagged branches from the default options (but allow the user to -override via "Other"). - -#### Merge selected branches - -For each selected branch, one at a time: - -```bash -git merge --no-edit -``` - -If a merge conflicts, **stop immediately**. Report the conflict and do NOT -continue to the next branch. The user must resolve before proceeding. - -After all merges, show the final state with `git log --oneline -N` (where N -covers the new commits). - -#### Backup the shared database - -After successful merges on main, snapshot the database for git tracking: - -```bash -make db-backup -``` - -This copies the shared `settledreach.db` (in the parent directory) to -`docs/backups/settledreach.db.backup`. Stage and commit it with the merge -if the file changed. - -### 2b. Not on `main` — merge main into current branch - -```bash -git fetch --all -git merge origin/main --no-edit -``` - -If clean, report the result (fast-forward or merge commit, files changed). -If conflicts, report them and stop. - -### 3. Push - -After a successful merge, push the branch: - -```bash -git push origin -``` diff --git a/CLAUDE.md b/CLAUDE.md index bae2d468f..f9696cd30 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -44,18 +44,17 @@ Development follows a strict cascade. Each phase has a concrete deliverable. **D ### Team boundaries -**Your team identity is `$WORKTREE_TEAM`.** All work must stay within the current working directory. +**Your team is determined by your sprint branch** (e.g. `sprint-31/server` → server team). -- All file paths are relative to the current working directory (e.g. `server/src/bridge/types.rs`). -- **Do NOT navigate to parent or sibling directories** (`../`, `../client/`, etc.) unless explicitly instructed. Do NOT use absolute paths to reach other team directories. -- **Do NOT write auto-memory files for other teams.** If `$WORKTREE_TEAM` is `server`, do not write to memory paths containing `client`, `main`, etc. -- For context: each team has its own directory via git worktrees, sharing a parent directory (`settled-reach/`). The `.git` file points to a shared git directory — do not follow it to determine your working root. -- **Exception — stale git lock files:** If a `git` command fails with `index.lock: File exists`, you may remove the lock file for **your own team only** (e.g. `main/.git/worktrees/$WORKTREE_TEAM/index.lock`). Never touch lock files belonging to other teams. -- **Never chain git commands** in a single Bash call (e.g. `git add ... && git commit ...`). The shared `.git` directory means concurrent index access from the same terminal creates `index.lock` collisions. Always run `git add` and `git commit` as **separate sequential Bash calls**. +- All file paths are relative to the repo root (e.g. `server/src/bridge/types.rs`). +- **Stay within your team's scope.** Server team modifies `server/`. Client team modifies `client/`. Copy team modifies `wiki/`, `docs/atlas/`, `content/`. Shared directories (`docs/`, `decisions/`) are readable by all teams. +- **Do NOT modify files outside your team scope** unless the ticket explicitly requires it. +- **Never chain git commands** in a single Bash call (e.g. `git add ... && git commit ...`). Always run `git add` and `git commit` as **separate sequential Bash calls**. +- **Stale git lock files:** If a `git` command fails with `index.lock: File exists`, you may remove the lock file at `.git/index.lock` (or `.git/worktrees//index.lock` if in a worktree). ### Database -The ticketing database (`settledreach.db`) lives in the **parent directory** shared across all worktrees — it is not tracked in git. A backup is committed to `docs/backups/settledreach.db.backup` via main only. +The ticketing database (`settledreach.db`) is accessed via `SR_DB_PATH` env var (set in `.claude/settings.json`). A backup is committed to `docs/backups/settledreach.db.backup` via main only. ### Before starting work 1. Read your sprint briefing at `docs/sprints/sprint-N/{team}.md` for current tasks @@ -97,7 +96,7 @@ The ticketing database (`settledreach.db`) lives in the **parent directory** sha ### File conventions - Decisions: domain files in `decisions/` (see `decisions/README.md` for index) - Decision IDs: `D-NNN` (confirmed), `Q-NNN` (open questions), `R-NNN` (rejected) -- **Claim IDs before writing:** `tooling/db/decision claim D "title"` — prevents ID collisions across worktrees +- **Claim IDs before writing:** `tooling/db/decision claim D "title"` — prevents ID collisions across parallel branches - Diagrams: `.d2` source + `.png` renders in `docs/diagrams/{category}/`. Create or update diagrams via `/d2-diagram` when D-records are added or modified. - Discussion rounds: numbered sequentially, archived to `docs/discussions/` when complete - Briefings: one per agent, updated after decision-producing rounds diff --git a/tooling/db-backup b/tooling/db-backup index 9911f5040..71dd20213 100755 --- a/tooling/db-backup +++ b/tooling/db-backup @@ -5,7 +5,8 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" WORKTREE_ROOT="$(dirname "$SCRIPT_DIR")" -DB_PATH="$(dirname "$WORKTREE_ROOT")/settledreach.db" +# Database path: SR_DB_PATH env var (absolute), or fallback to parent directory heuristic. +DB_PATH="${SR_DB_PATH:-$(dirname "$WORKTREE_ROOT")/settledreach.db}" BACKUP_PATH="$WORKTREE_ROOT/docs/backups/settledreach.db.backup" branch="$(git -C "$WORKTREE_ROOT" branch --show-current)" diff --git a/tooling/db/decisions_sync.py b/tooling/db/decisions_sync.py index cd9c94551..b1ea7d0e2 100644 --- a/tooling/db/decisions_sync.py +++ b/tooling/db/decisions_sync.py @@ -26,8 +26,8 @@ CONFIG_PATH = SCRIPT_DIR / "config.json" WORKTREE_ROOT = (SCRIPT_DIR / ".." / "..").resolve() SCHEMA_PATH = WORKTREE_ROOT / "db" / "schema.sql" DECISIONS_DIR = WORKTREE_ROOT / "decisions" -# Shared database lives in the parent of all worktrees (three levels up from tooling/db/). -DB_PATH = (WORKTREE_ROOT / ".." / "settledreach.db").resolve() +# Database path: SR_DB_PATH env var (absolute), or fallback to parent directory heuristic. +DB_PATH = Path(os.environ["SR_DB_PATH"]).resolve() if os.environ.get("SR_DB_PATH") else (WORKTREE_ROOT / ".." / "settledreach.db").resolve() # --------------------------------------------------------------------------- # Config / DB (same pattern as sqlite_connector.py) diff --git a/tooling/db/sprint b/tooling/db/sprint index 0eae01517..f8ebe4dc6 100755 --- a/tooling/db/sprint +++ b/tooling/db/sprint @@ -24,7 +24,8 @@ from pathlib import Path SCRIPT_DIR = Path(__file__).resolve().parent TICKET_CLI = str(SCRIPT_DIR / "ticket") WORKTREE_ROOT = (SCRIPT_DIR / ".." / "..").resolve() -DB_PATH = (WORKTREE_ROOT / ".." / "settledreach.db").resolve() +# Database path: SR_DB_PATH env var (absolute), or fallback to parent directory heuristic. +DB_PATH = Path(os.environ["SR_DB_PATH"]).resolve() if os.environ.get("SR_DB_PATH") else (WORKTREE_ROOT / ".." / "settledreach.db").resolve() PROJECT_ROOT = WORKTREE_ROOT REMINDER = """--- diff --git a/tooling/db/sqlite_connector.py b/tooling/db/sqlite_connector.py index 1f41587da..b3a16ebdb 100755 --- a/tooling/db/sqlite_connector.py +++ b/tooling/db/sqlite_connector.py @@ -24,8 +24,8 @@ SCRIPT_DIR = Path(__file__).resolve().parent CONFIG_PATH = SCRIPT_DIR / "config.json" WORKTREE_ROOT = (SCRIPT_DIR / ".." / "..").resolve() SCHEMA_PATH = WORKTREE_ROOT / "db" / "schema.sql" -# Shared database lives in the parent of all worktrees (three levels up from tooling/db/). -DB_PATH = (WORKTREE_ROOT / ".." / "settledreach.db").resolve() +# Database path: SR_DB_PATH env var (absolute), or fallback to parent directory heuristic. +DB_PATH = Path(os.environ["SR_DB_PATH"]).resolve() if os.environ.get("SR_DB_PATH") else (WORKTREE_ROOT / ".." / "settledreach.db").resolve() def load_config(): diff --git a/tooling/db/ticket b/tooling/db/ticket index 04028e02f..777b0e3fa 100755 --- a/tooling/db/ticket +++ b/tooling/db/ticket @@ -31,8 +31,8 @@ from pathlib import Path SCRIPT_DIR = Path(__file__).resolve().parent CONFIG_PATH = SCRIPT_DIR / "config.json" WORKTREE_ROOT = (SCRIPT_DIR / ".." / "..").resolve() -# Shared database lives in the parent of all worktrees (three levels up from tooling/db/). -DB_PATH = (WORKTREE_ROOT / ".." / "settledreach.db").resolve() +# Database path: SR_DB_PATH env var (absolute), or fallback to parent directory heuristic. +DB_PATH = Path(os.environ["SR_DB_PATH"]).resolve() if os.environ.get("SR_DB_PATH") else (WORKTREE_ROOT / ".." / "settledreach.db").resolve() def load_config(): diff --git a/whatsinagame/templates/CLAUDE.md b/whatsinagame/templates/CLAUDE.md index cc70bb0bf..75976f628 100644 --- a/whatsinagame/templates/CLAUDE.md +++ b/whatsinagame/templates/CLAUDE.md @@ -42,19 +42,13 @@ See [docs/DEVOPS.md](docs/DEVOPS.md) for build, test, lint, and CI procedures. A ## Agent Instructions -### Worktree boundaries +### Team boundaries -{If using git worktrees:} +{If using sprint branches with ephemeral worktrees:} -This project uses **git worktrees** in a shared parent directory. Each team branch is checked out in its own worktree under that parent. The parent directory also contains shared resources like the ticketing database. +Teams work on sprint branches (`sprint-{N}/{team}`). Ephemeral worktrees may be created per sprint via `start-sprint`. All file paths are relative to the repo root. -Each worktree contains the full repository. The worktree root IS the git root — use `git rev-parse --show-toplevel` if in doubt. - -Unless there is a direct instruction or a functional need (e.g. accessing the shared database in the parent directory), **all work must remain within the scope of the git root Claude is running in.** - -- All file paths are relative to the worktree/git root. -- Do not navigate to or access sibling worktrees unless explicitly instructed. -- Do not navigate above the git root unless explicitly instructed. +Each team has a scope — directories they may modify. Shared directories (`docs/`, `decisions/`) are readable by all teams. {If single-branch workflow:} @@ -62,7 +56,7 @@ All work happens on feature branches from `main`. All file paths are relative to ### Database -The ticketing database (`{db_name}`) lives {in the parent directory shared across worktrees | in the repository root}. Access via CLI wrappers — never use the `sqlite3` CLI directly (it crashes in Claude Code due to std::bad_alloc): +The ticketing database (`{db_name}`) is accessed via `SR_DB_PATH` env var or parent directory fallback. Access via CLI wrappers — never use the `sqlite3` CLI directly (it crashes in Claude Code due to std::bad_alloc): ```bash tooling/db/ticket list --sprint N --team {team} diff --git a/whatsinagame/templates/DEVOPS.md b/whatsinagame/templates/DEVOPS.md index 77c167883..e94619672 100644 --- a/whatsinagame/templates/DEVOPS.md +++ b/whatsinagame/templates/DEVOPS.md @@ -92,29 +92,26 @@ This runs: 1. Decision sync (ensures SQLite index is current) 2. {Add project-specific checks as needed} -## Worktree Workflow (if configured) +## Sprint Branch Workflow -If the project uses git worktrees for team branches: +Teams work on ephemeral sprint branches (`sprint-{N}/{team}`). The `start-sprint` +script creates worktrees under `.sprint/` for parallel team work: ``` {parent}/ - main/ # Integration branch (worktree) - server/ # Server team branch (worktree) - client/ # Client team branch (worktree) - {team}/ # Additional team branches - {db_name} # Shared ticketing database + main/ # Permanent — integration branch + .sprint/sprint-{N}/{team}/ # Ephemeral — created per sprint, deleted after close + {db_name} # Shared ticketing database ``` -Each worktree is a full checkout. The shared database lives in the parent directory. Agents should stay within their worktree root unless accessing the shared database. - ### Branch management ```bash -# Update worktree branch from main -git merge main +# Start sprint session (creates worktrees + terminal tabs) +./start-sprint [sprint-number] -# Check worktree status -git worktree list +# Clean up after sprint close +.claude/skills/sprint-start/scripts/sprint-teardown.sh {N} ``` -**Protected branches** (never delete): `main`, and all team branches. +**Protected branches** (never delete): `main`.