Create, debug, and update triage automation
Security
notification-triage
Try itClassify, score, prioritize, and batch notifications. ⚠️ Auto-creates persistent per-source rules on first classification (a single misclassification persist...
What it does
Classify, score, prioritize, and batch notifications. ⚠️ Auto-creates persistent per-source rules on first classification (a single misclassification persists forever). Ignored notifications are silently dropped but logged to dropped.json. Digest clears digest.json, not batch.json. Destructive ops require --force. All writes are atomic (no corruption on crash).
The skill document
Notification Triage ⚡
Stop every notification from flooding your chat. Start filtering what matters.
The Problem
Every notification goes to the chat — email, calendar, social, system alerts. No filtering, no prioritization, no batching. The agent drowns in noise.
Notification Triage fixes this with one tool.
⚠️ Critical Warnings — Read Before Use
1. Auto-Rule Creation Is Permanent
On the first classification of a new source, a rule is auto-created and persisted to memory/notification-triage/rules.json. A single misclassification (e.g., classifying a security alert as ignore) permanently affects all future notifications from that source. There is no expiry or auto-correction.
Mitigation:
- Use
--classify --forceto test-classify without persisting a rule - Review rules regularly with
--rules - Remove bad auto-rules with
--rules remove - Wipe all rules with
--rules clear
2. Silently-Dropped Notifications
Notifications classified as ignore are silently dropped — never queued, batched, or reported. They are logged to dropped.json (capped at 1000 entries, oldest dropped first on overflow) for audit, but the agent does not see them at runtime. Misconfigured rules can cause important messages to be missed without any alert.
Mitigation: Review dropped.json regularly. Any source in rules.json at ignore level should be re-evaluated periodically.
3. Destructive Operations Require --force
The following operations are silently destructive — they mutate or clear state without confirmation. To prevent accidental data loss, they require the --force flag:
| Operation | Effect | Force Required? |
|---|---|---|
--send with no count | Flushes ALL pending batched notifications | Use --send N to limit; or accept that flush marks all as seen |
--seen --all | Marks every batched notification as seen | No |
--digest | Clears the digest.json store (capped at 1000 entries) | No |
--rules clear | Wipes every per-source rule | No |
--classify for a new source | Auto-persists a new rule forever | Use --force to suppress auto-rule persistence |
--send (with or without count) is not gated because flushing pending notifications is the core feature. The destructive read of --digest is also not gated because the digest store is only populated by manual calls and never auto-written.
4. Disk Persistence & Hard Caps
rules.json— per-source classification rules (no cap, manually managed)seen.json— seen notification tracking (auto-pruned bymarkSeen/markAllSeen)batch.json— pending notification queue (capped at 5000 entries; oldest dropped first on overflow)dropped.json— silently-dropped notifications (capped at 1000 entries)digest.json— digest store (capped at 1000 entries)
All JSON writes are atomic (temp + rename) — a crash mid-write cannot corrupt the state files. Clear state by deleting files under memory/notification-triage/.
5. Digest vs. Batch — They're Separate
--digest clears the digest.json store. It does NOT clear the batch.json queue. To clear the batch queue, flush with --send (all pending) or mark items as seen individually.
Quick Start
Classify a notification
node skills/notification-triage/notification-triage.js --classify "Security alert: unusual login detected" email
Classifies by urgency (urgent/batch/ignore) based on keywords and source rules. Auto-persists a rule for the email source on first run.
Test-classify without persisting a rule
node skills/notification-triage/notification-triage.js --classify "test message" test-source --force
Classification is computed and reported, but no rule is written to rules.json.
Check pending notifications
node skills/notification-triage/notification-triage.js --batch
Shows all pending notifications grouped by urgency level.
Flush batched notifications
node skills/notification-triage/notification-triage.js --send 10
Outputs the next 10 pending notifications (marks them as seen).
Manage rules
# List rules
node skills/notification-triage/notification-triage.js --rules
# Add rule: email = urgent, social = batch
node skills/notification-triage/notification-triage.js --rules add email urgent
node skills/notification-triage/notification-triage.js --rules add twitter batch
# Remove rule
node skills/notification-triage/notification-triage.js --rules remove facebook
# Wipe all rules
node skills/notification-triage/notification-triage.js --rules clear
Status
node skills/notification-triage/notification-triage.js
Shows pending count, total processed, rules configured, seen count, and the hard caps.
Generate a digest
# Daily digest (default)
node skills/notification-triage/notification-triage.js --digest
# Weekly digest
node skills/notification-triage/notification-triage.js --digest weekly
Compiles the digest store into a formatted summary grouped by source, then clears digest.json. The batch.json queue is NOT affected.
Override data directory
node skills/notification-triage/notification-triage.js --dir /tmp/triage-test --status
Or via env: NOTIFY_TRIAGE_DIR=/tmp/triage-test node skills/notification-triage/notification-triage.js --status
How It Works
Classification
- Check source rules first — if you have a rule for this source, use it
- Keyword analysis — urgent keywords (security, error, deadline) → urgent, batch keywords (update, summary, reminder) → batch
- Time sensitivity — "today", "immediately", "deadline" boost urgency
- Default to batch — if no clear signal, batch for later
- Persist a rule for the source (unless
--forceis set)
Batching
- Ignored notifications are silently dropped (logged to
dropped.json) - Batch notifications are queued in
batch.json(capped at 5000 entries) - Urgent notifications are always available immediately
- All notifications are tracked for seen/seen count
Per-Source Rules
| Level | Behavior |
|---|---|
urgent | Always available immediately |
batch | Queued in batch.json until flushed |
ignore | Silently dropped (logged to dropped.json) |
Hard Caps (oldest dropped first on overflow)
| File | Cap | Behavior on overflow |
|---|---|---|
batch.json | 5000 entries | Drop seen first, then oldest unseen |
dropped.json | 1000 entries | Drop oldest |
digest.json | 1000 entries | Drop oldest |
Heartbeat Integration
Add to your HEARTBEAT.md:
### 💬 Notification Triage
- Run `node skills/notification-triage/notification-triage.js --batch` to check pending
- Run `node skills/notification-triage/notification-triage.js --send 5` to flush 5 notifications
- Only reach out if urgent notifications are pending
Agent Protocol
When notifications arrive:
- Test-classify first (if uncertain about the source):
--classify --force - Classify for real (auto-persists rule):
--classify - Check urgency: If urgent, alert immediately
- If batch: Queue silently, flush during heartbeat
- If ignore: Drop silently (logged to
dropped.json) - During heartbeat: Flush batched items, only alert if urgent pending
- Periodically: Review
rules.jsonfor misclassifications, reviewdropped.jsonfor missed critical messages
Configuration
No config needed. Rules are stored in memory/notification-triage/rules.json.
Override data directory:
--dir /path/to/data
# or
NOTIFY_TRIAGE_DIR=/path/to/data
Performance
- Classification: <1ms
- Batch operations: instant
- Storage: JSON files, auto-created
- Atomic writes: temp+rename, no corruption on crash
Comparison
| Approach | Noise Reduction | Setup | Maintenance |
|---|---|---|---|
| No filtering | 0% | None | None |
| Notification Triage | 70-90% | None | Minimal |
| Manual rules | 50-70% | High | High |
| External service | 80-95% | Very High | Medium |
Notification Triage gives you 70-90% noise reduction with zero setup.
Design Principles
- Zero setup — Works immediately, no config needed
- No dependencies — Pure Node.js, no npm packages
- Smart defaults — Auto-classification with keyword analysis
- Configurable — Per-source rules override auto-classification
- Persistent — Rules and seen state survive restarts
- Atomic — All writes use temp+rename, crash-safe
- Bounded — Hard caps prevent unbounded disk growth
- Auditable — Dropped notifications are logged for review
- Testable —
--forceon--classifylets you probe without committing a rule
Related skills
Triage, categorize, and conquer email overload. Classifies emails by urgency, generates quick replies, detects newsletters for bulk unsubscribe, and produces daily digests. Use when facing an overflowing inbox or wanting to maintain inbox zero.
Narrative-aware, approval-gated inbox triage
Triage, reply to, and escalate support email
Choose a notification cadence and deduplication key for an operations update stream.
Search and summarize agent inboxes safely