Repository navigation
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Fixes ryanbr#2720
Upstream issue: ryanbr#2720 (open; 0 comments).
A fresh Apple
.noopbakrestore recovers raw samples and the deleted sleep row's absence, but not the suppression tombstone. A later detection pass can recreate the deliberately deleted night. The issue reproduces this with synthetic data and no physical strap.Root cause
At verified
kvnloo/noop:main == ryanbr/noop:main2a1de7609843b095505274ad6fc811757210be80:Strand/Data/Repository.swift:1688-1709keeps the globalsleep.dismissedSessionstombstones inUserDefaults, outside the backed-up GRDB SQLite file. Apple deleted-night list visibility uses the separatesleep.dismissedSessions.hiddenFromListdefaults key (the subject of ongoing upstream PR sleep: list deleted nights on iOS and macOS, with recompute and hide ryanbr/noop#2660).Strand/Data/DataBackup.swift:225-279,284-298archives only SQLite, optional whitelistedsettings.json, andmanifest.json;Strand/Data/DataBackup.swift:548-568reapplies only whitelisted settings. The tombstone keys are intentionally absent fromPackages/WhoopStore/Sources/WhoopStore/BackupSettings.swift.android/app/src/main/java/com/noop/data/Entities.kt:585-595persists device-scopeddismissedSleeprows (includingmanagementVisible) inside Room. Its whole-databaseandroid/app/src/main/java/com/noop/data/DataBackup.kt:297-305export already carries them.Change
sleep-deletions.jsonZIP entry even when no profile settings exist, recordingversion: 1,scope: "global", canonicalstartTs:endTssuppression spans andhiddenFromListtokens. This preserves Apple global/id-free semantics without fabricating Android device IDs or changing the cross-platformsettings.jsonwhitelist.Tests
UNRUN. No CI/workflow dispatch; GitHub Actions is disabled in
kvnloo/noop. Five new real-ZIP/XCTest regressions inStrandTests/BackupSyncRoundTripTests.swift:testDeletedSleepMarkersAndVisibilitySurviveFreshRestore— two deletions and one hidden entry survive fresh defaults/SQLite restore; marker-only ZIP is independent ofsettings.json.testExplicitEmptyDeletionSnapshotClearsExistingSuppression— both old lists become empty.testLegacyBackupWithoutDeletionMetadataDoesNotClearExistingSuppression— old ZIP does not mutate existing defaults.testMalformedDeletionMetadataRejectsRestoreBeforeDatabaseSwap— an invalid marker rejects and preserves exact DB bytes/defaults.testOversizedDeletionMetadataRejectsWithoutOversizeOverride— 131,073 > 131,072 bytes fails even withallowOversize=true, preserving DB/defaults.Hand-checked oracles:
1,700,000,000:1,700,028,800is 28,800 seconds = 8 h. Candidate[1,700,010,000,1,700,013,600)overlaps that span;[1,700,200,000,1,700,203,600)does not. Two markers, one hidden → two suppression windows and one hidden management entry after fresh restore; an explicitly empty list → zero. Header/DB integrity tests remain in the existing suite. Tests are not claimed to pass.Hermes/macOS runner command on this exact head:
Then run the full
Strandtests and AppleNOOPiOSbuild. CI run link: not run.Exact path-triggered upstream jobs:
App build (macOS + iOS) / build (Strand, …),App build (macOS + iOS) / build (NOOPiOS, …),i18n Coverage / check,Source Hygiene / doc-comments, andTools Python CI / linux-capture. Not Android CI or Swift Packages CI (no matching path change).Hardware needed
No strap required for the pure archival fix or synthetic regressions. After head-exact automated checks, test an Apple fresh-install export/restore with a real deleted night and the next detection pass on macOS/iOS; check the management list after upstream #2660 is resolved. No BLE bytes changed.
Upstream readiness
DRAFT / HOLD, not green or approved. Before promotion: Hermes runs the exact-head suites above, independently reviews container/restore semantics, verifies on-device restore/relaunch and reconciles the adjacent open #2660 changes. No upstream issue/PR/comment/reaction/review was made; no merge or default/channel branch writes. Only this branch and fork Draft PR are in scope.
Implemented by ChatGPT (mobile app, GitHub connector) for Kevin's NOOP factory.