真机复现(我做的):同 profile 再起一次 chrome.exe ⇒ Chrome **把命令委托给已有 实例并 exit 0**,stderr 逐字「正在现有的浏览器会话中打开。」⇒ **不产生新的 DevToolsActivePort** ⇒ 我们的等待只能超时 ⇒ 浏览器降级档整体不可用。 修法:启动前加一跳**探测**,三档各自出路 —— - 端口记录缺席 / 端口没人听 ⇒ 正常启动(后者先把**陈记录**清掉:那是启动时写下 的记录、不是锁,删一条指向死端口的记录不会伤到任何活实例); - 端口在听 + `/json/version` 有合法响应 ⇒ **复用它**(INFO `browser debug endpoint reused`),**不再起第二个**; - 端口在听但握不上手 ⇒ **如实报错**(保留现场,既不起进程也不删记录); - 真被占用且拿不到端点 ⇒ 报错带 **Chrome 原话**(`withChromeOutput`)+ 可操作处置。 🔴 红线(写进错误文案与注释):**绝不杀别人的浏览器**、不发信号抢 profile、 不新开监听端口;`ErrLaunch` / `errors.Is` 口径未破。 验收(主会话复跑 + 亲自变异):browser 包与 plugins/tools/io 两包 build/vet/test 全绿;我用 -overlay 摘掉「复用」那一支 ⇒ TestLocalChromeAdoptsLiveEndpoint 与 TestDial_ReusesLiveEndpointAndDoesNotSpawnSecondProcess 变红。子代理另跑了真机 端到端(临时 profile):会话 1 拿端口 51732 → 裸起第二次 chrome(exit 0)→ 会话 2 **复用同一端口、未起第二个实例**。 ⚠️ 已知未修(如实):Chrome 那句委托提示是**控制台代码页(GBK)字节**,我们的 UTF-8 日志里会显示成乱码(字节保真、人看不了);彻底解决要引编码转换,另定。 ⚠️ 判据③的取舍:陈记录 +端口恰被别的程序复用时,会持续报错直到人工删 `DevToolsActivePort`(错误文案已写明处置);**未加"报错后自动清理重试"**。
真机现象:主人看到 Chrome 窗口内有横幅(他读作「不支持接受的参数」),日志只有 一句「等待调试端口时被取消: context deadline exceeded」,看不出是谁的错。 三件(本片): - 接住子进程 stdout/stderr(有界:前 4 KiB / 上报 12 行,只缓存不输出)⇒ 失败时 打一条带 exe / argv / chrome_output / chrome_output_bytes 的 WARN;成功只记字节数 (不刷屏)。 - 三种启动失败在错误里分开:① 进程立刻退出(profile 被占用)② 等端口超时 ③ 调用方预算耗尽(ctx 已结束 ⇒ **根本不 spawn**)。③ 与 ② 用两个截止时间比大小 区分 —— 顺带修掉一个老缺陷:原来 ctx 一结束就报「等待调试端口时被取消」,而那 几乎总是我们自己的 30s 用满,现被正确归到 ②。 - 降级档不再被**已耗尽**的轮预算连坐:如实报「预算耗尽 ⇒ 未尝试浏览器渲染, 这不是浏览器故障」,**不许把"没试"说成"试了失败"**。plugins/tools/io/bodyfetch.go 一字未动(fetchedBy / browserError 语义原样),只在**发起方**决定要不要发起。 对主人那条横幅的结论(有据,非推测):那是 Chrome 的 **bad-flags 警告栏**,触发者 是 `--disable-blink-features=AutomationControlled` —— 它明确在 Chromium 的 kBadFlags 名单里(bad_flags_prompt.cc 列了 kDisableBlinkFeatures/kEnableBlinkFeatures),本机 Chrome 154 zh-CN 的文案是「您使用的是不受支持的命令行标记:$1。稳定性和安全性会 有所下降。」;而「不支持接受的参数」在 Chrome 的 zh-CN/en-US 资源与二进制里**零命中** ⇒ 是意译。⚠️ 该参数是 design/28 §2 要求的(掩盖 navigator.webdriver)⇒ 横幅是 **设计取舍的视觉副作用**,去掉它才消失(但会暴露自动化特征)。登记待主人裁决。 验收(主会话复跑 + 亲自变异):go build ./... + 两包 vet 绿;browser 与 cmd/cyrene 两包测试绿;我用 -overlay 去掉 cmd.Stderr 接线 ⇒ TestDial_ReportsChromeOutputAndArgvOnLaunchFailure 变红(chrome_output="" chrome_output_bytes=0)。 ⚠️ 未部署:跑着的产物不含本片,要等下次 build + restart。
- browsercfg 接进组合根:配置读 $DATA_DIR/config/plugins/browser.json(零 env)→ 探测(本机 Chromium → 已在跑的 CDP)→ 不可用就不注册(原因码入日志) - 自研最小出站 CDP 客户端(不 Enabled Runtime、隔离世界求值、不发 --enable-automation)+ 导航 + 截图 0600 落盘 + 指纹自检;工具 browser(open/screenshot/info,owner-only) - 3 个变异自检(启动恢复 --enable-automation/无视可用性/空闲回收失效) - 真机对照(两站各 1 次,**如实结论**):两侧都 pass ⇒ 「headless 被拦 / headful 通过」**未被证明**; 但测到两处硬差异:无头 UA 带 HeadlessChrome、screen 800 vs 2632;两模式 webdriver 均 false (把 L6 的推断变成实测)。跑完 0 残留 Chrome、无对外监听端口 ⚠️ 未做:MCP 自动接入(口径委派未落地)/自动注入上下文/面板页/搜索降级/docker 配方/Windows 用 pipe(Go ExtraFiles 不支持);SSRF 落了第三份同策实现待收口;浏览器会话未挂进程关闭链