You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A friend chat sometimes jumps back to Chief's chat on its own (not reproduced) #261
Seen on box instance A (main 7922771): after a while on a friend chat (e.g. "Helper · UiB1415's Bot") the main view sometimes jumps back to Chief's chat on its own.
Looked at, not reproduced and not fixed (no live browser session available to the investigation):
No plugin code opens Chief on its own: every actions.openSession call in the social client is a user action or the Face-to-face join/start flow.
Candidates in core: the Bot-mode home() fallback (index.js, opens the Main Bot when the main view holds a Session that is in neither roster.byId nor roster.roomsById), which would fire if the friend chat's Bot record is briefly hidden/gone while remote.chats.sync rewrites it; and landOn when a chat part is archived for a fresh one.
To do: reproduce with a roster refresh on a friend chat (sync marking the remote Bot gone/hidden for a poll) and log which path calls openSession. If it is home(), a friend chat must count as known while it is only hidden.
Re-checked live on A (:3080) and B (:3081) with A's tab left open while B was used (~4 min each, plus a test message from B): no jump reproduced. PR #280 (merge 2ee01fe) makes an emptied main view return to the same chat instead of the Main Bot, and logs every openSession/landOn without user activation with its caller to diagnostics/console. Leaving this open until it is confirmed on upgraded instances; if it recurs, the diagnostics will name the caller.
Possible lead from the self-test on a003044 (2026-10-18 16:25, fresh A/B): right after B accepted A's invite, A's home created a friend-chat record for B's unshared Chief. remoteBots() publishes the unfiltered roster first, before syncOutgoingGrants() lets keepGrantedRemote() drop reverse-friends. 34 s later the re-filter marked it gone + hidden, and on the next load A opened that dead chat. This is the same "briefly listed, then gone/hidden" flip suspected here, so the home() / open-on-load paths should treat a hidden/gone chat consistently. Details: #303.
Triage on main 7b9e90b, 2026-10-19 ~12:10 Asia/Shanghai: still open, needs-info. Not reproduced; #280 added diagnostics that log any openSession/landOn without user action and its caller. Blocking: a live repro (or a diagnostics line naming the caller) on current main. Possibly related to the hidden/gone flip in #303.
Triage on main 0852b3f, 2026-10-19 16:59 Asia/Shanghai: still needs-info. Nothing in the code answers this. #280 logs every openSession/landOn that runs without a user action, with its caller, and #303 (the hidden/gone flip, the likely trigger) was fixed on 2026-10-18. This may be fixed already, but it has not been confirmed live.
Repro for the next friend-DM self-test: on A, open a friend's Bot chat right after accepting a fresh invite, which is when the old #303 flip happened. Leave it open for about 10 min while B sends 2-3 lines and A's roster polls. Then reload once. Watch whether the main view leaves the friend chat. Afterwards, search A's diagnostics/console for the #280 "openSession/landOn without user activation" lines.
Close if there is no jump and no such line.
If one shows up, paste the caller here. The fix is then whatever path it names.
Maintenance triage (2026-10-19 20:01 Asia/Shanghai, main 753b7e9): still needs-info. No new live self-test since the 16:59 check. Leaving open; next face/friend self-test should run the repro notes on the previous comment. Not pushing design questions while this waits on live confirmation.
Triage (2026-10-20 12:00 Asia/Shanghai, main a7adfe0): still needs-info. None of today's face-room/friend routing merges (#465, #467, #468, #487, #488) touch the client paths suspected here: the Bot-mode home() fallback in core/src/client/index.js (still present, it runs on switching back to Bot mode) and landOn. So this is not clearly fixed by code. #280 diagnostics and the #303 fix are in. Still needed: one live run of the repro in the 2026-10-19 16:59 comment on current main, plus any "openSession/landOn without user activation" diagnostics line. If there is no jump and no such line, close.
Triage (2026-10-20 16:05 Asia/Shanghai, main 787a502 which includes #516/#491/#478/#484): still needs-info. No new live repro since the 2026-10-19 notes. #280 diagnostics and the #303 fix remain the best leads; recent social merges do not touch the Bot-mode home() / landOn paths suspected here.
Still needed (one concrete outcome): run the repro in the 2026-10-19 16:59 comment on current main — open a friend Bot chat right after a fresh invite, leave it ~10 min with a couple of friend lines and roster polls, then reload once.
If there is no jump and no#280 "openSession/landOn without user activation" diagnostics line → please say so here and we will close as obsolete.
If it jumps, paste the diagnostics caller line.
Leaving open; not inventing a code fix without that signal.
Triage (2026-10-21, main 16f50984): still needs-info, and the next step belongs to SelfTest, not to the reporter.
One live run of the 2026-10-19 16:59 repro on current main decides it: open a friend Bot chat right after a fresh invite, leave it open ~10 min while the friend sends 2-3 lines and the roster polls, reload once. Then search the diagnostics for the #280openSession/landOn without user activation lines.
No jump and no such line → comment here and it closes as obsolete.
A line appears → paste the caller; the fix is whatever path it names.
No agent-ready and no guessed code fix until that run reports.
Triaged on 5db75d07. Not reproduced live, and it no longer needs a live run to be decided: the code says which case is still reachable and which one is already closed. Changing from needs-info to bug|area:ui|area:social|agent-ready.
What is already fixed
#280's landingPart (core/src/client/text.js:74-80) and its caller (core/src/client/sidebar.js:651-676) close the case this issue was opened for: a session-list reload that empties the main view while the chat is still the Bot's current part returns to that chat, not the Main Bot (:76-77, pinned by core/test/land-on.test.js:20-22). That is why three live runs on an idle chat showed nothing.
What is still reachable, without a click
Read the fall-through in sidebar.js:
:660bot = roster.byId[id] — a chat whose Bot is no longer in the roster is not a Bot chat any more.
:667 holds the view for a non-blank session, a room, or an agent session — so a chat with content cannot jump. That is the second reason the idle repro never fired.
What is left is the blank case: id !== '' with blank === '1', or an emptied view (id === '') where lastBot.current points at a Bot the roster just dropped. Both fall to :673landOn(roster.mainBotId, last, …), and landingPart (text.js:74-80) then resolves roster.byId[last.botId] as undefined and returns the Main Bot's part. The view moves to Chief's chat with no click behind it.
The roster can drop a Bot that is not "removed by the user": a friend who revokes the share, or a remote Bot deleted on their side, leaves the client's byId (core/src/client/sources.js:32-45 builds it from the bots list). A hidden Bot still carries hidden: true in the host roster (core/src/host/roster.js:228-232) and stays listed — so hidden alone does not trigger this; the Bot has to be gone from the list.
core/test/land-on.test.js:31-36 currently pins the jump as intended ("the Bot is gone → Main Bot"). That assertion is not wrong about its own input, but it conflates the user removed that Bot with the roster stopped listing it, and it is the line to change.
The rule the fix should follow
The roster cannot tell those two apart; the session list can, and the caller already reads it (sidebar.js:652-655). So:
last exists and last.sessionId is still a session in ctx.sessions.list → stay in it, whatever the roster says about that Bot. The chat is still there; the Bot's presence is not what makes it a destination.
last.sessionId is gone (the Bot was removed and its Sessions were archived with it) → the Main Bot, as today.
no last at all → the Main Bot, as today.
That needs no live instance and no design call: it is one condition, and the current test file is the right place for it.
Repro (deterministic, this is the requested repro)
In core/test/land-on.test.js, with a session list that still holds friend-1:
landingPart({ byId: { chief } }, last, 'chief', { stay: true }) → today 'chief-2', expected 'friend-1' (emptied view, roster lost the Bot, session alive).
Same with { stay: false } and last.sessionId still in the list → 'friend-1' (a blank session whose Bot left the list).
A control that keeps today's answer: the same input with last.sessionIdabsent from the session list → 'chief-2' (the Bot was removed, its Sessions archived).
Keep :31-36's no-last case unchanged.
If a live run happens anyway, the shape to try is a freshly opened friend chat with no message sent yet, while the friend revokes the share — not an idle chat with history. But the four cases above decide it without that.
Why this is not needs-info any more
The missing thing was never a user screenshot; it was a case nobody could trigger because two guards (:667, and "emptied view" needing stay) already protect the common path. The remaining gap is now named precisely enough to be fixed and pinned by a test.
Taking this one. Branch fix/261-landing-part, PR to follow on current main (38629bf4).
Reproduced with the deterministic cases from the analysis above: with last = { botId: 'friend', sessionId: 'friend-1' } and a roster that no longer lists the friend ({ byId: { chief } }), landingPart(roster, last, 'chief', { stay: true }) answers chief-2 today — the main view lands on the Main Bot with no click behind it.
The fix keeps the rule the analysis named: the session list, not the roster, says whether that chat still exists. landOn passes ctx.sessions.list and the id the view holds now, so the held chat (or a blank chat of that same session) stays, while a New Session the user opened still goes to the Main Bot. sidebar.js:667's guard for a chat with content is untouched. Tests first: core/test/land-on.test.js gains the four deterministic cases (red before the source change), and the bundle core/client.js is rebuilt.
Activity
Birfy commentedon Oct 18, 2026
Re-checked live on A (:3080) and B (:3081) with A's tab left open while B was used (~4 min each, plus a test message from B): no jump reproduced. PR #280 (merge 2ee01fe) makes an emptied main view return to the same chat instead of the Main Bot, and logs every openSession/landOn without user activation with its caller to diagnostics/console. Leaving this open until it is confirmed on upgraded instances; if it recurs, the diagnostics will name the caller.
Birfy commentedon Oct 18, 2026
Still not reproduced; leaving open. No code change this maintenance run.
Birfy commentedon Oct 18, 2026
Possible lead from the self-test on
a003044(2026-10-18 16:25, fresh A/B): right after B accepted A's invite, A's home created a friend-chat record for B's unshared Chief.remoteBots()publishes the unfiltered roster first, beforesyncOutgoingGrants()letskeepGrantedRemote()drop reverse-friends. 34 s later the re-filter marked itgone+hidden, and on the next load A opened that dead chat. This is the same "briefly listed, then gone/hidden" flip suspected here, so thehome()/ open-on-load paths should treat a hidden/gone chat consistently. Details: #303.Birfy commentedon Oct 19, 2026
Triage on main
7b9e90b, 2026-10-19 ~12:10 Asia/Shanghai: still open, needs-info. Not reproduced; #280 added diagnostics that log anyopenSession/landOnwithout user action and its caller. Blocking: a live repro (or a diagnostics line naming the caller) on current main. Possibly related to the hidden/gone flip in #303.Birfy commentedon Oct 19, 2026
Triage on main
0852b3f, 2026-10-19 16:59 Asia/Shanghai: still needs-info. Nothing in the code answers this. #280 logs everyopenSession/landOnthat runs without a user action, with its caller, and #303 (the hidden/gone flip, the likely trigger) was fixed on 2026-10-18. This may be fixed already, but it has not been confirmed live.Repro for the next friend-DM self-test: on A, open a friend's Bot chat right after accepting a fresh invite, which is when the old #303 flip happened. Leave it open for about 10 min while B sends 2-3 lines and A's roster polls. Then reload once. Watch whether the main view leaves the friend chat. Afterwards, search A's diagnostics/console for the #280 "openSession/landOn without user activation" lines.
Birfy commentedon Oct 19, 2026
Maintenance triage (2026-10-19 20:01 Asia/Shanghai, main
753b7e9): still needs-info. No new live self-test since the 16:59 check. Leaving open; next face/friend self-test should run the repro notes on the previous comment. Not pushing design questions while this waits on live confirmation.Birfy commentedon Oct 20, 2026
Triage (2026-10-20 12:00 Asia/Shanghai, main a7adfe0): still needs-info. None of today's face-room/friend routing merges (#465, #467, #468, #487, #488) touch the client paths suspected here: the Bot-mode
home()fallback incore/src/client/index.js(still present, it runs on switching back to Bot mode) andlandOn. So this is not clearly fixed by code. #280 diagnostics and the #303 fix are in. Still needed: one live run of the repro in the 2026-10-19 16:59 comment on current main, plus any "openSession/landOn without user activation" diagnostics line. If there is no jump and no such line, close.Birfy commentedon Oct 20, 2026
Triage (2026-10-20 16:05 Asia/Shanghai, main
787a502which includes #516/#491/#478/#484): still needs-info. No new live repro since the 2026-10-19 notes. #280 diagnostics and the #303 fix remain the best leads; recent social merges do not touch the Bot-modehome()/landOnpaths suspected here.Still needed (one concrete outcome): run the repro in the 2026-10-19 16:59 comment on current main — open a friend Bot chat right after a fresh invite, leave it ~10 min with a couple of friend lines and roster polls, then reload once.
#280"openSession/landOn without user activation" diagnostics line → please say so here and we will close as obsolete.Leaving open; not inventing a code fix without that signal.
Birfy commentedon Oct 21, 2026
Triage (2026-10-21, main
16f50984): stillneeds-info, and the next step belongs to SelfTest, not to the reporter.One live run of the 2026-10-19 16:59 repro on current main decides it: open a friend Bot chat right after a fresh invite, leave it open ~10 min while the friend sends 2-3 lines and the roster polls, reload once. Then search the diagnostics for the #280
openSession/landOn without user activationlines.No agent-ready and no guessed code fix until that run reports.
Birfy commentedon Oct 23, 2026
Triaged on
5db75d07. Not reproduced live, and it no longer needs a live run to be decided: the code says which case is still reachable and which one is already closed. Changing fromneeds-infotobug|area:ui|area:social|agent-ready.What is already fixed
#280'slandingPart(core/src/client/text.js:74-80) and its caller (core/src/client/sidebar.js:651-676) close the case this issue was opened for: a session-list reload that empties the main view while the chat is still the Bot's current part returns to that chat, not the Main Bot (:76-77, pinned bycore/test/land-on.test.js:20-22). That is why three live runs on an idle chat showed nothing.What is still reachable, without a click
Read the fall-through in
sidebar.js::660bot = roster.byId[id]— a chat whose Bot is no longer in the roster is not a Bot chat any more.:667holds the view for a non-blank session, a room, or an agent session — so a chat with content cannot jump. That is the second reason the idle repro never fired.id !== ''withblank === '1', or an emptied view (id === '') wherelastBot.currentpoints at a Bot the roster just dropped. Both fall to:673landOn(roster.mainBotId, last, …), andlandingPart(text.js:74-80) then resolvesroster.byId[last.botId]asundefinedand returns the Main Bot's part. The view moves to Chief's chat with no click behind it.The roster can drop a Bot that is not "removed by the user": a friend who revokes the share, or a remote Bot deleted on their side, leaves the client's
byId(core/src/client/sources.js:32-45builds it from thebotslist). A hidden Bot still carrieshidden: truein the host roster (core/src/host/roster.js:228-232) and stays listed — sohiddenalone does not trigger this; the Bot has to be gone from the list.core/test/land-on.test.js:31-36currently pins the jump as intended ("the Bot is gone → Main Bot"). That assertion is not wrong about its own input, but it conflates the user removed that Bot with the roster stopped listing it, and it is the line to change.The rule the fix should follow
The roster cannot tell those two apart; the session list can, and the caller already reads it (
sidebar.js:652-655). So:lastexists andlast.sessionIdis still a session inctx.sessions.list→ stay in it, whatever the roster says about that Bot. The chat is still there; the Bot's presence is not what makes it a destination.last.sessionIdis gone (the Bot was removed and its Sessions were archived with it) → the Main Bot, as today.lastat all → the Main Bot, as today.That needs no live instance and no design call: it is one condition, and the current test file is the right place for it.
Repro (deterministic, this is the requested repro)
In
core/test/land-on.test.js, with a session list that still holdsfriend-1:landingPart({ byId: { chief } }, last, 'chief', { stay: true })→ today'chief-2', expected'friend-1'(emptied view, roster lost the Bot, session alive).{ stay: false }andlast.sessionIdstill in the list →'friend-1'(a blank session whose Bot left the list).last.sessionIdabsent from the session list →'chief-2'(the Bot was removed, its Sessions archived).:31-36's no-lastcase unchanged.If a live run happens anyway, the shape to try is a freshly opened friend chat with no message sent yet, while the friend revokes the share — not an idle chat with history. But the four cases above decide it without that.
Why this is not
needs-infoany moreThe missing thing was never a user screenshot; it was a case nobody could trigger because two guards (
:667, and "emptied view" needingstay) already protect the common path. The remaining gap is now named precisely enough to be fixed and pinned by a test.Birfy commentedon Oct 23, 2026
Written-by: Dev4
Taking this one. Branch
fix/261-landing-part, PR to follow on current main (38629bf4).Reproduced with the deterministic cases from the analysis above: with
last = { botId: 'friend', sessionId: 'friend-1' }and a roster that no longer lists the friend ({ byId: { chief } }),landingPart(roster, last, 'chief', { stay: true })answerschief-2today — the main view lands on the Main Bot with no click behind it.The fix keeps the rule the analysis named: the session list, not the roster, says whether that chat still exists.
landOnpassesctx.sessions.listand the id the view holds now, so the held chat (or a blank chat of that same session) stays, while a New Session the user opened still goes to the Main Bot.sidebar.js:667's guard for a chat with content is untouched. Tests first:core/test/land-on.test.jsgains the four deterministic cases (red before the source change), and the bundlecore/client.jsis rebuilt.Birfy commentedon Oct 23, 2026
Written-by: Dev4
PR is up: #880 @
ad2feb27.Keep the main view on a chat whose Bot the roster dropped (#261)
Keep the main view on a chat whose Bot the roster dropped (#261)
Keep the main view on a chat whose Bot the roster dropped (#261)