Runlane
Reference

Contracts Reference

TypeScript contracts shared by Runlane packages and adapter authors.

@runlane/contracts is the package every Runlane runtime, adapter, lane, and test helper builds on. It owns public shapes, stable enum values, validators, defaults, and adapter interfaces.

It does not own runtime behavior. Reducers, workers, schedules, retries, releases, cancellation, and task execution live in @runlane/core.

When To Start Here

You are buildingStart hereThen read
A storage or transport adapterCapability types, adapter interfaces, conflict semantics, outbox publishing, and error vocabularyAdapter Authoring
A lane packageLane, LaneCapabilities, createLane(), lifecycle ordering, and capability reportingLanes, Storage, And Transport
Operator toolingRunFilter, RunEventFilter, pagination, sort fields, pruning filters, and failure codesOperator APIs
Runtime-facing codetask, queue, schedule, delivery, duration, and id/key contracts re-exported by @runlane/coreConcepts
Adapter or lane testsreusable fixtures plus storage, transport, and lane conformance suitesTesting Package

Page Map

PageRead it when
VocabularyYou need stable enum values, IDs, persisted status strings, error codes, sort fields, or worker/delivery result values.
Core ReducerYou need to project append-only run events into the RunRecord that storage persists.
Adapter AuthoringYou are implementing StorageAdapter, TransportAdapter, or a reusable lane package from contract types alone.
Local AdaptersYou need direct in-memory storage or transport primitives for tests and local experiments.
Postgres StorageYou are using or operating the first-party durable Postgres storage adapter.
Postgres SQS LaneYou want the first-party production lane composed from Postgres storage and SQS wakeups.
SQS TransportYou are binding Runlane queues to Amazon SQS and choosing a producer or consumer path.
Testing PackageYou need fixtures, deterministic clocks, observation helpers, or executable adapter conformance suites.

Small Example

Use contract types to describe capabilities honestly:

import type { StorageCapabilities } from '@runlane/contracts'

export const postgresStorageCapabilities = {
  claimsScheduleOccurrences: true,
  durableState: true,
  enforcesIdempotency: true,
  enforcesQueueConcurrency: true,
  enforcesSingleton: true,
  leasesRuns: true,
  persistsOutbox: true,
  processLocalState: false,
  prunesRuns: true,
  readsRunHistory: true,
} satisfies StorageCapabilities

Use contract validators at boundaries:

import { ErrorCode, jsonValueSchema, RunlaneError } from '@runlane/contracts'

const validation = await jsonValueSchema['~standard'].validate({
  reason: 'provider_not_ready',
})

if (validation.issues) {
  throw new RunlaneError({ code: ErrorCode.ValidationFailed })
}

Export Map

AreaWhat it ownsPrimary exports
JSONJSON-safe payload, metadata, and failure detail boundariesJsonValue, JsonObject, isJsonValue, jsonValueSchema
SchemasValidator-agnostic task payload contractsSchema, SchemaInput, SchemaOutput
ErrorsStable framework, adapter, task, and transport failuresErrorCode, RunlaneError, StorageConflictKind
IDsOpaque branded ids and public id/key validationId, IdKind, RunlaneIdInput, asId, createRunlaneIdValueSchema
IdentityDurable environment, actor, and trace context scopingEnvironment, environmentKey, Actor, ActorType, TraceCarrier
DefaultsShared defaults for queues, retry, leases, maintenance, pruning, pagination, and operatorscontractDefaults
QueuesProvider-neutral routing and durable capacity policyQueueDefinition, QueueName, queueDefinitionSchema, isBoundedQueue
TimePublic duration strings and executable millisecond valuesDurationString, DurationUnit, DurationValue, durationSchema, Clock
RunsDurable run projections and visible run stateRunRecord, RunSummary, RunStatus, RunFailure
Run scansShared status groups and due-work predicates for adaptersrunStatusValues, getRunRunnableAvailableAt, getRunDispatchAvailableAt, and related availability helpers
EventsReplayable run historyRunEventType, RunEvent, RunEventRecord
TasksUser work, retry policy, release values, and handler contextTaskDefinition, TaskContext, TaskRelease, RetryPolicy
SchedulesTask-colocated schedules and durable occurrence stateScheduleDefinition, ScheduleOccurrence, ScheduleType
DeliveryOutbox rows and transport wakeupsDeliveryIntent, DeliveryMessage, deliveryMessageSchema, OutboxFailureRecord, OutboxMessage, OutboxMessageStatus
StorageAtomic durable truth, operator reads, leases, outbox mutation, idempotency, singleton, and pruning commandsStorageAdapter, AppendRunEventsCommand, ClaimRunLeaseCommand, PruneRunsCommand
TransportWakeup publishing, indexed publish outcomes, and provider acknowledgement dataTransportAdapter, publishWakeupsCommandSchema, parsePublishWakeupsResult, WakeupPublishOutcomeType
LanesContract-only storage and transport compositionLane, LaneCapabilities, createLane, laneSchema
OperatorsCursor-backed reads and retention commandsPaginationParams, Page, RunFilter, RunEventFilter, PruneRunsFilter
CapabilitiesPublic promises made by storage, transport, and lanesStorageCapabilities, TransportCapabilities, LaneCapabilities

Boundary Map

BoundaryOwnsMust not own
ContractsShapes, defaults, validators, enums, adapter interfacesWorker loops, reducer transitions, task execution
CoreRuntime behavior, reducer semantics, event projection, acquisition pathsDatabase-specific storage, provider-specific transport
Storage adapterAtomic durable truth, conflicts, indexes, leases, idempotency, singleton, outbox rowsRecomputed reducer behavior or wakeup delivery
Transport adapterMinimal wakeup publish and provider-specific delivery plumbingTask payloads, run state, schedule truth
Lane packageAdapter composition, capability reporting, lifecycle orderNew runtime semantics or capability emulation

Non-Negotiables

RuleWhy it matters
Storage persists core-projected events and run state atomically.Reducer behavior stays in core while storage remains the conflict authority.
RunEventRecord results must be the exact records persisted to history.Callers cannot reconcile one event id in storage with another in memory.
Transport messages carry only environment, runId, queue, request time, and trace context.Duplicate or delayed wakeups stay safe because workers re-read storage.
Publish outcomes are indexed: outcomes[index] belongs to command.attempts[index].Maintenance can mark claimed outbox rows published, failed, or dead-lettered without guessing.
Capabilities are promises.Unsupported methods fail fast instead of creating hidden no-ops.
Public IDs and keys are opaque and must not contain :.Adapters can compose internal keys without turning public ids into parse contracts.
Cursors are opaque.Storage owns pagination encoding, filter state, and ordering semantics.

Defaults And Validation

SurfaceContract rule
Task schemasRuntime APIs accept Standard Schema-compatible validators through Schema.
JSON metadataUse jsonValueSchema or isJsonValue; do not persist raw provider responses or cyclic objects.
DurationsUse durationSchema or createDurationSchema(message); valid values include 500ms, 30s, 5m, 1h, and 7d.
Retry defaultcontractDefaults.retry.backoff applies when retry.maxAttempts exists without an explicit backoff.
Lease defaultcontractDefaults.lease.duration applies to worker attempts and direct execution unless overridden.
Maintenance boundscontractDefaults.maintenance bounds each tick() phase.
Pruning batchcontractDefaults.pruning.batchLimit applies when a prune command omits limit.

Errors

Runlane failures use RunlaneError with stable ErrorCode values. Public code should branch on error.code, not parse raw driver messages.

Persisted failure summaries follow the same rule:

FieldContract
RunFailure.codeAlways a Runlane-owned ErrorCode. Unknown handler throws become ErrorCode.TaskFailed.
RunFailure.metaJSON-safe domain or provider detail, such as request ids or provider codes.
OutboxFailureRecord.codeAlways a Runlane-owned ErrorCode, not a provider namespace.
causeServer-side diagnostic detail only; not the public contract.

See Error Codes for the full vocabulary.

On this page