fix(api): distinguish ansible dry run from repair
Some checks failed
Code Review / ai-code-review (push) Successful in 14s
CD Pipeline / tests (push) Successful in 1m35s
CD Pipeline / build-and-deploy (push) Successful in 5m0s
CD Pipeline / post-deploy-checks (push) Successful in 1m33s
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
Some checks failed
Code Review / ai-code-review (push) Successful in 14s
CD Pipeline / tests (push) Successful in 1m35s
CD Pipeline / build-and-deploy (push) Successful in 5m0s
CD Pipeline / post-deploy-checks (push) Successful in 1m33s
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
This commit is contained in:
@@ -3963,6 +3963,22 @@ def _has_nonrepair_operation_evidence(facts: dict[str, Any]) -> bool:
|
||||
)
|
||||
|
||||
|
||||
def _status_chain_ansible_dry_run_only(
|
||||
execution_section: dict[str, Any],
|
||||
facts: dict[str, Any],
|
||||
) -> bool:
|
||||
ansible = execution_section.get("ansible")
|
||||
if not isinstance(ansible, dict):
|
||||
return False
|
||||
return (
|
||||
_safe_int(ansible.get("check_mode_total")) > 0
|
||||
and _safe_int(ansible.get("apply_total")) == 0
|
||||
and not bool(ansible.get("applied"))
|
||||
and not bool(ansible.get("controlled_apply"))
|
||||
and _safe_int(facts.get("auto_repair_execution_records")) == 0
|
||||
)
|
||||
|
||||
|
||||
def _latest_remediation_history_item(
|
||||
history: dict[str, Any] | None,
|
||||
) -> dict[str, Any]:
|
||||
@@ -4795,6 +4811,12 @@ def _build_awooop_status_chain(
|
||||
|
||||
mcp_section = _status_chain_mcp_section(truth_chain)
|
||||
execution_section = _status_chain_execution_section(truth_chain)
|
||||
ansible_dry_run_only = _status_chain_ansible_dry_run_only(execution_section, facts)
|
||||
if ansible_dry_run_only:
|
||||
verdict = "ansible_check_mode_only"
|
||||
repair_state = "ansible_check_mode_only"
|
||||
next_step = "owner_review_apply_gate_or_create_verifier_plan"
|
||||
needs_human = True
|
||||
source_section = _status_chain_source_section(truth_chain)
|
||||
if source_correlation is not None:
|
||||
source_section["correlation"] = source_correlation
|
||||
@@ -4809,7 +4831,23 @@ def _build_awooop_status_chain(
|
||||
if fetch_error:
|
||||
blockers.append("truth_chain_fetch_failed")
|
||||
outcome = {}
|
||||
if isinstance(quality.get("operator_outcome"), dict):
|
||||
if ansible_dry_run_only:
|
||||
outcome_quality = dict(quality)
|
||||
outcome_facts = dict(facts)
|
||||
ansible = execution_section.get("ansible") if isinstance(execution_section.get("ansible"), dict) else {}
|
||||
outcome_facts["ansible_check_mode_total"] = _safe_int(ansible.get("check_mode_total"))
|
||||
outcome_facts["ansible_apply_total"] = _safe_int(ansible.get("apply_total"))
|
||||
outcome_quality["facts"] = outcome_facts
|
||||
outcome_quality["verdict"] = "ansible_check_mode_only"
|
||||
outcome_quality.pop("operator_outcome", None)
|
||||
outcome = build_operator_outcome(
|
||||
truth_status=truth_status,
|
||||
automation_quality=outcome_quality,
|
||||
remediation_state=remediation_state,
|
||||
fetch_error=fetch_error,
|
||||
source_id=source_id,
|
||||
)
|
||||
elif isinstance(quality.get("operator_outcome"), dict):
|
||||
outcome = dict(quality["operator_outcome"])
|
||||
else:
|
||||
outcome = build_operator_outcome(
|
||||
@@ -4849,6 +4887,7 @@ def _build_awooop_status_chain(
|
||||
"latest_mode": latest.get("mode"),
|
||||
"latest_at": latest.get("created_at"),
|
||||
"latest_preview": latest.get("verification_result_preview"),
|
||||
"ansible_dry_run_only": ansible_dry_run_only,
|
||||
},
|
||||
"writes": {
|
||||
"incident": latest.get("writes_incident_state"),
|
||||
|
||||
Reference in New Issue
Block a user