# Bead schema

<!-- REFERENCE COPY — do not edit this file. Edit the installed working copy at .beads/SCHEMA.md. -->
<!--
  Anti-ceremony (CHECKLIST.md A12):
  - Consumer: every agent closing a bead in the JSONL fallback; the reviewer auditing closes (B2).
  - Gate: B2 close-on-cited-evidence — the schema makes close_reason structural.
  - Defect class: prose-closed beads; beads whose criteria can be satisfied by believing.
  - Delete when: the project adopts a beads CLI with an enforced schema; until then this file IS the schema.
-->
One JSON object per line in `.beads/issues.jsonl`. Field names are stable;
add fields only by documenting them here first.

| Field | Required | Meaning |
|---|---|---|
| `id` | yes | stable, lowercase, e.g. `kit-a3` |
| `title` | yes | one line, outcome not activity ("Pin incumbent oracle", not "Research oracles") |
| `description` | yes | what / why / origin |
| `acceptance_criteria` | yes | objective commands or observable states; a bead whose criteria can be satisfied by believing it is not a bead |
| `status` | yes | `open` / `in_progress` / `blocked` / `closed` |
| `priority` | yes | `0` = blocks release · `1` = this phase · `2` = day-one · `3` = backlog |
| `issue_type` | yes | `task` / `bug` / `epic` / `chore` |
| `labels` | yes | e.g. `checklist`, `day-1`, `mechanical`, `maturity`, `provisional` |
| `dependencies` | yes | array of bead ids that must close first; no hidden cycles |
| `created_by` | yes | agent or human |
| `created_at` | yes | ISO-8601 UTC |
| `closed_at` | no | ISO-8601 UTC; empty until closed |
| `close_reason` | no | **required at close**: cites the evidence (commit, receipt, ledger row). Closure on cited evidence, not prose. |
| `source_repo` | no | where this bead was seeded from, if anywhere |

Close rules (from the suite):
- Close only on cited evidence; `close_reason` names the proof. (asupersync: "only a terminal receipt proves execution")
- Mark done only with command evidence and updated documentation. Mark blocked only with concrete artifact evidence (error text + command + path). (franken_whisper)
- Demotions are always allowed; promotions require the named gate. (frankensim)
- Retired ids stay in the file, marked retired — never reused, never deleted. (frankensympy: "retired claim IDs must remain")

## Example bead (JSONL, one line)

```json
{"id":"kit-a2","title":"Pin incumbent oracle before implementation","description":"What: record the incumbent at version + commit SHA before any implementation work.\nWhy: a self-speedup without the incumbent live in the same invocation is maintenance, not a win.\nOrigin: franken_whisper docs/INCUMBENT_CONTRACT.json","acceptance_criteria":"docs/planning/packet.md SOTA section names the pinned revision + SHA; oracle binary recorded in docs/evidence/ Verified by: check-readiness.sh CHECK: SOTA present and non-empty","status":"open","priority":2,"issue_type":"task","labels":["checklist","day-1","procedural"],"dependencies":[],"created_by":"starter-kit","created_at":"2026-09-22T00:00:00Z","closed_at":"","close_reason":"","source_repo":""}
```
