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.2 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 pending-command claim or arbitrary-
runIdwork-attachment API; - no packaged background recovery scanner or worker;
- no built-in automatic timer scheduler.
Persisted facts can reconstruct committed truth. An owned Session paused at a registered .wait() can be restored in a new process and accept its next validated input. That does not mean a new process can automatically claim and redispatch interrupted capability work.
The distinction is documented in the canonical Recovery Contract Matrix. Until the missing operations exist, cross-process work recovery 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. An Honest and Extensible Model-Input Boundary
The underlying OpenAI, Claude, and Gemini APIs can accept images and, depending on the provider, audio, video, and documents. The current Invariant model adapters do not expose those native content parts: they serialize the bounded context object into text. Putting an image URL or base64 string in context does not make it a visual input.
v1 does not need to implement every modality in every first-party adapter. It does need to freeze and prove the public ModelAdapter extension boundary, publish an honest capability matrix, and let applications ship a custom adapter—or contribute a compatible PR—without relying on private SDK internals.
When a custom adapter handles media, its application owns MIME and size limits, remote-URL safety, tenant authorization, redaction, provider data controls, and retention. Durable execution should normally store an immutable object reference, content hash, size, and MIME type—not silently copy raw base64 media into every state and event row. A provider-neutral content-parts API and first-party image mappings can evolve after v1 without becoming part of the initial stable promise.
7. 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. Invariant is now offered as proprietary technology; SDK access, deployment, and commercial terms are confirmed during product evaluation rather than inferred from the v1 milestone.
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.
An Evidence-Based Checklist
The release checklist is maintained with the product source and release evidence. Public documentation describes the supported runtime contract without implying that the product repository is publicly accessible.
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.