feat(telegram): persist callback status chain snapshots
All checks were successful
CD Pipeline / tests (push) Successful in 1m8s
Code Review / ai-code-review (push) Successful in 11s
CD Pipeline / build-and-deploy (push) Successful in 4m23s
CD Pipeline / post-deploy-checks (push) Successful in 1m31s

This commit is contained in:
Your Name
2026-05-25 09:58:42 +08:00
parent 4818ba45c0
commit daf9d4b00b
8 changed files with 304 additions and 0 deletions

View File

@@ -375,6 +375,12 @@ def test_callback_reply_event_item_surfaces_run_link_and_human_flag() -> None:
"incident_id": "INC-20260513-79ED5E",
"error": "HTTP error: 400",
},
"persisted_awooop_status_chain": {
"schema_version": "awooop_status_chain_callback_reply_snapshot_v1",
"repair_state": "blocked_manual_required",
"needs_human": True,
"next_step": "manual_investigation",
},
"persisted_km_stale_completion_summary": {
"schema_version": "km_stale_owner_review_callback_reply_snapshot_v1",
"status": "no_related_owner_review",
@@ -398,6 +404,9 @@ def test_callback_reply_event_item_surfaces_run_link_and_human_flag() -> None:
assert item["persisted_km_stale_completion_summary"]["triage"]["ai_lead_agent"] == (
"Hermes"
)
assert item["persisted_awooop_status_chain"]["repair_state"] == (
"blocked_manual_required"
)
def test_list_callback_replies_response_preserves_callback_evidence() -> None:
@@ -434,6 +443,30 @@ def test_list_callback_replies_response_preserves_callback_evidence() -> None:
"repair_state": "read_only_dry_run",
"needs_human": True,
},
"persisted_awooop_status_chain": {
"schema_version": "awooop_status_chain_callback_reply_snapshot_v1",
"source_schema_version": "awooop_status_chain_v1",
"source": "telegram_callback_reply_snapshot",
"source_id": "INC-20260513-79ED5E",
"incident_ids": ["INC-20260513-79ED5E"],
"current_stage": "approval_required",
"stage_status": "waiting",
"verdict": "approval_required",
"repair_state": "read_only_dry_run",
"verification": "missing",
"needs_human": True,
"next_step": "approve_or_escalate_from_awooop",
"evidence": {
"auto_repair_records": 0,
"operation_records": 0,
"mcp_gateway_total": 1,
"knowledge_entries": 0,
},
"writes": {
"incident": False,
"auto_repair": False,
},
},
"km_stale_completion_summary": {
"schema_version": (
"km_stale_owner_review_completion_callback_summary_v1"
@@ -497,6 +530,9 @@ def test_list_callback_replies_response_preserves_callback_evidence() -> None:
assert dumped["items"][0]["awooop_status_chain"]["repair_state"] == (
"read_only_dry_run"
)
assert dumped["items"][0]["persisted_awooop_status_chain"]["next_step"] == (
"approve_or_escalate_from_awooop"
)
assert dumped["items"][0]["km_stale_completion_summary"]["ready_count"] == 3
assert dumped["items"][0]["km_stale_completion_summary"]["related_total"] == 1
assert dumped["items"][0]["persisted_km_stale_completion_summary"]["triage"][

View File

@@ -177,6 +177,58 @@ def test_awooop_status_chain_lines_show_read_only_manual_gate() -> None:
assert "pending_human_approval" in joined
def test_callback_reply_awooop_status_chain_snapshot_marks_manual_gate() -> None:
"""Callback evidence 要保存當下 AwoooP 狀態鏈,不只保存 live query 結果。"""
snapshot = telegram_gateway_module._callback_reply_awooop_status_chain_snapshot(
incident_id="INC-20260514-F85F21",
truth_chain={
"truth_status": {
"current_stage": "approval_required",
"stage_status": "waiting",
"needs_human": True,
"blockers": ["pending_human_approval"],
},
"automation_quality": {
"verdict": "approval_required",
"facts": {
"auto_repair_execution_records": 0,
"automation_operation_records": 0,
"verification_result": "missing",
"mcp_gateway_total": 1,
"knowledge_entries": 0,
},
"blockers": [],
},
},
remediation_history={
"total": 1,
"items": [
{
"agent_id": "investigator",
"tool_name": "ssh_diagnose",
"required_scope": "read",
"safety_level": "read_only",
"verification_result_preview": "degraded",
"writes_incident_state": False,
"writes_auto_repair_result": False,
}
],
},
)
assert snapshot is not None
assert snapshot["schema_version"] == (
"awooop_status_chain_callback_reply_snapshot_v1"
)
assert snapshot["repair_state"] == "read_only_dry_run"
assert snapshot["needs_human"] is True
assert snapshot["next_step"] == "approve_or_escalate_from_awooop"
assert snapshot["evidence"]["mcp_gateway_total"] == 1
assert snapshot["evidence"]["latest_route"] == "investigator/ssh_diagnose/read"
assert snapshot["writes"]["incident"] is False
assert snapshot["blockers"] == ["pending_human_approval"]
def test_km_stale_completion_lines_show_owner_review_queue_state() -> None:
"""詳情/歷史要顯示 KM owner-review completion queue 是否卡住或可處理。"""
lines = telegram_gateway_module._format_km_stale_completion_lines({
@@ -329,6 +381,15 @@ async def test_send_request_strips_awooop_callback_metadata_before_telegram_api(
"status": "callback_reply_sent",
"incident_id": "INC-20260513-79ED5E",
},
"awooop_status_chain": {
"schema_version": "awooop_status_chain_callback_reply_snapshot_v1",
"repair_state": "read_only_dry_run",
"needs_human": True,
"evidence": {
"auto_repair_records": 0,
"operation_records": 0,
},
},
"km_stale_completion_summary": {
"schema_version": (
"km_stale_owner_review_callback_reply_snapshot_v1"
@@ -349,6 +410,9 @@ async def test_send_request_strips_awooop_callback_metadata_before_telegram_api(
assert captured["mirror"]["source_envelope_extra"]["callback_reply"]["status"] == (
"callback_reply_sent"
)
assert captured["mirror"]["source_envelope_extra"]["awooop_status_chain"][
"repair_state"
] == "read_only_dry_run"
assert captured["mirror"]["source_envelope_extra"][
"km_stale_completion_summary"
]["ready_count"] == 2
@@ -407,6 +471,29 @@ async def test_send_html_line_message_marks_callback_reply_evidence(monkeypatch)
reply_markup=reply_markup,
incident_id="INC-20260514-F85F21",
callback_action="history",
awooop_status_chain={
"schema_version": "awooop_status_chain_callback_reply_snapshot_v1",
"source": "telegram_callback_reply_snapshot",
"source_id": "INC-20260514-F85F21",
"incident_ids": ["INC-20260514-F85F21"],
"current_stage": "approval_required",
"stage_status": "waiting",
"verdict": "approval_required",
"repair_state": "read_only_dry_run",
"verification": "missing",
"needs_human": True,
"next_step": "approve_or_escalate_from_awooop",
"evidence": {
"auto_repair_records": 0,
"operation_records": 0,
"mcp_gateway_total": 1,
"knowledge_entries": 0,
},
"writes": {
"incident": False,
"auto_repair": False,
},
},
km_stale_completion_summary={
"schema_version": "km_stale_owner_review_completion_callback_summary_v1",
"project_id": "awoooi",
@@ -443,6 +530,10 @@ async def test_send_html_line_message_marks_callback_reply_evidence(monkeypatch)
assert first_extra["status"] == "callback_reply_sent"
assert first_extra["action"] == "history"
assert first_extra["parse_mode"] == "HTML"
assert first_source_extra["awooop_status_chain"]["repair_state"] == (
"read_only_dry_run"
)
assert first_source_extra["awooop_status_chain"]["needs_human"] is True
assert first_source_extra["km_stale_completion_summary"]["ready_count"] == 3
assert first_source_extra["km_stale_completion_summary"]["triage"]["flow_stage"] == (
"callback_observed_owner_review_link_missing"
@@ -450,6 +541,9 @@ async def test_send_html_line_message_marks_callback_reply_evidence(monkeypatch)
assert fallback_extra["status"] == "callback_reply_fallback_sent"
assert fallback_extra["incident_id"] == "INC-20260514-F85F21"
assert fallback_extra["parse_mode"] == "plain_text"
assert fallback_source_extra["awooop_status_chain"]["next_step"] == (
"approve_or_escalate_from_awooop"
)
assert fallback_source_extra["km_stale_completion_summary"]["triage"][
"ai_lead_agent"
] == "Hermes"