Orchestrata Ultimate / Specs / 016-vizint-command-center

016-vizint-command-center: VizInt Command Center

The VizInt Command Center is the unified dashboard and personal command center for Orchestrata. Built on the VizInt gadget portal framework (cloned at vizint-ui/), it provides a single browser-based interface where the user can observe, control, and interact with the entire orchestration system in real-time. The Command Center connects to Orchestrata via the SPEC-014 WebSocket Gateway (JSON-RPC 2.0 over WebSocket), presenting every orchestration feature as a composable gadget. The system...

At a glance

Item Value
Spec directory specs/016-vizint-command-center/
Status line in the spec Implemented (Core) + Gadgets Implemented
Requirement IDs defined 294
With a @traces citation in src/ 38 (12.9%)
With a @traces citation in tests/ 0 (0.0%)
Tracked files 6
RTM page 016-vizint-command-center

Reading this spec

The VizInt Command Center is the unified browser dashboard and personal command center for Orchestrata. Built on the VizInt gadget portal framework, it gives one interface to observe and control the orchestration system in real time, with every orchestration feature presented as a composable gadget. It connects through the WebSocket Gateway of spec 014. Before it, all interaction happened through the CLI or code, and the gateway's real-time data had no consumer.

The scope is fourteen user stories: a project dashboard, session management, a real-time CXP feed, a Volk status panel, Claude chat, a task and goal board, a QA dashboard, an audit trail viewer, a notification center, and gateway session and project handlers (priority 1), plus a knowledge graph explorer, personal productivity gadgets, and theme and layout customization (priority 2). Requirement IDs use the REQ-016- prefix.

The design is stated precisely. The portal runs in the browser as static HTML, JS and CSS with zero-build ES modules. A CommandCenterApp bootstraps five subsystems: a WebSocket bridge, a gadget bridge, state sync, a notification manager and a gadget registry. The gadget bridge translates between local events and gateway JSON-RPC 2.0 calls across five namespaces: session.*, cxp.*, volk.*, knowledge.* and governance.*. State sync replaces localStorage-only persistence with gateway-backed synchronization, debounced at 500ms with last-write-wins conflict resolution. Gateway handlers provide Neo4j-backed async queries with 10 second timeouts.

In the code, the server side is in the gateway handlers: orchestrata_ultimate/gateway/handlers/session, orchestrata_ultimate/gateway/handlers/_session_kg, orchestrata_ultimate/gateway/handlers/projects and orchestrata_ultimate/gateway/handlers/cxp, plus orchestrata_ultimate/knowledge_graph/query_engine. The browser gadgets are JavaScript and are not covered by the Python trace table. The per-requirement view is on the RTM page.

The spec's status line reads Implemented (Core) + Gadgets Implemented. It tracks 6 files and defines 294 requirement IDs. The full text follows below.

Measured coverage is 38 of 294 requirements cited by at least one @traces in src/ (12.9%), spread over 14 modules; the module citing the most of them is orchestrata_ultimate/gateway/handlers/session (8 requirements). In tests/, 0 requirements are cited by a test-side @traces.

Coverage gaps: 256 requirements have no citing symbol. The largest untraced groups are REQ-016-* (256). Untraced means no @traces names the ID; the behaviour may still exist in code that was never annotated. Test-side citations are thinner than code-side ones (0 against 38).

Requirements

Checkbox is the state recorded in the requirements checklist; Traced by is the count of src/ symbols whose @traces names the ID.

ID Done Requirement Traced by
REQ-016-001 yes ProjectExplorer gadget queries knowledge.nodes for the Project node on mount none
REQ-016-002 yes Gadget displays project name, version, description from Project node properties none
REQ-016-003 yes Gadget displays aggregate counts: total files, total classes, total functions, total LOC none
REQ-016-004 yes Gadget displays session summary: total sessions, active sessions, last session date none
REQ-016-005 no Gadget displays iteration summary: total iterations, last iteration number, gap trend none
REQ-016-006 no File tree populated via knowledge.nodes RPC with node_type=File and pagination 1
REQ-016-007 no File tree shows directory hierarchy with expand/collapse toggles none
REQ-016-008 no File tree supports keyword search with real-time filtering (debounced 300ms) none
REQ-016-009 no Each file entry shows: name, path, class count, function count none
REQ-016-010 no Click on file navigates to KGExplorer gadget with file-scoped context none
REQ-016-011 yes KG summary displays counts by node type: File, Class, Function, Session, Iteration, Spec none
REQ-016-012 no Each count displayed with sparkline trend (last 20 data points) none
REQ-016-013 no KG summary auto-refreshes every 60 seconds via gateway subscription none
REQ-016-014 no Click on node type count opens KGExplorer filtered to that type none
REQ-016-015 yes Recent sessions list (last 10) with: id, date, status badge, duration, achievements none
REQ-016-016 no Status badges: active (green pulse), closed (grey), error (red) none
REQ-016-017 no Recent iterations list (last 10) with: number, date, gap count, pass/fail indicator none
REQ-016-018 no Click on session row opens SessionManager gadget with that session selected none
REQ-016-019 no Click on iteration row opens IterationBrowser gadget with that iteration selected none
REQ-016-020 no Project metrics refresh on session.events and kernel.events subscriptions none
REQ-016-021 yes SessionManager gadget calls session.list on mount to find active session none
REQ-016-022 yes Active session displayed with: id, goals, portfolio, duration (live timer), status none
REQ-016-023 yes Session context displayed: current work description, recent achievements none
REQ-016-024 yes Session facts displayed as a scrollable list (last 50 facts) none
REQ-016-025 yes "No active session" placeholder shown when no session is active none
REQ-016-026 yes "Start Session" button opens dialog: goals (text area), portfolio (dropdown), purpose (text) none
REQ-016-027 yes Start Session sends session.open RPC with user-provided parameters none
REQ-016-028 yes Start Session button disabled when a session is already active none
REQ-016-029 yes "Close Session" button opens dialog: summary (text area), carryover tasks (checklist) none
REQ-016-030 yes Close Session sends session.close RPC with summary and carryover none
REQ-016-031 yes Close Session button disabled when no session is active none
REQ-016-032 yes Session open/close results displayed as success/error toast notification none
REQ-016-033 no Deferred work items displayed in a prioritized list (critical > high > medium > low) none
REQ-016-034 no Each item shows: description, priority badge, status, session added, notes none
REQ-016-035 no "Add Item" button opens inline form: description, priority dropdown, notes none
REQ-016-036 no Click on item opens inline editor for description, priority, and notes none
REQ-016-037 no "Mark Done" button on each item updates status to done none
REQ-016-038 no "Remove" button with confirmation dialog for item deletion 1
REQ-016-039 no Deferred work changes sent to gateway for persistence in context.json 1
REQ-016-040 no "Log Work" text input with send button in the session panel none
REQ-016-041 no Log work sends description to session context via RPC none
REQ-016-042 no Recent work log entries displayed below the input (last 10) none
REQ-016-043 yes Gadget subscribes to session.events for real-time updates none
REQ-016-044 yes Session open event updates display to show new active session none
REQ-016-045 yes Session close event updates display to show "no active session" none
REQ-016-046 yes Session history table accessible via "History" tab none
REQ-016-047 yes History table columns: id, date, duration, status, achievements (truncated) none
REQ-016-048 no History supports search across achievements and descriptions none
REQ-016-049 no History supports date-range filter none
REQ-016-050 no Click on history row shows full session detail in a side panel none
REQ-016-051 yes CXPFeed gadget subscribes to cxp.traffic via GadgetBridge on mount 1
REQ-016-052 yes Subscription re-established automatically on gateway reconnect none
REQ-016-053 yes Gadget unsubscribes from cxp.traffic on unmount 1
REQ-016-054 yes Packets displayed as rows in a scrolling list none
REQ-016-055 yes Each row shows: timestamp, from (volk alias), to (volk alias), subject, status, thread_id none
REQ-016-056 yes Delivery status color-coded: green (delivered), yellow (pending), red (failed), grey (expired) none
REQ-016-057 yes Click on row expands to show full CXP payload (all 11 fields) none
REQ-016-058 yes Expanded view shows JSON payload with syntax highlighting none
REQ-016-059 yes Maximum 5000 packets retained in memory (oldest discarded) none
REQ-016-060 yes Volk filter dropdown (populated from volk.list) for from/to filtering none
REQ-016-061 yes Thread filter text input with debounced search (300ms) none
REQ-016-062 yes Subject filter text input supporting glob patterns (e.g., "code_*") none
REQ-016-063 yes Delivery status filter dropdown (all, delivered, pending, failed, expired) none
REQ-016-064 yes Multiple filters combine with AND semantics none
REQ-016-065 yes Active filter count shown in filter bar none
REQ-016-066 yes "Clear Filters" button resets all filters none
REQ-016-067 yes Filters applied client-side for instant response none
REQ-016-068 yes Auto-scroll to bottom for new packets when scrolled to bottom none
REQ-016-069 yes Auto-scroll pauses when user scrolls up (manual inspection) none
REQ-016-070 yes "Jump to Bottom" floating button appears when paused none
REQ-016-071 yes Auto-scroll resumes on "Jump to Bottom" click or manual scroll to bottom none
REQ-016-072 yes Packet count badge shows total packets since gadget mount none
REQ-016-073 yes Throughput indicator shows packets/sec (rolling 10-second average) none
REQ-016-074 yes Filtered packet count shown when filters active (e.g., "42 / 1234") none
REQ-016-075 yes VolkStatus gadget calls volk.list on mount to populate initial state none
REQ-016-076 yes Each volk rendered as a card with: alias, role title, health indicator, current task 1
REQ-016-077 yes Health indicator: green circle (healthy), yellow circle (degraded), red circle (unhealthy) none
REQ-016-078 yes Current task shown as status text with elapsed time (live timer) none
REQ-016-079 yes Idle volks show "Idle" with grey status text none
REQ-016-080 yes Gadget subscribes to volk.lifecycle for real-time updates none
REQ-016-081 yes Health changes animate with CSS color transition (300ms fade) none
REQ-016-082 yes New volk registration adds card with slide-in animation none
REQ-016-083 yes Volk deregistration removes card with fade-out animation none
REQ-016-084 yes Task start/complete events update the current task display none
REQ-016-085 yes Click on volk card opens detail panel (slide-out right side) none
REQ-016-086 yes Detail panel shows: alias, role, capabilities list, protocols, registration time none
REQ-016-087 yes Detail panel shows: session_id, resource_usage (tokens, time), last_activity none
REQ-016-088 yes Detail panel shows: output artifacts list (files generated, CXP packets sent count) none
REQ-016-089 no Detail panel updated in real-time via volk.lifecycle events none
REQ-016-090 yes Default mode: volk cards in a grid (responsive columns based on gadget width) none
REQ-016-091 no Compact mode: horizontal bars with color-coded health (for width < 400px) none
REQ-016-092 no Layout mode auto-switches based on gadget container width none
REQ-016-093 no Manual mode toggle in gadget titlebar (grid/compact icon) none
REQ-016-094 yes ClaudeChat gadget renders message history as a scrollable conversation view none
REQ-016-095 yes User messages aligned right, Claude responses aligned left none
REQ-016-096 yes Message input area with multiline support (Shift+Enter for newline, Enter to send) none
REQ-016-097 yes Send button enabled only when input is non-empty none
REQ-016-098 yes Message timestamps displayed on hover none
REQ-016-099 yes User messages sent via cxp.send RPC with destination set to Claude-backed agent 1
REQ-016-100 yes Each chat thread uses a unique CXP thread_id 1
REQ-016-101 yes Responses received via cxp.traffic subscription filtered to the chat thread_id none
REQ-016-102 yes Work status tracked: "sent" -> "processing" -> "delivered" 1
REQ-016-103 yes Error responses displayed inline with red error styling none
REQ-016-104 yes Code blocks rendered with syntax highlighting (language detection) none
REQ-016-105 yes Inline code rendered with monospace font and background none
REQ-016-106 yes Lists (ordered and unordered) rendered with proper indentation none
REQ-016-107 yes Bold, italic, and links rendered correctly none
REQ-016-108 yes Markdown parser sanitizes HTML (no script tags, no event handlers) none
REQ-016-109 yes "New Thread" button creates a fresh CXP thread_id and clears display none
REQ-016-110 yes Thread selector dropdown lists recent threads (last 10) by first message preview none
REQ-016-111 yes Switching threads loads history from localStorage none
REQ-016-112 yes Chat history persisted in localStorage (last 100 messages per thread) none
REQ-016-113 yes Chat history synced via StateSync for cross-device persistence none
REQ-016-114 yes Typing indicator (animated dots) shown while awaiting response none
REQ-016-115 yes Typing indicator triggered by work_status change to "processing" none
REQ-016-116 yes Connection status shown in chat header (connected/disconnected) 1
REQ-016-117 yes "Reconnecting..." overlay shown when gateway is disconnected none
REQ-016-118 no Message search via keyword filter (search icon in chat header) none
REQ-016-119 yes TaskBoard gadget displays tasks as kanban columns: Not Started, In Progress, Completed none
REQ-016-120 yes Tasks displayed as cards within columns, sorted by priority (critical first) none
REQ-016-121 yes Card shows: title, priority badge, assigned volk (avatar), brief description none
REQ-016-122 yes Column header shows task count per status none
REQ-016-123 yes "Deferred" column displays deferred work items from context.json none
REQ-016-124 yes Tasks draggable between status columns (HTML5 Drag and Drop API) 1
REQ-016-125 yes Drop zones highlighted during drag (visual affordance) 1
REQ-016-126 yes Status change on drop sends RPC update to gateway none
REQ-016-127 yes Drag-and-drop works on touch devices (pointer events) none
REQ-016-128 yes Undo available for 5 seconds after status change (toast with "Undo" button) none
REQ-016-129 yes "New Task" button opens modal dialog none
REQ-016-130 yes Task form fields: title (required), description, priority dropdown none
REQ-016-131 yes Task creation sends RPC to gateway for persistence none
REQ-016-132 yes New task appears in "Not Started" column immediately none
REQ-016-133 yes "New Task" button within each column opens modal dialog none
REQ-016-134 yes Task form fields: title (required), description, assigned volk (dropdown), priority none
REQ-016-135 yes Task creation sends RPC to gateway for persistence none
REQ-016-136 yes New task appears in the appropriate column immediately none
REQ-016-137 no Click on task card opens detail panel (slide-out right side) none
REQ-016-138 no Detail panel shows: title, description, priority, assigned volk, parent goal none
REQ-016-139 no Detail panel shows: history (status changes with timestamps) none
REQ-016-140 no Detail panel shows: linked CXP threads, time spent none
REQ-016-141 no Inline editing of title, description, priority, assigned volk in detail panel 1
REQ-016-142 no Dashboard task edits flow to context.json via gateway RPC none
REQ-016-143 no CLI/external edits to context.json appear in dashboard via session.events subscription none
REQ-016-144 no Conflict resolution: last-write-wins with user notification of override none
REQ-016-145 yes QADashboard gadget displays current test count as a large number with label none
REQ-016-146 yes Gadget displays pass rate as percentage with color (green >=99%, yellow >=95%, red <95%) none
REQ-016-147 yes Gadget displays coverage percentage with color coding none
REQ-016-148 yes Metrics fetched from project state via knowledge.query or configuration none
REQ-016-149 yes Metrics displayed as metric cards with current value and delta since last session none
REQ-016-150 yes Coverage trend rendered as sparkline chart (last 20 data points) none
REQ-016-151 yes Sparkline rendered using Canvas 2D API (no external chart library) none
REQ-016-152 yes Hover on sparkline shows tooltip with exact value and date none
REQ-016-153 yes Trend data fetched from knowledge graph (Iteration nodes with coverage property) 1
REQ-016-154 yes Gate status displayed as pass/fail indicator none
REQ-016-155 yes Pass: green checkmark, Fail: red X, Partial: yellow warning triangle none
REQ-016-156 yes Hover on gate icon shows: iteration number, date, test count, gap count none
REQ-016-157 yes Click on gate icon shows detailed iteration results none
REQ-016-158 yes Failed tests section expandable (collapsed by default) none
REQ-016-159 yes Each failed test shows: test name, assertion message, file:line location none
REQ-016-160 yes Failed tests grouped by test module none
REQ-016-161 yes Click on file:line opens relevant context in ProjectExplorer gadget none
REQ-016-162 yes RTM progress bar: verified requirements / total requirements 1
REQ-016-163 yes RTM percentage displayed as text alongside progress bar none
REQ-016-164 yes Click on RTM progress bar opens RTM Viewer gadget none
REQ-016-165 yes Test execution events received via kernel.events subscription (test_completed) none
REQ-016-166 yes Test count and pass rate updated in real-time during test runs 5
REQ-016-167 yes "Run Tests" button sends test execution command via gateway RPC 3
REQ-016-168 yes Test run progress bar shown during execution 1
REQ-016-169 yes AuditTrail gadget queries governance.query on mount with default time range none
REQ-016-170 yes Query results displayed in a sortable table none
REQ-016-171 yes Table columns: timestamp, actor, action, resource, result, latency_ms none
REQ-016-172 yes Table sortable by any column (click column header, toggle asc/desc) none
REQ-016-173 yes Pagination: 50 items per page, next/prev buttons, page number display none
REQ-016-174 yes Full-text search input searches across all audit fields (debounced 300ms) none
REQ-016-175 yes Date range filter with date picker (from date, to date) none
REQ-016-176 yes Actor filter dropdown (populated from volk.list + gateway client IDs) none
REQ-016-177 yes Action type filter dropdown (CXP send, session open, governance check, etc.) none
REQ-016-178 yes Result filter dropdown (allow, deny, escalated, error) none
REQ-016-179 yes Constitutional article filter dropdown (I through XI) none
REQ-016-180 yes Active filter summary bar showing applied filters with remove buttons none
REQ-016-181 yes Constitutional article violations highlighted with red left border and article reference none
REQ-016-182 yes Escalation events displayed with escalation chain (involved parties, path) none
REQ-016-183 yes Governance decisions show Prolog query and evaluation latency none
REQ-016-184 yes Click on audit row expands to show full event detail (JSON formatted) none
REQ-016-185 no "Export CSV" button exports current filtered results as CSV download none
REQ-016-186 no "Export JSON" button exports current filtered results as JSON download none
REQ-016-187 no Export respects current filters and sort order none
REQ-016-188 no Export includes all fields (not just visible columns) none
REQ-016-189 yes KGExplorer renders a force-directed graph using Canvas 2D API none
REQ-016-190 yes Nodes displayed with type-based styling (table view with node type column) none
REQ-016-191 yes Node size proportional to relationship count (more connected = larger) none
REQ-016-192 yes Relationships rendered as labeled directed edges with arrowheads none
REQ-016-193 yes Node labels show name/alias (truncated to 20 chars) none
REQ-016-194 yes Zoom via scroll wheel (min 0.1x, max 5x) none
REQ-016-195 yes Pan via mouse drag on background none
REQ-016-196 yes Node drag repositions node (simulation continues around dragged node) none
REQ-016-197 yes Click on node selects it and shows property panel none
REQ-016-198 yes Double-click on node expands its relationships (loads connected nodes) none
REQ-016-199 yes Property panel shows all node properties as key-value pairs none
REQ-016-200 yes Property panel shows node labels and type none
REQ-016-201 yes Property panel shows relationship list (type, direction, target node) none
REQ-016-202 yes Property panel links to related gadgets (file -> ProjectExplorer, session -> SessionManager) none
REQ-016-203 yes Cypher input area for query entry none
REQ-016-204 yes Auto-complete for node types, relationship types, and property names none
REQ-016-205 yes "Run Query" button executes via knowledge.query RPC 1
REQ-016-206 yes Query results rendered as tabular data none
REQ-016-207 yes Query history dropdown (last 20 queries) for re-execution none
REQ-016-208 yes Query error messages displayed inline below the input none
REQ-016-209 yes NotificationManager subscribes to governance.decisions for escalation events none
REQ-016-210 yes NotificationManager subscribes to kernel.events for error and warning events none
REQ-016-211 yes NotificationManager subscribes to session.events for decision_needed events none
REQ-016-212 yes Subscriptions established on CommandCenter initialization none
REQ-016-213 yes Subscriptions re-established on gateway reconnect none
REQ-016-214 yes Notification API permission requested on first critical event none
REQ-016-215 yes Desktop notification shown when browser tab is not focused none
REQ-016-216 yes Desktop notification includes: title, body (truncated to 100 chars), icon none
REQ-016-217 yes Click on desktop notification focuses the browser tab and opens relevant gadget none
REQ-016-218 yes Desktop notifications sent only for warning priority and above none
REQ-016-219 yes Notification bell icon in dashboard header with unread count badge none
REQ-016-220 yes Click on bell opens notification dropdown (last 50 notifications) none
REQ-016-221 yes Each notification shows: timestamp, type icon, title, body preview none
REQ-016-222 yes Click on notification navigates to relevant gadget (audit trail, session manager, etc.) none
REQ-016-223 yes "Mark All Read" button clears unread count none
REQ-016-224 yes Per-notification dismiss (X button) removes from list none
REQ-016-225 yes Notification priority styling: info (blue), warning (yellow), error (red), critical (pulsing red) none
REQ-016-226 yes Settings panel for notification preferences (accessible from bell dropdown) none
REQ-016-227 yes Toggle desktop notifications on/off none
REQ-016-228 yes Toggle notification sound on/off (with sound file selection) none
REQ-016-229 yes Minimum priority filter (show only warnings and above, errors and above, etc.) none
REQ-016-230 yes Preferences persisted via StateSync none
REQ-016-231 yes PrayerTimes gadget wraps existing VizInt portal PrayerTimes gadget none
REQ-016-232 yes Connects to Chronus provider for accurate prayer calculations none
REQ-016-233 yes Displays next prayer name and countdown timer (HH:MM:SS) none
REQ-016-234 yes Displays all five daily prayer times in a compact table none
REQ-016-235 no TodoistGadget authenticates via personal API token (stored encrypted in localStorage) none
REQ-016-236 no Displays today's tasks grouped by project none
REQ-016-237 no Task completion toggle (checkbox) sends PATCH to Todoist API none
REQ-016-238 no Quick-add task input at bottom of list (POST to Todoist API) 1
REQ-016-239 no EmailGadget shows unread count and top 10 sender/subject previews none
REQ-016-240 no CalendarGadget shows today's events with time blocks 1
REQ-016-241 no API tokens encrypted with Web Crypto API before localStorage storage none
REQ-016-242 no All personal gadgets function independently when gateway is disconnected none
REQ-016-243 yes Theme toggle (dark/light) in dashboard header with smooth CSS variable transition none
REQ-016-244 yes Gadget grid supports drag-to-reposition and resize handles on chrome none
REQ-016-245 yes SessionHandler registered with gateway RPC router 7
REQ-016-246 yes session.active RPC returns the currently active session or null 13
REQ-016-247 yes session.list RPC returns all sessions with pagination 4
REQ-016-248 yes session.get RPC returns a single session by ID 5
REQ-016-249 yes session.open RPC creates and starts a new session 7
REQ-016-250 yes session.close RPC closes the active session with summary 9
REQ-016-251 yes session.events subscription pushes session lifecycle events 7
REQ-016-252 yes session.facts.subscribe subscription pushes session facts in real-time 2
REQ-016-253 yes ProjectsHandler registered with gateway RPC router 1
REQ-016-254 yes projects.list RPC returns all projects 2
REQ-016-255 yes projects.get RPC returns a single project by ID 2
REQ-016-256 yes projects.tasks RPC returns tasks for a project 2
REQ-016-257 yes projects.taskCreate RPC creates a new task for a project 2
REQ-016-258 yes WebSocketBridge implements JSON-RPC 2.0 over WebSocket none
REQ-016-259 yes Auto-reconnect with exponential backoff on connection loss none
REQ-016-260 yes Request queue buffers calls during disconnection for replay on reconnect none
REQ-016-261 yes Authentication token sent on connection handshake none
REQ-016-262 yes GadgetBridge maps EventBus events to WebSocket RPC calls none
REQ-016-263 yes Supports session, CXP, volk, knowledge, and governance event domains none
REQ-016-264 yes Bidirectional mapping: outbound events become RPC requests, inbound RPC responses become events none
REQ-016-265 yes EventBus uses CustomEvent pub/sub with vizint: prefix namespace none
REQ-016-266 yes Compatible with standard addEventListener API none
REQ-016-267 yes Supports wildcard subscriptions within event domains none
REQ-016-268 yes Dynamic ES module loading of gadgets at runtime none
REQ-016-269 yes Manifest validation ensures gadget metadata is complete none
REQ-016-270 yes basePath configuration for loading gadgets from different directories none
REQ-016-271 yes Gadget lifecycle management: mount, unmount, destroy none
REQ-016-272 yes Chrome factory provides consistent gadget window decoration (titlebar, controls) none
REQ-016-273 yes localStorage persistence for offline/quick-load state none
REQ-016-274 yes Gateway sync for cross-device state consistency 1
REQ-016-275 yes 500ms debounce on state writes to prevent thrashing none
REQ-016-276 yes Last-write-wins conflict resolution strategy none
REQ-016-277 yes Desktop notification support via Notification API 1
REQ-016-278 yes In-app notification queue with priority-based rendering none
REQ-016-279 yes Governance, kernel, and session event subscriptions for alert sources 1
REQ-016-280 yes Light and dark theme support via CSS custom properties 1
REQ-016-281 yes System preference detection (prefers-color-scheme media query) none
REQ-016-282 yes Theme preference persisted in localStorage none
REQ-016-283 yes Development layout profile: 5 gadgets (ProjectExplorer, SessionManager, CXPFeed, VolkStatus, ClaudeChat) none
REQ-016-284 yes Monitoring layout profile: 4 gadgets (CXPFeed, VolkStatus, AuditTrail, NotificationCenter) none
REQ-016-285 yes command-center.json configuration file with gateway, state_sync, notifications, layout sections none
REQ-016-286 yes Playwright E2E tests: page load, header, connection status, theme toggle, layout switching, WebSocket states none
REQ-016-287 yes Vitest unit tests: EventBus, WebSocketBridge, StateSync, NotificationManager, Registry, Chrome, Shared none
REQ-016-288 yes WsTestServer: Custom JSON-RPC mock server for testing none
REQ-016-289 yes Flashcards gadget: Arabic/Italian learning with CSV data (50KB) none
REQ-016-290 yes Iqama Countdown gadget: prayer time countdown (31KB) none
REQ-016-291 yes Time-to-POI gadget: point-of-interest countdown (1135 LOC) none
REQ-016-292 yes Chronus Sequencer gadget: timeline sequencer none
REQ-016-293 yes Settings gadget: settings panel (1125 LOC) none
REQ-016-294 yes Embed gadgets: iframe embedding for external content none

Code that traces this spec

Module Symbols Requirements
orchestrata_ultimate/gateway/handlers/_session_events 4 3
orchestrata_ultimate/gateway/handlers/_session_kg 15 6
orchestrata_ultimate/gateway/handlers/cxp 3 5
orchestrata_ultimate/gateway/handlers/knowledge 4 4
orchestrata_ultimate/gateway/handlers/projects 7 6
orchestrata_ultimate/gateway/handlers/session 15 8
orchestrata_ultimate/gateway/handlers/state 1 1
orchestrata_ultimate/gateway/handlers/test_metrics 2 1
orchestrata_ultimate/gateway/test_runner 7 3
orchestrata_ultimate/knowledge_graph/graph_context_validator 2 2
orchestrata_ultimate/knowledge_graph/query_engine 6 6
orchestrata_ultimate/knowledge_graph/types_nodes 3 3
orchestrata_ultimate/orchestrator/orchestrator 1 1
orchestrata_ultimate/session/event_emitting_session_controller 5 1

Checklists

checklists/README.md

VizInt Command Center Checklists

Project: Orchestrata VizInt Command Center (Spec 016) Component: Command Center Dashboard Status: Planning Phase Owner: Architecture Team


Overview

The VizInt Command Center is the unified dashboard and personal command center for Orchestrata. Built on the VizInt gadget portal framework, it connects to the SPEC-014 WebSocket Gateway (JSON-RPC 2.0 over WebSocket) to provide real-time observation, control, and interaction with the entire orchestration system — alongside personal productivity gadgets for a unified workspace.


Checklist Summary
Checklist Total Items Completed Progress
Requirements 244 0 0%
Constitutional Compliance 140 0 0%
Testing Plan 374 0 0%
TOTAL 758 0 0%

Key Responsibilities
1. WebSocket Bridge and Gateway Connection
2. Gadget Lifecycle and Registry
3. Real-Time Data Visualization
4. Session and Task Management
5. Claude Chat Interface
6. Notification System
7. Personal Productivity Integration
8. Theme and Layout Customization

Performance Targets
Metric Target Critical Threshold
Gadget Initial Render <100ms <200ms
WebSocket Reconnect <3s <10s
RPC Round-Trip <200ms p95 <500ms p99
CXP Feed Scroll 60fps 30fps minimum
Theme Switch <50ms <100ms
Initial Page Load <2MB <4MB
Memory (10 gadgets) <100MB <200MB
Event Delivery <200ms from gateway <500ms
Notification Display <1s from event <3s

Checklist Files
1. requirements.md

Functional requirements organized by user stories:

2. constitutional.md

Compliance with all 11 constitutional articles:

3. testing.md

Comprehensive testing strategy:


Integration Points
Upstream Dependencies
Downstream Consumers
External API Integrations

Dependencies
Required Services
Required Browser APIs
Optional Services

References

Last Updated: 2026-03-28 Version: 1.0.0 Maintained By: Architecture Team

checklists/constitutional.md

VizInt Command Center - Constitutional Compliance

Component: Command Center Dashboard Spec: 016-vizint-command-center Status: Compliance Review Total Compliance Items: 140


Overview

This document tracks compliance of the VizInt Command Center with all 11 articles of the Orchestrata Constitution. The Command Center is the primary user-facing interface, making constitutional compliance critical — it must faithfully represent system state without distortion, enforce governance visibility, and never bypass the kernel or PAM++ authorization chain.


Article I: Agent Autonomy

Principle: Volks (agents) retain autonomy; the Command Center observes but does not override agent decisions.

Compliance Requirements
Autonomy Preservation

Priority: Critical Verification: Integration tests + manual review


Article II: Prolog as Single Source of Truth

Principle: All governance rules are in Prolog; the Command Center queries governance through the gateway, never hardcodes authorization.

Compliance Requirements
Governance Fidelity

Priority: Critical Verification: Governance integration tests + policy compliance review


Article III: Session Isolation

Principle: Sessions are isolated; the Command Center does not leak state between sessions.

Compliance Requirements
State Isolation

Priority: Critical Verification: Session isolation tests + state leak detection


Article IV: Hooks for Extensibility

Principle: The Command Center provides extension points for customization without core modification.

Compliance Requirements
Extension Points

Priority: High Verification: Plugin gadget tests + extension API tests


Article V: Minimal Core, Maximal Extension

Principle: Command Center core is minimal; features are added via gadgets (extensions).

Compliance Requirements
Minimal Core

Priority: High Verification: Core size metrics + dependency audit


Article VI: Implementation Standards (JavaScript ES2024)

Principle: Code follows modern standards with proper async patterns and type safety.

Compliance Requirements
Language Standards
Code Quality

Priority: High Verification: ESLint + Prettier CI checks + code review


Article VII: Testing Without Mocks

Principle: Tests use real implementations, not mocks.

Compliance Requirements
Real Systems Testing

Priority: Critical Verification: Test code review + mock detector


Article VIII: Metrics and Observability

Principle: All operations are observable and measurable.

Compliance Requirements
Client-Side Metrics
Observability

Priority: High Verification: Metrics tests + observability review


Article IX: Graceful Degradation

Principle: System degrades gracefully under failure, does not crash.

Compliance Requirements
Failure Handling
Recovery

Priority: High Verification: Failure injection tests + disconnect simulation


Article X: Version Compatibility

Principle: APIs are versioned; breaking changes are avoided.

Compliance Requirements
API Versioning

Priority: Medium Verification: Compatibility tests + version migration tests


Article XI: Documentation First

Principle: Documentation precedes implementation.

Compliance Requirements
Design Documentation

Priority: High Verification: Documentation review + doc completeness check


Summary Statistics
Article Total Items Completed Percentage
Article I (Autonomy) 10 0 0%
Article II (Prolog) 10 0 0%
Article III (Isolation) 12 0 0%
Article IV (Hooks) 10 0 0%
Article V (Minimal Core) 10 4 40%
Article VI (JS ES2024) 20 8 40%
Article VII (No Mocks) 10 1 10%
Article VIII (Observability) 20 4 20%
Article IX (Degradation) 20 2 10%
Article X (Versioning) 10 2 20%
Article XI (Documentation) 10 1 10%
TOTAL 142 22 15.5%

Last Updated: 2026-05-26 Version: 1.0.0 Maintained By: Architecture Team

checklists/requirements.md

The requirement list above comes from this file; 242 of 294 checkbox items are ticked.

checklists/testing.md

VizInt Command Center - Testing Checklist

Component: Command Center Dashboard Spec: 016-vizint-command-center Updated: 2026-03-29 Total Test Cases: 62 implemented, 6 categories planned


Test Results Summary
Category Count Status Tool
E2E Dashboard 11 Implemented Playwright (Firefox)
Unit EventBus 8 Implemented Vitest
Unit WebSocketBridge 12 Implemented Vitest
Unit StateSync 8 Implemented Vitest
Unit NotificationManager 7 Implemented Vitest
Unit Registry 5 Implemented Vitest
Unit Chrome 4 Implemented Vitest
Unit Shared 4 Implemented Vitest
Contract Gateway RPC 0 Planned Vitest
Perf Rendering 0 Planned Playwright

Implemented: 62 tests across 10 suites Planned: Contract, Performance, Gadget Integration, Gateway Integration, Cross-browser, Accessibility


Test Infrastructure
Component Path Purpose
Playwright config playwright.config.js Firefox browser, baseURL http://<test-fleet-host>:5000 (e.g. http://10.53.2.13:5000 with ORCHESTRATA_ENV_PROFILE=test)
Vitest config vitest.config.js jsdom environment, ES module resolution
WS test server tests/helpers/ws-test-server.js Custom WebSocket server for JSON-RPC mock testing
E2E tests tests/e2e/dashboard.spec.js Playwright end-to-end suite
Unit tests tests/unit/*.test.js Vitest unit suites

E2E Tests - Playwright (11 tests)

File: tests/e2e/dashboard.spec.js


Unit Tests - EventBus (8 tests)

File: tests/unit/bus.test.js


Unit Tests - WebSocketBridge (12 tests)

File: tests/unit/websocket-bridge.test.js


Unit Tests - StateSync (8 tests)

File: tests/unit/state-sync.test.js


Unit Tests - NotificationManager (7 tests)

File: tests/unit/notification-manager.test.js


Unit Tests - Registry (5 tests)

File: tests/unit/registry.test.js


Unit Tests - Chrome (4 tests)

File: tests/unit/chrome.test.js


Unit Tests - Shared Utilities (4 tests)

File: tests/unit/shared.test.js


Contract Tests - Gateway RPC (planned)

Performance Tests (planned)

Integration Tests (planned)

Other tracked files

Full spec text

Verbatim from specs/016-vizint-command-center/spec.md; headings are pushed down two levels.

SPEC-016: VizInt Command Center

Metadata


Overview

What

The VizInt Command Center is the unified dashboard and personal command center for Orchestrata. Built on the VizInt gadget portal framework (cloned at vizint-ui/), it provides a single browser-based interface where the user can observe, control, and interact with the entire orchestration system in real-time. The Command Center connects to Orchestrata via the SPEC-014 WebSocket Gateway (JSON-RPC 2.0 over WebSocket), presenting every orchestration feature as a composable gadget. The system ships with 31 gadgets spanning orchestration production dashboards, personal productivity tools, developer utilities, and example templates. Zero-build ES modules via import maps in HTML eliminate the need for any bundler.

Why
How

User Scenarios & Stories

US-001: Project Dashboard (P1)

As a developer or project lead I want to open a project and see its knowledge graph nodes, source files, sessions, and iterations at a glance So that I have immediate situational awareness of the project state

Acceptance Criteria:


US-002: Session Management (P1)

As a developer I want to start and close sessions, see deferred work, and log work through the dashboard So that I can manage orchestration sessions without CLI commands

Acceptance Criteria:


US-003: Real-Time CXP Feed (P1)

As a developer or system operator I want to watch CXP packets flow between volks in real-time So that I can observe agent communication and debug routing issues

Acceptance Criteria:


US-004: Volk Status Panel (P1)

As a system operator I want to see all volks with their health, current task, and output artifacts So that I can monitor agent activity and detect failures

Acceptance Criteria:


US-005: Claude Chat (P1)

As a developer I want to chat with Claude directly through the dashboard So that I can get AI assistance without leaving the command center

Acceptance Criteria:


US-006: Task & Goal Board (P1)

As a project lead I want to create and manage tasks, goals, and deferred work items through the dashboard So that work items flow into context.json and the goal runner without manual file editing

Acceptance Criteria:


US-007: QA Dashboard (P1)

As a developer or QA lead I want to see test results, coverage trends, and gate status per iteration So that I know the quality state of the project at a glance

Acceptance Criteria:


US-008: Audit Trail Viewer (P1)

As a compliance auditor or developer I want to see every event, decision, and escalation with search and filter So that I can trace actions and verify governance compliance

Acceptance Criteria:


US-009: Knowledge Graph Explorer (P2)

As a developer or architect I want to visually browse the knowledge graph and run Cypher queries So that I can explore relationships between files, classes, sessions, and specs

Acceptance Criteria:


US-010: Notification Center (P1)

As a developer I want to receive alerts when orchestrata needs decisions or when escalations occur So that I can respond promptly without constant CLI monitoring

Acceptance Criteria:


US-011: Personal Productivity Gadgets (P2)

As a developer I want to see prayer times, language flashcards, and timers alongside orchestrata gadgets So that I have a unified personal command center without switching between apps

Acceptance Criteria:


US-012: Theme & Layout Customization (P2)

As a developer I want to customize the dashboard theme, gadget arrangement, and save layout profiles So that the command center fits my workflow and preferences

Acceptance Criteria:


US-013: Gateway Session Handlers (P1)

As a Command Center frontend I want to call session and project RPC methods backed by Neo4j So that I can display real-time session and project data without direct database access

Acceptance Criteria:


US-014: Gateway Project Handlers (P1)

As a Command Center frontend I want to query project data, tasks, and create tasks via RPC So that the ProjectExplorer and TaskBoard gadgets have backend support

Acceptance Criteria:


Functional Requirements

Core Platform

FR-001: WebSocket Bridge (P1)

FR-002: State Synchronization (P1)

FR-003: Gadget Bridge (P1)

FR-004: Gadget Registry (P1)

FR-005: Notification Manager (P1)

FR-006: Theming Engine (P1)

FR-007: Portal Framework (P1)

Project & Session Gadgets

FR-008: ProjectExplorer Gadget (P1)

FR-009: SessionManager Gadget (P1)

FR-010: TaskBoard Gadget (P1)

FR-011: RTM Viewer Gadget (P2)

Real-Time Monitoring Gadgets

FR-012: CXP Feed Gadget (P1)

FR-013: Volk Status Gadget (P1)

FR-014: QA Dashboard Gadget (P1)

FR-015: Audit Trail Gadget (P1)

Interaction Gadgets

FR-016: Claude Chat Gadget (P1)

FR-017: Task Board Interactions (P1)

FR-018: Metrics Dashboard Gadget (P2)

Knowledge & Data Gadgets

FR-019: Knowledge Graph Explorer Gadget (P2)

FR-020: RTM Coverage Viewer (P2)

FR-021: Session History Gadget (P2)

FR-022: Iteration Browser Gadget (P2)

Personal & Specialized Gadgets

FR-023: Prayer Times Gadgets (P2)

FR-024: Language & Learning Gadgets (P2)

FR-025: Timeline & Utility Gadgets (P2)

FR-026: Embedding & Extension Gadgets (P2)

Gateway Handlers

FR-027: SessionHandler (P1)

FR-028: ProjectsHandler (P1)


Non-Functional Requirements

Performance

NFR-001: Responsiveness

Reliability

NFR-002: Offline Resilience

Accessibility

NFR-003: WCAG 2.1 AA Compliance

Performance Budget

NFR-004: Bundle and Runtime

Extensibility

NFR-006: Plugin Gadgets


Technical Design

Architecture
+------------------------------------------------------------------------+
|                    VizInt Command Center (Browser)                      |
+------------------------------------------------------------------------+
|                                                                        |
|  +------------------+                                                  |
|  | CommandCenterApp |  Entry point: app.js                             |
|  | Bootstraps 5     |  Zero-build ES modules (import maps in HTML)    |
|  | subsystems       |                                                  |
|  +--------+---------+                                                  |
|           |                                                            |
|  +--------v---------+  +---------------+  +--------------------+       |
|  | WebSocketBridge   |  | GadgetBridge  |  | NotificationManager|      |
|  | JSON-RPC 2.0/WS   |  | bus <-> RPC   |  | Desktop + in-app   |      |
|  | Auto-reconnect    |  | 5 namespaces: |  | Subscribes to:     |      |
|  | Exp backoff 30s   |  |  session.*    |  |  governance.decisions|     |
|  | Queue max 100     |  |  cxp.*        |  |  kernel.events      |     |
|  +------------------+  |  volk.*       |  |  session.events     |     |
|                         |  knowledge.* |  | Max 200 stored      |     |
|  +------------------+  |  governance.* |  +--------------------+       |
|  | StateSync         |  +---------------+                              |
|  | localStorage +    |                                                 |
|  | gateway sync      |  +---------------+                              |
|  | Debounce 500ms    |  | GadgetRegistry|                              |
|  | Last-write-wins   |  | Dynamic load  |                              |
|  +------------------+  | Manifest valid |                              |
|                         | basePath param |                              |
|                         +---------------+                              |
|                                                                        |
|  +---------- Portal Framework (lib/) --------------------+             |
|  | portal.js  - Gadget lifecycle (mount/unmount)          |             |
|  | bus.js     - EventBus via CustomEvents, vizint: prefix |             |
|  | registry.js - Dynamic loading, manifest validation     |             |
|  | chrome.js  - Title bar, minimize/close, status bar     |             |
|  | shared.js  - generateId, debounce, formatTimestamp     |             |
|  +--------------------------------------------------------+            |
|                                                                        |
|  +---------- Gadget Grid Layout ---------------------------+           |
|  |                                                          |           |
|  | P1 Production Gadgets (10):                              |           |
|  | +----------+ +----------+ +----------+ +----------+     |           |
|  | |Project   | |Session   | |CXP       | |Volk      |     |           |
|  | |Explorer  | |Manager   | |Feed      | |Status    |     |           |
|  | |173 LOC   | |198 LOC   | |161 LOC   | |192 LOC   |     |           |
|  | +----------+ +----------+ +----------+ +----------+     |           |
|  | +----------+ +----------+ +----------+ +----------+     |           |
|  | |Claude    | |Task      | |QA        | |Audit     |     |           |
|  | |Chat      | |Board     | |Dashboard | |Trail     |     |           |
|  | |226 LOC   | |224 LOC   | |179 LOC   | |202 LOC   |     |           |
|  | +----------+ +----------+ +----------+ +----------+     |           |
|  | +----------+ +----------+                                |           |
|  | |KG        | |Notif     |                                |           |
|  | |Explorer  | |Center    |                                |           |
|  | |194 LOC   | |194 LOC   |                                |           |
|  | +----------+ +----------+                                |           |
|  |                                                          |           |
|  | Personal/Specialized Gadgets (21):                       |           |
|  | flashcards, iqama-countdown, prayer_vizint,              |           |
|  | time-to-poi, chronus_sequencer, settings,                |           |
|  | embed, embed-web, runway-viewport, chronus-dev,          |           |
|  | atlas-debug, helloworld, helloworld2,                    |           |
|  | helloworld-settings, daily, worldtz, eom,                |           |
|  | prayertimes-chronus                                      |           |
|  +----------------------------------------------------------+          |
+------------------------------------------------------------------------+
          |                                    |
          v                                    v
+--------------------+              +---------------------+
| SPEC-014 WebSocket |              | External APIs       |
| Gateway            |              | Aladhan Prayer API  |
| ws://host:18790    |              | (via Chronus)       |
| JSON-RPC 2.0       |              +---------------------+
+----+----------+----+
     |          |
     v          v
+----------+ +------------------+
| Redis    | | Memgraph KG      |
| 10.93.   | | 10.53.2.10:7687 |
| 53.10    | | 558K+ nodes      |
| Session  | | 223K CXP packets |
| state,   | | 156K test results|
| caching  | | 6K sessions      |
+----------+ | 2.7K requirements|
             | 439 source files |
             | 934 classes      |
             | 522 functions    |
             | 28K Prolog rules |
             +------------------+
Gadget Inventory (31 Total)
P1 Production Gadgets (10 -- All Implemented)
# Gadget LOC Description Primary RPC
1 project-explorer 173 Projects, KG nodes, recent sessions knowledge.nodes
2 session-manager 198 Session CRUD, lifecycle management session.*
3 cxp-feed 161 CXP traffic monitor cxp.traffic subscription
4 volk-status 192 Agent cards with health dots volk.list, volk.lifecycle
5 claude-chat 226 Chat with Claude, markdown rendering cxp.send
6 task-board 224 Kanban board with drag-drop projects.tasks, projects.taskCreate
7 qa-dashboard 179 QA metrics, coverage, gate status knowledge.query
8 audit-trail 202 Event audit log governance.query
9 kg-explorer 194 Knowledge graph exploration knowledge.query
10 notification-center 194 Notification hub governance.decisions, kernel.events
Personal & Specialized Gadgets (21 -- All Implemented)
# Gadget Size Description
11 flashcards 50KB Italian/Arabic language learning with CSV data
12 iqama-countdown 31KB Prayer time countdown timer
13 prayer_vizint -- Prayer times display
14 time-to-poi 1135 LOC Point-of-interest countdown
15 chronus_sequencer 14KB Chronus timeline sequencer
16 settings 1125 LOC Settings panel
17 embed -- Iframe embedding (native)
18 embed-web -- Iframe embedding (web)
19 runway-viewport 356 LOC Timeline visualization
20 chronus-dev -- Chronus development tools
21 atlas-debug -- Atlas debugging
22 helloworld -- Example gadget
23 helloworld2 -- Example gadget (variant)
24 helloworld-settings -- Example gadget with settings
25 daily -- Daily overview
26 worldtz -- World timezone display
27 eom -- End-of-month tracking
28 prayertimes-chronus -- Prayer times via Chronus provider
Package Structure

The VizInt Command Center is a pure JavaScript frontend -- no Python backend package. The SPEC-014 WebSocket Gateway serves as the backend. The frontend connects directly to the gateway over WebSocket.

vizint-ui/                          # Root directory (VizInt portal)
|-- index.html                      # Entry point (import maps, zero-build)
|-- app.js                          # CommandCenterApp bootstraps 5 subsystems
|-- lib/                            # Portal framework
|   |-- portal.js                   # Gadget lifecycle (mount/unmount)
|   |-- bus.js                      # EventBus via CustomEvents, vizint: prefix
|   |-- registry.js                 # Dynamic gadget loading, manifest validation
|   |-- chrome.js                   # Title bar, minimize/close, status bar
|   |-- shared.js                   # generateId, debounce, formatTimestamp
|   |-- atlas.js                    # Geolocation service
|   +-- chronus.js                  # Time engine
|-- bridge/                         # Gateway bridge layer
|   |-- websocket-bridge.js         # WebSocket connection + JSON-RPC 2.0
|   |-- gadget-bridge.js            # ctx.bus <-> gateway translation
|   |-- state-sync.js              # localStorage + remote sync (500ms debounce)
|   +-- notification-manager.js     # Desktop + in-app notifications (max 200)
|-- gadgets/                        # 31 gadget modules
|   |-- project-explorer/           # US-001 (173 LOC)
|   |-- session-manager/            # US-002 (198 LOC)
|   |-- cxp-feed/                   # US-003 (161 LOC)
|   |-- volk-status/                # US-004 (192 LOC)
|   |-- claude-chat/                # US-005 (226 LOC)
|   |-- task-board/                 # US-006 (224 LOC)
|   |-- qa-dashboard/               # US-007 (179 LOC)
|   |-- audit-trail/                # US-008 (202 LOC)
|   |-- kg-explorer/                # US-009 (194 LOC)
|   |-- notification-center/        # US-010 (194 LOC)
|   |-- flashcards/                 # 50KB, Italian/Arabic flashcards
|   |-- iqama-countdown/            # 31KB, prayer countdown
|   |-- prayer_vizint/              # Prayer times
|   |-- time-to-poi/                # 1135 LOC, POI countdown
|   |-- chronus_sequencer/          # 14KB, timeline sequencer
|   |-- settings/                   # 1125 LOC, settings panel
|   |-- embed/                      # Iframe embedding
|   |-- embed-web/                  # Web iframe embedding
|   |-- runway-viewport/            # 356 LOC, timeline viz
|   |-- chronus-dev/                # Chronus dev tools
|   |-- atlas-debug/                # Atlas debugging
|   |-- helloworld/                 # Example gadget
|   |-- helloworld2/                # Example gadget variant
|   |-- helloworld-settings/        # Example with settings
|   |-- daily/                      # Daily overview
|   |-- worldtz/                    # World timezone
|   |-- eom/                        # End-of-month
|   +-- prayertimes-chronus/        # Prayer times via Chronus
|-- styles/
|   |-- common.css                  # CSS variables, colors, shadows, fonts
|   |                               # Light/dark theme (system pref + toggle)
|   +-- command-center.css          # CSS Grid layout, header, gadget chrome, badges
|-- providers/
|   |-- chronus_civil_provider.js
|   +-- chronus_prayerTimes_provider.js
|-- Specs/                          # 23 internal spec files
|   |-- chronus-anchors/
|   |-- portal-1.1/ through portal-1.3/
|   |-- atlas/
|   +-- gadget-specs/
|-- res/                            # Assets
|-- configs/
|   +-- command-center.json         # Runtime configuration
+-- tests/                          # Frontend tests
    |-- vitest.config.js
    |-- unit/                       # Vitest unit tests
    +-- e2e/                        # Playwright E2E tests

packages/orchestrata-gateway/       # Backend gateway handlers
|-- src/orchestrata/gateway/
|   |-- handlers/
|   |   |-- session.py              # SessionHandler (7 RPC methods)
|   |   +-- projects.py             # ProjectsHandler (4 RPC methods)
|   |-- server.py
|   |-- session.py
|   +-- rpc.py
Gateway Handler Design
SessionHandler (handlers/session.py)
class SessionHandler:
    """Handles session.* RPC methods for the Command Center."""

    async def session_active(self, params: dict) -> dict:
        """Get current active session info."""

    async def session_list(self, params: dict) -> dict:
        """List all active sessions."""

    async def session_get(self, params: dict) -> dict:
        """Get session by ID with context and facts."""

    async def session_open(self, params: dict) -> dict:
        """Create new session with type and metadata."""

    async def session_close(self, params: dict) -> dict:
        """Close session by ID."""

    async def session_events(self, params: dict) -> dict:
        """Subscribe to session lifecycle events."""

    async def session_facts_subscribe(self, params: dict) -> dict:
        """Subscribe to fact emissions."""
ProjectsHandler (handlers/projects.py)
class ProjectsHandler:
    """Handles projects.* RPC methods for the Command Center."""

    async def projects_list(self, params: dict) -> dict:
        """List projects from Neo4j (name, path, status, language)."""

    async def projects_get(self, params: dict) -> dict:
        """Get project by name with tasks and sessions."""

    async def projects_tasks(self, params: dict) -> dict:
        """List tasks with filtering by status (limit 1000)."""

    async def projects_task_create(self, params: dict) -> dict:
        """Create task in Neo4j."""

Both handlers are backed by the Neo4j knowledge graph via async queries with 10-second timeouts.

Styles

common.css: Defines CSS custom properties for the full design system:

command-center.css: Layout and component styles:

For testing requirements, see ## Testing.

Key Interfaces
/**
 * CommandCenterApp -- Top-level application entry point (app.js).
 * Bootstraps 5 subsystems: WebSocketBridge, GadgetBridge,
 * StateSync, NotificationManager, GadgetRegistry.
 */
class CommandCenterApp {
    /** Initialize: connect gateway, load registry, apply theme. */
    async initialize(config) {}

    /** Mount all default gadgets into the grid layout. */
    async mountDefaultLayout() {}

    /** Shut down: disconnect gateway, persist state, unmount gadgets. */
    async shutdown() {}

    /** Get the WebSocket bridge instance. */
    getWebSocketBridge() {}

    /** Get the gadget registry instance. */
    getGadgetRegistry() {}

    /** Get the notification manager instance. */
    getNotificationManager() {}

    /** Get the state sync instance. */
    getStateSync() {}
}


/**
 * WebSocketBridge -- Manages the WebSocket connection to SPEC-014 gateway.
 * JSON-RPC 2.0 over WebSocket with auto-reconnect (exponential backoff,
 * max 30s) and request queue (max 100).
 */
class WebSocketBridge {
    /**
     * Connect to the gateway.
     * @param {string} url - WebSocket URL (e.g., "ws://10.53.2.13:8765")
     * @param {Object} authCredentials - Auth payload for auth.authenticate
     * @returns {Promise<void>}
     */
    async connect(url, authCredentials) {}

    /**
     * Send an RPC call and return the result.
     * @param {string} method - RPC method name (e.g., "session.active")
     * @param {Object} params - Method parameters
     * @returns {Promise<Object>} - JSON-RPC result
     */
    async call(method, params) {}

    /**
     * Subscribe to a gateway event topic.
     * @param {string} topic - Event topic (e.g., "cxp.traffic")
     * @param {Object} filters - Subscription filters
     * @param {Function} callback - Called with each event payload
     * @returns {Promise<string>} - Subscription ID
     */
    async subscribe(topic, filters, callback) {}

    /**
     * Unsubscribe from a topic.
     * @param {string} subscriptionId - Subscription ID from subscribe()
     * @returns {Promise<void>}
     */
    async unsubscribe(subscriptionId) {}

    /** Disconnect from the gateway. */
    async disconnect() {}

    /** Get current connection state: "connected" | "reconnecting" | "disconnected". */
    getState() {}

    /**
     * Register a connection state change listener.
     * @param {Function} listener - Called with new state string
     */
    onStateChange(listener) {}
}


/**
 * GadgetBridge -- Translates between portal ctx.bus events and
 * gateway RPC/subscriptions across 5 namespaces.
 */
class GadgetBridge {
    /**
     * Map a ctx.bus event type to a gateway RPC call.
     * @param {string} busEventType - Portal bus event name
     * @param {string} rpcMethod - Gateway RPC method
     * @param {Function} paramsMapper - Transforms bus event detail to RPC params
     */
    mapEventToRPC(busEventType, rpcMethod, paramsMapper) {}

    /**
     * Map a gateway subscription topic to a ctx.bus event type.
     * @param {string} topic - Gateway event topic
     * @param {string} busEventType - Portal bus event name to emit
     * @param {Function} payloadMapper - Transforms gateway payload to bus detail
     */
    mapSubscriptionToEvent(topic, busEventType, payloadMapper) {}

    /**
     * Convenience: call an RPC method and return result.
     * @param {string} method - RPC method
     * @param {Object} params - Parameters
     * @returns {Promise<Object>}
     */
    async call(method, params) {}

    /**
     * Convenience: subscribe to topic with callback.
     * @param {string} topic - Event topic
     * @param {Object} filters - Subscription filters
     * @param {Function} callback - Event callback
     * @returns {Promise<string>} - Subscription ID
     */
    async subscribe(topic, filters, callback) {}
}


/**
 * StateSync -- Synchronizes application state between localStorage
 * and gateway. Debounced 500ms, last-write-wins conflict resolution.
 */
class StateSync {
    /**
     * Get a value (checks localStorage first, then remote).
     * @param {string} key - State key
     * @returns {*} - Stored value or null
     */
    get(key) {}

    /**
     * Set a value (writes to localStorage immediately,
     * debounced sync to gateway after 500ms).
     * @param {string} key - State key
     * @param {*} value - Value to store (must be JSON-serializable)
     */
    set(key, value) {}

    /**
     * Delete a value from both localStorage and remote.
     * @param {string} key - State key
     */
    delete(key) {}

    /**
     * Force a full sync from remote to local.
     * @returns {Promise<void>}
     */
    async pullRemote() {}

    /**
     * Force a full sync from local to remote.
     * @returns {Promise<void>}
     */
    async pushLocal() {}
}


/**
 * EventBus (lib/bus.js) -- Portal event system.
 * CustomEvents with vizint: prefix, addEventListener/removeEventListener
 * compatibility.
 */
class EventBus {
    /**
     * Emit an event on the bus.
     * @param {string} type - Event type (vizint: prefix added automatically)
     * @param {Object} detail - Event payload
     */
    emit(type, detail) {}

    /**
     * Subscribe to an event type.
     * @param {string} type - Event type
     * @param {Function} handler - Event handler
     */
    on(type, handler) {}

    /**
     * Unsubscribe from an event type.
     * @param {string} type - Event type
     * @param {Function} handler - Event handler
     */
    off(type, handler) {}
}


/**
 * NotificationManager -- Desktop + in-app notifications.
 * Subscribes to governance.decisions, kernel.events, session.events.
 * Max 200 stored notifications.
 */
class NotificationManager {
    /**
     * Add a notification.
     * @param {NotificationEntry} entry - Notification to add
     */
    add(entry) {}

    /**
     * Get all stored notifications.
     * @returns {NotificationEntry[]}
     */
    getAll() {}

    /**
     * Mark a notification as read.
     * @param {string} id - Notification ID
     */
    markRead(id) {}

    /**
     * Mark all notifications as read.
     */
    markAllRead() {}

    /**
     * Get unread count.
     * @returns {number}
     */
    getUnreadCount() {}
}


/**
 * GadgetManifest -- Metadata for a gadget in the registry.
 */
const GadgetManifest = {
    id: "string",                   // Unique gadget identifier
    name: "string",                 // Display name
    version: "string",              // Semver version
    description: "string",          // Short description
    entry: "string",                // ES module URL (relative to gadgets/)
    icon: "string",                 // Icon identifier or SVG path
    category: "string",             // "orchestrata" | "productivity" | "plugin"
    dependencies: ["string"],       // Required provider/bridge IDs
    min_api_version: "string",      // Minimum CommandCenter API version
    default_size: {                 // Default grid size
        columns: 1,                 // 1-4 columns
        rows: 1,                    // 1-4 rows
    },
    supports_multi_instance: false, // Whether multiple instances are allowed
    config_schema: {},              // JSON Schema for gadget-specific settings
};


/**
 * NotificationEntry -- A single notification in the notification center.
 */
const NotificationEntry = {
    id: "string",                   // Unique notification ID
    timestamp: "ISO8601 string",    // When the notification was created
    type: "string",                 // "escalation" | "error" | "decision_needed" | "info"
    priority: "string",             // "info" | "warning" | "error" | "critical"
    title: "string",                // Short notification title
    body: "string",                 // Notification body text
    source_topic: "string",         // Gateway topic that generated this
    source_event: {},               // Original gateway event payload
    read: false,                    // Whether the user has seen this
    gadget_target: "string|null",   // Gadget ID to navigate to on click
};
WebSocket Bridge Protocol

The WebSocket bridge maps directly to SPEC-014 JSON-RPC 2.0:

Outbound (browser -> gateway):

{
    "jsonrpc": "2.0",
    "id": "cc-req-001",
    "method": "session.active",
    "params": {}
}

Inbound response (gateway -> browser):

{
    "jsonrpc": "2.0",
    "id": "cc-req-001",
    "result": {
        "session_id": "session-089",
        "session_number": 89,
        "status": "active",
        "started_at": "2026-03-29T08:00:00Z"
    }
}

Inbound push (gateway -> browser):

{
    "jsonrpc": "2.0",
    "method": "cxp.traffic",
    "params": {
        "sequence": 142,
        "timestamp": "2026-03-29T10:30:22Z",
        "payload": {
            "to": "U:Cd",
            "from": "U:Ox",
            "thread_id": "thread-042",
            "subject": "code_review_result",
            "delivery_status": "delivered"
        }
    }
}

Request ID generation: cc-req-{monotonic_counter} -- prefixed to distinguish from other gateway clients.

Reconnection protocol:

  1. WebSocket close event detected
  2. State set to reconnecting, indicator updated
  3. Exponential backoff: 1s, 2s, 4s, 8s, 16s, max 30s
  4. On connect: re-authenticate, re-subscribe all active subscriptions
  5. State set to connected, flush queued RPC calls (max 100 in queue)
  6. Emit gateway.reconnected on ctx.bus
State Sync Protocol

State synchronization uses a simple key-value model:

Local write (immediate):

stateSync.set("theme", "dark");
// 1. Write to localStorage immediately: commandcenter.state.theme = "dark"
// 2. Debounce 500ms, then send to gateway:

Remote sync (debounced):

{
    "jsonrpc": "2.0",
    "id": "cc-req-042",
    "method": "state.set",
    "params": {
        "key": "commandcenter.state.theme",
        "value": "dark",
        "timestamp": "2026-03-29T10:30:22.456Z"
    }
}

Conflict resolution: Last-write-wins based on timestamp. On reconnect, state.pull retrieves all remote state; keys with newer remote timestamps overwrite local.

Redis-Backed Shared State

State sync persists through the gateway to Redis:

orchestrata:commandcenter:state:{client_id}:{key}   -- HASH {value, timestamp}
orchestrata:commandcenter:state:{client_id}:keys     -- SET of all keys

TTL: None (persistent until explicitly deleted).

Configuration

Runtime configuration via configs/command-center.json:

{
    "gateway": {
        "url": "ws://10.53.2.13:8765",
        "auth_strategy": "static_token",
        "reconnect_max_interval_seconds": 30,
        "rpc_timeout_seconds": 10,
        "rpc_queue_max": 100
    },
    "state_sync": {
        "debounce_ms": 500,
        "conflict_resolution": "last_write_wins"
    },
    "notifications": {
        "desktop_enabled": true,
        "max_stored": 200
    },
    "layout": {
        "default_profile": "development",
        "profiles": {
            "development": {
                "gadgets": [
                    {"id": "orchestrata-session-manager", "position": {"col": 0, "row": 0}, "size": {"columns": 1, "rows": 1}},
                    {"id": "orchestrata-cxp-feed", "position": {"col": 1, "row": 0}, "size": {"columns": 2, "rows": 2}},
                    {"id": "orchestrata-volk-status", "position": {"col": 3, "row": 0}, "size": {"columns": 1, "rows": 1}},
                    {"id": "orchestrata-claude-chat", "position": {"col": 0, "row": 1}, "size": {"columns": 1, "rows": 2}},
                    {"id": "orchestrata-task-board", "position": {"col": 3, "row": 1}, "size": {"columns": 1, "rows": 1}}
                ]
            },
            "monitoring": {
                "gadgets": [
                    {"id": "orchestrata-cxp-feed", "position": {"col": 0, "row": 0}, "size": {"columns": 2, "rows": 2}},
                    {"id": "orchestrata-volk-status", "position": {"col": 2, "row": 0}, "size": {"columns": 2, "rows": 1}},
                    {"id": "orchestrata-qa-dashboard", "position": {"col": 2, "row": 1}, "size": {"columns": 2, "rows": 1}},
                    {"id": "orchestrata-audit-trail", "position": {"col": 0, "row": 2}, "size": {"columns": 4, "rows": 1}}
                ]
            }
        }
    },
    "theme": {
        "default": "system"
    },
    "gadgets": {
        "registry_path": "gadgets/",
        "max_instances": 20,
        "hot_reload": false
    }
}
Integration Points
Component Integration
SPEC-014 WebSocket Gateway Primary data channel -- all RPC calls and event subscriptions
VizInt Portal Framework Gadget lifecycle, chrome, ctx.bus, providers, grid layout
orchestrata-session Session management via session.* RPC methods (7 methods)
orchestrata-cxp CXP traffic observation via cxp.* RPC methods
orchestrata-governance Governance decisions via governance.* RPC methods
orchestrata-knowledge Knowledge graph queries via knowledge.* RPC methods
orchestrata-kernel Kernel events via kernel.events subscription
SessionHandler handlers/session.py -- Neo4j-backed session RPC
ProjectsHandler handlers/projects.py -- Neo4j-backed project/task RPC
context.json Deferred work and session state (read via session RPC)
Redis (test fleet 10.53.2.11; from active env profile) State sync persistence, notification storage, session caching
Memgraph KG (test fleet 10.53.2.10:7687, orchkg database) Knowledge graph (558K+ nodes), project data, task storage
Aladhan Prayer API Prayer time calculations (via Chronus provider)
Knowledge Graph Statistics

The Memgraph knowledge graph backing the Command Center contains:

Category Count
Total nodes 558K+
CXP packets 223K
Test results 156K
Sessions 6K
Requirements 2.7K
User stories 147
Source files 439
Classes 934
Functions 522
Packages 23
Prolog rules 28K
Deployment
Component Address Details
VizInt UI http://10.53.2.13:5000 (test fleet example) python3 -m http.server 5000 on container
WebSocket Gateway ws://10.53.2.13:8765 (test fleet example) SPEC-014 gateway, JSON-RPC 2.0
Redis 10.53.2.11 (test fleet) Session state, caching
Memgraph KG 10.53.2.10:7687 (test fleet) Knowledge graph (558K+ nodes), orchkg database

Endpoints come from the active env profile (ORCHESTRATA_ENV_PROFILE, default test); the addresses above are the test fleet (10.53.2.x).

Development mode: Set GATEWAY_ALLOW_ANONYMOUS=true to bypass authentication.

Verified: Playwright E2E tests on Firefox confirm full connection lifecycle, gadget rendering, theme toggle, and WebSocket state management.

Internal Specs Directory

The vizint-ui/Specs/ directory contains 23 internal specification files:

These are internal to the VizInt portal framework and pre-date the Orchestrata spec system.


Success Criteria

  1. Gateway Connection: Command Center connects to SPEC-014 gateway at ws://10.53.2.13:8765, authenticates, and maintains connection with automatic reconnection (exponential backoff, max 30s)
  2. Real-Time Visualization: CXP traffic, volk lifecycle events, and governance decisions displayed in their respective gadgets within 200ms of occurrence
  3. Session Control: Users can start, close, and manage sessions entirely through the dashboard via session.* RPC methods without CLI commands
  4. Task Management: Tasks created and managed through the dashboard via projects.* RPC methods with Neo4j backing
  5. Claude Chat: Users can converse with Claude through the chat gadget (226 LOC) with markdown rendering and thread management
  6. QA Visibility: Test results, coverage trends, and gate status visible and updated in real-time
  7. Notifications: Escalations and decision requests surface as desktop and in-dashboard notifications within 1 second (max 200 stored)
  8. Offline Resilience: Dashboard functions in read-only mode when gateway is disconnected, using cached localStorage state
  9. Performance: Initial load < 2MB, gadget render < 100ms, 60fps scrolling, < 100MB memory with 10 active gadgets
  10. Gadget Coverage: All 10 P1 production gadgets and 21 personal/specialized gadgets implemented and functional
  11. Gateway Handlers: SessionHandler (7 methods) and ProjectsHandler (4 methods) operational with Neo4j backing and 10s timeouts
  12. Test Coverage: Playwright E2E tests (11+ on Firefox) and Vitest unit tests for all bridge layer components pass

Visual Architecture

Class Diagram

Diagram source shown as text: Mermaid could not parse it (Error: Parse error on line 12:).

classDiagram-direction LR
    class VizIntWebUI {
        +__init__(host: str = 'localhost', port: int = 8765)
        +async start()
        +async shutdown()
        +async add_project(project_data: dict[str, Any])
        +async broadcast_edit_complete(file_path: str, result: dict[str, Any])
        +async update_task_status(task_id: str, status: str)
        +async get_projects(): list[dict[str, Any]]
    }
GadgetManifest Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "GadgetManifest",
    "type": "object",
    "required": ["id", "name", "version", "description", "entry", "category"],
    "properties": {
        "id": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9-]*$",
            "description": "Unique gadget identifier."
        },
        "name": {
            "type": "string",
            "description": "Human-readable display name."
        },
        "version": {
            "type": "string",
            "pattern": "^\\d+\\.\\d+\\.\\d+$"
        },
        "description": {
            "type": "string",
            "maxLength": 200
        },
        "entry": {
            "type": "string",
            "description": "ES module URL relative to gadgets/ directory."
        },
        "icon": {
            "type": "string",
            "description": "Icon identifier or SVG path."
        },
        "category": {
            "type": "string",
            "enum": ["orchestrata", "productivity", "plugin"]
        },
        "dependencies": {
            "type": "array",
            "items": {"type": "string"},
            "description": "Required bridge or provider IDs."
        },
        "min_api_version": {
            "type": "string",
            "pattern": "^\\d+\\.\\d+\\.\\d+$"
        },
        "default_size": {
            "type": "object",
            "properties": {
                "columns": {"type": "integer", "minimum": 1, "maximum": 4},
                "rows": {"type": "integer", "minimum": 1, "maximum": 4}
            }
        },
        "supports_multi_instance": {
            "type": "boolean",
            "default": false
        },
        "config_schema": {
            "type": "object",
            "description": "JSON Schema for gadget-specific settings."
        }
    },
    "additionalProperties": false
}
WebSocketBridge Message Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "WebSocketBridgeOutboundMessage",
    "type": "object",
    "required": ["jsonrpc", "method"],
    "properties": {
        "jsonrpc": {"type": "string", "const": "2.0"},
        "id": {
            "type": "string",
            "pattern": "^cc-req-\\d+$",
            "description": "Client-generated request ID with cc-req- prefix."
        },
        "method": {"type": "string"},
        "params": {"type": "object"}
    }
}
StateSyncEntry Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "StateSyncEntry",
    "type": "object",
    "required": ["key", "value", "timestamp"],
    "properties": {
        "key": {
            "type": "string",
            "pattern": "^commandcenter\\.state\\..+$"
        },
        "value": {
            "description": "Any JSON-serializable value."
        },
        "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Used for last-write-wins conflict resolution."
        }
    }
}
NotificationEntry Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "NotificationEntry",
    "type": "object",
    "required": ["id", "timestamp", "type", "priority", "title", "body"],
    "properties": {
        "id": {"type": "string"},
        "timestamp": {"type": "string", "format": "date-time"},
        "type": {
            "type": "string",
            "enum": ["escalation", "error", "decision_needed", "info"]
        },
        "priority": {
            "type": "string",
            "enum": ["info", "warning", "error", "critical"]
        },
        "title": {"type": "string", "maxLength": 200},
        "body": {"type": "string", "maxLength": 1000},
        "source_topic": {"type": "string"},
        "source_event": {"type": "object"},
        "read": {"type": "boolean", "default": false},
        "gadget_target": {
            "type": ["string", "null"],
            "description": "Gadget ID to navigate to on click."
        }
    }
}
LayoutProfile Schema
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "title": "LayoutProfile",
    "type": "object",
    "required": ["name", "gadgets"],
    "properties": {
        "name": {"type": "string"},
        "gadgets": {
            "type": "array",
            "items": {
                "type": "object",
                "required": ["id", "position", "size"],
                "properties": {
                    "id": {"type": "string"},
                    "position": {
                        "type": "object",
                        "required": ["col", "row"],
                        "properties": {
                            "col": {"type": "integer", "minimum": 0},
                            "row": {"type": "integer", "minimum": 0}
                        }
                    },
                    "size": {
                        "type": "object",
                        "required": ["columns", "rows"],
                        "properties": {
                            "columns": {"type": "integer", "minimum": 1, "maximum": 4},
                            "rows": {"type": "integer", "minimum": 1, "maximum": 4}
                        }
                    }
                }
            }
        }
    }
}

Error Conditions

ID Condition Handling
ERR-001 WebSocket connection to SPEC-014 gateway fails on initial connect Display connection error overlay, retry with exponential backoff (1s, 2s, 4s, 8s, 16s, max 30s)
ERR-002 Authentication with gateway fails (error code -32001) Display authentication error with gateway's data.reason, prompt user to verify token
ERR-003 Gateway connection drops during operation Transition to reconnecting state, display visual indicator, queue outbound RPC calls (max 100), attempt reconnection with exponential backoff
ERR-004 Gadget ES module fails to import (404 or syntax error) Display error boundary message within chrome frame without affecting other gadgets
ERR-005 Gadget mount() lifecycle method throws exception Unmount gadget, log error, display error card in grid cell
ERR-006 Gadget declares min_api_version higher than CommandCenter.API_VERSION Do not load gadget, show version mismatch warning in registry panel
ERR-007 localStorage is unavailable or full Fall back to in-memory storage, log warning, continue remote sync via gateway
ERR-008 State sync detects conflict (both local and remote have newer timestamps) Resolve via last-write-wins strategy based on timestamp
ERR-009 Desktop notifications denied by browser Fall back to in-app notifications only, do not re-prompt
ERR-010 RPC call queue exceeds 100 pending requests during disconnection Reject subsequent calls with QueueOverflowError for calling gadget to handle
ERR-011 More than 20 gadgets mounted simultaneously (exceeding max_instances) Reject additional mounts with capacity error
ERR-012 Gateway sends event for topic with no local subscribers Silently discard event without error
ERR-013 Gadget configuration fails validation against manifest config_schema Use default values, log configuration warning
ERR-014 Reconnection exhausts all retry attempts (10 at max interval) Display persistent connection failure banner with manual retry button
ERR-015 Neo4j query in SessionHandler or ProjectsHandler exceeds 10s timeout Return timeout error to client
ERR-016 NotificationManager storage exceeds 200 entries Discard oldest notifications to maintain cap

Performance Requirements

For testing requirements, see ## Testing.


Definition of Done


Examples

Example: Command Center Initialization
import { CommandCenterApp } from './app.js';

const config = await fetch('configs/command-center.json').then(r => r.json());
const cc = new CommandCenterApp();

await cc.initialize(config);
// 1. WebSocketBridge connects to ws://10.53.2.13:8765
// 2. Authenticates with static_token
// 3. GadgetRegistry loads manifests from gadgets/
// 4. StateSync pulls remote state (debounced 500ms, last-write-wins)
// 5. NotificationManager requests desktop notification permission

await cc.mountDefaultLayout();
// Mounts gadgets from the active layout profile into the grid
// Development profile: 5 gadgets
// Monitoring profile: 4 gadgets
Example: Gadget Subscribing to CXP Events
// Inside cxp-feed.js gadget
export default class CXPFeedGadget {
    async mount(ctx) {
        this.bridge = ctx.resolve('GadgetBridge');
        this.subscriptionId = await this.bridge.subscribe(
            'cxp.traffic',
            { volk_id: 'U:Cd' },
            (event) => this.renderPacket(event)
        );
    }

    renderPacket(event) {
        const row = document.createElement('div');
        row.className = 'cxp-packet-row';
        row.textContent = `${event.payload.from} -> ${event.payload.to}: ${event.payload.subject}`;
        this.container.prepend(row);
    }

    async unmount() {
        await this.bridge.unsubscribe(this.subscriptionId);
    }
}
Example: Session RPC via Gateway Handler
// Frontend: Get active session
const result = await bridge.call('session.active', {});
// Returns: { session_id: string, session_number: number, status: string, started_at: string, ended_at: string|null, metadata: object }

// Frontend: Create a new task
const task = await bridge.call('projects.taskCreate', {
    project: 'orchestrata',
    title: 'Implement compact volk view',
    status: 'not_started',
    priority: 'medium'
});
// Returns: { task_id: string, created_at: string, updated_at: string, status: string, priority: string }
Example: State Sync Usage
// Save gadget-specific settings
stateSync.set('commandcenter.state.cxp-feed.filters', { volk_id: 'U:Cd' });
// Writes to localStorage immediately, debounced sync to gateway after 500ms

// Read settings (local-first)
const filters = stateSync.get('commandcenter.state.cxp-feed.filters');
// Returns from localStorage if available, otherwise null
Example: Notification from Governance Escalation
{
    "id": "notif-2026-03-29-042",
    "timestamp": "2026-03-29T10:30:22Z",
    "type": "escalation",
    "priority": "critical",
    "title": "Governance Escalation: U:Cd budget exceeded",
    "body": "CodeDirector agent exceeded token budget for session-089. Requires approval to continue.",
    "source_topic": "governance.decisions",
    "source_event": {
        "volk_id": "U:Cd",
        "action": "token_request",
        "result": "escalated",
        "article": "III",
        "details": "Budget limit 50000 tokens exceeded (current: 52340)"
    },
    "read": false,
    "gadget_target": "orchestrata-audit-trail"
}

Security

Client-Side Security

NFR-005: Client-Side Security

Plugin Security

NFR-006: Plugin Gadgets


Governance

Prolog Governance Predicates
%% Command Center client access
commandcenter_access(ClientId, dashboard) :-
    gateway_access(ClientId, read_only).

commandcenter_access(ClientId, control) :-
    gateway_access(ClientId, read_write).

commandcenter_access(ClientId, admin) :-
    gateway_access(ClientId, admin).

%% Gadget-level permissions
commandcenter_can_mount(ClientId, GadgetId) :-
    commandcenter_access(ClientId, _),
    gadget_registered(GadgetId),
    \+ gadget_restricted(GadgetId).

commandcenter_can_mount(ClientId, GadgetId) :-
    commandcenter_access(ClientId, admin),
    gadget_registered(GadgetId).

%% Restricted gadgets require elevated access
gadget_restricted('orchestrata-kg-explorer').
gadget_restricted('orchestrata-audit-trail').

%% Notification routing
commandcenter_notify(ClientId, escalation) :-
    commandcenter_access(ClientId, control).
commandcenter_notify(ClientId, error) :-
    commandcenter_access(ClientId, dashboard).
commandcenter_notify(ClientId, decision_needed) :-
    commandcenter_access(ClientId, control).

Testing

Test Framework

Vitest Unit Tests: ESM-native, fast, Jest-compatible API

Playwright E2E Tests (dashboard.spec.js): 11+ tests on Firefox

Custom WsTestServer: Lightweight JSON-RPC mock server for unit tests

No mocking policy enforced: Tests use real WebSocket connections, real DOM (JSDOM for Vitest, real browser for Playwright), real localStorage.

Testability Considerations

API Contracts

Contract: Command Center Bridge Protocol (contracts/commandcenter/bridge-v1.0.0.yaml)
info:
  title: VizInt Command Center Bridge Protocol
  version: 1.0.0
  spec_id: 016-vizint-command-center
  spec_version: 2.0.0
  maturity: stable
  transport: websocket
  protocol: json-rpc-2.0
  consumer: vizint-command-center
  provider: 014-websocket-gateway

connection:
  url_pattern: "ws://{host}:{port}"
  default_port: 18790
  auth_strategy: static_token
  request_id_prefix: "cc-req-"
  reconnect:
    backoff_initial_ms: 1000
    backoff_max_ms: 30000
    backoff_multiplier: 2
    max_attempts: null

rpc_methods:
  session:
    - method: session.active
      description: Get current active session info
      handler: SessionHandler
    - method: session.list
      description: List all active sessions
      handler: SessionHandler
    - method: session.get
      description: Get session by ID with context and facts
      handler: SessionHandler
      params: [session_id]
    - method: session.open
      description: Create new session with type and metadata
      handler: SessionHandler
      params: [type, metadata]
    - method: session.close
      description: Close session by ID
      handler: SessionHandler
      params: [session_id]
    - method: session.events
      description: Subscribe to session lifecycle events
      handler: SessionHandler
    - method: session.facts.subscribe
      description: Subscribe to fact emissions
      handler: SessionHandler
  projects:
    - method: projects.list
      description: List projects from Neo4j (name, path, status, language)
      handler: ProjectsHandler
    - method: projects.get
      description: Get project by name with tasks and sessions
      handler: ProjectsHandler
      params: [name]
    - method: projects.tasks
      description: List tasks with filtering by status (limit 1000)
      handler: ProjectsHandler
      params: [status, limit]
    - method: projects.taskCreate
      description: Create task in Neo4j
      handler: ProjectsHandler
      params: [project, title, status, priority]

subscriptions:
  cxp.traffic:
    consumer_gadgets: [cxp-feed, claude-chat]
    filters_supported: [volk_id, thread_id, subject, delivery_status]
  volk.lifecycle:
    consumer_gadgets: [volk-status]
    filters_supported: [volk_alias]
  governance.decisions:
    consumer_gadgets: [audit-trail, notification-center]
    filters_supported: [volk_id, result, action]
  session.events:
    consumer_gadgets: [session-manager, notification-center]
    filters_supported: [session_id, event_type]
  kernel.events:
    consumer_gadgets: [notification-center]
    filters_supported: []
  gateway.presence:
    consumer_gadgets: [notification-center]
    filters_supported: []

state_sync:
  key_prefix: "commandcenter.state."
  conflict_resolution: last_write_wins
  debounce_ms: 500
  rpc_methods:
    set: "state.set"
    get: "state.get"
    delete: "state.delete"
    pull: "state.pull"

notifications:
  max_stored: 200
  classification_rules:
    - topic: "governance.decisions"
      condition: "result == 'escalated'"
      type: escalation
      priority: critical
    - topic: "governance.decisions"
      condition: "result == 'deny'"
      type: decision_needed
      priority: warning
    - topic: "kernel.events"
      condition: "event_type == 'error'"
      type: error
      priority: error
    - topic: "session.events"
      condition: "event_type == 'closed'"
      type: info
      priority: info

gadget_manifests:
  - id: orchestrata-project-explorer
    category: orchestrata
    gateway_methods: [knowledge.nodes, session.list]
    gateway_subscriptions: []
  - id: orchestrata-session-manager
    category: orchestrata
    gateway_methods: [session.active, session.open, session.close, session.get, session.list]
    gateway_subscriptions: [session.events, session.facts.subscribe]
  - id: orchestrata-cxp-feed
    category: orchestrata
    gateway_methods: [cxp.subscribe, cxp.unsubscribe, cxp.status]
    gateway_subscriptions: [cxp.traffic]
  - id: orchestrata-volk-status
    category: orchestrata
    gateway_methods: [volk.list, volk.get]
    gateway_subscriptions: [volk.lifecycle]
  - id: orchestrata-claude-chat
    category: orchestrata
    gateway_methods: [cxp.send]
    gateway_subscriptions: [cxp.traffic]
  - id: orchestrata-task-board
    category: orchestrata
    gateway_methods: [projects.tasks, projects.taskCreate]
    gateway_subscriptions: [session.events]
  - id: orchestrata-qa-dashboard
    category: orchestrata
    gateway_methods: [knowledge.query]
    gateway_subscriptions: [session.events]
  - id: orchestrata-audit-trail
    category: orchestrata
    gateway_methods: [governance.query]
    gateway_subscriptions: [governance.decisions]
  - id: orchestrata-kg-explorer
    category: orchestrata
    gateway_methods: [knowledge.query, knowledge.nodes, knowledge.relationships]
    gateway_subscriptions: []
  - id: orchestrata-notification-center
    category: orchestrata
    gateway_methods: []
    gateway_subscriptions: [governance.decisions, kernel.events, session.events]

performance:
  initial_load_max_bytes: 2097152
  gadget_render_p95_ms: 100
  rpc_roundtrip_p95_ms: 200
  event_display_p95_ms: 200
  max_memory_mb: 100
  target_fps: 60
  neo4j_query_timeout_ms: 10000

security:
  token_storage: localStorage
  csp_required: true
  xss_prevention: true
  origin_validation: true
  anonymous_dev_mode: GATEWAY_ALLOW_ANONYMOUS

spec_traceability:
  spec_id: "016-vizint-command-center"
  spec_version: "2.0.0"
  user_stories:
    - "US-001"
    - "US-002"
    - "US-003"
    - "US-004"
    - "US-005"
    - "US-006"
    - "US-007"
    - "US-008"
    - "US-009"
    - "US-010"
    - "US-011"
    - "US-012"
    - "US-013"
    - "US-014"

Observability

Logging Requirements
  1. Component Logging
    • Log all major operations with appropriate log levels
    • Include correlation IDs for request tracing
    • Log performance metrics for critical operations
    • Log errors with full context for debugging
Metrics Requirements
  1. Performance Metrics
    • Operation duration histograms
    • Request/error rate counters
    • Resource utilization gauges
    • Business metrics relevant to domain
Tracing Requirements
  1. Distributed Tracing
    • Trace propagation across component boundaries
    • Span attributes for domain-specific context
    • Trace sampling based on operational needs
Alerting Requirements
  1. Critical Alerts
    • Error rate spikes
    • Performance degradation
    • Resource exhaustion
    • Business metric anomalies
Dashboard Requirements
  1. Operational Dashboard
    • Real-time system health
    • Performance trends
    • Error analysis
    • Resource monitoring

Revision History

Date Version Author Changes
2026-03-28 1.0.0 Mohamed Initial specification
2026-03-28 1.0.0 Mohamed Added Data Models, Error Conditions, Performance Requirements, Testability, DoD, Terminology, Examples, Contracts sections per spec standard improvements
2026-03-29 2.0.0 Mohamed Major update: documented all 31 gadgets (10 P1 + 21 personal/specialized), added SessionHandler (7 methods) and ProjectsHandler (4 methods) gateway integration, added US-013/US-014 for gateway handlers, updated acceptance criteria checkboxes to reflect implementation state, documented portal framework (bus.js, portal.js, registry.js, chrome.js, shared.js), added KG statistics (558K+ nodes), documented deployment addresses, added configuration as JSON, documented test infrastructure (Playwright E2E on Firefox, Vitest units, WsTestServer), added MiniMax and OpenCode as contributors, updated contract with full RPC method inventory