fix: enforce open-limit rules proactively in the foreground #1

Merged
brendan merged 1 commits from fix/open-limit-proactive-enforcement into main 2026-06-13 17:54:21 +00:00
Owner

(co-authored by Claude Opus 4.8)

RuleEnforcer.refresh only shielded a limit rule once its budget was
spent, so it tore down the background's proactive open-limit "turnstile"
shield (the shield is how opens are counted) whenever the app was
foregrounded, and a freshly created open-limit rule did nothing until
the next midnight reset.

refresh now applies the same proactive gate as
LimitEnforcement.handleDayStart: an enabled, scheduled-today, un-paused
open-limit rule is shielded even before its budget is spent, so it takes
effect immediately. A new app-group OpenSessionStore records a granted
"Open" session's expiry so neither enforcement path re-shields (and cuts
short) a sanctioned ~15-minute session.

Overlapping rules already enforce strictly: each rule shields its own
ManagedSettingsStore and Screen Time unions them, so an app is blocked
if any covering rule blocks it. Document that model in the spec (§4.8)
and lock it in with tests, including a time limit blocking during an
open-limit's granted session and a daily opens reset.

(co-authored by Claude Opus 4.8) RuleEnforcer.refresh only shielded a limit rule once its budget was spent, so it tore down the background's proactive open-limit "turnstile" shield (the shield is how opens are counted) whenever the app was foregrounded, and a freshly created open-limit rule did nothing until the next midnight reset. refresh now applies the same proactive gate as LimitEnforcement.handleDayStart: an enabled, scheduled-today, un-paused open-limit rule is shielded even before its budget is spent, so it takes effect immediately. A new app-group OpenSessionStore records a granted "Open" session's expiry so neither enforcement path re-shields (and cuts short) a sanctioned ~15-minute session. Overlapping rules already enforce strictly: each rule shields its own ManagedSettingsStore and Screen Time unions them, so an app is blocked if any covering rule blocks it. Document that model in the spec (§4.8) and lock it in with tests, including a time limit blocking during an open-limit's granted session and a daily opens reset.
brendan added 1 commit 2026-06-13 17:54:18 +00:00
RuleEnforcer.refresh only shielded a limit rule once its budget was
spent, so it tore down the background's proactive open-limit "turnstile"
shield (the shield is how opens are counted) whenever the app was
foregrounded, and a freshly created open-limit rule did nothing until
the next midnight reset.

refresh now applies the same proactive gate as
LimitEnforcement.handleDayStart: an enabled, scheduled-today, un-paused
open-limit rule is shielded even before its budget is spent, so it takes
effect immediately. A new app-group OpenSessionStore records a granted
"Open" session's expiry so neither enforcement path re-shields (and cuts
short) a sanctioned ~15-minute session.

Overlapping rules already enforce strictly: each rule shields its own
ManagedSettingsStore and Screen Time unions them, so an app is blocked
if any covering rule blocks it. Document that model in the spec (§4.8)
and lock it in with tests, including a time limit blocking during an
open-limit's granted session and a daily opens reset.
brendan merged commit c826bbbe88 into main 2026-06-13 17:54:21 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: brendan/OpenAppLock#1