Skip to content

fix: W5 re-enabled a login item the user had turned off (v1.44 follow-up) - #391

Merged
JasonYeYuhe merged 1 commit into
mainfrom
fix/w5-respect-user-disabled-login-item
Jul 29, 2026
Merged

fix: W5 re-enabled a login item the user had turned off (v1.44 follow-up)#391
JasonYeYuhe merged 1 commit into
mainfrom
fix/w5-respect-user-disabled-login-item

Conversation

@JasonYeYuhe

Copy link
Copy Markdown
Collaborator

I shipped the same bug class as #382, one release later

enableLaunchAtLoginAtFirstValueIfNeeded asked SMAppService.mainApp.status == .enabled. That single comparison collapses two different worlds:

Status Meaning Safe to enable?
.notRegistered never registered yes
.requiresApproval registered, then the user switched it OFF in System Settings absolutely not

Both answer false, so the second sailed through every remaining guard.

userTouchedToggle cannot save it. That key is new in v1.44, so nobody upgrading from v1.43 has it — exactly the shape of #382: a newly added flag cannot speak for the install base that predates it. The state has to be read from the system, not from a marker we only just started writing.

Concrete failure: a v1.43 user who turned CLI Pulse off in System Settings → Login Items upgrades, opens the app, a collector returns numbers, and the app silently turns itself back on.

My own comment three lines above called that "how an app earns a one-star review".

FanDaemonInstaller.state() in this same package has distinguished all four SMAppService.Status cases since v1.39. The precedent was in the repo and I used a bare == .enabled anyway.

Fix

decide now takes a three-state LoginItemState and gained .skipAndRememberUserChoice, which also persists userTouchedToggleKey — so the answer settles instead of being re-derived from the system on every refresh pass.

Mutation-verified: restoring the naive predicate reddens exactly testAUserWhoDisabledItInSystemSettingsIsNotOverridden and leaves the other 14 green.

Remaining blind spot (a real limit, not an oversight)

A user who toggled it on and then off inside the app on v1.43 lands on .notRegistered, indistinguishable from never having touched it. The toggle is off by default, so reaching that state takes two deliberate trips into Settings — a much smaller population than the System Settings case, and undetectable without a marker that release never wrote.

Verification

Gate Result
CLIPulseCore, default 2274 passed / 0 failed
CLIPulseCore, -DDEVID_BUILD 2309 passed / 0 failed
macOS / iOS / watchOS BUILD SUCCEEDED ×3

🤖 Generated with Claude Code

…-up)

I shipped the same bug class as #382, one release later.

`enableLaunchAtLoginAtFirstValueIfNeeded` asked `SMAppService.mainApp.status
== .enabled`. That single comparison collapses two different worlds:

  .notRegistered   — never registered. Fine to enable.
  .requiresApproval — registered, and the user then switched it OFF in
                      System Settings. Absolutely not fine to enable.

Both answer `false`, so the second one sailed through every remaining guard.

`userTouchedToggle` cannot save it. That key is new in v1.44, so NOBODY
upgrading from v1.43 has it — which is exactly the shape of #382: a newly
added flag cannot speak for the install base that predates it. The state has
to be read from the system instead of from a marker we only just started
writing.

Concrete failure: a v1.43 user who turned CLI Pulse off in System Settings →
Login Items upgrades, opens the app, a collector returns numbers, and the app
silently turns itself back on. My own comment three lines above called that
"how an app earns a one-star review".

`FanDaemonInstaller.state()` in this same package has distinguished all four
`SMAppService.Status` cases since v1.39. I had the precedent in the repo and
used a bare `== .enabled` anyway.

Fixed by giving `decide` a three-state `LoginItemState` and a new
`.skipAndRememberUserChoice` outcome, which also persists
`userTouchedToggleKey` so the answer settles instead of being re-derived from
the system on every refresh pass.

Mutation-verified: restoring the naive predicate reddens exactly
`testAUserWhoDisabledItInSystemSettingsIsNotOverridden` and leaves the other
14 green.

Note the remaining blind spot, since it is a real limit rather than an
oversight: a user who toggled it on and then off *inside the app* on v1.43
lands on `.notRegistered`, indistinguishable from never having touched it. The
toggle is off by default, so reaching that state takes two deliberate trips
into Settings — a much smaller population than the System Settings case, and
undetectable without a marker that release never wrote.

CLIPulseCore 2274 passed / 0 failed (default), 2309 / 0 (-DDEVID_BUILD);
macOS + iOS + watchOS all BUILD SUCCEEDED.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@JasonYeYuhe
JasonYeYuhe merged commit 6329416 into main Jul 29, 2026
26 of 28 checks passed
@JasonYeYuhe
JasonYeYuhe deleted the fix/w5-respect-user-disabled-login-item branch July 29, 2026 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant