fix(relay): don't adopt foreign tabs/pop-ups on click — completes multi-agent isolation (#last hole)

After strict isolation (v1.5.16) a session's tracked set is only its OWN tabs, so
in `adopt_newly_opened` (run after every click to follow a pop-up) EVERY foreign
tab looks "new" relative to the session's `before` set and got adopted — a
click-heavy flow on a busy shared Chrome pulled other agents'/the user's tabs
(github, Lark, iphone-use) into the session mid-flow.

A pop-up the agent itself opened can't be told apart from a foreign tab over the
relay (the synthesized targetInfo carries no opener/window/group), so on the relay
`adopt_newly_opened` now adopts nothing: the agent drives only tabs it explicitly
created; pop-ups (OAuth/login windows) are the user's. Launched browsers (every
tab ours) still follow pop-ups. Verified live: a fresh click-heavy relay session
stays clean (only its own tabs), and 5 concurrent agents churning tabs show zero
cross-agent drift.
This commit is contained in:
leeguooooo
2026-06-17 13:31:49 +09:00
parent 32c25a6627
commit d86c9c4be2
2 changed files with 20 additions and 8 deletions
+12
View File
@@ -1560,6 +1560,18 @@ impl BrowserManager {
/// the active tab, per #7/#8.1); the caller surfaces it so the agent knows a
/// tab opened instead of seeing the old page (issue #24-A).
pub async fn adopt_newly_opened(&mut self, before: &HashSet<String>) -> Option<PageInfo> {
// STRICT MULTI-AGENT ISOLATION: on the relay this session's `before` set is
// only its OWN tabs, so EVERY foreign tab (the user's, other agents') looks
// "new" relative to it and would be adopted here — exactly the leak where a
// concurrent agent's tabs (github/Lark/iphone-use) showed up in this
// session mid-flow. A tab the agent itself opened (a pop-up) can't be
// distinguished from a foreign tab over the relay (no opener/window/group
// in the synthesized targetInfo), so don't adopt anything: the agent drives
// only tabs it explicitly created, and pop-ups (e.g. an OAuth/login window)
// are the user's. A launched browser (every tab ours) still follows pop-ups.
if self.agent_group().is_some() {
return None;
}
let result: GetTargetsResult = self
.client
.send_command_typed("Target.getTargets", &json!({}), None)