You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
6.3 KiB
141 lines
6.3 KiB
|
2 months ago
|
---
|
||
|
|
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\<date>\` 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 "<skillDir>\scan.ps1" | ConvertFrom-Json
|
||
|
|
|
||
|
|
# preview actions, then commit them
|
||
|
|
powershell -NoProfile -ExecutionPolicy Bypass -File "<skillDir>\apply.ps1"
|
||
|
|
powershell -NoProfile -ExecutionPolicy Bypass -File "<skillDir>\apply.ps1" -Execute
|
||
|
|
|
||
|
|
# undo a batch
|
||
|
|
powershell -NoProfile -ExecutionPolicy Bypass -File "<skillDir>\apply.ps1" -Mode Restore -RestoreDate 2026-09-14 -Execute
|
||
|
|
|
||
|
|
# before ever changing the age threshold, look at the cliff
|
||
|
|
powershell -NoProfile -ExecutionPolicy Bypass -File "<skillDir>\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\<date>\` |
|
||
|
|
| `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.
|