feat(governance): 新增 P2-143 owner response 預檢
All checks were successful
Code Review / ai-code-review (push) Successful in 13s
CD Pipeline / tests (push) Successful in 1m28s
CD Pipeline / build-and-deploy (push) Successful in 4m46s
CD Pipeline / post-deploy-checks (push) Successful in 1m48s

This commit is contained in:
Your Name
2026-06-14 14:37:04 +08:00
parent 1a2c9e36c7
commit 755b0a8d30
12 changed files with 1366 additions and 7 deletions

View File

@@ -91,6 +91,7 @@ import {
type AiAgentResultCaptureReleaseDecisionReadbackSnapshot,
type AiAgentResultCaptureReleaseDecisionNextHandoffSnapshot,
type AiAgentResultCaptureReleaseDecisionInputPrepSnapshot,
type AiAgentResultCaptureReleaseDecisionOwnerResponsePreflightSnapshot,
type AiAgentResultCaptureReleaseVerifierPreflightGateSnapshot,
type AiAgentResultCaptureReleaseVerifierOwnerReviewPacketSnapshot,
type AiAgentResultCaptureWriterImplementationReviewSnapshot,
@@ -515,6 +516,7 @@ export function AutomationInventoryTab() {
const [resultCaptureReleaseDecisionReadback, setResultCaptureReleaseDecisionReadback] = useState<AiAgentResultCaptureReleaseDecisionReadbackSnapshot | null>(null)
const [resultCaptureReleaseDecisionNextHandoff, setResultCaptureReleaseDecisionNextHandoff] = useState<AiAgentResultCaptureReleaseDecisionNextHandoffSnapshot | null>(null)
const [resultCaptureReleaseDecisionInputPrep, setResultCaptureReleaseDecisionInputPrep] = useState<AiAgentResultCaptureReleaseDecisionInputPrepSnapshot | null>(null)
const [resultCaptureReleaseDecisionOwnerResponsePreflight, setResultCaptureReleaseDecisionOwnerResponsePreflight] = useState<AiAgentResultCaptureReleaseDecisionOwnerResponsePreflightSnapshot | null>(null)
const [reportTruthActionabilityReview, setReportTruthActionabilityReview] = useState<AiAgentReportTruthActionabilityReviewSnapshot | null>(null)
const [ownerDryRunPackage, setOwnerDryRunPackage] = useState<AiAgentOwnerApprovedFixtureDryRunSnapshot | null>(null)
const [hostStatefulInventory, setHostStatefulInventory] = useState<AiAgentHostStatefulVersionInventorySnapshot | null>(null)
@@ -594,6 +596,7 @@ export function AutomationInventoryTab() {
apiClient.getAiAgentResultCaptureReleaseDecisionReadback(),
apiClient.getAiAgentResultCaptureReleaseDecisionNextHandoff(),
apiClient.getAiAgentResultCaptureReleaseDecisionInputPrep(),
apiClient.getAiAgentResultCaptureReleaseDecisionOwnerResponsePreflight(),
apiClient.getAiAgentReportTruthActionabilityReview(),
apiClient.getAiAgentOwnerApprovedFixtureDryRun(),
apiClient.getAiAgentHostStatefulVersionInventory(),
@@ -672,6 +675,7 @@ export function AutomationInventoryTab() {
resultCaptureReleaseDecisionReadbackResult,
resultCaptureReleaseDecisionNextHandoffResult,
resultCaptureReleaseDecisionInputPrepResult,
resultCaptureReleaseDecisionOwnerResponsePreflightResult,
reportTruthActionabilityReviewResult,
ownerDryRunPackageResult,
hostStatefulInventoryResult,
@@ -747,6 +751,7 @@ export function AutomationInventoryTab() {
setResultCaptureReleaseDecisionReadback(resultCaptureReleaseDecisionReadbackResult.status === 'fulfilled' ? resultCaptureReleaseDecisionReadbackResult.value : null)
setResultCaptureReleaseDecisionNextHandoff(resultCaptureReleaseDecisionNextHandoffResult.status === 'fulfilled' ? resultCaptureReleaseDecisionNextHandoffResult.value : null)
setResultCaptureReleaseDecisionInputPrep(resultCaptureReleaseDecisionInputPrepResult.status === 'fulfilled' ? resultCaptureReleaseDecisionInputPrepResult.value : null)
setResultCaptureReleaseDecisionOwnerResponsePreflight(resultCaptureReleaseDecisionOwnerResponsePreflightResult.status === 'fulfilled' ? resultCaptureReleaseDecisionOwnerResponsePreflightResult.value : null)
setReportTruthActionabilityReview(reportTruthActionabilityReviewResult.status === 'fulfilled' ? reportTruthActionabilityReviewResult.value : null)
setOwnerDryRunPackage(ownerDryRunPackageResult.status === 'fulfilled' ? ownerDryRunPackageResult.value : null)
setHostStatefulInventory(hostStatefulInventoryResult.status === 'fulfilled' ? hostStatefulInventoryResult.value : null)
@@ -820,6 +825,7 @@ export function AutomationInventoryTab() {
resultCaptureReleaseDecisionReadbackResult,
resultCaptureReleaseDecisionNextHandoffResult,
resultCaptureReleaseDecisionInputPrepResult,
resultCaptureReleaseDecisionOwnerResponsePreflightResult,
reportTruthActionabilityReviewResult,
ownerDryRunPackageResult,
hostStatefulInventoryResult,
@@ -2075,7 +2081,7 @@ export function AutomationInventoryTab() {
)
}
if (error || !snapshot || !backlog || !backupTargets || !backupReadiness || !backupPolicy || !offsiteEscrow || !giteaHealth || !observabilityMatrix || !providerRouteMatrix || !deploymentLayout || !warRoom || !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 || !resultCaptureReleaseDecisionNextHandoff || !resultCaptureReleaseDecisionInputPrep || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) {
if (error || !snapshot || !backlog || !backupTargets || !backupReadiness || !backupPolicy || !offsiteEscrow || !giteaHealth || !observabilityMatrix || !providerRouteMatrix || !deploymentLayout || !warRoom || !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 || !resultCaptureReleaseDecisionNextHandoff || !resultCaptureReleaseDecisionInputPrep || !resultCaptureReleaseDecisionOwnerResponsePreflight || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) {
return (
<div style={{ padding: 20 }}>
<GlassCard variant="subtle" padding="lg">
@@ -3482,6 +3488,32 @@ export function AutomationInventoryTab() {
+ resultCaptureReleaseDecisionInputPrep.rollups.playbook_trust_write_count
+ resultCaptureReleaseDecisionInputPrep.rollups.production_write_count
)
const resultCaptureReleaseDecisionOwnerResponsePreflightOverall = resultCaptureReleaseDecisionOwnerResponsePreflight.program_status.overall_completion_percent
const resultCaptureReleaseDecisionOwnerResponseLanes = resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.response_intake_lane_count
const resultCaptureReleaseDecisionOwnerResponseFields = resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.required_owner_field_count
const resultCaptureReleaseDecisionOwnerResponseChecks = resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.intake_validation_check_count
const resultCaptureReleaseDecisionOwnerResponseGuards = resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.rejection_guard_count
const resultCaptureReleaseDecisionOwnerResponseActions = resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.operator_action_count
const resultCaptureReleaseDecisionOwnerResponseWaiting = resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.waiting_external_response_count
const resultCaptureReleaseDecisionOwnerResponseReceived = (
resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.owner_response_received_count
+ resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.owner_response_accepted_count
+ resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.redacted_payload_ingested_count
)
const resultCaptureReleaseDecisionOwnerResponseLiveWrites = (
resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.writer_apply_count
+ resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.execution_apply_count
+ resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.receipt_write_count
+ resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.reviewer_queue_write_count
+ resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.gateway_queue_write_count
+ resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.telegram_send_count
+ resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.bot_api_call_count
+ resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.report_receipt_write_count
+ resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.result_capture_write_count
+ resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.learning_write_count
+ resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.playbook_trust_write_count
+ resultCaptureReleaseDecisionOwnerResponsePreflight.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
@@ -8187,6 +8219,129 @@ 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 }}>
<ShieldCheck size={14} style={{ color: '#275e9c' }} />
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 13, fontWeight: 700, color: '#141413' }}>
{t('resultCaptureReleaseDecisionOwnerResponsePreflight.title')}
</span>
</div>
<Chip
value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.source', {
generated: formatDateTime(resultCaptureReleaseDecisionOwnerResponsePreflight.generated_at),
current: resultCaptureReleaseDecisionOwnerResponsePreflight.program_status.current_task_id,
next: resultCaptureReleaseDecisionOwnerResponsePreflight.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('resultCaptureReleaseDecisionOwnerResponsePreflight.metrics.overall')} value={`${resultCaptureReleaseDecisionOwnerResponsePreflightOverall}%`} tone="ok" icon={<Gauge size={16} />} />
<MetricCard label={t('resultCaptureReleaseDecisionOwnerResponsePreflight.metrics.lanes')} value={resultCaptureReleaseDecisionOwnerResponseLanes} tone="warn" icon={<Route size={16} />} />
<MetricCard label={t('resultCaptureReleaseDecisionOwnerResponsePreflight.metrics.requiredFields')} value={resultCaptureReleaseDecisionOwnerResponseFields} tone="danger" icon={<FileText size={16} />} />
<MetricCard label={t('resultCaptureReleaseDecisionOwnerResponsePreflight.metrics.validationChecks')} value={resultCaptureReleaseDecisionOwnerResponseChecks} tone="warn" icon={<ShieldCheck size={16} />} />
<MetricCard label={t('resultCaptureReleaseDecisionOwnerResponsePreflight.metrics.rejectionGuards')} value={resultCaptureReleaseDecisionOwnerResponseGuards} tone="danger" icon={<ShieldAlert size={16} />} />
<MetricCard label={t('resultCaptureReleaseDecisionOwnerResponsePreflight.metrics.actions')} value={resultCaptureReleaseDecisionOwnerResponseActions} tone="warn" icon={<Target size={16} />} />
<MetricCard label={t('resultCaptureReleaseDecisionOwnerResponsePreflight.metrics.waiting')} value={resultCaptureReleaseDecisionOwnerResponseWaiting} tone="warn" icon={<Lock size={16} />} />
<MetricCard label={t('resultCaptureReleaseDecisionOwnerResponsePreflight.metrics.received')} value={resultCaptureReleaseDecisionOwnerResponseReceived} tone={resultCaptureReleaseDecisionOwnerResponseReceived === 0 ? 'ok' : 'danger'} icon={<Archive size={16} />} />
<MetricCard label={t('resultCaptureReleaseDecisionOwnerResponsePreflight.metrics.liveWrites')} value={resultCaptureReleaseDecisionOwnerResponseLiveWrites} tone={resultCaptureReleaseDecisionOwnerResponseLiveWrites === 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('resultCaptureReleaseDecisionOwnerResponsePreflight.priorTitle')}</SmallLabel>
<p style={{ margin: '6px 0 8px', fontFamily: "'DM Mono', monospace", fontSize: 10, lineHeight: 1.5, color: '#5c5a55', overflowWrap: 'anywhere' }}>
{resultCaptureReleaseDecisionOwnerResponsePreflight.prior_decision_input_prep.readiness_note}
</p>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
<Chip value={resultCaptureReleaseDecisionOwnerResponsePreflight.prior_decision_input_prep.schema_version} />
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.labels.priorCurrent', { value: resultCaptureReleaseDecisionOwnerResponsePreflight.prior_decision_input_prep.current_task_id })} muted />
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.labels.priorNext', { value: resultCaptureReleaseDecisionOwnerResponsePreflight.prior_decision_input_prep.next_task_id })} muted />
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.metrics.requiredFields') + ` ${resultCaptureReleaseDecisionOwnerResponsePreflight.prior_decision_input_prep.missing_input_field_count}`} muted />
</div>
</div>
<div style={{ padding: 10, border: '0.5px solid #d7c7a1', borderRadius: 7, background: '#fff', minWidth: 0 }}>
<SmallLabel>{t('resultCaptureReleaseDecisionOwnerResponsePreflight.truthTitle')}</SmallLabel>
<p style={{ margin: '6px 0 8px', fontFamily: "'DM Mono', monospace", fontSize: 10, lineHeight: 1.5, color: '#5c5a55', overflowWrap: 'anywhere' }}>
{resultCaptureReleaseDecisionOwnerResponsePreflight.owner_response_preflight_truth.truth_note}
</p>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.flags.p2Loaded', { value: String(resultCaptureReleaseDecisionOwnerResponsePreflight.owner_response_preflight_truth.p2_141_input_prep_loaded) })} />
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.flags.preflightOnly', { value: String(resultCaptureReleaseDecisionOwnerResponsePreflight.owner_response_preflight_truth.preflight_only_mode) })} />
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.flags.rejectionPolicy', { value: String(resultCaptureReleaseDecisionOwnerResponsePreflight.owner_response_preflight_truth.rejection_policy_active) })} />
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.labels.ownerReceived', { value: String(resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.owner_response_received_count) })} muted />
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.labels.redactedPayload', { value: String(resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.redacted_payload_ingested_count) })} muted />
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.labels.gatewayWrites', { value: String(resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.gateway_queue_write_count) })} muted />
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.labels.telegramSends', { value: String(resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.telegram_send_count) })} muted />
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.labels.productionWrites', { value: String(resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.production_write_count) })} muted />
</div>
</div>
</div>
<SmallLabel>{t('resultCaptureReleaseDecisionOwnerResponsePreflight.laneTitle')}</SmallLabel>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 10 }} className="automation-inventory-live-read-card-grid">
{resultCaptureReleaseDecisionOwnerResponsePreflight.response_intake_lanes.slice(0, 5).map(lane => (
<div key={lane.lane_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' }}>
{lane.display_name}
</span>
<Chip value={lane.target_next_task_id} muted />
</div>
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#64727a', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
{lane.preflight_summary}
</span>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
<Chip value={redisDryRunValueLabel('agents', lane.owner_agent)} muted />
<Chip value={lane.intake_status} muted />
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.labels.requiredFields', { value: String(lane.required_fields.length) })} muted />
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.labels.accepted', { value: String(lane.accepted) })} muted />
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.labels.runtimeWriteAllowed', { value: String(lane.runtime_write_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">
{resultCaptureReleaseDecisionOwnerResponsePreflight.rejection_guards.slice(0, 6).map(guard => (
<div key={guard.guard_id} style={{ padding: 10, border: '0.5px solid #e0b4a3', borderRadius: 7, background: '#fff', display: 'flex', flexDirection: 'column', gap: 7, minWidth: 0 }}>
<SmallLabel>{t('resultCaptureReleaseDecisionOwnerResponsePreflight.guardTitle')}</SmallLabel>
<span style={{ fontFamily: 'Syne, sans-serif', fontSize: 12, fontWeight: 700, color: '#141413', overflowWrap: 'anywhere' }}>
{guard.guard_id}
</span>
<span style={{ fontFamily: "'DM Mono', monospace", fontSize: 10, color: '#64727a', lineHeight: 1.45, overflowWrap: 'anywhere' }}>
{guard.reason}
</span>
<Chip value={t('resultCaptureReleaseDecisionOwnerResponsePreflight.labels.runtimeWriteAllowed', { value: String(guard.runtime_write_allowed) })} muted />
</div>
))}
</div>
<SmallLabel>{t('resultCaptureReleaseDecisionOwnerResponsePreflight.actionTitle')}</SmallLabel>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 10 }} className="automation-inventory-live-read-card-grid">
{resultCaptureReleaseDecisionOwnerResponsePreflight.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('resultCaptureReleaseDecisionOwnerResponsePreflight.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 }}>

View File

@@ -619,6 +619,11 @@ export const apiClient = {
return handleResponse<AiAgentResultCaptureReleaseDecisionInputPrepSnapshot>(res)
},
async getAiAgentResultCaptureReleaseDecisionOwnerResponsePreflight() {
const res = await fetch(`${API_BASE_URL}/agents/agent-result-capture-release-decision-owner-response-preflight`)
return handleResponse<AiAgentResultCaptureReleaseDecisionOwnerResponsePreflightSnapshot>(res)
},
async getAiAgentOwnerApprovedFixtureDryRun() {
const res = await fetch(`${API_BASE_URL}/agents/agent-owner-approved-fixture-dry-run`)
return handleResponse<AiAgentOwnerApprovedFixtureDryRunSnapshot>(res)
@@ -1295,8 +1300,8 @@ export interface AiAgent12AgentWarRoomSnapshot {
program_status: {
overall_completion_percent: number
current_priority: 'P0' | 'P1' | 'P2' | 'P3'
current_task_id: 'P2-142'
next_task_id: 'P2-143'
current_task_id: 'P2-143'
next_task_id: 'P2-144'
read_only_mode: true
runtime_authority: '12_agent_war_room_read_only_no_live_write'
status_note: string
@@ -9921,6 +9926,122 @@ export interface AiAgentResultCaptureReleaseDecisionInputPrepSnapshot {
}
}
interface AiAgentReleaseDecisionOwnerResponseIntakeLane {
lane_id: string
display_name: string
source_packet_id: string
owner_agent: string
current_task_id: string
target_next_task_id: string
intake_status: string
required_fields: string[]
preflight_summary: string
accepted: boolean
redacted_payload_ingested: boolean
runtime_write_allowed: boolean
telegram_send_allowed: boolean
evidence_hash?: string
}
export interface AiAgentResultCaptureReleaseDecisionOwnerResponsePreflightSnapshot {
schema_version: 'ai_agent_result_capture_release_decision_owner_response_preflight_v1'
generated_at: string
program_status: {
overall_completion_percent: number
current_priority: 'P0' | 'P1' | 'P2' | 'P3'
current_task_id: 'P2-142'
next_task_id: 'P2-143'
read_only_mode: true
runtime_authority: 'result_capture_release_decision_owner_response_preflight_only_no_live_write'
status_note: string
}
source_refs: string[]
prior_decision_input_prep: AiAgentReleaseDecisionNextHandoffZeroCounts & {
schema_version: string
current_task_id: string
next_task_id: string
decision_input_packet_count: number
missing_input_field_count: number
blocked_input_transition_count: number
operator_action_count: number
approval_required_subtotal: number
blocked_and_critical_subtotal: number
readiness_note: string
}
owner_response_preflight_truth: AiAgentReleaseDecisionNextHandoffZeroCounts & {
p2_141_input_prep_loaded: boolean
p2_142_war_room_baseline_preserved: boolean
required_owner_fields_declared: boolean
required_verifier_fields_declared: boolean
required_rollback_fields_declared: boolean
required_maintenance_window_fields_declared: boolean
required_live_apply_fields_declared: boolean
redaction_contract_loaded: boolean
preflight_only_mode: boolean
no_raw_payload_required: boolean
rejection_policy_active: boolean
truth_note: string
owner_response_received: boolean
owner_response_accepted: boolean
owner_response_rejected: boolean
redacted_payload_ingested: boolean
owner_response_received_count: number
owner_response_accepted_count: number
owner_response_rejected_count: number
redacted_payload_ingested_count: number
release_authorization_granted: boolean
gateway_queue_write_enabled: boolean
telegram_send_enabled: boolean
result_capture_write_enabled: boolean
learning_write_enabled: boolean
playbook_trust_write_enabled: boolean
production_write_enabled: boolean
}
response_intake_lanes: AiAgentReleaseDecisionOwnerResponseIntakeLane[]
intake_validation_checks: {
check_id: string
status: string
requirement: string
runtime_write_allowed: boolean
}[]
rejection_guards: {
guard_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: AiAgentReleaseDecisionNextHandoffZeroCounts & {
response_intake_lane_count: number
required_owner_field_count: number
intake_validation_check_count: number
rejection_guard_count: number
operator_action_count: number
waiting_external_response_count: number
approval_required_subtotal: number
blocked_and_critical_subtotal: number
owner_response_received_count: number
owner_response_accepted_count: number
owner_response_rejected_count: number
redacted_payload_ingested_count: number
}
}
export interface AiAgentOwnerApprovedFixtureDryRunSnapshot {
schema_version: 'ai_agent_owner_approved_fixture_dry_run_v1'
generated_at: string