Claude
Skills
Sign in
Back

verbatim-audit-notify

Included with Lifetime
$97 forever

Send Pushover notifications with UUID-linked verbatim JSONL audit trail. TRIGGERS - pushover notify, send pushover, observability alert, verbatim notification, fleet alert, pushover-lookup, audit log notification, push notification with UUID

Securityscripts

What this skill does


# Pushover Verbatim+UUID Notification

> **Self-Evolving Skill**: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.

A two-script skill that solves the **"Pushover message hit my phone but I don't remember what it was about"** problem for personal automation fleets. Every notification carries a UUID; the full verbatim payload (including everything that didn't fit in Pushover's 1024-char body) lands in a local JSONL audit log keyed by that UUID. You look it up by pasting the UUID back.

**Designed for**: cron-fired scripts, launchd daemons, hook outputs — any place that wants "fire-and-forget alerting with full context if you ever need to dig in." Personal scale; one Mac; one Pushover account. Not a microservices observability stack.

## Why this exists

Pushover messages are limited to 1024 UTF-8 characters in the body and 250 in the title (per [pushover.net/api](https://pushover.net/api)). Real failure events often need thousands of chars of context: stack traces, full env dumps, file paths, the exact failing command. Truncating loses what you actually need to debug.

The fix is the **correlation-ID-plus-JSONL** pattern: short summary on the device, full verbatim payload in a local newline-delimited JSON file, UUID linking them. When a notification fires, the body contains the UUID and a `pushover-lookup` command. Run that and you get the complete entry.

## Five scripts + three launchd templates

| Asset                                            | Role                                                                                            |
| ------------------------------------------------ | ----------------------------------------------------------------------------------------------- |
| `scripts/pushover-notify.sh`                     | Sender: generates UUID, writes verbatim JSONL, dispatches Pushover with summary+UUID            |
| `scripts/pushover-lookup.sh`                     | Retriever: given a UUID (or prefix), prints the pretty-printed JSONL entry                      |
| `scripts/pushover-prune.sh`                      | Retention pruner: deletes audit-YYYYMMDD.jsonl files older than N days (default 30)             |
| `scripts/pushover-quota.sh`                      | Quota monitor: hits Pushover /apps/limits.json, persists JSON, alerts when low (iter 12b)       |
| `scripts/pushover-heartbeat.sh`                  | Daily fleet status summary — companion+kokoro+github-notif+quota+disk+failed services (iter 20) |
| `templates/com.terryli.pushover-prune.plist`     | launchd timer — daily at 04:15, 90-day retention (iter 8)                                       |
| `templates/com.terryli.pushover-quota.plist`     | launchd timer — daily at 03:30, alerts when remaining <20% (iter 12b)                           |
| `templates/com.terryli.pushover-heartbeat.plist` | launchd timer — daily at 09:03, INFO heartbeat (auto-promotes to WARN on failure) (iter 20)     |

Add the scripts to your PATH:

```bash
ln -sf "$HOME/.claude/plugins/marketplaces/cc-skills/plugins/pushover-commander/skills/verbatim-audit-notify/scripts/pushover-notify.sh" ~/.local/bin/pushover-notify
ln -sf "$HOME/.claude/plugins/marketplaces/cc-skills/plugins/pushover-commander/skills/verbatim-audit-notify/scripts/pushover-lookup.sh" ~/.local/bin/pushover-lookup
ln -sf "$HOME/.claude/plugins/marketplaces/cc-skills/plugins/pushover-commander/skills/verbatim-audit-notify/scripts/pushover-prune.sh" ~/.local/bin/pushover-prune
ln -sf "$HOME/.claude/plugins/marketplaces/cc-skills/plugins/pushover-commander/skills/verbatim-audit-notify/scripts/pushover-quota.sh" ~/.local/bin/pushover-quota
ln -sf "$HOME/.claude/plugins/marketplaces/cc-skills/plugins/pushover-commander/skills/verbatim-audit-notify/scripts/pushover-heartbeat.sh" ~/.local/bin/pushover-heartbeat
```

**Verify the symlinks resolve to THIS skill** (iter 13a 2026-05-19 caught the trap where stale symlinks from a legacy pushover-notify in `~/.claude/tools/notifications/` silently masked the new flag-rich script — the legacy didn't understand `--service/--level/--extra`, so dispatches "succeeded" but wrote no JSONL audit and sent malformed Pushover payloads):

```bash
for cmd in pushover-notify pushover-lookup pushover-prune pushover-quota; do
    readlink "$HOME/.local/bin/$cmd" | grep -q "cc-skills/plugins/pushover-commander/skills/verbatim-audit-notify" \
        && echo "✓ $cmd → iter-5 skill" \
        || echo "✗ $cmd → STALE target ($(readlink "$HOME/.local/bin/$cmd" || echo 'not a symlink')) — rerun the ln -sf commands above"
done
```

Then sanity-fire the alert path once to catch any other silent failures:

```bash
pushover-quota --alert-threshold 1.0   # always fires; check phone + audit log
pushover-lookup --recent 2             # confirm WARN + pushover-notify dispatch lines pair up
```

Install the launchd timers (retention + quota monitor — see each template header for tuning):

```bash
# Retention (daily 04:15, 90-day window)
cp "$HOME/.claude/plugins/marketplaces/cc-skills/plugins/pushover-commander/skills/verbatim-audit-notify/templates/com.terryli.pushover-prune.plist" ~/Library/LaunchAgents/
mkdir -p ~/.local/state/launchd-logs/pushover-prune
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.terryli.pushover-prune.plist

# Quota monitor (daily 03:30, alert at <20% remaining)
cp "$HOME/.claude/plugins/marketplaces/cc-skills/plugins/pushover-commander/skills/verbatim-audit-notify/templates/com.terryli.pushover-quota.plist" ~/Library/LaunchAgents/
mkdir -p ~/.local/state/launchd-logs/pushover-quota
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.terryli.pushover-quota.plist

# Daily fleet heartbeat (09:03, INFO; auto-promotes to WARN on failure)
cp "$HOME/.claude/plugins/marketplaces/cc-skills/plugins/pushover-commander/skills/verbatim-audit-notify/templates/com.terryli.pushover-heartbeat.plist" ~/Library/LaunchAgents/
mkdir -p ~/.local/state/launchd-logs/pushover-heartbeat
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.terryli.pushover-heartbeat.plist
```

### Heartbeat sample output (iter 20)

```text
🔔 Fleet daily heartbeat

companion: ok · up 11h 36m · 320MB · audio✓ · bot=watching · tts=ready
kokoro: ok · idle=-1s · queue=0
pushover quota: 611/10000 (6.11%)
disk: launchd-logs=119MB · audit days=1
failed services: com.terryli.maccy-backup=1
```

Auto-promotes from INFO (silent) to WARN when any subsystem is degraded (companion or kokoro not `ok`, OR any `com.terryli.*` launchd service has `last_exit != 0`). The structured `--extra` payload captures every dimension as JSON for forensic lookup via `pushover-lookup`.

## Quick start

### Send a notification

```bash
pushover-notify \
    --title "maccy-backup failure" \
    --message "Maccy DB unreadable for 31 days; backup script needs TCC Full Disk Access" \
    --service maccy-backup \
    --level ERROR \
    --extra '{"db_path":"/Users/terryli/Library/Containers/org.p0deje.Maccy/Data/Library/Application Support/Maccy/Storage.sqlite","last_success":"2026-04-17","days_since":31}'
```

**Optional device targeting + sound override** (iter 14, 2026-05-19) — useful for high-priority events that should land on a specific device with an attention-grabbing sound:

```bash
pushover-notify \
    --title "Telegram rate-limit" \
    --message "Bot blocked for 4900s" \
    --service telegram-bot \
    --target rate-limit \
    --level ERROR \
    --priority 1 \
    --device iphone_13_mini \
    --sound siren
```

`--device <name>` sends only to the named Pushover device (omit to broadcast to all). `--sound <name>` selects the alert tone (`siren`, `magic`, `intermission`, `none`, etc.); the chosen device+sound are also persisted into the JSONL audit entry for forensic completeness.

Output (stdout): the UUID, e.g.

```
3f8c2d9e-4a1b-4c5d-8e7f-1a2b3c4d5e6f
```

Your phone receives:

``

Related in Security