fix(awooop): fail soft drift fingerprint readback
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Failing after 2m3s
CD Pipeline / build-and-deploy (push) Has been skipped
CD Pipeline / post-deploy-checks (push) Has been skipped
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Failing after 2m3s
CD Pipeline / build-and-deploy (push) Has been skipped
CD Pipeline / post-deploy-checks (push) Has been skipped
This commit is contained in:
@@ -15,6 +15,7 @@ leWOOOgo 積木化原則:
|
||||
|
||||
from typing import Literal
|
||||
|
||||
import structlog
|
||||
from fastapi import APIRouter, BackgroundTasks, HTTPException
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
@@ -32,6 +33,7 @@ from src.services.drift_analyzer import get_drift_analyzer
|
||||
from src.services.drift_detector import get_drift_detector
|
||||
from src.services.drift_fingerprint_state_service import (
|
||||
DriftFingerprintStateNotFoundError,
|
||||
build_drift_fingerprint_unavailable_state,
|
||||
get_drift_fingerprint_state_service,
|
||||
)
|
||||
from src.services.drift_interpreter import get_drift_interpreter
|
||||
@@ -39,6 +41,7 @@ from src.services.drift_remediator import get_drift_remediator
|
||||
from src.utils.timezone import now_taipei
|
||||
|
||||
router = APIRouter(prefix="/drift", tags=["drift"])
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
# 2026-04-09 Claude Sonnet 4.6: B4 drift_reports 持久化 — 改用 DB repository
|
||||
|
||||
@@ -157,6 +160,18 @@ async def get_drift_fingerprint_state(
|
||||
return await svc.get_state(report_id=report_id, namespace=namespace)
|
||||
except DriftFingerprintStateNotFoundError as exc:
|
||||
raise HTTPException(status_code=404, detail="drift_report_not_found") from exc
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
"drift_fingerprint_state_readback_degraded",
|
||||
report_id=report_id,
|
||||
namespace=namespace,
|
||||
error_type=type(exc).__name__,
|
||||
)
|
||||
return build_drift_fingerprint_unavailable_state(
|
||||
namespace=namespace,
|
||||
report_id=report_id,
|
||||
reason="internal_readback_error",
|
||||
)
|
||||
|
||||
|
||||
@router.post("/fingerprints/handoff", summary="記錄 Config Drift fingerprint 交接")
|
||||
|
||||
@@ -233,6 +233,67 @@ def build_drift_fingerprint_state(
|
||||
}
|
||||
|
||||
|
||||
def build_drift_fingerprint_unavailable_state(
|
||||
*,
|
||||
namespace: str | None = None,
|
||||
report_id: str | None = None,
|
||||
reason: str = "readback_exception",
|
||||
) -> dict[str, Any]:
|
||||
"""Build a no-write degraded payload when the read model cannot load."""
|
||||
|
||||
selected_namespace = namespace or DEFAULT_NAMESPACE
|
||||
return {
|
||||
"schema_version": SCHEMA_VERSION,
|
||||
"namespace": selected_namespace,
|
||||
"fingerprint": None,
|
||||
"latest_report_id": report_id,
|
||||
"latest_status": "readback_unavailable",
|
||||
"latest_scanned_at": None,
|
||||
"latest_created_at": None,
|
||||
"summary": "Drift fingerprint readback unavailable; AI controlled retry required",
|
||||
"high_count": 0,
|
||||
"medium_count": 0,
|
||||
"info_count": 0,
|
||||
"interpretation": None,
|
||||
"repeat_state": {
|
||||
"fingerprint": None,
|
||||
"occurrences_12h": 0,
|
||||
"matching_strategy": "readback_degraded_fallback_v1",
|
||||
},
|
||||
"occurrences_12h": 0,
|
||||
"matching_strategy": "readback_degraded_fallback_v1",
|
||||
"operator_stage": "readback_degraded_ai_controlled_repair",
|
||||
"fsm_state": "pending_human",
|
||||
"next_step": "manual_investigation_or_ansible_check_mode",
|
||||
"open_pr": None,
|
||||
"latest_handoff": None,
|
||||
"latest_remediation": None,
|
||||
"strict_fingerprint": None,
|
||||
"p0_escalation": {
|
||||
"suppresses_repeated_p0": False,
|
||||
"dedup_key_strategy": "readback_degraded_no_fingerprint",
|
||||
"dedup_window_hours": 24,
|
||||
},
|
||||
"read_model_route": {
|
||||
"agent_id": "openclaw",
|
||||
"tool_name": "drift_fingerprint_state",
|
||||
"required_scope": "read:drift read:gitea",
|
||||
"flywheel_node": (
|
||||
"drift_scanned>ai_analyzed>fingerprint_fsm>"
|
||||
"ai_controlled_readback_repair"
|
||||
),
|
||||
},
|
||||
"readback_status": "degraded",
|
||||
"readback_error": reason,
|
||||
"writes_incident_state": False,
|
||||
"writes_auto_repair_result": False,
|
||||
"writes_drift_status": False,
|
||||
"writes_ticket": False,
|
||||
"writes_remediation_record": False,
|
||||
"creates_external_ticket": False,
|
||||
}
|
||||
|
||||
|
||||
def _handoff_context(
|
||||
state: dict[str, Any],
|
||||
*,
|
||||
|
||||
Reference in New Issue
Block a user