From Beta to v1: The Contract Invariant Must Earn
What Invariant already guarantees in Beta, what still blocks v1, and the evidence required before the project can make a stable compatibility promise.
José Vásquez
Founder & Lead Engineer @ Invariant
Invariant now has a real Beta contract: typed workflows and agents, durable execution state, append-only events, transactional command intent, Sessions, projections, optimistic concurrency, leases, and SQLite and PostgreSQL adapters.
That is meaningful progress. It is not the same as being ready for v1.
A stable release should mean more than removing -beta from a package version. It should tell an engineering team what will remain compatible, what happens when a process fails at the worst possible moment, how persisted data evolves, and which operational responsibilities belong to Invariant versus the host application.
v1 is not a declaration that the software is finished. It is a promise that the public contract is stable, the failure boundaries are explicit, and every guarantee has reproducible evidence.
What the Beta Guarantees Today
The 0.1.0-beta.1 contract establishes several foundations that we intend to carry forward:
- Workflow topology and Runtime Actions constrain what a model is allowed to propose.
- Configured stores commit execution state, durable events, and command intent atomically with optimistic concurrency control.
- New runs receive host-generated UUID identities.
- Durable event identity is derived from
${runId}:${sequence}. - Authoritative revision advances once for every durable event, including transitions that emit multiple events.
- SQLite and PostgreSQL implement the same storage contract for state, events, commands, Sessions, leases, and runnable execution discovery.
- Legacy persisted histories remain readable and replayable.
- Invalid or stale proposals are rejected before authoritative progress is committed.
These are runtime guarantees, not prompt conventions. They are backed by reducer, SDK, store-conformance, real PostgreSQL, snippet, build, and external-consumer tests.
But the boundary matters just as much as the guarantee.
The Most Important Beta Limitation
The current host dispatches committed commands in process. Durable stores expose leases and runnable execution IDs, but the public API does not yet expose all of the operations required for a portable recovery loop:
- no atomic pending-command claim and acknowledgement contract;
- no supported cross-process execution attachment API;
- no packaged background recovery scanner or worker;
- no built-in automatic timer scheduler.
Persisted facts can reconstruct committed truth. That does not mean a new process can automatically become the live owner of an interrupted execution.
The distinction is documented in the canonical Recovery Contract Matrix. Until the missing operations exist, cross-process continuation remains application-owned.
External effects also remain at-least-once when redispatched. Stable idempotency keys reduce duplicate risk only when the external provider honors them. Invariant does not claim exactly-once execution across a database and an unrelated external system.
This is the largest technical gap between Beta and v1.
What Must Be True Before v1
1. A Complete Cross-Process Recovery Contract
The public store and host APIs need to support the full lifecycle of interrupted work:
discover runnable execution
↓
acquire fenced ownership
↓
attach and reconstruct the execution
↓
claim pending command atomically
↓
dispatch with the same idempotency identity
↓
acknowledge, retry, or terminate explicitly
This includes lease renewal and expiry, retry scheduling, bounded backoff, poison-command handling, and .wait() continuation from a new process. Crash-injection tests must cover every boundary before and after the external effect.
2. Stable Effect Semantics
v1 must document one precise answer for each of these questions:
- Which identity reaches the external provider?
- What becomes durable before dispatch?
- What happens after an ambiguous timeout?
- How does a retry preserve command identity?
- When does a command become terminal?
- What can compensation attempt, and what can it never guarantee?
The answer will continue to be based on at-least-once delivery and provider idempotency—not exactly-once marketing.
3. Schema Evolution and Data Safety
Persistent infrastructure needs an upgrade story. Before v1, SQLite and PostgreSQL schemas need explicit versions, forward migrations, backup and restore guidance, rollback procedures, and compatibility tests against legacy histories.
A runtime is not durable if upgrading it makes yesterday's runs unreadable.
4. Security and Tenant Boundaries
Wait re-entry, Sessions, webhooks, MCP endpoints, live-audio tokens, traces, and storage all cross trust boundaries. v1 requires a published threat model and an explicit division of responsibility for authentication, authorization, tenant isolation, secrets, PII, retention, and redaction.
5. Production Observability and Runbooks
An operator must be able to answer:
- What happened to this run?
- Which revision and event sequence are authoritative?
- Who owns the lease?
- Which command is pending or retrying?
- Why did the execution stop?
Stable trace schemas, health signals, sink examples, and runbooks for stale leases, provider outages, poison commands, and replay divergence are part of the v1 contract—not optional polish.
6. Compatibility and Release Evidence
The stable API must be exercised from the outside, through the same package artifacts users install. The final release gate therefore starts from one clean immutable commit and requires:
clean SHA
→ build, typecheck, and tests
→ real SQLite/PostgreSQL conformance
→ docs and protected snippet checks
→ pack all nine packages
→ hash and provenance verification
→ external-consumer smoke tests
→ npm preflight
→ release-candidate soak
→ publish and post-deploy verification
No package should be rebuilt between verification and publication. The docs, landing page, npm packages, changelog, and support matrix must all report the same version and guarantees.
What v1 Will Not Mean
v1 will not mean that every possible adapter, scheduler, UI, or deployment model has been built.
It will not mean that external effects become magically exactly-once. It will not turn declared compensation into a guaranteed reversal of external reality. It will not make an Elastic License 2.0 project OSI open source; Invariant remains source-available, as explained in Why I Chose ELv2.
It will mean the supported surface is deliberate, compatible, operable, and honest.
Features outside that surface can continue to evolve after v1 without weakening the core contract.
A Public, Evidence-Based Checklist
The complete checklist now lives in the repository as Invariant Beta → v1 Release Checklist.
An item is complete only when it links to reproducible evidence from a clean commit. Documentation or architectural intent alone does not count.
There is no artificial date attached to this transition. The goal is not to reach v1 as quickly as possible. The goal is to make 1.0.0 mean something engineers can rely on.
Beta gives us permission to refine the contract. v1 requires us to keep it.
If you are evaluating Invariant today, start with the Quick Start, read the Durability Guarantees, and treat the Recovery Contract Matrix as the authoritative boundary for the current release.
José Vásquez
Founder & Lead Engineer @ Invariant
Building the durable execution engine for TypeScript AI applications. Keep reasoning probabilistic. Make execution predictable.