Standardized YAML frontmatter on all 16 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 |
|---|---|---|---|---|---|---|---|
| Workshop Round 2 — Tyre (Technical Architect) | Revised testability decisions (GUT to gdUnit4), three-layer IPC test architecture, CauseChain endorsement, and final ticket list | workshop | archived | v01-gap-analysis | tyre | 2 | 2026-02-11 |
Workshop Round 2 — Tyre (Technical Architect)
Tracks: 3 + 4 (Cross-pollination and synthesis) Date: 2026-02-11
1. GUT vs gdUnit4 — Final Recommendation
I'm changing my mind. Hoshe is right.
I recommended GUT in Round 1 based on maturity, documentation breadth, community size, and Claude Code training data familiarity. Those are real advantages in a general context. But Hoshe's comparison table forced me to reconsider for THIS project's specific constraints: agent-driven development, headless execution, and structured output parsing.
Where Hoshe's arguments win
| My Round 1 argument for GUT | Hoshe's counter | My assessment |
|---|---|---|
| 8+ years maturity | gdUnit4 has been around since Godot 3, maintained by an organization (godot-gdunit-labs), not a solo developer | Hoshe wins. Bus factor matters for a multi-year project. bitwes is a single maintainer. |
| More documentation | gdUnit4 docs are comprehensive for what we need. Our Godot tests are thin by design (D-020: client is a pure renderer) | Draw. We're not writing complex GDScript tests — documentation depth is less critical. |
| Larger community | Irrelevant if headless execution has known issues | Hoshe wins on the specifics. GUT issue #491 (headless mode problems) is a real concern for agent-driven TDD. |
| More AI training data | Claude Code can work with gdUnit4's docs and examples. This was my weakest argument. | Weak argument. Withdrawing it. |
| Simpler, less magic | gdUnit4's extra features (GdUnitSceneRunner, 13 assertion types) are things we'll actually use for dialogue UI (#174) and fog overlay (#113) testing | Hoshe wins. The "extra complexity" is useful complexity. |
What clinches it
JSON output. This is the decisive factor. Our agents consume test results. gdUnit4 produces JSON natively. GUT produces console text that needs parsing. In an agent-driven workflow, structured output isn't a nice-to-have — it's how agents understand what broke and where. Hoshe's proposed JSON summary format (section 5 of their analysis) maps directly to gdUnit4's output, no post-processing tool needed.
Stable headless support. If agents can't reliably run godot --headless tests without hitting GUT-specific headless bugs, the entire Godot test infrastructure is unreliable. gdUnit4's GdUnitCmdTool is designed for CLI/headless from the start.
Scene runner with input simulation. GdUnitSceneRunner gives us time control and input simulation in scene tests. When Stig builds the dialogue UI (#174) or Stig tests the fog overlay rendering parameters (#113), scene-level tests with simulated inputs are exactly what's needed. GUT can do this, but gdUnit4's scene runner is purpose-built.
Final recommendation: gdUnit4
# Agent invocation — clean, structured
godot --headless --path client/ \
-s addons/gdUnit4/bin/GdUnitCmdTool.gd \
--test-suite "${1:-test/}" \
--report-format json
I'm being honest: I was wrong in Round 1, and Hoshe's argument is better. For general Godot projects, GUT is still a fine choice. For agent-driven development with headless execution requirements, gdUnit4 is the right tool.
2. Hoshe's CauseChain Proposal — Reaction
Verdict: Accept. This is a production feature, not test pollution.
Hoshe proposes adding a CauseChain component to information gain events — every piece of new information tracks HOW it was learned. The chain traces back through perception events (Cause::VisualObservation, Cause::AudioObservation, Cause::DialogueReveal) and flags scripted reveals (Cause::ScriptedReveal). Criterion 4 (#199) can then assert that discoveries are system-driven by checking that no chain contains Cause::ScriptedReveal.
Does it violate "no test pollution"?
No. Here's my analysis against the five production code constraints I defined in Round 1:
| Constraint | CauseChain assessment |
|---|---|
| No conditional compilation that changes production behavior | CauseChain is always present, not #[cfg(test)] |
No pub visibility escalation for tests |
CauseChain is a public ECS component that serves production needs |
| No test-specific parameters on production functions | CauseChain is attached by the information system, not injected for testing |
| Public API is the test surface | CauseChain IS public API — it's queryable through standard ECS queries |
| ECS World setup is the test fixture | Tests query CauseChain through normal component queries, no special hooks |
Why it's a production feature that HAPPENS to help testing
Reading across ALL the Round 1 analyses, the design team converged independently on the same need:
- Gestalt (Track 1, Claim 4): "No observation event pipeline — the SPINE of the game is spread across 4 epics with no connecting tissue." CauseChain IS the connecting tissue.
- Ozzie (Track 1, Claim 3): "NOTICING THAT AN NPC BROKE THEIR ROUTINE IS THE CORE GAMEPLAY LOOP AND IT'S NOT A TICKET." CauseChain tracks how that routine deviation was detected.
- Paula (Track 1, Claim 4): "The observe->notice->follow->discover chain... Each link has ticket coverage. The question is whether the chain is CONNECTED." CauseChain connects the links.
- Gore (Track 1, Claim 4): "The game rewards you for watching people... observation is ethically loaded." CauseChain enables the monologue system to comment on HOW information was gained.
CauseChain serves at least four production purposes:
- Monologue integration: The monologue system needs to know HOW information was learned to generate character-specific commentary. "I saw..." vs "I overheard..." vs "She told me..." — the cause chain determines monologue voice.
- Knowledge journal: When the player reviews their information inventory (#89), the journal can show provenance: "Learned by observing Kael at the loading bay, Day 3, 11pm."
- Debugging/storytelling: When a chain of events produces an unexpected outcome, developers can trace causality. This is the ECS equivalent of distributed tracing.
- Success criteria validation: Criterion 4 (#199) can programmatically verify that discoveries emerge from systems, not scripts.
Implementation sketch
/// How a piece of information was gained
#[derive(Component, Debug, Clone)]
pub struct CauseChain {
pub steps: Vec<CauseStep>,
}
#[derive(Debug, Clone)]
pub struct CauseStep {
pub cause: Cause,
pub tick: u64,
pub entity: Option<Entity>, // the entity involved
}
#[derive(Debug, Clone, PartialEq)]
pub enum Cause {
VisualObservation, // Saw it happen (perception system)
AudioObservation, // Heard it (sound system)
DialogueReveal, // NPC told you (dialogue system)
InferredFromPattern, // Character deduced it (monologue system)
InstitutionalAccess, // Case file, database, etc. (access tier)
StartingKnowledge, // Character knew at game start
// For criterion 4 validation:
ScriptedReveal, // Hard-coded trigger (should NOT appear in v0.1)
}
Effort: Small — it's a component definition + attachment logic in the information system. Maybe 1-2 days of work. But it should be designed alongside the information inventory (#89), not as a separate ticket. Same component model, same query patterns.
Recommendation
Add CauseChain to the information system design. Not as a testing feature — as a production component that the monologue system, knowledge journal, and criterion validation all consume. Hoshe identified the right architecture; the design team's Round 1 analyses independently confirmed the need.
3. Three-Layer IPC Testing — Merged Architecture
Hoshe proposes three layers: fixture-based (fast), mock subprocess (medium), real subprocess (slow). My Round 1 said "real IPC, not mocks." These aren't contradictory — they're complementary. Hoshe's layers test DIFFERENT things at DIFFERENT speeds.
Where we agree completely
- Real subprocess integration tests are the ground truth (my position, Hoshe's Layer 3)
- Serialization roundtrip tests should be fast and independent (Hoshe's Layer 1)
- Bash wrapper scripts for agent invocation (both proposed this)
cargo-nextestfor Rust test execution (both proposed this)- Flaky tests are bugs, not tolerated (both stated this)
Where Hoshe extends my proposal
My Round 1 had two test layers: unit tests (internal) and integration tests (real IPC). Hoshe inserts a middle layer: protocol sequence testing with a mock subprocess. This tests the GDScript LocalBridge implementation's state machine (handshake → tick loop → error recovery) without needing the full simulation.
cracks knuckles
Let me be honest about what this middle layer buys us. The real benefit is speed and isolation for client-side protocol development. When Oscar (networking) is building the LocalBridge in GDScript, they need to test protocol state transitions without waiting for the Rust simulation to compile and start. A mock subprocess that sends predetermined sequences lets Oscar iterate on the GDScript side independently. That's not test pollution — that's development velocity.
The mock subprocess is also where we test error recovery: what happens when the simulation sends malformed MessagePack? When the connection drops? When the handshake times out? These are adversarial conditions that are hard to trigger reliably with the real simulation but trivial to script with a mock.
Final merged test architecture
TEST LAYERS
===========
Layer 1 — Serialization Fixtures (fast, every edit cycle)
├── Rust: ObserverSnapshot → MessagePack → ObserverSnapshot roundtrip
├── Rust: PlayerInput → MessagePack → PlayerInput roundtrip
├── GDScript: MessagePack bytes → Dictionary → verify field values
├── Cross-language: Rust writes fixture files (.msgpack), GDScript reads + verifies
└── Target: < 1 second total
Layer 2 — Protocol State Machine (medium, every PR)
├── Mock subprocess sends predetermined message sequences
├── Tests handshake, tick loop, snapshot delivery, input receipt
├── Tests error conditions: malformed data, timeout, disconnect, reconnect
├── Tests GDScript LocalBridge without real simulation
└── Target: < 10 seconds total
Layer 3 — Real Integration (slow, daily / pre-merge)
├── Spawns actual simulation binary as subprocess
├── Sends real PlayerInput, receives real ObserverSnapshot
├── Tests: movement, perception filtering, NPC routines, info boundaries
├── Uses test fixtures: small map (10x10), minimal NPCs (3-5)
├── Deterministic: same seed + inputs = same outputs
└── Target: < 60 seconds total
SIMULATION-ONLY TESTS (no IPC involved)
=======================================
Unit tests — #[cfg(test)] inline
├── Shadowcasting algorithm edge cases
├── Pathfinding heuristics
├── Perception query filtering
├── Collision detection logic
├── Time-to-tick conversion
└── Target: < 5 seconds for full suite
Integration tests — tests/ directory
├── Full tick loop: spawn world → add entities → tick N → assert state
├── Observer snapshot generation and filtering
├── NPC behavior: routine execution, mood changes, relationship dynamics
├── Information boundary enforcement
├── CauseChain propagation through observation chain
└── Target: < 30 seconds for full suite
CLIENT-ONLY TESTS (Godot, no simulation)
=========================================
Unit tests — gdUnit4
├── MessagePack deserialization
├── ObserverSnapshot → scene tree mapping
├── Fog overlay parameter calculation
├── UI widget state from HUD data
├── Input capture → PlayerInput serialization
└── Target: < 5 seconds for full suite
Scene tests — gdUnit4 with GdUnitSceneRunner
├── Dialogue UI lifecycle (#174)
├── Fog rendering parameter application (#113)
├── Monologue display and fading (#122)
└── Target: < 10 seconds for full suite
WRAPPER SCRIPTS (test/ directory)
==================================
test/run-rust # cargo nextest run (all Rust unit + integration)
test/run-rust --filter X # filtered Rust tests
test/run-godot # gdUnit4 headless (all Godot tests)
test/run-ipc-fixtures # Layer 1 only (fast)
test/run-ipc-protocol # Layers 1-2 (medium)
test/run-ipc-integration # All three layers (slow)
test/run-all # Everything, sequential, combined report
Test output: JSON summary from all runners
Both Hoshe and I agree on structured output. The wrapper scripts produce a consistent JSON summary regardless of underlying framework:
{
"suite": "simulation::perception",
"runner": "cargo-nextest",
"duration_ms": 247,
"total": 15,
"passed": 14,
"failed": 1,
"failures": [
{
"test": "wall_blocks_vision_diagonal",
"file": "simulation/src/perception/shadowcast.rs",
"line": 142,
"message": "assertion failed: tile (3,3) should not be visible"
}
]
}
For Rust, cargo-nextest outputs structured results that can be piped through a small formatter. For Godot, gdUnit4's native JSON output is already in a usable format. The wrapper scripts normalize both into the same schema.
Test fixtures directory
test/
fixtures/
maps/
small_10x10.bin # Pre-generated test map
corridor_20x5.bin # Linear corridor for pathfinding tests
sightline_test.bin # Known sightline geometry
npcs/
minimal_3.json # 3 NPCs with known configs
triangle_test.json # 3 NPCs forming a triangle
routine_test.json # NPCs with known daily routines
protocol/
snapshot_basic.msgpack # Known-good ObserverSnapshot
input_move.msgpack # Known-good PlayerInput
malformed.msgpack # Intentionally broken data
4. Design Team Findings — Impact on Test Priority
The five hard blockers all agents converge on
Reading across Gestalt, Ozzie, Paula, Nigel, and Gore, the design team independently converged on five systems that are missing or underspecified:
| Hard Blocker | Who flagged it | Test implications |
|---|---|---|
| Collision detection | Tyre (Round 1), Gestalt | Highly unit-testable: can_move_to(tile) -> bool. Write tests alongside implementation. |
| Pathfinding | Tyre (Round 1), Gestalt | Highly unit-testable: A* algorithm, path validity, obstacle avoidance. Integration-testable: NPC follows path over N ticks. |
| Time system (Q-009) | Tyre (Round 1), Gestalt, Ozzie | Unit-testable: tick-to-time conversion, day-phase transitions. Integration-testable: routine triggers at correct game-time. |
| Interaction dispatcher | Tyre (Round 1), Gestalt | Integration-testable: player presses Interact near NPC → dialogue system activates. |
| Opening hook | Gestalt, Ozzie | Content validation: monologue fires appropriate lines in first 30 seconds. Tests depend on content packs existing. |
The monologue system as critical integration point
Every single design agent flagged the monologue system as THE critical integration point:
- Gestalt: "No observation event pipeline — the SPINE of the game"
- Ozzie: "The observation event pipeline and routine deviation detection I'm asking for are the GLUE between existing systems"
- Paula: "The monologue system is the MVP of narrative delivery"
- Gore: "Every gap I've identified routes through the monologue system"
This has a direct impact on test priority. The monologue system (#119-122) sits at the intersection of perception, information boundaries, NPC state, and character knowledge. It's the system where integration failures are most likely and most damaging. The first integration tests should exercise the monologue pipeline.
Revised test priority ordering
My Round 1 test priority was correct for infrastructure, but the design team's findings add content-integration testing as a priority:
Phase 1: Foundation (Sprint 1-2)
- Confirm testability decisions (#214) — this workshop
- Set up
cargo-nextest, gdUnit4, andtest/run-*scripts - Write first unit tests alongside collision and pathfinding implementation
- Write first integration test alongside #81 (E2E connection test)
Phase 2: System integration (Sprint 3-4) 5. Monologue pipeline integration test: perception → event → line selection → snapshot 6. Information boundary negative tests: "entity X CANNOT see component Y" (Hoshe's proposal — this is the highest-value integration test in the entire project) 7. IPC Layer 1 + 2 tests alongside bridge implementation (#78, #79) 8. Time system tests alongside time system implementation (#25)
Phase 3: Content validation (Sprint 5+) 9. CauseChain verification for observation chain (criterion 4) 10. Divergent snapshot tests (criterion 2): smuggler vs detective on same seed 11. IPC Layer 3 real integration tests 12. Content pack regression tests via line previewer (#193)
Key insight: test the monologue pipeline early
The monologue system receives events from at least 5 other systems (perception, information boundaries, NPC routines, relationship state, tells). An integration test that exercises this pipeline end-to-end is the single highest-value test we can write, because if monologue integration fails, every concept proof claim is at risk.
// This test exercises: perception → event → CauseChain → monologue trigger
#[test]
fn npc_routine_deviation_triggers_monologue_event() {
let mut sim = SimulationBuilder::new()
.with_seed(42)
.with_test_map(20, 20)
.with_player_at(10, 10)
.with_npc("kael", Position(5, 5), routine_morning_shift())
.with_game_time(23, 0) // 11pm — Kael should NOT be at work
.build();
// Place Kael in player's vision at unusual time
sim.set_npc_position("kael", Position(10, 11));
sim.tick();
let snapshot = sim.observer_snapshot(sim.player_entity());
// Monologue should fire: character noticed routine deviation
assert!(snapshot.monologue_events.iter().any(|e|
e.trigger == MonologueTrigger::RoutineDeviation
), "No monologue event for NPC seen outside routine hours");
// CauseChain should trace to visual observation
let info_events = sim.query_information_events(sim.player_entity());
assert!(info_events.iter().any(|e|
e.cause_chain.steps[0].cause == Cause::VisualObservation
), "Observation should be system-driven, not scripted");
}
This single test exercises collision (NPC placement), perception (can the player see Kael?), time system (is it outside routine hours?), routine system (what's Kael's expected schedule?), monologue generation (fire a deviation event), and CauseChain (track how the info was gained). If this test passes, we've proven the SPINE that every design agent asked for.
5. FINAL Testability Decisions for Ticket #214
These are the decisions I'm proposing for team confirmation. Changes from Round 1 are marked.
Decision 1: Rust test organization = Hybrid (UNCHANGED)
#[cfg(test)]for unit tests inside modules (algorithm internals, pure functions)tests/directory for integration tests (full tick loop, multi-system interaction)- Both run via
cargo nextest run
Hoshe agrees. No dissent.
Decision 2: Godot test framework = gdUnit4 (CHANGED from GUT)
- Install gdUnit4 as addon in client project
- Headless execution via
godot --headless+GdUnitCmdTool - JSON output format for agent consumption
GdUnitSceneRunnerfor scene lifecycle tests (dialogue UI, fog rendering)- Minimal initial tests, expand with UI complexity
Changed because: Hoshe's comparison demonstrated that gdUnit4's CLI interface, JSON output, scene runner, headless stability, and organizational maintenance are better fits for our agent-driven development workflow. See section 1 for full rationale.
Decision 3: IPC testing = Three-layer architecture (EXTENDED from "real IPC")
- Layer 1 — Fixture-based: Serialization roundtrip tests, cross-language verification. Fast, every edit cycle.
- Layer 2 — Protocol state machine: Mock subprocess, tests handshake/error/recovery. Medium speed, every PR.
- Layer 3 — Real integration: Actual simulation binary, real protocol. Slow, daily/pre-merge.
- Mock bridge for client-side unit tests (GDScript LocalBridge without real simulation)
Extended because: Hoshe's three-layer approach adds fast feedback for serialization changes and protocol state machine testing without contradicting my "real IPC for integration truth" position. The layers are complementary, not competing. See section 3 for merged architecture.
Decision 4: Production code constraints (UNCHANGED + CAUSECHAIN ENDORSED)
- No conditional compilation that changes production behavior
- No
pubvisibility escalation solely for tests - No test-specific parameters on production functions
- Public API is the test surface — if untestable through public API, the API boundary is wrong
- ECS World setup replaces mock injection
- Trait boundaries (
SimBridge) are natural test seams - CauseChain is a production component, not test pollution — serves monologue integration, knowledge journal, debugging, and criterion validation
CauseChain endorsed because: Hoshe's proposal aligns with what every design agent independently flagged as a need: tracking HOW information was gained through the observation chain. It's the ECS equivalent of distributed tracing — a production debugging/integration feature that tests can also leverage. See section 2 for analysis.
Decision 5: Test runner tooling (UNCHANGED)
cargo-nextestfor Rust (parallel execution, isolated processes, structured output)- gdUnit4 for Godot (JSON output, scene runner, stable headless)
- Bash wrapper scripts in
test/directory, whitelistable for Claude Code agents - Each script: exit code 0/non-zero, structured stdout, accepts filter arguments, no interactive input
Decision 6: Test output format = JSON summary (MERGED)
- Rust:
cargo-nexteststructured output, normalized to JSON by wrapper script - Godot: gdUnit4 native JSON output
- Integration: stdout + exit code + JSON summary
- JUnit XML as secondary format for future CI integration
- All wrappers produce consistent JSON schema (suite, total, passed, failed, failures array)
Merged because: Both Hoshe and I converged on JSON as the agent consumption format and JUnit XML as the CI format. gdUnit4's native JSON output eliminates the need for a separate formatter tool on the Godot side.
Decision 7: Deterministic replay promotion (NEW — from Hoshe)
- Promote #201 (Deterministic replay system) from HIGH to CRITICAL
- Without deterministic replay, sync tests (#211) and divergence tests (#197) are impossible
- The simulation MUST consume time, randomness, and player input exclusively through injectable resources:
SimulationTime,SimRng(seeded from world seed),InputQueue - No
std::time::Instant, norand::thread_rng()— everything through resources - This is a production architecture requirement (D-010 principle 4), not test infrastructure
Hoshe is right that #201 should be CRITICAL. Determinism is not just a testing concern — it's a core architectural principle (D-010). If the simulation isn't deterministic, the replay system can't work, the save system can't verify correctness, and cross-seed variation (#178) can't be validated.
Decision 8: Test priority alignment with hard blockers (NEW — from design team)
- Test infrastructure must be ready for the first hard blocker implementations: collision, pathfinding, time system
- Monologue pipeline integration test is the highest-value cross-system test — write it as soon as monologue and perception systems exist
- Information boundary negative tests are the second highest-value — verify that information DOESN'T leak
Still needs discussion (deferred beyond #214)
- Performance benchmarks (#204): Define baselines: tick budget (ms per tick), entity count targets, serialization throughput. Not urgent for v0.1 with 25 NPCs.
- Full playthrough automation (#212): Scope to smoke tests only for v0.1. Full automation is premature. Agree with Hoshe's assessment.
- Rendering verification (#208): Demote to LOW for v0.1 — headless Godot can't meaningfully verify visual output. Agree with Hoshe.
6. FINAL New Technical Tickets — Merged and Deduplicated
I've merged my Round 1 proposals with Hoshe's proposals and cross-referenced against the design team's findings. Duplicates eliminated, related tickets grouped.
Hard Blocker Tickets (v0.1 cannot ship without these)
| # | Title | Priority | Blocks | Effort | Source |
|---|---|---|---|---|---|
| NEW-1 | Tile collision system — walkability map + movement validation | Critical | #83, #101 | S | Tyre R1 §3.2 |
| NEW-2 | Tile-based A* pathfinding system (pathfinding crate) |
High | #101 | M | Tyre R1 §3.1, Gestalt, Hoshe |
| NEW-3 | NPC path following and per-tick movement system | High | #101 | M | Tyre R1 §3.1 |
| NEW-4 | Interaction dispatcher — routes Interact input to subsystems | High | #168 (dialogue) | M | Tyre R1 §3.11.1, Gestalt |
| PROMOTE | #25 (Time system) → HIGH, rename to "Game clock and day-phase system" | High | #88 | M | Tyre R1 §3.4, Gestalt, Ozzie |
| PROMOTE | #201 (Deterministic replay) → CRITICAL | Critical | #211, #197 | L | Hoshe R1 §4 |
Testability Infrastructure Tickets
| # | Title | Priority | Blocks | Effort | Source |
|---|---|---|---|---|---|
| NEW-5 | Test runner bash scripts (test/run-rust, run-godot, run-ipc-*, run-all) | High | #215, #216 | S | Tyre R1 §4.6, Hoshe R1 §1 |
| NEW-6 | IPC serialization fixture files (Layer 1 test data) | High | #210 | S | Hoshe R1 §4 |
| NEW-7 | Information boundary negative test suite | High | #199 | M | Hoshe R1 §8 |
| NEW-8 | CauseChain component — information provenance tracking | High | #199, #119 | S | Hoshe R1 §7, Gestalt, Paula, Ozzie, Gore |
| NEW-9 | Playtest protocol definition — structured form for D-027 criteria | Medium | #195 | XS | Hoshe R1 §7 |
Soft Blocker Tickets (v0.1 feels broken without these)
| # | Title | Priority | Blocks | Effort | Source |
|---|---|---|---|---|---|
| NEW-10 | Client audio manager and spatial playback | High | #124, #125 | S | Tyre R1 §3.5 |
| NEW-11 | Define placeholder art specification (tile size, sprite dims, colors) | High | #133 | XS | Tyre R1 §3.6 |
| NEW-12 | Save state data model and serialization (shares design with #96) | High | shared with #96 | L | Tyre R1 §3.7 |
| NEW-13 | Save/load game flow — client integration | Medium | — | M | Tyre R1 §3.7 |
| NEW-14 | Game session management — start/save/resume flow | Medium | — | S | Tyre R1 §3.8 |
| NEW-15 | Time display on insert HUD | Medium | — | S | Tyre R1 §3.4 |
| NEW-16 | Knowledge/journal display — client (info inventory UI) | Medium | — | M | Tyre R1 §3.11.3 |
Tickets from Design Team Convergence (not mine to spec, but endorsing)
These emerged from design team Round 1 analysis. I'm noting them because they have technical architecture implications, but the design agents should own the specifications:
| Title | Proposed by | Technical note |
|---|---|---|
| Opening hook / first 5 minutes experience design | Gestalt, Ozzie | Content + monologue trigger design, not a systems ticket |
| Observation event pipeline (perception → interpretation → monologue) | Gestalt, Ozzie | Integration glue — may be covered by CauseChain + monologue event wiring |
| Routine deviation detection system | Ozzie | Server-side system: compare NPC position vs expected routine position → generate monologue event. THIS is the core detective mechanic. |
| NPC-to-NPC conversation system | Gestalt | Server-side behavior system with sound events. Important for eavesdropping mechanic. |
| Follow mechanic — track NPC movement with distance/detection | Gestalt | Server-side input action + distance tracking. Required by D-027 criterion 4. |
| Triangle escalation events — observable NPC confrontations | Gestalt, Ozzie, Paula | Depends on #103 (relationship dynamics) and #105 (tolerance thresholds) — both need promotion to HIGH |
| Monologue content pack — separate authoring deliverable | Gestalt | Content volume estimation, not technical architecture |
| Contamination activation mechanic (simplified storyteller) | Gestalt, Ozzie | Even a timer-based trigger needs a system. Promote #162 to at minimum MEDIUM. |
Priority Promotions Endorsed (from design team analysis)
Multiple design agents independently recommended these promotions. I'm endorsing from the technical side because they affect testing priority and system integration:
| Ticket | Current | Recommended | Why (technical) |
|---|---|---|---|
| #103 Relationship dynamics | Medium | High | Required for triangle activation tests, NPC-alive-off-screen tests |
| #105 Tolerance threshold triggers | Medium | High | The only trigger mechanism for triangle escalation — untestable without it |
| #171 Trust-gated gossip | Medium | High | Layer 3 dialogue is where information-boundary testing gets interesting |
| #172 Unprompted disclosure | Medium | High | NPCs volunteering info is a testable integration point (mood + trust + topic) |
| #162 Storyteller module activation | Low | Medium | Even a timer trigger needs a system — without it, no 30-min arc, no contamination |
| #178 Seed-based variation | Low | High | Nigel's argument is compelling: without this, replay ceiling = 2 playthroughs |
Ticket count summary
| Category | Count |
|---|---|
| New hard blocker tickets | 4 (+ 2 promotions) |
| New testability tickets | 5 |
| New soft blocker tickets | 7 |
| Design team tickets (endorsed, not mine) | ~8 |
| Priority promotions endorsed | 6 |
| Total new tickets from Tyre | 16 |
S = Small (1-3 days), M = Medium (3-5 days), L = Large (5-10 days), XS = Extra Small (< 1 day)
Cross-Agent Alignment Summary
Where Hoshe and I now fully agree
| Topic | Status |
|---|---|
| Rust test organization: hybrid | Agreed from Round 1 |
| IPC testing: three-layer architecture | Merged — Hoshe's layers extend my "real IPC" position |
| Godot framework: gdUnit4 | I changed my recommendation after reading Hoshe's comparison |
| Bash wrapper scripts | Agreed from Round 1 |
| No test pollution in production code | Agreed from Round 1 |
| CauseChain as production component | Hoshe proposed, I endorse |
| cargo-nextest for Rust | Agreed from Round 1 |
| #201 promotion to CRITICAL | Hoshe proposed, I endorse |
| Flaky tests are bugs | Agreed from Round 1 |
| JSON as agent output format | Agreed from Round 1 |
Where I extend Hoshe's proposals
- Test priority ordering aligned with design team's hard blocker findings (section 4)
- Monologue pipeline test as highest-value integration test (section 4)
- Test fixture files with pre-generated maps and NPC configs (section 3)
Where the design team changes my thinking
- The monologue system is the critical integration point, not just perception or IPC. Tests should exercise the monologue pipeline early and often.
- Routine deviation detection is a system I hadn't called out in Round 1 — it needs a ticket AND it needs tests from day one.
- The opening hook is a content concern, but it affects WHEN we need content validation tests running.
That's my Round 2 synthesis. Hoshe and I are aligned on all testability decisions. The GUT/gdUnit4 disagreement is resolved in Hoshe's favor. The three-layer IPC architecture is stronger than either of our individual proposals. The design team's findings add content-integration testing as a priority I hadn't fully weighted in Round 1.
The testability decisions are ready for team confirmation. The new tickets are ready for Si to process.
— TYRE