All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m32s
CD Pipeline / build-and-deploy (push) Successful in 8m2s
CD Pipeline / post-deploy-checks (push) Successful in 2m22s
Restore D037 durable incident readback without weakening database failure semantics. Fence Agent99 dispatch and terminal learning to canonical identities, durable leases, verifier receipts, and reconciler-owned checkpoints. Drain backup and restore legacy receipts in bounded cohorts with strict transport, claim, projection, and no-false-green controls. Keep SSH service refusal visible while separating it from broker network-policy reachability.
120 lines
4.1 KiB
Python
120 lines
4.1 KiB
Python
"""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,
|
|
}
|