Skip to main content

Quiet Hours and Timezone-Aware Delivery

Goal

Hold all notifications during sleep hours, merge held messages into the morning briefing, and adjust automatically when the user travels.

What the User Gets

Without this: 3 AM pings from cron jobs. One bad notification and the user disables the entire system. With this: the brain works overnight (dream cycle, collectors, enrichment) but notifications are held until morning. Travel to Tokyo? The system adjusts automatically from your calendar, no config change needed.

Implementation

Quiet Hours Gate

Every cron job that sends notifications must check quiet hours FIRST.
Before sending any notification:
  1. Determine user’s current timezone (from config or heartbeat state)
  2. Convert current UTC time to local time
  3. If quiet hours: hold the message, don’t send

Held Messages

During quiet hours, output goes to a held directory instead of being sent:
The morning briefing picks up held messages:
This way nothing is lost. Overnight cron results get folded into the first thing the user sees in the morning.

Timezone Awareness

The agent should know what timezone the user is in. Store it in the agent’s operational state:
Update the timezone when:
  • Calendar shows the user flying somewhere (check for airline/hotel events)
  • User mentions being in a different city
  • User’s active hours shift (they’re responding at 3 AM PT = they’re probably traveling)
All times shown to the user should be in their LOCAL timezone. Never show UTC or a timezone the user isn’t in.

Shell Implementation

In cron job scripts:

Configurable Hours

Some users want different quiet hours. Store the config:
Set enabled: false to disable quiet hours entirely (e.g., for 24/7 monitoring).

Tricky Spots

  1. Gate on EVERY job. The quiet hours check must run before every single cron job that produces notifications. If even one job skips the gate, the user gets a 3 AM ping and loses trust in the entire system. No exceptions.
  2. Held messages MUST be picked up. If the morning briefing doesn’t read /tmp/cron-held/, overnight results vanish silently. Verify the briefing skill reads and clears the held directory. Orphaned held files mean the pickup integration is broken.
  3. Timezone auto-detection is fragile. Calendar-based timezone detection relies on the user having airline/hotel events with location data. If the user books travel without calendar entries, the system won’t detect the move. Fall back to activity-hour analysis (responding at 3 AM PT = probably not in PT anymore) and ask the user if uncertain.

How to Verify

  1. Set quiet hours to the current hour. Temporarily set QUIET_START to one hour before now and QUIET_END to one hour after. Trigger a cron job. Verify the output goes to /tmp/cron-held/ instead of being sent.
  2. Check held message pickup. After step 1, run or simulate the morning briefing. Verify the held message appears in the “Overnight Updates” section and the file is deleted from /tmp/cron-held/.
  3. Verify timezone adjustment. Change the timezone config to a zone where it’s currently quiet hours. Trigger a notification. Verify it’s held. Change back to your real timezone during active hours. Trigger again. Verify it sends.

Part of the ModusBrain Skillpack.