# Narrative Spec — v0 (draft)

Open, versioned contracts for the objects a story is built out of: works, characters,
worlds, factions, rulesets, locations, relationships, events, audiences and chapters.

Writers write prose. AIs should build the supporting objects against a spec — and today
every model invents its own shape for "character," which is why no two tools can read each
other's work and why nothing can be diffed against a canonical record.

This is a **data contract, not a writing methodology**. It says what a character document
looks like. It has no opinion about how you write one.

## The shape of it

Every object carries four fields and nothing else is required of it universally:

| Field | Meaning |
| --- | --- |
| `id` | `type:slug`, unique within a work. Immutable, never reused. |
| `specType` | Which schema this validates against. |
| `specVersion` | Which version it was written against. |
| `name` | Display name. This one may change; the slug may not. |

Each type then requires a small handful more — a Character needs a `role`, a World needs a
`summary` — and everything else is an optional **depth group**.

## Progressive completeness

A stub is valid. `{"id": "character:mara", "specType": "character", "specVersion": "0.1.0",
"name": "Mara", "role": "protagonist"}` is a whole character as far as this spec is
concerned, and it scores 0%.

Depth is **scored, not demanded**. That is the load-bearing decision in the whole document:
a schema that demands depth turns a writer into a database clerk, and an AI into a machine
for filling boxes with plausible nothing. So completeness is a number on a sheet, and it
never gates a write.

Depth groups are top-level optional objects — `arc`, `voice`, `appearance`. A group is
**started** when its key is present and its value is a non-null object, *including `{}`*.
Absent or `null` means not started. `{}` is a real state, meaning "opened, nothing in it
yet," and it round-trips unchanged.

A group is **filled** if a string in it trims to length > 0, an array has length > 0, or an
object has at least one non-empty child. Completeness is filled groups over total groups,
unweighted — see [validation.md](validation.md).

## Relations are references

`character:mara` and never an embedded copy of Mara. Two objects that both know about a
relationship do not each carry half a stale duplicate of it. See [ids.md](ids.md).

## Canon is the writer's

`status` is `stub` | `draft` | `canon`. An AI may propose a patch to any field; it never
flips an object to `canon` and it never overwrites one. That is a person's assertion about
their own work.

## Medium overlays

Core types are medium-agnostic. A novel's chapter function, a screenplay's sluglines and a
game's quest hooks live under `extensions`, namespaced. An overlay may not shadow a core
field name, and an overlay-unaware reader must still understand the object.

## The types

| Type | Required beyond the core | Depth groups |
| --- | --- | --- |
| [Work](work.md) | `medium` | 7 |
| [Character](character.md) | `role` | 7 |
| [World](world.md) | `summary` | 6 |
| [Faction](faction.md) | `goal` | 4 |
| [Ruleset](ruleset.md) | `systems` | 5 |
| [Location](location.md) | `kind` | 5 |
| [Relationship](relationship.md) | `endpoints`, `kind` | 4 |
| [Event](event.md) | `when` | 3 |
| [Audience](audience.md) | — | 4 |
| [Chapter](chapter.md) | `num` | 4 |
| [Scene](scene.md) | `purpose` | 6 |

**Scene and Event are different things.** The Event is what happened in the world; the
Scene is where a reader watches it happen. A single Event can be dramatized in three scenes
or in none, and the chronology stays coherent either way.

Not in v0: items, conlangs, bestiaries, spell cards, quest graphs, dialogue trees.

## Also

- [validation.md](validation.md) — the pipeline, the invariants, the error format, the score.
- [ids.md](ids.md) — slugs, tombstones, import collisions, library overlays.
- [versioning.md](versioning.md) — what a minor may do, what forces a major, how to pin.
- [overlays.md](overlays.md) — medium-specific extensions, and the two verdicts.
- [../CONTRIBUTING.md](../CONTRIBUTING.md) — core type or extension?
- [`examples/minimal/`](../examples/minimal) — one valid stub of every type.
- [`examples/tidewardens/`](../examples/tidewardens) — a worked example with real depth.
