Skip to main content
Shard counts, concurrency and matrix budgets, lint memory policy, Android rows, and cache-key bounds. Part of the CI scope and routing index. The standalone UI suite runs three native Vitest shards through the same group executor and cache leaf as its bounded four-file seed in the trusted warmer. Each row retains the root Node worker limit of three; Chromium uses its project default. The shards preserve the complete four-project inventory and each project’s isolation and cleanup policy. Every frozen target keeps its original singleton, unsharded test command. The window.open lint runs once in row one. The extra two jobs add two Blacksmith registrations per selected non-frozen run on Blacksmith routes, and none on hosted routes. They do not guarantee an eight-minute workflow: preflight, setup, queue time and other jobs still apply. Its native reporter records runtime CPU and memory facts, configured project workers, module diagnostics, and observed queue/end events. Browser pool logs record actual Chromium sessions. Project counts at run start describe discovery before sharding; completed module identities and final counts prove coverage. Event intervals are not scheduler-admission times; repeated environment/prepare durations must not be summed into wall time. These receipts do not establish transform-cache hits. Tooling stripes install Go only when their selected files include the docs translation test; historical whole-config plans retain their existing setup. The workflow pins the runner’s Go version so frozen targets cannot select a different compiler. Updates keep this pin aligned with the current translation module’s preferred toolchain and both Testbox bootstrap workflows. Shell-heavy macOS signing and elevation cases admit up to three cases per file, capped at Node’s available parallelism. Independent checkout fixture tables retain their two-case limit. Each case owns its commands and temporary roots; cleanup joins its process tree and callback work before removing those inputs. Outer suites and the remaining checkout contract cases stay sequential. Once admitted, canonical Linux CI permits up to 96 concurrent Node test jobs. The manifest separately enforces total-job budgets: 70 Node rows for canonical pushes and 130 for canonical PRs, including precise and plugin plans. GitHub also caps one job’s combined outputs at 1 MiB measured in UTF-16, so preflight has 524,288 characters for every matrix together. Grouped Node rows list each striped test file explicitly. The manifest projects the five fields consumed by the shard runner, then uses gzip+base64 (groups_gzip_base64) when the target contains the codec. Historical targets without that capability receive the same projection through legacy groups JSON. Workflow tests keep the complete generated output under half of the cap. The smaller fast/check lanes remain capped at 12; Windows is capped at two and Android at two because those runner pools are narrower. Compact whole-config batches run with a 120-minute batch timeout, while include-pattern groups share the same bounded job budget. Type-aware lint on CI runners with fewer than 8 CPUs or 24 GiB of RAM uses the existing Go compiler memory policy (GOGC=30, GOMEMLIMIT=3GiB) to reduce swap pressure. Explicit Go settings remain authoritative. The limit is soft and applies only to the lint child; declaration preparation retains its own policy. Explicit core-stripe invocations keep src/agents, src/gateway, src/infra, and ui in separate lint processes from their stripe’s remaining targets. Their semantic caches can exceed the Go soft limit when combined with neighboring targets. Constrained runners execute these processes serially and release each process tree before starting the next. The five stripe assignments, workflow rows, lint rules, and file coverage stay unchanged; this adds no runner registrations. Automatic full lint (pnpm lint) retains its original five aggregated core Programs, including when it inherits CI environment variables. Published Git updaters call this full pipeline with a fixed 20-minute command deadline; the explicit stripe caller must not add compiler startups to that preflight. Regular Android PR/main CI and PR release_gate dispatches use four rows: Play and Wear-shared unit tests/lint, third-party unit tests/lint, Wear unit tests/lint, and Kotlin lint for all four modules. Each phone flavor has its own source set and SensitiveFeatureConfig; apps/android/app/src/thirdParty/AndroidManifest.xml declares additional permissions and components. The Kotlin-lint row also compiles the benchmark when benchmark or Android build/dependency inputs change; missing or unusable changed-path data keeps that build. Ordinary full-scope manual validation retains six Android rows: the three test rows, build-play, build-wear, and Kotlin lint. The build rows own lint without repeating it in test rows. build-play assembles both phone flavors and the Wear shared module and compiles the benchmark; build-wear assembles Wear. build-play-compat retains Play-only packaging for older frozen targets. GitHub-hosted build-play gets a 35-minute job budget for its three memory-bounded Gradle invocations. Combined test-play and test-third-party unit tests and lint get 35 minutes on either runner route. Third-party Gradle invocations have completed in 18–19 minutes before checkout, toolchain setup, and cleanup. In an observed Play run, unit tests completed in 13 minutes 52 seconds, then lint was cancelled at the 20-minute job limit; this does not establish the full lint duration. Both test tasks without lint, Blacksmith build-play, and all other Android tasks retain 20 minutes. The budget follows the current attempt’s runner route even when a retry reuses the original preflight matrix. Each current Gradle task has one protected sticky disk; PR jobs use disposable clones, while protected runs refresh content-addressed Gradle entries in place. Existing Android opt-in and npm qualification deferral are unchanged. Robolectric resolves Android SDK artifacts outside Gradle’s dependency cache, so every Android test-* task receives a workflow-owned Gradle init script that points test JVMs at a dedicated Maven-local repository. Actions cache restores are task-, platform-, and Android-contract-scoped; a prefix restore can seed a changed contract, but only a successful trusted run may publish the completed exact cache after a miss. Cold runs may download missing SDK artifacts, while warm runs reuse the exact archive. Build and lint tasks do not receive the Robolectric init script. Remaining Blacksmith sticky-disk keys are deliberately bounded by supported task dimensions, never PR number, commit, run, branch, or dependency hash. Dependency, runtime transform, and compile caches use Actions cache instead because immutable archives expose verifiable restore/save results and avoid mutable snapshot-promotion failures. After a sticky key-version migration, add only the exact obsolete key, architecture, and region identities to .github/retired-sticky-disks.json, dispatch Sticky Disk Cleanup from main with the same dimensions and confirmation, verify deletion, then remove those entries. The workflow routes ARM identities to an ARM runner, rejects runner-region mismatches, uses Blacksmith’s exact-key deletion action, and never deletes Docker builder caches or wildcard prefixes. Actions cache archives use normal LRU and inactivity eviction. The check-dependencies shard runs Knip dependency, unused-file, and unused-export checks. Both guards enforce zero findings across production and full-tree scans, with no unused-file allowlist. The export guard also audits script entry exports. Production excludes test-support consumers; the full-tree and script scans include tests as consumers. Model intentional dynamic consumers in config/knip.config.ts, config/knip.all-exports.config.ts, or config/knip.scripts-exports.config.ts as appropriate. Each guard reports every scan outcome and fails if any scan fails. Historical targets run the export guard when they provide it and retain their older dead-code fallback otherwise.