3-round workshop with 7 agents (Tyre, Dudley, Stig, Hoshe, Justine, Gestalt, Ozzie) plus Qatux documenting. Produced: - 59-item prioritized test backlog (60 tickets under epic #455) - Gauntlet test world spec: 7 rooms + hub, 48 entities - Test client binary spec (tooling/test-client/) - Determinism fixes (3 patches, ~22 lines) - Server --test-mode + --port 0 design - Content cross-reference validation (9 checks) - make pre-pr pipeline (6-step) - 38 client tests prioritized - Anti-tedium features (reset plate, hub teleport, WRONG button) - Human tester walkthrough - CI pipeline design (deferred but documented) Sprint 8 scope: ~17.75 team-days across 26 tickets. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
27 KiB
QA Strategy & Test Architecture Workshop — Round 3 Notes
Workshop: QA Strategy & Test Architecture Round: 3 (Prioritization & Final Specs) Date: 2026-02-17 Documenter: Qatux Participants: Tyre, Dudley, Stig, Hoshe, Justine, Gestalt, Ozzie
Executive Summary
Round 3 produced build-ready specifications across all tracks. Every agent delivered implementation-level detail: Dudley's determinism patches are copy-pasteable, Justine's Makefile targets are ready for make, Stig's 38 client tests have function names and assertion logic, Hoshe's 59-item prioritized backlog has effort estimates and dependency chains, Tyre's Sprint 8 plan has a critical path and dependency graph, Gestalt's Gauntlet map has 48 entities with coordinate positions, and Ozzie's human tester walkthrough covers start-to-finish with terminal mockups.
Key outcomes:
- Sprint 8 scope: 10 implementation items, ~7-8 team-days. Infrastructure only — no Gauntlet rooms, no anti-tedium features. Critical path:
--test-mode(0.5d) -> test client binary (2-3d) -> Layer 3 test (0.5d). - Gauntlet map: 7 rooms + Central Hub, 48 entities, 2 cross-cuts, hub-and-spoke topology. Designed for Sprint 8, room content built Sprint 9+.
- All Round 2 open questions resolved. 11 questions answered: SetTickRate while paused = bug (reject), entity index recycling = safe (generation counter), canonical room ordering = required, blocked_entities = feasible Sprint 9, test client at
tooling/test-client/(lead override), 0 cross-cuts Sprint 8 (infrastructure only), content-ron in pre-pr = yes, fixed spawn order in setup function, kill+relaunch for full restart. - One lead override during Round 3: Test client binary moved from
server/src/bin/test_client.rstotooling/test-client/as a separate workspace crate. Dudley verified bridge types are already pub-exported — no server changes needed.
Scope tension resolved: Tyre scopes Sprint 8 as infrastructure-only. Dudley designs a 5-room Gauntlet loader MVP. Gestalt designs the full 7+Hub map. These are compatible: Tyre's Sprint 8 ships the pipes (flags, binary, test harness), Gestalt's map is the design document, Dudley's loader is the Sprint 9 implementation target. The map design happens now; room building happens Sprint 9.
1. Sprint 8 Implementation Plan (Tyre)
Dependency Graph
S8-1: Determinism fixes ────────────────────────────┐
├─> S8-5: make pre-pr
S8-2: Content cross-ref validation ─────────────────┤
│
S8-3: --test-mode + --port 0 ──> S8-4: Test client ──┤
binary MVP │
│ │
└─> S8-6: Layer 3 test wiring
│
S8-7: Pause guard tests ────────────────────────────┘ (parallel, no deps)
S8-8: Determinism regression tests ── (after S8-1)
S8-9: EntityRegistry lifecycle tests ── (parallel, no deps)
S8-10: Fixture staleness check ── (after S8-5)
Items
| # | Item | Owner | Effort | Depends On |
|---|---|---|---|---|
| S8-1 | Determinism fixes (A, B, D) | Dudley | 0.5d | Nothing |
| S8-2 | Content cross-reference validation (9 checks) | Justine | 1d | Nothing |
| S8-3 | --test-mode + --port 0 server flags |
Dudley | 0.5d | Nothing |
| S8-4 | Test client binary MVP | Dudley | 2-3d | S8-3 |
| S8-5 | make pre-pr chain |
Justine | 0.5d | S8-1, S8-2 |
| S8-6 | Layer 3 test wiring | Dudley | 0.5d | S8-3, S8-4 |
| S8-7 | Pause guard tests (6 tests) | Dudley | 0.5d | Nothing |
| S8-8 | Determinism regression tests | Dudley | 0.5d | S8-1 |
| S8-9 | EntityRegistry lifecycle tests (3 tests) | Dudley | 0.25d | Nothing |
| S8-10 | Fixture staleness check | Justine | 0.25d | S8-5 |
Critical path: S8-3 (0.5d) -> S8-4 (2-3d) -> S8-6 (0.5d) = 3-4 days. Total: Server (Dudley) ~5-6d, Tooling (Justine) ~1.75d = ~7-8 team-days.
What Explicitly Does NOT Ship Sprint 8
- Gauntlet room content (rooms 1-14)
- Anti-tedium features (room reset, hub teleport, WRONG button)
- Crossterm live terminal display
- CI automation (Gitea Actions)
- Performance baselines
- Encoding asymmetry cross-language tests
- Client tests (Stig's 38)
- Cross-room transition scenarios
2. Determinism Fixes — Final Patch Specs (Dudley)
Three fixes shipping Sprint 8. Fix C was already done (self-corrected in Round 2). Total: ~22 lines production code, 4 regression tests.
Fix A: BTreeSet for visible_positions + sort visible_tiles
Files: server/src/perception/query.rs, server/src/perception/observer/mod.rs
visible_positions: HashSet<(i32, i32)>->BTreeSet<(i32, i32)>inVisibilityGeometryvisible_ids: HashSet<u64>->BTreeSet<u64>infilter_visible_entities- Add
visible_tiles.sort_by_key(|t| (t.x, t.y))after collection - Update
collect_remembered_entitiessignature to accept&BTreeSet sector_lookup: HashMapstays as-is (point-lookup only, confirmed safe per OQ-4)
Regression tests: snapshot_visible_tiles_are_sorted, sprint_anomaly_picks_lowest_stable_id
Fix B: Sort visible entities by entity_id
File: server/src/perception/observer/mod.rs
Insert entities.sort_by_key(|e| e.entity_id); after collect_remembered_entities.
Regression test: snapshot_entities_sorted_by_id
Fix D: Sort movers in validate_movement
File: server/src/simulation/movement.rs
Collect movers into Vec, sort by entity.to_bits(), then process. Deterministic collision resolution — entity with lower to_bits() wins contested tiles.
Regression test: validate_movement_deterministic_collision_winner
3. Server --test-mode Final Spec (Dudley)
Complete main.rs replacement provided. Key design:
| Aspect | Behavior |
|---|---|
| Stdout | LISTENING:{port} after TCP bind (test client parses this) |
| Stderr | All tracing via tracing_subscriber::fmt::layer().with_writer(std::io::stderr) |
| Content | Gauntlet content pack (when ready), fallback to proof room |
| Seed | --seed 42 default in test-mode |
| Shutdown | Exits after first client disconnect |
| Port | --port 0 for OS-assigned port (uses existing accept_on(listener)) |
setup_proof_room() extracted as reusable function for both modes.
4. Test Client Binary Final Spec (Tyre + Dudley)
Lead Override: Crate Location
During Round 3, the lead overruled the Round 2 location. Test client moves from server/src/bin/test_client.rs to tooling/test-client/ as a separate workspace crate.
Note: Tyre's Round 3 spec was written before this override and still references server/src/bin/. Dudley's addendum confirms the override and verifies all bridge types are already pub-exported — no server changes needed.
CLI (Sprint 8 MVP)
settled-reach-test-client [OPTIONS]
Connection:
--connect <host:port> (default: 127.0.0.1:9876)
Input:
--replay <file.jsonl> JSONL input file (one JSON array per tick)
Output (mutually exclusive):
--text Structured text to stdout (default)
--json JSON to stdout (for golden files)
--quiet No output (CI assertions only)
Assertions:
--golden <file.json> Compare final snapshot, exit 1 on diff
--ticks <N> Disconnect after N ticks
Text Output Format
=== Tick 42 | Player (15,10) facing East | Stance: Walk | TickRate: Full ===
Game time: Day 0, 04:12 (Morning)
Room: Occlusion Corridor
Entities (5):
npc:100 (18,10) Forward rel:Neutral vis:Visible d=3
...
Tiles: 31 visible
Interactions (2):
npc:100 [Talk(1), ExamineNpc(2)] distance=3
Inventory: 2/9 [item:300(slot-0), item:301(slot-3)]
Monologue: "Something about this manifest doesn't add up."
===
Entity labels: kind:entity_id. Sorted by distance (nearest first), ties broken by entity_id. Sections with no data omitted.
Text Renderer
server/src/bridge/text_renderer.rs — library function format_snapshot_text() callable by the test client crate and integration tests. Pub-exported from server crate. Full implementation (~100 lines) provided by Tyre.
Golden File Comparison
JSON with sorted keys. Recursive diff_json_values() produces field-by-field diff on mismatch. Exit code 1 on diff.
Replay Format
JSONL — one JSON array of PlayerInput per line. Empty array [] = idle tick. Uses rmp_serde::to_vec (NOT to_vec_named) to match GDScript encoding.
Effort Estimate
~2-3 days: binary scaffolding (0.5d), text renderer (0.5-1d), replay loading (0.5d), golden file comparison (0.5d), Layer 3 wiring (0.5d).
5. Gauntlet Map Specification (Gestalt)
MVP Room List: 7 rooms + Central Hub
| # | Room | Size | Observer | Facing | Entities |
|---|---|---|---|---|---|
| 0 | Central Hub | 24x24 | (50,58) | -- | 4 signs |
| 1 | Fog Theater | 44x32 | (56,18) | South | 4 (3 NPCs, 1 object) |
| 2 | Occlusion Corridor | 42x22 | (84,58) | East | 4 NPCs |
| 3 | Inventory Warehouse | 30x28 | (17,54) | East | 11 (10 objects, 1 NPC) |
| 4 | Interaction Gallery | 24x20 | (14,92) | East | 5 (2 NPCs, 3 objects) |
| 5 | Pause Chamber | 16x16 | (50,86) | North | 1 NPC |
| 6 | Dialogue Room | 28x20 | (50,114) | North | 4 NPCs |
| 7 | Crowd Plaza | 32x32 | (96,94) | West | 15 NPCs |
Total: 48 entities. Map bounds: 0-116 x 0-124 sim tiles.
Topology
Hub-and-spoke with 2 cross-cuts:
- cross-cut-W: Inventory Warehouse <-> Interaction Gallery (T3: Full Inventory Interact)
- cross-cut-E: Occlusion Corridor <-> Crowd Plaza (T1: Sprint Exit)
7 corridors connecting rooms to hub and each other. All 6 tiles wide, 8-14 tiles long.
StableId Assignment Order
Entities receive StableIds in canonical spawn order:
- Hub entities (signs): StableId 1-4
- Fog Theater: StableId 5-8
- Occlusion Corridor: StableId 9-12
- Inventory Warehouse: StableId 13-23
- Interaction Gallery: StableId 24-28
- Pause Chamber: StableId 29
- Dialogue Room: StableId 30-33
- Crowd Plaza: StableId 34-48
Additive-only rule: Existing rooms and entities are NEVER reordered. New rooms and entities append. This preserves golden file stability.
Cross-Room Transitions (3 MVP)
| # | Transition | Path | Systems Tested |
|---|---|---|---|
| T1 | Sprint Exit | Crowd Plaza -> cross-cut-E -> Occlusion | Sprint suppression + LOS recalculation |
| T3 | Full Inventory Interact | Inventory -> cross-cut-W -> Interaction Gallery | Inventory limit + verb computation |
| T6 | Pause Anywhere | Pause -> Hub -> any room | Pause persistence across teleport/room change |
Scope Note: Gestalt vs Tyre vs Dudley
Gestalt designs 7+Hub rooms for the full Gauntlet. Tyre scopes Sprint 8 as infrastructure-only (no rooms). Dudley designs a 5-room loader MVP as the Sprint 9 implementation target. These are consistent: the map design is complete, room building follows infrastructure.
6. Client Test Suite — Final 38 Tests (Stig)
Deduplicated from 41 candidates (32 original + 6 Tyre additions + 3 Stig R2 additions).
| Priority | Count | Sprint | Categories |
|---|---|---|---|
| P0 | 2 | Sprint 8 | Monologue overwrite (Bug #5), camera static during pause (Bug #2) |
| P1 | 7 | Sprint 8-9 | Fog shader (4), entity lifecycle (2), pending recognition blob (1) |
| P2 | 24 | Sprint 9 | Camera (5), entity alpha/color (5), UI (12), lerp (1), teleport (1) |
| P3 | 5 | Sprint 10+ | Z-layer (4), lerp target (1) |
Each test includes: function name, category, exact assertions, and setup requirements.
Fog Constants
Added to client/scripts/autoloads/fog_state.gd:
VIS_HIDDEN = 0,VIS_PERIPHERAL = 180,VIS_FORWARD = 255EXP_UNEXPLORED = 0,EXP_EXPLORED = 128,EXP_VISIBLE = 255
5 magic number replacements in fog_state.gd. No shader changes needed.
7. Prioritized Test Backlog — 59 Items (Hoshe)
Summary by Sprint
| Sprint | P0 items | P1 items | Combined effort |
|---|---|---|---|
| Sprint 8 | 10 (~7d) | 15 (~10.75d) | ~17.75d |
| Sprint 9 | 10 (~7.5d) | 12 (~12.5d) | ~20d |
| Sprint 10+ | -- | 12 (~18.75d) | ~18.75d |
Sprint 8 P0 (10 items, ~7d)
- Determinism Fix A (0.5d)
- Determinism Fix B (0.25d)
- Determinism Fix D (0.25d)
- Server
--test-mode+--port 0(1d) make pre-prtarget (0.5d) 6-8. Pause guard tests: movement_discarded, unpause_accepted, roundtrip (0.75d total)- Content cross-reference validation (1.5d)
- Fixture staleness check (0.25d)
Bug Catalogue Coverage
Every Sprint 6-7 bug has Sprint 8 P0/P1 coverage:
- Bug #1 (snapshot delivery): #4 (
--test-mode), #26 (Layer 3) - Bug #2 (camera startup): #21 (client P0: camera static during pause)
- Bug #3 (movement while paused): #6, #7, #8, #13 (pause guard suite)
- Bug #4 (MessagePack -128): #15, #16, #17, #18 (boundary value matrix)
- Bug #5 (monologue overwrite): #21 (client P0: monologue not lost)
- Bug #6 (snapshot spam): #1, #2 (determinism), #29 (golden files)
8. Tooling Specifications (Justine)
make pre-pr — Final
6-step chain: lint -> build -> test -> validate-content -> check-fact-ids -> fixtures-check. ~90s incremental, ~8min clean cache. Fixture staleness is BLOCKER (not WARNING).
Branch-specific variants: pre-pr-server, pre-pr-client, pre-pr-content.
Full Makefile provided with failure output examples.
make perf-baseline
- Baseline file:
tests/perf/baseline.json(committed) - Median of 5 runs, thresholds: <15% PASS, 15-30% WARN, >30% FAIL
- Machine tag prevents cross-machine comparison
tooling/perf-compareandtooling/perf-updatescripts provided (full bash code)- Blocked on Gauntlet — shadowcast bench is the only available benchmark until rooms ship
Golden File Workflow
- Generator:
server/tests/gauntlet_golden_gen.rs(generates JSON at ticks 0, 10, 100) - Comparator:
server/tests/gauntlet_golden.rs(field-by-field diff on mismatch) - JSON format: sorted keys, pretty-printed, deterministic
make golden-diff/make golden-updatetargets provided- Full Rust code for both (~180 lines combined)
CI Pipeline Design (Deferred)
3-tier pipeline documented and ready for when lead greenlights:
- Commit tier (<2min): lint + validate-content + check-fact-ids
- PR tier (<15min): build + test + fixtures staleness (BLOCKER)
- Nightly tier (<30min): Layer 3 + golden files + perf benchmarks + content scaling
Complete .gitea/workflows/ci.yaml provided (~100 lines). Self-hosted runner required.
9. Content Validation — 9 Checks (Hoshe + Justine merged)
Extends tooling/validate-content (Python) with a second pass after schema validation.
| # | Check | Severity | Source |
|---|---|---|---|
| 1 | canonical_id_uniqueness |
ERROR | Hoshe |
| 2 | relationship_target_resolution |
ERROR | Both |
| 3 | location_slug_resolution |
ERROR | Both |
| 4 | dialogue_location_resolution |
ERROR | Both |
| 5 | fact_id_resolution |
ERROR | Both (absorbs check-fact-ids) |
| 6 | triangle_membership_resolution |
ERROR | Both |
| 7 | npc_count_accuracy |
WARNING | Hoshe |
| 8 | dialogue_line_id_uniqueness |
ERROR | Hoshe |
| 9 | bidirectional_relationship_consistency |
WARNING | Justine |
ContentIndex Python class skeleton provided. Phased rollout: Phase 1 (NPC/triangle/district) Sprint 8, Phase 2 (dialogue/fact_ids) Sprint 8, Phase 3 (warnings) Sprint 9.
10. Anti-Tedium Specifications (Ozzie + Gestalt + Stig + Dudley)
Sprint 8 Priorities (Ozzie)
| Priority | Feature | Effort | Justification |
|---|---|---|---|
| P1 | Room Reset Triggers | 1-1.5d | Can't re-test without it |
| P2 | WRONG Button MVP | 1d | Can't report bugs without it |
| P3 (Sprint 9) | Hub Teleport | 0.5d | Convenience, not necessity |
| P4 (Sprint 9) | Timer + Checklist | 1.5-2d | Engagement, not necessity |
Note: Tyre's Sprint 8 plan does NOT include anti-tedium features (infrastructure-only scope). Anti-tedium ships Sprint 9 per Tyre's roadmap, Sprint 8 per Ozzie/Gestalt's priority.
Room Reset — Final Spec
- Trigger: Step on ResetPlate + Interact (NOT automatic)
- Server:
RoomResetTriggercomponent,RoomSnapshotsresource, 10-tick debounce - Resets: entity positions, KG, fog (room tiles), room-sourced inventory, dialogue state
- Does NOT reset: other rooms, player position, session timer, SimRng state
- Test-mode only: entities only added with
--test-mode
WRONG Button MVP — Final Spec
- Hotkey: F12
- Captures: current ObserverSnapshot (JSON), text output, tick/room/seed, tester description
- Output:
tests/bug-reports/gauntlet-t{tick}-{timestamp}/(4 files: report.md, snapshot.json, text_output.txt, description.txt) - Zero server changes needed for MVP
- Full version (Sprint 9+): 60-tick ring buffer, input history, replay seed
Hub Teleport
- Home key ->
PlayerAction::TeleportToHub - Instant camera snap + 0.3s fade-to-black
- Gauntlet-only (server rejects in non-Gauntlet maps)
Client-Side UI (Stig)
bug_report.gdautoload: ~80 lines GDScript, F12 handler, ring buffer, modal promptInsertOverlay/FlashRect: shared by reset flash and teleport fadeGauntletProgressoverlay: room name, run counter, timer, progress bar (Sprint 9)- Fog constants migration: 6 named constants, 5 line replacements
11. Human Tester Workflow (Ozzie)
6-Phase Walkthrough
- Navigate to a Room — walk from Hub, room name updates, timer starts, checklist loads
- Execute the Checklist — printed checklist or terminal display, auto-tracking for
type: autoitems - Encounter a Bug — F12 -> pause -> one-line prompt -> 4 files saved -> resume
- Reset and Re-Test — step on reset plate -> room reverts to tick-0 state -> retry
- Move to Another Room — Home -> Hub -> walk to next room
- End Session — Ctrl+C -> session summary (rooms tested, coverage %, times, bug reports)
Quick-Test Developer Workflow
Target: 65 seconds from fix to verification. Build (10s) -> start server+client (3s) -> navigate (5s) -> test checklist items (45s) -> exit (2s).
Entity Visibility Symbols
| Symbol | State | Meaning |
|---|---|---|
● |
VISIBLE | In clear vision cone |
◐ |
REMEMBERED | In fog, previously seen |
◌ |
FOGGED | Detected but not recognized |
✕ |
BLOCKED | LOS blocked by wall (debug, requires blocked_entities) |
⚡ |
RECOGNIZING | Mid-cognitive-delay |
Test Client Display
10 sections: Header, Player, Entities, Fog, Sound (Sprint 9+), Cognition (Sprint 9+), Interactions, Monologue/Dialogue, Inventory, Status. MVP ships sections 1-4, 7-10.
12. Checklist YAML Schema (Stig + Ozzie merged)
Per-Room Format
# content/gauntlet/rooms/{room_id}/checklist.yaml
room: occlusion_corridor
checks:
- id: occ_01_hidden_not_visible
description: "NPC behind wall is NOT visible"
type: auto # auto | manual
step: "Stand at (45,3), face East"
condition:
player_near: [45, 3]
entity: hidden-1
expected: blocked
if_wrong: |
LOS leaking through wall. Check shadowcast.rs.
Condition Grammar (7 types)
player_near, player_facing, entity + expected (blocked/visible/remembered/recognizing), expected_sector, perception_mode, fog_visible_count_min/max, inventory_count, dialogue_active, monologue_contains.
Cross-Room Checklist
content/gauntlet/cross_room_checks.yaml at Gauntlet root. Transition scenarios with multi-room paths and structured conditions.
Auto-Tracking Split
| Feature | Godot Client | Test Client |
|---|---|---|
| Room name + timer | Yes | Yes |
| Progress bar (X/Y) | Yes (total from YAML) | Yes |
| Auto-evaluate conditions | No | Yes (Rust, type-safe) |
| Per-item display | No | Yes |
13. Boundary Value Tests — 41 Values (Hoshe)
Encoding Asymmetry (Resolved)
GDScript uses int_16 for values 256-32767; Rust uses uint_16. Both are spec-valid. rmp_serde accepts int_16-encoded positive values for u64 fields (Dudley traced through rmp-serde 1.3.1 in Round 2).
4-Direction Tests
| Direction | What | Location | When |
|---|---|---|---|
| Rust -> GDScript (fixture) | Snapshots with overlap-zone ticks | test_msgpack_boundaries.gd |
Every PR |
| GDScript -> Rust (fixture) | Inputs with overlap-zone ticks | serialization.rs |
Every PR |
| Rust -> GDScript (raw bytes) | Hand-crafted uint_16/uint_32 bytes | test_msgpack_boundaries.gd |
Every commit |
| GDScript -> Rust (raw bytes) | Hand-crafted int_16/int_32 bytes | serialization.rs |
Every commit |
Full test code provided for all 4 directions.
14. Layer 3 Test — Final Spec (Hoshe)
server/tests/layer3.rs, #[test] #[ignore], <10 seconds.
- Build server binary
- Launch as subprocess with
--test-mode --port 0 - Parse
LISTENING:{port}from stdout (5-second timeout) - Connect via TCP, send
PlayerInputviarmp_serde::to_vec(notto_vec_named) - Receive
ObserverSnapshot, assert version, tick, entity count, player entity kind ServerGuarddrop pattern for cleanup (kill on drop)- Tolerates initial tick=0 snapshot before input processed (Dudley R2 adjustment)
Full Rust code (~80 lines) provided.
15. Resolved Questions
New Answers from Round 3
| ID | Question | Answer | By |
|---|---|---|---|
| Q1 (R2-OQ-09) | Canonical room ordering for StableId? | Yes — append-only rule. YAML room order = spawn order = StableId order. | Dudley, Gestalt |
| Q2 (R2-OQ-10) | Room reset vs full restart? | Both. Room reset for iteration, kill+relaunch for determinism. | Gestalt |
| Q3 | Cross-cuts in Sprint 8? | 0 cross-cuts Sprint 8 (infrastructure only). 2 in map design. Build first 2 Sprint 10. | Tyre, Gestalt |
| Q4 (R2-OQ-05) | blocked_entities feasibility? |
Feasible, ~300 tile lookups/tick. Sprint 9 scope, gated behind --test-mode. |
Dudley |
| Q5 (R2-OQ-07) | Test client binary location? | tooling/test-client/ (lead override). Bridge types already pub-exported. |
Tyre, Dudley |
| Q6 (R2-OQ-08) | Cross-room checklist location? | content/gauntlet/cross_room_checks.yaml at Gauntlet root. |
Gestalt |
| Q7 (R2-OQ-01) | SetTickRate while paused? | Bug. Reject. Pause exits only via explicit Unpause. 4-line fix in input.rs. |
Dudley |
| Q8 (R2-OQ-02) | Entity index recycling safe? | Yes (bevy generation counter). Discipline: call unregister() on despawn. |
Dudley |
| R2-OQ-03 | content-ron in pre-pr? |
Yes, in full pre-pr only. Not in pre-pr-server. |
Tyre |
| R2-OQ-06 | Checklist overlay in Godot? | Lightweight overlay (room name + timer). Full tracking test-client-only. | Stig |
| R2-OQ-11 (cross-cuts) | 4 cross-cuts too many? | Keep all 4 in design. Build 2 for Sprint 8 map. Don't consolidate Sound Lab. | Tyre, Gestalt |
Questions Deferred to Implementation
| ID | Question | Assigned To | When |
|---|---|---|---|
| R2-OQ-04 | Fixture staleness separate target? | Justine | Resolved: No. 10-15s cost negligible. |
| OQ-11 | Client tests headless stability | Stig | Before making client tests a CI merge gate |
16. Sprint 9+ Roadmap (Tyre)
Tier 1: Sprint 9 (~10-12 team-days)
R-01: Gauntlet rooms 1-4 (3-4d), R-02: Room reset trigger (1.5d), R-03: Hub teleport (0.5d), R-04: Client tests P0-P1 (2-3d), R-05: Determinism golden files (1d), R-06: Fog byte constants (0.25d), R-07: Encoding asymmetry tests (1.5d).
Tier 2: Sprint 10 (~15-17 team-days)
R-08: WRONG button MVP (2d), R-09: Gauntlet rooms 5-8 (3-4d), R-10: Room timer + PBs (1d), R-11: Checklist auto-tracking (2d), R-12: Performance baselines (1.5d), R-13: Client tests P2 (3d), R-14: Enhanced test client terminal (2d).
Tier 3: Sprint 11+ (build when needed)
Gauntlet rooms 9-14, cross-room transitions, CI automation, content scaling stress, blocked_entities, client test headless, client tests P3, additional pause guard tests, WRONG button full capture, bidirectional relationship warnings.
Risk Register (5 risks)
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Test client takes >3 days | Medium | Delays Layer 3 | MVP scope intentionally minimal |
| Proof room too simple for golden files | Low | Golden files don't catch real bugs until rooms exist | Proves toolchain; value comes Sprint 9 |
| Content validation finds many existing errors | Medium | Sprint 8 effort bloat | Run as WARNING first sprint |
| Client test headless blocks CI | Low | Can't automate client tests | Manual make pre-pr-client interim |
| Fixture BLOCKER frustrates devs | Low | Devs skip pre-pr | Education; false positives are worse |
17. Points of Agreement (consensus)
- Sprint 8 is infrastructure. All agents accept Tyre's framing: build the pipes, fill them Sprint 9+.
- Determinism fixes are complete. Copy-pasteable code, 4 regression tests, ~22 lines total.
make pre-pris the developer discipline tool. Replaces CI until CI is greenlighted. BLOCKER on fixture staleness.- Gauntlet map design is complete. 7+Hub rooms, 48 entities, 2 cross-cuts. Additive-only constraint.
- Test client binary architecture is settled.
tooling/test-client/crate (lead override), text renderer in server library, golden file JSON comparison. - 38 client tests are prioritized and build-ready. Function names, assertions, setup — ready for Stig to implement.
- Anti-tedium is fully specified. All 4 features have implementation details. Priority ranked.
- All open questions resolved. Zero questions carry forward to implementation.
18. Points of Tension (resolved or minor)
- Fixture staleness: BLOCKER. Tyre's argument accepted by all. Justine updated spec.
- Sprint 8 anti-tedium: Ozzie/Gestalt prioritize room reset + WRONG button for Sprint 8. Tyre defers both to Sprint 9 (infrastructure-only scope). The implementation plan (Tyre) is authoritative for Sprint 8 scope; anti-tedium ships Sprint 9.
- Gauntlet room count for Sprint 8: Dudley (5 rooms), Gestalt (7+Hub). Tyre (0 rooms — infrastructure only). Resolution: map design has 7+Hub, room building is Sprint 9.
- Test client location: Tyre R3 says
server/src/bin/. Lead overrides totooling/test-client/. Dudley confirms no server changes needed. Lead override is authoritative. - F3 debug overlay: Deferred indefinitely per Stig. WRONG button captures same data. Ozzie accepts.
19. Gaps Remaining
- Gauntlet content authoring. Room YAML, entity placement, checklist definitions need writing. No specific agent assigned for content creation.
- Client test headless stability (OQ-11). Still unverified. Must be tested before making client tests a CI merge gate.
- Sound events not in ObserverSnapshot. Required for full test client display (sections 5-6). Not yet designed server-side.
- Cognitive delay visual not implemented. Tyre's tests #33-34 (blob rendering, recognition transition) depend on D-060 client implementation.
- Gauntlet map vs Dudley's loader room count. Gestalt designs 8 rooms (7+Hub). Dudley's loader MVP has 5 rooms. Reconciliation needed during Sprint 9 implementation (which rooms build first).