11 KiB
Pear run deprecation work (2026-07-31)
This document records what landed on 2026-07-31 to retire pear run as the host path for seeder/booter and replace it with Bare standalone binaries, Gitea rolling releases, a curl|bash installer, and optional pear install / OTA channels.
Why: Pear v3 removed pear run. Host distribution is now packed Bare binaries (bare-pack / bare-build), published as rolling tarballs, not Pear-swapped pear run processes.
Canonical docs after this work:
- docs/BINARY-RELEASE.md — build, install, run, secrets
- docs/PEAR-RUN.md — legacy channel notes only (no
pear runinstructions)
Commits (oldest → newest):
| Hash | Subject |
|---|---|
2b7025b2 |
Bare standalone packaging, OTA entries, Gitea rolling, pear-run retirement |
cdf776a6 |
Fix CI |
6105b8d4 |
Add installer |
33937db1 |
fixes (bin → package standalone.mjs / meta sync) |
633fe22b |
Updates (OTA stubs, package standalone entries) |
302c968b |
Update booter (--datadir, pear-runtime stub default, prune) |
d30b9184 |
booter fixes (static host modules, drive-bundle eval, verify) |
d1725bc8 |
Update README (canonical installer host) |
1. 2b7025b2 — Bare standalone packaging and pear-run retirement
Packaging toolchain
New / primary scripts:
scripts/bare-standalone.cjs— pack seeder or booter for a host (linux-x64,linux-arm64,darwin-*,win32-*):- merges
bare-node-runtime/importswith package/root import maps - applies
build/stubs/(e.g.undici, empty stubs) so pack does not pull Node-only graphs - runs
scripts/prepare-pack.mjs(kernel sync into seeder package, flattennode_modules) - optional omit of heavy/native bits (e.g. sshcrypto) as needed for size
- embeds
bare-runtimevia bare-build and writesout/bare-os-{product}-{host}/
- merges
scripts/make.cjs— orchestrates product × host buildsscripts/hosts.cjs— shared 64-bit host list / parsingscripts/prepare-pack.mjs— kernel image sync + node_modules flatten before packscripts/sign-macos-binary.cjs+ vendoredtools/rcodesign/(linux-x64 / linux-arm64) for Gatekeeper-friendly darwin signing from CI/Linux
App entries (no pear run)
bin/bare-os-seeder.mjs/bin/bare-os-booter.mjs— host entrypoints for packed binaries andnpm run os:*:bin- Root
package.jsonscripts shifted offpear runtowardbare/ make / release helpers - Seeder/booter
package.jsonupgrade links kept for OTA /pear install packages/*/lib/paths.jsadjusted for standalone / datadir layoutsscripts/pm2-run-binary.sh+ ecosystem updates — PM2 runs binaries instead of pearscripts/pm2-pear-run.shleft as legacy/shim-oriented, not the primary path
OTA wrapper
lib/bare-os-ota.mjs— optional pear-runtime OTA around the app; disable with--no-updates/BARE_OS_OTA_DISABLE=1- Default packaging story: binaries can embed or stub pear-runtime (refined in later commits)
Gitea rolling release
.gitea/workflows/release-rolling.yml— onmain, build and publish tagrollingscripts/gitea-rolling-release.sh— tarball assets + checksums; usesRELEASE_TOKEN- Artifacts:
bare-os-{seeder,booter}-<ver>-<host>.tar.gz,by-arch-*.tar.gz,*.sha256 - Seeder tarballs include
kernel/
Pear by-arch / offline stage (not CI pear-ci)
scripts/pear-stage-by-arch.sh— stageby-archtrees offline withPEAR_PRIMARY_KEYci/snapshot-seeder.json/ci/snapshot-booter.json— snapshots when staging- CI publishes by-arch tarballs but does not require pear-ci secrets on every push
Docs / product messaging
- New
docs/BINARY-RELEASE.md docs/PEAR-RUN.mdrewritten as legacy notes — explicitly: do not usepear run- README +
users-manual/03-running-seeder-and-booter.mdupdated for binary run paths
2. cdf776a6 — Fix CI
- Hardened
.gitea/workflows/release-rolling.ymlandscripts/gitea-rolling-release.shso rolling publish is reliable (token/env/docs alignment) - Small
docs/BINARY-RELEASE.mdclarifications for the CI path
3. 6105b8d4 — Web / curl installer
- New
scripts/install.sh— peardock-style interactive installer:- roles:
--seeder/--booter/--both --yesnon-interactive,--system(Linux/opt/bare-os+ systemd),--no-updates,--tag/--version/--dir- downloads rolling assets from Gitea; user install under
~/.local/share/bare-os/{seeder,booter}/with~/.local/binshims
- roles:
deploy/bare-os-seeder.service/deploy/bare-os-booter.servicefor system installs- README / BINARY-RELEASE / users-manual wired to the installer
4. 33937db1 — Entry graph fixes (pack must see ./index.js)
Problem: packing only the thin bin wrapper missed the package graph (MODULE_NOT_FOUND for package index.js under bare:/app.bundle/).
- Bin entries resolve through package
standalone.mjsnext to the app sobare-packtraces./index.js bin/meta/{seeder,booter}.mjs+scripts/sync-bin-meta.mjs— keep meta/bin packaging metadata in syncscripts/prepare-pack.mjstweak for that graph
5. 633fe22b — Package standalone.mjs + OTA stubs
packages/bare-os-{seeder,booter}/standalone.mjs— OTA prelude then appindex.js(pack root for each product)- Bin files slimmed to import runtime global + package standalone
- Stubs:
build/stubs/pear-appdrive.cjs,build/stubs/pear-ref.cjs lib/bare-os-ota.mjsrefined for standalone mkdir/storage behavior
6. 302c968b — Datadir, slim OTA default, CodeRange-safe pack
Host flags / storage
lib/bare-os-host-flags.mjs—--datadir/--data-dir→BARE_OS_HOST_DATA- Seeder/booter
index.js+ standalone honor datadir so Corestore lives under<datadir>/corestore/{seeder,booter}
OTA default for packed binaries
build/stubs/pear-runtime.cjs— stub so default pack does not embed full pear-runtime (Gitea rolling is the primary update path)- Real pear-runtime only when packing with
--with-ota lib/bare-os-ota.mjs— create OTA storage dirs when enabled; default OTA off unless--updates/BARE_OS_OTA=1(as documented on binaries)
Pack size / OOM
scripts/bare-standalone.cjs— prune hoisted duplicate deps underpackages/*/node_modulesbefore pack; rematerialize patchedbare-ssh2for booter- Target sizes ~90 MiB darwin / ~130 MiB linux booter (avoids V8 CodeRange OOM on fat embeds)
7. d30b9184 — Booter standalone ctx.bare / drive-bundle correctness
After slim install, boot reached the guest shell but flooded:
[drive_bundle_eval_failed]—ADDON_NOT_FOUND/__require.addon is not a function/ Dynamic require ofpath[ctx_bare_module_load_failed]— dynamicimport('holesail')/b4a/ … from packedbare-os-ctx-bare.js(no per-referrer resolution underbare:/app.bundle/)
Static module graph
bin/bare-os-booter.mjs— staticimport 'bare-node-runtime/global'+ package standalonepackages/bare-os-booter/standalone.mjs— static pack-import anchors +index.jspackages/bare-os-booter/lib/bare-os-host-ota-boot.mjs— OTA boot prelude as a static import fromindex.jspackages/bare-os-booter/lib/bare-os-standalone-pack-imports.mjs— ensures host-modules stay in the pack graph
Host module map + drive require
packages/bare-os-booter/lib/bare-os-ctx-bare-host-modules.mjs— static imports of holesail, b4a, protomux, manybare-*, plus Node-builtin aliases (path→bare-path,os→bare-os, …)bare-os-ctx-bare.js:- prefer packed host map in
buildBareCtxObjectFromHostbefore dynamicimport(ent.package) withDriveBundleGlobalRequire/createDriveBundleRequireWrapper— resolve builtins from the host map;require.addonvia bare-modulecreateRequire(static binding) + addon fallbacks across packed nativesrunDriveBundleSource— eval IIFEs with explicitrequire,__filename,__dirname- on
bare:standalone: host-import first, then drive merge; skip drive eval for optional non-bundle:truekeys already satisfied by host (stops optional native tooling spam: bare-apk, bare-ffmpeg, …) - pear-only load failures softened when
Pearis absent
- prefer packed host map in
Verify / CI quality gate
scripts/verify-standalone-build.cjs— size ceilings per product/host, pear-runtime stub marker check, native-host booter smoke with--datadirscripts/make.cjs/ rolling release script invoke verify after builds- Workflow / release script small follow-ups
Outcome verified locally: full boot against a seeder → 0 drive_bundle_eval_failed, 0 ctx_bare_module_load_failed / pear ctx noise; guest welcome / shell; binaries installed under ~/.local/share/bare-os/booter/ and linux-x64 rebuilt for CI artifact shape.
8. d1725bc8 — Canonical web installer URL
Installer host set to:
curl -fsSL https://install.bare-os.live | bash
Updated in:
README.mddocs/BINARY-RELEASE.mdscripts/install.sh(header +--help)users-manual/03-running-seeder-and-booter.md
Gitea raw URL remains a documented fallback.
End state (what operators use)
| Path | Status |
|---|---|
pear run pear://… |
Retired (Pear v3 + docs) |
| Bare standalone binary (tarball / installer) | Primary |
pear install pear://… + optional in-binary OTA |
Supported (upgrade links; OTA often stubbed in pack) |
Gitea rolling release |
CI publish of host tarballs + by-arch trees |
curl | bash installer |
https://install.bare-os.live |
| Dev without pack | npm run os:seeder / os:booter (or :bin entries) |
Key files touched (index)
.bin/bare-os-{seeder,booter}.mjs
bin/meta/{seeder,booter}.mjs
build/stubs/{empty,undici,pear-runtime,pear-appdrive,pear-ref}.cjs
lib/bare-os-ota.mjs
lib/bare-os-host-flags.mjs
packages/bare-os-{seeder,booter}/standalone.mjs
packages/bare-os-booter/lib/bare-os-ctx-bare.js
packages/bare-os-booter/lib/bare-os-ctx-bare-host-modules.mjs
packages/bare-os-booter/lib/bare-os-host-ota-boot.mjs
packages/bare-os-booter/lib/bare-os-standalone-pack-imports.mjs
scripts/bare-standalone.cjs
scripts/make.cjs
scripts/hosts.cjs
scripts/prepare-pack.mjs
scripts/verify-standalone-build.cjs
scripts/gitea-rolling-release.sh
scripts/pear-stage-by-arch.sh
scripts/install.sh
scripts/sign-macos-binary.cjs
scripts/pm2-run-binary.sh
deploy/bare-os-*.service
.gitea/workflows/release-rolling.yml
docs/BINARY-RELEASE.md
docs/PEAR-RUN.md
tools/rcodesign/