Skip to main content
Commit what a reviewer reads, regenerate the rest | ESSWhich files an ESS adoption puts under version control, which it rebuilds, and how to keep the first diff small.ESShow-toesshow-toadopterdevelopertry-spec-driven-developmentreference

Commit what a reviewer reads, regenerate the rest

Adding ESS to an existing repository writes more files than the change you made. Commit the files a reviewer or a consumer reads. Rebuild the rest in CI, where they cannot drift unseen.

artifactcommit?regenerated bydrift check
specification sources (system.yaml, domains, components, topology)yesnobody: you write themess specify validate
ess-inputs.yaml, with its requires: ess X.Y.Z pinyesnobody: you write itan older ess refuses it; --strict-requires refuses a newer one
authored scenarios, listed in ess-inputs.yamlyesnobody: you write themess specify validate compiles them against the model
ess-known-failures/1 declarationsyesnobody: you write themess verify conform run --known-failing refuses a stale one
compiled IRnoess specify compile; compiling twice is byte-identicalnone needed
run reports, histories and mutation outputnorerunning the suite, the explorer or ess verify conform mutatenone needed
projections a consumer reads, selected with --kind: openapi, asyncapi or schema, with .ess-outputyesess generate --kind <kind> --out <root>the same command with --check
site and docs projectionsno; build them in CI for publicationess generate --kind site or --kind docsnone needed
synthesized suite document (--target ir)yes, when ess verify impact --suite or a review reads itess verify conform synthesize --target ir --out <file>; synthesizing twice is byte-identicalthe same command with --check; review a change with ess verify conform diff
synthesized runner and suite (--target go or --target typescript)yesess verify conform synthesizethe same command with --check
type library a consumer links (ess generate types), with .ess-outputyesess generate types --target <target> --out <root>the same command with --check
synthesized code your implementation linksyesess generate synthesizeregenerate, then fail CI on a dirty tree
planning store and evidencesee AEPAEPAEP

Commit .ess-output with the projections it records. It is what lets a clone, a second worktree or CI regenerate the same files in place, and it records no absolute path, device or inode of the machine that wrote it; see repeated generation and recovery. Commit the generated runner explains why the synthesized runner is committed rather than imported. The pin is described in name the ess release. Drift-checking in CI shows the --check run.

Commit the suite document, check it, review it by construct​

Commit the --target ir suite when something reads the earlier revision of it: ess verify impact --suite needs the suite of the base revision to say which scenarios a specification change puts back to owed, and a reviewer reads what a change adds to the obligations. Synthesis is deterministic, so CI can prove the committed file current without regenerating the tree:

$ ess verify conform synthesize --path spec --target ir --out conformance/suite.json
$ ess verify conform synthesize --path spec --target ir --out conformance/suite.json --check

--check writes nothing. It compares the bytes the same command would write, so pass the same --compact, --suite-format and --component the committed file was written with. It exits 1 and names the file when it is missing or differs, and the same flag checks a go or typescript package.

A textual diff of a large suite is not a review. Compare the suite of the base revision with the one the change synthesizes instead:

$ git show main:conformance/suite.json > base-suite.json
$ ess verify conform diff --from base-suite.json --to conformance/suite.json
$ ess verify conform diff --from base-suite.json --to conformance/suite.json --format json

It lists the scenario ids added, removed and changed under the construct each is about, such as billing.invoice.CreateInvoice/outcome or, for a one-time disclosure cell, keys.api.IssueKey/disclosure/issued/secret/rotation, with the steps removed from and added to each changed scenario. The JSON form (ess-suite-diff/1) is what a CI comment can carry.

A suite grows with the obligations a specification declares, not with how it spells them: from ess-conformance/52 the declared event catalog and the one-time response authority are written once at the suite root, so a scenario does not repeat an observation window or an absent event for every declared event. If a committed suite still reaches tens of megabytes, commit it --compact (whitespace only, a pretty and a compact suite are the same suite) and keep --check on that spelling.

Why the first diff is large​

Without --kind, ess generate writes all five projections. For examples/billing that is 48 files, plus the .ess-output record: 29 under schema/, 9 under site/, 6 under docs/, and 2 each under openapi/ and asyncapi/. site/assets/mermaid.min.js alone is about 3.5 MB.

Select what a consumer reads with --kind, one owner per command, and leave the rest to CI:

$ ess generate --path spec --kind openapi --out generated
$ ess generate --path spec --kind openapi --out generated --check

A regeneration that changes nothing writes nothing, so a committed tree stays clean until the specification changes.