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>
144 lines
8.3 KiB
Markdown
144 lines
8.3 KiB
Markdown
---
|
|
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
|
|
```
|