Skip to content

[ABI] Stage exact candidates and prove admitted Pages products - #1247

Open
brandonpayton wants to merge 89 commits into
mainfrom
emdash/homebrew-pr-staging-1q1w6
Open

[ABI] Stage exact candidates and prove admitted Pages products#1247
brandonpayton wants to merge 89 commits into
mainfrom
emdash/homebrew-pr-staging-1q1w6

Conversation

@brandonpayton

Copy link
Copy Markdown
Member

Why

An application binary interface (ABI) change updates the contract
between Kandelo programs, the kernel, and the host runtime. We need to
rebuild and test the complete package and virtual-file-system (VFS)
product graph for the exact pull-request commit before that change
reaches main.

The previous release path did not provide one safe way to do that.
Candidate jobs could build useful artifacts, but those artifacts were
not consistently separated from trusted release metadata or bound to
the exact source, build policy, package inputs, and browser runtime that
produced them. A partial or stale result could also look ready to
publish.

This change adds an inert staging path. Candidate artifacts are public
and explicitly non-endorsed. Protected jobs verify them, and only
complete, current, admitted product sets can become inputs to a Pages
canary. Building a candidate does not promote a Homebrew bottle, deploy
Pages, or delete an older artifact.

What changed

  • Define exact-source request, candidate, verification, admission,
    retry, and evidence records with canonical hashes and bounded inputs.
  • Make VFS product manifests and consumer registries authoritative for
    the complete required product graph.
  • Build candidates without credentials, then verify the exact Node and
    browser runtimes through protected runners before admitting results.
  • Bind Homebrew inputs to the corresponding tap Formula, architecture,
    bottle layer, and current tap-main metadata projection.
  • Recompose the seven Pages products from admitted Homebrew layers and
    freshly captured current inputs. Candidate VFS bytes cannot enter the
    final site.
  • Build the browser, guide, and API site once from a private sealed
    product map, and retain incomplete canaries only as bounded hold
    records.
  • Add a real Chromium snapshot gate for the exact producer-returned
    tree. It proves two eager products, five lazy activations, response
    length and digest checks, service-worker identity, and fail-closed
    corrupt or missing bytes.
  • Add workflow mutation tests that keep promotion disabled, Pages
    activation on the legacy path, and candidate cleanup in observe-only
    mode.

The matching tap-side staging and admission implementation is
kandelo-dev/homebrew-tap-core#234. It should land first so the Kandelo
main-push canary observes the reviewed tap contracts.

Validation

All commands below ran from the repository dev shell on commit
2144e0c76be7b647b0df760402dabc1803c6de9e.

  • Combined Pages, producer, Node evidence, and browser evidence tests:
    188 total, 186 passed, 0 failed, 2 intentionally skipped.
  • Fresh atomic site build: Vite built 191 modules, VitePress and
    TypeDoc completed, the selected producer test passed 1/1, and Chromium
    passed 5/5.
  • Pages deployment mutation suite, freshness check, structural checker,
    and exact runtime preparation: passed.
  • Rust pages_readiness: 10/10; Rust builder_contract: 17/17.
  • Homebrew runtime-support materializer: 30/30.
  • Documentation TypeScript check, service-worker syntax, actionlint, and
    diff whitespace checks: passed.

The exact intentional Node skip is executes a miniature product through the built exact-host supervisor. The other skip is the expensive
seven-product producer fixture, which the atomic gate selects and runs
explicitly before Chromium.

Rollout boundary

This pull request does not deploy production Pages, activate promotion,
or delete artifacts. The first hosted proof is the inert protected-main
canary after both pull requests land. Production Pages remains on its
legacy activation until that canary is inspected separately.

Teach the browser dependency scanner and the exact shell workflow about
the sealed Pages product virtual module. Declare the shell catalog input
and refresh the generated package, resolver, evidence, and request-policy
identities.

Align source-closure assertions with the typed builders and inventory
fixture consumers once so the complete package suite remains stable under
parallel CI load.
@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Phase B-1 matrix build status — pr-1247-staging-run-31556813868-attempt-1

ABI v42. 0 built, 76 failed, 76 total.

Package Arch Status Sha
icu wasm32 failed
libcurl wasm32 failed
libcxx wasm32 failed
libcxx wasm64 failed
libiconv wasm32 failed
libpng wasm32 failed
libxml2 wasm32 failed
libzip wasm32 failed
openssl wasm32 failed
openssl wasm64 failed
sqlite wasm32 failed
sqlite wasm64 failed
zlib wasm32 failed
zlib wasm64 failed
bc wasm32 failed
bzip2 wasm32 failed
coreutils wasm32 failed
cpython wasm32 failed
curl wasm32 failed
dash wasm32 failed
diffutils wasm32 failed
dinit wasm32 failed
erlang wasm32 failed
fbdoom wasm32 failed
file wasm32 failed
findutils wasm32 failed
gawk wasm32 failed
git wasm32 failed
grep wasm32 failed
gzip wasm32 failed
homebrew-bootstrap wasm32 failed
kandelo-sdk wasm32 failed
kernel wasm32 failed
less wasm32 failed
lsof wasm32 failed
m4 wasm32 failed
make wasm32 failed
mariadb wasm32 failed
mariadb wasm64 failed
modeset wasm32 failed
msmtpd wasm32 failed
nano wasm32 failed
ncurses wasm32 failed
netcat wasm32 failed
nginx wasm32 failed
php wasm32 failed
posix-utils-lite wasm32 failed
ruby wasm32 failed
sed wasm32 failed
shell wasm32 failed
spidermonkey wasm32 failed
tar wasm32 failed
tcl wasm32 failed
unzip wasm32 failed
userspace wasm32 failed
vim wasm32 failed
wget wasm32 failed
xz wasm32 failed
zip wasm32 failed
zstd wasm32 failed
bash wasm32 failed
lamp wasm32 failed
mariadb-test wasm32 failed
mariadb-vfs wasm32 failed
mariadb-vfs wasm64 failed
nethack wasm32 failed
nginx-php-vfs wasm32 failed
nginx-vfs wasm32 failed
node wasm32 failed
redis-vfs wasm32 failed
spidermonkey-node wasm32 failed
vim-browser-bundle wasm32 failed
wordpress wasm32 failed
nethack-browser-bundle wasm32 failed
node-vfs wasm32 failed
rootfs wasm32 failed

Auto-generated; replaced on each push. Raw data in the publish-status workflow artifact.

This assertion performs four complete repository graph resolutions and
exceeded Vitest's default timeout by 64 milliseconds on the Ubuntu CI
runner. Give the integration check explicit headroom without changing
its inputs or assertions.
SQLite uses a reviewed ZIP archive. When a refreshed cache key forced a source build, the shared package helper passed that archive to tar and failed before compilation.

Detect ZIP magic after SHA-256 verification, reject unsafe or multi-root entries, and extract one regular source directory with the repo-declared unzip tool. Refresh package cache and request-policy identities.
@brandonpayton

Copy link
Copy Markdown
Member Author

Follow-up validation for ZIP source fallback

Commit 84a2d19 fixes a failure
found while staging the refreshed package graph. SQLite has a reviewed,
SHA-256-pinned ZIP source, but the shared source helper previously sent
all downloaded archives to tar.

The helper now recognizes ZIP magic after digest verification, rejects
unsafe, special, or multi-root entries, and extracts one regular source
directory with the repository-declared unzip tool. Tar-based package
sources retain their existing path.

Fresh local evidence on this commit:

  • package build-root contract: passed, including ZIP extraction and
    multi-root rejection;
  • complete package-system suite: 191/191 passed;
  • request-feed focused Rust suite: 23/23 passed, with its workflow and
    publication checks also passing;
  • program index, resolver bundle, evidence definitions, and request
    policy freshness: passed;
  • real SQLite wasm32 source fallback: verified the reviewed upstream
    ZIP, compiled it with the worktree SDK, and produced libsqlite3.a
    plus headers.

The local checkout has no wasm64 sysroot, so the fresh staging workflow
is the exact proof for the wasm64 source build. This follow-up does not
enable promotion, deploy Pages, or delete artifacts.

GNU's legacy /gnu selector path intermittently returns HTTP 502
while the canonical package path remains available.

Keep manifest and script defaults aligned, preserve every reviewed
checksum, and rotate exact package and request-policy identities.
@brandonpayton

Copy link
Copy Markdown
Member Author

Follow-up for exact head 16be1d847:

The previous staging run exposed a source-fallback availability issue before
configure: GNU's redundant /gnu/<package>/ mirror-selector path repeatedly
returned HTTP 502. This commit switches the 14 affected GNU manifests and
script defaults to the canonical /<package>/ selector path.

Package versions and reviewed SHA-256 values are unchanged. All 14 corrected
URLs were downloaded and matched those existing hashes. An exact Diffutils
fallback build also produced diff, cmp, sdiff, and diff3.

Fresh local dev-shell validation on this head:

  • package-system: 192/192
  • request-feed Rust suite: 23/23
  • package build roots: PASS
  • resolver bundle: PASS
  • evidence definitions and request-policy freshness: PASS

I am waiting for the newly triggered exact-head checks and will not mark the PR
ready to ship until the complete staging run is green.

MariaDB now declares the normal automatic fork-instrumentation policy
when it publishes both server and mysqltest artifacts into a sealed
resolver output. This preserves the artifact guard instead of bypassing
it after the hosted builds complete.

The msmtpd source now comes from an immutable Debian snapshot of the
byte-identical upstream archive and honors resolver-provided source
metadata. This avoids depending on the currently unreachable upstream
download host.

Regenerate the affected package identities and ABI staging
request-policy digest, and cover both boundaries in the isolated-output
contract test.
The ordinary browser suite discovered the assembled-site proof without the
sealed producer tree that test requires, so the staging aggregate failed
after every package and product build had passed.

Exclude that proof unless its exact site-root authority is present. The
dedicated atomic Pages gate still supplies the root and runs all five
Chromium cases. Regenerate the protected browser evidence and
request-policy identities for the selection change.
@brandonpayton
brandonpayton force-pushed the emdash/homebrew-pr-staging-1q1w6 branch from e46dced to 9a9cab5 Compare August 12, 2026 02:25
Hosted ABI staging reached the browser gate after every package and non-browser test passed, then rejected the valid 546 MiB LAMP image because its conservative per-block zstd bound exceeded the 1 GiB lifecycle ceiling. The broad Playwright suite also discovered the protected product-evidence spec without its runner-owned handoff.

Use an exact declared zstd content size when present while retaining the conservative bound for frames that omit it and the post-decompression byte check. Exclude protected product evidence from ordinary discovery unless both handoff paths exist, while keeping explicit direct invocations fail-closed. Refresh the protected evidence and request-policy identities.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant