Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

DocumentVersion fieldWhere it appearsSchema
projectversionstreamform.ymlstreamform schema project
sources(with project)sources.ymlstreamform schema sources
fixture(with project)tests/*.ymlstreamform schema fixture
plan-manifestmanifest_versioninspect-plan --json, explain --json, build/plan.jsonstreamform schema plan-manifest
applied-recordrecord_version.streamform/applied/<target>.jsonstreamform schema applied-record
diffdiff_versionplan --jsonstreamform schema diff
check-reportcheck_versioncheck --jsonstreamform schema check-report
test-reportreport_versiontest --jsonstreamform schema test-report
graphgraph_versiongraph --jsonstreamform schema graph

streamform schema --list prints the same table for the build you have, with the version each document is at.

The rules

  1. Every document has a version field, first. It is named <document>_version (the three project files share version in streamform.yml). Every document started at 1.
  2. 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.
  3. 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: false in every schema), so a document from a newer build that only added a field fails loudly instead of being half-read.
  4. Exit codes are 0, 1, 2 for every command. 0: the command ran and found nothing wrong. 1: the command ran and found something — problems in check, a failed fixture in test, a verdict above COMPATIBLE in plan, a cycle in graph --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 on 1; 2 is a setup problem.
  5. With --json, stdout holds the document and only the document. Anything written for a person goes to stderr. One exception: check --json prints a document even when the project fails to load — loaded: false, the reason as its one diagnostic, then exit 2 — because saying what is wrong is check’s job.
  6. Digests are lowercase-hex SHA-256 wherever a document carries one: the application digest, schema digests, state digests.
  7. 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. problem is the authority on whether it matched.

Using the schemas

  • Editors. Put # yaml-language-server: $schema=.streamform/schema/project.json at the top of streamform.yml (and likewise for sources.yml and fixtures) after streamform schema project > .streamform/schema/project.json; any editor with the YAML language server then completes field names and flags unknown ones the way check would.
  • CI. Parse test --json and gate on .passed; parse plan --json and gate on .verdict. Assert the version you were written against with streamform schema <document> --version N, which exits 2 if the build speaks another.
  • Programs. Validate any document against its schema with a JSON Schema 2020-12 validator; every schema carries an $id of the form urn: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.