This step therefore writes the union: the five existing keys, AGT-013's context_judge, and the
artifact seats record_registrar and indigo. Approval requests receive the same union.
Chat sessions remain on the existing five because ambient artifact work is not a chat.
run_origin is nullable, and a run may omit
user_id when it is system-originated or is the existing Vega frame rail. Story-2960 owns the
backfill, NOT NULL conversion, and removal of the Vega exception. This Story does none of that contraction.
Run status does not gain a fictional pending state. Artifact pendency lives on
delivery_status while the run remains running. Existing non-delivery rows retain all
ten live statuses, including aborted_cost and circuit_open.
| Delivery state | Allowed run state | Required evidence |
|---|---|---|
awaiting_artifact |
running |
Expected key and non-NULL deadline; no completion or artifact digest. |
delivered |
succeeded or failed |
Completion time, lowercase SHA-256, non-negative size; a failed run also carries an error. |
swept |
failed |
Completion time and error; no artifact digest or size. |
awaiting_artifact + deadline_at = NULL
→ rejected by agent_run_awaiting_artifact_has_deadline
why: NULL < now() is UNKNOWN
→ without the CHECK, the sweeper never selects the row
→ the user-visible run can remain non-terminal forever
(run_id, sha256) deliveries. Forced firm RLS permits a firm-scoped worker with no user
context while denying cross-firm runs and receipts.
Step 1 only widens and makes bad delivery states impossible; Step 2 backfills and contracts after the other epic settles.