From 00110500a7ab5b3a1a8bdf43638fa6411f3f7a5e Mon Sep 17 00:00:00 2001 From: maogeigei Date: Thu, 8 Oct 2026 23:10:12 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AB=8B=E3=80=8C=E6=94=B9=E5=8C=85=E7=BA=AA?= =?UTF-8?q?=E5=BE=8B=E3=80=8D=EF=BC=9A=E6=8A=8A=202026-10-08=20=E6=95=B4?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=A6=86=E7=9B=96=E4=BA=8B=E6=95=85=E7=9A=84?= =?UTF-8?q?=E9=98=B2=E7=BA=BF=E5=86=99=E8=BF=9B=E4=BB=93=E6=A0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户令「按照建议处理」。背景:2026-10-08 22:22 那次「说人话新稿按合并落地」实际是整文件覆盖, 抹掉了晚于新稿编写时点的全部改动(单一可信源声明 5→1、`## 供给` 块与六行表、供给口径翻转、 runbook §7 两条勾选项),并让闸门多出 12 条 FAIL。 四条硬纪律: 1、⛔ 不许整文件覆盖 —— 新稿是「改动意图」,逐节比对当前内容再落,宁可分多次小提交 2、落地前先比对时点 —— 新稿编写时点 vs 目标文件的最新修改时点,被改过就必须逐节比对 3、改完必跑闸门 —— `--ws` 必带、不许带 FAIL 提交;⛔ 但也别只看闸门绿(它查不出结构被删) 4、收到覆盖性提交先做结构体检 —— 拿「唯一权威处」这类结构标记的计数与上次收口版比 另附出事后的标准修法:先定性(两版本各跑一次闸门的可复现对比)/⛔ 别在被覆盖的基线上逐项修补/ 先存档再回退(对照 diff + 全文快照 + 说明)/回退后立刻提交推送。 --- 改包纪律.md | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 改包纪律.md diff --git a/改包纪律.md b/改包纪律.md new file mode 100644 index 0000000..76ded8b --- /dev/null +++ b/改包纪律.md @@ -0,0 +1,100 @@ +# 改包纪律(多会话共写 · 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 "唯一权威处" -- 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、**回退后立刻提交推送**,并把体检结果写进提交信息。⛔ 别攒着 —— 攒着就会被下一次覆盖顺手带走。 + +## 四、一句话 + +**新稿是意图,不是内容。落地 = 把意图逐节落到当前版本上,⛔ 不是把文件换掉。**