Type · chore (CI configuration) · Parent · MOTIR-1464, the epic holding this class — MOTIR-2970 (the call-site fix) and MOTIR-3569 (the ci.yml fix) · Discovered in · the run of MOTIR-3569, 2026-08-28 · Repo · motir-core
origin/main at 13a30285fMOTIR-3569 gives every runs-on job in .github/workflows/ci.yml a timeout-minutes, moving that file from 3 of 14 to 14 of 14. It is one file of twelve. The other eleven workflow files declare 19 runner jobs and not one timeout-minutes between them, so each still inherits GitHub's 360-minute default:
| workflow | runner jobs | unbounded | job ids |
|---|---|---|---|
sandbox-images.yml | 6 | 6 | sandbox-smoke · sandbox-profiles-matrix · sandbox-profiles · sandbox-published · sandbox-public · sandbox-commands |
acceptance-video.yml | 3 | 3 | membership · build · acceptance |
release-sandbox.yml | 2 | 2 | guard · readme |
runner-image.yml | 1 | 1 | runner-image |
codeql.yml | 1 | 1 | analyze |
backfill-boards.yml | 1 | 1 | backfill |
sandbox-staleness.yml | 1 | 1 | staleness |
release-brand.yml · release-cli.yml · release-design-system.yml · release-runner-image.yml | 1 each | 4 | release ×3 · version |
Derived by parsing each workflow's jobs: mapping (job-level keys at exactly four spaces, so a step's timeout-minutes cannot be miscounted as a job's); the script is in the MOTIR-3569 run's transcript and the counts are reproducible from the files.
ci.yml calls two of these workflows. Its sandbox and runner-image jobs are uses: calls into sandbox-images.yml and runner-image.yml, and GitHub does not accept timeout-minutes on a uses: job — the ceiling has to live in the CALLED workflow, where there is none. So seven of the nineteen sit inside a CI run, under ci-complete, which needs both callers:
CI complete unresolved for up to six hours, which is precisely the state MOTIR-3569 was filed about;tests/ci-job-timeouts.test.ts) reports ci.yml as fully bounded while that is true, because its scope is one file — it says so in its header and names this card;needs.changes.outputs.images), so the hole opens on exactly the PRs that touch the image inputs and is invisible on every other one.The remaining twelve are release and scheduled lanes. Their wedge costs no PR verdict, but it is the same six hours, on lanes nobody is watching — sandbox-staleness and backfill-boards run on a schedule, so a hang there is discovered by the next person who wonders why a sweep stopped reporting.
.github/workflows/*.yml that declares runs-on also declares timeout-minutes. The count moves from 14 of 33 to 33 of 33 across the twelve files.gh api repos/moooon-B-V/motir-core/actions/runs/<id>/jobs), never guessed; a lane with no recent run says so and takes a stated floor.sandbox-images legs ran 0.1–5.8 min and runner-image 1.3 min on run 3316740687833167406878 both jobs were skipped by their path filter — gh api repos/moooon-B-V/motir-core/actions/runs/33167406878/jobs -q '.jobs[] | select(.name|test("Sandbox|Runner image")) | "\(.name) \(.conclusion)"' returns Runner image skipped / Sandbox images skipped — so the range measures nothing. A skipped job reports a duration of zero, not an absence, which is why it read as a plausible measurement. Re-measured across the 14 runs of ci.yml / release-sandbox.yml / release-runner-image.yml where these jobs actually ran: sandbox-profiles is 2.6–16.68 min (worst: aider tier 2, run 33214411817, conclusion: success) and runner-image is 1.7–5.38 min (worst: run 33218152057). This matters rather than being pedantic: a ~3× ceiling on the card's 5.8 is 18, and 18 would have FAILED that green 16.68-minute run — the exact trade this card's own Out of scope forbids. Planning bug: MOTIR-3854.; the acceptance lane is 10–20× slower than ordinary E2E and needs its own reading, not a copy of e2e's 45 — confirmed: measured 4.9–11.3 min per shard from this lane's own runs, ceilinged at 40.)tests/ci-job-timeouts.test.ts is WIDENED from ci.yml to every file in .github/workflows/, still re-deriving the job list from each file rather than restating one, so a job added to any workflow without a ceiling fails the suite. Its SCOPE header paragraph and the ci.yml ceilings block that both name this card are updated or removed in the same change.ci.yml itself — MOTIR-3569 closes it. This card starts from the tree that card leaves..github/workflows/ — the twelve files; ci.yml:1127 (sandbox) and ci.yml:1156 (runner-image) are the uses: jobs whose ceilings live elsewhere.tests/ci-job-timeouts.test.ts (MOTIR-3569) — the guard to widen; its leaves NO other shape of job case is what documents why a uses: job carries none.Resolution: open.