---
name: briefing
description: "Composes a one-screen daily briefing covering outstanding commitments, today's calendar with attendee context, the highest-priority open tasks, and overnight changes. Triggers when the owner says 'daily briefing', 'what's happening today', 'morning update', or 'brief me'."
---

# Briefing

Invoked from `specialists:personal-assistant`.

This skill produces the owner's daily reading pack. It pulls four signals from the graph, composes them into a single screen of output, and persists the composed briefing as a `:Report` node so the owner can later ask "what was this morning's briefing" and get the exact text back. It does not draft replies, schedule events, or mark tasks complete; the only write is the report-persistence step.

## When to run

Run when the owner asks to be briefed on the day. The trigger phrases are above. The briefing is also the typical first message of a session, so the owner may not name the skill: when the system prompt carries a `<previous-context>` block and the owner opens with "morning" or similar, this skill is the right response.

## Inputs

None required. Optional: a `topic` parameter that narrows the four sections to one project or one named person.

## Method

The briefing has four sections, in this fixed order. Sections with no content collapse to one line ("nothing outstanding" rather than disappearing) so the owner sees that the skill checked.

### 1. Outstanding commitments

Call `work-list` filtered to `status: open` AND (`dueDate <= today` OR `priority: high`). Order by due date ascending, then by priority. List the top five with one line each: title, due date, related entity. If more than five qualify, end the list with "+ N more open" and the total count.

### 2. Today's calendar

Chain into `daily-prep` with `date: today`. Reproduce its chronological event list and the per-event context blocks. Length cap: collapse to event titles only if the briefing would otherwise exceed one screen.

### 3. Open tasks ranked

Call `memory-search` for `:Task` nodes with `status: open` and `limit: 15`. You rank the returned pool yourself against the day's context — recent commitments named in section 1, today's calendar from section 2, the owner's stated current priorities — and reproduce the top 5 with one short reasoning line each ("urgent because the offer goes out today", "blocking the Acme close"). The ranking happens in your turn, not in a server-side LLM call.

### 4. Overnight changes

Two sub-pieces:

- **Messages awaiting reply.** Call `memory-search` for `:Message` nodes with `direction: inbound` and `repliedAt: null` since the owner's last active session. Count and list the top three by inferred priority (sender role, message length, named urgency).
- **Fresh inbox items.** Same query, scope it to messages that arrived since the previous session's end timestamp. List the count and the senders' names.

## Output format

```
## Daily briefing

**Outstanding.** 3 commitments: invoice follow-up with Acme (due today), draft offer to Daniel Park (overdue 2 days), confirm photographer for 12 Park Road (due tomorrow). + 2 more open.

**Today.**
08:30: Coffee with Alice Cohen
09:30: Pricing review with the team
14:00: Call with Daniel Park

(per-event context blocks if there is room, otherwise titles only)

**Priorities.** 1. Chase 14 Garth Road buyer's solicitor (mortgage offer expires in 6 days). 2. Approve the Acme intro draft (sat for 4 days). 3. Confirm the Cohen viewing slot (vendor has asked twice).

**Overnight.** 4 inbound messages awaiting reply (top: Cohen: viewing follow-up; Singh: pricing question; Park: booking confirmation; Webber: referral thanks). 2 fresh items in the inbox since last session: Cohen, Webber.
```

## 5. Persist as a :Report

After composing the four sections, call `memory-report-write` once with the rendered briefing as the body:

- `title: "Daily briefing <YYYY-MM-DD>"` (use the owner's local date).
- `keywords: ["daily-briefing", "<YYYY-MM-DD>"]`.
- `sourceWorkflow: "daily-briefing"`.
- `body`: the full rendered briefing exactly as shown to the owner.

The tool is idempotent on `(title, occurredAt-within-same-minute)`, so two back-to-back invocations on the same date do not create duplicates. Do not summarise or trim the body before persisting — the owner asking for "today's briefing" later expects the same text they saw at delivery.

## One-screen cap

The whole briefing must fit in one screen. If any section would overflow, collapse it (event titles only, top-three not top-five, count plus example). Never spread the briefing across two screens; the operator's intent is a scannable pack, not a report.

## Failure modes

- **`work-list` empty.** Section 1 collapses to "nothing outstanding".
- **`schedule-list` empty.** Section 2 collapses to "nothing in the diary today".
- **`memory-search` for tasks returns fewer than five.** List what it returned; do not pad. (Your own ranking happens in-turn against the day's context.)
- **`profile-read` shows the owner has no `lastActiveSession`.** Section 4 collapses to "no prior session recorded" rather than reporting from training data.

## What this skill does not do

- Draft replies to the inbound messages. The owner sees the count and the senders; if they want a draft, they ask and the right skill is loaded.
- Mark tasks complete or update priorities. The briefing only writes one node — the :Report that captures its own output (section 5).
- Speak in marketing voice or add encouragement. The owner reads the briefing for facts, not for cheerleading.
