Sprint 9 theme: Gauntlet — test infrastructure backbone with test client binary, Gauntlet rooms 1-3, golden file suite, and client QA harness. 23 tickets across server (9), client (6), CI (6), audio (2). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
148 lines
6.7 KiB
Markdown
148 lines
6.7 KiB
Markdown
# Sprint 9: Gauntlet — Joint / Integration
|
|
|
|
**Goal:** Build the test infrastructure backbone — test client binary, Gauntlet rooms 1-3, golden file suite, and client QA harness — so every future sprint can be validated end-to-end.
|
|
|
|
**Agents:** All implementation agents (Dudley, Stig, Hoshe, Tyre, Justine, Inigo)
|
|
|
|
---
|
|
|
|
## Pre-Sprint Decisions
|
|
|
|
No new decisions are required before Sprint 9 begins. All sprint tickets operate within confirmed decisions. Items to monitor:
|
|
|
|
| Item | Status | Needed by |
|
|
|------|--------|-----------|
|
|
| `room_id` field in ObserverSnapshot | Server team must add as `Option<String>` with `#[serde(default)]` (part of #487/#488 scope) | #496 (room timer, client) |
|
|
| Checklist YAML schema design | CI and server team to align on condition types before #497 starts | #497 (checklist YAML, CI) |
|
|
| `format_snapshot_text()` signature | Server team (#481) must export pub from server crate before client can use it | #495 (WRONG button, client) |
|
|
|
|
---
|
|
|
|
## Cross-Team Dependencies
|
|
|
|
```
|
|
Server #480 (test client binary)
|
|
-> Server #481 (text renderer, pub export)
|
|
-> Client #495 (WRONG button F12 capture)
|
|
-> Server #484 (golden diff engine)
|
|
-> Server #485 (golden suite)
|
|
-> CI #486 (make golden-diff + golden-update)
|
|
|
|
Server #487 (Gauntlet rooms 1-3)
|
|
-> Server #488 (room constants)
|
|
-> Server #490 (room reset trigger)
|
|
-> Client #495 (WRONG button — reset plate context)
|
|
-> Client #502 (room reset UX — Sprint 10)
|
|
-> Client #496 (room timer)
|
|
-> CI #497 (checklist YAML schema)
|
|
|
|
Client #474 (done Sprint 8)
|
|
-> CI #475 (make fixtures-client, unblocked at sprint start)
|
|
|
|
CI #460 (make pre-pr)
|
|
-> CI #465 (fixture staleness check)
|
|
```
|
|
|
|
**Critical path:** `#480 → #481 → #484 → #485 → #486`. This chain must start and progress in the first days of the sprint. Tyre should review #480's workspace crate structure before Dudley starts to avoid rework.
|
|
|
|
---
|
|
|
|
## Sprint Completion Proof
|
|
|
|
Sprint 9 is complete when all of the following are observable:
|
|
|
|
**Test client and golden suite**
|
|
- `tooling/test-client/` builds cleanly as a separate workspace crate (`cargo build -p test-client`)
|
|
- Running `./tooling/test-client --connect <port> --json` against a live server produces formatted JSON output with tick, entities, and stance data
|
|
- `make golden-diff` exits 0 (snapshot output matches committed golden file)
|
|
- `make golden-update` regenerates `tests/golden/gauntlet_tick_10.json` without error
|
|
|
|
**Layer 3 subprocess test**
|
|
- `cargo nextest run layer3` passes: server spawns, `LISTENING:{port}` received, connection established, snapshot deserialized, all assertions green
|
|
|
|
**Gauntlet rooms**
|
|
- Server boots with Gauntlet content and three rooms load without panic
|
|
- `room_at(x, y)` resolves a coordinate within each of the 3 room boundaries to the correct `GauntletRoom`
|
|
- Room reset on trigger: entity positions, player KG (room refs), and fog return to tick-0 state
|
|
|
|
**Client QA**
|
|
- All P2 tests (#492), P3 tests (#493), and anti-tedium tests (#494) pass headless in `make test-client`
|
|
- F12 keypress in Godot (Gauntlet mode) pauses simulation, prompts for description, and produces 3 files in `tests/bug-reports/`
|
|
- Room timer displays in Gauntlet mode, hidden in non-Gauntlet mode
|
|
|
|
**CI chain**
|
|
- `make pre-pr` exits 0 on a clean checkout (lint + build + test + content validate + fixture staleness)
|
|
- `make pre-pr-server` and `make pre-pr-client` exist as branch-specific variants
|
|
- Content cross-reference validation (`tooling/validate-content`) runs all 9 checks without false positives on current content
|
|
|
|
**Audio**
|
|
- 6 interaction SFX assets committed to `audio` branch under `res://audio/`
|
|
- AudioManager registers them at startup (no-op fallback if absent — client branch unchanged)
|
|
- Sprint 7 chime assets revised and re-committed
|
|
|
|
---
|
|
|
|
## Test Plan Alignment (D-030)
|
|
|
|
Sprint 9 is Phase 3+ of the D-030 testability phases. The sprint adds the Layer 3 real subprocess test and the golden file regression suite. Both are explicit D-030 goals:
|
|
|
|
| D-030 Phase | Target | Sprint 9 Status |
|
|
|-------------|--------|-----------------|
|
|
| Phase 1 (Sprints 1-2): test infra | Done (Sprints 1-2) | |
|
|
| Phase 2 (Sprints 3-4): monologue pipeline, info boundary negatives | Done (Sprints 3-5) | |
|
|
| Phase 3 (Sprint 5+): CauseChain verification, divergent snapshots | Gauntlet golden suite (#485) starts this | In scope |
|
|
| Layer 3: real subprocess | `server/tests/layer3.rs` (#482) | In scope |
|
|
| Pre-PR gate: <3min full chain | `make pre-pr` (#460) | In scope |
|
|
| Fixture staleness detection | `check-fixture-staleness` (#465) | In scope |
|
|
| Cross-encoder protocol validation | #474 + #475 | In scope |
|
|
|
|
---
|
|
|
|
## Open Questions to Resolve Early
|
|
|
|
No blocking Q-NNN items for Sprint 9 tickets. Monitor:
|
|
|
|
- **`room_id` in snapshot**: Server team should confirm whether `ObserverSnapshot` gets a `room_id: Option<String>` field in this sprint (scope of #487/#488) or whether the client derives room from entity positions. Client #496 needs this resolved by mid-sprint.
|
|
- **Test client crate location**: Confirm `tooling/test-client/` as the workspace crate path with Tyre before #480 starts. The `tooling/` directory is currently scripts only — a Cargo workspace member there is new.
|
|
|
|
---
|
|
|
|
## Sequence Recommendation
|
|
|
|
**Days 1-3 (all teams in parallel):**
|
|
- Server: start #480 immediately (no blockers). Tyre reviews workspace structure.
|
|
- Server: start #487 in parallel (no blockers). Dudley on rooms, Tyre on architecture review.
|
|
- Server: start #489 (standalone, no blockers).
|
|
- Client: start #516 (small warm-up), then #474 (fixtures ready).
|
|
- Client: start #492, #493, #494 in parallel (all standalone).
|
|
- CI: start #460 and #464 in parallel (both standalone).
|
|
- Audio: finish #440 (in progress).
|
|
|
|
**Days 4-6:**
|
|
- Server: #481, #482 unblock once #480 is done.
|
|
- Server: #488, #490 unblock once #487 is done.
|
|
- CI: #465 unblocks once #460 is done. #475 unblocks once #474 is done.
|
|
- Client: #496 unblocks once #487 server work is done.
|
|
- Audio: start #453 once #440 is complete.
|
|
|
|
**Days 7-10:**
|
|
- Server: #484, #485 unblock once #481 is done.
|
|
- CI: #486 unblocks once #485 is done. #497 unblocks once #487 is done.
|
|
- Client: #495 unblocks once #481 + #490 are done.
|
|
|
|
---
|
|
|
|
## PR Workflow
|
|
|
|
Each team submits their own PR from their branch. Integration is via merge to `main`. No joint branch — all tickets are single-team (see team assignments in each briefing). The `joint.md` tracks integration readiness but does not produce a separate branch.
|
|
|
|
```bash
|
|
# Verify sprint assignment before PR
|
|
db/connectors/sprint status --team <team>
|
|
|
|
# Standard PR (all flags required — see CLAUDE.md)
|
|
tea pr create --repo jpmschweitzer/settled-reach --login schweitz \
|
|
--title "feat(<scope>): sprint 9 gauntlet — <team summary>" \
|
|
--description "body" --base main --head <branch>
|
|
```
|