# 2026-05-24 Agent健身房复盘
一句话概括:**这次发现的不是已经自动修复的问题,而是 5 类以后会反复浪费时间的操作摩擦 / 工具缺口。**
| 优先级 | 发现的问题 | 真实含义 | 计划怎么解决 |
| --- | --- | --- | --- |
| 1 | 浏览器插件卡死性能诊断器 | 浏览器扩展性能问题现在要靠人工看进程、猜 tab、再读代码,容易把页面自身问题误归因给插件。 | 做只读性能诊断器:采样 renderer CPU、映射 tab/extension、读取 observer 指标,再给出是否可归因。 |
| 2 | 语法 HUD helper 与页面标记诊断 | 高精度语法 HUD 已经变成 helper + 插件双链路,任一环挂掉都会表现成误识别或页面无标记。 | 做 helper/watchdog:检查 LaunchAgent、/health、金标句、页面候选和 .tense-hud-mark 数量。 |
| 3 | macOS 菜单栏改动先审阅清单 | 菜单栏、系统权限和可见状态是用户日常工作环境,直接改会破坏信任,即使技术上可逆。 | 沉淀 macOS 可见状态变更清单:先盘点、分常驻/隐藏/退出、等确认,再执行并保存恢复点。 |
| 4 | Surge DNS 与代理连通预检 | Surge 问题跨 DNS、系统代理、本地端口和规则层,单看 UI 很容易把 DoH 问题误判成代理不可用。 | 做 Surge 预检脚本:查 DoH、networksetup、6152/6153 端口、curl HTTP/SOCKS、FINAL/DIRECT 状态。 |
| 5 | 推文日报 roster 配置漂移检查 | 日报能靠历史 raw fallback 成功,但 config 缺 roster 会让账号名单来源长期漂移而不显眼。 | 给 twitter-fetcher 加 roster provenance/preflight,把 config 缺失、fallback 文件和账号数写进回执。 |
## 下一步
| 顺序 | 先做什么 | 为什么 |
| --- | --- | --- |
| 1 | 新增只读诊断入口 `/Users/bytedance/.codex/night-gym/tools/extension_perf_diagnostic.py`,并在 `/Users/bytedance/Documents/product-bu/tools/night-gym/README.md` 登记为 `diagnostic-tool`。输入来源包括浏览器名/Profile、疑似扩展名或 unpacked 路径、目标 URL/当前页面标题、`ps`/Activity Monitor renderer CPU 采样、可选的最小复现 HTML。核心检查步骤:采样 Edge/Chrome renderer CPU,尝试把高 CPU PID 对应到 tab/extension,记录插件启用态,输出是否足以归因;成功信号是能定位到具体页面或扩展并给出可复查证据,失败信号是 PID 无法映射或高 CPU 来自非目标页面,此时禁止直接归因给 Viva。 | value=high,risk=medium;先做能诊断/审阅的入口,避免直接改全局行为。 |
| 2 | 新增诊断入口 `20-products/tense-hud/30-rd/tools/tense_hud_watchdog.py`,输入来源支持 `--text`/`--text-file` 传入截图 OCR 或用户复制的句子,`--url` 传入当前网页。核心检查步骤:`launchctl print gui/$(id -u)/com.bytedance.tense-hud-helper`、`curl http://127.0.0.1:8767/health`、POST `/analyze` 检查 `Got my first paid user for my SaaS` 只返回 `Got` 不返回 `paid`。成功信号是 health ok 且 gold cases 全过;失败信号是 helper unreachable、spaCy unavailable、或谓语链结果偏离 gold。落地路径:先做只读 CLI,输出 JSON 和一段可直接贴回对话的诊断摘要。 | value=high,risk=low;先做能诊断/审阅的入口,避免直接改全局行为。 |
| 3 | 修改 `/Users/bytedance/.codex/AGENTS.md`:新增规则“涉及 macOS 菜单栏、Dock、登录项、通知、默认应用、系统设置显示项等可见状态改动时,先输出审阅清单并等待确认;除非用户明确说直接改,否则不主动隐藏、退出、卸载或调整显示策略”。 | value=high,risk=medium;先做能诊断/审阅的入口,避免直接改全局行为。 |
| 4 | 新增工具入口 `tools/surge_preflight.sh`:输入来源为 Surge 运行进程、本地监听端口、`networksetup` 当前 Wi-Fi/有线系统代理、Surge DNS 页面或导出的 profile 配置、以及一个可配置探测 URL;核心检查步骤依次为检查 `Surge` 进程、检查 `127.0.0.1:6152` 和 `127.0.0.1:6153` 监听、检查 macOS Web/SOCKS 代理是否指向这两个端口、检查 DoH/加密 DNS 是否为空或未启用、分别用 HTTP 和 SOCKS 代理 curl 探测 URL;成功信号是 DoH 关闭、系统代理启用且两类代理探测返回 2xx/3xx,失败信号是 DoH URL 非空、系统代理为空、端口未监听或 curl 超时;建议落地到 Night Gym 的本机诊断工具目录,并输出机器可读 JSON 和人类可读修复建议。 | value=high,risk=low;先做能诊断/审阅的入口,避免直接改全局行为。 |
| 5 | 在 `scripts/daily_tweet_summary.py` 的 roster 解析完成后补充结构化 `roster_provenance`:字段包含 `config_has_roster`、`roster_source`、`fallback_artifact`、`roster_count`、`active_accounts`,并确保最终 JSON 回执和 markdown front matter 都带这组信息。 | value=high,risk=low;先做能诊断/审阅的入口,避免直接改全局行为。 |
## 证据详情
## 1. 浏览器插件卡死性能诊断器
- 类型:`diagnostic-tool`
- 风险:`medium`
- 候选 id:`extension-performance-diagnostic`
- 摘要:这个主题有效,不是噪音:片段里有用户真实痛点、可疑实现链路、系统级 CPU 证据,以及后续纠偏信号。它适合沉淀成一个浏览器扩展性能诊断器,先把高 CPU renderer 映射到页面或扩展,再用 MutationObserver 指标和禁用扩展对照验证是否由内容脚本自触发 DOM 循环导致。
证据:
- `019e55be-80e4-73a2-8854-3b1ccda81e06` `~/Documents/product-bu`:我现在网站老是卡死,不知道和之前插件的迭代有么有关系
- `019e55be-80e4-73a2-8854-3b1ccda81e06` `~/Documents/product-bu`:我看到一个很可疑的链路:上次为了支持动态网页,observer 开始处理“新增 text node”。内容脚本自己给页面加 span/文本节点时,也会产生新增 text node,这可能让插件反复处理自己刚生成的 DOM。
- `019e55be-80e4-73a2-8854-3b1ccda81e06` `~/Documents/product-bu`:系统层面也看到异常:Edge 有两个 renderer 进程分别在 100%+ CPU,这符合“页面卡死”。我会短暂关闭“无痛英语 - 生词标记”做对照,确认 CPU 是否立刻回落;后面会重新加载修复版。
- `019e583f-2ea8-72d1-8b56-9516473aa228` `~/Documents/product-bu`:刚才第二轮进程采样又抓到了两个 Edge renderer 各自 100%+ CPU,这说明“卡死现象现在仍然存在”。下一步我会先把这两个 renderer 对应到页面/扩展,不能仅凭它们是 Edge 进程就判定一定是无痛英语。
## 2. 语法 HUD helper 与页面标记诊断
- 类型:`diagnostic-tool`
- 风险:`low`
- 候选 id:`tense-hud-helper-watchdog`
- 摘要:这个主题有效,不是噪音。片段里先出现了谓语链识别误判:`paid user` 里的 `paid` 被当成过去式谓语;随后又出现页面完全没有标记,且已有证据指向本地 helper 挂掉和 content script 扫描巨大 DOM 的执行顺序问题。它适合沉淀成一个三段式 watchdog:先验 helper,再验句子级分析,再验页面扫描与渲染。
证据:
- `019e5857-2c11-7191-8530-17f48f4cc96a` `~/Documents/product-bu`:算,**这是错误识别**。 截图里的句子是: `Got my first paid user for my SaaS` 这里真正的谓语是标题省略主语后的: `Got` = `(I) got`
- `019e5857-2c11-7191-8530-17f48f4cc96a` `~/Documents/product-bu`:`paid user` 里的 `paid` 不是谓语,它是分词/形容词作定语,修饰 `user`,意思是“付费用户”。所以这里不应该给 `paid` 标过去时蓝线。
- `019e5857-2c11-7191-8530-17f48f4cc96a` `~/Documents/product-bu`:你的需求不是普通 grammar checker,而是 **谓语链识别 + M/T/A/V 标注**,所以“能不能区分 `paid user` 里的 `paid` 不是谓语”是核心门槛。
- `019e5857-2c11-7191-8530-17f48f4cc96a` `~/Documents/product-bu`:页面没任何标记啊
- `019e5857-2c11-7191-8530-17f48f4cc96a` `~/Documents/product-bu`:两个明确证据:`127.0.0.1:8767` helper 进程已经挂了;另外 content script 现在是把 Reddit 整个巨大 DOM 从 `body` 扫一遍,顺序 await
## 3. macOS 菜单栏改动先审阅清单
- 类型:`workflow-pattern`
- 风险:`medium`
- 候选 id:`mac-menu-review-before-change`
- 摘要:这个主题有效,核心不是用户不想整理菜单栏,而是希望在可见系统状态被改变前先看到“保留/隐藏/退出”的审阅清单。macOS 菜单栏、登录项、常驻图标这类改动会直接影响日常使用感知,应从“可直接执行”升级为“先盘点、给建议、等确认、再操作”的工作流。
证据:
- `019e5839-8009-7850-b80f-d5c2a8ebbf21` `~/Documents/learning-bu`:我想长期清爽。
- `019e5839-8009-7850-b80f-d5c2a8ebbf21` `~/Documents/learning-bu`:你怎么直接帮我改了?你可以给我列个单子,我决定保留什么呀?你可以给我建议。
- `019e5839-8009-7850-b80f-d5c2a8ebbf21` `~/Documents/learning-bu`:这一步我应该先把“保留清单/隐藏清单”给你确认,再动显示策略。 我刚才已经做的只有这些:安装 `SaneBar`、开启辅助功能权限、选免费 `Basic`、保存了一个当前布局恢复点、确认它开机自启。后续我先不继续改图标显示。
- `019e5839-8009-7850-b80f-d5c2a8ebbf21` `~/Documents/learning-bu`:我先把 Ice 从这条链路里移除,避免它继续占一个菜单栏图标;然后只动两类东西:`系统设置 > 菜单栏` 里的系统项,以及能在 App 自己偏好设置里关闭的第三方菜单栏图标。Surge 和滴答清单按你的要求保留。
## 4. Surge DNS 与代理连通预检
- 类型:`diagnostic-tool`
- 风险:`low`
- 候选 id:`surge-dns-proxy-preflight`
- 摘要:这个主题有效:片段里有明确根因、可复现状态和可验证成功信号。它适合沉淀成一个本机预检工具,用于在公司内网场景快速判断 Surge 是否被 DoH、系统代理未启用或本地代理端口异常卡住。
证据:
- `019e582d-0913-71f3-a067-e5b148a5548a` `~/Documents/product-bu`:连接公司内网不能使用 Surge 进行代理,找 IT 排查了一个半小时解决了 原因是 Surge 使用了 DOH,公司内网不支持 DOH,切换回默认 DNS 后正常
- `019e582d-0913-71f3-a067-e5b148a5548a` `~/Documents/product-bu`:当前 DNS 页已经显示“使用系统 DNS 服务器”已选中,`加密 DNS URL` 也是空的。我会点一次“应用”让这个状态落盘。
- `019e582d-0913-71f3-a067-e5b148a5548a` `~/Documents/product-bu`:检测结果显示 Surge 进程和本地代理端口在跑:HTTP `127.0.0.1:6152`、SOCKS `127.0.0.1:6153`。但 macOS 当前系统代理是空的
- `019e582d-0913-71f3-a067-e5b148a5548a` `~/Documents/product-bu`:已关闭 DoH:`加密 DNS URL` 为空,DNS 选择 `使用系统 DNS 服务器`;已打开系统代理:macOS 现在指向 `127.0.0.1:6152` / `127.0.0.1:6153`
- `019e582d-0913-71f3-a067-e5b148a5548a` `~/Documents/product-bu`:HTTP 代理 `127.0.0.1:6152` 访问 `https://www.apple.com` 返回 `HTTP/2 200`;SOCKS 代理 `127.0.0.1:6153` 访问同站也返回 `HTTP/2 200`
## 5. 推文日报 roster 配置漂移检查
- 类型:`tool-upgrade`
- 风险:`low`
- 候选 id:`twitter-roster-config-drift`
- 摘要:这个主题有效:相关片段显示自动化说明仍要求读取 `.claude/skills/config.json` 的 `skills.twitter-fetcher.users`,但实际运行时配置缺失,主脚本改从历史 raw artifact 恢复账号名单。fallback 让任务跑通了,但也制造了配置真相源漂移:用户很难判断“今天抓了哪些账号、名单从哪来、是否和期望 roster 一致”。
证据:
- `019e5781-0ac4-7d23-a940-98ab0f2b9c8c` `~/Documents/Codex/2026-04-21-https-github-com-haopenglau-skills/repo`:使用当前工作区仓库里的 twitter-fetcher 流程抓取配置文件 .claude/skills/config.json 中 twitter-fetcher.users 的账号列表
- `019e5781-0ac4-7d23-a940-98ab0f2b9c8c` `~/Documents/Codex/2026-04-21-https-github-com-haopenglau-skills/repo`:配置里没有 `skills.twitter-fetcher.users`,这轮会按主脚本的既有 fallback 从 `tmp/twitter_raw` 最近成功 artifact 恢复账号名单
- `019e5781-0ac4-7d23-a940-98ab0f2b9c8c` `~/Documents/Codex/2026-04-21-https-github-com-haopenglau-skills/repo`:Odyssey 里现成的 `2026-05-23` 成品来自另一条系统级日报链路,不是这次要求的仓库主流程。为避免混淆,我继续以当前仓库脚本为准
- `019e5781-0ac4-7d23-a940-98ab0f2b9c8c` `~/Documents/Codex/2026-04-21-https-github-com-haopenglau-skills/repo`:结果已核对:仓库版日报覆盖 `17` 个账号、`13` 个活跃账号、`165` 条推文,且本轮无账号级抓取报错。最后补自动化记忆,记录这次使用的是仓库主脚本和 roster fallback 来源。
## 输入备注
本次 14 个 session 的 `agent_reflections` 均为空,因此候选来自用户消息、assistant 排障过程和验证证据。