fix(awooop): record source review dry-run audit
All checks were successful
Code Review / ai-code-review (push) Successful in 10s
CD Pipeline / tests (push) Successful in 4m4s
CD Pipeline / build-and-deploy (push) Successful in 3m34s
CD Pipeline / post-deploy-checks (push) Successful in 1m49s

This commit is contained in:
Your Name
2026-05-21 09:08:46 +08:00
parent 2e54b803f0
commit b5deca91df
3 changed files with 138 additions and 44 deletions

View File

@@ -869,11 +869,20 @@ def _recurrence_handoff_context(payload: dict[str, Any]) -> dict[str, Any]:
}
def _is_source_correlation_review_payload(payload: dict[str, Any]) -> bool:
state = _as_dict(payload.get("current_state_summary"))
return (
state.get("work_item_kind") == "source_correlation_review"
or payload.get("next_step") == "review_provider_source_match"
)
async def _record_recurrence_work_item_dry_run_history(
payload: dict[str, Any],
) -> dict[str, Any]:
incident_id = str(payload.get("incident_id") or "")
if not incident_id:
source_review = _is_source_correlation_review_payload(payload)
if not incident_id and not source_review:
return {"recorded": False, "reason": "missing_incident_id"}
history: dict[str, Any] = {
@@ -891,7 +900,7 @@ async def _record_recurrence_work_item_dry_run_history(
record = await get_alert_operation_log_repository().append(
"PRE_FLIGHT_PASSED" if allowed else "PRE_FLIGHT_FAILED",
incident_id=incident_id,
incident_id=incident_id or None,
auto_repair_id=str(payload.get("auto_repair_id") or "") or None,
actor="awooop_recurrence_work_item_service",
action_detail=f"recurrence_work_item_dry_run:{payload.get('mode')}"[:200],
@@ -907,26 +916,29 @@ async def _record_recurrence_work_item_dry_run_history(
error=str(exc),
)
try:
from src.services.approval_db import get_timeline_service
if incident_id:
try:
from src.services.approval_db import get_timeline_service
event = await get_timeline_service().add_event(
event_type="verifier",
status="success" if allowed else "warning",
title="AwoooP recurrence work item dry-run",
description=_recurrence_history_description(context),
actor="awooop_recurrence_work_item_service",
actor_role=str(payload.get("mode") or "dry_run"),
incident_id=incident_id,
)
if event:
history["timeline_event_id"] = event.get("id")
except Exception as exc:
logger.warning(
"awooop_recurrence_work_item_timeline_history_failed",
incident_id=incident_id,
error=str(exc),
)
event = await get_timeline_service().add_event(
event_type="verifier",
status="success" if allowed else "warning",
title="AwoooP recurrence work item dry-run",
description=_recurrence_history_description(context),
actor="awooop_recurrence_work_item_service",
actor_role=str(payload.get("mode") or "dry_run"),
incident_id=incident_id,
)
if event:
history["timeline_event_id"] = event.get("id")
except Exception as exc:
logger.warning(
"awooop_recurrence_work_item_timeline_history_failed",
incident_id=incident_id,
error=str(exc),
)
else:
history["timeline_reason"] = "source_review_not_incident_scoped"
history["recorded"] = bool(
history.get("alert_operation_id") or history.get("timeline_event_id")
@@ -940,7 +952,8 @@ async def _record_recurrence_work_item_handoff_history(
payload: dict[str, Any],
) -> dict[str, Any]:
incident_id = str(payload.get("incident_id") or "")
if not incident_id:
source_review = _is_source_correlation_review_payload(payload)
if not incident_id and not source_review:
return {"recorded": False, "reason": "missing_incident_id"}
history: dict[str, Any] = {
@@ -958,7 +971,7 @@ async def _record_recurrence_work_item_handoff_history(
record = await get_alert_operation_log_repository().append(
"ESCALATED",
incident_id=incident_id,
incident_id=incident_id or None,
auto_repair_id=str(payload.get("auto_repair_id") or "") or None,
actor="awooop_recurrence_work_item_service",
action_detail=(
@@ -976,26 +989,29 @@ async def _record_recurrence_work_item_handoff_history(
error=str(exc),
)
try:
from src.services.approval_db import get_timeline_service
if incident_id:
try:
from src.services.approval_db import get_timeline_service
event = await get_timeline_service().add_event(
event_type="human",
status="warning" if allowed else "error",
title="AwoooP recurrence work item handoff",
description=_recurrence_handoff_history_description(context),
actor="awooop_recurrence_work_item_service",
actor_role=str(payload.get("handoff_kind") or "handoff"),
incident_id=incident_id,
)
if event:
history["timeline_event_id"] = event.get("id")
except Exception as exc:
logger.warning(
"awooop_recurrence_work_item_handoff_timeline_history_failed",
incident_id=incident_id,
error=str(exc),
)
event = await get_timeline_service().add_event(
event_type="human",
status="warning" if allowed else "error",
title="AwoooP recurrence work item handoff",
description=_recurrence_handoff_history_description(context),
actor="awooop_recurrence_work_item_service",
actor_role=str(payload.get("handoff_kind") or "handoff"),
incident_id=incident_id,
)
if event:
history["timeline_event_id"] = event.get("id")
except Exception as exc:
logger.warning(
"awooop_recurrence_work_item_handoff_timeline_history_failed",
incident_id=incident_id,
error=str(exc),
)
else:
history["timeline_reason"] = "source_review_not_incident_scoped"
history["recorded"] = bool(
history.get("alert_operation_id") or history.get("timeline_event_id")

View File

@@ -555,6 +555,82 @@ def test_build_recurrence_work_item_dry_run_returns_ticket_preview_without_write
assert dry_run["read_model_route"]["required_scope"] == "read"
@pytest.mark.asyncio
async def test_source_correlation_dry_run_history_records_without_incident(
monkeypatch,
) -> None:
appended: list[dict[str, object]] = []
class FakeRecord:
id = "alert-op-1"
class FakeRepo:
async def append(self, event_type: str, **kwargs): # noqa: ANN001
appended.append({"event_type": event_type, **kwargs})
return FakeRecord()
from src.repositories import alert_operation_log_repository
monkeypatch.setattr(
alert_operation_log_repository,
"get_alert_operation_log_repository",
lambda: FakeRepo(),
)
history = (
await channel_event_dossier_service._record_recurrence_work_item_dry_run_history(
{
"source": "channel_event_dossier.recurrence",
"project_id": "awoooi",
"work_item_id": (
"source-evidence:sentry:upstream_canary:"
"awoooi-canary-codex-t115-production"
),
"incident_id": None,
"auto_repair_id": None,
"mode": "observe",
"requested_mode": "auto",
"allowed": True,
"executed": True,
"safety_level": "read_only",
"writes_incident_state": False,
"writes_auto_repair_result": False,
"writes_ticket": False,
"verification_result_preview": "observe_only",
"current_state_summary": {
"work_item_kind": "source_correlation_review",
"work_item_next_step": "review_provider_source_match",
"repair_status": "source_correlation_review",
"latest_stage": "upstream_canary",
"latest_provider_event_id": (
"sentry:upstream_canary:"
"awoooi-canary-codex-t115-production"
),
},
"ticket_preview": {"would_create": False},
"read_model_route": {
"agent_id": "awooop_recurrence_coordinator",
"tool_name": "channel_event_dossier.recurrence",
"required_scope": "read",
},
"checks": [],
"next_step": "review_provider_source_match",
}
)
)
assert history == {
"recorded": True,
"alert_operation_id": "alert-op-1",
"timeline_event_id": None,
"timeline_reason": "source_review_not_incident_scoped",
}
assert appended[0]["event_type"] == "PRE_FLIGHT_PASSED"
assert appended[0]["incident_id"] is None
assert appended[0]["actor"] == "awooop_recurrence_work_item_service"
assert appended[0]["context"]["work_item_id"].startswith("source-evidence:")
def test_build_recurrence_work_item_handoff_records_ticket_proposal_contract() -> None:
recurrence = build_dossier_recurrence(
[