# Glossary

This page is the single canonical home for BackWave's vocabulary. Every term below is defined
once here, and the rest of the documentation links back to it. Definitions are grouped by area.
Where a term has a full concept or reference page of its own, the definition links to it.

BackWave is a background job system: you enqueue work, it runs once on some worker, and it
retries on failure. Job internals are opaque; BackWave never records or replays the steps
inside a job body. It is not a durable execution or workflow engine in that sense.

## Architecture and determinism

BackWave separates the decisions about what should happen from the machinery that makes it
happen. The decision logic is a pure, deterministic layer; everything with I/O, concurrency,
and a real clock sits around it. The determinism boundary is the line between the two, and it
is the same line the test simulator can reproduce exactly.

| Term | Definition |
|---|---|
| Core | The pure decision logic: scheduling, retries, due calculation, lease and timeout handling, and state transitions. Deterministic functions of state, event, and time. The Core performs no I/O and never reads the wall clock. |
| Shell | The per-node imperative loop and its edges: fetch state, call the Core, and execute the resulting Commands through the storage contract. The Shell owns all concurrency, I/O, and the real clock. |
| Command | A value the Core returns describing what the Shell should do, such as mint a job, schedule a retry, expire a lease, or claim from a queue. The Core decides; only the Shell acts. |
| Event | An input to the Core, the counterpart to a Command. |
| Node Driver | The sans-I/O state machine holding all of a node's logic (claiming, heartbeats, lease renewal, hint reactions) as a single `Step(event)` that returns Commands. It never awaits, times, or threads; the Shell's Pump and the Simulator are its two callers. See [The Sans-IO Node Driver](/docs/advanced/node-driver). |
| Determinism boundary | The line between what is simulable and what is not. Everything inside is deterministic and reproducible; everything beyond it is not. Realized in code as the storage contract. See [The Determinism Boundary](/docs/advanced/determinism-boundary). |
| Virtual Time | A controllable clock that tests advance explicitly. The Core never reads the wall clock; time is supplied through a `TimeProvider` whose default is `TimeProvider.System`, and a test harness supplies a virtual clock instead. |

## Storage contract and adapters

Every place BackWave persists state goes through one seam with a precise behavioral
specification. Production implementations target real databases; a first-class in-memory
implementation ships for tests and local development.

| Term | Definition |
|---|---|
| Storage contract | The semantic specification every storage implementation must guarantee, including behavior under concurrent lease acquisition and crash mid-write. Realized as the `IJobStore` interface. Implementations must not read their own clock; time is always passed as an explicit `now` parameter. See [The Storage Contract](/docs/reference/storage-contract). |
| Storage adapter | A production implementation of the storage contract against a real database. Version 1 ships adapters for Postgres, SQL Server, and SQLite. Verified by the conformance suite. |
| Networked adapter | A storage adapter over a database server reachable across hosts: Postgres and SQL Server. |
| Embedded adapter | A storage adapter whose database is in-process or single-host. Version 1's embedded adapter is SQLite. Durable and conformance-verified, but bounded to one host. See [SQLite](/docs/storage/sqlite). |
| Co-resident deployment | An embedded-adapter deployment where BackWave tables live in the application's own database file, giving the tightest transactional enqueue. |
| Dedicated deployment | An embedded-adapter deployment where BackWave uses its own database file, which forgoes transactional enqueue. |
| In-memory store | A first-class, publicly shipped `IJobStore` implementation that is deterministic and runs on Virtual Time. It persists nothing and is single-process, so it cannot carry the execution guarantee; its home is tests and local development. |
| Transactional enqueue | Enqueueing a job inside the application's own database transaction so the business write and the job commit or roll back atomically. A storage-contract capability, not universal; surfaced as `IJobStore.SupportsTransactionalEnqueue`. See [Transactional Enqueue with EF Core](/docs/guides/transactional-enqueue-with-ef-core). |
| Schema name | The database schema (Postgres, SQL Server) or table-name prefix (SQLite) holding all of an adapter's objects. Default `"backwave"`, configurable per store and fixed for the life of the data. |
| In-place upgrade | A schema upgrade applied to a live database with no drain or maintenance window. Supported for every adapter. See [Schema Migrations](/docs/storage/schema-migrations). |
| Mixed-version fleet | Running more than one BackWave version against the same database at once. Supported at N-1 version skew only. |

## Jobs, handlers, and identity

A job is a unit of work with a stable wire identity and a handler that runs it. Identity in
storage is always explicit and never derived from a class name, so renaming code never changes
what is on the wire.

| Term | Definition |
|---|---|
| Scheduled job | A job with a due time, the only shape of work the Core knows. An "enqueued" job is simply one whose due time is now, on the same code path. |
| Wire Name | A job type's mandatory, explicitly declared identity in storage. Never derived from CLR type names, so renaming a class never changes it. Declared with `[Job("wire-name")]`. See [Job Attributes](/docs/reference/job-attributes). |
| `[Job]` attribute | The attribute that declares a job type's Wire Name and defaults. Applies to a payload record (class form) or a handler method (method form). See [Jobs and Handlers](/docs/core-concepts/jobs-and-handlers). |
| Handler | An implementation of `IJobHandler<TJob>` with a single `HandleAsync` method. Returning normally means success; throwing means failure and schedules a retry until the attempt ceiling. Every handler may run more than once, so idempotency is the author's responsibility. |
| Attempt | One execution try of a job, numbered and visible to the handler through `JobContext.Attempt`. The first attempt is 1. A lease expiry counts as an attempt, the same as a thrown exception. |
| JobContext | The execution context for one attempt. Carries `JobId` and `Attempt`, buffers tag additions and job output, and can pull a dependency ancestor's output. See [Jobs and Handlers](/docs/core-concepts/jobs-and-handlers). |
| Job Manifest | A committed snapshot of every registered Wire Name, verified by a shipped test helper so wire-format changes appear in pull-request diffs. See [Guard Wire Compatibility](/docs/guides/guard-wire-compatibility). |

The `[Job]` attribute carries these properties.

| Property | Type | Default | Meaning |
|---|---|---|---|
| `WireName` | `string` | required | The job type's storage identity, unique across all jobs. |
| `Queue` | `string` | `"default"` | The Queue jobs of this type go to unless overridden at enqueue. |
| `Labels` | `string[]` | `[]` | Default tag Labels applied to every job of this type. Additive only. |

```csharp title="OrderCharged.cs"
[Job("order-charged", Queue = "billing")]
public sealed record OrderCharged(Guid OrderId);
```

## Job states

A job moves through a small fixed set of states. Four are terminal; the rest are live. The
enum values, their canonical dashboard spellings, and their meanings are below. The full
lifecycle and the legal transitions live on [Job Lifecycle](/docs/core-concepts/job-lifecycle)
and [Job States](/docs/reference/job-states).

| State | Dashboard spelling | Terminal | Meaning |
|---|---|---|---|
| `Scheduled` | Scheduled | No | Enqueued and waiting for its due time; eligible to be claimed once due. |
| `AwaitingParent` | Awaiting Parent | No | Held back until its parents reach a terminal state; becomes Scheduled once the last parent resolves. |
| `Leased` | Leased | No | Claimed by a worker and running under a lease that must be renewed by heartbeat. |
| `Succeeded` | Succeeded | Yes | Completed successfully. |
| `Cancelled` | Cancelled | Yes | Cancelled by an operator, or because an on-success parent failed. |
| `DeadLettered` | Dead-Lettered | Yes | Exhausted its retry budget and set aside for inspection. |
| `Quarantined` | Quarantined | Yes | Could not be routed to a handler and was set aside. |

`JobStates.IsTerminal` returns true for Succeeded, Cancelled, DeadLettered, and Quarantined,
and false otherwise.

| Term | Definition |
|---|---|
| Terminal state | A state a job never leaves under any automatic path: Succeeded, Cancelled, Dead-Lettered, or Quarantined. |
| Dead-Lettered | Terminal state of a job that ran and kept failing until it exhausted its attempt ceiling. |
| Quarantined | Terminal state of a job that could not be routed or decoded: its Wire Name has no registered handler, or its payload no longer deserializes. Loud and visible, never a silent retry loop. |
| Terminal Cause | A short human-readable reason for the terminal state (the failure error, cancel actor, or unroutable reason), or null while the job is live. Distinct from Failure Detail, which is the diagnostics of one failed attempt. |

## Enqueueing

The client is the single entry point for putting work into BackWave. Every enqueue produces a
scheduled job with a due time; enqueueing "for now" just sets the due time to now.

| Term | Definition |
|---|---|
| `EnqueueAsync` | Enqueues a job with a due time and an optional queue, tags, and transaction. Returns the new job's `Guid`. |
| `EnqueueDependencyAsync` | Enqueues a job that waits until a parent job, identified by its `Guid`, reaches a terminal state before becoming due. See [Dependencies](/docs/core-concepts/dependencies). |
| `UpsertRecurringAsync` | Defines or redefines a recurring schedule from a cron expression and a template. Only future ticks are minted; defining does not back-fill. |
| `RemoveRecurringAsync` | Removes a recurring schedule. Already-minted instances run to completion; removing an unknown schedule is a no-op. |
| Enqueue result | The outcome of an enqueue attempt: `Ok`, `Duplicate`, `PayloadTooLarge`, `WireNameTooLong`, `UnknownParent`, or `TooManyParents`. |

Type-default tags declared on the `[Job]` attribute are additive only; they are always unioned
into the caller's tags, never subtracted. The full signatures and error behavior live on the
[Client API](/docs/reference/client-api) reference.

## Scheduling

A recurring schedule is a cron-defined template that mints scheduled jobs as time passes. The
schedule and the jobs it mints are distinct things with distinct lifecycles.

| Term | Definition |
|---|---|
| Recurring Schedule | A cron-defined template that mints scheduled-job instances over time, in UTC by default or in an opt-in IANA time zone. See [Scheduling](/docs/core-concepts/scheduling). |
| Cron | A standard cron expression, either 5-field (minute, hour, day-of-month, month, day-of-week) or 6-field with a leading seconds field. No Quartz extensions; any other field count is rejected. Schedules store the canonical 6-field, seconds-first form. See [Cron API](/docs/reference/cron-api). |
| Catch-Up Policy | What a schedule does about ticks missed while nothing was minting them: `Skip` (the default; mint nothing) or `Coalesce` (mint exactly one make-up run for the whole missed set). Replaying every missed occurrence is deliberately unsupported. |
| No-Overlap | A schedule setting that suppresses minting a new instance while a previous one is still non-terminal; the skipped tick is recorded visibly. Behaviorally equivalent to a per-schedule concurrency limit of 1, enforced at mint time. |
| Time zone | The IANA time zone a schedule's cron is interpreted in, for example `America/New_York`. Null means UTC. An unresolvable zone is rejected. |

The cron field ranges are seconds 0-59, minutes 0-59, hours 0-23, day-of-month 1-31, month
1-12, and day-of-week 0-7. When both day fields are restricted they combine with OR; otherwise
they combine with AND. The `Cron` fluent builder (`EveryMinute`, `Hourly`, `Daily`, `Weekly`,
`Monthly`, and others) produces these expressions; see [Cron API](/docs/reference/cron-api).

## Queues, workers, and dispatch

A queue is a named stream of jobs claimed in due-time order. Consumers are organized into
worker groups, each of which declares the queues it serves and how it shares effort across
them. Priority lives on the consumer side, never on the job.

| Term | Definition |
|---|---|
| Queue | A named stream of jobs, claimed in due-time order. A job belongs to exactly one Queue, declared on its type and overridable at enqueue. See [Queues](/docs/core-concepts/queues). |
| Paused Queue | A Queue that yields nothing on claim until it is resumed. Paused and resumed by an operator action. |
| Worker | One execution slot in a worker group's pool. Pool size is the group's `PoolSize`. Execution concurrency, distinct from a Pump's fetch-loop parallelism. |
| Pump | The Shell-side event loop running one worker group's claim, dispatch, and report cycle, feeding events to a single driver. A group's store I/O is serial within one Pump. A group runs one or more Pumps. See [The Job Pump](/docs/advanced/job-pump). |
| Worker Group | One registered set of workers in a process, declaring which queues it serves and its dispatch policy. See [Worker Groups and Dispatch](/docs/core-concepts/worker-groups). |
| Dispatch Policy | How a worker group shares claim effort across the queues it serves: `Strict` (fixed priority order) or `Weighted` (smooth weighted round-robin). Both are work-conserving. See [Dispatch Policies](/docs/reference/dispatch-policies). |
| Concurrency Limit | A per-Queue, cluster-wide cap on simultaneously executing jobs, enforced at claim time. One shared counter across the cluster per Queue. A slot is released on terminal state or lease expiry, never leaked by a crash. |
| Backpressure | Node-local flow control: a node stops claiming when its worker pool has no free worker, so claims never exceed free capacity. Independent of the cluster-wide Concurrency Limit. |
| Wake-Up Hint | An optional storage notification ("something was enqueued, poll now") that exists only to cut claim latency. Never correctness-bearing: the system behaves identically, minus latency, if every hint is dropped, duplicated, or delayed. Polling is the sole source of truth. See [Wake-Up Hints](/docs/storage/wakeup-hints). |

A worker group is configured with these options and defaults.

| Property | Type | Default | Meaning |
|---|---|---|---|
| `Name` | `string` | required | Unique within one registration; appears in health, metrics, and logs. |
| `Policy` | `DispatchPolicy` | required | Which queues the group serves and how effort is shared. |
| `PoolSize` | `int` | 20 | Max concurrent jobs per node; polling pauses while full. |
| `Pumps` | `int` | 1 | Independent pump loops in one process. Must be at least 1. |
| `MaxClaimBatch` | `int` | 32 | Max jobs claimed per poll. |
| `MaxOutcomeBatch` | `int?` | `MaxClaimBatch` | Max completed outcomes buffered before one batched write. |
| `PollInterval` | `TimeSpan` | 1 second | How often the group polls for new work. |
| `MaintenanceInterval` | `TimeSpan` | 5 seconds | Cadence of lease expiry, schedule minting, and retention purge. |
| `LeaseDuration` | `TimeSpan` | 60 seconds | How long a claimed job's lease is held before it lapses. |
| `HeartbeatInterval` | `TimeSpan?` | one third of `LeaseDuration` | Lease renewal cadence. |
| `RetryPolicy` | `RetryPolicy` | `RetryPolicy.Default` | Backoff and attempt ceiling. |
| `Retention` | `RetentionPolicy?` | `RetentionPolicy.Default` | Terminal-job keep-then-purge; null disables retention sweeping. |

## Leases and delivery guarantees

A worker holds a job under a time-bounded lease it renews by heartbeat. If the lease lapses,
the job becomes claimable again. This is the mechanism behind at-least-once delivery, and it is
why handlers must be idempotent.

| Term | Definition |
|---|---|
| Lease | A worker's time-bounded, heartbeat-renewed claim on a job. Expiry makes the job claimable again. A lease expires on its own; it is not a lock. See [Leases and Crash Recovery](/docs/advanced/leases-and-crash-recovery). |
| At-Least-Once Execution | BackWave's delivery contract: a handler body may run more than once, and idempotency is the author's responsibility. Exactly-once body execution is not offered. See [The Execution Guarantee](/docs/core-concepts/execution-guarantee). |
| Effect-Once | The property that despite at-least-once execution, the recorded outcome of an attempt and every state transition flowing from it (the terminal state, the dependency latch decrement, the concurrency-limit slot release) apply exactly once, caused by the node holding the live lease for that exact attempt. See [The Effect-Once Fence](/docs/advanced/effect-once-fence). |
| Stale-lease belief | The condition of an isolated node that keeps executing while believing it still holds a lease it has actually lost. Its late outcome is fenced out and changes nothing. |

## Retries and retention

A job that fails is retried on a backoff until it reaches its attempt ceiling, at which point
it is dead-lettered. Terminal jobs are kept for a policy-defined window and then purged.

| Term | Definition |
|---|---|
| Retry | An attempt after the first. Governed by a `RetryPolicy` with a backoff function and an attempt ceiling. See [Configure Retries and Error Handling](/docs/guides/configure-retries-and-error-handling). |
| Retry policy | `MaxAttempts` (default 10) plus a `Backoff` function. The default backoff is 2 raised to the attempt number in seconds, capped at 5 minutes (300 seconds). When a failed attempt reaches `MaxAttempts`, there is no next attempt and the job is dead-lettered. |
| Retention policy | Keep-then-purge for terminal jobs, timed from the instant a job reached a terminal state. Succeeded and Cancelled are kept 24 hours; Dead-Lettered and Quarantined are kept 14 days. See [Retention and Purge](/docs/dashboard-operations/retention-and-purge). |

## Limits and bounds

Storage enforces a set of named limits. Most are enforced by rejecting or clamping the write;
two payload-shaped limits differ deliberately. The full table with rationale lives on
[Limits and Defaults](/docs/reference/limits-and-defaults).

| Limit | Default | Behavior on exceed |
|---|---|---|
| `MaxPayloadBytes` | 65,536 | Reject enqueue |
| `MaxWireNameLength` | 128 characters | Reject enqueue |
| `MaxClaimBatch` | 32 | Clamp down |
| `MaxParentsPerJob` | 16 | Reject enqueue |
| `MaxMonitorPageSize` | 200 | Clamp down |
| `MaxPurgeBatch` | 500 | Clamp down |
| `MaxRecordedSkippedTicks` | 32 | Age out oldest |
| `MaxTransitionsPerJob` | 64 | Drop oldest transition |
| `MaxFailureDetailBytes` | 8,192 | Truncate (never rejects) |
| `MaxOutputBytes` | 65,536 | Reject (never truncates) |

Failure Detail is write-only diagnostics, so an over-limit value is truncated. Job Output is
functional data a descendant will deserialize, so an over-limit value is rejected rather than
silently corrupted.

## Tags

A tag is an observational annotation for search, filter, and grouping in the Monitor and
Dashboard. Tags are purely descriptive: the Core never reads a tag, so tags never cross the
determinism boundary. A tag is one of two structurally distinguished kinds.

| Term | Definition |
|---|---|
| Tag | An observational annotation on a job for search, filter, and grouping. Never read by the Core. See [Tags](/docs/core-concepts/tags). |
| Label | A bare-string tag, for example `urgent`. A colon inside a Label is ordinary data, never a separator. |
| Keyed Tag | A key-and-value tag, for example `tenant` to `acme`. One key may carry several values. |
| JobTags | A set of tags: re-adding an identical tag is a no-op, iteration is in first-seen order, and equality is order-independent. Set semantics keep tag authorship idempotent under at-least-once execution. |

Tag values are strings only; a date is a caller-canonicalized string, with no numeric or date
range semantics. In the Dashboard a Label renders as its bare value and a Keyed Tag renders as
`key:value` for display only; the colon is never parsed.

## Dependencies and workflows

A dependency is a static edge from a job to a set of parent jobs whose terminal states gate the
child's due-ness. Workflows are a Pro-tier grouping and identity layered over jobs connected by
dependency edges.

| Term | Definition |
|---|---|
| Dependency | A static edge from a job to a parent set whose terminal states gate the job's due-ness, a countdown latch. The orchestration mechanism, below the determinism boundary. Edges are static, declared at the dependent's enqueue time. See [Dependencies](/docs/core-concepts/dependencies). |
| Dependency mode | How a dependent reacts to its parents: `OnSuccess` (the default; release only if every parent Succeeded, and cancel the dependent on any other terminal outcome) or `OnAnyTerminal` (release once every parent is terminal, whatever the states). |
| Awaiting Parent | The state of a job whose dependency parent set is not yet fully terminal. |
| Job Output | The opaque blob a handler optionally emits on success, the success-side twin of Failure Detail. Written to the job row atomically with the Succeeded transition under the same Effect-Once fence, independent of the job history policy, and read lazily by a descendant. Bounded by `MaxOutputBytes`; over-limit is rejected, not truncated. See [Read Another Job's Output](/docs/guides/read-another-jobs-output). |
| Dependency output | The result a descendant gets when it pulls an ancestor's Job Output: the ancestor's state, whether output is present, and the value. Only transitive ancestors are readable, never a non-ancestor sibling. Absence is a normal result, not an error. |
| Workflow | The user-facing grouping and identity over jobs connected by dependency edges: a name, a sortable ID, a graph view, and lifecycle operations. Lives entirely above the determinism boundary; its status is always a projection of member-job states, never stored. A job belongs to at most one Workflow. A Pro feature. See [Workflows](/docs/core-concepts/workflows). |
| Workflow status | A projection over member-job states with first-match-wins precedence Running, Failed, Cancelled, Succeeded: Running if any member is non-terminal, else Failed if any member is Dead-Lettered or Quarantined, else Cancelled if any is Cancelled, else Succeeded. Failure dominates. |
| Workflow Restart | Recovery by re-instantiating a Workflow's definition as a brand-new Workflow with fresh job identities, optionally linked by lineage. Always re-runs the whole graph from the start, a redo rather than a resume. Ships in BackWave Pro. |

## History, observers, and monitoring

BackWave keeps a per-job history of state changes and exposes two ways to consume the
lifecycle: a pull-side Monitor and a push-side Observer. What history is recorded is governed
by a policy.

| Term | Definition |
|---|---|
| Transition Log | An append-only, per-job history of state changes the Monitor surfaces as a timeline. Each entry is a timestamp, resulting state, attempt number, and optional Failure Detail. Bounded by `MaxTransitionsPerJob` (64) and deleted with the job under retention. |
| Job History Policy | A ladder governing what the Transition Log records: `Off` (nothing), `Transitions` (transition rows, no failure detail), or `TransitionsAndFailureDetail` (the full log, and the default). The policy gates writes, never schema. |
| Failure Detail | The opaque diagnostic text (exception type, message, stack) captured at the edge when an attempt throws, attached to the failing transition entry. Never read by the Core. Bounded by `MaxFailureDetailBytes` (8,192) and truncated, never rejected. Viewing is gated behind the sensitive-data permission. |
| Transition Observer | Host-supplied, egress-only code BackWave invokes when a job reaches a declared state, the sanctioned way to react to the lifecycle. Observes transitions, never events, and can never alter a Core decision. Delivered at-least-once and not Effect-Once, so idempotency is the subscriber's responsibility. Requires a history policy of at least `Transitions`. See [Observers API](/docs/reference/observers-api). |
| Observer subscription | The filter that selects which transitions an observer receives: a set of states, and optional Wire Name and Queue filters. |
| Monitor | The pull-side read surface, the Observer's twin. Reads jobs, job history, payloads, output, queue depths, tag facets, schedules, and observer cursors and lag. See [Monitor API](/docs/dashboard-operations/monitor-api). |

## Operations and the dashboard

Operators act on jobs and queues through a fixed set of state-machine transitions, each with
recorded identity, never a raw row edit. The Dashboard authorizes these actions by asking the
host application.

| Term | Definition |
|---|---|
| Operator Action | A Dashboard- or API-initiated Core state transition with recorded identity: cancel a job, requeue a Dead-Lettered or Quarantined job to Scheduled, pause or resume a queue, set a concurrency limit, or trigger a schedule now. Editing a job's payload is deliberately not one. See [The Dashboard](/docs/dashboard-operations/overview). |
| Dashboard Permission | A capability the Dashboard checks before allowing an action: View, ViewSensitiveData, Requeue, Cancel, TriggerSchedule, and PauseQueue. Each is a delegated callback the host answers; BackWave never owns users or roles. View defaults to allow; every other permission defaults to deny. |
| Sensitive data exposure | A host-level master switch plus an environment kill-switch that together decide whether raw payload bytes, Failure Detail, and Job Output can be viewed in the Dashboard. See [Handle Sensitive Data](/docs/guides/handle-sensitive-data). |
| Dashboard Extension | A surface a separately installed Pro Dashboard package contributes to the free Dashboard: nav entries, a banner, page routes, and action routes. Each action route is gated by an existing permission. The Workflow surface is the first such extension. |

## Testing and simulation

BackWave's correctness is verified by deterministic simulation and by suites that hammer real
databases. These are internal testing infrastructure rather than public library API, but they
are part of the project's vocabulary and explain how its guarantees are established. The
[Testing](/docs/testing/how-backwave-is-tested) section covers what this means for your own
tests.

| Term | Definition |
|---|---|
| Simulator | A test harness driving many virtual node drivers and the in-memory store through compressed Virtual Time with seeded fault injection. One 64-bit seed fully determines a run. |
| Seed | The compact 64-bit discovery unit that fully determines a simulator run. |
| Plan | A serializable, replayable description of one simulator run: a scenario plus a fault map addressing every injected fault by stable identity. What is minimized, replayed, and checked in as a regression. |
| Swarm | Per-run randomization of the fault parameters themselves, a pure function of the seed. Not fuzzing: it randomizes fault configuration, not workload payload. |
| Fault Level | A contract chosen before a run, pairing the fault envelope the swarm may draw from with the oracles enforced: Pristine (no faults; full safety and strict liveness), Recoverable (self-healing faults; full safety and liveness once faults cease), or Adversarial (faults that may never heal; safety only). |
| Node Isolation | A simulator fault cutting one node off from the storage contract for a bounded window; the node keeps executing under a stale-lease belief. Distinct from a crash, and never split-brain, because peers are database-authoritative. |
| Conformance Suite | A test suite verifying that a storage adapter honors the storage contract against the real database. See [The Conformance Suite](/docs/advanced/conformance-suite). |
| Torture Suite | A non-deterministic correctness instrument for adapters: a randomized concurrent workload hammers a real database, then invariants are audited over the final state and logs. A torture failure is always a bug. |
| Benchmark Harness | A macro end-to-end throughput tool driving the real Shell against a real adapter under wall-clock time. Deliberately outside the determinism boundary; it measures performance, never correctness. See [Performance and Benchmarks](/docs/advanced/performance-and-benchmarks). |

## BackWave Pro and licensing

BackWave Pro is a commercial add-on feature set shipped as separate, publicly available
packages layered on the free base. The free base is complete and production-grade, and free for
everyone forever.

| Term | Definition |
|---|---|
| BackWave Pro | The commercial add-on feature set. Free to use for organizations under $1M annual revenue on the honor system; a paid, revenue-banded license is required above that. Features are identical regardless of tier; a license grants the permission to use Pro at commercial scale. |
| Soft enforcement | How a license is checked: an unlicensed production process runs normally but emits a startup log warning and a Dashboard banner. There is no hard failure, and the software cannot detect revenue. |
| License state | The result of checking a license string: `Valid` (present, verified, in term; no warning), `Missing` (no license, the expected free-use state), `Malformed` (present but not well-formed or failed verification), or `OutOfTerm` (genuine but the subscription term ended). Pro never changes behavior based on this value. |
| Revenue band | The self-reported revenue tier in a license. It sets price only, never which features run. |

## Where to go next

- [Job States](/docs/reference/job-states): the state enum and its terminal helper in full.
- [Limits and Defaults](/docs/reference/limits-and-defaults): every named limit and default in
  one place.
- [Job Lifecycle](/docs/core-concepts/job-lifecycle): how a job moves between the states above.
- [The Storage Contract](/docs/reference/storage-contract): the seam every definition here
  ultimately rests on.
- [Client API](/docs/reference/client-api): the exact enqueue and scheduling signatures.
