Skip to content

Briefings

A pencil sketch on a dark charcoal background: a pre-dawn operations desk, a fanned stack of dated briefing cards under a banker's lamp, a courier owl lifting off carrying a single folded brief toward a breaking dawn; one dossier and the owl's flight-path catch a faint teal halo.

Five briefings reach the operator’s Signal on a schedule. The rule that governs all of them is simple and unforgiving: if it pinged the phone, it had better have been worth reading. A briefing that cries wolf at 02:00 about a thermostat is worse than no briefing — it teaches you to ignore the channel. So every briefing here is built to stay silent until it has something, and to send to the dashboard instead of Signal when the something is merely interesting rather than actionable.

The briefings split cleanly by intent.

Intel briefings — Jocasta (calendar) and Mundi (dealflow) — exist to put information in front of you. Their content is the thing you want on Signal, so they page when there is something to act on and stay silent otherwise. Jocasta runs on a forward-looking schedule; Mundi is purely event-driven (below).

Alert briefings — Windu (security) and Cilghal (health) — exist to catch problems. Their normal state is a stream of low-grade yellows that are not worth a notification. So they page Signal only on a red (actionable) condition; everything yellow goes to the dashboard as ambient state. This is the alert doctrine in one sentence: Signal is for reds, the dashboard is for everything else.

The Morning briefing is the cross-cutting digest: one line on a clean day (“quiet night.”), expanding with root causes only when the overnight watchdog queue has something.

The single most important thing to know when debugging a briefing: the real senders are deterministic launchd jobs, not the OpenClaw cron agent-turns of the same name. The cron versions are stale duplicates — the Jocasta one was timing out fourteen runs in a row against its model and never actually sending, while the launchd job quietly did the real work. Find the launchd job. It is the source of truth.

Job (launchd)SenderScheduleTypeBehaviour
com.jocasta.heartbeat~/.openclaw/scripts/jocasta-heartbeat.py08:00 / 13:00 / 20:00intelForward-looking calendar; silent when nothing upcoming
com.mundi.briefingmundi-watch.py (sanctum-crm)every 30 min, 07:00-22:00intel, event-drivenFires only on a deal-related email or a due Affinity reminder; inline action brief + :2600 dossier
com.windu.briefing~/.openclaw/scripts/windu-briefing.pyevery 3halertRed pages Signal; yellow to dashboard
com.cilghal.briefing~/.openclaw/scripts/cilghal-briefing.pyevery 3halertRed pages Signal; yellow to dashboard
com.sanctum.morning-briefing~/.sanctum/lib/morning-briefing.sh08:00digestOne line clean, expands on problems

Jocasta’s briefing used to show meetings that had already happened. The cause was a self-contained DuckDB query that read date-only rows and guessed whether an event was in the future from text in its name — and defaulted to “future” when there was no time to parse. The fix was to delete that logic and delegate to ~/.openclaw/jocasta-preflight.py, which queries the calendar through icalBuddy with real start times and drops anything that has already ended. The briefing composer now renders exactly what the preflight hands it, so a past meeting cannot leak in — there is no longer any calendar logic in the sender to get wrong.

The window is time-of-day aware: the 08:00 and 13:00 runs show the rest of today; the 20:00 run shows tonight plus tomorrow morning. If nothing is upcoming and no mail is urgent, it sends nothing.

Mundi used to push the standing pipeline every four hours — “sixteen deals need you” whether or not anything changed. That is noise. It now polls every thirty minutes during waking hours and fires only on a real event, toward two goals: help the portfolio, and source or advance deals.

A trigger is a deal-related email — from a domain matching a Portfolio, active-pipeline, or Watchlist company in Affinity, or cold inbound from a real person (newsletters filtered out) carrying dealmaking language — or an Affinity reminder come due. On a trigger Mundi enriches from the same Affinity interaction history Jocasta’s CRM work feeds, then sends an inline action brief plus a tappable dossier on :2600. It primes its backlog on first run, so deploying it never replays history. Detection lives in mundi_triggers.py, unit-tested against the real inbox so a newsletter never fires.

Windu and Cilghal compose a briefing of coloured lines — red for hard failures, yellow for the ambient stuff — then hand the whole thing to ~/.sanctum/lib/briefing_routing.py. route_by_severity reads the worst colour present: a red anywhere routes the message to Signal as critical; a briefing of only yellows routes to the dashboard alone. That one function is why a stopped one-shot container or an 81% disk no longer wakes you, while a disabled firewall still does.

Pre-meeting briefs are the sixth piece. The Meeting Prep agent writes a dossier to ~/.openclaw/workspace/meeting-prep/, and com.sanctum.meeting-briefs-server renders it as mobile HTML on :2600 (loopback and tailnet). The Signal notification carries a tappable link straight to it, so the brief is one tap away on the phone rather than a filename you cannot open. The port lives deliberately outside the 407x Force Flow block — it is a read-only document server, not part of the notification stack.