Skip to content

Fix Swift SleepStagerV2 shuffled-input clipping - #1456

Merged
ryanbr merged 1 commit into
ryanbr:mainfrom
bhelm:fix/sleep-v2-sort-before-clip
Aug 19, 2026
Merged

ryanbr merged 1 commit into
ryanbr:mainfrom
bhelm:fix/sleep-v2-sort-before-clip

Conversation

@bhelm

@bhelm bhelm commented Aug 19, 2026

Copy link
Copy Markdown

What this PR does

Makes the Swift public SleepStagerV2.stageSession establish stable timestamp order before binary-search clipping, matching the Kotlin twin. Already-monotonic streams keep the allocation-free fast path; only genuinely shuffled inputs allocate a stable reorder. The uncached recipe consumes the already-ordered clipped streams directly, preserving same-second emission order.

Permanent mirrored native tests cover deterministic shuffled streams, freeze the existing sorted-input result, and use cache-isolated translated windows to prove two order-sensitive same-timestamp gravity outcomes remain distinct while timestamp-group shuffling preserves each outcome. Padding constants and the parity rollout harness are unchanged.

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation
  • CI / tooling

How it was tested

  • RED on unchanged 6df88d0d: the permanent Swift shuffled-input regression failed with sorted all-light versus shuffled light+REM.
  • RED mutation check: a legal unstable same-timestamp tie reorder made both retained-signal oracle runs change from wake to light.
  • Final focused Swift public outcome regression: passed.
  • Final mirrored Kotlin public outcome regression: passed with JDK 17, one worker, Kotlin compilation in-process, and parallelism disabled.
  • Production-identical full StrandAnalytics suite: 1,439 tests executed, 2 skipped, 0 failures.
  • Production-identical full Android :app:testFullDebugUnitTest: passed.
  • Clean current-main Kotlin SleepStagerV2Test: passed under the same resource limits.
  • Clean current-main Swift test invocation is presently blocked before test execution by the unrelated Linux baseline import of the Apple-only Compression module in WhoopStore/RawOutbox.swift; the fork full Swift suite and focused final Swift regression are green.
  • Range-diff from the reviewed fork commit to current main differs only in the already-landed Fix sleep cache gravity fingerprint collisions #1453 gravity-fingerprint context; behavior and tests are unchanged.
  • Parity ratchet against the exact fork base: 59 differential, 2,605 exempt, 0 errors.
  • Independent final delta review: no P0/P1/P2 findings.
  • No manual or hardware testing required: this changes pure sleep analytics ordering only.

Checklist

  • Swift package tests pass for any package I touched (swift test in Packages/<name>)
  • Android unit tests pass if I touched android/ (./gradlew testFullDebugUnitTest)
  • No new build warnings introduced
  • UI changes use only StrandDesign tokens — no hardcoded colors, fonts, or spacing
  • No hardcoded hex frame bytes; protocol facts live in the schema / decoders
  • Follows the conventions in docs/CONTRIBUTING.md
  • I did not commit generated output (Strand.xcodeproj/) or any secrets/keystores

Related issues

Tracked in bhelm#67.

@ryanbr
ryanbr merged commit 82bfd3d into ryanbr:main Aug 19, 2026
16 checks passed
@bhelm
bhelm deleted the fix/sleep-v2-sort-before-clip branch September 15, 2026 22:35
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.

2 participants