A lightweight, federated deadman switch that triggers notifications and scripts when you stop checking in.
- Check-in based: Authenticate with TOTP (works with any authenticator app)
- Federated: Multiple nodes can sync check-ins; any single node can trigger
- Multi-stage warnings: Configurable warning and grace periods before trigger
- Post-trigger scheduling: Run recurring actions after trigger (annual emails, birthday messages, etc.)
- Flexible notifications: Via Apprise - supports 80+ notification services
- Script execution: Run arbitrary Python/shell scripts on events
- Portable: Runs on laptop, workstation, Raspberry Pi, or VPS
pip install posthumous# Initialize a new node
posthumous init --node-name laptop
# Start the daemon
posthumous run
# Check in (when prompted by your authenticator)
posthumous checkin
# or use the alias
phm checkinConfiguration is stored in ~/.posthumous/config.yaml:
node_name: "laptop"
secret_key: "YOUR_TOTP_SECRET" # Generated by 'posthumous init'
listen: "0.0.0.0:8420"
# Timing
checkin_interval: 7 days # Expected check-in frequency
warning_start: 8 days # Begin warning notifications
grace_start: 12 days # Urgent warnings
trigger_at: 14 days # Execute trigger actions
# Peers (optional)
peers:
- https://workstation.home:8420
# Notification channels
notifications:
default:
- "ntfy://my-topic"
urgent:
- "ntfy://my-topic"
- "mailto://user:pass@smtp.example.com?to=contact@example.com"
# Actions
actions:
on_warning:
- notify: default
message: "Check-in needed. {days_left} days remaining."
on_grace:
- notify: urgent
message: "URGENT: Posthumous triggers in {hours_left} hours."
on_trigger:
- notify: urgent
message: "Posthumous has activated."
- script: "scripts/on_trigger.py"
# Post-trigger schedule
post_trigger:
- name: "annual_letter"
when: "every year on trigger"
script: "scripts/annual_letter.py"
- name: "birthday_message"
when: "every March 15"
notify: default
message: "Happy birthday. Thinking of you always."ARMED ──timeout──► WARNING ──timeout──► GRACE ──timeout──► TRIGGERED
▲ │ │ │
└───── check-in ────┴───── check-in ────┘ │
▼
(runs forever)
# Setup
posthumous init # Create config, generate TOTP, show QR
posthumous init --join URL # Join existing federation
# Operation
posthumous run # Start daemon (foreground)
posthumous stop # Stop daemon
# Check-in
posthumous checkin # Interactive TOTP prompt
phm checkin # Alias
posthumous checkin --token X # API key (for scripts)
# Status
posthumous status # Show state, time remaining
posthumous peers # Show peer status
# Testing
posthumous test-notify # Test all notification channels
posthumous test-trigger # Dry-run trigger actions
# Backup
posthumous export backup.yaml
posthumous import backup.yamlThe when field supports various expressions:
# Relative to trigger
"trigger" # At trigger time
"trigger + 3 days" # 3 days after trigger
# Recurring
"every day after trigger" # Daily from trigger
"every week after trigger" # Weekly from trigger
"every year on trigger" # Annual anniversary
# Absolute dates
"2030-01-01" # Specific one-time
"every December 25" # Yearly Christmas
"every March 15 - 7 days" # Week before birthdayMultiple nodes can form a federation:
- Check-ins broadcast to all peers
- Any node can trigger (failure mode: duplicates, not silence)
- Scheduled actions sync to prevent double-execution
- Health monitoring alerts when peers go down
- TOTP authentication (RFC 6238)
- Brute force protection with lockout
- Peer communication signed with shared secret
- API token available for automation (use with caution)
MIT