Standardized YAML frontmatter on all 20 files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
32 KiB
title, description, type, status, workshop, agent, round, created
| title | description | type | status | workshop | agent | round | created |
|---|---|---|---|---|---|---|---|
| Gestalt — Round 2: Coverage Audit, Anti-Tedium Mechanics, Transition Scenarios, Invariant Prioritization | Gestalt's coverage audit of the Gauntlet test world with anti-tedium mechanics and transition scenario design | workshop | archived | test-architecture | gestalt | 2 | 2026-02-17 |
Gestalt — Round 2: Coverage Audit, Anti-Tedium Mechanics, Transition Scenarios, Invariant Prioritization
Workshop: QA Strategy & Test Architecture Track: 1 (Test World Design) Date: 2026-02-17 Inputs: All Round 1 outputs (Gestalt, Ozzie, Tyre, Dudley, Stig, Hoshe, Justine) Lead decisions: Room count rolling, anti-tedium full suite approved, determinism confirmed.
1. Final Room Coverage Audit
I mapped every mechanical system from decisions/*.md to the complete Gauntlet room list (8 original + 6 proposed in Round 1). The goal: every system that creates a player decision is tested by at least one room.
Complete Room List (14 rooms)
| # | Room | Source | Primary Systems |
|---|---|---|---|
| 1 | Inventory Warehouse | Brief | Pickup, CarriedBy, inventory grid, 9-slot limit |
| 2 | Occlusion Corridor | Brief | LOS, shadowcasting, vision cone, perception modes |
| 3 | Interaction Gallery | Brief | ObjectType verbs, multi-verb NPC, sprint suppression |
| 4 | Crowd Plaza | Brief | Entity density, relationship colors, cognitive delay overlap |
| 5 | Fog Theater | Brief | Fog layer transitions, peripheral dimming, exploration persistence |
| 6 | Dialogue Room | Brief | Trust tiers, contradiction, walk-away, monologue during dialogue |
| 7 | Pause Chamber | Brief | TickRate toggle, state transitions, pause/unpause |
| 8 | Zone Gate | Brief (reserved) | Zone transition (future contract) |
| 9 | Eavesdrop Alcove | Gestalt R1 | ListeningFocus, zone ambient, Careful stance, conversation eavesdrop |
| 10 | Confrontation Stage | Gestalt R1 | Cognitive vulnerability, audio dip, graduated SFX suppression |
| 11 | Sprint Gauntlet | Gestalt R1 | Sprint suppression, anomaly survival, stance transitions |
| 12 | Sound Lab | Gestalt R1 | Three-range sound, sound pings, recognition chime sequence |
| 13 | Decay Observatory | Gestalt R1 | Knowledge decay, stale state, fog representation degradation |
| 14 | Shift Change | Gestalt R1 | Stress test: all systems simultaneously at density |
Coverage Matrix: System -> Room -> Key Assertion
Each row is a mechanical system drawn from a confirmed decision. The matrix shows which room exercises it and the primary assertion.
Pillar 1: Characters & Information
| System | Decision | Room(s) | Key Assertion |
|---|---|---|---|
| Knowledge graph — confidence levels | D-041 | Dialogue Room, Decay Observatory | Suspects < KnowsOf < KnowsDetails < Direct. Each level gates different verbs/dialogue. |
| Knowledge graph — decay | D-041 | Decay Observatory | Confidence downgrades once per game-minute (10 ticks). Direct -> KnowsDetails -> KnowsOf -> Suspects on schedule. |
| Knowledge graph — contradiction | D-041 | Dialogue Room | Two conflicting entries produce Contradicted state. Monologue fires. D-033 color shifts to PersonOfInterest. |
| Knowledge graph — event queue | D-041 | Shift Change | 15 entities generating KnowledgeEvents simultaneously. Queue drains completely per tick. No dropped events. |
| Entity color = relationship | D-033 | Crowd Plaza, Dialogue Room | Color maps to RelationshipState, not objective property. Unknown=#4a9ebb, Friendly=#6bc9a6, POI=#e8c547, Hostile=#d45d5d. |
| Entity color transitions | D-033 | Dialogue Room | 0.5s fade on relationship change. Contradiction shifts green -> amber. |
| Monologue — core system | D-016 | Sprint Gauntlet, Confrontation Stage, Eavesdrop Alcove | Fires as perception bridge, atmosphere, diegetic hint. Character voice varies by archetype. |
| Monologue — separate pools | D-032 | Dialogue Room | Smuggler and detective monologue pools are hard-partitioned. Same trigger, different pool. |
| Monologue — trigger types | D-016/D-032 | Multiple (see sub-table) | Each trigger type exercised at least once. |
| Invisible locked options | D-062 | Dialogue Room | No grayed-out options. No lock icons. Options appear only when unlocked. |
| Confrontation — same box | D-063 | Confrontation Stage | Confrontation uses same dialogue UI. Weight from italics + pre-delivery beat + world response. |
| Walk-away consequences | D-064 | Dialogue Room, Confrontation Stage | 300ms fade, NPC reacts, KG records incompleteness. Per-seed tolerance variation. |
| Inventory — physical items | D-065 | Inventory Warehouse | 9-slot limit (smuggler 3-4, detective 2). Take/Place verbs. CarriedBy component. |
Monologue trigger sub-table:
| Trigger Type | Room | Scenario |
|---|---|---|
enter_location |
Hub (entering any room) | Player crosses room threshold, location monologue fires |
observe_npc |
Crowd Plaza | First observation of NPC triggers character assessment monologue |
hear_sound |
Sound Lab | Sound from behind wall triggers "Footsteps behind me..." |
observe_anomaly |
Sprint Gauntlet, Confrontation Stage | NPC in wrong location triggers anomaly monologue |
post_conversation |
Dialogue Room | After dialogue ends, reflective monologue fires |
discover_evidence |
Dialogue Room (contradiction) | Contradiction discovery triggers "Wait — they said..." |
witness_interaction |
Eavesdrop Alcove | Witnessing NPC-to-NPC conversation triggers interpretation |
time_idle |
Eavesdrop Alcove (30+ tick wait) | Idle in alcove triggers reflective monologue |
return_visit |
Decay Observatory (return from Part B) | Returning to Part A triggers "Last time I was here..." |
Pillar 2: Perception
| System | Decision | Room(s) | Key Assertion |
|---|---|---|---|
| Fog of perception | D-011 | Fog Theater, Occlusion Corridor | LOS-based, not radius. Walls block. Fog returns on departure. |
| Camera locked to character | D-015 | All rooms | No panning. Vision cone: forward=full, peripheral=reduced, behind=fog. |
| Vision cone — forward/peripheral/behind | D-015 | Fog Theater, Occlusion Corridor | Forward: full LOS, full detail. Peripheral: reduced range, dimmed. Behind: blind. |
| Perception modes | D-017 | Occlusion Corridor | Mode switch reveals different information. Same entity, different ObserverSnapshot per mode. |
| Three-range sound | D-018 | Sound Lab | Close=stereo, high accuracy. Medium=directional indicator+monologue. Long=insert alert (deferred). |
| Shadowcasting — symmetric | D-035 | Occlusion Corridor, Fog Theater | If A sees B, B sees A. Verified with entities on both sides of LOS boundary. |
| Fog — 5 layers | D-059 | Fog Theater | Clear, light fog, deep fog, unexplored+maps, unexplored. Each layer tested for correct visual properties. |
| Fog — sound pings | D-059 | Sound Lab | 2-3 concentric expanding rings. Loud=3 bright fast. Quiet=1 faint slow. Fade 1.5s. |
| Fog — recognized vs unrecognized entity | D-059 | Sound Lab, Decay Observatory | Known: D-033 color glow + silhouette + 0.8s pulse + position drift. Unknown: grey blob. |
| Cognitive delay | D-060 | Fog Theater, Sound Lab, Crowd Plaza | 0.6s base, 0.3s urgent. Monologue fires DURING delay. Visual: blob -> color+silhouette over ~0.3s. |
| Recognition chime timing | D-067 | Sound Lab | Chime at ONSET of delay (not completion). 300-400ms. Sequence: detect -> chime -> delay -> monologue -> visual transition -> done. |
| Cognitive vulnerability (confrontation) | D-070 | Confrontation Stage | Emotional focus reduces ambient perception. Audio dip. Loud events break through, quiet don't. Post-confrontation delayed monologue. |
| ListeningFocus | D-071 | Eavesdrop Alcove | Stationary 30+ ticks -> +2 to +3dB World SFX. Far conversations become audible. |
| Zone ambient vs conversation | D-072 | Eavesdrop Alcove | High ambient hides conversations. Low ambient makes them conspicuous. |
| Insert overlay independence | D-048 | Fog Theater | Insert data (z-layer 6) renders regardless of fog state (z-layer 5). |
Pillar 3: Movement & Interaction
| System | Decision | Room(s) | Key Assertion |
|---|---|---|---|
| Stance toggle — Sprint/Walk/Careful/Crouch | D-053 | Sprint Gauntlet, Eavesdrop Alcove | Each stance: correct tick/tile speed, monologue rate, footstep volume, interaction availability. |
| Sprint — interaction suppression | D-055 | Sprint Gauntlet, Interaction Gallery | Interaction buffer EMPTY during sprint. Anomaly monologue survives (sprint double-take). |
| Sprint — monologue at 40% | D-053 | Sprint Gauntlet | Run 10 times: monologue fires ~4 times (statistical via SimRng). |
| Careful — tell notice bonus | D-053 | Eavesdrop Alcove | Careful stance monologue at 150%. Observation monologue fires for Tier 2 NPC behavior. |
| Tile-based movement | D-054 | All rooms | Discrete positions. Client Tween hides grid. TilePresence layers. |
| Same-tile occupancy | D-054 | Crowd Plaza | Multiple entities on one tile in different posture layers (Standing + Seated). |
| Dual-scale grid | D-066 | Occlusion Corridor, Fog Theater | 0.5m sim tiles, 1m visual tiles. 2x2 geometry minimum. Cover maps 1:1 at visual scale. |
| Entity interaction — vertical list | D-057 | Interaction Gallery | Two-phase verb computation. Phase 1 (ObjectType), Phase 2 (KG filter). Max 4 options. |
| Cursor states | D-056 | Interaction Gallery | Default/entity hover/object hover/(weapon aim future). 150ms transitions. D-033 color on hover. |
| World menu — radial | D-058 | Interaction Gallery | Right-click: 4 spokes. v0.1: 2 spokes (Observe + Insert). |
| Dialogue box | D-061 | Dialogue Room | Bottom screen, max 20%, no portraits. Max 3 response options. Monologue floats ABOVE. |
Pillar 4: Audio
| System | Decision | Room(s) | Key Assertion |
|---|---|---|---|
| 5-bus audio | D-068 | Sound Lab, Eavesdrop Alcove | Music, Ambient, World SFX, Player Actions, UI Sounds — all routable, independent sliders. |
| Audio dip — dialogue | D-069 | Dialogue Room | Ambient -6 to -8dB during dialogue. 300ms ease-in, 500ms ease-out. |
| Audio dip — confrontation | D-069 | Confrontation Stage | Ambient -10 to -12dB + low-pass 20kHz->800Hz. World SFX graduated. 500ms in, 1000ms out. |
| ListeningFocus boost | D-069 | Eavesdrop Alcove | World SFX +2 to +3dB when stationary 30+ ticks. |
| Zone crossfade | D-073 | Hub corridors (between rooms) | Hard tile boundary, 1.5-2s audio crossfade tween. |
| Audio aesthetic — insert-tech vs organic | D-074 | Sound Lab | Chimes = synthetic/precise. Footsteps = warm/breathy. Two sonic families. |
Pillar 5: Simulation & Architecture
| System | Decision | Room(s) | Key Assertion |
|---|---|---|---|
| Client-server separation | D-020 | All rooms (Layer 3 test) | ObserverSnapshot is the only data crossing boundary. PlayerInput is semantic actions. |
| Deterministic simulation | D-010 p4 | Shift Change (determinism test) | Same seed + same inputs = identical world state at tick N. INV-T01 master invariant. |
| Pause/unpause | D-031, Bug #3 | Pause Chamber | Movement discarded. No state changes. UI responsive. Round-trip preserves state. |
| Tick budget | D-026 | Shift Change | <=100ms per tick with 15+ active entities. Measured per tick, not averaged. |
| Snapshot delivery | D-020, Bug #1 | Shift Change (Layer 3) | Every tick produces exactly one ObserverSnapshot. No drops. No duplicates. In order. |
| SimRng determinism | D-030 #7 | Shift Change | RNG consumed in fixed system order. Explicit .after() constraints on all consumers. |
| Time system | D-031 | Decay Observatory | 10 ticks = 1 game-minute. Day phases drive routine transitions. |
| Simulation tiers | D-026 | Shift Change | Active tier: full sim. Entities within scope tags stay fully simulated. |
| MessagePack serialization | D-020 | Cross-language fixture tests (Hoshe) | Boundary values roundtrip. Bug #4 class prevented. |
| StableId/EntityRegistry | D-041 | All rooms with NPCs | Unique IDs. Bidirectional mapping. No dangling references. |
Content Systems
| System | Decision | Room(s) | Key Assertion |
|---|---|---|---|
| NPC 10-axis model | D-024 | Crowd Plaza, Dialogue Room | Want, Secret, Relationships, Tolerance, Routine, Information, Contentment, Personality, Tell, Skill. |
| Social site as unit | D-025 | Crowd Plaza | 4-8 NPCs in connected space with sightlines. |
| Dialogue — tagged pools | D-028 | Dialogue Room | 4 layers: access tier, relationship history, trust-gated gossip, unprompted disclosure. |
| Tag taxonomy | D-035 | Dialogue Room | 6 structural + 3 selection tags per line. Tag filtering produces valid line selection. |
| Two-tier animation | D-047 | Eavesdrop Alcove, Confrontation Stage | Tier 1 (clear activities) instantly readable. Tier 2 (ambiguous behaviors) observable but intention unclear. |
| Population ratio | D-029 | Crowd Plaza | ~30% flat, ~50% mundane triangles, ~20% entangled. Signal requires noise floor. |
Coverage Gaps: Systems With NO Room Coverage
| System | Decision | Gap | Recommendation |
|---|---|---|---|
| D-050 | v0.1 deferred | No action needed | |
| D-017 soft degradation | D-059 scan-line interference at high load | Could test in Occlusion Corridor by toggling modes rapidly. Low priority — soft visual effect. | |
| Favorite colors — object identification | D-052 | No room tests object-layer color as identification mechanic | Add to Inventory Warehouse: place personal objects (mug, cushion) with NPC favorite colors. Assert saturation below D-033 entity color. v0.1.2+ system — defer room addition. |
| News ticker | D-039 wow #5 | No room tests dual-character ticker reactions | Not a Gauntlet room — this is content-level, tested via the line previewer. No room needed. |
| Idle reflective monologue | D-039 wow #6 | Partially covered by Eavesdrop Alcove (time_idle trigger) | Eavesdrop Alcove covers the mechanic. The "wow moment" quality is a content concern, not a systems test. |
| Diegetic insert/POI navigation | D-013 | No room tests POI discovery or insert minimap | Add to Hub: place POI markers that appear/disappear based on knowledge state. Low priority — insert UI is v0.1 stretch. |
| Environmental neutrality | D-045 | No room verifies that world layer DOESN'T change with narrative state | Assertion on Dialogue Room: pre-confrontation and post-confrontation CanvasModulate values are identical. Zone lighting unchanged. Add as assertion, not a room. |
Verdict: 3 minor gaps, all addressable as assertions on existing rooms. No new rooms needed for coverage.
2. Anti-Tedium Feature Mechanics
Ozzie proposed 6 anti-tedium features. All approved by the lead. Let me map each to concrete game mechanics.
2.1 Room Reset Trigger
Mechanic: Reset Plate — a special TileKind at each room entrance.
Implementation:
- Tile type:
TileKind::ResetPlate— a new variant in the tile enum. Rendered as a floor plate with a distinct visual (pulsing outline, insert-style geometric pattern). - Trigger: Player steps onto the ResetPlate tile AND presses the Interact key (not automatic — prevents accidental resets during sprint-throughs).
- Server-side behavior:
- Identify the room boundary (room_id from ResetPlate's associated metadata)
- For all entities within the room boundary:
- Reset position to tick-0 spawn position (stored in
GauntletSpawnPositioncomponent) - Reset KnowledgeGraph to tick-0 state (stored in
GauntletKnowledgeBaselinecomponent) - Reset relationship state to tick-0 baseline
- Reset inventory to tick-0 baseline (for Inventory Warehouse)
- Reset any active cognitive delays, monologue queues, dialogue state
- Reset position to tick-0 spawn position (stored in
- Reset fog exploration state for tiles within the room boundary to unexplored
- Reset the player's KnowledgeGraph entries that reference entities in this room only
- Do NOT reset: player position (they're standing on the plate), global game time, player inventory items from other rooms
What resets (per room type):
| Room | Entity positions | Entity KG | Player KG (room refs) | Player inventory | Fog | Dialogue state |
|---|---|---|---|---|---|---|
| Inventory Warehouse | Yes | N/A | Yes | YES (clear room items) | Yes | N/A |
| Occlusion Corridor | Yes | N/A | Yes | No | Yes | N/A |
| Interaction Gallery | Yes | N/A | Yes | No | Yes | N/A |
| Crowd Plaza | Yes | N/A | Yes | No | Yes | N/A |
| Fog Theater | Yes | N/A | Yes | No | YES (critical) | N/A |
| Dialogue Room | Yes | Yes (trust tiers) | Yes | No | Yes | YES (reset tree) |
| Confrontation Stage | Yes | Yes | Yes | No | Yes | YES |
| All others | Yes | If applicable | Yes | No | Yes | If applicable |
ECS implementation sketch:
// New components for Gauntlet entities
#[derive(Component)]
pub struct GauntletSpawnPosition(pub TilePosition);
#[derive(Component)]
pub struct GauntletKnowledgeBaseline(pub KnowledgeGraph);
#[derive(Component)]
pub struct GauntletRoomId(pub u8);
// Reset system — triggered by player input on ResetPlate tile
fn reset_gauntlet_room(
room_id: u8,
entities: Query<(&GauntletRoomId, &GauntletSpawnPosition, &mut TilePosition, ...)>,
mut player_kg: Query<&mut KnowledgeGraph, With<PlayerCharacter>>,
) { ... }
Why Interact, not automatic: Automatic reset on step creates chaos during cross-room transitions. Sprint through the Hub into the Occlusion Corridor — you DON'T want the corridor to reset just because you crossed the plate. The deliberate Interact press is the "I want to try this again" signal.
2.2 Hub Teleport
Mechanic: Debug command, not a gameplay mechanic.
Implementation:
- Trigger: Keyboard shortcut (Home key or backtick). NOT an in-game interaction — this is a testing tool.
- Behavior:
- Immediately move player entity to Hub center position (
GAUNTLET.hub_center) - Clear any active dialogue/monologue state
- Clear interaction buffer
- Do NOT reset any room state (rooms maintain their current state — the tester left, they didn't reset)
- Do NOT affect game time or tick count
- Immediately move player entity to Hub center position (
- Server-side: New
PlayerAction::TeleportToHubvariant. The server validates this is a Gauntlet-only action (rejected in non-Gauntlet maps). - Game state impact: Position changes. That's it. No KG changes, no relationship changes, no inventory changes. The player just "walked really fast" back to the Hub.
Why debug command, not gameplay: Hub teleport breaks the information model (instant position change violates D-015 camera lock and D-011 fog progression). It exists for testing efficiency, not gameplay. The --gauntlet server flag enables it; production builds reject it.
2.3 WRONG Button (F12)
Mechanic: State capture system with minimal human input.
What gets captured:
| Layer | Data | Size estimate |
|---|---|---|
| ObserverSnapshot | Full current snapshot (what the client sees) | ~5-20 KB (MessagePack) |
| World digest (per Dudley's spec) | Entity count, registry count, RNG position, NPC positions | ~1-2 KB (JSON) |
| Input history | Last 100 ticks of PlayerInput | ~2-5 KB (JSON) |
| Tick number + room ID | Current tick, current room (from player position) | ~50 bytes |
| Text render | format_snapshot_text() output (per Tyre's spec) |
~2-5 KB (text) |
| Human description | One-line text from tester | ~100 bytes |
Minimum viable capture (Sprint 8):
- ObserverSnapshot (already exists — just serialize current buffer)
- Tick number + player position
- Text render output (once Tyre's formatter exists)
- Human description prompt
Full capture (Sprint 9+):
Add world digest, input history, and deterministic replay seed.
Output directory: tests/bug-reports/gauntlet-{tick}-{timestamp}/
tests/bug-reports/gauntlet-0142-20260217T141523/
snapshot.msgpack # ObserverSnapshot
snapshot.json # Human-readable JSON
text-render.txt # Formatted text output
digest.json # World digest (Sprint 9+)
inputs.json # Last 100 ticks of input (Sprint 9+)
description.txt # "NPC behind wall was visible"
Why this is the minimum: The snapshot + text render + human description gives a developer everything they need to understand WHAT was wrong. The input history + seed (Sprint 9+) gives them everything they need to REPRODUCE it. Minimum viable = understand. Full = reproduce.
Server-side: New PlayerAction::BugReport { description: String }. Server serializes state to the output directory. This is a Gauntlet-only action.
3. Cross-Room Transition Scenarios (Refined for Hub-and-Spoke)
Ozzie's hub-and-spoke layout with cross-cuts defines which rooms physically connect. Let me refine my Round 1 transition scenarios based on the actual topology.
Physical Layout (from Ozzie R1)
[Fog Theater]
|
[Inventory] --- [CENTRAL HUB] --- [Occlusion Corridor]
| | |
[Interaction [Pause Chamber] [Crowd Plaza]
Gallery] |
[Dialogue Room]
|
[Zone Gate (reserved)]
Cross-cut corridors (Ozzie R1):
- Crowd Plaza <-> Occlusion Corridor
- Fog Theater <-> Dialogue Room
- Inventory Warehouse <-> Interaction Gallery
New rooms to add to layout:
[Fog Theater]----[Sound Lab]
| |
[Inventory] --- [CENTRAL HUB] --- [Occlusion Corridor]
| | |
[Interaction [Pause Chamber] [Crowd Plaza]
Gallery] | |
| [Dialogue Room] [Shift Change]
| |
[Sprint [Confrontation [Eavesdrop
Gauntlet] Stage] Alcove]
|
[Decay Observatory]
|
[Zone Gate (reserved)]
New connections (proposed cross-cuts for system combination testing):
- Sprint Gauntlet <-> Interaction Gallery (sprint suppression into interaction range)
- Confrontation Stage <-> Eavesdrop Alcove (confrontation vulnerability into listening)
- Sound Lab <-> Fog Theater (sound pings across fog boundaries)
- Shift Change <-> Crowd Plaza (density stress into density observation)
Refined Transition Scenarios
All scenarios now reference physically connected rooms via corridors or cross-cuts.
| # | Scenario | Path | System Combination | Expected Behavior | Testable? |
|---|---|---|---|---|---|
| T1 | Sprint Exit | Crowd Plaza -> (cross-cut) -> Occlusion Corridor | D-055 + D-035 | Interaction buffer cleared during sprint. LOS recalculated at corridor entrance. No stale verbs from Plaza NPCs leak into Corridor snapshot. | YES — direct cross-cut exists |
| T2 | Fog into Dialogue | Fog Theater -> (cross-cut) -> Dialogue Room | D-059 + D-061 + D-060 | Player in light fog, initiates dialogue. Fog state preserved (entity in fog still tracked). Cognitive delay for fog entity completes during dialogue. Monologue from recognition appears ABOVE dialogue box (z-layer 7 vs dialogue at bottom). | YES — direct cross-cut exists |
| T3 | Full Inventory Interact | Inventory Warehouse -> (cross-cut) -> Interaction Gallery | D-065 + D-057 | Carry 9/9 inventory into interaction range. Take verb still offered by server (Phase 1). Client greys it out (Phase 2 filter: inventory full). Other verbs (Talk, Observe) unaffected. | YES — direct cross-cut exists |
| T4 | Sprint into Interaction | Sprint Gauntlet -> (cross-cut) -> Interaction Gallery | D-055 + D-057 | Sprint clears buffer. Arriving at Interaction Gallery entity in Walk stance: verbs repopulate within 1 tick. No buffer corruption from stance transition. | YES — proposed cross-cut |
| T5 | Confrontation to Eavesdrop | Confrontation Stage -> (cross-cut) -> Eavesdrop Alcove | D-070 + D-071 | Post-confrontation: audio dip releasing (1000ms ease-out). Enter Eavesdrop Alcove before dip fully releases. ListeningFocus not yet active (need 30 ticks stationary). Verify: dip release and ListeningFocus activation don't conflict. | YES — proposed cross-cut |
| T6 | Pause Anywhere | Pause Chamber -> Hub -> any room | D-031 + any system | Pause in Pause Chamber. Hub teleport. Enter any room. Unpause. All room systems resume correctly. No state corruption from pause during room transition. | YES — Hub connects all rooms |
| T7 | Sound across Fog | Sound Lab -> (cross-cut) -> Fog Theater | D-018 + D-059 | Sound events from Sound Lab NPCs propagate through wall into Fog Theater. Sound pings render in fog. Cognitive delay fires for recognized entity based on sound alone. | YES — proposed cross-cut |
| T8 | Walk-away Sprint | Dialogue Room -> Hub -> Sprint Gauntlet | D-064 + D-053 | Walk-away from dialogue (300ms fade). Walk to Hub. Sprint to Sprint Gauntlet. KG incompleteness recorded. NPC reaction in Dialogue Room occurs during player's Hub transit. Sprint suppresses any post-dialogue monologue. | YES — Hub path |
Scenarios dropped from Round 1:
- "Peripheral Interact" (Fog Theater -> Interaction Gallery): No direct cross-cut. Covered by Interaction Gallery's own peripheral-entity test. Peripheral interaction range is a geometry question, not a cross-room question.
Corridor Design for Transition Testing
The corridors between rooms aren't just hallways — they're testing infrastructure:
- Length: 10-15 sim tiles (~5-7.5 visual tiles) per Ozzie's spec. Long enough to test stance transitions, short enough to not waste time.
- Zone boundaries: Each corridor has a zone_id transition at its midpoint. Tests D-073 zone crossfade (1.5-2s audio tween).
- Fog behavior: Corridor enters deep fog within 5-6 tiles of leaving a room (D-059 fog gradient over 6-8 sim tiles). Tests fog re-engagement.
- Reset plates: At each room entrance (room side of corridor, not hub side). Tester walks corridor, hits plate, room resets.
4. Invariant Prioritization: Top 10 for Sprint 8
Ranked by: (1) does it catch a bug class we've actually seen? (2) how many systems does it protect? (3) implementation cost.
| Rank | ID | Invariant | Bug Catalogue Match | Systems Protected | Implementation | Sprint 8? |
|---|---|---|---|---|---|---|
| 1 | INV-T04 | Pause coherence | Bug #3 (movement while paused) | Pause, movement, state transitions | Dudley's 8 test cases exist. Just wire up. | YES — direct regression guard |
| 2 | INV-T01 | Deterministic replay | Bug #1 class (state divergence) | ALL systems | Tyre's determinism test spec + 4 fixes. Core value of the Gauntlet. | YES — Gauntlet's raison d'etre |
| 3 | INV-T03 | Snapshot delivery | Bug #1 (no snapshots), Bug #5 (overwrite) | IPC, bridge, client-server | Layer 3 subprocess test (Hoshe's spec). Catches the exact bug class. | YES — prevents #1 recurrence |
| 4 | INV-T05 | Input ordering | Bug #1 (blocking read stalls schedule) | IPC, input processing, tick ordering | Covered by Layer 3 test + Dudley's pause tests. | YES — part of Layer 3 |
| 5 | INV-S01 | Player spawn reachable | No bug yet, but SOFTLOCK risk | Pathfinding, map loading, content validation | Single pathfind check at map load. ~10 lines. | YES — trivial, high value |
| 6 | INV-C03 | StableId uniqueness | No bug yet, but CORRUPTION risk | Knowledge graph, entity lifecycle, save/load | Dudley's 4 registry lifecycle tests. | YES — direct from Dudley R1 |
| 7 | INV-C07 | Dialogue pool non-empty | No bug yet, but PLAYER-FACING failure | Dialogue, tag filtering, content pipeline | Load-time validation (Tyre's cross-reference validator). | YES — part of content validation |
| 8 | INV-T02 | Tick budget | Bug #6 class (rate mismatch) | Performance, entity density, all tick systems | Shift Change room perf assertion (p95 < 20ms per Tyre). | YES — performance gate |
| 9 | INV-P02 | LOS symmetry | No bug yet, but FAIRNESS guarantee | Shadowcasting, NPC perception, information boundaries | Property-based test: random positions, verify A sees B iff B sees A. | YES — D-035 mandates symmetry |
| 10 | INV-S05 | No entity inside geometry | No bug yet, but content scaling risk | Content loading, entity spawning, map geometry | Check at map load: every entity spawn position is walkable. | YES — trivial, prevents softlocks |
Deferred to Sprint 9+
| Rank | ID | Invariant | Reason for deferral |
|---|---|---|---|
| 11 | INV-T06 | SimRng consumption order | Depends on determinism fixes landing first (Sprint 8 P0) |
| 12 | INV-T07 | Cognitive delay monotonicity | Cognitive delay system not yet implemented |
| 13 | INV-T08 | Knowledge decay timing | Decay system implemented but not yet connected to fog rendering |
| 14 | INV-S06 | 2x2 geometry minimum | Requires map validation tooling not yet built |
| 15 | INV-P03 | Fog layer ordering | Fog shader is client-side; needs gdUnit4 test (Stig's domain) |
| 16 | INV-P04 | Insert independence | Insert overlay not yet implemented |
| 17 | INV-S07 | Zone boundary coherence | Zone system not yet implemented |
| 18 | INV-P05 | Sound propagation coherence | Sound propagation not yet implemented |
| 19 | INV-C06 | Monologue trigger reachability | Requires monologue system + content cross-reference |
| 20 | INV-S04 | NPC routine paths valid | Requires NPC routine system + pathfinding integration |
Bug Catalogue Mapping
Every Sprint 6-7 bug is now covered:
| Bug | Root Cause | Invariant(s) | Room(s) | Test Type |
|---|---|---|---|---|
| #1 Server never sends snapshots | read_framed() blocking | INV-T03, INV-T05 | Layer 3 subprocess test | Integration |
| #2 Camera doesn't center | No snapshot until keystroke | INV-T03 | Layer 3 + client gdUnit4 | Integration + unit |
| #3 Player moves while paused | process_player_input ignores TickRate | INV-T04 | Pause Chamber | Unit (Dudley's 8 tests) |
| #4 MessagePack -128 for 128 | Signed int8 branch boundary | Hoshe's BV matrix (41 values) | Fixture tests | Unit + cross-language |
| #5 Monologue lost on overwrite | Snapshot buffer drops one-shots | INV-T03 | Shift Change (density) | Integration |
| #6 Snapshot overwrite warning | Server faster than client | INV-T02, INV-T03 | Shift Change (perf) | Performance |
Summary
Deliverables
- Coverage matrix: 50+ system-to-room mappings. 3 minor gaps identified (favorite colors, POI navigation, environmental neutrality assertions) — all addressable without new rooms.
- Anti-tedium mechanics: Reset Plate (Interact-triggered, per-room state rollback), Hub Teleport (debug command, position-only), WRONG Button (MVP: snapshot + text render + description; full: + input history + replay seed).
- 8 transition scenarios: Refined for hub-and-spoke layout with cross-cuts. All physically testable. Corridor design specified (10-15 tiles, zone boundary at midpoint, reset plate at room entrance).
- Top 10 invariants for Sprint 8: Prioritized by bug catalogue match. Every Sprint 6-7 bug class covered. INV-T04 (pause) and INV-T01 (determinism) are #1-#2.
Open Questions for Round 3
- Room ordering in Gauntlet YAML: Should rooms have a canonical ordering in the content pack? Affects entity StableId assignment (lower room = lower IDs). Determinism depends on consistent entity spawn order.
- Reset Plate vs full server restart: Is per-room reset sufficient, or do some tests require a clean server state? If the latter, the Gauntlet needs a "full reset" command alongside per-room resets.
- Cross-cut corridor count: I proposed 4 new cross-cuts (Sprint Gauntlet<->Interaction Gallery, Confrontation Stage<->Eavesdrop Alcove, Sound Lab<->Fog Theater, Shift Change<->Crowd Plaza). Is this too many? Each cross-cut adds map complexity. Could consolidate Sound Lab into Occlusion Corridor as a sub-area instead of a separate room+cross-cut.