The protocol: what every --json document promises
Streamform exchanges documents with everything outside it: the project files it reads, the plan documents it writes, and the reports its commands print with --json. Each is a published specification — a JSON Schema generated from the Rust type that owns it, with prose and real examples, under spec/ in the source tree and mirrored to streamform-spec on every release. These are the rules every document and every command follow; they are the contract a tool, a CI job, or a library can build on without Streamform’s source.
The documents
| Document | Version field | Where it appears | Schema |
|---|---|---|---|
project | version | streamform.yml | streamform schema project |
sources | (with project) | sources.yml | streamform schema sources |
fixture | (with project) | tests/*.yml | streamform schema fixture |
plan-manifest | manifest_version | inspect-plan --json, explain --json, build/plan.json | streamform schema plan-manifest |
applied-record | record_version | .streamform/applied/<target>.json | streamform schema applied-record |
diff | diff_version | plan --json | streamform schema diff |
check-report | check_version | check --json | streamform schema check-report |
test-report | report_version | test --json | streamform schema test-report |
graph | graph_version | graph --json | streamform schema graph |
streamform schema --list prints the same table for the build you have, with the version each document is at.
The rules
- Every document has a version field, first. It is named
<document>_version(the three project files shareversioninstreamform.yml). Every document started at1. - A version is bumped only for a change an older Streamform must refuse. A field an older build may ignore is added with a default and no bump. A change in meaning, a removed field, a renamed one — bumps. When in doubt, it bumps.
- A newer version is refused, never guessed. The error names the version found and the version this build speaks. A document with fields this build does not know is refused too (
additionalProperties: falsein every schema), so a document from a newer build that only added a field fails loudly instead of being half-read. - Exit codes are
0,1,2for every command.0: the command ran and found nothing wrong.1: the command ran and found something — problems incheck, a failed fixture intest, a verdict aboveCOMPATIBLEinplan, a cycle ingraph --json.2: the command could not do its job — the project does not load, a file cannot be read, a target is missing. Gate CI on1;2is a setup problem. - With
--json, stdout holds the document and only the document. Anything written for a person goes to stderr. One exception:check --jsonprints a document even when the project fails to load —loaded: false, the reason as its one diagnostic, then exit2— because saying what is wrong ischeck’s job. - Digests are lowercase-hex SHA-256 wherever a document carries one: the application digest, schema digests, state digests.
- Values in reports are rendered after typing. In the test report, both the expected and the emitted value are shown as the model’s column type renders them — decimals as strings (exact; trailing zeros trimmed as in a fixture), timestamps as RFC 3339 in UTC, integers and booleans as themselves — so a matching row looks matching.
problemis the authority on whether it matched.
Using the schemas
- Editors. Put
# yaml-language-server: $schema=.streamform/schema/project.jsonat the top ofstreamform.yml(and likewise forsources.ymland fixtures) afterstreamform schema project > .streamform/schema/project.json; any editor with the YAML language server then completes field names and flags unknown ones the waycheckwould. - CI. Parse
test --jsonand gate on.passed; parseplan --jsonand gate on.verdict. Assert the version you were written against withstreamform schema <document> --version N, which exits2if the build speaks another. - Programs. Validate any document against its schema with a JSON Schema 2020-12 validator; every schema carries an
$idof the formurn:streamform:spec:<document>:v<N>.
The published copy: glyf-data/streamform-spec, one directory per document, v<N>/schema.json beside v<N>/examples/ and a README.md of prose. Every file in it is generated from the source tree; requests go to the issue tracker, not as pull requests to the mirror.