# Testability Architecture — D-030 # Three-layer IPC testing, test runner tooling, and phase priorities. vars: { color-bg: "#2a3040" color-stroke: "#333340" color-text: "#c8d0e0" color-accent: "#c8d8f0" color-dim: "#1a1e24" } direction: down runners: Test Runners { style.fill: ${color-dim} style.stroke: ${color-accent} style.font-color: ${color-text} rust_runner: cargo nextest\n(Rust) { style.fill: ${color-bg} style.stroke: ${color-stroke} style.font-color: ${color-text} } godot_runner: gdUnit4\n(Godot) { style.fill: ${color-bg} style.stroke: ${color-stroke} style.font-color: ${color-text} } wrapper: bash wrapper scripts\n(tests/ directory) { style.fill: ${color-bg} style.stroke: ${color-stroke} style.font-color: ${color-text} } } output: Test Output { shape: page style.fill: ${color-dim} style.stroke: ${color-stroke} style.font-color: ${color-text} } ipc_layers: IPC Test Layers { style.fill: ${color-dim} style.stroke: ${color-accent} style.font-color: ${color-text} l1: Layer 1 — Fixture Serialization\nRoundtrip (fast · every edit) { style.fill: ${color-bg} style.stroke: ${color-accent} style.font-color: ${color-text} style.bold: true } l2: Layer 2 — Mock Subprocess Protocol\nState machine (medium · every PR) { style.fill: ${color-bg} style.stroke: ${color-stroke} style.font-color: ${color-text} } l3: Layer 3 — Real Subprocess Integration\n(slow · daily / pre-merge) { style.fill: ${color-bg} style.stroke: ${color-stroke} style.font-color: ${color-text} style.stroke-dash: 4 } } phases: Test Phases { style.fill: ${color-dim} style.stroke: ${color-stroke} style.font-color: ${color-text} ph1: Phase 1 (Sprint 1-2)\nInfra + collision / pathfinding / time { style.fill: ${color-bg} style.stroke: ${color-accent} style.font-color: ${color-text} } ph2: Phase 2 (Sprint 3-4)\nMonologue pipeline + info boundary negatives { style.fill: ${color-bg} style.stroke: ${color-stroke} style.font-color: ${color-text} } ph3: Phase 3 (Sprint 5+)\nCauseChain + divergent snapshots { style.fill: ${color-bg} style.stroke: ${color-stroke} style.font-color: ${color-text} style.stroke-dash: 4 } } constraints: Production Code Constraints { style.fill: ${color-dim} style.stroke: ${color-stroke} style.font-color: ${color-text} c1: No cfg(test) in production code { style.fill: ${color-bg} style.stroke: ${color-stroke} style.font-color: ${color-text} } c2: ECS World setup replaces mock injection { style.fill: ${color-bg} style.stroke: ${color-stroke} style.font-color: ${color-text} } c3: CauseChain = production component\n(monologue provenance + debugging) { style.fill: ${color-bg} style.stroke: ${color-accent} style.font-color: ${color-text} } c4: Deterministic replay (D-010 P4)\nSimulationTime · SimRng · InputQueue injectable { style.fill: ${color-bg} style.stroke: ${color-accent} style.font-color: ${color-text} } } runners.rust_runner -> output: "JSON summary\n+ JUnit XML (CI)" { style.stroke: ${color-stroke} } runners.godot_runner -> output: "JSON summary\n+ JUnit XML (CI)" { style.stroke: ${color-stroke} } runners.wrapper -> runners.rust_runner runners.wrapper -> runners.godot_runner ipc_layers.l1 -> ipc_layers.l2: "gates" { style.stroke: ${color-accent} } ipc_layers.l2 -> ipc_layers.l3: "gates" { style.stroke: ${color-accent} } phases.ph1 -> phases.ph2: "unblocks" { style.stroke: ${color-stroke} } phases.ph2 -> phases.ph3: "unblocks" { style.stroke: ${color-stroke} }