"Incomplete receipts stay visible for recovery." — Tinker architecture, hide invariant 3
Only Two Phases
A receipt is either prepared or applied. There is no "failed", no "rolled back", no "pending retry". That spareness is deliberate. Applied means the OS confirmed the change and Tinker owns it: it will appear under "Changes Tinker will restore" and be undone when its last owner releases it. Prepared, once no action is running, means exactly one thing: an intent was recorded and its outcome is unknown. A receipt that was dropped because the capability proved it asked for nothing is not a third phase — it is simply gone. Everything else is one of the two.
What Prepared Does to the Engine
When the engine is constructed from the saved journal, it checks for any prepared receipt. If there is one, the engine starts stopped. Hotkeys are not registered and every apply is refused with "Tinker is stopped. Resume it in Settings." Restoring stays possible — the menu's Restore item still works — because taking back a confirmed change never needs the engine's trust. The reasoning is that an uncertain record describes a situation where Tinker's own understanding of the screen may be wrong, and acting on top of a possibly-wrong understanding is how one uncertainty turns into two.
Resume Has Conditions
resume() refuses while an action is executing, while the engine has a persistence fault, and while any prepared receipt remains — "Resolve uncertain changes before resuming." So the path out of an uncertain state is always the same: look at the app named in Recovery, decide what its visibility should be, use the ordinary Mac controls if anything needs changing, then Forget the record, then resume. Tinker's job in that path is to explain, not to act.
Uncertain Records Are Not Restored Either
Restore, release-all and Quit all walk the journal, and all of them skip prepared receipts with the message "Uncertain change …: inspect it in Recovery." Undoing a change you are not sure you made is the mirror image of the bug the whole design avoids: it could unhide an app someone else hid. So emergency release, which is otherwise the most forceful command Tinker has, still leaves uncertain records exactly where they are and reports that it did.
Names for People
A receipt's key is a machine string. For Recovery, Activity and the app door's change.list, the receipt offers a displayName: the name field from its payload if the capability put one there, otherwise the key. It is a small courtesy that keeps the root ignorant of apps while letting the screen say "Voyager" instead of a colon-separated identifier.