Full vs affected · cache key monotonicity · read-only fan-out · six-step gate and full fallback
Teams running a large monorepo across multiple remote Mac Mesh nodes often burn CI capacity on accidental full builds: cache keys drift, the affected graph disagrees with runner labels, or consumers pull half-written caches. This article gives a full vs affected vs dedicated heavy-compile node decision matrix, defines reproducible input boundaries and read-only fan-out roles, and adds a six-step gate with explicit fallback to full builds. Cross-read with cross-region artifact fan-out and Merge Queue and runner labels.
Affected workflows depend on the change graph, lockfiles, and toolchain fingerprints staying aligned across regions. When interactive sessions share the same cache prefix as unattended jobs, phantom dependencies and hand-copied DerivedData corrupt keys so affected silently expands toward full work without showing up as queue pressure.
Pair this guide with cache locality and artifacts for byte paths; here we focus on graph pruning and triggers. If ci-merge is not split from regular PR runners, read the Merge Queue article first.
Graph vs label drift: Different runner labels resolve different workspace roots so affected sets diverge.
Lockfile missing from keys: Resolver output changes while the cache still hits an old tarball.
No toolchain segment: Minor Xcode or Swift patches are absent from manifests, causing silent consumer mismatch.
Fan-out mixed with compute: Consumers can write cache prefixes, racing affected decisions.
Missing full fallback: Core packages or codegen scripts change but pipelines still force affected only.
Dimensions below target monorepo pipelines on multi-region remote Mac pools, not a single laptop.
| Dimension | Prefer full | Prefer affected | Split a heavy node |
|---|---|---|---|
| Change type | Codegen, build scripts, shared native surfaces | UI and copy inside one app package | Nightly bulk heavy modules vs daytime PRs on one pool |
| Queue signals | Two affected failures in a row or flaky integration | Stable graph and lockfile checks match | CPU idle but wall time high; interactive users complain |
| Cache key | Boost toolchain weight; temporarily disable cross-node reuse | Lockfile + change hash + runner OS layer | Heavy node uses isolated prefix; fan-out stays read-only |
| Cross-region | Single manifest generation before compile | Mirror lag allowed but no writes to primary prefix | Primary region writes; satellites read |
| Fallback to full | Before first green after protected merge | Scheduled weekly full as drift control | Mandatory full week after major Xcode moves |
Freeze reproducible inputs before tuning affected; reversing the order moves flaky builds from compilers into schedulers.
Assume runners can SSH across the pool per shared pool SSH. If bytes still cross oceans, apply manifest and lease fields from artifact fan-out.
Freeze the input triple: Commit, lockfile digest, and xcodebuild -version fingerprint in the pipeline header; any change bumps cache generation.
Emit the graph once: Parse affected packages on a fixed runner label and publish the list as an artifact; forbid per-node guessing.
Full-build thresholds: Short-circuit to full when codegen, shared kernels, or toolchain upgrade lists hit; record an audit reason code.
Primary write prefix: Only the primary builder writes; satellites use read-only credentials and never push DerivedData upstream.
Fan-out verify: Hash and size dual-field checks on archives before pointer flip; block compiles on failure.
Retry and rollback: Retry network errors with backoff; checksum failures open an incident and force full on the next commit until green.
CACHE_KEY="${CI_COMMIT_SHORT_SHA}:${LOCKFILE_SHA256}:$(xcodebuild -version | shasum -a 256 | cut -c1-12)"
export TURBO_REMOTE_CACHE_SIGNATURE="${CACHE_KEY}"
echo "affected=$(npx turbo run build --dry=json | jq -r '.packages | length')" > "${CI_PROJECT_DIR}/affected.meta"
Note: Swap Turbo for Nx, Bazel, or your own script; the invariant is a single authoritative graph and a monotonic cache key.
The painful conflict is two PRs bumping a shared package while cache prefixes interleave. Split identities: only CI primaries may write; readers compile remotely. Avoid syncing local DerivedData back into shared prefixes.
Combine with seat locks by embedding lease ids in cache paths, and reuse envelope fields from observable task chains for alerts.
Warning: Do not open multi-region fan-out before write permissions are removed; half-sync becomes multi-site false green.
Single writer: One lease may write a cache prefix at a time; others queue or use separate stage paths.
Consumer rule: Start compiles only after manifest generation is marked current.
Human gate: After two checksum failures, freeze affected until a signed-off full build is green.
Numbers below are planning defaults; replace them with your repository histograms. Do not treat them as public SLA statements.
When nightly affected jobs share disk with interactive indexing, CPU alone will mislead; chart tarball extract writes next to IDE writes.
| Team signal | Starting posture | Fan-out coupling |
|---|---|---|
| Small contributor base | Single region primary build plus local affected | Low fan-out; keep keys simple |
| Multi-region PRs | Primary writes cache; satellites read with manifest | Couples tightly to rsync or object storage fan-out |
| AI agent night jobs | Isolate heavy compile nodes from interactive pools | Prevents agents from exhausting shared key space |
Personal laptops as compile gateways fail on sleep, screen lock, and unstable uplinks together. Owned hardware is also slow to procure and depreciate on fixed cycles.
For teams that need contracted nodes, auditable bandwidth, and selectable regions while keeping iOS delivery and AI night workloads on one capacity story, VpsMesh Mac Mini cloud rental is usually the better fit: roles split cleanly, links auditable, and affected hit rates become reviewable like queue depth.
Use full builds for codegen, build scripts, shared native surfaces, and toolchain upgrades; also before the first green build after a protected merge. See the cross-region artifact matrix for fan-out gates.
Include commit or graph digest, lockfile hash, toolchain fingerprint, runner OS layer, plus generation and lease id for fan-out. Regions and SKUs are on the order page.
Open the help center for remote access and network items, and read the pricing page before choosing regions.