fix(operator): fail closed on missing backup evidence
This commit is contained in:
@@ -1515,8 +1515,9 @@ async def list_ai_alert_card_delivery_readback(
|
||||
FROM awooop_outbound_message m
|
||||
WHERE {where_sql}
|
||||
""")
|
||||
# Bound the page and the Agent99 subset before the lateral lookup. Without
|
||||
# both materialized sets PostgreSQL can rescan the full run ledger per card.
|
||||
# Resolve at most one Agent99 row per bounded page candidate. Materializing
|
||||
# every Agent99 row for the project still grows with ledger history and can
|
||||
# exhaust the readback timeout even when the requested page is small.
|
||||
list_sql = text(f"""
|
||||
WITH candidate_messages AS MATERIALIZED (
|
||||
SELECT m.*
|
||||
@@ -1525,18 +1526,56 @@ async def list_ai_alert_card_delivery_readback(
|
||||
ORDER BY COALESCE(m.sent_at, m.queued_at) DESC, m.message_id DESC
|
||||
LIMIT :limit OFFSET :offset
|
||||
),
|
||||
candidate_refs AS MATERIALIZED (
|
||||
SELECT
|
||||
m.message_id,
|
||||
m.project_id,
|
||||
NULLIF(
|
||||
COALESCE(m.source_envelope::jsonb, '{{}}'::jsonb) #>>
|
||||
'{{agent99_dispatch_receipt,run_id}}',
|
||||
''
|
||||
) AS receipt_run_id,
|
||||
NULLIF(
|
||||
COALESCE(m.source_envelope::jsonb, '{{}}'::jsonb) #>>
|
||||
'{{agent99_dispatch_receipt,incident_id}}',
|
||||
''
|
||||
) AS receipt_incident_id
|
||||
FROM candidate_messages m
|
||||
),
|
||||
agent99_runs AS MATERIALIZED (
|
||||
SELECT
|
||||
ars.error_detail,
|
||||
ars.state,
|
||||
ars.trace_id,
|
||||
ars.run_id,
|
||||
ars.project_id,
|
||||
ars.trigger_ref,
|
||||
ars.created_at
|
||||
FROM awooop_run_state ars
|
||||
WHERE ars.project_id = :project_id
|
||||
AND ars.agent_id = 'agent99_controlled_dispatch'
|
||||
cr.message_id,
|
||||
matched.error_detail,
|
||||
matched.state,
|
||||
matched.trace_id
|
||||
FROM candidate_refs cr
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT
|
||||
ars.error_detail,
|
||||
ars.state,
|
||||
ars.trace_id,
|
||||
ars.run_id,
|
||||
ars.created_at
|
||||
FROM awooop_run_state ars
|
||||
WHERE ars.project_id = cr.project_id
|
||||
AND ars.agent_id = 'agent99_controlled_dispatch'
|
||||
AND (
|
||||
(
|
||||
cr.receipt_run_id IS NOT NULL
|
||||
AND ars.run_id::text = cr.receipt_run_id
|
||||
)
|
||||
OR (
|
||||
cr.receipt_incident_id IS NOT NULL
|
||||
AND ars.trigger_ref LIKE (
|
||||
'agent99:' || cr.receipt_incident_id || ':%'
|
||||
)
|
||||
)
|
||||
)
|
||||
ORDER BY (
|
||||
ars.run_id::text = COALESCE(cr.receipt_run_id, '')
|
||||
) DESC, ars.created_at DESC
|
||||
LIMIT 1
|
||||
) matched ON TRUE
|
||||
)
|
||||
SELECT
|
||||
m.message_id,
|
||||
@@ -1566,46 +1605,8 @@ async def list_ai_alert_card_delivery_readback(
|
||||
LEFT JOIN awooop_run_state r
|
||||
ON r.project_id = m.project_id
|
||||
AND r.run_id = m.run_id
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT
|
||||
ars.error_detail,
|
||||
ars.state,
|
||||
ars.trace_id
|
||||
FROM agent99_runs ars
|
||||
WHERE ars.project_id = m.project_id
|
||||
AND (
|
||||
ars.run_id::text = COALESCE(
|
||||
COALESCE(m.source_envelope::jsonb, '{{}}'::jsonb) #>>
|
||||
'{{agent99_dispatch_receipt,run_id}}',
|
||||
''
|
||||
)
|
||||
OR (
|
||||
COALESCE(
|
||||
COALESCE(m.source_envelope::jsonb, '{{}}'::jsonb) #>>
|
||||
'{{agent99_dispatch_receipt,incident_id}}',
|
||||
''
|
||||
) <> ''
|
||||
AND ars.trigger_ref LIKE (
|
||||
'agent99:' ||
|
||||
COALESCE(
|
||||
COALESCE(
|
||||
m.source_envelope::jsonb,
|
||||
'{{}}'::jsonb
|
||||
) #>> '{{agent99_dispatch_receipt,incident_id}}',
|
||||
''
|
||||
) || ':%'
|
||||
)
|
||||
)
|
||||
)
|
||||
ORDER BY (
|
||||
ars.run_id::text = COALESCE(
|
||||
COALESCE(m.source_envelope::jsonb, '{{}}'::jsonb) #>>
|
||||
'{{agent99_dispatch_receipt,run_id}}',
|
||||
''
|
||||
)
|
||||
) DESC, ars.created_at DESC
|
||||
LIMIT 1
|
||||
) ar ON TRUE
|
||||
LEFT JOIN agent99_runs ar
|
||||
ON ar.message_id = m.message_id
|
||||
ORDER BY COALESCE(m.sent_at, m.queued_at) DESC, m.message_id DESC
|
||||
""")
|
||||
|
||||
@@ -1907,8 +1908,8 @@ async def _load_ai_alert_card_delivery_readback_direct(
|
||||
""", *args),
|
||||
timeout=_AI_ALERT_CARD_DIRECT_QUERY_TIMEOUT_SECONDS,
|
||||
)
|
||||
# Mirror the pooled-session plan so the pressure fallback does
|
||||
# not reintroduce a per-card full run-ledger scan.
|
||||
# Mirror the pooled-session plan: the materialized Agent99 set
|
||||
# is hard-bounded to one exact match per page candidate.
|
||||
list_rows = await asyncio.wait_for(
|
||||
conn.fetch(f"""
|
||||
WITH candidate_messages AS MATERIALIZED (
|
||||
@@ -1920,18 +1921,65 @@ async def _load_ai_alert_card_delivery_readback_direct(
|
||||
m.message_id DESC
|
||||
LIMIT ${limit_param} OFFSET ${offset_param}
|
||||
),
|
||||
candidate_refs AS MATERIALIZED (
|
||||
SELECT
|
||||
m.message_id,
|
||||
m.project_id,
|
||||
NULLIF(
|
||||
COALESCE(
|
||||
m.source_envelope::jsonb,
|
||||
'{{}}'::jsonb
|
||||
) #>> '{{agent99_dispatch_receipt,run_id}}',
|
||||
''
|
||||
) AS receipt_run_id,
|
||||
NULLIF(
|
||||
COALESCE(
|
||||
m.source_envelope::jsonb,
|
||||
'{{}}'::jsonb
|
||||
) #>> '{{agent99_dispatch_receipt,incident_id}}',
|
||||
''
|
||||
) AS receipt_incident_id
|
||||
FROM candidate_messages m
|
||||
),
|
||||
agent99_runs AS MATERIALIZED (
|
||||
SELECT
|
||||
ars.error_detail,
|
||||
ars.state,
|
||||
ars.trace_id,
|
||||
ars.run_id,
|
||||
ars.project_id,
|
||||
ars.trigger_ref,
|
||||
ars.created_at
|
||||
FROM awooop_run_state ars
|
||||
WHERE ars.project_id = $1
|
||||
AND ars.agent_id = 'agent99_controlled_dispatch'
|
||||
cr.message_id,
|
||||
matched.error_detail,
|
||||
matched.state,
|
||||
matched.trace_id
|
||||
FROM candidate_refs cr
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT
|
||||
ars.error_detail,
|
||||
ars.state,
|
||||
ars.trace_id,
|
||||
ars.run_id,
|
||||
ars.created_at
|
||||
FROM awooop_run_state ars
|
||||
WHERE ars.project_id = cr.project_id
|
||||
AND ars.agent_id = 'agent99_controlled_dispatch'
|
||||
AND (
|
||||
(
|
||||
cr.receipt_run_id IS NOT NULL
|
||||
AND ars.run_id::text = cr.receipt_run_id
|
||||
)
|
||||
OR (
|
||||
cr.receipt_incident_id IS NOT NULL
|
||||
AND ars.trigger_ref LIKE (
|
||||
'agent99:' ||
|
||||
cr.receipt_incident_id ||
|
||||
':%'
|
||||
)
|
||||
)
|
||||
)
|
||||
ORDER BY (
|
||||
ars.run_id::text = COALESCE(
|
||||
cr.receipt_run_id,
|
||||
''
|
||||
)
|
||||
) DESC, ars.created_at DESC
|
||||
LIMIT 1
|
||||
) matched ON TRUE
|
||||
)
|
||||
SELECT
|
||||
m.message_id,
|
||||
@@ -1967,52 +2015,8 @@ async def _load_ai_alert_card_delivery_readback_direct(
|
||||
LEFT JOIN awooop_run_state r
|
||||
ON r.project_id = m.project_id
|
||||
AND r.run_id = m.run_id
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT
|
||||
ars.error_detail,
|
||||
ars.state,
|
||||
ars.trace_id
|
||||
FROM agent99_runs ars
|
||||
WHERE ars.project_id = m.project_id
|
||||
AND (
|
||||
ars.run_id::text = COALESCE(
|
||||
COALESCE(
|
||||
m.source_envelope::jsonb,
|
||||
'{{}}'::jsonb
|
||||
) #>> '{{agent99_dispatch_receipt,run_id}}',
|
||||
''
|
||||
)
|
||||
OR (
|
||||
COALESCE(
|
||||
COALESCE(
|
||||
m.source_envelope::jsonb,
|
||||
'{{}}'::jsonb
|
||||
) #>> '{{agent99_dispatch_receipt,incident_id}}',
|
||||
''
|
||||
) <> ''
|
||||
AND ars.trigger_ref LIKE (
|
||||
'agent99:' ||
|
||||
COALESCE(
|
||||
COALESCE(
|
||||
m.source_envelope::jsonb,
|
||||
'{{}}'::jsonb
|
||||
) #>> '{{agent99_dispatch_receipt,incident_id}}',
|
||||
''
|
||||
) || ':%'
|
||||
)
|
||||
)
|
||||
)
|
||||
ORDER BY (
|
||||
ars.run_id::text = COALESCE(
|
||||
COALESCE(
|
||||
m.source_envelope::jsonb,
|
||||
'{{}}'::jsonb
|
||||
) #>> '{{agent99_dispatch_receipt,run_id}}',
|
||||
''
|
||||
)
|
||||
) DESC, ars.created_at DESC
|
||||
LIMIT 1
|
||||
) ar ON TRUE
|
||||
LEFT JOIN agent99_runs ar
|
||||
ON ar.message_id = m.message_id
|
||||
ORDER BY COALESCE(m.sent_at, m.queued_at) DESC, m.message_id DESC
|
||||
""", *args, per_page, offset),
|
||||
timeout=_AI_ALERT_CARD_DIRECT_QUERY_TIMEOUT_SECONDS,
|
||||
@@ -2198,8 +2202,13 @@ def _ai_alert_card_delivery_source_unavailable_response(
|
||||
target["status"] = "blocked_by_ai_alert_card_delivery_readback_unavailable"
|
||||
target["next_action"] = "repair_awooop_ai_alert_card_delivery_readback"
|
||||
|
||||
backup_restore_filtered = event_type == BACKUP_RESTORE_EVENT_TYPE
|
||||
summary.update({
|
||||
"status": "source_unavailable_ai_controlled_repair_required",
|
||||
"status": (
|
||||
"blocked_backup_restore_evidence_missing_source_unavailable"
|
||||
if backup_restore_filtered
|
||||
else "source_unavailable_ai_controlled_repair_required"
|
||||
),
|
||||
"db_read_status": "unavailable",
|
||||
"source_unavailable_reason": error_type,
|
||||
"source_unavailable_next_action": (
|
||||
@@ -2218,6 +2227,15 @@ def _ai_alert_card_delivery_source_unavailable_response(
|
||||
"repair_awooop_ai_alert_card_delivery_readback_then_consume_learning_registry"
|
||||
),
|
||||
})
|
||||
if backup_restore_filtered:
|
||||
summary.update({
|
||||
"backup_restore_readback_required": True,
|
||||
"no_false_green_enforced": True,
|
||||
"backup_restore_next_action": (
|
||||
"repair_awooop_ai_alert_card_delivery_readback_then_collect_"
|
||||
"backup_status_freshness_offsite_escrow_restore_and_resolution_receipts"
|
||||
),
|
||||
})
|
||||
learning_registry.update({
|
||||
"status": "source_unavailable_ai_controlled_repair_required",
|
||||
"ready_target_count": 0,
|
||||
@@ -2281,7 +2299,8 @@ def _ai_alert_card_delivery_summary_from_row(
|
||||
0,
|
||||
)
|
||||
backup_restore_policy_applied = bool(
|
||||
backup_restore_total
|
||||
backup_restore_filtered
|
||||
or backup_restore_total
|
||||
or backup_runtime_gate_excluded_total
|
||||
or backup_learning_writeback_excluded_total
|
||||
)
|
||||
@@ -2291,14 +2310,18 @@ def _ai_alert_card_delivery_summary_from_row(
|
||||
status_value = "delivery_failure_observed"
|
||||
elif pending_total > 0:
|
||||
status_value = "delivery_pending_observed"
|
||||
elif backup_restore_filtered and total > 0:
|
||||
status_value = "blocked_backup_restore_evidence_or_verifier"
|
||||
elif backup_restore_filtered:
|
||||
status_value = (
|
||||
"blocked_backup_restore_evidence_missing"
|
||||
if total == 0
|
||||
else "blocked_backup_restore_evidence_or_verifier"
|
||||
)
|
||||
elif backup_restore_policy_applied and total > 0:
|
||||
status_value = "observed_effective_backup_policy_projection_applied"
|
||||
|
||||
learning_next_action = (
|
||||
"collect_backup_status_freshness_offsite_escrow_restore_and_resolution_receipts"
|
||||
if backup_restore_policy_applied and total > 0
|
||||
if backup_restore_policy_applied
|
||||
else "none"
|
||||
if total > 0 and learning_writeback_missing_total == 0
|
||||
else "ensure_ai_alert_cards_include_event_type_lane_and_delivery_receipt"
|
||||
|
||||
Reference in New Issue
Block a user