feat(sre): require Agent99 RAG and MCP closure receipts

This commit is contained in:
Your Name
2026-07-19 00:24:44 +08:00
parent f1811bf8ab
commit 17e60dd36f
5 changed files with 294 additions and 11 deletions

View File

@@ -68,6 +68,8 @@ def test_accepted_without_inbox_trigger_is_delivery_unknown_not_authorized() ->
"incident_closure_receipt_id",
"telegram_lifecycle_receipt_id",
"km_writeback_ack_id",
"rag_writeback_ack_id",
"mcp_evidence_writeback_ack_id",
"playbook_trust_writeback_ack_id",
]
@@ -133,6 +135,8 @@ async def test_backup_learning_requires_dr_scorecard_ack() -> None:
"incident_closure_receipt_id": "incident:1",
"telegram_lifecycle_receipt_id": "telegram:1",
"km_writeback_ack_id": "km:1",
"rag_writeback_ack_id": "rag:1",
"mcp_evidence_writeback_ack_id": "mcp:1",
"playbook_trust_writeback_ack_id": "playbook:1",
},
)

View File

@@ -1,6 +1,7 @@
from __future__ import annotations
from pathlib import Path
from types import SimpleNamespace
import pytest
@@ -50,6 +51,102 @@ def test_agent99_playbook_identity_is_project_scoped() -> None:
assert job._playbook_id(IDENTITY) != job._playbook_id(other)
class _Context:
def __init__(self, db) -> None: # type: ignore[no-untyped-def]
self.db = db
async def __aenter__(self): # type: ignore[no-untyped-def]
return self.db
async def __aexit__(self, *_args): # type: ignore[no-untyped-def]
return False
class _Result:
def __init__(self, *, row=None, scalar=None) -> None: # type: ignore[no-untyped-def]
self.row = row
self.scalar_value = scalar
def mappings(self): # type: ignore[no-untyped-def]
return self
def first(self): # type: ignore[no-untyped-def]
return self.row
def scalar_one_or_none(self): # type: ignore[no-untyped-def]
return self.scalar_value
@pytest.mark.asyncio
async def test_agent99_rag_ack_requires_durable_embedding_readback(
monkeypatch,
) -> None:
class RagDB:
async def execute(self, _statement, _params): # type: ignore[no-untyped-def]
return _Result(row={
"entry_id": "00000000-0000-0000-0000-000000000099",
"embedding_persisted": True,
})
monkeypatch.setattr(
job,
"get_db_context",
lambda _project_id: _Context(RagDB()),
)
receipt = await job._ensure_rag_writeback(IDENTITY)
assert receipt == (
"knowledge_entries:00000000-0000-0000-0000-000000000099:"
"rag_embedding_verified"
)
@pytest.mark.asyncio
async def test_agent99_mcp_ack_is_same_run_durable_and_idempotent(
monkeypatch,
) -> None:
class McpDB:
def __init__(self) -> None:
self.row = None
async def execute(self, statement): # type: ignore[no-untyped-def]
if self.row is None:
values = statement.compile().params
self.row = SimpleNamespace(**values)
return _Result()
return _Result(scalar=self.row)
db = McpDB()
monkeypatch.setattr(
job,
"get_db_context",
lambda _project_id: _Context(db),
)
refs = {
"telegram_lifecycle_receipt_id": "telegram:1",
"km_writeback_ack_id": "km:1",
"rag_writeback_ack_id": "rag:1",
"playbook_trust_writeback_ack_id": "playbook:1",
}
first = await job._ensure_mcp_evidence_writeback(
IDENTITY,
receipt_refs=refs,
)
db.row = None
second = await job._ensure_mcp_evidence_writeback(
IDENTITY,
receipt_refs=refs,
)
expected = (
f"awooop_mcp_gateway_audit:{job._mcp_learning_call_id(IDENTITY)}:verified"
)
assert first == expected
assert second == expected
@pytest.mark.asyncio
async def test_reconciler_consumes_authenticated_outcome_and_closes_same_run(
monkeypatch,
@@ -262,7 +359,14 @@ async def test_learning_checkpoint_resumes_without_replaying_assets(
}
ledger = CheckpointLedger()
effects = {"playbook": 0, "km": 0, "telegram": 0, "dr": 0}
effects = {
"playbook": 0,
"km": 0,
"rag": 0,
"telegram": 0,
"mcp": 0,
"dr": 0,
}
terminal_calls = 0
async def write_playbook(*_args, **_kwargs): # type: ignore[no-untyped-def]
@@ -277,6 +381,14 @@ async def test_learning_checkpoint_resumes_without_replaying_assets(
effects["telegram"] += 1
return "telegram_outbound:1:durable_ack"
async def write_rag(*_args, **_kwargs): # type: ignore[no-untyped-def]
effects["rag"] += 1
return "knowledge_entries:km-1:rag_embedding_verified"
async def write_mcp(*_args, **_kwargs): # type: ignore[no-untyped-def]
effects["mcp"] += 1
return "awooop_mcp_gateway_audit:call-1:verified"
async def write_dr(*_args, **_kwargs): # type: ignore[no-untyped-def]
effects["dr"] += 1
return "knowledge_entries:dr-1:dr_scorecard"
@@ -297,7 +409,9 @@ async def test_learning_checkpoint_resumes_without_replaying_assets(
monkeypatch.setattr(job, "get_agent99_dispatch_ledger", lambda: ledger)
monkeypatch.setattr(job, "_ensure_playbook_trust", write_playbook)
monkeypatch.setattr(job, "_ensure_km_writeback", write_km)
monkeypatch.setattr(job, "_ensure_rag_writeback", write_rag)
monkeypatch.setattr(job, "_ensure_telegram_receipt", write_telegram)
monkeypatch.setattr(job, "_ensure_mcp_evidence_writeback", write_mcp)
monkeypatch.setattr(job, "_ensure_dr_scorecard", write_dr)
monkeypatch.setattr(job, "record_agent99_learning_writeback", terminal)
@@ -314,7 +428,14 @@ async def test_learning_checkpoint_resumes_without_replaying_assets(
assert first["runtime_closure_verified"] is False
assert second["runtime_closure_verified"] is True
assert effects == {"playbook": 1, "km": 1, "telegram": 1, "dr": 1}
assert effects == {
"playbook": 1,
"km": 1,
"rag": 1,
"telegram": 1,
"mcp": 1,
"dr": 1,
}
assert terminal_calls == 2