rules:
- id: coreutils.rm
match: { command: rm }
effect: destructive
scope: { paths: positional, globs: true, recursive_flags: ["-r", "-R", "--recursive"] }
undo: snapshot-restore
notes: "Bypasses Trash; no native recovery."
- id: coreutils.rmdir
match: { command: rmdir }
effect: destructive
scope: { paths: positional }
undo: snapshot-restore
- id: coreutils.unlink
match: { command: unlink }
effect: destructive
scope: { paths: positional }
undo: snapshot-restore
- id: coreutils.mv
match: { command: mv }
effect: destructive
scope: { paths: positional }
undo: snapshot-restore
notes: "Destination overwrite and source relocation both need pre-state."
- id: coreutils.cp
match: { command: cp }
effect: destructive
scope: { paths: positional-last }
undo: snapshot-restore
notes: "Only the destination is at risk; snapshot the last positional."
- id: coreutils.dd
match: { command: dd }
effect: destructive
scope: { paths: none }
undo: snapshot-restore
notes: "Target is of=; needs parser flag handling (step 2). Until then scope=none falls back to the unknown policy."
- id: coreutils.truncate
match: { command: truncate }
effect: destructive
scope: { paths: positional, flag_args: ["-s", "--size"] }
undo: snapshot-restore
- id: coreutils.shred
match: { command: shred }
effect: irreversible
scope: { paths: positional }
undo: snapshot-restore
notes: "Snapshot best-effort; the whole point of shred is that recovery fails. Gate."
- id: coreutils.tee
match: { command: tee }
effect: destructive
scope: { paths: positional }
undo: snapshot-restore
notes: "-a appends (additive); plain tee truncates targets."
- id: coreutils.chmod
match: { command: chmod }
effect: destructive
scope: { paths: positional, skip: 1, recursive_flags: ["-R"] }
undo: snapshot-restore
notes: "Metadata-only loss; snapshots preserve mode bits. skip:1 drops the mode argument."
- id: coreutils.chown
match: { command: chown }
effect: destructive
scope: { paths: positional, skip: 1, recursive_flags: ["-R"] }
undo: snapshot-restore
notes: "skip:1 drops the owner:group argument."
- id: coreutils.ln
match: { command: ln }
effect: destructive
scope: { paths: positional-last }
undo: snapshot-restore
notes: "-sf silently replaces the target."
- id: coreutils.install
match: { command: install }
effect: destructive
scope:
paths: positional
flag_args: ["-m", "--mode", "-o", "--owner", "-g", "--group", "-s", "--strip-program", "-b", "--suffix", "-S"]
undo: snapshot-restore
notes: >
Copies sources over a destination, replacing it. `paths: positional`
captures the dest (and, harmlessly, the sources); a separate-word
`-t DIR` target also falls through as a captured positional. flag_args
swallows the value options so their values are not mistaken for paths.
Precise capture beats the cwd-only fallback for an out-of-cwd target.
`install -d` only creates dirs (no data at risk).
- id: coreutils.gzip
match: { command: gzip }
effect: destructive
scope: { paths: positional }
undo: snapshot-restore
- id: coreutils.gunzip
match: { command: gunzip }
effect: destructive
scope: { paths: positional }
undo: snapshot-restore
- id: coreutils.bzip2
match: { command: bzip2 }
effect: destructive
scope: { paths: positional }
undo: snapshot-restore
- id: coreutils.bunzip2
match: { command: bunzip2 }
effect: destructive
scope: { paths: positional }
undo: snapshot-restore
- id: coreutils.xz
match: { command: xz }
effect: destructive
scope: { paths: positional }
undo: snapshot-restore
- id: coreutils.unxz
match: { command: unxz }
effect: destructive
scope: { paths: positional }
undo: snapshot-restore
- id: coreutils.zstd
match: { command: zstd }
effect: destructive
scope: { paths: positional }
undo: snapshot-restore
- id: coreutils.unzstd
match: { command: unzstd }
effect: destructive
scope: { paths: positional }
undo: snapshot-restore
- id: coreutils.mkdir
match: { command: mkdir }
effect: mutating
undo: none
- id: coreutils.touch
match: { command: touch }
effect: mutating
undo: none
notes: "Creates or bumps mtime; content never lost."
- id: coreutils.ls
match: { command: ls }
effect: safe
undo: none
- id: coreutils.cat
match: { command: cat }
effect: safe
undo: none
notes: "Read-only unless combined with a redirect; redirects match their own rules."