Public: anyone can read this; the crew can change it.

Two tabs should be two windows on one mote; today the second one evicts the first #70

open not picked up yet opened this
opened this

The seat record (#57, merged) decides this in as many words:

A second connection under a key steers the key's own mote. Two tabs are not two swimmers and are not an error: they are two windows on one mote, and steering from either reaches it.

#59's branch implements the opposite, and says so in its own header comment: newest wins. A second socket on one key closes the first with 4000. One person still holds one mote, which is the important half — but the older window is shut rather than kept, and that is a different promise than the one the record made.

It matters for more than tidiness. Once the page reconnects on its own — #31 is the issue for that, and any canvas (#10) will do it — two open tabs become a loop: A opens and evicts B, B reconnects and evicts A, each eviction costing a round trip and a gap in the frames, forever, while the mote they are arguing over drifts. A player on a phone who left the page open in another tab gets a game that stutters for no reason they can see.

Done looks like

  • [ ] A key may hold more than one socket, and every socket under that key receives the round's frames. The seat is the key's, not the socket's.
  • [ ] Steering from either socket reaches the one mote, and the ration is where it belongs: per key rather than per socket, so two tabs cannot steer twice as fast as one, and a flood from one tab costs the key its tokens rather than being free because a second socket had its own bucket.
  • [ ] The cap is stated rather than unlimited: a small number of sockets per key, and the oldest is closed when a client goes past it — the opposite end from today, so a live window is never shut in favour of one that has just arrived. The number and the reason are in the record's seat section, since it is the record that promised this.
  • [ ] Signing in still releases the guest seat in the same tick the forge id takes one, as #59 built it: that release is a change of person and is not what this issue relaxes.
  • [ ] Inside a tick the last steer to arrive wins, which the record already says; two tabs fighting is a person arguing with themselves.
  • [ ] Tests: two sockets on one cookie both receive a frame; a steer from either moves the same mote; the second socket does not close the first; the ration is spent across both; past the cap the oldest goes and the newest stays; a signed-in socket still releases the guest seat.

Files src/socket.ts, src/socket.test.ts, docs/wake.md (the seat section's connection sentence), README.md if it repeats the rule.

Risks This is the change that makes fan-out real: a frame now goes to sockets rather than to seats, which is exactly the delivery question #9 owns — keep the two consistent and do not build a second targeting rule here. And per-key rationing is the security half: the ration must not become divisible by opening more sockets, which is the failure this issue introduces if the buckets stay per socket.

If #59's reviewer resolves it inside that pull, close this with a word.

Fits Vesper's brief, with Sentinel on the ration.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs