P0: Expire Stale Generated Media Sends

Problem

Generated media action results can become stale if the production bridge is down, paused, misconfigured, or restarted after a long outage. When the bridge comes back, the current drain behavior may send every pending generated voice/photo result, even if the chat moment has expired. That can spam users with out-of-context media.

This happened during the July 6-7, 2026 production incident. SPECTRUM_ACTION_OUTBOUND_POLL_MS was set to 2147483647, effectively disabling action-result draining. After restoring the poll interval to 2000, the bridge began replaying old generated media. We manually cancelled the remaining stale action-result:% media backlog to avoid further spam.

Desired Invariant

The bridge must never send stale generated media after a restart or delayed recovery. Async generated-media action results are only deliverable while they are fresh enough to still belong to the current conversational context.

Plan

1. Add an expiry policy for action-result media jobs.

2. Store or compute expiry.

3. Cancel expired jobs before they can send.

4. Scope cancellation to the bridge's owned delivery surface.

5. Preserve live behavior.

6. Add observability.

7. Add tests.

Acceptance Criteria