fix(agents): apply telegram monitoring live receipts
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m14s
CD Pipeline / build-and-deploy (push) Successful in 4m49s
CD Pipeline / post-deploy-checks (push) Has been cancelled
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m14s
CD Pipeline / build-and-deploy (push) Successful in 4m49s
CD Pipeline / post-deploy-checks (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,419 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from src.api.v1 import agents
|
||||
from src.api.v1.agents import router
|
||||
from src.services import telegram_alert_monitoring_live_receipt_apply as apply_module
|
||||
from src.services.telegram_alert_monitoring_live_receipt_apply import (
|
||||
APPLY_SCHEMA_VERSION,
|
||||
OPERATION_TYPE,
|
||||
READBACK_SCHEMA_VERSION,
|
||||
apply_latest_telegram_alert_monitoring_live_receipts,
|
||||
build_telegram_alert_monitoring_live_receipt_apply_readback,
|
||||
build_telegram_alert_monitoring_live_receipt_apply_receipt,
|
||||
)
|
||||
|
||||
|
||||
class _FakeScalarResult:
|
||||
def __init__(self, value: str | None):
|
||||
self.value = value
|
||||
|
||||
def scalar(self) -> str | None:
|
||||
return self.value
|
||||
|
||||
|
||||
class _FakeMappings:
|
||||
def __init__(self, rows: list[dict]):
|
||||
self.rows = rows
|
||||
|
||||
def all(self) -> list[dict]:
|
||||
return self.rows
|
||||
|
||||
|
||||
class _FakeRowsResult:
|
||||
def __init__(self, rows: list[dict]):
|
||||
self.rows = rows
|
||||
|
||||
def mappings(self) -> _FakeMappings:
|
||||
return _FakeMappings(self.rows)
|
||||
|
||||
|
||||
class _FakeDb:
|
||||
def __init__(self, *, rows: list[dict] | None = None):
|
||||
self.params: list[dict] = []
|
||||
self.rows = rows or []
|
||||
|
||||
async def execute(self, statement, params: dict):
|
||||
if not params:
|
||||
return _FakeScalarResult(None)
|
||||
if "fallback_operation_type" in params:
|
||||
return _FakeScalarResult("km_linked")
|
||||
if "input" in params:
|
||||
self.params.append(params)
|
||||
live_receipt_id = str(params["live_receipt_id"]).rsplit("::", 1)[-1]
|
||||
return _FakeScalarResult(f"live-receipt-op-{live_receipt_id}")
|
||||
if params.get("operation_type") == OPERATION_TYPE and "project_id" in params:
|
||||
return _FakeRowsResult(self.rows)
|
||||
return _FakeScalarResult("existing-live-receipt-op")
|
||||
|
||||
|
||||
class _FakeContext:
|
||||
def __init__(self, db: _FakeDb):
|
||||
self.db = db
|
||||
|
||||
async def __aenter__(self) -> _FakeDb:
|
||||
return self.db
|
||||
|
||||
async def __aexit__(self, _exc_type, _exc, _tb) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
class _FailingContext:
|
||||
async def __aenter__(self):
|
||||
raise TimeoutError("pool checkout unavailable")
|
||||
|
||||
async def __aexit__(self, _exc_type, _exc, _tb) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def _coverage_payload() -> dict:
|
||||
batches = [
|
||||
{
|
||||
"batch_id": "tg_live_receipt_01_prometheus",
|
||||
"domain": "prometheus",
|
||||
"priority": "P0",
|
||||
"surface_count": 20,
|
||||
"write_capable_surface_count": 1,
|
||||
"missing_receipt_fields": ["receiver_receipt_readback_ref"],
|
||||
"tag_hints": {
|
||||
"project_id": "awoooi",
|
||||
"product_id": "awoooi-observability",
|
||||
"website_id": "awoooi.wooo.work",
|
||||
"service_name": "prometheus",
|
||||
"package_name": "prometheus-config",
|
||||
"tool_id": "prometheus",
|
||||
"log_source": "monitoring_live_receipt_metadata",
|
||||
"alertname": "monitoring_surface_live_receipt_gap",
|
||||
"playbook_id": "playbook://awoooi/monitoring-live-receipt/prometheus",
|
||||
"rag_context_ref": "rag://awoooi/monitoring/prometheus",
|
||||
"mcp_evidence_ref": "mcp://awoooi/monitoring/prometheus",
|
||||
"schedule_id": "schedule://awoooi/monitoring-live-receipt/prometheus",
|
||||
},
|
||||
"target_selector": {
|
||||
"surface_ids": ["prometheus_k8s_base_config"],
|
||||
"config_kinds": ["prometheus_config"],
|
||||
"control_tiers": ["C1"],
|
||||
"expected_scope_prefixes": ["k8s"],
|
||||
"repo_source_paths": ["k8s/monitoring/prometheus.yml"],
|
||||
},
|
||||
"controlled_next_action": (
|
||||
"ingest_metadata_only_live_receipt_batch_then_verify_gap_delta"
|
||||
),
|
||||
"post_verifier": (
|
||||
"/api/v1/agents/telegram-alert-monitoring-coverage-readback"
|
||||
),
|
||||
},
|
||||
{
|
||||
"batch_id": "tg_live_receipt_02_telegram",
|
||||
"domain": "telegram",
|
||||
"priority": "P0",
|
||||
"surface_count": 3,
|
||||
"write_capable_surface_count": 0,
|
||||
"missing_receipt_fields": ["notification_delivery_metadata_ref"],
|
||||
"tag_hints": {
|
||||
"project_id": "awoooi",
|
||||
"product_id": "awooop",
|
||||
"website_id": "awoooi.wooo.work",
|
||||
"service_name": "telegram-gateway",
|
||||
"package_name": "telegram-alert-delivery",
|
||||
"tool_id": "telegram",
|
||||
"log_source": "monitoring_live_receipt_metadata",
|
||||
"alertname": "monitoring_surface_live_receipt_gap",
|
||||
"playbook_id": "playbook://awoooi/monitoring-live-receipt/telegram",
|
||||
"rag_context_ref": "rag://awoooi/monitoring/telegram",
|
||||
"mcp_evidence_ref": "mcp://awoooi/monitoring/telegram",
|
||||
"schedule_id": "schedule://awoooi/monitoring-live-receipt/telegram",
|
||||
},
|
||||
"target_selector": {
|
||||
"surface_ids": ["telegram_gateway_config"],
|
||||
"config_kinds": ["telegram_gateway"],
|
||||
"control_tiers": ["C1"],
|
||||
"expected_scope_prefixes": ["telegram"],
|
||||
"repo_source_paths": ["apps/api/src/services/telegram_gateway.py"],
|
||||
},
|
||||
"controlled_next_action": (
|
||||
"ingest_metadata_only_live_receipt_batch_then_verify_gap_delta"
|
||||
),
|
||||
"post_verifier": (
|
||||
"/api/v1/agents/telegram-alert-monitoring-coverage-readback"
|
||||
),
|
||||
},
|
||||
]
|
||||
return {
|
||||
"schema_version": "telegram_alert_monitoring_coverage_readback_v1",
|
||||
"project_id": "awoooi",
|
||||
"status": "blocked_telegram_alert_monitoring_coverage_gaps_present",
|
||||
"summary": {
|
||||
"monitoring_surface_count": 60,
|
||||
"monitoring_live_receipt_gap_count": 60,
|
||||
"ai_controlled_live_receipt_batch_count": len(batches),
|
||||
"source_contract_ready": True,
|
||||
},
|
||||
"ai_controlled_live_receipt_batches": batches,
|
||||
"active_blockers": ["monitoring_live_receipt_gap:60"],
|
||||
"operation_boundaries": {
|
||||
"telegram_send_performed": False,
|
||||
"bot_api_call_performed": False,
|
||||
"gateway_queue_write_performed": False,
|
||||
"receiver_route_changed": False,
|
||||
"alertmanager_reload_performed": False,
|
||||
"raw_alert_payload_stored": False,
|
||||
"secret_value_read": False,
|
||||
"github_api_used": False,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _row_for(batch: dict, *, op_id: str) -> dict:
|
||||
return {
|
||||
"op_id": op_id,
|
||||
"operation_type": "km_linked",
|
||||
"actor": "ai_agent_monitoring_live_receipt_consumer",
|
||||
"status": "success",
|
||||
"semantic_operation_type": OPERATION_TYPE,
|
||||
"ledger_operation_type": "km_linked",
|
||||
"live_receipt_id": f"{OPERATION_TYPE}::{batch['batch_id']}",
|
||||
"batch_id": batch["batch_id"],
|
||||
"domain": batch["domain"],
|
||||
"priority": batch["priority"],
|
||||
"surface_count": str(batch["surface_count"]),
|
||||
"write_capable_surface_count": str(batch["write_capable_surface_count"]),
|
||||
"runtime_target_write_performed": "true",
|
||||
"raw_payload_included": "false",
|
||||
"target_selector": batch["target_selector"],
|
||||
"tag_hints": batch["tag_hints"],
|
||||
"monitoring_live_receipt_metadata_recorded": "true",
|
||||
"target_context_receipt_write_performed": "true",
|
||||
"next_action": "readback_telegram_monitoring_live_receipt_apply_then_verify_gap_delta",
|
||||
"post_apply_verifier_refs": [
|
||||
"/api/v1/agents/telegram-alert-monitoring-coverage-readback"
|
||||
f"#batch={batch['batch_id']}"
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def test_telegram_monitoring_live_receipt_apply_builder_creates_receipts():
|
||||
payload = build_telegram_alert_monitoring_live_receipt_apply_receipt(
|
||||
_coverage_payload()
|
||||
)
|
||||
|
||||
assert payload["schema_version"] == APPLY_SCHEMA_VERSION
|
||||
assert payload["status"] == "telegram_monitoring_live_receipt_apply_ready"
|
||||
assert payload["active_blockers"] == []
|
||||
assert payload["readback"]["operation_type"] == OPERATION_TYPE
|
||||
assert payload["rollups"]["source_live_receipt_batch_count"] == 2
|
||||
assert payload["rollups"]["source_surface_count"] == 23
|
||||
assert payload["rollups"]["metadata_only_receipt_count"] == 2
|
||||
|
||||
receipts = payload["live_receipt_apply_receipts"]
|
||||
assert {item["domain"] for item in receipts} == {"prometheus", "telegram"}
|
||||
for item in receipts:
|
||||
assert item["status"] == "ready_for_metadata_live_receipt_write"
|
||||
assert item["raw_payload_included"] is False
|
||||
assert item["check_mode"]["enabled"] is True
|
||||
assert item["rollback"]["required"] is True
|
||||
assert item["target_selector"]["surface_ids"]
|
||||
assert item["tag_hints"]["project_id"] == "awoooi"
|
||||
|
||||
boundaries = payload["operation_boundaries"]
|
||||
assert boundaries["metadata_ledger_write_only"] is True
|
||||
assert boundaries["telegram_send_performed"] is False
|
||||
assert boundaries["bot_api_call_performed"] is False
|
||||
assert boundaries["raw_alert_payload_stored"] is False
|
||||
assert boundaries["secret_value_read"] is False
|
||||
|
||||
serialized = json.dumps(payload, ensure_ascii=False)
|
||||
for marker in ["TELEGRAM_BOT_TOKEN", "authorization_header", "raw Telegram payload"]:
|
||||
assert marker not in serialized
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_telegram_monitoring_live_receipt_apply_writes_idempotent_rows(
|
||||
monkeypatch,
|
||||
):
|
||||
fake_db = _FakeDb()
|
||||
monkeypatch.setattr(
|
||||
apply_module,
|
||||
"get_db_context",
|
||||
lambda project_id: _FakeContext(fake_db),
|
||||
)
|
||||
|
||||
async def fake_coverage(*, project_id: str):
|
||||
assert project_id == "awoooi"
|
||||
return _coverage_payload()
|
||||
|
||||
monkeypatch.setattr(
|
||||
apply_module,
|
||||
"load_latest_telegram_alert_monitoring_coverage_readback",
|
||||
fake_coverage,
|
||||
)
|
||||
|
||||
payload = await apply_latest_telegram_alert_monitoring_live_receipts(
|
||||
project_id="awoooi"
|
||||
)
|
||||
|
||||
assert payload["status"] == "telegram_monitoring_live_receipt_apply_ready"
|
||||
assert payload["rollups"]["runtime_target_write_performed"] is True
|
||||
assert payload["rollups"]["live_receipt_apply_row_count"] == 2
|
||||
assert payload["rollups"]["inserted_live_receipt_apply_row_count"] == 2
|
||||
assert payload["operation_boundaries"]["runtime_target_write_performed"] is True
|
||||
assert payload["apply_result"]["operation_type"] == OPERATION_TYPE
|
||||
assert payload["apply_result"]["ledger_operation_type"] == "km_linked"
|
||||
|
||||
write_params = [params for params in fake_db.params if "input" in params]
|
||||
assert len(write_params) == 2
|
||||
for params in write_params:
|
||||
assert params["operation_type"] == OPERATION_TYPE
|
||||
assert params["ledger_operation_type"] == "km_linked"
|
||||
assert params["actor"] == "ai_agent_monitoring_live_receipt_consumer"
|
||||
assert '"semantic_operation_type": "telegram_monitoring_live_receipt_applied"' in params["input"]
|
||||
assert '"runtime_target_write_performed": true' in params["input"]
|
||||
assert '"raw_payload_included": false' in params["input"]
|
||||
assert '"monitoring_live_receipt_metadata_recorded": true' in params["output"]
|
||||
assert '"telegram_send_performed": false' in params["output"]
|
||||
|
||||
|
||||
def test_telegram_monitoring_live_receipt_apply_readback_preserves_gap_truth():
|
||||
coverage = _coverage_payload()
|
||||
rows = [
|
||||
_row_for(batch, op_id=f"live-op-{index}")
|
||||
for index, batch in enumerate(coverage["ai_controlled_live_receipt_batches"], start=1)
|
||||
]
|
||||
|
||||
payload = build_telegram_alert_monitoring_live_receipt_apply_readback(
|
||||
coverage=coverage,
|
||||
rows=rows,
|
||||
)
|
||||
|
||||
assert payload["schema_version"] == READBACK_SCHEMA_VERSION
|
||||
assert payload["status"] == "telegram_monitoring_live_receipt_apply_readback_ready"
|
||||
assert payload["active_blockers"] == []
|
||||
assert payload["operator_answer"][
|
||||
"all_ai_controlled_live_receipt_batches_have_apply_receipt"
|
||||
] is True
|
||||
assert payload["operator_answer"]["metadata_live_receipt_apply_performed"] is True
|
||||
assert payload["operator_answer"][
|
||||
"metadata_apply_does_not_mark_monitoring_live_receipt_accepted"
|
||||
] is True
|
||||
assert payload["operator_answer"]["monitoring_live_receipt_gap_count_source_truth"] == 60
|
||||
assert payload["rollups"]["expected_live_receipt_batch_count"] == 2
|
||||
assert payload["rollups"]["applied_live_receipt_batch_count"] == 2
|
||||
assert payload["rollups"]["expected_surface_count"] == 23
|
||||
assert payload["rollups"]["applied_surface_count"] == 23
|
||||
assert payload["rollups"]["monitoring_live_receipt_gap_count_source_truth"] == 60
|
||||
assert payload["operation_boundaries"]["monitoring_live_receipt_acceptance_mutated"] is False
|
||||
assert payload["operation_boundaries"]["telegram_send_performed"] is False
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_telegram_monitoring_live_receipt_apply_degrades_on_db_write_pressure(
|
||||
monkeypatch,
|
||||
):
|
||||
monkeypatch.setattr(
|
||||
apply_module,
|
||||
"get_db_context",
|
||||
lambda project_id: _FailingContext(),
|
||||
)
|
||||
|
||||
async def fake_coverage(*, project_id: str):
|
||||
assert project_id == "awoooi"
|
||||
return _coverage_payload()
|
||||
|
||||
monkeypatch.setattr(
|
||||
apply_module,
|
||||
"load_latest_telegram_alert_monitoring_coverage_readback",
|
||||
fake_coverage,
|
||||
)
|
||||
|
||||
payload = await apply_latest_telegram_alert_monitoring_live_receipts(
|
||||
project_id="awoooi"
|
||||
)
|
||||
|
||||
assert payload["status"] == "blocked_waiting_telegram_monitoring_live_receipt_apply_db"
|
||||
assert "telegram_monitoring_live_receipt_apply_db_write_unavailable" in payload[
|
||||
"active_blockers"
|
||||
]
|
||||
assert payload["apply_result"]["db_write_status"] == "unavailable"
|
||||
assert payload["operation_boundaries"]["runtime_target_write_performed"] is False
|
||||
|
||||
|
||||
def test_telegram_monitoring_live_receipt_apply_endpoint_returns_receipt(monkeypatch):
|
||||
async def fake_apply():
|
||||
payload = build_telegram_alert_monitoring_live_receipt_apply_receipt(
|
||||
_coverage_payload()
|
||||
)
|
||||
payload["rollups"]["runtime_target_write_performed"] = True
|
||||
payload["operation_boundaries"]["runtime_target_write_performed"] = True
|
||||
return payload
|
||||
|
||||
monkeypatch.setattr(
|
||||
agents,
|
||||
"apply_latest_telegram_alert_monitoring_live_receipts",
|
||||
fake_apply,
|
||||
)
|
||||
app = FastAPI()
|
||||
app.include_router(router, prefix="/api/v1")
|
||||
client = TestClient(app)
|
||||
|
||||
response = client.post(
|
||||
"/api/v1/agents/telegram-alert-monitoring-live-receipt-apply"
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
payload = response.json()
|
||||
assert payload["schema_version"] == APPLY_SCHEMA_VERSION
|
||||
assert payload["status"] == "telegram_monitoring_live_receipt_apply_ready"
|
||||
assert payload["rollups"]["runtime_target_write_performed"] is True
|
||||
|
||||
|
||||
def test_telegram_monitoring_live_receipt_apply_readback_endpoint_returns_receipt(
|
||||
monkeypatch,
|
||||
):
|
||||
async def fake_readback():
|
||||
coverage = _coverage_payload()
|
||||
rows = [
|
||||
_row_for(batch, op_id=f"live-op-{index}")
|
||||
for index, batch in enumerate(
|
||||
coverage["ai_controlled_live_receipt_batches"],
|
||||
start=1,
|
||||
)
|
||||
]
|
||||
return build_telegram_alert_monitoring_live_receipt_apply_readback(
|
||||
coverage=coverage,
|
||||
rows=rows,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
agents,
|
||||
"load_latest_telegram_alert_monitoring_live_receipt_apply_readback",
|
||||
fake_readback,
|
||||
)
|
||||
app = FastAPI()
|
||||
app.include_router(router, prefix="/api/v1")
|
||||
client = TestClient(app)
|
||||
|
||||
response = client.get(
|
||||
"/api/v1/agents/telegram-alert-monitoring-live-receipt-apply-readback"
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
payload = response.json()
|
||||
assert payload["schema_version"] == READBACK_SCHEMA_VERSION
|
||||
assert payload["status"] == "telegram_monitoring_live_receipt_apply_readback_ready"
|
||||
assert payload["rollups"]["applied_live_receipt_batch_count"] == 2
|
||||
assert payload["operator_answer"]["monitoring_live_receipt_gap_count_source_truth"] == 60
|
||||
Reference in New Issue
Block a user