fix(agent): keep verified closures moving
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 2m33s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 0s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 15s
CD Pipeline / build-and-deploy (push) Successful in 5m49s
CD Pipeline / post-deploy-checks (push) Successful in 1m54s
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 2m33s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 0s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 15s
CD Pipeline / build-and-deploy (push) Successful in 5m49s
CD Pipeline / post-deploy-checks (push) Successful in 1m54s
This commit is contained in:
@@ -3805,13 +3805,11 @@ async def backfill_missing_auto_repair_execution_receipts_once(
|
||||
projection.get("verified") or 0
|
||||
)
|
||||
projection_error = str(projection.get("error") or "")[:500]
|
||||
if stats["retry_terminal_projection_scanned"] or projection_error:
|
||||
stats["scanned"] = stats["retry_terminal_projection_scanned"]
|
||||
stats["incident_closure_written"] = stats[
|
||||
"retry_terminal_projection_written"
|
||||
]
|
||||
stats["error"] = projection_error or None
|
||||
return stats
|
||||
stats["scanned"] = stats["retry_terminal_projection_scanned"]
|
||||
stats["incident_closure_written"] = stats[
|
||||
"retry_terminal_projection_written"
|
||||
]
|
||||
stats["error"] = projection_error or None
|
||||
async with get_db_context(project_id) as db:
|
||||
await db.execute(text("SET LOCAL statement_timeout = '5000ms'"))
|
||||
result = await db.execute(
|
||||
@@ -3965,7 +3963,7 @@ async def backfill_missing_auto_repair_execution_receipts_once(
|
||||
},
|
||||
)
|
||||
rows = [dict(row) for row in result.mappings().all()]
|
||||
stats["scanned"] = len(rows)
|
||||
stats["scanned"] += len(rows)
|
||||
for row in rows:
|
||||
reconstructed = _claim_from_apply_operation_row(row)
|
||||
if reconstructed is None:
|
||||
|
||||
@@ -880,6 +880,107 @@ async def test_retry_terminal_projection_backfill_writes_and_verifies_no_apply(
|
||||
telegram_readback.assert_awaited_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_retry_projection_does_not_starve_verified_success_closure(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
class _RowsResult(_MappingResult):
|
||||
def __init__(self, rows: list[dict]) -> None:
|
||||
super().__init__()
|
||||
self._rows = rows
|
||||
|
||||
def all(self) -> list[dict]:
|
||||
return self._rows
|
||||
|
||||
apply_row = {
|
||||
"op_id": "00000000-0000-0000-0000-000000000104",
|
||||
"status": "success",
|
||||
"verifier_ready": True,
|
||||
}
|
||||
db = _SequenceDB(_MappingResult(), _RowsResult([apply_row]))
|
||||
|
||||
@asynccontextmanager
|
||||
async def fake_db_context(_project_id: str):
|
||||
yield db
|
||||
|
||||
monkeypatch.setattr(service, "get_db_context", fake_db_context)
|
||||
monkeypatch.setattr(
|
||||
service,
|
||||
"backfill_missing_retry_terminal_projections_once",
|
||||
AsyncMock(
|
||||
return_value={
|
||||
"scanned": 1,
|
||||
"written": 0,
|
||||
"retry_receipt_written": 0,
|
||||
"telegram_receipt_acknowledged": 1,
|
||||
"incident_receipt_written": 0,
|
||||
"lifecycle_written": 0,
|
||||
"verified": 0,
|
||||
"runtime_apply_executed": False,
|
||||
"error": None,
|
||||
}
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
service,
|
||||
"_claim_from_apply_operation_row",
|
||||
lambda _row: (_claim(), _verified_result()),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
service,
|
||||
"_record_post_apply_verifier_and_learning",
|
||||
AsyncMock(
|
||||
return_value={
|
||||
"verification": True,
|
||||
"verification_passed": True,
|
||||
"verification_result": "success",
|
||||
"learning": True,
|
||||
"trust_learning": True,
|
||||
"rag_writeback": True,
|
||||
"runtime_stage_receipts": [],
|
||||
}
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
service,
|
||||
"_record_auto_repair_execution_receipt",
|
||||
AsyncMock(return_value=True),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
service,
|
||||
"_record_timeline_projection_receipt",
|
||||
AsyncMock(return_value=None),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
service,
|
||||
"_record_runtime_stage_receipts",
|
||||
AsyncMock(return_value=True),
|
||||
)
|
||||
closure = AsyncMock(
|
||||
return_value={
|
||||
"status": "controlled_apply_closed",
|
||||
"closed": True,
|
||||
"telegram_receipt_acknowledged": True,
|
||||
"runtime_apply_executed": False,
|
||||
}
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
service,
|
||||
"_reconcile_verified_apply_closure_projections",
|
||||
closure,
|
||||
)
|
||||
|
||||
result = await service.backfill_missing_auto_repair_execution_receipts_once(
|
||||
limit=1
|
||||
)
|
||||
|
||||
assert result["retry_terminal_projection_scanned"] == 1
|
||||
assert result["scanned"] == 2
|
||||
assert result["incident_closure_written"] == 1
|
||||
assert result["telegram_receipt_acknowledged"] == 1
|
||||
closure.assert_awaited_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_broker_prioritizes_retry_terminal_projection_backfill(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
|
||||
Reference in New Issue
Block a user