Internal engineering overview: product scope, runtime architecture, module map, contracts, and where to change code. Not a sales deck.
web/creator/ — author playlists, triggers, voices, lexicon, LED layouts, publish to Azure PG.
src/ — always-on runtime: PIS-PT → triggers → TTS/cache → ADT + matrix/FF → proof.
web/ monitor · public/player.html · clients/go · clients/python.
Portal (scripts/dashboard-server.ts) mounts Creator, Monitor, player, docs and decks on one origin.
| Capability | Contract / note | Primary code |
|---|---|---|
| Triggers | 33 built-in + custom + geofence; edge-detect + gates | pis/ptEngine.ts |
| Playlist render | {vars} → MP3 + transcript; priority schedule | engine/playlistRenderer.ts |
| TTS + cache | Pluggable providers; LRU → FS → Azure Blob; single-flight | tts/* |
| Matrix LED | Display→Cycles→Layout; FNT; FF mono/RGB | engine/matrix/*, engine/ff/* |
| Config hot-swap | pg_notify/LISTEN ~1 s; file fallback | config/pgConfigSource.ts |
| Proof of play | Dispatched + engine/played ack | engine/history.ts |
| Dir | Topic | Payload |
|---|---|---|
| IN | {tenant}/{vehicleId}/pis/0/# | Journey / sensors into engine |
| OUT | …/pis/0/tts | ADT 4.x — base64 audio, speakers, traceId |
| OUT | …/display · …/exterior | Interior / exterior bitmaps |
| OUT | …/display/signs · …/**/ff | Matrix frames + raw Mobitec FF |
| ACK | engine/played | Client confirms clip finished |
| OPS | engine/fleet · health · metrics | Dashboard retained views |
Engine and dashboard never call each other privately — MQTT + a small HTTP surface only. Shared payload types: src/shared/payloads.ts.
tsx / tscsrc/index.ts composition rootmqtt/client.tsscripts/dashboard-server.tsMQTT broker · Azure PostgreSQL (config + pg_notify) + Blob cache · TTS suppliers (Azure / ElevenLabs / Acapela) · optional on-disk config fallback.
Never require redeploy for content. Publish path must keep ~1 s hot-swap. Keep file fallback working for edge.
Treat MQTT contract as public API. Prefer additive topic/payload changes. Ack path is required for proof.
Cache keys and FF encoding are fleet-visible. Measure cache hit-rate before changing synth paths.
ARCHITECTURE.md — system truthFUNCTIONAL-SPEC.md — FR list (incl. LED)OVERVIEW.md — product narrativePRESENTATION.html — stakeholder showcasenpm test / engine load scripts before fleet claimsnpm run docsBuild thin clients against MQTT. Keep content out of firmware. Prefer hot-swap over redeploy. Proof requires played-ack. Suite signs are first-class — Matrix/FF belongs in the same pipeline as audio.