Repository navigation
ci: move release toolchain builds to hosted runners - #777
luisleo526 wants to merge 4 commits into
Conversation
Split hosted x86 and ARM builds from one write-scoped release upload. Bind the private toolchain reader and verify actual archive bytes before publication. Retain the released-archive GLIBC comparison and packed native consumer. Update the routing documentation and explicitly supersede these earlier claims: - Release keeps its exact protected GKE pins in runner group 15; baseline promotion runs on hosted ubuntu-24.04. - e7fa559's short sentence "Hosted workflows declare nothing." is replaced by the current explicit per-job hosted runner map. - Credentialed release work keeps protected GKE runner group 15. - Only release.yml still names protected gkp-od-* scale sets. - Release uses protected GKE runner group 15 for its x64 artifact only. - Linux x64 prebuilt uses gkp-od-16cpu-32gb-amd64-128gb; baseline promote uses hosted ubuntu-24.04. - The x86_64 prebuilt requires 16 CPU/32 GB and 128 GB storage, plus the preloaded immutable Bookworm Docker image. - The secret-free gke-* credential ban stays binding. - The workflow-level contents: write setting scopes GITHUB_TOKEN. - Protected runner group 15 admits only allowlisted workflow refs at refs/heads/main; the probe keeps its release environment. - PRs build Ubuntu Release only (ci.yml); - Debug, sanitizers, kernel-only and the macOS cell run post-merge (ci-post.yml). - Only release.yml still names a protected scale set, in protected runner group 15: its x86_64 prebuilt cell. - Group 14's mirror .github/runner-group-allowlist.txt is empty because no workflow uses a group-14 label; group 15's required ref is replaced by the current empty mirror. - Release's x86_64 prebuilt cell uses gkp-od-16cpu-32gb-amd64-128gb, installs Eigen and asserts exactly 3.4.0 before CMake; the arm64 cell retains hosted execution under its separately named build job. The replacement text names the split jobs and their actual permissions, toolchain inputs and artifact checks. Source-byte and release protections remain enforced by the current admission contracts. Also supersede these bd1fa2f routing/resource statements as the named jobs move to hosted runners: - The protected 2 CPU/4 GB set runs promotion's API/tree checks, Node campaign tooling and Cloud SQL proxy; the probe reads rulesets with Python/gh. - Docs uses 4 CPU/8 GB for Doxygen and Graphviz over the full public header set before Pages upload. - The group 15 mirror lists only docs-post, promote-baseline, release-ruleset-probe and release at refs/heads/main; the current hosted routes replace that required-ref inventory.
Retain the digest-pinned repository reference and exact RepoDigests checks. Compare Docker's inspected image Id with the separately recorded config pin. Exercise the distinct identities and refusal cases in both transports, and bind admission to the actual updated helper bytes.
Use engine-release-toolchains instead of gke-runner-images for the pinned Bookworm image. Keep the manifest and Docker config identities, dedicated reader authentication, release admission and isolated build/consumer checks. Update all three release workflow image guards and their exact workflow contract. Compare the tracked image input with its complete approved repository@sha256 line, including its final newline. Add refusal controls for retired and different origins, digest and line shapes, and each pull/build/consume guard.
Make the negative control change the current pinned repository while retaining the assertions that the input changed and validation rejects it.
| from unittest import mock | ||
|
|
||
| import hashlib | ||
| import ci_preflight |
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 3 advisory finding(s) below merit a look before merge.
Not checked: tests were not run; formal verification proved 0 of 6 changed function(s) (4 sampled, not proven, 2 not verified).
Formal verification. PR-changed functions: 4/6 verified (0 proven, 4 may-equivalent, 0 distinguished) · 2 not verified (2 vacuous).
Not verified on this run: main (vacuous: never exercised), runner\_findings (vacuous: never exercised).
Graphify review — findings
Moves the x86_64 prebuilt build off the protected self-hosted GKE runner onto hosted ubuntu-24.04. The prebuilt-x86 job authenticates over OIDC as a dedicated toolchain reader, pulls a digest-pinned private Bookworm image whose reference is validated against a strict regex from a committed file instead of a repo variable, and exposes tarball and sha256 outputs for later jobs. Drops the self-hosted runner label and the group-15 allowlist entry, and defaults workflow permissions to contents: read with contents: write granted only on the release job. Adds a PR-triggered diagnostic workflow that records host identity and Docker driver/version on a hosted runner, limited to same-repo PRs touching the release build inputs. The preflight and release-gate tests are updated to pin the new hosted routing, the file-based image binding, and the emptied runner-group mirror.
Worth a look
- Release asset upload bypasses protected environment —
.github/workflows/release.yml:714· Escalate · high- NOT verified (no proof, no reproducing execution) — needs human review
- Self-hosted label and group-15 route removed while release.yml still appears to use them —
.github/actionlint.yaml:3· Escalate · medium- NOT verified (no proof, no reproducing execution) — needs human review
- Job output
sha256is wired to the hex digest, not the.sha256checksum file —.github/workflows/release.yml:372· Escalate · medium- NOT verified (no proof, no reproducing execution) — needs human review
Review partial — this diff was larger than one review pass covers, so later files were not reviewed; some findings may be missing.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 1524 functions depend on the 1517 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
ci_workflow_findings()— 84 callers, 24 callees - worse:
_job_values()— 32 callers, 3 callees - worse:
_job_block()— 19 callers, 3 callees - worse:
runner_findings()— 2 callers, 28 callees - worse:
release_prebuilt_workflow_findings()— 8 callers, 7 callees - new:
release_option_c_workflow_findings()— 3 callers, 8 callees - worse:
legacy_release_workflow()— 5 callers, 3 callees - worse:
main()— 1 callers, 14 callees
Verification — 1524 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 1524 function(s) in the blast radius were not formally verified this run
Docs that may be stale (advisory)
CHANGELOG.md§ Unreleased (lines 8-175): references changed symbolsstepCHANGELOG.md§ CI and release process (lines 763-824): references changed symbolsworkflowCHANGELOG.md§ 1.1.0 — 2026-10-04 (lines 3145-3359): references changed symbolsstepdocker/README.md§ Two-phase run (lines 98-274): references changed symbolsstepdocs/checked-settings.md§ Validation and receipt (lines 72-128): references changed symbolsstepdocs/coverage.md§ Inputs (lines 555-588): references changed symbolsstepdocs/design/native-feature-parity.md§ 2.iv Native HTF for bare hosts (L6) — chosen design per R5-6 (lines 292-310): references changed symbolsstepdocs/pages/examples-python-sweep.md§ Walk-forward variant (lines 145-169): references changed symbolsstepdocs/pages/native-engine.md§ The auxiliary finer feed (lines 2732-2928): references changed symbolsstepdocs/pages/public-contract.md§ Versions (lines 99-124): references changed symbolsworkflow
…and 9 more.
Formal verification
No difference found (not proven): No behavior difference found in actionlint\_runner\_label\_findings (not a proof).
The verifier ran both versions of actionlint\_runner\_label\_findings on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
No difference found (not proven): No behavior difference found in ci\_workflow\_findings (not a proof).
The verifier ran both versions of ci\_workflow\_findings on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
Could not verify: Could not verify main.
The verifier did not have enough to check main, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 1 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly NameError — names the real obstacle, not a sampling gap)
No difference found (not proven): No behavior difference found in release\_credential\_findings (not a proof).
The verifier ran both versions of release\_credential\_findings on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
No difference found (not proven): No behavior difference found in release\_prebuilt\_workflow\_findings (not a proof).
The verifier ran both versions of release\_prebuilt\_workflow\_findings on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
Could not verify: Could not verify runner\_findings.
The verifier did not have enough to check runner\_findings, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: non-vacuity: domain too small (only 2 distinct inputs exercised, need 3) — 'no divergence' would be near-vacuous
· 3 grounded finding(s) anchored inline below; 5 more finding(s) on lines outside this diff (see the check run).
| docker info --format '{{.Driver}}' | ||
| ''' | ||
|
|
||
| def release_option_c_workflow_findings(workflow: str) -> list[str]: |
There was a problem hiding this comment.
release_option_c_workflow_findings()
fans out to 8 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| @@ -3575,6 +4116,8 @@ def release_prebuilt_consumer_findings(source: str) -> list[str]: | |||
|
|
|||
| def release_prebuilt_workflow_findings(workflow: str) -> list[str]: | |||
There was a problem hiding this comment.
release_prebuilt_workflow_findings()
fans out to 7 callees (efferent coupling); 8 callers depend on it (afferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| ' needs: [release, prebuilt]\n', 1) | ||
|
|
||
|
|
||
| def legacy_release_workflow(workflow): |
There was a problem hiding this comment.
legacy_release_workflow()
high coupling complexity (Ca·Ce = 15).
Grounded coupling-delta finding (deterministic), not an LLM guess.
The x86 release job depends on a preloaded self-hosted toolchain. Move it to a standard hosted runner using a digest-pinned Bookworm image from Artifact Registry, and separate the platform builds from the write-scoped upload job.
Keep the dedicated read-only image identity, exact release admission, non-root isolated build and packed-artifact consumer, released-baseline GLIBC comparison and archive checksums before publication. Add a secret-free hosted diagnostic and mutation checks for the image reference, authentication, workflow ordering and artifact bytes.
Validation: the complete release-gate test module passed 294 tests, followed by seven admission tests and three source-loading smoke tests, without skips. The parent’s stale negative control failed at its unchanged-input assertion; the corrected control changes the active repository segment and verifies rejection.
Current-head PR CI and parity remain required. Whole current-head preflight/helper module coverage and real hosted authentication, pull, image-id/storage-driver behavior, build, consumer execution and release-leg timing remain to be observed through their normal runs.
🤖 Generated with Claude Code