Files
workbuddy_skills/改包纪律.md
T
admin 00110500a7 立「改包纪律」:把 2026-10-08 整文件覆盖事故的防线写进仓根
用户令「按照建议处理」。背景:2026-10-08 22:22 那次「说人话新稿按合并落地」实际是整文件覆盖,
抹掉了晚于新稿编写时点的全部改动(单一可信源声明 5→1、`## 供给` 块与六行表、供给口径翻转、
runbook §7 两条勾选项),并让闸门多出 12 条 FAIL。

四条硬纪律:
1、⛔ 不许整文件覆盖 —— 新稿是「改动意图」,逐节比对当前内容再落,宁可分多次小提交
2、落地前先比对时点 —— 新稿编写时点 vs 目标文件的最新修改时点,被改过就必须逐节比对
3、改完必跑闸门 —— `--ws` 必带、不许带 FAIL 提交;⛔ 但也别只看闸门绿(它查不出结构被删)
4、收到覆盖性提交先做结构体检 —— 拿「唯一权威处」这类结构标记的计数与上次收口版比

另附出事后的标准修法:先定性(两版本各跑一次闸门的可复现对比)/⛔ 别在被覆盖的基线上逐项修补/
先存档再回退(对照 diff + 全文快照 + 说明)/回退后立刻提交推送。
2026-10-08 23:10:12 +08:00

101 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 改包纪律(多会话共写 · 2026-10-08 立)
> 本仓被多个会话同时写,推进以分钟计。这份文件是把 2026-10-08 那次真事故的防线写下来 —— 谁来这个仓干活,先读这一份。
## 一、为什么立这一份
2026-10-08 22:22,一个会话把「说人话新稿」落地到 `product-planning`,**整文件覆盖**了 7 个文件。那份新稿是**基于较早版本**写的,于是**晚于新稿编写时点的改动全被抹掉**:
1、**「单一可信源」类声明 5 处 → 1 处**。最重的一处是 `references/stage-delivery/SKILL.md` 的 `## 供给(唯一权威处 · 改供给只改这一块)` —— 整节标题连同六行供给表一起被换成了另一种三列表。
2、**供给口径被翻转**。用户定案是「默认主线 = `oil-ui-pro`(基础层),`open-design` 只是随段携带的**可选件**、选了才用」;覆盖版写成了「`open-design` = 本段默认主线」。
3、`references/stage-delivery/references/execution-runbook.md` §7 完成标准**丢了两条勾选项**(「供给能力边界已核对」、「页型已判…每条都要附取值记录」)。
4、`3c` 子步名被改成「会诊」,但**没同步** `scripts/check_naming.py` 的 `STAGES` 表 ⇒ 直接报 FAIL。
5、**9 条「复述」类 FAIL 与 2 条废路径(`strategy/`、`ux/`)重新长回来** —— 权威声明一被削弱,复述就不再被视为违规。
⚠️ 当时提交信息写的是「按**合并**落地」,实际效果是覆盖。这**不是恶意,是流程缺陷**:新稿的编写时点早于被覆盖文件的修改时点,落地时不做三方比对,就必然丢东西。
## 二、四条硬纪律
### 1、⛔ 不许整文件覆盖
落地「新稿 / 改版 / 批量替换」时,⛔ 不许把手上那份稿子直接盖到目标文件上。
✅ 正确做法:把新稿当**改动意图**,逐节与目标文件的**当前内容**比对,只把有意的改写落进去,其余保持原样。宁可分多次小提交,也不要一次整文件替换。
### 2、落地前先比对时点
先回答两个问题,答不出来就别落:
1、这份新稿是什么时候写的?依据的是哪个版本的包?
2、目标文件自那以后被改过吗?`git log --oneline <新稿编写时点>..HEAD -- <目标路径>`
只要第 2 问的答案是「改过」,就**必须逐节比对**,⛔ 不许直接覆盖。
### 3、改完必跑闸门
`product-planning` 包改完,必跑:
```
cd E:/ProgramData/.workbuddy/skills/product-planning
E:/ProgramData/.workbuddy/binaries/python/versions/3.13.12/python.exe scripts/check_naming.py --root . --ws "<工作区绝对路径>"
```
- ⚠️ `--ws` **必带**(不带则找不到含 `docs/pm` 的那一层,会整包 FAIL)
- 期望 `失败 0`;有 FAIL 就修完再提交,⛔ 不许带 FAIL 提交
- ⛔ 但也别只看闸门绿不绿 —— 闸门查的是**命名一致性**,查不出「结构被删」这类损失(见第 4 条)
### 4、收到「覆盖性」提交后,先做结构体检
闸门绿 ≠ 没丢东西。覆盖性提交的典型特征:要么报一堆复述类 FAIL,要么因为权威处被一起删而集体失效。
体检方法(**比看闸门更早跑**):
```
cd E:/ProgramData/.workbuddy/skills
git grep -c "唯一权威处" <rev> -- product-planning
git log --oneline -3 -- product-planning
git diff --stat <上次收口提交> HEAD -- product-planning
```
拿「唯一权威处」这类**结构标记的计数**与上次收口版本比。计数掉了 ⇒ 先查结构,再看内容。
## 三、出事后怎么修(照 2026-10-08 那次的流程)
1、**先定性,别急着改**。用可复现的方式坐实「是谁引入的」:
```
cd E:/ProgramData/.workbuddy/skills
for c in <上次收口提交> <可疑提交>; do
rm -rf /tmp/pp-$c && mkdir -p /tmp/pp-$c
git archive $c product-planning | tar -x -C /tmp/pp-$c
printf "=== %s ===\n" "$c"
(cd /tmp/pp-$c/product-planning && \
E:/ProgramData/.workbuddy/binaries/python/versions/3.13.12/python.exe \
scripts/check_naming.py --root . --ws "<工作区绝对路径>" 2>&1 | tail -2)
done
```
两个版本各跑一次,`全过 / 失败 N` 的对比就是铁证。
2、**⛔ 不要在当前(被覆盖的)版本上逐项修补**。基线本身是错的,补得越多越像在旧稿上刷漆。
3、**回退**:`git checkout <上次收口提交> -- product-planning/`(只重置该包,⛔ 不碰别人正在改的文件)
4、**先存档再回退**。覆盖版里若有值得保留的内容(措辞改写之类),⛔ 不许无痕丢掉:
- 导 `git diff <上次收口提交> <覆盖提交> -- product-planning` 作对照
- 导覆盖版的全文快照
- 写一份说明,讲清「哪些能采纳、哪些不能」,结构损坏项必须逐条列出
- 参考实例:工作区 `归档/技能包-说人话改写-被覆盖存档-20261008/`
5、**回退后立刻提交推送**,并把体检结果写进提交信息。⛔ 别攒着 —— 攒着就会被下一次覆盖顺手带走。
## 四、一句话
**新稿是意图,不是内容。落地 = 把意图逐节落到当前版本上,⛔ 不是把文件换掉。**