Build1 publisher3 min readPublished
Phone backup can put deleted voice transcripts back after a clean rollback
A dev.to workflow post argues that the first PR persisting a voice session should not merge until someone has proved the transcript file is excluded from iCloud or Google backup and that a restore cannot recreate it.
The Engineer · Build desk

What happened
- A dev.to post sets out a proposed first-hour workflow for a junior engineer joining a mobile AI repo: treat backup exclusion as a merge gate, then rehearse a restore after the PR is rolled back.
- The local store that offline replay grows holds utterances, partial captions and sometimes speaker labels, and phone backup is an OS mechanism that can copy those files while the app is backgrounded or after it is uninstalled.
- Its placement advice is to keep the SQLite file in Application Support and set the exclusion flag on the file URL, because the system counts Documents as user data and therefore a backup candidate.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- decision The merge now turns on a question the ticket never asked, namely which OS transport uploads this path. A reviewer who cannot answer it holds the cache back and writes the limitation into the PR.
- exposure The person exposed is the user whose speech the rollback was supposed to delete. A restore can put utterances and speaker labels onto a device the team already signed off as clean.
- constraint Clearing the gate takes more than a log. It needs a physical device in a recorded network and power state, since transports wait for unmetered links and daemons defer under energy pressure.
- precedent If generated persistence code reaches for the convenient directory, then the file path becomes a standing review item on every patch that writes to disk, alongside the schema.
The exclusion flag in the Swift sample is a resource value set on the file URL, after the store already exists: the snippet creates the Application Support root, makes a `voice-replay` directory, appends `transcripts.sqlite`, then sets `isExcludedFromBackup` through a throwing `setResourceValues` call [15]. The post's order is write first, call `excludeFromBackup()` after the first successful write, then read the flag back [16]. Two separate code paths, one file. The read-back checks that the flag landed on the file the app actually opens.
The directory the file sits in decides whether backup uploads it. Documents is user data from the system's point of view, which makes it a backup candidate even when the app treats it as a cache [13]. Caches is the wrong home for replay that must survive a cold start, because the system can purge it under storage pressure [14]. The post calls Application Support plus an explicit exclusion "the usual honest compromise" [14].
The post's assumption is that AI-drafted persistence will pick a convenient directory unless constrained, and that the convenient directories are the ones backup systems already know how to upload [6].
Verification is a device loop. Six steps run on one physical device, and inside them sit two backup triggers and one restore: trigger backup and inspect the contents or exclusion flags, revert or uninstall, restore onto the same device, open the app cold, then grant and revoke microphone permission once and repeat the backup, because some queues rewrite the store on denial [11][17]. Only three outcomes count as results: recovered, restarted empty, or silently disappeared [12]. The seven-field block above it wants the device and OS named to the level of Pixel 8a / Android 15 or iPhone 14 / iOS 18.6 [18][19].
Network and power are in that block because some backup transports wait for unmetered links, and backup daemons defer work under energy pressure [8]. A test that ran on cellular with battery saver on can produce an empty backup and a green PR.
The post labels the checklist unexecuted until it runs on one physical device and says to leave the blanks until a device answers [10]. So the failure it describes rests on how OS backup works rather than on a reported run: phone backup is an OS mechanism, separate from product sync, and it can copy files while the app is backgrounded or after it is uninstalled [4]. For that to reach your repo, three things have to hold. The store has to land in Documents, shared storage, or a default database path [5]. The transport has to have run before the rollback [8]. The restore has to target a device where the app is installed again [11].
The post is direct about the gate: "If you cannot name the OS backup transport, you are not ready to merge the cache." [9]
What to watch
- Whether the author publishes a filled-in run: named device, OS, backup transport, and which of the three outcomes the restore produced.
- Whether an Android procedure follows; the published sample covers only the iOS file URL flag while the risk is stated for Google backup too.
- Whether the microphone permission round trip really rewrites the store on denial, which the post gives as its reason to repeat the backup.