Local storage
Visit records, duration measurements, and settings are held in the extension's own local storage. None of this data leaves the device unless SELFLEX Sync is enabled.
background.js · storage.localThis document defines what data leaves the device when SELFLEX Sync is enabled, the stages that data passes through, and who is able to access it. Each statement is accompanied by its counterpart in the source code.
The six stages below are the order the code follows in the published 1.4.5 release. The relevant source file is listed against each stage.
Visit records, duration measurements, and settings are held in the extension's own local storage. None of this data leaves the device unless SELFLEX Sync is enabled.
background.js · storage.localEach data group is governed by an independent permission and all groups are disabled by default. Data belonging to a disabled group is never written into the payload; it is not filtered out afterwards.
background.js · syncEnabledGroups()The selected records are assembled into a single JSON block and compressed with zlib. A 5,000-visit log measured 1.4 MB before compression and 128 KB after.
SelflexSyncEngine.swift · packed()The block is written into CloudKit's encrypted field before any network request begins. The encryption key is held in the iCloud Keychain and does not leave the user's devices.
record.encryptedValues["payload"]Records are written to a dedicated zone within the private iCloud database of the user's own Apple account, not to a SELFLEX server.
privateCloudDatabase · dedicated zoneAn authorised device decrypts the block and merges the records by identifier. Each device writes only to its own record, so no device supersedes another's data.
visits-<device id> · union mergeNone of the stages above involves a SELFLEX server. There is no SELFLEX account system, no user database, and no intermediary service through which the records pass. This is not a component that was later disabled, but one that was never built.
Access is assessed separately for three parties. Because the phrase “nobody can access it” would be incomplete on its own, the scope and the limit applying to each party are stated individually.
Records are held in the private iCloud database of the user's Apple account. An application developer holds no access rights to users' private databases; the developer console displays data belonging only to the developer's own account.
No second copy exists to be read either: SELFLEX operates no server, no telemetry infrastructure, and no analytics.The payload is encrypted on the device before it is written to iCloud, and the encryption key remains in the iCloud Keychain. Apple cannot decrypt the encrypted field or run queries against it.
Limit to be noted: Apple can see that SELFLEX records exist in the account, along with the time and size of those writes.Records can be decrypted only on devices signed into the same Apple account. The user determines which groups are enabled, and that preference is held separately for each device.
Synchronisation can be disabled at any time, and the cloud copy can be deleted in a single operation.All six groups are disabled following installation. Enabling synchronisation does not upload existing records; each group must be enabled separately.
settingsSettings and appearanceTheme, daily goals, privacy switches, and dashboard preferences.
DisabledcategoriesCustom categoriesCategory names and domain rules defined by the user.
DisabledexcludedExcluded sitesDomains removed from measurement, together with their deletion records.
DisabledvisitsVisit recordsDomain, category, duration, and timestamp. Last 30 days, 5,000 records maximum.
DisabledtitlesPage titlesThe title and full address of the visited page.
DisabledqueriesSearch queriesThe text entered into a search engine.
DisabledWhere visit records are enabled and page titles are left disabled, the address written into the payload is reduced to https://example.com/; the path, query string, and title are never written. This is not a display restriction — the data is produced in that form, so the copy transferred to iCloud never contained those fields.
The five behaviours below are structural properties of the application rather than editable preferences. The file and function names given are the actual names in the application source.
The enabled groups are re-read on every transfer and no payload is produced for a disabled group. The restriction is applied while the data is assembled, not in the interface.
background.js · runSyncPush()The block is stored in CloudKit's encrypted field rather than a plain one. Encrypted fields cannot be decrypted server-side and cannot be queried.
SelflexSyncEngine.swift · encryptedValuesThe identifier used to separate records is a random UUID; it is not a device name, serial number, or hardware identifier. The payload carries only a device kind such as “mac” or “ipad”.
SelflexSyncEngine.swift · deviceIdWhile the page-titles group is disabled, the full address is never written into the payload; the address is reduced to the bare domain. This is a restriction on the data itself, not a hidden interface field.
background.js · visitsForSync()Deletion does not clear records individually; it removes the entire zone allocated to SELFLEX. Once the zone is removed, every record within it ceases to exist.
SelflexSyncEngine.swift · wipe()When SELFLEX Sync is enabled, data does leave the device. The statement made in this document is not that the data remains stationary, but that the location it moves to is one SELFLEX cannot read. The following limits fall outside the scope of that statement:
Precise statement: when SELFLEX Sync is enabled, data leaves the device; it is not, however, transferred to any location accessible to SELFLEX, to advertising networks, or to any analytics provider.
The three checks below can be carried out on the user's own device without any developer tooling.
iCloud.SELFLEX Sync in the search field.A verifiable inconsistency report is worth more than any promotional claim.