lane-shas.yml has intermittently failed under Act-runner contention with
truncated/ambiguous logs (see docs/plans/adr-0241-0242-session-completion-
summary-2026-07-15.md #38 postmortem: run #167 failed at ~22m39s, but local
verify_lane_shas.py showed 9/9 pins matching — the failure was never
conclusively attributed to a timeout vs an incomplete log, because the
script buffers all per-lane output until every lane finishes).
Two changes, no lane logic touched:
1. Stream progress per lane (`-> lane_id ... done (Ns)`, flush=True) instead
of buffering until the end, so a hang shows exactly which lane and for
how long even if the job is killed before the final summary prints.
2. Make the per-lane subprocess timeout configurable via
CORE_LANE_VERIFY_TIMEOUT_S (default unchanged at 900s — same knob shape
as CORE_SHOWCASE_HARD_BUDGET), and report a TimeoutExpired distinctly
from a genuine SHA mismatch so the remediation text stops suggesting
`--update` (re-pinning) for what is actually runner contention.
[Verification]: tests/test_lane_sha_verifier.py 6 passed; ruff clean;
scripts/verify_lane_shas.py run locally with the new streaming output
confirmed correct per-lane timing (e.g. demo_composition 154s) end to end.