act caches each action as one shared git clone under /root/.cache/act/<hash> and re-pulls it per job. The three python matrix jobs start within the same second on the self-hosted runner, race on that directory, and the loser dies with "lstat /root/.cache/act/<hash>/.npmrc: no such file or directory" before any test runs — a red main with zero suite output and a different victim each push (3.12, then 3.11). The action was only fetching a binary; the matrix interpreter is selected per command by uvx --python. A run: step has no action-cache entry and cannot race, and keeps the jobs parallel — serialising the matrix would cost 3x the wall clock and still leave actions/checkout shared across four jobs. The uv version is pinned under the same rule as ruff. The accompanying test parses uses: directives rather than the raw text, so the comment can still name the action it avoids, and uses re instead of PyYAML because CI runs uvx pytest, whose environment holds pytest and nothing else.