feat(awooop): expose execution evidence on incidents
All checks were successful
Code Review / ai-code-review (push) Successful in 17s
CD Pipeline / tests (push) Successful in 3m27s
CD Pipeline / build-and-deploy (push) Successful in 4m6s
CD Pipeline / post-deploy-checks (push) Successful in 1m33s

This commit is contained in:
Your Name
2026-05-20 15:19:48 +08:00
parent 312042ae6d
commit d4573cd00a
6 changed files with 197 additions and 0 deletions

View File

@@ -1212,6 +1212,94 @@ def _status_chain_mcp_section(truth_chain: dict[str, Any] | None) -> dict[str, A
}
def _first_non_empty(row: Mapping[str, Any], keys: tuple[str, ...]) -> Any:
for key in keys:
value = row.get(key)
if value not in (None, ""):
return value
return None
def _status_chain_execution_section(truth_chain: dict[str, Any] | None) -> dict[str, Any]:
execution = truth_chain.get("execution") if isinstance(truth_chain, dict) else {}
if not isinstance(execution, dict):
execution = {}
ops = execution.get("automation_operation_log")
if not isinstance(ops, list):
ops = []
latest_op = ops[0] if ops and isinstance(ops[0], dict) else {}
playbook_ids: list[str] = []
playbook_paths: list[str] = []
for row in ops:
if not isinstance(row, dict):
continue
_append_unique(playbook_ids, row.get("matched_playbook_id"))
_append_unique(playbook_ids, row.get("input_playbook_id"))
_append_unique(playbook_ids, row.get("output_playbook_id"))
_append_unique(playbook_paths, row.get("input_playbook_path"))
_append_unique(playbook_paths, row.get("output_playbook_path"))
_append_unique(playbook_paths, row.get("input_ansible_playbook_path"))
_append_unique(playbook_paths, row.get("output_ansible_playbook_path"))
ansible = execution.get("ansible") if isinstance(execution.get("ansible"), dict) else {}
ansible_records = ansible.get("records") if isinstance(ansible.get("records"), list) else []
latest_ansible = (
ansible_records[0]
if ansible_records and isinstance(ansible_records[0], dict)
else {}
)
candidate_catalog = (
ansible.get("candidate_catalog")
if isinstance(ansible.get("candidate_catalog"), dict)
else {}
)
candidates = (
candidate_catalog.get("candidates")
if isinstance(candidate_catalog.get("candidates"), list)
else []
)
return {
"operation_total": len(ops),
"latest_operation_type": latest_op.get("operation_type"),
"latest_status": latest_op.get("status"),
"latest_actor": latest_op.get("actor"),
"latest_action": _first_non_empty(latest_op, ("input_action", "output_action")),
"latest_executor": _first_non_empty(
latest_op,
(
"input_executor",
"output_executor",
"input_execution_backend",
"output_execution_backend",
),
),
"playbook_ids": playbook_ids[:5],
"playbook_paths": playbook_paths[:5],
"ansible": {
"considered": bool(ansible.get("considered")),
"record_total": len(ansible_records),
"candidate_count": len(candidates),
"not_used_reason": ansible.get("not_used_reason"),
"latest_operation_type": latest_ansible.get("operation_type"),
"latest_status": latest_ansible.get("status"),
"latest_playbook_path": latest_ansible.get("playbook_path"),
"latest_check_mode": latest_ansible.get("check_mode"),
"candidate_playbooks": [
{
"catalog_id": item.get("catalog_id"),
"playbook_path": item.get("playbook_path"),
"risk_level": item.get("risk_level"),
"match_score": item.get("match_score"),
}
for item in candidates[:3]
if isinstance(item, dict)
],
},
}
def _build_awooop_status_chain(
*,
incident_ids: list[str],
@@ -1290,6 +1378,7 @@ def _build_awooop_status_chain(
needs_human = True
mcp_section = _status_chain_mcp_section(truth_chain)
execution_section = _status_chain_execution_section(truth_chain)
blockers = [
str(item)
for item in [
@@ -1332,6 +1421,7 @@ def _build_awooop_status_chain(
"auto_repair": latest.get("writes_auto_repair_result"),
},
"mcp": mcp_section,
"execution": execution_section,
}