v0.11.0
Backup handling, rule precedence, and a stronger gate.
Backups are sorted by kind (#11, #14, #20)
The audit previously treated every .bak as interchangeable clutter and advised pruning to "the most recent one or two" - a number the skill invented. Against a real setup with 106 CLAUDE.md snapshots and a rotation script whose policy is to compress rather than delete, that read as a proposal to destroy 104 files, in the one check that proposes destroying anything.
Backups are now two classes with opposite treatment:
- Your own snapshots - reported, never proposed for deletion. Compression is the safe offer; deletion needs an age threshold you name. An existing rotation policy of your own always wins.
- Notation's run backups - the rollback window for one run, offered for cleanup only once that run's verification passed.
Notation now writes every backup under ~/.claude/notation-backups/{global,<project>}/<stamp>/, one directory per run and never beside the original. Previously it wrote ~/.claude/CLAUDE.md.bak.<stamp> - the same pattern people use by hand - so the two were indistinguishable and a rotation script would gzip notation's droppings while pushing real snapshots out of its keep-uncompressed window.
A run directory is marked .verified only after its checks pass. Unmarked means the run failed, was interrupted, or was restored, and its backup is the only remaining copy of whatever it moved - never offered for deletion, and never sorted by age, since the oldest directory is exactly as likely to be that one.
Other projects' backups are reported as an aggregate and never deleted: an audit resolves one project and cannot verify another's run passed.
Conflicting rules now state which one wins (#9, #10)
Three issues have come from the same defect - two rules pulling opposite ways with neither mentioning the other. One principle settles them: does an index line buy findability, or only tidiness? Note bytes cost nothing until a note is opened; an index line costs context in every session, forever.
- Routing quality beats index-line cost. Preferring an existing note stops where that note is a stretch. If a future session searching for the fact would not open that file, mint the new note and offset the line. A fact filed where nobody looks passes every check here, including the preservation probe, because the string is on disk.
- The budget beats splitting an oversized note. A split buys no findability - those facts are already reachable - so it is deferred while the global file is at or over target, and said out loud rather than silently skipped. Merging thin siblings is the mirror case and always welcome.
Each conflict has one ruling that every participating rule points back at, so neither side can be read in isolation.
Guard against encoding drift (#17)
The project-directory encoding is inlined at nine call sites because shell state does not survive between tool calls. Only two were drift-guarded, and the repo-wide ban covered a single historically broken form - so a site rewritten into a differently-wrong one shipped clean while failing exactly like the original bug. Every call site is now checked.
Gate
./scripts/verify.sh grew two suites - rule precedence and backup lifecycle - and now runs seven. Each new guard was mutation-tested: 27 rows across the three changes, every one confirmed to fail the gate before being trusted.