diff --git a/.changeset/docs-prep-example-workflow-fix.md b/.changeset/docs-prep-example-workflow-fix.md
new file mode 100644
index 0000000..413f373
--- /dev/null
+++ b/.changeset/docs-prep-example-workflow-fix.md
@@ -0,0 +1,5 @@
+---
+"@cdot65/prisma-airs-cli": patch
+---
+
+Rewrite `docs/cli/examples/README.md` to document the real CLI-docs pipeline: YAML sidecars (`docs/cli/examples/.yaml`) feed `pnpm docs:gen`, which writes the auto-generated pages under `docs/cli/**`. Editing those pages by hand fails `pnpm docs:check`.
diff --git a/docs/cli/examples/README.md b/docs/cli/examples/README.md
index b90a65d..109af78 100644
--- a/docs/cli/examples/README.md
+++ b/docs/cli/examples/README.md
@@ -1,118 +1,164 @@
-# CLI Docs — Live Examples Template
+# CLI Docs — Live Examples Workflow
-This directory holds the fixture and example conventions used by every page
-under `docs/cli/runtime/`, `docs/cli/redteam/`, and `docs/cli/model-security/`.
+Every `airs` command must render at least one real input + real output on its
+docs page. This directory drives that rendering.
-Project rule: **every command must have a real input + real output**. No
-fabricated payloads. When a live capture is blocked by an upstream API, CLI,
-or SDK defect, document it with a `!!! bug` admonition and a tracking-issue
-link instead of inventing output.
+**Doc pages under `docs/cli/runtime/`, `docs/cli/redteam/`, and
+`docs/cli/model-security/` are AUTO-GENERATED. Never edit them by hand —
+your edit will be overwritten by `pnpm docs:gen` and will fail
+`pnpm docs:check` in CI.**
-## Capture environment
+## How the pipeline works
-All `airs` invocations during capture **must** run from
-`~/development/cdot65/prisma-airs-cli`. The repo-local `.env` (or
-`.env.cdot65` / `.env.dus` for alternate tenants) supplies
-`PANW_AI_SEC_API_KEY`, `PANW_MGMT_*`, and `PANW_DLP_ENDPOINT`. Running from
-anywhere else fails with missing-credential errors.
+1. `scripts/gen-cli-docs.ts` walks the live `airs` program tree, joins each
+ command with examples from the YAML sidecars in this directory, and writes
+ `docs/cli//.md`.
+2. `scripts/check-cli-docs.ts` (`pnpm docs:check`, runs in CI) regenerates
+ into a tempdir, byte-compares against the committed `.md`, and fails on
+ drift. It also fails when a leaf command has no examples AND is not on
+ `.missing-allowlist`.
+3. The allowlist is the burndown list — every entry should disappear as
+ examples land, except for entries explicitly blocked by an upstream / CLI /
+ SDK defect (see below).
-## Directory layout
+## Files in this directory
```
docs/cli/examples/
├── README.md # this file
-├── REDACTION.md # redaction rules
-├── dlp/
-│ ├── dictionaries/ # fixtures for write ops on dlp dictionaries
-│ ├── patterns/
-│ ├── profiles/
-│ └── filtering-profiles/
-├── runtime/ # fixtures for runtime/* write ops
-├── redteam/ # fixtures for redteam/* write ops
-└── model-security/ # fixtures for model-security/* write ops
+├── REDACTION.md # redaction rules (apply before pasting output)
+├── .missing-allowlist # commands awaiting examples (burn to zero)
+├── runtime.yaml # sidecar for `airs runtime ...` commands
+├── redteam.yaml # sidecar for `airs redteam ...` commands
+├── model-security.yaml # sidecar for `airs model-security ...` commands
+├── dlp/{dictionaries,patterns,profiles,filtering-profiles}/
+├── runtime/ # body-file fixtures for runtime/* write ops
+├── redteam/ # body-file fixtures for redteam/* write ops
+└── model-security/ # body-file fixtures for model-security/* write ops
```
-Fixture files live under `docs/cli/examples//.json` and follow
-the redaction rules in [REDACTION.md](REDACTION.md).
-
-## Example block format (the contract)
-
-Replaces each `!!! warning "Example needed"` placeholder. For **list/get**
-commands, show Pretty + JSON + YAML:
+Sidecar files key by **full command path** (no `airs` prefix):
-````markdown
-#### Examples
-
-**Input**
-```bash
-airs runtime dlp dictionaries list
+```yaml
+"runtime dlp dictionaries list":
+ examples:
+ - note: Pretty output (default)
+ input: airs runtime dlp dictionaries list
+ output: |
+
```
-**Output (pretty / default)**
-```text
-
-```
+The renderer emits each entry as italic note + bash codefence (input) + text
+codefence (output). There is no `!!! bug` admonition path — see "Blocked
+commands" below for how to handle defects.
+
+## Per-command authoring workflow
+
+1. `cd ~/development/cdot65/prisma-airs-cli` (required — `.env` auto-loads
+ `PANW_AI_SEC_API_KEY`, `PANW_MGMT_*`, `PANW_DLP_ENDPOINT`).
+2. For any write op needing `--body-file`, drop a minimal valid fixture under
+ `docs/cli/examples//.json`. Redact per
+ [REDACTION.md](REDACTION.md) before committing.
+3. Live-capture each command:
+ - **list / get** → run three times: pretty (default), `--output json`,
+ `--output yaml`. One sidecar entry per format.
+ - **create / update / replace / patch / delete** → JSON only.
+4. Redact every capture per [REDACTION.md](REDACTION.md).
+5. Append entries to the right sidecar (`runtime.yaml` / `redteam.yaml` /
+ `model-security.yaml`).
+6. Remove the command path from `.missing-allowlist`.
+7. `pnpm docs:gen` — regenerates `docs/cli/**/*.md`.
+8. `pnpm format` — Biome fixes JSON fixture formatting.
+9. `pnpm docs:check` — must pass before commit.
+10. Add `.changeset/.md` (`patch`) describing what got examples.
+11. Open PR.
+
+## Format contract (sidecar entries per command)
+
+**list / get** — three entries (pretty / JSON / YAML):
-**JSON**
-```bash
-airs runtime dlp dictionaries list --output json
-```
-```json
-
+```yaml
+"runtime dlp dictionaries list":
+ examples:
+ - note: Pretty output (default)
+ input: airs runtime dlp dictionaries list
+ output: |
+ ID NAME CATEGORY
+ 00000000-0000-0000-0000-000000000001 example-dict custom
+ - note: JSON output
+ input: airs runtime dlp dictionaries list --output json
+ output: |
+ [
+ {
+ "id": "00000000-0000-0000-0000-000000000001",
+ "name": "example-dict",
+ "category": "custom"
+ }
+ ]
+ - note: YAML output
+ input: airs runtime dlp dictionaries list --output yaml
+ output: |
+ - id: 00000000-0000-0000-0000-000000000001
+ name: example-dict
+ category: custom
```
-**YAML**
-```bash
-airs runtime dlp dictionaries list --output yaml
-```
+**create / update / replace / patch / delete** — JSON only, plus a
+reference to the fixture if one is used:
+
```yaml
-
+"runtime dlp patterns create":
+ examples:
+ - note: Create from body fixture (see docs/cli/examples/dlp/patterns/create.json)
+ input: airs runtime dlp patterns create --body-file docs/cli/examples/dlp/patterns/create.json --output json
+ output: |
+ {
+ "id": "00000000-0000-0000-0000-000000000001",
+ "name": "example-pattern",
+ "state": "created"
+ }
```
-````
-For **write ops** (`create` / `update` / `replace` / `patch` / `delete`),
-only the JSON capture appears (plus the body/fixture if applicable).
+## Blocked commands (upstream / CLI / SDK defect)
-## Bug admonition variant
+The renderer has no `!!! bug` admonition path — every sidecar entry produces
+input + output codefences. So when live capture is impossible:
-When live capture is blocked by an upstream API, CLI, or SDK defect, replace
-the example block with a `!!! bug` admonition that links the tracking issue.
-Never fabricate output.
+1. **File a tracking issue first.** Upstream API → label `upstream-bug` in
+ `cdot65/prisma-airs-cli`. CLI defect → label `bug` in
+ `cdot65/prisma-airs-cli`. SDK defect → label `bug` in
+ `cdot65/prisma-airs-sdk`. Search existing issues first
+ (#80 already covers DLP `patterns get` / `profiles get` 400).
+2. **Leave the entry on `.missing-allowlist`** with a comment line above
+ linking the tracking issue:
-````markdown
-#### Examples
+ ```
+ # Blocked by upstream — see https://github.com/cdot65/prisma-airs-cli/issues/80
+ runtime dlp patterns get
+ ```
-**Input**
-```bash
-airs runtime dlp patterns get
-```
+3. The doc page will render the default `!!! warning "Example needed"`
+ placeholder. That is correct until the bug is fixed — better than
+ fabricating output.
+4. Reference the tracking issue from your changeset so reviewers know why
+ the entry survives the burndown.
-!!! bug "Upstream API returns 400"
- The DLP `/v2/api/data-patterns/{id}` endpoint currently returns HTTP 400 for all
- pattern UUIDs. Tracking: [cdot65/prisma-airs-cli#80](https://github.com/cdot65/prisma-airs-cli/issues/80).
- Example will be backfilled once the upstream API is fixed.
+## Capture environment
-**Workaround**
-```bash
-airs runtime dlp patterns list --output json | jq '.[] | select(.id=="...")'
-```
-````
-
-If no tracking issue exists yet, file one before adding the admonition:
-
-- Upstream API defect → label `upstream-bug`
-- CLI defect → label `bug` (this repo)
-- SDK defect → label `bug` in `cdot65/prisma-airs-sdk`
-
-## Per-page workflow
-
-1. List every command on the page; confirm the placeholder is present.
-2. Build fixtures under `docs/cli/examples//` for any write op needing
- `--body-file`.
-3. Live capture: run each command up to three times (pretty / JSON / YAML)
- from `~/development/cdot65/prisma-airs-cli`; save outputs locally.
-4. Redact per [REDACTION.md](REDACTION.md).
-5. Detect bugs; file tracking issue + add `!!! bug` admonition if needed.
-6. Swap the placeholder for the example block above.
-7. Add a `.changeset/.md` (`patch`) with user-facing description.
-8. Open the PR; post the same summary as a PR comment.
+All `airs` invocations during capture **must** run from
+`~/development/cdot65/prisma-airs-cli`. The repo-local `.env` (and
+`.env.cdot65` / `.env.dus` for alternate tenants) supplies the management +
+runtime credentials. Running from anywhere else fails with
+"missing credentials".
+
+## Checklist before opening the PR
+
+- [ ] Sidecar entries added; YAML loads cleanly (try `pnpm docs:gen`).
+- [ ] `.missing-allowlist` updated (entries removed for completed commands;
+ comment + entry kept for blocked commands with tracking issue link).
+- [ ] Body fixtures redacted per REDACTION.md.
+- [ ] `pnpm docs:gen` run; regenerated `.md` committed.
+- [ ] `pnpm format` clean.
+- [ ] `pnpm docs:check` clean.
+- [ ] `.changeset/.md` present (`patch`).
+- [ ] No edits to `.md` files outside the autogenerated set.