Tasks 9.1+9.2: contracts (CapabilityRequest/Result/Provider, PolicyObligation) + service CapabilityBroker that fails closed via opa (PolicyDeniedError, nothing sent), enforces obligations before any provider call (DENY_OUTBOUND/REVIEW → BLOCKED; MASK/REDACT → mask payload field), then routes to a CapabilityProviderRegistry (SandboxProvider default; env-gated HttpProvider overrides per channel; unknown channel fails closed). 5 tests: allow/deny/block/redact/unknown-channel. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
18 KiB
IIOS — Insignia Interaction OS
Phase-by-phase overview · who uses what · a real build (Yamuna Expressway support)
A plain-language walkthrough of everything built so far (P0 → P8), the SDKs each phase produced, who consumes them, and a worked example of building an Intercom-style support experience for the Yamuna Expressway portal on top of it. Written to be read top-to-bottom in ~10 minutes.
1. What IIOS is, in one paragraph
IIOS is one backend and a family of small SDKs that treat every interaction — a chat message, a support ticket, a routed community post, an AI suggestion, a scheduled meeting — as the same underlying object (an "Interaction") sitting inside a tenant scope, behind the same safety gates (who's allowed, whose consent, what policy), and emitting the same audit trail. Instead of building a chat app, then a separate ticketing app, then a separate meetings app — each with its own identity, permissions, and audit — we built the shared core once and then "earned" each product capability as a thin specialization on top. The result: a WhatsApp-community manager, a customer-support console, and a meeting assistant are the same system wearing different hats.
Why a CEO should care: every new product surface (support, community, meetings, AI) reuses the same identity, permission, consent, and audit spine — so each new capability is faster to ship and safe by construction, not safe by remembering to add checks. That's the moat.
2. The one big idea (and three rules that make it safe)
- Everything is an Interaction. A message is an artifact of an interaction; so is a ticket, a route decision, an AI summary, a meeting. One data spine, one audit log.
- Kernel + specializations. A tiny kernel (identity, scope, threads, events) is the foundation. Messaging, inbox, support, routing, AI, meetings are specializations that import the kernel — never the other way around. A build check (
pnpm boundary) enforces this so the layers can't rot into spaghetti. - Three safety rules baked in everywhere:
- Fail-closed — if the policy/consent check is unavailable or says no, nothing is written. Never an accidental "allow."
- Replayable & idempotent — the same event processed twice produces one result, so nothing double-charges, double-sends, or double-books.
- Preview / propose before act — risky things (forwarding to a group, AI decisions, recording a meeting) are previewed or proposed, and a human or a deterministic rule is the gate. AI can suggest; it never decides.
Today the external world (real WhatsApp, real AI models, real calendars, the real policy engine) is faked with deterministic stand-ins so we could build and prove the whole system offline. Turning those fakes real is the final phase (P9). This is the single most important framing for the CEO: the engine and all the product SDKs are built and demonstrable end-to-end; what remains is wiring them to real external providers and hardening for scale.
3. The phases at a glance
| Phase | Capability | SDK / package produced | Who uses it | Live demo |
|---|---|---|---|---|
| P0–P1 | Kernel — identity, tenant scope, threads, events, fail-closed gates | iios-contracts, iios-testkit, iios-service (kernel) |
Foundation for everything (no direct end-user) | — |
| P2 | Native messaging — threads, messages, read receipts, unread counts, realtime | iios-message-web |
Any chat UI (customer↔agent, member↔member) | message-demo (5173) |
| P3 | Inbox — "needs reply / needs review" work queue | iios-inbox-web |
Agents & admins triaging work | message-demo sidebar |
| P4 | Support — tickets, queues, agent availability, escalation, callback | iios-support-web |
Support agents + customers asking for help | agent-demo (5174) |
| P5 | Adapters — inbound webhooks (signed), outbound send (sandbox), delivery tracking | iios-adapter-sdk |
Integration engineers connecting channels | adapter-inspector (5175) |
| P6 | Routing / rules — forward messages between groups, preview-first, deny-by-default | iios-community-web |
Community moderators / admins | route-admin (5176) |
| P7 | AI proposal layer — classify, summarize, extract; budget-governed; propose-never-decide | iios-ai-web |
Any surface wanting AI assist (human-gated) | ai-studio (5177) |
| P8 | Calendar & meetings — schedule, attendee consent, transcript, summary, action items | iios-meeting-web |
Support/scheduling; callback→meeting | meeting-studio (5178) |
| P9 | (next) Production hardening — real providers, real policy/consent, scale, retention | — | Ops / platform | — |
All of it runs on one NestJS service (iios-service) with one Postgres database (46 tables across 9 migrations), fronted by one low-level client (iios-kernel-client) that every React SDK is built on.
4. Phase by phase — what it does, who uses it, a real example
P0–P1 · The Kernel (the foundation)
What it adds. The vocabulary everything else speaks: a Scope (which org/tenant/app an interaction belongs to), a SourceHandle → ActorRef (turning "a WhatsApp number" or "a portal login" into a known actor), Threads and Interactions, a transactional outbox (every state change writes a business row and an event in the same transaction), and the fail-closed policy gate.
SDKs. iios-contracts (the shared types, event names, and the platform-port interfaces), iios-testkit (deterministic fakes of the platform: session, policy/OPA, consent/CMP, identity/MDM, context, tokenization, capability broker), and the kernel inside iios-service.
Who uses it. Nobody directly — it's the bedrock. Every other phase depends on it.
Real example. A message arrives from WhatsApp number +9198…. The kernel resolves it to an actor within the Yamuna org's scope (not globally — no cross-tenant leaks), checks policy (fail-closed), and writes both the interaction and a interaction.normalized event atomically. If the policy check had been down, nothing would be written — no silent half-writes.
P2 · Native messaging — iios-message-web
What it adds. Real chat: open a thread, send a message, delivery/read receipts, unread counters, and realtime delivery over websockets.
Who uses it. Any user-facing chat surface — a customer chatting with support, two members chatting, an agent replying.
Real example. A Yamuna plot-buyer opens the portal's chat widget and types "When is my next payment due?" — that's a thread + message via iios-message-web; the agent sees it live, replies, and the buyer's unread count updates instantly. Demo: message-demo (5173).
P3 · Inbox — iios-inbox-web
What it adds. Turns raw messages into a work queue. When a message needs a human, an inbox item ("needs reply") is created for the right owner, with a state machine (open → done/snoozed/archived). Built by a projector reacting to message.sent — so the queue is always consistent with what was actually said.
Who uses it. Agents and admins who triage: "what's waiting on me?"
Real example. The buyer's "payment due?" message auto-creates a needs-reply item in the assigned agent's inbox; once the agent replies, it auto-resolves. No message silently falls through the cracks. Demo: the inbox sidebar in message-demo.
P4 · Support — iios-support-web
What it adds. The support product: tickets, queues, agent availability (go online/offline), assignment (least-loaded agent), escalation (customer ↔ support thread), and callback requests. This is the Intercom-shaped layer. Who uses it. Support agents (a dashboard) and customers (a "get help / request callback" widget). Real example. The buyer clicks "Talk to support." A ticket is created, auto-assigned to an available agent, and a dedicated customer↔agent thread opens. If it needs a phone follow-up, the buyer requests a callback — which later becomes a meeting (see P8). Demo: agent-demo (5174).
P5 · Adapters — iios-adapter-sdk
What it adds. The bridge to the outside world: inbound provider webhooks are signature-verified (HMAC), normalized into kernel interactions, and outbound replies go through a sandbox sender with delivery-attempt tracking and rate limiting. Channels modeled: WEBHOOK, EMAIL, WHATSAPP, PORTAL. Who uses it. Integration engineers who connect a new channel; the service uses it to ingest/emit. Real example. A WhatsApp message to the Yamuna business number hits the webhook adapter → verified → becomes the same kind of interaction as a portal chat, so support handles WhatsApp and web chat identically. Replies are recorded but sandboxed (no real send yet — that's P9). Demo: adapter-inspector (5175).
P6 · Routing & rules — iios-community-web
What it adds. Community message routing: route bindings (from origin → destination), a preview-first simulator that shows exactly what would be forwarded and to whom (with reason codes) without sending, decisions of ALLOW/DENY/REVIEW, deny-by-default for restricted audiences (e.g. a children's group), and admin approve/deny. Automatic routing only for explicitly safe rules. Who uses it. Community managers / moderators (WhatsApp-community use case). Real example. In a residents' community, an "after-hours party at 9 PM" post is flagged and routed to REVIEW for adults and DENY for the kids' group — a moderator approves before anything is forwarded. Nothing leaks by accident. Demo: route-admin (5176).
P7 · AI proposal layer — iios-ai-web
What it adds. AI that only proposes: classify (moderation flags), summarize, extract (candidate events/FAQ) — each output carries confidence, evidence citations, model/cost, and an abstention reason. A budget governor caps spend; the pipeline fails closed; and an AI flag can only push a routing decision toward REVIEW/DENY — never auto-approve. AI suggests; a human accepts. Who uses it. Any surface wanting assistance — support-reply drafts, meeting summaries, community moderation hints. Real example. The support agent gets an AI-drafted reply and a one-line summary of a long buyer thread; a community post is auto-classified so the moderator sees "flagged: after-hours event" with the evidence. The agent/moderator always makes the call. Demo: ai-studio (5177).
P8 · Calendar & meetings — iios-meeting-web
What it adds. Turns a callback into a real meeting: schedule + attendees, per-attendee recording consent, transcript, AI summary (reuses P7), and action items that flow back into the inbox. The safety spine: no transcript/summary/action-item exists until every attendee consents (and attendees marked "no visibility" are excluded from follow-ups). Meetings can also be born from an accepted AI-extracted event. Who uses it. Support/scheduling flows; anyone turning a conversation into a scheduled follow-up. Real example. The buyer's callback becomes a scheduled call. Both sides grant recording consent → the call is transcribed and summarized → "send revised payment schedule" becomes an action item in the agent's inbox. If the buyer declines recording, no transcript is ever created. Demo: meeting-studio (5178).
5. The SDK catalog — who consumes what
Think of it as three tiers:
Tier 1 — Foundation (engineers, not end-users)
iios-contracts— shared types, event catalog, platform-port contracts. Everything imports this.iios-testkit— deterministic fakes + fixtures. Used by tests/QA to prove behavior offline.iios-service— the single backend API (NestJS) that contains every module (kernel, messaging, inbox, support, adapters, routing, ai, calendar).iios-kernel-client— the low-level REST + websocket client. Every React SDK is built on top of it; advanced apps can use it directly.iios-adapter-sdk— for authoring channel adapters (normalize + HMAC verify + sandbox send).
Tier 2 — Product React SDKs (front-end teams building app surfaces)
iios-message-web— chat.iios-inbox-web— work queue.iios-support-web— tickets/escalation/callback/agent-availability.iios-community-web— routing rules + approvals.iios-ai-web— AI proposals + accept/reject.iios-meeting-web— scheduling + consent + summaries.
Tier 3 — Demos (proof surfaces, one per capability)
- message-demo, agent-demo, adapter-inspector, route-admin, ai-studio, meeting-studio.
Each product SDK is a handful of React hooks — a front-end dev wires the UI, the SDK handles auth, data-fetching, realtime, and talking to the one backend.
6. The worked example: an Intercom-style support experience for Yamuna Expressway
The goal: a plot-buyer in the Yamuna portal can chat with support, get AI-assisted answers, escalate to a human, and book a callback — and agents work it all from one console. (Yamuna already has the shell: a support-live widget, a support-token endpoint, and an assistant panel — currently pointed at the older support-service. IIOS is the upgrade path.)
How it maps onto what we've built:
| Intercom-style feature | Built on | Status today |
|---|---|---|
| Customer chat widget in the portal | iios-message-web (P2) |
✅ works now (in-portal, realtime) |
| "Get help" → ticket + route to an agent | iios-support-web (P4) |
✅ works now |
| Agent console (queue of conversations) | iios-inbox-web + iios-support-web (P3/P4) |
✅ works now |
| AI-suggested replies + thread summary | iios-ai-web (P7) |
✅ works now (deterministic AI; real model = P9) |
| Escalate to human / assignment / availability | iios-support-web (P4) |
✅ works now |
| Request a callback → book a meeting → notes/action items | iios-meeting-web (P8) |
✅ works now (sandbox) |
| Also answer the buyer on WhatsApp/email, not just portal | iios-adapter-sdk (P5) |
◐ modeled + sandboxed; real send = P9 |
| Real AI answers from a real model | iios-ai-web + Capability Broker |
◐ deterministic stand-in today; real model = P9 |
Do we have everything to build it now?
- For in-portal live support (web chat between buyer and agent, tickets, escalation, AI-assist, callback→meeting): yes — today. Every piece exists as an SDK against one backend. This is a buildable, demoable product right now, entirely inside the Yamuna portal, with no external providers required (portal chat rides the kernel + websockets).
- For true omnichannel (the same conversation over WhatsApp/email) and real AI answers: not yet — that's P9. The adapters and AI layer are built and proven with sandbox/deterministic stand-ins; P9 swaps in the real WhatsApp Business Platform, a real LLM via the Capability Broker, and the real policy/consent engines.
So the honest one-liner for the CEO: "We can build Yamuna's in-portal support product on IIOS today; making it answer on WhatsApp and with a real AI model is the next phase (P9). The whole thing already runs end-to-end locally with safety, consent, and audit built in."
Concrete build path for Yamuna (all with existing SDKs):
- Point the portal's
support-tokenendpoint atiios-service's dev/session token. - Buyer widget:
MeetingProvider-styleMessageProvider+useThread/useSendMessage(message-web) for chat;useCreateTicket/useRequestCallback(support-web) for "talk to a human." - Agent console:
useInboxItems(inbox-web) + support-web queue/availability/assignment;useRunJob/useAiProposals(ai-web) for draft replies & summaries. - Callback →
useSchedule+ consent +useSummarize(meeting-web) to run and capture the call. - Later (P9): register a real WhatsApp adapter so the same conversations arrive from WhatsApp, and swap the deterministic AI for a real model.
7. What's real vs. simulated today (say this plainly)
| Area | Today | Becomes real in |
|---|---|---|
| Core engine, identity, scope, audit, events | Real | — |
| All 8 product capabilities (chat→meetings) | Real logic, proven by tests + demos | — |
| Outbound to WhatsApp/email | Sandbox (recorded, not sent) | P9 |
| AI answers | Deterministic golden model (no real LLM) | P9 |
| Policy / consent / identity resolution | Faked deterministic ports | P9 |
| Calendar/Zoom providers | Simulated sync | P9 |
| Multi-tenant scale, retention, SLOs | Not yet | P9 |
Proof it works: 95 automated tests pass; every capability has a runnable demo and an end-to-end smoke script; the layer-boundary check enforces the architecture.
8. What to actually show in the room
- message-demo (5173) — two people chat in realtime; a needs-reply item appears in the inbox. "This is the chat + work-queue spine."
- agent-demo (5174) — a customer escalates; a ticket auto-assigns to an agent. "This is support."
- ai-studio (5177) — run classify/summarize on a message; see confidence + evidence; accept a proposal. "This is AI that proposes, never decides."
- meeting-studio (5178) — schedule a meeting; try to transcribe without consent (blocked), grant consent (works), get a summary + action items. "This is consent-safe meetings."
- route-admin (5176) — simulate forwarding a flagged post; watch it deny to the kids' group. "This is safe community routing."
Narrative arc for the CEO: one engine → chat → inbox → support → channels → community routing → AI → meetings, each a small SDK, each safe by construction, all demonstrable — with P9 (real providers + scale) as the clearly-scoped remaining work.
Appendix — repo facts: 11 packages, 6 demo apps, one NestJS service, 46 Postgres tables across 9 migrations (kernel → messaging → inbox → support → adapters → routing → ai → calendar). Boundary-enforced dependency law; 95 passing tests; 7 end-to-end smoke scripts.