fix(agent): fail closed on incomplete Wazuh context

This commit is contained in:
ogt
2026-07-11 11:57:38 +08:00
parent f4e85fac38
commit 0fe6bd3ba0
2 changed files with 270 additions and 29 deletions

View File

@@ -359,8 +359,17 @@ def _wazuh_posture_incident(
receipt_ref = (
f"{bucket_ref}-{attempt_ref.upper()}" if attempt_ref else bucket_ref
)
incident_id = f"IWZ-POSTURE-{bucket_ref}"
if attempt_ref:
attempt_token = uuid5(
NAMESPACE_URL,
f"awoooi:iwooos:wazuh-manager-posture-attempt:{attempt_ref}",
).hex[:12].upper()
incident_id = f"IWZ-P-{bucket_ref}-{attempt_token}"
return {
"incident_id": f"IWZ-POSTURE-{receipt_ref}",
# IncidentEvidence.incident_id is VARCHAR(30). Keep retry identities
# deterministic and bounded while preserving the full ref separately.
"incident_id": incident_id,
"project_id": "awoooi",
"status": "INVESTIGATING",
"severity": "low",
@@ -422,7 +431,29 @@ async def enqueue_iwooos_wazuh_manager_posture_candidate_once(
candidate.status AS candidate_status,
candidate.input ->> 'automation_run_id' AS automation_run_id,
candidate.input ->> 'source_receipt_ref' AS source_receipt_ref,
check_mode.status AS latest_check_status
check_mode.status AS latest_check_status,
EXISTS (
SELECT 1
FROM incident_evidence evidence
WHERE evidence.incident_id = candidate.input ->> 'incident_id'
AND evidence.collected_at <= candidate.created_at
AND (
evidence.post_execution_state IS NULL
OR CAST(evidence.post_execution_state AS jsonb) = 'null'::jsonb
)
AND evidence.sensors_succeeded > 0
AND NULLIF(btrim(evidence.recent_logs), '') IS NOT NULL
AND EXISTS (
SELECT 1
FROM jsonb_each(
coalesce(
CAST(evidence.mcp_health AS jsonb),
'{}'::jsonb
)
) health
WHERE health.value = 'true'::jsonb
)
) AS predecision_evidence_ready
FROM automation_operation_log candidate
LEFT JOIN LATERAL (
SELECT check_receipt.status
@@ -446,8 +477,20 @@ async def enqueue_iwooos_wazuh_manager_posture_candidate_once(
},
)
existing_row = existing.mappings().first()
existing_evidence_ready = bool(
existing_row
and existing_row.get("predecision_evidence_ready") is True
)
latest_check_status = str(
existing_row.get("latest_check_status") or ""
) if existing_row else ""
retry_attempt_ref: str | None = None
if existing_row and existing_row.get("latest_check_status") != "failed":
retry_reason: str | None = None
if (
existing_row
and latest_check_status != "failed"
and existing_evidence_ready
):
return {
"status": "fresh_candidate_already_present",
"queued": 0,
@@ -463,30 +506,63 @@ async def enqueue_iwooos_wazuh_manager_posture_candidate_once(
}
if existing_row:
source_sha = os.getenv("AWOOOI_BUILD_COMMIT_SHA", "").strip().lower()
retry_attempt_ref = (
deploy_ref = (
source_sha[:12]
if len(source_sha) >= 12
and all(character in "0123456789abcdef" for character in source_sha)
else "runtime-retry"
)
existing_source_ref = str(
existing_row.get("source_receipt_ref") or ""
).lower()
if existing_source_ref.endswith(f"-{retry_attempt_ref.lower()}"):
if latest_check_status == "failed":
retry_attempt_ref = deploy_ref
retry_reason = "failed_check_mode"
elif latest_check_status == "success":
retry_attempt_ref = f"{deploy_ref}-context"
retry_reason = "predecision_context"
else:
return {
"status": "failed_check_retry_already_attempted_for_deploy",
"status": "fresh_candidate_predecision_evidence_not_verified",
"queued": 0,
"existing": 1,
"evidence_ready": 1,
"evidence_ready": 0,
"automation_run_id": str(
existing_row.get("automation_run_id")
or existing_row.get("op_id")
or ""
),
"work_item_id": _WAZUH_POSTURE_WORK_ITEM_ID,
"retry_of_failed_check_mode": True,
"active_blockers": [
"predecision_mcp_or_log_evidence_missing"
],
}
existing_source_ref = str(
existing_row.get("source_receipt_ref") or ""
).lower()
if existing_source_ref.endswith(f"-{retry_attempt_ref.lower()}"):
return {
"status": (
"failed_check_retry_already_attempted_for_deploy"
if retry_reason == "failed_check_mode"
else "context_retry_already_attempted_for_deploy"
),
"queued": 0,
"existing": 1,
"evidence_ready": 1 if existing_evidence_ready else 0,
"automation_run_id": str(
existing_row.get("automation_run_id")
or existing_row.get("op_id")
or ""
),
"work_item_id": _WAZUH_POSTURE_WORK_ITEM_ID,
"retry_of_failed_check_mode": (
retry_reason == "failed_check_mode"
),
"retry_of_incomplete_predecision_context": (
retry_reason == "predecision_context"
),
"active_blockers": [
"bounded_retry_already_attempted_for_deploy"
if retry_reason == "failed_check_mode"
else "bounded_context_retry_already_attempted_for_deploy"
],
}
@@ -522,6 +598,23 @@ async def enqueue_iwooos_wazuh_manager_posture_candidate_once(
error_type=type(exc).__name__,
)
if not evidence_ready:
return {
"status": "blocked_predecision_evidence_not_verified",
"queued": 0,
"existing": 1 if existing_row else 0,
"evidence_ready": 0,
"automation_run_id": automation_run_id,
"work_item_id": _WAZUH_POSTURE_WORK_ITEM_ID,
"retry_of_failed_check_mode": retry_reason == "failed_check_mode",
"retry_of_incomplete_predecision_context": (
retry_reason == "predecision_context"
),
"active_blockers": [
"predecision_mcp_or_log_evidence_missing"
],
}
queued = await recorder(
incident=incident,
proposal_data={
@@ -540,26 +633,23 @@ async def enqueue_iwooos_wazuh_manager_posture_candidate_once(
return {
"status": (
"queued_for_controlled_executor_retry"
if queued and evidence_ready and retry_attempt_ref
if queued and retry_reason == "failed_check_mode"
else "queued_for_controlled_executor_context_retry"
if queued and retry_reason == "predecision_context"
else "queued_for_controlled_executor"
if queued and evidence_ready
else (
"queued_for_controlled_executor_retry_with_degraded_context"
if queued and retry_attempt_ref
else "queued_for_controlled_executor_with_degraded_context"
if queued
else "candidate_race_deduplicated"
)
if queued
else "candidate_race_deduplicated"
),
"queued": 1 if queued else 0,
"existing": 0 if queued else 1,
"evidence_ready": 1 if evidence_ready else 0,
"automation_run_id": automation_run_id,
"work_item_id": _WAZUH_POSTURE_WORK_ITEM_ID,
"retry_of_failed_check_mode": bool(retry_attempt_ref),
"active_blockers": (
[] if evidence_ready else ["predecision_mcp_or_log_evidence_missing"]
"retry_of_failed_check_mode": retry_reason == "failed_check_mode",
"retry_of_incomplete_predecision_context": (
retry_reason == "predecision_context"
),
"active_blockers": [] if queued else ["candidate_write_not_acknowledged"],
}
except Exception as exc:
logger.warning(