From c910ee7ebeda3ef1ca64613bfabebd75975c40d9 Mon Sep 17 00:00:00 2001 From: ogt Date: Sat, 11 Jul 2026 14:49:47 +0800 Subject: [PATCH] fix(agent): replace terminally skipped candidates --- .../services/awooop_ansible_audit_service.py | 23 ++++++++++++++----- .../tests/test_awooop_truth_chain_service.py | 5 +++- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/apps/api/src/services/awooop_ansible_audit_service.py b/apps/api/src/services/awooop_ansible_audit_service.py index 1e4d8f0b5..f842b2812 100644 --- a/apps/api/src/services/awooop_ansible_audit_service.py +++ b/apps/api/src/services/awooop_ansible_audit_service.py @@ -742,12 +742,23 @@ async def record_ansible_decision_audit( ) existing = await db.execute( text(""" - SELECT op_id - FROM automation_operation_log - WHERE operation_type = 'ansible_candidate_matched' - AND coalesce(incident_id::text, input ->> 'incident_id') = :incident_id - AND input ->> 'executor' = 'ansible' - AND input ->> 'decision_path' = 'repair_candidate_controlled_queue' + SELECT candidate.op_id + FROM automation_operation_log candidate + WHERE candidate.operation_type = 'ansible_candidate_matched' + AND coalesce( + candidate.incident_id::text, + candidate.input ->> 'incident_id' + ) = :incident_id + AND candidate.input ->> 'executor' = 'ansible' + AND candidate.input ->> 'decision_path' + = 'repair_candidate_controlled_queue' + AND NOT EXISTS ( + SELECT 1 + FROM automation_operation_log terminal + WHERE terminal.parent_op_id = candidate.op_id + AND terminal.operation_type + = 'ansible_execution_skipped' + ) LIMIT 1 """), {"incident_id": incident_id}, diff --git a/apps/api/tests/test_awooop_truth_chain_service.py b/apps/api/tests/test_awooop_truth_chain_service.py index 577fbc60b..45da1ccdf 100644 --- a/apps/api/tests/test_awooop_truth_chain_service.py +++ b/apps/api/tests/test_awooop_truth_chain_service.py @@ -150,7 +150,10 @@ def test_ansible_audit_keeps_external_incident_id_in_json_not_bigint_column() -> claim_source = inspect.getsource(claim_pending_check_modes) assert "operation_type, actor, status, incident_id" in decision_source - assert "coalesce(incident_id::text, input ->> 'incident_id')" in decision_source + assert "candidate.incident_id::text" in decision_source + assert "candidate.input ->> 'incident_id'" in decision_source + assert "terminal.parent_op_id = candidate.op_id" in decision_source + assert "ansible_execution_skipped" in decision_source assert "operation_type, actor, status, incident_id" in claim_source assert "incident_db_id" in decision_source assert "incident_db_id" in claim_source