Skip to content

Homebrew: Remove the dormant implementation and staging pipeline - #1316

Merged
brandonpayton merged 1 commit into
mainfrom
brandonpayton/remove-homebrew
Aug 26, 2026
Merged

Homebrew: Remove the dormant implementation and staging pipeline#1316
brandonpayton merged 1 commit into
mainfrom
brandonpayton/remove-homebrew

Conversation

@brandonpayton

Copy link
Copy Markdown
Member

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) is
meant 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

  • Delete every Homebrew-named file repo-wide: host producers, the
    homebrew/ tap tree, packages/registry/homebrew-bootstrap, the
    homebrew build/publish scripts, apps demos/tests, the tools/xtask
    Homebrew modules, and the disabled Homebrew CI workflows.
  • Remove the ABI bottle-staging pipeline that existed only to produce and
    publish Homebrew bottles: fourteen abi_staging modules and their
    subcommands, plus the disabled GitHub Pages deploy workflow.
  • Result: a case-insensitive sweep for "homebrew"/"brewfile" returns zero
    matches.

Keep and rename the one non-Homebrew survivor

  • The VFS product-catalog code (product_manifest.rs + canonical_json.rs)
    is the only part ./run.sh local-build consumes. Move it out of the
    abi_staging shell: tools/xtask/src/abi_staging ->
    tools/xtask/src/vfs_products, and xtask abi-staging products ->
    xtask vfs products.

Treat the product catalog as a build output

  • images/vfs/products/generated/catalog.json is derived from the product
    manifests, 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

  • The Homebrew removal deleted abi-staging-pages-site-builder.ts and
    abi/staging/legacy-vfs-adapters.toml but left 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 each product's artifact and build
    target straight from catalog.json instead of the deleted legacy-adapter
    layer. Directory-scoped deployment is preserved; the legacy indirection is
    gone.

Converge VFS image naming

  • 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 but its catalog/package/build still said
    nginx.vfs.zst. Rename the canonical output to nginx-vfs.vfs.zst /
    nginx-php-vfs.vfs.zst so the catalog matches the on-disk and
    browser-import names with no adapter.

Fix the OpenSSL wasm build

  • OpenSSL's Makefile does not fully order its generated headers 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. Run build_generated as its own barrier first (matching
    the 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.
  • 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.
  • ./run.sh local-build completes source-only: 89/89 nodes, 7/7 products.
  • The browser demos serve from those artifacts (kernel boots the shell,
    nginx, wordpress, etc. images).
  • Case-insensitive repository sweep for "homebrew"/"brewfile": zero matches.

Known follow-up

scoped-deployments.spec (an @slow test not run in CI) fails on
pre-existing stale hardcoded closure constants (lazy-body and
snapshot-member counts) that origin/main also carries. My changes do not
touch 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

…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
brandonpayton merged commit fc2f3ef into main Aug 26, 2026
@brandonpayton
brandonpayton deleted the brandonpayton/remove-homebrew branch August 26, 2026 04:39
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>
@brandonpayton
brandonpayton restored the brandonpayton/remove-homebrew branch September 9, 2026 04:35
@brandonpayton
brandonpayton deleted the brandonpayton/remove-homebrew branch September 9, 2026 04:35
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