Share a file into a chat, and save one back — with the label it carries #80

Merged
paulhitt merged 1 commits from feat/files-share-into-chat into main 2026-09-04 20:50:12 +00:00
paulhitt commented 2026-09-04 19:34:31 +00:00 (Migrated from gitlab.com)

Both directions: pick a document from the vault inside a conversation, and
save a received one into the vault at the classification it arrived with.

This is the answer to android#15, and the codebase had already given
it.
Attachment.FILE has carried this since before the lattice existed:
the label is a MARKING, not a permission — the content key is in the same
envelope, so whoever can read the message can read the file.
That settles
the ★-property question. The key travels with the file by design, because
that is what makes sending work at all; there is no trusted computing base
to enforce against, since the person holds every key on a device they
control. A client-side refusal would be a suggestion, and a suggestion
dressed as a control is worse than none
— it is the one people plan
around.

So neither client implements the ★-property, LabelTest keeps asserting
that absence, and PARITY.md now says plainly that Files is not mandatory
access control. What it IS: cryptographic read separation, plus a
classification that travels. The picker says so before the tap, in those
words.

Three things found on the way:

A second copy of the vocabulary. classificationName in
ChatScreens listed the same four names as FileLevels, agreeing by
coincidence with nothing making them agree. Rename a level for the Files
screen and the chat bubble keeps showing the old word for the same number,
in the same conversation, on the same phone. Collapsed to one.

Attach and Camera did the same thing. Both launched the gallery, and
there was no way to send a document at all. Attach now opens a small panel
— photo, or from Files — which keeps the kit's composer row at its four
controls.

iOS's picker lists the root only, so a file inside a folder cannot
be sent from a conversation, and nothing says so — it is simply absent,
which reads as "it isn't there". LocalVault.allFiles() walks the whole
tree. Filed as ios#68.

The picker is the ONE place this vault hides a row it cannot read.
Everywhere else it insists on showing them, because hiding one leaves
somebody unable to see anything is there; a picker exists only for
choosing, and a row that can never be chosen is furniture.

A received file is always saved as an encrypted copy, never a link —
there is no file on this phone to point at — and always at the label it
arrived with. Re-labelling somebody else's document on receipt would
launder its classification, and the number is the only thing that survived
the trip.

9 new tests. Each guard proved by breaking the code: writing the label for
every attachment kind fails the image test; dropping compartments fails
the two that name them; removing the fallback caption fails the
older-build test.

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

Both directions: pick a document from the vault inside a conversation, and save a received one into the vault at the classification it arrived with. **This is the answer to android#15, and the codebase had already given it.** `Attachment.FILE` has carried this since before the lattice existed: *the label is a MARKING, not a permission — the content key is in the same envelope, so whoever can read the message can read the file.* That settles the ★-property question. The key travels with the file by design, because that is what makes sending work at all; there is no trusted computing base to enforce against, since the person holds every key on a device they control. A client-side refusal would be a suggestion, and **a suggestion dressed as a control is worse than none** — it is the one people plan around. So neither client implements the ★-property, `LabelTest` keeps asserting that absence, and PARITY.md now says plainly that Files is not mandatory access control. What it IS: cryptographic read separation, plus a classification that travels. The picker says so before the tap, in those words. Three things found on the way: **A second copy of the vocabulary.** `classificationName` in ChatScreens listed the same four names as `FileLevels`, agreeing by coincidence with nothing making them agree. Rename a level for the Files screen and the chat bubble keeps showing the old word for the same number, in the same conversation, on the same phone. Collapsed to one. **Attach and Camera did the same thing.** Both launched the gallery, and there was no way to send a document at all. Attach now opens a small panel — photo, or from Files — which keeps the kit's composer row at its four controls. **iOS's picker lists the root only**, so a file inside a folder cannot be sent from a conversation, and nothing says so — it is simply absent, which reads as "it isn't there". `LocalVault.allFiles()` walks the whole tree. Filed as ios#68. The picker is the ONE place this vault hides a row it cannot read. Everywhere else it insists on showing them, because hiding one leaves somebody unable to see anything is there; a picker exists only for choosing, and a row that can never be chosen is furniture. A received file is always saved as an encrypted copy, never a link — there is no file on this phone to point at — and always at the label it arrived with. Re-labelling somebody else's document on receipt would launder its classification, and the number is the only thing that survived the trip. 9 new tests. Each guard proved by breaking the code: writing the label for every attachment kind fails the image test; dropping compartments fails the two that name them; removing the fallback caption fails the older-build test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
paulhitt commented 2026-09-04 19:34:31 +00:00 (Migrated from gitlab.com)

assigned to @paulhitt

assigned to @paulhitt
paulhitt commented 2026-09-04 19:34:46 +00:00 (Migrated from gitlab.com)

restored source branch feat/files-share-into-chat

restored source branch `feat/files-share-into-chat`
paulhitt commented 2026-09-04 20:50:01 +00:00 (Migrated from gitlab.com)

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

deleted the `feat/files-screen` branch. This merge request now targets the `main` branch
paulhitt (Migrated from gitlab.com) merged commit c47533929e into main 2026-09-04 20:50:12 +00:00
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.