ADR: Build a generic "canvas-mode" shell in nova-frontend-litjs instead of a console-specific chat UI¶
Context¶
The Figma flow for new-hire-preboarding-console (design/figma-export.md,
node 576:13854) specifies every screen as the same shell: a persistent
chat-glass-panel (the "Nova" conversational agent, left) plus a canvas
(the step-specific content, right — heading, body, and primary/secondary CTA
buttons). The candidate advances either by talking to Nova or by clicking a
canvas button; both must drive the same step state.
No such component exists today. A repo review across the four candidate homes for this UI turned up:
nova-frontend-litjs/src/policy-editor/— the only existing two-panel "chat left, content right" component in the codebase. It's a real precedent for panel layout and for a chat turn triggering a change in the other panel, but it is wired specifically tonova-advisor-agent's own WebSocket protocol (/ws/chat+/ws/yjs/{room}for Yjs collaborative document editing) and to policy-review semantics (accept/decline changes). Extending it directly would mean either dragging Yjs/policy concepts into onboarding, or forking it — both wrong.nova-frontend-litjs/src/nora-widget-ionic/home-page-web.ts— the generic superagent chat surface used across Nova. It is single-pane: full chat overlay with a step accordion rendered inside the chat thread (nova-status-accordion), not a separate content panel. Its SSE contract (agent_dispatch/fa_node/agent_result/ text chunks, pernova-frontend-litjs's ownflow.md) has no notion of "render this in a side panel."nova-superagent-agent— grepped for any existing widget-render directive (render_widget,ui_action,open_widget, etc.). None exists. The agent can stream text and step-status updates into a chat thread; it cannot currently instruct a frontend to show specific canvas content.nova-frontend-sn-app— a passive ServiceNow portal shell that loadssp_instancewidgets (including the litjs bundle). It has no canvas concept of its own and isn't the runtime host for the guest console anyway (nova-guest-console-appis a standalone Novaworks-portal app, per its own KB).nova-guest-console-app— currently a plain task-list React app with no persistent-chat-driving-canvas behavior at all.
Building this as a one-off inside nova-guest-console-app's React frontend
would satisfy this Feature alone, but the explicit ask was for something
reusable across web, mobile (nova-frontend-mobile), and SN-hosted surfaces
— the same reuse boundary every other nova-frontend-litjs component
already respects.
Decision¶
Build a new, generic canvas-mode shell component in
nova-frontend-litjs, not inside nova-guest-console-app and not as an
extension of policy-editor:
- New component (name TBD at implementation, e.g.
nova-canvas-shell): persistent chat panel (reusingnora-ask-widget/nora-chat-inputprimitives, notpolicy-editor's WS client) + a swappablecanvasslot that any consumer fills with step-specific content (heading, body, CTA buttons) — modeled on the Figma shell'sstageLabel → title → subtitle → contentStack → ctastructure, generalized rather than hardcoded to onboarding. - The canvas advances via either input path, both converging on the same step-state update: a canvas CTA button click, or a chat-driven directive from the agent.
- The chat-driven path requires new capability in
nova-superagent-agent: an explicit SSE directive (e.g.canvas_stepor similar — exact shape is an implementation detail, not decided here) distinct from today's text/step-accordion vocabulary. This is real backend work, not just a frontend component — call it out as its own task when this Feature Set reaches Construction. policy-editorstays exactly as it is (Advisor-specific, WS/Yjs-based). It's cited here as prior art for panel CSS/layout conventions to borrow from, not a dependency to extend.nova-guest-console-app's React frontend consumes the new shell the same way it already consumes other@novaworks/lit-componentswidgets (file:./lit-componentslocal dependency, per its KB) — no new integration pattern needed on that side once the component exists.
Consequences¶
new-hire-preboarding-console/spec.md's UX Description/Key User Flows depend on this shared component rather than a console-specific chat widget — implementation can't start on those flows until the shell (or at least its canvas-slot contract) exists innova-frontend-litjs.- Mobile (
nova-frontend-mobile) and any future SN-hosted step-driven flow get this pattern for free once built, instead of each reimplementing a two-panel chat UI — the reuse boundary this ADR exists to protect. - Adds a real, non-trivial backend task to
nova-superagent-agent(the new SSE directive) that isn't captured in this Feature'sspec.mdyet — flagged as an open item there and must be scoped beforeimplementation-plan.mdis written for this Feature. - Risk: without a concrete SSE directive shape agreed early, frontend and agent work can drift out of sync — the directive's request/response shape should be nailed down (even informally) before either side starts coding, not discovered independently by both.
- Risk:
policy-editorand the new shell will look superficially similar (both two-panel, both chat-driven) — future contributors need to be told explicitly not to converge them, since their protocols and domains are genuinely different; see the KB pattern note added tonova-frontend-litjs/skills.md.