Skip to docs content
Browse documentation
On this page

Two-way and one-way doors

Ship cheap, reversible changes quickly. Spend the review on changes that are expensive or impossible to undo.

A two-way door is cheap to reverse: ship it, and change it if it turns out wrong. A one-way door is expensive or impossible to undo. Spend your review time there.

One-way doors in Minion include:

  • A stored format other code already relies on
  • A public contract, like the MCP execute tool's code, params and idempotencyKey
  • Deleting or rewriting user data
  • Database migrations that drop, rename or tighten a column

Guide copy, admin UI, error wording and internal function names are two-way. Change them.

Example

Compiled sandbox code is cached and never mutated. When the generated code or the capability interface changes, the version label changes instead:

/** Bump when generated code or the capability ABI changes; cached WorkerCode is immutable. */
export const DYNAMIC_ABI = 'minion-dynamic-v1'

Migrations follow a simple rule: additive changes ship with the code. Destructive ones ship as their own step, once nothing reads the old shape. See Finish the migration .

In your packages

Every save creates a new, immutable version, and minion.packages.publish({ name, version }) can make an earlier version the one that runs again. That makes most package changes two-way. The one-way parts are the ones outside the package: data you send to another service, emails, deleted storage, and the shape of anything other packages import from you. Slow down for those. See Mutating actions .