sponson, @sponson/core, @sponson/adapters, @sponson/sim) always share one version.
From the next release on, entries are written by changesets: each package’s
CHANGELOG.md is generated in the “Version Packages” PR, and the release highlights are copied here.
Unreleased
Added
- Contributor tooling:
pnpm new:adapter <name>scaffolds an adapter, its unit test, its sim routes and a scenario, and registers them; issue forms, PR template, CODEOWNERS, Dependabot, changesets-based release workflow; CI coverage thresholds, a package/pack smoke job and macOS. - Documentation as code:
ARCHITECTURE.md, ADRs indocs/adr/, the plan format spec and a JSON Schema (schema/release.plan.schema.json) kept in parity with the parser by tests,docs/errors.mdgenerated fromERROR_CODES, and runnableexamples/. ReceiptStore.close(); the CLI closes the git store after every command, so a long-runningsponson mcpno longer accumulates temporary clones.
Changed
- Breaking for
@sponson/coreusers: context detection (detectCtx, GitHub Actions and local git/gh) moved to thesponsonpackage behind aCtxSourceseam; core keeps the purescopeForandinterpolate. - The engine reads approval only from
approvedBy; the CLI resolves--approved-by/SPONSON_APPROVED_BY.
Fixed
- A lease holder whose renewals stall now stops itself before its lease could be taken over, instead of continuing to write to providers while another run legitimately holds the scope.
0.2.0 — 2026-10-10
A rebuild of the engine around a ledger, after system testing along six dimensions (team lifecycle in CI, concurrency, misbehaving providers, an agent operator, humans and plan refactors, secrets) found ~100 defects that were regrouped into six structural gaps and fixed once each.Breaking
- Receipts are version 2. Each receipt now carries a ledger of every resource the scope owns, the commit
history of the scope and a per-scope hash key. Version 1 receipts are migrated automatically: they are
read as v2 in memory and written back as v2 by the next run. Nothing to do — but a 0.1 CLI cannot read a
receipt written by 0.2 (it fails with
RECEIPT_VERSION), so upgrade every pipeline that shares a receipts store at once. - Production approval applies per line, not per run. Approval (
--approved-by, or the newSPONSON_APPROVED_BY) is required whenever any line writes toproduction— for example a Vercelenvline withtarget: production— whatever--envthe run uses. Plans that did this from a preview run without approval are now refused withENV_NOT_APPROVED. sponson initadopts values as{ keep: true }. Adopted Vercel environment variables are written into the plan as{ keep: true }instead of anything resembling their value: Sponson manages that they exist and never destroys them. Adopting a value that does not exist isPARAM_INVALID.- New line status
blocked.planpredicts refusals: a line that would be refused (drift without--reconcile, a resource owned by another scope, missing approval) or that depends on one (DEPENDENCY_BLOCKED) is reported asblockedinstead of as a normal create/update. Consumers that switch on line status must handle it. - JSON output contract. Every
--jsonpath — includinginit, usage errors and MCP tools — returns one JSON document with an errorcodewhen it fails. Diffs are structured data (before/aftersides with astateofliteral,sensitive,pending,secretorabsent) instead of display strings. - Error codes. Codes live in one table (
ERROR_CODESin@sponson/core) with their exit codes and CLI hints.APPLY_FAILEDis gone: failures carry a specific code (PROVIDER_*,ROLLBACK_FAILED,DESTROY_FAILED,EXTERNAL_FAILED,INTERRUPTED, …) orINTERNAL. New codes:LOCK_LOST,STORE_CONTENDED,STORE_REJECTED,OWNED_BY_OTHER_SCOPE,REF_OUTPUT_UNKNOWN,USAGE,PARAM_INVALID,DEPENDENCY_BLOCKED,INTENT_UNRESOLVED,STALE, and the provider classesPROVIDER_TRANSIENT,PROVIDER_CONFLICT,PROVIDER_NOT_FOUND,PROVIDER_AUTH,PROVIDER_INVALID,PROVIDER_TIMEOUT,PROVIDER_RESPONSE. - The
sponsonpackage’s programmatic API is reduced torun()(and theRunIOandSponsonPlugintypes). The renderers, command implementations and context helpers it used to export are internal. - Adapter contract (
@sponson/coretypes, for adapter authors): adoption moved into the adapter asOpSpec.adopt()— the CLI no longer parses provider keys; ops that target a deployment environment implementwritesEnvironment();AdapterContextgainedintend(keys)(call it before every create) andredact(text);diffreturns structuredDiffSides. The stable authoring helpers are exported from@sponson/adapters(clientFor,requireEnv,requireProvider,diffValue,desiredSide,assertNoPending,deleteIgnoringNotFound,paramError,stringParam).
Added
- Ledger and intents. Resources are keyed by adapter + provider block + key and kept across failed,
refused and crashed runs. Creates are recorded as intents before they are sent, so a lost response or a crash
never orphans a resource.
apply --destroyworks from the ledger: after a successful destroy nothing Sponson created survives (new invariant 8). - Commit history per scope. A late deployment event or re-run job for an older commit changes nothing: the
receipt is marked
staleand its lines areskippedwithSTALE— also for a never-applied commit that git ancestry shows is older than the last applied one. - Scope boundaries. Resources owned by another scope are excluded from adoption and cannot be changed
(
OWNED_BY_OTHER_SCOPE); a pull request scope takes over its head branch’s scope. - Plugins.
SPONSON_PLUGINS(comma-separated module specifiers) loads third-party adapters and secret sources: each module exportsregister(registry). - HTTP layer for adapters. One client with timeouts, retries honouring
Retry-After, pagination and classifiedPROVIDER_*errors; tunable withSPONSON_HTTP_TIMEOUT_MS,SPONSON_HTTP_RETRIESandSPONSON_HTTP_RETRY_BASE_MS. - Leases. Scope locks are renewed (self-paced, so renewals never pile up behind a slow store), receipt
writes are fenced by the lock holder, expired locks are taken over atomically (
lockPreemptedin the receipt), git receipt stores use per-process clones with budgeted backoff, and a receipt that cannot be pushed is kept under.sponson/unpushed/(STORE_REJECTED). - Redaction registers every secret, credential and sensitive output up front in all its encodings; text is redacted before it is truncated, and JSON is redacted field by field before serialization.
sponson --versionreports the installed package’s version.- The packages are publishable:
publishConfigpoints atdist/,prepackbuilds and copies the LICENSE, each package has a README andengines: { node: ">=20" }. - The GitHub Action gained the
skippedoutput (adeployment_statuswith no open pull request, or a production deployment for a preview run) and reportsstaleas a status. @sponson/simis split into a provider-neutral core and one routes file per provider (ProviderSim), each listing the API assumptions it encodes.
Fixed
- Roughly 100 defects found by the new journey suites (
scenarios/journeys/), among them: secrets echoed back by providers in error text, receipts lost when two runs raced for a scope, resources orphaned by a lost create response, and late deploy events rolling a scope back to an older commit.
0.1.0 — 2026-10-10
First release.Added
- Plan format
release.plan.yaml(version 1): lines withadapter,op, params,environmentsanddepends_on; values are literals,{ from: line.output }references or{ secret: "scheme://…" }references;${ctx.*}interpolation; a dependency graph with cycle and unknown-reference checks. - Engine:
plan/apply/apply --destroywith rollback of what the run created, resume after a partial run, a deploy barrier for outputs that only exist after a deployment, scope locks, drift detection (unmanaged,changed,missing,orphan) with--reconcile,--wait, and redaction of secrets. - Receipts in a local directory or on the orphan git branch
sponson/receipts. - Adapters:
neon.branch,vercel.env,vercel.deploy,clerk.redirect_allow; secret sourcesenv://,doppler://,op://. - CLI:
sponson init,plan(aliasstatus),apply, andmcp(an MCP server for agents);--jsonoutput;--approved-byrequired for--env production. - GitHub Action (
action/) for pull request, deployment status and close events, andSKILL.mdfor agents. @sponson/sim, a local fake Vercel / Neon / Clerk with chaos injection and a write log.- Tests: 53 YAML scenarios across nine failure categories, an MCP smoke test, a property suite checking
seven invariants over random plans, and a contract suite that runs against the sim or, with
pnpm test:live, the real APIs.