/**
* 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,
};