Releases: AndresSaa/mcp-durable-tasks
Releases · AndresSaa/mcp-durable-tasks
Release list
v0.2.1
A documentation-only maintenance release. It republishes the corrected README
to npm, whose package pages retain the README bundled with each immutable
version. There are no engine, API or dependency changes.
Fixed
- The README now identifies
v0.2.1as the current release, points source
validation at the current tag, scopes process-crash recovery to confirmed
state held byWalTaskStore, and documents both verified SDK era-gate
workarounds instead of reverting to the obsolete claim that only transport
rewriting works.
Changed
- The optional
0.3.0client driver is now explicitly gated on upstream
clarity around A6/A10 or demonstrated user need, so an SDK workaround does
not become public API merely because0.2.0has shipped.
v0.2.0
The first release published over OIDC with a provenance attestation. No engine
code changed since 0.1.0: what changed is the runnable evidence that the
central claim holds, and a correction to what the shipped documentation says
about the official SDK.
Added
examples/crash-recovery/: a real MCP server whose deferred task outlives
its process. One command starts it, defers work throughtools/call, kills
the server withSIGKILL, starts it again and reads the finished result back
from the new process. It asserts the recovered status and result rather than
narrating them, and it runs on every pull request, so it cannot quietly stop
being true. The README links a recording of it.examples/conformance-reproductions/: frozen reproductions of the three
upstream behaviours reported from this repository, pinned to
@modelcontextprotocol/*2.0.0. Each one asserts its own finding, so it
fails when upstream fixes it — reported as
ext-tasks#14,
typescript-sdk#2637
and a reproduction on
typescript-sdk#2598.
Fixed
- The README banner now resolves on the npm package page.
0.1.0shipped a
repository-relative path that only rendered on GitHub, and npm freezes a
published README, so the fix could not reach that version.
Changed
- The SDK compatibility profile in
docs/contract.mdanddocs/internals.md
now records two verified workarounds fortasks/getandtasks/cancel
instead of one. Answering those requests above the SDK, in HTTP middleware,
sidesteps the protocol-era gate rather than working around it, and is the
better starting point for a host; thetransport.onmessagerename still
works. An earlier revision called the rename "the only verified escape",
which was assumed rather than measured.
v0.1.0
First public release. The GitHub tag and Release are followed by the one-time
manual npm publication used to establish the package; automated trusted
publishing with provenance starts with the next version.
Added
- Stable
isTaskEntryTooLargeError()andisConcurrentUpdateError()guards
for recognising errors across duplicated packages and separate CJS bundles. - The lifecycle engine, in-memory store, typed input round-trip, TTL handling,
CAS retries and schema-safe wire projection. WalTaskStoreon themcp-durable-tasks/walentry point: durable across
process restarts, with an in-memory read index and a write-ahead log that
replays on open.process-walstays an optional peer, so the main entry
point still costs no dependencies.- The vendored
ext-tasksschema, pinned by blob SHA, plus
pnpm check:schemato detect and refresh upstream drift. - An English repository contract for scope, invariants, conformance decisions
and version boundaries, plusdocs/api.md,docs/durability.mdand
docs/internals.md; all four are shipped in the package for offline use. - Crash tests over real child processes and real
SIGKILL, covering task
creation, a parked input round, an instant-terminal completion, a kill during
appends, a compaction loop, and a TTL that elapsed while nothing was running.
The append child reports an acknowledged version as a recovery lower bound;
the compaction child reports a complete multi-task snapshot. They run against
the built package rather than the sources. - The store conformance kit on
mcp-durable-tasks/testing:
runTaskStoreConformance()declares the suite in your own runner, and
checkTaskStore()returns a report without needing one. It carries no
dependencies and passes against both included stores. - Regression coverage for prototype-named input keys, losing CAS candidates,
waiter registration, terminal/TTL settlement and public API boundaries. - A fast-check state-machine suite that generates progress, TTL and clock
schedules, input rounds, cancellation, terminal races and foreign CAS
conflicts, checking record/wire parity and exactly-once waiter effects after
every operation.
Fixed
- Protocol results now carry their required discriminator: task creation uses
resultType: "task", while get, update and cancel use
resultType: "complete". - Valid JSON containing
-0is canonicalised to0before either store
mutates, keeping live state, worker responses and WAL replay identical. - Task results, errors, input payloads, and direct store records now reject
non-JSON trees before mutation, keeping memory and WAL replay identical. - Automatic WAL compaction failures no longer make an already-durable mutation
appear rejected. They are observable throughonCompactionError, and a WAL
poisoned during snapshot writing fails the next store operation explicitly. - Input waiters now register before
input_requiredbecomes observable and
settle only from committed writes. - Terminal results and store snapshots no longer share mutable references with
callers. - Invalid TTLs and malformed MCP input requests/responses are rejected before
they can create an unreadable or unfulfillable task. Validation now follows
nested sampling content blocks, primitive elicitation schemas and response
values rather than accepting any JSON object at those boundaries. - MCP input validation now follows the SDK 1.30.0 source for URL elicitation
ids and URLs, integer token limits, Base64 content, tool schemas and task
support metadata, andfile://roots. - Corrupt status-specific records fail loudly instead of fabricating empty
result, error or input payloads. - The public conformance kit no longer produces false greens for durability,
missing runner capabilities or hanging stores. Optionalreopen()exercises
cross-instance persistence through a complete partial-input round, skips are
delegated to the runner, operations have finite deadlines, and cleanup
failures remain visible. WalTaskStorenow uses an explicit 8 MiB task-record default instead of
inheriting process-wal's 1 MiB event default. Oversized writes surface as
TaskEntryTooLargeErrorwith codeERR_ENTRY_TOO_LARGEbefore mutation, so
workers can retry completion with a bounded result.
Changed
- Development, CI, packaging and the lockfile now use pnpm 11.21.0. Dependency
install scripts are denied by default; onlyesbuildis explicitly allowed. defaultPollIntervalMs: nullnow omits the optional wire hint;undefined
continues to select the 1,000 ms default.- Public documentation links now target the packed English contract instead
of private planning drafts. - CAS conflicts are recognized by error name in both the lifecycle and
conformance kit, so duplicated package installations do not break retries. TaskPatchnow explicitly applies enumerable own string-keyed properties;
the conformance kit pins that boundary alongsideundefineddeletion.- Conformance factories are now required to return a fresh store instance per
check; duplicate creates, pure reads, input bookkeeping and exact sweep
deletion are checked against the complete persisted state. - Worker coordination is explicitly process-local; multi-instance hosts need
request affinity or external coordination for live workers. TaskPatchnow documentsundefinedas deletion for every store.- Durable mutation execution now lives in an internal
TaskMutator: terminal
guards, monotonic timestamps and bounded CAS retries have one owner, while
TaskLifecycleremains responsible for protocol decisions and committed
worker effects.