runOnce only mapped an expired context to llm.ErrTimeout when execute returned an error, so a PostProcess that succeeded after the deadline was reported as a success. Check the deadline after execution (context cause or the clock, since the timer may not have fired yet) and fail such a run with llm.ErrTimeout and a provider_error ai_runs row. Adds a TestRunTimeout case with a skill whose PostProcess succeeds only after its timeout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>