offmain
private beta · 2026 Join waitlist
// shipped

Changelog

Short dated notes on what landed across the apps and the backend.

$ cd ~/changelog·239 entries·page 4 of 5rss feed

week of jul 6, 2026

also this week

  • macOSRemove scheduled rules and the streak counter ahead of the minutes modelremoved
  • macOSRebuild the Mac app on the iOS design system, with a matching companionchanged
  • ChromeRebuild the popup, onboarding, and block page on one design systemchanged

week of jun 29, 2026

Android7 changes

Android blocks apps and holds through restarts

GitHub sign-in and backend sync land, an overlay covers locked apps as they come to the foreground, and push lifts the block within moments of an unlock.

  • Add opt-in crash and error reporting, off by default and scrubbedaddedwhy

    Add opt-in crash and error reporting. Off by default, revocable from onboarding and Home, and scrubbed of tokens, headers, and blocked-app identifiers before it leaves the device.

  • Switch crash reporting to opt-out and report detection-service crasheschangedwhy

    Switch crash reporting to opt-out instead of opt-in, and forward detection-service crashes to the consent-gated reporter instead of swallowing them silently.

  • Keep apps blocked when a rule refresh fails or goes stalesecuritywhy

    Make enforcement fail closed. A failed or stale rule refresh now keeps the last-known verdict instead of dropping the Shield, and locked apps stay covered through app restarts and lost permissions.

  • Lift the block within moments of an unlock, with a poll as a backstopaddedwhy

    Add FCM push pairing so an unlock lifts the Shield within moments of the backend verdict, with a periodic poll as a backstop when push does not arrive.

  • Stop the crash loop from registering a device before sign-infixedwhy

    Gate installation registration on a signed-in session. Fixes a crash loop from unauthenticated registration attempts and ensures a signed-in user without Firebase still registers their device.

  • Block locked apps with an overlay when they come to the foregroundaddedwhy

    Detect the foreground app through usage stats and raise an overlay Shield over locked apps. Home now shows the verdict and progress per rule, and onboarding walks through the required permissions and app picker.

  • Add GitHub sign-in and sync rules and verdicts from the backendaddedwhy

    Add GitHub sign-in and a Keystore-backed session to the app. Rules, verdicts, and the installed-app catalog now sync from the backend, and the device registers itself for push.

backend17 changes

The delivery path opens and hardens

Web Push, Firebase, and a live macOS connection carry unlocks, registering a device now needs a verified session, and OffMain encrypts push credentials at rest.

  • Catch commits a dropped or delayed webhook missed, on a scheduled sweepfixedwhy

    Add a scheduled reconciliation pass that catches commits a dropped or delayed webhook missed, and keeps a streak’s day record current even on a day with no GitHub activity, closing gaps where a lost webhook or a quiet day could silently break the streak.

  • Add push delivery over Firebase Cloud Messaging for an Android clientaddedwhy

    Add push delivery over Firebase Cloud Messaging, the transport an Android client needs to receive unlocks.

  • Land a menu-bar unlock the instant the goal flips, over a live macOS connectionaddedwhy

    Give the macOS app a live connection to the backend, so a menu-bar unlock lands the instant the goal flips instead of waiting on a push notification.

  • Encrypt push credentials at rest, as connected-account tokens already aresecuritywhy

    Encrypt push credentials (APNs device tokens, FCM registration tokens, Web Push keys) at rest instead of storing them in plaintext, matching how connected-account tokens are already sealed.

  • Add Web Push delivery and a per-client OAuth redirect for the Chrome extensionaddedwhy

    Add Web Push delivery and a per-client OAuth redirect target, opening the door for the Chrome extension to connect and receive unlock pushes. Also close a race where a fast double refresh of a session could log a device out instead of returning the same rotated token pair.

  • Count either author or reviewer on merged-pull-request and closed-issue rulesaddedwhy

    Add an “any” role option for merged-pull-request and closed-issue rules, so a rule can count activity where the account was either the author or the reviewer, not just one fixed role.

  • Require a live, verified session to register a devicesecuritywhy

    Close an account-takeover hole where registering a device only required asserting someone else’s GitHub id, with no proof of a real session. Registering a device now requires a live, verified session tied to that account.

  • Announce the moment the day's goal flips to met, with a visible notificationaddedwhy

    Add a visible notification announcing the moment the day’s goal flips from not-met to met, alongside the existing silent push that does the unlocking. If the device is offline right when it happens, the alert still lands anytime before the day resets.

  • Rate-limit sign-in and token refresh, and turn off the API docs in productionsecuritywhy

    Add rate limits on sign-in and token-refresh requests, and turn off the public API docs in production, closing off easy brute-force and reconnaissance paths at the edge.

  • Reject a scheduled-rule window off the 15-minute grid the phone can enactfixedwhy

    Reject scheduled-rule windows that don’t align to a 15-minute grid, matching the precision the phone can actually enact, instead of silently saving a window it could never honor.

  • Reject webhook deliveries when no signing secret is configuredsecuritywhy

    Harden the webhook and push pipeline: reject deliveries outright when no signing secret is configured, instead of accepting them, and make a crashed delivery safe to retry without dropping or duplicating events.

  • Add schedule-only rules, a time window alone, such as no Slack after 9pmaddedwhy

    Add schedule-only rules: define a rule as just a time window, such as no Slack after 9pm, with no GitHub activity required and kept separate from the streak.

  • Show the rule editor current GitHub signals, roles, and repo-match patternsaddedwhy

    Serve the list of valid GitHub signals, roles, and repo-match patterns from the backend, so a rule editor shows real, current options instead of a copy that can drift out of sync.

  • Show each day's outcome, not just today's streakaddedwhy

    Add a history endpoint that returns each day’s outcome, newest first, so a client can show more than just today’s streak.

  • Send the day's unlock push after a rule edit, by recomputing the verdictfixedwhy

    Fix rule changes to recompute the day’s verdict immediately, so editing a rule after already meeting the goal no longer suppresses that day’s unlock push.

Chrome6 changes

The extension arrives and fails closed

The extension lands with GitHub sign-in and site blocking, a failed sync now locks instead of unlocking, and sync no longer fails to a browser CORS block.

  • Stop re-fetching rules on every routine service-worker wakefixedwhy

    Skip redundant network calls on routine service-worker wakes. Alarm ticks now self-heal the sync schedule locally instead of re-fetching rules and re-registering the installation every time.

  • Add opt-in error and performance reporting, off by default and scrubbedaddedwhy

    Add opt-in error and performance reporting. Off by default, revocable in settings, and scrubbed of URLs and other identifying details before anything leaves the browser.

  • Stop sync and sign-in failing to a browser CORS blocksecuritywhy

    Grant the extension permission to reach the backend API host directly, so sync and sign-in no longer fail to a browser CORS block. Diagnostic trace headers now attach only to backend requests, not to every outgoing call.

  • Stop blocked URLs from sending the block page into a redirect loopfixedwhy

    Share one hostname-parsing helper between declarativeNetRequest and the block page, so a blocked URL can no longer send the block page into an infinite redirect loop.

  • Keep sites blocked when a sync step or a verdict failssecuritywhy

    Make enforcement fail closed. A failed sync step, an unresolved schedule, or an unexpected verdict now locks instead of unlocking, and a push key rotation no longer breaks unlock delivery for good.

  • Block distracting sites in Chrome until the day's goal is hitaddedwhy

    Ship the Chrome extension: sign in with GitHub, sync the day’s Rule, and block distracting sites with declarativeNetRequest until goal is hit. Adds a popup, onboarding flow, and branded block page, backed by a background alarm that keeps enforcement current.

iOS12 changes

Rules gain a scope and a schedule

A rule can now name one repository and a role, scheduled windows lock apps with no GitHub goal at all, and the home screen gains a day-history heatmap.

  • Add crash and error reporting behind a consent toggle in Settingssecuritywhy

    Add crash and error reporting, gated behind a consent toggle in Settings.

  • Switch crash reporting to on by default, with an opt-out toggle in Settingssecuritywhy

    Switch crash and error reporting to on by default, with an opt-out toggle in Settings instead of an opt-in one.

  • Hold the lock through corrupt rule state until a valid fetch replaces itsecuritywhy

    Fix a gap where a failed refresh after corrupt rule state could leave the shield clearable; the shield now stays locked until a valid fetch replaces the corrupt state.

  • Add an Any role that counts a PR or issue whatever your part in it wasaddedwhy

    Add an Any role to the rule role picker, so a rule can count a pull request or issue regardless of whether you authored or merged or closed it.

  • Snap schedule windows to a 15-minute grid so a lock cannot fire latefixedwhy

    Snap scheduled-rule window start and end times to a 15-minute grid so a lock can no longer fire late from a dropped short-interval wake.

  • Unlock a scheduled rule at its window end without opening the appfixedwhy

    Fix scheduled rules staying locked past their window end until the app was opened; background refresh now re-arms the monitor that watches the window.

  • Add a notification when a lock lifts, from a window ending or a goal metaddedwhy

    Add a notification when a lock lifts, whether from a scheduled window ending or a goal being met, so an unlock no longer goes unannounced.

  • Keep rules fresh across the daily reset and time-zone changesfixedwhy

    Fix rule freshness near the daily reset and across time-zone changes by reading the reset instant from the backend instead of recomputing it on device.

  • Add a heatmap of which recent days met their rules or held apps lockedaddedwhy

    Add a day-history heatmap to the home screen, showing which recent days met their rules, held apps locked, or had no active rules.

  • Add scheduled rules that lock apps on a time block, with no GitHub goaladdedwhy

    Add scheduled rules: time-block windows that lock apps on a schedule, independent of any GitHub goal, alongside day-scoped GitHub rules.

  • Rebuild home around what is locked now, your rules, and today's activitychangedwhy

    Rebuild the home screen as a sectioned summary of what’s locked now, your rules, and today’s activity, replacing the streak-first screen.

  • Scope a rule to one repository and to an authored, merged, or either roleaddedwhy

    Scope a rule to one repository and a role, authored, merged, or either, picked from your connected GitHub repositories.

macOS4 changes

The first Mac app arrives with its filter

The menu-bar app lands with a content-filter extension behind it, windows resolve in your stored time zone, and crash reporting arrives with a consent toggle.

  • Add crash and error reporting behind a consent togglesecuritywhy

    Add crash and error reporting to the menu-bar app and the content-filter extension, gated behind a consent toggle.

  • Switch crash reporting to on by default with an opt-out togglesecuritywhy

    Switch the menu-bar app and content-filter extension’s crash reporting to on by default, with an opt-out toggle instead of an opt-in one.

  • Block distracting sites from a new Mac menu-bar app and content filteraddedwhy

    Ship the first macOS app: a menu-bar app backed by a content-filter system extension that blocks distracting sites until the day’s rules are met.

  • Resolve the filter's windows in your stored time zone, not the machine'sfixedwhy

    Fix the content-filter extension resolving schedule windows in the machine’s time zone instead of the stored day-boundary zone.

also this week

  • siteName what Sentry receives in the privacy policy and how to turn it offsecurity

week of jun 22, 2026

backend8 changes

The backend decides, the client renders

Rules arrive with a backend-computed pass-or-hold verdict, GitHub's web authorization flow replaces token sign-in, and pull requests, issues, and reviews start counting.

  • Send account setup to the GitHub org or account owning the app installationaddedwhy

    Add an endpoint that deep-links account setup straight to the GitHub org or account that owns the app installation, instead of sending everyone to their personal installations list where an org install stays invisible.

  • Offer a rule's repo picker only the repos the GitHub App can seeaddedwhy

    Add an endpoint listing the repos a GitHub App installation can actually see, so a rule’s repo picker offers only repos that scoping will work for instead of free-text entry.

  • Count pull requests, issues, and reviews toward the day's goal beside commitsaddedwhy

    Count pull requests, issues, and reviews toward the day’s goal, not just commits. A rule can also narrow which activity counts, to specific repos and to a specific role such as author or reviewer.

  • Restrict counted commits to a repo's default branch in a non-fork repofixedwhy

    Restrict counted commits to pushes on a repo’s default branch (or gh-pages) in a non-fork repo, matching GitHub’s own contribution-graph definition. A commit on a feature branch or in a fork no longer counts toward the day’s goal.

  • Show today's already-logged activity on a new or edited rule right awayfixedwhy

    Fix a newly created or edited rule to reflect today’s already-logged activity right away, instead of showing empty progress until the next refresh. The rules list also now shows today’s real streak instead of zero when today hasn’t been recomputed yet.

  • Add rules that set a GitHub activity target, then edit or delete themaddedwhy

    Add rules: set a GitHub activity target, then create, edit, or delete it going forward. The backend now computes the day’s pass-or-hold verdict itself, with a step-by-step progress breakdown, instead of leaving that logic to the client.

  • Require every enabled rule to be met before the streak counts the dayfixedwhy

    Fix the streak to require every enabled rule to be met, not just one, and to carry through a day with no enabled rules instead of breaking it.

  • Replace personal-access-token sign-in with GitHub's web authorization flowchangedwhy

    Replace personal-access-token sign-in with GitHub’s own authorization-code web flow. A session now refreshes automatically in the background, and replaying an already-used refresh token revokes the whole session instead of quietly succeeding.

iOS10 changes

The iPhone unlocks without being opened

A background re-check and silent push unlock apps once GitHub activity clears the goal, GitHub's web sign-in replaces pasted tokens, and setup becomes a first-run flow.

  • Replace the single daily gate with a list of rules you can edit and disablechangedwhy

    Replace the single daily gate with rules: a list you can create, edit, enable, disable, and delete, each showing its own progress toward being lifted.

  • Sign in through GitHub's own web flow, so the token never touches the devicechangedwhy

    Replace personal-access-token sign-in with GitHub’s own web sign-in flow; the GitHub token never touches the device.

  • Add a first-run setup flow in place of the hidden Settings-only setupaddedwhy

    Add a first-run onboarding flow: connect GitHub, set a ship goal, pick distracting apps, and finish, replacing the hidden Settings-only setup.

  • Unlock a goal met while the app is closed, with no manual re-checkchangedwhy

    Move gate state onto the backend and add silent push, so a goal met while the app is closed unlocks without waiting on a manual re-check.

  • Re-arm the lock once on save instead of on every tap of the goal stepperfixedwhy

    Fix the daily-goal stepper in Settings re-arming the shield on every tap; the shield now re-arms once, when the change is saved.

  • Count merged PRs and closed issues instead of reading them as zerofixedwhy

    Fix merged-PR and issue-closed activity that was hardcoded to zero, so a goal set on either signal could actually be met.

  • Make Re-check now clear the lock from the lock screen, even with the app closedfixedwhy

    Fix the shield’s Re-check now button so it re-checks GitHub from the lock screen itself and clears the lock the moment the goal is met, even with the app closed.

  • Add a one-time notification the first time today's goal is metaddedwhy

    Add a notification when a background re-check first finds today’s goal met, firing only on the not-met-to-met flip so it never repeats.

  • Add a daily goal that unlocks apps on its own once GitHub activity clears itaddedwhy

    Add a settable daily goal in Settings and a background re-check that unlocks apps on its own once GitHub activity clears the goal.

  • Keep apps locked on stale or unreadable progress instead of assuming a met goalsecuritywhy

    Lock the shield closed on stale or unreadable progress instead of assuming the goal is met, with lock enforcement centralized to one path.

$ page 4 of 5