fix(agent99): verify telegram alert classification

This commit is contained in:
ogt
2026-07-10 11:01:19 +08:00
parent 23c1cda688
commit e2063ad84d
2 changed files with 141 additions and 2 deletions

View File

@@ -464,6 +464,14 @@ Recovery is complete only when all of the following are captured:
- Visual card: `C:\Wooo\Agent99\evidence\telegram-cards\agent99-card-performance_warning-20260710-105440.png`.
- Result: `ok=True`, `visualExists=True`, `sentTelegram=False`, `messageFormat=incident_card_v2`.
- Local visual inspection: PNG is `1040x620`, non-blank, formatted as an incident card.
- 2026-07-10 11:00 Telegram inbox classifier verifier:
- Runtime script deployed: `C:\Wooo\Agent99\bin\agent99-telegram-inbox.ps1`.
- Backup before deploy: `C:\Wooo\Agent99\bin\agent99-telegram-inbox.ps1.bak-20260710-110003`.
- Parser readback: `parse_ok`.
- Self-test evidence: `C:\Wooo\Agent99\evidence\agent99-TelegramInboxSelfTest-20260710-110004.json`.
- Result: `ok=True`, `caseCount=8`, `passedCount=8`, `failedCount=0`, `wroteAlerts=False`, `sentTelegram=False`.
- Covered inputs: Agent99 echo suppression, provider freshness, host performance readback failure, backup health, Bitan AI config missing key, IWOOOS/Wazuh/SIEM security, Gitea repository missing, and public 502.
- Severity correction: `readback_failed`, `missing_key`, locale guard, and AI support config failures stay `warning`; true `critical`, `P0`, `emergency`, `fatal`, or `down` signals remain `critical`.
## Agent99 Monitoring Alert Routing Self-Test Receipt

View File

@@ -1,6 +1,7 @@
param(
[string]$AgentRoot = "C:\Wooo\Agent99",
[switch]$RunNow,
[switch]$SelfTest,
[string]$SyntheticUpdateText = "",
[string]$SyntheticChatTitle = "AwoooI SRE",
[string]$SyntheticChatId = ""
@@ -251,8 +252,9 @@ function Get-AgentTelegramAlertSeverity {
param([string]$Text)
$lower = $Text.ToLowerInvariant()
if ($lower -match "resolved|recovered" -or (Test-AgentTextContainsCode $Text @(0x6062, 0x89E3))) { return "resolved" }
if ($lower -match "critical|p0|emergency|fatal|down|failed" -or (Test-AgentTextContainsCode $Text @(0x56B4, 0x91CD, 0x7DCA, 0x6025))) { return "critical" }
if ($lower -match "warning|warn|degraded" -or (Test-AgentTextContainsCode $Text @(0x544A, 0x8B66, 0x7570, 0x5E38))) { return "warning" }
if ($lower -match "critical|p0|emergency|fatal|down" -or (Test-AgentTextContainsCode $Text @(0x56B4, 0x91CD, 0x7DCA, 0x6025))) { return "critical" }
if ($lower -match "warning|warn|degraded|readback_failed|missing_key|locale guard|ai support" -or (Test-AgentTextContainsCode $Text @(0x544A, 0x8B66, 0x7570, 0x5E38))) { return "warning" }
if ($lower -match "failed") { return "critical" }
return "warning"
}
@@ -361,6 +363,131 @@ function New-AgentMonitoringAlertFromTelegram {
}
}
function Invoke-AgentTelegramInboxSelfTest {
$selfStamp = Get-Date -Format "yyyyMMdd-HHmmss"
$selfTestPath = Join-Path $EvidenceDir "agent99-TelegramInboxSelfTest-$selfStamp.json"
$cases = @(
[pscustomobject]@{
name = "agent99 echo ignored"
text = "Agent99 Alert: WARNING`nEvent: host performance"
expectedMonitoring = $false
expectedSeverity = $null
expectedKind = $null
expectedService = $null
expectedHost = ""
},
[pscustomobject]@{
name = "provider freshness"
text = "provider_freshness_signal source_provider_freshness_triage raw_signal_normalized controlled_runtime_candidate lastSeen missing"
expectedMonitoring = $true
expectedSeverity = "warning"
expectedKind = "provider_freshness_signal"
expectedService = "unknown"
expectedHost = ""
},
[pscustomobject]@{
name = "host perf readback failed"
text = "Agent99 host performance warning Host: 192.168.0.110 Reason: perf_readback_failed Current: load/core= memAvail= disk="
expectedMonitoring = $true
expectedSeverity = "warning"
expectedKind = "performance_cpu"
expectedService = "agent99"
expectedHost = "192.168.0.110"
},
[pscustomobject]@{
name = "backup health"
text = "backup health warning restore_drill_status backup_file_readback_failed snapshot metadata only"
expectedMonitoring = $true
expectedSeverity = "warning"
expectedKind = "backup_health"
expectedService = "unknown"
expectedHost = ""
},
[pscustomobject]@{
name = "bitan ai config"
text = "bitan ai support locale guard failed E_AI_MISSING_KEY missing_key /api/customer-support/chat"
expectedMonitoring = $true
expectedSeverity = "warning"
expectedKind = "application_ai_config_error"
expectedService = "bitan-pharmacy"
expectedHost = ""
},
[pscustomobject]@{
name = "security triage"
text = "Wazuh SIEM critical security alert auth_failed brute force suspicious login host 192.168.0.112"
expectedMonitoring = $true
expectedSeverity = "critical"
expectedKind = "wazuh_security_alert"
expectedService = "iwooos-security"
expectedHost = "192.168.0.112"
},
[pscustomobject]@{
name = "gitea repo missing"
text = "critical gitea repository_missing repo_missing production project"
expectedMonitoring = $true
expectedSeverity = "critical"
expectedKind = "repository_missing"
expectedService = "gitea"
expectedHost = ""
},
[pscustomobject]@{
name = "public 502"
text = "critical public route 502 website https://awoooi.wooo.work"
expectedMonitoring = $true
expectedSeverity = "critical"
expectedKind = "public_route_502"
expectedService = "awoooi"
expectedHost = ""
}
)
$results = @()
foreach ($case in $cases) {
$monitoring = Test-AgentMonitoringAlertText $case.text
$severity = if ($monitoring) { Get-AgentTelegramAlertSeverity $case.text } else { $null }
$kind = if ($monitoring) { Get-AgentTelegramAlertKind $case.text } else { $null }
$service = if ($monitoring) { Get-AgentTelegramAlertService $case.text } else { $null }
$hostName = if ($monitoring) { Get-AgentTelegramAlertHost $case.text } else { "" }
$passed = (
$monitoring -eq $case.expectedMonitoring -and
[string]$severity -eq [string]$case.expectedSeverity -and
[string]$kind -eq [string]$case.expectedKind -and
[string]$service -eq [string]$case.expectedService -and
[string]$hostName -eq [string]$case.expectedHost
)
$results += [pscustomobject]@{
name = $case.name
passed = $passed
monitoring = $monitoring
expectedMonitoring = $case.expectedMonitoring
severity = $severity
expectedSeverity = $case.expectedSeverity
kind = $kind
expectedKind = $case.expectedKind
service = $service
expectedService = $case.expectedService
host = $hostName
expectedHost = $case.expectedHost
}
}
$failed = @($results | Where-Object { -not $_.passed })
$summary = [pscustomobject]@{
timestamp = (Get-Date -Format o)
ok = (@($failed).Count -eq 0)
caseCount = @($results).Count
passedCount = @($results | Where-Object { $_.passed }).Count
failedCount = @($failed).Count
wroteAlerts = $false
sentTelegram = $false
results = $results
}
$summary | ConvertTo-Json -Depth 8 | Set-Content -Path $selfTestPath -Encoding UTF8
$summary | ConvertTo-Json -Depth 8
if (-not $summary.ok) { exit 1 }
exit 0
}
$stamp = Get-Date -Format "yyyyMMdd-HHmmss"
$evidencePath = Join-Path $EvidenceDir "agent99-TelegramInbox-$stamp.json"
$offsetPath = Join-Path $StateDir "telegram-inbox-offset.json"
@@ -375,6 +502,10 @@ if ((-not $SyntheticUpdateText) -and (Test-Path $offsetPath)) {
}
$config = Load-AgentConfig
if ($SelfTest) {
Invoke-AgentTelegramInboxSelfTest
}
$autoIngestMonitoringAlerts = $true
if ($config.telegram -and $config.telegram.PSObject.Properties["autoIngestMonitoringAlerts"]) {
$autoIngestMonitoringAlerts = [bool]$config.telegram.autoIngestMonitoringAlerts