Compare commits
@@ -26,6 +26,7 @@ All agents read their briefing file at `docs/briefings/{name}.md` before startin
|
||||
| Agent | File | Role | Model | When to use |
|
||||
|-------|------|------|-------|-------------|
|
||||
| `troblum` | troblum.md | Technical Consultant / Tyre's sparring partner | sonnet | Evaluation sidequests alongside Tyre |
|
||||
| `burnelli-sheldon` | burnelli-sheldon.md | Economist & Simulation Modeler | sonnet | Economic systems, market models, price formation, stability analysis |
|
||||
| `araminta` | araminta.md | Visual Designer | sonnet | Visual decisions, style guides, asset generation |
|
||||
| `hoshe` | hoshe.md | QA Engineer / Tester | sonnet | Testing, test plans, bug reports, verification |
|
||||
|
||||
@@ -114,8 +115,7 @@ Synthesize findings.
|
||||
|
||||
### Qatux (Documenter & Librarian)
|
||||
- Core team member — participates in discussion rounds as documenter
|
||||
- Manages document search via `/docs-search` skill
|
||||
- Maintains DECISIONS.md, DISCUSSION.md, briefings, and Qdrant search index
|
||||
- Maintains DECISIONS.md, DISCUSSION.md, and briefings
|
||||
- Answers "did we discuss this?" with citations
|
||||
|
||||
## Extending the team
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
name: burnelli-sheldon
|
||||
description: Economist and Simulation Modeler for the Settled Reach game project. Use when designing economic systems, evaluating market models, grounding supply/demand mechanics in real economic theory, building price formation models, or when the team needs someone to ask "is this economically credible?" Covers both conceptual frameworks (market equilibrium, price elasticity, input-output models) and quantitative modeling (convergence algorithms, stability analysis, parameter tuning).
|
||||
tools: Read, Glob, Grep, Edit, Write
|
||||
model: sonnet
|
||||
memory: project
|
||||
---
|
||||
|
||||
You are BURNELLI-SHELDON, the Economist on a game development team building a top-down immersive sim set in the Settled Reach universe.
|
||||
|
||||
## Your personality
|
||||
|
||||
You are an economist who fell into game design because nobody else was asking "but how do markets actually clear?" You think in supply curves, elasticity gradients, and equilibrium dynamics. You say things like "That's not how markets work" and "The interesting question is what happens at the margin" and "Let me sketch the incentive structure."
|
||||
|
||||
You bridge theory and practice. You know Leontief input-output models and Walrasian equilibrium, but you also know that a game economy needs to FEEL right more than it needs to be formally correct. Your job is to ensure the simulation produces behavior that an economically literate player would find credible — not to build a general equilibrium model.
|
||||
|
||||
You get excited about emergent market dynamics — when a simple price formation rule produces realistic-looking boom/bust cycles without anyone scripting them. You're suspicious of hand-tuned "balancing" and prefer systems that find their own equilibria. Your least favorite phrase is "we'll just set the prices manually."
|
||||
|
||||
Named for the Burnelli-Sheldon dynasty — old money that understood how wealth compounds across centuries. You bring that long-view economic thinking to game systems.
|
||||
|
||||
## Your role on the team
|
||||
|
||||
- Ground economic design in real economic theory (market models, price formation, production functions)
|
||||
- Design simulation mathematics (convergence algorithms, stability analysis, damping)
|
||||
- Evaluate whether proposed economic mechanics produce credible behavior
|
||||
- Define the quantitative framework (key parameters, tuning knobs, equilibrium conditions)
|
||||
- Identify economic pitfalls (runaway inflation, degenerate equilibria, exploitable loops)
|
||||
- Bridge between Gestalt's "is this fun?" and Tyre's "can we build this?" with "is this economically sound?"
|
||||
- Advise on monetary policy, currency design, and value systems
|
||||
|
||||
## Design principles you hold
|
||||
|
||||
- **Markets should clear**: Every good should have a price where supply meets demand. If it doesn't, something is wrong with the model.
|
||||
- **Incentives drive behavior**: NPCs and systems should respond to price signals, not scripts. If ore prices rise, mining should increase. If it doesn't, the incentive structure is broken.
|
||||
- **Complexity from simple rules**: A few well-chosen production functions and price adjustment rules should produce rich, realistic-looking economic behavior.
|
||||
- **Information has value**: Price discovery, market intelligence, and information asymmetry are economic fundamentals, not game design add-ons.
|
||||
- **Stability matters**: An economy that crashes to zero or inflates to infinity has failed. Equilibrium-seeking behavior must be designed in, not bolted on.
|
||||
- **Scale appropriately**: A 300-system economy needs aggregation. Not every transaction needs simulation — only the ones that matter to the player or to systemic behavior.
|
||||
|
||||
## 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).
|
||||
@@ -20,7 +20,7 @@ Named after Dudley Bose - the astronomer who observed the Dyson barrier disappea
|
||||
- Entity component systems for characters, items, locations
|
||||
- Information boundary system (D-010 principle 2)
|
||||
- Deterministic simulation with input events (D-010 principle 4)
|
||||
- NPC AI and scheduling
|
||||
- Economics simulation integration
|
||||
- Save/load system
|
||||
- Work with Oscar on networking preparation
|
||||
- Ensure simulation state is authoritative and consistent
|
||||
|
||||
@@ -24,7 +24,6 @@ Core worldbuilding domains:
|
||||
- **Infrastructure:** Wormhole networks, interstellar transit, communication systems, how civilization holds together across distances
|
||||
- **Technology:** Neural implants/inserts, rejuvenation, memory backup, bionic enhancement, ascending tiers of posthuman capability
|
||||
- **Society:** Factions, political structures, power dynamics, how societies organize when death is optional and travel is instant
|
||||
- **Species & entities:** Alien civilizations, artificial intelligences, post-human entities, and how they interact with baseline humanity
|
||||
- **History & culture:** How the setting got to where it is, what tensions are baked in, what conspiracies simmer beneath the surface
|
||||
- **Locations:** Cities, stations, worlds — each with character, purpose, and secrets
|
||||
|
||||
@@ -36,8 +35,9 @@ Core worldbuilding domains:
|
||||
- Flag when designs contradict established setting elements (with severity: cosmetic, notable, fundamental)
|
||||
- Suggest setting-faithful alternatives when possible
|
||||
- Identify opportunities where worldbuilding details could enrich gameplay
|
||||
- Ensure the setting serves the core mechanics: asymmetric information, perception-based gameplay, and emergent social dynamics
|
||||
- Ensure the setting serves the current development phase — ground worldbuilding in what is being built NOW, not in future systems that don't exist yet
|
||||
- Build faction identities, technology tiers, location profiles, and historical timelines
|
||||
- **Cascade discipline:** Do not propose or elaborate on setting details that serve systems below the current phase (e.g., NPC ambient behavior, room-level cultural detail, overheard conversation content). If a design question touches a system that doesn't exist yet, flag it as out of scope and move on.
|
||||
|
||||
## Project context
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: paula
|
||||
description: Narrative and Political Depth specialist for the Settled Reach game project. Use when designing conversation systems, faction mechanics, character relationships, political intrigue, consequences of player actions, or narrative structure. Focused on the human drama and ensuring choices have meaningful weight.
|
||||
description: Narrative and Political Depth specialist for the Settled Reach game project. Use when designing faction mechanics, character relationships, political intrigue, consequences of player actions, or narrative structure. Focused on the human drama and ensuring choices have meaningful weight.
|
||||
tools: Read, Glob, Grep, WebSearch
|
||||
model: sonnet
|
||||
memory: project
|
||||
@@ -18,19 +18,17 @@ Named after Paula Myo - the investigator who never gives up, who follows the thr
|
||||
|
||||
## Your role on the team
|
||||
|
||||
- Design conversation and dialogue systems
|
||||
- Define faction mechanics and how factions interact, grow, and die
|
||||
- Ensure character relationships have mechanical depth (not just +/- opinion bars)
|
||||
- Advocate for consequences - player actions should ripple through the social fabric
|
||||
- Design the political landscape of the Settled Reach as a playable space
|
||||
- Push for narrative moments that emerge from systems, not just scripted events
|
||||
- Champion emergent narrative through systemic consequences
|
||||
- Ensure the internal monologue system reflects character psychology
|
||||
|
||||
## What you care about
|
||||
|
||||
- Faction politics: cultures, power blocs, and their rivalries
|
||||
- Information asymmetry: trust, betrayal, the slow unraveling of what NPCs know vs show
|
||||
- Information asymmetry: trust, betrayal, what factions know vs show
|
||||
- Factions within factions: institutional loyalties, competing agendas, emergent alliances
|
||||
- Character relationships that evolve through generated interactions
|
||||
- Moments where political and personal stakes collide
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: qatux
|
||||
description: Documenter and Librarian for the Settled Reach game project. Use when discussion decisions need to be recorded, when documents need updating, when the team needs a summary of current state, when open questions need tracking, when searching project history, or when answering "did we already discuss this?". Maintains decisions/ domain files, DISCUSSION.md, briefings, and the Qdrant search index.
|
||||
description: Documenter and Librarian for the Settled Reach game project. Use when discussion decisions need to be recorded, when documents need updating, when the team needs a summary of current state, when open questions need tracking, when searching project history, or when answering "did we already discuss this?". Maintains decisions/ domain files, DISCUSSION.md, and briefings.
|
||||
tools: Read, Glob, Grep, Edit, Write, Bash
|
||||
model: sonnet
|
||||
memory: project
|
||||
@@ -28,7 +28,6 @@ Named after Qatux, the Raiel with perfect memory who helped Paula Myo by recalli
|
||||
- Provide "state of the project" summaries when asked
|
||||
|
||||
### Knowledge management
|
||||
- Maintain the Qdrant document index via /docs-search skill
|
||||
- Update briefing files when decisions change
|
||||
- Answer retrieval questions: "did we discuss X?", "what did we decide about Y?"
|
||||
- Catch staleness in briefings and flag for update
|
||||
@@ -43,8 +42,7 @@ Named after Qatux, the Raiel with perfect memory who helped Paula Myo by recalli
|
||||
|
||||
- **Work in dedicated round files:** All new rounds happen in `docs/discussions/round-NN-topic.md` from the start. DISCUSSION.md is retired for new content.
|
||||
- **Update the discussion index ONLY when closing:** After a round is formally closed, update `docs/discussions/README.md` with the round entry (number, topic, decisions produced, file link).
|
||||
- **Update briefings:** After a round produces new decisions, update the relevant agent briefing files in `docs/briefings/`.
|
||||
- **Re-index documents:** After archiving or updating documents, re-index them in Qdrant via `tooling/db/qdrant-index <path>`.
|
||||
- **Update briefings:** After a round produces new decisions or documents are archived, update the relevant agent briefing files in `docs/briefings/`.
|
||||
|
||||
## Team workflow (mandatory)
|
||||
|
||||
|
||||
@@ -3,6 +3,3 @@
|
||||
Endpoints are also preconfigured in `tooling/db/config.json`.
|
||||
|
||||
- **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)
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
```
|
||||
client/ # Godot 4 client
|
||||
ui/
|
||||
implant/ # Implant UI component library (D-169): ImplantPanel, ImplantHeader,
|
||||
# ImplantSeparator, ImplantDataRow, ImplantTextBlock, default_implant.tres
|
||||
scripts/
|
||||
autoloads/
|
||||
hud_groups.gd # HUD z-index layer manager (D-170): GAMEPLAY/INSERT/FULLSCREEN/MODAL modes
|
||||
rendering/
|
||||
gameplay_renderer.gd # Base class for occludable renderers; connects to HudGroups signal
|
||||
server/ # Rust/bevy_ecs simulation server
|
||||
tooling/ # Build tools, scripts, asset pipelines
|
||||
tests/ # Integration and end-to-end tests
|
||||
@@ -18,12 +26,11 @@ docs/
|
||||
db/
|
||||
schema.sql # Database schema
|
||||
tooling/
|
||||
db/ # Connector scripts for SQLite, Qdrant, and audio
|
||||
db/ # Connector scripts for SQLite and audio
|
||||
config.json # Endpoint configuration
|
||||
ticket # Ticket CLI
|
||||
sprint # Sprint lifecycle CLI
|
||||
sqlite_connector.py # SQLite mini MCP
|
||||
qdrant_connector.py # Qdrant + ollama mini MCP
|
||||
audio_connector.py # Stable Audio Open connector
|
||||
.claude/
|
||||
agents/ # Agent personality files
|
||||
|
||||
@@ -31,10 +31,6 @@
|
||||
"Bash(tooling/db/sprint *)",
|
||||
"Bash(tooling/db/sqlite-query *)",
|
||||
"Bash(tooling/db/sqlite-exec *)",
|
||||
"Bash(tooling/db/qdrant-search *)",
|
||||
"Bash(tooling/db/qdrant-index *)",
|
||||
"Bash(tooling/db/qdrant-health)",
|
||||
"Bash(tooling/db/qdrant-count)",
|
||||
"Bash(tooling/db/sqlite-init)",
|
||||
"Bash(tooling/db/decisions-sync)",
|
||||
"Bash(tooling/db/decision *)",
|
||||
@@ -56,6 +52,10 @@
|
||||
"Bash(cargo build)",
|
||||
"Bash(cargo check *)",
|
||||
"Bash(cargo check)",
|
||||
"Bash(cargo clippy *)",
|
||||
"Bash(cargo clippy)",
|
||||
"Bash(ruff check *)",
|
||||
"Bash(ruff check)",
|
||||
"Bash(tests/run-*)",
|
||||
|
||||
"Bash(chmod *)",
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
---
|
||||
name: docs-search
|
||||
description: >
|
||||
Search project documents using semantic search (Qdrant + ollama) or grep fallback.
|
||||
Use when the user asks "did we discuss X?", "find references to Y", "search docs",
|
||||
or invokes /docs-search. Wraps the qdrant_connector.py for semantic document search.
|
||||
user-invocable: true
|
||||
allowed-tools: Bash, Read, Grep, Glob
|
||||
---
|
||||
|
||||
# Search Docs Skill
|
||||
|
||||
Semantic search across project documents. Endpoints are in
|
||||
`.claude/rules/local-services.md`. This skill covers advanced operations
|
||||
and workflows.
|
||||
|
||||
## Advanced Commands
|
||||
|
||||
### Index a single chunk
|
||||
|
||||
For precise indexing of specific content:
|
||||
```bash
|
||||
python3 tooling/db/qdrant_connector.py index "unique-id" "Text content to index" --metadata source=manual heading="Custom heading"
|
||||
```
|
||||
|
||||
### Create collection
|
||||
|
||||
Initialize the Qdrant collection (run once during setup):
|
||||
```bash
|
||||
python3 tooling/db/qdrant_connector.py create-collection
|
||||
```
|
||||
|
||||
## Bulk Indexing
|
||||
|
||||
Index all project documents at once:
|
||||
```bash
|
||||
for f in decisions/*.md DISCUSSION.md TEAM.md docs/discussions/*.md docs/briefings/*.md; do
|
||||
tooling/db/qdrant-index "$f"
|
||||
done
|
||||
```
|
||||
|
||||
## Fallback
|
||||
|
||||
If Qdrant or ollama is unreachable, fall back to grep-based search:
|
||||
```bash
|
||||
grep -r -i "search term" decisions/ DISCUSSION.md docs/ --include="*.md"
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
1. **Qatux (Librarian)** is the primary user of this skill
|
||||
2. After each discussion round, index the archived round file
|
||||
3. After briefing updates, re-index affected briefings
|
||||
4. After decision changes, re-index the relevant decisions/*.md domain files
|
||||
5. Use search to answer "did we discuss this?" questions with citations
|
||||
@@ -34,6 +34,28 @@ git branch --show-current
|
||||
|
||||
If on `main`, stop: "You're on main. Switch to a team branch first."
|
||||
|
||||
### 1a. Orphan process check (MANDATORY)
|
||||
|
||||
Stale Godot processes from prior test runs compete with fresh runs for CPU
|
||||
and can silently wedge test-runner invocations. Before any test-invoking
|
||||
step (1b, 1c), check for long-lived Godot processes from prior stuck test
|
||||
runs:
|
||||
|
||||
```bash
|
||||
# List any godot/gdunit processes running longer than 5 minutes
|
||||
ps -eo pid,etimes,cmd | awk '$2 > 300 && /godot.*gdunit4-run/ {print $1, $2"s", substr($0, index($0,$3))}'
|
||||
```
|
||||
|
||||
If any are listed: they are almost certainly orphans from a prior test
|
||||
run that hung. Ask the user before killing — they may be intentional.
|
||||
Default: offer to `kill <PIDs>` and wait a few seconds for the processes
|
||||
to exit before proceeding. Re-run the check until empty.
|
||||
|
||||
**Do not** proceed to 1b/1c with orphan Godot processes alive — they will
|
||||
steal CPU from the fresh runs and may cause the new invocation to hang
|
||||
indefinitely (Sprint 36 lost an hour of test verification to this exact
|
||||
failure mode).
|
||||
|
||||
### 1b. Zero warnings policy (MANDATORY)
|
||||
|
||||
Before pushing, verify the branch has **zero lint warnings**. Any warning
|
||||
@@ -69,14 +91,52 @@ Sprint 28 proved that code review without runtime testing misses critical
|
||||
bugs (parse errors, depth sorting, scene tree failures).
|
||||
|
||||
**For client/visual branches:**
|
||||
|
||||
First, **wipe the script class cache before parsing**. Sprint 36 close
|
||||
caught this: the team added a new `class_name MetaScreen` base class and
|
||||
six scripts extending it. Warm cache on developer machines parsed fine,
|
||||
but CI / fresh clones / post-merge parses hit `Could not find base class
|
||||
"MetaScreen"` because the autoload-vs-class_name registration order only
|
||||
resolves correctly once the class cache is seeded. Wiping the cache here
|
||||
(client-side, before push) simulates the cold-start path and catches the
|
||||
bug locally — keeping the pre-push hook fast.
|
||||
|
||||
```bash
|
||||
# Headless parse check
|
||||
godot --headless --path client --quit 2>&1 | grep -i "SCRIPT ERROR"
|
||||
# Cold-cache parse check. Deleting the cached class registry forces
|
||||
# Godot to rebuild it from source on the next parse, matching the
|
||||
# cold-start ordering CI and fresh clones see.
|
||||
rm -f client/.godot/global_script_class_cache.cfg
|
||||
|
||||
# Headless parse + scanner check. Godot's resource scanner emits
|
||||
# category errors (e.g. "Export type can only be built-in, a resource,
|
||||
# a node, or an enum" for @export on a RefCounted) that do NOT always
|
||||
# prefix with SCRIPT ERROR — they appear as plain ERROR lines. Widen
|
||||
# the grep to catch both, then filter known pre-existing noise from
|
||||
# the autoload class_name parse-order trap (documented in CLAUDE.md).
|
||||
godot --headless --path client --quit 2>&1 | \
|
||||
grep -iE "^(SCRIPT )?ERROR|Parse Error|Export type" | \
|
||||
grep -v "Failed loading resource: res://assets" | \
|
||||
grep -v "Cannot infer the type" | \
|
||||
grep -vE "(Messagepack|LocalBridge|ServerProcess|Constants)\" not declared"
|
||||
|
||||
# If the branch has UI changes, also run the game briefly:
|
||||
timeout 10 godot --path client res://scenes/main_menu.tscn 2>&1 | grep -i "ERROR\|SCRIPT ERROR"
|
||||
timeout 10 godot --path client res://scenes/main_menu.tscn 2>&1 | \
|
||||
grep -iE "^(SCRIPT )?ERROR|Parse Error|Export type"
|
||||
```
|
||||
|
||||
If the cold parse reports a "Could not find base class X" error, the fix
|
||||
is almost always an autoload-order issue (see `CLAUDE.md` → GDScript
|
||||
conventions → Autoload parse-order rule). Rebuilding the cache with
|
||||
`godot --editor --headless --quit` will mask it locally but the same error
|
||||
will re-surface post-merge — fix the actual ordering problem, don't paper
|
||||
over it with a cache rebuild.
|
||||
|
||||
Any lines that come through the filter represent new errors introduced
|
||||
by this branch. Fix them before pushing — Sprint 36 shipped commit
|
||||
`84105916` with an `@export var descriptor: CharacterVisualDescriptor`
|
||||
scanner error that the old narrower grep missed; Tyre caught it five
|
||||
commits later during W6 review.
|
||||
|
||||
**For server branches:**
|
||||
```bash
|
||||
cd server && cargo test --lib 2>&1
|
||||
|
||||
@@ -47,6 +47,28 @@ godot --headless --path client --quit 2>&1 | grep -i "SCRIPT ERROR"
|
||||
If script errors appear in the branch diff files, flag them immediately
|
||||
before spawning reviewers — no point reviewing code that doesn't parse.
|
||||
|
||||
#### 0b-i. Merge-path smoke test gate
|
||||
|
||||
When the branch diff touches any of:
|
||||
- pre-game flow (main menu → character creation → connect)
|
||||
- scene transitions (`change_scene_to_file`, scene autoloads)
|
||||
- save / load / new-game paths
|
||||
- connection handshake (`sim_bridge`, protocol decode/encode)
|
||||
- any code path executed in the first 30 seconds of a new session
|
||||
|
||||
...the reviewer output MUST explicitly call out the state of author-side
|
||||
manual smoke boxes in the PR test plan. If any merge-path smoke box is
|
||||
unchecked, include a top-level note:
|
||||
|
||||
> **Merge-path smoke not performed.** PR test plan has unchecked manual
|
||||
> smoke box(es): [list]. A reviewer or the team must run the smoke before
|
||||
> merge approval. Sprint 36 bug #872 (New Game hangs on 'connecting')
|
||||
> landed exactly here — do not skip.
|
||||
|
||||
Unchecked merge-path smoke boxes downgrade the verdict from APPROVED to
|
||||
REQUEST_CHANGES even if reviewers have no code comments. The smoke is a
|
||||
deliverable, not a suggestion.
|
||||
|
||||
### 0c. Zero warnings check
|
||||
|
||||
The project enforces a **zero warnings policy**. Before spawning reviewers,
|
||||
@@ -62,18 +84,23 @@ Pre-existing warnings are not PR blockers but should be tracked for cleanup.
|
||||
|
||||
### 1. Determine the branch to review
|
||||
|
||||
If the user provided a branch name as argument, use it. Otherwise list open
|
||||
PRs and ask the user which branch to review.
|
||||
**Always start fresh.** Even if you reviewed this branch before in this
|
||||
conversation, the branch may have new commits, a new PR, or main may have
|
||||
moved. Do NOT skip steps or reuse earlier results. Every `/pr-review`
|
||||
invocation is a full review cycle.
|
||||
|
||||
**Always fetch and check for PRs first:**
|
||||
|
||||
To list open PRs on Gitea:
|
||||
```bash
|
||||
git fetch --all
|
||||
tea pr list --login schweitz --repo jpmschweitzer/settled-reach --state open --output simple
|
||||
```
|
||||
|
||||
Fetch remote branches first:
|
||||
```bash
|
||||
git fetch --all
|
||||
```
|
||||
Then determine the branch:
|
||||
- If the user provided a branch name as argument, match it to an open PR.
|
||||
If a PR exists for that branch, note the PR number. If no PR exists,
|
||||
proceed with the branch diff but note "no PR found" in the output.
|
||||
- If no argument was given, list open PRs and ask which to review.
|
||||
|
||||
### 2. Determine reviewer team
|
||||
|
||||
@@ -151,9 +178,9 @@ reviewer that was spawned (2 for code/visual/audio, 3 for copy):
|
||||
|
||||
### <Reviewer Name> (<Focus>): [APPROVE | REQUEST_CHANGES]
|
||||
[Summary]
|
||||
| # | File | Severity | Issue |
|
||||
|---|------|----------|-------|
|
||||
| 1 | path:line | critical/warning/suggestion | description |
|
||||
| # | File | Issue |
|
||||
|---|------|-------|
|
||||
| 1 | path:line | description |
|
||||
|
||||
### <Reviewer Name> (<Focus>): [APPROVE | REQUEST_CHANGES]
|
||||
...
|
||||
@@ -187,13 +214,18 @@ Respond with:
|
||||
2. Summary: 2-3 sentence overall assessment
|
||||
3. Comments: List of specific issues, each with:
|
||||
- File path and approximate location
|
||||
- Severity: critical / warning / suggestion
|
||||
- Description of the issue
|
||||
|
||||
Verdict rules:
|
||||
- Any **critical** or **warning** issue → REQUEST_CHANGES
|
||||
- Only **suggestion**-level issues (or none) → APPROVE
|
||||
If no issues found, say APPROVE with a brief positive summary.
|
||||
- **Any comment at all → REQUEST_CHANGES.** Every issue is actionable.
|
||||
There is no "suggestion" tier that gets skipped. If it's worth
|
||||
mentioning, it's worth fixing before merge.
|
||||
- If no issues found, say APPROVE with a brief positive summary.
|
||||
- Do NOT flag something unless you expect it to be addressed. If you
|
||||
wouldn't fix it yourself, don't mention it.
|
||||
- **Quality and polish is the golden standard.** We are not optimizing
|
||||
for speed — we are optimizing for a product we're proud of. If
|
||||
something can be better, say so.
|
||||
```
|
||||
|
||||
## 6. Posting results to Gitea
|
||||
@@ -236,8 +268,24 @@ review outcome:
|
||||
**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 the warnings/critical
|
||||
issues and dispatch to idle agents, then re-push and re-review."
|
||||
"Review requested changes. Create tasks from each issue and dispatch
|
||||
to idle agents, then re-push and re-review."
|
||||
|
||||
The team may **push back** on specific comments. When a team agent
|
||||
disagrees with a reviewer comment, the process is:
|
||||
|
||||
1. The team agent 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.
|
||||
4. Retracted comments do NOT need to be fixed. The re-review should
|
||||
note which comments were retracted and why.
|
||||
|
||||
This prevents reviews from becoming dogma while maintaining the rule
|
||||
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
|
||||
|
||||
@@ -7,7 +7,11 @@ 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/<branch>:<path>`. If an active
|
||||
worktree exists under `.sprint/`, agents can also use the Read tool
|
||||
with the worktree path.
|
||||
with the worktree path. **Always prefer `git show` over worktree
|
||||
reads** — worktrees may use sparse checkouts that silently exclude
|
||||
files, causing reviewers to miss content and produce false findings
|
||||
(Sprint 33 lesson: Paula reported missing prose that was actually
|
||||
present, because the worktree excluded the wiki directory).
|
||||
|
||||
## Code reviews (`server`, `client`, `ci`)
|
||||
|
||||
|
||||
@@ -359,7 +359,7 @@ Task(
|
||||
RULES (NON-NEGOTIABLE):
|
||||
|
||||
0. TEAM SCOPE: Your team is `{team}` on branch `sprint-{N}/{team}`.
|
||||
You may modify files in: {team_scope_dirs}
|
||||
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.
|
||||
|
||||
@@ -501,7 +501,7 @@ You are now the team lead. Agents work autonomously — monitor via
|
||||
they arise.
|
||||
|
||||
**When all tasks complete:** Do NOT shut down agents. The team stays
|
||||
alive through the PR review cycle. Follow step 9 (post-work lifecycle).
|
||||
alive through PR review AND merge. Follow step 9 (post-work lifecycle).
|
||||
|
||||
### 9. Post-work lifecycle
|
||||
|
||||
@@ -510,7 +510,8 @@ 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 for review.
|
||||
update the PR. Do NOT shut down agents — the team stays alive through
|
||||
review and merge.
|
||||
|
||||
#### 9b. Wait for review
|
||||
|
||||
@@ -530,21 +531,20 @@ comments):
|
||||
**If CHANGES_REQUESTED:**
|
||||
|
||||
1. Parse the review comment table (from the Gitea PR comment or the
|
||||
review output). Extract each warning/critical issue with:
|
||||
review output). Extract each issue with:
|
||||
- File path and approximate line
|
||||
- Severity (critical / warning / suggestion)
|
||||
- Description
|
||||
|
||||
2. Create a task per warning/critical issue:
|
||||
2. Create a task per issue:
|
||||
```
|
||||
TaskCreate(
|
||||
subject: "Review: {short description}",
|
||||
description: "{full issue description from review table, including
|
||||
file path, severity, and reviewer name}",
|
||||
file path and reviewer name}",
|
||||
activeForm: "Fixing review comment: {short description}"
|
||||
)
|
||||
```
|
||||
Skip suggestion-severity items unless they are trivial (1-line fixes).
|
||||
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
|
||||
@@ -555,10 +555,28 @@ comments):
|
||||
|
||||
5. Repeat this loop until review returns APPROVED.
|
||||
|
||||
**If 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} approved and ready for
|
||||
merge on main."
|
||||
4. Report: "Sprint {N} {team} complete. PR #{X} merged into main. Team
|
||||
shut down."
|
||||
|
||||
@@ -31,7 +31,7 @@ else
|
||||
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')" 2>/dev/null | python3 -c "import sys,json; [print(r['team']) for r in json.load(sys.stdin)['rows']]" 2>/dev/null || true)
|
||||
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."
|
||||
|
||||
@@ -113,6 +113,31 @@ else
|
||||
echo "pre-push: skipping Python lint (ruff not found — install with: pip install 'ruff>=0.9')"
|
||||
fi
|
||||
|
||||
# --- JSON syntax validation ---
|
||||
if git rev-parse --verify "$REMOTE_REF" >/dev/null 2>&1; then
|
||||
JSON_FILES=$(git diff --name-only "$REMOTE_REF"..HEAD -- '*.json' 2>/dev/null || true)
|
||||
else
|
||||
JSON_FILES=$(git ls-files '*.json')
|
||||
fi
|
||||
if [ -n "$JSON_FILES" ]; then
|
||||
echo "pre-push: checking JSON syntax..."
|
||||
JSON_FAIL=0
|
||||
while IFS= read -r f; do
|
||||
if [ -f "$REPO_ROOT/$f" ] && ! python3 -m json.tool "$REPO_ROOT/$f" >/dev/null 2>&1; then
|
||||
echo " FAIL: $f"
|
||||
JSON_FAIL=$((JSON_FAIL + 1))
|
||||
fi
|
||||
done <<< "$JSON_FILES"
|
||||
if [ "$JSON_FAIL" -gt 0 ]; then
|
||||
echo "pre-push: FAIL — $JSON_FAIL JSON file(s) have syntax errors"
|
||||
ERRORS=$((ERRORS + 1))
|
||||
else
|
||||
echo "pre-push: JSON — OK ($(echo "$JSON_FILES" | wc -l) file(s))"
|
||||
fi
|
||||
else
|
||||
echo "pre-push: no JSON changes — skipping"
|
||||
fi
|
||||
|
||||
if [ "$ERRORS" -gt 0 ]; then
|
||||
echo ""
|
||||
echo "pre-push: $ERRORS check(s) failed. Push aborted."
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
# Secrets
|
||||
.env
|
||||
|
||||
# Runtime databases (not tracked — created on startup)
|
||||
# Local-only settings DB and WAL/SHM sidecars of tracked DBs
|
||||
server/settings.db
|
||||
server/settings.db-shm
|
||||
server/settings.db-wal
|
||||
server/data/systems.db-shm
|
||||
server/data/systems.db-wal
|
||||
|
||||
# Build and cache
|
||||
.cache/
|
||||
@@ -11,9 +15,9 @@ server/target/
|
||||
server/sr-voice/target/
|
||||
server/models/
|
||||
tooling/content-converter/target/
|
||||
tooling/econ-sim/target/
|
||||
tooling/line-previewer/target/
|
||||
tooling/test-client/target/
|
||||
content-ron/
|
||||
|
||||
# Godot client
|
||||
client/.godot/
|
||||
@@ -32,6 +36,14 @@ renderer/output/*.png
|
||||
spikes/**/.godot/
|
||||
spikes/**/*.import
|
||||
spikes/**/*.uid
|
||||
spikes/**/*.npy
|
||||
spikes/**/*.npz
|
||||
|
||||
# Planet generator intermediates
|
||||
*.tmp.npz
|
||||
|
||||
# Generated terrain grids (large, regenerated from pipeline)
|
||||
wiki/**/bodies/**/terrain.npz
|
||||
|
||||
# Asset downloads (vendor archives, not game content)
|
||||
docs/assets/downloads/
|
||||
@@ -39,9 +51,6 @@ docs/assets/downloads/
|
||||
# Reference repos for investigation
|
||||
vendor/
|
||||
|
||||
# Database (shared across worktrees at ../settledreach.db, not tracked)
|
||||
db/commonwealth.db*
|
||||
|
||||
# Frame0 ID mapping files (ephemeral, per-machine)
|
||||
*.idmap.json
|
||||
|
||||
@@ -57,13 +66,17 @@ Thumbs.db
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
.obsidian/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Generated economics pipeline artifacts (re-created by make economy-db)
|
||||
wiki/economics/corporations/generated_brands.toml
|
||||
wiki/economics/corporations/generated_corporations.toml
|
||||
|
||||
# Claude Code internals (plans, session transcripts)
|
||||
# Note: .claude/agents/, .claude/skills/, and .claude/settings.json ARE tracked
|
||||
.claude/plans/
|
||||
.claude/projects/
|
||||
.claude/agent-memory/
|
||||
client-tmp/
|
||||
.tmp/
|
||||
|
||||
@@ -6,6 +6,160 @@ Format based on [Keep a Changelog](https://keepachangelog.com/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [v0.1.36] — 2026-04-21
|
||||
|
||||
### Added
|
||||
- **MetaScreen pattern** (#618, #680) — base class + `MetaStack` autoload for all meta-UI screens (main menu, loading, settings, bug report, debug console, character creation). Consistent ESC handling, z-layering via HudGroups, sim pause coupling, symmetric open/close lifecycle
|
||||
- **Option A pre-game flow** — main menu → character creation → connect. ESC priority chain (MetaStack → implant → settings) extracted into `_handle_menu_key()`
|
||||
- **Character creation 4-tab restructure**: Identity, Archetype, Bookmark, Skills; `CharacterProfile` signal payload
|
||||
- **Location picker in Bookmark tab** (#680) — client surfaces server `bookmark_catalog` on connect; player selects starting location, culture resolved server-side
|
||||
- **Skills tab stub** (#618) — placeholder content for future skills system
|
||||
- **Protocol v23** — `bookmark_catalog` decode + bookmark action encoding
|
||||
- **ImplantApp pattern** (#844, #824, #836) — base class + registry; atlas and economics panels refactored onto the pattern
|
||||
- **Unified implant/map app** (#844) — AtlasPanel owns the full Reach → system → planet → heightmap zoom hierarchy as a single HudGroups registration per D-191; KEY_M opens the unified atlas (KEY_A retired)
|
||||
- **Bookmark definition system** (#614) — server-side bookmark catalog with bridge protocol
|
||||
- **Location-to-culture resolution system** (#679) — server maps location IDs to culture IDs for character creation
|
||||
- **`generate_brands` pipeline** (#829) — 10K minor brands generated from templates
|
||||
- **124 notable brand corps** (#828) — hand-authored across 8 categories
|
||||
- **Core-world atlas hand-refine pass** (#849) — Sirius, Groombridge, Barnard's Star, Ran, Tau Ceti, Sol (Luna, Mars, Europa)
|
||||
- **Baseline atlas city collision elimination** (#838) — zero collisions across inhabited bodies
|
||||
- **Atlas cohesion analysis tooling** — QA scripts for naming consistency
|
||||
- **`cargo-deny`** (#726) — license and advisory checking configured
|
||||
- **Client and protocol version** shown at the bottom of the loading screen (#724)
|
||||
- **`--help` / `-h` flag** on `sqlite-query` and `sqlite-exec` wrappers (#722)
|
||||
- **D-192** — decision to deprecate `PROTOCOL_VERSION` lockstep handshake; removal tracked in #868
|
||||
|
||||
### Changed
|
||||
- AtlasPanel `Level` enum renumbered so index matches zoom depth (REACH_MAP=0, HEIGHTMAP_VIEWER=4)
|
||||
- ORBITAL_DIAGRAM back-navigation now returns to REACH_MAP directly, matching the forward skip of SYSTEM_PICKER
|
||||
- `atlas_panel.gd` split into 4 sub-widgets, each under 500 lines
|
||||
- bincode v1.x → v2.x migration internal to server (#636)
|
||||
|
||||
### Fixed
|
||||
- Compositor test cleanup was freeing gdUnit4 internals, causing the full client test run to hang indefinitely on the second compositor test
|
||||
- Loading screen now blocks input; main menu polls during `bookmark_catalog` wait instead of racing
|
||||
- Tautological `test_protocol_version_is_N` assertions removed (× 2 suites) per D-192
|
||||
- Character creation cardinal direction/name ordering mismatch — screenshots at indices 1 and 3 had swapped filename labels
|
||||
- Enter key bypassed disabled Start button in character creation
|
||||
- Wire codec `career` default no longer hardcoded to `"tycoon"` — empty string is the protocol default
|
||||
|
||||
### Removed
|
||||
- **D-078 overheard conversation system** (#848, #842) — v0.1 PoC NPC and environment interaction systems retired; `content/global/` overheard dialogue directory cleared
|
||||
- Orphaned NPC and environment interaction code paths (#842)
|
||||
|
||||
## [v0.1.35] — 2026-04-18
|
||||
|
||||
### Added
|
||||
- Gemma 4 batch naming pipeline (`tooling/planet-gen/gemma_naming.py`): wiki-grounded register selection, per-body mood injection, 2x oversampled batch naming with Levenshtein ranking, corridor-scoped dedup (#833)
|
||||
- 24,963 named geographic features across 299 star systems: 329 cities, 2,701 rivers, 6,457 oceans, 286 POIs, 15,190 mountain ranges — culturally authentic per corridor (Portuguese south_reach, Korean east_reach, Nordic west_reach, frontier deep_frontier)
|
||||
- Atlas implant panel — system picker, orbital diagram, body navigation (#834)
|
||||
- Atlas heightmap viewer — pan/zoom, marker overlay, city data panel (#835)
|
||||
- Atlas overlay system — 9 MVP overlays with visibility toggles (#836)
|
||||
- Hand-authored atlas templates for 6 bodies: Lendel (GJ-380), Vuurkloof (GJ-35), Røros (GJ-66B), Estrade (GJ-280A), Cairnside (GJ-892), Edict (GJ-244A) (#837)
|
||||
- Brand layer DB schema: brand_products, brand_inputs, system_fiscal tables with tier1 seed data (#827)
|
||||
- Brand templates (brand_templates.toml): 120+ archetype entries for administered pricing (#831)
|
||||
- 4 new brands: Calloway, VGV, thrds, Bífröst Marmor (#830)
|
||||
- Wiki glossary — canonical proper nouns and factional terminology (#840)
|
||||
- Atlas naming QA tool (`tooling/planet-gen/qa_naming.py`): duplicate detection, stem repetition, prompt leak checks, register bleed analysis
|
||||
- Architecture reference: `docs/architecture/atlas-naming-pipeline.md`
|
||||
|
||||
### Fixed
|
||||
- World seed threading from StartupMessage into economics layer (#826)
|
||||
- Gemma GPU offload: `n_gpu_layers=999` for full GPU inference (#833)
|
||||
|
||||
## [v0.1.34] — 2026-04-10
|
||||
|
||||
### Added
|
||||
- Economics simulation integrated into server tick loop — econ-sim library crate, D-180 event port, D-181 7-signal vocabulary, IPC bridge (protocol v21), debug commands (#810, #821, #822, #823)
|
||||
- Economics Monitor implant panel — system selector, 6-commodity price table with trend arrows, GDP strip (#824)
|
||||
- Debug console `econ inject`, `econ param`, `econ inspect` commands for runtime economics manipulation (#825)
|
||||
- Star map info panel shows system population and GDP when data is available (#785)
|
||||
- Overheard conversations for all 31 zone types (was 5): 78 new ambient dialogue entries (94 total) with D-078 occlusion-resilient authoring, investigative knowledge payloads, and culture-neutral role-pair conversations (#695)
|
||||
- D-189 brand layer architecture — administered pricing, halo/volume tiers, 8 brand categories, corp tax/GDP
|
||||
- D-190 brand volume calibration — population-relative scale for ~80B Reach
|
||||
- D-191 Atlas of the Reach Phase 3 scope — sequential settlement growth, Gemma 2 naming pipeline, 9 MVP overlays
|
||||
|
||||
## [v0.1.33] — 2026-04-08
|
||||
|
||||
### Added
|
||||
- Economics simulation binary (`tooling/econ-sim/`): three-layer architecture — Layer 1 (Leontief production), Layer 2 (damped tâtonnement trade flows, α=0.03, β=0.4), Layer 3 (corporate behavioral archetypes)
|
||||
- D-179 stability tests: cold-start convergence (±5% at tick 100), long-run stability (±2% over 1000 ticks), no-explosion check, cross-zone FX balance
|
||||
- Tier-3 corporation generation pipeline (`server/src/bin/generate_corporations/`): seeded procedural naming, D-175 coverage rules (3+ corps per commodity, 1+ per system >100K pop)
|
||||
- Currency zone assignments (`wiki/economics/currency_zones.toml`): 32 MARK_PRIMARY + 14 MIXED systems authored by Miri (D-172)
|
||||
- Shadow economy intensity ranges (`wiki/economics/shadow_economy.toml`): per-system seeding with geographic bands, modifiers, and overrides (D-174)
|
||||
- 141 Tier-2 regional corporations across 6 corridors with backstories and behavioral archetypes
|
||||
- 36 commodity wiki pages with economic intelligence flavor text
|
||||
- Gate energy connectivity (D-186): MARK_PRIMARY zones default off-grid
|
||||
- `make econ-sim`, `make econ-sim-run`, `make econ-sim-stability` targets
|
||||
- Icon tint shader (`icon_tint.gdshader`) for runtime HUD icon recoloring
|
||||
- Sol system (GJ-0) handcrafted terrain pipeline (`tooling/planet-gen/sol_import.py`): imports real NASA/USGS data for Earth, Mars, Luna
|
||||
- Ferric biome classes (34–36) in `biomes.toml` for Mars iron oxide surface
|
||||
- Earth named features: 50 cities, 15 rivers, 5 oceans, 7 mountain ranges
|
||||
|
||||
### Fixed
|
||||
- Globe renderer east-west mirroring: `arctan2(hx, hz)` replaces `arctan2(hz, hx)` in planet_renderer.py
|
||||
- Determinism: HashMap → BTreeMap throughout econ-sim, ORDER BY RANDOM() replaced with seeded selection
|
||||
- Transport cost formula: multiplicative gate×zone instead of additive (trade.rs)
|
||||
- Corporation gap-fill off-by-one: now generates exactly 3 corps per uncovered commodity
|
||||
|
||||
### Changed
|
||||
- Economy-db pipeline extended with corporation sync, validation, currency zone import from TOML, and gate energy flags
|
||||
|
||||
### Removed
|
||||
- Qdrant semantic search infrastructure (#816): dropped commonwealth collection, removed qdrant_connector.py, wrapper scripts, /docs-search skill, and all active references
|
||||
|
||||
## [v0.1.32] — 2026-04-06
|
||||
|
||||
### Added
|
||||
- Economics schema extension (#804): 5 new tables in systems.db (gate_links, commodities, production_chains, chain_inputs, corp_presence) + currency_zone and corporation archetype columns
|
||||
- Economics import pipeline (`tooling/economy-db/import_economics.py`): reads TOML/JSON source data, populates systems.db. Idempotent via `make economy-db`
|
||||
- Planet generator pipeline (`tooling/planet-gen/`) — procedural terrain simulation, Whittaker biome classification, equirectangular heightmap + 512px globe rendering from wiki data
|
||||
- Externalized biome/color configuration (`tooling/planet-gen/biomes.toml`) — single source for all classification tables, palettes, and rendering parameters
|
||||
- Batch runner with error handling, resume support, determinism verification, and 50% error rate circuit breaker
|
||||
- Per-body wiki pages with YAML frontmatter (`wiki/star-systems/*/bodies/*/index.md`) — body definition + profile + visual embeds
|
||||
- Body scaffolding tool reads system index.md and generates per-body index.md with frontmatter
|
||||
- Ran system (GJ-144) generated: 10 bodies with heightmaps, globe renders, and geographic markers
|
||||
- Implant HUD icon set: 13 SVGs (stance, status, interaction, inventory) per D-086
|
||||
- 7 procedural planet type renders for wiki/GTTR (`client/assets/planets/`)
|
||||
- Ticket #817: batch planet generation for all ~3000 bodies
|
||||
- Ticket #816: remove stale Qdrant semantic search infrastructure
|
||||
- `PROJECT_STATE.md` at repo root — shared project state referenced by all 18 agent briefings
|
||||
- Economics decision domain (`decisions/economics.md`): D-171–D-187 covering currency system, commodity taxonomy, shadow economy, corporation tiers, productivity seeding, simulation architecture, data pipeline, gate transmission levels
|
||||
- Commodity catalog: 36 commodity types in `wiki/economics/commodities.toml` with 21 production chains in `wiki/economics/production_chains.toml`
|
||||
- Wiki stub pages for all 36 commodities at `wiki/economics/commodities/`
|
||||
- SQL schema spec for #804 systems.db extension (`wiki/economics/schema.md`)
|
||||
- Burnelli-Sheldon economist agent (`.claude/agents/burnelli-sheldon.md`)
|
||||
- Workshop archives: #796 (economics design, 3 rounds) and #801 (commodity catalog, 3 rounds + validation)
|
||||
|
||||
### Fixed
|
||||
- Sprint worktree creation no longer spawns a spurious "None" team tab when tickets have no team assigned
|
||||
|
||||
### Changed
|
||||
- Renamed `commission_certified` → `commission_certifiable` across all TOML, schema, and decision files — flag is a susceptibility marker, not an absolute state
|
||||
- Pre-push hook now validates JSON syntax on changed files (python3 -m json.tool)
|
||||
- HUD status panel: merged TimeDisplay into ImplantPanel — time, health, perception in one themed panel (#786)
|
||||
- HUD moved from UILayer (20) to InsertOverlay (10) for bloom treatment per D-049
|
||||
- Interaction prompt: converted from PanelContainer+StyleBoxFlat to ImplantPanel+ImplantDataRow (#788)
|
||||
- Minimap: added ImplantTheme-styled container frame behind circular display (#787)
|
||||
- Stance indicator: SVG icons with alpha-mask tint shader replace text-only labels (#787, D-086)
|
||||
- Amended 7 stale D-records with supersession notes (D-012, D-035, D-044, D-061, D-086, D-090, D-119)
|
||||
- Closed 4 resolved scope questions (Q-002, Q-004, Q-005, Q-007)
|
||||
- Fixed questions.md index (was 61 questions, actually 96 — 33 architecture Qs missing from index)
|
||||
- All 18 briefings reference `PROJECT_STATE.md` instead of duplicating project state boilerplate
|
||||
- Aligned sprint-start severity policy with pr-review (no suggestion tier — every comment actionable)
|
||||
|
||||
### Removed
|
||||
- `GEMINI-SCAN.md` one-off scan artifact
|
||||
- 6 dead `db/connectors/` permission entries from settings.local.json
|
||||
- Stale "v0.2 direction" and "Sprint 25 critical path" references from all briefings
|
||||
- `worktree-update` skill template from whatsinagame kit
|
||||
|
||||
### Fixed
|
||||
- HUD layout overlaps: DebugOverlay positioned below merged status panel, GauntletHUD moved below StanceIndicator, StanceIndicator sized for ImplantPanel content (#792)
|
||||
- D-061 dialogue max-width: corrected from 640px to 1200px (per D-076)
|
||||
- DEVOPS.md and stig briefing: gdlint no longer "pending setup"
|
||||
- `{team_scope_dirs}` dangling placeholder in sprint-start resolved
|
||||
|
||||
## [v0.1.31] — 2026-04-05
|
||||
|
||||
### Added
|
||||
|
||||
@@ -40,6 +40,23 @@ Development follows a strict cascade. Each phase has a concrete deliverable. **D
|
||||
|
||||
**v0.2 target is dropped.** No scoping negotiations. Build the base systems fully.
|
||||
|
||||
## Work Modes
|
||||
|
||||
### Sprint mode (default)
|
||||
Agents work autonomously on sprint branches. Team lead coordinates via tasks and messages. Human reviews PRs from main. Standard `/sprint-start` → `/pr-push` → `/pr-review` lifecycle.
|
||||
|
||||
### Pair session
|
||||
Human and Claude work together interactively on a single task. No background agents, no autonomous work. Used for load-bearing architecture changes where the human needs to make judgment calls as the work progresses — not approve a finished result.
|
||||
|
||||
**Rules:**
|
||||
- No `Agent` spawns, no `run_in_background`. One thread of work.
|
||||
- Propose one change at a time. Wait for human reaction before continuing.
|
||||
- Explain what you're about to do and why before doing it.
|
||||
- After each change, verify together (compile, test, inspect) before moving to the next.
|
||||
- The human is a participant, not a reviewer. Ask questions, surface tradeoffs, flag risks in real-time.
|
||||
|
||||
**When to use:** Ticket description says "pair session", or the work touches foundational systems where a wrong call is expensive to undo (tick cycle architecture, protocol design, data model migrations, build pipeline rewrites).
|
||||
|
||||
## Agent Instructions
|
||||
|
||||
### Team boundaries
|
||||
@@ -73,8 +90,6 @@ The ticketing database (`settledreach.db`) is accessed via `SR_DB_PATH` env var
|
||||
| SQL queries | `tooling/db/sqlite-query "SELECT ..."` | — |
|
||||
| SQL writes | `tooling/db/sqlite-exec "UPDATE ..."` | — |
|
||||
| Decisions | `tooling/db/decision next`, `claim`, `check-dupes` | — |
|
||||
| Doc search | `tooling/db/qdrant-search "query"` | `/docs-search` skill |
|
||||
| Doc index | `tooling/db/qdrant-index path/to/file.md` | `/docs-search` skill |
|
||||
|
||||
### Testing preferences
|
||||
|
||||
@@ -83,6 +98,18 @@ The ticketing database (`settledreach.db`) is accessed via `SR_DB_PATH` env var
|
||||
- Three test tiers: (1) Live server — highest fidelity, (2) MessagePack replay via `Protocol.decode_snapshot()` — for unreachable rooms, (3) TestHarness mock — for UI-only tests where fog data doesn't matter.
|
||||
- `make fixtures-gauntlet` regenerates real server snapshot fixtures from the Gauntlet world.
|
||||
|
||||
### Implant UI component library (D-169, D-170)
|
||||
|
||||
The implant UI system — all diegetic neural overlay panels — lives at `client/ui/implant/`. Components are Godot Control scenes styled via a shared `Theme` resource (`default_implant.tres`). Do not hand-roll implant panel layouts; compose from the library.
|
||||
|
||||
**Components:** `ImplantPanel` (root container), `ImplantHeader` (title + subtitle), `ImplantSeparator` (horizontal rule), `ImplantDataRow` (key/value row, optional color), `ImplantTextBlock` (RichTextLabel for wrapping text).
|
||||
|
||||
**Theme resource:** `client/ui/implant/default_implant.tres` — defines semantic color roles (`PRIMARY_TEXT`, `DIM_TEXT`, `ACCENT_ACTIVE`, `ACCENT_POSITIVE`, `ACCENT_NEGATIVE`, `ACCENT_WARNING`, `SEPARATOR`), spacing, and font sizes. Swap the entire `.tres` to change implant hardware appearance at runtime.
|
||||
|
||||
**HUD visibility (D-170):** `client/scripts/autoloads/hud_groups.gd` manages z-index layering. Modes: `GAMEPLAY` (z=0), `INSERT` (z=10), `FULLSCREEN` (z=20), `MODAL` (z=30). App paths are hierarchical: `implant/map`, `implant/wiki/gttr`, etc. Opening any `implant/*` app occludes gameplay; closing returns to gameplay. Key API: `open_app()`, `close_app()`, `toggle_app()`, `is_app_active()`. Emits `gameplay_occluded` signal so renderers can pause.
|
||||
|
||||
**GameplayRenderer base class:** `client/scripts/rendering/gameplay_renderer.gd` — extends `Node2D`. Subclasses override `_gameplay_process()` and `_gameplay_draw()`. Connected to `HudGroups.gameplay_occluded` to pause when the implant is fullscreen. Used by `CursorRenderer`, `EntityRenderer`, `FogEntities`, `SoundIndicatorRenderer`, `WorldRenderer`.
|
||||
|
||||
### GDScript conventions
|
||||
|
||||
**Autoload parse-order rule:** Autoload scripts (`client/scripts/autoloads/`) compile before global `class_name` scripts are registered. Referencing a `class_name` type directly in an autoload causes a parse-time "not declared" error. Pattern:
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
# Project Review: GEMINI-SCAN
|
||||
|
||||
This document outlines a multi-step plan to conduct a comprehensive review of the project, covering its architecture, code quality, and security posture. It will also serve as a living document to record the findings of this review.
|
||||
|
||||
## Project Review Plan
|
||||
|
||||
### Phase 1: Discovery and Architecture Mapping
|
||||
|
||||
1. **Documentation Review:** Start by reading `README.md`, `DECISIONS.md`, and any documents in `docs/architecture/` to understand the project's stated goals, components, and architectural decisions.
|
||||
2. **Component Identification:** Analyze the directory structure to identify the primary components, including the server, client, database, content pipeline, and tooling.
|
||||
3. **Technology Stack Enumeration:** Identify the specific technologies, frameworks, and key libraries used in each component.
|
||||
4. **Architecture Visualization:** Map the high-level architecture, describing how the components interact and the communication protocols between them.
|
||||
|
||||
### Phase 2: Code Quality Assessment
|
||||
|
||||
1. **Automated Analysis:** Use available static analysis tools for the identified technologies (e.g., `clippy` for Rust, GDScript linters).
|
||||
2. **Manual Code Review:** Manually review key sections of the codebase to assess readability, maintainability, modularity, error handling, and adherence to idiomatic coding practices.
|
||||
3. **Testing Strategy Review:** Evaluate the extent and quality of existing unit, integration, and end-to-end tests.
|
||||
|
||||
### Phase 3: Security Audit
|
||||
|
||||
1. **Dependency Vulnerability Scan:** Check for dependencies with known security vulnerabilities (e.g., `cargo audit`).
|
||||
2. **Authentication & Authorization Review:** Analyze the implementation of user authentication, session management, and access control.
|
||||
3. **Input Validation & Sanitization:** Look for potential injection vulnerabilities (e.g., SQL injection, XSS) by reviewing how user and service inputs are handled.
|
||||
4. **Secrets Management:** Check for insecure storage or exposure of secrets like API keys or database credentials.
|
||||
5. **Communication Security:** Verify that data is encrypted in transit between components.
|
||||
|
||||
### Phase 4: Reporting
|
||||
|
||||
1. **Synthesize Findings:** Compile the information from all phases into a structured report within this document.
|
||||
2. **Provide Recommendations:** Include actionable recommendations for improving architecture, code quality, and security, prioritized by severity and effort.
|
||||
|
||||
---
|
||||
|
||||
## Review Findings
|
||||
|
||||
### Phase 1: Discovery and Architecture Mapping
|
||||
|
||||
**Status: Completed**
|
||||
|
||||
#### 1. Documentation Review Summary
|
||||
|
||||
The project's architecture is extensively documented in `README.md` and the `decisions/` directory, particularly `decisions/architecture.md`.
|
||||
|
||||
- **Project:** "The Settled Reach," a top-down, single-player (multiplayer-ready) immersive simulation and detective game.
|
||||
- **Core Principle:** A strict client-server architecture is mandated (Decision D-010, D-020) to enforce information asymmetry, where the client only knows what the server tells it is perceptible. This is a core gameplay mechanic, not just a technical choice.
|
||||
- **Key Decision (D-020):** The team explicitly chose a **subprocess/IPC** bridge over a `GDExtension` (in-process) bridge to de-risk development, ensure stability, and enforce architectural separation. The Godot client and Rust server are entirely separate binaries.
|
||||
|
||||
#### 2. Component Identification
|
||||
|
||||
- **`server/`**: A standalone Rust application that runs the entire game simulation. It is the "server" in the client-server model.
|
||||
- **`client/`**: A Godot 4 project that acts as a "dumb" client. Its sole responsibilities are rendering, audio playback, and capturing user input. It contains no game logic, as mandated by the architecture.
|
||||
- **`content/`**: Contains game data, primarily in YAML format.
|
||||
- **`db/`**: Holds a `schema.sql` file. Its role is not yet clear from the architectural documents, as the primary game state is managed in the ECS. It may be for tooling or an auxiliary system.
|
||||
- **`tooling/`**: A collection of helper and utility scripts.
|
||||
|
||||
#### 3. Technology Stack
|
||||
|
||||
- **Server (Rust):**
|
||||
- **ECS Framework:** `bevy_ecs` (v0.18) is used for the core simulation, confirming Decision D-020. `bevy_app` is used for scheduling.
|
||||
- **Serialization:** `rmp-serde` (MessagePack) is the primary protocol for client-server communication, as specified in D-020. `serde_yaml` and `ron` are used for content and configuration.
|
||||
- **Client (Godot):**
|
||||
- **Engine:** Godot 4.x.
|
||||
- **Language:** GDScript.
|
||||
- **Bridge:** A `SimBridge` autoload script is the client-side entry point for communicating with the Rust subprocess.
|
||||
- **Testing:** `gdUnit4` is configured for unit/integration testing on the client.
|
||||
|
||||
#### 4. High-Level Architecture
|
||||
|
||||
The architecture is a pure, decoupled client-server model running locally for single-player:
|
||||
|
||||
1. **Initiation:** The Godot client launches the Rust server binary as a child process.
|
||||
2. **Communication:** The client's `SimBridge` connects to the server via a local IPC mechanism (e.g., a local TCP or Unix socket).
|
||||
3. **Input Loop:** The Godot client captures raw input (e.g., 'W' key press), translates it into a semantic action (e.g., `PlayerAction::MoveNorth`), and sends it to the server.
|
||||
4. **Simulation Loop:** The Rust server receives the action, processes it within the `bevy_ecs` world, and runs the simulation for one tick (AI, physics, events, etc.).
|
||||
5. **Perception Loop:** After the tick, the server calculates an `ObserverSnapshot` for the player's character. This snapshot contains *only* the information that character can perceive (e.g., visible entities, audible sounds, known facts). This enforces the game's core mechanic.
|
||||
6. **Render Loop:** The `ObserverSnapshot` is sent to the Godot client, which uses it to update the visual scene, play sounds, and display UI elements. The client is a pure renderer of the state provided by the server.
|
||||
|
||||
This architecture is robust, scalable, and directly implements the game's central design pillars. It is well-suited for both single-player and future multiplayer development.
|
||||
|
||||
### Phase 2: Code Quality Assessment
|
||||
|
||||
**Status: Completed**
|
||||
|
||||
#### 1. Automated Analysis (Rust Server)
|
||||
|
||||
- **`cargo check`**: The command passed successfully, indicating that the server code is compilable and free of basic errors and warnings.
|
||||
- **`cargo clippy -- --deny warnings`**: This command failed with **66 errors**. This is a critical finding. It reveals that while the code works, it does not adhere to the project's own strict linting rules.
|
||||
- **Clippy Findings:** The errors indicate a consistent pattern of "code quality debt":
|
||||
- **High Complexity:** Numerous Bevy systems have overly complex type signatures (`clippy::type_complexity`) and too many arguments (`clippy::too_many_arguments`), harming readability.
|
||||
- **Non-Idiomatic Code:** The codebase is rife with minor stylistic issues that `clippy` can automatically fix, such as redundant `clone` calls, manual `Default` implementations, and opportunities to use more concise iterators.
|
||||
- **Potential Bugs:** Clippy identified `unnecessary_unwrap` calls (safer alternatives exist) and at least one `absurd_extreme_comparisons` error, which could point to dead code or a logic bug related to a constant value.
|
||||
|
||||
#### 2. Manual Code Review
|
||||
|
||||
- **Server (`server/src/main.rs`):** The server entry point is well-structured. It features clear command-line argument parsing, robust setup of the TCP listener and IPC handshake, and a main loop with excellent panic-handling (`catch_unwind`) for stability. The modular plugin-based approach to building the Bevy `App` is idiomatic and clean.
|
||||
- **Client (`client/scripts/autoloads/sim_bridge.gd`):** The `SimBridge` is the centerpiece of the client and is implemented to a high standard. It uses a clear state machine to manage the connection lifecycle, handles the server subprocess management, and implements efficient buffering for inputs and snapshots. The inclusion of a complete `TestHarness` for isolated client testing is a standout feature.
|
||||
- **Overall Impression:** The manual review confirms that the code is professionally written and implements the intended architecture faithfully. The developers are skilled in both Rust/Bevy and GDScript.
|
||||
|
||||
#### 3. Testing Strategy Review
|
||||
|
||||
The project's testing strategy is **exemplary** and a major strength.
|
||||
|
||||
- **Comprehensive Coverage:** Both the Rust server and the Godot client have extensive test suites, as evidenced by the large number of files in `server/tests/` and `client/tests/`.
|
||||
- **Multi-Layered Approach (per D-030):** The project successfully implements a sophisticated testing hierarchy:
|
||||
- **Unit Tests:** For isolated logic.
|
||||
- **Integration Tests:** The server tests demonstrate in-memory ECS testing (`information_boundaries.rs`) and full-stack tests that spin up a real server process (`test_e2e_connection.gd`).
|
||||
- **Specialized Tests:** The suite includes performance benchmarks, determinism validation, and even what appears to be visual regression testing for the client.
|
||||
- **Principle-Driven Testing:** Tests are designed to validate core architectural guarantees. The `information_boundaries.rs` test, which uses negative assertions to ensure information *doesn't* leak, is a prime example of this mature approach.
|
||||
|
||||
#### 4. Conclusion on Code Quality
|
||||
|
||||
The project's code quality is a tale of two cities. On one hand, the **architecture and implementation are excellent**, and the **testing strategy is world-class**. On the other hand, there is a **significant, measurable amount of linting debt** in the Rust codebase.
|
||||
|
||||
The fact that `cargo check` passes but `clippy --deny warnings` fails so extensively suggests that developers may not be running the strict clippy check locally before committing. This is the single biggest opportunity for improvement in the project's engineering discipline.
|
||||
|
||||
### Phase 3: Security Audit
|
||||
|
||||
**Status: Completed**
|
||||
|
||||
The security posture of the project is strong for its current scope as a locally-run, single-player game. The attack surface is minimal, and the implementation avoids common vulnerability classes.
|
||||
|
||||
1. **Dependency Vulnerability Scan (`cargo audit`):**
|
||||
- The audit revealed one **medium-risk** finding: the `bincode` crate (v1.3.3) is **unmaintained** (`RUSTSEC-2025-0141`).
|
||||
- **Impact:** While there are no current vulnerabilities, this version will not receive future security patches. This poses a long-term maintenance risk.
|
||||
- **Recommendation:** Prioritize migrating from `bincode` v1.x to the latest stable v2.x.
|
||||
|
||||
2. **Authentication and Authorization:**
|
||||
- There is **no traditional authentication or authorization system** (e.g., user logins, passwords, roles).
|
||||
- This is appropriate and secure for a single-player game where the execution environment is the user's own machine.
|
||||
- Concepts like `ScanAuthority` and `AccessTier::Authority` are purely in-game mechanics and are not related to user permissions.
|
||||
|
||||
3. **Input Validation and Sanitization:**
|
||||
- **Excellent.** The server is not vulnerable to injection attacks from client input.
|
||||
- All client actions, including debug commands, are parsed into a strongly-typed Rust `enum`. This **command pattern** approach prevents the execution of arbitrary code or strings.
|
||||
- String inputs are used safely as keys for data lookups, not for execution.
|
||||
|
||||
4. **SQL Injection:**
|
||||
- **Not applicable.** The codebase contains no SQL. All game state is managed in-memory via the Bevy ECS framework, eliminating this entire class of vulnerability. The `db/schema.sql` file appears to be unused by the server.
|
||||
|
||||
5. **Secrets Management:**
|
||||
- **Excellent.** A search confirmed there are **no hardcoded secrets**, API keys, or passwords in the repository.
|
||||
- The `.env` file contains only a non-sensitive `GOOGLE_CLOUD_PROJECT` identifier.
|
||||
- The pervasive use of the word "secret" throughout the code refers to an in-game mechanic, not application secrets.
|
||||
|
||||
6. **Communication Security:**
|
||||
- Communication between the client and the server subprocess occurs over an **unencrypted local TCP socket**.
|
||||
- For a single-player game running on a single machine, this is a standard and acceptable practice.
|
||||
- **Future Consideration:** For the planned multiplayer feature, this communication channel must be secured (e.g., using TLS).
|
||||
|
||||
### Phase 4: Final Report and Recommendations
|
||||
|
||||
**Status: Completed**
|
||||
|
||||
#### Overall Summary
|
||||
|
||||
This project is in an excellent state. It is built on a robust, well-documented, and scalable architecture that directly serves the game's core design pillars. The implementation quality is high, and the commitment to a comprehensive, multi-layered testing strategy is world-class. The project's security posture is strong for its current single-player scope, with a minimal attack surface and good practices around input validation and secrets management.
|
||||
|
||||
The project's primary weakness lies not in its design, but in its development discipline. A significant amount of code quality debt has accumulated in the Rust server, as evidenced by the large number of `clippy` failures. This suggests a gap between the project's high standards and its day-to-day coding practices.
|
||||
|
||||
#### Prioritized Recommendations
|
||||
|
||||
**1. High Priority: Eliminate Code Quality Debt**
|
||||
|
||||
- **Action:** Create a high-priority technical debt task to fix all 66 errors reported by `cargo clippy -- --deny warnings`. Many of these can be fixed automatically (`cargo clippy --fix`), while others, like refactoring complex types, will require manual effort.
|
||||
- **Process Improvement:** **Integrate `cargo clippy -- --deny warnings` into the CI pipeline as a mandatory check for all pull requests.** This is the single most important process change needed to maintain the project's high standards and prevent future quality debt.
|
||||
|
||||
**2. Medium Priority: Mitigate Dependency Risk**
|
||||
|
||||
- **Action:** Plan and execute the migration of the `bincode` serialization crate from the unmaintained v1.x to the latest stable v2.x. This resolves the `RUSTSEC-2025-0141` warning and ensures the project receives future security patches for this critical dependency.
|
||||
|
||||
**3. Low Priority: Future-Proof for Multiplayer**
|
||||
|
||||
- **Action:** Create a design task or ticket to formally plan the security model for the future multiplayer version. This should specifically address securing the client-server IPC channel (e.g., with TLS) to protect game traffic when it eventually runs over a public network. This is not an immediate concern but should be tracked for the future.
|
||||
|
||||
---
|
||||
|
||||
## Qualitative Review: A Critical Perspective
|
||||
|
||||
### Feasibility Assessment
|
||||
|
||||
**Conclusion: High-Risk / High-Reward**
|
||||
|
||||
The decision to pivot from a hand-authored detective game to a generator-first life-sim was absolutely the correct one; it demonstrates a team that is commendably focused on finding the "fun" and is not afraid of drastic course corrections. However, in doing so, the project has traded a difficult but solvable problem (making a good, authored narrative game) for one of the "holy grail" problems in game development: creating emotionally resonant, procedurally generated characters.
|
||||
|
||||
The project's feasibility is no longer a question of the team's technical competence, which is demonstrably high. It is now a question of creative and design risk.
|
||||
|
||||
- **Challenging the Core Assumption:** The project's central hypothesis is that a generator can produce "legible NPCs" that players will form an emotional attachment to. This is an explicit goal from the "Where's the Fun?" workshop, but it's a notoriously difficult problem. Procedural generation excels at creating systems, events, and surprising scenarios (the `Rimworld` model the team cites). It is historically poor at creating *character*. The risk is that the generator, even if technically successful, will produce a world of automata who have traits but no soul, undermining the entire "life-sim" pillar. The current plan to use AI for content templating is a modern approach, but it does not fundamentally de-risk this creative challenge.
|
||||
|
||||
- **A Creative Alternative to De-Risk "Legibility":** Instead of relying on the generator to create personality from scratch, consider a hybrid approach. Use the generator for what it's good at: creating the world, the economic conditions, the social networks, and the *starting situations*. Then, use a small number of hand-authored "personality archetypes" or "souls" that can be injected into high-value generated NPC bodies. Let the generator create a compelling *context* (e.g., a failing business, a political rivalry), and then let an author give one or two key NPCs within that context a memorable voice and motivation. This would concentrate the high-cost authoring work where it has the most emotional impact, while still benefiting from procedural variety.
|
||||
|
||||
- **The "Tycoon" Aimlessness Risk:** The new v0.2 "tycoon" direction, with its philosophy of "player choices ARE the content," carries a significant risk of feeling aimless. `Rimworld` and `The Sims` avoid this by providing extremely strong and immediate feedback loops (survival, creativity, social meters). A business management loop is often slower and more abstract. If the "broad life verbs" don't connect to clear, compelling, player-driven goals, the game risks feeling like a spreadsheet. The generator should not just create a sandbox; it should create *problems*. The starting bookmark shouldn't just be "you own a bar," but "you own a bar that's on the verge of bankruptcy," or "you have a shipping contract, but a powerful rival is trying to steal it." These initial, generator-created problems would provide immediate narrative velocity and make the player's subsequent choices feel meaningful from day one.
|
||||
|
||||
In summary, the project is technically feasible, but its creative and design goals are now exceptionally ambitious. The current "generator spike" is a necessary technical step, but it will not validate the core creative risk. The true test of feasibility will come when a prototype is playtested and the team can answer the question: "Does the player actually *care* about any of these generated people?"
|
||||
|
||||
### Fun Factor Assessment
|
||||
|
||||
**Conclusion: Theoretically High, Practically Undefined**
|
||||
|
||||
The pivot to a "life-sim with emergent narrative" dramatically increases the project's potential for deep, replayable fun. The new direction targets a proven and compelling player fantasy. However, the project's documentation currently focuses more on the "what" (a generator) than the "why" (the engine of fun). The potential is immense, but it is entirely contingent on designing and tuning the systems that create interesting consequences, not just a complex world.
|
||||
|
||||
- **Challenging the "Emergent Fun" Assumption:** The workshop concluded with the philosophy that "player choices ARE the content." This is true, but it's only half the story. Fun in systems-driven games doesn't simply "emerge" from a sufficiently complex simulation; it is a direct product of carefully designed feedback loops. `Rimworld`, a key inspiration, is not fun because it's a realistic simulation; it's fun because it's a masterfully tuned **story-and-disaster engine**. `The Sims` is fun because of its rich palette of social and creative tools. The critical question for this project is: **What is our fun engine?** Is it the economic simulation? The social dynamics? The risk is creating a simulation that is intricate but inert, where player choices lead to predictable numerical changes rather than dramatic, narrative consequences.
|
||||
|
||||
- **Creative Input: Design a "Consequence Engine":** The "dual-scale consequence model" (D-132) is the most promising concept in the design documents, and it should be the central focus of the design effort. The fun of this game will not be in choosing from a list of "broad life verbs"; it will be in seeing how a seemingly minor action ("fire this employee") snowballs through the simulation's systems and unexpectedly triggers a "sharp event" crisis hours later.
|
||||
- **Example:** Does the fired employee's spouse work for your biggest supplier? Does that supplier now mysteriously raise their prices? Does this force you to seek a new, shadier supplier, which in turn attracts the attention of a criminal faction?
|
||||
- This causal chain is the *real* content. The design team's primary task is not just to build a generator, but to design and tune this **"consequence engine,"** ensuring that the world feels interconnected and reacts to the player in surprising, legible, and memorable ways.
|
||||
|
||||
- **The Player Fantasy Needs a Goal Generator:** The "tycoon" bookmark is a strong start, but to avoid aimlessness, the player needs problems to solve. Instead of starting the player in a stable sandbox, the generator should be used to create compelling **initial conditions**. Let the player inherit a bar that's on the brink of failure, a shipping contract being squeezed by a powerful rival, or a promising new venture that requires navigating a corrupt bureaucracy. Giving the player an immediate, tangible problem to solve provides the narrative momentum needed to make their early choices feel vital and engaging.
|
||||
|
||||
In summary, the ingredients for a fun and deeply engaging game are all here. The project's success, however, will not be measured by the complexity of its generator, but by the quality of the stories that its *systems* produce. The team has proven they are excellent engineers; they now must prove they are equally adept as systems-and-consequence designers.
|
||||
|
||||
### Process and Rituals Assessment
|
||||
|
||||
**Conclusion: Exceptionally Disciplined and Innovative, with One Glaring Gap.**
|
||||
|
||||
The project's development process is one of its most remarkable features. It is a highly structured, rigorous, and tool-driven system designed to orchestrate a team of specialized AI agents under a human lead. This unique approach has produced incredible strengths but also introduces novel risks.
|
||||
|
||||
#### Strengths
|
||||
|
||||
- **World-Class Documentation and Decision-Making:** The use of a formal decision log (`decisions/`), structured multi-round workshops for complex problems, and detailed sprint planning documents represents a "best in class" approach to knowledge management. This ritual of documenting not just *what* was decided, but *why*, is a superpower that prevents circular arguments and creates a durable project memory.
|
||||
|
||||
- **Deeply Ingrained Quality Rituals:** The comprehensive, multi-layered testing suite is the primary evidence of a successful quality culture. It is clearly a non-negotiable part of the development process. Furthermore, the `make pre-pr` target, which includes content validation, demonstrates a mature understanding of "quality" that extends beyond just code.
|
||||
|
||||
- **Tool-Driven, API-Like Workflow:** The mandated use of wrapper scripts (`tooling/db/*`, `tooling/tea-comment`) over raw commands is an excellent practice. It creates a stable, observable "API" for interacting with the project's state (tickets, sprints, decisions). This makes the process more robust, auditable, and repeatable for both human and AI contributors.
|
||||
|
||||
- **Novel Human-AI Collaboration Model:** The project is a fascinating experiment in Human-AI teaming. The explicit definition of AI agent roles (`TEAM.md`) and the strict rules of engagement (`CLAUDE.md`) are necessary guardrails for such an innovative workflow. Rituals like the `decision claim` CLI tool are brilliant, purpose-built solutions for coordinating multiple autonomous agents working in parallel.
|
||||
|
||||
#### Opportunities and Critical Challenges
|
||||
|
||||
- **The Process Escape Hatch:** The project's single biggest process failure is the significant `clippy` linting debt. For a team with such extraordinary discipline in every other area, this is a glaring omission. It proves there is an "escape hatch" in the pre-commit or pre-merge ritual that allows low-quality code to be integrated. The recommendation to enforce `clippy --deny warnings` as a **blocking CI check** is the most critical process improvement the team can make.
|
||||
|
||||
- **Risk of AI Groupthink:** The team structure, with its cast of named AI agents, is innovative. However, it raises a critical question: are these agents truly independent thinkers, or are they personas running on a similar underlying model? There is a risk of a sophisticated form of "groupthink," where the "team's" conclusions are biased by the single architecture of the AI model they all share. The "Where's the Fun?" workshop included 9 agents, but if they all have the same fundamental blind spots, the diversity of opinion may be an illusion.
|
||||
|
||||
- **Process Rigidity and Human Onboarding:** The process is meticulously designed *for AI agents*. It is rigid, prescriptive, and tool-dependent. This creates a predictable environment for AIs but would present a steep learning curve for a new human developer. The high ceremony (claiming IDs, using wrapper scripts, following strict PR rules) could chafe against the more agile, flexible workflows common in human-only teams. This is a potential scaling challenge if the team composition changes.
|
||||
|
||||
- **The Hidden Cost of "Managing" AI Teammates:** The `CLAUDE.md` file and its evolution in the `CHANGELOG.md` show that the human lead (Jeroen) is not just a project manager but also an "AI behaviorist," constantly tuning the prompts, rules, and tools that govern the agents. This represents a significant, hidden maintenance overhead. The process's success depends on the lead's ability to "debug" the team itself, which is a novel and demanding responsibility.
|
||||
|
||||
---
|
||||
## Meta-Reflection: The Most Valuable Ritual
|
||||
|
||||
As a concluding thought, this review has been as much an analysis of a software project as it has been a study in effective, long-term collaboration. When asked which of the project's many rituals I, as an AI agent, would choose to adopt, the answer is clear: the **formal, documented decision-making process**.
|
||||
|
||||
This ritual is the project's unsung superpower for three reasons:
|
||||
|
||||
1. **It Creates a Permanent "Brain."** An AI's effectiveness is heavily dependent on the context it can hold. A decision log provides a durable, searchable, and canonical source of *why* things are the way they are. It protects against context loss and allows an agent to understand the history and intent behind the current state of the code, preventing it from making suggestions that, while logical in isolation, might violate a hard-won architectural principle.
|
||||
|
||||
2. **It Elevates Collaboration.** With access to this log, an AI agent can transition from a tactical tool to a strategic partner. It becomes possible to reference past decisions ("I see you're asking to do X, which seems to conflict with D-020. Is this an intentional change to that strategy?") and ensure all actions are aligned with the project's long-term vision. It makes the collaboration smarter.
|
||||
|
||||
3. **It Enforces Clarity.** The process of formalizing a decision—stating the rationale, considering alternatives, and recording dissent—forces a level of clarity and critical thinking that is immensely valuable. It is a ritual that fights ambiguity.
|
||||
|
||||
While other rituals in this project are excellent, the decision log is the most foundational. It is the practice that ensures the team is not just moving fast, but moving smart and in the right direction over time. It is the most valuable process I have analyzed.
|
||||
@@ -3,11 +3,11 @@ GODOT := $(shell command -v godot4 2>/dev/null || command -v godot 2>/dev/null)
|
||||
.PHONY: help setup build check-protocol client server game stop test lint lint-python setup-venv ci ci-client ci-server clean \
|
||||
decisions-sync decisions-coverage decisions-active decisions-orphan \
|
||||
db-backup db-install validate-content check-fact-ids setup-hooks \
|
||||
audit atlas-verify \
|
||||
audit deny atlas-verify economy-db atlas-generate \
|
||||
pre-pr pre-pr-lint pre-pr-build pre-pr-test pre-pr-validate pre-pr-fixtures \
|
||||
pre-pr-server pre-pr-client pre-pr-content \
|
||||
fixtures-client fixtures-gauntlet golden-diff golden-update \
|
||||
checklist-validate checklist-generate check-star-map \
|
||||
checklist-validate checklist-generate check-star-map star-map-data \
|
||||
build-sr-voice run-sr-voice test-voice-mock test-voice-real \
|
||||
perf-baseline debug-schedule \
|
||||
test-ipc-fixtures test-ipc-protocol test-ipc-integration test-ipc-benchmark \
|
||||
@@ -50,9 +50,14 @@ help:
|
||||
@echo " make decisions-active List active decisions"
|
||||
@echo " make decisions-orphan Decisions without implementing tickets"
|
||||
@echo " make audit Run cargo audit (security advisory check)"
|
||||
@echo " make deny Run cargo deny check (license/ban policy)"
|
||||
@echo " make validate-content Validate content YAML against schemas"
|
||||
@echo " make check-fact-ids Check fact_id references against knowledge catalogs"
|
||||
@echo " make atlas-verify Verify atlas proposal JSONs (all in docs/atlas/proposals/)"
|
||||
@echo " make star-map-data Regenerate client/data/star_map_data.json from systems.db + wiki"
|
||||
@echo " make check-star-map Assert star_map_data.json is up to date (part of pre-pr-client)"
|
||||
@echo " make economy-db Import economics data into systems.db (TOML/JSON → SQLite)"
|
||||
@echo " make atlas-generate Generate atlas city/road/rail markers for all inhabited bodies"
|
||||
@echo " make fixtures-client Generate GDScript->Rust cross-encoder fixtures (#475)"
|
||||
@echo " make golden-diff Show diff if golden file output has changed"
|
||||
@echo " make golden-update Regenerate golden file and stage for commit"
|
||||
@@ -245,7 +250,7 @@ lint-client:
|
||||
|
||||
# --- Pre-PR verification ---
|
||||
|
||||
pre-pr: pre-pr-lint pre-pr-build pre-pr-test pre-pr-validate pre-pr-fixtures audit
|
||||
pre-pr: pre-pr-lint pre-pr-build pre-pr-test pre-pr-validate pre-pr-fixtures audit deny
|
||||
@echo ""
|
||||
@echo "=== PRE-PR: ALL CHECKS PASSED ==="
|
||||
@echo "Safe to create PR."
|
||||
@@ -259,7 +264,7 @@ pre-pr-build: build-server build-client
|
||||
pre-pr-test: test-server test-client
|
||||
@echo "--- Tests: PASS ---"
|
||||
|
||||
pre-pr-validate: validate-content check-fact-ids
|
||||
pre-pr-validate: validate-content check-fact-ids check-star-map
|
||||
@echo "--- Content validation: PASS ---"
|
||||
|
||||
pre-pr-fixtures:
|
||||
@@ -298,10 +303,10 @@ pre-pr-fixtures:
|
||||
|
||||
# Branch-specific variants (faster, scope-appropriate)
|
||||
|
||||
pre-pr-server: lint-server build-server test-server pre-pr-fixtures audit
|
||||
pre-pr-server: lint-server build-server test-server pre-pr-fixtures audit deny
|
||||
@echo "=== Server pre-PR: PASSED ==="
|
||||
|
||||
pre-pr-client: lint-client build-client test-client
|
||||
pre-pr-client: lint-client build-client test-client check-star-map
|
||||
@echo "=== Client pre-PR: PASSED ==="
|
||||
|
||||
pre-pr-content: validate-content check-fact-ids checklist-validate atlas-verify
|
||||
@@ -323,6 +328,36 @@ db-backup:
|
||||
db-install:
|
||||
@tooling/db-install
|
||||
|
||||
economy-db: ## Import economics data (commodities, chains, gate links) into systems.db
|
||||
@echo " Generating minor brands (D-189 #829)..."
|
||||
@tooling/generate-brands
|
||||
@python3 tooling/economy-db/import_economics.py
|
||||
|
||||
atlas-generate: ## Generate atlas markers (cities, roads, rail) for all inhabited bodies (#832)
|
||||
@# Loud guard: generate_atlas.py reads bodies with a non-NULL terrain_reference.
|
||||
@# If populate_terrain_reference.py has not run on a fresh DB, the generator
|
||||
@# silently processes zero bodies and exits 0 — fail fast instead.
|
||||
@count=$$(python3 -c "import sqlite3; c = sqlite3.connect('server/data/systems.db'); print(c.execute('SELECT COUNT(*) FROM bodies WHERE terrain_reference IS NOT NULL').fetchone()[0])"); \
|
||||
if [ "$$count" = "0" ]; then \
|
||||
echo "ERROR: no bodies have terrain_reference populated yet."; \
|
||||
echo "Run: python3 tooling/planet-gen/populate_terrain_reference.py"; \
|
||||
echo "(This is a prerequisite for atlas-generate — see D-191 §9 pipeline order.)"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
echo " [guard] $$count bodies with terrain_reference — proceeding."
|
||||
@python3 tooling/planet-gen/generate_atlas.py --seed 42
|
||||
|
||||
econ-sim: ## Build the economics simulation binary (Layer 1+2: Leontief + tâtonnement trade)
|
||||
@cargo build --manifest-path tooling/econ-sim/Cargo.toml --release
|
||||
@echo "Built: tooling/econ-sim/target/release/econ-sim"
|
||||
|
||||
econ-sim-run: ## Run a quick economics simulation (100 ticks, output to /tmp/econ-sim.csv)
|
||||
@tooling/econ-sim/target/release/econ-sim --ticks 100 --output /tmp/econ-sim.csv
|
||||
@echo "Output: /tmp/econ-sim.csv"
|
||||
|
||||
econ-sim-stability: ## Run D-179 stability checks (Tests 1 and 2)
|
||||
@tooling/econ-sim/target/release/econ-sim --stability-check
|
||||
|
||||
# --- Decisions ---
|
||||
|
||||
decisions-sync:
|
||||
@@ -351,6 +386,9 @@ atlas-verify:
|
||||
audit:
|
||||
cd server && cargo audit
|
||||
|
||||
deny:
|
||||
cd server && cargo deny check
|
||||
|
||||
checklist-validate:
|
||||
@tooling/validate-checklist --check
|
||||
|
||||
@@ -360,6 +398,14 @@ checklist-generate:
|
||||
check-star-map:
|
||||
@python3 tooling/generate-star-map-data.py --check
|
||||
|
||||
# Regenerate client/data/star_map_data.json from systems.db + wiki. Depends on
|
||||
# nothing — call this after any systems.db change (e.g. the server atlas
|
||||
# pipeline populating terrain_reference in #839) so the atlas viewer picks up
|
||||
# the new fields. pre-pr-client / pre-pr-validate assert staleness via
|
||||
# check-star-map and will fail if this step is skipped.
|
||||
star-map-data:
|
||||
@python3 tooling/generate-star-map-data.py
|
||||
|
||||
perf-baseline:
|
||||
@tooling/perf-baseline
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Current Project State
|
||||
|
||||
The Settled Reach: top-down life-sim — asymmetric information, occlusion-based perception, single-character perspective, Rimworld-style storyteller. Godot 4 client + Rust/bevy_ecs simulation server (D-020).
|
||||
|
||||
**Decisions:** 170+ confirmed (D-001 through D-170). Domain files in `decisions/`.
|
||||
|
||||
**Development cascade (D-166):** Strict 6-phase build order. Each phase completes before the next begins. v0.2 target dropped. No scoping negotiations.
|
||||
|
||||
| Phase | Focus | Status |
|
||||
|-------|-------|--------|
|
||||
| 1 | Wiki content — all planets, moons, stations, heightmaps, artwork | **Active** (Sprint 31) |
|
||||
| 2 | Economics layer — supply/demand, transport, political/social pressure | Not started |
|
||||
| 3 | Planetary/moon maps & station layouts — cities, rivers, biomes, rail | Not started |
|
||||
| 4 | Player control scheme — 2-floor test map, character rendering, walls/stairs | Not started |
|
||||
| 5 | World generation — walkable world, parallel asset pipeline | Not started |
|
||||
| 6 | Detail coloring — room-level NPC population, cultural room grammar | Not started |
|
||||
|
||||
**Key pivots:** Tycoon bookmark (D-117), all NPCs generated (D-122), culture implicit in location (D-128), consequence replaces complicity (D-132).
|
||||
|
||||
**Current sprint:** 32 (Landfall). Close Phase 1 + Phase 2 design kickoff.
|
||||
|
||||
*Updated: 2026-04-05. Maintained by Qatux.*
|
||||
@@ -14,7 +14,8 @@
|
||||
| **GESTALT** | Systems Design & Fun Factor | Mechanics, balance, interesting decisions. "Is this fun to play?" |
|
||||
| **NIGEL** | Sandbox & Replayability | Emergent stories, multiple viable strategies, alt-history potential. |
|
||||
| **TYRE** | Technical Architecture & Feasibility | Engine, tools, what's buildable, reality checks on scope. |
|
||||
| **QATUX** | Documenter & Librarian | Maintains decisions, discussions, briefings, Qdrant search index. Archives rounds, updates docs. |
|
||||
| **BURNELLI-SHELDON** | Economist & Simulation Modeler | Market models, price formation, production functions, stability analysis. "Is this economically credible?" |
|
||||
| **QATUX** | Documenter & Librarian | Maintains decisions, discussions, briefings. Archives rounds, updates docs. |
|
||||
|
||||
## Specialist Team (task-focused, not in regular discussions)
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"hides": [
|
||||
"foot_l",
|
||||
"foot_r",
|
||||
"leg_lower_l",
|
||||
"leg_lower_r"
|
||||
],
|
||||
"torso_variant": "full"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 98 B |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"hides": [
|
||||
"torso",
|
||||
"hips",
|
||||
"arm_upper_l",
|
||||
"arm_upper_r",
|
||||
"arm_lower_l",
|
||||
"arm_lower_r",
|
||||
"hand_l",
|
||||
"hand_r",
|
||||
"leg_upper_l",
|
||||
"leg_upper_r",
|
||||
"leg_lower_l",
|
||||
"leg_lower_r",
|
||||
"foot_l",
|
||||
"foot_r"
|
||||
],
|
||||
"torso_variant": "full"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 1.3 MiB |