Files

199 lines
18 KiB
Markdown
Raw Permalink Normal View History

# 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`(重复段体检)。