[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 compile0 错 - ✅
pnpm build7.34s - ✅
pnpm scan:react0 命中(修复 v0.10.46 后稳定)