@routerhub/agent-rules 1.5.199 → 1.5.201

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.
package/AGENTS.base.md CHANGED
@@ -103,6 +103,20 @@ agent-rules 生成的规则文件分两层,行为与归属不同,评审/发
103
103
  2. **手动执行幂等建表/加字段 SQL**(`CREATE TABLE IF NOT EXISTS` / `ALTER TABLE ... ADD COLUMN IF NOT EXISTS`),并确认目标表/字段已存在。
104
104
  - ⚠️ **遇到缺表/缺字段类报错时,第一优先级检查表结构是否就绪,禁止直接定性为代码 bug。** 特征报错:`relation "..." does not exist`、`table ... does not exist`、`column ... does not exist`、`Unknown column`、`Unrecognized name` 等。先查表(`\d 表名` / `DESCRIBE` / `information_schema`)确认就绪后再排查代码。
105
105
 
106
+ ## ⚠️ 存量数据预演铁律(测试环境测好 ≠ 生产一次好:上线前用生产真实存量数据预演)
107
+
108
+ - ⚠️ **核心认知:测试环境反复调试通过,证明不了生产一次就好。** 测试环境的数据是调试中一次次清空重造出来的最新形态干净数据;生产库里躺着的却是旧代码时代写入的老数据、中间态记录、缺新字段的历史行。**代码对「新代码自己造的数据」走通 ≠ 对「旧代码留下的数据」走通**——新代码读老记录时字段缺失、状态机走到未定义分支、旧任务残留被重复触发,都只存在于生产,测试环境新造数据永远碰不到。判断标准:**凡改动会处理存量数据(读取 / 流转 / 推进 / 迁移 / 按状态判断 / 发布审核 / 媒体生成类任务),只在测试环境用新造数据验证 = 没验证完,上线必翻车。**
109
+ - ⚠️ **触发时机是写代码之前,不是部署的时候。** 写任何会读取/处理「生产已存在数据」的逻辑前,先自查三问(任一命中 → 本次必须登记存量预演,禁止只测新数据就算完成):
110
+ 1. **生产上这条数据现在处于什么状态?** 新逻辑会读到它吗?(例:生产已有该模型一条 `media_status` 停在旧枚举/缺新字段的生成记录——真实存在的形态,不是假设)
111
+ 2. **新代码读到那种旧状态,会走哪条分支?** 是优雅降级/显式报错,还是静默失败/走到未定义分支?测试环境新造数据能不能走到这条分支?
112
+ 3. **该分支用「同形态数据」在测试环境演练过了吗?**(只测新造数据 = 该分支零覆盖,等于没测)
113
+ - ⚠️ **命中三问 → 上线前必须做「存量数据预演」并登记进 `RELEASE_CHECKLIST.md`(commit 带 `release-prep:` 标记),未预演 = 上线准备未完成,禁止宣称可上线:**
114
+ 1. **取生产真实存量记录**:从生产库/后台导出本次改动会处理的那条真实数据,脱敏但**保留触发问题的形态**(旧 `media_status`、缺字段的行、中间态任务等),禁止顺手把它"修成新形态"再测;
115
+ 2. **灌进测试环境走与生产相同的完整流程**:对这条老数据执行真实操作序列(如 publish → 等待异步完成 → 断言产物 URL 可达 → 核对状态推进),确认新代码对老数据走的是预期分支;
116
+ 3. **预演不过 = 代码缺陷**:老数据触发的问题必须在代码里处理(对旧状态优雅降级 / 发版脚本一次性补偿迁移),禁止拿「测试环境新数据能过」当上线依据。
117
+ - **类比:新药在无菌实验室用规范培养的健康细胞试验有效,不等于对真实病患有效——病患带着旧病史与并发症(老数据),健康细胞(新造数据)里根本没有这些病。要在真实病患样本(生产存量数据)上验证过,才算药真能用;只在健康细胞上反复试,永远试不出问题。**
118
+ - ⚠️ **凡出现「测试环境测了很多遍都没事、一上生产就出问题」,第一反应不是再去测试环境多调几遍,而是先问「生产那条数据的状态,测试环境里存在吗?」**——不存在 = 测试环境数据形态与生产不一致,先把生产真实存量数据(脱敏)灌进测试复现,再改代码。
119
+
106
120
  ## ⚠️ 排查与协作铁律
107
121
 
108
122
  - ⚠️ **排查「以前能用、现在不行」类问题时禁止用绕过手段掩盖问题**(改配置屏蔽报错、写同步脚本搬数据、临时禁用校验等),必须先定位根因再修复。
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  所有对 @routerhub/agent-rules 的重大更改都会记录在这个文件中。
4
4
 
5
+ ## [1.5.201] - 2026-09-08
6
+
7
+ ### Fixed
8
+
9
+ - **清理 `agent-browser-cleanup auto` 的并发退出噪声**:当 Chrome 主进程退出时,部分 Helper 进程可能已经自行结束,脚本不再把这类正常竞态打印成 `kill: No such process`,自动收尾输出更干净。
10
+
11
+ ## [1.5.200] - 2026-09-08
12
+
13
+ ### Added
14
+
15
+ - **新增「存量数据预演铁律」**:根治「测试环境反复调试通过、一上生产就翻车」——核心认知是测试环境的数据是调试时清空重造的干净数据,生产库里躺着旧代码时代写入的老数据/中间态/缺字段历史行,代码对新造数据走通 ≠ 对老数据走通。规则要求写任何会处理存量数据(状态机 / 发布审核 / 媒体生成 / 迁移)的逻辑前自查三问(生产该数据什么状态?新代码读到走哪条分支?该分支用同形态数据演练过吗?),命中即登记 `RELEASE_CHECKLIST.md`(commit 带 `release-prep:`),上线前必须从生产导出真实存量记录(脱敏保留触发形态)灌进测试走完整流程预演,预演不过按代码缺陷处理,禁止拿「测试环境新数据能过」当上线依据。
16
+
5
17
  ## [1.5.199] - 2026-09-08
6
18
 
7
19
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@routerhub/agent-rules",
3
- "version": "1.5.199",
3
+ "version": "1.5.201",
4
4
  "description": "Shared Copilot agent rules and guidelines for RouterHub projects",
5
5
  "main": "AGENTS.base.md",
6
6
  "bin": {
package/rules/global.md CHANGED
@@ -103,6 +103,20 @@ agent-rules 生成的规则文件分两层,行为与归属不同,评审/发
103
103
  2. **手动执行幂等建表/加字段 SQL**(`CREATE TABLE IF NOT EXISTS` / `ALTER TABLE ... ADD COLUMN IF NOT EXISTS`),并确认目标表/字段已存在。
104
104
  - ⚠️ **遇到缺表/缺字段类报错时,第一优先级检查表结构是否就绪,禁止直接定性为代码 bug。** 特征报错:`relation "..." does not exist`、`table ... does not exist`、`column ... does not exist`、`Unknown column`、`Unrecognized name` 等。先查表(`\d 表名` / `DESCRIBE` / `information_schema`)确认就绪后再排查代码。
105
105
 
106
+ ## ⚠️ 存量数据预演铁律(测试环境测好 ≠ 生产一次好:上线前用生产真实存量数据预演)
107
+
108
+ - ⚠️ **核心认知:测试环境反复调试通过,证明不了生产一次就好。** 测试环境的数据是调试中一次次清空重造出来的最新形态干净数据;生产库里躺着的却是旧代码时代写入的老数据、中间态记录、缺新字段的历史行。**代码对「新代码自己造的数据」走通 ≠ 对「旧代码留下的数据」走通**——新代码读老记录时字段缺失、状态机走到未定义分支、旧任务残留被重复触发,都只存在于生产,测试环境新造数据永远碰不到。判断标准:**凡改动会处理存量数据(读取 / 流转 / 推进 / 迁移 / 按状态判断 / 发布审核 / 媒体生成类任务),只在测试环境用新造数据验证 = 没验证完,上线必翻车。**
109
+ - ⚠️ **触发时机是写代码之前,不是部署的时候。** 写任何会读取/处理「生产已存在数据」的逻辑前,先自查三问(任一命中 → 本次必须登记存量预演,禁止只测新数据就算完成):
110
+ 1. **生产上这条数据现在处于什么状态?** 新逻辑会读到它吗?(例:生产已有该模型一条 `media_status` 停在旧枚举/缺新字段的生成记录——真实存在的形态,不是假设)
111
+ 2. **新代码读到那种旧状态,会走哪条分支?** 是优雅降级/显式报错,还是静默失败/走到未定义分支?测试环境新造数据能不能走到这条分支?
112
+ 3. **该分支用「同形态数据」在测试环境演练过了吗?**(只测新造数据 = 该分支零覆盖,等于没测)
113
+ - ⚠️ **命中三问 → 上线前必须做「存量数据预演」并登记进 `RELEASE_CHECKLIST.md`(commit 带 `release-prep:` 标记),未预演 = 上线准备未完成,禁止宣称可上线:**
114
+ 1. **取生产真实存量记录**:从生产库/后台导出本次改动会处理的那条真实数据,脱敏但**保留触发问题的形态**(旧 `media_status`、缺字段的行、中间态任务等),禁止顺手把它"修成新形态"再测;
115
+ 2. **灌进测试环境走与生产相同的完整流程**:对这条老数据执行真实操作序列(如 publish → 等待异步完成 → 断言产物 URL 可达 → 核对状态推进),确认新代码对老数据走的是预期分支;
116
+ 3. **预演不过 = 代码缺陷**:老数据触发的问题必须在代码里处理(对旧状态优雅降级 / 发版脚本一次性补偿迁移),禁止拿「测试环境新数据能过」当上线依据。
117
+ - **类比:新药在无菌实验室用规范培养的健康细胞试验有效,不等于对真实病患有效——病患带着旧病史与并发症(老数据),健康细胞(新造数据)里根本没有这些病。要在真实病患样本(生产存量数据)上验证过,才算药真能用;只在健康细胞上反复试,永远试不出问题。**
118
+ - ⚠️ **凡出现「测试环境测了很多遍都没事、一上生产就出问题」,第一反应不是再去测试环境多调几遍,而是先问「生产那条数据的状态,测试环境里存在吗?」**——不存在 = 测试环境数据形态与生产不一致,先把生产真实存量数据(脱敏)灌进测试复现,再改代码。
119
+
106
120
  ## ⚠️ 排查与协作铁律
107
121
 
108
122
  - ⚠️ **排查「以前能用、现在不行」类问题时禁止用绕过手段掩盖问题**(改配置屏蔽报错、写同步脚本搬数据、临时禁用校验等),必须先定位根因再修复。
@@ -695,6 +709,32 @@ agent-rules 生成的规则文件分两层,行为与归属不同,评审/发
695
709
  4. 一旦 `eval` / `snapshot` 返回的内容不是自己操作的页面(URL/内容不符),
696
710
  **第一反应是标签页被抢占**:切回自己的 tab id 后重试,禁止盲目重试同一条命令。
697
711
 
712
+ ## 🚨 agent-browser 内存收尾铁律(用完必须收摊)
713
+
714
+ **根因**:agent-browser CLI 本体很轻,但它背后复用的 Chrome Profile 会保留标签页、
715
+ Service Worker、登录态缓存和页面运行时。每次任务只打开不关闭,`9223` / `9226` 的
716
+ Chrome Helper 会越积越多,表现为“agent-browser 用着用着越来越卡”。
717
+
718
+ **必须遵守**:
719
+
720
+ 1. 每次 `agent-browser tab new` 后必须记录本次任务创建的 tab id;任务结束前,必须关闭
721
+ 本任务打开的所有 tab,禁止把 Cloud Console、GitHub、Slack、Google 登录页等任务页面
722
+ 长期留在 agent-browser Chrome 里。
723
+ 2. 每次浏览器自动化任务结束前,**执行任务的 Agent 必须自动运行** `agent-browser-cleanup auto`
724
+ (或仓库源码内 `bash scripts/agent-browser-cleanup.sh auto`),禁止把这一步交给用户手动判断。
725
+ 用户只负责提出任务,Agent 负责判断是否该释放内存。
726
+ 3. `9226` 无头 Chrome 优先用于 agent 自动化;`agent-browser-cleanup auto` 会在 `9226` 的 tab 数
727
+ > 10,或 RSS > 1500MB 时自动释放它。释放后下次需要浏览器时再重新启动,不要为了“可能等会用”
728
+ 长期占着内存。
729
+ 4. `9223` 有头 Chrome 只在需要用户手动登录、手动查看动态效果、或必须共享可见页面时启动;
730
+ 任务结束且用户不再需要查看时,必须关闭本任务 tab;`auto` 默认不会关闭 `9223`,避免误关用户
731
+ 正在看的页面。只有明确确认 `9223` 没有人工操作中的页面时,才允许设置
732
+ `AGENT_BROWSER_CLEANUP_INCLUDE_HEADED=1 agent-browser-cleanup auto` 或执行 `agent-browser-cleanup hard`。
733
+ 5. 禁止长期同时保留 `9223` + `9226` 两套 agent-browser Chrome 实例,除非当前任务明确需要。
734
+ 多会话并行时也必须各自用 namespace 隔离,任务完成各自清理自己创建的 tab。
735
+ 6. 禁止用 `kill -9` / `pkill -9` 强杀 Chrome;清理只能使用 `agent-browser-cleanup`、
736
+ `chrome-bridge headless-stop`,或 `/bin/kill -TERM` 这类可让 Chrome 正常退出的方式。
737
+
698
738
  ## 优先级
699
739
 
700
740
  1. 项目私有规则(AGENTS.private.md)
@@ -98,7 +98,7 @@ closeChromeByPort() {
98
98
  fi
99
99
 
100
100
  echo "port ${portNumber}: graceful quit"
101
- printf '%s\n' "$processIds" | xargs -n1 /bin/kill -TERM
101
+ printf '%s\n' "$processIds" | xargs -n1 /bin/kill -TERM 2>/dev/null || true
102
102
  }
103
103
 
104
104
  softCleanup() {