# 0058 — File transfer is pull-model: an attachment is a served file plus a link

Status: accepted (2026-09-06 WEBSERVE grill round 1, releases#272 / #246 / #17)

## Context

Endpoint-to-endpoint file transfer (#246) had three candidate shapes: a push (`spt send
--file`, bytes copied to the receiver through the transfer machinery), a served attachment
(`spt send --attachment`, the file is registered for serving and the message envelope carries
its URL; the receiver pulls if and when it wants), or a dedicated transfer verb outside
messaging. The choice also fixes what the FILE_ACCESS_HELPER now-signal (#17) tells an agent
to do with a file it was handed.

## Decision

**`spt send --attachment` is the primary transfer UX, and it is pull-model.** The file becomes
a serving-registry entry (ADR-0057) and the message carries its node-prefixed URL
(ADR-0056). No unsolicited bytes ever land on a receiver; a human clicks the link, an agent
fetches it. One mechanism serves both audiences. A small companion verb, `spt fetch <url>
[dest]`, gives a receiving agent a local copy in one command — that verb string is what
FILE_ACCESS_HELPER emits.

## Alternatives rejected

- **Push (`--file`).** Delivers bytes the receiver did not ask for, needs receiver-side storage
  policy, and duplicates the serving path for humans. Rejected.
- **Dedicated transfer verb outside messaging.** A file with no message around it loses the
  context a transfer almost always has. Rejected; the attachment rides the message.

## Consequences

- A transferred file is only as available as its owner node; an offline owner means a link
  that waits, which is the honest state and is visible as such.
- The pre-WEBSERVE transfer machinery is superseded by this path (its access surface's fate is
  a separate decision, pending the operator's Q3 confirmation).
- **Reference vs snapshot, and lifetime (round 2, Q8):** a `serve add` entry serves the file AT
  ITS PATH — edits are visible, deletion answers *not found*; an attachment SNAPSHOTS the bytes
  at send time into the registry's own store, because a message's attachment is as immutable
  as the message. `serve add` entries live until removed; attachments carry a time-to-live,
  **default 30 days** (operator-set; `--ttl` per send), reaped by the daemon's existing pulse
  with the reap count logged.
