fix(agent): anchor closure on terminal runs
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 1m16s
CD Pipeline / build-and-deploy (push) Successful in 4m48s
CD Pipeline / post-deploy-checks (push) Successful in 4m48s
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 1m16s
CD Pipeline / build-and-deploy (push) Successful in 4m48s
CD Pipeline / post-deploy-checks (push) Successful in 4m48s
This commit is contained in:
@@ -3277,9 +3277,17 @@ def _build_work_item_progress(
|
||||
def _first_operation(
|
||||
rows: Iterable[Mapping[str, Any]],
|
||||
operation_type: str,
|
||||
*,
|
||||
statuses: set[str] | None = None,
|
||||
) -> dict[str, Any] | None:
|
||||
for row in rows:
|
||||
if str(row.get("operation_type") or "") == operation_type:
|
||||
if (
|
||||
str(row.get("operation_type") or "") == operation_type
|
||||
and (
|
||||
statuses is None
|
||||
or str(row.get("status") or "") in statuses
|
||||
)
|
||||
):
|
||||
return dict(row)
|
||||
return None
|
||||
|
||||
@@ -3303,7 +3311,15 @@ def _missing_runtime_operation_chain_ref_ids(
|
||||
"""Return exact apply/check/candidate receipt ids missing from a bounded read."""
|
||||
|
||||
operation_rows = [_row_mapping(row) for row in rows]
|
||||
latest_apply = _first_operation(operation_rows, "ansible_apply_executed")
|
||||
latest_observed_apply = _first_operation(
|
||||
operation_rows,
|
||||
"ansible_apply_executed",
|
||||
)
|
||||
latest_apply = _first_operation(
|
||||
operation_rows,
|
||||
"ansible_apply_executed",
|
||||
statuses={"success", "failed"},
|
||||
) or latest_observed_apply
|
||||
if latest_apply is None:
|
||||
return []
|
||||
|
||||
@@ -3481,7 +3497,21 @@ def _autonomous_execution_loop_ledger(
|
||||
telegram_rows = [_row_mapping(row) for row in telegram_latest_rows]
|
||||
auto_repair_rows = [_row_mapping(row) for row in auto_repair_latest_rows]
|
||||
|
||||
latest_apply = _first_operation(operation_rows, "ansible_apply_executed")
|
||||
latest_observed_apply = _first_operation(
|
||||
operation_rows,
|
||||
"ansible_apply_executed",
|
||||
)
|
||||
latest_apply = _first_operation(
|
||||
operation_rows,
|
||||
"ansible_apply_executed",
|
||||
statuses={"success", "failed"},
|
||||
) or latest_observed_apply
|
||||
latest_inflight_apply = (
|
||||
latest_observed_apply
|
||||
if latest_observed_apply is not None
|
||||
and latest_observed_apply.get("op_id") != (latest_apply or {}).get("op_id")
|
||||
else None
|
||||
)
|
||||
latest_check = None
|
||||
latest_candidate = None
|
||||
if latest_apply is not None:
|
||||
@@ -3717,6 +3747,23 @@ def _autonomous_execution_loop_ledger(
|
||||
"schema_version": "ai_agent_autonomous_execution_loop_ledger_v1",
|
||||
"project_id": project_id,
|
||||
"operation_id": apply_op_id or check_mode_op_id or candidate_op_id or None,
|
||||
"completion_anchor": (
|
||||
"latest_terminal_apply"
|
||||
if latest_apply is not None
|
||||
and str(latest_apply.get("status") or "") in {"success", "failed"}
|
||||
else "latest_observed_operation"
|
||||
),
|
||||
"latest_inflight_apply": (
|
||||
{
|
||||
"op_id": latest_inflight_apply.get("op_id"),
|
||||
"status": latest_inflight_apply.get("status"),
|
||||
"automation_run_id": latest_inflight_apply.get("automation_run_id"),
|
||||
"incident_id": latest_inflight_apply.get("incident_id"),
|
||||
"created_at": latest_inflight_apply.get("created_at"),
|
||||
}
|
||||
if latest_inflight_apply is not None
|
||||
else None
|
||||
),
|
||||
"automation_run_id": automation_run_id or None,
|
||||
"root_candidate_op_id": candidate_op_id or None,
|
||||
"check_mode_op_id": check_mode_op_id or None,
|
||||
@@ -6028,6 +6075,7 @@ _RUNTIME_OPERATION_LATEST_SQL = """
|
||||
input ->> 'source_candidate_op_id' AS candidate_op_id
|
||||
FROM automation_operation_log
|
||||
WHERE operation_type = 'ansible_apply_executed'
|
||||
AND status IN ('success', 'failed')
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 1
|
||||
)
|
||||
@@ -6104,6 +6152,7 @@ _RUNTIME_OPERATION_LATEST_DIRECT_SQL = """
|
||||
input ->> 'source_candidate_op_id' AS candidate_op_id
|
||||
FROM automation_operation_log
|
||||
WHERE operation_type = 'ansible_apply_executed'
|
||||
AND status IN ('success', 'failed')
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 1
|
||||
)
|
||||
|
||||
@@ -2448,11 +2448,53 @@ def test_runtime_telegram_receipt_queries_include_alert_notifications() -> None:
|
||||
def test_runtime_operation_latest_queries_prioritize_latest_apply_chain() -> None:
|
||||
for sql in (_RUNTIME_OPERATION_LATEST_SQL, _RUNTIME_OPERATION_LATEST_DIRECT_SQL):
|
||||
assert "WITH latest_apply_chain AS" in sql
|
||||
assert "AND status IN ('success', 'failed')" in sql
|
||||
assert "operation_row.op_id::text = latest_apply_chain.apply_op_id" in sql
|
||||
assert "operation_row.op_id::text = latest_apply_chain.check_mode_op_id" in sql
|
||||
assert "operation_row.op_id::text = latest_apply_chain.candidate_op_id" in sql
|
||||
|
||||
|
||||
def test_runtime_execution_loop_uses_terminal_apply_without_hiding_inflight_apply():
|
||||
ledger = runtime_control_module._autonomous_execution_loop_ledger(
|
||||
project_id="awoooi",
|
||||
operation_latest_rows=[
|
||||
{
|
||||
"op_id": "pending-apply",
|
||||
"operation_type": "ansible_apply_executed",
|
||||
"status": "pending",
|
||||
"automation_run_id": "pending-run",
|
||||
"incident_id": "INC-PENDING",
|
||||
"created_at": "2026-07-10T15:00:00Z",
|
||||
},
|
||||
{
|
||||
"op_id": "terminal-apply",
|
||||
"operation_type": "ansible_apply_executed",
|
||||
"status": "failed",
|
||||
"automation_run_id": "terminal-run",
|
||||
"incident_id": "INC-TERMINAL",
|
||||
"created_at": "2026-07-10T14:59:00Z",
|
||||
},
|
||||
],
|
||||
verifier_latest_rows=[],
|
||||
km_latest_rows=[],
|
||||
telegram_latest_rows=[],
|
||||
auto_repair_latest_rows=[],
|
||||
latest_flow_closure={},
|
||||
latest_failure_classification={},
|
||||
controlled_retry_package={},
|
||||
)
|
||||
|
||||
assert ledger["operation_id"] == "terminal-apply"
|
||||
assert ledger["completion_anchor"] == "latest_terminal_apply"
|
||||
assert ledger["latest_inflight_apply"] == {
|
||||
"op_id": "pending-apply",
|
||||
"status": "pending",
|
||||
"automation_run_id": "pending-run",
|
||||
"incident_id": "INC-PENDING",
|
||||
"created_at": "2026-07-10T15:00:00Z",
|
||||
}
|
||||
|
||||
|
||||
def test_runtime_execution_loop_ledger_does_not_mix_unrelated_check_mode_rows():
|
||||
apply_op_id = "db3f12ce-08fc-4289-8c93-338305d5850c"
|
||||
readback = build_runtime_receipt_readback_from_rows(
|
||||
|
||||
Reference in New Issue
Block a user