feat(governance): 新增報表 runtime 啟動前閘門
This commit is contained in:
@@ -46,6 +46,7 @@ import {
|
||||
type AiAgentProactiveOperationsContractSnapshot,
|
||||
type AiAgentRedisDryRunGateSnapshot,
|
||||
type AiAgentReportAutomationReviewSnapshot,
|
||||
type AiAgentReportRuntimeReadinessSnapshot,
|
||||
type AiAgentReportTruthActionabilityReviewSnapshot,
|
||||
type AiAgentRuntimeVerifierEvidenceReviewSnapshot,
|
||||
type AiAgentRuntimeWriteGateReviewSnapshot,
|
||||
@@ -338,6 +339,7 @@ export function AutomationInventoryTab() {
|
||||
const [postWriteVerifierPackage, setPostWriteVerifierPackage] = useState<AiAgentPostWriteVerifierPackageSnapshot | null>(null)
|
||||
const [runtimeVerifierEvidenceReview, setRuntimeVerifierEvidenceReview] = useState<AiAgentRuntimeVerifierEvidenceReviewSnapshot | null>(null)
|
||||
const [reportAutomationReview, setReportAutomationReview] = useState<AiAgentReportAutomationReviewSnapshot | null>(null)
|
||||
const [reportRuntimeReadiness, setReportRuntimeReadiness] = useState<AiAgentReportRuntimeReadinessSnapshot | null>(null)
|
||||
const [reportTruthActionabilityReview, setReportTruthActionabilityReview] = useState<AiAgentReportTruthActionabilityReviewSnapshot | null>(null)
|
||||
const [ownerDryRunPackage, setOwnerDryRunPackage] = useState<AiAgentOwnerApprovedFixtureDryRunSnapshot | null>(null)
|
||||
const [hostStatefulInventory, setHostStatefulInventory] = useState<AiAgentHostStatefulVersionInventorySnapshot | null>(null)
|
||||
@@ -371,6 +373,7 @@ export function AutomationInventoryTab() {
|
||||
apiClient.getAiAgentPostWriteVerifierPackage(),
|
||||
apiClient.getAiAgentRuntimeVerifierEvidenceReview(),
|
||||
apiClient.getAiAgentReportAutomationReview(),
|
||||
apiClient.getAiAgentReportRuntimeReadiness(),
|
||||
apiClient.getAiAgentReportTruthActionabilityReview(),
|
||||
apiClient.getAiAgentOwnerApprovedFixtureDryRun(),
|
||||
apiClient.getAiAgentHostStatefulVersionInventory(),
|
||||
@@ -403,6 +406,7 @@ export function AutomationInventoryTab() {
|
||||
postWriteVerifierPackageResult,
|
||||
runtimeVerifierEvidenceReviewResult,
|
||||
reportAutomationReviewResult,
|
||||
reportRuntimeReadinessResult,
|
||||
reportTruthActionabilityReviewResult,
|
||||
ownerDryRunPackageResult,
|
||||
hostStatefulInventoryResult,
|
||||
@@ -432,6 +436,7 @@ export function AutomationInventoryTab() {
|
||||
setPostWriteVerifierPackage(postWriteVerifierPackageResult.status === 'fulfilled' ? postWriteVerifierPackageResult.value : null)
|
||||
setRuntimeVerifierEvidenceReview(runtimeVerifierEvidenceReviewResult.status === 'fulfilled' ? runtimeVerifierEvidenceReviewResult.value : null)
|
||||
setReportAutomationReview(reportAutomationReviewResult.status === 'fulfilled' ? reportAutomationReviewResult.value : null)
|
||||
setReportRuntimeReadiness(reportRuntimeReadinessResult.status === 'fulfilled' ? reportRuntimeReadinessResult.value : null)
|
||||
setReportTruthActionabilityReview(reportTruthActionabilityReviewResult.status === 'fulfilled' ? reportTruthActionabilityReviewResult.value : null)
|
||||
setOwnerDryRunPackage(ownerDryRunPackageResult.status === 'fulfilled' ? ownerDryRunPackageResult.value : null)
|
||||
setHostStatefulInventory(hostStatefulInventoryResult.status === 'fulfilled' ? hostStatefulInventoryResult.value : null)
|
||||
@@ -459,6 +464,7 @@ export function AutomationInventoryTab() {
|
||||
postWriteVerifierPackageResult,
|
||||
runtimeVerifierEvidenceReviewResult,
|
||||
reportAutomationReviewResult,
|
||||
reportRuntimeReadinessResult,
|
||||
reportTruthActionabilityReviewResult,
|
||||
ownerDryRunPackageResult,
|
||||
hostStatefulInventoryResult,
|
||||
@@ -864,6 +870,36 @@ export function AutomationInventoryTab() {
|
||||
.slice(0, 5)
|
||||
}, [reportAutomationReview])
|
||||
|
||||
const visibleReportRuntimeLanes = useMemo(() => {
|
||||
if (!reportRuntimeReadiness) return []
|
||||
const priority = { blocked_by_runtime_gate: 0, ready_for_owner_review: 1 } as Record<string, number>
|
||||
return [...reportRuntimeReadiness.runtime_lanes]
|
||||
.sort((a, b) => {
|
||||
const left = priority[a.contract_status] ?? 2
|
||||
const right = priority[b.contract_status] ?? 2
|
||||
if (left !== right) return left - right
|
||||
return a.lane_id.localeCompare(b.lane_id)
|
||||
})
|
||||
.slice(0, 7)
|
||||
}, [reportRuntimeReadiness])
|
||||
|
||||
const visibleReportRuntimeDecisions = useMemo(() => {
|
||||
if (!reportRuntimeReadiness) return []
|
||||
const statusPriority = { approval_required: 0, blocked_by_runtime_gate: 1, ready_for_review: 2 } as Record<string, number>
|
||||
const riskPriority = { critical: 0, high: 1, medium: 2, low: 3 } as Record<string, number>
|
||||
return [...reportRuntimeReadiness.operator_decisions]
|
||||
.sort((a, b) => {
|
||||
const left = statusPriority[a.status] ?? 3
|
||||
const right = statusPriority[b.status] ?? 3
|
||||
if (left !== right) return left - right
|
||||
const leftRisk = riskPriority[a.risk_tier] ?? 4
|
||||
const rightRisk = riskPriority[b.risk_tier] ?? 4
|
||||
if (leftRisk !== rightRisk) return leftRisk - rightRisk
|
||||
return a.decision_id.localeCompare(b.decision_id)
|
||||
})
|
||||
.slice(0, 7)
|
||||
}, [reportRuntimeReadiness])
|
||||
|
||||
const visibleReportTruthFindings = useMemo(() => {
|
||||
if (!reportTruthActionabilityReview) return []
|
||||
const priority = { critical: 0, high: 1, medium: 2, low: 3 } as Record<string, number>
|
||||
@@ -1083,7 +1119,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 || !reportAutomationReview || !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 || !reportRuntimeReadiness || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) {
|
||||
return (
|
||||
<div style={{ padding: 20 }}>
|
||||
<GlassCard variant="subtle" padding="lg">
|
||||
@@ -1232,6 +1268,16 @@ export function AutomationInventoryTab() {
|
||||
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 reportRuntimeOverall = reportRuntimeReadiness.program_status.overall_completion_percent
|
||||
const reportRuntimeLanes = reportRuntimeReadiness.rollups.runtime_lane_count
|
||||
const reportRuntimeReady = reportRuntimeReadiness.rollups.ready_contract_count
|
||||
const reportRuntimeBlocked = reportRuntimeReadiness.rollups.blocked_contract_count
|
||||
const reportRuntimeApprovals = reportRuntimeReadiness.rollups.approval_required_decision_ids.length
|
||||
const reportRuntimeEnabled = reportRuntimeReadiness.rollups.current_enabled_count
|
||||
const reportRuntimeLiveDelivery = reportRuntimeReadiness.rollups.live_report_delivery_count
|
||||
const reportRuntimeQueueWrites = reportRuntimeReadiness.rollups.telegram_gateway_queue_write_count
|
||||
const reportRuntimeAiRuns = reportRuntimeReadiness.rollups.live_ai_analysis_count
|
||||
const reportRuntimeMediumLowRuns = reportRuntimeReadiness.rollups.live_medium_low_auto_execution_count
|
||||
const reportTruthOverall = reportTruthActionabilityReview.program_status.overall_completion_percent
|
||||
const reportTruthFindings = reportTruthActionabilityReview.rollups.zero_signal_finding_count
|
||||
const reportTruthCritical = reportTruthActionabilityReview.rollups.critical_finding_count
|
||||
@@ -1997,6 +2043,132 @@ export function AutomationInventoryTab() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ padding: 12, border: '0.5px solid #b9d0dd', borderRadius: 7, background: '#f8fcff', 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 }}>
|
||||
<Route size={14} style={{ color: '#0284c7' }} />
|
||||
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 13, fontWeight: 700, color: '#141413' }}>
|
||||
{t('reportRuntimeReadiness.title')}
|
||||
</span>
|
||||
</div>
|
||||
<Chip
|
||||
value={t('reportRuntimeReadiness.source', {
|
||||
generated: formatDateTime(reportRuntimeReadiness.generated_at),
|
||||
current: reportRuntimeReadiness.program_status.current_task_id,
|
||||
next: reportRuntimeReadiness.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('reportRuntimeReadiness.metrics.overall')} value={`${reportRuntimeOverall}%`} tone="warn" icon={<Gauge size={16} />} />
|
||||
<MetricCard label={t('reportRuntimeReadiness.metrics.lanes')} value={reportRuntimeLanes} tone="warn" icon={<Route size={16} />} />
|
||||
<MetricCard label={t('reportRuntimeReadiness.metrics.ready')} value={reportRuntimeReady} tone="ok" icon={<ShieldCheck size={16} />} />
|
||||
<MetricCard label={t('reportRuntimeReadiness.metrics.blocked')} value={reportRuntimeBlocked} tone={reportRuntimeBlocked > 0 ? 'danger' : 'ok'} icon={<ShieldAlert size={16} />} />
|
||||
<MetricCard label={t('reportRuntimeReadiness.metrics.approvals')} value={reportRuntimeApprovals} tone={reportRuntimeApprovals > 0 ? 'danger' : 'ok'} icon={<Lock size={16} />} />
|
||||
<MetricCard label={t('reportRuntimeReadiness.metrics.enabled')} value={reportRuntimeEnabled} tone={reportRuntimeEnabled === 0 ? 'warn' : 'ok'} icon={<Database size={16} />} />
|
||||
<MetricCard label={t('reportRuntimeReadiness.metrics.delivery')} value={reportRuntimeLiveDelivery} tone={reportRuntimeLiveDelivery === 0 ? 'warn' : 'ok'} icon={<BellRing size={16} />} />
|
||||
<MetricCard label={t('reportRuntimeReadiness.metrics.mediumLow')} value={reportRuntimeMediumLowRuns} tone={reportRuntimeMediumLowRuns === 0 ? 'warn' : 'ok'} icon={<Target size={16} />} />
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr)', gap: 12 }} className="automation-inventory-live-read-grid">
|
||||
<div style={{ padding: 11, border: '0.5px solid #d8e8f1', borderRadius: 7, background: '#fff', display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
|
||||
<SmallLabel>{t('reportRuntimeReadiness.truthTitle')}</SmallLabel>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#64727a', lineHeight: 1.5, overflowWrap: 'anywhere' }}>
|
||||
{reportRuntimeReadiness.activation_truth.truth_note}
|
||||
</span>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={t('reportRuntimeReadiness.flags.scheduler', { value: String(reportRuntimeReadiness.activation_truth.report_scheduler_contract_ready) })} />
|
||||
<Chip value={t('reportRuntimeReadiness.flags.queue', { value: reportRuntimeQueueWrites })} muted />
|
||||
<Chip value={t('reportRuntimeReadiness.flags.aiRuns', { value: reportRuntimeAiRuns })} muted />
|
||||
<Chip value={t('reportRuntimeReadiness.flags.mediumLow', { value: reportRuntimeMediumLowRuns })} muted />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ padding: 11, border: '0.5px solid #d8e8f1', borderRadius: 7, background: '#fff', display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
|
||||
<SmallLabel>{t('reportRuntimeReadiness.telegramTitle')}</SmallLabel>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#64727a', lineHeight: 1.5, overflowWrap: 'anywhere' }}>
|
||||
{t('reportRuntimeReadiness.telegramSummary', {
|
||||
room: reportRuntimeReadiness.telegram_route_readiness.canonical_room,
|
||||
secret: reportRuntimeReadiness.telegram_route_readiness.secret_ref,
|
||||
blocked: reportRuntimeReadiness.telegram_route_readiness.blocked_route_count,
|
||||
})}
|
||||
</span>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={t('reportRuntimeReadiness.flags.gateway', { value: String(reportRuntimeReadiness.telegram_route_readiness.gateway_required) })} />
|
||||
<Chip value={t('reportRuntimeReadiness.flags.directApi', { value: String(reportRuntimeReadiness.telegram_route_readiness.direct_bot_api_allowed) })} muted />
|
||||
<Chip value={t('reportRuntimeReadiness.flags.deliveryVerified', { value: String(reportRuntimeReadiness.telegram_route_readiness.e2e_delivery_verified) })} muted />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 10 }} className="automation-inventory-live-read-card-grid">
|
||||
{visibleReportRuntimeLanes.map(lane => {
|
||||
const tone = lane.contract_status === 'blocked_by_runtime_gate' ? 'danger' : lane.risk_tier === 'high' || lane.risk_tier === 'critical' ? 'warn' : 'ok'
|
||||
return (
|
||||
<div key={lane.lane_id} style={{ padding: 10, border: '0.5px solid #d8e8f1', 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' }}>
|
||||
{lane.display_name}
|
||||
</span>
|
||||
<Chip value={redisDryRunValueLabel('agents', lane.owner_agent)} muted />
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={t(`reportRuntimeReadiness.statuses.${lane.contract_status}` as never)} muted={tone !== 'danger'} />
|
||||
<Chip value={t(`reportRuntimeReadiness.riskTiers.${lane.risk_tier}` as never)} muted={tone === 'ok'} />
|
||||
<Chip value={t('reportRuntimeReadiness.labels.liveCount', { count: lane.current_live_count_24h })} muted />
|
||||
</div>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#64727a', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
|
||||
{lane.enablement_required.slice(0, 2).join(' / ')}
|
||||
</span>
|
||||
<Chip value={lane.target_runtime} muted />
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 10 }} className="automation-inventory-live-read-card-grid">
|
||||
{reportRuntimeReadiness.automation_policies.map(policy => (
|
||||
<div key={policy.risk_id} style={{ padding: 10, border: '0.5px solid #d8e8f1', 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' }}>
|
||||
{policy.display_name}
|
||||
</span>
|
||||
<Chip value={t('reportRuntimeReadiness.labels.enabled', { value: String(policy.current_execution_enabled) })} muted />
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={t('reportRuntimeReadiness.labels.autoAfterGuard', { value: String(policy.auto_allowed_after_guard) })} muted={!policy.auto_allowed_after_guard} />
|
||||
<Chip value={t('reportRuntimeReadiness.labels.approvalRequired', { value: String(policy.approval_required) })} muted={!policy.approval_required} />
|
||||
</div>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#64727a', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
|
||||
{policy.reporting_rule}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 10 }} className="automation-inventory-live-read-card-grid">
|
||||
{visibleReportRuntimeDecisions.map(decision => (
|
||||
<div key={decision.decision_id} style={{ padding: 10, border: '0.5px solid #d8e8f1', 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' }}>
|
||||
{decision.display_name}
|
||||
</span>
|
||||
<Chip value={redisDryRunValueLabel('agents', decision.owner_agent)} muted />
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={t(`reportRuntimeReadiness.statuses.${decision.status}` as never)} />
|
||||
<Chip value={t('reportRuntimeReadiness.labels.approvalRequired', { value: String(decision.approval_required) })} muted={!decision.approval_required} />
|
||||
</div>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#64727a', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
|
||||
{decision.next_safe_step}
|
||||
</span>
|
||||
</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 }}>
|
||||
|
||||
@@ -327,6 +327,11 @@ export const apiClient = {
|
||||
return handleResponse<AiAgentReportAutomationReviewSnapshot>(res)
|
||||
},
|
||||
|
||||
async getAiAgentReportRuntimeReadiness() {
|
||||
const res = await fetch(`${API_BASE_URL}/agents/agent-report-runtime-readiness`)
|
||||
return handleResponse<AiAgentReportRuntimeReadinessSnapshot>(res)
|
||||
},
|
||||
|
||||
async getAiAgentOwnerApprovedFixtureDryRun() {
|
||||
const res = await fetch(`${API_BASE_URL}/agents/agent-owner-approved-fixture-dry-run`)
|
||||
return handleResponse<AiAgentOwnerApprovedFixtureDryRunSnapshot>(res)
|
||||
@@ -2074,6 +2079,128 @@ export interface AiAgentReportAutomationReviewSnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
export interface AiAgentReportRuntimeReadinessSnapshot {
|
||||
schema_version: 'ai_agent_report_runtime_readiness_v1'
|
||||
generated_at: string
|
||||
program_status: {
|
||||
overall_completion_percent: number
|
||||
current_priority: 'P0' | 'P1' | 'P2' | 'P3'
|
||||
current_task_id: 'P2-403L'
|
||||
next_task_id: string
|
||||
read_only_mode: true
|
||||
runtime_authority: 'report_runtime_readiness_only_no_live_delivery_or_optimization'
|
||||
status_note: string
|
||||
}
|
||||
source_refs: string[]
|
||||
activation_truth: {
|
||||
report_scheduler_contract_ready: true
|
||||
telegram_gateway_queue_contract_ready: true
|
||||
telegram_delivery_receipt_contract_ready: true
|
||||
ai_readback_analysis_contract_ready: true
|
||||
medium_low_auto_guard_contract_ready: true
|
||||
high_risk_approval_gate_contract_ready: true
|
||||
live_report_delivery_enabled: false
|
||||
live_report_delivery_count_24h: number
|
||||
telegram_gateway_queue_write_enabled: false
|
||||
telegram_gateway_queue_write_count_24h: number
|
||||
report_read_receipt_write_enabled: false
|
||||
report_read_receipt_count_24h: number
|
||||
ai_analysis_runtime_enabled: false
|
||||
ai_analysis_runtime_count_24h: number
|
||||
medium_low_auto_worker_enabled: false
|
||||
medium_low_auto_execution_count_24h: number
|
||||
production_optimization_enabled: false
|
||||
production_optimization_count_24h: number
|
||||
high_risk_auto_execution_enabled: false
|
||||
high_risk_auto_execution_count_24h: number
|
||||
truth_note: string
|
||||
}
|
||||
runtime_lanes: Array<{
|
||||
lane_id: string
|
||||
display_name: string
|
||||
owner_agent: 'openclaw' | 'hermes' | 'nemotron'
|
||||
risk_tier: 'low' | 'medium' | 'high' | 'critical'
|
||||
target_runtime: string
|
||||
contract_status: 'ready_for_owner_review' | 'blocked_by_runtime_gate'
|
||||
current_live_count_24h: number
|
||||
enablement_required: string[]
|
||||
blocked_actions: string[]
|
||||
}>
|
||||
automation_policies: Array<{
|
||||
risk_id: 'low' | 'medium' | 'high' | 'critical'
|
||||
display_name: string
|
||||
approval_required: boolean
|
||||
auto_allowed_after_guard: boolean
|
||||
current_execution_enabled: false
|
||||
required_guards: string[]
|
||||
reporting_rule: string
|
||||
}>
|
||||
report_delivery_cadence_gates: Array<{
|
||||
cadence_id: 'daily' | 'weekly' | 'monthly'
|
||||
display_name: string
|
||||
scheduler_source: string
|
||||
telegram_digest_policy: string
|
||||
recipient_room: string
|
||||
dry_run_required: true
|
||||
current_delivery_enabled: false
|
||||
live_delivery_count_24h: number
|
||||
}>
|
||||
telegram_route_readiness: {
|
||||
canonical_room: 'AwoooI SRE 戰情室'
|
||||
secret_ref: 'SRE_GROUP_CHAT_ID'
|
||||
gateway_required: true
|
||||
direct_bot_api_allowed: false
|
||||
bot_log_out_allowed: false
|
||||
legacy_routes_must_converge: true
|
||||
telegram_gateway_queue_write_enabled: false
|
||||
e2e_delivery_verified: false
|
||||
delivery_receipt_write_enabled: false
|
||||
blocked_route_count: number
|
||||
}
|
||||
agent_post_report_actions: Array<{
|
||||
agent_id: 'openclaw' | 'hermes' | 'nemotron'
|
||||
display_name: string
|
||||
after_report_responsibility: string
|
||||
allowed_without_approval: string[]
|
||||
blocked_until_approval: string[]
|
||||
live_action_count_24h: number
|
||||
}>
|
||||
operator_decisions: Array<{
|
||||
decision_id: string
|
||||
display_name: string
|
||||
risk_tier: 'low' | 'medium' | 'high' | 'critical'
|
||||
owner_agent: 'openclaw' | 'hermes' | 'nemotron'
|
||||
approval_required: boolean
|
||||
status: 'ready_for_review' | 'blocked_by_runtime_gate' | 'approval_required'
|
||||
why_it_matters: string
|
||||
next_safe_step: string
|
||||
}>
|
||||
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_display_fields: string[]
|
||||
blocked_display_fields: string[]
|
||||
}
|
||||
rollups: {
|
||||
runtime_lane_count: number
|
||||
report_cadence_gate_count: number
|
||||
operator_decision_count: number
|
||||
automation_policy_count: number
|
||||
ready_contract_count: number
|
||||
blocked_contract_count: number
|
||||
approval_required_decision_ids: string[]
|
||||
current_enabled_count: number
|
||||
live_report_delivery_count: number
|
||||
live_ai_analysis_count: number
|
||||
live_medium_low_auto_execution_count: number
|
||||
telegram_gateway_queue_write_count: number
|
||||
high_risk_auto_execution_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