1) dsh-server-docs/ 从工作区(原 E:\...\aliyun-dsh-server\dsh-server-docs)**整体并入本仓**,
保留目录名 ⇒ 仓库内 dsh-server-docs/... 的相对引用天然继续有效;旧目录(含其 .git)已归档到
工作区 _中间产物_待清理/,未随本提交带入。
2) .gitattributes:新增 `dsh-server-docs/** -text` —— 原文档库是 `* -text` + autocrlf=false,
必须保持纯 LF,否则会被本仓的 CRLF 规则翻掉。
3) 活引用里的绝对路径已全部改到新位置(docs 的 INDEX / README / scripts / skills + 用户级 skills
+ ~/.workbuddy/settings.json 的 hooks);历史档案(04-调整方案/、archive/)按「只增不改」未动。
⚠️ hooks 路径改动需「完全重启会话」才生效(配置是会话启动快照)。
4) 交接单/T08:新增 §16「生产整体切换执行记录」(形态 / 落地动作 / **4 个只有真上线才暴露的真 bug** /
验收证据 / 回滚命令 / 残留项);台账 T08 行 → 已完成并归档;03-路线图 §二 登记 T08 收尾项。
5) 统一称谓:**「本机」只指跑 WorkBuddy 的开发机**,47 / 106 一律写「远程服务器」。
16 KiB
T02 · 文档库收尾 —— 编号消歧(37/38)+ INDEX 瘦身与事实校正
- 日期:2026-09-11
- 状态:⏳ 待执行(已规划,未开工)
- 来源:
04-调整方案/53-文档质量审查与精简方案.md §四.1(编号冲突)+04-调整方案/54-文档信息架构优化-BRIEF与机读清单.md §四.A(INDEX 瘦身) - 规划会话边界:本单由规划会话产出(未 ssh、未改码);执行会话按单开工
一、目标
- 消歧:让
37/38两个编号各自唯一指向一份档案 →docs-audit.py的「编号冲突」归零。 - 瘦身:
INDEX.md从 28,805 字符 / 185 行 压到 ≤ 10,000 字符,入口读取成本再降。 - 校正(本轮新增,见 §四.3):修掉 INDEX 里与现状相反的陈述(本机镜像是否存在、对账脚本是否存在、下一号、代码 HEAD)。
做完的判定:python3 scripts/docs-audit.py 退出码 0(编号冲突 0 / 标题号不符 0 / 悬空引用 0),且 INDEX.md 字符数 ≤ 10,000。
二、只读前置
| # | 事实 | 命令 | 期望 |
|---|---|---|---|
| 1 | 当前基线(先量再改) | python3 -c "import io;print(len(io.open('INDEX.md',encoding='utf-8').read()))" |
28,805 字符 / 185 行(2026-09-12 07:20 实测) |
| 2 | 双端是否已拉齐 | bash scripts/docs-sync-check.sh |
退出码 0;不为 0 先拉齐再改 |
| 3 | 现存冲突与悬空项 | python3 scripts/docs-audit.py |
实测:总 107 文件(md 78 / 其他 29);【1】37 与 38 各 2 份 + 01/02/03/06 的"两套体系"提示;【2】2 份标题号不符;【6】无悬空 |
| 4 | 引用清单可复现 | `grep -rnE "档案 (37 | 38)" --include=*.md .` |
| 5 | 代码 HEAD(填 INDEX §五) | ssh bt-server "git -C /opt/dshs log --oneline -1" |
实测值(以实跑为准) |
基线刷新记录(2026-09-12 07:20):并行通道在此期间新增档案 57-60(已登记进 INDEX)→ INDEX 25,581 → 28,805 字符、旧编号引用 25 → 27 处、audit 总文件 103 → 107。 这再次印证:T01 / T02 与并行通道处在同一冲突域(都改
INDEX.md/README.md/03-路线图)→ 必须串行,且开跑前务必复跑 §二#1–#4 重新取基线,不要沿用本单旧数字。
三、任务 A:编号消歧(采用方案 A 字母后缀)
37 / 38 各被两份占用(并行通道撞号),且其中两份标题号与文件名号不符。规划会话已按 档案 53 §四.1 方案 A 立项:
现文件名(04-调整方案/) |
新文件名 | 标题改为 | 指向 |
|---|---|---|---|
37-guest会话取证与平台缺陷清单.md(现标题写 36) |
37a-guest会话取证与平台缺陷清单.md |
37a · … |
37a |
37-功能插件分区v0.2官方token与i18n.md |
37b-功能插件分区v0.2官方token与i18n.md |
37b · … |
37b |
38-实例软件安装共享与网络安边界核查.md(现标题写 37) |
38a-实例软件安装共享与网络安边界核查.md |
38a · … |
38a |
38-术语统一…改功能插件.md |
38b-术语统一…改功能插件.md |
38b · … |
38b |
方案 B(顺延重编号)与 C(只对齐标题)已在档案 53 §四.1 排除:B 改动更大且破坏时序语义,C 不能消歧。
3.1 ⚠️ 必须同步改两个脚本的正则(否则"改完更糟")
37a-… 不匹配 ^(\d+)-,会让 4 份档案从统计里消失(docs-manifest.py 会把它们判成 tier=doc / num=null,档案份数与 hot/warm 分层全部失真)。所以方案 A 的必要组成部分是改 6 处正则:
| 文件 | 行 | 现值 | 改为 |
|---|---|---|---|
scripts/docs-manifest.py |
41 | r'^|\s*04-(\d+)\s*|' |
r'^|\s*04-(\d+[a-z]?)\s*|' |
scripts/docs-manifest.py |
58 | r'^(\d+)-' |
r'^(\d+[a-z]?)-' |
scripts/docs-manifest.py |
51 | r'档案\s*(\d{1,2})\b' |
r'档案\s*(\d{1,2}[a-z]?)'(去掉 \b,否则 档案 37a 匹配不到) |
scripts/docs-audit.py |
59 | r'^(\d+)-' |
r'^(\d+[a-z]?)-' |
scripts/docs-audit.py |
60 | (\d+) 标题号 |
(\d+[a-z]?) |
scripts/docs-audit.py |
122 | r'档案\s*(\d{1,2})\b' |
r'档案\s*(\d{1,2}[a-z]?)' |
另外:docs-audit.py 的 num_map 现在用 int(mf.group(1)) 作键(L62)→ 改成字符串键(mf.group(1)),L118 的 existing 与 L124 的比较也一并按字符串,避免 '37a' 与 int 混比。
验证:改完在未改名状态下先跑一次两个脚本 → 输出应与改前一致(证明正则改动无语义漂移);再做改名。
3.2 引用修正规则(按内容判定,勿机械替换)
| 引用的语境 | 指向 |
|---|---|
| 会话取证 / 会话级播种 / 零技能投放 / 存量会话 | 37a |
| 功能插件分区 v0.2 / 官方 token / i18n | 37b |
| 实例软件安装共享 / Playwright / 网络与安全边界 / 共享技能层挂载 / 无磁盘配额 | 38a |
| 术语统一 / 以某档案为准的术语口径 | 38b |
已知待改位置(2026-09-12 07:20 实测:27 处 / 13 个文件;执行时以 §二#4 实跑复核):
| 位置 | 处数 | 现语境 → 改为 |
|---|---|---|
BRIEF.md:68 |
1 | 术语以旧 38 为准 → 38b |
README.md:18 |
1 | 同上 → 38b |
INDEX.md |
3 | §二 表行与行内引用 → 37a / 37b / 38a / 38b 分别对齐(表行见 §4.1 重复行合并) |
skills/dsh-change-workflow/SKILL.md |
3 | :452 边界章节 → 38a;:779 术语章节 → 38b;:472 按内容判 |
04-调整方案/38-实例软件安装共享与网络安边界核查.md |
5 | 会话取证引用 → 37a |
04-调整方案/38-术语统一…改功能插件.md |
1 | 分区 v0.2 引用 → 37b |
04-调整方案/39-实例可见面收窄与宿主访问封锁.md |
2 | 边界核查起因 → 38a |
04-调整方案/40-共享技能层挂载修复.md |
1 | 挂载起因 → 38a |
04-调整方案/41-技能上传安全加固与用户技能启停.md |
1 | 无磁盘配额 → 38a |
04-调整方案/45-存量会话新开会话提示.md |
1 | 会话级播种 P0-1 → 37a |
04-调整方案/46-实例共享工具jq-ripgrep-ffmpeg.md |
1 | Playwright 是否每人一份 → 38a |
04-调整方案/53-文档质量审查与精简方案.md |
5 | 本档自身的冲突描述(§二 P0 行 + §四.1 全节)→ 改 37a/37b/38a/38b + 追加「已执行」一行 |
⚠️ 两处副本都要改:
skills/dsh-change-workflow/在本目录是服务器归档副本,工作副本在本机.workbuddy/skills/(技能必须本地加载)——单向推进 本机 → 本目录,勿反向覆盖。
自带验证器:改名后
docs-audit.py会把所有残留的裸旧号(不带字母后缀的那种写法)判为悬空引用(退出码 1)→ 改不干净就过不了验收,这正是我们要的强制力。注意:本单自身、以及归档后的本单同样会被扫描,收尾时一并清理。
四、任务 B:INDEX 瘦身(目标 ≤ 10,000 字符)
体积主因 = §二「全量清单」表(60+ 行,每行 300–900 字符,含「文档路径 / 状态 / 最后更新 / 一句话内容 / 证据」五列)。
做法(已定):
| 章节 | 动作 |
|---|---|
| §一 场景速查表 | 保留(定位层,最高频) |
| §二 顶部「状态摘要(30 秒视图)」 | 保留 4 行(状态计数 + 分层 + 指针) |
| §二 明细表 | 压成精简表:| 号 | 状态 | 一句话(≤25 字) | 三列,删掉「文档路径 / 最后更新 / 证据」三列——路径与标题看 docs-manifest.json 的 path/title,日期看它的 date,commit 归各档案自身 |
| §三 变化追踪 | 保留,手段表 5 行 → 压到 3 行(把已作废的"服务器 git init 建议"按结论一行带过) |
| §四 归档残留 | 保留;归档表精简为"文件 + 状态"两列 |
| §五 仓库与同步拓扑 | 保留(关键事实,逐行核对更新到当前 HEAD) |
| §六 落位规则 | 保留 7 条 + 新增第 8 条(交接单落位,本单已加) |
测量:python3 -c "import io;print(len(io.open('INDEX.md',encoding='utf-8').read()))";一次压不到位时,继续删「一句话」列长度与 §三/§四 的冗余表述,不要删 §一 场景表。
4.1 顺手修掉的事实错误(同时是"歧义源")
| 位置 | 现文 | 应为 |
|---|---|---|
INDEX.md:6 |
「服务器唯一源…本机不保留副本…61 文件…原整库对账脚本 docs-sync-check.sh 已删除」 |
与本机镜像存在(本目录即工作树)、且 scripts/docs-sync-check.sh 在用(README §对账、BRIEF §6 都在引用)直接矛盾 → 改为"本机工作树 + 服务器镜像双端,对账脚本在用" |
INDEX.md:7 |
本机工作区 = D:\AI技能\aliyun-work-space\,称 aliyun-dsh-server "已不存在" |
写反了 → 应为 D:\AI技能\aliyun-dsh-server\dsh-server-docs |
INDEX.md:8 |
最后核对 10:12 / 代码至档案 28 | 更新到当前(档案 56) |
INDEX.md §二 |
3 处重复行:04-37×2、04-38×2、04-21×2 |
合并为 37a/37b、38a/38b 两行;21 只留一行 |
INDEX.md §二 |
无「编号 48 未使用」说明 | 补一行说明(缺号) |
INDEX.md:117 |
阶段 3/4 待办 | T01 完成后勾销 |
INDEX.md §五 |
代码 master @ 8355e99 |
按 §二#5 实测值更新 |
INDEX.md §六① |
「下一号 = 20」 | 更新为当前值(以 README §使用约定 的「下一号」为准,改前先与 T01 当时的占号结果对齐,避免两个通道同时取号) |
README.md 模块一览 |
称 skills/dsh-change-workflow/ 的工作副本在本机 .workbuddy/skills/ |
规划会话在 4 个候选路径(~/.workbuddy/skills/、~/.dsh/skills/、D:\dshworkspace\ 下两级、本工作区 .workbuddy/skills/)均未找到该技能(~/.dsh/skills/ 下是 dsh-multi-user-migration)→ 请核实真实位置并订正「同步方向本机 → 本目录」这句 |
五、明确不做
- ❌ 历史档案里的旧域名 / 旧术语不回改(档案 53 §五已判定:档案是当时事实)
- ❌
archive/全文不动;❌02-运维手册/06-工作台UI规范长文不拆 - ❌ 档案 53 §四 的其余待裁定项(02 正文加历史前缀、19 份补状态行、
.bak清理、SKILL.md 拆分)→ 不在本单 - ❌ 那个结尾带点号的
INDEX.md.bak-20260911111003.(Windows 落不了地)→ 不动
六、验收
| # | 命令 | 期望 |
|---|---|---|
| A | python3 scripts/docs-audit.py |
退出码 0;【1】无冲突、【2】无、【6】无悬空 |
| B | python3 -c "import io;print(len(io.open('INDEX.md',encoding='utf-8').read()))" |
≤ 10000 |
| C | python3 scripts/docs-manifest.py |
档案份数与改前一致;37a/37b/38a/38b 出现在 items 且各自有 refs 与 tier(证明 3.1 的正则改动生效) |
| D | `grep -rnE "档案 (37 | 38)" --include=*.md .` |
| E | bash scripts/docs-sync-check.sh |
退出码 0(含新增的 交接单/ 目录已推送服务器) |
| F | INDEX.md 内所有指向 T01 的相关行 |
与 T01 执行结果一致(若 T01 未完成,保持"待办"表述) |
七、回滚
- 文档:
git -C dsh-server-docs checkout -- <文件>;改名用git mv反向再来一次(保留历史)。 - 脚本:两处正则改动若异常,
git checkout -- scripts/docs-{audit,manifest}.py并同时撤销改名(正则与文件名必须成对,半改状态会让 manifest 统计失真)。 - 服务器镜像:
scp前先备份/opt/dsh/docs对应文件;权限维持 root 600(README 644)。
八、回报格式(执行会话填)
## T02 执行回报(2026-09-12 执行完毕)
- **改名前基线**:INDEX **28,809 字符 / 184 行**;audit:【1】37 与 38 各被 2 份占用 + 2 份标题号不符;【2】2 份;【6】无悬空**但 T02 单子自身引用 `37a` 被判悬空** → 退出码 1
- **改名**:4 份经 `git mv` → `37a`/`37b`/`38a`/`38b`(git 识别为 **R 重命名,历史保留**)+ 4 个标题号同步改写(`# 36`→`# 37a`、原 `# 37`→`# 37b`、原 `# 37`→`# 38a`、`# 38`→`# 38b`)
- **脚本正则**:`docs-audit.py` **4 处** + `docs-manifest.py` **4 处** = 共 **8 处**(**多于单子列的 6 处**:单子漏了 `index_status`/`ref` 的键转换,以及 `%02d` 格式化 —— 键改字符串后 `%02d` 会 TypeError,必须同改);**未改名状态下先复跑** ✅,差异全部可解释且**更准确**:audit 唯一差异 = 新号 `37a` 被判悬空(预期);manifest 归一化后 11 条 = 9 条零填充(`1`→`'01'`,类型变更连带,反而与 INDEX 的 `04-01` 更一致)+「`03` 的 refs 4→2」(原先被 `int()` 误并进来的裸旧号 —— 即 `档案` 与数字分开写的那种 —— 分离出去,那是**单子自身的示例文本**)+「`16` 的 refs 24→25」(去掉 `\b` 后**修复了一个漏匹配**)
- **引用修正**:实跑命中 **28 处 / 14 文件**(单子估 27 处/13 文件,**偏少 1**);逐条按内容判定归属 —— **37a 7 处**(INDEX:98 / 38a:6,55,139,178,188 / 45:5)、**37b 1 处**(38b:56)、**38a 9 处**(INDEX:93,99 / 39:12,118 / 40:5 / 41:28 / 46:5 / SKILL:489,509)、**38b 6 处**(BRIEF:68 / INDEX:112 / README:18 / 53:55 / 60:43 / SKILL:816);另 **53 自身 3 处描述改写**(P0 行、§四.1 标题、方案 A 段落,均加「✅ 已执行」)+ **T02 单子自身 2 处示例文本**改写
- **INDEX 瘦身**:**28,809 → 7,468 字符**(184 → 168 行,**减 74%**,达标);删除列 = 文档路径 / 最后更新 / 证据(均指向 `docs-manifest.json`);§二 明细压成三列;§三 手段表重排(对账/机读/审计/代码侧/文档侧/时间线);§四 精简为 4 行;§五 补「行尾」约定;§六 保留 7 条 + 第 8 条(交接单落位)
- **事实校正**:L6(「服务器唯一源 / 本机不保留副本 / 对账脚本已删除」→ **实为双端模型且脚本在用**)✅|L7(本机工作区误写 `aliyun-work-space` 且称 `aliyun-dsh-server` 已不存在 → **写反了,已改正**)✅|L8(最后核对 → 2026-09-12 / md 78 / 代码 `ebe8075` / 档案 60)✅|§二 重复行(37×2、38×2、21×2 → 合并)✅|缺号 48 ✅|§五 代码 HEAD(`8355e99` → **`ebe8075`**)✅|§六① 下一号(20 → **61**)✅|**另修** README 的技能工作副本路径(规划会话在 4 个候选路径均未找到 → 实际在 **`E:\ProgramData\.workbuddy\skills\`**,因 `.workbuddy` 数据目录已迁至 E 盘)✅
- **验收**:**A ✅ B ✅ C ✅ D ✅ E ✅ F ✅**
- **证据**:
- `docs-audit.py` → `结论:无 P0 级问题`、`【6】✓ 无悬空档案号引用`、**退出码 0**
- `docs-manifest.json` → `items: 78`(与改前一致),含字母后缀编号 `['37a','37b','38a','38b']` 且各有 refs/tier
- 裸旧号检查(`档案` 后直接跟两位数字、不带字母后缀的写法)→ **残留 0**
- `docs-sync-check.sh` → `一致: 107 / 内容不一致: 0 / 仅本地: 0 / 仅服务器: 0` → **双端一致 ✅**
- **偏离**:① 脚本正则由 6 处增至 **8 处**(键类型连带的必需修改);② 引用实为 **28 处 / 14 文件**(单子估 27/13);③ 额外修正 **T02 单子自身 2 处示例文本**(原 `grep "档案\s*3[78]"` 会被新正则匹配成裸旧号 → 永久悬空,改为 `grep -rnE "档案 (37|38)"`);④ 除单子列的 8 处事实校正外,另修 README 技能工作副本路径