BID · Console
Baseline · Intelligence · Decision
src/agents/decision/visualization/schema.ts 2,940 bytes · typescript
/**
 * Visualization — input and output schemas (Std 2 + Std 11).
 */

import { z } from 'zod';
import { outputIngestionOutputSchema } from '../output-ingestion/schema.js';

export const visualizationInputSchema = outputIngestionOutputSchema;
export type VisualizationInput = z.infer<typeof visualizationInputSchema>;

export const disclosurePolicyResultSchema = z.object({
  visualizationId: z.string(),
  audienceTier: z.string(),
  decision: z.enum(['cleared', 'restricted', 'no-policy']),
  policyApplied: z.string().optional(),
  detail: z.string(),
});
export type DisclosurePolicyResult = z.infer<typeof disclosurePolicyResultSchema>;

export const visualizationSpecSchema = z.object({
  /** Structured chart kind from rule.action.chart_type — opaque
   *  to the framework, meaningful to the downstream renderer. */
  chartType: z.string(),
  /** Where each visual axis / channel is bound to a recommendation
   *  field. Copy of rule.action.data_binding plus any concrete value
   *  substitutions. */
  dataBinding: z.record(z.unknown()),
  /** Color palette identifier from rule.action.color_palette. */
  colorPalette: z.string().optional(),
  /** Static-image, pdf-embed, tabular fallback, etc. */
  format: z.object({
    primary: z.string(),
    secondary: z.string().optional(),
    fallback: z.string().optional(),
  }),
  /** Narrative wrapper with template tokens already substituted. */
  narrativeWrapper: z.object({
    headline: z.string(),
    supporting: z.string(),
    constraints: z.array(z.string()).default([]),
  }),
  /** Optional structured annotations the renderer should draw. */
  annotations: z.array(z.string()).default([]),
});
export type VisualizationSpec = z.infer<typeof visualizationSpecSchema>;

export const visualizationSchema = z.object({
  visualizationId: z.string(),
  recommendationReference: z.string(),
  visualizationRuleApplied: z.string(),
  audienceTier: z.string(),
  outputSpecification: visualizationSpecSchema,
  disclosurePolicy: disclosurePolicyResultSchema,
  reasoningLineage: z.array(z.string()),
  confidence: z.number().min(0).max(1),
  flags: z.array(z.string()),
});
export type Visualization = z.infer<typeof visualizationSchema>;

export const visualizationGapSchema = z.object({
  recommendationReference: z.string(),
  reason: z.enum([
    'no-rule-matched',
    'disclosure-blocked',
    'fidelity-violation',
    'template-binding-failed',
  ]),
  detail: z.string(),
  triedTriggers: z.array(z.string()),
});
export type VisualizationGap = z.infer<typeof visualizationGapSchema>;

export const visualizationOutputSchema = z.object({
  visualizations: z.array(visualizationSchema),
  visualizationGapsEscalated: z.array(visualizationGapSchema),
  disclosurePolicyResults: z.array(disclosurePolicyResultSchema),
  appliedRules: z.array(z.string()),
  notes: z.array(z.string()),
});
export type VisualizationOutput = z.infer<typeof visualizationOutputSchema>;