一键导入
alert-rca
Read-only root cause analysis for homelab alerts. Investigate, diagnose, and optionally open a signed PR to fix config issues in nixosconfig.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Read-only root cause analysis for homelab alerts. Investigate, diagnose, and optionally open a signed PR to fix config issues in nixosconfig.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Create, search, comment on, and manage issues in the canonical nixosconfig Forgejo tracker via its REST API.
Manage pfSense firewall - rules, NAT, VPN, DHCP, DNS, and system configuration
Spin up and manage Apollo/Sunshine gaming Windows VMs on the prom hypervisor — clones of the GTX-1080-passthrough golden template, one per game, streamed via Moonlight/Artemis. Use when the user wants a new gaming VM, another gaming VM, a VM "for <game>", or to start/switch/stop/list/destroy their gaming VMs. Single GPU = one runs at a time. Trigger phrases include "new gaming vm", "spin up a gaming vm", "gaming vm for <game>", "make me a windows gaming vm", "another gaming machine", "start the <game> vm", "switch to <game>", "list gaming vms", "stop the gaming vm", "destroy the <game> vm".
Add an MCP server to the project and sync to all AI tools
Detect configuration drift using hash-based verification.
Debug a NixOS service that is down, unhealthy, or misbehaving. Identifies which host runs the service, connects via SSH if remote, and investigates using journalctl. Trigger phrases include "debug X", "X is down", "why is X broken", "check X service", "X not working", "investigate X".
| name | alert-rca |
| description | Read-only root cause analysis for homelab alerts. Investigate, diagnose, and optionally open a signed PR to fix config issues in nixosconfig. |
| version | 1.0.0 |
| metadata | {"hermes":{"tags":["homelab","alerting","rca","nixosconfig","pr"]}} |
Triggered by an alert forwarded from the alert-bridge (doc2). The alert payload contains enriched context: alert name, severity, Loki log lines, and/or journalctl output from the failing service.
The webhook delivers either a single enriched alert or a 10-minute RCA batch. For batches, treat the whole batch as one incident unless the alert list clearly contains unrelated failures. Key fields:
title — alert title or batch title (e.g. "Alert batch: 50 alerts in 10m")message — enriched body with Loki lines / journal output, or a batch body
containing multiple --- alert N/M ... sectionspriority — max/representative priority for the batchalertname, severity — for Grafana alertsmonitor.name, monitor.url, heartbeat.msg — for Kuma alertsExtract the hostnames, service names, and repeated error signatures from the message. For a batch, look for the common root first: shared host, shared network path, shared storage, shared upstream, recent deploy, or one root alert followed by many dependent symptom alerts.
Loki is at https://loki.ablz.au (no auth, reachable fleet-wide).
curl -s -G "https://loki.ablz.au/loki/api/v1/query_range" \
--data-urlencode "query=<logql>" \
--data-urlencode "start=$(date -d '30 min ago' +%s)000000000" \
--data-urlencode "end=$(date +%s)000000000" \
--data-urlencode "limit=20" \
--data-urlencode "direction=backward" | python3 -m json.tool
Useful LogQL patterns:
{hostname="doc2"} |= "error" — error logs for a host{unit="podman-foo.service"} — specific systemd unit{host="prom"} |= "oom" — OOM messages on a Proxmox hostSSH is available to all fleet hosts from doc1. Use READ-ONLY commands only:
journalctl -u <unit> --since "30 min ago" -n 50systemctl status <unit>systemctl list-units --faileddocker logs <container> --tail 50 (on doc2 via SSH)zpool status (on doc2 for ZFS issues)df -h, free -h, uptimeNEVER run: systemctl restart, nixos-rebuild, docker restart, rm, write to config files, or anything that changes system state. This is READ-ONLY.
The nixosconfig repo is at /home/abl030/nixosconfig. Search for the service config, look at recent commits, check if a config change caused the alert:
grep -r <service> modules/nixos/services/git log --oneline -20 -- <relevant file>git diff HEAD~5 -- <relevant file> (recent changes)Classify the alert:
If the root cause is a fixable nixosconfig issue:
cd /home/abl030/nixosconfig
git fetch origin
git checkout -b fix/<short-description> origin/master
Edit the relevant .nix file(s). Keep changes minimal and focused on the root cause. Do not refactor or touch unrelated code.
nix-instantiate --parse <file> (basic parse check)nixos-rebuild dry-build --flake .#<hostname> (read-only, no switch)doc1 signs automatically (gpg.format=ssh, commit.gpgsign=true). Verify:
git add <file>
git commit -m "fix: <short description of the fix>"
git log -1 --format=%G? # must print 'G'
export GIT_CONFIG_COUNT=1 \
GIT_CONFIG_KEY_0="http.https://git.ablz.au.extraHeader" \
GIT_CONFIG_VALUE_0="Authorization: token $(cat /run/secrets/forgejo/nixbot-token)"
git push origin fix/<short-description>
curl -s -X POST "https://git.ablz.au/api/v1/repos/abl030/nixosconfig/pulls" \
-H "Authorization: token $(cat /run/secrets/forgejo/nixbot-token)" \
-H "Content-Type: application/json" \
-d "$(python3 -c "
import json
print(json.dumps({
'title': 'fix: <short description>',
'head': 'fix/<short-description>',
'base': 'master',
'body': '## Root Cause\n\n<explanation>\n\n## Alert\n\n<link to original alert>\n\n## Fix\n\n<what was changed and why>\n\nAuto-generated by alert-rca skill.',
}))
")"
Extract html_url from the response — this goes in the Gotify message.
After investigation (with or without a PR), push the RCA summary to Gotify. The Gotify token is at /run/secrets/gotify/token (format: GOTIFY_TOKEN=xxx).
TOKEN=$(grep GOTIFY_TOKEN /run/secrets/gotify/token | cut -d= -f2)
curl -s -X POST "http://192.168.1.35:8050/message?token=$TOKEN" \
-d "title=RCA: <alertname>" \
-d "message=<summary>" \
-d "priority=5"
If a PR was opened:
RCA: <alertname>
Root cause: <one-liner>
Classification: config issue
Fix: <one-liner description>
PR: <html_url>
If no fix needed:
RCA: <alertname>
Root cause: <one-liner>
Classification: transient/external/hardware
Action: <what was happening, why it self-healed or what manual step is needed>
No PR needed.
Keep it phone-readable. Max ~500 chars. The alert-bridge already sent the raw alert; this is the analysis that replaces "what do I do about this?"
Be efficient. Most RCAs should complete in 5-15 tool calls:
If after 10 tool calls you don't have a clear root cause, summarize what you found and push that to Gotify. Don't burn tokens spiraling.