Experience Architecture — the chat-first journey
How an everyday user drives insigz by prompting, with the chat as the command surface and interactive widgets completing tasks in place.
Files:
analyst-chat.jsx(the chat surface + the seed listener) ·app-chat-host.jsx(onCommit→ stores,onCanvas→ spatial pop-outs) ·app-chat-prompts.jsx(the widget engine, the six-step prompts, theJourneyRail) ·app-onboarding.jsx(the Door-2 first-run wizard) Doctrine: the human-commit gates (Q8/Q9/Q10) render as inline buttons, not separate pages — chat-first does not weaken the rigor. Couples to: every surface in §4, the agents in §5, the autonomy layer in §13, the network in §14, Pattern of Life in §15.
Files 00–15 describe a capable platform. This file describes how an everyday user drives it: the chat is the command surface, and the user does almost everything by prompting. The AI replies with interactive widgets that complete the task in place. The user only leaves the chat to look at something spatial. The deep machinery (canonical model, resolution, provenance, doctrine gates) stays in the engine room and surfaces on demand.
The one rule: verbs in chat, nouns on canvas
- Chat = verbs. Anything the user does or decides — set up a project, upload data, ask a question, open a case, draft a report, set a watch, accept a flag, start a wargame — happens as a widget inside the conversation. No page navigation required.
- Canvas = nouns you must see. The live map (
/explore), the entity network (/network, §14), the activity timeline (§15) and the wargame arena are full-screen visual surfaces. You pop out to look, then return to the chat to act.
Forms, approvals, drafts, configs and decisions are widgets; spatial exploration is a canvas.
The two doors
- Door 1 — the Analyst Journey (default). Chat-first, with the six-step journey rail (Set up → Upload → Ask → Cases & Reports → Watchers → Wargame) in the chat panel header. The rail is a map, not a wizard cage — ignore it and just talk.
- Door 2 — the Expert Back Office. The full surfaces (source-onboarding wizard §6, Analyst Studio + Trust Evals §13, Workshop + AAR §7, settings). Reached from Settings / org tools, role-gated.
- The escape hatch (non-negotiable). Every chat widget carries an "open the full view →" link (
openFull) to its Door-2 surface. The chat is the fast path, never a trap.
The widget engine (app-chat-prompts.jsx)
A reply can carry a widget of one of three kinds, rendered inline by ChatActionWidget. Every kind also renders the openFull escape hatch.
{ "kind": "launch | form | decision", "icon": "…", "title": "…", "desc": "…",
"openFull": { "route": "/projects", "label": "Open the full setup →" },
// launch — the ONLY widget that leaves the chat: canvas pop-out or deep-link
"launch": { "targets": [ { "target": "map|graph|arena|timeline|navigate", "route": "…", "focus": "VESSEL-SF12", "label": "⟢ SHOW ON GRAPH" } ] },
// form — prefilled editable fields; submit commits via the real store, in place
"form": { "fields": [ { "key": "name", "label": "PROJECT NAME", "value": "…", "type": "text|select", "options": [] } ],
"submit": "createProject", "confirm": "Create project", "launchAfter": "/cases", "successMsg": "…" },
// decision — a doctrine gate as buttons
"decision": { "gate": "Q8|Q9|Q10", "summary": "…", "actions": ["accept","modify","explain","show_logic"],
"grounding": { "reasoning": "…", "observations": ["OBS-50412"] },
"commit": "decideProposal", "payload": { "id": "LATEST" }, "launchAfter": "/sources/onboard" }
}launch— go look at a canvas (onCanvas(target, focus)) or navigate (onNavigate(route)), then return.form— on submit calls the same store method a Door-2 surface would (onCommit(method, payload)), then shows a ✓ success line;launchAfteroptionally pops to the result.decision— the approve-the-mapping / accept-the-flag gate. Accept / Modify commit viaonCommit; Explain expands the rationale; Show Logic reveals the cited[OBS-####]chips — the four Proposal-Inbox actions (§13), reused verbatim. This is how Q8/Q9/Q10 render in a chat-first world: as buttons, not pages.
Legacy single deep-link widgets are normalised into a launch widget, so nothing older breaks.
The host callbacks (app-chat-host.jsx)
Alongside onNavigate, the host threads two callbacks into AnalystChat (all three panel modes — side panel, mobile sheet, fullscreen):
onCommit(method, payload)— dispatches to the real stores:createProject(useProjects),addCase/addReport(useCaseStore),saveWatch/decideProposal(useData, §13). Same write path as the back office, so chat and Door-2 can never diverge; fires the standard toast.onCanvas(target, focus)— pops out spatially:map→ fly the/explorebasemap (window.__insigzMap.flyTo);graph→/network+insigz:network-focusto select the node (§14);timeline→/networktimeline view;arena→/sessions.
The six steps as widgets
| Step | Prompt | Widget | Inline gate | Commit |
|---|---|---|---|---|
| 1 · Set up | "Set up a new project" | form (name · blueprint · region) | — | createProject (real) |
| 2 · Upload | "Upload data and map it to the model" | decision (approve mapping) | Q9 | stages, then launches the wizard |
| 3 · Ask | "Where has SHADOW STAR been dark?" | grounded answer + launch (Show on map / graph) | — | canvas pop-out |
| 4 · Cases & Reports | "Open a case…" / "Draft a report…" | form | — | addCase / addReport (real) |
| 5 · Watchers | "Watch for dark loiters…" / "Review the latest flag" | form then decision | Q10 | saveWatch / decideProposal (real) |
| 6 · Wargame | "Set up a Baltic cable-cut Strategy Day" | form (scenario) | — | stages, then opens the arena |
The pattern is uniform: prompt → widget → (optional inline approve) → done, without leaving the chat — except step 3's map/graph buttons and step 6's arena, which are canvases.
The journey rail (JourneyRail)
A slim, dismissible six-step strip inside the chat panel header. It reflects the active project's state (a ✓ on Set up if a project exists, Upload if sources are connected, Cases if any exist, Watch if any watches exist, Wargame if the project has sessions) and, on click, drops the matching prompt into the chat via handlePrompt — never a separate wizard. The Wargame step only shows on wargame-shaped projects. The prompt-library category chips are the same six steps.
The seed mechanism is loose: AnalystChat listens for insigz:chat-seed-prompt { text }, matches a CHAT_PROMPTS entry, and runs it — so any surface (not just the rail) can drive the chat.
Doctrine fit
| Principle | How chat-first preserves it |
|---|---|
| Q8 — AI supports, never decides | Customer-facing / irreversible steps are decision widgets with an explicit human button (publish, approve). The AI drafts into the card; the human commits. |
| Q9 — agent-drafts, human-commits (onboarding) | The Upload card shows the agent's mapping as a plain-English summary with Accept; field-level control is one "open the full wizard →" away. |
| Q10 — bounded, reversible autonomy | Watch flags arrive as decision cards (Accept / Modify / Explain / Show Logic); only internal, reversible outputs auto-apply, exactly as §13. |
| Grounding | Answers stream with [OBS-####] chips that open the provenance drawer; "show on map/graph" is the canvas pop-out. Nothing is asserted without a citation. |
Making the front simple does not loosen any gate — the gates move from pages to buttons; the human still commits, the trail is still written.
Canonical-model fit
This adds no new data. It is a presentation-and-orchestration layer over the existing model and stores; the chat orchestrates the same reads/writes a Door-2 surface would. The only new objects are ephemeral UI widgets.
Prototype boundary
Real now: the verbs-in-chat / nouns-on-canvas rule; the three widget kinds rendered inline; widgets committing through the real useProjects / useCaseStore / useData stores; the four decision actions reused from the Proposal Inbox; canvas pop-outs to map (/explore), network (/network, focused) and arena (/sessions); the six-step JourneyRail reflecting project state; the escape hatch on every widget; the insigz:chat-seed-prompt seam. Deferred: the production agent that decides which widget to emit for an arbitrary free-text prompt (the prototype uses the prompt-library mapping + intent patterns); rich in-chat editing for large drafts (those still open the full editor); and the backend swap noted in §13 — once ApiDataLayer lands, every widget action already points at it.
Pattern of Life — baselines, anomalies & early warning
Pattern of Life plots an entity's activity over time against its normal range and flags the moments it leaves that range, feeding Standing Watches.
The Control Plane — insigz Control (platform-owner console)
The backstage console platform owners use to run the fleet of single-tenant instances, handling provisioning, billing, support, and maintenance.