Repository navigation
Fix build, deploy, and P2P discovery gaps found in P0/P1 audit - #2
Merged
Merged
Conversation
CI and the build/release workflows ran on npm while .npmrc's node-linker=hoisted only means anything under pnpm, plus both package-lock.json and pnpm-lock.yaml were committed. Standardize everything (ci.yaml, build.yaml, scripts/make.js) on pnpm and drop the npm lockfile. Also fixes the release artifact/binary name in build.yaml, which still pointed at hello-pear-bare from the template instead of towerbell.
Both are required directly by backend/ and bin.mjs but were only resolving via hoisted transitive deps, which node-linker=hoisted can mask until the dependency graph shifts.
peer-lost was documented in AGENTS.md and already listened for in the CLI TUI, but no backend ever emitted it. DiscoveryDHT now tracks the announced key per connection and fires peer-left on close; Scanner turns that into peer-lost with the same hex id peer-found uses. Both mocks (backend/mock.js, frontend/backend/mock.js) simulate a beacon going out of range so --fake and the Expo demo exercise the same path.
workers/main.js only required the unmodified hello-pear-worker boilerplate, which never passes a delay to PearRuntime and so falls back to its library default of up to one hour before checking a detected update -- unusable for a live demo. Replaced it with a small worker written directly against the documented PearRuntime/IPC API (dir, version, upgrade, name, app, updates, delay), keeping the same 'updating'/'updated'/pear:applyUpdate message protocol App.js already expects. delay is set to 5s; raise it back up for a real multi-peer production deploy. Drops the now-unused hello-pear-worker dependency.
traveler.mjs had literal ASCII '?' where status glyphs/separators should be (confirmed the file itself is plain ASCII, not a rendering issue). Swapped in plain ASCII glyphs consistent with style.mjs, which never uses Unicode either. trade.mjs was checked too and was already fine. lunte now also covers frontend/cli and the frontend/*.mjs barrels, since those run under Bare via bin.mjs and were the only Bare-executed files not linted.
AGENTS.md now says explicitly that the Spanish names in planning docs are for human readability only and never go into code -- the implemented contract (scan/beacon, peer-found/peer-lost/status/visitor) is the frozen one. Added FRONTEND_INTEGRATION.md (referenced by AGENTS.md but missing) covering the contract, the two consumers (Pear CLI vs Expo mock), and the boundary rules. Also notes that frontend/src/store/app.store.js doesn't listen for peer-lost yet, for whoever owns frontend/src next.
Verified against the actually-installed pear-runtime@1.3.1 and pear-runtime-updater@3.4.0 source: PearRuntime swallows its own ready() rejection, so update-time errors (failed drive update, failed prefetch) are emitted on pear.updater, not on pear itself. The previous commit only listened on pear.
pnpm install after declaring the two missing deps explicitly. pnpm-workspace.yaml is new: pnpm's supply-chain policy flagged bare-fs@4.8.1 as too recently published and this records the explicit allow, not a manual choice.
pnpm >=10.6 stopped reading node-linker from .npmrc -- only auth/registry settings are still read there. The .npmrc setting was silently dead, pnpm fell back to isolated linking, and Bare's module resolver doesn't walk pnpm's .pnpm symlink structure the way Node's require() does. Result: streamx (a transitive dep of framed-stream) failed to resolve at runtime with MODULE_NOT_FOUND, both under bare bin.mjs and in the compiled binary -- reproduced and confirmed fixed by hand. Real fix is nodeLinker: hoisted in pnpm-workspace.yaml; kept .npmrc for anyone on an older pnpm.
Found live while testing the deploy pipeline end to end (stage -> seed -> install -> run): pear stage has no default ignore, so staging the repo root ships .git and node_modules whole (~1.8GB, confirmed by actually running it). package.json's pear.stage.ignore trims that to ~620MB by dropping .git, out/, the Expo app, and devDependencies (bare-build's cross-compile toolchains alone account for most of the removed size). Bigger finding: staging the repo root does not work for pear install at all. towerbell has "bin": "bin.mjs" and OTA swaps the installed binary, which makes pear install look for /by-arch/<host>/app/<name> on the staged drive -- confirmed by reproducing the 'Not found' failure, then confirming a deployment folder built with bare-build + pear-build installs and runs correctly. Documented the real recipe in docs/RELEASES.md and linked it from README; the previous 'pear stage <link>' one-liner there was untested and wrong for this app's distribution model.
bin.mjs has had an app.on('updating-delta', ...) listener the whole time, but nothing ever sent that message -- confirmed pear.updater does emit it (one entry per mirrored file during an update) by reading the installed pear-runtime-updater source. Worker now forwards it as JSON on the same ad hoc string-message protocol the other control messages use; app.js parses it back out.
graceful-goodbye was declared in package.json but never required anywhere, and Scanner had no way to close its swarm on exit -- only Beacon did. Added stop() to the real Scanner and both mocks (mirroring Beacon.stop()), and wired graceful-goodbye in bin.mjs so Ctrl+C/SIGTERM closes the DHT swarm right away instead of leaving it for the OS to tear down.
Replaces the REMOVE ME placeholder with four real tests against Corestore/Hyperbee (not mocked): put/get roundtrip, overwrite, null when nothing was written, and getRemoteDb caching by key. All four run and pass under brittle-bare.
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.
What changes
pear-buildpackaging); release artifact/binary name corrected from a leftoverhello-pear-baretemplate name totowerbell.bare-eventsandbare-fsdeclared as explicit dependencies (were resolving only by accident via hoisting).node-linkerin.npmrc(pnpm >=10.6 only reads it frompnpm-workspace.yamlnow) -- this was causing astreamxmodule-not-found failure at runtime, in both dev and the compiled binary.peer-lostis now emitted by the real backend (on Hyperswarm connection close) and simulated by both mocks; the CLI TUI already expected it and had no source for it until now.workers/main.js) is a real implementation instead of the untouchedhello-pear-workerboilerplate, with an explicit lowdelay(the boilerplate never set one, so it defaulted to up to 1h before checking an update) and correct error/progress event wiring, verified against the installedpear-runtime/pear-runtime-updatersource.pear.stage.ignoreadded topackage.json: staging the repo root with no ignore list ships.gitandnode_moduleswhole (~1.8GB); trimmed to ~620MB. Also documented (docs/RELEASES.md) that this app's real distribution needs theby-archdeployment folder built bybare-build+pear-build, not a raw source stage -- confirmed live, staging the repo root does not work withpear install.Scanner.stop()added (onlyBeaconhad a stop method) and wired tograceful-goodbye, which was declared as a dependency but never used, so Ctrl+C now closes the swarm instead of leaving it for the OS.AGENTS.md; addedFRONTEND_INTEGRATION.md(referenced but missing).?characters (confirmed plain ASCII corruption, not a display issue) in the CLI TUI, widenedlintto cover the Bare-run frontend files it was missing.test/index.jsplaceholder with 4 real tests against Corestore/Hyperbee.What was verified
pnpm run lint(prettier + lunte): clean.pnpm test: 4/4 pass.bare bin.mjs --fake scan/beacon: both run,peer-foundandpeer-lostfire end to end.scan+beacon, separate storage, no--fake) discovered each other over real Hyperswarm.pnpm run make: compiles totowerbell.exe, runs correctly, all modules resolve includingstreamx.upgradelink):bare-build+pear-build->pear stage->pear seed->pear install-> ran the installed binary. Staging raw source was also tried and confirmed to fail the same way, before finding the by-arch fix.