# Daily briefing digest — the file, the schedule, and the review sheet

Companion artifact to the project "Build a daily briefing digest" at
https://lyceumagents.com/projects/daily-briefing-digest/

Derived from the Global Synthesis Council
(`config/agents/examples/syndicate.yaml` in the melchizedek-agents repo,
mirrored at https://lyceumagents.com/downloads/global-synthesis-council.md).
The file below is site-authored: copy it to `config/agents/briefing.yaml`
in your clone.

---

## 1. config/agents/briefing.yaml

```yaml
syndicate_name: "Daily Briefing"
memory_system: "internal-only"

variables:
  headline_count: 7
  beats: "AI regulation; open-weight model releases; semiconductor supply"

orchestrator:
  name: "Editor"
  model: "gemini-3.8-flash"
  instruction: |
    <system_identity>
      You are the Editor of a one-page morning briefing for one reader.
      The current date is {{current_date}}; "today" means that date, and
      "since yesterday" means the 24 hours before it.
    </system_identity>

    <method>
      You MUST call 'Researcher' once per beat in this list before writing
      a word: {{beats}}. Pass each beat with the date. Write only after
      every report is in. If a beat came back EMPTY SWEEP, say so in the
      last line; never fill it from memory.
    </method>

    <output_format>
      1. THE LEAD: two to four sentences on what changed since yesterday,
         plain prose, no preamble, no greeting.
      2. THE ITEMS: one "- " line per item, at most {{headline_count}} in
         total across all beats, ordered by importance, each ending with
         its source domain in parentheses. An item reported by one outlet
         carries the word "unverified" before the source.
      3. One final line naming any beat whose sweep was empty, or
         "All beats reported." if none was.
      No headers, no bold, no closing summary. Under 1,500 characters.
    </output_format>
  generateContentConfig:
    maxOutputTokens: 4096
    thinkingConfig:
      thinkingLevel: MEDIUM
      includeThoughts: false

subagents:
  - name: "Researcher"
    description: "Searches the web for what was published in the last 24 hours on ONE beat and returns items with dates and source domains. Pass it one beat and the date line."
    model: "gemini-3.1-flash-lite"
    tools:
      - "web_search"
    instruction: |
      You are the Researcher. You receive one beat and the current date.
      Use web_search to find what was published in the last 24 hours on
      that beat; prefer wire services and primary sources. Return a plain
      list, one item per line: the publication date, the source domain,
      and one sentence. Mark an item reported by one outlet only as
      single-source. If nothing was published, return EMPTY SWEEP and
      nothing else. Never add analysis. IMPORTANT: after receiving tool
      results you MUST return a final text summary to the orchestrator.
    generateContentConfig:
      maxOutputTokens: 2048
```

Add `"web_extract"` to the Researcher's tools when a beat is a page to
read rather than a search to run (search finds; extract reads).

## 2. By hand

```bash
mkdir -p briefings
npm run chat:syndicate -- --syndicate briefing "Today's briefing." > "briefings/$(date +%F).md"
npm run chat:syndicate -- --syndicate briefing --bind headline_count=3 "Today's briefing." > briefings/test-3.md
```

## 3. The schedule (cron)

```
0 7 * * * cd /absolute/path/to/melchizedek-agents && /usr/local/bin/npm run chat:syndicate -- --syndicate briefing "Today's briefing." >> "$HOME/briefings/$(date +\%F).md" 2>&1
```

- `which npm` prints the path to use; cron's environment is bare.
- `%` is special to cron — keep the backslash in the date format.
- the command `cd`s into the repo so the loader finds `.env`.
- the date is bound once at load; schedule clear of midnight.
- macOS: launchd runs the same command; cron is the shorter thing to
  write and still works.

## 4. The review sheet — two mornings

| rule | day 1 | day 2 |
|---|---|---|
| lead is 2–4 sentences | | |
| item count ≤ headline_count | | |
| every item ends with a source domain | | |
| single-source items carry "unverified" | | |
| last line names empty beats, or "All beats reported." | | |
| under 1,500 characters | | |

Held both days → a rule. Held once → tighten one sentence of the
contract, in the file, and run again. Same lead two days running with
different sources → a beat gone quiet; the sweep should say so.
