Invariants

This document lists formal invariants that the engine enforces. These are design goals that tests and runtime logic are built to preserve.


Runtime vs test-only invariants


1. Token invariants

See Execution Model (Token & Concurrency) for the token lifecycle and claim algorithm.


2. Join invariants


3. External task invariants


4. Timer and persistence invariants

See Crash Recovery & Rehydration and Database Schema.


5. Testing invariants

Tests are written to assert these invariants under concurrency and failure:

Adding or changing behavior should preserve these invariants; new tests should be added when extending the engine.


6. Invariant violations in errors

When the runtime rejects an operation because it would violate an invariant, it returns an error that carries an invariant violation kind (InvariantViolationKind). This makes failures identifiable in logs, crash post-mortems, and issue reports, and supports future tooling (e.g. Execution Inspector UI).

REST API: when an external-task complete or fail call fails with an invariant violation, the response includes a X-Invariant-Violation header with the kind name (e.g. ExternalTaskLeaseConflict).