feat(governance): 新增 Agent 日週月報風險自動化審查
This commit is contained in:
@@ -45,6 +45,7 @@ import {
|
||||
type AiAgentPostWriteVerifierPackageSnapshot,
|
||||
type AiAgentProactiveOperationsContractSnapshot,
|
||||
type AiAgentRedisDryRunGateSnapshot,
|
||||
type AiAgentReportAutomationReviewSnapshot,
|
||||
type AiAgentReportTruthActionabilityReviewSnapshot,
|
||||
type AiAgentRuntimeVerifierEvidenceReviewSnapshot,
|
||||
type AiAgentRuntimeWriteGateReviewSnapshot,
|
||||
@@ -336,6 +337,7 @@ export function AutomationInventoryTab() {
|
||||
const [runtimeWriteGateReview, setRuntimeWriteGateReview] = useState<AiAgentRuntimeWriteGateReviewSnapshot | null>(null)
|
||||
const [postWriteVerifierPackage, setPostWriteVerifierPackage] = useState<AiAgentPostWriteVerifierPackageSnapshot | null>(null)
|
||||
const [runtimeVerifierEvidenceReview, setRuntimeVerifierEvidenceReview] = useState<AiAgentRuntimeVerifierEvidenceReviewSnapshot | null>(null)
|
||||
const [reportAutomationReview, setReportAutomationReview] = useState<AiAgentReportAutomationReviewSnapshot | null>(null)
|
||||
const [reportTruthActionabilityReview, setReportTruthActionabilityReview] = useState<AiAgentReportTruthActionabilityReviewSnapshot | null>(null)
|
||||
const [ownerDryRunPackage, setOwnerDryRunPackage] = useState<AiAgentOwnerApprovedFixtureDryRunSnapshot | null>(null)
|
||||
const [hostStatefulInventory, setHostStatefulInventory] = useState<AiAgentHostStatefulVersionInventorySnapshot | null>(null)
|
||||
@@ -368,6 +370,7 @@ export function AutomationInventoryTab() {
|
||||
apiClient.getAiAgentRuntimeWriteGateReview(),
|
||||
apiClient.getAiAgentPostWriteVerifierPackage(),
|
||||
apiClient.getAiAgentRuntimeVerifierEvidenceReview(),
|
||||
apiClient.getAiAgentReportAutomationReview(),
|
||||
apiClient.getAiAgentReportTruthActionabilityReview(),
|
||||
apiClient.getAiAgentOwnerApprovedFixtureDryRun(),
|
||||
apiClient.getAiAgentHostStatefulVersionInventory(),
|
||||
@@ -399,6 +402,7 @@ export function AutomationInventoryTab() {
|
||||
runtimeWriteGateReviewResult,
|
||||
postWriteVerifierPackageResult,
|
||||
runtimeVerifierEvidenceReviewResult,
|
||||
reportAutomationReviewResult,
|
||||
reportTruthActionabilityReviewResult,
|
||||
ownerDryRunPackageResult,
|
||||
hostStatefulInventoryResult,
|
||||
@@ -427,6 +431,7 @@ export function AutomationInventoryTab() {
|
||||
setRuntimeWriteGateReview(runtimeWriteGateReviewResult.status === 'fulfilled' ? runtimeWriteGateReviewResult.value : null)
|
||||
setPostWriteVerifierPackage(postWriteVerifierPackageResult.status === 'fulfilled' ? postWriteVerifierPackageResult.value : null)
|
||||
setRuntimeVerifierEvidenceReview(runtimeVerifierEvidenceReviewResult.status === 'fulfilled' ? runtimeVerifierEvidenceReviewResult.value : null)
|
||||
setReportAutomationReview(reportAutomationReviewResult.status === 'fulfilled' ? reportAutomationReviewResult.value : null)
|
||||
setReportTruthActionabilityReview(reportTruthActionabilityReviewResult.status === 'fulfilled' ? reportTruthActionabilityReviewResult.value : null)
|
||||
setOwnerDryRunPackage(ownerDryRunPackageResult.status === 'fulfilled' ? ownerDryRunPackageResult.value : null)
|
||||
setHostStatefulInventory(hostStatefulInventoryResult.status === 'fulfilled' ? hostStatefulInventoryResult.value : null)
|
||||
@@ -453,6 +458,7 @@ export function AutomationInventoryTab() {
|
||||
runtimeWriteGateReviewResult,
|
||||
postWriteVerifierPackageResult,
|
||||
runtimeVerifierEvidenceReviewResult,
|
||||
reportAutomationReviewResult,
|
||||
reportTruthActionabilityReviewResult,
|
||||
ownerDryRunPackageResult,
|
||||
hostStatefulInventoryResult,
|
||||
@@ -840,6 +846,24 @@ export function AutomationInventoryTab() {
|
||||
})
|
||||
}, [runtimeVerifierEvidenceReview])
|
||||
|
||||
const visibleReportCharts = useMemo(() => {
|
||||
if (!reportAutomationReview) return []
|
||||
return reportAutomationReview.report_charts.slice(0, 4)
|
||||
}, [reportAutomationReview])
|
||||
|
||||
const visibleReportRecommendations = useMemo(() => {
|
||||
if (!reportAutomationReview) return []
|
||||
const priority = { critical: 0, high: 0, medium: 1, low: 2 } as Record<string, number>
|
||||
return [...reportAutomationReview.analysis_recommendations]
|
||||
.sort((a, b) => {
|
||||
const left = priority[a.risk_tier] ?? 3
|
||||
const right = priority[b.risk_tier] ?? 3
|
||||
if (left !== right) return left - right
|
||||
return Number(b.approval_required) - Number(a.approval_required)
|
||||
})
|
||||
.slice(0, 5)
|
||||
}, [reportAutomationReview])
|
||||
|
||||
const visibleReportTruthFindings = useMemo(() => {
|
||||
if (!reportTruthActionabilityReview) return []
|
||||
const priority = { critical: 0, high: 1, medium: 2, low: 3 } as Record<string, number>
|
||||
@@ -1059,7 +1083,7 @@ export function AutomationInventoryTab() {
|
||||
)
|
||||
}
|
||||
|
||||
if (error || !snapshot || !backlog || !backupTargets || !backupReadiness || !backupPolicy || !offsiteEscrow || !giteaHealth || !observabilityMatrix || !providerRouteMatrix || !deploymentLayout || !proactiveOperations || !interactionLearningProof || !liveReadModelGate || !redisDryRunGate || !learningWritebackPackage || !telegramReceiptPackage || !ownerApprovedLearningDryRun || !runtimeWriteGateReview || !postWriteVerifierPackage || !runtimeVerifierEvidenceReview || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) {
|
||||
if (error || !snapshot || !backlog || !backupTargets || !backupReadiness || !backupPolicy || !offsiteEscrow || !giteaHealth || !observabilityMatrix || !providerRouteMatrix || !deploymentLayout || !proactiveOperations || !interactionLearningProof || !liveReadModelGate || !redisDryRunGate || !learningWritebackPackage || !telegramReceiptPackage || !ownerApprovedLearningDryRun || !runtimeWriteGateReview || !postWriteVerifierPackage || !runtimeVerifierEvidenceReview || !reportAutomationReview || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) {
|
||||
return (
|
||||
<div style={{ padding: 20 }}>
|
||||
<GlassCard variant="subtle" padding="lg">
|
||||
@@ -1198,6 +1222,16 @@ export function AutomationInventoryTab() {
|
||||
const runtimeVerifierApprovals = runtimeVerifierEvidenceReview.rollups.approval_required_action_ids.length
|
||||
const runtimeVerifierBlockedActions = runtimeVerifierEvidenceReview.rollups.blocked_runtime_action_count
|
||||
const runtimeVerifierLiveTotal = runtimeVerifierEvidenceReview.rollups.live_verifier_execution_count
|
||||
const reportAutomationOverall = reportAutomationReview.program_status.overall_completion_percent
|
||||
const reportCadenceCount = reportAutomationReview.rollups.report_cadence_count
|
||||
const reportAgentCount = reportAutomationReview.rollups.agent_count
|
||||
const reportWorkloadTotal = reportAutomationReview.rollups.workload_unit_total
|
||||
const reportWorkloadDone = reportAutomationReview.rollups.workload_done_total
|
||||
const reportRecommendations = reportAutomationReview.rollups.recommendation_count
|
||||
const reportApprovalRecommendations = reportAutomationReview.rollups.approval_required_recommendation_ids.length
|
||||
const reportAutoEnabled = reportAutomationReview.rollups.current_auto_execution_enabled_count
|
||||
const reportLiveDelivery = reportAutomationReview.rollups.live_report_delivery_count
|
||||
const reportLiveOptimization = reportAutomationReview.rollups.live_auto_optimization_count
|
||||
const reportTruthOverall = reportTruthActionabilityReview.program_status.overall_completion_percent
|
||||
const reportTruthFindings = reportTruthActionabilityReview.rollups.zero_signal_finding_count
|
||||
const reportTruthCritical = reportTruthActionabilityReview.rollups.critical_finding_count
|
||||
@@ -1793,6 +1827,176 @@ export function AutomationInventoryTab() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ padding: 12, border: '0.5px solid #cdd9c4', borderRadius: 7, background: '#fbfdf8', display: 'flex', flexDirection: 'column', gap: 12, minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, flexWrap: 'wrap' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 7, minWidth: 0 }}>
|
||||
<FileText size={14} style={{ color: '#16a34a' }} />
|
||||
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 13, fontWeight: 700, color: '#141413' }}>
|
||||
{t('reportAutomationReview.title')}
|
||||
</span>
|
||||
</div>
|
||||
<Chip
|
||||
value={t('reportAutomationReview.source', {
|
||||
generated: formatDateTime(reportAutomationReview.generated_at),
|
||||
current: reportAutomationReview.program_status.current_task_id,
|
||||
next: reportAutomationReview.program_status.next_task_id,
|
||||
})}
|
||||
muted
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(128px, 1fr))', gap: 10 }} className="automation-inventory-live-read-kpi-grid">
|
||||
<MetricCard label={t('reportAutomationReview.metrics.overall')} value={`${reportAutomationOverall}%`} tone="ok" icon={<Gauge size={16} />} />
|
||||
<MetricCard label={t('reportAutomationReview.metrics.cadences')} value={reportCadenceCount} tone="ok" icon={<RefreshCw size={16} />} />
|
||||
<MetricCard label={t('reportAutomationReview.metrics.agents')} value={reportAgentCount} tone="ok" icon={<Boxes size={16} />} />
|
||||
<MetricCard label={t('reportAutomationReview.metrics.workload')} value={reportWorkloadTotal} tone="warn" icon={<Layers3 size={16} />} />
|
||||
<MetricCard label={t('reportAutomationReview.metrics.done')} value={reportWorkloadDone} tone="ok" icon={<ShieldCheck size={16} />} />
|
||||
<MetricCard label={t('reportAutomationReview.metrics.recommendations')} value={reportRecommendations} tone="warn" icon={<Target size={16} />} />
|
||||
<MetricCard label={t('reportAutomationReview.metrics.approval')} value={reportApprovalRecommendations} tone={reportApprovalRecommendations > 0 ? 'danger' : 'ok'} icon={<Lock size={16} />} />
|
||||
<MetricCard label={t('reportAutomationReview.metrics.autoEnabled')} value={reportAutoEnabled} tone={reportAutoEnabled === 0 ? 'warn' : 'ok'} icon={<Database size={16} />} />
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr)', gap: 12 }} className="automation-inventory-live-read-grid">
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 10, minWidth: 0 }}>
|
||||
<div style={{ padding: 11, border: '0.5px solid #e4eadf', borderRadius: 7, background: '#fff', display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
|
||||
<SmallLabel>{t('reportAutomationReview.truthTitle')}</SmallLabel>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#87867f', lineHeight: 1.5, overflowWrap: 'anywhere' }}>
|
||||
{reportAutomationReview.report_truth.truth_note}
|
||||
</span>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={t('reportAutomationReview.flags.daily', { value: String(reportAutomationReview.report_truth.daily_report_ready) })} />
|
||||
<Chip value={t('reportAutomationReview.flags.weekly', { value: String(reportAutomationReview.report_truth.weekly_report_ready) })} />
|
||||
<Chip value={t('reportAutomationReview.flags.monthly', { value: String(reportAutomationReview.report_truth.monthly_report_ready) })} />
|
||||
<Chip value={t('reportAutomationReview.flags.delivery', { value: reportLiveDelivery })} muted />
|
||||
<Chip value={t('reportAutomationReview.flags.optimization', { value: reportLiveOptimization })} muted />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ padding: 11, border: '0.5px solid #e4eadf', borderRadius: 7, background: '#fff', display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
|
||||
<SmallLabel>{t('reportAutomationReview.policyTitle')}</SmallLabel>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#87867f', lineHeight: 1.5, overflowWrap: 'anywhere' }}>
|
||||
{reportAutomationReview.risk_tier_policy.policy_summary}
|
||||
</span>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={t('reportAutomationReview.flags.highApproval', { value: String(reportAutomationReview.report_truth.high_risk_requires_approval) })} />
|
||||
<Chip value={t('reportAutomationReview.flags.mediumLowPolicy', { value: String(reportAutomationReview.report_truth.medium_low_auto_policy_defined) })} muted />
|
||||
<Chip value={t('reportAutomationReview.flags.mediumLowExecution', { value: String(reportAutomationReview.report_truth.medium_low_auto_execution_enabled) })} muted />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(170px, 1fr))', gap: 10 }}>
|
||||
{reportAutomationReview.report_cadences.map(cadence => (
|
||||
<div key={cadence.cadence_id} style={{ padding: 10, border: '0.5px solid #e4eadf', borderRadius: 7, background: '#fff', display: 'flex', flexDirection: 'column', gap: 7, minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, alignItems: 'center' }}>
|
||||
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 12, fontWeight: 700, color: '#141413' }}>
|
||||
{cadence.display_name}
|
||||
</span>
|
||||
<Chip value={redisDryRunValueLabel('agents', cadence.owner_agent)} muted />
|
||||
</div>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#87867f', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
|
||||
{cadence.schedule}
|
||||
</span>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={t('reportAutomationReview.labels.sections', { count: cadence.sections.length })} />
|
||||
<Chip value={t('reportAutomationReview.labels.liveDelivery', { count: cadence.live_delivery_count })} muted />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 10, minWidth: 0 }}>
|
||||
<SmallLabel>{t('reportAutomationReview.workloadTitle')}</SmallLabel>
|
||||
{reportAutomationReview.agent_workload_metrics.map(agent => {
|
||||
const progress = agent.work_units_total > 0 ? Math.round((agent.work_units_done / agent.work_units_total) * 100) : 0
|
||||
return (
|
||||
<div key={agent.agent_id} style={{ padding: 10, border: '0.5px solid #e4eadf', borderRadius: 7, background: '#fff', display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, alignItems: 'center', minWidth: 0 }}>
|
||||
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 12, fontWeight: 700, color: '#141413' }}>
|
||||
{agent.display_name}
|
||||
</span>
|
||||
<Chip value={t('reportAutomationReview.labels.workUnits', { count: agent.work_units_total })} />
|
||||
</div>
|
||||
<MiniBar
|
||||
label={t('reportAutomationReview.labels.doneRatio')}
|
||||
value={progress}
|
||||
detail={t('reportAutomationReview.labels.doneDetail', {
|
||||
done: agent.work_units_done,
|
||||
total: agent.work_units_total,
|
||||
approval: agent.work_units_waiting_approval,
|
||||
})}
|
||||
tone={progress >= 85 ? 'ok' : 'warn'}
|
||||
/>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={t('reportAutomationReview.labels.targets', { count: agent.deployment_targets })} muted />
|
||||
<Chip value={t('reportAutomationReview.labels.capabilities', { count: agent.delegable_capabilities })} muted />
|
||||
<Chip value={t('reportAutomationReview.labels.liveRuntime', { count: agent.live_runtime_work_units_24h })} muted />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 10 }} className="automation-inventory-live-read-card-grid">
|
||||
{visibleReportCharts.map(chart => {
|
||||
const maxValue = Math.max(...chart.series.map(item => item.value), 1)
|
||||
return (
|
||||
<div key={chart.chart_id} style={{ padding: 10, border: '0.5px solid #e4eadf', borderRadius: 7, background: '#fff', display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, alignItems: 'center' }}>
|
||||
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 12, fontWeight: 700, color: '#141413' }}>
|
||||
{chart.display_name}
|
||||
</span>
|
||||
<Chip value={chart.chart_type} muted />
|
||||
</div>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#87867f', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
|
||||
{chart.operator_question}
|
||||
</span>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>
|
||||
{chart.series.map(item => (
|
||||
<div key={`${chart.chart_id}-${item.label}`} style={{ display: 'grid', gridTemplateColumns: '88px minmax(0, 1fr) 36px', gap: 8, alignItems: 'center', minWidth: 0 }}>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#605f59', overflowWrap: 'anywhere' }}>
|
||||
{item.label}
|
||||
</span>
|
||||
<div style={{ height: 7, borderRadius: 999, background: '#e7e3d8', overflow: 'hidden' }}>
|
||||
<div style={{ height: '100%', width: `${Math.max(4, Math.round((item.value / maxValue) * 100))}%`, borderRadius: 999, background: toneColor(item.tone) }} />
|
||||
</div>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, fontWeight: 700, color: toneColor(item.tone), textAlign: 'right' }}>
|
||||
{item.value}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 10 }} className="automation-inventory-live-read-card-grid">
|
||||
{visibleReportRecommendations.map(recommendation => {
|
||||
const tone = recommendation.risk_tier === 'high' || recommendation.risk_tier === 'critical' ? 'danger' : recommendation.risk_tier === 'medium' ? 'warn' : 'ok'
|
||||
return (
|
||||
<div key={recommendation.recommendation_id} style={{ padding: 10, border: '0.5px solid #e4eadf', borderRadius: 7, background: '#fff', display: 'flex', flexDirection: 'column', gap: 7, minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, alignItems: 'center', minWidth: 0 }}>
|
||||
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 12, fontWeight: 700, color: '#141413', overflowWrap: 'anywhere' }}>
|
||||
{recommendation.display_name}
|
||||
</span>
|
||||
<Chip value={redisDryRunValueLabel('agents', recommendation.owner_agent)} muted />
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={t(`reportAutomationReview.riskTiers.${recommendation.risk_tier}` as never)} muted={tone !== 'danger'} />
|
||||
<Chip value={t('reportAutomationReview.labels.approvalRequired', { value: String(recommendation.approval_required) })} muted={!recommendation.approval_required} />
|
||||
</div>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#87867f', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
|
||||
{recommendation.proposed_solution}
|
||||
</span>
|
||||
<Chip value={recommendation.blocked_runtime_action} muted />
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ padding: 12, border: '0.5px solid #d8c6a6', borderRadius: 7, background: '#fffdf7', display: 'flex', flexDirection: 'column', gap: 12, minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, flexWrap: 'wrap' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 7, minWidth: 0 }}>
|
||||
|
||||
@@ -322,6 +322,11 @@ export const apiClient = {
|
||||
return handleResponse<AiAgentReportTruthActionabilityReviewSnapshot>(res)
|
||||
},
|
||||
|
||||
async getAiAgentReportAutomationReview() {
|
||||
const res = await fetch(`${API_BASE_URL}/agents/agent-report-automation-review`)
|
||||
return handleResponse<AiAgentReportAutomationReviewSnapshot>(res)
|
||||
},
|
||||
|
||||
async getAiAgentOwnerApprovedFixtureDryRun() {
|
||||
const res = await fetch(`${API_BASE_URL}/agents/agent-owner-approved-fixture-dry-run`)
|
||||
return handleResponse<AiAgentOwnerApprovedFixtureDryRunSnapshot>(res)
|
||||
@@ -1948,6 +1953,127 @@ export interface AiAgentReportTruthActionabilityReviewSnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
export interface AiAgentReportAutomationReviewSnapshot {
|
||||
schema_version: 'ai_agent_report_automation_review_v1'
|
||||
generated_at: string
|
||||
program_status: {
|
||||
overall_completion_percent: number
|
||||
current_priority: 'P0' | 'P1' | 'P2' | 'P3'
|
||||
current_task_id: string
|
||||
next_task_id: string
|
||||
read_only_mode: true
|
||||
runtime_authority: 'reporting_and_risk_policy_review_only_no_live_execution'
|
||||
status_note: string
|
||||
}
|
||||
source_refs: string[]
|
||||
report_truth: {
|
||||
daily_report_ready: true
|
||||
weekly_report_ready: true
|
||||
monthly_report_ready: true
|
||||
per_agent_workload_ready: true
|
||||
chart_package_ready: true
|
||||
report_delivery_enabled: false
|
||||
report_delivery_count_24h: number
|
||||
report_read_receipt_count_24h: number
|
||||
ai_analysis_after_report_enabled: false
|
||||
medium_low_auto_policy_defined: true
|
||||
medium_low_auto_execution_enabled: false
|
||||
live_medium_low_auto_execution_count_24h: number
|
||||
high_risk_requires_approval: true
|
||||
live_auto_optimization_count_24h: number
|
||||
truth_note: string
|
||||
}
|
||||
report_cadences: Array<{
|
||||
cadence_id: 'daily' | 'weekly' | 'monthly'
|
||||
display_name: string
|
||||
owner_agent: 'openclaw' | 'hermes' | 'nemotron'
|
||||
schedule: string
|
||||
sections: string[]
|
||||
chart_ids: string[]
|
||||
delivery_channel: string
|
||||
status: string
|
||||
live_delivery_count: number
|
||||
}>
|
||||
agent_workload_metrics: Array<{
|
||||
agent_id: 'openclaw' | 'hermes' | 'nemotron'
|
||||
display_name: string
|
||||
primary_role: string
|
||||
deployment_targets: number
|
||||
delegable_capabilities: number
|
||||
report_owned_sections: number
|
||||
analysis_owned_recommendations: number
|
||||
work_units_total: number
|
||||
work_units_done: number
|
||||
work_units_waiting_approval: number
|
||||
live_runtime_work_units_24h: number
|
||||
workload_note: string
|
||||
}>
|
||||
report_charts: Array<{
|
||||
chart_id: string
|
||||
display_name: string
|
||||
chart_type: string
|
||||
unit: string
|
||||
series: Array<{
|
||||
label: string
|
||||
value: number
|
||||
tone: 'ok' | 'warn' | 'danger' | 'neutral'
|
||||
}>
|
||||
operator_question: string
|
||||
}>
|
||||
risk_tier_policy: {
|
||||
policy_summary: string
|
||||
risk_tiers: Array<{
|
||||
risk_id: 'low' | 'medium' | 'high' | 'critical'
|
||||
display_name: string
|
||||
approval_required: boolean
|
||||
auto_action_policy: string
|
||||
current_execution_enabled: false
|
||||
required_before_enable: string[]
|
||||
}>
|
||||
}
|
||||
analysis_recommendations: Array<{
|
||||
recommendation_id: string
|
||||
display_name: string
|
||||
owner_agent: 'openclaw' | 'hermes' | 'nemotron'
|
||||
risk_tier: 'low' | 'medium' | 'high' | 'critical'
|
||||
approval_required: boolean
|
||||
current_auto_execution_enabled: false
|
||||
problem: string
|
||||
proposed_solution: string
|
||||
expected_report_signal: string
|
||||
blocked_runtime_action: string
|
||||
}>
|
||||
approval_boundaries: Record<string, boolean>
|
||||
display_redaction_contract: {
|
||||
redaction_required: true
|
||||
raw_report_payload_display_allowed: false
|
||||
private_reasoning_display_allowed: false
|
||||
secret_value_display_allowed: false
|
||||
work_window_transcript_display_allowed: false
|
||||
allowed_frontend_content: string[]
|
||||
forbidden_frontend_content: string[]
|
||||
frontend_display_policy: string
|
||||
}
|
||||
rollups: {
|
||||
report_cadence_count: number
|
||||
agent_count: number
|
||||
chart_count: number
|
||||
recommendation_count: number
|
||||
workload_unit_total: number
|
||||
workload_done_total: number
|
||||
workload_waiting_approval_total: number
|
||||
low_risk_recommendation_count: number
|
||||
medium_risk_recommendation_count: number
|
||||
high_risk_recommendation_count: number
|
||||
critical_risk_recommendation_count: number
|
||||
approval_required_recommendation_ids: string[]
|
||||
medium_low_auto_policy_count: number
|
||||
current_auto_execution_enabled_count: number
|
||||
live_report_delivery_count: number
|
||||
live_auto_optimization_count: number
|
||||
}
|
||||
}
|
||||
|
||||
export interface AiAgentOwnerApprovedFixtureDryRunSnapshot {
|
||||
schema_version: 'ai_agent_owner_approved_fixture_dry_run_v1'
|
||||
generated_at: string
|
||||
|
||||
Reference in New Issue
Block a user