跳转至

[ISSUE-0031] 第三轮 agent 找到 3 真 bug

第三轮独立 agent(convergence test)证明:连做两轮独立 audit 仍未收敛。 又找到 3 个真 bug,其中 1 个是 ISSUE-0028 的镜像 —— 修复模式没复用到姊妹路径。

三个 bug

🔴 Bug I (P0):watchdog 自动恢复漏调 pumpAllSchedulers(ISSUE-0028 镜像)

位置scrape-watchdog.ts:298-302 (onWatchdogResume) + 199-200 (cooldown=0 path)

// v0.10.47 之前 ❌
export async function onWatchdogResume() {
  await pumpTasks().catch(() => {});
  manageQueue();
}

链条: 1. watchdog 连续异常 → nukeAllSchedulerState { keepTasksRunning: true } 保留地图 task status='running' 2. cooldownMs 到期 alarm 触发 onWatchdogResume 3. pumpTasks() 只处理 status='queued' task(task-manager.ts:97)→ 跳过 status='running' 的地图 batch 4. manageQueue() 只调 engine-manager → 不动 batch-controller 5. 缺 pumpScheduler / pumpPager → 地图任务永远不再派 tab

与 ISSUE-0028 完全镜像:那个是拦截恢复路径漏调地图调度;这个是 watchdog 自动恢复路径漏调。

修法:抽 pumpAllSchedulers() helper(batch-controller.ts),强制所有 resume 路径调齐:

// batch-controller.ts 新增
export async function pumpAllSchedulers() {
  await pumpScheduler();
  await pumpPager();
}

// scrape-watchdog.ts onWatchdogResume + cooldown=0 path 都调
await pumpAllSchedulers().catch(() => {});

// doResumeFromInterception 也换成调 pumpAllSchedulers(统一)

🟡 Bug F1:'has-new-data' 是孤儿 listener

位置local-data-view.tsx:435-452

onMessage('has-new-data', ...) 在整个 src 里只注册 0 发送。架构在 v0.8.56 改了: content-script 不再 sendMessage 到 popup,改成 browser.runtime.sendMessage({type:'store-page-data'}) 走 background。

v0.10.45 ISSUE-0029 的修复是给死代码加 cleanup —— 不解决问题。本次直接删整段 + 4 个仅此用的 import。

🟡 Bug H:DEFAULT_EMAIL_REGEX 残留 ISSUE-0023 的坏正则

位置storage-data.ts:145

// 旧 ❌ —— 正是 ISSUE-0023 修过的坏模式
export const DEFAULT_EMAIL_REGEX = '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}';

ISSUE-0023 修了 scraper.ts 的 EMAIL_REGEX(去掉 % + 加 {1,64}),但 storage-data 的姊妹常量没改。

后果: - settings-view 把此值当 placeholder → 误导用户「默认是这个」 - RegexTester 在 emailRegex 留空时跑此旧正则 → 演示匹配与实际提取不一致

运行时不爆(if (opts?.emailRegex) truthy 检查让 '' 走 scraper 的新正则)—— 但用户复制 placeholder 当自定义就把坏正则塞回。

:复用 ISSUE-0023 的新模式。

跨模块发现(agent 提到,未本次修)

发现 评估 处置
task delete 不删 MapTaskData 行 可能是设计(保留爬取结果) 登记 raw/inbox 待确认
restoreExtensionTabs vs ext-context-guard 双 reload 不致命,浪费一次加载 登记 raw/inbox
has-new-data 协议失配 = Bug F1,已修

元教训

1. 修复模式必须扫所有姊妹路径

ISSUE-0027(watchdog setTimeout)+ ISSUE-0028(interception 漏 pump)都涉及"nuke + 延迟恢复 + pump"三联,但每次只修触发到的那一条路径,没系统扫所有恢复入口

未来准则:

修复任何 alarm 触发后的 resume 路径时,必须 grep 所有 nukeAllScheduler / forceResetLocks / restoreBatch 的调用方,确认每条恢复路径后续 pump 三件套(pumpTasks / pumpAllSchedulers / manageQueue)齐不齐。

2. ISSUE 改动是否还有姊妹文件没改

Bug H 就是 ISSUE-0023 漏掉 storage-data.ts —— 同一个常量在两处定义但只改了一处。

未来准则(写进 docs/rules/version-release-flow.md 候选):

改正则 / 常量 / 类型时,必须 grep 全仓 <旧值> 看是否别处也有。frontmatter 强制列「改动文件全集」。

3. 独立 agent 多轮仍有边际

第一轮 agent (v0.10.44):3 个真 bug(含 1 P0)
第二轮 agent (v0.10.45):2 个真 bug + 1 系统性盲区
第三轮 agent (v0.10.47):3 个真 bug(含 1 P0 镜像)

三轮都有新发现,且每轮 P0 级别都至少 1 个。 证明:独立 agent 多次仍有边际收益,不要满足于"一两次就完"。

agent 还提出 3 个系统性改进方向(todo): - 「nuke + 延迟恢复 + pump」三联模式扫描脚本 - 「注册 onMessage vs 实际发送」匹配扫描(dead listener 检测) - ISSUE frontmatter 强制列改动文件全集 + commit hook 反查

改动文件

文件 改了什么
src/entrypoints/background/batch-controller.ts + pumpAllSchedulers helper export + doResumeFromInterception 改用它
src/utils/scrape-watchdog.ts onWatchdogResume + cooldown=0 path 补 pumpAllSchedulers + import
src/sections/page/local-data-view.tsx 删 has-new-data 死 listener + 4 个 import
src/utils/storage-data.ts DEFAULT_EMAIL_REGEX 应用 ISSUE-0023 修法
docs/raw/inbox/2026-05-26-task-delete-cascade-cleanup-tbd.md 🆕 登记
docs/raw/inbox/2026-05-26-restore-ext-tabs-double-reload.md 🆕 登记
package.json 0.10.46 → 0.10.47

验证

  • pnpm compile 0 错
  • pnpm build 7.34s
  • pnpm scan:react 0 命中(修复 v0.10.46 后稳定)