Orchestrata Ultimate › Plans › spec-audit › reverify-2026-10-18 › G-gateway-ui
Cluster G — Gateway, UI, TUI & plugins — RE-VERIFICATION (2026-10-18)
Source: plans/spec-audit/reverify-2026-10-18/G-gateway-ui.md at 8a2cb42ad · last changed 2026-10-18 · first committed 2026-10-18 · 150 lines.
Prose pending.
Plan text
Cluster G — Gateway, UI, TUI & plugins — RE-VERIFICATION (2026-10-18)
Re-verification against CURRENT code (branch components, HEAD de9e996f2). Builds on
docs/spec-gap-register.md (2026-07-14) and plans/spec-audit/G-gateway-ui.md (session 195).
Method: code-only judgement (spec - [ ] boxes ignored); Python structure via the AST toolkit
(symbols / refs / source) — no hand-reading of .py files; vizint-ui/ JS inspected via ls/grep.
Main-session findings treated as authoritative (not re-derived): SPEC-014 FR-021 HTTP surface CLOSED.
What changed vs. the session-195 audit (headline)
- SPEC-014 FR-021/022 (HTTP health/metrics) is now CLOSED —
gateway/http_surface.pyserves/health,/ready,/metrics(Prometheus) and is wired atgateway/server.py:903 _start_http_surface. - SPEC-015 is no longer orphaned — the plugin manager is now constructed/booted from
kernel/cli_main.py:475 _boot_plugin_system(called from_boot_monolithicat cli_main.py:754), and theorchestrataconsole entry now exists (pyproject.toml:122). The plugin CLI andplugins.*RPC remain unbuilt. - SPEC-050
route_commandlatent bug is fixed (now usesasyncio.iscoroutine(result), no__wrapped__on lambdas) but remains orphaned (0 production refs) and maps only 6 commands.
SPEC-014 WebSocket Gateway — DIVERGENCE (functional surface + observability DONE; auth-strategy abstraction is unbuilt structure)
- Specifies: Real-time WS control plane — JSON-RPC 2.0 dispatch, pluggable auth (
IAuthStrategy+ Static/HMAC/Prolog), pub/sub topics, ring-buffer replay, heartbeat, PAM++ gateway predicates, HTTP health/metrics, audit. - Verified:
- ✅ WS server + lifecycle —
WebSocketGatewaygateway/server.py:374;_start_websocket_serverserver.py:867;start/stopserver.py:931/966. - ✅ JSON-RPC dispatch + full method surface —
RPCHandler.dispatchgateway/rpc.py:340;MessageProcessorgateway/protocol.py:27. - ✅ All FR-015–FR-020 RPC methods registered —
gateway/method_table.py(METHODStuple):cxp.send/subscribe/unsubscribe/status(138–154),volk.list/get/register/deregister/lifecycle(161–171),session.list/get/active/open/close/events/facts.subscribe(178–203),governance.decisions/query/evaluate/rules(211–232),knowledge.query/nodes/relationships(+ extras, 240–282),gateway.ping/info/clients/replay(69–85). - ✅ Ring buffer + replay —
RedisRingBuffergateway/ring_buffer.py:53. - ✅ Heartbeat —
ConnectionManagergateway/session.py:18; heartbeat loopserver.py:1058. - ✅ Audit trail (FR-024) —
AuditWritergateway/audit.py:72. - ✅ HTTP health/metrics CLOSED (FR-021/022) —
build_gateway_http_appgateway/http_surface.py:32(routes/health,/api/v1/health,/ready,/metricsviaprometheus_client; mountspostman.healthrouter),serve_httphttp_surface.py:133; wired at_start_http_surfacegateway/server.py:903; confighealth_enabledgateway/config.py:159,http_port:165,http_host:175,http_bind_host:179. - ✅ Serve CLI (US-010) —
gateway/cli.pyserve|version(prior-audit confirmed; unchanged). - ⚠️ Auth is a divergence, not a gap (FR-005–008):
TokenAuthenticatorgateway/auth.py:19(JWT) +StaticTokenAuthenticatorgateway/auth.py:120(static token + Redis rotation).symbols IAuthStrategy→ 0;symbols StaticTokenAuth|HMACAuth|PrologPolicyAuth→ 0 (only the two concrete classes above exist). No pluggableIAuthStrategyprotocol, no HMAC, no Prolog policy auth. - ⚠️ FR-001 structural divergence:
symbols IGatewayServer→ 0;ComponentTypeenum (core/protocols/base.py:24-37) hasAPI_GATEWAYbut noGATEWAYmember. The concrete class isWebSocketGateway, constructed directly. - ⚠️ FR-023 PAM++ gateway predicates (
gateway_access/gateway_can_execute/…) are the Prolog side of the same auth divergence — not shipped. - ℹ️ Minor stale-config drift (not a gap): default port
8765(gateway/config.py:156), hostlocalhost(:154), vs. spec's18790/0.0.0.0; spec namesmetrics_port/metrics_enabledbut code useshttp_port/health_enabled.
- ✅ WS server + lifecycle —
- Remaining work / plan:
- Scope: spec-text update — record the JWT/static-token auth (no
IAuthStrategy, no HMAC/Prolog) and theIGatewayServer/ComponentType.GATEWAYabsence as intentional divergences, and the port/config drift. No code work unless HMAC/Prolog auth is genuinely required. - Target files:
specs/014-websocket-gateway/spec.md(FR-001, FR-005–008, config block). - Approach: mirror the SPEC-028/SPEC-008 divergence-note pattern already used in the register.
- Dependencies: none (auth-strategy build, if chosen, would be M/L — security surface, needs governance/prolog).
- Effort: S (spec doc). Risk: low. Optional HMAC/Prolog auth build = M/L, med risk.
- Scope: spec-text update — record the JWT/static-token auth (no
- Evidence log:
symbols --pattern WebSocketGateway;symbols --pattern IAuthStrategy→0 symbol(s);symbols --pattern 'StaticTokenAuth|HMACAuth|PrologPolicyAuth|TokenAuthenticator|StaticTokenAuthenticator'→ auth.py:19/120 only;refs IAuthStrategy→0 def, 0 import, 0 use;source gateway.method_table(method list above);source gateway.http_surface(endpoints + prometheus_client);symbols --pattern 'build_gateway_http_app|serve_http|http_bind_host|health_enabled'→ http_surface.py:32/133, config.py:159/179;source core.protocols.base→ ComponentType members (no GATEWAY).
SPEC-015 Plugin SDK — PARTIAL (SDK DONE + now boot-wired; CLI + RPC + DI enum still absent)
- Specifies: Runtime extension framework —
IPluginManager(DIComponentType.PLUGIN_MANAGER), discovery, validation, load/lifecycle, SDK registration (volk/tool/provider/channel/rules/kg), capability governance, resource limits,orchestrata pluginsCLI,plugins.listRPC, audit. - Verified:
- ✅ SDK + manager fully implemented —
PluginManagerplugin/manager.py:49;IPluginManagerplugin/interfaces.py:354(discover/load/unload/reload/get/list/enable/disable/install/uninstall); module functionsinstall_pluginplugin/discovery.py:61,uninstall_plugin:179,enable_plugin:219,disable_plugin:267,discover_plugins:32;list_pluginsplugin/registry.py:195. - ✅ Boot wiring now DONE (closes the orphaned finding) —
_boot_plugin_systemkernel/cli_main.py:475constructsPluginManager, discovers + loads + starts plugins whenORCHESTRATA_PLUGINS_DIRis set, wires tool registration into the SPEC-062ToolRegistry(default_registry()), and returns the pluginVolkRegistryfor projection via_boot_agent_runtime→PipelineRunner(plugin_volk_registry=...); called from_boot_monolithicatcli_main.py:754(refs _boot_plugin_system→ USE cli_main.py:754; dedicated teststests/kernel/test_cli_main_plugin_boot.py). - ✅ Console entry now exists —
pyproject.toml:122orchestrata = "orchestrata_ultimate.kernel.cli_main:main"(closes the session-195 "no console entry" note). - ❌ No
pluginsCLI subcommand (FR-014/015/016) — full symbol scan ofkernel/cli_main.pyshowscli()(:806) with commandsstart/version/health/init/stop/status/config/team/agents/packets/intent/respond/approve/reject/watch/review/governance/check/log/policies/verify/knowledge/query/sessionandmain()(:1690); nodef pluginsanywhere in the tree (symbols --pattern ''grep fordef plugins|plugin_cli→ 0). The boot docstring states it plainly: "Out of scope (not built here): … a plugin CLI/ops surface". - ❌ No
plugins.*gateway RPC (US-007 last criterion) —source gateway.method_tablegrep forplugins|plugin.→ 0;gateway/handlers/has noplugins.py(22 handler modules, none named plugins). - ❌
ComponentType.PLUGIN_MANAGERabsent (FR-001) —ComponentType(core/protocols/base.py:24-37) members: KERNEL, POSTMAN, ORCHESTRATOR, STATE_MANAGER, VOLK_RUNTIME, MEMORY_ENGINE, PROVIDER_MANAGER, ARTIFACT_MANAGER, UI_CONSOLE, API_GATEWAY, SERVICE — no PLUGIN_MANAGER. - ⚠️ Explicitly out of scope per boot docstring: plugin Prolog rule loading, plugin audit trail, hot-reload manifest fix.
- ✅ SDK + manager fully implemented —
- Remaining work / plan:
- Scope: (1) add a
pluginsClick group (list/info/install/uninstall/enable/disable) on the existingcli()group, delegating toplugin/discovery.py+manager.list_plugins(); (2) addComponentType.PLUGIN_MANAGER; (3) add aPluginsHandlerwithplugins.list/plugins.install/… togateway/method_table.py. - Target files:
kernel/cli_main.py(new@cli.group() plugins),core/protocols/base.py(enum member), newgateway/handlers/plugins.py+gateway/method_table.py. - Approach: additive — manager/discovery/registry code is complete and test-shaped; this is thin CLI/RPC adapters + one enum member, not new logic.
- Dependencies: SPEC-014 gateway (RPC), kernel/DI (
ComponentType). - Effort: M. Risk: low–med (ops surface only; the boot wiring already isolates plugin load errors).
- Scope: (1) add a
- Evidence log:
symbols --pattern 'PluginManager|IPluginManager|install_plugin|…';source kernel.cli_main(boot docstring +cli()group);refs _boot_plugin_system→ USE cli_main.py:754;source gateway.method_tablegrepplugins|plugin.→ 0;ls gateway/handlers/→ no plugins.py;source core.protocols.base→ ComponentType members;sed pyproject.toml [project.scripts].
SPEC-016 VizInt Command Center — DONE (confirm register)
- Specifies: Browser command center over SPEC-014 gateway (JSON-RPC/WS); 10 P1 orchestration gadgets + Session/Projects handlers.
- Verified:
- ✅ P1 gadgets present —
vizint-ui/gadgets/ships 14:project-explorer, session-manager, cxp-feed, volk-status, claude-chat, task-board, qa-dashboard, audit-trail, kg-explorer, notification-center(the 10 P1) +orchestrator, debug-panel, calendar, todoist(4 extras). - ✅ Portal + bridge framework —
vizint-ui/lib/:portal.js, bus.js, registry.js, chrome.js, shared.js(+ atlas/chronus/crypto/error-boundary/metrics/performance-overlay/session-handoff/sparkline);vizint-ui/bridge/:websocket-bridge.js, gadget-bridge.js, state-sync.js, notification-manager.js. - ✅ FR-027 SessionHandler —
gateway/handlers/session.py:87(handle_active/list/get/open/close/events/facts_subscribe), registeredsession.*ingateway/method_table.py:178-203. - ✅ FR-028 ProjectsHandler —
gateway/handlers/projects.py:15(handle_list/get/tasks/task_create/task_update), registeredprojects.list/get/tasks/taskCreate/taskUpdatemethod_table.py:289-305. - ✅ Pipeline→UI wiring —
orchestrator.intent+state.*RPC live (session-193 wiring; unchanged). - ℹ️ Spec-accuracy nit (not a gap): spec claims 31 gadgets; repo ships 14 (the 21 "personal" gadgets — flashcards/prayer/iqama/etc. — are upstream-portal inventory, not vendored).
- ✅ P1 gadgets present —
- Remaining work / plan: none for classification DONE. Optional: correct the gadget-inventory count in the spec. Per-US frontend polish items (inline task edit, CSV export, cypher autocomplete) are JS-only polish, outside Python audit scope.
- Evidence log:
ls vizint-ui/gadgets lib bridge(14/13/4 files);symbols --pattern 'SessionHandler|ProjectsHandler'→ session.py:87, projects.py:15;source gateway.method_table(session/projects rows).
SPEC-022 Terminal User Interface — GAP (Design Phase; still unimplemented)
- Specifies: A Textual three-panel app (
tui_app.py+panels/+widgets/+tui.tcss) launched viaorchestrata tui, replacing thepipeline_cli.pyREPL. - Verified:
- ❌ No Textual anywhere —
symbols --pattern 'TUIApp|TUIKernelInterface|ThreadListPanel|CommandPalette|Textual'→ 0 symbols;grep -niE 'textual|tui' pyproject.toml→ 0 (notextualdep). - ❌ No
orchestrata tuicommand —cli()group (kernel/cli_main.py:806) has notuisubcommand;symbols --pattern ''grep fordef tui→ 0. The only "tui" token is the SPEC-050 gateway RPC prefix (tui.*ingateway/handlers/ultimatetui.py+method_table.py), unrelated to a terminal UI. - ⚠️ The REPL to be replaced still exists —
kernel/pipeline_cli.py(basicinput()/print()loop). Spec status is "Design Phase", so this is planned scope, not a regression.
- ❌ No Textual anywhere —
- Remaining work / plan:
- Scope: build the Textual app —
tui_app.py(3-panel grid: ThreadList | Chat | Status + input + header/footer),panels/{thread_list,chat,status}.py,widgets/{input_area,command_palette}.py,tui.tcss; registerorchestrata tui; drive it viaTUIKernelInterface(submit_intent/respond/approve/reject/get_status/subscribe) againstPipelineRunner/PipelineKernel; declaretextual>=0.90in deps. - Target files: new
src/orchestrata_ultimate/tui/package;kernel/cli_main.py(@cli.command() tui);pyproject.toml(textual dep). - Approach: greenfield but well-scoped; reuse
pipeline_clisemantics as the kernel adapter; the gatewaytui.*/orchestrator.intentRPC path is an alternative backend. - Dependencies: SPEC-000 (CLI) subcommand; kernel
PipelineRunner/PipelineKernel(approve/reject overlaps SPEC-023); newtextualdep (must be declared —check-depsgate). - Effort: L (full app). Risk: med (approval workflow couples to Article I governance).
- Scope: build the Textual app —
- Evidence log:
symbols --pattern 'TUIApp|TUIKernelInterface|Textual|…'→ 0;grep -niE 'textual|tui' pyproject.toml→ 0;source kernel.cli_maincli()group (notui).
SPEC-050 CheetahClaws Integration — PARTIAL (multi-agent edit + governance wired; checkpoint/40-cmds/path-traversal/live-diff still missing)
- Specifies: CheetahClaws Rich TUI + 40+ slash commands routed through the kernel, multi-agent (Cd/Qa/Ar/Ux) coordinated edits, PAM++ governance, checkpoint create/restore, multi-provider model switching, live diff, audit.
- Verified:
- ✅ FR-001 multi-agent edit —
MultiAgentCoordinator.dispatch_reviewintegrations/cheetahclaws/__init__.py:144(parallel Cd/Qa/Ar[/Ux], fail-closed viarejecting_feedback:233);UltimateTUI.handle_edit:350;UltimateTUIHandler.handle_editgateway/handlers/ultimatetui.py:54. - ✅ FR-002 governance pre-edit —
GovernanceBridge.can_editintegrations/cheetahclaws/__init__.py:283(10 MB cap, null-byte binary detect, secret-name + blocked-path patterns). - ✅ Live surface wired —
UltimateTUIHandlerexposestui.edit/intent/agents/models/model_switch/readgateway/handlers/ultimatetui.py, registered ingateway/method_table.py:314-332. - ✅ Intent pipeline (FR-009 partial) —
UltimateTUI.handle_intent:431→PipelineRunner.run. - ❌ FR-005 path traversal NOT enforced —
GovernanceBridge.can_editchecks exists/is_dir/10MB/binary/secrets/blocked-list but never rejects..(read full method body; no../Path.resolve/traversal check). TheEditRequestJSON-schema in the spec declares the../pattern; the code does not. - ❌ FR-003/004 checkpoint create/restore NOT wired to the CC surface — no
tui.checkpoint/tui.rewindRPC (source gateway.method_tablegrepcheckpoint|rewind→ 0); no/checkpoint//rewindinroute_command. Real checkpoints exist but are separate subsystems:CheckpointManagersession/checkpoint.py:21(create/restore/list) andPipelineCheckpointkernel/pipeline_checkpoint.py:57, used byorchestrator/pipeline_runner.py:295— none exposed as a CC command. - ⚠️ FR-008 model switch is profile-based, not per-agent —
UltimateTUI._handle_model:514callsselect_profile;tui.model_switch→handle_model_switchultimatetui.py:170→ profile switch. Divergence consistent with SPEC-028 "profiles-only". - ❌ FR-009 "40+ commands" not routed —
route_commandintegrations/cheetahclaws/__init__.py:457maps only 6 (/edit /intent /read /write /agents /model);refs route_command→ 0 production uses (8 uses all intests/integrations/test_cheetahclaws.py). Only ~6tui.*RPC methods exist. - ❌ FR-012 live diff rendering absent —
handle_editreturns a plaindiffstring (f"-{old_string}\n+{new_string}"), no live/annotated diff view. - 🐞 Dead-code note (surface, don't fix):
route_commandis orphaned (0 production refs). The session-195 latent bug (asyncio.iscoroutinefunction(handler.__wrapped__)on lambdas) is fixed — the body now doesresult = handler(); return await result if asyncio.iscoroutine(result) else result. Still candidate for delete or revival with the 40-command router.
- ✅ FR-001 multi-agent edit —
- Remaining work / plan:
- Scope: (1) add
tui.checkpoint/tui.rewind/tui.listRPC + CC handlers delegating to the existingsession/checkpoint.py CheckpointManager(orPipelineCheckpoint) — files+session+KG per FR-003; (2) enforce..rejection inGovernanceBridge.can_edit(FR-005); (3) decide the 40-command scope (route what's real, drop the aspirational catalog + delete/fix deadroute_command); (4) optionally live-diff (FR-012). Reconcile FR-008 to the profile model. - Target files:
integrations/cheetahclaws/__init__.py(path guard, checkpoint methods, remove/repairroute_command),gateway/handlers/ultimatetui.py+gateway/method_table.py(newtui.checkpoint/rewind), spec update for FR-008/FR-009. - Approach: path guard is 4 lines; checkpoint wiring reuses
session/checkpoint.py; the 40-command catalog + live diff is a scope decision. - Dependencies: session subsystem (
CheckpointManager), SPEC-014 gateway RPC, SPEC-016 orchestrator gadget (consumer), SPEC-028 LLM profile design (FR-008), pipeline (PipelineRunner). - Effort: M (checkpoint wiring + path guard + dead-code cleanup). Risk: low–med (restore touches files/session/KG atomically).
- Scope: (1) add
- Evidence log:
symbols --pattern 'MultiAgentCoordinator|UltimateTUI|GovernanceBridge|UltimateTUIHandler|route_command|…';source integrations.cheetahclaws(can_edit + handle_edit + route_command bodies);refs route_command→ 0 production;source gateway.method_tablegrepcheckpoint|rewind→ 0;symbols --pattern 'CheckpointManager|PipelineCheckpoint'→ session/checkpoint.py:21, kernel/pipeline_checkpoint.py:57.
SPEC-051 VizInt UI — DIVERGENCE (deprecated; superseded by SPEC-016 — no action)
- Specifies: FastAPI + HTMX + TailwindCSS web dashboard (
VizIntWebUI, REST/api/projects, Jinja templates, OAuth2, CSRF).spec.md:1declares it DEPRECATED — superseded by SPEC-016; Status = Deprecated. - Verified:
- ✅ Deprecation authoritative —
specs/051-vizint-ui/spec.md:1"⚠️ DEPRECATED … superseded by SPEC-016". - ✅ FastAPI/HTMX app never built —
symbols --pattern VizIntWebUI→ the only hit is the empty WS aliasgateway/server.py:1459(class VizIntWebUI(WebSocketGateway)), not the HTMX server the spec describes; no/api/projectsREST, noapp/routes/, no Jinjatemplates/. - ✅ Real UI is the SPEC-016 zero-build ES-module
vizint-ui/talking to the SPEC-014 WS gateway — intentionally different architecture.
- ✅ Deprecation authoritative —
- Remaining work / plan: none. Keep the spec retired. Do not build the SPEC-051 FastAPI/HTMX stack.
- Evidence log:
symbols --pattern VizIntWebUI→ server.py:1459 (empty alias); spec header read.
Cluster summary table
| Spec | Class | Effort | Hard deps |
|---|---|---|---|
| SPEC-014 WebSocket Gateway | DIVERGENCE (functional + observability DONE; auth-strategy abstraction unbuilt) | S (spec update); M/L only if HMAC/Prolog auth built | governance/Prolog (only if auth built) |
| SPEC-015 Plugin SDK | PARTIAL (SDK + boot wiring DONE; CLI + plugins.* RPC + ComponentType.PLUGIN_MANAGER missing) |
M | SPEC-014 (RPC), kernel/DI (ComponentType) |
| SPEC-016 VizInt Command Center | DONE | — | SPEC-014 gateway, pipeline (done) |
| SPEC-022 TUI | GAP (Design Phase, unimplemented) | L | SPEC-000 (CLI subcommand), kernel PipelineRunner, SPEC-023 (approval), textual dep |
| SPEC-050 CheetahClaws | PARTIAL (checkpoint/40-cmds/path-traversal/live-diff missing; dead route_command) |
M | session CheckpointManager, SPEC-014, SPEC-016, SPEC-028 (models) |
| SPEC-051 VizInt UI | DIVERGENCE (deprecated → SPEC-016) | — | none |
Cross-cluster dependencies noticed
- SPEC-015
pluginsCLI ↔ SPEC-000 CLI, and SPEC-022orchestrata tui↔ SPEC-000 CLI: both hang off thecli()Click group (kernel/cli_main.py:806). Theorchestrataconsole entry now EXISTS (pyproject.toml:122), so these are pure subcommand additions — no console-entry scaffold remains. Sequence 015 and 022 independently off the existing group. - SPEC-015 ↔ SPEC-014:
plugins.listRPC (US-007) is a gateway handler +method_table.pyaddition. - SPEC-016 & SPEC-050 ↔ pipeline: the VizInt orchestrator gadget and the CC
tui.*bridge both consumeorchestrator.intent/PipelineRunner— pipeline contract changes ripple to both UIs. - SPEC-050 ↔ session subsystem: checkpoint wiring reuses
session/checkpoint.py CheckpointManager(session cluster) rather than building new. - SPEC-050 FR-008 ↔ SPEC-028: model switching is profile-based per the SPEC-028 "profiles-only" decision — reconcile the SPEC-050 per-agent-model text there.
- SPEC-014 auth divergence ↔ SPEC-099 (security/auth framework, GAP in master plan): the missing
IAuthStrategy/HMAC/Prolog-auth surface is the gateway slice of the broader SPEC-099 auth gap; sequence any auth-strategy build with SPEC-099, else record the divergence in the spec and close.