lasso-mcp 1.27.0 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/ARCHITECTURE.md +28 -11
  2. package/README.en.md +6 -3
  3. package/README.md +6 -3
  4. package/dist/channels/BrowseChannel.d.ts +102 -4
  5. package/dist/channels/BrowseChannel.d.ts.map +1 -1
  6. package/dist/channels/BrowseChannel.js +245 -21
  7. package/dist/channels/BrowseChannel.js.map +1 -1
  8. package/dist/channels/DesktopChannel.d.ts +9 -2
  9. package/dist/channels/DesktopChannel.d.ts.map +1 -1
  10. package/dist/channels/DesktopChannel.js +46 -3
  11. package/dist/channels/DesktopChannel.js.map +1 -1
  12. package/dist/desktop/CGEventProvider.d.ts +6 -2
  13. package/dist/desktop/CGEventProvider.d.ts.map +1 -1
  14. package/dist/desktop/CGEventProvider.js +42 -2
  15. package/dist/desktop/CGEventProvider.js.map +1 -1
  16. package/dist/desktop/desktop-doctor-checks.d.ts +12 -3
  17. package/dist/desktop/desktop-doctor-checks.d.ts.map +1 -1
  18. package/dist/desktop/desktop-doctor-checks.js +229 -22
  19. package/dist/desktop/desktop-doctor-checks.js.map +1 -1
  20. package/dist/desktop/desktop-types.d.ts +38 -0
  21. package/dist/desktop/desktop-types.d.ts.map +1 -1
  22. package/dist/desktop/desktop-types.js.map +1 -1
  23. package/dist/doctor/doctor.d.ts +1 -1
  24. package/dist/doctor/doctor.js +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/tools/admin.d.ts +2 -1
  27. package/dist/tools/admin.d.ts.map +1 -1
  28. package/dist/tools/admin.js +15 -4
  29. package/dist/tools/admin.js.map +1 -1
  30. package/dist/tools/browse.d.ts.map +1 -1
  31. package/dist/tools/browse.js +73 -30
  32. package/dist/tools/browse.js.map +1 -1
  33. package/dist/tools/descriptions.d.ts.map +1 -1
  34. package/dist/tools/descriptions.js +63 -8
  35. package/dist/tools/descriptions.js.map +1 -1
  36. package/dist/tools/desktop.d.ts.map +1 -1
  37. package/dist/tools/desktop.js +6 -0
  38. package/dist/tools/desktop.js.map +1 -1
  39. package/dist/tools/read-text.d.ts +6 -0
  40. package/dist/tools/read-text.d.ts.map +1 -1
  41. package/dist/tools/read-text.js +3 -1
  42. package/dist/tools/read-text.js.map +1 -1
  43. package/dist/tools/screenshot.d.ts.map +1 -1
  44. package/dist/tools/screenshot.js +5 -2
  45. package/dist/tools/screenshot.js.map +1 -1
  46. package/dist/types.d.ts +9 -0
  47. package/dist/types.d.ts.map +1 -1
  48. package/doc/README.md +19 -9
  49. package/doc/architecture/02-/345/256/236/346/226/275/346/216/222/346/234/237.md +3 -1
  50. package/doc/bugs/10-2026-09-17-/345/225/206/346/240/207/347/253/231/346/273/221/345/235/227/346/211/271-cgEvent/346/212/225/351/200/222/350/257/201/344/274/252/344/270/216/345/233/236/346/211/247/350/257/255/344/271/211/345/206/263/350/256/256.md +233 -0
  51. package/doc/bugs//345/256/236/346/234/272/346/212/245/345/221/212-20260917-/345/225/206/346/240/207/347/253/231/346/273/221/345/235/227-cgEvent/346/212/225/351/200/222/346/226/255/350/243/202-v1.27.1.md +139 -0
  52. package/doc/bugs//345/256/236/346/234/272/346/212/245/345/221/212-20260917-/350/257/201/346/215/256/01-headed-/346/273/221/345/235/227/351/246/226/346/254/241/347/216/260/350/272/253.png +0 -0
  53. package/doc/bugs//345/256/236/346/234/272/346/212/245/345/221/212-20260917-/350/257/201/346/215/256/02-/346/213/226/346/213/275/345/211/215/345/237/272/347/272/277.png +0 -0
  54. package/doc/bugs//345/256/236/346/234/272/346/212/245/345/221/212-20260917-/350/257/201/346/215/256/03-/346/213/226/346/213/2751/345/220/216-/351/233/266/345/217/230/345/214/226.png +0 -0
  55. package/doc/bugs//345/256/236/346/234/272/346/212/245/345/221/212-20260917-/350/257/201/346/215/256/04-/350/201/232/347/204/246/345/220/216/346/213/226/346/213/2752-/351/233/266/345/217/230/345/214/226.png +0 -0
  56. package/doc/bugs//345/256/236/346/234/272/346/212/245/345/221/212-20260917-/350/257/201/346/215/256/05-/345/205/263/351/227/255X/347/202/271/345/207/273/345/220/216-/351/233/266/345/217/230/345/214/226-/345/206/263/345/256/232/346/200/247.png +0 -0
  57. package/doc/bugs//345/256/236/346/234/272/346/212/245/345/221/212-20260917-/350/257/201/346/215/256/06-desktop/345/205/250/345/261/217/346/210/252/345/233/276-/345/205/211/346/240/207/351/252/214/350/257/201/345/244/261/350/264/245.png +0 -0
  58. package/doc/testing/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/270/205/345/215/225.md +2 -0
  59. package/doc/usage/01-KEY-GUIDE.md +2 -1
  60. package/doc/usage/02-TROUBLESHOOTING.md +16 -0
  61. package/doc/usage/04-/345/267/245/345/205/267/347/244/272/344/276/213/344/275/223/347/263/273.md +193 -0
  62. package/package.json +1 -1
  63. package/src/channels/BrowseChannel.ts +256 -20
  64. package/src/channels/DesktopChannel.ts +45 -3
  65. package/src/desktop/CGEventProvider.ts +66 -5
  66. package/src/desktop/desktop-doctor-checks.ts +266 -23
  67. package/src/desktop/desktop-types.ts +35 -0
  68. package/src/doctor/doctor.ts +1 -1
  69. package/src/index.ts +1 -1
  70. package/src/invariants/check-invariants.mjs +150 -0
  71. package/src/tools/admin.ts +15 -4
  72. package/src/tools/browse.ts +93 -30
  73. package/src/tools/descriptions.ts +63 -8
  74. package/src/tools/desktop.ts +6 -0
  75. package/src/tools/read-text.ts +3 -1
  76. package/src/tools/screenshot.ts +5 -2
  77. package/src/types.ts +9 -0
package/ARCHITECTURE.md CHANGED
@@ -334,7 +334,7 @@ engine=auto(默认)→ 多源扇出(machine_mcp + brave 两 API 源)
334
334
  |---|---|---|---|
335
335
  | 架构不变量 | `check-invariants.mjs`(自写) | INV-1..100 编号域静态 grep + 形状测 | **实装 100 条**(85-96 = BUG-03~08 五批;97/99 = BUG-09 批;**INV-98 = 驱逐哨兵契约,尾款轮 §8.A/8.F 转真锚;INV-100 = 链真值契约,尾款轮 §8.B/8.E.1**——2026-09-16 合并轮实跑 100/100 PASS) |
336
336
  | INV 自测 | `inv-selftest.mjs`(`npm run inv-selftest`) | 抽样 INV 做「注入违规 → 必红」复证 | **样本覆盖 20/84 时代口径 + 26 个 pin 红翻转实证**(外部契约类全覆盖;85-96 批次自带形状测) |
337
- | TS 单测 | vitest | channel / fallback / forest / doctor / launcher / outline-contract / replay-baseline / stealth / lifecycle / cdp-actions / search-local / content-second-hop / elicitation / extract-refs / quality / http-serp / fetch-feed / tool-descriptions-no-leak / render / bug03-09 批次 spec 等 | **3120 passed + 1 skipped**(192 文件,BUG-09 尾款轮+合并轮实跑;1 skip = linux-only ResourceMonitor 在 macOS 对称跳过) |
337
+ | TS 单测 | vitest | channel / fallback / forest / doctor / launcher / outline-contract / replay-baseline / stealth / lifecycle / cdp-actions / search-local / content-second-hop / elicitation / extract-refs / quality / http-serp / fetch-feed / tool-descriptions-no-leak / render / bug03-10 批次 spec 等 | **3186 passed + 1 skipped**(196 文件,BUG-10 §9.5 终局复验实跑;1 skip = linux-only ResourceMonitor 在 macOS 对称跳过) |
338
338
  | Rust 单测 | cargo test | ax / applescript / cgevent(+keymap) / screenshot / tcc / windows / protocol / role-map | **207 测试**(cargo test 实跑;`rust-helper/src/*.rs` 自 v1.13 零改——v1.18.4 仅动 `build/sign.sh` ad-hoc 签名链) |
339
339
  | 跨平台编译 | cargo check --target | Windows (x86_64-pc-windows-msvc) + Linux (x86_64-unknown-linux-gnu) | 本地手测(CI 为 JS 门禁三件套,不含 Rust 步骤——r4 轮改真口径) |
340
340
  | 录制回放回归 | npm run replay-baseline | fixtures/serp-baseline/ 三引擎录制基线 | 6 条 HTML fixture(baidu/bing/google ×2;doctor #32 实跑 detail) |
@@ -342,7 +342,7 @@ engine=auto(默认)→ 多源扇出(machine_mcp + brave 两 API 源)
342
342
  | 全量功能测试 | doc/testing/01 清单 + ft 执行记录 | 四面板(search / browse / infra / perf)~170 用例真机 | ft-round1 **ALL-CLEAN**(2026-08-18) |
343
343
  | 契约锁 | chrome-devtools-mcp@**1.7.0** version pin(`LOCKED_CDP_MCP_VERSION` 单一真源) | 上游小版本升级不破 Lasso;迁移要点见 §2.1 | SubprocessManager.ts |
344
344
 
345
- ## 11. 不变量(实装 100 条,编号至 100)分类
345
+ ## 11. 不变量(实装 103 条,编号至 103)分类
346
346
 
347
347
  | 范畴 | INV 编号 | 守的是什么 |
348
348
  |---|---|---|
@@ -368,6 +368,7 @@ engine=auto(默认)→ 多源扇出(machine_mcp + brave 两 API 源)
368
368
  | v1.25 当前页截图(BUG-07) | **95** | url 省略 + action=screenshot = current-page 截图(零导航;有 url 字节级不变)——schema↔description 同 commit 等 A⁺ 六面 |
369
369
  | v1.26 马拉松稳定性(BUG-08) | **96** | 五组防线:callTool timeout 透传 / doEvaluate 传预算 / 栈扫除判定序 + chrome-stop 域隔离 / fresh profile 先杀后删 + 陈年双闸 / wait current-page 家族 / fallback 耗尽 primary-first 复合串 |
370
370
  | v1.27 反爬通道与 url 统一(BUG-09,预写态) | **97 / 98 / 99 / 100** | HeadedChannel 平级契约(spawn 无 --headless + lasso-owned `--user-data-dir` + 无 StealthEngine 注入 + 装配四处)/ 驱逐哨兵契约(**尾款轮 §8.A/8.F 已实装**:三信号漏斗 + INV-98 a-g 全组)/ 链真值契约(尾款轮 §8.B/8.E.1:尾读真值 + 种子等值守卫 + INV-100)/ 两态生命周期(reapPolicy 判定序 + 探测器并发安全 + 存量 spec 字节级不变回归锚 + C3 逃生门) |
371
+ | v1.28 桌面投递回执(BUG-10,预写态) | **101 / 102 / 103** | 坐标鼠标动作落地回执(per-action 必附 `cursor_after`;`landed:false` → `ok:false`+`cgevent_no_landing`;全失败沿 unknown→tier4 策略;(2b) 触发分支形态×4 + (2c) `ev.post(HID)` 路由钉——对抗复审变异锚)/ doctor #22 投递自检 consent 门(无 env 零 cgevent_dispatch + 有 env 复位 move 在场)/ TCC 诚实化(dispatch 门仅 "denied" 拒绝;macOS<15 无 IOHID 拒绝分支;`iohid_post_event` 为 advisory 字段) |
371
372
 
372
373
  完整 INV 列表 + 释义见 `src/invariants/check-invariants.mjs` 顶部注释。
373
374
 
@@ -462,10 +463,12 @@ $ lasso launch-chrome
462
463
 
463
464
  ## 14. 版本与发布
464
465
 
465
- - **当前版本**:npm latest `1.26.0`;工作树 HEAD `6cecb70`(BUG-09 尾款轮+合并轮终态)为 **v1.27.0 预写态**(changelog 已预写、版本行未改,发版归审查循环后用户指令——README v1.27.0 条目)
466
+ - **当前版本**:npm latest `1.27.1`(v1.27.0 `0cbd950` / v1.27.1 `81e882d` 均已于 2026-09-16 发布);工作树(BUG-10 批终态 `fa7a56a` + 同日 doc 收卷轮)为 **v1.28.0 预写态**(changelog 双语已预写、版本行未改,发版归审查循环后用户指令——README v1.28.0 条目)
466
467
  - **version 真源**:`package.json` + `src/index.ts:LASSO_SERVER_VERSION` + `src/doctor/doctor.ts:LASSO_VERSION`(INV-63 守:三处必字面量一致)
467
- - **v1.19.0 → v1.27.0 要点**(2026-09-16 增补;用户向完整版见 README changelog;决策记录见 doc/bugs/03-09 + doc/渲染档文档组):
468
- - **v1.27.0(预写)**:反爬根治通道 + url 语义统一批(BUG-09)——`browse_headed` 有头强力档(L2 防御梯:真实有头 Chrome、consent 首行、两态生命周期 30min idle/接管粘滞+24h 硬顶、`LASSO_HEADED_IDLE_MS`/`LASSO_HEADED_HARD_CAP_MS`)+ url 单一 ensure-navigation 语义(四族收敛,`did_navigate` 回显,消灭「extract+url 读残留页」假数据形态)+ steps wait 三键统一 + worked⇒error 迁 `warnings` + headless→logged_in 跨通道 fallback 边默认移除(`LASSO_FALLBACK_CROSS_CHANNEL` 逃生门)+ final_url 尾句读剥离 + doctor CDP 报生效端口 + **WT4 驱逐哨兵(尾款轮 §8.A)**:`eviction_suspected:{from,to,at_ms}` 三信号漏斗(S1 5s 静默窗 / S2 闸门漂移复核 / S3「Execution context was destroyed」∧ host 偏离合取 typed error)一次性 advisory 回显 + consent hint,绝不自动升级通道;LoggedInChannel 显式 opt-out + **steps 链回显真值化(尾款轮 §8.B,INV-100)**:链级 `final_url` 改链尾真值读(种子等值守卫,永不回显请求串)+ 链级 `did_navigate` 回显 + 先导导航 sd 双标注透传(链执行语义零变化)+ **macOS occlusion 真机定案(尾款轮 §8.E.2)**:「屏幕外全藏窗口被判 occluded」假设证伪(恒 visible + rAF 满速),A.4④ 窗口终值维持边缘露出 `8,40`(零参数变更、零 INV 迁移)。
468
+ - **v1.19.0 → v1.28.0 要点**(2026-09-16 增补,2026-09-17 收卷轮扩至 v1.28;用户向完整版见 README changelog;决策记录见 doc/bugs/03-10 + doc/渲染档文档组):
469
+ - **v1.28.0(预写,BUG-10 桌面投递回执批)**:商标站滑块实机报告(cgEvent「投递断裂」P0)白盒**证伪**后重定向为「消灭静默失败」——`cgevent_cursor_state` 纯读原语(光标/空闲/主屏 bounds,零新依赖)/ 坐标鼠标动作落地回执(`cursor_after`+`landed`,0.5pt 容差;未落地 → `ok:false`+`cgevent_no_landing`,全失败沿 unknown→tier4)/ 物理竞争警示(`physical_input.attribution`,合成事件自扣 D-γ)/ doctor #22 投递自检(opt-in `LASSO_DOCTOR_INPUT_SELFTEST`,光标 wiggle 7px+复位,consent 伦理门)/ TCC 探测诚实化(IOHID 四态 advisory,门语义字节不变)/ desktop screenshot 默认落盘(对齐 browse 通道)/ evaluate 表达式自动返回值(P2 静默错值)+ `js_form` 错误教学 / TROUBLESHOOTING §2.18 分层拦截面。INV 100→103;对坑复审 §9 adversarial clean(gate 4/4)。决策记录 doc/bugs/10
470
+ - **v1.27.1(已发布 2026-09-16,`81e882d`)**:工具示例体系批(doc/usage/04)——13 调用示例进工具描述 + 错误即教学 + schema `.describe()` 全覆盖 + 防漂移四闸(verbatim/consent 前缀/调用形⊆schema/预算帽);盲测 8/8 + 变异 9/9 kill
471
+ - **v1.27.0(已发布 2026-09-16,`0cbd950`)**:反爬根治通道 + url 语义统一批(BUG-09)——`browse_headed` 有头强力档(L2 防御梯:真实有头 Chrome、consent 首行、两态生命周期 30min idle/接管粘滞+24h 硬顶、`LASSO_HEADED_IDLE_MS`/`LASSO_HEADED_HARD_CAP_MS`)+ url 单一 ensure-navigation 语义(四族收敛,`did_navigate` 回显,消灭「extract+url 读残留页」假数据形态)+ steps wait 三键统一 + worked⇒error 迁 `warnings` + headless→logged_in 跨通道 fallback 边默认移除(`LASSO_FALLBACK_CROSS_CHANNEL` 逃生门)+ final_url 尾句读剥离 + doctor CDP 报生效端口 + **WT4 驱逐哨兵(尾款轮 §8.A)**:`eviction_suspected:{from,to,at_ms}` 三信号漏斗(S1 5s 静默窗 / S2 闸门漂移复核 / S3「Execution context was destroyed」∧ host 偏离合取 typed error)一次性 advisory 回显 + consent hint,绝不自动升级通道;LoggedInChannel 显式 opt-out + **steps 链回显真值化(尾款轮 §8.B,INV-100)**:链级 `final_url` 改链尾真值读(种子等值守卫,永不回显请求串)+ 链级 `did_navigate` 回显 + 先导导航 sd 双标注透传(链执行语义零变化)+ **macOS occlusion 真机定案(尾款轮 §8.E.2)**:「屏幕外全藏窗口被判 occluded」假设证伪(恒 visible + rAF 满速),A.4④ 窗口终值维持边缘露出 `8,40`(零参数变更、零 INV 迁移)。
469
472
  - **v1.19.0**:确定性渲染档(`render-chrome --ensure/--status/--stop/doctor`,`src/render/` 5 文件 + 冻结旗标快照 + detached guardian)+ perf/acc 裁决批(npx registry 税 `--prefer-offline` 等)——设计决议见 doc/渲染档设计决议.md
470
473
  - **v1.20.0**:渲染档并行安全批——`--stop` 端口作用域化(显式合法=只收该 port / 未设=全收 / 非法=exit 1,提案 §6 裁决)
471
474
  - **v1.21.0**:浏览器主权与生命周期根治批(BUG-03)——CLI 默认 30min 回收 + 停机三维谓词 + 端口占用归因(`ledger_zombie_collected` / `never_kill_user_asset` / `user_taken_asset`)+ `--mode headless` 档
@@ -484,7 +487,7 @@ $ lasso launch-chrome
484
487
  - **v1.18.7**:架构重审落地——browse 族接口面死参数清扫(诚实化)+ doctor/channels 解耦(INV-84)+ firstText 单一定义(INV-83)+ 文档改真 + INV 82→84;随后 P2 处置轮(doc/governance/11)46 项三档裁决 + `launch-chrome --help` 误启动修复 + CI actions 升 checkout@v7 / setup-node@v6 并加 Node 24
485
488
  - **doctor readiness 现状(如实)**:任一 check fail → `ready:false`。**#15 `rust_helper_signed` 现行语义 = ad-hoc 签名 → warn**(2026-08-31 用户裁决降级:ad-hoc 是官方免费合法方案、功能正常,唯一代价 rebuild 后 TCC 重授权;FAIL 把正常配置判成 ready:false 属噪音。Developer ID 长期方案保留在 next_step;Developer ID 正签仍 pass、未签仍 warn——回归测试 rust-helper-signed-warn.spec 三态锚定)
486
489
  - **跨平台 backend**:macOS 本机全证;Win/Linux 编译可证 + 契约可证,真机执行待社区反馈
487
- - **门禁(本地)**:`npm run build` / `npm test`(**2026-09-16 尾款轮+合并轮基准:3120 passed + 1 skipped,192 文件 + readme-sync**——BUG-09 §8 实跑口径)/ `npm run check-invariants`(**100 实装全 PASS**,编号至 100 全实装,2026-09-16 实跑)/ `npm run inv-selftest` + `cargo test`(207,CI 不含);`npm run gate` 后台化 + 60s 轮询读 log(180s stall 防误判;vitest 树超时追杀带 `LASSO_GATE_VITEST_TIMEOUT_MS`,doc/bugs/08 §12)
490
+ - **门禁(本地)**:`npm run build` / `npm test`(**2026-09-17 BUG-10 收卷基准:3186 passed + 1 skipped,196 文件 + readme-sync**——bugs/10 §9.5 终局复验实跑口径)/ `npm run check-invariants`(**103 实装全 PASS**,编号至 103 全实装,2026-09-17 实跑)/ `npm run inv-selftest` + `cargo test`(`#[test]`+`#[tokio::test]` 计 178,2026-09-17 grep 实测;CI 不含——**注意 2 个 v1.11 起既有 dispatch 测试在有 GUI 的 mac 本机跑会物理 post**,bugs/10 §9.4 观察项);`npm run gate` 后台化 + 60s 轮询读 log(180s stall 防误判;vitest 树超时追杀带 `LASSO_GATE_VITEST_TIMEOUT_MS`,doc/bugs/08 §12)
488
491
  - **CI(.github/workflows/ci.yml 实况)**:ubuntu-latest × Node **20/22/24** 矩阵(20=下限锚点 / 22=maintenance LTS / 24=active LTS——search-local 的 `node:sqlite` 依赖 NODE_MAJOR>=23,加 24 后该文件 40 测在 CI 真跑);actions checkout@v7 / setup-node@v6;步骤 = npm ci → build → test → check-invariants(**JS 门禁三件套,无 cargo 步骤**——Rust 面靠本地 cargo test/check 守)
489
492
 
490
493
  ## 15. 质量与决策主线(doc/governance/01 → doc/governance/06 → doc/testing/01)
@@ -501,12 +504,13 @@ $ lasso launch-chrome
501
504
  8. **渲染档 + BUG-03~08 五批实战驱动线**(2026-09-01 → 09-15,doc/渲染档文档组 + doc/bugs/03-08):确定性渲染档(v1.19-1.20,media-gen-mcp 消费方托付浏览器生命周期)→ 浏览器主权根治(BUG-03 事故:用户 Chrome 被裸 kill)→ 归属鉴定 chrome-status(BUG-04,消费方实战)→ 消费方台账 L1-L4 两批(BUG-05/07,novel-engine)→ 幽灵常驻 24h 硬顶(BUG-06,用户 12h 实锤)→ 反爬马拉松稳定性(BUG-08,3 小时商标库实战 + F 组用户负载 188 实锤)。每批 = 事故/台账驱动 → 设计决议 → 实施 → 对抗复审 clean 闭环;INV 84 → 96。
502
505
  9. **BUG-08 审查循环(2026-09-16,Gauntlet 对抗复核)**:主对象 `git diff 92200d3..7ab999b`(16 commit/43 files)+ 五批累计架构漂移面——R-INT-06 证据修订后记(testing/01 §6:BrowseChannel.ts 磁石效应五批中四批落点 14 commit、doEvaluate 85 行 ≥4 职责类,**下批触碰 navigate/evaluate 语义须抽导航语义模块**,doc/testing/01 表后记)等。
503
506
  10. **BUG-09 反爬根治批(2026-09-16,喵虎核验报告驱动,doc/bugs/09)**:消费方核心诉求「强力反爬就完全没办法」→ 四路线裁决矩阵(stealth patch REJECTED〔D-α/β 实效反证〕/ 有头通道采纳为 L2〔WT0 spike 前置定生死 + tm 真机四轮 6/6〕/ 分层防御梯采纳)+ url 语义统一(三分裂 Set 收敛单一 ensure-navigation,P1 假数据面根治)+ P2 批 C1-C5;三 worktree 并行(WT1/2/3)+ WT0 spike + 三轮对抗复审 clean(r3 变异 6 kill 1 存活归类 + 真机六探针)+ 尾款轮(§8):§7.2 移交项 1/2/3 全清偿——WT4 驱逐哨兵(A.5r2 三信号漏斗,INV-98 真锚)+ steps 链真值化(INV-100)+ macOS occlusion 定案(A.4④ 维持 8,40)。**未竟**:R-INT-06「抽导航语义模块」义务触发未执行(doc/bugs/09 §7.2 #6 登记,移交下批)。
507
+ 11. **BUG-10 桌面投递回执批(2026-09-17,商标站滑块实机报告驱动,doc/bugs/10)**:报告判定「desktop cgEvent 投递断裂 P0」→ 设计合成员白盒**证伪**(三路独立投递成功 + 受控计数器页 `isTrusted:true` 完整序列;真凶 = 并发物理输入竞争 + 报告 diff 判定法盲区)→ 修复重定向为「消灭静默失败」:决议 A(读原语/落地回执/物理竞争警示/doctor 自检/TCC 诚实化——报告四建议中 PostToPid 被 SOTA 反证驳回)+ B(evaluate 表达式自动返回)+ C(desktop 截图默认落盘)+ D(分层拦截面文档);双 worktree(U-R/U-B 文件域互斥)+ 对抗否定复审轮 1 五路变异(2 存活当场修为 INV-101(2b)(2c) 变异锚)+ 终局复验 adversarial clean(gate 4/4,196 文件/3186+1/INV 103)。伦理面:合成输入只做检测与诚实报告,零绕过输入监控路径(§9.5 亲验)。R-INT-06 义务第三次触发未执行(testing/01 §6 ④″ 登记,继续顺延)。
504
508
 
505
509
  方法学沉淀(供复用):裁决官不采信文档(关键声称白盒双源亲验);证据阶梯 L0-L3;mutation 即验收;「先拿事实再加参数」;收敛协议前置;零基视角才可见方案级盲区;决策分级(GO/DECISION/WATCH/NOGO)交用户裁决而非默认全做。
506
510
 
507
- ## 16. v1.19 → v1.27 新增架构面(渲染档 + BUG-03~09 六批;2026-09-16 增补)
511
+ ## 16. v1.19 → v1.28 新增架构面(渲染档 + BUG-03~10 七批;2026-09-16 增补,2026-09-17 收卷轮扩 v1.28)
508
512
 
509
- > 本节为增量对齐段:v1.18.7 基线之后新增、且改变架构形态的面。逐项决策记录见 doc/bugs/03-09 与 doc/渲染档文档组(索引 doc/README.md ⑦/⑤)。
513
+ > 本节为增量对齐段:v1.18.7 基线之后新增、且改变架构形态的面。逐项决策记录见 doc/bugs/03-10 与 doc/渲染档文档组(索引 doc/README.md ⑦/⑤)。
510
514
 
511
515
  ### 16.1 台账体系(chrome ledger,v1.9 既有 + 五批扩展为治理中枢)
512
516
 
@@ -533,7 +537,7 @@ chrome-devtools-mcp 栈(进程内 spawn,跨进程不可见)与台账(主
533
537
 
534
538
  vitest 池显式钉死 `threads`(主进程死 = worker 线程随之死,forks 孤儿类结构性消灭——用户负载 188 实锤事故)+ `npm run gate` 对 vitest 树的超时追杀带(到点树根存活即整树 SIGKILL;E1 白盒实锤 spawnSync timeout 形态必漏杀忙 worker,已否决)。gate 运行纪律:后台化 + 60s 轮询读 log(防 180s stall 误判死)。
535
539
 
536
- ### 16.7 反爬防御梯 + url 单一导航语义(BUG-09,v1.27.0 预写态)
540
+ ### 16.7 反爬防御梯 + url 单一导航语义(BUG-09,v1.27.0)
537
541
 
538
542
  - **防御梯三层**:L0 = 既有 headless + stealth 栈(字节级不变,覆盖指纹层);L1 = **url 单一 ensure-navigation 语义的副产品**——`extract/evaluate/snapshot` + url ≠ 当前页在单次调用内「导航→load→抢读」,无 MCP 往返间隔(JS 层延迟驱逐站点的快照窗口机制化;诚实边界:驱逐提前到 DOMContentLoaded 前或服务端 302 则无效);L2 = **`browse_headed` 有头强力档**(`src/channels/HeadedChannel.ts`,SteelChannel 同配方平级兄弟;同上游 chrome-devtools-mcp@1.7.0 不带 `--headless`,零新二进制/依赖——不触新组件红线;真实环境即真实指纹,**不接 StealthEngine**〔与 headless 相反取舍,INV-97 钉〕)。
539
543
  - **两态生命周期**(SubprocessManager per-spec `reapPolicy` 三元组,存量 spec 缺省=行为字节级不变):未接管态 30min idle 回收(`LASSO_HEADED_IDLE_MS`,宽于 headless 域 5min);**接管粘滞**——pipe 会话 30s 周期 `document.hasFocus()` 探测,用户聚焦即标记、永不 idle 回收(visible 红线延伸到有头通道;用户关窗 = pipe 断 = 既有清理路径);24h 硬顶 `LASSO_HEADED_HARD_CAP_MS` 是唯一兜底出口(BUG-06 孤儿舰队防线同型)。INV-99 钉判定序/并发安全/回归锚。
@@ -542,6 +546,19 @@ vitest 池显式钉死 `threads`(主进程死 = worker 线程随之死,forks
542
546
  - **驱逐哨兵(尾款轮 §8.A 落地,决议 A.5r2——判据面修订)**:原案 framenavigated 监听在 lasso 层不可达(McpClient 无订阅面,ExpectPoll.ts:32 同型定谳先例)→ 三信号漏斗替代:S1 5s 静默窗采样(did_navigate 后 setTimeout+unref,读后复检 actSeq/client)/ S2 闸门漂移复核(ensure-nav 门既有读上加 host 判等,零新增读)/ S3 错误串合取(「Execution context was destroyed」∧ 确认读 host 偏离 ⇒ typed error `page_redirect_eviction_suspected:` + classify didnt 自持)。三硬守卫(G-placeholder/G-client/S1 读后复检)是判据的一部分。回显 `eviction_suspected:{from,to,at_ms}` 一次性消费 + consent hint(**绝不自动升级通道**——零 FallbackDecider/spawn);LoggedInChannel 显式 opt-out(SSO 跨域流转合法常态)。诚实边界:同 host 驱逐仅 S3 可捕(症状兜底句接手)、www↔apex 异 host 误报可容忍(advisory)。开放项与移交清单见 doc/bugs/09 §7.2/§8。
543
547
  - **steps 链回显真值化 + headed 窗口终值(尾款轮 §8.B/§8.E)**:链级 `final_url` 从「恒回显请求串」(残留页上跑链谎称目标页——R2-1 行为面)改为**链尾一次 `readCurrentHref` 真值读**(种子链:最后携带真值的 step partial → entryNav.final_url → 缺席;**种子等值守卫**:候选=请求串视同缺席——doNavigate `?? url` 回退形态不得洗白进链级真值;INV-100 来源判据措辞)+ 链级 `did_navigate` 如实回显 + 先导导航 same-document 双标注透传;**链执行语义零变化**(否决「链入口 ensure-nav」——先导 navigate step 既有范式会双重导航伤 SPA 态)。macOS occlusion 三臂真机实验(§8.E.2)证伪「屏幕外窗被判 occluded」假设(P2 全藏恒 visible + rAF 满速)→ A.4④ 窗口终值维持边缘露出 `8,40`(consent 契约 + 归属锚可见性 + hasFocus 探测器语义三理由否决全藏为默认)。
544
548
 
549
+ ### 16.8 桌面合成输入回执体系(BUG-10,v1.28.0 预写态)
550
+
551
+ 诚实交付家族(INV-13/19)在 desktop 合成输入维度的延伸——「API worked 实际零效果」这类静默失败的系统性消灭面(触发源:商标站滑块实机报告 P0「投递断裂」,白盒证伪后重定向):
552
+
553
+ - **`cgevent_cursor_state` 纯读原语**(rust-helper 单 op,零新依赖):光标位置 + `CGEventSourceSecondsSinceLastEventType` 空闲态(extern "C",stateID int 签名)+ 主屏 bounds——回执/自检/归因三处共用的基座(R-CI-02)。
554
+ - **落地回执(Tier A,自动)**:坐标鼠标动作(click/move/drag + 带 x,y 的 scroll 先导 move)最终 post 后 30ms settle 读回光标 → per-action `cursor_after{x,y}` + `landed`(0.5pt 严格容差);未落地 → 该动作 `ok:false` + `cgevent_no_landing`,全部失败沿既有「unknown → 升 tier4」策略(D-β:回执只让失败可见,不改升级策略)。语义边界(自洽,防假阳):`landed` 声明的是**光标落点**而非页面效果——动画页不可能假阳,「click worked ≠ 被接受」通则见 TROUBLESHOOTING §2.18。
555
+ - **物理输入竞争警示(Tier C,自动)**:dispatch 入口单读空闲态 + 进程内 `last_synthetic_mouse_ms`(AtomicI64 单写者,R-INT-07)→ `physical_input.attribution ∈ {idle, synthetic, physical}` 纯函数归因(合成事件同样计入空闲钟,须自扣——D-γ);**信号不策略**:worked 不因此翻转,agent 收 `physical` 自行重发。
556
+ - **Tier B(opt-in 语义回执)= 既有 `expect` 后置条件**(v1.11 T15),本批零代码只补文档指针——三层回执各就各位,不造第二套 expect。
557
+ - **doctor #22 投递自检(opt-in consent 门)**:`LASSO_DOCTOR_INPUT_SELFTEST=1` 才执行(默认 warn skip)——光标 wiggle 7px + 复位 + 读回判读(无歧义,优于像素 diff——后者有 33×30px 恒定动画盲区,报告实锤)。opt-in 的伦理根据(D-α):探针会真实移动用户光标;doctor 可被 agent 触发,未经部署者明示的位移违反「合成输入=真实干预须可预期」红线。INV-102 钉 consent 门。
558
+ - **TCC 探测诚实化**:`IOHIDCheckAccess` 四态直报(Undefined 是真实第三态,**该状态下投递实证可用**——macOS<15 绝不可折叠为 denied,否则杀死可用生产路径);`iohid_post_event` 为 advisory 字段,dispatch 门语义字节不变(仅 "denied" 拒绝;<15 永不因 IOHID 拒)。探测只报 OS 所说,不推断不规避。
559
+ - **Rejected-by-design**(§8 全录):PostToPid 定向(SOTA 反证:PID 定向鼠标被 AppKit 静默丢弃——绕过 WindowServer 指针状态)/ act 内置像素 diff 回执(判定法盲区即反例)/ act 内自动重试(信号不策略)/ <15 IOHID 门控 / desktop screenshot filePath 选项(免白名单诉求由 lasso 管理默认路径满足)/ helper 会话重挂(疑因三路证伪)/ 自检开真实小窗。
560
+ - 同批非回执面:desktop screenshot 默认落盘(browse 通道唯一做法对齐,`inline_base64` 逃生舱——860KB base64 爆 token 根治)+ evaluate 表达式自动返回(BrowseChannel 形态判定五路由——P2 静默错值)。**键盘路径无回执**(本批范围=鼠标;§9.5 补充观察:后续批若补键盘回执,INV-101(2c) 路由锚须同步扩)。
561
+
545
562
  ## 17. 相关文档
546
563
 
547
564
  - [README.md](./README.md) — 用户手册(安装 / 配置 / 工具列表 / 隐私 / 故障排查)
@@ -555,9 +572,9 @@ vitest 池显式钉死 `threads`(主进程死 = worker 线程随之死,forks
555
572
  - [doc/governance/07 文档查缺补漏](./doc/governance/07-文档查缺补漏/gap-matrix.md) — 文档盘点矩阵(新鲜度档位 + F 编号映射真源)
556
573
  - [doc/governance/11 P2 处置台账](./doc/governance/11-P2处置台账.md) — 全面重审 46 项 P2 三档裁决全记录(20 修 / 25 留档 / 1 已偿)
557
574
  - [doc/governance/12 回告收口决议](./doc/governance/12-回告收口与交付物测试载体决议.md) — 交付物必须自带测试载体制度(deny-hook 样例落仓 + 文档同步锚)
558
- - [doc/bugs](./doc/bugs/) — BUG 档案(01 rust-helper 路径 / 02 外部消费与隐藏生命周期 / 03 hidden 档劫持 / 04 死锁与 chrome-status+附录E / 05 消费方台账 L1-L3 / 06 幽灵常驻 / 07 消费方台账 L4 / 08 商标马拉松五组 / 09 反爬根治通道与 url 语义统一)
575
+ - [doc/bugs](./doc/bugs/) — BUG 档案(01 rust-helper 路径 / 02 外部消费与隐藏生命周期 / 03 hidden 档劫持 / 04 死锁与 chrome-status+附录E / 05 消费方台账 L1-L3 / 06 幽灵常驻 / 07 消费方台账 L4 / 08 商标马拉松五组 / 09 反爬根治通道与 url 语义统一 / 10 商标站滑块批——cgEvent 投递证伪与回执语义)
559
576
  - [doc/渲染档设计决议](./doc/渲染档设计决议.md) 等根级渲染档文档组 7 件 — 决议/需求/对接契约/并行配方/perf-acc 裁决/stop 作用域提案/登记开项(索引见 doc/README.md ⑦)
560
577
 
561
578
  ---
562
579
 
563
- 本文档是 Lasso 架构概览(user-first;2026-08-31 全量对齐刷新至 v1.18.7——事实基准 = HEAD `4a40b7e` 源码实核 + `tools/list` / `npm test` / `check-invariants` / `inv-selftest` / `cargo test` / `doctor` 实跑,20 条机械断言逐条对账零漂移;**2026-09-16 DocAudit 轮增补对齐至 v1.26.0 预写态**——头部横幅 / §2.1 渲染档与 sidecar / §9 三层防线 / §10 计数 / §11 INV 96 / §14 版本要点 / §15 主线 8-9 / 新 §16 五批新增面;**2026-09-16 BUG-09 批增补对齐至 v1.27.0 预写态**——§1 工具面 18 / §2-§3.1 HeadedChannel / §11 INV 编号至 99(实装 98)/ §14-§15 / §16.7 反爬防御梯与 url 单一语义,实跑核验 = check-invariants 98/98 + vitest 全量)。深度架构基线(含 F 编号 / 不变量推导链 / 测试策略)见 [`doc/architecture/01`](./doc/architecture/01-功能架构.md);v0.1 → v1.27.0 实施排期(含每 phase 决策记录)见 [`doc/architecture/02`](./doc/architecture/02-实施排期.md)。
580
+ 本文档是 Lasso 架构概览(user-first;2026-08-31 全量对齐刷新至 v1.18.7——事实基准 = HEAD `4a40b7e` 源码实核 + `tools/list` / `npm test` / `check-invariants` / `inv-selftest` / `cargo test` / `doctor` 实跑,20 条机械断言逐条对账零漂移;**2026-09-16 DocAudit 轮增补对齐至 v1.26.0 预写态**——头部横幅 / §2.1 渲染档与 sidecar / §9 三层防线 / §10 计数 / §11 INV 96 / §14 版本要点 / §15 主线 8-9 / 新 §16 五批新增面;**2026-09-16 BUG-09 批增补对齐至 v1.27.0 预写态**——§1 工具面 18 / §2-§3.1 HeadedChannel / §11 INV 编号至 99(实装 98)/ §14-§15 / §16.7 反爬防御梯与 url 单一语义,实跑核验 = check-invariants 98/98 + vitest 全量;**2026-09-17 BUG-10 收卷轮增补对齐至 v1.28.0 预写态**——§11 INV 编号至 103(实装 103)/ §14 版本要点 v1.27.0 转已发布 + v1.27.1 + v1.28.0 / §10 计数 / §15 主线 11 / 新 §16.8 桌面合成输入回执体系,实跑核验 = bugs/10 §9.5 终局复验 gate 4/4〔196 文件 / 3186+1 skipped / INV 103/103〕)。深度架构基线(含 F 编号 / 不变量推导链 / 测试策略)见 [`doc/architecture/01`](./doc/architecture/01-功能架构.md);v0.1 → v1.28.0 实施排期(含每 phase 决策记录)见 [`doc/architecture/02`](./doc/architecture/02-实施排期.md)。
package/README.en.md CHANGED
@@ -212,7 +212,7 @@ Goes to the Internet Archive (Wayback Machine) to find the last archived copy of
212
212
 
213
213
  ## Install
214
214
 
215
- **Current version v1.27.0** (changelog in the collapsed block at the end of this section).
215
+ **Current version v1.28.0** (changelog in the collapsed block at the end of this section).
216
216
 
217
217
  Prerequisites: Node.js ≥ 20 + Claude Code (or any MCP-capable client).
218
218
 
@@ -227,9 +227,12 @@ Restart Claude Code → `/mcp` → `lasso ✓ Connected`. **That's the one line
227
227
  **Deterministic render browser for other AI tools (render tier)**: if you use rendering tools like media-gen-mcp that demand "same input → same pixels", one line after installing lasso — `npx -y lasso-mcp render-chrome --ensure` — brings up a deterministic headless Chrome on port 9224 (frozen flag snapshot + isolated temp profile) and prints the `wsEndpoint` for the consumer to attach to; **the browser keeps running even if the consumer process is SIGKILLed** (lifecycle owned by lasso), and it is idle-reaped after 10 minutes with its profile cleaned up (tunable via `LASSO_RENDER_IDLE_MS`). Companions: `render-chrome --status` introspection / `--stop` (honors `LASSO_RENDER_PORT`: an explicit valid port stops only that port, unset = all render records, an invalid value exits 1; global teardown remains `chrome-stop --modes render`) / `render-chrome doctor [--clean]` orphan & stale-profile sweep (dry-run by default; honors `LASSO_RENDER_PORT` like `--stop`: an explicit valid port scopes the orphan scan, unset = full scan, an invalid value exits 1; in-use instances with a touch heartbeat within 10 minutes are exempt from orphan judgment). **Multiple parallel acceptance agents on one machine** (whose independent teardown commands would kill each other's instances) need a three-env namespace: `LASSO_RENDER_PORT` + `LASSO_LAUNCHED_CHROMES_PATH` + `LASSO_RENDER_GUARDIAN_PID_PATH` — with all three set, parallel agents are mutually invisible; see the full recipe and teardown discipline in [doc/渲染档-并行验收隔离配方.md](doc/渲染档-并行验收隔离配方.md) (Chinese).
228
228
 
229
229
  <details>
230
- <summary>📋 Changelog (v1.8 → v1.27.0 — click to see what each version changed)</summary>
230
+ <summary>📋 Changelog (v1.8 → v1.28.0 — click to see what each version changed)</summary>
231
231
 
232
- - **v1.27.0** (unreleased prewrite — release awaits the user's call): anti-scraping root-cause channel + url-semantics unification batch (BUG-09, driven by the Miaohu verification report, doc/bugs/09) — (1) **new tool `browse_headed` (headed power tier — the anti-scraping root-cause channel)**: the root remedy for sites that evict headless automation at the JS layer (the page loads, then redirects itself away 2-3s later — trademark-registry shape): a REAL on-screen headful Chrome window (same upstream chrome-devtools-mcp, just without `--headless`; zero new dependencies); real-machine trademark-site residency 6/6 across four rounds. The stealth trade-off is the opposite of the headless tier (a real environment IS the real fingerprint — nothing injected). **Calling it opens a real window on your screen** — description and hint both pin "call only after explicit user consent". Two-state lifecycle: unclaimed sessions idle-reclaim after 30 minutes (`LASSO_HEADED_IDLE_MS`); the moment you click into the window it is marked user-taken and **never auto-reclaimed** (close the window yourself to reclaim; a 24h hard cap `LASSO_HEADED_HARD_CAP_MS` is the only orphan-fleet backstop). (2) 🔴 **url semantics unified (corrective behavior change — the fake-data face)**: every url-aware action now follows ONE rule — **omit url = current page** (no active session → explicit error, never a silent blank page) / **url == current page = zero-navigation direct execution** (no more reloads wiping SPA state) / **url ≠ current page = navigate first, then execute**; every url-aware action now echoes `did_navigate:true/false`. Fixed: `extract`+url used to **read the stale session page while claiming success** (fake data) → now reads after navigating; `evaluate` with url omitted used to be rejected → now legal (the old description's promise honored); `screenshot`/`pdf`/`network` with the same url as the current page switch from reload to skip (SPA state preserved). (3) `wait` validation inside steps chains is now consistent with the top level (three keys: text/selector/url_contains — chains previously accepted only text). (4) step chains with `outcome:worked` no longer leave transient errors in the `error` field (moved to a new `warnings[]`; contract hardened: worked ⇒ error always empty). (5) **breaking (one-switch recoverable)**: `browse_headless` no longer auto-falls-back to `browse_logged_in` (the logged-in channel must be an explicit choice; cross-channel error cross-contamination was a marathon misdiagnosis root) — set `LASSO_FALLBACK_CROSS_CHANNEL=1` to restore the old behavior. (6) `final_url` trailing punctuation stripped (`.,;:!?` — forensically pinned to upstream prose end-sentences being swallowed; parentheses/quotes untouched); `lasso doctor` CDP-check failure details now carry the effective port. (7) **WT4 eviction sentinel (final-payment round, doc/bugs/09 §8.A)**: `browse_headless`/`browse_headed` responses can now carry `eviction_suspected:{from,to,at_ms}` + hint — when the channel observes the page drifting to a different host after lasso's own navigation settled (three-signal funnel: a 5s silent-window sample / gate-drift re-check / the conjunction of evaluate dying with `Execution context was destroyed` AND a host offset → typed error `page_redirect_eviction_suspected:`), a one-shot advisory signal is attached (consumers can for the first time mechanically tell "my call was wrong" from "the site killed headless"); **signal only, NEVER auto-upgrades the channel** — the hint pins "ASK THE USER FIRST, then retry with browse_headed" (the surprise of opening a real window requires consent); `browse_logged_in` explicitly opts out (cross-domain SSO flows are legitimate there — the signal would be pure noise); (8) **step-chain echo truthification (corrective lie-removal)**: chain-level `final_url` used to echo the request string verbatim (a chain running on a stale session page would claim the target page) → now a tail-of-chain ground-truth read (the page's real href; omitted when no truth is available — **never the request string**) + chain-level `did_navigate` echoed honestly + leading-navigation same-document annotations passed through — chain execution semantics unchanged (zero consumer workflow breakage); (9) macOS occlusion real-machine experiment settled (§8): the "fully offscreen windows get judged occluded by the system" hypothesis is **refuted** (measured constantly visible + full-speed rAF); the `browse_headed` window default stays edge-visible `8,40` (consent-contract and window-attribution-anchor ruling; zero parameter change); Tests 2997→3120 (192 files) / invariants 96→100 implemented (numbered to 100 — INV-98 eviction-sentinel real anchor + INV-100 step-chain URL truth contract; reserved slots cleared to zero).
232
+ - **v1.28.0**: the kill-silent-failure batch after the cgEvent delivery "break" was falsified (driven by the trademark-site slider field report, doc/bugs/10) — white-box verdict: the HID delivery chain is intact (a controlled counter page produced a full `isTrusted:true` sequence); the real culprit is concurrent physical input racing plus a blind judgment method, so the deliverable is not "fix delivery" but "make the failure visible": ① **landing receipts for coordinate mouse actions**: `desktop act` click/move/drag (scroll with x,y likewise) each echo `cursor_after{x,y}` + `landed` (the real cursor is read back after the final post, 0.5pt tolerance) — **not landed → that action gets `ok:false` + `cgevent_no_landing`** (previously "API worked, zero effect" was silent); ② **physical-input racing warning**: dispatch-level `physical_input.attribution` (idle/synthetic/physical) — `physical` = a mouse event later than our own synthetic post was detected (the user is physically operating; just resend — worked never flips on this, signal not policy); ③ **honest TCC probing**: macOS<15 no longer fakes "dimension absent" — the raw IOHID PostEvent probe reports four states (Undefined is a real third state and delivery is proven to work under it; per-process attribution recorded honestly), **gate semantics unchanged** (<15 never rejects on IOHID); ④ **doctor #22 delivery selftest** (opt-in `LASSO_DOCTOR_INPUT_SELFTEST=1`: moves your cursor 7px and restores it — off by default, agents cannot trigger it; cursor read-back judgment, unambiguous); ⑤ **desktop screenshot writes to disk by default** (browse-channel parity: `/tmp/lasso-screenshot-<uuid>.png`, path only — previously a full-screen 860KB base64 blob blew the token budget; `inline_base64:true` restores the old behavior). Ethical red line: synthetic input only gets "detect and report honestly" — no capability to bypass user input monitoring is introduced. Rejected: PostToPid targeting (SOTA counter-evidence: PID-targeted mouse events are silently dropped by AppKit) / in-act pixel diff / in-act auto-retry.
233
+ - **v1.28.0**: bugs/10 browse/docs half — evaluate return-value contract + anti-bot detection-surface docs batch, BUG-10, driven by the trademark-site slider campaign, doc/bugs/10) — (1) 🔴 **corrective behavior change (the silent-wrong-value face)**: `evaluate`'s `options.js` gains two expression routes — previously a **single-line bare expression** (`JSON.stringify({...})`, `document.title`) got wrapped as a statement body, the expression's value swallowed by the statement → **always undefined**; a **parenthesized expression** (`({a:1})`) got passed through as a function expression, upstream evaluating it to an object → **`fn is not a function`** (real-machine report P2: a hidden contract that took two trial-and-error calls to discover). Both shapes are now auto-wrapped as expression bodies and their **VALUE is returned**; the three existing forms (function expression passthrough / IIFE wrapping / statement body) are byte-identical (statement bodies still require an explicit `return`); (2) **errors as teaching**: a statement body returning undefined now echoes `data.js_form:"statement_body"` + `js_form_hint` (one sentence on WHY it is undefined and how to fix it); upstream `is not a function` errors get the same hint appended; (3) the tool description's evaluate section gains a RETURNS contract clause ("THREE forms … All work" was false for expression shapes — that description gap WAS P2); (4) `browse_headless`/`browse_headed` descriptions gain a "**click worked ≠ submission accepted**" NOTE + TROUBLESHOOTING §2.18 (tm.aliyun.com layered interception profile: home layer now open / submission layer silently swallowed on headless, slider captcha on headed — verify submissions with `wait url_contains`/`text` or `extract`, never trust the act receipt). This entry is part 2 (the browse/docs half); the same batch's part 1 (rust/desktop half: cgEvent delivery receipts / doctor self-test / desktop screenshots to disk) is the v1.28.0 entry above.
234
+ - **v1.27.1**: tool-examples batch (consumer-facing self-description) — fixes "callers learn by trial and error": previously only 1 of 18 tools carried a copyable example, the rest were rules-only prose (proven by seven consumer reports). ① **13 call examples landed in tool descriptions** (visible end-to-end via `tools/list`, every one reverse-engineered from a real trial-and-error incident); ② **errors as teaching** — high-frequency errors embed the correct call shape (Rust "did you mean" style); ③ full schema `.describe()` coverage (previously zero field descriptions repo-wide); ④ **four anti-drift gates** — verbatim anchor / consent-prefix anchor / call-shape⊆schema / budget cap. Pure interface self-description, zero behavior change; blind-test 8/8 + 9/9 mutations killed. System doc in doc/usage/04.
235
+ - **v1.27.0**: anti-scraping root-cause channel + url-semantics unification batch (BUG-09, driven by the Miaohu verification report, doc/bugs/09) — (1) **new tool `browse_headed` (headed power tier — the anti-scraping root-cause channel)**: the root remedy for sites that evict headless automation at the JS layer (the page loads, then redirects itself away 2-3s later — trademark-registry shape): a REAL on-screen headful Chrome window (same upstream chrome-devtools-mcp, just without `--headless`; zero new dependencies); real-machine trademark-site residency 6/6 across four rounds. The stealth trade-off is the opposite of the headless tier (a real environment IS the real fingerprint — nothing injected). **Calling it opens a real window on your screen** — description and hint both pin "call only after explicit user consent". Two-state lifecycle: unclaimed sessions idle-reclaim after 30 minutes (`LASSO_HEADED_IDLE_MS`); the moment you click into the window it is marked user-taken and **never auto-reclaimed** (close the window yourself to reclaim; a 24h hard cap `LASSO_HEADED_HARD_CAP_MS` is the only orphan-fleet backstop). (2) 🔴 **url semantics unified (corrective behavior change — the fake-data face)**: every url-aware action now follows ONE rule — **omit url = current page** (no active session → explicit error, never a silent blank page) / **url == current page = zero-navigation direct execution** (no more reloads wiping SPA state) / **url ≠ current page = navigate first, then execute**; every url-aware action now echoes `did_navigate:true/false`. Fixed: `extract`+url used to **read the stale session page while claiming success** (fake data) → now reads after navigating; `evaluate` with url omitted used to be rejected → now legal (the old description's promise honored); `screenshot`/`pdf`/`network` with the same url as the current page switch from reload to skip (SPA state preserved). (3) `wait` validation inside steps chains is now consistent with the top level (three keys: text/selector/url_contains — chains previously accepted only text). (4) step chains with `outcome:worked` no longer leave transient errors in the `error` field (moved to a new `warnings[]`; contract hardened: worked ⇒ error always empty). (5) **breaking (one-switch recoverable)**: `browse_headless` no longer auto-falls-back to `browse_logged_in` (the logged-in channel must be an explicit choice; cross-channel error cross-contamination was a marathon misdiagnosis root) — set `LASSO_FALLBACK_CROSS_CHANNEL=1` to restore the old behavior. (6) `final_url` trailing punctuation stripped (`.,;:!?` — forensically pinned to upstream prose end-sentences being swallowed; parentheses/quotes untouched); `lasso doctor` CDP-check failure details now carry the effective port. (7) **WT4 eviction sentinel (final-payment round, doc/bugs/09 §8.A)**: `browse_headless`/`browse_headed` responses can now carry `eviction_suspected:{from,to,at_ms}` + hint — when the channel observes the page drifting to a different host after lasso's own navigation settled (three-signal funnel: a 5s silent-window sample / gate-drift re-check / the conjunction of evaluate dying with `Execution context was destroyed` AND a host offset → typed error `page_redirect_eviction_suspected:`), a one-shot advisory signal is attached (consumers can for the first time mechanically tell "my call was wrong" from "the site killed headless"); **signal only, NEVER auto-upgrades the channel** — the hint pins "ASK THE USER FIRST, then retry with browse_headed" (the surprise of opening a real window requires consent); `browse_logged_in` explicitly opts out (cross-domain SSO flows are legitimate there — the signal would be pure noise); (8) **step-chain echo truthification (corrective lie-removal)**: chain-level `final_url` used to echo the request string verbatim (a chain running on a stale session page would claim the target page) → now a tail-of-chain ground-truth read (the page's real href; omitted when no truth is available — **never the request string**) + chain-level `did_navigate` echoed honestly + leading-navigation same-document annotations passed through — chain execution semantics unchanged (zero consumer workflow breakage); (9) macOS occlusion real-machine experiment settled (§8): the "fully offscreen windows get judged occluded by the system" hypothesis is **refuted** (measured constantly visible + full-speed rAF); the `browse_headed` window default stays edge-visible `8,40` (consent-contract and window-attribution-anchor ruling; zero parameter change); Tests 2997→3120 (192 files) / invariants 96→100 implemented (numbered to 100 — INV-98 eviction-sentinel real anchor + INV-100 step-chain URL truth contract; reserved slots cleared to zero).
233
236
  - **v1.26.0**: anti-scraping marathon stability batch (BUG-08, driven by a 3-hour trademark-registry session, doc/bugs/08) — (1) 🔴 **corrective behavior changes (the fake-data face — an order of magnitude more dangerous than crashes)**: navigating to a URL that differs ONLY by hash (SPA `#/search?q=` param change) used to be treated as same-document with no reload — the page kept showing OLD query results under the NEW url (in the field this nearly reported a true value of 3718 as "0, clean"); lasso now detects the shape and reloads on the target hash by default, echoing `same_document_navigated/same_document_reloaded` (opt out with `options.no_reload:true` — annotated, not reloaded; the detection basis is normalized URL comparison via `new URL()` origin+pathname+search — the empty-path-omitted-slash form `http://x#/q=b` IS same-document with `http://x/#/q=a`, which raw string comparison misses and would revive the fake-data shape — sealed in the review round). `evaluate` with a `url` used to silently run on the CURRENT page while final_url echoed the target (fabricated); url now means ensure-navigation (different page → navigate first, then run) and final_url is always real. (2) **long-evaluate stability**: per-call budget `options.budget_ms` (default 120s / `LASSO_EVAL_TIMEOUT_MS` / cap 600s) now reaches the MCP call layer — previously every call fell into the SDK's accidental 60s default, so any >60s batch JS timed out; timeouts are typed `mcp_request_timeout:` + a teaching hint (**the browser is NOT dead** — the upstream mutex wedge self-heals in ~3min); fallback-chain exhaustion errors became primary-first composites (the primary channel's own error leads, last-hop excerpt trails — attribution pollution eliminated). (3) **freshProfile escape hatch**: the only remedy once a site server-side-fingerprints the headless instance (silent zero results) — `options.freshProfile:true` swaps in a whole new coherent identity (throwaway profile dir [owner-anchored name + four cleanup paths, no BUG-03 garbage repeat] + deterministic stealth rotation + full stack respawn; logged_in never supports it). (4) **internal stack governance**: chrome-devtools-mcp stacks now register to a sidecar at spawn and any spawn sweeps orphans first (pid-level merge + triple guard + lstart cross-check — never touches non-lasso processes), ending the marathon "two zombie stacks nobody may touch" deadlock; new admin action `browser_recycle` (the sanctioned in-process restart, never touches detached Chrome). (5) `wait` gains current-page mode (omit url, same session contract as screenshot); `browse_logged_in` auto-discovers the newest non-render ledger port when default 9222 has no CDP (three-layer resolution, result carries `+auto_discovered_port:<port>`; explicit `LASSO_CDP_PORT` always wins); `fetch_url` failures classified (`fetch_failed:dns_failed/connect_refused/connect_timeout/tls_failed/aborted_timeout` — local env vs target refusal now distinguishable). (6) test-infra self-healing (BUG-08 F, the real load-188 incident on the user's machine): the vitest pool is explicitly pinned to threads (main process death = worker threads die with it — the forks-pool orphan class is structurally eliminated) and `npm run gate` gains a timeout kill-belt for the whole vitest tree (fires while the tree root is still alive and SIGKILLs the entire tree; `LASSO_GATE_VITEST_TIMEOUT_MS` tunable; the spawnSync-timeout form was disproven by whitebox experiment E1 — it always misses busy workers; doc/bugs/08 §12). Tests 2895→2997 / invariants 95→96 (INV-96); existing consumers (cc-control / media-gen-mcp) zero breaking.
234
237
  - **v1.25.0**: current-page screenshot batch (BUG-07, novel-engine animation-forensics driven) — `action=screenshot` **with url omitted now screenshots the current managed page directly** (the standalone `screenshot` tool gains the same semantics): previously both screenshot paths re-navigated unconditionally, wiping whatever page state evaluate had established (a CSS animation paused mid-frame, injected temporary DOM) — state-sensitive screenshots were unreachable and the consumer had to detour through a second browser-automation stack. Now the same session closes the loop across four channels: open with url → `evaluate` freeze/inject → screenshot without url → `console` forensics. With no active session (cold channel / page closed / healed-over), it errors explicitly with guidance — **never silently opening a browser, never faking state with a blank page**; the old url-bearing behavior is unchanged (pinned by regression anchors); three clean adversarial rounds — 6/6 mutations red + session-drift attacks on live dual channels with zero penetration (concurrent races refused / popup vectors pinned to the managed page / silent page-swap invalidated at the commit point). Upstream research verdict: the industry-universal screenshot semantic IS "capture the current state" — this version realigns lasso with the standard.
235
238
  - **v1.24.0**: ghost-instance root-fix batch (BUG-06, driven by a live 12-hour instance) — ① 🔴 **behavior change**: `launch-chrome --idle-ms 0` changes from "never reap" to "**no self-reaping, but a 24-hour hard cap as a safety net**" — a windowless hidden instance can no longer linger indefinitely as an "invisible, uncloseable ghost" (this batch's trigger: a 12-hour instance invisible in the Dock and menu bar with no way to close it). True unlimited now requires the additional explicit `--no-hard-cap` (**double intent** — prevents scripts passing 0 casually); deployments can tune or disable via `LASSO_LAUNCH_HARD_CAP_MS` (`=0` disables entirely); failure direction is always safe (invalid values fall back to capped). Old scripts relying on "0 = forever" should add `--no-hard-cap`. ② **cross-process liveness truth**: before hard-cap reaping, the touch-file heartbeat is consulted (any session / any consumer still using it → no wrongful kill); userTakenAt / visible exemptions carry over natively (re-evaluated at kill time, the race window sealed). ③ **over-age observability**: `doctor` / `chrome-status` warn early on instances past half the hard cap (no new kill surface added). Six live-machine acceptance checks all PASS + two clean adversarial rounds (three mutations all red / wrongful-kill panorama replayed with live stand-in processes, zero casualties / render tier zero cross-contamination).
package/README.md CHANGED
@@ -221,7 +221,7 @@ macOS 上能控 Finder / Mail / Safari / Notes / 系统设置等任何原生 app
221
221
 
222
222
  ## 安装
223
223
 
224
- **当前版本 v1.27.0**(更新日志见本节末尾折叠块)。
224
+ **当前版本 v1.28.0**(更新日志见本节末尾折叠块)。
225
225
 
226
226
  前提:Node.js ≥ 20 + Claude Code(或任何支持 MCP 的客户端)。
227
227
 
@@ -236,9 +236,12 @@ claude mcp add lasso -- npx -y lasso-mcp
236
236
  **给其它 AI 工具当确定性渲染浏览器(渲染档)**:如果你在用 media-gen-mcp 这类要求「同一输入必须产出同一像素」的渲染工具,装好 lasso 后只需一行 `npx -y lasso-mcp render-chrome --ensure`——它会在 9224 端口拉起一个确定性 headless Chrome(冻结旗标快照 + 独立临时 profile),输出消费方直连用的 `wsEndpoint`;**消费方进程被强杀浏览器也照常存活**(生命周期归属 lasso),空闲 10 分钟自动回收并连带清理 profile(`LASSO_RENDER_IDLE_MS` 可调)。配套:`render-chrome --status` 自省 / `--stop` 收尾(认 `LASSO_RENDER_PORT`:显式设 port 只收该 port,未设=全部 render 记录,非法值 exit 1;全局收口仍可用 `chrome-stop --modes render`)/ `render-chrome doctor [--clean]` 孤儿与陈年 profile 清理(默认只报告;认 `LASSO_RENDER_PORT`,同 `--stop`:显式设 port 只判该 port,未设=全扫,非法值 exit 1;touch 心跳 10 分钟内的在用实例豁免不判孤儿)。**同机多 agent 并行验收**(多个 agent 各自清场会互杀对方实例)需配三 env 契命名空间隔离:`LASSO_RENDER_PORT` + `LASSO_LAUNCHED_CHROMES_PATH` + `LASSO_RENDER_GUARDIAN_PID_PATH`,配齐后并行互不可见,配方与清场纪律见 [doc/渲染档-并行验收隔离配方.md](doc/渲染档-并行验收隔离配方.md)。
237
237
 
238
238
  <details>
239
- <summary>📋 更新日志(v1.8 → v1.27.0,点开看每版改了什么)</summary>
239
+ <summary>📋 更新日志(v1.8 → v1.28.0,点开看每版改了什么)</summary>
240
240
 
241
- - **v1.27.0**(未发版预写——发版归用户指令):反爬根治通道 + url 语义统一批(BUG-09,喵虎核验报告驱动,doc/bugs/09)——① **新工具 `browse_headed`(有头强力档——反爬根治通道)**:针对「无头被站点 JS 层驱逐」类反爬(页面加载 2-3 秒后自己跳走,商标库/查询库形态)的根治层:真实有头 Chrome 窗口(同一上游 chrome-devtools-mcp、只是不带 `--headless`,零新依赖),真机商标站四轮驻留 6/6 存活;stealth 取舍与无头档相反(真实环境即真实指纹,不做注入)。**调用即在你屏幕弹真实窗口**——description 与 hint 都钉死「先获用户明确同意再调」;两态生命周期:未接管 30 分钟 idle 回收(`LASSO_HEADED_IDLE_MS`),你一旦点击聚焦该窗口即标记「已接管」、**永不自动回收**(自己关窗即回收;24h 硬顶 `LASSO_HEADED_HARD_CAP_MS` 是防孤儿舰队的唯一兜底)。② 🔴 **url 语义统一(修正型行为变更——假数据面)**:全部 url 感知 action 收敛为单一规则——**省略 url = 当前页**(无活动会话显式报错,不静默开空白页)/ **url = 当前页 = 零导航直执行**(不再 reload 洗掉 SPA 状态)/ **url ≠ 当前页 = 先导航再执行**;返回体统一新增 `did_navigate:true/false` 如实回显。修复面:`extract`+url 此前会**读会话残留页并伪装成功**(假数据)→ 现在导航后读;`evaluate` 省略 url 此前被拒 → 现在合法(描述承诺兑现);`screenshot`/`pdf`/`network` 传与当前页相同的 url 从 reload 改为跳过(SPA 状态保留)。③ steps 链内 `wait` 条件校验与顶层统一(text/selector/url_contains 三键——此前链内只认 text)。④ steps 链 `outcome:worked` 时瞬态错误不再留在 `error` 字段(迁入新 `warnings[]`;契约固化:worked ⇒ error 必空)。⑤ **breaking(一键可恢复)**:`browse_headless` 失败不再自动回退 `browse_logged_in`(登录态通道必须显式选择;跨通道错误串染曾是马拉松误判根)——配 `LASSO_FALLBACK_CROSS_CHANNEL=1` 恢复旧行为。⑥ `final_url` 剥尾部句读(`.,;:!?`——上游散文句末被吞入的取证定案,括号引号不剥);`lasso doctor` CDP 检查失败明细带当前生效端口。⑦ **WT4 驱逐哨兵(尾款轮,doc/bugs/09 §8.A)**:`browse_headless`/`browse_headed` 的返回体现在可携带 `eviction_suspected:{from,to,at_ms}` + hint——通道层观测到「本 lasso 导航 settle 后页面漂移到异 host」(三信号漏斗:5s 静默窗采样 / 闸门漂移复核 / evaluate 死于 `Execution context was destroyed` ∧ host 偏离的合取 typed error `page_redirect_eviction_suspected:`)即附一次性 advisory 信号(消费方首次能机械区分「我的调用错了」vs「站点杀了无头」);**只供信号绝不自动升级通道**——hint 内钉死「先问用户再转 browse_headed」(弹真实窗口的惊讶面必须经同意);`browse_logged_in` 显式 opt-out(SSO 跨域流转是合法常态,信号在那边纯噪音);⑧ **steps 链回显真值化(修正型消谎)**:链级 `final_url` 此前恒回显请求串(残留页上跑链会谎称目标页)→ 改为链尾真值读(页面真实 href;读不到且无真值种子时省略,**永不回显请求串**)+ 链级 `did_navigate` 如实回显 + 先导导航 same-document 双标注透传——链执行语义零变化(消费方工作流零破坏);⑨ macOS occlusion 真机实验定案(§8):「屏幕外全藏窗口会被系统判 occluded」假设**证伪**(实测恒 visible + rAF 满速),`browse_headed` 窗口默认维持边缘可见 `8,40`(consent 契约与窗口归属锚裁定,零参数变更);测试 2997→3120(192 文件)/ 不变量 96→100 实装(编号至 100——INV-98 驱逐哨兵真锚 + INV-100 steps 链 URL 真值契约,保留位清零)。
241
+ - **v1.28.0**(未发布预写 · 上半:bugs/10 rust/desktop 半——桌面投递回执批):cgEvent 投递「断裂」证伪后的**消灭静默失败**批(商标站滑块实机报告驱动,doc/bugs/10)——白盒定谳:HID 投递链完好(受控计数器页产出完整 `isTrusted:true` 序列),真凶是并发物理输入竞争 + 判定法盲区,故交付物不是「修投递」而是让失败可见:① **坐标鼠标动作落地回执**:`desktop act` 的 click/move/drag(带 x,y 的 scroll 同)每个动作回 `cursor_after{x,y}` + `landed`(最终 post 后读回真实光标,容差 0.5pt)——**未落地 → 该动作 `ok:false` + `cgevent_no_landing`**(此前「API worked 实际零效果」是静默的);② **物理竞争警示**:dispatch 级 `physical_input.attribution`(idle/synthetic/physical)——`physical` = 检测到晚于本进程合成 post 的鼠标事件(用户在物理操作,重发即可;worked 不因此翻转,信号不策略);③ **TCC 探测诚实化**:macOS<15 不再假报「无此维度」——IOHID PostEvent 原始探测四态直报(Undefined 是真实第三态且该状态下投递实证可用;per-process 归因如实入档),**门控语义零变化**(<15 永不因 IOHID 拒绝);④ **doctor #22 投递自检**(opt-in `LASSO_DOCTOR_INPUT_SELFTEST=1`:移动你的光标 7px 后复位——默认关,agent 不可触发;光标读回判读,无歧义);⑤ **desktop screenshot 默认落盘**(对齐 browse 通道:`/tmp/lasso-screenshot-<uuid>.png` 只回路径——此前全屏 860KB base64 直塞爆 token;`inline_base64:true` 恢复旧行为)。伦理红线:合成输入只做「检测与诚实报告」,不引入任何绕过用户输入监控的能力。Rejected:PostToPid 定向(SOTA 反证 PID 定向鼠标被 AppKit 静默丢弃)/ act 内置像素 diff / act 内自动重试。
242
+ - **v1.28.0**(未发布预写 · 下半:bugs/10 browse/docs 半——evaluate 返回值契约 + 反爬检测面文档批,BUG-10,商标站滑块战役驱动,doc/bugs/10)——① 🔴 **修正型行为变更(静默错值面)**:`evaluate` 的 `options.js` 新增两条表达式路由——此前传**单行裸表达式**(`JSON.stringify({...})`、`document.title`)会被包进语句体,表达式值被语句吞掉 → **恒 undefined**;传**括号表达式**(`({a:1})`)会被当函数表达式透传,上游求值为对象 → **报 `fn is not a function`**(实机报告 P2:两次调用试错才暴露的隐藏契约)。现在这两类入参自动包成表达式体箭头,**值直达**;既有三形态(函数表达式透传 / IIFE 包裹 / 语句体)字节级不变(语句体仍须显式 `return`);② **错误即教学**:语句体 + 返回 undefined 时响应附 `data.js_form:"statement_body"` + `js_form_hint`(一句说清「为什么是 undefined」与怎么改);上游 `is not a function` 错误文案同款追加;③ 工具描述 evaluate 段补 RETURNS 契约句(「THREE forms … All work」对表达式形态为假——描述缺口即 P2 本体);④ `browse_headless`/`browse_headed` 描述 NOTE 新增「**click worked ≠ 提交被接受**」标注 + TROUBLESHOOTING 新增 §2.18 tm.aliyun.com 分层拦截面实测(首页层已放行 / 提交层 headless 静默吞、headed 弹滑块——判定提交成败用 `wait url_contains`/`text` 或 `extract`,不能信 act 回执)。本条为下半(browse/docs 半);同批上半(rust/desktop 半:cgEvent 投递回执 / doctor 自检 / desktop 截图落盘)见上一条 v1.28.0。
243
+ - **v1.27.1**:工具示例体系批(消费方接口自描述完善)——修复「调用者靠试错学用法」:此前 18 个工具只有 1 个含可抄示例,其余全是规则散文(七家消费方报告的试错考古实证)。本批:① **13 个调用示例进工具 description**(agent 经 `tools/list` 端到端可见——内容全部从真实试错事故反推:navigate+screenshot 一步/evaluate current-page/驱逐信号响应/freshProfile/browse_headed consent 等);② **错误即教学**:`unknown_action` / 无会话等高频错误内嵌正确调用形态(学 Rust "did you mean");③ schema 全量 `.describe()` 补齐(action enum 值说明——此前全仓零 field 描述);④ **防漂移四道闸**:示例逐字锚 / consent 前缀锚 / call-shape⊆schema / 预算帽。纯接口自描述增强零行为变更;盲测 8/8 + 9/9 变异全杀。体系文档见 doc/usage/04。
244
+ - **v1.27.0**:反爬根治通道 + url 语义统一批(BUG-09,喵虎核验报告驱动,doc/bugs/09)——① **新工具 `browse_headed`(有头强力档——反爬根治通道)**:针对「无头被站点 JS 层驱逐」类反爬(页面加载 2-3 秒后自己跳走,商标库/查询库形态)的根治层:真实有头 Chrome 窗口(同一上游 chrome-devtools-mcp、只是不带 `--headless`,零新依赖),真机商标站四轮驻留 6/6 存活;stealth 取舍与无头档相反(真实环境即真实指纹,不做注入)。**调用即在你屏幕弹真实窗口**——description 与 hint 都钉死「先获用户明确同意再调」;两态生命周期:未接管 30 分钟 idle 回收(`LASSO_HEADED_IDLE_MS`),你一旦点击聚焦该窗口即标记「已接管」、**永不自动回收**(自己关窗即回收;24h 硬顶 `LASSO_HEADED_HARD_CAP_MS` 是防孤儿舰队的唯一兜底)。② 🔴 **url 语义统一(修正型行为变更——假数据面)**:全部 url 感知 action 收敛为单一规则——**省略 url = 当前页**(无活动会话显式报错,不静默开空白页)/ **url = 当前页 = 零导航直执行**(不再 reload 洗掉 SPA 状态)/ **url ≠ 当前页 = 先导航再执行**;返回体统一新增 `did_navigate:true/false` 如实回显。修复面:`extract`+url 此前会**读会话残留页并伪装成功**(假数据)→ 现在导航后读;`evaluate` 省略 url 此前被拒 → 现在合法(描述承诺兑现);`screenshot`/`pdf`/`network` 传与当前页相同的 url 从 reload 改为跳过(SPA 状态保留)。③ steps 链内 `wait` 条件校验与顶层统一(text/selector/url_contains 三键——此前链内只认 text)。④ steps 链 `outcome:worked` 时瞬态错误不再留在 `error` 字段(迁入新 `warnings[]`;契约固化:worked ⇒ error 必空)。⑤ **breaking(一键可恢复)**:`browse_headless` 失败不再自动回退 `browse_logged_in`(登录态通道必须显式选择;跨通道错误串染曾是马拉松误判根)——配 `LASSO_FALLBACK_CROSS_CHANNEL=1` 恢复旧行为。⑥ `final_url` 剥尾部句读(`.,;:!?`——上游散文句末被吞入的取证定案,括号引号不剥);`lasso doctor` CDP 检查失败明细带当前生效端口。⑦ **WT4 驱逐哨兵(尾款轮,doc/bugs/09 §8.A)**:`browse_headless`/`browse_headed` 的返回体现在可携带 `eviction_suspected:{from,to,at_ms}` + hint——通道层观测到「本 lasso 导航 settle 后页面漂移到异 host」(三信号漏斗:5s 静默窗采样 / 闸门漂移复核 / evaluate 死于 `Execution context was destroyed` ∧ host 偏离的合取 typed error `page_redirect_eviction_suspected:`)即附一次性 advisory 信号(消费方首次能机械区分「我的调用错了」vs「站点杀了无头」);**只供信号绝不自动升级通道**——hint 内钉死「先问用户再转 browse_headed」(弹真实窗口的惊讶面必须经同意);`browse_logged_in` 显式 opt-out(SSO 跨域流转是合法常态,信号在那边纯噪音);⑧ **steps 链回显真值化(修正型消谎)**:链级 `final_url` 此前恒回显请求串(残留页上跑链会谎称目标页)→ 改为链尾真值读(页面真实 href;读不到且无真值种子时省略,**永不回显请求串**)+ 链级 `did_navigate` 如实回显 + 先导导航 same-document 双标注透传——链执行语义零变化(消费方工作流零破坏);⑨ macOS occlusion 真机实验定案(§8):「屏幕外全藏窗口会被系统判 occluded」假设**证伪**(实测恒 visible + rAF 满速),`browse_headed` 窗口默认维持边缘可见 `8,40`(consent 契约与窗口归属锚裁定,零参数变更);测试 2997→3120(192 文件)/ 不变量 96→100 实装(编号至 100——INV-98 驱逐哨兵真锚 + INV-100 steps 链 URL 真值契约,保留位清零)。
242
245
  - **v1.26.0**:反爬马拉松稳定性批(BUG-08,3 小时商标库查询实战驱动,doc/bugs/08)——① 🔴 **修正型行为变更(假数据面,比崩溃危险一个数量级)**:`navigate` 到**仅 hash 不同**的 URL(SPA `#/search?q=` 换词)此前按 same-document 处理不重载——页面留旧查询结果、URL 已新词(实战差点把真值 3718 写成 0 条干净);现在默认检测命中即补 reload,回显 `same_document_navigated/same_document_reloaded` 双标注(`options.no_reload:true` opt-out 只标注;判定基为 URL 规范化比较 `new URL()` origin+pathname+search——空路径省略斜杠形态 `http://x#/q=b` 是 `http://x/#/q=a` 的 same-document,raw 串比较会漏检致假数据复活,审查轮已封口)。`evaluate` 传 `url` 此前**静默跑在当前页 + final_url 伪造目标 URL**;现在 url ≠ 当前页先导航再执行(=ensure-navigation),final_url 永远真实。② **长 evaluate 稳定性**:单调用预算 `options.budget_ms`(默认 120s / `LASSO_EVAL_TIMEOUT_MS` 可调 / 上限 600s)传导 MCP 调用层——此前恒落 SDK 60s 缺省事故,>60s 批量 JS 必超时;超时错误类型化 `mcp_request_timeout:` + 教学 hint(**Chrome 没死**,上游互斥锁楔死 ~3min 自愈);全链 fallback 耗尽的错误改为 primary-first 复合串(主通道错误打头,fallback 尾跳摘录在尾——归因污染消灭)。③ **freshProfile 换脸逃生门**:headless 被服务端指纹拉黑(静默假 0)后的唯一解——`options.freshProfile:true` 换完整新一致身份(临时 profile【归属锚目录名+四路清理防 BUG-03 垃圾重演】+ stealth 宿主适用集确定性轮换 + 完整栈 respawn;logged_in 永不支持)。④ **内部栈治理**:chrome-devtools-mcp 栈 spawn 即登记 sidecar、任意 spawn 前孤儿扫除(pid 归并 + 三重守卫 + lstart 交叉核对,绝不触碰非 lasso 进程)——marathon「两代栈并存 + 谁也动不了」死锁根治;admin 新 action `browser_recycle`(内部栈受控重启正门,永不动 detached Chrome)。⑤ `wait` 支持当前页(省 url,与截图同会话契约);`browse_logged_in` 默认 9222 失败时自动发现台账最新非 render 口(三层解析,结果带 `+auto_discovered_port:<port>` 标注;显式 `LASSO_CDP_PORT` 恒赢);`fetch_url` 失败细分(`fetch_failed:dns_failed/connect_refused/connect_timeout/tls_failed/aborted_timeout`——本机环境 vs 目标站拒绝可分辨)。⑥ 测试基建自愈(BUG-08 F,用户实锤负载 188 事故):vitest 池显式钉死 threads(主进程死 = worker 线程随之死,forks 孤儿类结构性消灭)+ `npm run gate` 对 vitest 树的超时追杀带(belt 到点在树根存活时整树 SIGKILL,`LASSO_GATE_VITEST_TIMEOUT_MS` 可调;E1 白盒实锤:spawnSync timeout 形态必漏杀忙 worker,已否决——doc/bugs/08 §12)。测试 2895→2997 / 不变量 95→96(INV-96 五组防线);既有消费方(cc-control / media-gen-mcp)零 breaking。
243
246
  - **v1.25.0**:当前页截图批(BUG-07,novel-engine 动画取证驱动)——`action=screenshot` **省略 url 即对当前受管页面直接截屏**(独立 `screenshot` 工具同义):此前两条截图路径都必经重导航,把 evaluate 建立的页面现场(冻结的 CSS 动画中间帧、注入的临时 DOM)全部洗掉——状态敏感截图不可达,消费方被迫借道第二套浏览器栈。现在同会话四通道闭环:带 url 建会话 → `evaluate` 冻结/注入 → 无 url 截当前帧 → `console` 取证。无活动会话(冷通道/页面已关/被自愈换页)显式报错带指引,**绝不静默新开、绝不截空白页伪造状态**;带 url 的旧行为零变化(回归锚钉死);对抗三轮 clean——6 变异全红 + 会话漂移攻击真机双通道零穿透(并发竞态拒/弹窗钉受管页/静默换页 invalidate 封口)。上游调研定谳:截图的业界普适语义就是「截当前状态」——本版把 lasso 对齐回行业标准。
244
247
  - **v1.24.0**:幽灵常驻根治批(BUG-06,用户 12 小时实例实锤驱动)——① 🔴 **行为变更**:`launch-chrome --idle-ms 0` 的语义从「永不回收」改为「**不自收,但 24 小时硬顶保命**」——无窗口的隐藏实例从此不可能无限常驻成「看不见也关不掉的幽灵」(本轮用户实锤:一个 12 小时实例,Dock/菜单栏不可见无从关闭)。要真正无限需再显式 `--no-hard-cap`(**双重意图**,防脚本顺手传 0);部署级可用 `LASSO_LAUNCH_HARD_CAP_MS` 调整或 `=0` 全禁;失效方向恒安全(非法值回退有顶)。旧脚本若依赖「0=无限」请加 `--no-hard-cap`。② **跨进程活动真源**:硬顶收割前看 touch 文件心跳(任何会话/任何消费方还在用 → 不误杀);userTakenAt / visible 豁免天然继承(kill 时刻二次重估,竞态窗口封口)。③ **超龄可观测**:`doctor` / `chrome-status` 对过半硬顶的实例提前 warn(不新增任何 kill 面)。真机验收六项全 PASS + 对抗两轮 clean(三变异全红 / 误杀全景真活替身重放零误伤 / 渲染档零交叉)。
@@ -381,10 +381,12 @@ export declare const EVICTION_WINDOW_MS = 5000;
381
381
  */
382
382
  export declare function httpHostKey(u: string): string | null;
383
383
  /**
384
- * E④(BUG-03 决议 E④)+ BUG-04 决议 C1(doc/bugs/04 §7):evaluate 的 js 入参 →
385
- * 上游 function 参数归一(导出供测试)。
384
+ * E④(BUG-03 决议 E④)+ BUG-04 决议 C1(doc/bugs/04 §7)+ 决议 B.1(doc/bugs/10,
385
+ * 2026-09-17):evaluate 的 js 入参 → 上游 function 参数归一(导出供测试)。
386
386
  *
387
- * 三形态兼容:
387
+ * 五形态兼容(B.1 前三形态字节级沿用,后两条为 bug10 新增表达式路由——消灭
388
+ * 「裸表达式落语句体恒 undefined / 括号表达式透传报 fn is not a function」两类
389
+ * 静默错值,实机报告 P2):
388
390
  * - **函数表达式**(起手 `(` / `function` / `async`,或单标识符箭头 `x => x`)
389
391
  * → 原样透传——上游 evaluate_script 契约本就吃函数表达式并自调用;旧 wrapper
390
392
  * 会把它包成「函数体内的函数表达式语句」(求值不 return → 恒 undefined 静默
@@ -395,7 +397,21 @@ export declare function httpHostKey(u: string): string | null;
395
397
  * 后 `fn(...args)`:IIFE 串求值成**结果**而非函数 → `fn is not a function`
396
398
  * (报告 §9-②a)。包裹成 `() => (iife)` 后外层箭头求值即得 IIFE 结果
397
399
  * (Promise 由上游 await fn() 解开,语义不变)。
398
- * - **语句体**(`return ...` / 声明 / 多语句 / 裸表达式)→ 维持包裹
400
+ * - **括号表达式**(bug10 B.1 路由 1:起手 `(` 且首平衡括号组后不接 `=>`、
401
+ * 组内容非函数起手——`({a:1})`、`(1+2)`、`(a+b)`)→ 包 `() => (\n<t>\n)`。
402
+ * 旧三形态把它们当函数表达式透传 → 上游求值为**对象/值** → `fn is not a
403
+ * function`(实机报告 P2 症状②)。保守排除集(判伪方向=维持透传,现行行为
404
+ * 字节级不变):首闭合组后接 `=>`(`(a,b)=>a` 参数组);外组内容以
405
+ * `async`/`function` 起手(`(function () {...})`,E④ 语料);外组内容以 `(`
406
+ * 起手(`(() => 42)` 嵌套括号函数形态,E④ 语料)或单标识符箭头(`(x => x)`)
407
+ * ——函数表达式族整族维持透传,宁可漏网(透传错形态=上游响亮报错)不可
408
+ * 误包(包裹函数表达式=静默错值,毒中之毒)。
409
+ * - **单行裸表达式**(bug10 B.1 路由 2:单行 + 剥尾 `;` 后无串外 `;` + 非语句
410
+ * 关键字起手 + 括号/引号平衡——`JSON.stringify({...})`、`document.title`、
411
+ * `1+2`)→ 包 `() => (\n<t>\n)`——旧三形态落语句体包裹,表达式值被语句体
412
+ * 吞掉 → 恒 undefined(实机报告 P2 症状①)。多行/多语句/声明维持语句体
413
+ * (现行行为字节级不变——B.2 的 js_form 教学回执兜住这类输入的诚实边界)。
414
+ * - **语句体**(`return ...` / 声明 / 多语句 / 多行)→ 维持包裹
399
415
  * `() => { ... }`(W1-DEF-1b:直接透传 `return` 会被当函数表达式语法错,
400
416
  * wave2 smoke 实证 "Unexpected token 'return'")。
401
417
  *
@@ -411,6 +427,12 @@ export declare function httpHostKey(u: string): string | null;
411
427
  * 表达式位置包 `() => (expr)` 求值不变。
412
428
  */
413
429
  export declare function evaluateFunctionArg(js: string): string;
430
+ /**
431
+ * 决议 B.1(doc/bugs/10):js 入参形态分类(导出供单测——doEvaluate 的 B.2
432
+ * 教学回执按形态接线;与 evaluateFunctionArg 同一真源 derive,零漂移)。
433
+ */
434
+ export type JsForm = "function_expression" | "iife" | "paren_expression" | "single_expression" | "statement_body";
435
+ export declare function evaluateJsForm(js: string): JsForm;
414
436
  /**
415
437
  * BUG-04 决议 C1:IIFE 立即执行式结构化判定(导出供测试)。
416
438
  *
@@ -421,6 +443,24 @@ export declare function evaluateFunctionArg(js: string): string;
421
443
  * 3. 全串括号/花括号平衡(排除截断/畸形输入——畸形按响亮上游错误处理)。
422
444
  */
423
445
  export declare function isIifeString(t: string): boolean;
446
+ /**
447
+ * B.1 路由 1:括号表达式判定(调用方保证 t 以 `(` 起手)。
448
+ *
449
+ * 判真(三条全中):括号/引号平衡;首**闭合**括号组后(跳空白)不接 `=>`
450
+ * (接 `=>` = 箭头参数组——`(a,b)=>a`,函数表达式族);外组(0 位开括号的
451
+ * 匹配闭)内容 trim 后不以 `async`/`function`/`(` 起手且非单标识符箭头
452
+ * (`(() => 42)`/`(function () {...})`/`(x => x)` 函数表达式族保守排除——
453
+ * 判伪方向=维持现行透传,E④ 语料字节级不变)。
454
+ */
455
+ export declare function isParenExpression(t: string): boolean;
456
+ /**
457
+ * B.1 路由 2:单行裸表达式判定(调用方保证已过函数起手/IIFE/单标识符箭头
458
+ * 三道前置分支)。
459
+ *
460
+ * 判真:单行(无 `\n`)+ 剥尾 `;` 后非空 + 非语句关键字起手(词边界——
461
+ * `document.title` 不被 `do` 误伤)+ 串外无 `;`(多语句排除)+ 括号/引号平衡。
462
+ */
463
+ export declare function isSingleLineExpression(t: string): boolean;
424
464
  /**
425
465
  * v1.17(doc/governance/06 verify ⑤,真机实证):refs 附录感知截断——长页正文超
426
466
  * PREVIEW_MAX_CHARS 时朴素 truncatePreview 会把**缀在末尾**的
@@ -431,6 +471,64 @@ export declare function isIifeString(t: string): boolean;
431
471
  * truncatePreview 完全一致(byte-identical)。
432
472
  */
433
473
  export declare function truncatePreviewKeepingRefs(s: string): string;
474
+ export declare const CURRENT_PAGE_ACTIONS: Set<string>;
475
+ /**
476
+ * frozen 列表(顺序 = actionDispatch 插入序)。三方消费:
477
+ * (a) tools/browse.ts schema `action` / `steps[].action` 的 .describe();
478
+ * (b) unknown_action 动态 hint(hint 本体从 actionDispatch keys 运行时派生
479
+ * ——Map 增删 action,hint 自动同步,drift-free by construction);
480
+ * (c) test/unit/tool-examples-truth.spec(示例合法值锚 + 与 dispatch keys
481
+ * 的相等性断言)。
482
+ *
483
+ * 注:actionDispatch Map 字面量保持 INV-91(a) 源锚形态(不在构造期改由本
484
+ * 列表重建)——列表与 Map 的同源性由 truth spec 的相等性断言钉死(新增
485
+ * action 必须两处同 commit,漏一处即红)。
486
+ */
487
+ export declare const BROWSE_ACTIONS: readonly string[];
488
+ /**
489
+ * ignored_options 诚实标注机制的单一真源:表项 = **channel 实际消费键**。
490
+ *
491
+ * 纪律(决议 r1 修订):把死键列入消费表会让 ignored_options 机制对其豁免
492
+ * (调用方传了也零信号),恰是本机制要消灭的静默面——
493
+ * network_timeout_ms / network_include_bodies 自 v1.11 起「字段保留(zod 契约
494
+ * 稳定),值被忽略」(cdp-actions.ts 注释明载),故不进 network 表项。
495
+ *
496
+ * 实施注(白盒修正,偏离决议 D1 字面表——已回写决议 §6-D1 定稿标注):
497
+ * 「会导航的 action」(navigate 本尊 + ENSURE_NAV_ACTIONS 六者的先导导航分支
498
+ * )都经 doNavigate 消费 no_cache——no_cache 记入这些 action 的表项,防止
499
+ * 主流路径(如空白会话首 snapshot 传 no_cache)被误标 ignored。方向性理由:
500
+ * 误标(实际消费却被标 ignored,诱导调用方删有效参数)比漏标(实际忽略却
501
+ * 沉默 = 旧行为)有害。wait/click/fill 从不导航,传 no_cache 属真死键 →
502
+ * 如实标注;evaluate 同页跳过分支(did_navigate:false)经 no_navigation
503
+ * 模式派生剔除(决议 B——本调用确未导航,如实标注)。
504
+ *
505
+ * 对抗复审第 1 轮 I-3(bug09):no_reload 与 no_cache 同形——统一后
506
+ * doNavigate 对全部 ENSURE_NAV_ACTIONS 的先导导航分支读它(same-document
507
+ * 命中的 reload opt-out,:1335),却只钉在 navigate 表项下 → 组合路径实际
508
+ * 消费(reload 确被跳过)却谎报 ignored_options:["no_reload"]。修法与
509
+ * no_cache 完全同构:入 ensure-nav 六 action 表项 + NAV_ONLY_OPTION_KEYS
510
+ * 派生(无导航模式 = 真死键,如实标注)。
511
+ *
512
+ * 入口级消费(browse() 分流,非本表):steps 非空 → StepEngine 链(steps 路径
513
+ * 不走 browseSingle,无本标注);budget_ms 在 steps 路径为链预算、在单 action
514
+ * evaluate 为单调用预算(BUG-08 决议 A-2 兑现——此前是「死键诚实标注」,现为
515
+ * 生效键);其余单 action 传入 budget_ms 仍进 ignored_options(如实标注)。
516
+ */
517
+ export declare const CONSUMED_OPTIONS: Readonly<Record<string, readonly string[]>>;
518
+ /**
519
+ * BUG-07 决议 A⁺(§5.2③):仅经导航消费的 options 键(doNavigate 读
520
+ * no_cache/no_reload;无导航即死键)。current-page 模式下运行时从
521
+ * CONSUMED_OPTIONS 表派生剔除(消费表仍是单一真源,模式变体不落表)。
522
+ */
523
+ /** 同上(doc/usage/04 D.1 r1):export 供 schema describe 派生 + truth spec。 */
524
+ export declare const NAV_ONLY_OPTION_KEYS: Set<string>;
525
+ /**
526
+ * BUG-08 决议 C:browse() 入口消费的 options 键(freshProfile 在 getMcpClient
527
+ * 之前被入口拦截——支持通道上全 action 生效,不落 per-action 消费表)。仅在
528
+ * worked 出口的 ignored_options 计算里豁免;拒绝路径(didnt)本就不标注。
529
+ */
530
+ /** 同上(doc/usage/04 D.1 r1):export 供 schema describe 派生 + truth spec。 */
531
+ export declare const ENTRY_CONSUMED_OPTION_KEYS: Set<string>;
434
532
  /**
435
533
  * BUG-05 决议 D1:计算「传入但该 action 未消费」的 options 键(导出供测试)。
436
534
  * 只对 worked 出口调用(didnt/unknown 路径不标——错误已自解释)。
@@ -1 +1 @@
1
- {"version":3,"file":"BrowseChannel.d.ts","sourceRoot":"","sources":["../../src/channels/BrowseChannel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BrowseChannel.d.ts","sourceRoot":"","sources":["../../src/channels/BrowseChannel.ts"],"names":[],"mappings":"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"}