fix(sre): type backup learning as read-only
This commit is contained in:
@@ -300,6 +300,60 @@ def _playbook_id(identity: Agent99DispatchIdentity) -> str:
|
||||
return f"PB-A99-{digest}"
|
||||
|
||||
|
||||
def _learning_profile(
|
||||
identity: Agent99DispatchIdentity,
|
||||
*,
|
||||
mode: str,
|
||||
) -> dict[str, Any]:
|
||||
if "backup_health" in identity.route_id:
|
||||
return {
|
||||
"description": (
|
||||
"Verified Agent99 read-only BackupCheck with independent DR "
|
||||
"evidence readback; no backup or restore write was performed."
|
||||
),
|
||||
"affected_services": ["backup_restore"],
|
||||
"keywords": [
|
||||
"agent99", "backup", "restore", "escrow", "offsite", mode,
|
||||
],
|
||||
"action_type": "agent99_readonly_check",
|
||||
"expected_result": "independent backup/DR verifier passes",
|
||||
"rollback_command": "not_applicable_no_write",
|
||||
"tags": ["agent99", "controlled_dispatch", "backup_restore"],
|
||||
"notes": (
|
||||
"Backup/restore/delete/retention/escrow writes and raw secret "
|
||||
"values are not permitted or persisted."
|
||||
),
|
||||
"km_title": f"Agent99 verified backup readback {identity.incident_id}",
|
||||
"km_content": (
|
||||
f"Run {identity.run_id} on route {identity.route_id} completed "
|
||||
f"read-only Agent99 {mode or 'BackupCheck'} with independent "
|
||||
"backup/DR verifier success. No backup, restore, delete, "
|
||||
"retention or escrow write was performed; LLM had no runtime authority."
|
||||
),
|
||||
"km_category": "資料保護/DR Scorecard",
|
||||
}
|
||||
return {
|
||||
"description": (
|
||||
"Verified Agent99 controlled route with independent outcome "
|
||||
"readback and same-run learning receipts."
|
||||
),
|
||||
"affected_services": ["cold-start-gate"],
|
||||
"keywords": ["agent99", "cold-start", mode],
|
||||
"action_type": "agent99_mode",
|
||||
"expected_result": "independent verifier passes",
|
||||
"rollback_command": "Agent99 Status (no-write)",
|
||||
"tags": ["agent99", "controlled_dispatch"],
|
||||
"notes": "No raw logs or secret values are persisted.",
|
||||
"km_title": f"Agent99 verified recovery {identity.incident_id}",
|
||||
"km_content": (
|
||||
f"Run {identity.run_id} on route {identity.route_id} completed "
|
||||
f"Agent99 mode {mode or 'Status'} with independent verifier success. "
|
||||
"Raw logs and secret values are not stored."
|
||||
),
|
||||
"km_category": "AI自動化/Agent99受控修復",
|
||||
}
|
||||
|
||||
|
||||
async def _ensure_playbook_trust(
|
||||
identity: Agent99DispatchIdentity,
|
||||
*,
|
||||
@@ -307,6 +361,7 @@ async def _ensure_playbook_trust(
|
||||
) -> str | None:
|
||||
playbook_id = _playbook_id(identity)
|
||||
run_tag = f"agent99_run:{identity.run_id}"
|
||||
profile = _learning_profile(identity, mode=mode)
|
||||
now = now_taipei()
|
||||
try:
|
||||
async with get_db_context(identity.project_id) as db:
|
||||
@@ -324,25 +379,22 @@ async def _ensure_playbook_trust(
|
||||
playbook_id=playbook_id,
|
||||
project_id=identity.project_id,
|
||||
name=f"Agent99 {mode or 'Status'}: {identity.route_id}",
|
||||
description=(
|
||||
"Verified Agent99 controlled route with independent "
|
||||
"outcome readback and same-run learning receipts."
|
||||
),
|
||||
description=profile["description"],
|
||||
status="approved",
|
||||
source="ai_extracted",
|
||||
symptom_pattern={
|
||||
"alert_names": [],
|
||||
"affected_services": ["cold-start-gate"],
|
||||
"affected_services": profile["affected_services"],
|
||||
"severity_range": ["P0", "P1", "P2"],
|
||||
"label_patterns": {},
|
||||
"keywords": ["agent99", "cold-start", mode],
|
||||
"keywords": profile["keywords"],
|
||||
},
|
||||
repair_steps=[{
|
||||
"step_number": 1,
|
||||
"action_type": "agent99_mode",
|
||||
"action_type": profile["action_type"],
|
||||
"command": mode,
|
||||
"expected_result": "independent verifier passes",
|
||||
"rollback_command": "Agent99 Status (no-write)",
|
||||
"expected_result": profile["expected_result"],
|
||||
"rollback_command": profile["rollback_command"],
|
||||
"requires_approval": False,
|
||||
"risk_level": "LOW",
|
||||
}],
|
||||
@@ -356,8 +408,8 @@ async def _ensure_playbook_trust(
|
||||
trust_score=0.37,
|
||||
approved_by="agent99_independent_verifier",
|
||||
approved_at=now,
|
||||
tags=["agent99", "controlled_dispatch", run_tag],
|
||||
notes="No raw logs or secret values are persisted.",
|
||||
tags=[*profile["tags"], run_tag],
|
||||
notes=profile["notes"],
|
||||
requires_approval_level="auto",
|
||||
stateful_targets=[],
|
||||
requires_pre_backup=False,
|
||||
@@ -401,20 +453,16 @@ async def _ensure_km_writeback(
|
||||
mode: str,
|
||||
) -> str | None:
|
||||
knowledge = get_knowledge_service()
|
||||
profile = _learning_profile(identity, mode=mode)
|
||||
try:
|
||||
entry = await knowledge.create_entry(
|
||||
KnowledgeEntryCreate(
|
||||
title=f"Agent99 verified recovery {identity.incident_id}",
|
||||
content=(
|
||||
f"Run {identity.run_id} on route {identity.route_id} "
|
||||
f"completed Agent99 mode {mode or 'Status'} with independent "
|
||||
"verifier success. Raw logs and secret values are not stored."
|
||||
),
|
||||
title=profile["km_title"],
|
||||
content=profile["km_content"],
|
||||
entry_type=EntryType.INCIDENT_CASE,
|
||||
category="AI自動化/Agent99受控修復",
|
||||
category=profile["km_category"],
|
||||
tags=[
|
||||
"agent99",
|
||||
"controlled_dispatch",
|
||||
*profile["tags"],
|
||||
f"automation_run_id:{identity.run_id}",
|
||||
],
|
||||
source=EntrySource.AI_EXTRACTED,
|
||||
|
||||
Reference in New Issue
Block a user