Homebrew: Remove the dormant implementation and staging pipeline - #1316
Merged
Conversation
…line PR #1307 deactivated Homebrew from active image products, builds, tests, and CI but deliberately left the implementation dormant in the tree. This removes that now-unreferenced second packaging system entirely, along with the ABI bottle-staging / GitHub Pages machinery that existed only to produce and publish Homebrew bottles. The result is a single packaging path (source-only-v1 through the SDK, libc, resolver, and VFS image tooling) with zero Homebrew references remaining in the repository. Delete every Homebrew-named file repo-wide (host/src producers, the homebrew/ tap tree and configs, packages/registry/homebrew-bootstrap, the homebrew build/publish scripts, apps Homebrew demos and tests, the tools/xtask Homebrew modules, and the disabled Homebrew CI workflows), plus the non-Homebrew-named Homebrew files (inspect-canonical-flat-shell and the Homebrew package-layer browser spec). Remove the ABI bottle-staging pipeline that only served Homebrew bottles: fourteen abi_staging modules (builder_contract, check_projection, consumer_registry, evidence_policy, guard_registry, local_transport, mini_lifecycle, pages_readiness, product_evidence, records, request_derivation, request_feed, request_policy, selection) and their subcommands, plus the disabled GitHub Pages deploy workflow. Drop the HomebrewSoftwareV1 manifest field and the homebrew input-kind from the TypeScript VFS product builder, staged-product inputs, and shell VFS composition. Rename the surviving product-catalog code out of the abi_staging shell so its name stops implying Homebrew/staging: tools/xtask/src/abi_staging -> tools/xtask/src/vfs_products, and the `xtask abi-staging products` command -> `xtask vfs products`. product_manifest.rs + canonical_json.rs are the only survivors -- they read images/vfs/products/*.toml and emit the canonical VFS product catalog that browser demos and the VFS image builder consume. Treat images/vfs/products/generated/catalog.json as the derived artifact it is: gitignore it (like every other build output) and generate it at the start of every `xtask local-build` run from the committed manifests, so it can no longer drift from its sources. The browser demo and VFS image builder already require a completed build, so they inherit the fresh catalog; standalone `xtask vfs products generate` also recreates the directory from a clean checkout. Rebuild the browser demo product serving on the VFS catalog. The abi-staging deletion removed scripts/abi-staging-pages-site-builder.ts and abi/staging/legacy-vfs-adapters.toml but left apps/browser-demos/ vite.config.ts importing them, which broke the browser build. Replace that with scripts/vfs-product-deployment.ts, which serves the same directory- scoped VFS product deployments but derives every product's artifact, build target, and package straight from the catalog (product.output and product.builder) instead of the deleted legacy-VFS-adapter registry. Drop the now-inert legacy-binary and abi-staging-evidence Vite plugins (both no-ops outside the removed deploy modes) and reduce the unscoped path to a small virtual-module plugin. The scoped-deployment feature and its Playwright coverage are preserved; the legacy adapter indirection is gone. Converge the nginx/nginx-php VFS image names onto the repository convention. VFS images whose base name collides with a same-named program carry a `-vfs` suffix (node-vfs, mariadb-vfs, ...); nginx already installed and imported as nginx-vfs.vfs.zst everywhere, but its catalog output, package output, and builders still said nginx.vfs.zst, which is what forced the legacy adapter's build->install rename. Rename the canonical output to nginx-vfs.vfs.zst / nginx-php-vfs.vfs.zst across the product manifests, nginx-vfs/nginx-php-vfs packages, build scripts, demos, run.sh, and docs so the catalog matches the on-disk and browser-import names with no adapter. De-Homebrew the surviving surfaces that referenced deleted paths: strip the Homebrew subcommands and module declarations from main.rs; repoint the canonical product fixture off the deleted main-shell config; remove the dead HOMEBREW_* credential names from the hermetic-build scrub lists in build_deps.rs and the shell/CI scripts; drop the Homebrew and KANDELO_HOMEBREW_* environment passthroughs from scripts/dev-shell.sh so host Homebrew state can no longer leak into the pure Nix dev shell; and delete the stale bottle-staging entries from docs/future-improvements.md. Regenerate program-packages.json, whose per-package cache keys shift because the scrubbed-variable-name set is part of the hermetic build hash. Fix the openssl wasm build so the source-only build path actually completes. openssl's Makefile does not fully order its generated headers (opensslv.h and the STACK_OF/version macros) ahead of object compilation under -j, so folding build_generated into the parallel libssl.a/libcrypto.a targets let a .c compile before its headers existed; the macros then failed to expand and openssl/macros.h tripped "OPENSSL_API_COMPAT expresses an impossible API compatibility level" with implicit-int cascades, failing openssl and blocking every downstream product. Run build_generated as its own barrier first (matching the reference formula), then build the libraries in parallel. Verified in scripts/dev-shell.sh: cargo test -p xtask --target aarch64-apple-darwin passes (738 unit tests + integration binaries, 0 failed); host Vitest passes for the affected VFS/product-builder suites; check-pages-vfs-product-registry node tests pass (9/9); the browser Vite config loads with zero abi-staging/legacy-pages plugins; `xtask vfs products generate` reproduces the catalog byte-identically from a clean checkout; program-index-check confirms program-packages.json is current; and a case-insensitive repository sweep for "homebrew"/"brewfile" returns zero matches. `./run.sh local-build` now completes source-only (89/89 nodes, 7/7 products) and the browser demos serve from those artifacts on http://127.0.0.1:5401. The scoped-deployments Playwright e2e still fails on pre-existing stale hardcoded closure constants (lazy-body and snapshot- member counts) that predate this branch and are unrelated to these changes; correcting those constants and their unit fixtures is left to a follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
brandonpayton
added a commit
that referenced
this pull request
Aug 27, 2026
## Why The framebuffer demos assume a desktop. fbDOOM is keyboard-driven, so on a phone or tablet there is no way to move, shoot, or even leave the demo attract loop. The modeset drawing demo listened only for mouse events, so a finger could not draw. Worse, tapping the fbDOOM canvas requested browser pointer lock; on a touch device there is no Esc key to release it, so a tap could strand the user in locked mode. Small screens had their own problems: the Launch New Machine pane trapped vertical scrolling inside the machines table, the theme popup clipped its lower entries so Dark mode was unreachable, and the dock could scroll its left edge out of reach. ## What changed - New touch overlay for keyboard-driven framebuffer demos (`apps/browser-demos/pages/kandelo/panes/TouchControls.tsx`): a keyboard-shaped d-pad bottom-left, a FIRE button (LeftCtrl) bottom-right, and a MENU button (Esc) top-left. Buttons send the same Linux MEDIUMRAW bytes as the physical keyboard path, with a minimum 50 ms hold so clients that latch key state once per tic never miss a press. - A tap on the fbDOOM canvas sends Enter and Space together: the DOOM menu reads Enter (select) and ignores Space, the game reads Space (use — doors, switches) and ignores Enter, so one gesture covers both without extra buttons. - The overlay is gated by a new optional `presentation.touchControls` boolean carried through the demo-config pipeline (`web-libs/kandelo-session`), set on the doom profile in `packages/registry/shell/source-rootfs-shell-demo-profiles.json` and the builtin fallback (`web-libs/kandelo-session/src/demo-guides.ts`), and shown only on coarse-pointer devices while a process owns the framebuffer. - The modeset demo now uses pointer events, so a touch acts as a left-button mouse: single-finger tracking, pointer capture for drags past the canvas edge, and coordinates clamped to the framebuffer bounds to stay in sync with the guest cursor. - Pointer-capture requests coming from touch input are ignored in `host/src/framebuffer/browser-controls.ts`, so a tap can never strand a touch user in pointer-lock mode, and the pointer-lock rejection thrown by touch-only platforms is swallowed. - Small-screen CSS: the launch pane scrolls as one page (title, filter, and machines list together) with horizontal overflow confined to the table itself, the theme popup scrolls vertically, and the dock keeps both edges reachable when it overflows. - Packaging: the seven image packages that declare `web-libs/kandelo-session/src/demo-config.ts` as a build input get revision bumps (shell moves to revision 30) so the changed demo-config invalidates their cached products and forces a rebuild through the normal source path. - `docs-site/guide/vfs-images.md` documents `presentation.touchControls`. - `docs/future-improvements.md` records follow-up work to re-evaluate the Linux-specificity of the framebuffer VT keyboard input path — both the MEDIUMRAW byte encoding and the `KDGKBTYPE`/`KDGKBMODE`/`KDSKBMODE` ioctl stubs the kernel answers so Linux-VT software runs unmodified. ## Validation - 149/149 Vitest tests pass via `scripts/dev-shell.sh` across the four affected suites: `host/test/shell-vfs-build.test.ts` (revision pins), `host/test/shell-lazy-archive-inputs.test.ts`, `web-libs/kandelo-session/test/kandelo-session.test.ts` (including the `touchControls` fixture assertions), and `tests/package-system/source-rootfs-shell-bridge.test.ts` (the doom profile carries `touchControls: true` and shell pins revision 30). - Browser assets rebuilt from source via `./run.sh prepare-browser`: the image packages recompiled at their new revisions (shell revision 30) and the local SourceOnly build reported 7/7 products ready. - `apps/browser-demos` TypeScript typecheck is clean for the changed files (`Framebuffer.tsx`, `TouchControls.tsx`, `Modeset.tsx`, `browser-controls.ts`). - Originally verified in Chrome device emulation via `./run.sh browser`: overlay layout portrait and landscape, d-pad movement, FIRE, MENU, tap-to-use on doors, tap-to-select in menus, theme popup reaching Dark mode, and launch-pane scrolling. The rebase did not change feature behavior. - Not run: conformance suites and benchmarks (no kernel, syscall, or hot-path changes), and Playwright. ## Rebase note This branch was rebased onto current `main`, which had removed the dormant Homebrew implementation and staging pipeline (#1316), the remote binary channel (#1322), and the committed `packages/registry/program-packages.json` program index. The touch feature now lands against the relocated `packages/registry/shell` demo sources; no homebrew artifacts, lazy-shell artifact lock, or program index are touched, and the revision bumps were remapped onto main's current values. The earlier "known unrelated failure" in the `exact-linux-contract` check no longer applies: that check and the `homebrew/homebrew-native-compatibility-lock.json` it depended on were deleted on main along with the rest of the Homebrew pipeline. --------- Co-authored-by: Brandon Payton <brandon@happycode.net> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Kandelo carried two packaging systems. PR #1307 turned Homebrew off for
active image products, builds, tests, and CI, but deliberately left the
whole Homebrew implementation dormant in the tree -- a second, unused
packaging path that still had to be reasoned about, kept compiling, and
maintained. That is exactly the kind of parallel system the platform-values
contract warns against: it invites drift and hides which path is real.
At the same time, the source-only build path (
./run.sh local-build) ismeant to be the single way user software is built, but it did not actually
complete from a clean checkout. An OpenSSL build race made openssl fail to
compile, which blocked every downstream product (php, curl, node, nginx,
mariadb, wordpress, lamp) -- so the "one true build path" the Homebrew
removal depends on was itself broken.
This PR removes the dormant Homebrew system entirely so there is one
packaging path, decouples the browser build from the removed machinery,
and fixes OpenSSL so that single source-only path builds end to end.
What changed
Remove Homebrew and its staging pipeline
homebrew/tap tree,packages/registry/homebrew-bootstrap, thehomebrew build/publish scripts, apps demos/tests, the
tools/xtaskHomebrew modules, and the disabled Homebrew CI workflows.
publish Homebrew bottles: fourteen
abi_stagingmodules and theirsubcommands, plus the disabled GitHub Pages deploy workflow.
matches.
Keep and rename the one non-Homebrew survivor
product_manifest.rs+canonical_json.rs)is the only part
./run.sh local-buildconsumes. Move it out of theabi_stagingshell:tools/xtask/src/abi_staging->tools/xtask/src/vfs_products, andxtask abi-staging products->xtask vfs products.Treat the product catalog as a build output
images/vfs/products/generated/catalog.jsonis derived from the productmanifests, so it is now gitignored and regenerated at the start of every
xtask local-build, instead of being a committed file that could drift.Rebuild the browser demo product serving on the catalog
abi-staging-pages-site-builder.tsandabi/staging/legacy-vfs-adapters.tomlbut leftvite.config.tsimportingthem, which broke the browser build. Replace that with
scripts/vfs-product-deployment.ts, which serves the same directory-scopedVFS product deployments but derives each product's artifact and build
target straight from
catalog.jsoninstead of the deleted legacy-adapterlayer. Directory-scoped deployment is preserved; the legacy indirection is
gone.
Converge VFS image naming
-vfssuffix (node-vfs,mariadb-vfs, ...). nginx already installed andimported as
nginx-vfs.vfs.zstbut its catalog/package/build still saidnginx.vfs.zst. Rename the canonical output tonginx-vfs.vfs.zst/nginx-php-vfs.vfs.zstso the catalog matches the on-disk andbrowser-import names with no adapter.
Fix the OpenSSL wasm build
object compilation under
-j, so foldingbuild_generatedinto theparallel
libssl.a/libcrypto.atargets let a.ccompile before itsheaders existed. Run
build_generatedas its own barrier first (matchingthe reference formula), then build the libraries in parallel.
Validation
Run in
scripts/dev-shell.sh:cargo test -p xtask --target aarch64-apple-darwin: 738 unit tests +integration binaries, 0 failed.
check-pages-vfs-product-registrynode tests pass (9/9)../run.sh local-buildcompletes source-only: 89/89 nodes, 7/7 products.nginx, wordpress, etc. images).
Known follow-up
scoped-deployments.spec(an @slow test not run in CI) fails onpre-existing stale hardcoded closure constants (lazy-body and
snapshot-member counts) that
origin/mainalso carries. My changes do nottouch that counting logic, so this is a pre-existing staleness, not a
regression here; correcting those constants and their unit fixtures is left
to a follow-up.
🤖 Generated with Claude Code