* ci: consolidate CI workflow from 15 jobs to 8
Merge single-gate ubuntu jobs into grouped jobs sharing one checkout and
install: Lint & Format (plus the static text assertions), Repo Guards
(layering/selector/wiring/maestro/mcp-metadata), Compatibility &
Provenance (shared fetch-depth: 0 checkout), Typecheck & Package, and
Integration Tests (absorbs the web smoke with step-scoped env). Every
gate remains an independently named run-gate step; the gate manifest
derives lane ownership structurally.
Drop the Bun setup from FreeRange: @chenglou/freerange's bin is a plain
Node script. It stays GitHub-owned; only the runtime requirement is
retired.
* ci: fold FreeRange into Repo Guards and skip no-op fixture release jobs
FreeRange runs on plain Node now, so its gate joins Repo Guards as the
last step instead of occupying its own worker for the slowest guard.
The fixture release matrix filters to entries that will actually build,
so a cached-fingerprint PR starts zero release runners.
* ci: fold host XCTests into the macOS smoke lane and shard Coverage
The macOS lane now builds one unit-test-flagged runner bundle that both
the host XCTest run and the replay smoke consume, so the host lane no
longer occupies its own macos-26 runner behind a separate queue. The
host lane's file moves with it, and check:xctest-selection follows.
Coverage shards across two runners via blob reports and merges them on
a report job that evaluates thresholds once over the full suite and
produces every coverage artifact. The tmpdir leak check runs per shard,
since a leak lands on whichever runner executed the file.
* ci: drop local shard-smoke artifacts from tracking
* ci: enforce coverage thresholds only on the merged run
A shard evaluates its own half-suite coverage, so the global gate fired
per shard. Shards now report without gating; Coverage Report keeps the
real thresholds over the full merged suite.
* ci: include hidden files when uploading coverage blobs
Every declared AgentDeviceRunnerUITests method now belongs to a lane, and
the #if guard is the classification: AGENT_DEVICE_RUNNER_UNIT_TESTS alone
means a pure runner decision (runs on the macOS host on every PR — ci.yml's
existing compile job now executes the bundle it builds), '&& os(iOS)' means
runner/XCTest semantics (simulator lanes only). check:xctest-selection
evaluates the guards per platform, derives each lane's reach, and fails on
a flagged identifier that is undeclared or uncompiled on that lane, on a
declared test no lane reaches (found the two tvOS-only tests, dark since
birth — widened to os(tvOS) || os(macOS)), and on testCommand reaching any
lane. The host and nightly lanes assert executed == derived reach, so a
missing -D flag or a guard that compiles a file out reads red, not as a
smaller green. One duplicate test deleted (sparse-verdict assertions folded
into its twin).
* ci(ios): run the full XCTest suite nightly and check the PR test list (#1781 A7)
* fix(ci): skip the runner server entry point in the nightly and validate both test flags
* docs(ci): restate the nightly lane cost and timeout honestly
* docs(ci): stop quoting XCTest counts that drift between commits
* ci(ios): tighten the nightly timeout to the measured suite duration