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
executetool'scode,paramsandidempotencyKey - 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 .