# Central email attention queue

Phase 3 milestone 21, built locally on **2026-10-20** during **Phase 6 pilot preparation**. The shared inbox on web, iOS and Android now brings together outbound attempts that need administrator attention. This is a read-only index into the existing attempt and delivery-investigation workflows; it creates no queue worker, send, retry or notification.

## Staff workflow

Open **Inbox → Email attention**. Filter by **Reports need review**, **Investigation in progress**, **Uncertain attempts**, **Expired attempts**, or **All attention**. Assignment filters use the conversation's current assignee: all staff, assigned to me or unassigned. Assignment is not a separate investigation owner. Closed conversations and unavailable assignees remain visible so closing a conversation or disabling an account cannot hide unfinished work.

The list shows the subject, assignee, conversation state, approved reply revision, attempt state, linked report count and investigation status. It orders by oldest attempt creation time, with an ID tie-breaker, and shows 25 attempts per page. The checked time is a snapshot, not a live subscription. Use **Refresh attention queue** after changes in another session or when a claim deadline passes. A review or new report may change page membership; refresh returns to page one.

**Inspect attempt** opens the exact selected attempt, including an older revision that would otherwise require paging through history. It fetches current server evidence. Administrators use the same existing guarded recovery/review and investigation forms; other staff can inspect the history. Returning to the queue refreshes its membership, asks before discarding unsaved notes and is disabled during a save. Navigating away from the inbox through other navigation still discards local unsaved text.

A reviewed report disappears from the report-review filter only while that review covers the current append-only report set. Another linked report brings it back. An unresolved uncertain attempt remains in the uncertainty filter even when its delivery reports have been reviewed. Expired claims indicate that administrator assessment is needed; the queue never assumes a worker has stopped or performs recovery. Reviewed or blocked attempts without outstanding report work do not appear. A clean or empty queue does not establish successful delivery.

Failed reads hide stale list rows and actions. Session expiry uses the existing sign-out handling; old responses after filter changes or unmount are ignored. Names and subjects are displayed as literal text. No new provider connection or delivery claim is introduced.

## Server contract and consistency

`GET /v1/email-attention` requires an active staff session and returns `as_of`, `total` and `items`. It accepts `kind=all|reports|investigating|uncertain|expired`, `assignment=all|mine|unassigned`, nonnegative `offset`, and `limit` from 1 to 50 (default 25). There is no mutation route. Responses are no-store through the existing middleware/proxy.

The server joins attempts to conversations, groups linked reports and selects the latest investigation version. Filtering, count and page execute in one SQL statement snapshot, including out-of-range pages. Only page summaries are materialized; the queue does not load every message body, report document or investigation note into Python. PostgreSQL/SQLite handle the grouped/windowed selection. Deployment-scale load and indexes still need verification against real data volume.

Report-count comparison relies on the application's append-only report retention. It detects new imports without hashing every report on every queue request. It is not an integrity check for unsupported direct database edits that replace existing evidence without changing its count. The investigation detail/save routes retain their full evidence-digest checks and current-authority/version fences. Queue summaries never authorize a write or a resend.

`GET /v1/inbox/{conversation_id}/outbound/attempts` now optionally accepts `attempt_id=UUID`. This limits the response to that exact attempt within the named conversation; missing or cross-conversation attempts return 404. Omitting the filter retains normal paginated history. Write routes and administrator permissions are unchanged.

## Scope and operation

No migration is added; the schema head remains `53eac242f8c3`. Older deployments must still apply the delivery-investigation migration using the normal backup/grant procedure. Existing preview/development business databases and public PHP files were not changed.

Unmatched and unsupported delivery-report source messages remain in the shared inbox. They are not automatically linked or assigned to this attempt queue. The subsequent [case responsibility milestone](EMAIL-CASE-PLANS.md) adds separate ownership, deadlines and overdue filters. Proactive alerts, provider verification and real server/device acceptance remain open. Live receiving/sending, mobile signing and model training remain deferred. See [VALIDATION.md](VALIDATION.md) for dated local evidence.

Milestone 22 extends this endpoint with `owner=all|mine|unassigned|unavailable` and `kind=overdue`; the original conversation-assignment filter remains independent. The latest schema head is now `64fbd353a9d4`; this guide describes the earlier queue milestone.
