--- title: "Sprint 24 — Joint Briefing" description: "v0.1 capstone coordination, StartupMessage wire format, end-to-end playthrough proof" type: sprint status: archived sprint: 24 team: "joint" --- # Sprint 24: Signal — Joint / Integration **Goal:** Wire the storyteller's activation event into player-visible consequences, thread character archetype through the full session lifecycle, and deliver the first unscripted end-to-end v0.1 playthrough — from main menu to triangle activation. **Agents:** All implementation agents (Dudley, Tyre, Hoshe, Stig, Mellanie, Paula, Gestalt) > **This is the capstone sprint for v0.1.** Sprint 23 built the world. Sprint 24 makes it > legible as a story. Sprint 25 is playtest. Every ticket in this sprint feeds into a single > proof: a real human can boot the game, pick a character, play for 30 minutes, and experience > the storyteller doing its job — without scripted interventions or debug shortcuts. --- ## Pre-Sprint Actions These must happen at sprint start, before implementation tickets begin: | Action | Owner | Blocks | |--------|-------|--------| | Confirm `StartupMessage` wire format with `character_archetype` field | Dudley + Stig sync (day 1) | #588 — client serialization cannot be finalized until server field is published in `bridge/types.rs` | | Confirm PROTOCOL_VERSION bump: 18 → 19 | Dudley + Stig | #587 server + #588 client must land together — version mismatch crashes handshake | | Confirm `triangle_crisis_events` decode path for `TriangleCrisisEventWire` field names | Dudley + Stig sync (day 1) | #590 — client `protocol.gd` decode speculates from `bridge/types.rs`; confirm field names before merging | | Confirm `current_ticker` snapshot field structure (`id`, `text`, `category`) | Dudley + Stig sync (day 1) | #592 — client ticker decode needs field names from server `bridge/types.rs` | --- ## Cross-Team Dependencies | Dependency | Direction | Notes | |------------|-----------|-------| | `character_archetype` in StartupMessage | Server (#587) → Client (#588) | Client cannot send archetype until server defines the field. Stig reads `bridge/types.rs` for the field name before finalizing `Protocol.encode_startup_message()`. | | PROTOCOL_VERSION 18 → 19 | Server (#587) ↔ Client (#588) | Both must land in the same merge window. A mismatch crashes the handshake. | | `RoutineDeviation` tell in snapshot | Server (#589) → Client (#590) | Client registers `triangle_crisis_events` handler; server populates it after tell escalation is wired. | | `current_ticker` in snapshot | Server (#591) → Client (#592) | Client ticker hides when field is absent (null). Client can be merged before server; it simply renders nothing until server sends data. | | Triangle activation monologue lines | Copy (#597) → Server (#593) | Lines must be in YAML files before playthrough proof run. Copy is unblocked — merge first. | | Playthrough proof | All tickets → Server (#593) | #593 is the convergence gate. Cannot be filed done until all upstream tickets are merged and CI is green across all branches. | --- ## Housekeeping Done at Sprint Planning The following tickets were closed during planning as their work was already complete: | # | Reason | |---|--------| | #38 | Client-Server Integration epic — all 11 children done across Sprints 1–22 | | #369 | v0.1 Content Scoping Workshop Outputs — all 39 children done | | #455 | QA Strategy & Test Infrastructure — all 59 children done | | #575 | LOS boundary bug — fixed by #584/#585 in Sprint 23 | | #596 | Opening monologue content — fully authored in Sprint 12 (#299 smuggler, #300 detective) | --- ## Sprint Completion Proof The sprint is done when **all of the following are observable in a live production session** (no `--gauntlet`, no `SR_TEST=1`, no forced debug shortcuts): 1. **Character selection works.** From the main menu, click "New Game." A character select screen appears with two cards: Smuggler and Detective. Both keyboard and mouse selection work. ESC cancels without creating a save. Selecting a character proceeds to the game. 2. **Opening monologue is character-correct.** The first monologue line that fires on session start matches the selected archetype. Smuggler opening: contracted, dock-worker voice, insider framing. Detective opening: analytical, institutional framing, uncontracted. Both fire within the first 5 seconds of game load. 3. **Storyteller activates naturally.** Play as Smuggler. Walk to The Terminal. Observe Kael for ~3 game-minutes (no teleport, no debug shortcut). Eventually (after ~30 game-minutes real or via debug `contaminate`): the urgent monologue chime fires. The next time you approach Kael, a proximity monologue line fires from the `triangle_activated` situation pool. 4. **Tell state is observable.** After activation, stand near Kael. The debug console `npc ` reports `tell_state: RoutineDeviation`. The entity renderer colors/indicators for Kael reflect the tell (future animation deferred — tell state emitted is sufficient for v0.1). 5. **News ticker displays in The Last Shift.** Walk to The Last Shift bar. A scrolling text headline is visible in the HUD. Leaving the bar hides it. Returning shows a headline (possibly different, if 200 ticks have elapsed). 6. **CI green across all branches.** `make ci` passes on `main`, `server`, `client`, `copy` branches. No regressions. --- ## Test Plan Alignment (D-030) Sprint 24 is Phase 3 territory (D-030 Phase 3: CauseChain verification + divergent snapshots): - **#587/#588:** Protocol round-trip test — `StartupMessage { character_archetype: Smuggler }` survives serialize/deserialize. Phase 1 (data structure). - **#589:** Unit test — after `TriangleActivatedQueue` is populated, triangle NPCs have `RoutineDeviation`; `derive_tell_state()` returns `RoutineDeviation`. Phase 1. - **#591:** Unit test — `TickerPool` loads 30 headlines from YAML, rotation advances deterministically with `SimRng`. Phase 1. - **#595:** Integration test — 1-tick simulation with `StartupMessage { character_archetype: Smuggler }` emits opening monologue line from smuggler pool (not detective pool). Phase 2. - **#590:** Client test — mock snapshot with `triangle_crisis_events: [{ triangle_id: 1 }]` triggers `CHIME_ACTIVATION` play call once; second snapshot with same triangle_id does not retrigger. Phase 2. - **#593:** End-to-end integration test — `test_v0_1_integration_playthrough` (server `tests/` directory). Boot server, send Smuggler startup message, advance to contamination via debug command, assert TriangleActivated and RoutineDeviation in golden snapshot. Phase 3. --- ## Open Questions | ID | Question | Blocks | Action | |----|----------|--------|--------| | Q-052 | Storyteller hint delivery channels | — | Resolved at v0.1 scope this sprint. #589 implements channel 1 (behavioral tell escalation), #597 implements channel 7 (proximity monologue). Channels 2 (environmental change) and 4 (overheard NPC conversation) deferred to v0.2. File resolution note in `decisions/questions-content.md` after sprint. | --- ## PR Merge Order To avoid conflicts on shared files (`bridge/types.rs`, `protocol.gd`, `PROTOCOL_VERSION`): 1. Copy PR (#597) — no code dependencies; merge first. Lines must be in `main` before playthrough proof runs. 2. Server PRs (#589, #591, #594) — no client dependencies; merge in any order. These are independent. 3. **Server PR #587 (StartupMessage + archetype) + Client PR #588 (character select)** — must land together. Both bump `PROTOCOL_VERSION` to 19. Coordinate merge timing. 4. Client PR #590 (triangle consumer) — merge after server #589 is in main. 5. Client PR #592 (ticker HUD) — can merge before server #591 (renders nothing when field absent); merge after for clean integration test. 6. Server PR #595 (opening monologue gate) — merge after server #587 is in main. 7. Server PR #593 (playthrough proof) — last to merge. Requires all upstream PRs green. **Critical:** #587 and #588 share the PROTOCOL_VERSION bump. Do not merge one without the other. --- ## v0.1 Readiness After This Sprint After Sprint 24 ships, the vertical slice (D-027) satisfies: | D-027 Criterion | Sprint 24 Delivery | Status | |----------------|-------------------|--------| | 30 minutes of daily-life breathing room before contamination | Contamination delay (Sprint 22 #254) + storyteller lifecycle (Sprint 23 #572) | Done — Sprint 22/23 | | Both playthroughs feel fundamentally different | Character archetype select (#587/#588) + archetype-gated monologue (#595) + character voice (#597) | Done — this sprint | | Player names an NPC they felt conflicted about | Kael/Sera content (Sprint 12–22) + tell escalation (#589) + proximity monologue (#597) | Done — this sprint | | Observe→notice→follow→discover emerges from systems | Tell escalation (#589) + proximity monologue (#597) + existing dialogue/knowledge graph | Done — this sprint | Sprint 25 will address wow moments #3 (THE FRIEND's Contradiction) and #6 (The Quiet Moment) — the two that require deeper playtest-driven tuning. The core loop is complete after Sprint 24.