"A corrupt settings file or journal is preserved and disables actions." — Tinker's house sign
The Tempting Recovery
When a JSON file fails to parse, the easiest code path is to log a warning and start from an empty document. For most apps that is merely rude. For Tinker it would be dangerous: an empty journal means "Tinker owns nothing", so every app it had hidden before the corruption would become unowned and would never be restored. Worse, the next save would write the empty document over the unreadable one and destroy whatever might still have been recovered from it.
Three Checks on Every Load
The journal is validated before the engine accepts it. The schema version must be 1. Receipt keys must be unique. Every receipt must have a non-empty key, at least one owner, and owners that all appear in the active set. A document that fails any of these is not "repaired"; the engine refuses to construct and reports "Invalid change journal; automatic actions are held." The checks are cheap and they catch the classic hand-edit and partial-merge mistakes — an owner removed from active but left on a receipt, a receipt duplicated by a copy-paste.
Preserved Means Untouched
The file itself is never rewritten while it cannot be read. CwkKit's document store refuses to save over a present-but-unreadable file unless the caller explicitly asks to replace it, and Tinker never asks. The journal is read with defaults materialisation turned off, so even a successful read does not trigger a rewrite. The bad file sits there for a person to open, fix or move aside. "Disables actions" in the house sign means commands: a held journal or held settings stop presets from running, but — as the next lesson shows — an unreadable settings file never takes emergency release away.
Forget: the One Way to Drop a Claim
Uncertain records are cleared only by a deliberate decision in the Recovery tab. forgetUncertain(key:) refuses while an action is executing — a receipt that is prepared because its hide is in progress right now must not be erased under it, and Tinker's tests freeze a hide mid-flight to prove exactly that. It refuses for applied receipts, which belong to normal restore. When it succeeds it removes the receipt and drops from active any owner that no longer has a receipt. In the UI, Forget is an armed two-click control, like Delete Preset: the first click arms it, the second acts.
Why Not a Timeout?
One could argue that an uncertain record older than a day is surely stale and could be dropped automatically. Tinker does not, because age is not evidence. The record exists precisely because Tinker could not tell what happened; waiting does not make it able to tell. Only a person looking at the screen can.