@routerhub/agent-rules 1.5.205 → 1.5.206
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
|
@@ -249,6 +249,36 @@ agent-rules 生成的规则文件分两层,行为与归属不同,评审/发
|
|
|
249
249
|
- ⚠️ **不命中触发条件的改动,两段都不走**(纯文案、纯展示类改动不受影响)。
|
|
250
250
|
- ⚠️ **具体操作流程见 `/real-chain-verify` skill**(怎么画链路、每类系统怎么取证、两段各自做到什么程度、证据怎么组织成报告)。
|
|
251
251
|
|
|
252
|
+
## ⚠️ 取证报告铁律(证明「该变的变了」+「不该动的地方一行没动」)
|
|
253
|
+
|
|
254
|
+
- ⚠️ **核心认知:功能验证只回答了一半问题。** 「页面功能验证铁律」「跨系统真实链路验收铁律」证明的都是**该变的地方变了**;但一次写操作真正危险的部分是它的**副作用范围**——级联删除、批量更新、绑定清理会不会顺手把不该动的数据一起带走。**副作用失控是静默的**:页面照常渲染、功能照常用、接口照常 200,只有被顺带删掉的那几张表知道出过事,而没有任何页面会主动告诉你「我多删了 3 行」。所以「不该动的地方一行没动」必须**单独取证**,不能由「功能正常」推出来。
|
|
255
|
+
- **类比:做完手术医生不能只说「手术很成功」,还得给你看一份术后检查报告——切掉的是该切的(病灶)、没碰的是不该碰的(正常器官),每一项都有影像对照。只说「很成功」,你没法知道有没有顺手多切了一刀。**
|
|
256
|
+
- ⚠️ **交付物铁律:任何需求 / 修复的交付,除「功能生效证据」外必须同时附一份「取证报告」,至少回答三个问题:**
|
|
257
|
+
1. **该变的地方,精确变了多少?**——不是「账户删掉了」,而是 `provider_accounts` −1 行、`account_models` −2 行、`models` / `providers` / `provider_model_pricing` 0 变化。
|
|
258
|
+
2. **不该动的地方,怎么证明一行没动?**——负向证据(见下条)。**这是全篇最容易被糊弄过去的地方**:说一句「没影响其他表」谁都会说,能拿出对照物才是证据。
|
|
259
|
+
3. **用户自己去哪儿能复核?**——可复核导航(见下条)。
|
|
260
|
+
- ⚠️ **证据强度按改动类型自动分级,但「可复核导航」不可降级——它是所有级别的必带项。**
|
|
261
|
+
|
|
262
|
+
| 级别 | 适用改动 | 证据构成 |
|
|
263
|
+
|---|---|---|
|
|
264
|
+
| **三层**(完整) | 动了数据本身:删除 / 级联、金额 / 权限 / 路由、共享表或目录数据(`models` / `providers` / 定价 / 账户绑定这类「别人也在读」的表) | ① 页面数字 A/B ② **逐像素相减** ③ **数据库逐行** |
|
|
265
|
+
| **两层** | 普通业务逻辑改动,落库但影响面清楚 | ① 页面数字 A/B ② 数据库行数对照 |
|
|
266
|
+
| **一层** | 纯文案 / 纯样式 / 无数据变化的改动 | 功能证据 + 可复核导航 |
|
|
267
|
+
|
|
268
|
+
- ⚠️ **「可复核导航」为什么一级都不能省**:报告是给用户看的,而他判断「数据到底动没动」的唯一办法是**自己去那个页面看一眼**。报告不告诉他去哪儿看,他就只剩「信」或「不信」两个选项——这等于把「可核实」偷偷降级成了「请相信我」。**判断标准:用户拿着这份报告、不问你任何一句话,能不能自己把那几个数字核对一遍?能 = 合格。**
|
|
269
|
+
- ⚠️ **负向取证铁律:证明「没变」时,任何一处差异都必须能归因,归因不清就是没证完。**
|
|
270
|
+
- 像素级 / 字节级比对里出现的每一处差异,都要逐处定位(哪一列、哪一行、前后各是什么颜色 / 什么值)并给出**归因**(如「搜索框里的文本光标」)。**「应该只是光标吧」不算归因。**
|
|
271
|
+
- ⚠️ **归因到「非数据因素」(光标、时间戳、动画、随机序)时,必须把差异位置放大后附进报告让人自己看**——放大到能一眼看出「这是条 1px 的竖线」而不是「一团色斑」,并标出前后色值与左右相邻像素的值。**让用户自己排除掉「这会不会是数据变了」,比你在文字里保证十遍都有用。**
|
|
272
|
+
- ⚠️ **「总数没变」不等于「没被动过」**:总数恒定也可能是「删了 A 的行、又从别处补了几行」的巧合。凡涉及共享表的负向取证,必须**按维度切片再核一遍**(如按 `provider_id` 分组数行数,确认目标供应商名下 10 行 → 10 行,一行未动)。
|
|
273
|
+
- ⚠️ **基线铁律:负向证据的对照物必须在改动之前取。** 「证明没变」= 改动前有一份值、改动后有一份值、两者逐项相同。改动前没取值 → 事后无论怎么补都补不出基线(代码已变、数据已变),只能推倒重来。**所以「取基线」是动手改代码之前的第一步,不是交报告之前的最后一步**(与「⚠️ 缺陷复现铁律」的「复现截图必须在改代码之前当场拍下」是同一个道理)。
|
|
274
|
+
- ⚠️ **副作用范围上界表:每条 DELETE / 每次写操作,都要在报告里逐条列出「动什么 / 为什么在这里动 / 最多影响多少行」,且实测影响必须 ≤ 上界。** 这条把「⚠️ 数据库 DELETE 铁律」要求的那三个问题**从代码注释搬进报告**——注释只有写代码的人看得到,报告是给用户和 reviewer 看的。上界说不清、或实测超出上界的,直接视为本次改动未完成。
|
|
275
|
+
- ⚠️ **操作链必须是「真人在真实界面里点出来的」,并在报告里逐步列明。** 禁止用脚本模拟、直接改数据库、调内部接口去造出「改动后」的状态——那不是「用户这么操作会发生什么」,而是「我造了一个我希望看到的结果」。报告里要能让读者看出每一步点的是哪个按钮、点完看到什么。
|
|
276
|
+
- ⚠️ **交付形式跟随交付场景,禁止一律套同一种:**
|
|
277
|
+
- **走 PR 的改动** → 取证报告**并入 PR 顶部那份「详细实现文档」**(截图版 HTML→PDF,托管到 `<项目>-docs` 私有仓库,链接置顶 PR Description)。它是那份文档里的一节,**不另起一份**——reviewer 点一个链接就该看到全部,而不是在两个链接之间来回跳。
|
|
278
|
+
- **不走 PR 的即时修复**(用户当场让你修个 bug、要立刻看结果)→ 直接给**桌面上的单文件 HTML 绝对路径**(截图 `data:image/png;base64` 内嵌、双击即开、可搜索、转发不裂图),不走私有仓库、不起本地 HTTP 服务、不用相对路径。
|
|
279
|
+
- ⚠️ **与相邻铁律的分工(四者是同一条路径在时间轴上不同位置各跑一次,不可互相替代):** 「⚠️ 缺陷复现铁律」= 改之前证明问题存在;「⚠️ 修复验证铁律」= 改之后证明问题消失;「⚠️ 跨系统真实链路验收铁律」= 整条链路成不成立(下游接住了没有);**本铁律 = 这次改动的副作用范围有没有失控(不该动的动了吗)**。前三条全过、本铁律不过的情况真实存在——功能修好了、链路跑通了、但目录数据被顺带删了。
|
|
280
|
+
- ⚠️ **具体操作流程见 `/forensic-report` skill**(三层证据怎么拍、逐像素怎么相减、差异怎么归因、可复核导航怎么组织、报告骨架长什么样)。
|
|
281
|
+
|
|
252
282
|
## Git 规范
|
|
253
283
|
|
|
254
284
|
- 分支用 Git Flow(`feature/`、`bugfix/`、`hotfix/`、`refactor/`、`chore/`、`docs/`、`test/`),英文小写中划线分隔。
|
|
@@ -745,6 +775,7 @@ agent-rules 生成的规则文件分两层,行为与归属不同,评审/发
|
|
|
745
775
|
|
|
746
776
|
- ⚠️ **日常对话中,只要聊到写代码/改代码/排查问题/验证功能/实现需求等任何越过「闲聊」的实质内容,就自动触发 `/visual-report` skill,用它管理「验证证据」的产出**,无需用户额外吩咐。触发不依赖于用户正式说「提需求」「做功能」——用户在平常对话里随口提到的开发任务(如「这个页面的按钮没反应」「Redis 里这个 key 好像不对」「帮我把这个查询优化一下」)同样自动触发。该 skill 的职责是:真实数据 + 真实交互 + 可视化证据(页面截图 / Redis 截图 / 数据库截图),把「功能对不对」用用户能一眼看懂的截图和报告证明给用户看。
|
|
747
777
|
- ⚠️ **只有用户显式提到「测试 / TDD / 测试用例」时,才调用 `/tdd-workflow` skill**(写测试用例、跑回归)。没有明确指令时,禁止把 TDD 当作默认开发流程;默认开发流程是上面的 `/visual-report`。
|
|
778
|
+
- ⚠️ **`/visual-report` 证明「功能对不对」,`/forensic-report` 证明「副作用有没有失控」——两者在同一次交付里都要有,缺一不算完成。** 任何需求实现 / bug 修复,除功能生效证据外,必须自动触发 `/forensic-report` skill 产出取证报告(证明「该变的变了 + 不该动的一行没动」,证据强度按改动类型自动分级、交付形式按是否走 PR 分流)。**「功能验证过了」不能替代取证**:页面全绿、接口全 200,都不代表没有别的数据被静默带走。
|
|
748
779
|
|
|
749
780
|
## 🚨 agent-browser 标签页防串扰(所有项目通用)
|
|
750
781
|
|
package/PULL_REQUEST_TEMPLATE.md
CHANGED
|
@@ -57,6 +57,28 @@ Closes #
|
|
|
57
57
|
- ❌「门户页面显示 Active」 ✅「网关 `/v1/models` 里精确出现了这个模型」
|
|
58
58
|
- **默认值类字段与存量数据对照**(命中触发条件 2 时必填):默认值 → 下游消费规则 → 线上存量数据 → 叠加效果
|
|
59
59
|
|
|
60
|
+
## 取证报告
|
|
61
|
+
|
|
62
|
+
<!-- 依据 AGENTS.base.md「⚠️ 取证报告铁律」:功能验证只回答了一半问题,另一半是「不该动的地方有没有被动」。
|
|
63
|
+
页面全绿、接口全 200,都不代表没有别的数据被静默带走(级联删除、批量更新最典型)。
|
|
64
|
+
⚠️ 证据强度按改动类型自动分级(三层:动了数据本身 / 两层:普通业务逻辑 / 一层:纯文案样式)。
|
|
65
|
+
⚠️ 可复核导航一级都不可降级——它是所有级别必带项。
|
|
66
|
+
⚠️ 本栏目是「摘要 + 链接」:完整报告并入 PR 顶部那份「详细实现文档」;不走 PR 的即时修复给桌面 HTML 绝对路径。 -->
|
|
67
|
+
|
|
68
|
+
- [ ] 本次为**一层**改动(纯文案 / 纯样式 / 无数据变化),只需功能证据 + 可复核导航,无需三层取证
|
|
69
|
+
|
|
70
|
+
**① 该变的地方,精确变了多少**:<具体数字 / 行数 / 字段,不是「改好了」>
|
|
71
|
+
|
|
72
|
+
**② 不该动的地方,怎么证明一行没动**:<对照物是什么、基线在哪取的、差异如何归因;涉及共享表时按维度切片再核一遍>
|
|
73
|
+
|
|
74
|
+
**③ 用户自己去哪儿能复核**:<入口 + 点哪几下 + 直达 URL / 可复制命令 + 搜索词>
|
|
75
|
+
|
|
76
|
+
**④ 副作用范围上界表**(有 DELETE / 写操作时必填,每条一行)
|
|
77
|
+
|
|
78
|
+
| 写操作 | 删什么 / 改什么 | 最多影响多少行 | 为什么在这里动 | 实测影响 |
|
|
79
|
+
|---|---|---|---|---|
|
|
80
|
+
| | | | | |
|
|
81
|
+
|
|
60
82
|
## Test Plan
|
|
61
83
|
|
|
62
84
|
<!-- 硬性必填:如何验证改动正确,附可复现步骤或证据(命令 + 结果、手动操作步骤、日志、请求响应、修复前后对比)。 -->
|
|
@@ -74,6 +96,7 @@ Closes #
|
|
|
74
96
|
- [ ] Test Plan 完整且带证据
|
|
75
97
|
- [ ] 修 bug 的 PR 已按「缺陷复现」栏目写下改动前的复现证据(非修 bug 的已勾选豁免项)
|
|
76
98
|
- [ ] 跨系统链路验收已按上方栏目填完(未命中触发条件则勾选豁免项)
|
|
99
|
+
- [ ] 已按「取证报告」栏目给出取证数据(或勾选一层豁免项)
|
|
77
100
|
- [ ] UI 改动已贴截图(或注明无界面变化)
|
|
78
101
|
- [ ] 本地编译 / lint / 测试通过,CI 全绿
|
|
79
102
|
- [ ] 已关联 issue、指定 reviewer
|
package/package.json
CHANGED
package/rules/global.md
CHANGED
|
@@ -249,6 +249,36 @@ agent-rules 生成的规则文件分两层,行为与归属不同,评审/发
|
|
|
249
249
|
- ⚠️ **不命中触发条件的改动,两段都不走**(纯文案、纯展示类改动不受影响)。
|
|
250
250
|
- ⚠️ **具体操作流程见 `/real-chain-verify` skill**(怎么画链路、每类系统怎么取证、两段各自做到什么程度、证据怎么组织成报告)。
|
|
251
251
|
|
|
252
|
+
## ⚠️ 取证报告铁律(证明「该变的变了」+「不该动的地方一行没动」)
|
|
253
|
+
|
|
254
|
+
- ⚠️ **核心认知:功能验证只回答了一半问题。** 「页面功能验证铁律」「跨系统真实链路验收铁律」证明的都是**该变的地方变了**;但一次写操作真正危险的部分是它的**副作用范围**——级联删除、批量更新、绑定清理会不会顺手把不该动的数据一起带走。**副作用失控是静默的**:页面照常渲染、功能照常用、接口照常 200,只有被顺带删掉的那几张表知道出过事,而没有任何页面会主动告诉你「我多删了 3 行」。所以「不该动的地方一行没动」必须**单独取证**,不能由「功能正常」推出来。
|
|
255
|
+
- **类比:做完手术医生不能只说「手术很成功」,还得给你看一份术后检查报告——切掉的是该切的(病灶)、没碰的是不该碰的(正常器官),每一项都有影像对照。只说「很成功」,你没法知道有没有顺手多切了一刀。**
|
|
256
|
+
- ⚠️ **交付物铁律:任何需求 / 修复的交付,除「功能生效证据」外必须同时附一份「取证报告」,至少回答三个问题:**
|
|
257
|
+
1. **该变的地方,精确变了多少?**——不是「账户删掉了」,而是 `provider_accounts` −1 行、`account_models` −2 行、`models` / `providers` / `provider_model_pricing` 0 变化。
|
|
258
|
+
2. **不该动的地方,怎么证明一行没动?**——负向证据(见下条)。**这是全篇最容易被糊弄过去的地方**:说一句「没影响其他表」谁都会说,能拿出对照物才是证据。
|
|
259
|
+
3. **用户自己去哪儿能复核?**——可复核导航(见下条)。
|
|
260
|
+
- ⚠️ **证据强度按改动类型自动分级,但「可复核导航」不可降级——它是所有级别的必带项。**
|
|
261
|
+
|
|
262
|
+
| 级别 | 适用改动 | 证据构成 |
|
|
263
|
+
|---|---|---|
|
|
264
|
+
| **三层**(完整) | 动了数据本身:删除 / 级联、金额 / 权限 / 路由、共享表或目录数据(`models` / `providers` / 定价 / 账户绑定这类「别人也在读」的表) | ① 页面数字 A/B ② **逐像素相减** ③ **数据库逐行** |
|
|
265
|
+
| **两层** | 普通业务逻辑改动,落库但影响面清楚 | ① 页面数字 A/B ② 数据库行数对照 |
|
|
266
|
+
| **一层** | 纯文案 / 纯样式 / 无数据变化的改动 | 功能证据 + 可复核导航 |
|
|
267
|
+
|
|
268
|
+
- ⚠️ **「可复核导航」为什么一级都不能省**:报告是给用户看的,而他判断「数据到底动没动」的唯一办法是**自己去那个页面看一眼**。报告不告诉他去哪儿看,他就只剩「信」或「不信」两个选项——这等于把「可核实」偷偷降级成了「请相信我」。**判断标准:用户拿着这份报告、不问你任何一句话,能不能自己把那几个数字核对一遍?能 = 合格。**
|
|
269
|
+
- ⚠️ **负向取证铁律:证明「没变」时,任何一处差异都必须能归因,归因不清就是没证完。**
|
|
270
|
+
- 像素级 / 字节级比对里出现的每一处差异,都要逐处定位(哪一列、哪一行、前后各是什么颜色 / 什么值)并给出**归因**(如「搜索框里的文本光标」)。**「应该只是光标吧」不算归因。**
|
|
271
|
+
- ⚠️ **归因到「非数据因素」(光标、时间戳、动画、随机序)时,必须把差异位置放大后附进报告让人自己看**——放大到能一眼看出「这是条 1px 的竖线」而不是「一团色斑」,并标出前后色值与左右相邻像素的值。**让用户自己排除掉「这会不会是数据变了」,比你在文字里保证十遍都有用。**
|
|
272
|
+
- ⚠️ **「总数没变」不等于「没被动过」**:总数恒定也可能是「删了 A 的行、又从别处补了几行」的巧合。凡涉及共享表的负向取证,必须**按维度切片再核一遍**(如按 `provider_id` 分组数行数,确认目标供应商名下 10 行 → 10 行,一行未动)。
|
|
273
|
+
- ⚠️ **基线铁律:负向证据的对照物必须在改动之前取。** 「证明没变」= 改动前有一份值、改动后有一份值、两者逐项相同。改动前没取值 → 事后无论怎么补都补不出基线(代码已变、数据已变),只能推倒重来。**所以「取基线」是动手改代码之前的第一步,不是交报告之前的最后一步**(与「⚠️ 缺陷复现铁律」的「复现截图必须在改代码之前当场拍下」是同一个道理)。
|
|
274
|
+
- ⚠️ **副作用范围上界表:每条 DELETE / 每次写操作,都要在报告里逐条列出「动什么 / 为什么在这里动 / 最多影响多少行」,且实测影响必须 ≤ 上界。** 这条把「⚠️ 数据库 DELETE 铁律」要求的那三个问题**从代码注释搬进报告**——注释只有写代码的人看得到,报告是给用户和 reviewer 看的。上界说不清、或实测超出上界的,直接视为本次改动未完成。
|
|
275
|
+
- ⚠️ **操作链必须是「真人在真实界面里点出来的」,并在报告里逐步列明。** 禁止用脚本模拟、直接改数据库、调内部接口去造出「改动后」的状态——那不是「用户这么操作会发生什么」,而是「我造了一个我希望看到的结果」。报告里要能让读者看出每一步点的是哪个按钮、点完看到什么。
|
|
276
|
+
- ⚠️ **交付形式跟随交付场景,禁止一律套同一种:**
|
|
277
|
+
- **走 PR 的改动** → 取证报告**并入 PR 顶部那份「详细实现文档」**(截图版 HTML→PDF,托管到 `<项目>-docs` 私有仓库,链接置顶 PR Description)。它是那份文档里的一节,**不另起一份**——reviewer 点一个链接就该看到全部,而不是在两个链接之间来回跳。
|
|
278
|
+
- **不走 PR 的即时修复**(用户当场让你修个 bug、要立刻看结果)→ 直接给**桌面上的单文件 HTML 绝对路径**(截图 `data:image/png;base64` 内嵌、双击即开、可搜索、转发不裂图),不走私有仓库、不起本地 HTTP 服务、不用相对路径。
|
|
279
|
+
- ⚠️ **与相邻铁律的分工(四者是同一条路径在时间轴上不同位置各跑一次,不可互相替代):** 「⚠️ 缺陷复现铁律」= 改之前证明问题存在;「⚠️ 修复验证铁律」= 改之后证明问题消失;「⚠️ 跨系统真实链路验收铁律」= 整条链路成不成立(下游接住了没有);**本铁律 = 这次改动的副作用范围有没有失控(不该动的动了吗)**。前三条全过、本铁律不过的情况真实存在——功能修好了、链路跑通了、但目录数据被顺带删了。
|
|
280
|
+
- ⚠️ **具体操作流程见 `/forensic-report` skill**(三层证据怎么拍、逐像素怎么相减、差异怎么归因、可复核导航怎么组织、报告骨架长什么样)。
|
|
281
|
+
|
|
252
282
|
## Git 规范
|
|
253
283
|
|
|
254
284
|
- 分支用 Git Flow(`feature/`、`bugfix/`、`hotfix/`、`refactor/`、`chore/`、`docs/`、`test/`),英文小写中划线分隔。
|
|
@@ -745,6 +775,7 @@ agent-rules 生成的规则文件分两层,行为与归属不同,评审/发
|
|
|
745
775
|
|
|
746
776
|
- ⚠️ **日常对话中,只要聊到写代码/改代码/排查问题/验证功能/实现需求等任何越过「闲聊」的实质内容,就自动触发 `/visual-report` skill,用它管理「验证证据」的产出**,无需用户额外吩咐。触发不依赖于用户正式说「提需求」「做功能」——用户在平常对话里随口提到的开发任务(如「这个页面的按钮没反应」「Redis 里这个 key 好像不对」「帮我把这个查询优化一下」)同样自动触发。该 skill 的职责是:真实数据 + 真实交互 + 可视化证据(页面截图 / Redis 截图 / 数据库截图),把「功能对不对」用用户能一眼看懂的截图和报告证明给用户看。
|
|
747
777
|
- ⚠️ **只有用户显式提到「测试 / TDD / 测试用例」时,才调用 `/tdd-workflow` skill**(写测试用例、跑回归)。没有明确指令时,禁止把 TDD 当作默认开发流程;默认开发流程是上面的 `/visual-report`。
|
|
778
|
+
- ⚠️ **`/visual-report` 证明「功能对不对」,`/forensic-report` 证明「副作用有没有失控」——两者在同一次交付里都要有,缺一不算完成。** 任何需求实现 / bug 修复,除功能生效证据外,必须自动触发 `/forensic-report` skill 产出取证报告(证明「该变的变了 + 不该动的一行没动」,证据强度按改动类型自动分级、交付形式按是否走 PR 分流)。**「功能验证过了」不能替代取证**:页面全绿、接口全 200,都不代表没有别的数据被静默带走。
|
|
748
779
|
|
|
749
780
|
## 🚨 agent-browser 标签页防串扰(所有项目通用)
|
|
750
781
|
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: forensic-report
|
|
3
|
+
description: >-
|
|
4
|
+
取证报告——证明「该变的地方变了」+「不该动的地方一行没动」。
|
|
5
|
+
功能验证证明不了副作用范围:级联删除 / 批量更新会静默带走不该动的数据,页面照常全绿、接口照常 200,
|
|
6
|
+
没有任何页面会主动告诉你「我多删了 3 行」。「不该动的地方没动」必须单独取证。
|
|
7
|
+
本 Skill 产出一份可复核的取证报告,回答三件事:动了什么(精确到行数)、没动什么(怎么证明的)、
|
|
8
|
+
用户自己去哪儿能自己核一遍。
|
|
9
|
+
触发场景包括但不限于:
|
|
10
|
+
「证明没动」「数据没变化」「一行没动」「怎么证明没删」「取证报告」「取证」「留个证据」
|
|
11
|
+
「我要能自己复核」「我去哪儿能看到」「这个表有没有被动」「副作用范围」「影响范围」
|
|
12
|
+
「删了之后别的表动了吗」「怎么确认只删了该删的」「负向证据」「基线对照」「影响面」
|
|
13
|
+
「会不会误删」「级联删了什么」「别的数据有没有被带走」。
|
|
14
|
+
**任何需求 / 修复的交付都会自动触发本 Skill**(证据强度按改动类型分级,见下),无需用户开口。
|
|
15
|
+
与其他验证 Skill 的分工:`real-chain-verify` 证明「下游真的接住了」(正向链路),
|
|
16
|
+
本 Skill 证明「副作用没失控」(不该动的动了吗)——两者互补,不可互相替代。
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# 取证报告(Forensic Report)
|
|
20
|
+
|
|
21
|
+
⚠️ **本 Skill 已触发。在用户回复中第一句话必须输出:「🔧 已触发 `forensic-report`,产出取证报告(证明该变的变了 + 不该动的一行没动)…」然后严格按照以下步骤执行,不得跳过。**
|
|
22
|
+
|
|
23
|
+
## ⚠️ 核心铁律(违反即错误)
|
|
24
|
+
|
|
25
|
+
- ⚠️ **功能正常 ≠ 副作用受控。** 一次写操作真正危险的是它的**作用范围**。「账户删掉了、页面也刷新了」只证明前半句;后半句「顺带删掉的东西」没有任何页面会告诉你。**这两件事必须分别取证。**
|
|
26
|
+
- ⚠️ **「我看了,没影响别的表」不是证据。** 证据 = 有对照物、有数值、有差异归因、用户能自己核。**说「没动」谁都会说,能拿出前后两份逐项相同的值才算证完。**
|
|
27
|
+
- ⚠️ **基线必须在动手改之前取。** 改完再补 = 补不出来(代码已变、数据已变),只能推倒重来。「取基线」是第一步,不是最后一步。
|
|
28
|
+
- ⚠️ **任何一处差异都必须归因,归因不清 = 没证完。** 越小的差异越要较真——1 个像素的差别,恰恰是最容易用「应该是误差吧」糊过去、而实际可能是数据变了的地方。
|
|
29
|
+
- ⚠️ **可复核导航一级都不能省。** 报告不告诉用户去哪儿自己看,他就只剩「信」或「不信」——等于把「可核实」降级成了「请相信我」。
|
|
30
|
+
|
|
31
|
+
## 第 0 步(动手之前):取基线
|
|
32
|
+
|
|
33
|
+
⚠️ **在改任何代码之前先做完这一步。** 记下你要证的东西的**当前值**,作为事后对照的基准:
|
|
34
|
+
|
|
35
|
+
| 要证什么 | 基线取什么 | 存到哪 |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| 某张表 / 某几行没被动 | 相关表的行数(必要时按维度分组)+ 目标行的原始内容 | 文本文件 + 终端输出 |
|
|
38
|
+
| 某个页面没变 | 该页面的**整页截图**(同视口宽、同 DPR、同滚动位置) | `screenshots/` 临时目录 |
|
|
39
|
+
| 某个接口返回值没变 | 完整响应体 | 文本文件 |
|
|
40
|
+
|
|
41
|
+
⚠️ **基线截图必须配「拍摄条件」一起记**:视口宽、DPR、URL、滚动位置。**条件不一致 = 两张图逐像素相减出来的全是噪声**(内容按比例缩放、位置错位),而不是你要找的差异。
|
|
42
|
+
|
|
43
|
+
## 证据强度分级(按改动类型自动选,可复核导航不可降级)
|
|
44
|
+
|
|
45
|
+
| 级别 | 适用改动 | 证据构成 |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| **三层**(完整) | 动了数据本身:删除 / 级联、金额 / 权限 / 路由、共享表或目录数据(`models` / `providers` / 定价 / 账户绑定这类「别人也在读」的表) | ① 页面数字 A/B ② 逐像素相减 ③ 数据库逐行 |
|
|
48
|
+
| **两层** | 普通业务逻辑改动,落库但影响面清楚 | ① 页面数字 A/B ② 数据库行数对照 |
|
|
49
|
+
| **一层** | 纯文案 / 纯样式 / 无数据变化的改动 | 功能证据 + 可复核导航 |
|
|
50
|
+
|
|
51
|
+
⚠️ **拿不准等级时按高的做。** 事后发现「其实只动了 1 行」的代价,远小于事后发现「原来它级联删了别的东西、但我没取证」。
|
|
52
|
+
|
|
53
|
+
⚠️ **无论哪一级,「可复核导航」都必须有**(见下文专节)。
|
|
54
|
+
|
|
55
|
+
## 三层证据怎么做
|
|
56
|
+
|
|
57
|
+
### 第 1 层 · 页面数字(最直观,人人能自己看)
|
|
58
|
+
|
|
59
|
+
- 同一页面、**改动前**截一张整页图、**改动后**再截一张,并排放进报告。
|
|
60
|
+
- 截图必须能看到 **URL**(证据可追溯)与**关键数字**(如 `Total 2`、行数、金额),关键区域用箭头标注(走 `/screenshot-annotate`,坐标来自 `getBoundingClientRect()`,禁止肉眼估)。
|
|
61
|
+
- ⚠️ **这一层最容易被骗过**:页面可能有缓存、可能分组折叠了没展开、可能有多条同名路径看到的是不同视图、数字可能四舍五入后看起来一样。所以它只是**第一层**,不是唯一一层。
|
|
62
|
+
|
|
63
|
+
### 第 2 层 · 逐像素相减(把「看不见的变化」逼出来)
|
|
64
|
+
|
|
65
|
+
用同一台浏览器、同一视口宽、同一 DPR,对同一页面在改动前后各截一张整页 PNG,然后逐像素相减:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
# 依赖:pip install pillow (本机用 /usr/bin/python3,Homebrew 的 3.14 没有 PIL)
|
|
69
|
+
import hashlib
|
|
70
|
+
from PIL import Image, ImageChops
|
|
71
|
+
|
|
72
|
+
def md5(path):
|
|
73
|
+
with open(path, "rb") as f:
|
|
74
|
+
return hashlib.md5(f.read()).hexdigest()
|
|
75
|
+
|
|
76
|
+
def brief(values, keep=12):
|
|
77
|
+
"""差异列/行可能有几百个,只列前 keep 个,避免刷屏。"""
|
|
78
|
+
if len(values) <= keep:
|
|
79
|
+
return values
|
|
80
|
+
return values[:keep] + ["… 共 %d 个" % len(values)]
|
|
81
|
+
|
|
82
|
+
before, after = "before.png", "after.png"
|
|
83
|
+
print("md5 一致?", md5(before) == md5(after)) # True = 逐字节完全相同,最强证据
|
|
84
|
+
|
|
85
|
+
a = Image.open(before).convert("RGB")
|
|
86
|
+
b = Image.open(after).convert("RGB")
|
|
87
|
+
assert (a.width, a.height) == (b.width, b.height), "尺寸不同,无法逐像素对照"
|
|
88
|
+
|
|
89
|
+
diff = ImageChops.difference(a, b)
|
|
90
|
+
bbox = diff.getbbox()
|
|
91
|
+
if bbox is None:
|
|
92
|
+
print("逐像素 diff:0 个像素不同")
|
|
93
|
+
else:
|
|
94
|
+
pa, pb, pd = a.load(), b.load(), diff.load()
|
|
95
|
+
pts = [(x, y) for y in range(a.height) for x in range(a.width) if pd[x, y] != (0, 0, 0)]
|
|
96
|
+
print("差异像素数:%d" % len(pts))
|
|
97
|
+
print("包围盒:x=%d..%d y=%d..%d" % (bbox[0], bbox[2]-1, bbox[1], bbox[3]-1))
|
|
98
|
+
print("差异列:%s" % brief(sorted(set(x for x, _ in pts))))
|
|
99
|
+
print("差异行:%s" % brief(sorted(set(y for _, y in pts))))
|
|
100
|
+
x0, y0 = pts[0]
|
|
101
|
+
print("首处差异 (%d,%d):before=%s after=%s" % (x0, y0, pa[x0, y0], pb[x0, y0]))
|
|
102
|
+
# 关键:看差异点左右相邻的像素,判断它是不是一条孤立的 1px 竖线
|
|
103
|
+
print("左右相邻:before %s / %s after %s / %s"
|
|
104
|
+
% (pa[x0-1, y0], pa[x0+1, y0], pb[x0-1, y0], pb[x0+1, y0]))
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
⚠️ **本脚本已实测跑通**(PR #158 删除账户取证,四组前后截图各 1680×2400),四组输出可直接作为对照基准:**md5 全等 → 0 像素**(Provider List);**17 像素 / 单列 x=383 / y=150..166**(Model List,光标);**16 像素 / 单列 x=388 / y=202..217**(Price Center,光标);**470708 像素 / 跨度 x=260..1666 y=93..2298**(Accounts,真实变化)。**同样的输入跑出同样的数字 = 方法本身可复现**,不是「我这边跑得通」。若你跑出来的数字与预期不符,先核对拍摄条件(视口宽 / DPR / URL / 滚动位置)是否一致,再怀疑数据。
|
|
108
|
+
|
|
109
|
+
**两个概念要向读者解释清楚(报告里直接写人话)**:
|
|
110
|
+
|
|
111
|
+
- **「md5 一致」是什么意思**:md5 是把一整个文件算成一段 32 位十六进制指纹,文件里哪怕只改了 1 个 bit,指纹就完全不同。两张 PNG 的 md5 相同 = **逐字节完全相同**,比「像素一样」还强一层(连压缩块、元数据都没变)。
|
|
112
|
+
- **「逐像素相减」是怎么做的**:两张同尺寸的整页图,按坐标一一对应的像素做减法,统计有多少个像素不一样、落在哪一列哪一行。一张 1680 宽的整页截图约 300 万个像素,**只要有一个像素颜色变了就会被抓到**。
|
|
113
|
+
|
|
114
|
+
### 第 3 层 · 数据库逐行(绕过前端,最权威)
|
|
115
|
+
|
|
116
|
+
⚠️ 前端页面有缓存、有多个同名视图、分组可能折叠,所以最后再**直连数据库数一遍**——这是最权威的口径,绕过了整个前端。
|
|
117
|
+
|
|
118
|
+
```sql
|
|
119
|
+
-- 目录类共享表:改动前后各数一次,必须完全相同
|
|
120
|
+
SELECT 'models', count(*) FROM models; -- 96 → 96
|
|
121
|
+
SELECT 'providers', count(*) FROM providers; -- 21 → 21
|
|
122
|
+
SELECT 'provider_model_pricing', count(*) FROM provider_model_pricing; -- 153 → 153
|
|
123
|
+
|
|
124
|
+
-- 该变的表:确认减少量正好等于预期
|
|
125
|
+
SELECT 'provider_accounts', count(*) FROM provider_accounts; -- 83 → 82(删了 1 个账户,−1 ✓)
|
|
126
|
+
SELECT 'account_models', count(*) FROM account_models; -- 453 → 451(该账户挂了 2 个模型,−2 ✓)
|
|
127
|
+
|
|
128
|
+
-- 关键:共享表还要按维度切片再核一遍(见下「总数不变 ≠ 没动过」)
|
|
129
|
+
SELECT provider_id, count(*) FROM provider_model_pricing
|
|
130
|
+
WHERE provider_id = 18 GROUP BY provider_id; -- 10 → 10,一行未动
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
⚠️ **报告里要写清「−1 和 −2 正好是预期值」这件事**:删掉 1 个账户,`provider_accounts` 就该少 1 行;该账户名下挂着 2 个模型,`account_models` 就该少 2 行。**该少的正好少了这么多,一行不多一行不少**——如果级联范围失控,目录表就会跟着掉;如果什么都没删,账户表就不会变。实测卡在「只删该删的」这个点上,才叫证完。
|
|
134
|
+
|
|
135
|
+
## 负向取证:把「没变」证成可复核的事实
|
|
136
|
+
|
|
137
|
+
### ① 精确增减 = 预期值(正向锚点)
|
|
138
|
+
|
|
139
|
+
别只说「目录表没变」,要说「**该变的变成了多少、该不变的一行没动**」,两者互为佐证。只有前者没有后者 = 没证明副作用受控;只有后者没有前者 = 没证明操作真的发生了(可能是操作压根没生效)。
|
|
140
|
+
|
|
141
|
+
### ② 每一处差异都要归因,归因到「非数据因素」时必须放大让人自己看
|
|
142
|
+
|
|
143
|
+
像素比对往往不是 0 差异——搜过东西的输入框会有**文本光标**(闪烁的竖线),截图时机不同就会留下一道 1px 的线。这不是数据变化,但**你不能只在文字里说「应该是光标」**。
|
|
144
|
+
|
|
145
|
+
正确做法:把差异位置**放大后并排附进报告**,让人自己看:
|
|
146
|
+
|
|
147
|
+
- 放大用**最近邻插值**(`Image.NEAREST`),放大倍率取 7~8 倍——每个原始像素变成一个 7×7 的方块,**不做平滑**,这样放大后不会糊、能一眼看出形状。
|
|
148
|
+
- 左(改动前)右(改动后)并排,配 `BEFORE` / `AFTER` 标题带。
|
|
149
|
+
- 图注写清:差异的**列/行坐标、前后色值、以及左右相邻像素的值**。
|
|
150
|
+
|
|
151
|
+
**实例(可直接作为图注模板)**:
|
|
152
|
+
|
|
153
|
+
> 整页 1680×2400 共约 300 万像素,**只有 17 个不同**,全部落在 `x=383` 这**一列**、`y=150..166` 这 17 **行**。改动前该处纯白 `(255,255,255)`,改动后是一条 1px 深灰竖线 `(55,65,81)`;左右相邻的 `(382)` 与 `(384)` 前后**都是纯白**。单列、1px 宽、竖直、两侧纯白、位于搜索框内部 —— 只可能是输入框的文本光标,不是数据变化。
|
|
154
|
+
|
|
155
|
+
⚠️ **「左右相邻像素前后都是纯白」这一句是关键**:它排除了「这是一块色斑 / 一个被改动的单元格 / 一段被换掉的文字」。报告里要给出这几个值,让读者能自己下同样的结论。
|
|
156
|
+
|
|
157
|
+
### ③ 「总数没变」不等于「没被动过」
|
|
158
|
+
|
|
159
|
+
⚠️ 总数恒定也可能是「删了 A 的行、又从别处补了几行」的巧合。**凡涉及共享表的负向取证,必须按维度切片再核一遍。**
|
|
160
|
+
|
|
161
|
+
> 实例:`provider_model_pricing` 全表 153 → 153。但只核总数不够——还要按 `provider_id` 分组数一遍,确认目标供应商(`provider_id=18`,DeepSeek)名下 **10 行 → 10 行**,一行未动。这排除了「总数没变,但把 DeepSeek 的行删了、又从别处补了几行」这种巧合。
|
|
162
|
+
|
|
163
|
+
### ④ 最强的负向证据是「逐字节相同」
|
|
164
|
+
|
|
165
|
+
如果某个页面的前后两张截图 **md5 完全相同**(不是「像素一样」,是文件逐字节一样),直接说这一句就够了——它强于任何像素级论证。报告里要给出完整 md5 值让读者自己复算。
|
|
166
|
+
|
|
167
|
+
## 可复核导航(每一级都必须有)
|
|
168
|
+
|
|
169
|
+
⚠️ **这是用户最初会问的那个问题:「你说了没动,我去哪儿能看到?」报告必须正面回答它。**
|
|
170
|
+
|
|
171
|
+
在报告靠前的位置给一节「去哪儿看」,包含:
|
|
172
|
+
|
|
173
|
+
1. **完整的 4 个(或 N 个)入口在真实界面里的实拍位置**(截图 + 箭头标注),不是文字描述「左侧菜单里」。
|
|
174
|
+
2. **一张导航表,逐行给出**:看什么表 / **点哪几下**(左侧菜单点哪个分组展开 → 点第几项)/ **直达 URL** / **搜索词**(该页面搜索框里输什么过滤出目标行)/ 删前 → 删后。
|
|
175
|
+
3. **入口坐标来自 DOM 测量**(`getBoundingClientRect()`),不是肉眼估位——用户按图索骥时框要真的套在菜单项上。
|
|
176
|
+
|
|
177
|
+
⚠️ **判断标准:用户拿着这份报告、不问你任何一句话,能不能自己把那几个数字核对一遍?** 能 = 合格;不能 = 补导航,别急着交付。
|
|
178
|
+
|
|
179
|
+
## 副作用范围上界表
|
|
180
|
+
|
|
181
|
+
⚠️ **每条 DELETE / 每次写操作,都要在报告里逐条列表回答三个问题**(这是把「数据库 DELETE 铁律」要求的注释内容搬进报告——注释只有写代码的人看得到,报告是给用户和 reviewer 看的):
|
|
182
|
+
|
|
183
|
+
| DELETE 语句 | 删什么 | 最多影响多少行 | 为什么在这里删 |
|
|
184
|
+
|---|---|---|---|
|
|
185
|
+
| `DELETE FROM account_model_pricing WHERE account_id = ?` | 该账户自己的议价定价 | 该账户的行(本次 **0** 行) | 账户没了,它的议价定价无归属 |
|
|
186
|
+
| `DELETE FROM account_models WHERE account_id = ?` | 该账户名下的模型绑定 | 该账户的绑定(本次 **2** 行) | 绑定是「账户↔模型」的中间行,账户没了它就没意义 |
|
|
187
|
+
| `DELETE FROM provider_accounts WHERE account_id = ? AND vendor_id = ?` | 账户本身 | **1** 行(本次 1 行) | 用户点的就是「删这个账户」 |
|
|
188
|
+
|
|
189
|
+
然后补一句结论,说清为什么「没动」不是巧合:
|
|
190
|
+
|
|
191
|
+
> 三条 DELETE **全部以 `account_id` 为唯一收敛条件**——不存在「按列表反选」「全量同步」这类会误伤别的行 / 别的表的写法。被解绑的模型和供应商**根本不在任何一条 DELETE 的范围内**,所以前面观测到的「逐行不变」不是运气,是这三条 SQL 的写法决定的。
|
|
192
|
+
|
|
193
|
+
⚠️ **要求:实测影响 ≤ 上界。** 上界说不清、或实测超出上界 → 直接视为本次改动未完成。
|
|
194
|
+
|
|
195
|
+
## 操作链必须真人真点
|
|
196
|
+
|
|
197
|
+
⚠️ **报告里的「改动后」状态,必须是真人在真实界面里一步步点出来的**,并在报告里**逐步列明**(一步一张图 + 图注):
|
|
198
|
+
|
|
199
|
+
| 步 | 点哪几下 | 这一步之后的状态 |
|
|
200
|
+
|---|---|---|
|
|
201
|
+
| ① | 打开 `…/accounts`,看 `xxx` 那一行 | 账户 Active,名下挂着 2 个模型 |
|
|
202
|
+
| ② | 点该行的 **Disable** → 弹窗 → 点 Disable | 账户变 Disabled;**此时才出现 Enable / Edit / Delete 三个按钮**;2 条绑定**仍然挂在账户上** |
|
|
203
|
+
| ③ | 点该行的 **Delete** → 读一遍确认框文案 → 点红色 Delete | 确认框文案即产品自己的承诺 |
|
|
204
|
+
| ④ | 页面自动刷新 | 计数 8 → 7 total;其他分组不受影响 |
|
|
205
|
+
|
|
206
|
+
⚠️ **禁止用脚本模拟点击、直接改数据库、或调内部接口去造出「改动后」的状态。** 那不是「用户这么操作会发生什么」,而是「我造了一个我希望看到的结果」——两者的差别正是这个 Skill 要防的东西。**报告里要能让读者看出每一步点的是哪个按钮。**
|
|
207
|
+
|
|
208
|
+
⚠️ **遇到「必须先做某个前置动作才能走到目标操作」时,要把前置原因一并写清**(如「删除接口有硬前置校验 `if account.IsActive` → 400 `account must be disabled before deletion`,所以第 ② 步不是可选项」)——否则读者自己复现时会卡在第一步,以为报告是错的。
|
|
209
|
+
|
|
210
|
+
## 报告骨架(缺一不算完成)
|
|
211
|
+
|
|
212
|
+
1. **产品自己的承诺**(可选但强烈建议):产品在界面上对用户承诺了什么(如确认框文案原文)。**先摆产品的承诺,再用证据逐条验证它有没有兑现**——这比自说自话有说服力得多。
|
|
213
|
+
2. **去哪儿看**(可复核导航):N 个入口的实拍位置 + 点哪几下 + 直达 URL + 搜索词。
|
|
214
|
+
3. **证据分层结论**:三层(页面数字 / 逐像素 / 数据库)各自的关键数值,并按「从软到硬」说明**每一层会被什么骗过、为什么需要下一层**。
|
|
215
|
+
4. **差异归因**:每一处差异的定位 + 放大图 + 归因结论。
|
|
216
|
+
5. **数据库逐行对照**:基线 → 事后 → 增减量 → 是否等于预期。
|
|
217
|
+
6. **真实的操作链**:逐步截图 + 前置条件说明。
|
|
218
|
+
7. **副作用范围上界表**:逐条 DELETE 的三个问题 + 实测值。
|
|
219
|
+
8. **结论**:逐条列出证据关键数值与可复查标识,量化说清「该变的变了多少、不该动的 0 变化」。
|
|
220
|
+
|
|
221
|
+
⚠️ **报告要在靠前位置放一张「为什么这样验证成立」的原理卡**:先讲清「本次变更的本质是哪一个动作」,再论证「手动模拟该动作 = 真实场景」。**本次的核心论证是**:这个修复的唯一改动点,可以精确映射成一个可手动触发的原子操作(如「对一个还挂着 Active 模型映射的账户执行删除」)——它在旧代码上必定失败、在新代码上必定成功,**是一个天然的「版本判别器」**。所以并不是「删了账户再回头证明表没被动」,而是**刻意构造了一个只有新版本才做得成的动作**:动作做成了 = 新版在跑;副作用范围正确 = 级联被限制住了。**两件事一起成立,才等于「修复按预期生效」。**
|
|
222
|
+
|
|
223
|
+
## 交付形式(跟随交付场景,禁止一律套同一种)
|
|
224
|
+
|
|
225
|
+
| 场景 | 交付形式 |
|
|
226
|
+
|---|---|
|
|
227
|
+
| **走 PR 的改动** | 取证报告**并入 PR 顶部那份「详细实现文档」**(截图版 HTML→PDF,托管到 `<项目>-docs` 私有仓库,链接置顶 PR Description)。**它是那份文档里的一节,不另起一份**——reviewer 点一个链接就该看到全部,不该在两个链接之间来回跳。走 `/create-doc` skill。 |
|
|
228
|
+
| **不走 PR 的即时修复**(用户当场让你修个 bug、要立刻看结果) | 直接给**桌面上的单文件 HTML 绝对路径**(如 `/Users/<me>/Desktop/<任务名>/xxx-取证报告.html`)。截图一律 `data:image/png;base64` 内嵌,双击即开、可搜索、转发不裂图。**不走私有仓库、不起本地 HTTP 服务、不用相对路径、不用 `file:///`。** |
|
|
229
|
+
|
|
230
|
+
⚠️ **两种形式都要求截图内嵌,禁止用文件路径引用外部 PNG**——文档会被打开、移动、分享,外部图片路径一旦脱离原目录就全是裂图。
|
|
231
|
+
|
|
232
|
+
## 判断边界
|
|
233
|
+
|
|
234
|
+
- ⚠️ **改动命中「三层」条件却没做负向取证就宣称完成 → 直接违背铁律,必须停下并补齐。**
|
|
235
|
+
- ⚠️ **改完才发现没取基线** → 如实说明「基线缺失、本次无法证明未变更」,并说明补救方案(如在下一个可对照的时点重新取基线跑一次),禁止用「应该没动」搪塞过去。
|
|
236
|
+
- ⚠️ **用户明确说「不用取证,我就要结果」** → 按用户指令执行,但交付时必须显式说明「本次跳过了取证」及跳过了哪几层。
|
|
237
|
+
- **纯文案 / 纯样式 / 无数据变化的改动** → 走一级轻量版(功能证据 + 可复核导航)即可,不必强上三层。
|
|
238
|
+
|
|
239
|
+
## 相关
|
|
240
|
+
|
|
241
|
+
- 规则出处:`AGENTS.base.md`「⚠️ 取证报告铁律」
|
|
242
|
+
- 改之前证明问题存在:`AGENTS.base.md`「⚠️ 缺陷复现铁律」
|
|
243
|
+
- 改之后证明问题消失:`AGENTS.base.md`「⚠️ 修复验证铁律」
|
|
244
|
+
- 链路成不成立(下游接住了吗):`AGENTS.base.md`「⚠️ 跨系统真实链路验收铁律」+ `real-chain-verify` skill
|
|
245
|
+
- DELETE 的三个问题(写在代码注释里):`AGENTS.base.md`「⚠️ 数据库 DELETE 铁律」
|
|
246
|
+
- 截图标注:`screenshot-annotate` skill
|
|
247
|
+
- 文档生成与交付:`create-doc` skill
|
|
248
|
+
- 报告产出规范:`visual-report` skill
|
|
@@ -45,9 +45,13 @@ description: >-
|
|
|
45
45
|
- 需要用户操作浏览器/插件时,明确告诉用户「请打开 X,做 Y 操作,然后截图发给我」——具体到点哪个按钮、看哪个 key。
|
|
46
46
|
- 用户截的图与 AI capability(agent-browser 截图 / 后台页面自动化截图)互为验证,双证据对齐。
|
|
47
47
|
|
|
48
|
-
##
|
|
48
|
+
## 报告格式(交付形式跟随交付场景)
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
⚠️ **交付形式分两种,禁止一律套同一种**(详见 `forensic-report` skill「交付形式」一节):
|
|
51
|
+
|
|
52
|
+
- **走 PR 的改动** → 并入 PR 顶部那份「详细实现文档」(截图版 HTML→PDF,托管到 `<项目>-docs` 私有仓库,链接置顶 PR Description)。⚠️ **它不是另起一份报告,而是那份文档里的一节**——reviewer 点一个链接就该看到全部,不该在两个链接之间来回跳。用 `/create-doc` skill:生成 HTML → 转 PDF → push 到 `<项目>-docs` 的 `docs` 分支 → 在代码仓库 `docs/index.html` 索引记录「文档名 | 链接」。交付给用户的是一行可点击的 GitHub 链接(`https://github.com/<ORG>/<项目>-docs/blob/docs/<文件名>.pdf`)。
|
|
53
|
+
- **不走 PR 的即时修复**(用户当场让你修个 bug、要立刻看结果)→ 直接给**桌面上的单文件 HTML 绝对路径**,截图 `data:image/png;base64` 内嵌,双击即开、可搜索、转发不裂图。不走私有仓库、不起本地 HTTP 服务、不用相对路径、不用 `file:///`。
|
|
54
|
+
- ⚠️ **两种形式都要求截图内嵌**,禁止用文件路径引用外部 PNG——文档会被移动、分享,外部路径一脱离原目录就全是裂图。散落的零散 PNG 应一并清理,只保留文档本身。
|
|
51
55
|
- ⚠️ 代码仓库 `docs/` 只维护索引,禁止把报告正文(HTML/PDF/截图)直接放进 `docs/`。
|
|
52
56
|
- **报告骨架**(每个验证点必须有):
|
|
53
57
|
1. **结论卡**:本次改动改了什么、验证结果是对是错、用户确认没有
|