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.
- name: billing.invoice.Money
kind: struct
fields:
- name: amount
type: Decimal
- name: currency
type: String
invariants:
- amount >= 0
ess generate generate --kind openapi
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
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.
Model
ShippedSystems, domains, entities, commands, outcomes, events, views, components, bindings and topology are validated as typed structures. Every reference resolves to a compiler-minted handle.
Project
ShippedMarkdown 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.
Prove
ShippedThe 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.
Synthesize
ShippedStructural Rust, Go, browser and Clap code from the same model. What the specification does not determine stays a typed obligation for someone to implement.
Import
ShippedOpenAPI documents and sanitized Kubernetes observations become typed input. An importer never guesses: unsupported constructs remain coverage gaps, obligations or refusals.
Track change
Shippedverify 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.
- Authorsystem.yaml
A system, its domains, entities, commands and views, as YAML.
- Validateess specify validate
Every reference resolves; meaning the model cannot express is refused.
- Compilecanonical IR
Resolved handles, ordered collections, one serialization.
- Projectess generate
Documentation, schemas and interface contracts from the IR.
- 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 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
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
Issuing invoices and tracking whether they are paid.
- Entities2
- Owns
- One
- Many
- Initial state
Hover or focus an entity to see its fields, lifecycle and relations. Press Enter to pin it, Escape to clear.
Lifecycles with transitions
InvoiceDomain as text
| Entity | Identity and fields | Lifecycle | Relations |
|---|---|---|---|
Account | account_id: AccountId (identity) display_name: string | states Active; initial Active | invoices owns many Invoice |
Invoice | invoice_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: integer | states 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) | — |
More columns: swipe horizontally, or focus the table and use the arrow keys.
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 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
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
- PlannedObligations as trackable recordsToday an obligation is an entry in the generated plan, not a record evidence can close.
- PlannedA conformance target in another processverify conform run reaches only the targets built into ess.
As of 2026-10-04 · Maintained with the source; shipped means a command that runs in the current source checkout