@routerhub/agent-rules 1.5.204 → 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 +37 -1
- package/CHANGELOG.md +14 -0
- package/PULL_REQUEST_TEMPLATE.md +27 -1
- package/package.json +1 -1
- package/rules/global.md +37 -1
- package/skills/create-pr/SKILL.md +3 -2
- package/skills/forensic-report/SKILL.md +248 -0
- package/skills/real-chain-verify/SKILL.md +1 -0
- package/skills/visual-report/SKILL.md +6 -2
package/AGENTS.base.md
CHANGED
|
@@ -142,10 +142,15 @@ agent-rules 生成的规则文件分两层,行为与归属不同,评审/发
|
|
|
142
142
|
1. **环境与版本**:哪个环境(生产 / 测试 / 本地)、哪个 commit 或 revision、用哪个账号 / 哪条数据(具体到 ID);
|
|
143
143
|
2. **可被别人照着做的操作步骤**:点哪个按钮、发哪条请求(参数写全,禁止用 `...` 省略)、按什么顺序——**标准是别人拿到这几行就能一步步重演**,而不是只有你自己看得懂;
|
|
144
144
|
3. **观测到的坏现象**:报错原文、HTTP 状态码、日志片段、页面截图,带时间戳或 request id 之类可复查的标识。**「有时候会出问题」「偶尔失败」不合格——必须能指出出问题的是哪一次。**
|
|
145
|
+
- ⚠️ **这三要素的载体是下面那条「逐步截图 + 箭头标注」的可视化文档,不是三段纯文字**——文字是索引,截图才是能让别人跟着走一遍的东西。
|
|
145
146
|
- ⚠️ **复现步骤与修复后的验证步骤必须是同一套——这是 A/B 对照能成立的唯一前提。** 同一条路径跑两遍:第一遍看到坏现象(A = 改动前),第二遍看到好现象(B = 改动后),两者之间只差你这次改动,这才证明了「是这个改动修好的」。两次走的路径不一样 = 没对照(详见「⚠️ 修复验证铁律」)。
|
|
146
147
|
- ⚠️ **复现不出来 → 停下来回到描述方对口径,禁止「复现不出来那我按理解先改」。** 按描述的步骤复现不出来,说明「问题到底是什么」这件事本身还没对齐:可能理解错了现象、可能真正的触发入口是另一个、可能已经被别的改动修掉、可能环境或数据形态不同。此时正确动作是带着证据回去对齐——**「我按你说的步骤做了,看到的是 X 而不是 Y,能不能确认下当时的环境 / 账号 / 时间点」**——而不是照着自己想象改一遍交差。按想象改的后果:改动与真问题无关,PR 里却写着「已修复」,等用户再碰到时,这一轮排查和后面所有 review 全部白费。
|
|
147
148
|
- ⚠️ **复现要用真实触发场景的数据和路径,禁止自己造一个顺手能触发的输入。** 造出来的输入只能复现你想象的那个问题,不是用户真实碰到的那个——真实数据的边界形态(空值、超长文本、特殊字符、异常关联、旧状态记录)恰恰是问题的来源(呼应「⚠️ 验证功能是否修复时,要用真实存在的数据/路径去测试」)。
|
|
148
|
-
- ⚠️
|
|
149
|
+
- ⚠️ **复现的交付物必须是「逐步截图 + 箭头标注」的可视化文档,不能只是一串文字步骤。** 文字步骤只说得清「点了什么」,说不清「点在哪、界面长什么样、坏现象出现在屏幕哪个位置」——看的人得自己在心里拼图,拼错了就以为复现不出来,或者以为自己复现的是另一回事。正确做法:**每一步一张截图,图上用箭头 + 短标签标出「这一步点哪里 / 填什么 / 坏现象出现在哪」**,让人照着走一遍就等于把 bug 亲手复现了一次。
|
|
150
|
+
- ⚠️ **落点:PR 顶部那份「详细实现文档」(截图版 HTML→PDF,见 `/create-pr` 步骤 5)里必须有「复现步骤」一节**,按步骤编号排开截图;PR 描述里的「缺陷复现」栏目放三要素摘要 + 指向该节的链接。**禁止只在 PR 里贴一段文字步骤就算交差。**
|
|
151
|
+
- ⚠️ **纯后端 / 无界面的 bug(接口、定时任务、数据链路等)同样要可视化**:把每一步的 curl 请求与响应渲染成暗色终端风格截图(带上请求 ID、时间戳),坏现象那一步单独放大标注——而不是贴一段文字日志。(取证方式见「非 UI / 后端 / 基础设施改动的效果截图获取方法」)
|
|
152
|
+
- ⚠️ **复现截图必须在「改代码之前」当场拍下并存盘**(遵循「⚠️ 截图规范」:浏览器真实视口、`fullPage` 全页、URL 可见、存到临时目录),不能等改完再写文档时回头补——那时代码已经变了,补出来的不是复现。箭头标注统一走 `/screenshot-annotate` skill(坐标由 `getBoundingClientRect()` 换算,禁止肉眼看图估位)。
|
|
153
|
+
- ⚠️ **复现证据必须写进 PR(PR 模板已内置「缺陷复现」栏目),不写等于没复现。** 这一栏是给 reviewer 看的:他据此判断「这个改动确实是对着这个现象去的」,也能照着那份可视化文档自己重跑一遍确认修好了。只有作者本机跑过一次、PR 里一个字没有 = 这一环做了也没人知道。
|
|
149
154
|
- **类比:看病。医生不会听你说一句「我头疼」就直接开止痛药——先做检查(复现)确认到底是什么病、是不是这个病,拿到检查报告(证据),再开药(改代码)。检查下来一切正常,那说明你说的「头疼」可能不是你以为的那个原因,得回去问清楚,而不是照着头疼开药;照着症状开药,病没治好,还耽误了真病因。**
|
|
150
155
|
- ⚠️ **与相邻铁律的分工**:本铁律管「改之前证明问题存在」;「⚠️ 修复验证铁律」管「改之后证明问题消失」;「⚠️ 跨系统真实链路验收铁律」管「整条链路成不成立」。三者是**同一条路径**在时间轴上不同位置各跑一次:复现(改前)→ 复验(改后)→ 链路验收(上线前整条链路)。
|
|
151
156
|
- ⚠️ **例外(可以不先复现的只有这几类,除此之外一律先复现)**:① 本次不是修 bug 的改动(新增功能、重构、文案、依赖升级);② 问题现象本身已带完整证据(用户给的截图里有报错原文 + 时间戳 + 账号,等同于已复现——此时仍需按上面三要素把它整理成「可重演步骤」写进 PR);③ 用户明确说「不用复现,直接改」——按用户指令执行,但交付时必须说明本次跳过了复现。
|
|
@@ -244,6 +249,36 @@ agent-rules 生成的规则文件分两层,行为与归属不同,评审/发
|
|
|
244
249
|
- ⚠️ **不命中触发条件的改动,两段都不走**(纯文案、纯展示类改动不受影响)。
|
|
245
250
|
- ⚠️ **具体操作流程见 `/real-chain-verify` skill**(怎么画链路、每类系统怎么取证、两段各自做到什么程度、证据怎么组织成报告)。
|
|
246
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
|
+
|
|
247
282
|
## Git 规范
|
|
248
283
|
|
|
249
284
|
- 分支用 Git Flow(`feature/`、`bugfix/`、`hotfix/`、`refactor/`、`chore/`、`docs/`、`test/`),英文小写中划线分隔。
|
|
@@ -740,6 +775,7 @@ agent-rules 生成的规则文件分两层,行为与归属不同,评审/发
|
|
|
740
775
|
|
|
741
776
|
- ⚠️ **日常对话中,只要聊到写代码/改代码/排查问题/验证功能/实现需求等任何越过「闲聊」的实质内容,就自动触发 `/visual-report` skill,用它管理「验证证据」的产出**,无需用户额外吩咐。触发不依赖于用户正式说「提需求」「做功能」——用户在平常对话里随口提到的开发任务(如「这个页面的按钮没反应」「Redis 里这个 key 好像不对」「帮我把这个查询优化一下」)同样自动触发。该 skill 的职责是:真实数据 + 真实交互 + 可视化证据(页面截图 / Redis 截图 / 数据库截图),把「功能对不对」用用户能一眼看懂的截图和报告证明给用户看。
|
|
742
777
|
- ⚠️ **只有用户显式提到「测试 / TDD / 测试用例」时,才调用 `/tdd-workflow` skill**(写测试用例、跑回归)。没有明确指令时,禁止把 TDD 当作默认开发流程;默认开发流程是上面的 `/visual-report`。
|
|
778
|
+
- ⚠️ **`/visual-report` 证明「功能对不对」,`/forensic-report` 证明「副作用有没有失控」——两者在同一次交付里都要有,缺一不算完成。** 任何需求实现 / bug 修复,除功能生效证据外,必须自动触发 `/forensic-report` skill 产出取证报告(证明「该变的变了 + 不该动的一行没动」,证据强度按改动类型自动分级、交付形式按是否走 PR 分流)。**「功能验证过了」不能替代取证**:页面全绿、接口全 200,都不代表没有别的数据被静默带走。
|
|
743
779
|
|
|
744
780
|
## 🚨 agent-browser 标签页防串扰(所有项目通用)
|
|
745
781
|
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
所有对 @routerhub/agent-rules 的重大更改都会记录在这个文件中。
|
|
4
4
|
|
|
5
|
+
## [1.5.205] - 2026-09-10
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **「缺陷复现铁律」补齐可视化交付要求(原文只要求文字步骤,落地成了「一串文字 + 自己脑补界面」)**:发版后发现 1.5.204 的规则只说「把复现过程详写进 PR 描述」,没规定交付形态,结果是一段文字步骤——而**文字只说得清「点了什么」,说不清「点在哪、界面长什么样、坏现象出现在屏幕哪个位置」**,看的人得自己在心里拼图,拼错了就会以为「复现不出来」或以为自己复现的是另一回事。现在明确:**复现的交付物必须是「逐步截图 + 箭头标注」的可视化走查**——每一步一张截图,图上用箭头 + 短标签标出「这一步点哪里 / 填什么 / 坏现象出现在哪」,让人照着走一遍就等于把 bug 亲手复现了一次。
|
|
10
|
+
- **落点**:PR 顶部那份「详细实现文档」(截图版 HTML→PDF)里新增「复现步骤」一节承载完整走查;PR 描述里的「缺陷复现」栏目改为「三要素摘要 + 指向该节的链接」。**禁止只在 PR 里贴一段文字步骤就算交差。**
|
|
11
|
+
- **纯后端 / 无界面的 bug 同样要可视化**:每一步的 curl 请求与响应渲染成暗色终端风格截图(带请求 ID、时间戳),坏现象那一步单独放大标注,而不是贴一段文字日志。
|
|
12
|
+
- **复现截图必须在「改代码之前」当场拍下并存盘**:改完代码已经变了,回头补出来的不是复现;箭头标注统一走 `screenshot-annotate` skill(坐标由 `getBoundingClientRect()` 换算,禁止肉眼看图估位)。
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **PR 模板「缺陷复现」栏目的「① 复现证据」新增「逐步截图走查(必填,附链接)」项**,置于环境版本之前——先给可视化走查的入口,再给文字摘要。
|
|
17
|
+
- **`create-pr` skill**:详细实现文档的适用范围从「至少覆盖三部分」扩为「**修 bug / 修故障的 PR 还必须多一部分『复现步骤』**」(逐步截图 + 箭头标注,后端 bug 用终端风格截图),并明确这些截图必须来自改代码之前的复现、不是改完回头补的。
|
|
18
|
+
|
|
5
19
|
## [1.5.204] - 2026-09-10
|
|
6
20
|
|
|
7
21
|
### Added
|
package/PULL_REQUEST_TEMPLATE.md
CHANGED
|
@@ -11,12 +11,15 @@ Closes #
|
|
|
11
11
|
|
|
12
12
|
<!-- 仅「修 bug / 修故障 / 修线上异常」的 PR 需要填(新增功能、重构、文案、依赖升级直接勾豁免项)。
|
|
13
13
|
依据 AGENTS.base.md「⚠️ 缺陷复现铁律」:必须先复现、留证、写下来,再动手改。
|
|
14
|
-
⚠️ 复现必须在【改动前的代码】上做(线上/测试环境当前版本,或打补丁前的 commit),改完再补的「复现」不算。
|
|
14
|
+
⚠️ 复现必须在【改动前的代码】上做(线上/测试环境当前版本,或打补丁前的 commit),改完再补的「复现」不算。
|
|
15
|
+
⚠️ 本栏目是「摘要 + 链接」:完整的逐步截图走查放在 PR 顶部那份「详细实现文档」的「复现步骤」一节里。 -->
|
|
15
16
|
|
|
16
17
|
- [ ] 本次 PR **不是**修 bug(新增功能 / 重构 / 文案 / 依赖升级),无需缺陷复现
|
|
17
18
|
|
|
18
19
|
**① 复现证据(改动前的代码上跑出来的)**
|
|
19
20
|
|
|
21
|
+
- **逐步截图走查(必填)**:详细实现文档「复现步骤」一节 → `<链接>`
|
|
22
|
+
- ⚠️ 必须**每一步一张截图 + 箭头标注**(标出「点哪里 / 填什么 / 坏现象在哪」),不是一串文字步骤;纯后端 bug 用暗色终端风格的请求响应截图。
|
|
20
23
|
- **环境与版本**:<环境(生产/测试/本地) + commit 或 revision + 账号 / 数据 ID>
|
|
21
24
|
- **操作步骤**(别人照着能一步步重演,禁止省略参数):
|
|
22
25
|
1.
|
|
@@ -54,6 +57,28 @@ Closes #
|
|
|
54
57
|
- ❌「门户页面显示 Active」 ✅「网关 `/v1/models` 里精确出现了这个模型」
|
|
55
58
|
- **默认值类字段与存量数据对照**(命中触发条件 2 时必填):默认值 → 下游消费规则 → 线上存量数据 → 叠加效果
|
|
56
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
|
+
|
|
57
82
|
## Test Plan
|
|
58
83
|
|
|
59
84
|
<!-- 硬性必填:如何验证改动正确,附可复现步骤或证据(命令 + 结果、手动操作步骤、日志、请求响应、修复前后对比)。 -->
|
|
@@ -71,6 +96,7 @@ Closes #
|
|
|
71
96
|
- [ ] Test Plan 完整且带证据
|
|
72
97
|
- [ ] 修 bug 的 PR 已按「缺陷复现」栏目写下改动前的复现证据(非修 bug 的已勾选豁免项)
|
|
73
98
|
- [ ] 跨系统链路验收已按上方栏目填完(未命中触发条件则勾选豁免项)
|
|
99
|
+
- [ ] 已按「取证报告」栏目给出取证数据(或勾选一层豁免项)
|
|
74
100
|
- [ ] UI 改动已贴截图(或注明无界面变化)
|
|
75
101
|
- [ ] 本地编译 / lint / 测试通过,CI 全绿
|
|
76
102
|
- [ ] 已关联 issue、指定 reviewer
|
package/package.json
CHANGED
package/rules/global.md
CHANGED
|
@@ -142,10 +142,15 @@ agent-rules 生成的规则文件分两层,行为与归属不同,评审/发
|
|
|
142
142
|
1. **环境与版本**:哪个环境(生产 / 测试 / 本地)、哪个 commit 或 revision、用哪个账号 / 哪条数据(具体到 ID);
|
|
143
143
|
2. **可被别人照着做的操作步骤**:点哪个按钮、发哪条请求(参数写全,禁止用 `...` 省略)、按什么顺序——**标准是别人拿到这几行就能一步步重演**,而不是只有你自己看得懂;
|
|
144
144
|
3. **观测到的坏现象**:报错原文、HTTP 状态码、日志片段、页面截图,带时间戳或 request id 之类可复查的标识。**「有时候会出问题」「偶尔失败」不合格——必须能指出出问题的是哪一次。**
|
|
145
|
+
- ⚠️ **这三要素的载体是下面那条「逐步截图 + 箭头标注」的可视化文档,不是三段纯文字**——文字是索引,截图才是能让别人跟着走一遍的东西。
|
|
145
146
|
- ⚠️ **复现步骤与修复后的验证步骤必须是同一套——这是 A/B 对照能成立的唯一前提。** 同一条路径跑两遍:第一遍看到坏现象(A = 改动前),第二遍看到好现象(B = 改动后),两者之间只差你这次改动,这才证明了「是这个改动修好的」。两次走的路径不一样 = 没对照(详见「⚠️ 修复验证铁律」)。
|
|
146
147
|
- ⚠️ **复现不出来 → 停下来回到描述方对口径,禁止「复现不出来那我按理解先改」。** 按描述的步骤复现不出来,说明「问题到底是什么」这件事本身还没对齐:可能理解错了现象、可能真正的触发入口是另一个、可能已经被别的改动修掉、可能环境或数据形态不同。此时正确动作是带着证据回去对齐——**「我按你说的步骤做了,看到的是 X 而不是 Y,能不能确认下当时的环境 / 账号 / 时间点」**——而不是照着自己想象改一遍交差。按想象改的后果:改动与真问题无关,PR 里却写着「已修复」,等用户再碰到时,这一轮排查和后面所有 review 全部白费。
|
|
147
148
|
- ⚠️ **复现要用真实触发场景的数据和路径,禁止自己造一个顺手能触发的输入。** 造出来的输入只能复现你想象的那个问题,不是用户真实碰到的那个——真实数据的边界形态(空值、超长文本、特殊字符、异常关联、旧状态记录)恰恰是问题的来源(呼应「⚠️ 验证功能是否修复时,要用真实存在的数据/路径去测试」)。
|
|
148
|
-
- ⚠️
|
|
149
|
+
- ⚠️ **复现的交付物必须是「逐步截图 + 箭头标注」的可视化文档,不能只是一串文字步骤。** 文字步骤只说得清「点了什么」,说不清「点在哪、界面长什么样、坏现象出现在屏幕哪个位置」——看的人得自己在心里拼图,拼错了就以为复现不出来,或者以为自己复现的是另一回事。正确做法:**每一步一张截图,图上用箭头 + 短标签标出「这一步点哪里 / 填什么 / 坏现象出现在哪」**,让人照着走一遍就等于把 bug 亲手复现了一次。
|
|
150
|
+
- ⚠️ **落点:PR 顶部那份「详细实现文档」(截图版 HTML→PDF,见 `/create-pr` 步骤 5)里必须有「复现步骤」一节**,按步骤编号排开截图;PR 描述里的「缺陷复现」栏目放三要素摘要 + 指向该节的链接。**禁止只在 PR 里贴一段文字步骤就算交差。**
|
|
151
|
+
- ⚠️ **纯后端 / 无界面的 bug(接口、定时任务、数据链路等)同样要可视化**:把每一步的 curl 请求与响应渲染成暗色终端风格截图(带上请求 ID、时间戳),坏现象那一步单独放大标注——而不是贴一段文字日志。(取证方式见「非 UI / 后端 / 基础设施改动的效果截图获取方法」)
|
|
152
|
+
- ⚠️ **复现截图必须在「改代码之前」当场拍下并存盘**(遵循「⚠️ 截图规范」:浏览器真实视口、`fullPage` 全页、URL 可见、存到临时目录),不能等改完再写文档时回头补——那时代码已经变了,补出来的不是复现。箭头标注统一走 `/screenshot-annotate` skill(坐标由 `getBoundingClientRect()` 换算,禁止肉眼看图估位)。
|
|
153
|
+
- ⚠️ **复现证据必须写进 PR(PR 模板已内置「缺陷复现」栏目),不写等于没复现。** 这一栏是给 reviewer 看的:他据此判断「这个改动确实是对着这个现象去的」,也能照着那份可视化文档自己重跑一遍确认修好了。只有作者本机跑过一次、PR 里一个字没有 = 这一环做了也没人知道。
|
|
149
154
|
- **类比:看病。医生不会听你说一句「我头疼」就直接开止痛药——先做检查(复现)确认到底是什么病、是不是这个病,拿到检查报告(证据),再开药(改代码)。检查下来一切正常,那说明你说的「头疼」可能不是你以为的那个原因,得回去问清楚,而不是照着头疼开药;照着症状开药,病没治好,还耽误了真病因。**
|
|
150
155
|
- ⚠️ **与相邻铁律的分工**:本铁律管「改之前证明问题存在」;「⚠️ 修复验证铁律」管「改之后证明问题消失」;「⚠️ 跨系统真实链路验收铁律」管「整条链路成不成立」。三者是**同一条路径**在时间轴上不同位置各跑一次:复现(改前)→ 复验(改后)→ 链路验收(上线前整条链路)。
|
|
151
156
|
- ⚠️ **例外(可以不先复现的只有这几类,除此之外一律先复现)**:① 本次不是修 bug 的改动(新增功能、重构、文案、依赖升级);② 问题现象本身已带完整证据(用户给的截图里有报错原文 + 时间戳 + 账号,等同于已复现——此时仍需按上面三要素把它整理成「可重演步骤」写进 PR);③ 用户明确说「不用复现,直接改」——按用户指令执行,但交付时必须说明本次跳过了复现。
|
|
@@ -244,6 +249,36 @@ agent-rules 生成的规则文件分两层,行为与归属不同,评审/发
|
|
|
244
249
|
- ⚠️ **不命中触发条件的改动,两段都不走**(纯文案、纯展示类改动不受影响)。
|
|
245
250
|
- ⚠️ **具体操作流程见 `/real-chain-verify` skill**(怎么画链路、每类系统怎么取证、两段各自做到什么程度、证据怎么组织成报告)。
|
|
246
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
|
+
|
|
247
282
|
## Git 规范
|
|
248
283
|
|
|
249
284
|
- 分支用 Git Flow(`feature/`、`bugfix/`、`hotfix/`、`refactor/`、`chore/`、`docs/`、`test/`),英文小写中划线分隔。
|
|
@@ -740,6 +775,7 @@ agent-rules 生成的规则文件分两层,行为与归属不同,评审/发
|
|
|
740
775
|
|
|
741
776
|
- ⚠️ **日常对话中,只要聊到写代码/改代码/排查问题/验证功能/实现需求等任何越过「闲聊」的实质内容,就自动触发 `/visual-report` skill,用它管理「验证证据」的产出**,无需用户额外吩咐。触发不依赖于用户正式说「提需求」「做功能」——用户在平常对话里随口提到的开发任务(如「这个页面的按钮没反应」「Redis 里这个 key 好像不对」「帮我把这个查询优化一下」)同样自动触发。该 skill 的职责是:真实数据 + 真实交互 + 可视化证据(页面截图 / Redis 截图 / 数据库截图),把「功能对不对」用用户能一眼看懂的截图和报告证明给用户看。
|
|
742
777
|
- ⚠️ **只有用户显式提到「测试 / TDD / 测试用例」时,才调用 `/tdd-workflow` skill**(写测试用例、跑回归)。没有明确指令时,禁止把 TDD 当作默认开发流程;默认开发流程是上面的 `/visual-report`。
|
|
778
|
+
- ⚠️ **`/visual-report` 证明「功能对不对」,`/forensic-report` 证明「副作用有没有失控」——两者在同一次交付里都要有,缺一不算完成。** 任何需求实现 / bug 修复,除功能生效证据外,必须自动触发 `/forensic-report` skill 产出取证报告(证明「该变的变了 + 不该动的一行没动」,证据强度按改动类型自动分级、交付形式按是否走 PR 分流)。**「功能验证过了」不能替代取证**:页面全绿、接口全 200,都不代表没有别的数据被静默带走。
|
|
743
779
|
|
|
744
780
|
## 🚨 agent-browser 标签页防串扰(所有项目通用)
|
|
745
781
|
|
|
@@ -86,6 +86,7 @@ Closes #issue编号
|
|
|
86
86
|
⚠️ **每个 PR 的 Description 顶部必须附一条醒目的「详细实现文档」链接(截图版 HTML→PDF),把 PR 分成「快速浏览」与「详细展开」两层看**:PR 正文只承载 What / Why / Test Plan 精华 + 关键效果截图(几十秒看懂这次改了什么);链接指向的 PDF 承载「做了什么 + 为什么这样做 + 每一步怎么做的」完整过程,并配上带箭头标注的真实截图。想深入细节的 reviewer 点开链接即看;禁止在正文里翻流水账,也禁止只有正文、缺详细文档链接。
|
|
87
87
|
|
|
88
88
|
1. **汇总素材**:本 PR 的「改了什么 + 为什么改 + 每一步怎么改/怎么验证」,以及步骤 4 产出的全部效果截图(含修复前后对比)。
|
|
89
|
+
- ⚠️ **修 bug / 修故障的 PR,文档必须额外覆盖第四部分「复现步骤」**(依据「⚠️ 缺陷复现铁律」):把复现时按步骤拍下的截图按编号排开,**每一步一张图 + 箭头标注出「这一步点哪里 / 填什么 / 坏现象出现在哪」**,让人照着走一遍就等于亲手复现了一次。⚠️ **纯后端 / 无界面的 bug 也要可视化**:每一步的 curl 请求与响应渲染成暗色终端风格截图(带请求 ID、时间戳),坏现象那一步单独放大标注。⚠️ 这些截图必须是**改代码之前**复现时当场存下来的,不是改完之后回头补的(改完代码变了,补出来的不是复现)。禁止只在 PR 描述里贴一段文字步骤就算交差。
|
|
89
90
|
- ⚠️ **素材取材优先级:前端可视化优先,纯逻辑才退而用代码/接口图**:讲「改了什么、效果如何」时,**凡这个功能有真实前端页面承载的(如 routerhub-ui 的 admin / 用户平台等页面),必须用真实页面截图证明**——打开页面、真实数据操作、箭头标注出「这个功能在页面哪儿用、操作前后效果长什么样」,让人不写代码也能看懂;只有页面截不出来、纯后端逻辑(计费、限流、路由、数据链路等)的部分,才允许退而用代码截图 / curl 请求响应图 / 日志图代替。页面能截出来的就不许偷懒贴代码——前端可视化是最有说服力的证据,reviewer 要的是一眼看到改动效果,不是读代码猜。
|
|
90
91
|
2. **生成截图版 HTML → 转 PDF**:走 `/create-doc` skill 输出自包含 HTML——截图一律 `data:image/png;base64` 内嵌并自动加箭头标注(遵循「⚠️ 截图规范」「⚠️ HTML 文档截图与 curl 命令规范」),图文逐步说明每一步怎么做的;再经无头 Chrome 转 PDF。
|
|
91
92
|
3. **托管到私有文档仓库**:push 到该项目的 `<项目>-docs` 私有仓库 `docs` 分支(仓库名从 git remote 推导:`git@github.com:<ORG>/<项目>.git` → 文档仓库 `<ORG>/<项目>-docs`),文件名用与 PR 主题相关的英文短名。
|
|
@@ -96,7 +97,7 @@ Closes #issue编号
|
|
|
96
97
|
```
|
|
97
98
|
reviewer 建议以新标签页打开,看完细节再回 PR 正文。
|
|
98
99
|
|
|
99
|
-
**适用范围**:所有 PR
|
|
100
|
+
**适用范围**:所有 PR 一律附此链接,无例外;内容至少覆盖「改了什么、为什么改、每一步怎么改/怎么验证的」三部分。⚠️ **修 bug / 修故障的 PR 还必须有第四部分「复现步骤」**——逐步截图 + 箭头标注的复现走查(见上方第 1 点)。后续步骤 6 创建 PR 时,此链接已作为 body 第一条。
|
|
100
101
|
|
|
101
102
|
### 6. 创建 PR
|
|
102
103
|
|
|
@@ -166,6 +167,6 @@ gh pr checks <PR>
|
|
|
166
167
|
- ⚠️ 每次修改 PR 后(含创建、push 新提交、响应 review 意见)都必须做三步收尾:冲突检查 → 静态编译检查 → PR 合并后发新版本(见步骤 8)
|
|
167
168
|
- ⚠️ **创建完 PR 后必须自动走完整闭环流程(见步骤 7.5)**:创建 PR → 先做 CI 闸门检查并修复失败项 → **链路预演(命中跨系统链路验收触发条件时,在循环 review 之前先跑,只为尽早暴露需要大改的问题)** → 自动循环 review → 重新部署测试环境验证(全程截图 + 箭头标注,命中触发条件的走 `/real-chain-verify` 阶段 2)→ 确认没问题 → 发新版本,七步缺一不可,未走完不算完成
|
|
168
169
|
- ⚠️ **PR 描述里必须填「跨系统链路验收」栏目**(PR 模板已内置):命中 4 条触发条件的填链路预演链路图 + 下游真实生效证据 + 默认值对照;未命中的勾选豁免项。**留痕是给 reviewer 看的——不填等于这一环做了也没人知道。**
|
|
169
|
-
- ⚠️ **PR 描述里必须填「缺陷复现」栏目**(PR 模板已内置):修 bug / 修故障的 PR 必须填**改动前**的复现证据(环境版本 → 可重演步骤 → 坏现象 + 可复查标识)与「同一套步骤复验后坏现象消失」;非修 bug 的勾选豁免项。⚠️
|
|
170
|
+
- ⚠️ **PR 描述里必须填「缺陷复现」栏目**(PR 模板已内置):修 bug / 修故障的 PR 必须填**改动前**的复现证据(环境版本 → 可重演步骤 → 坏现象 + 可复查标识)与「同一套步骤复验后坏现象消失」;非修 bug 的勾选豁免项。⚠️ **复现的交付物是「逐步截图 + 箭头标注」的可视化走查(放在详细实现文档的「复现步骤」一节),不是一串文字步骤**——文字说不清「点在哪、界面长什么样、坏现象在屏幕哪个位置」,看的人只能自己拼图。⚠️ **动手改代码之前就要先复现并当场存图**,改完再补的不算复现。见「⚠️ 缺陷复现铁律」。
|
|
170
171
|
- ⚠️ **直接创建正式 PR(非 Draft)**:PR 创建完成即进入可评审状态,可直接交付 review,禁止先开 Draft PR、后续再手动标记 Ready for review
|
|
171
172
|
- 作者不能 Approve 自己的 PR
|
|
@@ -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. **结论卡**:本次改动改了什么、验证结果是对是错、用户确认没有
|