跳转至

[ISSUE-0033] 第四轮 agent 找到 ISSUE-0031 第 4 兄弟

第四轮 agent convergence test 仍失败:又找到 1 个 P1 + 2 个 dead listener + 1 个工具盲区。

Bug J (P1):ISSUE-0031 三胞胎的第 4 兄弟

位置scrape-watchdog.ts:207-211 alarm-create-fail 兜底分支

// v0.10.47 修了 cooldown=0 分支 + onWatchdogResume(2/3 路径)
// 漏了 alarm-create-fail 兜底
} catch (e) {
  pumpTasks().catch(() => {});
  manageQueue();
  // ❌ 缺 pumpAllSchedulers
}

与 ISSUE-0028 / ISSUE-0031 是同一家族,但在同一个 90 行函数内

分支 v0.10.47 状态 v0.10.49 修
cooldown<=0 ✓ 已补 pumpAllSchedulers ↓ helper
alarm-create-fail catch ❌ 漏 ✅ helper
onWatchdogResume(alarm 触发) ✓ 已补 ↓ helper

修法:抽 watchdogResumePump() helper

function watchdogResumePump(): void {
  pumpTasks().catch(() => {});
  pumpAllSchedulers().catch(() => {});
  manageQueue();
}

3 个分支都改成调一行 watchdogResumePump()视觉上无法漏看第 N 个分支。

Bug K:'clear-search-data' 孤儿 listener

位置content-search/index.tsx:144-157

唯一发送方在 page-results/index.tsx:105 整段已注释。listener 永不触发。

scan:protocol v0.10.48 没抓到 — 因为它是 browser.runtime.onMessage + if(type==='x') router-dispatch 模式,工具故意不扫(router-dispatch 实测 22/23 FP)。

修法:删整段 useEffect。

Bug L:'search-api-response' 孤儿 listener(工具自身盲区)

位置content-search/index.tsx:74

websiteMessager.onMessage('search-api-response', ...) // ← listener 注册

全仓 0 websiteMessager.sendMessage('search-api-response', ...)。injected.ts 只发 'search-api-url'

讽刺:这是 webext-bridge onMessage 模式,新 scan:protocol 工具理论上应抓到。 但 v0.10.48 工具用 (?:^|[^a-zA-Z_.])onMessage\( 排除 method call —— 因为 原来想排除 websiteMessager.onMessage(...) 的发送方在 injected 层我们扫不到。

工具自身盲区暴露

# v0.10.49 修
LISTENER_PATTERNS = [
    # 主:webext-bridge 顶层
    (r"(?:^|[^a-zA-Z_.])onMessage\(\s*['\"]([^'\"]+)['\"]", "webext-bridge"),
    # 🆕 自定义 messager:限定 messager 后缀
    (r"\w*[Mm]essager\.onMessage\(\s*['\"]([^'\"]+)['\"]", "custom-messager"),
]

修法:删整段 listener + pushData 死函数(删 listener 后 0 调用)+ parseSearchData import。

元-观察(agent 提出)

四轮 P0/P1 共同模式:

bug 共同特征
1 (v0.10.44) 拦截恢复漏 pumpScheduler(ISSUE-0028) resume 路径漏 pump
3 (v0.10.47) watchdog onWatchdogResume 漏 pump(ISSUE-0031) resume 路径漏 pump
4 (v0.10.49) watchdog alarm-fail 漏 pump(ISSUE-0033 本 issue) resume 路径漏 pump

共同 100%:resume-after-failure 路径漏调 pump 链

深层根因: 1. 修复者只 grep 触发的具体函数名,不 grep 同函数内多个分支 2. try-catch 视觉切割导致认知盲区 3. 已抽 helper(pumpAllSchedulers)但作者复用到"主路径",catch 兜底分支被遗忘 4. scan 工具偏"数据"而非"控制流"

agent 建议的下一步(todo): - 写 scan-pump-coverage.py 检测 nukeAllSchedulerState / forceCloseSharedWindow 调用后控制流是否经过 pumpAllSchedulers(控制流分析需 AST)

改动文件

文件 改了什么
src/utils/scrape-watchdog.ts + watchdogResumePump helper,3 个分支统一调用
src/sections/content-search/index.tsx 删 'clear-search-data' listener + 'search-api-response' listener + 死 pushData + 死 import
scripts/scan-protocol-orphan.py + \w*[Mm]essager\.onMessage 自定义 messager 扫描(修工具盲区)
.protocol-orphan-baseline.json 19 → 18(search-api-response 删了 1)
package.json 0.10.48 → 0.10.49

验证

  • pnpm compile 0 错
  • pnpm build 7.32s
  • pnpm scan:mv3 --diff 0 新增
  • pnpm scan:protocol 现在 0 dead + 18 lost(更新基线后)

复盘

第四轮 agent 元-观察精彩:

修复者只 grep 触发的具体函数名,不 grep 同函数内多个分支 try-catch 视觉切割导致认知盲区

这正是 v0.10.47 我 ISSUE-0031 修复的现场重演 —— 我看了 onWatchdogResume + cooldown=0 但没看 cooldown>0 的 try-catch 内部 catch 分支。视觉上 if/else + try/catch 嵌套有 3 个分支,我只看了 2 个。

未来准则:修任何"在某分支补缺失调用"的 bug 时,必须看同一函数所有分支,最好抽 helper。

累计 4 轮 agent 共同发现

轮 1: ISSUE-0028 Bug A (P0)  — 拦截恢复路径
轮 2: ISSUE-0029 Bug E (中-高) — 浪费索引
       ISSUE-0029 Bug S4 (中)  — listener cleanup
轮 3: ISSUE-0031 Bug I (P0 镜像) — watchdog 主路径
       ISSUE-0031 Bug F1 (中) — has-new-data 孤儿
       ISSUE-0031 Bug H (中-低) — 正则姊妹漂移
轮 4: ISSUE-0033 Bug J (P1) — watchdog 第 4 兄弟
       ISSUE-0033 Bug K (中) — clear-search-data 孤儿
       ISSUE-0033 Bug L (中) — search-api-response 孤儿(工具盲区)

4 轮独立 agent 共 9 个真发现,其中 4 个 P0/P1 全是"resume 路径漏 pump"同源 bug 在不同位置展开。