Skip to content
C.W.K.
Lesson 02 of 05 · published

Never Acquire What Was Already Hidden

~12 min · pre-hidden, needs-apply, restore, user-intent

Level 0Idle Hands
0 XP0/39 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Already-hidden apps are never acquired." — Tinker architecture, hide invariant 2

The Restore That Lies

Imagine the naive version. Dad hid Eagle with ⌘H an hour ago because he did not want to see it. Now he presses the editing key: the preset lists Eagle, Claude and Voyager, so "hide all three" runs and Eagle, already hidden, stays hidden. Two hours later he presses the key again, and the naive restore "shows all three". Eagle pops back — an app Dad himself had put away, now undone by a tool that never put it away in the first place. That is a restore that lies about history.

needsApply Is the Whole Defence

Tinker's defence is not a special rule in restore; it is earlier and simpler. At prepare time the plan for Eagle is emitted with needsApply: false because Eagle is already hidden. The engine never writes a receipt for a plan that does not need applying, so Eagle never becomes Tinker's. When restore later walks the journal it finds receipts for Claude and Voyager only. Eagle is not skipped by restore; it was never in restore's world.

The Promise in the UI

This behaviour is visible to Dad, not just to the code. Under every preset Settings prints: "Apps remain running. Apps already hidden stay hidden when this preset is restored." The Access & Recovery tab lists the changes Tinker will restore with the presets that own each one, and an app that was already hidden simply never appears there. If Dad wonders why Eagle did not come back, the answer is on the screen before he asks.

Why Not "Remember and Return to the Previous State"?

A plausible alternative is to snapshot every candidate's visibility at apply time and return each to its snapshot at restore time. It sounds equivalent and it is not. A snapshot of "Eagle was hidden" would make restore re-hide Eagle if Dad had shown it in the meantime — Tinker would be acting on a state it did not create, in the direction Dad had just reversed. Owning only your own changes is strictly safer than restoring a remembered world: when Tinker is unsure what Dad wants, it does nothing.

Code

The two lines that make pre-hidden apps invisible to restore·swift
// prepare(): an already-hidden app is described but not claimed
ChangePlan(key: snapshot.identity.key,
           payload: try jsonValue(snapshot.identity),
           needsApply: !snapshot.hidden)

// engine apply loop: no receipt, so never restored later
guard change.needsApply else { continue }   // pre-existing state is not ours
A unit test in the spirit of Tinker's own (fake visibility, no real apps)·swift
import Testing

@MainActor @Test func preHiddenAppStaysHiddenAfterRestore() async throws {
  let apps = FakeVisibility(running: [
    .init(bundleID: "tw.ogdesign.eagle", hidden: true),   // Dad hid it himself
    .init(bundleID: "com.cwk.voyager", hidden: false)])
  let engine = try makeEngine(apps)
  let step = hideStep(["tw.ogdesign.eagle", "com.cwk.voyager"])

  try await engine.apply(id: "preset/edit", steps: [step])
  #expect(engine.journal.changes.count == 1)              // only Voyager is ours

  try await engine.restore(id: "preset/edit")
  #expect(apps.isHidden("tw.ogdesign.eagle") == true)     // still Dad's choice
  #expect(apps.isHidden("com.cwk.voyager") == false)
  #expect(apps.quitCount == 0)                            // nothing was quit
}

External links

Exercise

Rewrite the scenario for a 'Do Not Disturb' capability: Dad turned Focus on by hand before the preset ran. Using needsApply, describe what prepare should emit, what apply should do, and what restore should do. Then describe the bug the 'snapshot and return' design would produce if Dad turned Focus off by hand while the preset was active.
Hint
Focus already on → needsApply false → no receipt → restore leaves Focus on (it was Dad's). With snapshot-and-return, the snapshot says 'on', so restore would switch Focus back on even though Dad had just turned it off — acting against the most recent human decision.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign in — Please sign in to comment.

No comments yet — be the first.