# Cronjob Patterns for Daily Briefings

## Timezone Warning

Cron schedules are in **UTC**. Always confirm the user's local timezone before setting the schedule.

| User Location | UTC Offset (Summer) | UTC Schedule for 9 AM local |
|-------------|---------------------|----------------------------|
| Brussels (CEST) | UTC+2 | `0 7 * * *` |
| Brussels (CET) | UTC+1 | `0 8 * * *` |
| Arizona (MST) | UTC-7 | `0 16 * * *` |

If the user says "9 AM" without specifying UTC, ask: *"What timezone are you in?"* and convert. DST changes shift the effective local time — warn the user if their country observes DST.

## Delivery Channel Priority

When creating cron reminders or briefings, confirm the user's preferred delivery channel before setting `deliver`. Common options:

| Channel | `deliver` value | When to use |
|---------|----------------|-------------|
| Messaging (Telegram/Discord/WhatsApp) | `telegram:...`, `discord:...`, `whatsapp:...` | User wants instant notifications on their phone |
| Email | Requires external sender (Himalaya, SMTP) | User prefers non-intrusive delivery; good for reminders that don't need immediate action |
| Local-only | `local` (default) | Testing only; output is saved but NOT delivered. Do not default to this for user reminders. |

> **Default preference for this user:** Cron reminders should be sent as email by default (to `sage.stockmans@pm.me`). Only fall back to `local` if no email sender is configured on the Hermes session and the user explicitly accepts local-only delivery.

### Email Delivery Setup

If the user prefers email delivery, check for an email sender before promising delivery:

1. **Himalaya CLI** — Check `which himalaya`. If installed, ensure `~/.config/himalaya/config.toml` is configured for an SMTP backend (Gmail, iCloud, ProtonMail Bridge, or other provider). See `himalaya` skill for full config reference.
2. **Python SMTP** — If Himalaya is missing, check if `python3` and `smtplib` can reach an SMTP relay. ProtonMail (`pm.me`) requires ProtonMail Bridge running locally. Other providers (Gmail app password, Mailgun, etc.) work with direct SMTP.
3. **Fallback:** If no email sender is available, warn the user and offer:
   - Install Himalaya + configure SMTP
   - Use a messaging platform (Telegram/Discord) as temporary substitute
   - Accept local-only delivery (saved to session, no real notification)

### ProtonMail-specific note

ProtonMail (`sage.stockmans@pm.me`) requires ProtonMail Bridge for SMTP access. The Bridge is a local application that decrypts mail and exposes an SMTP endpoint. It does not run inside a standard Hermes session. For ProtonMail users, the realistic options are:
- Run ProtonMail Bridge on their laptop (e.g., via Tailscale tunnel to the Hermes host)
- Use a different SMTP provider for outgoing notifications
- Use a messaging platform instead of email

## Email-Only Delivery (No WhatsApp)

To send briefings via email without messaging platform spam:

1. Set `deliver: "local"` in the cron job (prevents WhatsApp/Telegram/Delivery)
2. The cron prompt should run a script that sends email directly (e.g., Apple SMTP)
3. The script's stdout confirms success; no `send_message` tool call needed

Example prompt:
```
Send the morning briefing ONLY via email (Apple iCloud SMTP). No WhatsApp delivery.
Steps:
1. Execute: bash /home/$USER/.hermes/scripts/run_send_briefing_email.sh
2. Confirm from stdout that the email was sent successfully.
```

## Schedule Syntax

| Schedule | Meaning |
|---|---|
| `0 9 * * *` | Daily at 9:00 AM |
| `0 9 * * 1-5` | Weekdays at 9:00 AM |
| `0 9,18 * * *` | Twice daily (9 AM, 6 PM) |
| `0 9 * * 1` | Weekly Monday at 9 AM |
| `*/30 * * * *` | Every 30 minutes (for testing) |

## Toolsets

Briefing cron jobs need:
- `"terminal"` — to run the briefing script
- `"send_message"` — to deliver output to messaging platforms

Other optional toolsets:
- `"web"` — if the briefing script uses web_search internally
- `"browser"` — if the briefing script needs to scrape dynamic pages

## Delivery

Set `deliver: "origin"` to send the briefing message back to the chat that created the cron job.

## Prompt Pattern

The cron job prompt should be explicit:

```
1. Run the briefing script via terminal:
   bash /home/$USER/.hermes/scripts/run_briefing.sh
2. Capture the stdout output
3. Send the exact output via send_message with:
   - target: "whatsapp:Contact Name (dm)"
   - message: <the script output>
```

## no_agent Mode for Simple Watchdogs

If the briefing script itself produces the final message (and you just want to pipe it), you can use `no_agent: true` with a shell command in `script`. However, for multi-step tasks (calendar + news + compliment), the LLM-driven agent mode is more flexible.

## WhatsApp Target Format

Find exact target names:
```
send_message action="list"
```

WhatsApp targets look like:
- `whatsapp:Contact Name (dm)`

## Testing a Cron Job Manually

```
cronjob action=run job_id=<your-job-id>
```

This immediately triggers a run without waiting for the scheduled time.
