Formats and digests
Choose a reader by the document's producer and shape as well as its marker. Some ESS outputs are unversioned, and two different shapes can share a marker. A successful JSON or YAML parse does not necessarily validate the document's claims.
A format version such as ess/1, a specification version such as v3, and a software release
such as 0.18.0 identify different things. Specification versions are major-only; typed IR serializes
that major as a number. Delivery release versions and constraints use SemVer independently.
Version owners, specification format support.
Format version history says what each version number changed and which release introduced it.
Which digest is this?
| Identity | Hash input and spelling |
|---|---|
Compiled model: source_digest or suite spec_digest | SHA-256 of compact typed EssIr JSON, with no appended newline. Bare 64 lowercase hexadecimal characters. This is not a hash of raw YAML or pretty ess compile output. Source |
Whole contract: whole-model contract_digest | SHA-256 of a compact, key-sorted construct payload. Bare 64 lowercase hex; the payload differs from the compiled-model hash input. Source |
Sliced contract: Constructs contract_digest | slice-sha256/2:<64 lowercase hex>, from the selected constructs and their dependency closure. The profile prefix is part of identity; a bare legacy slice digest requires regeneration. Source |
Delivery document: Digest | sha256:<64 lowercase hex>. Canonical delivery digest() methods hash pretty JSON including its final LF. Artifact/OCI digests can use the same spelling for different bytes. Source |
Realization: realization_digest | Prefixed SHA-256 of the compact specification/synthesis/implementations tuple in v1; v2 prepends ess-realization/2 to that tuple. Not the entire realization document. Source |
Infrastructure model: InfraIR digest | Bare SHA-256 of compact, key-sorted model JSON, excluding the envelope and observation provenance. Source |
Infrastructure intent: InfraSpec::digest(), projection provenance.specification_digest | Bare 64 lowercase SHA-256 of compact, key-sorted serialized typed InfraSpec: format, name and expectations, with no appended newline. Array order, including declared expectation order, remains significant. This differs from authored-file, InfraIR-model and whole-projection identity. Digest, consumer |
More columns: swipe horizontally, or focus the table and use the arrow keys.
A digest field identifies only the bytes its producer defines. Matching syntax does not establish that two digest domains are interchangeable, that a report covers its exact suite, or that a remote artifact has been fetched and verified.
Generated output state
ess-output-state/1 is a private checkpoint format for CLI generation, adoption and
recovery, introduced in 0.21.0. Its .ess-output directory binds an enrolled root to its fixed generator owners,
file inventory and any pending transaction. It is not part of a generated artifact's format or
model digest. Generated artifact bytes retain their existing identities.
The reader accepts canonical sorted-key JSON with a final LF and rejects unknown versions,
fields, duplicate keys, noncanonical bytes, unsafe paths and contradictory inventories.
UnixBytes1 encodes native path components as lowercase hexadecimal; it preserves native names
without interpreting them as UTF-8. File digests use lowercase SHA-256. The checkpoint checksum
covers its canonical payload without the checksum member and detects inconsistent bytes; it
does not authenticate another writer.
Recovery follows the recorded staging, prepared, committed or restored decision and retains it
until cleanup finishes. An unpublished state.next is not recovery authority. Preserve unknown
state and initialization entries for diagnosis. Older ESS versions have no reader or lock
protocol for this format.
A checkpoint with a pending transaction records the root's absolute path and directory identity,
and refuses at any other root. A settled (idle) checkpoint records neither, so a committed
.ess-output/state.json names nothing about the machine that wrote it. A settled checkpoint is
admitted in any root, the one that generated it or a clone or second worktree of it, when every
owned file present has its recorded length and digest, and refused otherwise, naming the
differing files and the route that re-enrolls the root.
ess-output-state/2 (added in 0.34.0) is /1 plus one required nonempty string, producer: the ess
release that last published into the root, as ess X.Y.Z. Every publication writes /2; the
reader accepts /1 without producer and /2 with it, and refuses either shape under the other
version. A publication that changes the root and finds a different recorded producer prints a
note: naming both releases. Recovery and adoption keep the producer they found. Releases before
/2 refuse a /2 checkpoint as an unsupported output-state version.
ess-output-state/3 is /2 with the root binding (root, directory) present only while a
transaction is pending. Every publication writes /3; the reader accepts /1, /2 and /3,
and refuses a /1 or /2 checkpoint without the binding, a settled /3 checkpoint with it and
a pending /3 checkpoint without it. A generation that finds a settled /1 or /2 checkpoint
rewrites it as /3 even when no file changes, keeping its owners and producer. With --check
it reports no drift for it and prints one warning naming root and directory. Recovery and
adoption settle as /3 too, keeping a recorded producer. A state.next left by an interrupted
run, which may hold a pending checkpoint and its binding, is never authoritative: a write-mode
command that finds the root settled removes it, and --check reports it. Releases before /3 refuse a /3 checkpoint before
writing: a settled one as an invalid output state missing root, a pending one as an
unsupported output-state version.
Design. See the generation workflow
for the filesystem assumptions and recovery command.
Directory input configuration
This format was introduced in 0.21.0.
ess-inputs.yaml declares one format: ess-inputs/1 document with exactly three required fields:
format, specification and scenarios. The latter two are lists of strings. Nulls, wrong types,
unknown fields, duplicate mapping keys, multiple YAML documents and other format versions refuse.
This is optional immediate-directory acquisition configuration, not an authored ESS fragment or a
persisted IR. Pass its containing directory; passing the file itself keeps ordinary direct-file
reader behavior. Reader.
Each path is a nonempty UTF-8 identity relative to that root. Split on /: empty, . and ..
segments refuse, as do backslashes, colons and control characters. Case and Unicode are preserved;
* is a literal filename character. Duplicates within either list and the same spelling across
roles refuse. There are no globs, includes, remote expansion or inherited configuration.
Only the active role resolves filesystem entries. Its list must be nonempty. The root, manifest,
selected files and intermediate directories below that root must not be symlinks; selected inputs
must be regular files whose canonical targets stay inside the root and are not repeated. Inactive
paths receive structural checks only and may name missing files. Unlisted files are not enumerated,
inspected or read. ess specify validate treats a nonempty scenarios list as active beside
specification, so its files must exist and compile against the model. Distinct copied or
hardlinked files retain separate identities and can trigger existing semantic duplicate refusals.
Selected original UTF-8 text is retained without newline conversion. Entries are read in sorted identity order. Model Source/SourceMap and suite/5 source identities are the listed relative paths; suite/4 keeps a readable joined origin label. The manifest has no canonical writer or raw-file hash contract and is not added to EssIr, suite provenance or suite/5 authored sources. Source-byte and semantic digests keep their existing, separate meanings.
An invalid reserved filename refuses without legacy fallback. Rename an older ESS fragment named
ess-inputs.yaml or adopt this configuration. Older readers do not understand this format and
refuse it; some old conformance semantic-refusal paths can retain incomplete diagnostic outputs.
The direct-file, recursive-model (system.yaml) and shallow-scenario layouts remain supported when
configuration is absent. Manifest selection does not infer generation, authorship or ownership.
The named ESS model describes the closed fields, singleton format enum, lists and string values. Its projection does not enforce complete path grammar, cross-list uniqueness, active-role cardinality, filesystem facts, deterministic acquisition or exact source-byte custody. The CLI reader owns those checks; declaration validation alone is not discovery evidence.
format: ess-inputs/2 (added in 0.34.0) is /1 plus one optional string, requires: ess X.Y.Z for
exactly that release, or ess X.Y for any X.Y.*. Components are decimal without leading zeros;
any other spelling refuses. requires in a /1 document refuses, naming /2. An ess older than
the requirement refuses before any selected file is read and names b10x upgrade and
/ess:upgrade; a newer one warns once per command, and the global --strict-requires makes that a
refusal. /2 without requires behaves exactly as /1. Releases before /2 refuse it as an
unsupported format. The named model admits the field and both versions; the version grammar and
the /1 exclusion are the reader's.
Design.
Specifications and implementation plans
“Closed DTO” below means unknown fields are refused. The named compile or validation step still checks semantics. “Pretty JSON” means the writer's deterministic rendering with a final LF unless the row says otherwise; it does not imply that those bytes are hashed.
| Document and discriminator | Version/identity carried separately | Reader and byte contract |
|---|---|---|
Authored specification: format: ess/1 … ess/5 | Specification vN | RawSpecFile::parse, assembly/validation and compilation. Binary64 requires major 2 or later at every declared position; map keys refuse. Major 3 (0.23.0) adds bounded binding accessors, ordered list selection, periodic host causes, subject-state guards and clock-reading attachments; earlier source formats refuse those declarations. Major 4 (0.23.0) adds error naming, typed command responses and explicit emitted-payload ownership; majors 1–3 preserve sparse payload semantics. Major 5 (0.27.0) lets an enum variant declare its own wire, display, summary and code; majors 1–4 refuse a variant that declares naming. No canonical raw-source hash. Source, version history |
Authored specification: format: ess/6 | Specification vN | Added in 0.28.0. External eligibility predicates, observed subject-history selection and silent subject preservation. Earlier source formats refuse these declarations. Source |
Authored specification: format: ess/7 | Specification vN | Added in 0.29.0. Command-local retained-result replay and effect-free default state refusals. Origin references, identity authority, exclusivity and finite state coverage are validated; exact replay observation refuses recursive Decimal/Binary64 response positions. Source |
Authored specification: format: ess/8 | Specification vN | Added in 0.34.0. String predicate operators starts_with, ends_with and contains, map form only, over String and newtypes of it in every predicate position. Earlier source formats refuse them as unsupported_format_version. A model that uses none keeps its IR bytes and digest. Predicates |
Authored specification: format: ess/9 | Specification vN | Added in 0.34.0. when_subject: {predicate: …} guards an outcome by a predicate over the existing subject's declared stored fields, beside the unchanged {field, equals}; a refusal may carry it and reads the subject its siblings name. Earlier source formats refuse the predicate form; {field, equals} documents keep the format they were written in, and their bytes. Source |
Authored specification: format: ess/10 | Specification vN | Added in 0.34.0. Aggregate views: a view field may declare aggregate: (count, count_distinct, sum, min, max, avg) and a view may declare group_by: over its other fields. The filter runs per source row, admitted rows are grouped, and empty groups are absent; an ungrouped aggregate view returns one row. avg is Optional<Decimal>, rounded to 6 places half-even. Earlier source formats refuse the construct as unsupported_format_version; a model without it keeps its IR bytes and digest. Source |
Authored specification: format: ess/11 | Specification vN | Added in 0.34.0. A String newtype may declare alphabet:, an input may declare example:, and .count on a String is its length in Unicode scalar values. Earlier source formats refuse each construct as unsupported_format_version; a model without them keeps its IR bytes and digest. Source |
Authored specification: format: ess/12 | Specification vN | Added in 0.34.0. Outcome groups: a top-level outcome_groups: declares one external refusal (external: and error:) once for a commands: list, an actor: or a domain:, with except: beside a selector. Expanded into each member before validation, after its own outcomes and in group-name order; a same-named outcome in a member, or from two groups, is refused. A group and its hand copy compile to identical IR. Earlier source formats refuse a group as unsupported_format_version; a model without one keeps its IR bytes and digest. Source |
Authored specification: format: ess/13 | Specification vN | Added in 0.35.0. A command may declare fixture_inputs:, mapping a declared input field to a lower-kebab fixture name whose type is that input's type. Conformance resolves those values from an independent provider before the scenario starts; the input's requests and its event-value assertions use the same copied value. A fixture input read by an outcome predicate, naming an undeclared input or a scenario-owned subject, or reused under a different type is refused. Earlier source formats refuse the key as unsupported_format_version; a model without it keeps its IR bytes and digest. Source |
Authored specification: format: ess/14 | Specification vN | Added in 0.36.0. Value expressions in payload: and sets:: {subject: <field>} (the addressed entity before the outcome, on moves: and updates:), {increment: <number>} (a sets: source over a required Integer or Decimal), {input: <field>, else: {generated: true}} (an optional input, or a minted value), a nested mapping for a struct-typed target, and {generated: true} in sets:. Earlier source formats refuse each as unsupported_format_version; a model without them keeps its IR bytes and digest. Source |
Authored specification: format: ess/15 | Specification vN | Added in 0.37.0. Outcome shapes (unknown_instance:, deletes:, into:, accepts: nothing, system preconditions:), input. operands in when_subject predicates, equals_ignore_case / in_ignore_case, skip_absent aggregates and Optional group keys, prefix: on String newtypes, the Json primitive and field presence:. Earlier source formats refuse each as unsupported_format_version; a model without them keeps its IR bytes and digest. Source |
Authored specification: format: ess/16 | Specification vN | Added in 0.38.0. Literal fallbacks after else:, defined()/missing() over optional structs, lists and maps, input_absent:, {related: …} value sources, the now operand, existence-selected outcomes (unknown_instance: beside an update, existing_instance:), actor attributes: and caller reads, bounded binding retries, view paging:, and set effects (instances:, affects:, {count: changed}). Earlier source formats refuse each as unsupported_format_version; a model without them keeps its IR bytes and digest. Source |
Authored specification: format: ess/17 | Specification vN | Added in 0.39.0. returns: true declares a successful typed command return without claiming persistence or absence of side effects. It requires a nonempty response and cannot accompany an error, accepts: nothing or replays. Earlier formats refuse it; a model without it keeps its bytes and digest. Source |
Authored specification: format: ess/18 | Specification vN | Added in 0.41.0. A list of held states in when_subject_state:, and when_subject_state: on a refusal that names no subject, which reads the subject its siblings name (beyond10x/ess#201); state, the held lifecycle state, in a when_subject predicate (beyond10x/ess#204); when_related:, a guard over the row of another entity named by an input field (beyond10x/ess#211); a binding's delivery context, when.context_fields and when.context_authority, read as context.<field> (beyond10x/ess#195). Earlier source formats refuse each as unsupported_format_version; a model without them keeps its IR bytes and digest. Source |
Authored specification: format: ess/19 | Specification vN | Added in 0.46.0. payload: sources for the fields of the error an outcome reports, in a block keyed by the error, taking the sources an event payload takes; a field the error does not declare and a source of another type are refused (story:error-payload-sources). Earlier source formats refuse each as unsupported_format_version; a model without them keeps its IR bytes and digest. Source |
Authored specification: format: ess/20 | Specification vN | Added in 0.49.0. state, the related row's held lifecycle state, in a when_related: predicate, typed by the related entity's lifecycle (beyond10x/ess#229). Earlier source formats refuse each as unsupported_format_version; a model without them keeps its IR bytes and digest. Source |
Authored specification: format: ess/21 | Specification vN | Added in 0.53.0. Outcome-local one_time_response: [field] marks required String response fields, including transparent constrained String newtypes, on a successful returns: true outcome. Plaintext is disclosed only at its originating response position and must never be redisclosed; retained replay and declared plaintext output flows are refused. Omitted policy preserves legacy bytes. Structural projections retain the policy and implementation obligations; code targets without durable issuance support refuse it by name. Source |
Authored specification: format: ess/22 | Specification vN | Added in 0.53.0. A when_related: guard's via: input.<field> may name an Optional<…> input of the other entity's identity (beyond10x/ess#304); the guard is checked only when present, and an absent reference reads no row and selects no when_related branch. Earlier source formats refuse it as unsupported_format_version naming ess/22; a model without it keeps its IR bytes and digest. An affects: entry may move the records it selects, moves: <Entity>.<transition>, skipping a selected record outside the move's from states (beyond10x/ess#229); earlier source formats refuse it at affects[<n>].moves as unsupported_construct naming ess/22, and a model without it keeps its IR bytes and digest. A union variant may carry no payload (Open: or Open: ~, beyond10x/ess#418): the IR writes it null and its value is the tag alone; earlier source formats refuse it as unsupported_format_version naming ess/22, and a union without one keeps its IR bytes. Source |
Authored specification: format: ess/23 | Specification vN | Added in 0.54.0. An updates: that writes the entity's identity re-keys the record, with a declared collision refusal (beyond10x/ess#429); {subject: state}, the lifecycle state held before the outcome, as a value (beyond10x/ess#458); deletes: with instances:, and deletes: <Entity> in an affects: entry (beyond10x/ess#452); typed enum variant attributes:, read as <fact>.<attribute> (beyond10x/ess#450); an affects: entry that writes one record per element of an input list, each: (beyond10x/ess#459); and the synthesis of state-predicate refusals, of row-set selectors beside an addressed record and of struct-identity member selectors (beyond10x/ess#461, #462, #463). Below ess/23 each keeps the answer it had; the version history says what each admits and refuses. Source |
Authored specification: format: ess/24 | Specification vN | Added in 0.58.0. undeclared_fields: ignored on a kind: struct type, and on a command with a non-empty response:, where it governs the response only: the record admits fields it does not declare, and every declared field stays required and typed (beyond10x/ess#500). refused is the default. The key is refused by name on a command without response: (missing_declaration) and on every other declaration (unsupported_construct), and earlier source formats refuse it as unsupported_format_version naming ess/24; a model without it keeps its IR bytes and digest. Source |
Authored specification: format: ess/25 | Specification vN | Added in 0.60.0. A create-or-update command may select among its update branches with when_subject: predicates over the stored row's fields and held state beside an unknown_instance: branch that creates: the row (beyond10x/ess#530): the creating branch answers an identity no row carries, and the predicates must partition the stored rows alone. Earlier source formats keep refusing the pairing as conflicting_declaration, its hint naming ess/25; a model without it keeps its IR bytes and digest. An outcome with instances: may publish an event once per changed row, {event: <name>, each: changed, when_state: …} in emits:, its payload reading the row with {changed: …} (beyond10x/ess#531). An external: refusal may declare before_row: true (beyond10x/ess#534): it answers among the input-guarded refusals, before existence and the held state; earlier source formats refuse the key as unsupported_format_version naming ess/25, and a model without it keeps its IR bytes and digest. A command guard may wrap a text operator in trimmed:, compared with the fact's surrounding ASCII whitespace removed (beyond10x/ess#532); earlier source formats refuse it as unsupported_format_version naming ess/25. Source A view selected by identity may declare absent: {row: …}, its default row for an identity no row carries (beyond10x/ess#533); earlier source formats refuse the key as unsupported_format_version naming ess/25, and a model without it keeps its IR bytes and digest. |
Authored specification: format: ess/26 | Specification vN | Added in 0.62.0. A named external: refusal of a command that addresses an existing row, before_row: true included, compiles with complete_refusal: its scenario snapshots the complete row before forcing the branch and requires it unchanged afterwards (beyond10x/ess#587). No key is added; below ess/26 the IR and the suite keep their bytes. Source |
Authored specification: format: ess/27 | Specification vN | Added in 0.63.0. A binding condition and a binding selection compare a Boolean leaf with true or false (downstream report, 2026-10-18); the condition's IR read of such a leaf is {kind: boolean}. Earlier source formats refuse the comparison as unsupported_format_version naming ess/27, and a model without it keeps its IR bytes and digest. A command guarding on a related row (when_related:) may declare an unknown_instance: branch for the row its input addresses, answered at step 3 of the precedence order, after an exists: false over the related row and before its predicate refusals. No key is added; below ess/27 the pairing is refused as conflicting_declaration naming ess/27, and every older document keeps its IR and suite bytes. shorthand: <field> on a kind: struct type: a value of the struct may be written as that field alone, a required scalar field beside only Optional ones, and its JSON Schema is oneOf the field's schema and the struct's object, closed unless the struct declares undeclared_fields: ignored, annotated x-ess-shorthand (beyond10x/ess#594). The key is refused by name at <type>.shorthand when the field is undeclared, not a required scalar or beside another required field, as unsupported_construct on every other declaration, and below ess/27 as unsupported_format_version naming ess/27; a model without it keeps its IR bytes and digest. A minted value may be required present, {generated: true, present: true}, and a sets: entry may store the value its own outcome publishes, {payload: <Event>.<field>} (beyond10x/ess#545); earlier source formats keep reading both as nested mappings. An actor may declare system: true and a command every grant of which is such an actor is system-issued, awaited by conformance rather than invoked, with an optional await_within: PT<seconds>S (beyond10x/ess#542). A value may read the head of an ordered selection, {related: {entity, where, order_by, first}} (beyond10x/ess#543). A set effect's filter may read the candidate row's identity (beyond10x/ess#547), and a selector's where: may read a value its own outcome publishes, payload.<Event>.<field> (beyond10x/ess#549). A value may be computed by an expression, {expr: "<expression>"}, in sets: and payload:, and a view field from its source row with expr: (beyond10x/ess#560); below ess/27 the mapping keeps its nested-mapping reading. Earlier source formats refuse each new key or shape as unsupported_format_version naming ess/27, or keep the reading they had; a model without them keeps its IR bytes and digest. Source |
Authored specification: format: ess/28 | Specification vN | Added in 0.64.0. A value may read the lifecycle state of the row a reference names, {related: {via, field: state}} (beyond10x/ess#557). A view may read the row a reference of its source names, one hop, as that row is when the view is read: a field field: {related: {via: <reference>, field: <field | state>}}, typed Optional, and a filter path <reference>.<field> (beyond10x/ess#564). A branch may require several related rows at once, when_related: {all: [{via: input.<field>, predicate: …}, …]}. A when_related: guard may read an input typed List<…> of one entity's identity, {via: input.<list>, exists: false}, taken when some element names no row, its payload reading the first such element with {missing: input.<list>} (beyond10x/ess#558). Earlier source formats refuse each new key or shape naming ess/28, or keep the reading they had; a model without them keeps its IR bytes and digest. Source |
Authored specification: format: ess/29 | Specification vN | Added in 0.67.0. A command outcome's guard may call a function of one fact on the left of a compact comparison, coalesce(is_error, true) == false, so a guard over an Optional says what an absent value compares as (beyond10x/ess#620). An external: branch may carry when_subject: {predicate: …}, narrowing it to the records the predicate selects; a guarded branch declared after one a later step of the one precedence rule answers is refused as conflicting_declaration (beyond10x/ess#554). Earlier source formats refuse each new spelling naming ess/29, or keep the reading they had; a model without them keeps its IR bytes and digest. Source |
Authored specification: format: ess/30 | Specification vN | Added in 0.68.0. A command reading the row a stored reference names may leave out its exists: false branch where every write of the field checks the row first and no branch deletes a row of the referenced entity; the suite then reads that row again after every accepting branch writing either entity, under the existing invariant scenario (beyond10x/ess#509). A selector's where: may compare coalesce(<field>, <literal>) of a candidate's field with a literal (beyond10x/ess#627). An authored scenario may state an exact value for a {generated: true} field its earlier steps determine, and an external: race narrowed by when_subject: may declare compensates: true (beyond10x/ess#623). The where: of instances: and of an affects: entry may read the candidate row's state (beyond10x/ess#564), and a view's filter: may order a Timestamp field against now, the instant of the read (beyond10x/ess#560). No suite format moves. Earlier source formats refuse each new spelling naming ess/30, or keep the reading they had; a model without them keeps its IR bytes and digest. Source |
Authored specification: format: ess/31 | Specification vN | Added in 0.69.0. A sets: entry may store the empty list [] in a required List<…> field, and may append one input element to a stored list, {append: input.<field>}. An input of List type may carry an example:, which synthesis sends at the plain instance where no guard reads into the list. A field's presence: may be omitted_or_null, the member left out or sent as null and both read as one absent value, and a view field written field by field carries its source field's presence: (beyond10x/ess#677). Earlier source formats refuse each new spelling naming ess/31, or keep the reading they had; a model without them keeps its IR bytes and digest. Source |
Authored specification: format: ess/32 | Specification vN | Added in 0.70.0. A command may guard on rows its input names, when_related: {via: input.<field>, …}, beside a row-set guard, when_related: {entity, where, …} (beyond10x/ess#554). A struct may declare fields: [], open or closed (beyond10x/ess#649). A lifecycle state may declare its wire spelling, states: [{name: Indexing, wire: indexing}], and two variants of one enum spelled alike on the wire are refused as conflicting_declaration (beyond10x/ess#639). Earlier source formats refuse each new spelling naming ess/32, or keep the reading they had; a model without them keeps its IR bytes and digest. Source |
Authored specification: format: ess/33 | Specification vN | Added in 0.78.0. An input typed as a struct, a Map<…> or Json may carry an example:, which synthesis sends at the plain instance, and an open struct's example keeps the members it does not declare. An entity may declare provided: true, the deployment holding its rows, and synthesis resolves such a row as an entity fixture where no declared outcome creates it. A lifecycle transition may carry a one-line summary:, and a state may carry one in its mapping form, {name, wire?, summary?}. Earlier source formats refuse each new spelling naming ess/33; a model without them keeps its IR bytes and digest. Source |
Compiled EssIr: unversioned | Numeric specification major | Compiler-minted, Serialize-only; no general persisted-IR reader. Pretty JSON output; compiled-model digest uses compact bytes instead. The TypeScript and Go conformance packages carry those compact bytes plus one LF as essconform/ir.json (since 0.34.0), read only by the emitted explorer, which refuses the file unless its SHA-256 without the final LF equals suite.json's provenance.spec_digest. Optional replay/retained-result metadata is omitted for legacy models. There is no current ess-ir/1 marker. Source |
Authored composition: format: ess-composition/1 with a services array | Composition/service keys, system/version, selected component and exact compiled-model digest | Closed JSON/YAML DTO, then compile checks identity and selected-surface membership against supplied services. Pretty canonical JSON; no whole-composition digest. Source |
Compiled composition: format: ess-composition/1 with a services map | Resolved imported model identities, components and selected named references | Serialize-only compiler output; no complete payload or codec definitions. The authored reader does not read this shape. Pretty JSON; model digests remain references. Source |
Authored composition: format: ess-composition/2 | The services and references of the earlier format, plus conformances | Added in 0.38.0. A reference may name any type declared in a domain the selected component owns. conformances: entries (local: and conforms_to:, each {service, type}) assert that a consumer's type has an imported type's shape: same field names and wire names (and enum variant wire spellings), the same presence where both fields are Optional, conforming types, compared recursively through named types; a local value may be Optional where the imported one is required, nothing else may differ. Drift is refused as type_conformance_drift, naming both types and every differing field. An earlier-format document carrying conformances, even empty, is refused as unsupported_format; earlier-format documents keep their meaning and their compiled and client-plan bytes. Source |
Compiled composition: format: ess-composition/2 | As /1, plus the checked conformances | Serialize-only. The compiled format echoes the authored one; owner-declared types are referenceable but are not added to the service's types or the client plan. Source |
Authored composition: format: ess-composition/3 | As the earlier format; a conformances entry may add reader: true | Added in 0.40.0. A reader entry asserts that the consumer's type reads every value the imported type allows, so beyond the earlier rule it may read an imported newtype (through any chain) as what it wraps, an enum as String (Optional<String> where the imported enum is optional), enum variants by wire name with every imported wire name present, a value that is always a JSON object (a struct, or a map with String keys) as Map<String, Json>, and a subset of a struct's fields: an extra local field is compared with the imported field that shares its wire name, omitted or not, and one that meets none must be Optional and not null_when_absent. Anything that could reject an imported value (a different primitive, a missing wire name, a local field required where the imported one may be absent, Json read as any map, an extra field reading an imported key as another type) stays type_conformance_drift. reader: true also asserts that the consumer's reader ignores keys it does not declare; ESS-generated closed types (additionalProperties: false, deny_unknown_fields) do not, so a consumer reading through them must not use reader for a field subset. An entry without reader is compared exactly as before. An earlier-format document carrying reader, whatever its value (null included), is refused as unsupported_format; earlier-format documents keep their meaning and bytes. Source |
Compiled composition: format: ess-composition/3 | As the earlier format, with each checked conformance's reader as authored | Added in 0.40.0. Serialize-only; the compiled format echoes the authored one, and the client plan is unchanged. Source |
Authored composition: format: ess-composition/4 | As the earlier format, plus roles | Added in 0.60.0. A roles: entry (service:, plays:, both service keys of the composition, and optional commands:) says that the component service selects plays the component plays selects, and which local command stands where in that contract: each command entry is {local, stands, contract}, stands being implements or gates; any other value is refused when read. Both commands must be on their selected components' accepts surfaces (unresolved_semantic_reference or reference_outside_component, the detail naming roles[i].commands[j].local or .contract). An implements entry compares inputs: every contract input field must be a local input field of the same wire name and a conforming type, compared as a type conformance compares fields, and a local input the contract does not declare must be Optional and not null_when_absent; a difference is role_input_drift, naming every field. A gates entry compares no inputs; the ordering is recorded, not executed. A key that is not imported is unknown_role_service; a role playing its own service, a repeated role or a repeated command entry is conflicting_role. An earlier-format document carrying roles, even empty, is refused when read as an unknown field; earlier-format documents keep their meaning and bytes. Source |
Compiled composition: format: ess-composition/4 | As the earlier format, plus the checked roles | Added in 0.60.0. Serialize-only. Roles and their command entries keep document order; each role's service and plays carry the key, system, version, digest and component it was checked at. roles is omitted when empty, and the client plan is unchanged. Source |
Authored composition: format: ess-composition/5 | As the earlier format; a conformances end may name an event, an error, or a command's input or response | Added in 0.76.0. An end is {service, <kind>: <name>} with exactly one of type, event, error or command; a command end also carries part: input or part: response. Two kinds, no kind, a command end without part and part on another kind are refused when read. An event, error or command end must be on its selected component's surface (reference_outside_component); only a type end may name a type the owned domains declare. A payload (an event's or an error's fields, a command's input or response) is compared as a struct with those fields, against another payload or a struct type, by the field rules above, reader: true included; a newtype, enum or union against a payload is type_conformance_drift. A response end on a command that declares no response: is unresolved_semantic_reference. reader and roles stay admitted. Under an earlier format an event, error, command or part key is refused when read as an unknown field, naming /5; a type end reads and writes {service, type} as before, so earlier-format documents keep their meaning and bytes. Value constraints and variant attributes are compared too: newtype alphabet, prefix and invariants, struct invariants (an alphabet as a set of characters, invariants by parsed predicate split at conjunctions, so neither spelling, order nor grouping into invariants matters) and enum variant attributes and their values must agree; a reader: true end may state a wider alphabet, a shorter prefix the owner's starts with, and a subset of the invariants and attributes. Earlier formats compare none of these. Source |
Compiled composition: format: ess-composition/5 | As the earlier format, with each conformance end as authored | Added in 0.76.0. Serialize-only; a type end is written {service, type}, a payload end {service, event}, {service, error} or {service, command, part}. Conformance ends are not added to the surface, so the client plan is unchanged. Source |
Client plan: format: ess-client-plan/1 | Composition key and the same selected service metadata/names | Derived from compiled composition; Serialize-only. No complete payload or codec definitions. Pretty JSON; no client-plan byte digest or live service identity check. Source |
Authored UI document: format: ess-ui/1 | Application name (app) and the ESS system its views, commands and events resolve against (model) | Added in 0.47.0. Defined as data in schemas/ui/ess-ui.schema.yaml (reference). The loader expands every short form, merges each page over its page kind and each widget instance over its widget, and reads the result into typed Rust, refusing an undeclared key with the path of its node. No document digest. |
UI check report: format: ess-ui-check/1 | The document checked (document) | Added in 0.47.0. Written by ess ui check --format json: {format, document, findings}, each finding {path, check, severity, message} with path the failing node's canonical path, check one of the checks the schema's checks.list declares or the checker adds, and severity error or warning; findings ordered by path, then check. Serialize-only; no digest. |
UI test file: format: ess-ui-test/1 | The document tested (document, relative to the file) and each test's name | Added in 0.48.0. Read by ess ui test: tests of one-key steps that select nodes by canonical node path (reference). Unknown keys and steps are refused with the file, test and step. No digest. |
UI test report: format: ess-ui-test-report/1 | The document tested (document) | Added in 0.48.0. Written by ess ui test --format json: {format, document, tests}, each test {name, status, step?, message?} with status passed or failed and step the failing step, from 1; tests in file order. Serialize-only; no digest. |
Authored realization: type: ess-realization/1 | Realization id and specification/synthesis identities | Closed JSON/YAML DTO, then compilation against supplied ESS authority. No raw-document digest contract. Source |
Compiled realization: type: ess-realization-ir/1 | Same identities plus realization digest | Serialize-only compiled output. Pretty JSON; realization tuple digest. Source |
Authored realization: type: ess-realization/2 | Realization id and specification/synthesis identities | Opt-in implementation-only selection: empty entrypoints allowed only without actors or conformance claims. Nonempty entrypoints retain v1 rules. Closed DTO and semantic compilation; v1 readers reject this version. Source |
Compiled realization: type: ess-realization-ir/2 | Same identities plus version-separated realization digest | Serialize-only compiled output; pretty JSON. V1 canonical bytes and identity remain unchanged. Source |
Authored transport: type: ess-transport/1 | Specification identity (system, version, sha256: source digest) | Closed JSON/YAML DTO binding events to a broker, subject, envelope, delivery and capturing stream; compiled against the supplied ESS. Refusals ESS-TRANSPORT-001–016. Source |
Compiled transport: format: ess-transport-ir/1 | Same specification identity | Serialize-only compiled output; pretty JSON, every collection ordered. Read by ess generate --kind asyncapi --transport. Source |
Authored transport: type: ess-transport/2 | Specification identity | Added in 0.53.0. The previous version plus an optional per-channel parameters map from each whole-token {name} address expression in subject to a required String event path (event.<field>, up to three members through required structs). A reader of the previous version refuses it, and this reader refuses parameters in a document of the previous version. A parameterized subject must have exactly one capturing stream for every expansion and no overlapping one, and refuses a literal event naming.wire. Refusals ESS-TRANSPORT-001–020: 017 a malformed or embedded address expression, 018 a missing, unused, empty or repeated mapping, 019 a source that is not an admitted event. path, 020 a source that is not a required String through required structs. Source |
Compiled transport: format: ess-transport-ir/2 | Same specification identity | Added in 0.53.0. Compiled from ess-transport/2: the previous compiled version plus, on a parameterized channel, parameters ordered by name, each a tagged {kind: event_path, path} with semantic field names. Serialize-only; recompilation is byte-identical. Source |
Authored HTTP binding: type: ess-http/1 | Specification identity (system, version, sha256: source digest) | Added in 0.60.0. Closed JSON/YAML DTO binding commands and views to routes: each names one command or view, a lower-case method, and optionally a path template and parameters; a route without a path is open. An optional refines: sha256:<hex> pins the bytes of the binding it fills in, supplied with --refines; it may fill in an open path and add routes, and may not change a fixed method or path or drop a route. Compiled against the supplied ESS by ess specify http. Every object refuses an unknown key by name. Path templates take variables only as whole segments {name}, each mapped to one input.<field> or param.<name> of a type a segment carries, and no source read by two variables. A command route may declare request: {encoding: json | form | query, unknown: refuse | ignore} (stage 2 of the format): form is a form-encoded body, query carries every unmapped input field in the query string and is the only encoding a get command may write and one a delete command may write, ignore is admitted beside form and query only, and a form or query field is a scalar, an Optional scalar or a List of scalars; a view takes no request. A command route may list outcomes: {<outcome>: {status, body}}: a status from 100 to 599, never 1xx, a 2xx only on an outcome without an error and a 4xx or 5xx only on one with an error, a 3xx only 301, 302, 303, 307 or 308; a body envelope (the default), response (a returns: true outcome without an error), response.<field> (one non-Optional field of such an outcome's response, answered bare; added in 0.69.0), none (required on 204) or {<member>: error} (an outcome with an error); two outcomes on one status must be told apart by their bodies, or as two redirects by a parameter one always writes (its source not Optional) and the other never writes or by distinct error wire names both write under one parameter from error.wire, an unlisted outcome counting at its derived status with envelope. A command route may declare errors: (added in 0.69.0), one answer with the keys of a listed outcome for every outcome with an error the route does not list; a listed outcome wins, a response or response.<field> body is refused under it, and errors on a view or on a route with no unlisted error outcome is ESS-HTTP-022. A listed outcome may declare encoding: text (added in 0.77.0) beside a response.<field> body naming a String field (a newtype of one counts), answered as the string alone, text/plain; charset=utf-8; text anywhere else, and any encoding but json and text, is ESS-HTTP-024. A command route may declare alike: [[<outcome>, …], …] (added in 0.77.0): groups of two or more of its outcomes, each with a declared answer, whose answers (status, body, encoding, headers, redirect) are equal and that the wire does not tell apart (no envelope body, no error objects under distinct wire names or over errors whose fields differ, no header reading error.wire under distinct wire names); two outcomes in one group are not refused as indistinguishable, a group whose answers differ or that the wire tells apart is ESS-HTTP-025, and an unknown name, a name in two groups or twice, a group of one, a name with no declared answer and alike on a view are ESS-HTTP-022. A view route may declare body: single with empty: {status: <4xx>} when its filter selects the source entity by identity and it is not paged; from 0.77.0 empty also takes a body of none (the default) or {<member>: {literal: <text>}}, and a view route that is not paged may declare body: array, its rows as a bare JSON array. Top-level refusals: overrides malformed and not_granted with a 4xx and unfinished with a 5xx, each with status and a body of none or {<member>: {literal: <text>}}; from 0.77.0 a route may declare its own refusals: with the same keys and checks, standing in place of the top-level entries on that route alone. An outcome and a refusal may declare headers: {<Name>: …}, each name an RFC 9110 token other than Connection, Content-Type, Content-Encoding, Content-Length, Transfer-Encoding and Location, once ignoring case, each value {literal: <text>} (a field value), {source: <path>} (input.<field>, response.<field>, error.<field> or error.wire, a scalar or Optional scalar the outcome supplies, error.wire only when the error's wire name is a field value; never on a refusal) or, under WWW-Authenticate only, {challenge: {scheme, params}} with token names and literal or source params, each a text a quoted string carries; every 401 declares a challenge. A 301, 302, 303, 307 or 308 outcome declares redirect: {location, mode: query | fragment, parameters} with body: none, its location a String source, never Optional and never error.wire, each parameter name one or more RFC 3986 unreserved characters, and no other status declares one. A refinement restates each refined route's request, outcomes (with their headers and redirect), errors, body and empty, and refusals:, and, from 0.77.0, each listed outcome's encoding, the route's alike, its empty body and its own refusals:. Refusals ESS-HTTP-001 to 014, 020 (request encoding), 021 (a field without a flat spelling), 022 to 025 (outcomes, statuses, bodies, distinguishability), 026 (headers), 027 (challenges), 028 (redirects), 029 (refusals), 030 and 031 (single views), 032 (operation ids) and 033 (servers); the refined binding's own refusals are keyed under refined.. A route may declare operation_id (added in 0.76.0), its OpenAPI operationId: [A-Za-z_][A-Za-z0-9_.-]*, unique in the binding and never another operation's qualified name, kept by a refinement once fixed. Top-level servers: {<component>: [{url, description}]} (added in 0.76.0) lists a reached_by: network component's base URLs in order, each absolute http(s):// with a host or /-rooted, without whitespace, {, }, query, fragment or userinfo, once per component; a refinement does not compare it. Source |
Compiled HTTP binding: format: ess-http-ir/1 | Same specification identity | Added in 0.60.0. Pretty JSON; refines records the refined binding's digest and is absent when it refines nothing; routes ordered by path (an open route first), then method, then operation, and parameters ordered by variable, each a typed source; a route's request records encoding and unknown only where they differ from json and refuse, and is absent when both are defaults, so a binding without request keeps its 0.60.0 bytes; a command route's outcomes holds each listed outcome by name with its status and its body unless envelope, and its errors holds that one answer in the same shape and is absent when not declared, an outcome's encoding is written only when it is text, a command route's alike follows errors, each group's names in name order and the groups in the order of their first names, and is absent when not declared, a view route records body: single with its empty, whose body is written only when it is not none, or body: array, and omits rows, a route's own refusals follows its empty, held by key as top-level refusals holds each override, by key with status and body, and is absent when the route states none, an outcome or refusal's headers, a challenge's params and a redirect's parameters are ordered by name, each name as authored, and each is absent when empty, so a binding using none of them keeps its 0.60.0 bytes; derived_routes holds the route ESS derives for every operation the binding does not name, ordered by component, path, method and operation, and is absent when empty; a reader refuses, naming the key, any of these out of its order and IR that breaks what compiling guarantees without the specification (an operation routed twice, a derived route for a routed operation, a derived path with a variable, parameters that disagree with their path, encoding: json written out or text beside any body but response.<field>, an alike written empty or whose group's answers differ or hold an envelope); recompilation is byte-identical. A route's operation_id follows its operation key and top-level servers follows refusals, ordered by component, each list in the order written; both are absent when not declared, so a binding without them keeps its bytes, and a reader refuses an id outside the grammar or given twice, components out of order, an empty list and a URL outside the rule. Read by ess generate --kind openapi --http, which refuses a binding with an open route. Source |
plan.json: unversioned SynthesisPlan | Specification provenance | Neutral generated plan, consumed as a typed value by emitters. Pretty JSON and PLAN.md; compiled-model/whole-contract references, no plan-file hash. Source |
target.json: unversioned TargetReport | Target name and specification provenance | Successful Go/Web/Clap synthesis includes this refusal/weakening report; successful Rust has target: None and no target metadata. No persisted admission reader. Unchanged pretty JSON and TARGET.md; provenance references, no report-file hash. Source |
Complete failure: format: ess-target-failure/1 | Target rust or web; unchanged neutral plan and its provenance | Serialize-only TargetFailure has format, target, plan, nonempty causes; private construction, read-only accessors, no Deserialize/admission reader. Typed pretty JSON+LF or CLI YAML; no failure-file digest or artifacts. Source |
Complete failure: format: ess-target-failure/2 | Target go or clap; unchanged neutral plan and provenance | Located finite Binary64 codec refusal, or Go missing-type-owner refusal, with the same failure fields and no artifacts. Rust/Web keep target-failure/1. Source |
Complete failure: format: ess-target-failure/3 | Target and originating model provenance | Added in 0.23.0. Selected for accessor/selection plans, periodic causes or clock-reading attachments, including early failures. Includes bounded-output and required-periodic-host causes. Same envelope fields and no artifacts. Legacy models retain /1 or /2 output. Source |
More columns: swipe horizontally, or focus the table and use the arrow keys.
Composition selects commands from the component's accepts and views from its owned domains.
Its named-type traversal covers command inputs, event/error fields and query row shapes/fields,
but not view parameters; from ess-composition/2 a reference may also name any type the
component's owned domains declare, without adding it to that traversal. The imported digest
identifies compiled semantics, not raw YAML, plan bytes or a running endpoint. The generated
Rust client restricts normal callers to selected
operation descriptors while forwarding &[u8] requests and Vec<u8> responses unchanged through
Transport<Authority>. Provider injection adds no authority verification or live model handshake;
the client does no payload admission, decoding or sanitization.
See the executed Todo example,
where both a String title and an incompatible numeric title reach the same selected command.
ess_synth::synthesize and synthesize_for return Result<Synthesis, TargetFailure>.
The direct rust::workspace and web::workspace APIs return Result<Vec<Artifact>, TargetFailure>
and Result<web::Emission, TargetFailure> respectively. Go and Clap workspace APIs
now also return Result<Emission, TargetFailure> in ESS 0.20.0. Rust checks allocation and representation
before rendering; Web checks its Rust prerequisite and Web codec allocation. Err withholds the
whole requested workspace, even if some modules could be emitted. Ok retains the existing
Synthesis fields and neutral plan bytes; partial Go/Web/Clap reports remain successful values.
Synthesis itself has no serialized envelope.
Facade, Rust, Web.
Each failure cause has a code, nonempty sorted unique sources, and nonempty detail; causes
are also sorted and deduplicated. Current codes are invalid-identifier, symbol-collision,
path-collision, recursive-layout, binding-assignment, missing-type-owner, wire-collision
and missing-representation. Format /3 also admits accessor-resource
when bounded accessor generation exceeds its output budget, and selection-constraint
when list selection requires invariant or reading validation outside its supported capability. A plan with zero capabilities can still fail. The typed error
implements Display and std::error::Error; it carries no independent digest.
Go checks every named type against the actual domain type rosters before package allocation,
including unreferenced types. A missing owner returns missing-type-owner with that qualified
type as its source; the existing Binary64 refusal takes precedence.
These checks do not constitute a universal compiler proof; internal coverage assertions remain,
and direct workspace calls require the plan for the supplied IR.
Error, API limits.
For a complete target failure, ess synthesize prints the text error or JSON/YAML envelope to
stdout and exits 1 before writing artifacts. It creates no output directory and leaves an existing
destination untouched. Successful text output still counts the neutral plan; partial target notes
are in TARGET.md/target.json. Later I/O failures have no new rollback guarantee.
CLI.
Schema imports and data realization
These surfaces are separate from full application synthesis. Structural data targets do not implement a model's lifecycle, and normalization executes only an explicitly checked recipe.
| Document | Reader and byte contract |
|---|---|
format: ess-schema-bundle/1 | Qualified component import. Bundle::read reimports retained source and compares the complete typed result, including selection and dialect. Pretty typed JSON plus LF; source_digest hashes exact retained UTF-8 source bytes. Source |
format: ess-schema-bundle/2 | Document-root import with explicit document_root identity and local definition closure. The same replay reader checks this shape; /1 cannot carry document-root identity and its existing bytes remain unchanged. Source |
format: ess-types-report/3 | Serialize-only structural target accounting: roots, declarations, configuration, the bundle options that are on (options, omitted while every one is off, as for every report written before them), annotations and obligations. Bundle input carries raw-source and complete-bundle identities; model input carries compiled-model, contract and model-schema projection identities. No report-file digest or persisted admission reader. Earlier /1 and /2 reports are not current writers. Source |
format: ess-client-report/1 | Serialize-only accounting for a generated event publisher (ess generate client): the component, the transport's specification identity, every publish operation (event, subject, envelope, batch, delivery, stream and its owner) and every obligation the library does not discharge. Written beside types-report.json. Source |
format: ess-client-report/2 | Added in 0.53.0. Written instead of the previous version when any operation of the generated publisher has a parameterized subject: each operation's subject is its template, and a parameterized operation adds parameters, the normalized event path of each address expression. A publisher with only literal operations keeps writing the previous version, byte for byte. Source |
format: ess-normalization/1 | Closed recipe DTO, then normalize::Plan::read/check with supplied checked bundles. All branches and ordered stage boundaries check before execution. Canonical typed pretty JSON plus LF; parsing alone is not admission. Source |
format: ess-normalization/2 | Extends /1 with ordered text/list construction, original item indices, filtered mapping, first-match selection and explicit binary64 input/conversion declarations. The /1 checker refuses these additions; existing /1 canonical bytes and numeric admission remain unchanged. Source |
format: ess-normalization/3 | Adds compiler-owned model roots with complete provenance and explicit selected root sets. Plan::check_with_models requires sealed model selections; imported x-ess-* annotations cannot provide authority. Versions 1 and 2 refuse model roots. Model invariant obligations refuse until an executable evaluator exists. Generated targets use ess-normalization-target/2 for this recipe version. Source |
format: ess-normalization-target/1 | Serialize-only standalone library report from Plan::rust, Plan::go or Plan::typescript, with explicit target configuration, recipe, root/schema and emitted-file identities. Pretty typed JSON plus LF; no persisted report-admission API. It is not a full-synthesis target report. Source |
format: ess-normalization/4 | Adds explicit branch/field/items/root lexical capture through raw_json_inputs before first input-schema validation. Selected tokens become canonical standard base64; captures preserve duplicate members and numeric spelling while enforcing JSON grammar, Unicode and global depth 64. Capture/numeric overlaps refuse; decoded-value APIs require the text edge for capture branches. Versions 1–3 refuse the member, including an empty map. Source |
format: ess-normalization-target/2 | Report for format-3 recipes, retaining complete model-root identities and source/schema/file digests. Existing format-1/2 recipes retain target/1. Source |
format: ess-normalization/5 | Adds modeled finite Binary64 with explicit complete input policy, token-string binary64_literal, finite value-producing binary64 steps and two-typed-Binary64 IEEE equality. Formats 1–4 refuse selected Binary64 models and the new expressions; their qualified-schema numeric behavior and full emitted maps remain unchanged. Raw capture/helpers remain available. Source |
format: ess-normalization/6 | Adds closed positional_inputs declarations and checked position { value, index } reads. Explicit fixed-string-array policies prepare the first input into an exact closed tuple; raw capture and Binary64 remain available. Formats 1–5 refuse the new member and operation, retaining their complete emitted maps at the same generator version. Report version remains target/3. Source |
format: ess-normalization-target/3 | Report for every format-4, format-5 or format-6 recipe. The embedded canonical recipe and its digest bind input policies; first-stage schemas describe the prepared representation. Same report fields, new semantics; older readers must reject this version. No general report-admission API exists. Formats 1–5 preserve generated file maps through frozen legacy templates; generator versions remain truthful across releases. Source |
More columns: swipe horizontally, or focus the table and use the arrow keys.
The TypeScript normalization writer adds a package-bearing configuration arm local to normalization; structural TypeScript configuration remains separate. Recipes 1/2 retain target report 1, recipe 3 uses report 2, and recipes 4/5/6 use report 3. These are serialize-only reports, so the additional target needs no new report version. Its fixed schema profile and runtime files enter the existing file-digest map; unsupported constraints refuse before a report exists. Complete Rust/Go maps retain exact bytes at a fixed generator version.
Format-5/6 static checking adds equality for two typed Binary64 operands. The frozen runtime has a broader floating-pair branch: two floating representations compare numerically even in an admitted Integer expression. Mixed integer/floating pairs still require integer eligibility. TypeScript preserves that reference limitation without granting general Number equality or Binary64 output provenance. No core equality tightening is included in this target addition.
The following hashes are bare lowercase SHA-256, but have different input domains:
- Bundle
source_digest: original source bytes, not parsed or canonicalized JSON. bundle_digest: completeBundle::to_json()bytes, including retained source, dialect, root selection, format identity and final LF. A raw-source digest cannot replace it.- Model
projection_digest: completeModelTypes::to_json()JSON Schema projection bytes, including provenance and final LF. Its modelsource_digestandcontract_digestretain their separately defined semantic domains. Model projection - Normalization
recipe_digest: checkedPlan::to_json()bytes, including final LF. - Normalization
schema_digestandfilesvalues: exact emitted UTF-8 file bytes.normalization-report.jsonis deliberately excluded from its own file-digest map.
Component delivery
Every marker here uses the format key. Build/runtime/component inputs are closed DTOs followed
by compilation. Persisted IR, release, bundle, catalog and lock readers validate through generic
Serde as well as convenience readers; nested documents cross that boundary too. Revalidate mutable
values before use. These checks establish local consistency, with additional checks where authority
inputs are supplied; they do not prove remote artifact contents or authenticity.
Validation owner.
| Document | Independent version or identity | Reader / canonical digest |
|---|---|---|
ess-build/1 | Build/system and semantic references | BuildSpec DTO → compile_build; authored bytes have no canonical digest. Source |
ess-build-ir/1 | Compiled build identity | Checked BuildIr; pretty JSON, delivery-document digest. Source |
ess-runtime/1 | Exact ESS/realization/build references | RuntimeSpec DTO → compile_runtime; no raw-input digest. Source |
ess-runtime-ir/1 | Compiled runtime identity | Checked RuntimeIr; supplied-build validation is separate. Pretty JSON, delivery-document digest. Source |
ess-runtime/2 | As ess-runtime/1, plus scheduled workloads (schedule:, rendered as a CronJob) and pod settings: container resources, read_only_root_filesystem and TCP probes, workload security, service_account_token, annotations and affinity, secret slots mounted as volumes, and process images pinned by digest | RuntimeSpec DTO → compile_runtime, which compiles it to ess-runtime-ir/2; a /1 document carrying one of these keys is refused naming ess-runtime/2. Source |
ess-runtime-ir/2 | Compiled runtime identity | Checked RuntimeIr, as /1. A /1 document keeps its bytes and digest. Source |
ess-component/1 | Semantic major and release-unit names | ComponentSpec DTO → compile_component; no raw-input digest. Source |
ess-component-ir/1 | Component and semantic version | Checked ComponentIr; pretty JSON, delivery-document digest. Source |
ess-release/1 | Release SemVer, source commit and exact artifact/evidence identities | Checked ReleaseManifest; verify against supplied build/runtime where available. Pretty JSON, delivery-document digest. Source |
ess-release-bundle/1 | Independent runtime/chart releases | Checked ReleaseBundle and bundle verification. Pretty JSON, delivery-document digest, separate from the OCI registry manifest digest. Source |
ess-release-catalog/1 | Candidate semantic versions and release SemVers | Checked ReleaseCatalog; no whole-catalog canonical hash API. Source |
ess-stack/1 | Semantic-major and release SemVer constraints | Closed StackSpec DTO → resolver with catalog; no raw-input digest. Source |
ess-stack-lock/1 | Exact selected release versions/digests | Checked StackLock; pretty JSON, delivery-document digest. Source |
ess-environment/1 | Environment id and exact stack digest | Closed EnvironmentSpec DTO → deployment compiler; no raw-input digest. Source |
ess-deployment/1 | Exact stack and release identities | Checked DeploymentIr; pretty JSON, delivery-document digest. Source |
ess-deployment-diff/1 | Before/after deployment digests | CLI-produced added/changed/removed sets; no reader. Key-sorted pretty JSON; no diff-file digest. Source |
More columns: swipe horizontally, or focus the table and use the arrow keys.
Release and bundle /1 wire fields, canonical bytes and four required evidence kinds are unchanged.
Their validators establish consistency of declared metadata and relationships. Evidence.digest
is the OCI attachment manifest digest, not the SHA-256 of a report file. Provenance, SBOM,
signature and conformance entries remain declared attachments: attachment binding, producer origin
and artifact execution are unverified; signature verification is unsupported. Fetch additionally
checks OCI content identity without authenticating the evidence references inside a bundle.
Local release qualification uses existing report/2 plus an independent original suite/5 or fully admitted input/1 carrier and an explicit model/deployment context. It creates no new envelope or persisted assessment. Only the supplied nonempty complete all-pass selection qualifies; legacy report/1 readers remain unchanged and cannot satisfy this positive gate. Optional CLI/action raw pins cover the complete original report and selected suite/carrier files. They do not change any format's canonical digest profile or provide remote attachment proof. See the action migration.
Change and conformance records
| Document and discriminator | Separate identity | Reader and byte contract |
|---|---|---|
format: ess-diff/1 | Before/after compiled-model digests and specification majors | Legacy vocabulary/bytes retained; raw closed DTO → validated delta. Explicit legacy writing refuses new-only kinds. Pretty JSON; no delta-file hash. Writer, reader |
Default format: ess-diff/2 | Same endpoint identities | Supported delta majors are 1 to 11; legacy changes retain /2. Admission checks ids, relations, order, uniqueness and same-system identity; serialization checks the selected vocabulary. Pretty JSON. Source |
format: ess-diff/3 | Same endpoint identities | Added in 0.23.0. New periodic-cause, selection-plan and clock-reading-contract changes retain typed before/after values. Explicit /1 or /2 writing refuses these variants. Source |
format: ess-diff/4 | Same endpoint identities | Added in 0.23.0. Error naming, command response declarations and response/generated payload source changes. Earlier delta writers refuse this vocabulary; legacy-only changes keep their existing formats. Source |
format: ess-diff/5 | Same endpoint identities | Added in 0.27.0. VariantWireNameChanged, VariantDisplayNameChanged and VariantSummaryChanged on TypeChange: a variant's own name does not move when its wire spelling does, so majors 1 to 4 returned an empty delta for it and refuse this vocabulary. Source |
format: ess-diff/6 | Same endpoint identities | Added in 0.29.0. Typed changes record the original outcome whose result a retry retains and the complete refusal-observation requirement. Earlier formats refuse the new vocabulary; unchanged legacy comparisons retain their bytes. Source |
format: ess-diff/7 | Same endpoint identities | Added in 0.34.0. grouping-changed and field-aggregate-changed on a view: its group keys, and what one field computes (sum(talk_seconds), count(), or not an aggregate). Earlier formats refuse the new vocabulary; every other change keeps its earlier format. Source |
format: ess-diff/8 | Same endpoint identities | Added in 0.34.0. alphabet-changed on a type, related by set membership (a declared or narrowed alphabet narrows, a dropped or widened one expands, a reorder is changed), and input-example-changed on a command, which is changed. Earlier formats refuse the new vocabulary; every other change keeps its earlier format. Source |
format: ess-diff/9 | Same endpoint identities | Added in 0.38.0. paging-changed on a view: its paging: (ess/16) declared, dropped or changed, each side null or the paging parameters, first_page and total. outcome-set-effect-changed on a command: an outcome's instances: or affects: (ess/16) declared, dropped or changed, one line per construct on each side. Earlier formats refuse the new vocabulary; every other change keeps its earlier format. Source |
format: ess-diff/10 | Same endpoint identities | Added in 0.41.0. cause-changed on a binding whose before or after is {"external": {event, authority, context_fields}}: an event binding's ess/18 delivery context (beyond10x/ess#195) declared, dropped or changed, where each context field carries its name, type and any wire name. context-field-display-changed and context-field-summary-changed on a binding, {field, before, after}: a context field's display or summary moved, which is documentation and not a cause change. Writing such a delta in an earlier format is refused, and a reader of an earlier format refuses it with unsupported_format_version; a cause change without an external side keeps its earlier format. Source |
format: ess-diff/11 | Same endpoint identities | Added in 0.42.0. prefix-added {after} (narrowed), prefix-removed {before} (expanded) and prefix-changed {before, after} on a type: a newtype's prefix: (beyond10x/ess#219) declared, dropped or replaced, a replacement narrowed when the new prefix extends the old one, expanded when the old one extends the new one, and changed otherwise. Before, the change fell to the residual as unclassified-changed. Writing such a delta in an earlier format is refused, and a reader of an earlier format refuses it with unsupported_format_version; every other change keeps its earlier format. Source |
format: ess-diff/12 | Same endpoint identities | Added in 0.46.1. outcome-error-payload-added {outcome, after}, outcome-error-payload-removed {outcome, before} and outcome-error-payload-changed {outcome, before, after} on a command: an outcome's error payload: sources (beyond10x/ess#253) declared, dropped or replaced, one change per outcome, each side one <Error>.<field> <- <source> line per determined field, related changed as outcome-payload-changed is; and outcome-accepts-nothing-changed, outcome-returns-changed and outcome-decided-by-caller-changed on a command, {outcome, before, after} booleans related changed as outcome-refuses-changed is: an outcome's accepts: nothing, returns: or caller-decided refusal moved. Before, each fell to the residual as unclassified-changed. Writing such a delta in an earlier format is refused, and a reader of an earlier format refuses it with unsupported_format_version; every other change keeps its earlier format. Source |
format: ess-diff/13 | Same endpoint identities | Added in 0.53.0. outcome-one-time-response-changed carries the outcome and sorted before/after field lists. Adding disclosure restrictions narrows allowed behavior; removing them expands it; replacing incomparable sets is changed. Older explicit delta formats refuse this kind. Unchanged policies preserve the earlier delta format. Source |
format: ess-diff/14 | Same endpoint identities | Added in 0.53.0. Written when a caller asks for compatibility (ess verify diff --compatibility or --fail-on, ess_diff::classified), and on its own, classified, when the delta holds a refusal-policy-changed or a binding predicate-changed change, which no earlier format can carry (ess verify diff, ess_diff::diff); any other default delta keeps its earlier format and bytes. Every change carries compatibility {verdict, callers, readers, history}, each compatible, unknown or breaking, and a type change also carries uses, the subset of input, output, stored and unmodelled the type reaches in either revision; unmodelled (a mention the classifier reads no role from) makes every answer unknown for any change other than documentation or adding or removing the type. A reader re-derives each answer from the change and its uses and refuses a mismatch with conflicting_declaration, a /14 change without compatibility with missing_declaration, and compatibility below /14 with unsupported_format_version. It also carries binding/<name>/refusal-policy-changed for an ess/22 refusal-selected on_failure: (beyond10x/ess#269), with the complete resolved per-refusal table keyed by outcome (name order) and fallback on each side, so declaring the refusals in another order is no change, null for a universal policy, with relation changed; earlier formats refuse it written or read, and a universal policy change keeps failure-changed. It also carries predicate-changed on a binding, {before, after}, each an optional predicate as written: a binding's event-payload condition (beyond10x/ess#268) added, removed or changed, relation changed. It also carries outcome-compensates-changed on a command, {outcome, before, after} booleans, relation changed: an ess/22 refusal's compensates: true (beyond10x/ess#197) added or removed, with the change it declares reported beside it as outcome-subject-changed; classified breaking for callers and readers and compatible for history, and earlier formats refuse it. Source, classification |
format: ess-diff/15 | Same endpoint identities | Added in 0.57.0. domain/<name>/added and domain/<name>/removed, relation changed: a domain entered in, or dropped from, system.yaml's domains: list (beyond10x/ess#469), ordered right after the system changes. Before, the entry fell to the residual as system/<name>/unclassified-changed, unknown, so a purely additive revision failed --fail-on breaking-or-unknown. /15 is always classified, also on its own (ess verify diff, ess_diff::diff): added is compatible for callers, readers and history; removed is breaking for callers and readers and compatible for history, and each construct the domain declared carries its own change beside it. A domain both revisions declare is compared as before, and its naming stays residual. Reordering the domains: list is no change. Writing such a delta in an earlier format is refused, and a reader of an earlier format refuses it with unsupported_format_version; every other delta keeps its earlier format. Source, classification |
format: ess-diff/16 | Same endpoint identities | Added in 0.57.0. A classified command input-type-changed change whose input field's type moves between JSON containers (a value, an object, an array) carries shapes {before, after} in its compatibility, each scalar, record (a struct or a union), list or map, read through Optional and newtypes in its own revision. Such a change is breaking for callers, unknown for readers and compatible for history: a caller still sending the old shape is refused before anything runs. Before, it was unknown for callers and --fail-on breaking passed it. The same move under one type name, a kind-changed, representation-changed, field-type-changed or variant-type-changed change of a type with an input use (Receipt redefined from a newtype of String into a struct, a member retyped from String to List<String>), carries shapes of what moved beside its uses and is breaking for callers, with readers and history answered by its uses as before; a type with no input use records none. A change between two types of one container, or with Json on either side, records no shapes and keeps its earlier answer and format, as does every unclassified delta. A reader re-derives the answer from shapes and refuses with conflicting_declaration shapes of one container or an answer they do not derive, and with unsupported_format_version shapes below /16; writing such a delta in an earlier format is refused. Source, classification |
format: ess-diff/17 | Same endpoint identities | Added in 0.57.0. A classified command change that refuses an existing caller carries narrows in its compatibility: required-input on an input-added whose type is not Optional (read through newtypes), refusal-added on an outcome-added that reports an error, and refusal-widened on an outcome-condition-changed whose outcome reports an error. Both refusals are recorded only where every outcome of the earlier revision, and each up to the refusal in the later one, is a plain when: or otherwise branch, and the mutation audit's satisfiability check finds an input a caller of the earlier revision could send (an enum leaf ranges over the earlier revision's variants only) that the earlier revision accepted (no refusal took it, an accepting outcome did) and the later revision answers with this refusal. An input the earlier revision already refused, by any refusal under any name, does not count. Such a change is breaking for callers, unknown for readers and compatible for history; before, it was unknown for callers and --fail-on breaking passed it. An added accepting outcome, an added Optional input and a guard change the check does not decide record nothing and keep their earlier answer and format, as does every unclassified delta. A reader re-derives the answer from narrows and refuses with conflicting_declaration a narrows on another change kind, required-input on an input written Optional<…>, or an answer it does not derive, and with unsupported_format_version narrows below /17; writing such a delta in an earlier format is refused. Source, classification |
format: ess-diff/18 | Same endpoint identities | Added in 0.58.0. type/<name>/undeclared-fields-changed and command/<name>/response-undeclared-fields-changed, each {before, after} of refused and ignored: an ess/24 kind: struct type's, or a command response's, undeclared_fields: moved (beyond10x/ess#500). Before, the move fell to the residual as system/<name>/unclassified-changed, unknown. Opening (refused → ignored) is relation expanded, closing narrowed. ess-diff/18 is always classified, also on its own (ess verify diff, ess_diff::diff). A struct is answered through its uses as any widened or narrowed type is: opened, breaking for readers of an output use and compatible for callers and history; closed, breaking for callers of an input use and for a stored use, and compatible for readers. An opened response is breaking for readers, since one written against the closed response may be sent a field it refuses, and compatible for callers and history; a closed response is compatible. A struct declared in one revision only is its own added or removed, and the list of open structs is no longer residual. Writing such a delta in an earlier format is refused, and a reader of an earlier format refuses it with unsupported_format_version; every other delta keeps its earlier format. Source, classification |
format: ess-diff/19 | Same endpoint identities | Added in 0.60.0. view/<name>/absent-changed, {before, after}, each side the view's default row (field to literal text) or null: an ess/25 view's answer for an identity no row carries (absent:) gained, lost or changed (beyond10x/ess#533). Relation changed; breaking for readers, since a read of an unknown identity answers differently, and compatible for callers and history. ess-diff/19 is always classified. Writing such a delta in an earlier format is refused, and a reader of an earlier format refuses it with unsupported_format_version; every other delta keeps its earlier format. Source, classification |
format: ess-diff/20 | Same endpoint identities | Added in 0.63.0. type/<name>/shorthand-changed, {before, after}, each side the field's declared name or null: an ess/27 kind: struct type's shorthand: declared, dropped or moved to another field (beyond10x/ess#594). Declaring one is relation expanded, since every long form stays a value and the field's scalar alone becomes one; dropping or moving one is narrowed, since a short form written against the earlier revision is refused or read as another field. A struct is answered through its uses as any widened or narrowed type is, and the list of shorthands is no longer residual. actor/<name>/system-changed and command/<name>/await-within-changed, each {before, after}: an ess/27 actor became the system itself or stopped being it, and a system-issued command's await_within: was declared, dropped or changed (beyond10x/ess#542). An actor becoming the system is breaking for callers, as a grant removed is; the reverse and every await_within: move are compatible. A command becoming system-issued is reported through these and its grants, never as a change of its own. ess-diff/20 is always classified. Writing such a delta in an earlier format is refused, and a reader of an earlier format refuses it with unsupported_format_version; every other delta keeps its earlier format. Source, classification domain/<name>/display-name-changed, {before, after}, each side the display name or the domain's last segment, and domain/<name>/summary-changed, {before, after}, each side the summary or null: a domain both revisions declare shown as, or summarised as, something else. Both are documentation, compatible for callers, readers and history; before, they fell to the residual as system/<name>/unclassified-changed, unknown, and a summary edit failed --fail-on breaking-or-unknown. A domain's wire name stays residual. ess verify impact still owes everything for either, as it did. Source, classification |
format: ess-diff/21 | Same endpoint identities | Added in 0.64.0. view/<name>/field-source-changed, {field, before, after}, each side <reference>.<field>, the row a reference of the view's source names, or null where the field is the source's own of that name: an ess/28 view field came to read through a reference, stopped, or reads another one (beyond10x/ess#564). Relation changed; breaking for readers, since a read meets other values, compatible for callers and history. ess-diff/21 is always classified. Writing such a delta in an earlier format is refused, and a reader of an earlier format refuses it with unsupported_format_version; every other delta keeps its earlier format. Source, classification |
format: ess-diff/22 | Same endpoint identities | Added in 0.78.0. entity/<name>/transition-summary-changed/<transition>, {transition, before, after}, each side the transition's summary: or null: an ess/33 lifecycle transition's summary added, dropped or edited. Relation changed; compatible for callers, readers and history, as documentation. A moved state summary is reported as the state enum's variant-summary-changed. ess-diff/22 is always classified. Writing such a delta in an earlier format is refused, and a reader of an earlier format refuses it with unsupported_format_version; every other delta keeps its earlier format. Source, classification |
format: ess-diff-acknowledgements/1 | The before and after spec digests of the one comparison it acknowledges | Read by ess verify diff --acknowledgements. {format, before, after, acknowledged}, unknown fields refused; each acknowledged id must be a change of that comparison, once. Digests of another pair are refused with conflicting_declaration. Source |
format: ess-suite-diff/1 | from and to: each suite's suite_version, spec_digest and scenario count | Added in 0.63.0. Written by ess verify conform diff --format json (beyond10x/ess#572): {format, from, to, counts, constructs}. counts and each construct's counts are {added, removed, changed, unchanged}; a construct is listed only when a scenario of it moved, and its unchanged is 0; constructs maps a construct (a scenario id's subject and family, and for a one-time disclosure cell also its origin outcome, field and aspect) to {counts, added, removed, changed}, the ids sorted, each changed scenario {scenario, parts, removed_steps, added_steps} with parts among purpose, steps, source and one_time_response and each step {index, step} at its position in the earlier or later scenario. Scenarios are compared as read, so a compact suite/52 spelling of the same scenario is no change. Output only; nothing reads it back. |
Current format: ess-impact/3 | Embedded versioned delta, optional suite and artifact identities | ess_diff::impact returns EssImpact with typed dependency relations; no persisted report reader. Pretty JSON; references input digests. Source |
Authored type: ess-scenario/1, ess-scenario/2 or ess-scenario/3 | Domain/scenario identity and purpose | Closed authored DTO, then compilation against IR. /2, added in 0.23.0, adds typed backend entity setup; /1 refuses setup fields. /3, added in 0.35.0, adds typed fixtures: declarations and {$fixture: name} references in inputs, view expectations and event payloads; earlier versions refuse both. No raw-source canonical digest. Source |
Authored type: ess-scenario/4 | Domain/scenario identity and purpose | Added in 0.39.0. An act's response: {field: literal} asserts selected return fields, checked against their complete declared types. {} requests the complete response shape check. Selected returns: true outcomes receive that check automatically. Earlier versions refuse the new key. Source |
Authored type: ess-scenario/5 | Domain/scenario identity and purpose | Added in 0.59.0. An act's caller: {attribute: value} states the caller its command is sent as: each value a literal of the attribute's declared type, or {$instance: name} for an instance arranged with setup:. An attribute the act's actor: does not declare is refused (ESS-AUTHOR-013), and so is a required attribute the command reads that the act leaves unstated (ESS-AUTHOR-014), naming the attribute and the command. The values compile into the step's existing suite/26 caller; an act with no caller: sends none and its suite keeps its bytes. Earlier versions refuse the new key, and an older ess refuses the header. Source |
Authored type: ess-scenario/6 | Domain/scenario identity and purpose | Added in 0.79.0. A claim may name one member of a nested value by its dotted path, checkpoint.checkpoint_id: cp-1, in an act's response:, an event's payload:, an error's fields: and a row's contains, excludes and at; each path is compared alone, through Optional and newtypes, and the members it does not name are not read. A nested value written whole is still compared whole: a partial one is refused for the members it leaves out, named at their path (ESS-AUTHOR-014, response: included at every header). A path naming no member is refused with the full path (ESS-AUTHOR-013); a path through a list, map, union, enum or primitive, a path to a reference, and a path in input:, setup:, caller: or a view's params: are refused by name. Event, error and row paths compile to suite/26 dotted keys, a path ending at a struct as its leaves; a response path compiles to expected under ess-conformance/62. An act's literal input that its declared type refuses, at any depth, is refused naming the field and the constraint (ESS-AUTHOR-015). Below ess-scenario/6 a dotted key is refused as an undeclared field and an input is checked for its shape only, and an older ess refuses the header. Source |
Suite provenance.suite_version: ess-conformance/4 | Specification vN, model and whole-contract digests | Historical Deserialize/from_json parses an unadmitted DTO. Original-byte admission checks the closed, major-specific vocabulary before execution; serialize-once admission of a DTO binds only its newly serialized bytes. Suite bytes/defaults stay frozen; report/2 separately carries exact identity. Source |
Rust format: ess-conformance-report/1 | Model digest, implementation and suite-version claim | Checked closed reader validates version/counts/list/status; it does not establish exact-suite coverage or unique opaque result ids. Pretty JSON; unsigned u64 completed_at. Source |
Go format: ess-conformance-report/1 | Same claims, Go failed/skipped vocabulary | Generated Go writer; current Rust admission accommodates its non-pass vocabulary. Indented JSON+LF, signed int64 completed_at; no cross-producer byte/range equivalence is implied. Source |
Default detailed ConformanceReport: unversioned | Suite provenance, implementation, run/scenario identities | Detailed CLI JSON/YAML is distinct from standalone --report-out JSON. Serialize-only; pretty canonical JSON, no report-file or exact-suite hash. Source |
Opt-in ess-conformance-report/2 and ess-conformance-run/2 | Exact original suite/1–17 bytes, producer profile and five outcome categories | Separate standalone and detailed surfaces with paired readers. Sorted UTF-8 object keys, two-space JSON plus LF, exact unsigned u64 counts/timestamps. Ordinary coverage remains unknown; complete nonempty suite/5, /7, /9, /11, /13, /15 or /17 selection can qualify. Suites /6 to /9 arrived in 0.23.0. Count contracts |
format: ess-conformance-results/1 | One terminal status per scenario of a suite ESS admits, and optionally that suite's sha256-json-bytes/1 digest | Added in 0.48.0. Read by ess verify conform report, which writes report/2 from it. Closed format, exact u64 completed_at, optional suite_digest and results of {scenario_id, status, message?}; status is passed, failed, error or unsupported. Refused: a result for a scenario outside the suite, a scenario with no result, two results for one scenario, any other status, a suite_digest that is not the admitted suite's. The report's producer_profile is external-scenario-status/1, or external-scenario-status/1;runner=<name>@<version>, with Rust category rules. Source |
format: ess-known-failures/1 | Original specification digest (spec_digest), exact suite-byte digest (suite_digest), the report's implementation label and the public implementation_build (sha256: and 64 lowercase hex digits) | Added in 0.53.0. An external declaration of scenarios one build of an implementation is known to fail, read by --known-failing on ess verify conform run, report and mutate (beyond10x/ess#294, #296). Closed format, spec_digest, suite_digest, implementation, implementation_build and a nonempty failures list of {scenario, reason, tracking} in scenario ID order, each string nonempty; tracking names a repair record and is never fetched. IDs match exactly: no wildcard, prefix, command-wide or outcome-wide match. It never makes a run pass and is never a marker on an authored outcome. Refusals, each first in its message and exit 2 on the CLI: known-failures.malformed (unknown or duplicate key, other format, invalid digest, empty or unordered list); known-failures.identity (another specification, other suite bytes, another implementation label or build); known-failures.unknown-scenario (an ID the suite does not hold); known-failures.stale (a declared scenario passed); known-failures.not-failed (a declared scenario ended error, unsupported or skipped); known-failures.unbound (a declaration supplied to mutate --collect that the emission did not bind, or other bytes than the ones it bound); known-failures.accounting (an accounting document that is not the partition its report and declaration make). Source |
format: ess-conformance-execution/1 | The exact report-byte digest (report_digest), suite-byte digest (suite_digest), the report's implementation label and the host's implementation_build | Added in 0.53.0. Host execution provenance beside a report/2: which public build produced exactly that report of exactly that suite. Written by the generated Go and TypeScript runners when ESS_IMPLEMENTATION_BUILD and ESS_EXECUTION_CONTEXT_OUT are both set (with ESS_REPORT_FORMAT=2 and ESS_REPORT_OUT, read before any target is made), and by ess verify conform report --results … --implementation-build … --execution-context-out …; read by report --observed-report and by mutate --collect under a bound declaration, conventionally as execution.json beside report.json. Closed: those five keys and nothing else — no values, timestamps, host text or commands; a protected one-time run carries its fixed redacted label. Declared host provenance, not remote attestation. Source |
format: ess-known-failure-accounting/1 | The digests of the original report, suite and declaration bytes, the specification digest, the implementation label and build | Added in 0.53.0. Written as a new file by --accounting-out on ess verify conform run and report. known_failed (the declared failures, each failed in the report) and unexpected_failed (every other failed scenario) partition the report's failed scenarios; counts are the report's own five terminal counts, so a known failure is never a pass and never leaves the total. There is no conformance field: the report keeps its verdict, run its exit status (strict included) and report its exit 0. Its validator recomputes every identity and the partition from the original documents. Source |
Opt-in provenance.suite_version: ess-conformance/5 | Model/contract provenance and complete declared selection inventory | Closed original-byte admission retains source ownership, known outside IDs and every refusal occurrence. Explicit selections require exact parent input. Coverage contract |
provenance.suite_version: ess-conformance/6 or ess-conformance/7 | Existing provenance; /7 also carries declared coverage | Added in 0.23.0. Conditional accessor, entity setup, selection, periodic and clock-observation vocabulary: /6 is ordinary, /7 retains the /5 coverage and exact-parent contract. Execution requires existing report/2; report/1 refuses before target callbacks. Existing /4 and /5 bytes remain unchanged. Accessor observation |
provenance.suite_version: ess-conformance/8 or ess-conformance/9 | Existing provenance; /9 also carries declared coverage | Added in 0.23.0. Typed command-response observations compare an invocation's actual response with its emitted event payload. Structured text predicates requiring lossless literal decoding also select these versions. /8 is ordinary; /9 retains exact-parent coverage lineage. Rust and generated Go require report/2; older suite envelopes refuse the new vocabulary before execution. Browser execution retains explicit refusals for unsupported steps. |
provenance.suite_version: ess-conformance/10 or ess-conformance/11 | Existing provenance; /11 also carries declared coverage | Added in 0.28.0. Independent subject snapshots compare every actual field, with an explicit no-error assertion. /10 is ordinary; /11 retains declared coverage and exact-parent lineage. Requires report/2. |
provenance.suite_version: ess-conformance/12 or ess-conformance/13 | Existing provenance; /13 also carries declared coverage | Added in 0.29.0. Immutable original-command result capture and exact retry comparison bind response, original subject identity, input and actor. Retry has no error or direct events; paired snapshots compare the complete subject. Integer/text/collection equality preserves optional absence versus null; Decimal/Binary64 responses refuse. Rust, Go and TypeScript execute with report/2. Browser replay and older envelopes refuse before callbacks. |
provenance.suite_version: ess-conformance/14 or ess-conformance/15 | Existing provenance; /15 also carries declared coverage | Added in 0.34.0. A satisfies expectation or an observed selection plan carrying starts_with, ends_with or contains; each implies every major below it. /14 is ordinary; /15 retains declared coverage and exact-parent lineage. Rust, Go and TypeScript admit and evaluate them with report/2 and refuse a non-string operand; older envelopes refuse the operators. Browser replay refuses these envelopes before replay. A string guard over command input is decided at synthesis, so its suite keeps its earlier format. |
provenance.suite_version: ess-conformance/16 or ess-conformance/17 | Existing provenance; /17 also carries declared coverage | Added in 0.34.0. An <view>/aggregate scenario, which arranges rows through the declared creating outcome and asserts each group's exact aggregates with contains and excludes; each major implies every one below it. Coverage /17 also admits the aggregate refusals ESS-SYNTH-016 and ESS-SYNTH-017. Rust, Go and TypeScript admit and run them with report/2; older envelopes refuse an aggregate scenario or refusal. Browser replay refuses these envelopes before replay. |
provenance.suite_version: ess-conformance/18 or ess-conformance/19 | Existing provenance; /19 also carries declared coverage | Added in 0.35.0. A leading resolve_fixtures prelude carrying fixture names and their source-owned type declarations, {kind: fixture} scenario values, and expect_event_values, which compares the first direct occurrence of an event by name with literal and fixture values; each major implies every one below it. Rust, Go and TypeScript resolve and validate the values before BeginScenario with report/2: malformed values stop before target activity and a missing provider is an explicit unsupported result. Browser replay refuses fixtures. A suite without fixtures keeps its earlier format. |
provenance.suite_version: ess-conformance/20 or ess-conformance/21 | Existing provenance; /21 also carries declared coverage | Added in 0.37.0. A satisfies expectation or an observed selection plan carrying equals_ignore_case or in_ignore_case, compared under ASCII case folding; each major implies every one below it. /20 is ordinary; /21 retains declared coverage and exact-parent lineage. Rust, Go and TypeScript admit and evaluate them with report/2 and refuse an operand that is not a JSON string (a list of them under in_ignore_case); older envelopes refuse the operators. Browser replay refuses these envelopes by their version. A case-insensitive guard over command input is decided at synthesis, so its suite keeps its earlier format. |
provenance.suite_version: ess-conformance/22 or ess-conformance/23 | Existing provenance; /23 also carries declared coverage | Added in 0.37.0. Adds expect_subject_absent (after a deletes: outcome), snapshot_view and expect_view_unchanged (around an accepts: nothing outcome); each major implies every one below it. /22 is ordinary; /23 retains declared coverage. Rust, Go and TypeScript execute these steps with report/2. |
provenance.suite_version: ess-conformance/24 or ess-conformance/25 | Existing provenance; /25 also carries declared coverage | Added in 0.37.0. A payload leaf may carry presence: null_when_absent or omitted_when_absent (ess/15): the first refuses an absent key, the second an explicit null. Each major implies every one below it. The Go and TypeScript runtimes execute both from 0.40.0 (beyond10x/ess#188); earlier runtimes refuse them by version. A suite without a policy keeps its earlier format. |
provenance.suite_version: ess-conformance/26 or ess-conformance/27 | Existing provenance; /27 also carries declared coverage | Added in 0.38.0 for the ess/16 constructs. First (beyond10x/ess#179), an event payload or view row expectation may name one leaf of a struct field by its dotted path (lead.number), which is how a nested mapping with an undetermined leaf is asserted leaf by leaf; the undetermined leaf stays covered by the payload shape. In a row, a dotted path that finds nothing reads as null, and an excludes of the subject with the undetermined leaf null requires it to be present; its type is checked only in the payload. A dotted payload key must name a leaf of the step's own shape. Second (beyond10x/ess#176), a view satisfies predicate may read defined(x) or missing(x) where x is an Optional struct, union, list, map or Json in the view's declared fields: a present value, even an empty one, is defined and null is not. A 0.37.0 runner binds no fact at such a path and reads it as absent, so the invariant any: [state == Paused, not defined(metrics)] would pass without being checked; the version makes it refuse the suite instead. The same predicate over an Optional scalar is carried by the suite but selects no new format; a view filter or when_subject guard is decided at synthesis and does not reach the suite. Third, A changed_by view expectation (beyond10x/ess#148) holds when the view's one row moved, since the snapshot_view of it, by exactly each named amount; both reads must hold one row and each amount is a number. A field listed in its absent_is_zero (a skipping sum) reads as zero where absent; any other field absent on either read fails it. Fourth, A scenario value {kind: now_offset, seconds: <n>} (beyond10x/ess#171) is an instant <n> seconds from the moment the runner first sends it in the scenario, resolved from the runner's wall clock (Clock::wall, which a caller running against a real clock supplies; it defaults to the runner's own clock) rounded up to a whole second; later values of the same number in the scenario read the same instant. Fifth, A command step may carry caller, the attribute values of the caller it is sent as (beyond10x/ess#168); the target sends the command authenticated as that caller, or answers unsupported. Sixth, a bounded retry (beyond10x/ess#165) adds times to configure_external_outcome, count to expect_invocation (exactly that many matching invocations) and the final-failure binding aspect; times and count are whole numbers of at least 1. Each major implies every one below it. The Rust runner compares them, and from 0.40.0 so do the Go and TypeScript runtimes (beyond10x/ess#188); earlier runtimes refuse both envelopes by version. A suite with none of them keeps its earlier format. |
provenance.suite_version: ess-conformance/28 or ess-conformance/29 | Existing provenance; /29 also carries declared coverage | Added in 0.39.0. expect_direct_response checks the immediately preceding invocation's actual typed return and authored literals, without inventing events or state. /28 is ordinary; /29 retains declared coverage and exact-parent lineage. Rust, Go and TypeScript execute this observation with report/2. Older readers refuse these envelopes before callbacks. Historical suites retain their bytes. |
provenance.suite_version: ess-conformance/30 or ess-conformance/31 | Existing provenance; /31 also carries declared coverage | Added in 0.41.0. For the ess/18 delivery context (beyond10x/ess#195): deliver_event delivers one occurrence of an event nothing in the specification publishes, with its payload and the context its external channel (authority) binds, and expect_every_invocation requires at least one invocation for the occurrence its selecting inputs name and that every such invocation carries input. A later redeliver_event repeats the most recent delivered occurrence with its own context. Each major implies every one below it. The Rust runner executes both; a target without deliver_event reports the scenario unsupported with its reason. Rust, Go and TypeScript execute these steps with report/2. Older readers refuse these envelopes before callbacks. A suite without them keeps its earlier format. |
provenance.suite_version: ess-conformance/32 or ess-conformance/33 | Existing provenance; /33 also carries declared coverage | Added in 0.43.0. Instance references inside a structured value (beyond10x/ess#242): a value of kind list carries items and one of kind members carries members by field name or map key, and each of those is a literal, an instance, or another list or members, at most 64 deep. The runner resolves every element and sends the list or mapping; an authored {$instance: …} inside a list element, a map value or a struct member compiles to one. A structured value holding no reference stays a literal. Each major implies every one below it. Rust, Go and TypeScript resolve both with report/2. Older readers refuse these envelopes before callbacks. A suite without them keeps its earlier format. |
provenance.suite_version: ess-conformance/34 or ess-conformance/35 | Existing provenance; /35 also carries declared coverage | Added in 0.53.0. Closed scenario one_time_response authority binds originating commands/outcomes, complete response schemas and String constraints, required successful origins, and independent event-log observation windows. Earlier suite envelopes refuse the policy before target callbacks. Observed plaintext remains private runner state and never belongs in suite or report documents. The finite trace does not prove storage, logging, restart or concurrency behavior. |
provenance.suite_version: ess-conformance/36 or ess-conformance/37 | Existing provenance; /37 also carries declared coverage | Added in 0.53.0. For the ess/22 binding condition (beyond10x/ess#268): expect_no_invocation requires that a binding invoked its command no times under the scenario's correlation, through the step's whole eventual window. Any invocation seen fails at once, including a refused one and one made visible late. None seen passes only at the deadline, and a target that cannot expose invocations is unsupported. An optional obligation (binding condition) marks an occurrence the condition is Unknown on: the binding must report that unmet obligation, which is unsupported, and an invocation or a window that ends silent fails. Adds the condition-false and condition-absent binding aspects, and the scenario id <binding>/binding/refusal/<outcome> for each refusal a refusal-selected on_failure: answers (beyond10x/ess#269), witnessed with the existing configure_external_outcome, expect_invocation count and event steps, plus expect_no_publication and expect_publication_count: an event published no times, or exactly count times, under the scenario's correlation for the whole eventual window, more failing at once and the exact number passing only at the deadline; an escalated refusal requires its escalation exactly once. Each major implies every one below it, including the empty scenario_initial_state of /34. Rust, Go and TypeScript execute the step with report/2. Older readers refuse these envelopes before callbacks. A suite without them keeps its earlier format. |
provenance.suite_version: ess-conformance/38 or ess-conformance/39 | Existing provenance; /39 also carries declared coverage | Added in 0.53.0. The aggregate observation of a conditional measure (beyond10x/ess#363): an <view>/aggregate scenario over a view a measure of which declares where:, with ordinary expected rows. Cumulative over every major below. Selected from the model; a reader holding the model refuses such a suite labelled earlier before callbacks. A suite without one keeps its number. |
provenance.suite_version: ess-conformance/40 or ess-conformance/41 | Existing provenance; /41 also carries declared coverage | Added in 0.53.0. The persisted expression vocabulary of ess/22: a one-segment fact operand {fact: …}, a comparison tagged {compare: {left, op, right, as: timestamp}}, which compares two Timestamp facts as instants, one constant offset of a fact, {offset: {fact: <path>, add|subtract: <magnitude>}}, the UTF-8 byte length of a text, {utf8_bytes: <path>}, on either side of a comparison (on the left in the untagged {compare: {left, op, right}}, beside which a text's .count is asserted on view rows in the same satisfies), a text's .count read off a view row on its own, which the model tells from a member named count and which also selects this pair, and distinct list members, {distinct: {in, as, by, kind}}, whose kind every reader requires and whose lists a runner reads element by element in a view row. A calendar window, {window: {at, days, from, to, offset}}, is read too, which a synthesized suite never carries because a window is admitted only in a command guard. Cumulative over every major below. A suite labelled earlier that carries either form is refused before any step runs; a suite needing neither keeps its number. |
provenance.suite_version: ess-conformance/42 or ess-conformance/43 | Existing provenance plus the required synthesis_seeds record; /43 also carries declared coverage | Added in 0.53.0. Written only when --synthesis-seed FILE INSTANCE selected explicit seeds (beyond10x/ess#413). synthesis_seeds is closed: sources maps each checked source identity to the sha256: digest of its original bytes; selections are the exact admitted setup rows (source, instance, entity, identity, fields, state), sorted, kept even when unused; applications bind a selection to a generated scenario, its establish_step and the asserted command_step sent to that row. Each major implies 1–35. Rust, Go and TypeScript readers refuse the record under any major other than 42–45, a 42/43 suite without it, and any dangling, unsorted or forged binding before target callbacks; older readers refuse 42/43 by version. A seed-free suite never carries it and keeps its earlier format and bytes. Browser replay refuses a seeded suite by name. Synthesis seeds |
provenance.suite_version: ess-conformance/44 or ess-conformance/45 | Existing provenance, with synthesis_seeds where seeds were selected; /45 also carries declared coverage | Added in 0.54.0. Counted event claims (beyond10x/ess#427). Written exactly when one act — the steps between one command and the next — claims one event more than once: an outcome whose emits: lists the event several times, or an authored act listing it several times under events:. Every expect_event and expect_event_values after one command then claims an occurrence of its own: the first unclaimed occurrence carrying its values and shape, else the first unclaimed one, whose values fail ESS-CF-PAYLOAD. A claim left with no occurrence fails ESS-CF-EVENT, naming how many were published and how many the act claims. More occurrences than claims is not a failure. Cumulative over every major below, the seed-bearing pair included. Rust, Go and TypeScript execute it with report/2; older readers refuse 44/45 by version. A suite labelled 43 or below keeps first-match semantics, and a suite with no repeated claim keeps its earlier format and bytes. |
provenance.suite_version: ess-conformance/46 or ess-conformance/47 | Existing provenance, with synthesis_seeds where seeds were selected; /47 also carries declared coverage | Added in 0.57.0. String-newtype constraints on response observations (beyond10x/ess#499). Written exactly when an expect_direct_response or expect_response_payload carries constraints: a map from each constrained String newtype the response (or a mapped event target) reaches to its {alphabet, prefix, invariants}, the carrier the one-time profile uses. Every runner holds each actual returned value at every position of such a type — the field, a record field, a union variant, an Optional, List or Map element — to the alphabet, the prefix and every invariant over a lone value text fact, and fails the step ESS-CF-PAYLOAD otherwise. An invariant that reads anything but value or value.count is refused at synthesis by name. Cumulative over every major below, the counted pair included. Rust, Go and TypeScript execute it with report/2; older readers refuse 46/47 by version, and every reader refuses constraints under a lower major. A suite with no constrained response type keeps its earlier format and bytes. Browser replay refuses 46/47 by version. Design |
provenance.suite_version: ess-conformance/48 or ess-conformance/49 | Existing provenance, with synthesis_seeds where seeds were selected; /49 also carries declared coverage | Added in 0.58.0. Ignored undeclared fields on response observations (beyond10x/ess#500). Written exactly when an expect_direct_response or expect_response_payload carries undeclared_fields: "ignored", which opens the response object of a command declaring undeclared_fields: ignored, or undeclared_fields_ignored, the sorted names of the struct declarations of the observation declared ignored. Each member is left out when closed; a present undeclared_fields is always ignored, and a present list is non-empty, names each type once, and names only struct declarations of the same observation. Every runner admits an undeclared key at exactly those objects, reads nothing of it, and keeps every declared field's presence and type check; a closed response, a closed sibling struct and a union still fail an undeclared key with ESS-CF-PAYLOAD. Cumulative over every major below, the constrained-response pair included. Rust, Go and TypeScript execute it with report/2; older readers refuse 48/49 by version, and every reader refuses either member under a lower major. A suite with no opened object keeps its earlier format and bytes. Browser replay refuses 48/49 by version. Design |
provenance.suite_version: ess-conformance/50 or ess-conformance/51 | Existing provenance, with synthesis_seeds where seeds were selected; /51 also carries declared coverage | Added in 0.62.0. A held now for one command (beyond10x/ess#586). Written exactly when a scenario carries {step: hold_now, seconds: <n>}, which stands immediately before the execute_command it holds and is refused anywhere else. seconds is a now_offset number, resolved through the scenario's one table of them, and the command's other now_offset values resolve against the reading that instant was fixed from, so a held step and the values compared with it name one instant. The runner writes the instant into the command clock it handed out, or calls the target's optional hold_now; a target without it reports the scenario unsupported, naming hold_now. Cumulative over every major below, the opened-response pair included. Rust, Go and TypeScript execute both with report/2: the generated Go runtime asks a target implementing NowHolder, the TypeScript one a target with holdNow; older readers refuse 50/51 by version, and every reader refuses the step under a lower major. A suite without the step keeps its earlier format and bytes. Design |
provenance.suite_version: ess-conformance/52 or ess-conformance/53 | Existing provenance, with synthesis_seeds where seeds were selected; /53 also carries declared coverage | Added in 0.63.0. A value type's invariants observed at a wrapped view position. Written exactly when a view expectation carries {expect: value_invariants, root, declarations, value, position, witness, work_limit}, the closed members in that order, or a scenario is named <type>/invariant-wrapped/at/<view>/<field>/<digest>. root is the view field (name, canonical type, optional presence); declarations is exactly the closure of named types the root and the witness identity reach, each newtype (of, invariants, optional alphabet, prefix), struct (fields, invariants), enum (variants) or union (tag, variants); position is {kind: site, path: [segment…]} or {kind: recursive, edge, site}, each segment one of field, present, element, map_value, variant, unwrap; witness is any_observed_occurrence or arranged_row with a projected_identity or identity_query selector; work_limit is a positive integer of at most 2^53-1. The digest is the lowercase SHA-256 of the position's compact JSON. Every actual occurrence on every row must satisfy the type's invariants and its alphabet: and prefix:, and a witness row must hold at least one: an empty List or Map, an absent Optional and another Union variant are legal and witness nothing. An undecidable invariant or an exhausted work_limit is an error, never a pass. The reference runner, the interpreted target and the browser product execute a site position; a recursive position and an identity_query witness are admitted and reported unsupported. The generated Go and TypeScript runtimes admit 52/53 and report a scenario carrying the expectation unsupported, naming value_invariants; older readers refuse 52/53 by version, and every reader refuses the expectation under a lower major. The same pair writes once what a scenario used to repeat per declared event (beyond10x/ess#570): the root may carry events, the declared event catalog in name order, and one_time_response: {commands: [{command, response, outcomes: [{outcome, fields}]}]}, each marked command's complete response authority in name order; a scenario may carry absent_events: [{before, except}], each a run of expect_no_event steps for every catalog event outside except inserted before written step before, and unpublished_events: [{step, except}], the unpublished of written expect_not_granted step step; and a one-time trace may be written {required_origins, within_ms}, standing for every catalog origin of a command the scenario invokes, every catalog event observed with within_ms, a window after each operation immediately and at within_ms, and the catalog events among its sources. Every reader expands these before admission and the writer uses them only where the expansion reproduces the scenario, so they change no meaning; a fresh suite whose scenario carries a one-time trace is written 52 or 53. Cumulative over every major below, the held-now pair included. A suite with neither keeps its earlier format and bytes. Design The same pair awaits a command the system issues itself (beyond10x/ess#542), written exactly when a scenario carries await_outcome (an outcome of the system-issued command on an instance within the declared bound), expect_not_issued (no outcome of it on the instance within the bound, and none of its events published) or a {kind: awaited} value, the input the most recent await's answer carried in one field. A coverage suite whose inventory refuses a system-issued command (ESS-SYNTH-023, ESS-SYNTH-024) is /53. Cumulative over every major below, the held-now pair included. Rust, Go and TypeScript execute both with report/2: the generated Go runtime asks a target implementing AwaitTarget, the TypeScript one a target with awaitOutcome; a target without it reports the scenario unsupported. Every reader refuses the await vocabulary under a lower major. A suite without either keeps its earlier format and bytes. Browser replay refuses 52/53 by version. Design Design |
provenance.suite_version: ess-conformance/54 or ess-conformance/55 | Existing provenance, with synthesis_seeds where seeds were selected; /55 also carries declared coverage | Added in 0.64.0. A view read through a reference of its source (beyond10x/ess#564). Written exactly when a scenario is named <view>/reference/<field>, one per ess/28 view and reference it reads through, a field declaring field: {related: …} or its filter reading <reference>.<field>: it reads the view before and after the row the reference names changes. Its steps and expectations are ones every runner already executes; only the identity is new. Cumulative over every major below, the 52/53 pair included. Rust, Go and TypeScript execute both with report/2; older readers refuse 54/55 by version, and every reader refuses the identity under a lower major. A suite without it keeps its earlier format and bytes. |
provenance.suite_version: ess-conformance/56 or ess-conformance/57 | Existing provenance, with synthesis_seeds where seeds were selected; /57 also carries declared coverage | Added in 0.67.0. A one-time read cell names its reader (beyond10x/ess#614). Written exactly when a suite holds a <command>/disclosure/<outcome>/<field>/read/<view>/as/actor/<A> cell: the value is issued as A where A is granted the issuing command, else as its first granted actor, and the view is then read as A after a read_as step. Below 56 the same id names the issuer and the view is read as no actor; every reader keeps that meaning for an older suite. The identity spelling and the steps are ones older majors carry; only what the actor names is new. Cumulative over every major below, the 54/55 pair included. Rust, Go and TypeScript execute both with report/2; older readers refuse 56/57 by version. A suite without such a cell keeps its earlier format and bytes. |
provenance.suite_version: ess-conformance/58 or ess-conformance/59 | Existing provenance, with synthesis_seeds where seeds were selected; /59 also carries declared coverage | Added in 0.70.0. A Decimal in an exact observer. Written exactly when a complete subject (snapshot_subject with a shape) or a retained result (capture_result) reaches a Decimal through a field, a named wrapper, a struct, a union or a collection: the value is compared by numeric value, so 1.5 and 1.50 are one value and 1.25 another. Go and TypeScript compare the exact value of the number token. The Rust runner holds a target's number as ess_primitives holds every number, reading a non-integer and an integer past 64 bits through binary64, so it compares two decimals that round to one binary64, such as 0.1 and 0.10000000000000001, as one value. A Binary64 there is still refused, and the refusal names the field. Cumulative over every major below, the 56/57 pair included. Rust, Go and TypeScript execute both with report/2; older readers refuse 58/59 by version, and every reader refuses a Decimal in an exact observer under a lower major. A suite without one keeps its earlier format and bytes. Design |
provenance.suite_version: ess-conformance/60 or ess-conformance/61 | Existing provenance, with synthesis_seeds where seeds were selected; /61 also carries declared coverage | Added in 0.78.0. An entity fixture: a resolve_fixtures field may carry entity and state together, naming a row of an ess/33 entity marked provided: true that the deployment holds. The provider makes or finds a row of entity resting in state and answers its identity, a value of type. Synthesis writes one where a when_related: {via: input.<field>} guard reads a provided row that no declared outcome creates; the exists: false branch is sent a fresh identity. Cumulative over every major below, the 58/59 pair included. Rust, Go and TypeScript execute both with report/2, and the interpreted target creates the row; older readers refuse 60/61 by version, and every reader refuses an entity fixture under a lower major. A suite without one keeps its earlier format and bytes. Design |
provenance.suite_version: ess-conformance/62 or ess-conformance/63 | Existing provenance, with synthesis_seeds where seeds were selected; /63 also carries declared coverage | Added in 0.79.0. A response observation's expected may name one member of a nested value by its dotted path ("checkpoint.checkpoint_id"), compared alone at the member's declared type: a value that is absent or null along the path matches only a null literal, and the members the path does not name are not read. Each path names a declared struct member at every step, through Optional and newtypes, and is refused otherwise before target effects. Cumulative over every major below, the provided-row pair included. Rust, Go and TypeScript execute both with report/2; older readers refuse 62/63 by version, and every reader refuses a response member path under a lower major. A suite without one keeps its earlier format and bytes. |
format: ess-conformance-input/1 | Selected inner original bytes and full original parent chain | Closed format/suite_json/parent_suites carrier; complete admission checks original references and typed lineage. Only selected inner bytes are hashed. Coverage contract |
format: ess-conformance-replay/1 | Paired typed model, exact selected suite reference and input | Closed format/model/suite/input; browser admission precedes replay state. Reduced projection, no execution evidence or full model digest reconstruction. Replay contract |
format: ess-mutation-report/7 | As version 6 | Added in 0.62.0. The version-6 report with unchanged_suite: true on a mutant (beyond10x/ess#586), written by either route wherever a mutant carries it; a report none of whose mutants carries it keeps the version in the rows below, with its earlier bytes. A mutant that would otherwise be survived or inconclusive is unwitnessed (ESS-MUTATE-004) with unchanged_suite when its synthesized suite has the baseline's scenario ids, each with the same steps and one-time trace, and no authored scenario ran; its text line ends — ESS-MUTATE-004: the suite does not change. killed and equivalent stand. The manifest does not change. No reader. source |
format: ess-mutation-report/6 | As version 5 | Added in 0.60.0. The version-5 report with overlap_taken_by on a mutant (beyond10x/ess#539), written by either route wherever a precedence-swap mutant carries it; a report none of whose mutants carries it keeps the version in the rows below, with its earlier bytes. overlap_taken_by lists, in declaration order, the branches answered before both branches of a precedence-swap whose input guards take every input both select, decided as an unsatisfiable_guard is and counting only branches selected by their input guard alone; such a mutant is equivalent (ESS-MUTATE-005) on the terms an unsatisfiable_guard makes one, and its text line ends — ESS-MUTATE-005: every input both branches select is taken first by `<branch>` . It is recorded apart from unsatisfiable_guard, which still says only that the two guards never overlap. No reader. source |
format: ess-mutation-report/5 | As version 4 | Added in 0.57.0. The version-4 report with identical_answer on a mutant (beyond10x/ess#517), written by either route wherever a precedence-swap mutant carries it; a report none of whose mutants carries it keeps the version in the row below, with its earlier bytes. identical_answer is the answer both branches of a precedence-swap give where it is the same one — the same error, the same or no payload, neither branch changing state, setting or emitting anything, and every binding invoking the command answering both with the same failure policy and final membership — such as refuse with `shop.order.Invalid` and no payload; neither changes state, sets or emits anything; such a mutant is equivalent (ESS-MUTATE-005) on the terms an unsatisfiable_guard makes one, and its text line ends — ESS-MUTATE-005: both branches <answer>. It is recorded apart from unsatisfiable_guard, which still says only that the two guards never overlap. No reader. source |
format: ess-mutation-report/4 | Original model digest (spec_digest), implementation, <system> <version>, the component and the known-failure declaration | Added in 0.53.0. Written by ess verify conform mutate --collect DIR for an emission scoped to a component (--emit --component NAME), and by mutate under a known-failure declaration (--known-failing, beyond10x/ess#294), and by either route where a selected emit-swap site has no admissible alternative (beyond10x/ess#295); every other report keeps the version in the row below. Such a report carries unavailable_sites, each as {class, command, event, id, outcome, reason, unaudited} in byte order of id, where id is emit-swap/<command>/<outcome>/<event> and reason is no_compatible_event_alternative: no declared event other than the outcome's only one has exactly its resolved fields, is published by every component that accepts the command, and compiles in its place, so single-event substitution was not audited there, as unaudited says. In an emission scoped to a component, a site whose command another component handles has outside_component instead. An unavailable site is neither a mutant nor counted in counts; one that is not outside_component makes the audit exit 3 unless a mutant survived, and is listed in the text after the inconclusive mutants and counted in the summary line as ; N unavailable. Under a declaration it carries known_failures (declaration_digest, the declared failures as {reason, scenario, tracking} and the implementation_build), and each mutant carries exclusions, the scenarios of its suite that are not eligible witnesses, as {reason, scenario} in scenario order: known_failed (declared, and failed in the baseline) or no_baseline_control (not in the baseline suite). Only a baseline-passing scenario can kill; a mutant whose changed declared scenario or new scenario hid a kill is inconclusive, and one with no eligible witness at all is inconclusive unless a gained or baseline synthesis refusal makes it unwitnessed, never killed or equivalent. A failure the declaration does not name still refuses with ESS-MUTATE-001; a stale or mismatched declaration exits 2. Known failures are listed in the text straight after the summary line, and the audit makes no conformance claim. No reader. That document, with component, the component every suite was scoped to, and out_of_scope: each mutant whose site belongs to another component (a command that component handles, a view it owns, a transition one of its commands performs, by the membership synthesize --component uses), as {change, class, id} in byte order of id. It had no suite, is not scored and is not counted in counts.mutants, so it never changes the exit status; a survivor on the component's own site is scored and counted. Codes as in the row below. source |
format: ess-mutation-report/3 | Original model digest (spec_digest), implementation and <system> <version> | Added in 0.42.0. This build no longer writes the version-1 or version-2 report; see the version history. Written by ess verify conform mutate only, to --report-out and as --format json (the same bytes); yaml renders them. No reader: nothing in this repository admits it. Sorted keys, two-space JSON plus LF, no timestamp, so the bytes are a function of the tree and the target. baseline carries scenarios, refusals and not_scored: each baseline scenario the target reported unsupported or the runner skipped, with that status, in suite order; no mutant is scored on one. One entry per mutant in byte order of id, with class, change, verdict (killed, survived, unwitnessed, inconclusive, equivalent, stillborn), the suite scenarios and refusals counts, killers on killed only, stillborn on stillborn only, added_refusals (each synthesis refusal of the mutant's suite the baseline's lacks, as {code, scenario, subject}, scenario absent when the refusal has none, subject the element refused, or the invariant (ESS-SYNTH-011), view (ESS-SYNTH-005, -014) or input path (ESS-SYNTH-001) one element or scenario is refused per; counted key by key, so a second refusal with a key the baseline holds once is added; sorted) when there is one, baseline_refusals (the baseline's synthesis refusals of the scenario of the outcome the mutant is on, as {code, scenario, subject}, sorted) where no baseline scenario takes that outcome and the baseline refused it, and on a from-drop or transition-to mutant the refusals of every outcome that performs its transition, where no baseline scenario takes any of them and the baseline refused each, unsatisfiable_guard (the guard a guard mutant left its outcome, as written) where no input satisfies it while some input satisfies the baseline's guard there, or on a precedence-swap mutant the overlap of its two guards where no input satisfies it, decided only for equality, membership and truth tests of non-optional scalar input fields, other than a Timestamp, against literals, over every combination of each field's values (a boolean's two, an enum's variants, and for any other field its literals and one value none of them equals) where there are at most 64 combinations, counted before any invariant applies; a combination no admitted input takes is still tried, so a guard is never called dead that an input satisfies, and excluded (the mutant's scenarios the baseline did not execute, sorted) when there is one; a mutant nothing killed with an excluded scenario it changed is inconclusive; one whose excluded scenarios are all the baseline's own, unchanged, can still be survived. counts adds unwitnessed and equivalent. A report --collect writes from a version-1 or version-2 manifest names no unsatisfiable_guard and scores no mutant equivalent. A report written by --collect also carries unscored on an inconclusive mutant whose report.json is missing, unreadable, or of another suite or implementation. Codes: ESS-MUTATE-001, a baseline scenario failed or ended error (stderr, exit 3, no report); ESS-MUTATE-002, assemble or compile refused a mutant (on its entry, with the refusal's own code as cause); ESS-MUTATE-003, the selected classes found no site (stderr, exit 3, no report); ESS-MUTATE-004, unwitnessed: the mutant's suite gained a synthesis refusal, or it has baseline_refusals, and no scored scenario failed (exit 3 unless a mutant survived); ESS-MUTATE-005, equivalent: the mutant has an unsatisfiable_guard, no scored scenario failed and no scenario it changed went unscored, which outranks unwitnessed; an inconclusive mutant stays inconclusive (does not change the exit status, but a run whose every mutant is equivalent or stillborn exits 3). A baseline that executed no scenario is refused as nothing scored (stderr, exit 3, no report). Mutation audit, source |
format: ess-mutation-report/2 | Original model digest (spec_digest), implementation and <system> <version> | Added in 0.41.0. Written by 0.41.0; this build writes ess-mutation-report/3, see the version history. 0.41.0 wrote it from ess verify conform mutate only, to --report-out and as --format json (the same bytes); yaml renders them. No reader: nothing in this repository admits it. Sorted keys, two-space JSON plus LF, no timestamp, so the bytes are a function of the tree and the target. baseline carries scenarios, refusals and not_scored: each baseline scenario the target reported unsupported or the runner skipped, with that status, in suite order; no mutant is scored on one. One entry per mutant in byte order of id, with class, change, verdict (killed, survived, unwitnessed, inconclusive, stillborn), the suite scenarios and refusals counts, killers on killed only, stillborn on stillborn only, added_refusals (each synthesis refusal of the mutant's suite the baseline's lacks, as {code, scenario, subject}, scenario absent when the refusal has none, subject the element refused, or the invariant (ESS-SYNTH-011), view (ESS-SYNTH-005, -014) or input path (ESS-SYNTH-001) one element or scenario is refused per; counted key by key, so a second refusal with a key the baseline holds once is added; sorted) when there is one, and excluded (the mutant's scenarios the baseline did not execute, sorted) when there is one; a mutant nothing killed with an excluded scenario it changed is inconclusive; one whose excluded scenarios are all the baseline's own, unchanged, can still be survived. counts adds unwitnessed. A report written by --collect also carries unscored on an inconclusive mutant whose report.json is missing, unreadable, or of another suite or implementation. Codes: ESS-MUTATE-001, a baseline scenario failed or ended error (stderr, exit 3, no report); ESS-MUTATE-002, assemble or compile refused a mutant (on its entry, with the refusal's own code as cause); ESS-MUTATE-003, the selected classes found no site (stderr, exit 3, no report); ESS-MUTATE-004, unwitnessed: the mutant's suite gained a synthesis refusal and no scored scenario failed (exit 3 unless a mutant survived). A baseline that executed no scenario is refused as nothing scored (stderr, exit 3, no report). Mutation audit, source |
format: ess-mutation-manifest/6 | As version 5 | Added in 0.60.0. The version-5 manifest with overlap_taken_by on a precedence-swap mutant whose overlap branches answered before both take, as the version-6 report carries it (beyond10x/ess#539). Written by ess verify conform mutate --emit DIR wherever a mutant carries it; any other emission keeps the version in the rows below, with its earlier bytes. Read back by --collect DIR exactly as version 5 is. A manifest of this version carrying overlap_taken_by on any other class is refused, and a version-5 or earlier one carrying it is refused naming this version. source |
format: ess-mutation-manifest/5 | As version 4 | Added in 0.57.0. The version-4 manifest with identical_answer on a precedence-swap mutant whose two branches answer alike, as the version-5 report carries it (beyond10x/ess#517). Written by ess verify conform mutate --emit DIR wherever a mutant carries it; any other emission keeps the version in the row below, with its earlier bytes. Read back by --collect DIR exactly as version 4 is. A manifest of this version carrying identical_answer on any other class is refused, and a version-4 or earlier one carrying it is refused naming this version. source |
format: ess-mutation-manifest/4 | Original model digest (spec_digest), <system> <version>, each suite's spec_digest and suite_digest, the component and the bound known-failure declaration | Added in 0.53.0. Every suite records suite_digest, the SHA-256 of its exact bytes, and --collect scores only report/2 of exactly those bytes (report/1 is collected only from version-3 and earlier manifests). With --emit --known-failing FILE the declaration is checked against the emitted baseline, copied byte for byte to known-failures.json, and bound as known_failures (digest, file, implementation, implementation_build); --collect then needs the host's ess-conformance-execution/1 beside every report.json (execution.json) of the bound build, refusing the collection when the baseline's is missing or mismatched and leaving a mutant whose is inconclusive, and refuses a declaration supplied again in other bytes, or to an emission that bound none. Written by ess verify conform mutate --emit DIR where the emission names a component, binds a declaration, or holds a sets-drop or precedence-swap mutant, an emit-swap mutant or an emit-swap site with no admissible alternative, recorded as unavailable_sites exactly as the version-4 report carries them; any other emission keeps the version in the row below, so its readers still collect it. Read back by --collect DIR. That document, with component, the component every suite was scoped to as synthesize --component scopes one, where one was named, and on each mutant whose site belongs to another component out_of_scope: true and no suite fields: nothing is written for it. A manifest of this version with an out_of_scope mutant and no component is refused; an earlier one carrying a component, an out_of_scope mutant, a sets-drop, precedence-swap or emit-swap mutant, or unavailable_sites is refused naming this version, and one of this version carrying identical_answer is refused naming version 5; an unavailable site of another class, with an id or unaudited that is not its own, out of byte order of id, also a mutant's site, or outside_component with no component is refused, and a format this build does not know is refused by name before any field is read. source |
format: ess-mutation-manifest/3 | Original model digest (spec_digest), <system> <version>, and each suite's spec_digest | Added in 0.42.0. Written by ess verify conform mutate --emit DIR as DIR/manifest.json; read back only by --collect DIR, which still reads the version-2 and version-1 manifests, and which reads the baseline's ir.json for the outcomes that perform each transition (without it, a transition mutant is scored without them). Sorted keys, two-space JSON plus LF, no timestamp. baseline names the unmutated suite's dir, scenarios, refusals, refused and spec_digest; mutants lists every mutant in byte order of id with class, site, change and either the same five suite fields, with unsatisfiable_guard where the emitter found the guard it left dead, or stillborn (ESS-MUTATE-002, no suite). refused lists each synthesis refusal as {code, scenario, subject} (at least one of scenario and subject), sorted, and must hold refusals entries; a version-2 manifest has no unsatisfiable_guard, so its emission scores no mutant equivalent; a version-1 manifest has neither, so its emission also judges a mutant's gained refusals by count and names none. A version-1 or version-2 manifest carrying unsatisfiable_guard is refused. Each dir is relative, of plain segments; --collect refuses any other. Unknown fields are refused. source |
format: ess-mutation-manifest/2 | Original model digest (spec_digest), <system> <version>, and each suite's spec_digest | Added in 0.41.0. Written by 0.41.0 from ess verify conform mutate --emit DIR as DIR/manifest.json; this build emits ess-mutation-manifest/3, and its --collect DIR still reads version 2 and version 1. Sorted keys, two-space JSON plus LF, no timestamp. baseline names the unmutated suite's dir, scenarios, refusals, refused and spec_digest; mutants lists every mutant in byte order of id with class, site, change and either the same five suite fields or stillborn (ESS-MUTATE-002, no suite). refused lists each synthesis refusal as {code, scenario, subject} (at least one of scenario and subject), sorted, and must hold refusals entries; a version-1 manifest has no refused, so its emission judges a mutant's gained refusals by count and names none. Each dir is relative, of plain segments; --collect refuses any other. Unknown fields are refused. source |
format: ess-history/3 | spec_digest of the specification the run was recorded against, history_id, seed | Added in 0.61.0. The format 2 document, whose operations may also carry input, the command's input as the client sent it (every input field by name, the field naming the subject included); events, each event a Returned command's answer published, in order, as {event, payload}; and arranged, the external: branches the client asked the target to arrange through ConfigureExternalOutcome before sending the call ([] for none). Each is absent where the writer recorded none and never null; events is refused on an Indeterminate operation, and all three are refused in a format 1 or format 2 document. A number inside input or a payload has one spelling, the ECMAScript spelling of its binary64 value that JSON.stringify and Go's encoding/json write (100, never 100.0 or 1e2; 1e+21; 0, never -0), and an object there repeats no key; either is refused by name otherwise, so a history read and written back keeps its bytes. A writer selects ess-history/3 exactly when an operation records any of the three, so a history without them keeps its format and its bytes. ess verify conform check-history steps an operation that records its input with exactly that input, where it otherwise asks whether some candidate input explains the answer; holds an operation that records its events to the events the branch it takes publishes, in order, and, with its input, each payload field the branch maps from the input or a literal to the value the model computes; and, for an operation that records arranged, admits an external: branch other than a replays: one only where an operation of the same command recorded arranging it and was invoked before this one returned. Written by the Go and TypeScript concurrent explorers for every command call (beyond10x/ess#576); a reader of format 1 refuses ess-history/3 by its format. source |
format: ess-history/2 | spec_digest of the specification the run was recorded against, history_id, seed | Added in 0.53.0. The format 1 document, whose operations may also carry decision_time: the UTC instant that call's command decision observed, read once at its decision edge, in one spelling (Z, a fraction only when it is not zero, no trailing zero, years 0000 through 9999). Absent where no decision was observed — a call refused before deciding, a retained answer delivered again, a target recording none — and never null; an Indeterminate operation keeps the instant its decision began at. invoked_at and returned_at stay ordering coordinates and are never read as the current time. A writer selects ess-history/2 exactly when an operation records a decision_time, so a history without one is still written as format 1, byte for byte as before, and writing format 1 with one is refused. ess verify conform check-history and web --history read both formats and refuse a decision_time in a format 1 document, written null, in another spelling, or a future major; a reader of format 1 only refuses ess-history/2 by its format before reading any operation. The checker reads each operation's recorded instant as now on every alternative it tries; an operation recording none leaves a guard that needs one unresolved, never a violation. Written by the Go and TypeScript concurrent explorers from a target's decision receipt. source |
format: ess-history/1 | spec_digest of the specification the run was recorded against, history_id, seed | Added in 0.39.0. One concurrent run: clients and, per operation, operation_id, client, command, subject_key, invoked_at, returned_at, completion (Returned or Indeterminate), outcome, a view read's rows and a retried request's retry_of. Declared by models/concurrent-history/, published as schemas/ess-history.schema.json. Read by ess verify conform check-history and web --history, which refuse an unknown, missing or repeated field, another format, a history of another specification, an operation whose completion disagrees with its instants or outcome, and any integer above 2^53 − 1. Written by the Go and TypeScript concurrent explorers and by import-history. source |
format: ess-history-adapter/1 | None | Added in 0.39.0. Maps each ess-history/1 operation field to a JSON pointer into one line of a JSON Lines call log, or declares it absent, and maps the log's completion words to Returned and Indeterminate. Read by ess verify conform import-history, YAML or JSON. source |
More columns: swipe horizontally, or focus the table and use the arrow keys.
For retained-result Integer observations, the actual target adapter must preserve the handler's exact integer before constructing its typed response. JSON adapters must decode it losslessly or report Unsupported; parity of typed observations does not certify arbitrary JSON numeric spellings or a generic floating-point conversion. Existing numeric bytes remain unchanged.
Source ess/7 also selects these stronger observations for ordinary wrong_state
refusal witnesses: every direct event is refused and the complete held subject
must remain unchanged. Missing complete observations refuse synthesis. Earlier
source formats keep their existing canonical witnesses.
The complete pair is snapshot_complete_subject followed by
expect_complete_subject_unchanged. Its required shape contains
identity_field, typed fields and reachable declarations; it supplies
schema authority, not expected target values. Both actual rows must satisfy that
shape; missing required fields or incompatible values fail execution. Invalid
pairings or unsupported recursive observers refuse admission. Extra top-level row fields remain
permitted and participate in exact comparison. Legacy snapshot_subject and
expect_subject_unchanged retain their original semantics, including inside a
newer suite.
Replay synthesis checks the retry's condition against the original input and post-command subject. It refuses an unavailable immediate witness without rejecting a model whose retry may become eligible after later activity.
ess verify impact computes generated-artifact obligations from the compared models. The CLI
has no --generated option and does not inspect a committed output tree. The library API can accept
a GeneratedTree for that additional check. See Track specification change
and the impact implementation.
ConformanceSuite::to_canonical_json, Go/Web emit and Runner::run now return
Result with a located AdmissionError for unsupported Binary64 contracts. The
model producer/CLI guard also checks sparse models whose unsupported fields would
be absent from the suite. Suite readers and serializers reject the new primitive
under the existing suite vocabulary; no new suite version or float codec support
is implied. Existing admitted canonical suites retain their bytes.
Generated documents and external formats
| Document | Independent version/identity | Reader and bytes |
|---|---|---|
format: ess-docs/1 | Specification version and per-page provenance | Derived document/page parsing; explicit page-id and renderer checks are separate. CLI pretty JSON; nested String digests are not automatically profile-validated. Source |
format: ess-browser-catalog/1 | Specification version and plan provenance | Web writer/generated browser consumer; no general catalog-admission API. Key-sorted pretty JSON, whole-contract provenance. Source |
format: ess-service-interface/1 | source_openapi version and service.version | Retained structural DTO, then explicit validate; legacy integer, number and boolean unit variants discard unknown fields. Unchanged pretty JSON; no interface digest or durable import-accounting claim. Legacy files require original-source reimport for checked CLI projection. Source |
format: ess-openapi-import/1 | Fixed ess-openapi-service-subset/1 profile, admitted schema dialect and source version | Closed envelope; read_import refuses duplicate keys, reimports retained source and compares the complete interface, accounting and identity. Typed pretty JSON plus LF. source.sha256 is bare lowercase SHA-256 of exact retained UTF-8 source bytes, distinct from compiled-model identity. Old interface readers reject this wrapper. Source |
| JSON Schema draft 2020-12 | Specification version and ESS provenance; no generated root $id | ESS contract projection for external schema consumers. Pretty JSON, source/sliced stamps. An adopter-owned registry copy can add its own resource ID. Source |
| OpenAPI 3.1.0 from ESS | info.version and ESS provenance | ESS generation and HTTP synthesis; deterministic YAML or pretty JSON, source/sliced stamps. Source |
| OpenAPI 3.1.0 from imported interface | Interface service version | Checked CLI projection requires complete semantic accounting and resolved references; legacy or partial input refuses before output. Known annotation omissions may pass. The retained low-level interface API is structural. Deterministic YAML, no invented compiled-ESS digest. Source |
| AsyncAPI 3.0.0 | info.version and ESS provenance | ESS generation; deterministic YAML, source/sliced stamps. Source |
| ESS authoring schema, draft-07 | Describes source format/version syntax | cargo xtask schema; pretty JSON, complete-byte drift check. Schema validation does not resolve a whole specification. Source |
Rust HTTP startup JSON lines: log: ess/1 | Specification facts plus runtime language/address/port | Generated server output; compact lines, no whole-record hash. This shared marker value does not make the log a specification document. Source |
Go HTTP startup JSON lines: log: ess/1 | Shared specification facts plus Go runtime fields | Separate generated writer using shared startup facts; no log-admission reader or cross-language byte promise. Source |
More columns: swipe horizontally, or focus the table and use the arrow keys.
web::browser_catalog(ir, plan) -> BrowserCatalog remains a separate semantic catalog API with
unchanged ess-browser-catalog/1 bytes. It does not run the workspace's fatal feasibility gate;
catalog availability does not establish that a Rust/Web workspace can be emitted. When a Web
workspace is emitted, its catalog uses the same bytes. Catalog API.
Generated artifact maps, validation/refusal/adapter summaries, inspected declarations, interaction graphs, delivery/composition/realization diagnostics, infrastructure diagnoses and schema-validation reports are unversioned machine presentations. Their JSON/YAML can be saved, but there is no general ESS reader for those report files or an implicit whole-report digest. CLI owners, schema reports, infrastructure diagnosis.
Markdown, HTML, generated source code and build manifests follow their individual writers.
Kubernetes apiVersion/kind, Helm artifacts and BuildKit inputs use their external contracts;
they do not introduce another ESS format marker. Adopter-owned JSON Schema $id identifies its
schema resource independently of any digest. Neither the contract nor syntax schema generator
assigns that ID or a hosted schema endpoint. The
local registry workflow
adds only root IDs to separate copies and uses strict application envelopes with absolute payload
references. Original generated bytes, dialects, constraints and provenance remain intact; a copied
resource's model or slice digest is not its file checksum. Registry validation resolves the supplied
resources offline, and its successful records identify the selected envelopes. It does not establish
whole-system semantic validity or support in the separate restricted TypeScript projector.
Infrastructure records
The ess verify bindings command, introduced in 0.21.0, connects admitted realization selections to
native infrastructure observations. ess-observed-bindings/1 and /2 are closed authored
JSON/YAML DTOs; the binding digest hashes compact typed JSON after sorting bindings by id and
sorting declared evidence, and, for /2, sorting foreign_containers by workload and container
name. It retains all authored image expectations and the exact realization digest. /2 adds
optional foreign_containers: per bound workload, containers this realization does not build,
each with a name and a nonempty reason and no image. /1 is read unchanged and acknowledges
nothing; its binding digest is the one earlier releases computed, and a /1 document carrying
foreign_containers is refused. Earlier readers refuse /2 by its format.
ess-observed-bindings-report/3 is serialize-only, deterministic pretty JSON plus LF with no
whole-report digest or report-admission reader. /2 added the OBS-BIND-008 check (an unbound
container or native sidecar in a bound workload violates), so the same input can be satisfied
under /1 and violated under /2. /3 adds each binding's acknowledged list (container,
reason) of acknowledged foreign containers observed in its workload; a satisfied OBS-BIND-008
now means each entry is bound or acknowledged. An acknowledged container running a declared
image or artifact locator, or its @sha256: digest under another name, violates it, and an acknowledgement naming no observed container or
native sidecar leaves it unknown, since plain init containers are not recorded. A /1 reader must reject /2, and a /2 reader /3. It carries that binding digest, realization digest,
observation model digest and provenance, per-binding results and explicit exclusions. These
identities name different bytes. Missing evidence produces unknown, never an empty successful
comparison. Binding guide.
The namespace topology profile adds infra-observation/2, infra-ir/2, infra-graph/2,
infra-drift/2 and infra-simulation/2. Its closed coverage claim names the namespace and
namespace_topology profile. IR coverage belongs to the canonical model and its digest;
graph and drift retain that coverage, and simulation retains it in its typed unknown reason.
Version 1 bytes remain unchanged, and version 1 cannot carry version 2 qualifications.
See namespace collection
for omitted content, comparison restrictions and projection refusal.
| Document and discriminator | Independent identity | Reader and byte contract |
|---|---|---|
format: infra-observation/1 | Context, scan time, scanner release | Sanitized scanner output; permissive raw DTO → observation validation. Pretty JSON without an appended LF; scanner-reported hash covers those file bytes. It does not prove complete collection scope. Writer, reader |
format: infra-observation/3 | Context, scan time, scanner release | What ess-kubernetes scan writes for a full scan. /1 with one meaning changed: each Secret data/stringData value is exactly {"present": true} — the key name and that a value exists, with no digest and no length. Anything else is refused (INFRA-SECRET-001 for a plain value, INFRA-SECRET-003 otherwise). /1 wrote each value's unsalted SHA-256 and byte length, which let anyone holding the file confirm a guessed low-entropy secret; /1 still reads, its digests are checked for shape and discarded. Same byte contract as /1. Writer, reader |
format: infra-ir/1 | Observation provenance and model digest | read_document checks exact format, closed mirrors, hash and resolved-reference membership. CLI pretty envelope; infrastructure-model digest. Checked model transformations add no wire version or completeness proof. A workload's optional native_sidecars (name and image of each initContainers entry with restartPolicy: Always) is absent when the observation did not record init containers and [] when it recorded none; before 0.32.0 the field is written only for a native sidecar or an explicit initContainers: [], so every other document from those producers keeps its bytes and digest; older readers refuse a document that carries the field. API, reader |
format: infra-ir/3 | Observation provenance and model digest | /1 with one meaning changed: each Secret key holds {"present": true} and nothing derived from its value. Written for every full observation that has a Secret key, including a compiled infra-observation/1; an IR with no Secret key keeps /1 and its bytes. read_document refuses a document whose declared version disagrees with its Secret values, and one model mixing markers and legacy digests. A persisted /1 still reads: its own digest is checked, then each Secret key is reduced to presence, so what was read is /3 with a different model digest. Every derived document (graph source_digest, drift from/to, simulation snapshot, projection snapshot_digest, observed-bindings observation) names that stripped digest, and none chains to the /1 file's own digest any more: a digest over the unsalted Secret digests, beside the /3 of the same model, confirms a guessed Secret value. API, reader |
format: infra-spec/1 | Human-readable intent name and typed-intent digest | JSON/YAML → raw shapes → validated InfraSpec. digest() hashes the compact sorted typed intent; no canonical authored-file digest. Reader, digest |
format: infra-drift/1 | Before/after context and model digests | Written by earlier releases for full scans. Serialize-only typed comparison; key-sorted pretty JSON. Context agreement does not prove equal collection scope. For a Secret, changed_keys named keys whose value digest moved, so an empty list meant "not rotated". This build no longer writes it. Source |
format: infra-drift/3 | Before/after context and model digests | What ess infra diff writes for full scans: /1's fields with one meaning changed. For a Secret, config_content_changed names added and removed keys only and changed_keys is always empty, over any pair of IR versions: a rotated Secret value is unknown, not unchanged, because the IR no longer records anything that would detect it — a digest of a low-entropy secret is a guess oracle. /2 remains the namespace topology profile. Serialize-only; no drift reader exists. Source |
format: infra-simulation/1 | Intent name and snapshot digest | Serialize-only simulation with unknown outcomes; key-sorted pretty JSON, no simulation hash. Source |
format: infra-graph/1 | Context/namespace and source_digest | Serialize-only graph; pretty JSON. Its source digest names the InfraIR model, not EssIr. Source |
format: infra-projection/1 JSON, artifacts list | Intent name; provenance.snapshot_digest names InfraIR model, provenance.specification_digest names typed InfraSpec | ProjectionDocument contains emitted file contents and both input digests; key-sorted pretty JSON, no reader or whole-output hash. Source |
format: infra-projection/1 YAML, patches/objects lists | Same intent name, snapshot digest and typed-intent specification_digest | CLI serializes Projection directly, retaining both input digests. This differs from the JSON document despite the shared marker; no persisted reader. Type, CLI |
More columns: swipe horizontally, or focus the table and use the arrow keys.
CLI presentation bindings
The /1 versions were introduced in 0.21.0. Each document carries its version in a format key.
The binding reader admits ess-cli/1 and ess-cli/2, and a binding compiles to the plan version
of the same number, so an ess-cli/1 binding compiles to the same ess-cli-plan/1 bytes as before
/2 existed.
| Document | Written or read by | What it holds |
|---|---|---|
format: ess-cli/1 | Authored; read by ess specify cli and ess generate cli | The binary, its command paths, aliases, argument sources and process context, bound to operations of an ESS model. All three globals, config, state and output, are required. A binding naming another format is refused. Source |
format: ess-cli/2 | Authored; read by ess specify cli and ess generate cli | ess-cli/1 with config and output optional; state stays required. An omitted global is no flag at all, and a CLI without output writes JSON only. In either version null, ~, an empty value and "" are refused naming the global: omitting the key is the one spelling of absence. Source |
format: ess-cli-plan/1 | Printed by ess specify cli | The resolved binding: the binary, its about text and global arguments, the callables, every command sorted by path, and the obligations the generated package leaves to its handlers. Source |
format: ess-cli-plan/2 | Printed by ess specify cli for an ess-cli/2 binding | ess-cli-plan/1 whose globals omits an undeclared config or output key; it never writes null. A /1 reader refuses one that omits a global, naming the missing field. Source |
format: ess-cli-artifacts/1 | manifest.json in the package ess generate cli writes | The binary and package names, every generated file, and the plan's obligations. Pretty JSON plus LF. Source |
format: ess-cli-generation/1 | Printed by ess generate cli --format json or yaml | The files written, or compared under --check, and whether it was a check. Source |
More columns: swipe horizontally, or focus the table and use the arrow keys.
Deployment recovery records
ess generate deployment reconcile --authority UUID reads and writes five record formats. The
registry and its authorities live under the protected root /etc/ess/recovery; the store header,
lock and journal live under the state_root the selected authority names. All five were
introduced in 0.21.0, and each has exactly one admitted version: a record naming any other is
refused. The bytes are canonical JSON: recursively sorted keys, array order kept, no duplicate
key, no floating-point number, and exactly one trailing newline. Source
| Document | What it is |
|---|---|
format: ess-execution-registry/1 | The complete active registry snapshot, registry.json: its generation and every active authority, sorted by authority UUID. An empty registry authorizes nothing. |
format: ess-execution-authority/1 | One authority revision inside the registry: the pinned cluster, principal, host and store policy, permitted contexts, the environment it owns, the exact desired and baseline digests, one release permit per service, and any quiescence decisions. |
format: ess-execution-store/1 | store.json, the header of a provisioned recovery store: its epoch, the host it belongs to and the cluster its lock excludes on. |
format: ess-execution-lock/1 | target.lock, the durable claim one invocation holds on one cluster: the invocation, the authority and its revision, the cluster, and the registry generation and digest it was admitted under. |
format: ess-execution-evidence/1 | One immutable journal entry of an invocation, under invocations/: its sequence number, the digest of the previous entry's bytes, and one recorded fact. |
More columns: swipe horizontally, or focus the table and use the arrow keys.
Compatibility boundaries
Use the owning reader's validation API. The stamp reader accepts complete authoritative envelopes and supported profiles, including matching comment/structured copies where the writer emits both. Generic String deserialization does not perform that check. Cargo synthesis stamp recognition does not validate TOML, and a docs document has per-page stamps rather than one artifact stamp. Stamp reader.
Explicit report /2 and detailed ess-conformance-run/2 pair admitted original suite/1–13
bytes under sha256-json-bytes/1. Ordinary suite/1–4, /6, /8, /10 and /12 coverage remains unknown, including all-pass runs.
Suite /5 adds a closed declared inventory: exact selection, origin/source ownership, outside
scenarios and every refusal occurrence. Only nonempty all-pass execution with complete inventory
and no in-scope refusal qualifies for that exact selection. Suite/7 retains these rules with
extended observation/setup vocabulary; suite/9 adds typed command-response observation,
suite/11 adds independent subject snapshots, and suite/13 adds retained-result comparison.
Legacy defaults remain suite/4, report/1 and diagnostic execution;
an extended suite requires explicit report/2. Suites /5 to /13 with report/1 refuse before execution, including without an
output destination or with allow-incomplete. Report/1 keeps its historical non-pass aggregate and
does not establish exact suite-byte identity. Coverage workflow.
A runner outside ESS reports through ess-conformance-results/1 rather than by writing report/2
itself. ess verify conform report admits the suite the runner executed and takes coverage, the
suite reference and policy from that admission, so the report it writes qualifies exactly as one
ESS's own run would. Its producer_profile, external-scenario-status/1, says that ESS executed
nothing; a reader that admits only rust-scenario-status/1 and go-scenario-status/1 refuses it.
message is read and not carried into the report.
Generated Go and TypeScript count reports use go-scenario-status/2 to distinguish a
failed assertion, an execution error, an unsupported required observation and an explicit skip.
An unsupported observation makes execution fail; an error or skip makes it inconclusive unless
another scenario failed or was unsupported. Counts and outcome lists retain each category.
The older go-scenario-status/1 remains readable with its original passed/failed/skipped
categories; it cannot carry error or unsupported outcomes. Unknown producer profiles are refused.
Legacy report/1 keeps its diagnostic presentation and does not establish this count-profile parity.
ess-conformance-input/1 has exactly format, original selected suite_json and nearest-first
parent_suites strings. Every explicit child needs its complete original parent chain. The selected
inner string is hashed, never the carrier or the reduced execution DTO; all surviving definitions,
dependencies, source mappings and refusal occurrences must agree. ess-conformance-replay/1 pairs
that input with the exact SuiteReference and a closed typed reduced model before browser state is
created. The player displays coverage but emits no evidence; it does not reconstruct the full model
digest, authenticate a publisher or fill the existing literal-assignment/view-evaluation omissions.
New counts and timestamps use exact unsigned decimal u64 tokens. Go's selected execution adapter
separately checks its host int width after admitting all parents, and its clock remains nonnegative
int64; Rust timestamps retain the full u64 range. Declared Node payloads retain finite binary64
meaning. Modeled Binary64 remains refused before conformance output. Impact with complete admitted
input retains ess-impact/3 and presents selection separately; unknown/incomplete input refuses.
A format catalog alone does not establish an installed external consumer upgrade.