Skip to content

mobile: share inbox has no cap, expiry, or way out #228

Description

@rynfar

Found during adversarial review of #8237 adoption (PR for upstream/2026-08-31-mobile-files). Upstream design, adopted as-is; filing rather than folding into that PR to keep it to one concern.

Problem

apps/mobile/src/features/sharing/incoming-share-storage.ts writes one JSON per share with no count cap, no size cap, and no expiry. Nothing prunes the directory — INCOMING_SHARE_DIRECTORY appears in that file only.

removeIncomingShareDraft is reachable only via IncomingShareInbox.consume, whose sole production caller is NewTaskDraftScreen.tsx:534 — on a successful import. Dismissing the sheet latches dismissedShareId (incoming-share-presentation.ts:44-49) and leaves the draft on disk permanently.

Only drafts[0] is ever surfaced (IncomingShareProvider.tsx:324). There is no inbox list, so anything at index >= 1 is unreachable while the top item is merely dismissed.

Why it matters more now

Before file attachments, an image share stored base64 in the JSON, bounded at 8 x 10 MB. Now each share can additionally copy up to 8 x 50 MB into Documents/t3-composer-attachments/ — the non-evictable, iCloud-backed directory, not the cache.

Share and dismiss 20 files: roughly 1 GB, invisible in-app, unreclaimable without reinstalling.

Rule this violates

AGENTS.md "Reverse states": If you added a way in, add the way out and the way to see it. A one-way door is a bug.

Sketch

Any of: a retention cap or TTL with a pruner; deleting the draft on dismiss rather than latching it; or an inbox list so items behind drafts[0] are reachable.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions