Files
Pranay Prakash 08318f6da0 perf(core): arm one queue-owned backstop per replay pass and gate it on ownership-stamping runs
Review follow-ups on #4100:

- The queue-owned row no longer sends a backstop per running step per
  replay. The dispatch pass folds every queue-owned running step into ONE
  delayed run continuation, due when the latest bare start's lease expires
  and keyed `${runId}:queue-backstop:${latestStartedAt}`. The invocation
  remembers the epochs it armed and skips the send on later passes over an
  unchanged log, so three replay passes over one running step (or one pass
  over N running steps) cost a single publish; concurrent invocations
  collapse onto one pending wake server-side via the shared key. A coarser
  bucket key would either be deduped against an in-flight wake that fires
  before a newer step's lease expires, or need a delay past the queue's
  per-message cap, so the epoch is the key. A wake on a finished run is the
  ordinary already-terminal exit.
- `isQueueOwnedRunning` additionally requires the run's specVersion to be
  at or above SPEC_VERSION_SUPPORTS_SLOT_IDENTITY (6), the first spec
  version every ownership-stamping runtime mints (#2848 shipped under spec
  5). A bare start on an older or unknown run is not proof of a queue
  delivery, since the replay contract tolerates a legacy unstamped inline
  start, so such runs keep the immediate re-enqueue.
- `workflow.queue_ownership.backstop_wakes_armed` is now 0/1 per pass.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 13:51:14 -07:00
..
2026-09-09 12:12:11 -07:00
2026-09-09 12:12:11 -07:00

@workflow/world

Core interfaces and types for Workflow SDK storage backends.

This package defines the World interface that abstracts workflow storage, queuing, authentication, and streaming operations. Implementation packages like @workflow/world-local and @workflow/world-vercel provide concrete implementations.

Used internally by @workflow/core and world implementations. Should not be used directly in application code.

Implementation constraint: no mutable module state

A World implementation must not keep mutable state at module scope. Hold it on the World instance, or, when it is genuinely process-wide (an ID generator whose sequence must not fork, a log-once latch), on globalThis via globalSingleton() from @workflow/utils.

@workflow/world-local and @workflow/world-vercel are bundled into the host application's server build, and a bundler keys module identity on (resource, layer): Next.js alone compiles instrument, app-route, ssr and edge as separate module graphs, so one process holds one copy of every module in these packages per layer. A top-level let, or a const holding a Map, is therefore per-copy state rather than the singleton it reads as.

A world loaded at runtime through WORKFLOW_TARGET_WORLD is deduped by Node's module cache and does not have this problem today, but that is a property of how it is loaded, not of how it is written, and it has changed before (vercel/workflow#3493). scripts/lint/module-scope-state.mjs enforces the rule across every published world package; see docs/content/worlds/*/building-a-world.mdx for the author-facing version.