Skip to main content

Executable system specifications · experimental

Specify once.
Derive contracts.
Prove the code.

ESS turns system intent into a validated typed model, deterministic artifacts and an executable conformance suite. A specification is YAML; the compiler resolves every reference, the projections derive documentation and interface contracts from the result, and the same model generates the scenarios an implementation must pass. Nothing it does applies infrastructure.

Rust · YAML specifications · canonical JSON IR · Apache-2.0

examples/billing/domains/invoice.yaml
- name: billing.invoice.Money
kind: struct
fields:
- name: amount
type: Decimal
- name: currency
type: String
invariants:
- amount >= 0

ess generate generate --kind openapi

generated/openapi/invoice-service.yaml
billing.invoice.Money:
title: Money
x-ess-name: billing.invoice.Money
x-ess-kind: struct
type: object
properties:
amount:
type: string
format: decimal
pattern: ^-?(0|[1-9][0-9]*)(\.[0-9]+)?$
currency:
type: string
required:
- amount
- currency
additionalProperties: false
x-ess-invariants:
- amount >= 0
A declared type of examples/billing and the OpenAPI schema ess generates from it, quoted verbatim by cargo xtask site-data and checked for drift by task check.

ess built from this repository, recorded by `cargo xtask site-data` on a copy of examples/billing

capabilities tracked
12
shipped, runs today
10
planned
2
entities in the domain
2

01 / What it does

Model, project, prove.

Architecture notes, API descriptions, manifests and test plans each hold a fragment of a system, and nothing proves they still describe the same thing. ESS makes those claims typed input: validation refuses unresolved meaning, compilation produces deterministic IR, and every projection states its coverage and obligations.

  1. Model

    Shipped

    Systems, domains, entities, commands, outcomes, events, views, components, bindings and topology are validated as typed structures. Every reference resolves to a compiler-minted handle.

  2. Project

    Shipped

    Markdown and HTML documentation, JSON Schema, OpenAPI 3.1 and AsyncAPI 3.0 come from the compiled IR. Each adapter declares the subset and direction it supports.

  3. Prove

    Shipped

    The specification synthesizes its own conformance suite. Run it against a built-in target, or emit a Go or TypeScript runner and hold your implementation to it.

  4. Synthesize

    Shipped

    Structural Rust, Go, browser and Clap code from the same model. What the specification does not determine stays a typed obligation for someone to implement.

  5. Import

    Shipped

    OpenAPI documents and sanitized Kubernetes observations become typed input. An importer never guesses: unsupported constructs remain coverage gaps, obligations or refusals.

  6. Track change

    Shipped

    verify diff compares two revisions of a specification semantically; verify impact reports the conformance scenarios and generated artifacts the change invalidates.

02 / How it works

From a specification to a verdict.

Each step is a command that runs today. The terminal below is these steps on the billing example, recorded rather than typed.

  1. Authorsystem.yaml

    A system, its domains, entities, commands and views, as YAML.

  2. Validateess specify validate

    Every reference resolves; meaning the model cannot express is refused.

  3. Compilecanonical IR

    Resolved handles, ordered collections, one serialization.

  4. Projectess generate

    Documentation, schemas and interface contracts from the IR.

  5. Proveess verify conform

    Synthesize the suite the specification obliges, then run it.

03 / See it run

The same steps, on the billing example.

Validate, compile, synthesize the suite the specification obliges and run it against the built-in billing target.

ess / the billing example
ess specify validate --path examples/billing
billing v3 — 5 file(s), valid

ess specify compile --path examples/billing
billing v3 — 5 file(s), 26 declaration(s), compiled

ess verify conform synthesize --path examples/billing --out suite.json
note: the specification declares actors and serves no component, so enforcing a grant is the caller's, against the generated grant table, and no `<command>/grant/denied` scenario is owed
32 scenario(s) (0 authored), 0 refusal(s), written to suite.json

ess verify conform run --suite suite.json --target billing --report-format 2
Requires an empty logical modeled-instance/event/invocation namespace before each scenario setup; unrelated physical data need not be deleted.
Requires an empty logical modeled-instance/event/invocation namespace before each scenario setup; unrelated physical data need not be deleted.
billing v3 against billing-reference 0.85.0 — passed
  passed billing.email.SendEmail/outcome/failed
  passed billing.email.SendEmail/outcome/sent
  passed billing.invoice.CancelInvoice/outcome/cancelled
  passed billing.invoice.CancelInvoice/outcome/wrong-state
  passed billing.invoice.CreateInvoice/outcome/accepted
  passed billing.invoice.CreateInvoice/outcome/rejected
  passed billing.invoice.Invoice/invariant/after/billing.invoice.CancelInvoice/cancelled
  passed billing.invoice.Invoice/invariant/after/billing.invoice.CreateInvoice/accepted
  passed billing.invoice.Invoice/invariant/after/billing.invoice.IssueInvoice/issued
  passed billing.invoice.Invoice/invariant/after/billing.invoice.PayInvoice/settled
  passed billing.invoice.Invoice/state/Cancelled/refuses/billing.invoice.CancelInvoice
  passed billing.invoice.Invoice/state/Cancelled/refuses/billing.invoice.IssueInvoice
  passed billing.invoice.Invoice/state/Cancelled/refuses/billing.invoice.PayInvoice
  passed billing.invoice.Invoice/state/Draft/refuses/billing.invoice.PayInvoice
  passed billing.invoice.Invoice/state/Issued/refuses/billing.invoice.IssueInvoice
  passed billing.invoice.Invoice/state/Paid/refuses/billing.invoice.CancelInvoice
  passed billing.invoice.Invoice/state/Paid/refuses/billing.invoice.IssueInvoice
  passed billing.invoice.Invoice/state/Paid/refuses/billing.invoice.PayInvoice
  passed billing.invoice.Invoice/transition/cancel/by/billing.invoice.CancelInvoice/cancelled
  passed billing.invoice.Invoice/transition/issue/by/billing.invoice.IssueInvoice/issued
  passed billing.invoice.Invoice/transition/settle/by/billing.invoice.PayInvoice/settled
  passed billing.invoice.IssueInvoice/outcome/issued
  passed billing.invoice.IssueInvoice/outcome/wrong-state
  passed billing.invoice.Money/invariant/at/billing.invoice.InvoiceById/total
  passed billing.invoice.Money/invariant/at/billing.invoice.OutstandingInvoices/total
  passed billing.invoice.PayInvoice/outcome/rejected
  passed billing.invoice.PayInvoice/outcome/settled
  passed billing.invoice.PayInvoice/outcome/wrong-state
  passed notify-on-invoice-created/binding/delivery
  passed notify-on-invoice-created/binding/flow
  passed notify-on-invoice-created/binding/mapping
  passed notify-on-invoice-created/binding/on-failure
  32 scenarios: 32 passed, 0 failed, 0 error, 0 unsupported
ess built from this repository, recorded by `cargo xtask site-data` on a copy of examples/billing4/4 exit 0 · 3 ✓ · 0 ✕

04 / See a specification run

The billing example, as its compiler sees it.

The invoicing domain of examples/billing, drawn from the IR that ess specify compile produces. Entities with their identities and fields, the lifecycle each one moves through and the commands that move it, and the relations between them. Hover an entity to trace what it relates to.

ESS domain · billing.invoice

Invoicing

Issuing invoices and tracking whether they are paid.

  • Entities2
  • Owns
  • One
  • Many
  • Initial state
ENTITY · 2 FIELDSAccountActiveENTITY · 13 FIELDSInvoiceCancelledDraftIssued+1

Hover or focus an entity to see its fields, lifecycle and relations. Press Enter to pin it, Escape to clear.

Lifecycles with transitions

Invoice
Generated from the compiled IR by cargo xtask site-data; task check fails when it falls behind the specification.
Domain as text
Entities
EntityIdentity and fieldsLifecycleRelations
Accountaccount_id: AccountId (identity) display_name: stringstates Active; initial Activeinvoices owns many Invoice
Invoiceinvoice_id: InvoiceId (identity) account_id: AccountId total: Money payee: Payee channel: Channel lines: List<LineItem> note: Optional<string> metadata: Map<string, string> issued_at: Optional<timestamp> settlement_window: duration is_recurring: boolean signature: bytes reminder_count: integerstates Cancelled, Draft, Issued, Paid; initial Draft issue: Draft → Issued (billing.invoice.IssueInvoice) settle: Issued → Paid (billing.invoice.PayInvoice) cancel: Draft or Issued → Cancelled (billing.invoice.CancelInvoice)—

Source: examples/billing, compiled by `ess specify compile`; generated by `cargo xtask site-data`

05 / Generate

Contracts and code from the same model.

One projection and one synthesis target, on the same specification. The synthesis report counts what it generated, what it left as an obligation and what it refused.

ess / generate and synthesize
ess generate generate --path examples/billing --kind openapi --out generated
openapi/email-service.yaml — 7599 byte(s)
openapi/invoice-service.yaml — 32249 byte(s)
2 artifact(s), written to generated

ess generate synthesize --path examples/billing --target rust --out billing-rust
48 capabilities: 40 generated, 4 obligation(s), 4 refused
17 artifact(s), written to billing-rust
ess built from this repository, recorded by `cargo xtask site-data` on a copy of examples/billing2/2 exit 0

06 / Status

Experimental. Here is exactly what exists.

Shipped means a command that runs today in the current source. Planned means on the roadmap and not scheduled. Live imports and the commands named execute, publish, fetch and reconcile are explicit credential edges.

Shipped · runs today

  • ShippedValidation and canonical compilationName resolution, reusable shapes, entity relations, total handle lookup, inspection and graphing.
  • ShippedDocumentation and interface projectionsdocs, site, schema, openapi and asyncapi; docs-ir on request.
  • ShippedJSON Schema registriesOffline validation and deterministic TypeScript projection for adopter-owned registries.
  • ShippedStructural synthesisrust, go, web and clap targets, with explicit obligations and refusals.
  • ShippedConformance suites and runsAuthored and component-scoped suites, outcome-to-entity assignments and parameterized views; built-in targets billing, oracle-fixture and interpreted; generated Go and TypeScript runners with standalone reports.
  • ShippedMutation auditMutates the specification to find rules the synthesized suite does not pin; seeded command exploration and linearizability checks of recorded histories.
  • ShippedSemantic diff and impactverify diff and verify impact.
  • ShippedOpenAPI and Kubernetes importOpenAPI 3.0 and 3.1 service subset; sanitized Kubernetes observations to infrastructure IR, analysis and manifest projection.
  • ShippedComponent deliveryBuild, runtime, release, stack and deployment models; generated Services, stateful workloads and volume claims; digest-pinned OCI bundles and affected-only Helm reconciliation behind explicit executor commands.
  • ShippedUI documentsess-ui/1 documents load, check, render and test headless.

Planned · roadmap only

As of 2026-10-04 · Maintained with the source; shipped means a command that runs in the current source checkout