ADR-0031: Visual Contract Unification

Date: 2026-03-13 Status: Proposed Author: Architect Agent Supersedes: N/A

1. Context

Jorvis already ships useful visualization capability, but the stack is heterogeneous:

  • backend visualization services and typed visual payloads under analytics-platform/src/visualization/**
  • client/runtime rendering helpers under deploy/jorvis-brand/static/modules/visuals-toolkit.js
  • Open WebUI functions such as functions/mermaid_overlay.py and functions/visuals_toolkit.py
  • markdown/table-like formatting paths outside a single visual contract

This is enough to deliver charts, tables, and Mermaid output, but it leaves one architecture problem unresolved: Jorvis does not yet define one canonical semantic contract for visual output across charts, tables, KPI summaries, and diagram-like renderers.

Without that decision, future visual work risks drifting across:

  • payload schemas
  • server vs client rendering assumptions
  • Mermaid vs chart vs table semantics
  • tool/function output expectations

2. Decision

Jorvis should treat a typed backend-owned visual contract as the canonical truth surface for visual output.

Current and future renderers are adapters around that canonical contract, not independent semantic sources of truth.

2.1 Canonical Model

The canonical visual model should cover at least:

  • charts
  • tables
  • KPI/summary visuals
  • diagram-like visual intents

The existing typed payload work under analytics-platform/src/visualization/** is the correct starting point for that model.

2.2 Renderer Adapters

The following are renderer/adaptation layers, not separate truth sources:

  • backend-rendered chart/image paths
  • client-rendered ECharts paths
  • Mermaid renderers
  • Open WebUI visualization helper/functions

Mermaid should be treated as a diagram renderer or adapter choice, not as a parallel architecture contract that bypasses the canonical visual payload.

Tables should be treated as first-class members of the visual contract, not as an ad hoc formatting side path only.

2.3 Non-Authorization Rule

This ADR does not authorize implementation by itself.

It does not issue GO for:

  • rewriting all current visualization surfaces
  • moving Mermaid into NestJS core
  • removing current function/tool rendering paths
  • introducing new interactive client behavior
  • changing public API contracts immediately

Any such work requires a fresh Stage 0 and fresh exact-head GO.

3. Alternatives Considered

  • Keep all renderers as equal truth surfaces. Rejected: drift risk stays high and testing becomes ambiguous.
  • Treat Mermaid/Open WebUI functions as the primary visual contract. Rejected: too UI-specific and not suitable as the backend semantic source of truth.
  • Treat charts only as the canonical contract and keep tables/diagrams separate. Rejected: continues fragmentation instead of reducing it.

4. Consequences

Positive

  • future visual work gets one semantic contract to target
  • backend, frontend, and tool surfaces can be tested against one truth model
  • tables and Mermaid can be reasoned about as adapters instead of exceptions

Negative

  • current heterogeneous renderer stack remains in place until a later Stage 0 defines the actual unification work
  • some current docs still describe surfaces separately and will need future normalization

5. References

  • analytics-platform/src/visualization/visual-payload.types.ts
  • analytics-platform/src/visualization/visualization.controller.ts
  • analytics-platform/src/visualization/chart.service.ts
  • deploy/jorvis-brand/static/modules/visuals-toolkit.js
  • analytics-platform/functions/mermaid_overlay.py
  • analytics-platform/functions/visuals_toolkit.py
  • docs/architecture/BUSINESS_INTELLIGENCE.md