fix(sre): require unique durable learning receipts

This commit is contained in:
Your Name
2026-07-19 06:20:27 +08:00
parent 70112d7f84
commit c707d6dc15
4 changed files with 273 additions and 54 deletions

View File

@@ -1,9 +1,9 @@
"""Telegram alert learning context post-apply verifier readback.
Verifies metadata-only Telegram alert learning context receipts emitted by the
AI Loop consumer readback. This module only reads public-safe receipt metadata;
it does not write KM/RAG/PlayBook, call MCP tools, send Telegram, or touch
runtime infrastructure.
Verifies public-safe Telegram alert learning receipts and requires durable
target-write evidence for every learning target. This module remains a
read-only independent verifier; it does not write KM/RAG/PlayBook, call MCP
tools, send Telegram, or touch runtime infrastructure.
"""
from __future__ import annotations
@@ -81,7 +81,8 @@ def build_telegram_alert_learning_context_post_apply_verifier(
_verify_context_receipt(receipt) for receipt in context_receipts
]
target_count = _safe_int(telegram_context.get("target_count")) or len(_TARGETS)
expected_target_count = len(_TARGETS)
reported_target_count = _safe_int(telegram_context.get("target_count"))
verified_targets = sorted(
{
str(item["target"])
@@ -97,6 +98,20 @@ def build_telegram_alert_learning_context_post_apply_verifier(
failed_results = [
item for item in verifier_results if item["verifier_status"] != "passed"
]
verified_target_context_write_count = sum(
1
for item in verifier_results
if item["verified_target_context_write_performed"] is True
)
verified_target_context_write_receipt_ids = {
str(item["target_context_write_receipt_id"])
for item in verifier_results
if item["verified_target_context_write_performed"] is True
and item["target_context_write_receipt_id"]
}
verified_target_context_write_receipt_count = len(
verified_target_context_write_receipt_ids
)
source_ready = (
telegram_context.get("status") == "ai_loop_agent_context_receipt_ready"
)
@@ -104,7 +119,11 @@ def build_telegram_alert_learning_context_post_apply_verifier(
source_ready
and context_receipts
and not failed_results
and len(verified_targets) == target_count
and reported_target_count == expected_target_count
and len(context_receipts) == expected_target_count
and set(verified_targets) == set(_TARGETS)
and verified_target_context_write_count == expected_target_count
and verified_target_context_write_receipt_count == expected_target_count
and verified_ai_agent_count > 0
)
active_blockers = _active_blockers(
@@ -112,7 +131,13 @@ def build_telegram_alert_learning_context_post_apply_verifier(
context_receipts=context_receipts,
failed_results=failed_results,
verified_targets=verified_targets,
target_count=target_count,
context_receipt_count=len(context_receipts),
reported_target_count=reported_target_count,
expected_target_count=expected_target_count,
verified_target_context_write_count=verified_target_context_write_count,
verified_target_context_write_receipt_count=(
verified_target_context_write_receipt_count
),
verified_ai_agent_count=verified_ai_agent_count,
)
@@ -157,7 +182,8 @@ def build_telegram_alert_learning_context_post_apply_verifier(
1 for item in verifier_results if item["verifier_status"] == "passed"
),
"failed_context_receipt_count": len(failed_results),
"target_count": target_count,
"target_count": expected_target_count,
"reported_target_count": reported_target_count,
"verified_target_count": len(verified_targets),
"verified_targets": verified_targets,
"verified_ai_agent_context_receipt_count": verified_ai_agent_count,
@@ -165,9 +191,7 @@ def build_telegram_alert_learning_context_post_apply_verifier(
1 for item in verifier_results if item["target_selector_verified"]
),
"source_of_truth_diff_verified_count": sum(
1
for item in verifier_results
if item["source_of_truth_diff_verified"]
1 for item in verifier_results if item["source_of_truth_diff_verified"]
),
"check_mode_verified_count": sum(
1 for item in verifier_results if item["check_mode_verified"]
@@ -178,10 +202,11 @@ def build_telegram_alert_learning_context_post_apply_verifier(
"post_apply_verifier_ref_count": sum(
len(item["post_apply_verifier_refs"]) for item in verifier_results
),
"verified_target_context_write_count": sum(
1
for item in verifier_results
if item["verified_target_context_write_performed"] is True
"verified_target_context_write_count": (
verified_target_context_write_count
),
"verified_target_context_write_receipt_count": (
verified_target_context_write_receipt_count
),
"metadata_only_receipt_count": sum(
1 for item in verifier_results if item["metadata_only"] is True
@@ -198,7 +223,12 @@ def build_telegram_alert_learning_context_post_apply_verifier(
"next_action": (
"surface_verified_telegram_alert_context_receipts_in_awooop_runs_work_items_alerts"
if ready
else "fix_failed_telegram_alert_context_receipts_then_rerun_post_apply_verifier"
else (
"collect_exact_six_unique_durable_consumer_write_receipts_then_rerun_post_apply_verifier"
if verified_target_context_write_count != expected_target_count
or verified_target_context_write_receipt_count != expected_target_count
else "fix_failed_telegram_alert_context_receipts_then_rerun_post_apply_verifier"
)
),
"operation_boundaries": {
"metadata_read_performed": True,
@@ -238,14 +268,18 @@ def _verify_context_receipt(receipt: dict[str, Any]) -> dict[str, Any]:
else _ALERT_CARD_TARGET_SELECTOR_FIELDS
)
required_checks = (
_CONSUMER_REQUIRED_CHECKS
if consumer_receipt
else _ALERT_CARD_REQUIRED_CHECKS
_CONSUMER_REQUIRED_CHECKS if consumer_receipt else _ALERT_CARD_REQUIRED_CHECKS
)
target_selector_missing = [
key for key in required_target_selector_fields if not target_selector.get(key)
]
target_selector_contract_verified = _target_selector_contract_verified(
receipt,
target_selector=target_selector,
target=target,
receipt_kind=receipt_kind,
)
checks = _strings(check_mode.get("checks"))
missing_checks = [check for check in required_checks if check not in checks]
source_diff_verified = _source_diff_verified(
@@ -267,6 +301,8 @@ def _verify_context_receipt(receipt: dict[str, Any]) -> dict[str, Any]:
failed_checks.append("receipt_ready_for_ai_loop_context")
if target_selector_missing:
failed_checks.append("target_selector_required_fields_present")
elif not target_selector_contract_verified:
failed_checks.append("target_selector_bound_to_receipt")
if not source_diff_verified:
failed_checks.append("source_of_truth_diff_verified")
if check_mode.get("enabled") is not True or missing_checks:
@@ -296,6 +332,7 @@ def _verify_context_receipt(receipt: dict[str, Any]) -> dict[str, Any]:
"receipt_kind_supported",
"receipt_ready_for_ai_loop_context",
"target_selector_required_fields_present",
"target_selector_bound_to_receipt",
"source_of_truth_diff_verified",
"check_mode_required_checks_present",
"rollback_ref_present",
@@ -320,7 +357,9 @@ def _verify_context_receipt(receipt: dict[str, Any]) -> dict[str, Any]:
"verifier_status": "passed" if not failed_checks else "failed",
"passed_checks": passed_checks,
"failed_checks": failed_checks,
"target_selector_verified": not target_selector_missing,
"target_selector_verified": (
not target_selector_missing and target_selector_contract_verified
),
"target_selector_missing_fields": target_selector_missing,
"source_of_truth_diff_verified": source_diff_verified,
"check_mode_verified": check_mode.get("enabled") is True and not missing_checks,
@@ -334,6 +373,14 @@ def _verify_context_receipt(receipt: dict[str, Any]) -> dict[str, Any]:
receipt.get("target_write_performed") is True
and target_write_contract_verified
),
"target_context_write_receipt_id": (
str(
_dict(receipt.get("consumer_write_receipt")).get("consumer_receipt_id")
or ""
)
if target_write_contract_verified and receipt_kind == _CONSUMER_RECEIPT_KIND
else ""
),
"verifier_write_performed": False,
"metadata_only": receipt.get("metadata_only") is True,
"raw_payload_included": receipt.get("raw_payload_included") is True,
@@ -355,7 +402,11 @@ def _active_blockers(
context_receipts: list[dict[str, Any]],
failed_results: list[dict[str, Any]],
verified_targets: list[str],
target_count: int,
context_receipt_count: int,
reported_target_count: int,
expected_target_count: int,
verified_target_context_write_count: int,
verified_target_context_write_receipt_count: int,
verified_ai_agent_count: int,
) -> list[str]:
blockers: list[str] = []
@@ -363,8 +414,22 @@ def _active_blockers(
blockers.append("telegram_alert_learning_context_source_not_ready")
if not context_receipts:
blockers.append("telegram_alert_learning_context_receipts_missing")
if len(verified_targets) < target_count:
blockers.append("telegram_alert_learning_context_verified_target_count_below_target")
if reported_target_count != expected_target_count:
blockers.append("telegram_alert_learning_context_target_count_not_exact")
if context_receipt_count != expected_target_count:
blockers.append("telegram_alert_learning_context_receipt_count_not_exact")
if set(verified_targets) != set(_TARGETS):
blockers.append(
"telegram_alert_learning_context_verified_target_count_below_target"
)
if verified_target_context_write_count != expected_target_count:
blockers.append(
"telegram_alert_learning_context_verified_target_write_count_not_exact"
)
if verified_target_context_write_receipt_count != expected_target_count:
blockers.append(
"telegram_alert_learning_context_unique_target_write_receipt_count_not_exact"
)
if verified_ai_agent_count <= 0:
blockers.append("telegram_alert_learning_context_ai_agent_receipt_not_verified")
for item in failed_results:
@@ -422,16 +487,44 @@ def _target_write_contract_verified(
if receipt_kind != _CONSUMER_RECEIPT_KIND:
return receipt.get("target_write_performed") is False
consumer_write_receipt = _dict(receipt.get("consumer_write_receipt"))
target_selector = _dict(receipt.get("target_selector"))
consumer_receipt_id = str(consumer_write_receipt.get("consumer_receipt_id") or "")
return bool(
receipt.get("target_write_performed") is True
and consumer_write_receipt.get("consumer_receipt_id")
and consumer_receipt_id
and consumer_receipt_id == str(receipt.get("source_receipt_id") or "")
and consumer_receipt_id == str(target_selector.get("consumer_receipt_id") or "")
and consumer_write_receipt.get("status") == "success"
and consumer_write_receipt.get("target_context_receipt_write_performed")
is True
and consumer_write_receipt.get("target_context_receipt_write_performed") is True
and consumer_write_receipt.get("runtime_target_write_performed") is True
)
def _target_selector_contract_verified(
receipt: Mapping[str, Any],
*,
target_selector: Mapping[str, Any],
target: str,
receipt_kind: str,
) -> bool:
if target_selector.get("target") != target:
return False
if target_selector.get("source_ref") != receipt.get("source_ref"):
return False
if receipt_kind == _CONSUMER_RECEIPT_KIND:
consumer_write_receipt = _dict(receipt.get("consumer_write_receipt"))
return bool(
target_selector.get("dispatch_receipt_id") == receipt.get("source_ref")
and target_selector.get("consumer_receipt_id")
== receipt.get("source_receipt_id")
== consumer_write_receipt.get("consumer_receipt_id")
)
return bool(
target_selector.get("run_id") == receipt.get("source_run_id")
and target_selector.get("message_id") == receipt.get("source_message_id")
)
def _dict(value: Any) -> dict[str, Any]:
return value if isinstance(value, dict) else {}

View File

@@ -3975,6 +3975,60 @@ def _telegram_context_receipts() -> list[dict]:
]
def _durable_telegram_context_receipts() -> list[dict]:
receipts = _telegram_context_receipts()
for receipt in receipts:
target = receipt["target"]
dispatch_receipt_id = f"log_controlled_writeback_dispatched::{target}"
consumer_receipt_id = f"log_controlled_writeback_consumed::{target}"
receipt.update(
{
"receipt_kind": "log_controlled_writeback_consumer",
"receipt_id": (
"telegram_alert_learning_context_fallback::"
f"{consumer_receipt_id}"
),
"source_receipt_id": consumer_receipt_id,
"source_ref": dispatch_receipt_id,
"target_write_performed": True,
"verifier_write_performed": False,
"consumer_write_receipt": {
"consumer_receipt_id": consumer_receipt_id,
"status": "success",
"target_context_receipt_write_performed": True,
"runtime_target_write_performed": True,
},
"target_selector": {
"project_id": "awoooi",
"dispatch_receipt_id": dispatch_receipt_id,
"consumer_receipt_id": consumer_receipt_id,
"target": target,
"source_ref": dispatch_receipt_id,
},
"source_of_truth_diff": {
"current_state": (
"telegram_alert_registry_unavailable_or_not_ready"
),
"desired_state": "ai_loop_agent_context_receipt_available",
"delta_kind": (
f"log_controlled_writeback_{target}_context_fallback"
),
"raw_payload_included": False,
},
"check_mode": {
"enabled": True,
"checks": [
"consumer_binding_ready",
"consumer_apply_receipt_present",
"metadata_only_raw_payload_absent",
"post_apply_verifier_refs_present",
],
},
}
)
return receipts
def _consumer_readback_ready() -> dict:
return {
"schema_version": "ai_agent_log_controlled_writeback_consumer_readback_v1",
@@ -4039,7 +4093,7 @@ def _consumer_readback_ready() -> dict:
"next_action": (
"verify_telegram_alert_learning_context_receipts_with_ai_loop_post_apply_verifier"
),
"context_receipts": _telegram_context_receipts(),
"context_receipts": _durable_telegram_context_receipts(),
"active_blockers": [],
"operation_boundaries": {
"metadata_read_performed": True,

View File

@@ -111,9 +111,7 @@ def _fallback_context_receipts() -> list[dict]:
"metadata_only": True,
"target_write_performed": True,
"consumer_write_receipt": {
"consumer_receipt_id": (
f"log_controlled_writeback_consumed::{target}"
),
"consumer_receipt_id": (f"log_controlled_writeback_consumed::{target}"),
"status": "success",
"target_context_receipt_write_performed": True,
"runtime_target_write_performed": True,
@@ -125,20 +123,14 @@ def _fallback_context_receipts() -> list[dict]:
"dispatch_receipt_id": (
f"log_controlled_writeback_dispatched::{target}"
),
"consumer_receipt_id": (
f"log_controlled_writeback_consumed::{target}"
),
"consumer_receipt_id": (f"log_controlled_writeback_consumed::{target}"),
"target": target,
"source_ref": f"log_controlled_writeback_dispatched::{target}",
},
"source_of_truth_diff": {
"current_state": (
"telegram_alert_registry_unavailable_or_not_ready"
),
"current_state": ("telegram_alert_registry_unavailable_or_not_ready"),
"desired_state": "ai_loop_agent_context_receipt_available",
"delta_kind": (
f"log_controlled_writeback_{target}_context_fallback"
),
"delta_kind": (f"log_controlled_writeback_{target}_context_fallback"),
"raw_payload_included": False,
},
"check_mode": {
@@ -180,12 +172,14 @@ def _consumer_readback(*, receipts: list[dict] | None = None) -> dict:
"ready_target_count": 6,
"context_receipt_count": 6,
"ai_agent_context_receipt_count": 1,
"context_receipts": receipts if receipts is not None else _context_receipts(),
"context_receipts": receipts
if receipts is not None
else _context_receipts(),
},
}
def test_telegram_alert_learning_context_post_apply_verifier_passes_receipts():
def test_telegram_alert_learning_context_post_apply_verifier_blocks_metadata_only_receipts():
payload = build_telegram_alert_learning_context_post_apply_verifier(
consumer_readback=_consumer_readback()
)
@@ -194,17 +188,23 @@ def test_telegram_alert_learning_context_post_apply_verifier_passes_receipts():
"telegram_alert_learning_context_post_apply_verifier_v1"
)
assert payload["status"] == (
"telegram_alert_learning_context_post_apply_verified"
"blocked_telegram_alert_learning_context_post_apply_verifier"
)
assert payload["active_blockers"] == [
"telegram_alert_learning_context_verified_target_write_count_not_exact",
"telegram_alert_learning_context_unique_target_write_receipt_count_not_exact",
]
assert payload["next_action"] == (
"collect_exact_six_unique_durable_consumer_write_receipts_then_rerun_post_apply_verifier"
)
assert payload["active_blockers"] == []
assert payload["controlled_verifier"]["post_apply_verifier_executed"] is True
assert payload["controlled_verifier"]["raw_payload_absence_verified"] is True
assert payload["controlled_verifier"]["raw_payload_absence_verified"] is False
assert payload["operation_boundaries"]["runtime_target_write_performed"] is False
assert payload["operation_boundaries"]["telegram_send_performed"] is False
assert payload["operation_boundaries"]["secret_value_collection_allowed"] is False
rollups = payload["rollups"]
assert rollups["telegram_alert_learning_context_post_apply_verifier_ready"] is True
assert rollups["telegram_alert_learning_context_post_apply_verifier_ready"] is False
assert rollups["context_receipt_count"] == 6
assert rollups["verified_context_receipt_count"] == 6
assert rollups["verified_target_count"] == 6
@@ -233,15 +233,15 @@ def test_telegram_alert_learning_context_post_apply_verifier_passes_fallback_rec
consumer_readback=_consumer_readback(receipts=_fallback_context_receipts())
)
assert payload["status"] == (
"telegram_alert_learning_context_post_apply_verified"
)
assert payload["status"] == ("telegram_alert_learning_context_post_apply_verified")
assert payload["active_blockers"] == []
assert payload["rollups"]["verified_context_receipt_count"] == 6
assert payload["rollups"]["reported_target_count"] == 6
assert payload["rollups"]["verified_target_context_write_count"] == 6
assert {
result["receipt_kind"] for result in payload["verifier_results"]
} == {"log_controlled_writeback_consumer"}
assert payload["rollups"]["verified_target_context_write_receipt_count"] == 6
assert {result["receipt_kind"] for result in payload["verifier_results"]} == {
"log_controlled_writeback_consumer"
}
assert all(
result["target_write_contract_verified"] is True
and result["verified_target_context_write_performed"] is True
@@ -250,6 +250,73 @@ def test_telegram_alert_learning_context_post_apply_verifier_passes_fallback_rec
)
def test_telegram_alert_learning_context_post_apply_verifier_rejects_shrunk_five_of_five_contract():
receipts = _fallback_context_receipts()[:5]
readback = _consumer_readback(receipts=receipts)
readback["telegram_alert_learning_context"]["target_count"] = 5
readback["telegram_alert_learning_context"]["context_receipt_count"] = 5
payload = build_telegram_alert_learning_context_post_apply_verifier(
consumer_readback=readback
)
assert payload["status"] == (
"blocked_telegram_alert_learning_context_post_apply_verifier"
)
assert payload["rollups"]["target_count"] == 6
assert payload["rollups"]["reported_target_count"] == 5
assert payload["rollups"]["verified_target_context_write_count"] == 5
assert payload["active_blockers"] == [
"telegram_alert_learning_context_target_count_not_exact",
"telegram_alert_learning_context_receipt_count_not_exact",
"telegram_alert_learning_context_verified_target_count_below_target",
"telegram_alert_learning_context_verified_target_write_count_not_exact",
"telegram_alert_learning_context_unique_target_write_receipt_count_not_exact",
"telegram_alert_learning_context_ai_agent_receipt_not_verified",
]
def test_telegram_alert_learning_context_post_apply_verifier_rejects_reused_write_receipt_id():
receipts = _fallback_context_receipts()
reused_id = receipts[0]["source_receipt_id"]
receipts[1]["source_receipt_id"] = reused_id
receipts[1]["target_selector"]["consumer_receipt_id"] = reused_id
receipts[1]["consumer_write_receipt"]["consumer_receipt_id"] = reused_id
payload = build_telegram_alert_learning_context_post_apply_verifier(
consumer_readback=_consumer_readback(receipts=receipts)
)
assert payload["rollups"]["verified_target_context_write_count"] == 6
assert payload["rollups"]["verified_target_context_write_receipt_count"] == 5
assert payload["status"] == (
"blocked_telegram_alert_learning_context_post_apply_verifier"
)
assert payload["active_blockers"] == [
"telegram_alert_learning_context_unique_target_write_receipt_count_not_exact"
]
def test_telegram_alert_learning_context_post_apply_verifier_rejects_mismatched_write_receipt_id():
receipts = _fallback_context_receipts()
receipts[0]["consumer_write_receipt"]["consumer_receipt_id"] = "wrong-receipt"
payload = build_telegram_alert_learning_context_post_apply_verifier(
consumer_readback=_consumer_readback(receipts=receipts)
)
failed = [
result
for result in payload["verifier_results"]
if result["verifier_status"] == "failed"
]
assert failed[0]["failed_checks"] == [
"target_selector_bound_to_receipt",
"consumer_write_receipt_verified",
]
assert payload["rollups"]["verified_target_context_write_count"] == 5
def test_telegram_alert_learning_context_post_apply_verifier_blocks_bad_fallback_receipt():
receipts = _fallback_context_receipts()
receipts[0]["consumer_write_receipt"]["runtime_target_write_performed"] = False
@@ -310,7 +377,7 @@ def test_telegram_alert_learning_context_post_apply_verifier_rejects_unknown_kin
def test_telegram_alert_learning_context_post_apply_verifier_endpoint(monkeypatch):
async def fake_loader():
return build_telegram_alert_learning_context_post_apply_verifier(
consumer_readback=_consumer_readback()
consumer_readback=_consumer_readback(receipts=_fallback_context_receipts())
)
monkeypatch.setattr(

View File

@@ -816,7 +816,10 @@
"apps/api/src/services/agent99_controlled_dispatch_ledger.py",
"apps/api/src/services/agent99_telegram_lifecycle.py",
"apps/api/src/services/agent99_public_receipts.py",
"apps/api/src/repositories/knowledge_repository.py"
"apps/api/src/repositories/knowledge_repository.py",
"apps/api/src/services/telegram_alert_learning_context_post_apply_verifier.py",
"apps/api/src/services/telegram_alert_monitoring_coverage_readback.py",
"apps/web/src/app/[locale]/awooop/alerts/page.tsx"
],
"executor": "learning writeback consumer",
"verifier": "durable same-run acknowledgement readback",
@@ -827,7 +830,9 @@
"Backup/restore recipient-visible recovered cards name Agent99 BackupCheck as the read-only executor and backup_restore_readback_verifier as the typed independent verifier; apply remains not_applicable and the final durable closure receipt is required",
"BackupCheck learning assets are reconciled idempotently as read-only DR evidence rather than controlled repair",
"the Telegram learning verifier now distinguishes alert-card registry receipts from log-controlled consumer receipts, verifies the latter only with an exact successful consumer write receipt, and keeps verifier runtime writes false",
"the monitoring coverage readback no longer lets consumer candidates or alert-card metadata refs bypass the independent verifier; learning readiness requires every declared target write plus an AI Agent context receipt to be verified"
"the monitoring coverage readback no longer lets consumer candidates or alert-card metadata refs bypass the independent verifier; learning readiness requires every declared target write plus an AI Agent context receipt to be verified",
"the independent verifier now rejects metadata-only 0/6 receipts, shrunk 5/5 contracts, duplicated consumer write receipt IDs and selector/receipt ID mismatches; ready requires exactly six unique durable consumer-write receipts bound to the six canonical targets",
"the AwoooP alerts surface distinguishes verified, candidate and blocked learning closure and displays durable write, verified target, AI Agent receipt, evidence-source and blocker readbacks without claiming source evidence as production closure"
],
"runtime_gaps": [
"production exposed six fallback context receipts but the deployed verifier rejected all six under the alert-card-only contract, while the deployed coverage could still treat unverified fallback metadata as ready; this source revision fixes both false-negative and false-green paths but still has no production same-run receipt",