# Authorized attachment picker

> ROM 0.1.3 integration candidate. This guide is not evidence of a completed release.
> Matching package version: 0.1.2. Archive SHA-256: 25f0f1ed5e83bd01f71a81be4987d3ceea182aecbc5382b0bcc1ccdcf36b99f4.
> Guide origin: isolated ROM checkout; guide is outside the package archive.


This composition is a ROM 0.1.3 candidate. Browser and installed-consumer qualification remain open.

Import `AttachmentPicker` from `rom-studio/ui/components`.
Supply the session-owned client, a disclosed Blob Resource descriptor, and the current authority token.
Replace the authority token after a session or permission change.

The picker reads authorized pages through `RomClient.query`.
It uses native query anchors for continuation. Continuation tokens belong to one catalog instance.
Search filters the current candidate page. It is not a full-text query.
The flat catalog does not invent folders or storage paths.
Titles use only disclosed fields from the Resource descriptor.

Selection returns the exact `{ kind, id }` reference. Selection does not upload, attach, or mutate a Resource.
Use `createAttachments` from `rom-studio/client` for the existing reserve, upload, detach, and recovery lifecycle.
An unknown outcome requires recovery of the existing operation. It does not permit a new upload operation.

The host must dispose controllers when authority changes.
The catalog rejects late results after disposal, cancellation, or client generation changes.
The picker closes after an authority token change.

## Upload composition

Import `AttachmentUpload` from `rom-studio/ui/components`.

Supply an optional `picker` snippet to use another local selection component, such as `UppySelection` from `rom-ui/files/uppy`.
Import its argument type, `AttachmentUploadPicker`, from `rom-studio/ui/components`.
The snippet receives `authority`, `disabled`, `maxFiles`, `maxBytes`, and `select(files)`.
Forward these limits and the disabled state to the picker. Call `select` with one local `File`.
Studio rejects callbacks after disposal, while an operation is unresolved, or when the selection exceeds its limits.
The existing controller owns reservation, byte transfer, confirmation, and retry. The picker does not confirm an attachment.
Without a snippet, the native local file picker remains the default.

```svelte
{#snippet picker(state: AttachmentUploadPicker)}
  <UppySelection
    authority={state.authority}
    disabled={state.disabled}
    maxFiles={state.maxFiles}
    maxBytes={state.maxBytes}
    onselect={state.select}
  />
{/snippet}
<AttachmentUpload {client} {authority} {capabilities} {id} {store} {picker} />
```
Supply the session client, advertised Blob capabilities, authority token, exact Resource ID, and approved store.
The component owns and disposes the existing attachment controller for that scope.
It uses the shared local file picker and upload queue.
It accepts one local file at a time. The file name does not determine the Resource ID or store.

Select a file, then select **Upload attachment**.
The component reports processing while the existing controller reserves and uploads the bytes.
It does not report measured transfer progress.
After an unknown outcome, select **Reconcile** to resume the same operation.
The component calls `onconfirmed` only after the controller receives a successful ROM result.
A later local file selection starts in the selected state. It does not inherit the earlier confirmation.

Host notification failures do not change a confirmed ROM result into an unknown outcome.
The component reports notification failure separately.

The eight Chromium and WebKit composition checks use a fixture client.
They do not prove backend authorization, durable reload recovery, or a published release.
