Status
AcceptedContext
Between two runs people edit consoles: they fix an incident by changing a variable, delete a branch, add something by hand. A plan line may also be deleted while its resource still exists. Each case needs a different answer, and the wrong default is costly: silently overwriting a console edit can undo an emergency fix at the worst moment, and treating unknown resources as “to be deleted” is the largest source of accidents with tools that do so.Decision
plan reports drift in its own section (drift[]), separate from the diff. There are four kinds (DriftKind in
packages/core/src/types.ts):
Further rules:
- A console edit that already matches the plan is accepted silently: only conflicting edits are refused.
planpredicts the refusal: the line’s status isblockedwitherrorCode: DRIFT_CHANGED, so nobody learns about it halfway through an apply.applyre-reads live state for every line instead of trusting whatplansaw, so an edit made betweenplanandapplyis still caught.--reconcileapplies only tochanged: the plan’s value wins and the receipt line notesreconciled: true. A replaced resource reconciled this way is treated as adopted, because Sponson did not create it.- Drift is only looked for where plan lines could own resources (each op’s
listScope): no account-wide scans and no permissions beyond what the plan needs. apply --destroydeletes a resource Sponson created even when it haschangeddrift: the scope is going away and what it created goes with it. The edit is never lost silently: destroy re-reads the line first, names the resource in a warning (so in the output and the PR comment) and records it under the line’snotes.changedOutsidein the receipt. There is no flag to keep such a resource: destroy runs unattended when a pull request closes, and a kept resource would belong to no scope, the garbage nothing collects (ADR 0002’s missing fourth command). A resource re-created outside Sponson (a new provider id) is not Sponson’s, so destroy leaves it, as before.
Consequences
- Deleting a plan line never destroys anything. Removal is always the explicit
apply --destroy. - A human decides whether a console edit or the plan wins; SKILL.md tells agents to show the drift and leave
--reconcileto a person. - The ledger must keep a hash and provider id for every entry (ADR 0005),
or
changedcannot be told frommissing. - Resources other scopes manage are excluded from
unmanaged(ADR 0008).