@llm-dev-ops/agentics-cli 1.6.2 → 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -34,6 +34,43 @@ function safeArray(obj, ...keys) {
34
34
  return Array.isArray(val) ? val : [];
35
35
  }
36
36
  // ============================================================================
37
+ // ADR-PIPELINE-020: Agent result extraction utilities
38
+ // ============================================================================
39
+ /** Extract all successful agent results for a given domain. */
40
+ function extractAgentsByDomain(results, domain) {
41
+ return results.filter(r => r.domain === domain && r.status >= 200 && r.status < 300);
42
+ }
43
+ /** Extract a single agent's data payload. Returns null if not found or failed. */
44
+ function extractAgentData(results, domain, agent) {
45
+ const r = results.find(a => a.domain === domain && a.agent === agent && a.status >= 200 && a.status < 300);
46
+ if (!r)
47
+ return null;
48
+ const payload = extractSignalPayload(r.response);
49
+ return (payload.data ?? r.response);
50
+ }
51
+ /** Summarize agent fleet metrics for reporting. */
52
+ export function computeFleetMetrics(results) {
53
+ const domainBreakdown = {};
54
+ let successful = 0;
55
+ let failed = 0;
56
+ for (const r of results) {
57
+ if (!domainBreakdown[r.domain]) {
58
+ domainBreakdown[r.domain] = { success: 0, fail: 0, agents: [] };
59
+ }
60
+ const d = domainBreakdown[r.domain];
61
+ d.agents.push(r.agent);
62
+ if (r.status >= 200 && r.status < 300) {
63
+ d.success++;
64
+ successful++;
65
+ }
66
+ else {
67
+ d.fail++;
68
+ failed++;
69
+ }
70
+ }
71
+ return { totalInvoked: results.length, successful, failed, domainBreakdown };
72
+ }
73
+ // ============================================================================
37
74
  // Extract signal payload from nested agent response
38
75
  // ============================================================================
39
76
  function extractSignalPayload(response) {
@@ -188,19 +225,51 @@ export function renderExecutiveSummary(query, simulationResult, platformResults)
188
225
  lines.push('');
189
226
  }
190
227
  }
191
- lines.push('---', '', `*Generated: ${now}*`);
228
+ // ADR-PIPELINE-020: Financial overview from costops agents
229
+ const roiAgent = extractAgentData(platformResults, 'costops', 'roi');
230
+ const forecastAgent = extractAgentData(platformResults, 'costops', 'forecast');
231
+ if (roiAgent || forecastAgent) {
232
+ lines.push('## Financial Overview', '');
233
+ if (roiAgent) {
234
+ const insights = synthesizeAgentInsights(roiAgent, 'costops-roi');
235
+ lines.push(...insights);
236
+ }
237
+ if (forecastAgent) {
238
+ const insights = synthesizeAgentInsights(forecastAgent, 'costops-forecast');
239
+ lines.push(...insights);
240
+ }
241
+ lines.push('');
242
+ }
243
+ // ADR-PIPELINE-020: Provenance footer
244
+ const execSources = [
245
+ execSummaryAgent && 'platform/executive-summary',
246
+ riskAgent && 'platform/risk-score',
247
+ decisionAgent && 'platform/decision-memo',
248
+ roiAgent && 'costops/roi',
249
+ forecastAgent && 'costops/forecast',
250
+ ].filter(Boolean);
251
+ lines.push('---', '');
252
+ if (execSources.length > 0) {
253
+ lines.push(`*Sources: ${execSources.join(', ')}*`);
254
+ }
255
+ lines.push(`*Generated: ${now}*`);
192
256
  return lines.join('\n');
193
257
  }
194
258
  // ============================================================================
195
259
  // Decision Memo Renderer
196
260
  // ============================================================================
197
- export function renderDecisionMemo(query, simulationResult, _platformResults) {
261
+ export function renderDecisionMemo(query, simulationResult, platformResults) {
198
262
  const now = new Date().toISOString();
199
263
  const simPayload = extractSignalPayload(simulationResult);
200
264
  const simData = simPayload.data ?? {};
201
265
  const successProb = extractSuccessProbability(simData);
202
266
  const riskFactors = safeArray(simData, 'risk_factors');
203
267
  const recommendations = safeArray(simData, 'recommendations');
268
+ // ADR-PIPELINE-020: Extract agent data for enrichment
269
+ const roiData = extractAgentData(platformResults, 'costops', 'roi');
270
+ const tradeoffData = extractAgentData(platformResults, 'costops', 'tradeoff');
271
+ const riskScoreData = extractAgentData(platformResults, 'platform', 'risk-score');
272
+ const plannerData = extractAgentData(platformResults, 'copilot', 'planner');
204
273
  let recommendation = 'DEFER';
205
274
  let rationale = 'Insufficient confidence to proceed.';
206
275
  if (successProb >= 0.9) {
@@ -230,11 +299,42 @@ export function renderDecisionMemo(query, simulationResult, _platformResults) {
230
299
  '',
231
300
  `**Success Probability:** ${(successProb * 100).toFixed(0)}%`,
232
301
  '',
233
- '## Risk Summary',
234
- '',
235
302
  ];
236
- if (riskFactors.length > 0) {
237
- for (const risk of riskFactors) {
303
+ // ADR-PIPELINE-020: Financial impact from costops agents
304
+ if (roiData || tradeoffData) {
305
+ lines.push('## Financial Impact', '');
306
+ if (roiData) {
307
+ const roi = safeString(roiData, 'roi') || safeString(roiData, 'expected_roi') || safeString(roiData, 'return_on_investment');
308
+ const payback = safeString(roiData, 'payback_period') || safeString(roiData, 'payback');
309
+ const totalCost = safeString(roiData, 'total_cost') || safeString(roiData, 'estimated_cost');
310
+ if (roi)
311
+ lines.push(`- **Expected ROI:** ${roi}`);
312
+ if (payback)
313
+ lines.push(`- **Payback Period:** ${payback}`);
314
+ if (totalCost)
315
+ lines.push(`- **Estimated Total Cost:** ${totalCost}`);
316
+ const insights = synthesizeAgentInsights(roiData, 'costops-roi');
317
+ if (insights.length > 0)
318
+ lines.push('', ...insights);
319
+ }
320
+ if (tradeoffData) {
321
+ lines.push('', '**Cost-Quality Tradeoff:**');
322
+ const insights = synthesizeAgentInsights(tradeoffData, 'costops-tradeoff');
323
+ lines.push(...insights);
324
+ }
325
+ lines.push('');
326
+ }
327
+ lines.push('## Risk Summary', '');
328
+ // Combine simulation risks with platform risk-score agent
329
+ const allRisks = [...riskFactors];
330
+ if (riskScoreData) {
331
+ const agentRisks = safeArray(riskScoreData, 'risk_factors')
332
+ .concat(safeArray(riskScoreData, 'risks'))
333
+ .concat(safeArray(riskScoreData, 'factors'));
334
+ allRisks.push(...agentRisks);
335
+ }
336
+ if (allRisks.length > 0) {
337
+ for (const risk of allRisks) {
238
338
  lines.push(`- ${typeof risk === 'string' ? risk : JSON.stringify(risk)}`);
239
339
  }
240
340
  }
@@ -252,7 +352,19 @@ export function renderDecisionMemo(query, simulationResult, _platformResults) {
252
352
  lines.push(`- ${typeof rec === 'object' && rec !== null ? JSON.stringify(rec) : String(rec)}`);
253
353
  }
254
354
  }
255
- lines.push('', '---', '', `*Generated: ${now}*`);
355
+ // ADR-PIPELINE-020: Implementation approach from copilot/planner
356
+ if (plannerData) {
357
+ lines.push('', '## Implementation Approach', '');
358
+ const insights = synthesizeAgentInsights(plannerData, 'copilot-planner');
359
+ lines.push(...insights);
360
+ }
361
+ // Provenance footer
362
+ const sources = [roiData && 'costops/roi', tradeoffData && 'costops/tradeoff', riskScoreData && 'platform/risk-score', plannerData && 'copilot/planner'].filter(Boolean);
363
+ lines.push('', '---', '');
364
+ if (sources.length > 0) {
365
+ lines.push(`*Sources: ${sources.join(', ')}*`);
366
+ }
367
+ lines.push(`*Generated: ${now}*`);
256
368
  return lines.join('\n');
257
369
  }
258
370
  /** Known enterprise systems with regex patterns. */
@@ -805,6 +917,10 @@ export function buildRoadmapArtifact(query, simulationResult, platformResults) {
805
917
  .filter(r => r.agent === 'executive-summary' && r.status >= 200 && r.status < 300)
806
918
  .map(r => extractSignalPayload(r.response).data)
807
919
  .filter(Boolean),
920
+ // ADR-PIPELINE-020: Enrich roadmap with planner and costops data
921
+ cost_estimate: extractAgentData(platformResults, 'costops', 'forecast'),
922
+ implementation_plan: extractAgentData(platformResults, 'copilot', 'planner'),
923
+ resource_requirements: extractAgentData(platformResults, 'costops', 'budget'),
808
924
  };
809
925
  }
810
926
  // ============================================================================
@@ -819,11 +935,45 @@ export function buildRiskAssessment(query, simulationResult, platformResults) {
819
935
  // Extract risk agent data if available
820
936
  const riskAgent = platformResults.find(r => r.agent === 'risk-score');
821
937
  const riskAgentData = riskAgent ? extractSignalPayload(riskAgent.response).data : null;
938
+ // ADR-PIPELINE-020: Extract sentinel and shield agents for deeper risk analysis
939
+ const sentinelAgents = extractAgentsByDomain(platformResults, 'sentinel');
940
+ const shieldAgents = extractAgentsByDomain(platformResults, 'shield');
941
+ const observatoryAgents = extractAgentsByDomain(platformResults, 'observatory');
822
942
  let overallRisk = 'HIGH';
823
943
  if (successProb >= 0.9)
824
944
  overallRisk = 'LOW';
825
945
  else if (successProb >= 0.7)
826
946
  overallRisk = 'MEDIUM';
947
+ // Combine risk factors from all sources
948
+ const allRiskFactors = [...riskFactors];
949
+ // Extract sentinel findings (anomaly, drift, correlation, rca)
950
+ for (const agent of sentinelAgents) {
951
+ const data = extractSignalPayload(agent.response).data;
952
+ if (data) {
953
+ const findings = safeArray(data, 'findings').concat(safeArray(data, 'anomalies')).concat(safeArray(data, 'risks'));
954
+ for (const finding of findings) {
955
+ allRiskFactors.push(typeof finding === 'string' ? finding : finding);
956
+ }
957
+ }
958
+ }
959
+ // Extract shield findings (pii, secrets, credential-exposure)
960
+ const securityFindings = [];
961
+ for (const agent of shieldAgents) {
962
+ const data = extractSignalPayload(agent.response).data;
963
+ if (data) {
964
+ const findings = safeArray(data, 'findings').concat(safeArray(data, 'vulnerabilities')).concat(safeArray(data, 'issues'));
965
+ securityFindings.push(...findings);
966
+ }
967
+ }
968
+ // Extract observatory health data
969
+ const healthFindings = [];
970
+ for (const agent of observatoryAgents) {
971
+ const data = extractSignalPayload(agent.response).data;
972
+ if (data) {
973
+ const findings = safeArray(data, 'findings').concat(safeArray(data, 'failures')).concat(safeArray(data, 'health_issues'));
974
+ healthFindings.push(...findings);
975
+ }
976
+ }
827
977
  return {
828
978
  metadata: {
829
979
  title: `Risk Assessment: ${query}`,
@@ -832,19 +982,268 @@ export function buildRiskAssessment(query, simulationResult, platformResults) {
832
982
  },
833
983
  overall_risk_level: overallRisk,
834
984
  success_probability: successProb,
835
- risk_factors: riskFactors.map((r, i) => {
985
+ risk_factors: allRiskFactors.map((r, i) => {
836
986
  if (typeof r === 'string') {
837
987
  return { id: `risk-${i + 1}`, description: r, severity: 'medium', mitigation: 'To be determined' };
838
988
  }
839
989
  return r;
840
990
  }),
841
991
  platform_risk_analysis: riskAgentData ?? null,
992
+ security_findings: securityFindings.length > 0 ? securityFindings : null,
993
+ health_findings: healthFindings.length > 0 ? healthFindings : null,
994
+ sentinel_analysis: sentinelAgents.length > 0 ? sentinelAgents.map(a => ({
995
+ agent: a.agent,
996
+ data: extractSignalPayload(a.response).data,
997
+ })) : null,
842
998
  mitigation_strategy: {
843
- immediate: riskFactors.length > 0
999
+ immediate: allRiskFactors.length > 0
844
1000
  ? ['Address highest-severity risks before proceeding']
845
1001
  : ['No immediate mitigations required'],
846
1002
  ongoing: ['Continuous monitoring during implementation', 'Regular stakeholder reviews'],
847
1003
  },
1004
+ sources: [
1005
+ riskAgentData && 'platform/risk-score',
1006
+ ...sentinelAgents.map(a => `sentinel/${a.agent}`),
1007
+ ...shieldAgents.map(a => `shield/${a.agent}`),
1008
+ ...observatoryAgents.map(a => `observatory/${a.agent}`),
1009
+ ].filter(Boolean),
848
1010
  };
849
1011
  }
1012
+ // ============================================================================
1013
+ // ADR-PIPELINE-020: Financial Analysis Renderer (costops agents)
1014
+ // ============================================================================
1015
+ export function renderFinancialAnalysis(query, _simulationResult, platformResults) {
1016
+ const now = new Date().toISOString();
1017
+ const problemStatement = distillProblemStatement(query);
1018
+ const roiData = extractAgentData(platformResults, 'costops', 'roi');
1019
+ const forecastData = extractAgentData(platformResults, 'costops', 'forecast');
1020
+ const attributionData = extractAgentData(platformResults, 'costops', 'attribution');
1021
+ const budgetData = extractAgentData(platformResults, 'costops', 'budget');
1022
+ const tradeoffData = extractAgentData(platformResults, 'costops', 'tradeoff');
1023
+ const lines = [
1024
+ '# Financial Analysis',
1025
+ '',
1026
+ `**Date:** ${now}`,
1027
+ `**Subject:** ${problemStatement}`,
1028
+ '',
1029
+ '---',
1030
+ '',
1031
+ ];
1032
+ // ROI Analysis
1033
+ lines.push('## Return on Investment', '');
1034
+ if (roiData) {
1035
+ const insights = synthesizeAgentInsights(roiData, 'costops-roi');
1036
+ lines.push(...insights);
1037
+ }
1038
+ else {
1039
+ lines.push('*ROI analysis pending — costops/roi agent data not available.*', '');
1040
+ }
1041
+ // Cost Forecast
1042
+ lines.push('## Cost Forecast', '');
1043
+ if (forecastData) {
1044
+ const insights = synthesizeAgentInsights(forecastData, 'costops-forecast');
1045
+ lines.push(...insights);
1046
+ }
1047
+ else {
1048
+ lines.push('*Cost forecast pending — costops/forecast agent data not available.*', '');
1049
+ }
1050
+ // Cost Attribution
1051
+ lines.push('## Cost Attribution', '');
1052
+ if (attributionData) {
1053
+ const insights = synthesizeAgentInsights(attributionData, 'costops-attribution');
1054
+ lines.push(...insights);
1055
+ }
1056
+ else {
1057
+ lines.push('*Cost attribution pending — costops/attribution agent data not available.*', '');
1058
+ }
1059
+ // Budget Allocation
1060
+ lines.push('## Budget Allocation', '');
1061
+ if (budgetData) {
1062
+ const insights = synthesizeAgentInsights(budgetData, 'costops-budget');
1063
+ lines.push(...insights);
1064
+ }
1065
+ else {
1066
+ lines.push('*Budget allocation pending — costops/budget agent data not available.*', '');
1067
+ }
1068
+ // Cost-Quality Tradeoff
1069
+ lines.push('## Cost-Quality Tradeoff Analysis', '');
1070
+ if (tradeoffData) {
1071
+ const insights = synthesizeAgentInsights(tradeoffData, 'costops-tradeoff');
1072
+ lines.push(...insights);
1073
+ }
1074
+ else {
1075
+ lines.push('*Tradeoff analysis pending — costops/tradeoff agent data not available.*', '');
1076
+ }
1077
+ const sources = [roiData && 'costops/roi', forecastData && 'costops/forecast', attributionData && 'costops/attribution', budgetData && 'costops/budget', tradeoffData && 'costops/tradeoff'].filter(Boolean);
1078
+ lines.push('---', '');
1079
+ lines.push(`*Sources: ${sources.length > 0 ? sources.join(', ') : 'none — costops agents not invoked'}*`);
1080
+ lines.push(`*Generated: ${now}*`);
1081
+ return lines.join('\n');
1082
+ }
1083
+ // ============================================================================
1084
+ // ADR-PIPELINE-020: Security Assessment Renderer (shield agents)
1085
+ // ============================================================================
1086
+ export function renderSecurityAssessment(query, _simulationResult, platformResults) {
1087
+ const now = new Date().toISOString();
1088
+ const problemStatement = distillProblemStatement(query);
1089
+ const shieldAgents = extractAgentsByDomain(platformResults, 'shield');
1090
+ const govAgents = extractAgentsByDomain(platformResults, 'governance-dashboard');
1091
+ const lines = [
1092
+ '# Security & Compliance Assessment',
1093
+ '',
1094
+ `**Date:** ${now}`,
1095
+ `**Subject:** ${problemStatement}`,
1096
+ '',
1097
+ '---',
1098
+ '',
1099
+ '## Security Posture', '',
1100
+ ];
1101
+ if (shieldAgents.length > 0) {
1102
+ for (const agent of shieldAgents) {
1103
+ const data = extractSignalPayload(agent.response).data;
1104
+ if (data) {
1105
+ lines.push(`### ${agent.agent.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase())} Scan`, '');
1106
+ const insights = synthesizeAgentInsights(data, `shield-${agent.agent}`);
1107
+ lines.push(...insights);
1108
+ }
1109
+ }
1110
+ }
1111
+ else {
1112
+ lines.push('*Security scan pending — shield agents not invoked.*', '');
1113
+ }
1114
+ lines.push('## Governance & Compliance', '');
1115
+ if (govAgents.length > 0) {
1116
+ for (const agent of govAgents) {
1117
+ const data = extractSignalPayload(agent.response).data;
1118
+ if (data) {
1119
+ lines.push(`### ${agent.agent.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase())}`, '');
1120
+ const insights = synthesizeAgentInsights(data, `governance-${agent.agent}`);
1121
+ lines.push(...insights);
1122
+ }
1123
+ }
1124
+ }
1125
+ else {
1126
+ lines.push('*Governance analysis pending — governance-dashboard agents not invoked.*', '');
1127
+ }
1128
+ const sources = [...shieldAgents.map(a => `shield/${a.agent}`), ...govAgents.map(a => `governance-dashboard/${a.agent}`)];
1129
+ lines.push('---', '');
1130
+ lines.push(`*Sources: ${sources.length > 0 ? sources.join(', ') : 'none'}*`);
1131
+ lines.push(`*Generated: ${now}*`);
1132
+ return lines.join('\n');
1133
+ }
1134
+ // ============================================================================
1135
+ // ADR-PIPELINE-020: Integration Assessment Renderer (connector-hub agents)
1136
+ // ============================================================================
1137
+ export function renderIntegrationAssessment(query, _simulationResult, platformResults) {
1138
+ const now = new Date().toISOString();
1139
+ const problemStatement = distillProblemStatement(query);
1140
+ const connectorAgents = extractAgentsByDomain(platformResults, 'connector-hub');
1141
+ const edgeAgents = extractAgentsByDomain(platformResults, 'edge');
1142
+ const extracted = extractScenarioFromQuery(query);
1143
+ const lines = [
1144
+ '# Integration Assessment',
1145
+ '',
1146
+ `**Date:** ${now}`,
1147
+ `**Subject:** ${problemStatement}`,
1148
+ `**Target Systems:** ${extracted.systems.join(', ') || 'To be identified'}`,
1149
+ '',
1150
+ '---',
1151
+ '',
1152
+ '## ERP & System Integration', '',
1153
+ ];
1154
+ if (connectorAgents.length > 0) {
1155
+ for (const agent of connectorAgents) {
1156
+ const data = extractSignalPayload(agent.response).data;
1157
+ if (data) {
1158
+ lines.push(`### ${agent.agent.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase())}`, '');
1159
+ const insights = synthesizeAgentInsights(data, `connector-hub-${agent.agent}`);
1160
+ lines.push(...insights);
1161
+ }
1162
+ }
1163
+ }
1164
+ else {
1165
+ lines.push('*Integration analysis pending — connector-hub agents not invoked.*', '');
1166
+ }
1167
+ lines.push('## Edge & Resilience Patterns', '');
1168
+ if (edgeAgents.length > 0) {
1169
+ for (const agent of edgeAgents) {
1170
+ const data = extractSignalPayload(agent.response).data;
1171
+ if (data) {
1172
+ lines.push(`### ${agent.agent.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase())}`, '');
1173
+ const insights = synthesizeAgentInsights(data, `edge-${agent.agent}`);
1174
+ lines.push(...insights);
1175
+ }
1176
+ }
1177
+ }
1178
+ else {
1179
+ lines.push('*Edge analysis pending — edge agents not invoked.*', '');
1180
+ }
1181
+ const sources = [...connectorAgents.map(a => `connector-hub/${a.agent}`), ...edgeAgents.map(a => `edge/${a.agent}`)];
1182
+ lines.push('---', '');
1183
+ lines.push(`*Sources: ${sources.length > 0 ? sources.join(', ') : 'none'}*`);
1184
+ lines.push(`*Generated: ${now}*`);
1185
+ return lines.join('\n');
1186
+ }
1187
+ // ============================================================================
1188
+ // ADR-PIPELINE-020: Agent Fleet Report Renderer
1189
+ // ============================================================================
1190
+ export function renderAgentFleetReport(query, _simulationResult, platformResults) {
1191
+ const now = new Date().toISOString();
1192
+ const problemStatement = distillProblemStatement(query);
1193
+ const metrics = computeFleetMetrics(platformResults);
1194
+ const effectivenessScore = metrics.totalInvoked > 0
1195
+ ? Math.round((metrics.successful / metrics.totalInvoked) * 100)
1196
+ : 0;
1197
+ const lines = [
1198
+ '# Agent Fleet Report',
1199
+ '',
1200
+ `**Date:** ${now}`,
1201
+ `**Subject:** ${problemStatement}`,
1202
+ '',
1203
+ '---',
1204
+ '',
1205
+ '## Fleet Summary',
1206
+ '',
1207
+ `| Metric | Value |`,
1208
+ `|--------|-------|`,
1209
+ `| Total Agents Invoked | ${metrics.totalInvoked} |`,
1210
+ `| Successful (real data) | ${metrics.successful} (${metrics.totalInvoked > 0 ? Math.round((metrics.successful / metrics.totalInvoked) * 100) : 0}%) |`,
1211
+ `| Failed / Error | ${metrics.failed} (${metrics.totalInvoked > 0 ? Math.round((metrics.failed / metrics.totalInvoked) * 100) : 0}%) |`,
1212
+ `| Fleet Effectiveness Score | ${effectivenessScore}% |`,
1213
+ '',
1214
+ '## Per-Domain Breakdown',
1215
+ '',
1216
+ '| Domain | Agents | Success | Failed | Agents Used |',
1217
+ '|--------|--------|---------|--------|-------------|',
1218
+ ];
1219
+ const sortedDomains = Object.entries(metrics.domainBreakdown)
1220
+ .sort(([, a], [, b]) => (b.success + b.fail) - (a.success + a.fail));
1221
+ for (const [domain, data] of sortedDomains) {
1222
+ const total = data.success + data.fail;
1223
+ const agentList = [...new Set(data.agents)].join(', ');
1224
+ lines.push(`| ${domain} | ${total} | ${data.success} | ${data.fail} | ${agentList} |`);
1225
+ }
1226
+ lines.push('');
1227
+ // Agent contribution to documents
1228
+ lines.push('## Agent Contributions to Documents', '');
1229
+ const docMap = {
1230
+ 'executive-summary.md': ['platform/executive-summary', 'platform/risk-score', 'platform/decision-memo', 'costops/roi', 'costops/forecast'],
1231
+ 'decision-memo.md': ['costops/roi', 'costops/tradeoff', 'platform/risk-score', 'copilot/planner'],
1232
+ 'financial-analysis.md': ['costops/roi', 'costops/forecast', 'costops/attribution', 'costops/budget', 'costops/tradeoff'],
1233
+ 'security-assessment.md': ['shield/prompt-injection', 'shield/pii', 'shield/secrets', 'shield/credential-exposure', 'governance-dashboard/audit'],
1234
+ 'integration-assessment.md': ['connector-hub/erp-surface', 'connector-hub/database-query', 'connector-hub/webhook-ingest', 'edge/circuit-breaker', 'edge/failover'],
1235
+ 'risk-assessment.json': ['platform/risk-score', 'sentinel/anomaly', 'sentinel/drift', 'shield/pii', 'shield/secrets', 'observatory/failures'],
1236
+ 'roadmap.json': ['copilot/planner', 'costops/forecast', 'costops/budget', 'research-lab/metrics'],
1237
+ };
1238
+ for (const [doc, agents] of Object.entries(docMap)) {
1239
+ const available = agents.filter(a => {
1240
+ const [d, ag] = a.split('/');
1241
+ return platformResults.some(r => r.domain === d && r.agent === ag && r.status >= 200 && r.status < 300);
1242
+ });
1243
+ const status = available.length > 0 ? `${available.length}/${agents.length} agents contributed` : 'no agent data available';
1244
+ lines.push(`- **${doc}**: ${status}`);
1245
+ }
1246
+ lines.push('', '---', '', `*Generated: ${now}*`);
1247
+ return lines.join('\n');
1248
+ }
850
1249
  //# sourceMappingURL=simulation-renderers.js.map