Close the fixed blocker, and record what withdrawal converging faster does NOT mean

Six variations against the real application, one thing varied at a time: the
sign-up-breaks-the-next-connection defect is gone. New identity, immediate
reload or delayed; an identity already used for several cycles; and the very
identity poisoned by the pre-fix code, which now reconnects cleanly three times
out of three. So nothing needed healing -- the fix does not merely stop writing
the bad state, it makes what was already written harmless. The leaf is deleted
rather than graduated: its reproduction method, the stale-server trap it led to,
and "a provider gap is not worked around here" all live elsewhere already.

The count defect stays open, with its shape now known: it does converge across
connections, but takes one more than expected -- the first reconnect still shows
zero, the second shows the value.

And a correction worth keeping. The explanation offered for why withdrawal
converges in a single connection -- that it writes straight to the owner's
document instead of depositing -- is contradicted by the code: it deposits its
own marker into the same inbox, drained by the same owner routine, "symmetric"
by the code's own comment. The asymmetry is real and recorded as verified; its
cause is recorded as unknown rather than filled with a plausible story. Same
mechanism, same inbox, two connections against one, is a lead worth having
honestly.

The dev-server caveat is upgraded from inferred to verified, and it is worse
than it read: an edit to application source triggers a genuine rebuild, new
bundle hash and all, and that rebuild still carries the stale dependency. Only a
restart works, and "touch a file to force a rebuild" is now explicitly ruled out
as a substitute.
This commit is contained in:
Sylvain Duchesne
2026-08-16 22:40:08 +02:00
parent ac55dc96a4
commit ff26f26e60
7 changed files with 28 additions and 63 deletions
@@ -1,14 +1,16 @@
---
type: caveat
summary: A running `bun run dev` never picks up a refreshed data-layer package — the overlay lives in node_modules, which watchers exclude, so the server keeps serving whatever it loaded at startup. Restart after every `link:polyfill`, and suspect a stale server before suspecting the code.
summary: A running `bun run dev` never picks up a refreshed data-layer package — VERIFIED, not even across a real rebuild (new bundle hash, still the stale dependency). Only a restart serves the fresh copy; suspect a stale server before suspecting the code.
last_checked: 2026-08-16
---
# Pitfall: refreshing the data-layer package does not reach a running dev server
# Pitfall: refreshing the data-layer package never reaches a running dev server, not even across a rebuild
`pnpm run link:polyfill` overlays the local package into `node_modules/@ng-eventually/polyfill/` as real files, and keeps them current. **That is all it does.** A `bun run dev` already running goes on serving the package it loaded at startup, however many times the overlay is rewritten underneath it`node_modules` is excluded by file watchers as a matter of convention, so the change happens in the one place nothing is looking.
`pnpm run link:polyfill` overlays the local package into `node_modules/@ng-eventually/polyfill/` as real files, and keeps them current. **That is all it does.** A `bun run dev` already running goes on serving the package it loaded at startup, however many times the overlay is rewritten underneath it, and however many rebuilds happen in between.
**So: restart `bun run dev` after every refresh of the package.** There is no signal that you needed to; a stale server looks exactly like a current one.
**VERIFIED, controlled sandbox test with this project's own bun.** A dependency resolving to copy A, overlaid with copy B: the running server still serves A at +3 s and +13 s after the overlay. An edit to **application source** then triggers a genuine rebuild — a new bundle hash confirms it — and the rebuilt bundle **still serves A**. Only a restart serves B. So the mechanism is not "the watcher never fires because `node_modules` is excluded" — a rebuild the watcher DOES trigger still carries the stale dependency forward; the server's resolution of that import is pinned at process start, and a rebuild does not re-resolve it.
**So: restart `bun run dev` after every refresh of the package — a rebuild is not a substitute, even a real one.** There is no signal that you needed to; a stale server looks exactly like a current one.
## Why this is worth a leaf
@@ -26,6 +28,6 @@ When a fix does not appear to take effect, or when a hand-run and an automated r
ps -o lstart= -p $(pgrep -f 'bun --hot src/index.ts' | head -1)
```
The same reasoning applies to anything else served out of `node_modules` — the trap is the location, not this package.
Do not reach for "touch a source file to force a rebuild" as a lighter alternative to restarting — it does trigger a real rebuild, and the rebuild still serves the stale dependency. The same reasoning applies to anything else served out of `node_modules` — the trap is the location, not this package.
Related: [[cookbook_live-probe]] (bdd-testing) — a probe answers only for the code the server actually holds, so a stale server invalidates the probe's conclusion, not the product's behaviour.