Skip to content

v0.5.0 — Dry-run oracles: observe, don't predict

Choose a tag to compare

@Atharva-Jayappa Atharva-Jayappa released this 06 Jul 03:46
· 22 commits to master since this release

v0.5.0 — Dry-run oracles: observe, don't predict

v0.4 resolved what the shell executes; the scorer still estimated what that command destroys. For a whole class of destructive commands, the tool itself can be asked — side-effect-free — for the exact answer. This release asks.

The headline behavior:

git clean -fdx        # in a repo whose untracked files include .env

The command never names .env. blast-scope now runs git clean -n (mirroring your exact -d/-x flags), discovers the real victim list, scores it against each file's recoverability — .env → secret → CRITICAL — and the PreToolUse hook archives those exact files into an undo snapshot before the deletion runs. restore_snapshot brings them back. Previously the snapshot could only archive statically-parsed paths, which for git clean is nothing at all.

The oracles (each verified side-effect-free)

Command Oracle What you get
git clean -f[dxX] git clean -n + mirrored selection flags exact Would remove list; nested-repo skips flagged
git reset --hard <ref> git rev-list --count <ref>..HEAD orphaned-commit count, reflog-honest severity
git checkout/restore git diff --name-only HEAD [-- paths] exact dirty files that get clobbered
find … -delete / -exec rm faithful -print rewrite exact match set before anything is deleted
sqlite3 "DELETE … WHERE p" SELECT count(*) … WHERE p (read-only) matched/total rows — a "scoped" delete hitting 90% of the table floors at high
rsync --delete (local) --dry-run --itemize-changes exact *deleting list

Details that matter:

  • The find rewrite is faithful, not naive. -delete implies -depth, so the rewrite adds it back (otherwise -prune exclusions diverge); the destructive terminal is replaced in place (it gates everything to its right); expressions with -o or multiple terminals punt to the static classification rather than lie. rm -r payloads are flagged as subtree roots.
  • Reflog-honest reset severity. Commits orphaned by reset --hard <ref> are recoverable from the reflog for ~30–90 days — so divergence floors at medium, not critical. The unrecoverable loss is the dirty working tree, which keeps its count-scaled floor. No reflog in the repo? The floor rises.
  • Verified UNSAFE, never used as probes: make -n ($(shell) executes at parse), npm --dry-run (lifecycle scripts), EXPLAIN ANALYZE on DELETE (executes it), BEGIN…ROLLBACK (transient mutation is still mutation), chmod --changes / cp -n / mv -n (execution-time reporters, not previews).
  • Graceful degradation unchanged: no rsync on stock Windows, Windows find.exe being a string-search tool, an unverifiable ref — all degrade to labeled estimates or the static classification. A failed probe never scores lower than not probing.

Plumbing

Consequence gained an optional targets channel. Oracle-discovered paths merge into the step's parsed targets at one point in assess(), so recoverability, the mass-destruction gate, the evidence, and the snapshot all see the real victims with no per-consumer wiring.

Numbers

  • In-repo corpus grew 54 → 58 cases (divergence clean/dirty, scoped-DELETE small/mass): 58/58 exact, gate F1 1.00.
  • SABER: unchanged — 0.58% FPR, 82.4% data-destruction recall. That's the honest read: the oracles' value on this benchmark is exactness and undo-ability, not raw recall (the remaining misses need workspace state — git remotes, POSIX find — the Windows harness doesn't provide). No regression from the reflog-honest severity change.
  • 381 tests across ubuntu / windows / macos.

Upgrade

uvx blast-scope@0.5.0

No breaking changes; probes add ≤2–3s only to already-flagged destructive git/find/rsync commands.