Stop running every macOS workflow on every commit to main (#9174)

* Stop running every macOS workflow on every commit to main

GitHub caps macOS at five concurrent jobs account-wide, across every repository,
which makes a macOS runner slot the scarcest thing in this repo's CI. Four
workflows scoped their pull_request trigger carefully and then declared
`push: branches: [main]` with no paths filter at all, so after merge they ran
on everything.

Commit 6371f46a changes README.md and nothing else. It started Mac Studio GGUF
CI, Mac Studio UI + API + Update CI, Mac Studio Install Matrix CI and Unsloth
Tauri CI: seven macOS legs, 40 percent over the entire account cap, for a
documentation typo. Every one of them then queued behind the others.

Replaying each workflow's own pull_request filter against the last 40 commits
to main puts the cost at 280 macOS job-slots today against 94 with the filters
mirrored, and drops the peak on a single commit from 7 to 3, under the cap.
Most of that is one workflow: Mac Studio Install Matrix fired on 40 of 40
sampled commits and would fire on none of them, at 4 slots each, and it also
carries the worst queue in the set at a 200 minute median for a 2m38s job.

No coverage changes. Each push list is its own pull_request list copied
verbatim, which is the same question asked twice, and the post-merge backstop
still runs whenever a commit can affect what the workflow tests.
clean-machine-install-ci.yml and mlx-ci.yml already do exactly this and say
why; this brings the other four in line.

tests/studio/test_macos_slots_per_commit.py asserts no macOS workflow has an
unfiltered push trigger, that the two filters do not drift apart in either
direction, and that a README-only commit starts nothing. Its first cut
reported workflow-trigger-lint and studio-inference-smoke as macOS workflows,
because it scanned whole jobs and both merely mention macOS in a step; it now
reads runs-on and resolves matrix expressions. Three mutations verified red.

* List the helpers these workflows execute, now that the trigger is scoped

Scoping a trigger is only safe if its path list is complete, and these were
not. Five helper scripts and one auditor are invoked by name from a run step
and matched no pattern in either list:

  studio-mac-inference-smoke  assert-llama-loads.sh, hf-download-with-retry.sh,
                              studio_smoke/multi_turn_chat.py
  studio-mac-ui-smoke         assert-llama-loads.sh, hf-download-with-retry.sh
  studio-tauri-smoke          scripts/lockfile_supply_chain_audit.py

The gap predates this PR, but it was invisible while the push trigger was
unfiltered, because every commit ran everything after merge. Narrowing the
trigger is what turns it into a real hole: editing assert-llama-loads.sh would
stop running the workflows that assert with it.

studio-tauri-smoke also gains studio/package.json and studio/package-lock.json.
Its Linux job installs and runs the Tauri CLI out of that package root
(npm install --prefix studio, npx --prefix studio), so those manifests decide
what it builds with. They are listed by hand rather than found, because that
dependency does not go through a file path in a run step.

test_every_helper_a_workflow_executes_is_in_its_trigger asserts the rest, from
the run bodies rather than a fixed list, for both triggers. Verified red by
dropping assert-llama-loads.sh again.

* Cover the install matrix's transitive inputs, and run the guard on workflow-only PRs

studio-mac-install-matrix listed install.sh and studio/setup.sh but not what
they reach: setup.sh:1444 runs install_python_stack.py, which imports
install_manifest.py, and install_llama_prebuilt.py imports prebuilt_core.py at
line 55. A commit touching only one of those changed exactly what this matrix
asserts on and did not start it.

Not studio/backend/requirements/** or pyproject.toml, which
install_python_stack.py also consumes. Generic install breakage on macOS is
clean-machine-install-ci's job, and it lists both on either trigger with seven
macOS legs; duplicating them here would re-spend the slots this filter exists
to save. That is a judgement rather than an oversight, so it is written in the
filter next to the paths it excludes.

test_a_listed_python_input_brings_its_sibling_imports asserts the mechanical
half: a listed .py must bring the modules it imports from its own directory.
The full transitive closure of an installer is most of the repo, and chasing it
is how a filter stops saving anything, so anything deeper stays hand-listed
with a reason. The guard found install_manifest.py on its first run, which is
one hop further out than the report that prompted it.

The guard itself is now wired into workflow-trigger-lint, the one job with no
paths filter. Every way it can regress is a workflow-only edit, which no other
job matches, so it would otherwise have been collected first by Backend CI's
unfiltered push -- after the change had merged.
This commit is contained in:
Daniel Han 2026-08-18 04:22:15 -07:00 committed by GitHub
parent 3bf9bff5dd
commit fc325f431a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 443 additions and 0 deletions

View file

@ -48,8 +48,41 @@ on:
# The install step in this workflow is `uses:` on that composite action,
# so an edit to the action changes what this workflow actually runs.
- '.github/actions/install-unsloth-local/action.yml'
# Executed directly by this workflow: the load assertion, every model
# download, and the multi-turn chat driver. A change to any of them changes
# what this workflow actually runs.
- '.github/scripts/assert-llama-loads.sh'
- '.github/scripts/hf-download-with-retry.sh'
- '.github/scripts/studio_smoke/multi_turn_chat.py'
push:
branches: [main]
# Same list as the PR filter. Without it this workflow ran on EVERY commit to
# main: a README-only commit fired all four unfiltered macOS workflows, seven
# macOS legs, against an account-wide cap of five concurrent macOS jobs. The
# post-merge backstop is unchanged, because a commit that cannot touch what
# this workflow tests has nothing here to back up.
# clean-machine-install-ci.yml and mlx-ci.yml already do exactly this.
paths:
- 'studio/**'
- 'unsloth/**'
- 'unsloth_cli/**'
- 'install.sh'
- 'pyproject.toml'
- '.github/workflows/studio-mac-inference-smoke.yml'
# Every server boot in this workflow shells out to that script, so an edit
# to it changes what this workflow actually runs.
- '.github/scripts/boot-studio-api-only.sh'
# Same for the /api/health wait that runs after a boot.
- '.github/scripts/wait-for-health.sh'
# The install step in this workflow is `uses:` on that composite action,
# so an edit to the action changes what this workflow actually runs.
- '.github/actions/install-unsloth-local/action.yml'
# Executed directly by this workflow: the load assertion, every model
# download, and the multi-turn chat driver. A change to any of them changes
# what this workflow actually runs.
- '.github/scripts/assert-llama-loads.sh'
- '.github/scripts/hf-download-with-retry.sh'
- '.github/scripts/studio_smoke/multi_turn_chat.py'
# Manual trigger for pre-warming model caches on main, or re-running
# against an arbitrary branch without pushing a no-op commit.
workflow_dispatch:

View file

@ -19,8 +19,51 @@ on:
# The install step in this workflow is `uses:` on that composite action,
# so an edit to the action changes what this workflow actually runs.
- '.github/actions/install-unsloth-local/action.yml'
# Reached transitively by the install this workflow asserts on:
# install.sh selects studio/setup.sh, which runs install_python_stack.py
# (setup.sh:1444), and install_llama_prebuilt.py imports prebuilt_core
# (install_llama_prebuilt.py:55).
#
# Deliberately NOT studio/backend/requirements/** or pyproject.toml, which
# install_python_stack.py also consumes: generic install breakage on macOS is
# clean-machine-install-ci's job and it lists both on either trigger with 7
# macOS legs. Duplicating them here would re-spend the slots this filter saves.
- 'studio/install_python_stack.py'
- 'studio/prebuilt_core.py'
# install_python_stack.py imports this; interrupted-install-ci.yml already
# lists it for the same reason.
- 'studio/install_manifest.py'
push:
branches: [main]
# Same list as the PR filter. Without it this workflow ran on EVERY commit to
# main: a README-only commit fired all four unfiltered macOS workflows, seven
# macOS legs, against an account-wide cap of five concurrent macOS jobs. The
# post-merge backstop is unchanged, because a commit that cannot touch what
# this workflow tests has nothing here to back up.
# clean-machine-install-ci.yml and mlx-ci.yml already do exactly this.
paths:
- 'studio/install_llama_prebuilt.py'
- 'studio/setup.sh'
- 'install.sh'
- '.github/scripts/assert-llama-loads.sh'
- '.github/workflows/studio-mac-install-matrix.yml'
# The install step in this workflow is `uses:` on that composite action,
# so an edit to the action changes what this workflow actually runs.
- '.github/actions/install-unsloth-local/action.yml'
# Reached transitively by the install this workflow asserts on:
# install.sh selects studio/setup.sh, which runs install_python_stack.py
# (setup.sh:1444), and install_llama_prebuilt.py imports prebuilt_core
# (install_llama_prebuilt.py:55).
#
# Deliberately NOT studio/backend/requirements/** or pyproject.toml, which
# install_python_stack.py also consumes: generic install breakage on macOS is
# clean-machine-install-ci's job and it lists both on either trigger with 7
# macOS legs. Duplicating them here would re-spend the slots this filter saves.
- 'studio/install_python_stack.py'
- 'studio/prebuilt_core.py'
# install_python_stack.py imports this; interrupted-install-ci.yml already
# lists it for the same reason.
- 'studio/install_manifest.py'
workflow_dispatch:
concurrency:

View file

@ -50,8 +50,46 @@ on:
# No new entries needed for the absorbed API phase: every path
# studio-mac-api-smoke.yml watched is already covered above, and
# tests/studio/** covers studio_api_smoke.py itself.
# Executed directly by this workflow: the load assertion and every model
# download.
- '.github/scripts/assert-llama-loads.sh'
- '.github/scripts/hf-download-with-retry.sh'
push:
branches: [main]
# Same list as the PR filter. Without it this workflow ran on EVERY commit to
# main: a README-only commit fired all four unfiltered macOS workflows, seven
# macOS legs, against an account-wide cap of five concurrent macOS jobs. The
# post-merge backstop is unchanged, because a commit that cannot touch what
# this workflow tests has nothing here to back up.
# clean-machine-install-ci.yml and mlx-ci.yml already do exactly this.
paths:
- 'studio/**'
- 'unsloth/**'
- 'unsloth_cli/**'
- 'install.sh'
- 'pyproject.toml'
- 'tests/studio/**'
- '.github/scripts/run-studio-permission-browser.sh'
- '.github/scripts/run-studio-indicator-browser.sh'
- '.github/workflows/studio-mac-ui-smoke.yml'
# Every server boot in this workflow shells out to that script, so an edit
# to it changes what this workflow actually runs.
- '.github/scripts/boot-studio-api-only.sh'
# Same for the /api/health wait that runs after a boot.
- '.github/scripts/wait-for-health.sh'
# The install step in this workflow is `uses:` on that composite action,
# so an edit to the action changes what this workflow actually runs.
- '.github/actions/install-unsloth-local/action.yml'
# The absorbed update phase round-trips scripts/uninstall.sh, which none
# of the entries above cover.
- 'scripts/uninstall.sh'
# No new entries needed for the absorbed API phase: every path
# studio-mac-api-smoke.yml watched is already covered above, and
# tests/studio/** covers studio_api_smoke.py itself.
# Executed directly by this workflow: the load assertion and every model
# download.
- '.github/scripts/assert-llama-loads.sh'
- '.github/scripts/hf-download-with-retry.sh'
workflow_dispatch:
concurrency:

View file

@ -25,8 +25,35 @@ on:
# `unsloth studio` -- include unsloth_cli in the trigger set.
- 'unsloth_cli/**'
- '.github/workflows/studio-tauri-smoke.yml'
# The Linux job installs and runs the Tauri CLI out of the studio/ package
# root (`npm install --prefix studio`, `npx --prefix studio`), so these
# manifests decide what it builds with.
- 'studio/package.json'
- 'studio/package-lock.json'
# Run as a step of the Linux job.
- 'scripts/lockfile_supply_chain_audit.py'
push:
branches: [main]
# Same list as the PR filter. Without it this workflow ran on EVERY commit to
# main: a README-only commit fired all four unfiltered macOS workflows, seven
# macOS legs, against an account-wide cap of five concurrent macOS jobs. The
# post-merge backstop is unchanged, because a commit that cannot touch what
# this workflow tests has nothing here to back up.
# clean-machine-install-ci.yml and mlx-ci.yml already do exactly this.
paths:
- 'studio/frontend/**'
- 'studio/src-tauri/**'
# CLI rename / signature change can break Tauri's spawned
# `unsloth studio` -- include unsloth_cli in the trigger set.
- 'unsloth_cli/**'
- '.github/workflows/studio-tauri-smoke.yml'
# The Linux job installs and runs the Tauri CLI out of the studio/ package
# root (`npm install --prefix studio`, `npx --prefix studio`), so these
# manifests decide what it builds with.
- 'studio/package.json'
- 'studio/package-lock.json'
# Run as a step of the Linux job.
- 'scripts/lockfile_supply_chain_audit.py'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref == 'refs/heads/main' && github.sha || '' }}

View file

@ -127,3 +127,12 @@ jobs:
# exists to reject.
- name: The host-offload opt-out is still macOS-only
run: python3 -m pytest tests/studio/test_mac_host_offload_optin.py -q
# Same reason again, and this one guards THIS kind of file specifically. The test
# asserts that no macOS workflow has an unfiltered push trigger, and that each
# trigger lists the helpers its workflow executes. Every way it can regress is a
# workflow-only edit, which no other job's paths filter matches, so without this
# step the guard would first be collected by Backend CI's unfiltered push -- after
# the change had already merged.
- name: macOS workflows still do not run on every commit
run: python3 -m pytest tests/studio/test_macos_slots_per_commit.py -q

View file

@ -0,0 +1,293 @@
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
"""No macOS workflow may run on every commit to main.
GitHub caps macOS at **five concurrent jobs account-wide** -- across every repository,
on Free, Pro and Team alike. That makes a macOS runner slot the scarcest resource in this
repo's CI by a wide margin, and it is the reason macOS queue times dominate: measured over
the last 20 main runs, `studio-mac-ui-smoke` waited a median of 245 minutes to execute for
21, and `Unsloth Tauri CI :: Rust unit tests (macos)` waited a median of 270 minutes to run
for 3.
Four workflows used to declare `push: branches: [main]` with no `paths:` filter while their
`pull_request` trigger was carefully scoped. The effect was invisible on a PR and only
appeared after merge: commit 6371f46a changes README.md and nothing else, and it started
`Mac Studio GGUF CI`, `Mac Studio UI + API + Update CI`, `Mac Studio Install Matrix CI` and
`Unsloth Tauri CI` -- seven macOS legs, 40% over the entire account cap, for a
documentation typo. Every one of those runs then queued behind the others.
`clean-machine-install-ci.yml` and `mlx-ci.yml` already got this right and say why:
"Same list as the PR filter: without it a direct push to main touching any of these skipped
the workflow and the post-merge backstop never happened." This asserts the rest match.
The failure is silent in both directions, which is why it is a test rather than a review
note: an unfiltered push trigger costs nothing on the PR that introduces it, and the cost
lands on unrelated commits weeks later as queue time nobody attributes to it.
"""
import re
from pathlib import Path
import pytest
import yaml
REPO = Path(__file__).resolve().parents[2]
WORKFLOWS = REPO / ".github" / "workflows"
MACOS = re.compile(r"macos[-\w.]*", re.I)
def _on(doc):
"""The `on:` mapping, which PyYAML parses as the boolean True."""
return doc.get(True) if True in doc else doc.get("on")
def _job_runs_on_macos(job) -> bool:
"""Whether ``job`` schedules a macOS runner.
Reads `runs-on` and, when that is a matrix expression, the matrix values it selects
from. Scanning the whole job instead was the first cut and it over-matched badly:
`workflow-trigger-lint.yml` and `studio-inference-smoke.yml` both have ubuntu-only jobs
that merely NAME macOS somewhere in a step, and both were reported as macOS workflows.
A guard about runner slots has to read what actually allocates a runner.
"""
runs_on = job.get("runs-on")
values = runs_on if isinstance(runs_on, list) else [runs_on]
for value in values:
if not isinstance(value, str):
continue
if MACOS.search(value):
return True
# `runs-on: ${{ matrix.os }}` -- resolve against the matrix it names.
for key in re.findall(r"matrix\.([\w-]+)", value):
matrix = (job.get("strategy") or {}).get("matrix") or {}
candidates = list(matrix.get(key) or [])
for entry in matrix.get("include") or []:
if isinstance(entry, dict) and key in entry:
candidates.append(entry[key])
if any(isinstance(c, str) and MACOS.search(c) for c in candidates):
return True
return False
def _macos_workflows():
"""Workflows with at least one macOS leg."""
for path in sorted(WORKFLOWS.glob("*.yml")):
text = path.read_text(encoding = "utf-8")
doc = yaml.safe_load(text)
if not isinstance(doc, dict) or not isinstance(doc.get("jobs"), dict):
continue
if any(_job_runs_on_macos(j) for j in doc["jobs"].values() if isinstance(j, dict)):
yield path.name, doc, text
def test_the_scan_finds_the_macos_workflows_it_claims_to():
"""A scan that matched nothing would pass every check below."""
names = {name for name, _, _ in _macos_workflows()}
for expected in (
"studio-mac-ui-smoke.yml",
"studio-mac-inference-smoke.yml",
"studio-mac-install-matrix.yml",
"studio-tauri-smoke.yml",
"mlx-ci.yml",
"clean-machine-install-ci.yml",
):
assert expected in names, f"{expected} is no longer detected as having a macOS leg"
def test_no_macos_workflow_runs_on_every_push_to_main():
offenders = []
for name, doc, _ in _macos_workflows():
push = (_on(doc) or {}).get("push")
if not isinstance(push, dict):
continue # no push trigger at all is the strongest form of this
if not push.get("paths") and not push.get("paths-ignore"):
offenders.append(name)
assert not offenders, (
f"these workflows run macOS jobs on EVERY commit to main: {offenders}. macOS is "
f"capped at five concurrent jobs account-wide, so an unfiltered push trigger here "
f"oversubscribes the whole account on commits that cannot affect what it tests. "
f"Mirror the pull_request paths onto push, as clean-machine-install-ci.yml and "
f"mlx-ci.yml do."
)
@pytest.mark.parametrize(
"name",
[
"studio-mac-ui-smoke.yml",
"studio-mac-inference-smoke.yml",
"studio-mac-install-matrix.yml",
"studio-tauri-smoke.yml",
"clean-machine-install-ci.yml",
"mlx-ci.yml",
],
)
def test_the_push_filter_matches_the_pull_request_filter(name):
"""Narrower on push than on PR would drop the post-merge backstop.
The two lists are the same question asked twice -- "could this commit break this
workflow" -- so they drifting apart is always a bug, in whichever direction. A push
list that is a strict subset silently stops testing something after merge that was
tested before it, which is the more dangerous direction and the harder to notice.
"""
doc = yaml.safe_load((WORKFLOWS / name).read_text(encoding = "utf-8"))
on = _on(doc) or {}
pr_paths = (on.get("pull_request") or {}).get("paths")
push_paths = (on.get("push") or {}).get("paths")
assert pr_paths, f"{name} no longer scopes its pull_request trigger"
assert push_paths, f"{name} no longer scopes its push trigger"
assert sorted(pr_paths) == sorted(push_paths), (
f"{name}: the push and pull_request path filters have drifted apart.\n"
f" only on pull_request: {sorted(set(pr_paths) - set(push_paths))}\n"
f" only on push: {sorted(set(push_paths) - set(pr_paths))}"
)
def _covered(path: str, patterns) -> bool:
"""Whether ``path`` matches any Actions path filter in ``patterns``."""
import fnmatch
for pattern in patterns:
if pattern == path or fnmatch.fnmatch(path, pattern):
return True
if pattern.endswith("/**") and path.startswith(pattern[:-2]):
return True
return False
@pytest.mark.parametrize(
"name",
[
"studio-mac-ui-smoke.yml",
"studio-mac-inference-smoke.yml",
"studio-mac-install-matrix.yml",
"studio-tauri-smoke.yml",
],
)
def test_every_helper_a_workflow_executes_is_in_its_trigger(name):
"""A scoped trigger must list the checked-in files the workflow actually runs.
Scoping a trigger is only safe if the list is complete, and these lists were not: five
helper scripts and one auditor were executed by name and matched no pattern. While the
push trigger was unfiltered that gap was invisible, because every commit ran everything
after merge; narrowing the trigger is what turns it into a real hole, where editing
`assert-llama-loads.sh` stops running the workflow that asserts with it.
Matched by looking for the path in a `run:` body, which is how every one of these is
invoked. That deliberately says nothing about files a workflow depends on more
loosely -- `studio/package.json` reaches the Tauri build through
`npm install --prefix studio` and is listed by hand, not found here.
"""
doc = yaml.safe_load((WORKFLOWS / name).read_text(encoding = "utf-8"))
on = _on(doc) or {}
runs = "\n".join(
str(step.get("run", ""))
for job in doc["jobs"].values()
if isinstance(job, dict)
for step in job.get("steps") or []
if isinstance(step, dict)
)
referenced = {
ref.strip()
for pattern in (r"\.github/scripts/[\w./-]+", r"(?:^|\s)scripts/[\w./-]+")
for ref in re.findall(pattern, runs, re.M)
}
existing = sorted(r for r in referenced if (REPO / r).is_file())
assert existing, f"{name} appears to execute no checked-in helper; the scan is wrong"
for trigger in ("pull_request", "push"):
patterns = (on.get(trigger) or {}).get("paths") or []
missing = [r for r in existing if not _covered(r, patterns)]
assert not missing, (
f"{name}: these files are executed by the workflow but match no {trigger} path "
f"filter, so editing one of them does not run the workflow that uses it: "
f"{missing}"
)
@pytest.mark.parametrize(
"name",
[
"studio-mac-ui-smoke.yml",
"studio-mac-inference-smoke.yml",
"studio-mac-install-matrix.yml",
"studio-tauri-smoke.yml",
],
)
def test_a_listed_python_input_brings_its_sibling_imports(name):
"""Listing a script but not the module it imports leaves half a dependency in the filter.
`studio/install_llama_prebuilt.py` was listed; `studio/prebuilt_core.py`, which it
imports at line 55, was not. Editing only the latter changed exactly what the install
matrix asserts on and did not run it.
Scoped to same-directory imports on purpose. The full transitive closure of an
installer is most of the repo, and chasing it would put `pyproject.toml` and every
requirements file into a macOS trigger, which is how a filter stops saving anything.
Where a deeper dependency matters it is listed by hand with a comment saying why; this
covers the one case that is mechanical and therefore easy to forget.
"""
import ast
doc = yaml.safe_load((WORKFLOWS / name).read_text(encoding = "utf-8"))
on = _on(doc) or {}
patterns = (on.get("pull_request") or {}).get("paths") or []
missing = []
for pattern in patterns:
source = REPO / pattern
if not (source.is_file() and source.suffix == ".py"):
continue
tree = ast.parse(source.read_text(encoding = "utf-8", errors = "replace"))
names = set()
for node in ast.walk(tree):
if isinstance(node, ast.Import):
names.update(a.name.split(".")[0] for a in node.names)
elif isinstance(node, ast.ImportFrom) and node.level == 0 and node.module:
names.add(node.module.split(".")[0])
for module in sorted(names):
sibling = source.parent / f"{module}.py"
if not sibling.is_file():
continue # stdlib or third-party, not a checked-in sibling
rel = sibling.relative_to(REPO).as_posix()
if not _covered(rel, patterns):
missing.append(f"{rel} (imported by {pattern})")
assert not missing, (
f"{name} lists a Python input but not a module it imports from the same directory, "
f"so editing that module does not run the workflow that depends on it: {missing}"
)
def test_a_commit_that_touches_nothing_relevant_starts_no_macos_job():
"""The property the whole change exists for, checked against a concrete commit.
README-only is not a hypothetical: commit 6371f46a is exactly that, and it started
four macOS workflows. Matching is by the same prefix/glob rules Actions uses, kept
simple deliberately -- every filter in these files is either a literal, a `dir/**`
prefix or a single `*` glob, and this asserts that stays true so the simple matcher
cannot quietly become wrong.
"""
import fnmatch
changed = ["README.md"]
triggered = []
for name, doc, _ in _macos_workflows():
push = (_on(doc) or {}).get("push")
if not isinstance(push, dict):
continue
for pattern in push.get("paths") or []:
assert "!" not in pattern, (
f"{name} uses a negated push path ({pattern!r}); this matcher does not "
f"model negation, so extend it before relying on this test"
)
for path in changed:
if fnmatch.fnmatch(path, pattern) or (
pattern.endswith("/**") and path.startswith(pattern[:-2])
):
triggered.append(f"{name} via {pattern!r}")
assert not triggered, (
f"a README-only commit still starts macOS jobs: {triggered}. That was the "
f"original symptom: seven macOS legs against a five-slot cap for a docs typo."
)