OverviewFilesCommitsIssuesDocsReleasesPeers

favela-surface-android commits / a2d4d55

0.0.16: THE ENOENT, and it was my own regression
⛔ `swarmFetcher` REPLACES `fetcher.getLatestRelease` with the makeGetLatestRelease closure, and pgh-runtime calls that on EVERY `_check()` — long after swarmFetcher returns. Passing `latest` skipped the call HERE and did nothing for the calls pgh-runtime makes later. In 0.0.11 I removed `storeDir` from that closure to dodge a Corestore lock conflict with the watch. That sent it to `homedir()/.config/pgh/registries`, which on Android cannot be created — so every check threw ENOENT. Three earlier "homedir" fixes were all correct and all irrelevant to this one. The fix is a SEPARATE directory: the lock is exclusive so it cannot be the watch's, and absent it defaults to a home directory that does not exist. ★ FOUND BY REPRODUCING IT, not by grepping. `bare-os` honours $HOME, so `HOME=/proc/self` recreates the handset exactly. The stack named it in one run: resolveRelease < NetworkFetcher.getLatestRelease < PghRuntime._check < start Four rounds of reading call sites found nothing; the first reproduction found it immediately. Verified under the same hostile HOME — watching, downloading 0.0.15, staged. ⚠ 0.0.15's stack filter was also needed to read it: 0.0.14 sliced a fixed depth and reported three frames of bare-fs's recursive mkdir, hiding the caller. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
a2d4d554a468784f60d114035062a19f2bdce0c4
by plankatron <fleeky@gmail.com> · 2026-09-10T18:40:09.000Z

Changed files (3) +19 -4

lib/host/ota.js +16 -1
……@@ -363,8 +363,23 @@ export async function swarmFetcher ({ registryKeyHex = DEFAULT_REGISTRY, repo =
363363 // ⚠ The cost is a slow check, not a slow boot: startOta is awaited but non-fatal, the interval is
364364 // hours, and a check that answers in 30s having actually replicated beats one that answers in
365365 // 500ms having seen nothing.
366 // ⛔ ITS OWN storeDir, AND IT MUST HAVE ONE. This closure is not only used here: swarmFetcher
367 // REPLACES `fetcher.getLatestRelease` with it, and pgh-runtime calls that on every `_check()` —
368 // so it resolves long after this function returns. Passing `latest` skips the call HERE and does
369 // nothing for the calls pgh-runtime makes later.
370 //
371 // ⛔ AND IT MUST NOT BE THE WATCH'S DIRECTORY. RocksDB's lock is exclusive; sharing the path the
372 // watch holds fails with "File descriptor could not be locked". Dropping storeDir entirely to
373 // avoid that — which is what I did — sent it to `homedir()/.config/pgh/registries`, and on Android
374 // that cannot be created, so every `_check()` threw ENOENT. A separate directory satisfies both.
375 //
376 // MEASURED with HOME pointed at an uncreatable path, which reproduces the handset exactly:
377 // resolveRelease < NetworkFetcher.getLatestRelease < PghRuntime._check < PghRuntime.start
366378 const getLatestRelease = makeGetLatestRelease({
367 registryKeyHex, preferSidecar: false, storeDir, settleMs: COLD_SETTLE_MS
379 registryKeyHex,
380 preferSidecar: false,
381 storeDir: storeDir || (destDir ? path.join(destDir, '..', 'registry-check') : undefined),
382 settleMs: COLD_SETTLE_MS
368383 })
369384 const latest = opts_latest || await getLatestRelease(repo)
370385 if (!latest || !latest.serverKey) throw new Error('no published release with a serverKey for ' + repo)
lib/version.js +2 -2
……@@ -1,4 +1,4 @@
11// GENERATED by scripts/gen-version.mjs — do not edit.
2export const VERSION = "0.0.15"
3export const BUILT_AT = 1789064949030
2export const VERSION = "0.0.16"
3export const BUILT_AT = 1789065599425
44export default { VERSION, BUILT_AT }
package.json +1 -1
……@@ -1,6 +1,6 @@
11{
22 "name": "favela-surface-android",
3 "version": "0.0.15",
3 "version": "0.0.16",
44 "description": "favela-surface-android \u2014 a React Native shell over a bare-kit worklet running a full favela-peer node (markdown records, no atproto) with favela-surface rendering its pages in a WebView.",
55 "type": "module",
66 "private": true,