BID · Console
Baseline · Intelligence · Decision
src/agents/decision/visualization/matrix.ts 6,476 bytes · typescript
/**
 * Visualization agent — matrix row.
 *
 * Per Pillar 3 spec §Agent 2: render interpreted recommendations as
 * audience-appropriate visual outputs using declared visualization
 * rules. Chart type, axis selection, color, narrative framing — all
 * rule-driven. No improvised visual decisions.
 *
 * The agent produces a visualization SPECIFICATION (chart_type +
 * data_binding + narrative_wrapper + format) for a downstream
 * renderer; it does not embed a charting library. This keeps the
 * framework render-agnostic, same pattern as the channel-adapter
 * registry for delivery.
 */

import {
  type AgentRules,
  type AgentStandardsContract,
  type Capability,
  DECISION_FORBIDDEN,
  type RunbookStep,
  type TriggerCategory,
  type WriteBackDeclaration,
} from '../../../standards.js';

export const AGENT_NAME = 'decision.visualization';
export const AGENT_VERSION = '1.0.0';

export const visualizationMatrix = {
  '1_objective':
    'Render interpreted recommendations as audience-appropriate visual outputs using declared visualization rules. Render only — do not re-interpret or deliver.',
  '2_inputs':
    'Recommendations from Output Ingestion + the Rule Library. Each recommendation carries its source rule citation and audience tier. Validates schema + that each recommendation cites a rule.',
  '3_decisionLogic':
    'Every visualization choice (chart_type, data_binding, color, narrative wrapper, format) traces to a declared visualization rule. Logs which rule was selected, which conditions matched, which output specification was produced.',
  '4_rulesConstraints':
    'No visual choices that misrepresent the data (no misleading scaling, no aggregation that obscures values). No content beyond what the underlying recommendation contains. Disclosure-policy filters enforced at the rule level.',
  '5_methodsTools':
    'Rule Library lookup via find_rules / get_rule (capability: rule-library). Disclosure-policy enforcement (capability: disclosure-policy-check). No fresh data, no re-interpretation (DECISION_FORBIDDEN).',
  '6_processing':
    'Receive recommendations → for each, deterministically find applicable visualization rule(s) via library → resolve precedence → if zero, escalate as visualization-rule-gap → otherwise apply rule.action deterministically (chart_type / data_binding / narrative_wrapper from the rule, values from the recommendation). LLM reasoning reserved for ambiguous cases — none in the foundational rule set. Cost-appropriate execution per Std 6.',
  '7_validation':
    'Validate that rendered specification accurately reflects the underlying recommendation (no field bound to a value the recommendation does not carry). Validate audience-appropriateness via disclosure-policy check. Per-visualization confidence.',
  '8_conditionalTriggers':
    'visualization-rule-gap, disclosure-policy-concern, fidelity-violation, material-impact-finding (carried through from upstream).',
  '9_hitlEscalation':
    'Escalates aggressively (Pillar 3 stricter regime). Recommended reviewers: domain-expert (rule gaps), compliance-reviewer (disclosure concerns), authorizing-decision-maker (material findings).',
  '10_repositoryWriteBack':
    'Rendered specification, visualization rule applied, source recommendation reference, audience tier, disclosure-policy results.',
  '11_handoff':
    'Visualizations object → Delivery & Distribution agent.',
  '12_failureHandling':
    'Fails per-output when rules do not fit. Falls back to lower-fidelity rendering if the rule declares a fallback format; otherwise escalates. Other visualizations in the same run continue.',
} as const;

const capabilities: readonly Capability[] = [
  'rule-library',
  'visualization-rendering',
  'disclosure-policy-check',
  'audience-tier-routing',
];

const runbook: readonly RunbookStep[] = [
  { n: 1, name: 'receive-recommendations', description: 'Verify Recommendations schema and that each entry cites a rule (Std 2).' },
  { n: 2, name: 'find-rules', description: 'For each recommendation, deterministically search the Rule Library for applicable visualization rules (Std 5).' },
  { n: 3, name: 'resolve-precedence', description: 'If multiple rules match, apply precedence (most-specific then newest).' },
  { n: 4, name: 'check-disclosure-policy', description: 'Run the rule\'s disclosure_policy against the recommendation\'s audience tier (Std 4 + Std 7). Block + escalate on policy concern.' },
  { n: 5, name: 'apply-rule', description: 'Construct the visualization specification deterministically from rule.action + recommendation fields. LLM only when the rule explicitly requires judgment.' },
  { n: 6, name: 'validate-fidelity', description: 'Cross-check that every spec field is bound to a real recommendation field — no misleading scaling, no fabricated bindings (Std 4 + Std 7).' },
  { n: 7, name: 'score-confidence', description: 'Per-visualization confidence applying the rule\'s confidence framework.' },
  { n: 8, name: 'package-handoff', description: 'Hand off to Delivery & Distribution agent (Std 11).' },
];

const triggers: readonly TriggerCategory[] = [
  'rule-gap',
  'disclosure-policy-concern',
  'fidelity-violation',
  'material-impact-finding',
];

const writeBack: WriteBackDeclaration = {
  structuredOutputs: true,
  metadata: true,
  lineage: true,
  validation: true,
  confidence: true,
  exceptionLogs: true,
  learnedRules: false,
  humanOverrides: false,
};

const rules: AgentRules = {
  preserveRawSource: true,
  preserveLineage: true,
  preserveAuditability: true,
  forbidFabrication: true,
  forbidDestructiveOverwrite: true,
  approvedToolsOnly: true,
  pillarSpecificForbidden: DECISION_FORBIDDEN,
};

export const visualizationContract: AgentStandardsContract = {
  agentName: AGENT_NAME,
  agentVersion: AGENT_VERSION,
  pillar: 'decision',
  objective: {
    does: visualizationMatrix['1_objective'],
    produces: 'A typed Visualizations object — each visualization with a specification, rule citation, audience tier, and disclosure-policy result.',
    doesNot: [
      're-interpret findings',
      'deliver or dispatch',
      'embed a charting library (downstream renderer\'s job)',
      'misrepresent data via aggregation / scaling',
      'invent visualization rules outside the library',
    ],
    downstreamPurpose: 'Hand off to Delivery & Distribution for channel-aware routing.',
  },
  rules,
  capabilities,
  runbook,
  triggers,
  writeBack,
};