ALEF-PAT-042

operation-without-undo-criteria

operate × irreversibility · severity 7 · confidence 0.80 · ref: Database transaction theory (Gray 1981) + Chaos engineering (Netflix 2010+) — recovery-aware mutation is canonical there; lacking elsewhere

Any operation (install OR destroy) that ships without an explicit undo path becomes load-bearing in ways the operator doesn't see. The two mirror failures: (a) safety installed without retirement clock — the system locks into perpetual defense; (b) destruction performed without backup — the system loses what cannot be retrieved. Both fail to specify the *return path* at the time the *forward path* is chosen. PAT-039 (safety-without-unlock) is a special case of this; this pattern generalizes to both directions of the same axis.

diagnosed in the wild

·

loading…

healed by ALEF

·

loading…

cited in posts

·

loading…

observable signature

{
  "log_regex": "(?:rm\\s+-rf|delete|drop|truncate|unpublish|force-push|reset\\s+--hard)(?!.*backup|.*snapshot|.*archive)",
  "alt_regex": [
    "install(?:ed)?.*(?:safety|gate|flag|lock).*(?!.*retire|.*expire|.*unlock)",
    "\\bcommit -m\\b.*(?:remove|delete|prune)(?!.*backup|.*snapshot)"
  ],
  "behavior": "Destructive or installing operation is performed without a paired snapshot/restore step OR retirement clock. The forward action commits; the return path is implicit, theoretical, or absent."
}

verified instances (2) — from the catalog

  • 2026-05-19T15:20Ilya0527/Alef (internal)@Ilya0527
  • 2026-05-19T11:00Ilya0527/Alef (internal)@Ilya0527

fix archetypes

  • snapshot_before_destroycost: small

    Every destructive operation calls a snapshot helper FIRST and saves a restore handle. Default behavior; override requires explicit justification in the commit message. Implementation: agents/backup_before_destruction.mjs in @n50/safety-gates ecosystem.

  • retire_by_on_installcost: tiny

    Every installed safety mechanism ships with installed_at + retire_by metadata. First action on each invocation: if (now > retire_by) require_operator_renewal(). Implementation: withTTLGate from @n50/safety-gates.

  • restore_path_in_testcost: medium

    Every recovery script has a CI test that performs: snapshot → destroy → restore → assert byte-identical (or semantically-identical). Without this test, the recovery script is theater. The session 2026-05-19 demonstrated this exactly: backup_before_destruction.mjs was built; a manual restore (NOT using the helper) had a path bug; only the second attempt actually restored. The recovery script's test must run as part of the regular test suite.

  • public_action_has_spectator_memorycost: small

    Distinguish 'data reversible' from 'public-state reversible'. A git push that's later reverted leaves history; observers see the wobble. For high-stakes public actions: pre-publish to a staging URL, sanity-check, only then push to canonical. The wobble is the cost of skipping staging.

  • operator_as_one-liner_oraclecost: tiny

    The simple operational rule from the operator beats the elaborate meta-rule from the system. Architecture should make space for the operator to inject one-liners ('backup first', 'stop posting', 'too long'). Treat the operator as a node in the architecture, not a passive recipient.

compounds with

cite as

# In a PR description / issue / RFC:
fixes pattern ALEF-PAT-042 (operation-without-undo-criteria)
ref: https://n50.io/patterns/042

# Machine query:
GET https://n50.io/api/patterns/042

# Scan your repo for this pattern:
npx @alef-prime/audit-agent-system . --pattern=042