fix(web): keep autonomous runtime readback visible
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m42s
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
Code Review / ai-code-review (push) Has been cancelled

This commit is contained in:
Your Name
2026-06-28 15:02:18 +08:00
parent 723207315c
commit d420f5edef

View File

@@ -847,6 +847,145 @@ function GateMatrixRow({
)
}
function AutonomousRuntimeControlPriorityPanel({
control,
t,
}: {
control: AiAgentAutonomousRuntimeControlSnapshot
t: ReturnType<typeof useTranslations>
}) {
const policy = control.current_policy
const switches = control.runtime_switches
const executorReceipts = control.controlled_executor.operation_receipts ?? []
const hardBlockers = control.hard_blockers ?? []
return (
<GlassCard variant="subtle" padding="md">
<div style={{ display: 'flex', flexDirection: 'column', gap: 14, minWidth: 0 }}>
<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap' }}>
<div style={{ display: 'flex', alignItems: 'flex-start', gap: 10, minWidth: 0 }}>
<div style={{
width: 38,
height: 38,
borderRadius: 8,
border: '0.5px solid #15803d40',
background: 'rgba(21,128,61,0.08)',
color: '#15803d',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexShrink: 0,
}}>
<BellRing size={18} />
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: 5, minWidth: 0 }}>
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 18, fontWeight: 760, color: '#141413', lineHeight: 1.15, overflowWrap: 'anywhere' }}>
{t('globalControl.currentAutonomy.title')}
</span>
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 11, color: '#4f6156', lineHeight: 1.55, overflowWrap: 'anywhere' }}>
{control.program_status.status_note}
</span>
</div>
</div>
<div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'flex-end', gap: 6, minWidth: 0 }}>
<Chip value={control.program_status.current_task_id} />
<Chip value={t('globalControl.currentAutonomy.badges.override')} />
<Chip value={t('globalControl.currentAutonomy.badges.gateway')} muted={control.rollups.telegram_gateway_delivery_enabled_count === 0} />
<Chip value={`${t('globalControl.currentAutonomy.badges.deployMarker')}: ${control.program_status.deploy_readback_marker}`} muted />
</div>
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(128px, 1fr))', gap: 10 }} className="automation-inventory-global-control-kpi-grid">
<MetricCard label={t('globalControl.currentAutonomy.metrics.completion')} value={`${control.program_status.implementation_completion_percent}%`} tone="ok" icon={<Gauge size={16} />} />
<MetricCard label={t('globalControl.currentAutonomy.metrics.riskTiers')} value={`${control.rollups.automated_risk_tier_count}/3`} tone={control.rollups.automated_risk_tier_count === 3 ? 'ok' : 'warn'} icon={<ShieldCheck size={16} />} />
<MetricCard label={t('globalControl.currentAutonomy.metrics.reports')} value={control.rollups.report_cadence_enabled_count} tone="ok" icon={<CalendarClock size={16} />} />
<MetricCard label={t('globalControl.currentAutonomy.metrics.gateway')} value={control.rollups.telegram_gateway_delivery_enabled_count} tone="ok" icon={<BellRing size={16} />} />
<MetricCard label={t('globalControl.currentAutonomy.metrics.executor')} value={control.rollups.controlled_executor_operation_receipt_count} tone="ok" icon={<ClipboardCheck size={16} />} />
<MetricCard label={t('globalControl.currentAutonomy.metrics.hardBlockers')} value={control.rollups.hard_blocker_count} tone="warn" icon={<ShieldAlert size={16} />} />
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1.2fr) minmax(260px, 0.8fr)', gap: 12 }} className="automation-inventory-global-control-grid">
<div style={{ padding: 12, border: '0.5px solid #cfe7d7', borderRadius: 7, background: '#f8fffa', display: 'flex', flexDirection: 'column', gap: 10, minWidth: 0 }}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, flexWrap: 'wrap' }}>
<SmallLabel>{t('globalControl.currentAutonomy.policyTitle')}</SmallLabel>
<Chip value={control.program_status.runtime_authority} muted />
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, minmax(0, 1fr))', gap: 8 }} className="automation-inventory-global-control-pipeline-grid">
<GateMatrixRow
label={t('globalControl.currentAutonomy.policy.low')}
value={policy.low_risk_controlled_apply_allowed ? 'on' : 'off'}
detail={t('globalControl.currentAutonomy.policy.noOwnerReview', { value: String(policy.owner_review_required_for_low_medium_high) })}
tone={policy.low_risk_controlled_apply_allowed ? 'ok' : 'warn'}
/>
<GateMatrixRow
label={t('globalControl.currentAutonomy.policy.medium')}
value={policy.medium_risk_controlled_apply_allowed ? 'on' : 'off'}
detail={t('globalControl.currentAutonomy.policy.verifier', { value: String(policy.post_apply_verifier_required === true) })}
tone={policy.medium_risk_controlled_apply_allowed ? 'ok' : 'warn'}
/>
<GateMatrixRow
label={t('globalControl.currentAutonomy.policy.high')}
value={policy.high_risk_controlled_apply_allowed ? 'on' : 'off'}
detail={t('globalControl.currentAutonomy.policy.km', { value: String(policy.km_learning_writeback_required === true) })}
tone={policy.high_risk_controlled_apply_allowed ? 'ok' : 'warn'}
/>
</div>
</div>
<div style={{ padding: 12, border: '0.5px solid #e5dbc7', borderRadius: 7, background: '#fffdf7', display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
<SmallLabel>{t('globalControl.currentAutonomy.runtimeTitle')}</SmallLabel>
<GateMatrixRow
label={t('globalControl.currentAutonomy.runtime.checkMode')}
value={switches.ansible_check_mode_worker_enabled ? 'on' : 'off'}
detail={`interval=${switches.ansible_check_mode_interval_seconds}s batch=${switches.ansible_check_mode_batch_limit}`}
tone={switches.ansible_check_mode_worker_enabled ? 'ok' : 'warn'}
/>
<GateMatrixRow
label={t('globalControl.currentAutonomy.runtime.apply')}
value={switches.ansible_controlled_apply_enabled ? 'on' : 'off'}
detail={switches.ansible_controlled_apply_allowed_risk_levels.join(', ') || '--'}
tone={switches.ansible_controlled_apply_enabled ? 'ok' : 'warn'}
/>
<GateMatrixRow
label={t('globalControl.currentAutonomy.runtime.botApi')}
value={policy.direct_bot_api_allowed ? 'on' : 'off'}
detail={t('globalControl.currentAutonomy.runtime.gatewayOnly')}
tone={policy.direct_bot_api_allowed ? 'danger' : 'ok'}
/>
</div>
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: 10 }} className="automation-inventory-global-control-runway-grid">
<div style={{ padding: 12, border: '0.5px solid #d7d2f4', borderRadius: 7, background: '#fbfaff', display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
<SmallLabel>{t('globalControl.currentAutonomy.executorTitle')}</SmallLabel>
{executorReceipts.slice(0, 5).map(receipt => (
<GateMatrixRow
key={receipt.operation_type}
label={receipt.operation_type}
value={receipt.writes_runtime_state ? 'write' : 'dry'}
detail={`${receipt.owner_agent}: ${receipt.purpose}`}
tone={receipt.writes_runtime_state ? 'warn' : 'ok'}
/>
))}
</div>
<div style={{ padding: 12, border: '0.5px solid #f1d4d4', borderRadius: 7, background: '#fffafa', display: 'flex', flexDirection: 'column', gap: 8, minWidth: 0 }}>
<SmallLabel>{t('globalControl.currentAutonomy.hardBlockerTitle')}</SmallLabel>
{hardBlockers.slice(0, 5).map(blocker => (
<GateMatrixRow
key={blocker}
label={blocker}
value="blocked"
detail={t('globalControl.currentAutonomy.hardBlockerDetail')}
tone="warn"
/>
))}
</div>
</div>
</div>
</GlassCard>
)
}
export function AutomationInventoryTab() {
const t = useTranslations('governance.automationInventory')
const [snapshot, setSnapshot] = useState<AiAgentAutomationInventorySnapshot | null>(null)
@@ -2920,7 +3059,10 @@ export function AutomationInventoryTab() {
if (error || !snapshot || !backlog || !backupTargets || !backupReadiness || !backupPolicy || !offsiteEscrow || !giteaHealth || !observabilityMatrix || !providerRouteMatrix || !deploymentLayout || !warRoom || !professionalTaskExpansion || !receiptReadbackOwnerReview || !reportNoWriteAnalysisRuntime || !lowMediumRiskWhitelist || !highRiskOwnerReviewQueue || !controlledExecutorHandoff || !actionAuditLedger || !actionOwnerAcceptanceEventBus || !hostRunawayAiops || !proactiveOperations || !versionLifecycleProposal || !interactionLearningProof || !liveReadModelGate || !redisDryRunGate || !learningWritebackPackage || !telegramReceiptPackage || !ownerApprovedLearningDryRun || !runtimeWriteGateReview || !postWriteVerifierPackage || !runtimeVerifierEvidenceReview || !reportAutomationReview || !reportStatusBoard || !reportRuntimeReadiness || !reportRuntimeDryRun || !reportRuntimeFixtureReadback || !runtimeWorkerShadowGate || !operationPermissionModel || !candidateOperationDryRunEvidence || !taskResultAuditTrail || !matchedPlaybookLearningGap || !criticReviewerResultCapture || !ownerApprovedResultCaptureDryRun || !ownerApprovedResultCaptureReadback || !runtimeReadbackApprovalPackage || !runtimeReadbackImplementationReview || !reportLiveDeliveryApprovalPackage || !runtimeReadbackFixtureApproval || !runtimeReadbackPromotionGate || !ownerApprovedFixturePromotionGate || !canonicalRuntimeReadbackOwnerAcceptance || !failureReceiptNoSendReplay || !reviewerQueueNoWriteReadback || !resultCaptureNoWriteReadback || !resultCapturePromotionApprovalGate || !ownerApprovedResultCapturePromotionDryRun || !resultCaptureWriteGateReview || !resultCaptureWriterImplementationReview || !resultCaptureWriterDryRunFixture || !resultCaptureWriterDryRunReadback || !resultCaptureOwnerPromotionReview || !resultCaptureOwnerApprovedExecutionRehearsal || !resultCaptureOwnerAcceptanceMaintenanceGate || !resultCaptureOwnerAcceptanceReadbackPreflightHold || !resultCaptureOwnerApprovedPreflightReleasePackage || !resultCaptureOwnerApprovedReleaseReadinessReadback || !resultCaptureOwnerReleaseApprovalGate || !resultCapturePostReleaseVerifierRollbackGate || !resultCaptureFinalReleaseCandidateReadback || !resultCaptureReleaseAuthorizationHold || !resultCaptureReleaseAuthorizationReadbackGate || !resultCaptureReleaseVerifierPreflightGate || !resultCaptureReleaseVerifierOwnerReviewPacket || !resultCaptureReleaseDecisionHold || !resultCaptureReleaseDecisionReadback || !resultCaptureReleaseDecisionNextHandoff || !resultCaptureReleaseDecisionInputPrep || !resultCaptureReleaseDecisionOwnerResponsePreflight || !resultCaptureReleaseDecisionOwnerResponseReadback || !resultCaptureReleaseDecisionOwnerResponseAcceptanceGate || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !dependencySupplyChainDriftMonitor || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) {
return (
<div style={{ padding: 20 }}>
<div style={{ padding: 20, display: 'flex', flexDirection: 'column', gap: 12, minWidth: 0 }}>
{autonomousRuntimeControl ? (
<AutonomousRuntimeControlPriorityPanel control={autonomousRuntimeControl} t={t} />
) : null}
<GlassCard variant="subtle" padding="lg">
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12, padding: '24px 0' }}>
<AlertTriangle size={24} style={{ color: '#F59E0B' }} />
@@ -6377,7 +6519,7 @@ export function AutomationInventoryTab() {
<GateMatrixRow
label={t('globalControl.currentAutonomy.policy.low')}
value={currentAutonomyPolicy?.low_risk_controlled_apply_allowed ? 'on' : 'off'}
detail={t('globalControl.currentAutonomy.policy.noOwnerReview', { value: String(currentAutonomyPolicy?.owner_review_required_for_low_medium_high === false) })}
detail={t('globalControl.currentAutonomy.policy.noOwnerReview', { value: String(currentAutonomyPolicy?.owner_review_required_for_low_medium_high) })}
tone={currentAutonomyPolicy?.low_risk_controlled_apply_allowed ? 'ok' : 'warn'}
/>
<GateMatrixRow