Skip to main content

ADR-209: Executive Briefing Generator Integration

Status: Accepted Date: 2026-02-17 Deciders: Hal Casteel (CTO) Extends: ADR-197 (Unified Web Publishing Component System)


Context

Problem

CODITECT projects require executive-level briefing dashboards that synthesize project data into actionable narratives for C-suite personas (CEO, CMO, CIO, CFO). The current Web Publishing Platform (WPP, ADR-197) provides rich markdown/JSX/Mermaid rendering with 8 reusable components and 28+ lazy-loaded dashboards, but lacks:

  1. AI-narrated content generation — dashboards display static data; there is no pipeline to generate contextual narratives from structured project data
  2. Interactive decision capture — no pattern for executives to record decisions within dashboards with state persistence across tab switches
  3. Data-driven dashboard assembly — dashboards are hand-authored JSX; there is no mechanism to generate dashboards from database queries + computed metrics
  4. Executive-specific UI primitives — components like progress rings, radar charts, status dots, and expandable cards with AI narratives are not in the shared component library

A prototype executive briefing system has been developed that demonstrates a complete 3-phase pipeline (query → compute → narrate → assemble) producing a 5-tab interactive dashboard from SQLite data. This ADR integrates that capability into the WPP as a general-purpose platform feature.

Scope

This ADR is a general CODITECT coditect-core platform solution. Any CODITECT project (product development, research, consulting, compliance) can generate executive briefings by:

  1. Populating a standardized SQLite schema with project data
  2. Running the Python orchestrator with project-specific configuration
  3. Receiving a fully-rendered JSX dashboard with AI narratives

Current WPP Architecture (ADR-197)

ComponentLOCPurpose
viewer.jsx528Hash-routed viewer with sidebar, search, presentation mode
Sidebar.jsx144Navigation with toggle-all and collapse state
MarkdownRenderer.jsx287unified/remark/rehype pipeline with Mermaid, KaTeX
SearchPanel.jsx156Full-text search across dashboards
ProjectSwitcher.jsx85Multi-project dropdown (ADR-170)
PresentationMode.jsx120Fullscreen dashboard cycling
Breadcrumbs.jsx52Navigation path display
TableOfContents.jsx89Auto-generated heading navigation
28 dashboards~15KLazy-loaded JSX dashboards across categories

New Executive Briefing Components

LayerComponentLOCPurpose
Specexecutive-briefing-generator.md1,225System prompt defining 3-phase pipeline
Speccomponent-data-contracts.md457TypeScript interfaces for 12 data structures
Specmethodology-references.md29724 verified citations with confidence levels
Implgenerate-briefing.py961Python orchestrator (query→compute→narrate→assemble)
Implinit-database.sql520Schema DDL (22 tables + 5 views)
Implseed-*.sql440Representative seed data
Output*-csuite-briefing.jsx1,9765-tab interactive dashboard (gold standard)
Outputexecutive-briefing-data.json867Computed data manifest

Component Diff Analysis

75% reusability — the majority of new code addresses gaps in the existing WPP:

Existing WPPNew BriefingOverlapGap
Sidebar with collapseSidebar with forwardRef, toggleAll80%toggleAll already merged (J.18)
MarkdownRendererN/A (JSX-only)0%No markdown in briefings
SearchPanelN/A0%Briefings use tab navigation
Hash routingTab routing30%Different navigation paradigm
CSS variablesInline T object tokens10%Token unification needed
N/AProgressRing0%New primitive needed
N/ARadarChart0%New primitive needed
N/AStatusDot0%New primitive needed
N/AExpandableCard0%New pattern needed
N/ADecision capture0%New interaction pattern
N/ASQLite data layer0%New data pipeline
N/AAI narrative gen0%New LLM integration

6 Extractable UI Primitives

PrimitiveAtomic LevelExisting in ADR-085?Description
StatusDotAtomNoColored dot (green/amber/red) with optional pulse
BadgeAtomNoStatus label (HIGH/MEDIUM/LOW) with semantic color
SectionTitleAtomNoHeading with icon, persona tag, and accent color
ExpandableCardMoleculeNoClick-to-expand card with animation + AI narrative
ProgressRingMoleculeNoSVG circular progress with percentage label
RadarChartMoleculeNoSVG radar/spider chart (6 axes) with overlay

Decision

D1: Executive Briefing as WPP Dashboard Type

Executive briefings integrate as a new dashboard category in the WPP, not as a separate application.

Implementation:

  • New dashboard category: executive-briefing/ alongside planning/, system/, tracking/
  • Lazy-loaded via existing WPP React.lazy() pattern
  • Accessible through sidebar navigation and hash routing
  • Compatible with search, presentation mode, and multi-project switching

Rationale: Maintaining a single viewer with consistent UX across all dashboard types eliminates tool sprawl. Executives access briefings through the same interface as technical dashboards.

D2: UI Primitive Extraction into Atomic Design Hierarchy (ADR-085)

The 6 UI primitives are extracted into the shared component library following ADR-085's Atomic Design levels:

Atoms (3 new):

  • StatusDot — semantic status indicator (green/amber/red)
  • Badge — labeled status chip with urgency colors
  • SectionTitle — icon + heading + persona tag

Molecules (3 new):

  • ExpandableCard — container with click-to-expand behavior, animation, and slot for AI narrative
  • ProgressRing — SVG circular progress visualization
  • RadarChart — SVG spider chart with current/target overlays

Location: tools/web-publishing-platform/components/atoms/ and components/molecules/

Interface contract: Each primitive accepts a TypeScript props interface documented in component-data-contracts.md.

D3: Design Token Unification with design-system.json (ADR-091)

The executive briefing's inline T object is reconciled with design-system.json as the single source of truth:

T Object Tokendesign-system.json MappingResolution
T.navy (#0B1629)colors.semantic.surface-darkMap to semantic token
T.navyLight (#2D3F5E)colors.semantic.surface-dark-lightAdd to semantic palette
T.teal (#0D9488)colors.brand.primaryAlready exists as primary
T.gold (#C8A951)colors.semantic.highlightAdd highlight token
T.red (#DC2626)colors.semantic.dangerAlready exists
T.amber (#D97706)colors.semantic.warningAlready exists
T.green (#059669)colors.semantic.successAlready exists
T.*Ghost (8-10% opacity)colors.semantic.*-ghostAdd ghost variants
T.headerFrom/To (#4B6DA0/#5B80B2)colors.gradient.headerAdd gradient tokens
T.font (Outfit)typography.fontFamily.displayAlready exists
T.fontMono (JetBrains Mono)typography.fontFamily.monoAlready exists

Tab accent colors are registered as colors.dashboard.tab.*:

  • summary: teal (#0D9488)
  • accomplishments: blue (#3B82F6)
  • decisions: amber (#F59E0B)
  • investment: emerald (#10B981)
  • methodology: indigo (#6366F1)

Runtime: The generated JSX consumes tokens from a T constant that is auto-generated from design-system.json at build time. Claude.ai artifact mode uses inline values since no build step is available.

D4: SQLite + Python Orchestrator Data Layer

Project data flows through a standardized SQLite schema into a Python orchestrator:

Project Data Sources → SQLite (22 tables + 5 views) → Python Orchestrator → JSX Dashboard
├── 15 SQL queries
├── 8 metric computations
├── ~50 narrative generations (LLM)
└── JSX template assembly

Schema (22 tables):

  • Core: projects, sessions, session_events, tracks, sprints, tasks
  • Decisions: decisions, decision_options, decision_dependencies
  • Analysis: risks, competitors, cost_inputs, market_data
  • Architecture: architecture_axes, gtm_readiness
  • Financial: revenue_milestones, unit_economics
  • Documentation: methodology_sections, references_table
  • Caching: narrative_cache, briefing_snapshots

Views (5):

  • v_sprint_summary — aggregated sprint progress
  • v_velocity_metrics — traditional vs. agentic velocity
  • v_decision_status — decision completion state
  • v_risk_summary — computed risk scores
  • v_track_progress — per-track completion percentage

Why SQLite:

  • Zero infrastructure — runs alongside Claude Code with no server
  • Single-file portable — entire project database in one .db file
  • WAL mode — concurrent reads during briefing generation
  • Standard SQL — migration path to PostgreSQL when needed

D5: Narrative Caching with SHA-256 Hash

AI-generated narratives are cached in a narrative_cache table keyed by (component_id, data_hash):

CREATE TABLE narrative_cache (
component_id TEXT NOT NULL,
data_hash TEXT NOT NULL,
narrative TEXT NOT NULL,
model TEXT DEFAULT 'claude-sonnet-4-5-20250929',
generated_at TEXT NOT NULL,
tokens_used INTEGER,
PRIMARY KEY (component_id, data_hash)
);

Cache hit: If the SHA-256 hash of the input data matches a cached entry, the stored narrative is reused. This saves ~60% of LLM tokens on repeat generation when data hasn't changed.

Cache invalidation: When any underlying data changes, the hash changes, triggering regeneration for that component only. Unchanged components retain their cached narratives.

Token budget: Full generation ~50 narrative calls at ~200 tokens each = ~10,000 tokens. With caching, typical regeneration = ~4,000 tokens.

D6: Interactive Decision Capture Pattern

Executive briefings include an interactive decision capture system where C-suite personas can record decisions directly in the dashboard:

State architecture:

// Lifted to parent component — persists across tab switches
const [decisions, setDecisions] = useState({}); // {[decisionIdx]: optionIdx}
const selectDecision = (idx, optIdx) => {
setDecisions(prev => {
const next = {...prev};
if (next[idx] === optIdx) delete next[idx]; // toggle off
else next[idx] = optIdx; // select
return next;
});
};

Tab badge: Shows {decided}/{total} count. Gold when in progress, green when all decided.

Clipboard export: Decisions can be exported as formatted text for meeting minutes.

Key constraint: stopPropagation on option click prevents card expand/collapse from firing when recording a decision.

D7: Single-File JSX Constraint for Artifact Compatibility

Generated dashboards MUST be deployable in two modes:

ModeConstraintUse Case
Claude.ai ArtifactSingle file, single default export, no imports except React hooks + lucide-react + rechartsExecutive sharing via Claude conversations
WPP IntegrationStandard React component, can import shared primitivesIntegrated dashboard viewer

Resolution: The Python orchestrator generates both formats:

  1. executive-briefing-standalone.jsx — self-contained artifact with inline primitives and tokens
  2. executive-briefing.jsx — WPP-integrated version importing shared components from components/

Template switching: A --mode standalone|integrated flag on the orchestrator controls which template is used.

D8: 3-Phase Pipeline Architecture

The briefing generation follows a deterministic 3-phase pipeline:

Phase 1: Query + Compute (0 LLM tokens, <1s)

  • Execute 15 SQL queries against project SQLite database
  • Compute 8 derived metrics (velocity ratios, cost projections, unit economics, risk scores)
  • Produce structured JSON data for all 12 component data contracts

Phase 2: Narrate (~10K LLM tokens, ~30s)

  • For each component, check narrative cache
  • Generate AI narratives only for changed components
  • Each narrative prompt includes component context, persona, and tone guidelines
  • Narratives explain significance, not just describe data

Phase 3: Assemble (0 LLM tokens, <1s)

  • Populate JSX template with computed data + generated narratives
  • Apply design tokens from resolved T object
  • Output final JSX file + JSON data manifest

Alignment with ADR-199: This mirrors the two-phase token optimization pattern — Phase 1 is the "Node.js metrics" equivalent (zero AI tokens), Phase 2 is the "AI narrative" layer.

D9: Component Data Contract Standard

Each JSX component consumes a formally defined JSON structure. The 12 data contracts serve as the interface between the Python orchestrator and the JSX template:

ContractTypeFieldsAI-Generated Fields
SESSION_METRICSArray[6]label, value, sub, narrativenarrative
QUADRANTSArray[4]title, icon, persona, metric, bodybody
GTM_READINESSArray[N]area, status, detail, narrativenarrative
ARCH_MATURITYArray[N]axis, current, target, narrativenarrative
ACCOMPLISHMENTSArray[5]rank, title, metric, roiNote, detailroiNote, detail
SESSION_FLOWArray[N]time, label, color, narrativenarrative
DECISIONSArray[N]title, urgency, options, context, stakescontext, stakes
DECISION_DEPSArray[N]from, to, note, narrativenarrative
RISK_MATRIXArray[N]name, likelihood, impact, narrativenarrative
SPRINT_DATAArray[N]id, tasks, done, label, narrativenarrative
INVESTMENT_DATAObjectbuildCost, humanEquivalent, unitEconomicsper-metric narratives
COMPETITORSArray[N]name, fit, strength, weakness, narrativenarrative

TypeScript interfaces are defined in component-data-contracts.md and serve as the canonical reference for both the Python orchestrator's output and the JSX template's input.

D10: Lazy-Loaded Tab Architecture

The 5-tab executive briefing uses independent expand state per tab to prevent state leakage:

TabState TypeExpand Keys
Executive SummarySet<number|string>"metric-0", "progress", "sprint", "gtm-0"..
AccomplishmentsSet<number|string> + flowIdx: number|nullCard indices + single-select timeline
DecisionsSet<number|string>"dec-0", "risk-0", "dep-0"
InvestmentSet<string>"ue-0", "rev-0", "comp-0"
MethodologySet<number>Section indices 0-14

Why per-tab state: Each tab renders independently. Expanding a card on one tab does not affect other tabs. The single exception is decisions state which is lifted to the parent because it persists across the Decisions tab and the Executive Summary tab badge.

D11: Multi-Project Executive Briefing Support

Executive briefings support the multi-project architecture from ADR-170:

  • Each project maintains its own SQLite database
  • The project-manifest.json (ADR-170) lists available projects with their briefing database paths
  • The Python orchestrator accepts --project <id> to target a specific project
  • Generated JSX files follow the naming convention: executive-briefing-{project-id}.jsx
  • The WPP ProjectSwitcher (ADR-197 D11) handles switching between project briefings

D12: Landing Page First Architecture

The executive briefing landing page (executive-landing.jsx) serves as the default home view for the WPP dashboard viewer, replacing the category grid:

  • Default view: DEFAULT_BRANDING.homeDashboard is set to "dashboards-executive-executive-landing" in viewer.jsx
  • Single data source: The landing page consumes exclusively from project-dashboard-data.json (Node.js generator)
  • Zero duplication: Enforced by build-time validator (validate-dedup.py) and RESERVED_KEYS boundary in BriefingValidator
  • Progressive disclosure: Hero metrics above the fold, expandable track narratives and risk/recommendation cards below
  • Actionable insights: Every element answers "What should I do about this?" — risks link to tracks, recommendations include effort estimates
  • Less is more: Target <30 data points on initial view, detail on demand via expandable sections
  • Multi-project compatible: Accepts projectJsonUrl prop from ProjectSwitcher (J.18.4), falls back to default JSON path

Design principles documented in internal/analysis/executive-briefing/landing-page-design-direction-2026-02-17.md.


Consequences

Positive

  1. Any CODITECT project can generate executive briefings by populating the SQLite schema
  2. 6 new shared UI primitives (3 atoms + 3 molecules) enrich the component library for all dashboards
  3. AI narratives transform raw metrics into persona-targeted insights
  4. Narrative caching reduces LLM costs by ~60% on repeat generations
  5. Dual-mode output (standalone + integrated) maximizes distribution flexibility
  6. Design token unification brings all dashboards under design-system.json governance

Negative

  1. Python dependency — the orchestrator requires Python 3.10+ with anthropic SDK (already available in CODITECT venvs)
  2. Claude API dependency — narrative generation requires API key (mitigated by --dry-run mode with placeholder narratives)
  3. SQLite schema migration — adding new tables to existing project databases requires migration scripts

Neutral

  1. Single-file JSX constraint limits component reuse within artifact mode but ensures broad distribution
  2. 22-table schema is comprehensive but well-documented; seed scripts serve as templates
  3. Existing WPP dashboards are unaffected — executive briefings are additive

Implementation

File Locations

tools/web-publishing-platform/
├── components/
│ ├── atoms/
│ │ ├── StatusDot.jsx # NEW (D2)
│ │ ├── Badge.jsx # NEW (D2)
│ │ └── SectionTitle.jsx # NEW (D2)
│ ├── molecules/
│ │ ├── ExpandableCard.jsx # NEW (D2)
│ │ ├── ProgressRing.jsx # NEW (D2)
│ │ └── RadarChart.jsx # NEW (D2)
│ └── ... (existing)
├── dashboards/
│ └── executive-briefing/ # NEW category (D1)
│ └── executive-briefing.jsx
├── scripts/
│ ├── generate-briefing.py # Python orchestrator (D4, D8)
│ ├── init-database.sql # Schema DDL (D4)
│ └── seed-template.sql # Template seed data
├── specs/
│ ├── executive-briefing-generator.md # System prompt (D8)
│ ├── component-data-contracts.md # Interface specs (D9)
│ └── methodology-references.md # Citation database
└── design-tokens/
└── executive-briefing-tokens.json # Token mapping (D3)

Migration Path

  1. Phase 1: Extract UI primitives into components/atoms/ and components/molecules/
  2. Phase 2: Register tokens in design-system.json and generate T object mapping
  3. Phase 3: Integrate Python orchestrator into scripts/ with CLI interface
  4. Phase 4: Create dashboards/executive-briefing/ category in WPP
  5. Phase 5: Add executive briefing to scaffold templates for new projects

Track Tasks

Implementation tracked in TRACK-J Section J.19 (Executive Briefing Generator Integration).


Alternatives Considered

A1: Standalone Executive Briefing Application

Build a separate React app specifically for executive briefings.

Rejected: Creates tool sprawl, duplicates WPP infrastructure, and fragments the user experience. Executives should use the same viewer as technical teams.

A2: Pure LLM Generation (No Python Orchestrator)

Have the LLM generate the entire dashboard from raw project data.

Rejected: Non-reproducible (same data produces different dashboards), expensive (full JSX generation = ~50K tokens per run), and un-auditable (no traceable computation path for derived metrics).

A3: External BI Tool Integration (Metabase, Grafana)

Use an existing BI tool for executive dashboards.

Rejected: Adds infrastructure dependency, doesn't support AI narratives, and breaks the single-viewer UX. The WPP approach requires zero additional infrastructure.

A4: Inline T Object (No Token Unification)

Keep the executive briefing's T object as-is without mapping to design-system.json.

Rejected: Creates a parallel token system that drifts from the platform standard. Unified tokens ensure visual consistency when briefing components appear alongside other dashboards.


References

  • ADR-197: Unified Web Publishing Component System
  • ADR-085: Atomic Design Component Library (component hierarchy)
  • ADR-091: Unified Design System Architecture (design-system.json SSOT)
  • ADR-163: Agentic Trajectory Dashboard Architecture (precedent pattern)
  • ADR-170: Multi-Project Executive Dashboard (multi-project support)
  • ADR-199: Two-Phase Project Status Token Optimization (pipeline pattern)
  • component-data-contracts.md — TypeScript interface specifications
  • executive-briefing-generator.md — System prompt specification