fix(agent99): polish recovery incident card

This commit is contained in:
ogt
2026-07-11 21:00:20 +08:00
parent aceedcc202
commit a1f87282ef
2 changed files with 19 additions and 7 deletions

View File

@@ -797,11 +797,11 @@ function Get-AgentIncidentCardModel {
$coordinatorVerified = Convert-AgentBool (Get-AgentObjectValue $Data "coordinatorVerified" $false)
$rebootSloClaimed = Convert-AgentBool (Get-AgentObjectValue $Data "rebootSloClaimed" $false)
$verification = if ($coordinatorVerified) {
if ($rebootSloClaimed) { "協調器與 fresh reboot SLO verifier 均已通過。" } else { "服務協調器已通過;本輪不是 fresh reboot drill不宣稱全主機 SLA。" }
if ($rebootSloClaimed) { "協調器與全主機重啟 SLO verifier 均已通過。" } else { "服務協調器已通過;本輪不是新的全主機重啟演練,不宣稱 10 分鐘 SLA。" }
} else {
"協調器尚未通過,事件保持開啟。"
}
$action = if ($completed) { "完成獨立驗證並寫回 incident/KM receipt" } else { "持續處理失敗 phase維持 maintenance fallback" }
$action = if ($completed) { "完成獨立驗證並寫入事件與知識紀錄" } else { "持續處理失敗階段,維持系統維護頁" }
$phases = if ($Data -and $Data.PSObject.Properties["phases"]) { @($Data.phases) } else { @() }
$visualKind = "recovery"
} elseif ($EventType -match "^performance_") {
@@ -1172,7 +1172,7 @@ function New-AgentTelegramCardImage {
$graphics.FillRectangle($bgBrush, 0, 0, $width, $height)
$graphics.FillRectangle($panelBrush, 36, 34, $width - 72, $height - 68)
$graphics.FillRectangle($accentBrush, 36, 34, 14, $height - 68)
$graphics.DrawString("Agent99 事故狀態 / INCIDENT STATUS", $titleFont, $textBrush, 72, 54)
$graphics.DrawString("Agent99 事故狀態", $titleFont, $textBrush, 72, 54)
$graphics.DrawString($card.lifecycleLabel, $statusFont, $accentBrush, 72, 96)
$graphics.DrawString(("$($card.severityLabel) | $($card.incidentId) | 發生 $($card.occurrences)"), $labelFont, $mutedBrush, 72, 137)
$graphics.DrawString($card.title, $titleFont, $textBrush, [System.Drawing.RectangleF]::new(72, 176, 1048, 46))
@@ -1244,8 +1244,18 @@ function New-AgentTelegramCardImage {
$phaseIndex += 1
$passed = [bool]([string]$phase.status -eq "ok")
$phaseBrush = if ($passed) { $goodBrush } else { $badBrush }
$phaseLabel = switch ([string]$phase.name) {
"vm_start" { "VMware" }
"host_reachability" { "主機連線" }
"host112_guest_readiness" { "Kali 112" }
"harbor_registry" { "Harbor" }
"k3s_workloads" { "K3s" }
"public_routes" { "公開網站" }
"full_sop_scorecard" { "Full SOP" }
default { Limit-AgentTextLine ([string]$phase.name) 18 }
}
$graphics.FillRectangle($phaseBrush, $x, 620, ($phaseWidth - 10), 12)
$graphics.DrawString((Limit-AgentTextLine ([string]$phase.name) 18), $smallFont, $textBrush, $x, 643)
$graphics.DrawString($phaseLabel, $smallFont, $textBrush, $x, 643)
$graphics.DrawString($(if ($passed) { "PASS" } else { "OPEN" }), $smallFont, $phaseBrush, $x, 668)
}
} else {
@@ -1262,7 +1272,7 @@ function New-AgentTelegramCardImage {
}
$graphics.DrawString(("下一次更新:" + $card.nextUpdate), $smallFont, $mutedBrush, [System.Drawing.RectangleF]::new(72, 698, 850, 30))
$graphics.DrawString((Get-Date -Format "yyyy-MM-dd HH:mm:ss zzz"), $smallFont, $mutedBrush, 930, 704)
$graphics.DrawString((Get-Date -Format "yyyy-MM-dd HH:mm:ss zzz"), $smallFont, $mutedBrush, 860, 704)
$bitmap.Save($imagePath, [System.Drawing.Imaging.ImageFormat]::Png)
$graphics.Dispose()

View File

@@ -51,8 +51,8 @@ def test_agent99_recovery_completion_has_human_lifecycle_receipt() -> None:
assert '$EventType -in @("recovery_slo_result")' in source
assert 'schemaVersion = "agent99_incident_card_v5"' in source
assert '主機與服務已通過恢復驗證' in source
assert '本輪不是 fresh reboot drill不宣稱全主機 SLA' in source
assert 'Agent99 事故狀態 / INCIDENT STATUS' in source
assert '本輪不是新的全主機重啟演練,不宣稱 10 分鐘 SLA' in source
assert 'Agent99 事故狀態' in source
assert '使用者影響' in source
assert 'Agent99 實際動作' in source
assert '獨立驗證' in source
@@ -73,6 +73,8 @@ def test_agent99_telegram_v5_hides_raw_evidence_and_has_operator_fields() -> Non
assert "kmPath" not in formatter
assert "verifierName=" not in formatter
assert 'messageFormat = "incident_card_zh_tw_v5"' in source
for phase_label in ("VMware", "主機連線", "Kali 112", "公開網站", "Full SOP"):
assert f'{{ "{phase_label}" }}' in source
def test_agent99_v5_formatter_synthetic_gate_loads_model_dependencies() -> None: