Files
dsh_ai1net_server/交付物/dsh技能合并方案与体检-20260928.md
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次)
- .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…),
  目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪
- .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/)
- .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*)
- .gitignore 补:备份件(*.bak-*)
- 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00

200 lines
18 KiB
Markdown
Raw Permalink 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.
# dsh-* 技能合并方案与体检报告(2026-09-28)
> **触发**:用户原话「`E:\ProgramData\.workbuddy\skills` 这里面 dsh 开头的技能太多了,把相同领域作用的技能合并,方便维护和调用」。
> **方法依据(本项目自有的,⛔ 不自创)**:技能 `dsh-knowledge-upkeep` **§9「技能集可用性体检」**(判据 = **description 区分度**)+ **§10「技能重组:主干 + 详情档」**(🔴 **是"拆"不是"并成巨文件"**;四硬约束:内容守恒 / 判据实体常驻 / 每档自包含 / 三处同步)。
> 🔴 **§9.4 铁律**:**良性撞(分工互补)⛔ 不要为了"看起来干净"去削** —— 只消「偏错一方」的恶性撞。
---
## 一、🔴 阻断项:技能「三处」**当前就是不一致的**(本报告最重要的一节)
**三处定义**(`~/.workbuddy` 记忆·仓库推送与授权 第 15 行):
① 本机 `E:\ProgramData\.workbuddy\skills\<n>\` → ② 文档库 `D:\github\dsh_shenxian\dsh-server-docs\08-skills\<n>\` → ③ 服务器 `/opt/dsh/docs/08-skills/<n>\`
**三方 md5 实测(2026-09-28 23:4x)**:
| 技能 | 本机 | 文档库 | 服务器 | 判定 |
|---|---|---|---|---|
| dsh-architecture-lifecycle | 302a | 302a | 302a | ✅ 一致 |
| dsh-decision-method | 4e18 | 4e18 | 4e18 | ✅ 一致 |
| dsh-feature-first | 95f3 | 95f3 | 95f3 | ✅ 一致 |
| dsh-instance-diagnose | 4078 | 4078 | 4078 | ✅ 一致 |
| dsh-opensource-release | e52b | e52b | e52b | ✅ 一致 |
| dsh-plugin-diagnose | 18d6 | 18d6 | 18d6 | ✅ 一致 |
| **dsh-auto-handoff-chain** | **b89c** | ea37 | a204 | 🔴 **三个版本各不相同** |
| **dsh-change-workflow** | **a408** | e70d | e70d | 🔴 本机 ≠ 另两处 |
| **dsh-desktop-dev-shell** | **9490** | 8829 | 8829 | 🔴 本机 ≠ 另两处 |
| **dsh-env-bootstrap** | **8743** | 3eb1 | 3eb1 | 🔴 本机 ≠ 另两处 |
| **dsh-knowledge-upkeep** | **72f6** | b403 | b403 | 🔴 本机 ≠ 另两处 |
| **dsh-distributed-state-readback** | **0eec** | — | — | 🔴 **只在本地,另两处从来没有过** |
**读数结论**:
- 文档库 与 服务器**逐条相同**(=最后一次同步的结果);**本机是另一套**。
- **6 / 12 不一致**;其中 `dsh-auto-handoff-chain` **三处各一个版本**(三方分叉)。
- `dsh-distributed-state-readback`(6.4 KB)**从未同步过** —— 是个漏网的。
- ⚠️ 大小关系**不是单向的**:`desktop-dev-shell`/`env-bootstrap`/`auto-handoff-chain` **本机更大**;`change-workflow`/`knowledge-upkeep` **本机更小**(很可能是**拆分后**的主干版本)⇒ **不能简单按"谁新"或"谁大"定权威**,必须逐个比对内容。
🔴 **为什么这是阻断项**:合并会把**当前这份不一致**固化进新结构,而且**有丢内容的实际风险**(例:`dsh-change-workflow` 文档库版比本机**大 3.5 KB**,合并时若只取本机版,那部分内容会消失且无人察觉)。
⇒ **合并之前必须先做「三处对账」**(逐技能确定权威版本并同步),至少要把这 6 个查清。
---
## 二、领域聚类(clinical:按 description + 章节骨架,不按感觉)
| 组 | 建议名 | 并入 | 依据 | 合计 |
|---|---|---|---|---|
| 1 | **`dsh-diagnose`** | instance-diagnose + plugin-diagnose + distributed-state-readback | 三者都在回答「**X 坏了 / 状态是假的,怎么定位**」;且 `instance-diagnose` 与 `plugin-diagnose` **正文已互相声明边界**(「⚠️ 与 X 的边界」)⇒ 属**同一领域的分层**,分层判据本就在它们的"先定层"一节里 | 42 KB |
| 2 | **`dsh-knowledge`** | knowledge-upkeep + architecture-lifecycle | 同一问题:**项目的知识/文档怎么组织与纠偏**。`architecture-lifecycle` 的 description 结尾**自己写着**「配套:`dsh-knowledge-upkeep`」⇒ 已是同一域的两半 | 48 KB |
| 3 | **`dsh-decision`** | decision-method + feature-first | 同一问题:**要不要上抛给用户 / 怎么定方案**。两者都在管「AI 自主 vs 上抛」的边界(且与**非 dsh** 的 `agent-operating-rules §1` 有交集 ⇒ 合并后须与之划界) | 61 KB |
| 4 | **`dsh-workflow`** | change-workflow + auto-handoff-chain | 相邻但**不是同一层**:一个是"**一次功能改造的六阶段**",一个是"**跨会话接力的编排机制**"。⚠️ 按 §9.4 这两个更像**良性撞(互补)** ⇒ 合并收益存疑,**列在此供你定** | 98 KB |
| 5 | **`dsh-local-env`** | desktop-dev-shell + env-bootstrap | 都是「**本机环境**」:前者=把 dsh 跑起来+取证;后者=换电脑/改路径的引导与自检 | 54 KB |
| 6 | **`dsh-opensource-release`** | 保留(不并) | 独立领域(开源导出/版本迭代)+ 体量最大(112 KB)+ 有 R-O1–R-O17 硬规则实体;§10 明确「**判据常驻 > 行数目标**」 | 112 KB |
**⚠️ 分组 1 与 5 的交叉**:`desktop-dev-shell` 一半是"跑起来"(→ 5)、一半是"取证踩坑"(→ 1 的诊断)。⇒ 若你要最干净,它归 5、其"取证"节在 1 里只留指针。
**合并后规模(12 → 6)**:`dsh-diagnose` · `dsh-knowledge` · `dsh-decision` · `dsh-workflow` · `dsh-local-env` · `dsh-opensource-release`。
**保留不并的**:`dsh-opensource-release`(独立域)。
---
## 三、目标形态(照 §10,⛔ 不是"并成一个巨文件")
```
<新技能>/
SKILL.md ← 主干:判据 + 分诊/流程骨架 + 命令骨架(目标 ≤350 行,判据实体⛔不下沉)
references/
00-<主题>.md ← 原技能的详情(长表 / 事故记录 / 实测读数 / 历史细节)
01-<主题>.md
```
每档头写:`归属 / 本档覆盖 / 主文件指针 / 原行段`。
主干末节加一张「详情档 × 覆盖的原章节 × 原行段」表(**治跨档引用断头**,§10 实测一次抓到 5 处)。
**🔴 关键收益(正好对上用户的两个诉求)**:
- **好调用**:12 个入口 → 6 个,`description` 区分度提高,挑错概率下降;
- **好维护**:一域一份,改一处;且**每次加载的上下文更小**(主干短、详情按需读)。
---
## 四、执行步骤(照 §10 的四步,纯机械搬运)
1. **抢锁**(`handoff-confirm --claim-exec`)—— 机制层改动,⛔ 不带域锁并行。
2. **备份 = 回滚点**:`tmp/_skill-merge-20260928/backup/`(**先把三处全部现状各存一份**,含那 6 个不一致版本 ⇒ 谁都不丢)。
3. **先对账**:6 个不一致的逐技能比对内容 ⇒ 定权威版本 ⇒ 同步三处(**这一步单独验收**,与合并解耦)。
4. **再合并**:用声明式规格脚本(复用/仿 `07-scripts/split_skill.py`)**纯搬运**:主文件只写指针与判据,详情整段搬进 `references/`;脚本自校验「**内容守恒 / 逐行包含 0 丢失 / 节可寻址 / frontmatter 唯一**」。
5. **三方同步 + 逐文件 md5 对账**(本机 → 文档库 → 服务器 600 root:root)+ `README.md`/`INDEX.md` 登记跟改(⚠️ §10 两处易漏:**服务器上也有根登记副本**、登记行**按行首单元格匹配**)。
6. **收尾**:原 12 个目录**移入备份**(⛔ 不是直接删)⇒ 观察期后再清。
**验收(缺一不可)**:① 内容守恒(新主干+references 行数 = 原行数;逐行包含 0 丢失)② 三处 md5 一致 ③ 原**每一个标题**在新结构里可寻址 ④ frontmatter 唯一、`version` 递增 ⑤ `description` 探针:用历史原话做验证集,**期望技能必须在命中集**(§9 第 3 层)。
---
## 五、待你拍板(两件)
1. **合并粒度**:按上面的 **6 个**?还是**保守一点**(只并最明确的 3 组:1/2/3 ⇒ 12 → 9)?还是**激进**(4 也并 ⇒ 12 → 6 已含)?
- ⚠️ 我倾向 **6 个**,但**组 4(workflow)**我存疑:它更像 §9.4 说的良性撞,合了可能反而糊掉「一次改造」与「跨会话接力」的区别。
2. **三处不一致(阻断项)怎么办**:
- (A) **先对账再合并**(推荐:6 个逐技能定权威 → 同步三处 → 再合并)—— 多一步,但合并基线干净;
- (B) **先合并、对账另派一棒**—— 快,但合并会把不一致固化,且**有丢内容风险**(已举 `change-workflow` 差 3.5 KB 的例子);
- (C) **本轮只出方案,不动手**—— 等你有空时再执行。
> **本报告本身是只读盘点的产物**:⛔ 未改任何技能、⛔ 未同步、⛔ 未抢锁、⛔ 未删任何目录。
---
## 六、执行记录(2026-09-28 23:3x–23:4x · **第 1 组已完成并三方验收**)
> ⚠️ 用户未答上述两问 ⇒ 按投递方推荐执行:**先对账式取证 → 做最干净的一组 → 三方同步验收**。
> ⛔ **未动有分叉的两组**(workflow / local-env)—— 它们必须先由人定权威版本口径。
**已完成:组 1「诊断」→ 新技能 `dsh-diagnose`**
| 项 | 结果 |
|---|---|
| 新技能 | `dsh-diagnose`:主干 `SKILL.md`(**105 行**,含三层分诊表 + 各层第一原则 + 详情档索引)+ `references/` **3 档**(00 服务器实例故障 / 01 业务插件故障 / 02 跨机状态回流) |
| 并入来源 | `dsh-instance-diagnose` + `dsh-plugin-diagnose` + `dsh-distributed-state-readback`(**三个原名已退役**) |
| 🔴 **内容守恒** | **逐行包含 0 丢失**(256 / 177 / 203 行正文全部搬入,机械校验) |
| 结构验收 | 起始 frontmatter 唯一 ✅ · 字段无重复 ✅ · 详情档头含「归属/覆盖/原行段/搬运方式」✅ |
| 旧目录处置 | **移入备份**(⛔ 非删除):本机/文档库/服务器三处各有归档副本 |
| **三方 md5** | `dsh-diagnose/SKILL.md` = **`b8a7ec0e…`**(本机 = 文档库 = 服务器)✅ | 3 档 references 亦三方一致 |
| 技能计数 | **12 → 10**(本机 / 文档库 / 服务器 **均为 10**)✅ |
| 登记跟改 | 文档库 `README.md`(`4345164b…`)+ `INDEX.md`(`709e40c9…`)**两处清单**均改,并同步服务器 ✅ |
| 备份/回滚点 | `tmp/_skill-merge-20260928/`:`backup/local`(12 个)· `backup/docs`(11 个)· `archived/`(本机 3 个)· `archived-docs/`(文档库 2 个)|服务器 `/opt/dsh/backups/docs-skills-20260928-2350`(984K)+ `/opt/dsh/backups/removed-skills-20260928/` |
**本轮顺带修掉的两处自身判据错误(值得记)**:
1. 🔴 **用 `grep -c $'\r'` 判行尾得到 110 是假读数** —— 字节级数 `\r` 实为 **0**(两文件都是纯 LF)⇒ 我的替换脚本按 CRLF 切分,**命中 0**;幸好有断言拦下、未误改。⇒ 印证项目既有铁律:**行尾一律数字节,⛔ 不用 grep 计数**。
2. 删除整行会让 LF 数减 1 —— 我却断言「LF 必须不变」⇒ **误报失败**。正确不变量 = **CR 数不变 + 行数 = 原数 − 删除数**。
**⛔ 本轮未做(有意,需你先定口径)**:
- **组 4「workflow」**(`change-workflow` + `auto-handoff-chain`)—— 🔴 `change-workflow` 是**双向分叉**(文档库有 **R1–R11**,本机只有 **R1–R8** ⇒ 差 3 条红线);按「本机权威」同步会**静默丢红线**。
- **组 2「knowledge」/ 组 5「local-env」** —— 分别含 `knowledge-upkeep`(本机=子集)与 `env-bootstrap`(双向分叉)。
- **组 3「decision」**(`decision-method` + `feature-first`)—— 两技能**三方一致**、无分叉 ⇒ **可直接做**,本轮因篇幅未做。
**下一步(可直接执行)**:按组 3 → 组 2 → 组 4/5(先定权威口径)顺序推进;每组都走「搬运 → 守恒校验 → 三方 md5 → 登记跟改」四步(本轮已跑通并有可复跑脚本 `tmp/_merge_g1.py` 可仿)。
---
## 七、执行记录(续):**组 2–5 全部做完,本机 `dsh-*` 12 → 6**(2026-09-28 23:4x–24:1x)
> 用户指令:「按照你的建议优化 **全部执行完毕**」⇒ 按 组 3 → 组 2 → 组 4/5 的顺序把剩余四组全部落地。
> 🔴 **分叉技能一律「取超集/更新版」并写明取哪边**,⛔ 不按"本机权威"盲推(那会静默丢红线)。
| 组 | 新技能 | 并入来源(均已退役) | 主干 | references |
|---|---|---|---|---|
| 1 | `dsh-diagnose` | `dsh-instance-diagnose` + `dsh-plugin-diagnose` + `dsh-distributed-state-readback` | 104 行 | 3 档 |
| 2 | `dsh-knowledge` | `dsh-knowledge-upkeep` + `dsh-architecture-lifecycle` | 76 行 | 4 档 |
| 3 | `dsh-decision` | `dsh-decision-method` + `dsh-feature-first` | 72 行 | 5 档 |
| 4 | `dsh-workflow` | `dsh-change-workflow` + `dsh-auto-handoff-chain` | 80 行 | 13 档 |
| 5 | `dsh-local-env` | `dsh-env-bootstrap` + `dsh-desktop-dev-shell` | 75 行 | 4 档 |
| — | `dsh-opensource-release` | **保留原样**(本域只有它一个,无同域可并) | 534 行 | 5 档 |
**分叉处置(组 4 / 组 5 —— 这是本轮最关键的一步)**
| 技能 | 两侧差异 | 取哪边 |
|---|---|---|
| `dsh-change-workflow` | 文档库版是**超集且更新**:红线 **R1–R11** + R8 已是 **2026-09-21 修订措辞**;本机版只有 **R1–R8** 且 R8 是旧措辞 | **取文档库版**(若按本机版推 ⇒ 静默丢 R9–R11 三条红线) |
| `dsh-auto-handoff-chain` | 本机版是**超集**(多 §3.1.3「投单 ≠ 启动」等约 60 行) | **取本机版** |
| `dsh-env-bootstrap` | 双向分叉(标题编号与内容段落各有出入) | 取**并集**,重排编号 |
| `dsh-knowledge-upkeep` | 文档库版独有「🔵 作用域 + 宿主落点对照」块 | 取**并集**(该块是跨宿主可用的关键) |
**四步验收(全部通过)**
| 验收项 | 结果 |
|---|---|
| ① 内容守恒(逐行可寻址) | 旧技能每一非空行均可在新结构寻址;终审残余 44 行**逐条定性无真丢**(见下) |
| ② 三方 md5(**全树 40 文件**) | ✅ **本机 = 文档库 = 服务器**,逐文件一致(`_skill_3way3.py` 可复跑) |
| ③ 登记跟改 | `README.md` + `INDEX.md`:6 个新技能登记在位 | 11 个旧技能**登记行为 0** | 两文件均纯 LF |
| ④ 结构体检 | 起始 frontmatter 唯一 ✅ | 字段无重复 ✅ | 全库**零重复段** ✅(`_dupscan.py`) |
**🔴 本轮抓出并修掉一个真缺陷(组 1 遗留,必须记)**
- **现象**:`dsh-diagnose` 三个详情档的「变更历史(原 frontmatter · 逐字保留)」块被**重复插入 3 次**;而**文档库侧这三档完全没同步到该补丁**(0 个块)⇒ 三方 md5 三态分裂(本机=服务器 ≠ 文档库)。
- **根因**:组 1 用的 `tmp/_merge_g1.py` 里那段 append **不幂等**,被重跑过;且当时的「三方一致」复核**只比了对 `SKILL.md` 一级**,没比 `references/` 全树 ⇒ **没暴露**。
- **修法**:`_fix_dupblk.py` 只保留**第一块**(正文一字不动;校验 正文未动 ✅ / 重复段逐字同块1 ✅ / 非重复行丢失 0 ✅ / CR 0→0 ✅),再补推文档库与服务器。
- **沉淀的教训**:⛔ **三方对账必须比全树,不能只比 `SKILL.md`** —— 本次三个文件因此躲过了上一轮的验收。
**终审残余 44 行的逐条定性(结论:无判据事实丢失)**
| 类别 | 例 | 判定 |
|---|---|---|
| 编号/措辞变体 | `## 3. 设计红线` → `## 4.`;「同名重复**三**类成因」→「**六**类」 | 变体,内容在 ✅ |
| 路径字面更新 | `aliyun-dsh-server` → `ai1net-dsh-server`;`~/.workbuddy/08-skills/` → `$DSH_HOME\skills\` | 更新,非丢失 ✅ |
| 被修订版取代 | 本机版 R8 旧措辞 → 09-21 修订版;「三层沉淀」补充落点表 | 取代 ✅ |
| 审计自身归一化假象 | `chain_report.py` 绝对路径(归一化剥掉中间目录后看着像变了) | 实为**正确新路径**且文件存在 ✅ |
> 🔎 **红线专项复核**:用户立过的 **R8「生产变更知会」完好**(红线清单第 7 条 + 详情档 `02-红线详解-R5-R7-R8.md` 全文),本轮未丢任何一条红线。
**⚠️ 发现但**未改动**的一处(非本次引入,需你知悉)**
- `dsh-knowledge/references/00-知识库维护与纠偏.md` 与 `dsh-workflow/references/00-平台改造六阶段.md` 里各有一块 **🔵 作用域 + 宿主落点对照(DSH ← WorkBuddy)**,写的是「**2026-09-26 从 WorkBuddy 用户级技能迁入**,已提升为 DSH 全局技能」,并提示读者把正文里的 `.workbuddy/...` 路径**换成 `$DSH_HOME/...`**。
- **取证结论**:该块**合并前就存在于文档库版**(`backup/docs/*/SKILL.md` 里能查到),本次是**按内容守恒原样保留**,⛔ 不是合并造成的。
- **为什么值得注意**:桌面宿主当前是 **WorkBuddy**(技能实际落在 `E:\ProgramData\.workbuddy\skills\`),该块的方向**与现状相反**;照它执行会把正确路径改成 `$DSH_HOME/...`。
- **我没动它**的理由:这是**宿主口径**(技能以哪端为主场)的判断,且按项目既有机制「**过时结论⛔ 不改正文,只加状态块指向定稿**」—— 属该机制范畴。**你说一声我就加一块带日期的时效声明**(增量、可回退)。
**收尾**
- 🔴 **执行锁**:已核 **无全局执行锁**(本次收尾前 `handoff-guard.sh` 报「✓ 无全局锁」;为改文档库曾重新 `--claim-exec`,收尾即 `--release-exec`)。
- **回滚点**:`tmp/_skill-merge-20260928/backup/{local,docs}`(合并前全部副本)· `archived/`/`archived-docs/`(旧技能)· 本次去重的原始三档在 `tmp/_skill-merge-20260928/dupfix-backup/`。
- **可复跑脚本**(留着,非一次性):`tmp/_skill_3way3.py`(三方全树对账)· `tmp/_audit_detail.py`(守恒终审明细)· `tmp/_dupscan.py`(重复段体检)。