The recovery manual
This manual is for the person holding the phone, not for the person who wrote the code. It covers the Android app, the macOS companion and the Windows companion.
State of this manual: reconciled against the frozen UI at commit 8e637cb
(Android app 0.3.0, desktop companion 1.0.0) on 2026-10-13. Every step below was
checked against the UI source in app/src/main/kotlin/.../ui/ and
desktop/src/main/kotlin/.../ui/; the per-row record is
.orchestration/evidence/T4/manual-to-ui-audit-checklist.md (kept out of the
repository with the other raw evidence). External facts are traceable through
../SOURCES.md, the committed source register.
This manual is text only, and that is now a choice rather than a limit. The
Android screens can be captured at any time with
bash scripts/capture-screenshots.sh, which renders the running app's window on
whatever device is attached and writes into design/screenshots/. The three
captures used for the Play listing live there. They are not embedded here
because a manual that has to be regenerated whenever a button moves ages badly;
the labels are quoted verbatim instead, and
scripts/capture-screenshots.sh will show the current UI in seconds.
Where a description could not be checked against a running build, it is labelled "not re-run" rather than left to read as if it had been.
What is implemented, verified and not
Checked against the frozen source; the evidence column names what proves it.
| Behaviour | Chapter | State | Evidence |
|---|---|---|---|
| SAF folder grant, persisted across restarts | 06 | Implemented | SafStorage.persistReadWriteGrant; the app logs "Folder access granted" or a session-only warning |
| Discovery scan of the granted folder with candidate list | 06 | Implemented | CandidateScanner; instrumented test RecoveryWorkflowInstrumentedTest.discoveryFindsLeftoversAndArbitraryFilesInAGrantedTree (passes on device) |
| Container inspection before repair | 06 | Implemented | "Inspect" button; ContainerInspector |
| Repair of an interrupted recording | 06 | Implemented | Engine tests plus the on-device end-to-end test aRealBrokenRecordingIsRepairedWithPlayableVideoAndNonSilentAudio |
| Automatic audio recovery on the phone | 07 | Implemented and measured on device | MediaCodec decoded 88 of 88 AAC frames from one unframed buffer (Galaxy S25 Ultra, SM-S938B, Android 16, codec c2.android.aac.decoder; HISTORY.md, 2026-10-12) |
| Manual alignment (signed offset) and imported-audio fallback | 07 | Implemented | Alignment preview with muted video; AlignmentPlayback unit tests; engine edit-list offset tests |
| Export to a user-chosen folder, hash-verified, never overwriting | 06 | Implemented | "Export folder" + "Export repaired"; ByteExporter; instrumented tests verify both hashes and a refused overwrite |
| Cancel during scan, repair and export | 06 | Implemented | "Cancel" in the work banner; cancelled export leaves nothing behind (instrumented test) |
| Progress: bytes processed while the work runs | 06 | Implemented, no percentage or ETA | Work banner shows a spinner, a stage label and "N / M bytes" |
| Repair surviving backgrounding behind a notification | 06 | Not implemented. Keep the app in the foreground | No service in AndroidManifest.xml; HISTORY.md lists a foreground service as an open item |
| In-app whole-file decode verification as a result screen | 06 | Not implemented as a screen. The app reports the engine's real numbers in the activity log; full decode verification runs in the automated device test | describe(result) prints frame count, duration, audio frames, SHA-256 and warnings; the end-to-end instrumented test decodes the output |
| Reference recording matched automatically against the broken file | 06 | Not implemented. The app takes the recording you mark and reports what the engine did with it | useSelectedAsReference; no codec/resolution match check in the view model |
| Saving to the gallery through MediaStore | 06 | Not implemented, and not planned as the primary path. Export goes to a folder you choose | RecoverTab "Export folder"; no MediaStore reference in the app |
| A rewarded ad before the repaired file is exported | 06 | No production ad unit is configured in this build, so the ad surface reports itself unavailable and export is never blocked. When a unit is configured, one rewarded ad is offered and skipping still exports | RewardedAdGate; release builds with a blank unit id fail closed; AdPolicy.BEST_EFFORT |
| Anonymous analytics | 06 | No analytics backend is configured. The consent gate is implemented and fails closed; with no Firebase project the sink is a no-op | FirebaseTelemetrySink.create -> NullTelemetrySink; TelemetryGate blocks unset/denied |
Read in this order
| Chapter | Read it when |
|---|---|
| 01 Getting started on macOS | You have a Mac and a phone |
| 02 Getting started on Windows | You have a Windows PC and a phone |
| 03 Enabling USB debugging | You have never enabled Developer options |
| 04 Wireless ADB | The cable will not work, or the port is damaged |
| 05 USB connection problems | The computer does not see the phone |
| 06 The repair workflow | Ready to actually recover a recording |
| 07 Audio alignment | The video is back but the sound is wrong |
| 08 What this cannot do | Before you believe any recovery claim |
| 09 Troubleshooting appendix | Something printed an error and you want the fix |
Brand-specific steps (where the menu item lives, which vendor switch to flip,
where to get the USB driver) are in ../brand-guides/.
The one-minute version
- Install the companion (desktop) or the app (phone), or both. The desktop companions are the more complete path today.
- On the phone, enable Developer options and USB debugging (chapter 03).
- Plug the phone in, unlock it, and accept the "Allow USB debugging?" prompt.
- In the app, choose the broken recording. Choose any working recording from the same phone as the reference. Start the repair.
- Check the result, then save it. The app always saves a new file and never modifies the original.
Two words that cause most disappointment
- Undelete. This product cannot bring back a deleted file without root. Chapter 08 explains why in plain language. If a recovery tool claims it can, check what it actually returned.
- Overwritten. Once new data has been written over the space a file used, the original bytes are gone. No tool recovers them, with or without root.
Safety
- Repairing never writes to the original file. Keep that guarantee: if a step in the UI offers to modify the original in place, do not accept it and report it as a defect.
- Keep the phone charged while recovering a large recording. A phone that dies mid-way keeps the original file intact, but nothing else gets done.
- Do not factory reset, wipe, or "clean" the phone while trying to recover something. Those actions overwrite the space that recovery would need.