Files on Android: set up, unlock, browse, add, folders, delete, promote #79

Merged
paulhitt merged 1 commits from feat/files-screen into main 2026-09-04 20:49:59 +00:00
paulhitt commented 2026-09-04 19:22:58 +00:00 (Migrated from gitlab.com)

The screen, the Storage Access Framework resolver behind
LocalVault.ReferenceResolver, and the passphrase-protected identity the
vault opens under.

Android asks for a Files passphrase, as iOS does, and that was a
decision rather than a port.
The Android wallet sits behind the
Keystore-sealed vault alone, so an unlocked phone opens it. Files does
not: the identity record is encrypted under a key stretched from a
passphrase this app deliberately keeps no copy of, with the Keystore seal
around it as the second layer. Dropping the inner one for convenience
would be a real reduction and not a refactor — a vault that opens because
the phone is open is a folder with a lock drawn on it.

OpenDocument, never GetContent. GetContent hands back a URI
whose read grant dies with the process, so a linked file works for the
rest of the session and is broken on the next launch — and whoever added
it watched it work. filesReference REFUSES when the grant cannot be
persisted and offers to copy the file in instead, rather than filing a row
that will be dead tomorrow.

Locking drops the identity; it does not hide a screen. The open
vault is a field, deliberately not part of FilesState — a state object
gets logged, compared and copied into recompositions, none of which should
ever have a private key in it.

The classification ordinals are pinned by a change-detector test, on
purpose: the NUMBER travels with a file and the word is only how it is
drawn, so renumbering them would file a Restricted document as Internal on
the other phone with nothing erroring and neither screen looking wrong.

Not yet run on a device. The machine was carrying an iOS simulator
at 99% CPU on 8 cores, and booting an emulator on top of that produces a
flaky run rather than evidence. Two things need a real device before this
is done: the SAF picker with its persistable grant, and whether a linked
file still reads after a reboot. Neither can be faked on the JVM.

Files is its own destination, not a section of the wallet. They share an
unlock, which is true and is an implementation detail; iOS grouped them
once and what it produced was somebody pressing "wallet" and arriving at a
file list.

Full build and all JVM suites green.

Co-Authored-By: Claude Opus 5 noreply@anthropic.com

The screen, the Storage Access Framework resolver behind `LocalVault.ReferenceResolver`, and the passphrase-protected identity the vault opens under. **Android asks for a Files passphrase, as iOS does, and that was a decision rather than a port.** The Android wallet sits behind the Keystore-sealed vault alone, so an unlocked phone opens it. Files does not: the identity record is encrypted under a key stretched from a passphrase this app deliberately keeps no copy of, with the Keystore seal around it as the second layer. Dropping the inner one for convenience would be a real reduction and not a refactor — a vault that opens because the phone is open is a folder with a lock drawn on it. **`OpenDocument`, never `GetContent`.** `GetContent` hands back a URI whose read grant dies with the process, so a linked file works for the rest of the session and is broken on the next launch — and whoever added it watched it work. `filesReference` REFUSES when the grant cannot be persisted and offers to copy the file in instead, rather than filing a row that will be dead tomorrow. **Locking drops the identity; it does not hide a screen.** The open vault is a field, deliberately not part of `FilesState` — a state object gets logged, compared and copied into recompositions, none of which should ever have a private key in it. The classification ordinals are pinned by a change-detector test, on purpose: the NUMBER travels with a file and the word is only how it is drawn, so renumbering them would file a Restricted document as Internal on the other phone with nothing erroring and neither screen looking wrong. **Not yet run on a device.** The machine was carrying an iOS simulator at 99% CPU on 8 cores, and booting an emulator on top of that produces a flaky run rather than evidence. Two things need a real device before this is done: the SAF picker with its persistable grant, and whether a linked file still reads after a reboot. Neither can be faked on the JVM. Files is its own destination, not a section of the wallet. They share an unlock, which is true and is an implementation detail; iOS grouped them once and what it produced was somebody pressing "wallet" and arriving at a file list. Full build and all JVM suites green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
paulhitt commented 2026-09-04 19:22:58 +00:00 (Migrated from gitlab.com)

assigned to @paulhitt

assigned to @paulhitt
paulhitt commented 2026-09-04 20:49:57 +00:00 (Migrated from gitlab.com)

deleted the feat/files-local-vault branch. This merge request now targets the main branch

deleted the `feat/files-local-vault` branch. This merge request now targets the `main` branch
paulhitt (Migrated from gitlab.com) merged commit 730a40141d into main 2026-09-04 20:49:59 +00:00
paulhitt commented 2026-09-04 20:50:00 +00:00 (Migrated from gitlab.com)

mentioned in commit 730a40141d

mentioned in commit 730a40141dcdb63e0896b692ceb8128bf5e5a008
paulhitt commented 2026-09-09 19:01:27 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
Sign in to join this conversation.