chore(meta): plan Sprint 27: Scale
9 tickets assigned. Teams: server (5), copy (3), planning (1). Sprint goal: extend zone-type template library from 2 to 31 zone types, wire server structs for D-142, eliminate Clippy debt. New ticket #676 created: assign teams to v0.2 story backlog (#614-#626). Tickets #669 and #672 reassigned from maintenance to server. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,146 @@
|
||||
---
|
||||
title: "Sprint 27 — Copy Briefing"
|
||||
description: "Author all 29 remaining zone-type behavior templates, replace overheard.yaml, extend validate-ron name collision checking"
|
||||
type: sprint
|
||||
status: active
|
||||
sprint: 27
|
||||
team: "copy"
|
||||
---
|
||||
|
||||
# Sprint 27: Scale — Copy Tasks
|
||||
|
||||
**Goal:** Extend the zone-type template library from 2 to 31 zone types, wire the server to load them, and eliminate Clippy debt — clearing the path to the NPC legibility sprint.
|
||||
|
||||
**Branch:** `copy`
|
||||
**Agents:** Mellanie (author), Paula (narrative), Gestalt (systems)
|
||||
|
||||
## New Tickets
|
||||
|
||||
| # | Title | Blocked by |
|
||||
|---|-------|------------|
|
||||
| #662 | Author zone-type behavior templates (29 remaining types) | #663 (server structs, soft dependency — can author in parallel, but validate-ron requires server struct changes to pass) |
|
||||
| #664 | Replace overheard.yaml with generator-compatible conversation system | — |
|
||||
| #665 | Extend validate-ron to cross-culture name pool collision checking | — |
|
||||
|
||||
Use `tooling/db/ticket show <id>` for full details.
|
||||
|
||||
## Key Decisions
|
||||
|
||||
- `decisions/content.md` — D-142 (zone-type template architecture — primary reference for all authoring in this sprint), D-139 (composable behavior primitives — the three-layer assembly model), D-121 (voice is culture-driven, job as modifier), D-122 (all NPCs generated), D-128 (culture implicit in starting location)
|
||||
- `decisions/scope.md` — D-114 (generator-first proof-of-life)
|
||||
|
||||
## Open Questions to Resolve Early
|
||||
|
||||
- **Q-WTF-033: AI templating (Claude API vs ollama vs manual)** — does not block #662. The primitives authored this sprint are Layer 1 (culture-neutral physical actions). Layer 3 (LLM flavor) is an optional runtime layer; the base text must be fully playable without it. Author for standalone readability per D-142's standalone readability constraint.
|
||||
|
||||
## Notes
|
||||
|
||||
### #662 — Author zone-type behavior templates (29 remaining types)
|
||||
|
||||
**Existing files (done, use as reference):**
|
||||
- `content/global/zone-types/rural_agricultural.ron` — canonical authoring reference
|
||||
- `content/global/zone-types/industrial_freight.ron`
|
||||
|
||||
**29 remaining zone types to author (canonical list from D-142):**
|
||||
|
||||
| Group | Zone Types |
|
||||
|-------|-----------|
|
||||
| Rural | `rural_pastoral`, `rural_aquaculture`, `rural_orbital` |
|
||||
| Industrial | `industrial_manufacturing`, `industrial_processing` |
|
||||
| Port | `port_space`, `port_surface`, `port_maritime`, `port_fishing` |
|
||||
| Extraction | `extraction_space`, `extraction_surface`, `extraction_platform` |
|
||||
| Commercial | `commercial_market`, `commercial_transit` |
|
||||
| Administrative | `administrative_civil`, `administrative_judicial` |
|
||||
| Single | `research_station`, `medical_facility`, `military_garrison`, `security_checkpoint`, `entertainment_hospitality`, `entertainment_venue`, `residential_station`, `residential_surface`, `residential_dispersed`, `detention_facility`, `archaeological_site`, `wilderness_frontier`, `diplomatic_elite` |
|
||||
|
||||
**Authoring rules (non-negotiable, from D-142):**
|
||||
|
||||
1. **Primitives are culture-neutral.** Do not encode cultural attitudes, speech patterns, or voice register in action text. "Works a crop row, stopping to pull weeds by the root" is correct. "Works with quiet dignity, as is the Krenn way" is incorrect. Culture is applied by the culture modifier layer at assembly time.
|
||||
|
||||
2. **Standalone readability constraint.** Every `action` must be informative without a culture modifier. "farms" fails. "kneels at the base of a struggling plant and parts the soil with two fingers" passes. A player reading base text must be able to read what an NPC is doing.
|
||||
|
||||
3. **~15 primitives per role, ~4 roles per zone type.** (~60 primitives per zone type file, ~1,740 total.) Quality over volume — 12 excellent primitives beats 20 mediocre ones.
|
||||
|
||||
4. **Context tags:** Use `OnShift`, `OffDuty`, `Social`, `Any`. Most primitives are `OnShift`. Include at least 3–5 `Social` primitives per role for tavern/social-site coverage.
|
||||
|
||||
5. **modifier_hint:** Match the seven D-142 categories: `work_pace`, `physical_manner`, `social_signal`, `task_completion`, `environmental_scan`, `offduty_posture`, `authority_response`. Every primitive should have a hint.
|
||||
|
||||
6. **Grammar constraint (D-142):** Culture modifier clauses attach as prepositional phrases or coordinating conjunctions. Your action text should end in a form that accepts a trailing clause cleanly. "loads a wheelbarrow" → accepts "with unhurried efficiency". Avoid action text that ends in a subordinate clause that would create a grammatically broken assembly.
|
||||
|
||||
7. **Roles:** Each zone type needs roles that match its physical reality. A `detention_facility` has `guard`, `administrator`, `prisoner`, `medic`. A `research_station` has `researcher`, `technician`, `security`, `support`. Use the zone type's physical space and social function to derive the roles.
|
||||
|
||||
8. **social_site_types:** Every zone type needs at least two social site types. Include one "work" site (workshop, lab bench, loading dock) and one "off-duty" site (break room, canteen, recreation space). List `eligible_roles` for each.
|
||||
|
||||
**Validate each file:**
|
||||
```bash
|
||||
tooling/validate-ron content/global/zone-types/<zone_type>.ron zone_type
|
||||
```
|
||||
Note: this requires #663 (server struct changes) to be merged first for `validate-ron` to accept the `zone_type` schema. Until then, validate structurally by checking the file matches the pattern in `rural_agricultural.ron`.
|
||||
|
||||
---
|
||||
|
||||
**Large content push execution — team-patterns.md model:**
|
||||
|
||||
This is a large batch of structured content (29 files, ~1,740 primitives). Use the parallel writer pattern from `docs/` team patterns:
|
||||
|
||||
1. **Lore librarian agent (read-only):** Loads `rural_agricultural.ron`, `industrial_freight.ron`, D-142, D-139. Answers authoring questions from writers. Tracks cross-file consistency (do `commercial_transit` and `commercial_market` have distinct enough flavor? Does `port_space` read differently from `port_maritime`?).
|
||||
|
||||
2. **Multiple writer agents (parallel, by group):** Split by zone-type group:
|
||||
- Writer A: Rural (3 files) + Port (4 files)
|
||||
- Writer B: Industrial (2) + Extraction (3) + Commercial (2)
|
||||
- Writer C: Administrative (2) + Single group part 1 (4 files: `research_station`, `medical_facility`, `military_garrison`, `security_checkpoint`)
|
||||
- Writer D: Single group part 2 (5 files: `entertainment_hospitality`, `entertainment_venue`, `residential_station`, `residential_surface`, `residential_dispersed`)
|
||||
- Writer E: Single group part 3 (4 files: `detention_facility`, `archaeological_site`, `wilderness_frontier`, `diplomatic_elite`)
|
||||
|
||||
Each writer writes directly to disk using the Write tool — one file at a time. No text accumulation. Write often.
|
||||
|
||||
3. **Reviewer agent (after writing complete):** Reads all 29 new files + the 2 existing references. Checks: voice consistency (do all zone types read as the same authoring voice?), context tag coverage (are OnShift/Social balanced?), standalone readability (no cultural encoding?), grammar constraint compliance.
|
||||
|
||||
**Heartbeat rule:** If any agent has been working on a single file for more than 15 minutes without progress, message the team lead. Do not silently retry.
|
||||
|
||||
---
|
||||
|
||||
### #664 — Replace overheard.yaml with generator-compatible conversation system
|
||||
|
||||
`content/npc-conversations/overheard.yaml` contains 48 hand-authored conversation entries referencing named v0.1 NPCs (Kael, Sera, Torek, etc.) and the detective arc. Per D-122 (all NPCs generated), this content is superseded.
|
||||
|
||||
**What to do:**
|
||||
1. Read `content/npc-conversations/overheard.yaml` to understand its current structure.
|
||||
2. Design a replacement RON format that supports generator-compatible overheard conversations: no named NPC references, parameterized by role pair and zone type, culture-neutral content that accepts culture modifier at assembly time.
|
||||
3. Author 10–15 sample overheard conversation snippets in the new format covering at least 3 zone types.
|
||||
4. Rename/archive the old YAML: `content/npc-conversations/overheard.yaml.deprecated` with a header comment explaining why.
|
||||
5. File the new format spec as a note in `decisions/content.md` if it introduces a new content pattern (check with Qatux).
|
||||
|
||||
The old format is not salvageable as-is — the named NPC references make all 48 entries invalid. The structural value (the idea of overheard conversation as an ambient information layer) is worth preserving; the content is not.
|
||||
|
||||
---
|
||||
|
||||
### #665 — Extend validate-ron to cross-culture name pool collision checking
|
||||
|
||||
Currently `tooling/validate-ron` validates individual RON files against their schema. Name pool collisions across culture profiles (a given name appearing in both Krenn and Vael pools) are caught only in PR review.
|
||||
|
||||
**Deliverable:** A new mode in `tooling/validate-ron` (or a separate `tooling/validate-names` script):
|
||||
```bash
|
||||
tooling/validate-ron --check-name-collisions content/global/
|
||||
```
|
||||
This scans all `culture-*.ron` files, extracts `naming.given_names` and `naming.family_names` pools, and reports any name that appears in more than one culture's pool. Output should be machine-readable (exit 1 on collision, print the colliding names and which cultures they appear in).
|
||||
|
||||
This is a tooling task. It does not require server changes — the culture RON files are already parseable by the existing validator infrastructure.
|
||||
|
||||
---
|
||||
|
||||
## Dependency Chain
|
||||
|
||||
```
|
||||
#665 (validate-ron name collision) — standalone, no blockers
|
||||
#664 (replace overheard.yaml) — standalone, no blockers
|
||||
#662 (29 zone-type templates) → soft dependency on #663 (server structs) for full validate-ron pass
|
||||
└── Parallel writer agents (groups A/B/C/D/E) — all parallel once authoring begins
|
||||
```
|
||||
|
||||
## PR Workflow
|
||||
|
||||
When ready to submit, create a PR with `tea` CLI. **All flags are required** to avoid TTY prompts (see `CLAUDE.md` "Gitea access" section):
|
||||
```bash
|
||||
tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(content): description" --description "body" --base main --head copy
|
||||
```
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
title: "Sprint 27 — Joint Briefing"
|
||||
description: "Cross-team coordination, integration points, sprint completion proof"
|
||||
type: sprint
|
||||
status: active
|
||||
sprint: 27
|
||||
team: "joint"
|
||||
---
|
||||
|
||||
# Sprint 27: Scale — Joint
|
||||
|
||||
**Goal:** Extend the zone-type template library from 2 to 31 zone types, wire the server to load them, and eliminate Clippy debt — clearing the path to the NPC legibility sprint.
|
||||
|
||||
## Pre-Sprint Checks
|
||||
|
||||
| Item | Owner | Status |
|
||||
|------|-------|--------|
|
||||
| Sprint 26 all done (15/15) | SI | confirmed |
|
||||
| content/global/zone-types/ has rural_agricultural.ron and industrial_freight.ron | copy/server | confirmed |
|
||||
| validate-ron currently accepts zone spec format | server | needs update (#663) |
|
||||
| Sprint 27 created in planning status | SI | confirmed (ID: 27) |
|
||||
|
||||
## Cross-Team Dependencies
|
||||
|
||||
| Dependency | Upstream | Downstream | Notes |
|
||||
|------------|----------|------------|-------|
|
||||
| #669 (move content/) completes | server | server (#663 loader paths) | #663 loader should target `server/content/` from the start — coordinate on timing |
|
||||
| #663 (ZoneTypeTemplate structs) merges | server | copy (#662 validate-ron) | Copy team can author in parallel; full validate-ron pass requires #663 merged |
|
||||
| #663 struct design | server | copy (#662 authoring) | Server team: share the new struct field names before copy team starts batch authoring so RON files are aligned from the start |
|
||||
|
||||
**Action required — sprint start:** Server team (`#663` agent) to post the finalized `ZoneTypeTemplate` struct layout (field names and types) as a comment on #663 before copy team begins batch authoring. Copy team is authoring to the existing RON format (which IS the schema per D-142's "Rust structs match the RON files" contract) — but if the struct rename changes any field names, copy team needs to know before producing 29 files.
|
||||
|
||||
## Sprint Completion Proof
|
||||
|
||||
Sprint 27 is done when all of the following are observable:
|
||||
|
||||
**Server:**
|
||||
- `cargo clippy -- --deny warnings` passes with zero warnings on the `server` branch.
|
||||
- `cargo audit` runs as `make audit` and reports the RUSTSEC-2025-0141 advisory as ignored (expected), with no new advisories failing.
|
||||
- `tooling/validate-ron content/global/zone-types/rural_agricultural.ron zone_type` passes against the new `ZoneTypeTemplate` struct.
|
||||
- `cargo run --bin generator_spike -- --zone-type rural_agricultural --seed 42 --from-files` produces legible NPC output (eyeball test: you can tell it's a rural agricultural zone from the behaviors).
|
||||
|
||||
**Copy:**
|
||||
- `content/global/zone-types/` contains all 31 RON files (2 existing + 29 new).
|
||||
- All 31 files pass `tooling/validate-ron content/global/zone-types/<zone_type>.ron zone_type` (requires #663 merged).
|
||||
- Each file has at least 3 roles with at least 12 `OnShift` primitives and 3 `Social` primitives per role.
|
||||
- `content/npc-conversations/overheard.yaml.deprecated` exists; replacement RON file exists with 10+ entries.
|
||||
|
||||
**Planning:**
|
||||
- All 12 v0.2 story tickets (#614–#626) have a team assigned in the DB.
|
||||
- Q-WTF-039 and Q-WTF-040 are marked resolved in `decisions/questions-content.md`.
|
||||
- Any required split tickets created with blockers wired.
|
||||
|
||||
## Test Plan Alignment
|
||||
|
||||
Sprint 27 is a content + infrastructure sprint. No new ECS systems, no new IPC protocol changes. Test surface:
|
||||
|
||||
- **#663 struct changes:** Unit test deserializing `rural_agricultural.ron` into the new `ZoneTypeTemplate`. Existing spike integration test (`make generator-spike-test` or equivalent) must still pass. No regressions in existing blueprint deserialization tests.
|
||||
- **#635 Clippy:** `cargo clippy -- --deny warnings` is the test. Zero warnings = done.
|
||||
- **#669 content/ move:** `make test` must pass after the move. All fixture paths verified.
|
||||
- **#662 zone-type files:** `tooling/validate-ron` pass for all 31 files is the acceptance criterion.
|
||||
- **#664 overheard replacement:** New RON file deserializes without errors. Old YAML archived (not deleted).
|
||||
|
||||
## Sprint Retro Trigger
|
||||
|
||||
If any of these conditions are hit mid-sprint, flag to SI immediately:
|
||||
|
||||
- Server struct changes in #663 force RON file format changes that break the copy team's partially-authored files. (Mitigation: struct field names should be locked before copy batch authoring begins — see cross-team dependencies above.)
|
||||
- Copy batch authoring produces more than 5% of primitives with cultural encoding (failing standalone readability). (Mitigation: reviewer agent pass at end of each batch.)
|
||||
- #669 (content/ move) breaks more than 3 test files. (Mitigation: run `make test` after each subdirectory move, not at the end.)
|
||||
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: "Sprint 27 — Planning Briefing"
|
||||
description: "Assign teams and review open questions for v0.2 story tickets #614–#626"
|
||||
type: sprint
|
||||
status: active
|
||||
sprint: 27
|
||||
team: "planning"
|
||||
---
|
||||
|
||||
# Sprint 27: Scale — Planning Tasks
|
||||
|
||||
**Goal:** Extend the zone-type template library from 2 to 31 zone types, wire the server to load them, and eliminate Clippy debt — clearing the path to the NPC legibility sprint.
|
||||
|
||||
**Branch:** `planning`
|
||||
**Agents:** Gestalt (systems), Tyre (technical), Paula (narrative), Ozzie (player experience), Qatux (documenter/decisions), SI (project manager/ticket updates)
|
||||
|
||||
## New Tickets
|
||||
|
||||
| # | Title | Blocked by |
|
||||
|---|-------|------------|
|
||||
| #676 | Assign team and sprint for v0.2 story tickets (#614–#626) | — |
|
||||
|
||||
Use `tooling/db/ticket show <id>` for full details.
|
||||
|
||||
## Context
|
||||
|
||||
The v0.2 story tickets were created during the Where's the Fun? workshop (2026-03-05) and captured in the backlog without team assignments. Before they can enter a sprint they need a team and any cross-team splits resolved.
|
||||
|
||||
The full ticket list:
|
||||
| # | Title | Epic | Dependencies |
|
||||
|---|-------|------|-------------|
|
||||
| #614 | Bookmark definition system | Tycoon Bookmark (#605) | blocks #618 |
|
||||
| #615 | Tycoon small business owner starting state | Tycoon Bookmark | blocks #617 |
|
||||
| #616 | Broad economic verb vocabulary design | Tycoon Bookmark | — |
|
||||
| #617 | Auto-generated apartment | Tycoon Bookmark | blocked by #615 |
|
||||
| #618 | CK3-style character creation screen | Character Creation (#606) | blocked by #614 |
|
||||
| #619 | Full character customisation | Character Creation | open Q-WTF-040 |
|
||||
| #620 | Culture-implicit-in-location system | Character Creation | blocks #621 |
|
||||
| #621 | NPC personality surface area | NPC Legibility (#607) | blocked by #620, blocks #622 |
|
||||
| #622 | Relationship formation system | NPC Legibility | blocked by #621 |
|
||||
| #624 | Quietly responsive world | World Feel (#608) | — |
|
||||
| #625 | Dual-scale consequence model | World Feel | — |
|
||||
| #626 | Setting delivery — both layers | World Feel | — |
|
||||
|
||||
## Key Decisions
|
||||
|
||||
- `decisions/scope.md` — D-114 (generator-first), D-115 (character creation: skills + bookmark only), D-117 (tycoon bookmark for v0.2), D-118 (tycoon = aspiration, not starting state), D-120 (no skill ceiling)
|
||||
- `decisions/content.md` — D-121 (voice is culture-driven), D-122 (all NPCs generated), D-125 (world quietly responsive), D-126 (Groundhog Day homage on first game day), D-128 (culture implicit in starting location), D-129 (NPC personality: traits + behavior first), D-130 (emergent moral arc), D-131 (broad economic verb vocabulary), D-132 (dual-scale consequence model), D-133 (skills affect outcome), D-134 (full character customization), D-135 (setting delivery via both layers), D-136 (First Settled Reach moment: apartment + insert activation), D-137 (generator: structural and cosmetic variety)
|
||||
|
||||
## Open Questions to Resolve
|
||||
|
||||
Before assigning teams, resolve or document the following open questions:
|
||||
|
||||
**Q-WTF-039: Character creation portrait vs tile-scale preview**
|
||||
- Does the character creation screen show a portrait render or a tile-scale in-world preview of the player character?
|
||||
- Affects: #618 (CK3-style character creation screen) team assignment — portrait render is a `visual` team deliverable, tile-scale preview is `client`.
|
||||
- Needs: Araminta (visual) + Stig/Tyre (client architecture) input. Decision determines whether #618 splits into two tickets.
|
||||
|
||||
**Q-WTF-040: Do creation choices trace into the generated apartment?**
|
||||
- If the player picks hair colour and clothing in #619, does the generator use those choices when laying out the starting apartment (furniture style, colour palette)?
|
||||
- Affects: #617 (auto-generated apartment) scope. If yes, #619 blocks #617 (not just #615).
|
||||
- Needs: Gestalt (systems) + Mellanie (content) input. Low complexity to resolve — yes/no decision with a rationale.
|
||||
|
||||
## Discussion Structure
|
||||
|
||||
Three focused rounds:
|
||||
|
||||
**Round 1 — Team assignment pass**
|
||||
For each ticket, propose a team. Apply the rule: one team per ticket. If a story spans server + client, it must be split. Output: proposed team assignment for each of the 12 tickets, with rationale.
|
||||
|
||||
Heuristics:
|
||||
- Data model / simulation logic → `server`
|
||||
- UI screen / rendering / player-facing interaction → `client`
|
||||
- Design doc / verb vocabulary / narrative spec → `copy` or `planning`
|
||||
- Open question must be resolved before implementation can start → `planning` first, then re-assign
|
||||
|
||||
**Round 2 — Split review**
|
||||
Identify which tickets need to be split into server + client pairs. For each split: write the two child tickets with explicit blocker relationship. #620 (culture-implicit-in-location) is almost certainly a split: server (location-to-culture resolution logic) + client (location picker in character creation UI).
|
||||
|
||||
**Round 3 — Sprint readiness check**
|
||||
Which of the 12 tickets are ready for Sprint 28? Criteria: team assigned, no unresolved open questions blocking implementation, no upstream blocker still in backlog. Present a Sprint 28 candidate list.
|
||||
|
||||
## Output Specification
|
||||
|
||||
Deliverables from this planning session:
|
||||
|
||||
1. **Team assignments committed to DB** — `tooling/db/sqlite-exec "UPDATE tickets SET team = '...' WHERE id = ..."` for all 12 tickets.
|
||||
2. **Split tickets created** — new tickets for any server/client splits, with blocker relationships wired via `tooling/db/sqlite-exec "INSERT INTO ticket_deps ..."`.
|
||||
3. **Q-WTF-039 and Q-WTF-040 resolved** — file resolution notes in `decisions/questions-content.md` (Qatux).
|
||||
4. **Sprint 28 candidate list** — a short list of tickets ready for Sprint 28, delivered to SI for sprint planning.
|
||||
|
||||
## PR Workflow
|
||||
|
||||
When ready to submit planning artifacts, create a PR with `tea` CLI. **All flags are required** to avoid TTY prompts:
|
||||
```bash
|
||||
tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "chore(meta): plan v0.2 story ticket team assignments" --description "body" --base main --head planning
|
||||
```
|
||||
@@ -0,0 +1,143 @@
|
||||
---
|
||||
title: "Sprint 27 — Server Briefing"
|
||||
description: "ZoneTypeTemplate structs, Clippy cleanup, cargo audit CI, content/ move to server/, v0.1 YAML audit"
|
||||
type: sprint
|
||||
status: active
|
||||
sprint: 27
|
||||
team: "server"
|
||||
---
|
||||
|
||||
# Sprint 27: Scale — Server Tasks
|
||||
|
||||
**Goal:** Extend the zone-type template library from 2 to 31 zone types, wire the server to load them, and eliminate Clippy debt — clearing the path to the NPC legibility sprint.
|
||||
|
||||
**Branch:** `server`
|
||||
**Agents:** Dudley (simulation), Tyre (arch), Hoshe (QA)
|
||||
|
||||
## New Tickets
|
||||
|
||||
| # | Title | Blocked by |
|
||||
|---|-------|------------|
|
||||
| #663 | ZoneTypeTemplate and LocationSpec structs for D-142 | — |
|
||||
| #635 | Clippy cleanup and CI enforcement | — |
|
||||
| #637 | Add cargo audit to CI/review pipeline | — |
|
||||
| #669 | Move content/ directory under server/ | — |
|
||||
| #672 | Audit and flag v0.1 YAML content | — |
|
||||
|
||||
Use `tooling/db/ticket show <id>` for full details.
|
||||
|
||||
## Key Decisions
|
||||
|
||||
- `decisions/content.md` — D-142 (zone-type template architecture — the schema this sprint implements), D-139 (composable behavior primitives — `assemble_behaviors` already in `server/src/npc/blueprint.rs`)
|
||||
- `decisions/scope.md` — D-114 (generator-first proof-of-life), D-122 (all NPCs generated)
|
||||
|
||||
## Notes
|
||||
|
||||
### #663 — ZoneTypeTemplate and LocationSpec structs
|
||||
|
||||
The existing `ZoneSpec` struct (`server/src/npc/blueprint.rs`, line 38) was authored for the Sprint 25 spike. The zone-type RON files the copy team has now shipped (`content/global/zone-types/rural_agricultural.ron`, `industrial_freight.ron`) use the D-142 format, which does not match the current struct. Four changes required:
|
||||
|
||||
**1. Rename and extend `ZoneSpec` to `ZoneTypeTemplate`:**
|
||||
- Add `id: String` — the canonical zone-type identifier (e.g. `"rural_agricultural"`)
|
||||
- Add `subtype: Option<String>` — subtype discriminator (currently `None` in all files)
|
||||
- Rename `social_sites: Vec<SocialSiteSpec>` to `social_site_types: Vec<SocialSiteTypeSpec>`
|
||||
- The new `SocialSiteTypeSpec` uses `eligible_roles: Vec<String>` (role IDs), not `min_npcs`/`max_npcs` — those are location-spec metadata
|
||||
- `economic_level` and `population_density` become defaults, overridable by location specs
|
||||
|
||||
**2. Update `RoleSpec`:**
|
||||
- Remove `weight: u8` — weights are declared on location specs, not zone-type templates. Roles in a zone-type template are authoritative behavior pools; location specs declare which roles appear and at what frequency.
|
||||
- `behavior_primitives` is the primary field; `typical_behaviors` is preserved as `#[serde(default)]` for backward compatibility until migration is verified.
|
||||
|
||||
**3. Add `LocationSpec` struct:**
|
||||
- `zone_type: String` — references a `ZoneTypeTemplate.id`
|
||||
- `culture: String` — references a culture profile
|
||||
- `role_weights: Vec<RoleWeight>` — `{ role_id: String, weight: u8 }` entries
|
||||
- `economic_level: Option<u8>` — overrides zone-type default if set
|
||||
- `population_density: Option<u8>` — overrides zone-type default if set
|
||||
- `abandoned: bool` — D-142 abandoned flag
|
||||
- `poi_overlay: Vec<String>` — D-142 poi_overlay list
|
||||
- `social_sites: Vec<LocationSocialSite>` — site instances with `site_type`, `label`, `min_npcs`, `max_npcs`
|
||||
|
||||
**4. Update loader in `generator_spike.rs`:**
|
||||
- `--from-files` currently loads `content/global/<zone>-zone-spec.ron`. Update to load from `content/global/zone-types/<zone_type>.ron`.
|
||||
- Resolve `(zone_type, role_id)` → `BehaviorPrimitive` pool by loading the `ZoneTypeTemplate` file then indexing by role ID.
|
||||
- The generator spike binary passes zone-type ID as `--zone-type rural_agricultural` (update the `--zone` arg). Keep `--from-files` mode.
|
||||
|
||||
**Validate:** After struct changes, run `tooling/validate-ron content/global/zone-types/rural_agricultural.ron zone_type` — it must pass without modification to the RON files. The RON files are the ground truth; the Rust structs must match them, not the other way around.
|
||||
|
||||
**Test:** Add a unit test in `blueprint.rs` that deserializes `rural_agricultural.ron` from disk and asserts the roles, primitive count, and social_site_types are non-empty. This test will fail until both the struct and the RON files align.
|
||||
|
||||
**Schema registration in validate-ron:** After struct changes, update `server/src/bin/validate_ron.rs` to accept `zone_type` as a schema name that deserializes to `ZoneTypeTemplate`.
|
||||
|
||||
---
|
||||
|
||||
### #635 — Clippy cleanup and CI enforcement
|
||||
|
||||
Two-phase:
|
||||
|
||||
1. **One-time cleanup:** Run `cargo clippy --fix` for auto-fixable warnings. Remaining complex warnings (too_many_arguments, complex type signatures) require manual refactors — fix by refactoring, not by suppressing with `#[allow()]`. Goal: zero warnings under `--deny warnings`.
|
||||
2. **CI gate:** Add `cargo clippy -- --deny warnings` to `make pre-pr` (see `Makefile`). After this sprint, Clippy warnings in PRs are a blocking failure.
|
||||
|
||||
Run `cargo clippy -- --deny warnings 2>&1 | wc -l` before starting to get a baseline count. The Gemini review found 66 warnings — verify the current count first (Clean House sprint may have reduced it). Fix in batches and commit frequently; a single large Clippy PR is hard to review.
|
||||
|
||||
---
|
||||
|
||||
### #637 — Add cargo audit to CI/review pipeline
|
||||
|
||||
Trigger on `Cargo.toml`/`Cargo.lock` changes (not every commit). Approach:
|
||||
|
||||
1. Add `cargo audit` target to `Makefile` under `make audit`.
|
||||
2. Wire it as a check in the CI configuration (`.config/`) that runs when `Cargo.lock` changes.
|
||||
3. Also add to `make pre-pr` so it runs locally before PRs.
|
||||
|
||||
The current open advisory is `RUSTSEC-2025-0141` (bincode v1.3.3 unmaintained). `cargo audit` will flag it — this is expected until #636 (bincode migration, deferred) is completed. Add an advisory ignore for this specific ID so CI stays green while the known advisory is tracked, but new advisories will fail.
|
||||
|
||||
---
|
||||
|
||||
### #669 — Move content/ directory under server/
|
||||
|
||||
`content/` is consumed exclusively by the server (generator, validate-ron, tests). Move it to `server/content/`.
|
||||
|
||||
**Steps:**
|
||||
1. `git mv content/ server/content/` — preserves git history.
|
||||
2. Update all path references in server Rust code: search for `"content/"` string literals in `server/src/`. Key files: `server/src/bin/generator_spike.rs` (default `--content-root`), `server/src/bin/validate_ron.rs`, any test fixtures.
|
||||
3. Update Makefile targets that reference `content/`.
|
||||
4. Update `tooling/validate-ron` script if it has hardcoded paths.
|
||||
5. Run `make test` after the move — fixture paths in integration tests may need updating.
|
||||
|
||||
**Do not** touch `client/data/` — that is client-only and stays put.
|
||||
|
||||
After the move, `tooling/db/sqlite-query 'SELECT * FROM tickets WHERE description LIKE "%content/global%"'` to identify any ticket descriptions with stale paths (update them for future agents).
|
||||
|
||||
---
|
||||
|
||||
### #672 — Audit and flag v0.1 YAML content
|
||||
|
||||
Survey task, not deletion. The server and copy branches contain ~67 YAML files from v0.1 that reference deleted named NPCs (Kael, Sera, Torek, etc.) and the detective arc.
|
||||
|
||||
**Deliverable:** A single file `docs/architecture/v01-yaml-content-audit.md` listing:
|
||||
- Each YAML file path and its status: `deprecated` (pure detective/named NPC content, no generator value), `convertible` (has useful data worth porting to RON generator format), or `already-superseded` (content was already replaced in main).
|
||||
- For `convertible` files: what specifically is worth extracting (name pools? voice patterns? dialogue seeds?).
|
||||
- Recommended disposition: archive vs delete vs convert.
|
||||
|
||||
**Do not delete anything.** Flag only. Deletion requires explicit team review in a follow-up ticket.
|
||||
|
||||
---
|
||||
|
||||
## Dependency Chain
|
||||
|
||||
```
|
||||
#669 (move content/) → must complete before #663 (loader path updates assume new location)
|
||||
#663 (ZoneTypeTemplate structs) → unblocks copy team (#662) full pipeline run
|
||||
#635 (Clippy cleanup) → #637 (cargo audit — add both to pre-pr in same pass)
|
||||
#672 (v0.1 YAML audit) — standalone, parallel track
|
||||
```
|
||||
|
||||
Note: #669 should ideally complete first so #663's loader uses the new `server/content/` paths from the start. If they run in parallel, the loader path can target `server/content/` directly and #669 will confirm the files are there.
|
||||
|
||||
## PR Workflow
|
||||
|
||||
When ready to submit, create a PR with `tea` CLI. **All flags are required** to avoid TTY prompts (see `CLAUDE.md` "Gitea access" section):
|
||||
```bash
|
||||
tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(simulation): description" --description "body" --base main --head server
|
||||
```
|
||||
Reference in New Issue
Block a user