01 · On-prem — at the store
Dashboard connectorconnectors/dashboard
Node/TypeScript + Stagehand. Rides a saved login session on customer hardware, walks the
URL-addressable report views of a retail back-office (site adapters; Loyverse is adapter #1), and runs one
schema-gated LLM extraction per view. Emits sensor.raw@1 to the platform door; a failed schema
is never emitted. Credentials never leave the store.
Screen connectorconnectors/screen
Human-in-the-loop companion UI: the operator shares a tab, the connector narrates it and
extracts the readable numbers. Change-detection gates the model calls.
Edge Perception Unitsrc/LumicIQ.Edge
.NET + ONNX. Per-camera pipeline: YOLO11 detect → ByteTrack → subject aggregation, with CLIP
appearance re-ID carrying identity across track loss. Two doors: a frame door and a continuous H.264/TS stream
door. Emits typed video events + a periodic world-state aggregate, and ships 60-second segments to the cloud
world store for lookback. Model artifacts are SHA-pinned and verified at load. Runs on a store box — or, for
the synthetic twin only, as a cloud Container App.
Producer tokens · fake cameratools/
ES256 token minting scoped per source (the ingress auth for every door), and a camera
stand-in that proves the whole video path without UE5.
Simulation — dev & training
UE5 photoreal store twinsimulator/engine
A digital-twin store: modular kit build, walking shoppers, five virtual cameras producing real
video frames. The visual front half of the simulator.
Twin brain — the world enginesimulator/brain
A standalone .NET world engine (its own solution, deliberately outside the platform build):
scenarios, shopper behaviour, ground truth, batch mode for load, plus the operator control UI. It docks at the
same /ingest/events webhook a real store's sensors use — behind ES256 producer tokens in
cloud — so nothing inside the platform fabricates events (ADR-0010).
Eval harnessessimulator/tools · tools/edge-ml
Model export/exporters, the real-model gate, and the scoring scripts that grade edge world-state
and the video→VLM cascade against the twin's ground truth.
02–03 · Ingress & spine
Adapters — the doorssrc/LumicIQ.Adapters
The one ingress host: the sensor webhook, the video frame + segment-SAS doors, the pull adapters
(OpenWeather, Ticketmaster), and the cloud VLM cascade for stores with no edge box. Dedupes and rate-limits
before publish (over-limit is dead-lettered, never dropped), emits source.heartbeat even when quiet,
and writes the source-health marker the attention gate reads. Every door is a row in the admin-owned Sources
registry — new sources are deploy-free and kill-switchable.
Event Hubs — the spine
Five hubs (events, suggestions-proposed,
suggestions-published, conversations, module-metrics) and nine
variant-scoped consumer groups. ULID eventId is the platform-wide idempotency key; partitioned by
hash(tenant, store).
StateProjectionsrc/LumicIQ.StateProjection
The only writer of current truth. Consumes two hubs on two cursors — the event stream (archive +
hot-state markers) and the suggestion lifecycle. Emit-then-project: it never writes back to the spine.
04–05 · Decide & reason
InterestingnessDetectorsrc/LumicIQ.Interestingness
The learned attention gate and the cost control: per-(store, event type, subject, hour-of-week)
Welford baselines in Redis with a durable Cosmos backing, emitting anomaly and periodic-tick candidates. No
per-tenant configuration — it learns each store's normal.
SafetyNetsrc/LumicIQ.SafetyNet
The deterministic floor: a small set of hardcoded critical conditions, no LLM, plus the one
audited-exempt path in the platform — the templated fallback that fires when the agent is down.
The Agentsrc/LumicIQ.Agent · src/LumicIQ.AgentWorker
A persistent reasoner per (tenant, store). The eight-stage pipeline composes the five context
layers plus a live NOW block, retrieves scoped knowledge, calls tools (knowledge search, state, source health),
validates the model's output, and emits a quantified suggestion — or declines. Writes memory and an immutable
LlmCallRecord for every call.
BFFsrc/LumicIQ.Bff
Hosts the same agent in-process for the solicited path: chat answers streamed over SignalR,
conversation turns published to the spine, and the published-suggestion fan-out to connected clients. Serves the
manager app.
LlmProvider SDKshared/sdks/llmprovider-dotnet
The vendor-agnostic seam (OpenRouter today, a deterministic fake at $0 for gates). Per-task model
routing is data — model hint → store assignment → platform table — with a daily USD budget gate and
spend roll-up behind the console's LLM Control page.
06–08 · Route, deliver, act
Routersrc/LumicIQ.Router
Coalesces proposals, parses the target expression, resolves recipients (Cosmos employees joined
with the Redis roster overlay), walks the tenant's escalation ladder, and durably retries to TTL. It never edits
agent-authored content.
PushDeliverersrc/LumicIQ.PushDeliverer
The real Web Push channel (VAPID), with a durable claim row per (suggestion, user) as the dedup
gate; a delivery cancels the Router's matching fallback timer.
Manager appweb/manager
The shipped mobile-first PWA: suggestion queue, tasks, team, and chat with the store's agent.
Push subscriptions, offline-capable shell, dispositions (acted · dismissed · delegated) back onto the spine.
Admin consoleweb/console
Workspace-scoped admin + monitoring: tenants and stores, access grants, the sources registry,
knowledge (upload, versioning, restore), cameras, the segments explorer, LLM control and LLM observability.
Shared design tokensweb/_design
One token + primitive layer both web clients build on, so console and manager stay one product.
Knowledge & memory
KnowledgeIngestionsrc/LumicIQ.KnowledgeIngestion
Ingests the seed corpus idempotently on start and serves the tenancy-gated document surface:
chunk → embed → index, retire-and-purge on delete.
Knowledge SDKshared/sdks/knowledge-dotnet
Retrieval with scope precedence (platform → enterprise → store) over a pgvector index — the same
engine locally and in Azure. Documents are versioned: immutable snapshots with a current pointer, and retrieval
always reads the current version.
Prompts & seed datashared/sdks/prompts-dotnet · prompts/ · data/
Prompt-as-code with pinned composition ids (recorded on every audit record), plus the vertical
packs, reasoning contexts, layouts, employees and scenarios the seeder provisions.
Operational stores
Cosmos (records, memory, baselines, audit), Redis (hot state, cooldowns, rate limits, dedup
claims, delay queues), Azure SQL (the config registry), Blob (the immutable archive, video frames and segments).
Platform & control plane
Admin hostsrc/LumicIQ.Admin
A separate host from the BFF — the cross-tenant admin posture can't share the BFF's
fail-closed-401 pipeline. Owns tenant/store CRUD, admin grants, the sources registry, the platform knowledge
plane, the recorded-feed reads, and per-door token minting.
IdentityMappersrc/LumicIQ.IdentityMapper
The Entra External ID custom-auth-extension endpoint: at token issuance it resolves the signing-in
user against the SQL registry and returns the lumiciq_* claims the BFF reads (ADR-0006).
Config & registrysrc/LumicIQ.Config
EF Core over Azure SQL: the system-of-record for tenants, stores, users, grants, routing policy,
sources, LLM control and the knowledge-document registry. Migrations run at startup.
Cross-cutting SDKsshared/sdks/
Contracts (the one canonical serializer — wire = Cosmos = audit), Tenancy (fail-closed
ITenantContext), Variants (the resolver behind every variant-namespaced state key), Persistence,
Adapter + Adapter.Abstractions, Seeding.
AppHost & ServiceDefaultssrc/LumicIQ.AppHost
.NET Aspire stands the entire platform — spine, Cosmos, SQL, Redis, Blob, pgvector, every service,
and the twin brain — up on one laptop with Docker emulators; the same manifest publishes 12 Azure Container Apps
via azd, keyless, on managed identity.
Build phase 6 — not built yet
Learning loop
Outcomes → backtest → prompt evolution, shipped as context edits. The substrate it needs is
already there and has been from day one: every LLM call is an immutable, replayable record, and every disposition
is captured. What's missing is the machinery that scores and proposes.
Experiments machinery
The variant resolver and variant-namespaced state exist and are load-bearing today; assignment,
holdouts and readouts on top of them do not.
Further channels
SMS and the earpiece / walkie-talkie endpoint are designed, not built. In-app SignalR and real Web
Push are.
Native mobile client
A React Native client remains a later track; the shipped manager surface is the mobile-first PWA.