--- name: "scratchpad-cleanup" description: "Use when tidying, auditing, or freeing space in the Scratchpad working folder at D:\\Repos\\Scratchpad - the weekly sweep or an ad-hoc pass. Also use when reviewing or restoring files quarantined under _trash, or deciding whether a scratch artifact should be promoted into the Obsidian vault. Triggers: /scratchpad-cleanup, clean up scratchpad, tidy scratchpad, scratchpad is a mess, what can I delete in scratchpad, restore from _trash." --- ## Scratchpad Cleanup Keeps `D:\Repos\Scratchpad` from silting up, without ever destroying something that mattered. **Core principle: Scratchpad is NOT a git repo.** There is no history and no undo. Every irreversible action is therefore either provably safe or routed through a `_trash\\` quarantine with a grace period. The quarantine *is* the undo. ### When to Use - The weekly automated sweep. - Ad-hoc: "scratchpad is a mess", "what can I delete", "what's stale in there". - Reviewing what got quarantined, or restoring something binned by mistake. - Deciding whether a scratch artifact is actually a durable finding that belongs in the vault or a repo. ### Division of labour The mechanical decisions live in scripts so they are reproducible and identical every run. The skill only makes the calls a script *shouldn't*. | Script | Does | Writes? | |---|---|---| | `scan.ps1` | Classifies every file into buckets, emits JSON | No - read-only | | `apply.ps1` | Executes the safe actions | Only with `-Execute` | ```pwsh # classify (read-only); this is always step 1 powershell -NoProfile -ExecutionPolicy Bypass -File "\scan.ps1" | ConvertFrom-Json # preview actions, then commit them powershell -NoProfile -ExecutionPolicy Bypass -File "\apply.ps1" powershell -NoProfile -ExecutionPolicy Bypass -File "\apply.ps1" -Execute # undo a batch powershell -NoProfile -ExecutionPolicy Bypass -File "\apply.ps1" -Mode Restore -RestoreDate 2026-09-14 -Execute # before ever changing the age threshold, look at the cliff powershell -NoProfile -ExecutionPolicy Bypass -File "\scan.ps1" -ReportOnlyAges ``` **Always invoke the scripts with `powershell -File` and an absolute path.** They are saved UTF-8 *with BOM* deliberately: Windows PowerShell 5.1 reads a BOM-less file as Windows-1252, which corrupts any non-ASCII byte and silently changes control flow. Keep both scripts ASCII-only; do not paste em dashes or smart quotes into them. ### Buckets, and who owns each | Bucket | Owner | Action | |---|---|---| | `autoPurgeFiles` | script | delete - `.log` / `.err` | | `emptyDirs` | script | delete | | `quarantine` | script | move to `_trash\\` | | `trashExpired` | script | delete batches past grace | | `protected` | nobody | never touched | | `largeFiles` | **you** | report only | | `supersession` | **you** | report only | | `promoteCandidates` | **you** | report only | ### The judgment calls **1. Promotion candidates.** Markdown >= 2 KB and older than 14 days is held *out* of quarantine, because an age rule must never silently bin a findings doc. For each, decide: does this belong in the Obsidian vault (a durable finding, design note, or decision record), in a real repo (a script worth keeping), or is it genuinely spent? Recommend a destination; never move it yourself without the user agreeing. **2. Supersession groups.** Numbered siblings - `parse.js` / `parse2.js` / `parse3.js`, `render_v2.py` / `render_v4.py`, `smap-check.ps1` / `smap-check2.ps1`. Newest-wins is the usual answer but not always right; the older one occasionally holds the approach that actually worked. Present the group with dates and sizes and let the user choose. **3. Large files.** Anything >= 5 MB is reported and never auto-actioned. In this folder the space story is almost entirely a handful of `.db` snapshots, so "reclaim space" and "reduce clutter" are different jobs with different targets. Note that a file whose name contains `backup`, `prenuke`, `restore`, `snapshot` or `.bak` is protected outright - those exist precisely to save someone. ### Protection rules (never overridden) - Any path containing a `.git` segment - repo internals. - Any top-level folder carrying `.git`, `node_modules`, `package.json`, `*.dll`, `*.psd1`, `*.csproj`, or `requirements.txt` - a vendored tree or checked-out repo, protected wholesale. Partial deletion of a module tree is worse than leaving it. - Names matching `backup|prenuke|restore|snapshot|\.bak$`. - Everything already under `_trash\`. ### Run report Lead with what changed, then what needs a decision: ``` Scratchpad cleanup - 2026-09-14 Reclaimed: 5 log files, 2 empty dirs Quarantined: 14 files -> _trash\2026-09-14 (restorable until 2026-10-14) Needs your call: Promote? 5 findings docs, 34d idle - e.g. "SMAP-Kusto-Findings.md" Superseded? parse.js/parse2.js/parse3.js - keep parse3 only? Large: bellwether-prenuke-*.db (20.8 MB) - protected, but is it still needed? ``` Silence is fine. If nothing was reclaimed and nothing needs a decision, say so in one line rather than padding the report. ### Guardrails - Never act outside `D:\Repos\Scratchpad`. - Never delete anything that has not been through quarantine first, except `.log` / `.err` files and empty directories. - `apply.ps1` is dry-run by default. Do not pass `-Execute` to a mode you have not previewed in the same run. - `MaxQuarantinePerRun` (60) is a deliberate circuit breaker. If it trips, do NOT raise it to get past it - it means the age threshold changed and is about to sweep the folder. Check `scan.ps1 -ReportOnlyAges` and report to the user instead. - Never move a promotion candidate into the vault unprompted; the vault has its own schema rules (see `D:\Repos\Obsidian\AGENTS.md`) and an unannounced write there will fail lint. ### Common Mistakes - Lowering the age threshold without checking `-ReportOnlyAges` first. The distribution is lumpy: a single day's work can put 100+ files in one band, so a small threshold change can be the difference between 14 files and 147. - Treating `.db` / `.tm7` / `.excalidraw` as junk because they are large or binary. They are usually the most expensive artifacts in the folder. - Deleting an empty directory inside `.git` - it corrupts the repo. The scan already excludes these; do not re-add them by hand.