Skip to content

fix: re-register forked/replaced sessions with the broker#45

Open
iRonin wants to merge 1 commit into
nicobailon:mainfrom
iRonin:fix/fork-session-reregister
Open

fix: re-register forked/replaced sessions with the broker#45
iRonin wants to merge 1 commit into
nicobailon:mainfrom
iRonin:fix/fork-session-reregister

Conversation

@iRonin

@iRonin iRonin commented Jun 16, 2026

Copy link
Copy Markdown

Summary

Forked/replaced sessions never re-register with the broker. The runtime is initialized only in session_start; when a session's id changes in-process without a fresh session_start (forking/branching a session, or a resume path that adopts an id), it never (re-)registers and stays unreachable over intercom until a full process restart. No error surfaces — the session is alive and running turns locally but invisible to peers.

Fixes #44.

Root cause

  • getLiveContext() returns null whenever ctx.sessionManager.getSessionId() !== currentSessionId.
  • Every lifecycle handler is gated by getLiveContext() and bails first.
  • currentSessionId is only advanced inside those gated handlers (e.g. turn_start).

So once the live id diverges from currentSessionId, the guard rejects every handler, currentSessionId can never catch up, and the broker registration is stranded under the old identity. A related case: if no session_start ever fires, the extension stays inert even while the session runs turns.

Fix

  • Extract the session_start initialization into startSessionRuntime(ctx) (also drops any client still registered under the previous identity).
  • Add adoptSessionContext(ctx), called from turn_start, which re-initializes when the runtime never started or the live session id diverged from the registered one. A turn_start only fires for a live session, so the disposed/shuttingDown flags (true both before the first session_start and after a real shutdown) are intentionally not used to gate adoption — startSessionRuntime resets them.

Minimal and protocol-neutral; no broker changes.

Tests

Adds two regression tests to intercom.integration.test.ts:

  • a forked session that starts on its first turn (no session_start) registers with the broker — fails before the fix (session never appears); passes after.
  • an in-process session fork re-registers under the new identity — with no /name, the presence name is derived from the session id; before the fix the broker keeps the stale pre-fork name, after the fix it switches to the new identity and drops the old one.

Verified fail-then-pass against the unpatched tree. Full suite green:

ℹ tests 38
ℹ pass 38
ℹ fail 0

The intercom runtime only initialized on session_start. When a session's
id changed in-process without a fresh session_start (forking/branching a
session, or a resume path that adopts an id), it never re-registered and
stayed unreachable until a full process restart.

getLiveContext() rejects any context whose live session id diverges from
currentSessionId, and currentSessionId is only advanced inside handlers
that are themselves gated by getLiveContext() — so once the id diverges,
no handler can ever update it and the broker registration is stranded.

Extract the session_start init into startSessionRuntime() and add
adoptSessionContext(), called from turn_start, which re-initializes when
the runtime never started or the live session id diverged. A turn_start
only fires for a live session, so the disposed/shuttingDown flags are not
used to gate adoption.

Adds regression tests: a forked session that starts on its first turn
registers, and an in-process fork re-registers under the new identity.

Fixes nicobailon#44
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.

Forked/replaced session never re-registers with the broker (unreachable until full restart)

1 participant