6.7 KiB
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/
commonwealth.db # SQLite ticketing database
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
perception.md # D-011, D-015, D-016, D-017, D-018, D-019
content.md # D-023, D-024, D-025, D-028, D-029
scope.md # D-001, D-003, D-005, D-006, D-007, D-013, D-014, D-027
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 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
Path resolution
This project uses git worktrees — each team branch is a separate directory.
The $REPO_ROOT environment variable is pre-set per worktree via
.claude/settings.local.json. Use it as a prefix for all path-sensitive
commands (especially Bash calls to scripts and CLIs).
Before starting work
- Read your sprint briefing at
$REPO_ROOT/docs/sprints/sprint-N/{team}.mdfor current tasks - Use
"$REPO_ROOT/db/connectors/ticket" show <id>for full ticket details - Read the relevant
$REPO_ROOT/decisions/*.mddomain file(s) referenced in the briefing - Background context:
$REPO_ROOT/docs/briefings/{your-name}.md,$REPO_ROOT/docs/discussions/
Ticket and database access
Prefer the ticket CLI over raw SQL. The CLI handles column names, joins, and output formatting correctly:
"$REPO_ROOT/db/connectors/ticket" list --sprint 2 --team server
"$REPO_ROOT/db/connectors/ticket" show 78
"$REPO_ROOT/db/connectors/ticket" sprint --active
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:
"$REPO_ROOT/db/connectors/sqlite-query" "SELECT * FROM tickets WHERE status='in_progress'"
"$REPO_ROOT/db/connectors/sqlite-exec" "UPDATE tickets SET status='done' WHERE id=1"
Qdrant / document search
"$REPO_ROOT/db/connectors/qdrant-search" "asymmetric information design"
"$REPO_ROOT/db/connectors/qdrant-index" docs/briefings/tyre.md
"$REPO_ROOT/db/connectors/qdrant-health"
"$REPO_ROOT/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.
# 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 <PR_NUMBER>
# Post a comment on a PR (or issue)
tea comment --login schweitz --repo jpmschweitzer/settled-reach <NUMBER> "comment body"
# Approve a PR
tea pr approve --login schweitz --repo jpmschweitzer/settled-reach <PR_NUMBER>
# List issues
tea issue list --login schweitz --repo jpmschweitzer/settled-reach --state open --output simple
Key rules:
- All flags must be explicit — omitting
--loginor--repotriggers interactive prompts that crash in Claude Code (no TTY) - Use
--output simplefor machine-readable output (no table borders) tea pr rejectdoes not work on your own PRs — usetea commentinstead- Never delete protected branches:
main,maintenance,server,client,copy,audio,visual,ciare protected on Gitea. Do not usetea pr clean,git push --delete, orgit branch -Don these branches.
File conventions
- Decisions: domain files in
decisions/(seedecisions/README.mdfor 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
"$REPO_ROOT/db/connectors/ticket"CLI or/ticketskill
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:
tea pr create \
--repo jpmschweitzer/settled-reach \
--login schweitz \
--title "feat(scope): short description" \
--description "PR body here" \
--base main \
--head branch-name
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)