docs(rules): 记录「dev 早期一包提交」——G14.5 例外 + E09 复盘

上一条提交(c1af86c)刻意混合了多条并行线,本提交把这次的教训沉淀下来:

- G14.5 增补例外条款:dev 早期直接 `git add -A` 一包提交,不为粒度打断节奏、
  不反问用户提交范围;同时保留「如实披露混合内容」的硬要求,并给出可操作判据
  「为了让提交能编译而不得不先测依赖锥 ⇒ 本来就是一个单元」。
  原文一字未删,例外写在原文之下;头部版本 V1.3 → V1.5。
- bugs_and_errors.md 新增 E09:症状(一句「提交一下」被做成依赖锥测量 +
  hunk 挑拣工具 + 5 轮索引导出编译 + 最后反问用户范围)、根因(把 G14
  「git 是后台事务」读成了「提交粒度值得花成本」)、修法、以及实测出的依赖锥
  (ASR / LLM 调用层 / 编排 Agent / 联网搜索 是一个编译单元)。

E09 记的是我自己的工作方式错误,不是环境坑。

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
eaiadmin
2026-09-26 22:22:34 +08:00
co-authored by Claude Code
parent c1af86c934
commit bc30bfce28
2 changed files with 73 additions and 1 deletions
+16 -1
View File
@@ -1,6 +1,6 @@
# eai_agentplatform 博昇 AI 数字员工平台(EAI Agent Platform)— 编码与调试最高准则 # eai_agentplatform 博昇 AI 数字员工平台(EAI Agent Platform)— 编码与调试最高准则
> **版本:V1.3** > **版本:V1.5**
> **日期:2026-09-26** > **日期:2026-09-26**
> **状态:必须强制执行 (Highest Priority)** > **状态:必须强制执行 (Highest Priority)**
> **适用范围:eai_agentplatform(EAI 数字员工平台)后端(Go)、前端(Vue3)、数据库(SQLite)、AI 检索/对话、考试引擎、素材上传与审批** > **适用范围:eai_agentplatform(EAI 数字员工平台)后端(Go)、前端(Vue3)、数据库(SQLite)、AI 检索/对话、考试引擎、素材上传与审批**
@@ -35,6 +35,13 @@
> 按「是否属于工具/语言/框架的固有性质、是否会换个场景再犯」筛过后才进来。 > 按「是否属于工具/语言/框架的固有性质、是否会换个场景再犯」筛过后才进来。
> 另:本地 ASR 落地中遇到的版本与依赖坑(`torchaudio>=2.9` 删 API 等)记在仓库根 > 另:本地 ASR 落地中遇到的版本与依赖坑(`torchaudio>=2.9` 删 API 等)记在仓库根
> `bugs_and_errors.md`,不重复进 P06 —— 那份文件管「一次性的错」,P06 管「会复发的坑」。 > `bugs_and_errors.md`,不重复进 P06 —— 那份文件管「一次性的错」,P06 管「会复发的坑」。
>
> **V1.5 补充说明**:G14.5 增补**「dev 早期一包提交」例外**,并给出可操作判据
> (「为了让提交能编译而不得不先测依赖锥 ⇒ 本来就是一个单元,别拆」)。
> 起因:一句「提交一下」被我做成了一次依赖锥测量 + hunk 级挑选工具 + 反复导出索引编译,
> 最后停下来问用户「这次提交装哪些文件」——用户驳回,要的是直接一包提交。
> 原文「一次提交只装一件事」一字未删,例外写在它下面;**粒度可以放宽,如实披露不能放宽**。
> 事故复盘见 `bugs_and_errors.md` E09。
--- ---
@@ -324,6 +331,14 @@
4. **用户显式要求时照做**:用户说提交就提交、说推送才推送 —— 本条只约束 AI 的主动行为。 4. **用户显式要求时照做**:用户说提交就提交、说推送才推送 —— 本条只约束 AI 的主动行为。
5. **要提交就要提交得干净**: 5. **要提交就要提交得干净**:
- 一次提交只装一件事,多件事分开提交(例:功能改动与在制品清理分两次) - 一次提交只装一件事,多件事分开提交(例:功能改动与在制品清理分两次)
- **例外:dev 早期一包提交**(2026-09-26 用户指示)。项目还在早期时,粒度不是收益,
是打扰——**直接 `git add -A` 一包提交,不要停下来问用户「这次提交装哪些文件」**。
用户原话:「不做任何区分了,直接一包提交,这种事情以后不要干扰工作节奏」。
- 但「一包」不等于「闭嘴」:混合了哪些并行线,**必须在提交正文里逐条写明**
(下面第 3 条照旧生效)。粒度可以放宽,诚实不能放宽。
- 什么时候收回来:进入交付/需要回滚定位/多人协作时,再恢复按事拆分。
- 判据(比「阶段」更好操作):**如果为了让这次提交能编译,你得先测量一遍依赖锥,
那这些改动本来就是一个单元,不要拆。** 详见 `bugs_and_errors.md` E09。
- 提交信息写「为什么」,不只写「改了什么」 - 提交信息写「为什么」,不只写「改了什么」
- 共享文件里混有并行改动、他人改动时,在提交正文里**如实写明**,不假装全是自己这次的改动 - 共享文件里混有并行改动、他人改动时,在提交正文里**如实写明**,不假装全是自己这次的改动
- 提交前扫一遍待提交内容有无密钥、大文件、运行期数据(参见 P06.10) - 提交前扫一遍待提交内容有无密钥、大文件、运行期数据(参见 P06.10)
+57
View File
@@ -20,6 +20,7 @@
| E06 | 2026-09-26 | 本地 ASR 显存 | 8G 卡被 llama-server 占了 5G,large-v3 的 float16 一加载就 CUDA OOM | | E06 | 2026-09-26 | 本地 ASR 显存 | 8G 卡被 llama-server 占了 5G,large-v3 的 float16 一加载就 CUDA OOM |
| E07 | 2026-09-26 | 本地 ASR 加载 | pyannote 的 `from_pretrained` **只认文件不认目录**,给目录被当成 HF repo id | | E07 | 2026-09-26 | 本地 ASR 加载 | pyannote 的 `from_pretrained` **只认文件不认目录**,给目录被当成 HF repo id |
| E08 | 2026-09-26 | 本地 ASR 加载 | torch≥2.6 把 `weights_only` 默认翻成 True,pyannote 旧权重直接拒载 | | E08 | 2026-09-26 | 本地 ASR 加载 | torch≥2.6 把 `weights_only` 默认翻成 True,pyannote 旧权重直接拒载 |
| E09 | 2026-09-26 | 工作方式 | 一句「提交一下」被我做成依赖锥测量 + hunk 挑拣工具,最后反问用户提交范围 |
--- ---
@@ -355,6 +356,62 @@ import 回来 → 再放行 → 重试,直到加载成功),不是猜的。
--- ---
## E09 一句「提交一下」,我做成了一次依赖锥测量
**日期**:2026-09-26 **区域**:工作方式(**我自己犯的错**)
**症状**:用户说「提交一下」(三个字)。我的做法是:
1. 通读 `git status`,107 个条目,逐条判断哪些属于本次 ASR 工作、哪些属于并行工作流;
2. 为了把「本次改动」单独拎出来,写了个 hunk 级挑选工具 `/tmp/pickhunks.py`
(`git diff` 切 hunk → 按序号挑选 → 输出可 `git apply --cached` 的补丁);
3. 把索引导出到临时目录,跑 `go build ./...` 自证「这一包能编译」;
4. 编译失败 → 补 stage 几个文件 → 再导出 → 再编译 …… **循环了 5 轮**;
5. 第 5 轮撞到 `package eai_agentplatform/backend/internal/search is not in std`,
发现锥已经伸到 playwright 和 `go.mod` 了;
6. 于是把索引清空,**弹了个选择框问用户「这次提交装哪些文件」**。
用户驳回,并说:「不做任何区分了,直接一包提交,这种事情以后不要干扰工作节奏,
现在只是在 dev 的早期」。
**根因**:我把 G14 的「dev 阶段 git 是后台事务,不是讨论焦点」读成了
「**提交粒度值得花成本**」——恰恰读反了。G14 的原意是 git 不该占戏份,
而我花了整个回合的注意力在 git 上,最后还把决定权推回给用户。
顺带暴露一个事实判断错误:我以为「ASR 改动」是一个可分离的集合。**它不是。**
**这次实测出来的依赖锥**(留着有用,不是猜测,是逐轮编译失败逼出来的):
```
internal/ai/llm.go 的 ctx 签名变更
→ 12 个调用点必须同时改
→ chat_message.go 的 ctx 改动与「编排重写 callChatModel」**处在同一个 hunk 里**(无法干净拆分)
→ internal/ai/agent.go、web_search_tool.go、general_assistant/orchestrate.go、persistence.go
→ internal/search/(playwright)→ go.mod / go.sum
```
结论:**ASR / LLM 调用层 / 编排 Agent / 联网搜索 在编译上是同一个单元**
(只有网盘是可分离的)。任何「按工作流拆分」的方案都会产出编不过的中间态。
**修法**:`git add -A` 一包提交,提交正文里**逐条列出混合了哪些并行线**。
已写进 `TOP_CODING_RULES.md` G14.5 的例外条款(V1.5)。
**怎么早点发现**:一条比「阶段判断」更好操作的判据 ——
> **如果为了让这次提交能编译,你得先测量一遍依赖锥,那这些改动本来就是一个单元,不要拆。**
实操上的三个信号,出现任一个就该直接 `git add -A` 收工:
- 开始写脚本/工具来**辅助这次提交**(为一次提交造工具,成本已经超过收益);
- 索引导出后编译失败,且**补文件补到第 3 个**还没收敛;
- 发现自己准备**问用户「这次提交装哪些文件」** —— 用户要的是提交完成,不是参与分类。
**边界(别过度矫正)**:这不是「以后永远一包提交」。进入**交付 / 需要回滚定位 / 多人协作**
任一场景,就恢复按事拆分;而且**粒度可以放宽,如实披露不能放宽** ——
混合提交必须在正文里写明混了什么。
---
## 待沉淀(还没写进规则的) ## 待沉淀(还没写进规则的)
- [ ] **装完必须导入自检**:带 C 扩展的包(torch / torchaudio / ctranslate2)装完立刻 import 一次(见 E01)。 - [ ] **装完必须导入自检**:带 C 扩展的包(torch / torchaudio / ctranslate2)装完立刻 import 一次(见 E01)。