A spec here is a contract more than one roadmap line depends on — a file format, a vocabulary, or a behaviour every tool obeys. It exists because a rationale section says why in 250 words, and a format needs to say what, at whatever length that takes.
Every spec describes code that exists, and is the contract that code is held to. Where the code and a spec disagree, that is evidence about the spec, not only about the code.
| Spec | What it fixes | Lines it binds |
|---|---|---|
tool-surface.md | How every call behaves: handles, post-conditions, errors, self-description, conventions | PW1–PW6 |
project-config.md | What a project declares, and how a value is resolved | PW5 |
measurements.md | The closed vocabulary a comparison may return | PW8–PW11 |
rungs.md | The preview ladder: what each rung is, and which question it carries | PW7, PW13–PW15 |
context.md | Judging an asset where it will be seen, and what survives at display size | PW10, PW15 |
fetching.md | Buying a mesh: the shape check, the ledger, the schema, the reference | PW16–PW21 |
engine.md | Driving the engine: the verdict, real pixels offscreen, units, environment | PW22–PW25 |
motion.md | A skeleton fitted to a mesh, and a clip and its curves authored once as TOML | PW26–PW29 |
acceptance-spec.md | What “correct” means, as a file a search can aim at | PW12, PW13, PW15 |
geometry.md | A shape as data rather than as a program | PW30–PW34 |
provenance.md | What is recorded beside an artefact, and the cache key | PW6, PW14, PW17 |
world.md | A game's names, factions and characters declared beside its prose, and the text a player reads held to them | PW196–PW200 |
music.md | A score written as a source in mini-notation, the note model it compiles to, and MIDI | PW186–PW188 |
effects.md | Retro effects as sfxr parameters and a seed, and realistic ones bought under a ceiling, each at the cue a game declares | PW189, PW190 |
store.md | A store's capsule set cut from one key art and a logo, with the store's shapes as data | PW268 |
video.md | A teaser cut together from captured runs, scored, encoded as an MP4 and measured | PW429 |
vfx.md | A particle or ribbon effect declared as data and built into the scene the engine plays, with what it measures | PW259 |
driving.md | A running game held still between an agent's calls, and the commands that move and read it | PW211–PW217 |
panel.md | A menu panel's frame declared once and built to nine-patch textures and styleboxes, by state | PW316 |
inventory.md | Every item a project governs, by kind, in one paged read with its record's state | PW299 |
adoption.md | What one asset cost to make each way, so the claim can be falsified | PW35 |
kit.md | A part every game repeats, made once in the plugin as a kit with its proof, and the five steps every kit keeps | PW340–PW342 |
Each one lives in docs/specs/. They are ordinary documents, edited directly, unlike the roadmap, which roadkeep governs.
TOML for documents a person authors or reads — the project config, an acceptance spec, a geometry declaration, an animation clip. JSON for records a machine writes — provenance sidecars, job state, ledgers, cache entries. The split is about who edits the file, not about what is in it. A document may also arrive as JSON where a caller emits it programmatically; a record never arrives as TOML.
One file per asset, beside it or under a directory the project config names. This is the whole grammar: a list of named predicates, each naming a measure from the closed vocabulary and stating one bound, and a block per parameter the search is permitted to move.
asset = "mascot"
rung = "final" # the lowest preview rung a verdict may be taken at
[[predicate]]
id = "face-reads-cream"
measure = "delta_e"
region = [120, 80, 180, 140]
target = "#E8D5C4"
max = 2.0
[[predicate]]
id = "silhouette-holds"
measure = "silhouette_iou"
against = "docs/design/art/ui/mascot.png"
min = 0.97
[[predicate]]
id = "has-a-saturated-tail"
measure = "saturation_p99"
region = "subject"
min = 0.85
weight = 0.5
[search.light]
min = 0.5
max = 4.0
[search.form]
min = 1.0
max = 4.0
step = 0.1Anything no measure can compute. “Reads as cloth rather than paper” is a real criterion and not a predicate, and pretending otherwise by inventing a proxy for it is how a spec ends up satisfied by a render a person rejects. That case is expected rather than designed away — it is exactly what the contact sheet is for.
python -m polyweave serve answers tools/list, and tool-surface.md says how each call behaves.