fix(agent): project no-write lifecycle prefixes
This commit is contained in:
@@ -4088,22 +4088,47 @@ async def _load_missing_stdin_boundary_terminal_projection_rows(
|
||||
'{detail,repository_readback_verified}' = 'true'
|
||||
AND receipt.value ->> 'durable_receipt' = 'true'
|
||||
)
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM jsonb_array_elements(
|
||||
coalesce(
|
||||
terminal.input -> 'runtime_stage_receipts',
|
||||
'[]'::jsonb
|
||||
)
|
||||
) receipt(value)
|
||||
WHERE receipt.value ->> 'stage_id' = 'incident_closure'
|
||||
AND receipt.value ->> 'automation_run_id'
|
||||
= terminal.input ->> 'automation_run_id'
|
||||
AND receipt.value #>>
|
||||
'{detail,terminal_op_id}' = terminal.op_id::text
|
||||
AND receipt.value #>>
|
||||
'{detail,projection_readback_verified}' = 'true'
|
||||
AND receipt.value ->> 'durable_receipt' = 'true'
|
||||
AND (
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM jsonb_array_elements(
|
||||
coalesce(
|
||||
terminal.input -> 'runtime_stage_receipts',
|
||||
'[]'::jsonb
|
||||
)
|
||||
) receipt(value)
|
||||
WHERE receipt.value ->> 'stage_id'
|
||||
= 'incident_closure'
|
||||
AND receipt.value ->> 'automation_run_id'
|
||||
= terminal.input ->> 'automation_run_id'
|
||||
AND receipt.value #>>
|
||||
'{detail,terminal_op_id}' = terminal.op_id::text
|
||||
AND receipt.value #>>
|
||||
'{detail,projection_readback_verified}' = 'true'
|
||||
AND receipt.value ->> 'durable_receipt' = 'true'
|
||||
)
|
||||
OR NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM alert_operation_log lifecycle
|
||||
WHERE lifecycle.incident_id = incident.incident_id
|
||||
AND lifecycle.event_type::text
|
||||
= 'AUTO_REPAIR_TRIGGERED'
|
||||
AND lifecycle.context ->> 'automation_run_id'
|
||||
= terminal.input ->> 'automation_run_id'
|
||||
AND lifecycle.context ->> 'apply_op_id'
|
||||
= terminal.op_id::text
|
||||
)
|
||||
OR NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM alert_operation_log lifecycle
|
||||
WHERE lifecycle.incident_id = incident.incident_id
|
||||
AND lifecycle.event_type::text
|
||||
= 'EXECUTION_STARTED'
|
||||
AND lifecycle.context ->> 'automation_run_id'
|
||||
= terminal.input ->> 'automation_run_id'
|
||||
AND lifecycle.context ->> 'apply_op_id'
|
||||
= terminal.op_id::text
|
||||
)
|
||||
)
|
||||
ORDER BY terminal.created_at ASC, terminal.op_id ASC
|
||||
LIMIT :limit
|
||||
@@ -4504,6 +4529,30 @@ async def _verify_stdin_boundary_terminal_projection_readback(
|
||||
'{callback_reply,apply_op_id}'
|
||||
= CAST(:terminal_op_id AS text)
|
||||
)
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM alert_operation_log lifecycle
|
||||
WHERE lifecycle.incident_id = :incident_id
|
||||
AND lifecycle.event_type::text
|
||||
= 'AUTO_REPAIR_TRIGGERED'
|
||||
AND lifecycle.context
|
||||
->> 'automation_run_id'
|
||||
= :automation_run_id
|
||||
AND lifecycle.context ->> 'apply_op_id'
|
||||
= CAST(:terminal_op_id AS text)
|
||||
)
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM alert_operation_log lifecycle
|
||||
WHERE lifecycle.incident_id = :incident_id
|
||||
AND lifecycle.event_type::text
|
||||
= 'EXECUTION_STARTED'
|
||||
AND lifecycle.context
|
||||
->> 'automation_run_id'
|
||||
= :automation_run_id
|
||||
AND lifecycle.context ->> 'apply_op_id'
|
||||
= CAST(:terminal_op_id AS text)
|
||||
)
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM alert_operation_log lifecycle
|
||||
@@ -4660,6 +4709,28 @@ async def backfill_missing_stdin_boundary_terminal_projections_once(
|
||||
continue
|
||||
stats["telegram_receipt_acknowledged"] += 1
|
||||
|
||||
trigger_lifecycle = await _append_alert_lifecycle_receipt(
|
||||
claim,
|
||||
"AUTO_REPAIR_TRIGGERED",
|
||||
apply_op_id=terminal_op_id,
|
||||
success=True,
|
||||
action_detail=(
|
||||
"stdin_boundary_no_write_replay_triggered"
|
||||
),
|
||||
project_id=project_id,
|
||||
post_verifier_passed=None,
|
||||
)
|
||||
started_lifecycle = await _append_alert_lifecycle_receipt(
|
||||
claim,
|
||||
"EXECUTION_STARTED",
|
||||
apply_op_id=terminal_op_id,
|
||||
success=True,
|
||||
action_detail=(
|
||||
"stdin_boundary_no_write_replay_started"
|
||||
),
|
||||
project_id=project_id,
|
||||
post_verifier_passed=None,
|
||||
)
|
||||
execution_lifecycle = await _append_alert_lifecycle_receipt(
|
||||
claim,
|
||||
"EXECUTION_COMPLETED",
|
||||
@@ -4683,7 +4754,12 @@ async def backfill_missing_stdin_boundary_terminal_projections_once(
|
||||
project_id=project_id,
|
||||
post_verifier_passed=False,
|
||||
)
|
||||
if not execution_lifecycle or not telegram_lifecycle:
|
||||
if not all((
|
||||
trigger_lifecycle,
|
||||
started_lifecycle,
|
||||
execution_lifecycle,
|
||||
telegram_lifecycle,
|
||||
)):
|
||||
stats["blockers"].append("lifecycle_projection_pending")
|
||||
continue
|
||||
stats["lifecycle_written"] += 1
|
||||
|
||||
@@ -2145,12 +2145,16 @@ def test_stdin_boundary_terminal_projection_closes_only_from_durable_receipts(
|
||||
assert "replay_of_check_mode_op_id" in source
|
||||
assert "retry_of_check_mode_op_id" in source
|
||||
assert "TELEGRAM_RESULT_SENT" in verifier_source
|
||||
assert "AUTO_REPAIR_TRIGGERED" in loader_source
|
||||
assert "EXECUTION_STARTED" in loader_source
|
||||
assert "AUTO_REPAIR_TRIGGERED" in verifier_source
|
||||
assert "EXECUTION_STARTED" in verifier_source
|
||||
assert "km_playbook_writeback" in verifier_source
|
||||
assert "playbook_trust" in verifier_source
|
||||
assert "runtime_apply_executed" in verifier_source
|
||||
assert verifier_source.count(
|
||||
"CAST(:terminal_op_id AS text)"
|
||||
) == 4
|
||||
) == 6
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -2307,6 +2311,14 @@ async def test_stdin_boundary_terminal_projection_runs_no_write_pipeline(
|
||||
assert result["runtime_apply_executed"] is False
|
||||
assert result["blockers"] == []
|
||||
assert ("telegram_send", "no_write_replay") in calls
|
||||
assert (
|
||||
"lifecycle",
|
||||
("AUTO_REPAIR_TRIGGERED", terminal_op_id, True),
|
||||
) in calls
|
||||
assert (
|
||||
"lifecycle",
|
||||
("EXECUTION_STARTED", terminal_op_id, True),
|
||||
) in calls
|
||||
assert (
|
||||
"lifecycle",
|
||||
("EXECUTION_COMPLETED", terminal_op_id, False),
|
||||
@@ -2315,6 +2327,13 @@ async def test_stdin_boundary_terminal_projection_runs_no_write_pipeline(
|
||||
"lifecycle",
|
||||
("TELEGRAM_RESULT_SENT", terminal_op_id, False),
|
||||
) in calls
|
||||
lifecycle_calls = [value for name, value in calls if name == "lifecycle"]
|
||||
assert lifecycle_calls == [
|
||||
("AUTO_REPAIR_TRIGGERED", terminal_op_id, True),
|
||||
("EXECUTION_STARTED", terminal_op_id, True),
|
||||
("EXECUTION_COMPLETED", terminal_op_id, False),
|
||||
("TELEGRAM_RESULT_SENT", terminal_op_id, False),
|
||||
]
|
||||
append_calls = [value for name, value in calls if name == "append"]
|
||||
assert len(append_calls) == 3
|
||||
assert all(item[0] == terminal_op_id for item in append_calls)
|
||||
|
||||
Reference in New Issue
Block a user