"""Production ingestion for Agent99 outcome, verifier, and learning receipts.""" from __future__ import annotations from typing import Any from src.services.agent99_controlled_dispatch_ledger import ( parse_agent99_dispatch_identity, record_agent99_verifier_receipt, validate_agent99_outcome_identity, ) from src.services.agent99_public_receipts import ( extract_agent99_outcome_evidence_refs, ) def _public_evidence_refs( payload_refs: dict[str, Any], outcome_receipt: dict[str, Any], ) -> dict[str, str]: """Merge only bounded, public-safe identifiers from authenticated input.""" return extract_agent99_outcome_evidence_refs( outcome_receipt, payload_refs, ) async def ingest_agent99_outcome_receipt( payload: dict[str, Any], ) -> dict[str, Any]: """Write the Agent99 outcome and optional learning acks to one run. The caller must carry the complete deterministic identity both in the request identity and in the Agent99 outcome receipt. This prevents a valid outcome from being rebound to another incident or execution generation. """ identity_payload = ( payload.get("identity") if isinstance(payload.get("identity"), dict) else {} ) identity = parse_agent99_dispatch_identity(identity_payload) outcome_receipt = ( payload.get("outcome_receipt") if isinstance(payload.get("outcome_receipt"), dict) else {} ) if not outcome_receipt: raise ValueError("agent99_outcome_receipt_required") if not validate_agent99_outcome_identity(identity, outcome_receipt): raise ValueError("agent99_outcome_identity_mismatch") payload_evidence_refs = ( payload.get("evidence_refs") if isinstance(payload.get("evidence_refs"), dict) else {} ) evidence_refs = _public_evidence_refs( payload_evidence_refs, outcome_receipt, ) verifier = await record_agent99_verifier_receipt( identity=identity, outcome_receipt=outcome_receipt, evidence_refs=evidence_refs, ) if verifier.get("receipt_persisted") is not True: return { "schema_version": "agent99_outcome_ingestion_receipt_v1", "status": str(verifier.get("status") or "verifier_rejected"), "accepted": False, "identity": identity.public_dict(), "verifier": verifier, "learning_writeback": { "status": "blocked_verifier_not_persisted", "receipt_persisted": False, }, "runtime_closure_verified": False, } # The relay is authoritative for the Agent99 outcome, but it is not the # authority for Telegram/KM/PlayBook/DR delivery acknowledgements. Those # side effects are created and checkpointed by the server-side reconciler. # Keep the compatibility field in the webhook schema, but never let its # caller-provided values enter the terminal transaction. untrusted_learning_refs = ( payload.get("learning_receipt_refs") if isinstance(payload.get("learning_receipt_refs"), dict) else {} ) learning = { "status": ( "untrusted_external_receipts_ignored_reconciler_pending" if verifier.get("post_verifier_passed") is True and untrusted_learning_refs else "pending_reconciler_durable_receipts" if verifier.get("post_verifier_passed") is True else "blocked_verifier_failed" ), "receipt_persisted": False, "runtime_closure_verified": False, } return { "schema_version": "agent99_outcome_ingestion_receipt_v1", "status": ( "verifier_recorded_learning_pending" if verifier.get("post_verifier_passed") is True else "verifier_failed_no_runtime_closure" ), "accepted": True, "identity": identity.public_dict(), "verifier": verifier, "learning_writeback": learning, "untrusted_learning_receipt_refs_ignored": bool( untrusted_learning_refs ), "runtime_closure_verified": False, }