Skip to content

daycycle: drop the reliableAwakeCoverage parameter nothing reads (#1572 follow-up) - #1887

Merged
ryanbr merged 3 commits into
mainfrom
chore/1572-drop-unused-awake-coverage
Sep 5, 2026
Merged

ryanbr merged 3 commits into
mainfrom
chore/1572-drop-unused-awake-coverage

Conversation

@ryanbr

@ryanbr ryanbr commented Sep 5, 2026 •

Copy link
Copy Markdown
Owner

Cleanup on top of #1572, found while reviewing it. Nothing here changes a window boundary.

A parameter nothing reads

DayCycleResolver.activeWindow took reliableAwakeCoverage on both platforms. Neither body referenced it, and every call site — both production ones and all the tests — passed a constant. It is the residue of an earlier design that gated staying-open-across-midnight on whether awake coverage was reliable; the gate was dropped and the parameter was not.

Left in, it reads like a working switch, so the next caller to pass true would get silence.

Why it survived

Two Kotlin cases asserted a distinction the code never made:

  • reliableAllNighterStaysOpenUntilTheAbsoluteCap passed true
  • missingCoverageKeepsSleepOnsetCycleOpenAcrossMidnight passed false

Both would have passed either way. Renamed to what they actually pin (allNighterStaysOpenUntilTheAbsoluteCap, sleepOnsetCycleStaysOpenAcrossMidnight), with the Swift twin renamed to match.

A fallback branch neither platform reached

My first attempt at this was wrong, and re-review caught it. I added a Swift case asserting a 23:00 onset resolves to 2 * 86_400 — but the existing testSleepOnsetCycleStaysOpenAcrossMidnight already asserted that exact value through that exact branch from a 20:00 onset. It was a vacuous test. I had matched case counts across the platforms and called that parity, which is not the same as matching what they reach.

The branch neither platform reached is the other one. fallbackMidnightAfter picks floorDiv(minimum, day) * day, which is at or below minimum always — so atMidnight >= minimum is true only on exact equality, when onset sits precisely 18 h before a midnight. Every case on both platforms used an onset that rolls past it.

A >= quietly weakened to > would therefore have moved that boundary a full day with nothing failing. Verified rather than argued: mutating >= to > fails the new case and only the new case — the five existing ones, including the 23:00 roll, stay green.

Both platforms now pin both branches, with the rolling case kept at an onset distinct from the direct one so the pair are not the same test twice.

A boundary nothing said was local

Every day-cycle case on both platforms passed a zero timezone offset, so the offset arithmetic — the part that decides which local day a boundary lands on — was pinned by nothing. That is the one input this repo has already been bitten by, when recent nights re-bucketed on travel.

The two implementations do agree today: Swift's Int(floor(Double(local) / Double(day))) and Kotlin's Math.floorDiv(local, day) return identical answers across every offset from UTC-12 to UTC+13 and every onset hour across two days. Nothing recorded that agreement; now a case does.

06:00 local at UTC-5 is 11:00 UTC; plus 18 h is 05:00 UTC the next day, which is local midnight there, so the direct branch takes it and the answer is 104_400 — 29 h UTC, 00:00 local. A resolver that floored to UTC midnight would answer 86_400 and be a full day out for a third of the planet.

Verified the same way: dropping the offset term so the resolver floors to UTC midnight fails the new case and only the new case. All six existing cases stay green — the evidence that they were blind to the offset entirely.

Verification

  • Android full suite 5251 tests, 0 failures (--rerun-tasks --no-build-cache, result-XML timestamps checked).
  • Both platforms compile; doc-comment lint and i18n audit clean; no schema change.
  • Both new expectations were derived by re-implementing fallbackMidnight's arithmetic independently rather than copying a constant across.

A note for the record: the Kotlin test call sites passed the flag positionally, so a search for the parameter name did not find them and the first build failed on four call sites a name-grep had missed.

… follow-up)

`DayCycleResolver.activeWindow` took a `reliableAwakeCoverage` flag on both platforms. Neither body
referenced it, and every call site — both production ones and all the tests — passed a constant. It
is the residue of an earlier design that gated staying-open-across-midnight on whether awake coverage
was reliable; the gate was dropped and the parameter was not.

Left in, it reads like a working switch, so the next caller to pass `true` would get silence.

Two of the Kotlin cases are why it survived: `reliableAllNighterStaysOpenUntilTheAbsoluteCap` passed
`true` and `missingCoverageKeepsSleepOnsetCycleOpenAcrossMidnight` passed `false`, so their names
asserted a distinction the code never made and both would have passed either way. Renamed to what
they actually pin, and the Swift twin renamed to match.

Also adds the one resolver case Apple was missing: the 18-hour fallback rule. It is a shared numeric
contract with a branch that is easy to get subtly wrong — the first midnight at least
`minSyntheticMidnightAgeSeconds` after onset, rolling to the NEXT one when that midnight falls short
— and only Kotlin pinned it. A 23:00 onset exercises the roll. The two resolver suites now carry the
same five cases.

Found while reviewing #1572, which is already merged; this is cleanup on top rather than a change to
its behaviour. Nothing here alters a window boundary: the parameter was inert.
…low-up)

Re-review of the previous commit, which claimed to add "the one resolver case Apple was missing".
That claim was wrong and the test was vacuous: it asserted a 23:00 onset resolves to 2 * 86_400, and
the existing `testSleepOnsetCycleStaysOpenAcrossMidnight` already asserted exactly that value through
exactly that branch from a 20:00 onset. I had matched case COUNTS across the platforms and called it
parity, which is not the same thing as matching what they reach.

The branch neither platform reached is the other one. `fallbackMidnightAfter` picks
`floorDiv(minimum, day) * day`, which is at or BELOW `minimum` always, so `atMidnight >= minimum` is
true only on exact equality — when onset sits precisely 18 h before a midnight. Every case on both
platforms used an onset that rolls past it.

So a `>=` quietly weakened to `>` would have moved that boundary a full day with nothing failing.
Verified rather than argued: mutating `>=` to `>` fails the new case and ONLY the new case; the five
existing ones, including the 23:00 roll, stay green.

Both platforms now pin both branches, with the rolling case kept at an onset distinct from the
direct one so the pair are not the same test twice.
…follow-up)

Re-review pass three. Every day-cycle case on both platforms passed a zero timezone offset, so the
offset arithmetic — the part that decides which LOCAL day a boundary lands on — was pinned by
nothing at all. That is the one input this repo has already been bitten by, when recent nights
re-bucketed on travel.

The two implementations do agree today: Swift's `Int(floor(Double(local) / Double(day)))` and
Kotlin's `Math.floorDiv(local, day)` return identical answers across every offset from UTC-12 to
UTC+13 and every onset hour across two days. Nothing recorded that agreement, though, and the
resolver now carries a case that does.

06:00 local at UTC-5 is 11:00 UTC; plus 18 h is 05:00 UTC the next day, which IS local midnight
there, so the direct branch takes it and the answer is 104_400 — 29 h UTC, 00:00 local. A resolver
that floored to UTC midnight would answer 86_400 and be a full day out for a third of the planet.

Verified rather than argued, as with the previous commit: dropping the offset term so the resolver
floors to UTC midnight fails the new case and ONLY the new case. All six existing cases stay green,
which is the evidence that they were blind to the offset entirely.
@ryanbr
ryanbr merged commit b3f8333 into main Sep 5, 2026
15 checks passed
@ryanbr
ryanbr deleted the chore/1572-drop-unused-awake-coverage branch September 5, 2026 02:40
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