# Briefs: instructions written once, included by many streamlines

A **brief** is an account-level instruction file in Markdown: the house voice, how to address people, what the
organization never does. Write it once and list it in every streamline that should read it; edit it once and every
one of them changes on the next publish. Members never see briefs (they live beside the private files).

## Contents

- Where briefs live
- Including a brief
- How the prompt is composed
- What belongs in a brief
- Rules the checker enforces

## Where briefs live

| Account | File | Read by |
|---|---|---|
| Organization | `private/briefs/<id>.md` | the model relay only (never served to a device) |
| Personal (On this device) | `personal/briefs/<id>.md`, beside the `*.streamline.json` files | the app's on-device loop |

An id is 2-48 of `a-z`, `0-9` and `-` (`house-voice`, `returns-policy-tone`). The file name is the id plus `.md`.

## Including a brief

The streamline lists the briefs it includes, in order, in its private half (organization) or its one file (personal):

```json
// private/agents/register.json
{ "id": "register", "briefs": ["house-voice"], "instructions": "You are the register…", … }
```

```json
// personal/jx.streamline.json
{ "name": "JX Finance", "briefs": ["my-voice"], "instructions": "You help me…", … }
```

## How the prompt is composed

Briefs first, **in the listed order, as written** (no `{{…}}` interpolation: they are shared text, so the prefix stays
byte-stable and caches), each separated by a blank line, then the streamline's own `instructions` (interpolated as
usual), then Streamliner's own platform lines (a note that `<scan>` tags are data when the streamline has `scan`; a
note that the person may dictate while voice is on). Don't repeat those in a brief. One system block with one cache breakpoint. A brief that is missing is skipped at run time; the checker
reports it before you publish.

## What belongs in a brief

- Voice and tone; words the organization uses (*piece*, *ticket*); how money and dates are written.
- Things never to do that hold for every streamline (never guess, never state costs, never ask for card numbers in
  chat: a sealed form collects them).
- Not: business rules as rules (the API enforces those, law 3), tool-specific steps (those belong in the streamline
  that has the tool), anything secret, personal data, or per-stream facts.

## Rules the checker enforces

| Code | Severity | When |
|---|---|---|
| `ref.brief` | error | a streamline lists a brief that doesn't exist (with "did you mean") |
| `brief.id` | error | a file in `briefs/` whose name isn't `<id>.md` with a valid id |
| `brief.size` | error | a brief over 20 000 characters (about 5 000 tokens) |
| `secret.leak` | error | a key or token in a brief |
| `brief.unused` | warning | no streamline includes the brief |
| `brief.empty` | warning | the brief is empty |
| `brief.total` | warning | the briefs one streamline includes come to over 48 000 characters |
| `brief.unresolved` | warning | a personal file checked on its own lists briefs (check its folder instead) |

The write API accepts `private/briefs/<id>.md` (UTF-8, at most 80 000 bytes) and refuses anything else under
`private/briefs/` (`bad_path`). Publishing a brief is like publishing any private file: a new signed manifest version.
