Skip to content

fix(actor): drop a stopped provisional site actor's binding - #439

Open
jonybur wants to merge 3 commits into
mainfrom
fix/site-actor-binding-cleanup
Open

fix(actor): drop a stopped provisional site actor's binding#439
jonybur wants to merge 3 commits into
mainfrom
fix/site-actor-binding-cleanup

Conversation

@jonybur

@jonybur jonybur commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Closes #438.

What broke

The cleanup that removes a provisional site actor's binding when the actor is stopped split the binding key on a space. The map that writes that key joins with a NUL. indexOf(' ') was therefore always -1, the loop always hit its continue, and the drop never ran.

So a provisional site actor stopped for landing outside its boundary kept a live binding: a retry resolved the stopped session instead of minting a fresh actor, and per the block's own comment could reopen an orphaned tab. The stopped state still fences queued calls, so this is recovery quality, not an authority bypass.

What changed

The root cause is that the key shape was known in two files. It now lives in one: the binding map gains dropBySession(), and the controller asks for the removal instead of taking the key apart itself.

How it was verified

Two regression tests, driving a REAL binding map - every existing test passed while the cleanup did nothing, because none of them used one. Revert-proven: restoring the old loop turns the provisional test red, and the fix turns it green.

Gates: 6413 bun, 948 in-browser, lint, typecheck, boundary, imports, tscheck, copy.

Found while mapping the dispatcher for #234; filed separately rather than folded into that PR.

Closes #438.

The cleanup split a site-actor binding key on a space while the map that
writes it joins with a NUL. indexOf(' ') was therefore always -1, the loop
always hit its `continue`, and the drop never ran: a provisional site actor
stopped for landing outside its boundary kept a live binding, so a retry
resolved the stopped session instead of minting a fresh actor.

The root cause is that the key shape was known in two files. It now lives in
one: the binding map gains dropBySession(), and the controller asks for the
removal instead of taking the key apart itself.

Every existing test passed while the cleanup did nothing, because none of
them used a real binding map. The two new ones do.

Signed-off-by: Jonathan Bursztyn <jobur93@gmail.com>
…up regression tests

Signed-off-by: Jonathan Bursztyn <jobur93@gmail.com>
@jonybur
jonybur requested a review from NotASithLord as a code owner August 25, 2026 01:17
@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown

Visual regression

No visual change. All 68 screens render exactly as they do at the merge base.

09032f7bf7c6 (merge base) ⟶ 465eb8d21f3f. peerd commits no reference screenshots, so both sides were rendered from source in this run.

jonybur added a commit that referenced this pull request Aug 25, 2026
That fix lives in #439, not here. Claiming it in this PR's entry would
credit this change with something it does not contain.

Signed-off-by: Jonathan Bursztyn <jobur93@gmail.com>
Signed-off-by: Jonathan Bursztyn <jobur93@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Provisional site-actor cleanup never runs: the binding key is split on the wrong separator

1 participant