# Run completion notifications Execution Core owns completion. Its supervisor commits `execution_core.run.completed.v1` with the final Run and Attempt. Browser and mail adaptors use that existing outcome; a failed intermediate Attempt does not produce a completion notification. Succeeded and failed final Runs qualify. Other terminal outcomes retain their existing interfaces. ## Browser delivery and links `ListRunCompletions` returns only the initiating member's final Runs in a currently authorised Project, with canonical Run and Attempt IDs, state, occurrence time and Run revision. Pages are explicit, ordered by creation time and Run ID, and cursors remain scoped to the member and Project. Authority is checked before and after reading. Historical completions are readable. The retained browser's existing layout connection receives server-selected Project subscriptions and typed Run projections. Initial subscriptions, reconnection and own-Run updates trigger paginated completion reads through the generated HTTP client. Updates coalesce; each Run has one visible entry. Unsubscription, disconnection and refused reads remove cached completion data. The browser adds no polling or client-selected subscription. Both delivery paths link to `/runs/`. `GetRunLocation` rechecks current Project authority and asks Source Control for the canonical repository's known binding. A Project transfer that differs from the Run's accepted Project is refused. The browser resolves the authorised repository path and selects the exact `jobs/` or `deployments/` fragment. An unsigned visitor sees a sign-in form preserving the canonical return path. No provider reference, address, action parameter or log enters a notification. ## Verified contact and mail state Party Governance exposes `GetPartyNotificationContact` only to Execution Core's actorless owner caller. It checks current authentication eligibility and the current, generation-qualified identity-attribute observation, and rechecks authentication after the read. Missing or stale attributes remain pending; disabled Parties and absent verified email are unavailable. There is no email fallback or browser contact route. Migration 0017 creates Execution Core's private `run_completion_mail` technical queue. A trigger on newly inserted completion outbox rows reserves one intent per Run and Attempt in the same transaction. It does not insert historical events. Migration 0016 is the unchanged pending log-read index prerequisite. The queue references immutable event bytes; it stores no email address or body. Its runtime role can update delivery metadata but cannot rewrite correlation columns or delete intents. Workers lease pending work and check the final owner Run, exact Attempt, initiating member, current Project authority and current verified contact before each send. Missing current evidence retries without sending. Lost authority or an unavailable recipient suppresses the intent. Intents expire 72 hours after their completion fact. The sending state commits before SMTP. Confirmed SMTP rejection returns to pending with bounded backoff. Positive DATA acknowledgement settles sent, including when QUIT later fails. A lost DATA acknowledgement, an unexpected error after sending starts, a lost sent receipt or an expired sending lease settles uncertain and never automatically resends. A stable Run-and-Attempt Message-ID aids correlation; it does not claim exactly-once SMTP delivery. Operators must investigate uncertain outcomes against relay evidence. There is no public retry or queue-edit interface. ## Configuration and qualification The execution worker enables mail when `EXECUTION_CORE_SMTP_HOST` is set. It then requires `EXECUTION_CORE_SMTP_FROM` and the exact enrolled `EXECUTION_CORE_PUBLIC_WEB_ORIGIN`. Optional settings are `EXECUTION_CORE_SMTP_PORT` (587), `EXECUTION_CORE_SMTP_TLS` (`starttls`), `EXECUTION_CORE_SMTP_EHLO`, and the paired `EXECUTION_CORE_SMTP_USERNAME` / `EXECUTION_CORE_SMTP_PASSWORD_FILE`. Passwords are reread for each attempt. TLS verifies the relay certificate; unencrypted SMTP is limited to loopback. Application containers receive context credentials and a relay account, never administrator credentials. The origin is HTTPS, with HTTP loopback permitted only in explicit local mode. The devbox overlay enables a separate Mailpit sidecar in `execution-worker`, binding SMTP and its read API to loopback. It has no Service or Ingress and forwards no external mail. Its bounded, ephemeral inbox is qualification evidence, not durable delivery storage. Operators may use `kubectl -n pharos port-forward deployment/execution-worker 8025:8025` to inspect exact Run-correlated mail, then close the forward. Full verification and the Beto, Metallo and cross-service infrastructure lanes cover the contracts, restricted contact caller, persistence and SMTP outcomes. Live acceptance still requires fresh owned success and failure Runs after deployment: inspect the exact browser links and one matching mailbox entry, reload/reconnect without duplication, and confirm a foreign or removed member cannot read the Run. Runs completed before migration must produce no new mail.