fix(agent99): persist canonical verifier run identity
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 2m25s
CD Pipeline / build-and-deploy (push) Successful in 15m19s
CD Pipeline / post-deploy-checks (push) Successful in 2m12s

This commit is contained in:
ogt
2026-07-15 18:27:03 +08:00
parent 057001d866
commit 77d55ddedc
2 changed files with 67 additions and 0 deletions

View File

@@ -5760,6 +5760,7 @@ async def _record_post_apply_verifier_and_learning(
result,
verifier_receipt,
)
automation_run_id = _automation_run_id_for_claim(claim)
post_state = {
**verifier_receipt,
"automation_run_id": automation_run_id,

View File

@@ -41,6 +41,14 @@ class _RowsResult:
return self._rows
class _ScalarResult:
def __init__(self, value) -> None:
self._value = value
def scalar(self):
return self._value
class _SequenceDB:
def __init__(self, *results) -> None:
self._results = list(results)
@@ -208,6 +216,64 @@ def test_backfill_accepts_only_same_run_successful_durable_verifier() -> None:
)
@pytest.mark.asyncio
async def test_post_apply_verifier_persists_canonical_same_run_identity(
monkeypatch: pytest.MonkeyPatch,
) -> None:
claim = _wazuh_claim()
apply_op_id = "00000000-0000-0000-0000-000000000203"
receipt = _durable_verifier_receipt(claim, apply_op_id=apply_op_id)
verifier_db = _SequenceDB(_ScalarResult("evidence-id"))
context_calls = 0
@asynccontextmanager
async def fake_db_context(_project_id: str):
nonlocal context_calls
context_calls += 1
if context_calls == 1:
yield verifier_db
return
raise RuntimeError("KM persistence is outside this focused receipt test")
monkeypatch.setattr(service, "get_db_context", fake_db_context)
monkeypatch.setattr(
service,
"_resolve_ansible_post_verifier_receipt",
AsyncMock(return_value=(receipt, True)),
)
monkeypatch.setattr(
service,
"_record_apply_post_verifier_terminal",
AsyncMock(return_value=True),
)
monkeypatch.setattr(
service,
"_record_learning_writeback_receipt",
AsyncMock(return_value=None),
)
result = await service._record_post_apply_verifier_and_learning(
claim,
service.AnsibleRunResult(
returncode=0,
stdout="",
stderr="",
duration_ms=5,
),
apply_op_id=apply_op_id,
project_id="default",
durable_verifier_receipt=receipt,
)
post_state = json.loads(verifier_db.parameters[0]["post_execution_state"])
assert post_state["automation_run_id"] == claim.input_payload["automation_run_id"]
assert post_state["trace_id"] == claim.input_payload["trace_id"]
assert post_state["run_id"] == claim.input_payload["run_id"]
assert result["verification"] is True
assert result["verification_passed"] is True
assert result["durable_verifier_receipt_reused"] is True
@pytest.mark.asyncio
async def test_backfill_repairs_orphan_incident_and_reuses_verifier(
monkeypatch: pytest.MonkeyPatch,