feat(governance): auto-deprecate low-trust unused playbooks (>30d)
trust_drift previously fired alerts forever for playbooks stuck below the 0.2 threshold. With user authorization for governance-class auto-fixes, check_trust_drift now retires playbooks that have been unused for 30+ days (or never used and created 30+ days ago) by flipping status to 'deprecated' before alerting. Alerts now report drifted_count, auto_deprecated_count, and the kept playbook_ids that still need human review (those in their 30d trial window). Existing alert noise from the four currently-drifted playbooks should drop to whatever fraction is genuinely in trial. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,10 @@ logger = structlog.get_logger(__name__)
|
||||
# 閾值常數
|
||||
# =============================================================================
|
||||
TRUST_DRIFT_THRESHOLD = 0.2 # playbook trust_score 低於此值 → 告警
|
||||
# 2026-05-02 ogt + Claude Sonnet 4.6: trust_drift auto-deprecate
|
||||
# trust < 0.2 + (last_used > N 天前 OR 從沒用過 + 創建超過 N 天) → 自動 deprecate
|
||||
# 這個 N 設 30 天,給 playbook 充足試用期,避免新提案被早期幾次失敗就廢棄
|
||||
TRUST_DRIFT_AUTO_DEPRECATE_AFTER_DAYS = 30
|
||||
KM_STALE_DAYS = 7 # 知識條目超過幾天未更新視為陳舊
|
||||
KM_STALE_RATIO = 0.20 # 陳舊比例超過此值 → 告警
|
||||
HALLUCINATION_RATE_THRESHOLD = 0.10 # LLM verification failed 比例超過此值 → 告警
|
||||
@@ -69,9 +73,12 @@ class GovernanceAgent:
|
||||
# =========================================================================
|
||||
|
||||
async def check_trust_drift(self) -> dict[str, Any]:
|
||||
"""Playbook trust_score < 0.2 → 告警建議廢棄
|
||||
"""Playbook trust_score < 0.2 → 告警建議廢棄;30 天沒用過的直接 auto-deprecate
|
||||
|
||||
2026-04-26 P2.2 by Claude
|
||||
2026-05-02 ogt + Claude Sonnet 4.6: 加 auto_deprecate_low_trust_unused 自治路徑
|
||||
守衛條件:trust < 0.2 AND (last_used_at < 30 天前 OR 從未使用且創建超過 30 天)
|
||||
→ status 改 'deprecated',alert 改報「N 個告警 + M 個 auto-deprecated」
|
||||
"""
|
||||
async with get_db_context() as db:
|
||||
result = await db.execute(
|
||||
@@ -81,9 +88,31 @@ class GovernanceAgent:
|
||||
)
|
||||
all_records = result.scalars().all()
|
||||
|
||||
total = len(all_records)
|
||||
drifted = [r for r in all_records if float(r.trust_score) < TRUST_DRIFT_THRESHOLD]
|
||||
drifted_ids = [r.playbook_id for r in drifted[:10]]
|
||||
total = len(all_records)
|
||||
drifted = [r for r in all_records if float(r.trust_score) < TRUST_DRIFT_THRESHOLD]
|
||||
|
||||
# auto-deprecate eligibility
|
||||
cutoff = now_taipei() - timedelta(days=TRUST_DRIFT_AUTO_DEPRECATE_AFTER_DAYS)
|
||||
auto_deprecated_ids: list[str] = []
|
||||
kept_ids: list[str] = []
|
||||
for r in drifted:
|
||||
last = r.last_used_at
|
||||
created = r.created_at
|
||||
# 沒用過 → 用 created_at 作為「進入系統時間」
|
||||
ref_time = last if last is not None else created
|
||||
if ref_time is not None and ref_time < cutoff:
|
||||
r.status = "deprecated"
|
||||
auto_deprecated_ids.append(r.playbook_id)
|
||||
else:
|
||||
kept_ids.append(r.playbook_id)
|
||||
|
||||
if auto_deprecated_ids:
|
||||
await db.commit()
|
||||
logger.info(
|
||||
"governance_trust_drift_auto_deprecated",
|
||||
count=len(auto_deprecated_ids),
|
||||
ids=auto_deprecated_ids[:10],
|
||||
)
|
||||
|
||||
if drifted:
|
||||
await self._alert(
|
||||
@@ -91,8 +120,11 @@ class GovernanceAgent:
|
||||
{
|
||||
"drifted_count": len(drifted),
|
||||
"total_playbooks": total,
|
||||
"playbook_ids": drifted_ids,
|
||||
"playbook_ids": kept_ids[:10],
|
||||
"auto_deprecated_count": len(auto_deprecated_ids),
|
||||
"auto_deprecated_ids": auto_deprecated_ids[:10],
|
||||
"threshold": TRUST_DRIFT_THRESHOLD,
|
||||
"auto_deprecate_after_days": TRUST_DRIFT_AUTO_DEPRECATE_AFTER_DAYS,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -100,8 +132,15 @@ class GovernanceAgent:
|
||||
"governance_trust_drift_checked",
|
||||
total=total,
|
||||
drifted=len(drifted),
|
||||
auto_deprecated=len(auto_deprecated_ids),
|
||||
kept=len(kept_ids),
|
||||
)
|
||||
return {"checked": total, "drifted": len(drifted)}
|
||||
return {
|
||||
"checked": total,
|
||||
"drifted": len(drifted),
|
||||
"auto_deprecated": len(auto_deprecated_ids),
|
||||
"kept": len(kept_ids),
|
||||
}
|
||||
|
||||
# =========================================================================
|
||||
# 2. 知識庫衰退
|
||||
|
||||
Reference in New Issue
Block a user