Pre-release Harn is pre-1.0 — the language, standard library, and CLI may change between releases. See the release notes

Release runner policy

Release binary runner labels are data, not workflow control flow. The source of truth is .github/release-runner-policy.json; scripts/release_runner_matrix.sh validates that document and resolves the matrix consumed by build-release-binaries.yml.

Each target declares five labels:

  • warm: routine default-branch cache refreshes.
  • primary: tag-push release builds on the product critical path.
  • recovery: manual tag recovery when no override is requested.
  • standard: an explicit standard-capacity recovery or benchmark override.
  • fast: an explicit latency-prioritized recovery or benchmark override.

Primary and warm builds always use policy. Recovery accepts policy, standard, or fast; the default is policy. The non-publishing benchmark mode requires an explicit target subset and either standard or fast. It compiles and runs the binary-size gate, but cannot sign, notarize, package, upload, finalize a release, publish a container, or save a cache.

gh workflow run build-release-binaries.yml \
  --ref <branch> \
  -f benchmark_only=true \
  -f runner_profile=fast \
  -f targets=x86_64-apple-darwin

The policy is also the source of truth for metered runner rates, source URLs, and their effective date; the approximate costs below are projections from that data. GitHub rounds each job to a whole minute. See Actions runner pricing, the larger runner reference, and Blacksmith pricing.

Current decision#

Use macos-15-intel for policy-selected x86_64-apple-darwin builds and macos-latest for native workspace certification by default. Keep the proven Blacksmith M4 and GitHub xlarge profiles available only for explicit incident or benchmark dispatches. Routine main pushes, scheduled cache refreshes, certification, and shipping therefore stay on the public repository's free standard capacity unless an owner opts into a paid profile.

The public repository uses GitHub-hosted release capacity by default. Set the repository Actions variable HARN_RELEASE_ENABLE_BLACKSMITH_MACOS=true to opt policy-selected primary and recovery Intel builds into Blacksmith. Explicit standard and fast recovery or benchmark profiles still honor the operator's selected profile. Set HARN_RELEASE_ENABLE_BLACKSMITH_LINUX=true to opt release and benchmark CLI AOT preparation into Blacksmith; warm-cache runs use ubuntu-latest regardless. Leave both variables unset unless a reviewed release incident justifies paid capacity.

The primary and recovery choice is based on a same-source cold-cache pair. Both runs used Harn source commit 34e00360c1f310b364b92dd2e4aeabeddde46528, the same target, AOT payload, thin-LTO profile, and 16 codegen units. The branches differed only in runner policy, and both reported Swatinem cache hit: false.

ReceiptRunnerCargo durationJob durationCost
GitHub M2 benchmarkmacos-15-xlarge10m01s10m25sabout $1.12 before credits
Blacksmith M4 benchmarkblacksmith-12vcpu-macos-155m30s5m53sabout $0.96

Blacksmith saved 4m31s of Cargo time, or 45.1%, and 4m32s of job wall time over the credit-eligible GitHub M2 recovery. More importantly, it cut 18m39s from the previously selected cache-hit Intel Large job. Harn published 60 v0.10.x releases in the 30 days ending 2026-08-09. At that unusually high cadence, the measured Blacksmith macOS job projects to about $58 per month. The 16-vCPU Blacksmith AOT job adds about $6 per month at the same cadence.

A second Blacksmith validation run identified the cross-compiled output as an x86_64 Mach-O and executed harn --version under Rosetta. The downloaded artifact independently passed the same execution check, then passed ad-hoc signing, strict signature verification, and another x86_64 execution on an Apple Silicon host.

CLI AOT preparation used to take 4m57s on standard Linux in the same benchmark cohort. A controlled 16-vCPU Blacksmith run finished that job in 2m26s. A GitHub 16-core trial was abandoned after five minutes without runner assignment, so it is not a production fallback. The measured AOT plus primary macOS job is about 8m19s before the sub-minute signing and notarization tail; this is a component-path estimate, not a completed release SLO claim.

Cache availability remains the larger lever. The v0.10.67 release missed its cache and spent 79m05s in Cargo on standard Intel. A warm standard runner cut that to 36m38s without paid capacity. The ARM runners complete cold builds faster than that warm Intel path, so primary release latency no longer depends on an x86 cache hit. Intel cache warms remain useful for the emergency standard fallback and retain the repository's existing storage budgets and pruning.

Compiler-cache backends#

Each target also declares sccache_backend next to use_sccache:

BackendMeaning
stickyBlacksmith sticky-disk SCCACHE_DIR. Hosted runners for the same target fall back to the bounded local blob cache.
localBounded local SCCACHE_DIR restored/saved as one Actions cache blob. SCCACHE_GHA_ENABLED=false.
installHistorical Linux install path through .github/actions/sccache-install.
noneExplicit skip with a job-summary reason.

The per-object GHA sccache backend stays off. Windows previously failed mid harn-vm compile with os error 10054 (#2114), and the hosted per-object trial spent 5.35 GiB for negligible hits (v0.10.39). Local blob persistence is the next-best reusable boundary on hosted macOS ARM and Windows: restore once before compile, save once after, never talk to the cache API during rustc.

Every Build job records cache mode, hit/miss statistics (or an explicit skip reason), and Build-step wall time in the job summary. Warm and candidate modes compare that Build-step duration to .github/release-warm-build-budget.json, which ratchets from the measured v0.10.65 fanout (run 31288092986). Queue time and skipped targets do not count.

An earlier cold-cache benchmark saved only 55 seconds on Large. That result correctly blocked adoption at the time, but cold dependency compilation is not the intended steady-state Intel release path. The later cache-hit pair showed a 36.1% Intel Large advantage and justified the first paid default; the controlled ARM pair above supersedes it with a faster and cheaper primary.

Update this table and any primary label change only from an observed workflow/job receipt. Force standard capacity if Blacksmith has two consecutive runner/platform failures, if the primary job p95 exceeds 10 minutes over five releases, or if projected release-runner spend exceeds $150 per month without a matching release cadence. Do not infer a capacity win from runner specifications alone.