fix(iwooos): surface security queue verifier gaps
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m9s
CD Pipeline / build-and-deploy (push) Successful in 9m44s
CD Pipeline / post-deploy-checks (push) Successful in 2m43s

This commit is contained in:
ogt
2026-07-10 20:21:48 +08:00
parent 34276c807b
commit 866811bbb3
3 changed files with 99 additions and 25 deletions

View File

@@ -13982,7 +13982,10 @@
"signals": "signals",
"sources": "sources",
"p0": "P0 tracks",
"controlled": "controlled"
"controlled": "controlled",
"missing": "missing",
"action": "next",
"verifier": "verifier"
},
"guards": {
"runtimeActions": "runtime action",

View File

@@ -13982,7 +13982,10 @@
"signals": "signals",
"sources": "sources",
"p0": "P0 軌",
"controlled": "controlled"
"controlled": "controlled",
"missing": "缺口",
"action": "下一步",
"verifier": "驗證器"
},
"guards": {
"runtimeActions": "runtime action",

View File

@@ -773,7 +773,11 @@ const SECURITY_TOOL_CLOSURE_BOOTSTRAP_QUEUE: IwoooSSecurityToolClosureQueueEntry
track_id: 'wazuh_detection_response',
state: 'wazuh_source_verifier_ready_runtime_closure_open',
next_action: 'attach_live_event_case_controlled_response_and_post_verifier',
next_executable_action: 'attach_live_wazuh_event_forensics_incident_case_controlled_response_and_independent_post_verifier_receipts',
ready_signal_count: 6,
required_signal_count: 6,
missing_signal_count: 0,
required_verifier: 'wazuh_registry_fim_vulnerability_alert_receipt_post_verifier',
controlled_apply_policy_allowed: true,
},
{
@@ -781,6 +785,11 @@ const SECURITY_TOOL_CLOSURE_BOOTSTRAP_QUEUE: IwoooSSecurityToolClosureQueueEntry
track_id: 'supply_chain_sbom_scan',
state: 'sbom_and_scan_artifacts_missing',
next_action: 'stage_trivy_syft_grype_check_mode_reports',
next_executable_action: 'stage_trivy_syft_grype_check_mode_reports',
ready_signal_count: 0,
required_signal_count: 5,
missing_signal_count: 5,
required_verifier: 'sbom_vulnerability_artifact_post_verifier',
controlled_apply_policy_allowed: true,
},
{
@@ -788,7 +797,11 @@ const SECURITY_TOOL_CLOSURE_BOOTSTRAP_QUEUE: IwoooSSecurityToolClosureQueueEntry
track_id: 'ai_agent_controlled_apply',
state: 'preflight_ready_for_controlled_policy_check',
next_action: 'connect_target_selector_diff_check_mode_rollback_post_verifier_km',
next_executable_action: 'connect_target_selector_diff_check_mode_rollback_post_verifier_km',
ready_signal_count: 2,
required_signal_count: 9,
missing_signal_count: 7,
required_verifier: 'ai_controlled_apply_same_run_post_verifier_km_writeback',
controlled_apply_policy_allowed: true,
},
]
@@ -16550,6 +16563,40 @@ function publicSecurityToolClosureMarker(marker: string) {
.replace(/token/g, 'approval_id')
}
const SECURITY_TOOL_CLOSURE_ACTION_LABELS: Record<string, string> = {
attach_live_event_case_controlled_response_and_post_verifier: 'Wazuh live event -> case -> response verifier',
attach_live_wazuh_event_forensics_incident_case_controlled_response_and_independent_post_verifier_receipts:
'Wazuh live event -> case -> response verifier',
stage_trivy_syft_grype_check_mode_reports: 'Trivy/Syft/Grype check-mode evidence',
connect_target_selector_diff_check_mode_rollback_post_verifier_km:
'Target selector -> check-mode -> rollback verifier -> KM',
run_allowlisted_check_mode_with_rollback_post_verifier_and_km_writeback:
'Check-mode -> rollback verifier -> KM writeback',
wazuh_registry_fim_vulnerability_alert_receipt_post_verifier:
'Wazuh/FIM alert receipt verifier',
sbom_vulnerability_artifact_post_verifier: 'SBOM vulnerability verifier',
ai_controlled_apply_same_run_post_verifier_km_writeback:
'Same-run AI controlled apply verifier',
ai_controlled_apply_post_verifier_and_learning_writeback:
'AI apply post-verifier + learning writeback',
}
function publicSecurityToolClosureAction(action: string | undefined) {
if (!action) return '--'
return (
SECURITY_TOOL_CLOSURE_ACTION_LABELS[action] ??
action
.replace(/_/g, ' ')
.replace(/\bkm\b/gi, 'KM')
.replace(/\bsbom\b/gi, 'SBOM')
.replace(/\bwazuh\b/gi, 'Wazuh')
.replace(/\bfim\b/gi, 'FIM')
.replace(/\bai\b/gi, 'AI')
.replace(/\bmcp\b/gi, 'MCP')
.replace(/\brag\b/gi, 'RAG')
)
}
function IwoooSSecurityToolClosureBoard() {
const t = useTranslations('iwooos.securityToolClosure')
const textWrap = { overflowWrap: 'anywhere' as const, wordBreak: 'break-word' as const }
@@ -16762,7 +16809,7 @@ function IwoooSSecurityToolClosureBoard() {
</div>
<div style={{ marginTop: 8, display: 'flex', flexWrap: 'wrap', gap: 6 }}>
<span style={{ border: '0.5px solid #e2cbb4', borderRadius: 999, background: '#fff', color: '#9a5d1d', padding: '4px 7px', fontSize: 10, fontWeight: 900 }}>
{primaryQueue.ready_signal_count ?? 0}/6
{primaryQueue.ready_signal_count ?? 0}/{primaryQueue.required_signal_count ?? 0}
</span>
<span style={{ border: '0.5px solid #d6e1d9', borderRadius: 999, background: '#fff', color: '#315f43', padding: '4px 7px', fontSize: 10, fontWeight: 900 }}>
{t('compact.controlled')}
@@ -16892,29 +16939,50 @@ function IwoooSSecurityToolClosureBoard() {
<span style={{ marginLeft: 6 }}>{t('detailsTitle')}</span>
</summary>
<div style={{ marginTop: 9, display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 190px), 1fr))', gap: 8 }}>
{queue.map(item => (
<div
key={`${item.queue_id}-${item.track_id}`}
style={{
border: '0.5px solid #e2dccb',
borderRadius: 8,
background: '#fffaf1',
padding: 9,
minWidth: 0,
}}
>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 7 }}>
<span style={{ color: '#9a5d1d', fontSize: 11, fontWeight: 900 }}>{item.queue_id}</span>
<Activity size={13} color={toneColors.warn} />
{queue.map(item => {
const ready = item.ready_signal_count ?? 0
const required = item.required_signal_count ?? 0
const missing = item.missing_signal_count ?? Math.max(required - ready, 0)
const nextAction = publicSecurityToolClosureAction(item.next_executable_action ?? item.next_action)
const verifier = publicSecurityToolClosureAction(item.required_verifier)
return (
<div
key={`${item.queue_id}-${item.track_id}`}
style={{
border: '0.5px solid #e2dccb',
borderRadius: 8,
background: '#fffaf1',
padding: 9,
minWidth: 0,
display: 'grid',
gap: 7,
}}
>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 7 }}>
<span style={{ color: '#9a5d1d', fontSize: 11, fontWeight: 900 }}>{item.queue_id}</span>
<Activity size={13} color={toneColors.warn} />
</div>
<div style={{ color: '#141413', fontSize: 12, fontWeight: 900, lineHeight: 1.2, ...textWrap }}>
{t(`queue.${item.queue_id}.title` as never)}
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: 6 }}>
<span style={{ border: '0.5px solid #e2cbb4', borderRadius: 8, background: '#fff', color: '#9a5d1d', padding: '5px 7px', fontSize: 10, fontWeight: 900, ...textWrap }}>
{t('compact.signals')}: {ready}/{required}
</span>
<span style={{ border: '0.5px solid #e2cbb4', borderRadius: 8, background: '#fff', color: missing > 0 ? '#9a5d1d' : '#315f43', padding: '5px 7px', fontSize: 10, fontWeight: 900, ...textWrap }}>
{t('compact.missing')}: {missing}
</span>
</div>
<div style={{ color: '#5f5b52', fontSize: 10.5, lineHeight: 1.35, fontWeight: 800, ...textWrap }}>
{t('compact.action')}: {nextAction}
</div>
<div style={{ color: '#315f43', fontSize: 10, lineHeight: 1.3, fontWeight: 800, ...textWrap }}>
{t('compact.verifier')}: {verifier}
</div>
</div>
<div style={{ marginTop: 6, color: '#141413', fontSize: 12, fontWeight: 900, lineHeight: 1.2, ...textWrap }}>
{t(`queue.${item.queue_id}.title` as never)}
</div>
<div style={{ marginTop: 5, color: '#5f5b52', fontSize: 10.5, lineHeight: 1.35, ...textWrap }}>
{t(`queue.${item.queue_id}.next` as never)}
</div>
</div>
))}
)
})}
</div>
<div style={{ marginTop: 8, display: 'flex', flexWrap: 'wrap', gap: 6 }}>
{boundaryMarkers.slice(0, 10).map(marker => (