This technical blog post is written as part of the **Kiroween 2026 Hackathon* (
ResurrectionCategory +Best Startup Project+Best Demo).*
- Live Control Tower Demo: https://blog.gggodlin.com/kiroween-signal-box/
- Public GitHub Repository: https://github.com/GGGODLIN/kiroween-signal-box
- Devpost Submission: https://devpost.com/software/kiroween-signal-box
- 45s Launch Film: https://youtu.be/qXKqfpr7NzE
1. The Problem: Concurrent AI Coding Agents Colliding on Shared Tracks
When engineering teams run multiple autonomous AI coding agents in parallel—a Builder agent editing application code, a Migrator agent altering database schemas, a Deployer agent pushing releases, and a Verifier agent running integration audits—agents routinely collide on shared resources. Even worse, traditional example-based unit tests only test a handful of happy paths and miss multi-step interleaving bugs where two agents acquire conflicting locks after 8 or 10 steps.
In 1856, Victorian railway engineer John Saxby solved this exact mutual-exclusion problem for steam locomotives using the Mechanical Tappet Interlocking Frame: a physical bed of perpendicular steel locking bars beneath brass levers controlling track points, facing point locks (FPL), and semaphore signals. Before a signalman could clear a signal, the steel tappets physically blocked any conflicting lever pull.
For Kiroween 2026, we built Signal Box (LeverFrame) to resurrect Saxby & Farmer's 1856 Victorian mechanical interlocking frame as a deterministic, MCP-enabled mutual-exclusion control tower for parallel AI agents—specified and verified end-to-end with Kiro.
2. How Kiro Transformed Our Development Workflow
A. Spec-Driven Development (/.kiro/specs/) vs. Vibe Coding
If you try to "vibe code" an 8-lever railway interlocking frame with 6 track blocks, crossover points, facing point locks, and back-locks, an LLM will inevitably conflate the locking rules with the state transitions or forget symmetric reverse locks.
Using Kiro's Spec-Driven Development (/.kiro/specs/lever-frame/requirements.md, design.md, and tasks.md), we first expressed all 8 mechanical interlocking invariants in formal EARS (WHEN ... THE SYSTEM SHALL ...) syntax:
-
EARS-ILK-01: WHEN Lever #1 (North Up Home Signal) is pulled to REVERSE, THE SYSTEM SHALL require Lever #2 (Junction Crossover) at NORMAL and Lever #3 (Facing Point Lock) at REVERSE, and SHALL mechanically lock Levers #2, #3, #4, and #6. -
EARS-ILK-04: WHEN Lever #4 (South Branch Home Signal) is pulled to REVERSE, THE SYSTEM SHALL require Lever #2 at REVERSE and Lever #3 at REVERSE, preventing simultaneous occupation ofjunction-throatandschema-bridge.
Having requirements.md and design.md pinned in /.kiro/specs/ meant Kiro generated the exact tappet locking matrix (src/lib/interlocking.ts) with traceable EARS rule IDs on every single lock rejection.
B. Steering Docs (/.kiro/steering/): Enforcing SUT vs. Independent Oracle Separation
A classic failure mode in AI-generated tests is tautological testing—where the test copies the implementation's own helper function to compute the expected result.
We used Kiro Steering Docs (/.kiro/steering/product.md, tech.md, structure.md) to enforce a non-negotiable architectural boundary:
- System Under Test (
getInterlockPreset): Evaluates the lever-to-lever tappet locking matrix (STANDARD_SAFEvs. the fault-injectedCURSED_MISSING_CROSSOVER_LOCKpreset). - Independent Physical Topology Oracle (
evaluatePhysicalTopology): Completely decoupled frompresetIdand lever rules; it inspects only the physical track-block occupancy (north-approach,south-branch,junction-throat,schema-bridge,prod-mainline,audit-siding) and switch geometry after every step:-
P1_NO_CONFLICTING_ROUTES: No two active signals may ever occupy overlapping physical track blocks simultaneously. -
P2_SIGNAL_POINT_LOCK_INTEGRITY: Every active signal must have its required points aligned and facing point locks plunged.
-
C. Stepwise Property-Based Testing (PBT) Exorcist (src/lib/pbt-exorcist.ts)
Kiro's emphasis on Property-Based Testing (PBT) is where Signal Box shines. Instead of checking only final states or filtering out invalid inputs with fc.pre(), our runInterlockingExorcism(presetId) runner generates arbitrary sequences of lever pulls and releases via fast-check and asserts P1 and P2 after every individual step:
- On
STANDARD_SAFE: 80 randomized multi-step runs (461 stepwise assertions) pass with0violations and verified reachability witnesses (clearedSignalCount: 19,blockedInterlockCount: 100). - On
CURSED_MISSING_CROSSOVER_LOCK(which simulates a subtle bug whereEARS-ILK-01forgets to lock out Signal #4 across the throat):fast-checkcatches the physical train/agent collision on["junction-throat", "schema-bridge"]inside an 11-step sequence and automatically shrinks it to a minimal 3-step counterexample (3.67xreduction):-
{ leverId: 3, intent: "PULL" }— Engage Facing Point Lock #3 -
{ leverId: 1, intent: "PULL" }— Clear North Up Home Signal #1 (Builderentersjunction-throat&schema-bridge) -
{ leverId: 4, intent: "PULL" }— Clear South Branch Signal #4 (Migratorcollides onjunction-throat&schema-bridgeatfailingStepIndex: 2).
-
D. Kiro Agent Hooks (/.kiro/hooks/) & MCP Server (POST /api/mcp)
We wired Kiro Agent Hooks (/.kiro/hooks/verify-interlocking-pbt.json) so that any edit to src/lib/interlocking.ts or /.kiro/specs/ automatically triggers the fast-check PBT Exorcist and blocks regressions before commit.
Finally, we exposed the interlocking frame as a deterministic Model Context Protocol (MCP) tool surface (request_route, release_route, inspect_interlock, run_pbt_exorcism at POST /api/mcp), allowing a crew of AI coding agents to request and release physical track clearances with zero race conditions.
3. Try It Yourself
- Interactive Web Control Tower: https://blog.gggodlin.com/kiroween-signal-box/ — Pull brass levers, hear the WebAudio mechanical tappet latches, switch to the
CURSED_MISSING_CROSSOVER_LOCKpreset, and step through the 3-step shrunk counterexample replay. - Source Code &
/.kiroSpecs: https://github.com/GGGODLIN/kiroween-signal-box




