# The Settled Reach A top-down immersive sim — occlusion-based detective game with combat elements, set in an original science fiction universe. Single-character perspective, asymmetric information as core mechanic, Rimworld-style storyteller. Godot 4 client + Rust/bevy_ecs simulation server via subprocess/IPC (D-020). **Official Title:** The Settled Reach (D-021) **Repository name:** commonwealth (historical code name, retained for path stability) ## Project Structure ``` client/ # Godot 4 client (D-020) server/ # Rust/bevy_ecs simulation server (D-020) tooling/ # Build tools, scripts, asset pipelines tests/ # Integration and end-to-end tests .config/ # Configuration files (linters, formatters, CI) .cache/ # Local caches for testing/linting (gitignored) docs/ discussions/ # Discussion rounds (all rounds archived here per D-022) briefings/ # Per-agent context briefings (maintained by Qatux) architecture/ # Technical architecture documents design/ # Game design documents sprints/ # Sprint briefings per team (server.md, client.md, copy.md, joint.md, etc.) workshops/ # Workshop briefs and outputs (per-workshop subdirectories) db/ schema.sql # Database schema connectors/ # Connector scripts for SQLite and Qdrant config.json # Endpoint configuration ticket # Ticket CLI (list, show, create, assign, sprint, etc.) sqlite_connector.py # SQLite mini MCP qdrant_connector.py # Qdrant + ollama mini MCP .claude/ agents/ # Agent personality files skills/ # Skill definitions decisions/ # Decision domain files (source of truth) README.md # Domain index and query examples architecture.md # D-008, D-009, D-010, D-012, D-020, D-026, D-030, D-031, D-041, D-042, D-054, D-055, D-066 perception.md # D-011, D-015, D-016, D-017, D-018, D-019, D-033, D-035, D-043-D-049, D-052, D-056-D-061 content.md # D-023, D-024, D-025, D-028, D-029, D-032, D-034-D-037, D-050, D-062-D-064 scope.md # D-001, D-003, D-005, D-006, D-007, D-013, D-014, D-027, D-038, D-039, D-051, D-053, D-065 process.md # D-004, D-021, D-022 questions.md # Q-001 through Q-011 rejected.md # R-001 through R-010 DECISIONS.md # Redirect to decisions/ directory TEAM.md # Team roster and roles ``` ## DevOps See [docs/DEVOPS.md](docs/DEVOPS.md) for build, test, lint, and CI procedures. All development operations go through the top-level `Makefile` — run `make` for a summary of targets. ## Agent Instructions ### Worktree boundaries This project uses **git worktrees** in a shared parent directory (`settled-reach/`). Each team branch (`server`, `client`, `copy`, `audio`, `visual`, `ci`) is checked out in its own worktree under that parent. The parent directory also contains shared resources like the ticketing database. Each worktree contains the full repository: `server/` (Rust backend), `client/` (Godot client), `docs/`, `decisions/`, etc. 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 (e.g. `server/src/bridge/types.rs`, `client/scripts/rendering/fog.gd`). - Do not navigate to or access sibling worktrees in the parent directory (`../client/`, `../copy/`, etc.) unless explicitly instructed. - Do not navigate above the git root unless explicitly instructed. ### 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. ### Before starting work 1. Read your sprint briefing at `docs/sprints/sprint-N/{team}.md` for current tasks 2. Use `db/connectors/ticket show ` for full ticket details 3. Read the relevant `decisions/*.md` domain file(s) referenced in the briefing 4. Background context: `docs/briefings/{your-name}.md`, `docs/discussions/` ### Ticket and database access **Prefer the ticket CLI over raw SQL.** The CLI handles column names, joins, and output formatting correctly: ```bash db/connectors/ticket list --sprint 2 --team server db/connectors/ticket show 78 db/connectors/ticket sprint --active ``` ### Sprint CLI **Use the sprint CLI for sprint-scoped operations.** It batches ticket queries and formats output for agent consumption: ```bash db/connectors/sprint status # Current sprint progress db/connectors/sprint status --team server # Team-scoped view db/connectors/sprint start-work --team client # Full context dump for starting work db/connectors/sprint prepare # Prepare next sprint (candidates + gaps) db/connectors/sprint start # Activate a planned sprint db/connectors/sprint stop # Complete an active sprint ``` Team is auto-detected from the current git branch (if not `main`). Sprint is auto-detected from DB state. Only fall back to raw SQL for queries the CLI doesn't support. **Never use the `sqlite3` CLI** — it crashes in Claude Code due to a known std::bad_alloc bug. Use the wrapper scripts instead: ```bash db/connectors/sqlite-query "SELECT * FROM tickets WHERE status='in_progress'" db/connectors/sqlite-exec "UPDATE tickets SET status='done' WHERE id=1" ``` ### Qdrant / document search ```bash db/connectors/qdrant-search "asymmetric information design" db/connectors/qdrant-index docs/briefings/tyre.md db/connectors/qdrant-health db/connectors/qdrant-count ``` ### Gitea access (tea CLI) **Never access the Gitea API directly** — use the `tea` CLI with all required flags to bypass interactive mode. Always pass `--login schweitz --repo jpmschweitzer/settled-reach --output simple` to avoid TTY prompts. ```bash # List open PRs tea pr list --login schweitz --repo jpmschweitzer/settled-reach --state open --output simple # View a PR with comments tea pr --login schweitz --repo jpmschweitzer/settled-reach --comments -o simple # Post a comment on a PR (or issue) tea comment --login schweitz --repo jpmschweitzer/settled-reach "comment body" # Approve a PR tea pr approve --login schweitz --repo jpmschweitzer/settled-reach # List issues tea issue list --login schweitz --repo jpmschweitzer/settled-reach --state open --output simple ``` Key rules: - **All flags must be explicit** — omitting `--login` or `--repo` triggers interactive prompts that crash in Claude Code (no TTY) - **Use `--output simple`** for machine-readable output (no table borders) - **`tea pr reject` does not work on your own PRs** — use `tea comment` instead - **Never delete protected branches:** `main`, `maintenance`, `server`, `client`, `copy`, `audio`, `visual`, `ci` are protected on Gitea. Do not use `tea pr clean`, `git push --delete`, or `git branch -D` on these branches. ### 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) - Discussion rounds: numbered sequentially, archived to `docs/discussions/` when complete - Briefings: one per agent, updated after decision-producing rounds - Tickets: managed via `db/connectors/ticket` CLI or `/ticket` skill ### Commit conventions Use conventional commits with project-specific scopes: `agents`, `skills`, `docs`, `briefings`, `discussions`, `schema`, `db`, `config`, `engine`, `simulation`, `client`, `ui`, `audio`, `assets`, `meta` ### Pull requests **Use `tea` (Gitea CLI), not `gh` (GitHub CLI).** The remote is Gitea at `git.schweitz.internal`. Always provide all required flags to ensure non-interactive execution: ```bash tea pr create \ --repo jpmschweitzer/settled-reach \ --login schweitz \ --title "feat(scope): short description" \ --description "PR body here" \ --base main \ --head branch-name ``` ### Large content pushes (team pattern) When producing many files (wiki pages, content batches, bulk docs): 1. **Lore librarian** agent (read-only): ingests all source material, answers focused context queries from writers, tracks cross-file consistency 2. **Multiple writer** agents (parallel, by domain): each gets a task slice, writes directly to disk using the Write tool — one file at a time, write often, no text accumulation 3. **Reviewer** agents (blocked until writing done): check voice consistency, attribute uniformity, style Key: writers use Write tool directly (no transcription bottleneck), librarian catches contradictions early, split work by domain not volume. ### Local services - Gitea: `http://git.schweitz.internal` (login: `schweitz`) - Qdrant: `http://tower-of-joy:6333/` - Ollama: `http://tower-of-joy:11434/` (nomic-embed-text) - Collection: `commonwealth` (768 dimensions, cosine distance)