diff --git a/cli/src/native/browser.rs b/cli/src/native/browser.rs index ca39ee0..9bad985 100644 --- a/cli/src/native/browser.rs +++ b/cli/src/native/browser.rs @@ -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) -> Option { + // 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) diff --git a/skill-data/core/SKILL.md b/skill-data/core/SKILL.md index ac536a2..df6ab93 100644 --- a/skill-data/core/SKILL.md +++ b/skill-data/core/SKILL.md @@ -134,14 +134,14 @@ drives the page without moving the user's mouse/keyboard, so it doesn't fight them for control. **Strict multi-agent isolation.** A session over the relay tracks and drives -**only the tabs it created** (its own group) plus pop-ups its own clicks open. It -does **not** adopt the user's existing tabs or other agents' tabs, so several -agents (and other tools opening tabs) can work in the same real Chrome -concurrently without ever dropping or stealing each other's tabs — another -agent's tab churn can't make your bound tab vanish or drift your commands onto the -wrong page. Consequence: `tab list` shows only *your* session's tabs; to drive a -specific pre-existing tab, navigate to it in your own tab instead of expecting it -in the list. **Anti-detection ranking: this real logged-in Chrome (extension +**only the tabs it created** (its own group). It does **not** adopt the user's +existing tabs, other agents' tabs, or pop-ups (e.g. an OAuth/login window — that's +the user's), so several agents (and other tools opening tabs) can work in the same +real Chrome concurrently without ever dropping or stealing each other's tabs — +another agent's tab churn can't make your bound tab vanish or drift your commands +onto the wrong page. Consequence: `tab list` shows only *your* session's tabs; to +drive a specific page, navigate to it in your own tab instead of expecting a +pre-existing or popped-up tab to appear in the list. **Anti-detection ranking: this real logged-in Chrome (extension connect) > a headed launched browser > headless (forbidden).** A genuine human browser has no headless/automation tells at all, so prefer it for anything anti-bot-sensitive.