feat(governance): 新增 release decision readback
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
Archive,
|
||||
BellOff,
|
||||
BellRing,
|
||||
BookOpenCheck,
|
||||
Boxes,
|
||||
CalendarClock,
|
||||
Database,
|
||||
@@ -86,6 +87,7 @@ import {
|
||||
type AiAgentResultCaptureReleaseAuthorizationHoldSnapshot,
|
||||
type AiAgentResultCaptureReleaseAuthorizationReadbackGateSnapshot,
|
||||
type AiAgentResultCaptureReleaseDecisionHoldSnapshot,
|
||||
type AiAgentResultCaptureReleaseDecisionReadbackSnapshot,
|
||||
type AiAgentResultCaptureReleaseVerifierPreflightGateSnapshot,
|
||||
type AiAgentResultCaptureReleaseVerifierOwnerReviewPacketSnapshot,
|
||||
type AiAgentResultCaptureWriterImplementationReviewSnapshot,
|
||||
@@ -497,6 +499,7 @@ export function AutomationInventoryTab() {
|
||||
const [resultCaptureReleaseVerifierPreflightGate, setResultCaptureReleaseVerifierPreflightGate] = useState<AiAgentResultCaptureReleaseVerifierPreflightGateSnapshot | null>(null)
|
||||
const [resultCaptureReleaseVerifierOwnerReviewPacket, setResultCaptureReleaseVerifierOwnerReviewPacket] = useState<AiAgentResultCaptureReleaseVerifierOwnerReviewPacketSnapshot | null>(null)
|
||||
const [resultCaptureReleaseDecisionHold, setResultCaptureReleaseDecisionHold] = useState<AiAgentResultCaptureReleaseDecisionHoldSnapshot | null>(null)
|
||||
const [resultCaptureReleaseDecisionReadback, setResultCaptureReleaseDecisionReadback] = useState<AiAgentResultCaptureReleaseDecisionReadbackSnapshot | null>(null)
|
||||
const [reportTruthActionabilityReview, setReportTruthActionabilityReview] = useState<AiAgentReportTruthActionabilityReviewSnapshot | null>(null)
|
||||
const [ownerDryRunPackage, setOwnerDryRunPackage] = useState<AiAgentOwnerApprovedFixtureDryRunSnapshot | null>(null)
|
||||
const [hostStatefulInventory, setHostStatefulInventory] = useState<AiAgentHostStatefulVersionInventorySnapshot | null>(null)
|
||||
@@ -572,6 +575,7 @@ export function AutomationInventoryTab() {
|
||||
apiClient.getAiAgentResultCaptureReleaseVerifierPreflightGate(),
|
||||
apiClient.getAiAgentResultCaptureReleaseVerifierOwnerReviewPacket(),
|
||||
apiClient.getAiAgentResultCaptureReleaseDecisionHold(),
|
||||
apiClient.getAiAgentResultCaptureReleaseDecisionReadback(),
|
||||
apiClient.getAiAgentReportTruthActionabilityReview(),
|
||||
apiClient.getAiAgentOwnerApprovedFixtureDryRun(),
|
||||
apiClient.getAiAgentHostStatefulVersionInventory(),
|
||||
@@ -646,6 +650,7 @@ export function AutomationInventoryTab() {
|
||||
resultCaptureReleaseVerifierPreflightGateResult,
|
||||
resultCaptureReleaseVerifierOwnerReviewPacketResult,
|
||||
resultCaptureReleaseDecisionHoldResult,
|
||||
resultCaptureReleaseDecisionReadbackResult,
|
||||
reportTruthActionabilityReviewResult,
|
||||
ownerDryRunPackageResult,
|
||||
hostStatefulInventoryResult,
|
||||
@@ -717,6 +722,7 @@ export function AutomationInventoryTab() {
|
||||
setResultCaptureReleaseVerifierPreflightGate(resultCaptureReleaseVerifierPreflightGateResult.status === 'fulfilled' ? resultCaptureReleaseVerifierPreflightGateResult.value : null)
|
||||
setResultCaptureReleaseVerifierOwnerReviewPacket(resultCaptureReleaseVerifierOwnerReviewPacketResult.status === 'fulfilled' ? resultCaptureReleaseVerifierOwnerReviewPacketResult.value : null)
|
||||
setResultCaptureReleaseDecisionHold(resultCaptureReleaseDecisionHoldResult.status === 'fulfilled' ? resultCaptureReleaseDecisionHoldResult.value : null)
|
||||
setResultCaptureReleaseDecisionReadback(resultCaptureReleaseDecisionReadbackResult.status === 'fulfilled' ? resultCaptureReleaseDecisionReadbackResult.value : null)
|
||||
setReportTruthActionabilityReview(reportTruthActionabilityReviewResult.status === 'fulfilled' ? reportTruthActionabilityReviewResult.value : null)
|
||||
setOwnerDryRunPackage(ownerDryRunPackageResult.status === 'fulfilled' ? ownerDryRunPackageResult.value : null)
|
||||
setHostStatefulInventory(hostStatefulInventoryResult.status === 'fulfilled' ? hostStatefulInventoryResult.value : null)
|
||||
@@ -786,6 +792,7 @@ export function AutomationInventoryTab() {
|
||||
resultCaptureReleaseVerifierPreflightGateResult,
|
||||
resultCaptureReleaseVerifierOwnerReviewPacketResult,
|
||||
resultCaptureReleaseDecisionHoldResult,
|
||||
resultCaptureReleaseDecisionReadbackResult,
|
||||
reportTruthActionabilityReviewResult,
|
||||
ownerDryRunPackageResult,
|
||||
hostStatefulInventoryResult,
|
||||
@@ -2028,7 +2035,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 || !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 || !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 || !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 || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) {
|
||||
return (
|
||||
<div style={{ padding: 20 }}>
|
||||
<GlassCard variant="subtle" padding="lg">
|
||||
@@ -3353,6 +3360,46 @@ export function AutomationInventoryTab() {
|
||||
+ resultCaptureReleaseDecisionHold.rollups.playbook_trust_write_count
|
||||
+ resultCaptureReleaseDecisionHold.rollups.production_write_count
|
||||
)
|
||||
const resultCaptureReleaseDecisionReadbackOverall = resultCaptureReleaseDecisionReadback.program_status.overall_completion_percent
|
||||
const resultCaptureReleaseDecisionReadbacks = resultCaptureReleaseDecisionReadback.rollups.release_decision_readback_count
|
||||
const resultCaptureReleaseOwnerDecisionReadbacks = resultCaptureReleaseDecisionReadback.rollups.owner_decision_readback_count
|
||||
const resultCaptureReleaseVerifierDecisionReadbacks = resultCaptureReleaseDecisionReadback.rollups.verifier_decision_readback_count
|
||||
const resultCaptureReleaseRollbackDecisionReadbacks = resultCaptureReleaseDecisionReadback.rollups.rollback_decision_readback_count
|
||||
const resultCaptureReleaseMaintenanceDecisionReadbacks = resultCaptureReleaseDecisionReadback.rollups.maintenance_window_decision_readback_count
|
||||
const resultCaptureReleaseLiveApplyDecisionReadbacks = resultCaptureReleaseDecisionReadback.rollups.live_apply_decision_readback_count
|
||||
const resultCaptureReleaseDecisionReadbackBlockedTransitions = resultCaptureReleaseDecisionReadback.rollups.blocked_readback_transition_count
|
||||
const resultCaptureReleaseDecisionReadbackActions = resultCaptureReleaseDecisionReadback.rollups.operator_action_count
|
||||
const resultCaptureReleaseDecisionReadbackApprovalRequired = (
|
||||
resultCaptureReleaseDecisionReadback.rollups.approval_required_release_decision_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.approval_required_owner_decision_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.approval_required_verifier_decision_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.approval_required_rollback_decision_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.approval_required_maintenance_window_decision_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.approval_required_live_apply_decision_count
|
||||
)
|
||||
const resultCaptureReleaseDecisionReadbackBlocked = (
|
||||
resultCaptureReleaseDecisionReadback.rollups.blocked_release_decision_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.blocked_owner_decision_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.blocked_verifier_decision_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.blocked_rollback_decision_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.blocked_maintenance_window_decision_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.blocked_live_apply_decision_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.critical_blocker_count
|
||||
)
|
||||
const resultCaptureReleaseDecisionReadbackLiveWrites = (
|
||||
resultCaptureReleaseDecisionReadback.rollups.writer_apply_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.execution_apply_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.receipt_write_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.reviewer_queue_write_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.gateway_queue_write_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.telegram_send_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.bot_api_call_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.report_receipt_write_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.result_capture_write_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.learning_write_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.playbook_trust_write_count
|
||||
+ resultCaptureReleaseDecisionReadback.rollups.production_write_count
|
||||
)
|
||||
const reportTruthOverall = reportTruthActionabilityReview.program_status.overall_completion_percent
|
||||
const reportTruthFindings = reportTruthActionabilityReview.rollups.zero_signal_finding_count
|
||||
const reportTruthCritical = reportTruthActionabilityReview.rollups.critical_finding_count
|
||||
@@ -8087,6 +8134,160 @@ export function AutomationInventoryTab() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ padding: 12, border: '0.5px solid #aebfd8', borderRadius: 7, background: '#f8fbff', 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 }}>
|
||||
<BookOpenCheck size={14} style={{ color: '#275e9c' }} />
|
||||
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 13, fontWeight: 700, color: '#141413' }}>
|
||||
{t('resultCaptureReleaseDecisionReadback.title')}
|
||||
</span>
|
||||
</div>
|
||||
<Chip
|
||||
value={t('resultCaptureReleaseDecisionReadback.source', {
|
||||
generated: formatDateTime(resultCaptureReleaseDecisionReadback.generated_at),
|
||||
current: resultCaptureReleaseDecisionReadback.program_status.current_task_id,
|
||||
next: resultCaptureReleaseDecisionReadback.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('resultCaptureReleaseDecisionReadback.metrics.overall')} value={`${resultCaptureReleaseDecisionReadbackOverall}%`} tone="ok" icon={<Gauge size={16} />} />
|
||||
<MetricCard label={t('resultCaptureReleaseDecisionReadback.metrics.releaseReadbacks')} value={resultCaptureReleaseDecisionReadbacks} tone="warn" icon={<BookOpenCheck size={16} />} />
|
||||
<MetricCard label={t('resultCaptureReleaseDecisionReadback.metrics.ownerReadbacks')} value={resultCaptureReleaseOwnerDecisionReadbacks} tone="warn" icon={<ShieldCheck size={16} />} />
|
||||
<MetricCard label={t('resultCaptureReleaseDecisionReadback.metrics.verifierReadbacks')} value={resultCaptureReleaseVerifierDecisionReadbacks} tone="warn" icon={<ShieldAlert size={16} />} />
|
||||
<MetricCard label={t('resultCaptureReleaseDecisionReadback.metrics.rollbackReadbacks')} value={resultCaptureReleaseRollbackDecisionReadbacks} tone="warn" icon={<Undo2 size={16} />} />
|
||||
<MetricCard label={t('resultCaptureReleaseDecisionReadback.metrics.maintenanceReadbacks')} value={resultCaptureReleaseMaintenanceDecisionReadbacks} tone="warn" icon={<CalendarClock size={16} />} />
|
||||
<MetricCard label={t('resultCaptureReleaseDecisionReadback.metrics.liveApplyReadbacks')} value={resultCaptureReleaseLiveApplyDecisionReadbacks} tone="warn" icon={<Lock size={16} />} />
|
||||
<MetricCard label={t('resultCaptureReleaseDecisionReadback.metrics.blockers')} value={resultCaptureReleaseDecisionReadbackBlockedTransitions} tone="danger" icon={<AlertTriangle size={16} />} />
|
||||
<MetricCard label={t('resultCaptureReleaseDecisionReadback.metrics.actions')} value={resultCaptureReleaseDecisionReadbackActions} tone="warn" icon={<Target size={16} />} />
|
||||
<MetricCard label={t('resultCaptureReleaseDecisionReadback.metrics.approvalRequired')} value={resultCaptureReleaseDecisionReadbackApprovalRequired} tone="warn" icon={<ShieldAlert size={16} />} />
|
||||
<MetricCard label={t('resultCaptureReleaseDecisionReadback.metrics.blocked')} value={resultCaptureReleaseDecisionReadbackBlocked} tone="danger" icon={<ShieldAlert size={16} />} />
|
||||
<MetricCard label={t('resultCaptureReleaseDecisionReadback.metrics.liveWrites')} value={resultCaptureReleaseDecisionReadbackLiveWrites} tone={resultCaptureReleaseDecisionReadbackLiveWrites === 0 ? 'ok' : 'danger'} icon={<BellOff size={16} />} />
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(260px, 1fr))', gap: 10 }}>
|
||||
<div style={{ padding: 10, border: '0.5px solid #d7c7a1', borderRadius: 7, background: '#fff', minWidth: 0 }}>
|
||||
<SmallLabel>{t('resultCaptureReleaseDecisionReadback.priorTitle')}</SmallLabel>
|
||||
<p style={{ margin: '6px 0 8px', fontFamily: "'DM Mono', monospace", fontSize: 10, lineHeight: 1.5, color: '#5c5a55', overflowWrap: 'anywhere' }}>
|
||||
{resultCaptureReleaseDecisionReadback.prior_release_decision_hold.readiness_note}
|
||||
</p>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={resultCaptureReleaseDecisionReadback.prior_release_decision_hold.schema_version} />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.metrics.releaseReadbacks') + ` ${resultCaptureReleaseDecisionReadbacks}`} muted />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.metrics.liveWrites') + ` ${resultCaptureReleaseDecisionReadback.prior_release_decision_hold.result_capture_write_count}`} muted />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ padding: 10, border: '0.5px solid #d7c7a1', borderRadius: 7, background: '#fff', minWidth: 0 }}>
|
||||
<SmallLabel>{t('resultCaptureReleaseDecisionReadback.truthTitle')}</SmallLabel>
|
||||
<p style={{ margin: '6px 0 8px', fontFamily: "'DM Mono', monospace", fontSize: 10, lineHeight: 1.5, color: '#5c5a55', overflowWrap: 'anywhere' }}>
|
||||
{resultCaptureReleaseDecisionReadback.release_decision_readback_truth.truth_note}
|
||||
</p>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.flags.p2Loaded', { value: String(resultCaptureReleaseDecisionReadback.release_decision_readback_truth.p2_138_release_decision_hold_loaded) })} />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.flags.readbackReady', { value: String(resultCaptureReleaseDecisionReadback.release_decision_readback_truth.release_decision_readback_ready) })} />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.flags.maintenanceStillRequired', { value: String(resultCaptureReleaseDecisionReadback.release_decision_readback_truth.maintenance_window_decision_still_required) })} />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.flags.liveApplyStillRequired', { value: String(resultCaptureReleaseDecisionReadback.release_decision_readback_truth.live_apply_decision_still_required) })} />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.labels.ownerReleaseAuthorized', { value: String(resultCaptureReleaseDecisionReadback.rollups.owner_release_authorized_count) })} muted />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.labels.decisionPassed', { value: String(resultCaptureReleaseDecisionReadback.rollups.release_decision_pass_count) })} muted />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.labels.gatewayWrites', { value: String(resultCaptureReleaseDecisionReadback.rollups.gateway_queue_write_count) })} muted />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.labels.telegramSends', { value: String(resultCaptureReleaseDecisionReadback.rollups.telegram_send_count) })} muted />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.labels.productionWrites', { value: String(resultCaptureReleaseDecisionReadback.rollups.production_write_count) })} muted />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 10 }} className="automation-inventory-live-read-card-grid">
|
||||
{resultCaptureReleaseDecisionReadback.release_decision_readbacks.slice(0, 5).map(readback => (
|
||||
<div key={readback.readback_id} style={{ padding: 10, border: '0.5px solid #aebfd8', 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' }}>
|
||||
{readback.display_name}
|
||||
</span>
|
||||
<Chip value={readback.readback_status} muted={readback.readback_status === 'readback_complete'} />
|
||||
</div>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#64727a', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
|
||||
{readback.readback_summary}
|
||||
</span>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={redisDryRunValueLabel('agents', readback.owner_agent)} muted />
|
||||
<Chip value={readback.readback_mode} muted />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.labels.decisionPassed', { value: String(readback.release_decision_passed) })} muted />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.labels.authorizationGranted', { value: String(readback.release_authorization_granted) })} muted />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.labels.telegramSendAllowed', { value: String(readback.telegram_send_allowed) })} muted />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 10 }} className="automation-inventory-live-read-card-grid">
|
||||
{[
|
||||
...resultCaptureReleaseDecisionReadback.owner_decision_readbacks.slice(0, 2),
|
||||
...resultCaptureReleaseDecisionReadback.verifier_decision_readbacks.slice(0, 2),
|
||||
...resultCaptureReleaseDecisionReadback.rollback_decision_readbacks.slice(0, 2),
|
||||
...resultCaptureReleaseDecisionReadback.maintenance_window_decision_readbacks.slice(0, 2),
|
||||
...resultCaptureReleaseDecisionReadback.live_apply_decision_readbacks.slice(0, 2),
|
||||
].map(readback => (
|
||||
<div key={readback.readback_id} style={{ padding: 10, border: '0.5px solid #aebfd8', 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' }}>
|
||||
{readback.display_name}
|
||||
</span>
|
||||
<Chip value={readback.readback_status} muted={readback.readback_status === 'readback_complete'} />
|
||||
</div>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#64727a', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
|
||||
{readback.readback_summary}
|
||||
</span>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={redisDryRunValueLabel('agents', readback.owner_agent)} muted />
|
||||
<Chip value={readback.readback_mode} muted />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.labels.runtimeWriteAllowed', { value: String(readback.runtime_write_allowed) })} muted />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.labels.telegramSendAllowed', { value: String(readback.telegram_send_allowed) })} muted />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 10 }} className="automation-inventory-live-read-card-grid">
|
||||
{resultCaptureReleaseDecisionReadback.blocked_readback_transitions.slice(0, 6).map(transition => (
|
||||
<div key={transition.transition_id} style={{ padding: 10, border: '0.5px solid #e0b4a3', 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' }}>
|
||||
{transition.transition_id}
|
||||
</span>
|
||||
<Chip value={transition.status} muted />
|
||||
</div>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#64727a', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
|
||||
{transition.reason}
|
||||
</span>
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.labels.runtimeWriteAllowed', { value: String(transition.runtime_write_allowed) })} muted />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 10 }} className="automation-inventory-live-read-card-grid">
|
||||
{resultCaptureReleaseDecisionReadback.operator_actions.slice(0, 5).map(action => (
|
||||
<div key={action.action_id} style={{ padding: 10, border: '0.5px solid #aebfd8', 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' }}>
|
||||
{action.action_id}
|
||||
</span>
|
||||
<Chip value={action.status} muted={action.status === 'ready_for_operator_review'} />
|
||||
</div>
|
||||
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#64727a', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
|
||||
{action.operator_instruction}
|
||||
</span>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
|
||||
<Chip value={redisDryRunValueLabel('agents', action.owner_agent)} muted />
|
||||
<Chip value={t('resultCaptureReleaseDecisionReadback.labels.runtimeWriteAllowed', { value: String(action.runtime_write_allowed) })} muted />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ padding: 12, border: '0.5px solid #aebfd8', borderRadius: 7, background: '#f8fbff', 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 }}>
|
||||
|
||||
@@ -590,6 +590,11 @@ export const apiClient = {
|
||||
return handleResponse<AiAgentResultCaptureReleaseDecisionHoldSnapshot>(res)
|
||||
},
|
||||
|
||||
async getAiAgentResultCaptureReleaseDecisionReadback() {
|
||||
const res = await fetch(`${API_BASE_URL}/agents/agent-result-capture-release-decision-readback`)
|
||||
return handleResponse<AiAgentResultCaptureReleaseDecisionReadbackSnapshot>(res)
|
||||
},
|
||||
|
||||
async getAiAgentOwnerApprovedFixtureDryRun() {
|
||||
const res = await fetch(`${API_BASE_URL}/agents/agent-owner-approved-fixture-dry-run`)
|
||||
return handleResponse<AiAgentOwnerApprovedFixtureDryRunSnapshot>(res)
|
||||
@@ -9305,6 +9310,229 @@ export interface AiAgentResultCaptureReleaseDecisionHoldSnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
interface AiAgentReleaseDecisionReadbackItem {
|
||||
readback_id: string
|
||||
display_name: string
|
||||
owner_agent: string
|
||||
source_hold_id: string
|
||||
readback_status: string
|
||||
readback_mode: string
|
||||
readback_summary: string
|
||||
release_decision_passed: boolean
|
||||
release_authorization_granted: boolean
|
||||
runtime_write_allowed: boolean
|
||||
telegram_send_allowed: boolean
|
||||
evidence_hash?: string
|
||||
}
|
||||
|
||||
export interface AiAgentResultCaptureReleaseDecisionReadbackSnapshot {
|
||||
schema_version: 'ai_agent_result_capture_release_decision_readback_v1'
|
||||
generated_at: string
|
||||
program_status: {
|
||||
overall_completion_percent: number
|
||||
current_priority: 'P0' | 'P1' | 'P2' | 'P3'
|
||||
current_task_id: 'P2-139'
|
||||
next_task_id: 'P2-140'
|
||||
read_only_mode: true
|
||||
runtime_authority: 'result_capture_release_decision_readback_only_no_live_write'
|
||||
status_note: string
|
||||
}
|
||||
source_refs: string[]
|
||||
prior_release_decision_hold: {
|
||||
schema_version: string
|
||||
release_decision_hold_count: number
|
||||
owner_decision_hold_count: number
|
||||
verifier_decision_hold_count: number
|
||||
rollback_decision_hold_count: number
|
||||
maintenance_window_decision_hold_count: number
|
||||
live_apply_decision_hold_count: number
|
||||
blocked_decision_transition_count: number
|
||||
operator_action_count: number
|
||||
approval_required_total: number
|
||||
blocked_total: number
|
||||
readiness_note: string
|
||||
owner_release_authorized_count: number
|
||||
owner_release_approved_count: number
|
||||
owner_review_approved_count: number
|
||||
owner_decision_approved_count: number
|
||||
verifier_decision_approved_count: number
|
||||
maintenance_window_approved_count: number
|
||||
rollback_owner_confirmed_count: number
|
||||
post_release_verifier_ready_count: number
|
||||
final_release_candidate_approved_count: number
|
||||
final_release_candidate_pass_count: number
|
||||
release_decision_pass_count: number
|
||||
release_authorization_granted_count: number
|
||||
release_authorization_pass_count: number
|
||||
rollback_release_pass_count: number
|
||||
live_apply_release_pass_count: number
|
||||
writer_apply_count: number
|
||||
execution_apply_count: number
|
||||
receipt_write_count: number
|
||||
reviewer_queue_write_count: number
|
||||
gateway_queue_write_count: number
|
||||
telegram_send_count: number
|
||||
bot_api_call_count: number
|
||||
report_receipt_write_count: number
|
||||
result_capture_write_count: number
|
||||
learning_write_count: number
|
||||
playbook_trust_write_count: number
|
||||
production_write_count: number
|
||||
secret_read_count: number
|
||||
destructive_operation_count: number
|
||||
}
|
||||
release_decision_readback_truth: {
|
||||
p2_138_release_decision_hold_loaded: boolean
|
||||
release_decision_readback_ready: boolean
|
||||
owner_decision_still_required: boolean
|
||||
verifier_decision_still_required: boolean
|
||||
rollback_decision_still_required: boolean
|
||||
maintenance_window_decision_still_required: boolean
|
||||
live_apply_decision_still_required: boolean
|
||||
redaction_review_still_required: boolean
|
||||
release_decision_readback_only: boolean
|
||||
truth_note: string
|
||||
owner_release_authorized: boolean
|
||||
owner_release_approved: boolean
|
||||
owner_review_approved: boolean
|
||||
owner_decision_approved: boolean
|
||||
verifier_decision_approved: boolean
|
||||
maintenance_window_approved: boolean
|
||||
rollback_owner_confirmed: boolean
|
||||
post_release_verifier_ready: boolean
|
||||
final_release_candidate_approved: boolean
|
||||
final_release_candidate_passed: boolean
|
||||
release_decision_passed: boolean
|
||||
release_authorization_granted: boolean
|
||||
release_authorization_passed: boolean
|
||||
rollback_release_passed: boolean
|
||||
live_apply_release_passed: boolean
|
||||
writer_apply_enabled: boolean
|
||||
execution_apply_enabled: boolean
|
||||
receipt_write_enabled: boolean
|
||||
reviewer_queue_write_enabled: boolean
|
||||
gateway_queue_write_enabled: boolean
|
||||
telegram_send_enabled: boolean
|
||||
bot_api_call_enabled: boolean
|
||||
report_receipt_write_enabled: boolean
|
||||
result_capture_write_enabled: boolean
|
||||
learning_write_enabled: boolean
|
||||
playbook_trust_write_enabled: boolean
|
||||
production_write_enabled: boolean
|
||||
secret_read_enabled: boolean
|
||||
destructive_operation_enabled: boolean
|
||||
owner_release_authorized_count: number
|
||||
owner_release_approved_count: number
|
||||
owner_review_approved_count: number
|
||||
owner_decision_approved_count: number
|
||||
verifier_decision_approved_count: number
|
||||
maintenance_window_approved_count: number
|
||||
rollback_owner_confirmed_count: number
|
||||
post_release_verifier_ready_count: number
|
||||
final_release_candidate_approved_count: number
|
||||
final_release_candidate_pass_count: number
|
||||
release_decision_pass_count: number
|
||||
release_authorization_granted_count: number
|
||||
release_authorization_pass_count: number
|
||||
rollback_release_pass_count: number
|
||||
live_apply_release_pass_count: number
|
||||
writer_apply_count: number
|
||||
execution_apply_count: number
|
||||
receipt_write_count: number
|
||||
reviewer_queue_write_count: number
|
||||
gateway_queue_write_count: number
|
||||
telegram_send_count: number
|
||||
bot_api_call_count: number
|
||||
report_receipt_write_count: number
|
||||
result_capture_write_count: number
|
||||
learning_write_count: number
|
||||
playbook_trust_write_count: number
|
||||
production_write_count: number
|
||||
secret_read_count: number
|
||||
destructive_operation_count: number
|
||||
}
|
||||
release_decision_readbacks: AiAgentReleaseDecisionReadbackItem[]
|
||||
owner_decision_readbacks: AiAgentReleaseDecisionReadbackItem[]
|
||||
verifier_decision_readbacks: AiAgentReleaseDecisionReadbackItem[]
|
||||
rollback_decision_readbacks: AiAgentReleaseDecisionReadbackItem[]
|
||||
maintenance_window_decision_readbacks: AiAgentReleaseDecisionReadbackItem[]
|
||||
live_apply_decision_readbacks: AiAgentReleaseDecisionReadbackItem[]
|
||||
blocked_readback_transitions: {
|
||||
transition_id: string
|
||||
status: string
|
||||
reason: string
|
||||
runtime_write_allowed: boolean
|
||||
}[]
|
||||
operator_actions: {
|
||||
action_id: string
|
||||
owner_agent: string
|
||||
status: string
|
||||
operator_instruction: string
|
||||
runtime_write_allowed: boolean
|
||||
}[]
|
||||
display_redaction_contract: {
|
||||
redaction_required: boolean
|
||||
raw_prompt_display_allowed: boolean
|
||||
private_reasoning_display_allowed: boolean
|
||||
secret_value_display_allowed: boolean
|
||||
raw_runtime_payload_display_allowed: boolean
|
||||
internal_collaboration_content_display_allowed: boolean
|
||||
frontend_display_policy: string
|
||||
}
|
||||
rollups: {
|
||||
release_decision_readback_count: number
|
||||
owner_decision_readback_count: number
|
||||
verifier_decision_readback_count: number
|
||||
rollback_decision_readback_count: number
|
||||
maintenance_window_decision_readback_count: number
|
||||
live_apply_decision_readback_count: number
|
||||
blocked_readback_transition_count: number
|
||||
operator_action_count: number
|
||||
approval_required_release_decision_count: number
|
||||
blocked_release_decision_count: number
|
||||
approval_required_owner_decision_count: number
|
||||
blocked_owner_decision_count: number
|
||||
approval_required_verifier_decision_count: number
|
||||
blocked_verifier_decision_count: number
|
||||
approval_required_rollback_decision_count: number
|
||||
blocked_rollback_decision_count: number
|
||||
approval_required_maintenance_window_decision_count: number
|
||||
blocked_maintenance_window_decision_count: number
|
||||
approval_required_live_apply_decision_count: number
|
||||
blocked_live_apply_decision_count: number
|
||||
critical_blocker_count: number
|
||||
owner_release_authorized_count: number
|
||||
owner_release_approved_count: number
|
||||
owner_review_approved_count: number
|
||||
owner_decision_approved_count: number
|
||||
verifier_decision_approved_count: number
|
||||
maintenance_window_approved_count: number
|
||||
rollback_owner_confirmed_count: number
|
||||
post_release_verifier_ready_count: number
|
||||
final_release_candidate_approved_count: number
|
||||
final_release_candidate_pass_count: number
|
||||
release_decision_pass_count: number
|
||||
release_authorization_granted_count: number
|
||||
release_authorization_pass_count: number
|
||||
rollback_release_pass_count: number
|
||||
live_apply_release_pass_count: number
|
||||
writer_apply_count: number
|
||||
execution_apply_count: number
|
||||
receipt_write_count: number
|
||||
reviewer_queue_write_count: number
|
||||
gateway_queue_write_count: number
|
||||
telegram_send_count: number
|
||||
bot_api_call_count: number
|
||||
report_receipt_write_count: number
|
||||
result_capture_write_count: number
|
||||
learning_write_count: number
|
||||
playbook_trust_write_count: number
|
||||
production_write_count: number
|
||||
secret_read_count: number
|
||||
destructive_operation_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