Refactor prepare_timeout
What does this MR do?
Refactors the prepare_timeout disambiguation logic to use context.WithTimeoutCause.
The previous two-context guard (!errors.Is(ctx.Err(), context.DeadlineExceeded) && errors.Is(prepareCtx.Err(), context.DeadlineExceeded)) is replaced with a single errors.Is(context.Cause(prepareCtx), ErrJobPrepareTimeout) check.
The cause carries the configured timeout duration, so the user-visible error now reads Job failed: prepare timeout: exceeded timeout of 30s (previously: Job failed: prepare timeout).
Why was this MR needed?
The previous error message told operators which timeout fired but not what value was configured (they had to consult config.toml to find the specific value which fired). Including the duration in the message removes that step. The disambiguation also becomes a single per-site cause check, which is easier to reason about and establishes the pattern for upcoming per-stage timeouts such as get_sources_timeout.
What's the best way to test this MR?
Unit tests in common/build_test.go pass and assert the new error message format including the duration.
For end-to-end verification a reviewer can build the runner locally, set prepare_timeout to a short value in config.toml, and trigger any job (the job log should end with Job failed: prepare timeout: exceeded timeout of <duration> and the failure attribution should be unchanged from prior behaviour).
What are the relevant issue numbers?
Follow-up from #26583 (closed) (prepare_timeout implementation).