# 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](docs/BINARY-RELEASE.md) — build, install, run, secrets - [docs/PEAR-RUN.md](docs/PEAR-RUN.md) — legacy channel notes only (no `pear run` instructions) **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/imports`** with 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, flatten `node_modules`) - optional omit of heavy/native bits (e.g. sshcrypto) as needed for size - embeds **`bare-runtime`** via bare-build and writes `out/bare-os-{product}-{host}/` - **`scripts/make.cjs`** — orchestrates product × host builds - **`scripts/hosts.cjs`** — shared 64-bit host list / parsing - **`scripts/prepare-pack.mjs`** — kernel image sync + node_modules flatten before pack - **`scripts/sign-macos-binary.cjs`** + vendored **`tools/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 and `npm run os:*:bin` - Root **`package.json`** scripts shifted off `pear run` toward `bare` / make / release helpers - Seeder/booter **`package.json`** upgrade links kept for OTA / `pear install` - **`packages/*/lib/paths.js`** adjusted for standalone / datadir layouts - **`scripts/pm2-run-binary.sh`** + ecosystem updates — PM2 runs binaries instead of pear - **`scripts/pm2-pear-run.sh`** left 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`** — on `main`, build and publish tag **`rolling`** - **`scripts/gitea-rolling-release.sh`** — tarball assets + checksums; uses **`RELEASE_TOKEN`** - Artifacts: `bare-os-{seeder,booter}--.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`** — stage `by-arch` trees offline with **`PEAR_PRIMARY_KEY`** - **`ci/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.md`** rewritten as **legacy notes** — explicitly: do not use `pear run` - README + **`users-manual/03-running-seeder-and-booter.md`** updated for binary run paths --- ## 2. `cdf776a6` — Fix CI - Hardened **`.gitea/workflows/release-rolling.yml`** and **`scripts/gitea-rolling-release.sh`** so rolling publish is reliable (token/env/docs alignment) - Small **`docs/BINARY-RELEASE.md`** clarifications for the CI path --- ## 3. `6105b8d4` — Web / curl installer - New **`scripts/install.sh`** — peardock-style interactive installer: - roles: `--seeder` / `--booter` / `--both` - `--yes` non-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/bin` shims - **`deploy/bare-os-seeder.service`** / **`deploy/bare-os-booter.service`** for 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.mjs`** next to the app so **`bare-pack`** traces `./index.js` - **`bin/meta/{seeder,booter}.mjs`** + **`scripts/sync-bin-meta.mjs`** — keep meta/bin packaging metadata in sync - **`scripts/prepare-pack.mjs`** tweak for that graph --- ## 5. `633fe22b` — Package `standalone.mjs` + OTA stubs - **`packages/bare-os-{seeder,booter}/standalone.mjs`** — OTA prelude then app `index.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.mjs`** refined 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 `/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 under `packages/*/node_modules` before pack; rematerialize patched **`bare-ssh2`** for 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 of `path` - `[ctx_bare_module_load_failed]` — dynamic `import('holesail')` / `b4a` / … from packed `bare-os-ctx-bare.js` (no per-referrer resolution under `bare:/app.bundle/`) ### Static module graph - **`bin/bare-os-booter.mjs`** — static `import 'bare-node-runtime/global'` + package standalone - **`packages/bare-os-booter/standalone.mjs`** — static pack-import anchors + `index.js` - **`packages/bare-os-booter/lib/bare-os-host-ota-boot.mjs`** — OTA boot prelude as a static import from `index.js` - **`packages/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, many `bare-*`, plus Node-builtin aliases (`path`→`bare-path`, `os`→`bare-os`, …) - **`bare-os-ctx-bare.js`**: - prefer packed host map in **`buildBareCtxObjectFromHost`** before dynamic `import(ent.package)` - **`withDriveBundleGlobalRequire`** / **`createDriveBundleRequireWrapper`** — resolve builtins from the host map; **`require.addon`** via bare-module `createRequire` (static binding) + addon fallbacks across packed natives - **`runDriveBundleSource`** — eval IIFEs with explicit `require`, `__filename`, `__dirname` - on **`bare:`** standalone: host-import first, then drive merge; skip drive eval for optional non-`bundle:true` keys already satisfied by host (stops optional native tooling spam: bare-apk, bare-ffmpeg, …) - pear-only load failures softened when `Pear` is absent ### Verify / CI quality gate - **`scripts/verify-standalone-build.cjs`** — size ceilings per product/host, pear-runtime stub marker check, native-host booter smoke with `--datadir` - **`scripts/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: ```bash curl -fsSL https://install.bare-os.live | bash ``` Updated in: - `README.md` - `docs/BINARY-RELEASE.md` - `scripts/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/ ```