Skip to content

ADR 0033: Live classify on connected mail

Status

Accepted

Context

Duckbill™ already classifies golden-set fixtures and persists versioned AIInference rows (ADR 0022). Sync enqueues CLASSIFY work and leaves mail visible as UNPROCESSED when that work has not run. Home counts stay empty because classify never ran on a connected mailbox. MAIL-217 remains the parked latency measurement. This decision is the worker, not that measurement.

Decision

  1. POST /api/classify/live classifies one bounded page of stored messages for a mailbox the signed-in user owns. The page size is at most 10. The handler does not receive a provider adapter and does not call Graph, Gmail, or iCloud.
  2. Labels come from stored subject and body through classifyConnectedMail. That function does not look up golden-set ids. Prompt-injection text is recorded as low-confidence review, not executed.
  3. Each new result is an insert-only inference with classify.v1, schema 1.0.0, and taxonomy 1.0.0. A matching fingerprint keeps the current row. A changed message inserts another row. Current classification pointers stay correctable by the existing human-correction path.
  4. The worker writes conversation attention from the classification (RESPOND, WAITING, FYI, ARCHIVE, or NONE). Home counts read that attention plus current classifications. The empty state says the mailbox is not classified yet, or that classify ran and Needs Me, Respond, and Waiting are empty.
  5. iCloud stays read-write. This route does not change provider capability flags and does not move mail.

Alternatives

Consequences

Home can change after one signed-in classify of stored mail. Adapter write count stays 0. Preview still needs the route deployed before a browser session can press Classify connected mail.