Run reliable reminders an agent actually keeps: schedule one-shot and recurring reminders, poll them from cron, retry delivery with backoff, escalate unacknowledged ones up a role ladder, and keep a replayable audit trail. Use when an agent must remember and nudge something later (follow-ups, deadlines, health checks, SLA warnings) without dropping it silently.
./install.sh reminder-systemname: reminder_system description: "Run reliable reminders an agent actually keeps: schedule one-shot and recurring reminders, poll them from cron, retry delivery with backoff, escalate unacknowledged ones up a role ladder, and keep a replayable audit trail. Use when an agent must remember and nudge something later (follow-ups, deadlines, health checks, SLA warnings) without dropping it silently." metadata: { "includeInPrompt": true }
A durable reminder pipeline that never loses an item silently: schedule reminders against a persistent store, deliver them through a pluggable channel, retry transient delivery failures with exponential backoff and jitter, escalate items that stay unacknowledged, and log every state transition to an append-only audit trail. One binary (bin/remind.py) implements the whole thing on SQLite, so it runs on any box without infrastructure.
remind.py add: a message, a due time (ISO 8601 or relative like +30m, +2h, +3d), an optional --repeat interval, a priority, and an escalation ladder. Every reminder gets a stable id that doubles as the idempotency key for delivery.remind.py due lists items whose due time has passed and that are not acknowledged, exhausted, or in a quiet window. Run it every 1-5 minutes; it records a scan watermark so missed runs are rediscovered by the next scan, not by trusting the queue.remind.py deliver --channel stdout|log|exec --exec-cmd "..." where {id}, {message}, {due} in the command are substituted. The channel write commits first, then the reminder transitions to delivered. Crash between send and commit = the next scan redelivers using the same id; the channel adapter must dedupe on that id.base * 2^attempt capped at max, with full jitter, up to --max-attempts (default 5). Permanent failures (validation, most other 4xx) go straight to failed, never retried. Ambiguous failures (timeout after send) retry only if the channel confirms idempotent delivery.remind.py escalate moves any delivered-but-unacknowledged reminder past its --escalate-after to the next level of its --escalate-to ladder (a comma-separated list of roles/channels). Recipients are roles, never individuals, so staff changes don't break the chain.created, attempt, delivered, failed, ack, escalated, redriven, expired) is appended to the audit table with timestamp, reminder id, actor, and detail JSON. Nothing is ever deleted; failed items park in failed for manual redrive.--db (default ~/.reminders.db): tables reminders, audit, scan_watermark.remind.py list and due emit one JSON object per line for easy piping into jq.deliver prints per-item ok/retry/failed verdicts and exits nonzero if anything failed permanently or exhausted attempts.done only via explicit ack <id> (or auto-ack on a repeat's next scheduled occurrence). Silence never counts as success.--stale-after (default 7d) transition to expired instead of being delivered: a reminder that missed its lateness objective is usually worse than silence, and the expiry is audited.--max-attempts, backoff base/max, retry budget per run, and a concurrency limit for delivery. Set these before the first incident, not during it.--quiet 22:00-07:00 with --tz): due items in a quiet window wait, and the wait is audited as deferred, not as a failure.series_id on each due scan; never mutate the original row's due time, so history stays intact.failed only after the cause is known and idempotency is confirmed: remind.py redrive <id> --note "...". Who did it and why goes in the audit row.references/patterns.md (scan patterns, backoff math, escalation-ladder design, redrive runbook). Read it when designing a deployment; SKILL.md alone is enough for daily operation.publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e
No ratings yet — be the first to rate it.