# 交接单(规划会话 → 执行会话) - 日期:2026-09-11(2026-09-12 增「待执行清单」) - 状态:✅ **启用**(本目录是「方案规划」与「落地执行」的唯一传递面) - 触发:用户口径「执行任务时间太久 → 一个会话做任务规划,另一个会话执行」 > **本目录只在「要执行某个任务」时读**;日常对齐现状请读 `BRIEF.md`。 > **待执行 = 本目录**(`交接单/*.md`);**已完成 = `archive/交接单-已完成/`**(首次完成后自动出现)。 > 完成后:单子头部状态改 ✅ 并附证据 → `git mv` 归档 → 在 `INDEX.md §四` 归档表加一行。 --- ## 一、待执行清单(**唯一来源 = 本表**) | 单子 | 状态 | **占用者 / 开始** | 一句话 | 冲突域 | 依赖 | |---|---|---|---|---|---| | `T01-档案16阶段3-4-实例内我的技能.md` | ✅ **已完成并归档**(2026-09-15,执行会话 `T01我的技能-0825`) | `—`(已释放) | 实例内「我的技能」(上传/启停/删除);**形态修正 = 并入既有「功能管理」内分组**(不新开 section)+ 阶段 4 权限收口复核 | **代码**(`poc/business-plugins`)+ profile 层 + 实例重启;**文档** `README`/`INDEX`/`03-路线图` | 决策点 1 = **A 扩展 `business-plugins`**(已定)|**证据**:档案 **100**;插件 **0.3.21** 已投放两实例;`npm run verify` 全绿;06 §7 三段式全绿(壳页 combo 含 `@dsh-local/business-plugins`、`rev=533537bbc02b`、bundle 200 · 11,363,655 B 含新特征);端到端 **19/19**(共享技能 409 / 非 zip 400);阶段 4 收口 = 未新增 section、未改角色补丁 ⇒ 可见性不变 | | `T02-文档库收尾-编号消歧与INDEX瘦身.md` | ✅ **已完成并归档**(2026-09-12,并行执行会话) | `—`(已释放) | 37a/37b/38a/38b 编号消歧(+ 2 个脚本 **8 处**正则)+ INDEX 瘦身 + 事实校正 | 纯文档 | — **证据**:4 文件已改名;`scripts/docs-{audit,manifest}.py` 正则已支持 `[a-z]?`;INDEX **28,805 → 7,468 字符**(≤10K 达标);audit【1】冲突 0、【2】标题号不符 0、【6】无悬空;陈旧表述("服务器唯一源"/`aliyun-work-space`/"下一号 = 20"/`8355e99`)已归零;**已归档 `archive/交接单-已完成/`** | | `T03-plugin_package整合为单插件并投放.md` | ✅ **已完成并归档**(2026-09-13 18:0x;原状态:🔄 进行中 —— 步骤 1–9 已完成;**候选池上传已完成 —— 现行池内版本 = `dsh-plugin-mcn-suite @0.3.9`**(09-13 00:02 上传;历史:22:0x 曾传 0.3.1 → 实例启用失败,根因 = peer 依赖被 pnpm 按公开 registry 解析;22:2x 加 `peerDependenciesMeta.optional` 修复后重传,HTTP 200 / `replaced:true` / `compat.level=ok`)。⚠️ **09-13 07:1x 复核**:0.3.2→0.3.9 期间连修:漏声明 `xlsx` 依赖、client 注册层 id、`inject` 语义);**admin 侧已装 0.3.9 且 host 面 3 个注册加载通过**;**guest `bundles` 仍未含 mcn-suite**(⚠️ **07:4x 用户尝试启用 → 失败**:装上后实例探活不通过(**内存不够**),失败路径上又触发**档案 79 的 P0 缺陷**(orchestrator 退出)⇒ 已**手工回滚 profile** 并验证实例恢复)⇒ 「guest 启用」仍待做,**前置 = 先修档案 79 + 解决堆容量**(用户已定:**暂不改配额档位**)) | `—`(**已释放**;原由 `exec-session-B` 持有,接管自卡死的 `exec-session-A`) | 7 个自研插件整合成 1 个功能插件包(`dsh-plugin-mcn-suite`);**业务技能随包投放**(用户要求「不分开管理」) | **代码**(新建整合包 + 打包脚本)+ **平台候选池**(上传/下架)+ 实例重启;**文档** `README`/`INDEX`/`03-路线图` | ✅ 决策已定(2026-09-12 用户拍板):① 不进 social-workbench ② 进 voxemw ③ 多入口并列 ④ **技能随包投放**(§4.1)⑤ v0.3.0。**进度**:产物已出 `D:\dshworkspace\plugin_package\dist\dsh-plugin-mcn-suite-0.3.0.tgz`(438 条目 / 1.90 MB / md5 `f98a3303…`);路由 48+6+7 条 ✓;**本地 smoke 17 组全绿** ✓;上传扫描 **P0=0** ✓;死引用 **0** ✓;**待执行**:**用户在实例「功能管理」里启用**(用户动作,平台不代劳)→ 启动实例 → §八验收 → 归档。⚠️ **2026-09-13 阻塞**:启用会因**同堆内存不够**致探活失败,并触发**档案 79 的 P0 缺陷** ⇒ 先修 79 + 解决容量后再启用 | | `T04-并发治理落地-commit常态化与服务器侧锁.md` | ✅ **已完成并归档**(2026-09-12 15:10,`exec-session-C`) | `—`(已释放) | 并发治理落地:commit 常态化 / 服务器侧操作锁 / 权限统一 700·600 | **git**(本机提交,不 push)+ **服务器**(建锁目录 / chmod)+ `scripts/` | ① 文档库 git 基线提交 + 此后只提自己改的文件 ② 服务器侧操作锁(`/opt/dsh/state/.op-lock/`)③ 交接单目录权限统一 700/600|决策已定(用户「A 按最佳方案」);基线提交需"静态窗口" | | `T05-插件兼容性预检.md` | ✅ **已完成并归档**(2026-09-12 16:35,`exec-session-D`,commit `8d19e89`) | `—`(已释放) | 插件在**导入/上传时**即判定与平台 dsh 的兼容性(semver 依赖判据 + 运行时导出符号判据),不再等实例崩 | **代码** `src/web/{plugin-compat.ts,routes/*.ts}` + build + 重启;**文档** `README`/`INDEX`/`03-路线图` | 方案见 **`04-71`**;⚠️ 与改 `orchestrator.ts` 的并行会话**冲突域重叠 → 必须串行** | | `T06-模型设置页-多厂家条目可开关.md` | ✅ **已完成并归档**(2026-09-13 23:5x,`craft-session-T06`) | `—`(已释放) | 平台自建「设置 → **模型设置**」:条目**各自开关、可同时启用** + 官方「模型」分区对全角色隐藏 + spawn 时把「已启用条目」落地到实例 `.credentials.yaml` / `settings.yaml` | **代码** `src/db/*`、`src/web/{model-landing.ts,server.ts,routes/auth.ts}`、`ensure-role-profile-patch.cjs`、`poc/business-plugins`(**0.3.11**) + `systemctl restart dshs` + `ensure-biz-plugins --all --restart`;**文档** `README`/`INDEX`/`03-路线图` | ✅ 无阻塞(口径用户已定);证据与判据见 **`04-87`**;⚠️ 本轮**顺手修掉两颗雷**:角色补丁脚本的整文件覆盖会抹掉 admin 另两个平台块、`verify-mem-model` 的陈旧断言 | | `T07-内置dsh安装路径探测.md` | ✅ **已完成并归档**(2026-09-14 05:0x,`craft-session-installpath` + `craft-session-tailclear`) | `—`(已释放) | 修 **P1 静默失效**:三处把内置 dsh 安装目录写死 ⇒ 在 `npm root -g` = `/usr/lib/node_modules` 的发行版上,厂家目录读空 / 兼容性预检安全网失效 / 目录选择器 import 抛错 | **代码** 新增 `src/web/dsh-install.ts` + 三处调用点(含 `poc/workspace-scoped-picker`)+ 插件 `business-plugins` **0.3.13** / `workspace-scoped-picker` **0.1.5** + build/restart/铺发;**文档** `04-88` + `README` 补 3 个 env | ✅ 无阻塞;**由开源导出会话提出**(它抢不到锁按 R9 停手),源仓独立复核后经用户「确认修改」落地。⚠️ 复核时**发现提出方漏了第 3 处**、且其 env 名是导出侧的 ⇒ 均已纠正 | | `T08-集群化落地-兼容单例模式.md` | ✅ **已完成并归档**(2026-09-15 18:0x,`exec-cluster-1a`) | `—`(已释放) | 把平台改造成「1 组 Manager(≥2 台,也支持单活)+ N 台 Worker + 共享归属状态」的集群形态;**硬约束 = 全程兼容单例模式** + 每步可单独回滚。**证据**:S0–S7 全绿(冒烟 6/8 与开工基线相同 · 5 个端到端 · lease 单测两后端 10/10)|**真跨机演练**(47 Manager / 106 Worker,跨云)✅|**域名形态访问** ✅|**2026-09-15 17:4x 生产整体切换**(47=Manager+本地 Worker w-47、106=Worker w-106、控制面库=47 的 PG13;存量用户留 w-47、新用户落 w-106;**回滚=删 drop-in**)。⚠️ **残留小项**(已登记 `03-路线图 §二`):`join-worker.sh` 一键装机 · 隧道服务化(心跳重建)· 集中日志/metrics · `smoke-domain` 定性。详见 §9–§16 | **代码**(`src/supervisor/`、`src/db/`、`src/cli.ts`、`src/fs/`)+ **服务器**(**106 另起一套**测试环境;**47 不动**)+ **文档**(本单 + 完工时的 `04-调整方案/101`) | 设计单一来源 = 项目根 `集群化改造方案_Manager-Worker_20260914.md`(19 节);**决策 D1–D5 已定**(双活+支持单活 / 存储可插拔 / 自建 PG / 跨云只当测试床 / 测试环境用 106);⏳ **仅 D6「生产拓扑最终落点」需用户拍板**,且**不阻塞 S0–S5** | > **🔒 占用怎么声明(2026-09-12 新增,防两会话撞车)**:开工前先**原子占位** —— > `mkdir 交接单/.doing-<单号>`(`mkdir` 原子:**成功=你拿到;报 File exists=已有人在做 → 停手,别开工**), > 回来把本表「占用者 / 开始」填上(会话标识 + `HH:MM`);完工 `rmdir 交接单/.doing-<单号>` + 状态改 ✅。 > 查当前占用:`ls -d 交接单/.doing-* 2>/dev/null`。标记是**纯本机目录**(空目录不会 scp 出去),两会话同机所以够用。 > **⚠️ 占位与台账必须"同一动作"完成(2026-09-12 实证)**:T03 10:14 就占了位,但 §一 台账那行直到 **12:59** 才改成「执行中」→ 中间 **2.5 小时里别人看台账会以为没人做**,随时可能重复开工。所以:`--claim` 之后**立刻**把该行状态改「🔄 执行中」并把「占用者 / 开始」填上。`handoff-guard.sh` 的 **【1b】已能自动检出这种不一致**(硬失败)。 > **🔐 两级锁(2026-09-12 新增,用户建议)** —— 一把粗、一把细: > - **粗 = 全局执行锁 `交接单/.exec-lock`**:**同一时刻只允许一个执行会话**去动「文档 / 代码 / 服务器」。这是**默认工作模式**(本库共享入口文件多、且要动生产)。 > - **细 = 单级占用锁 `交接单/.doing-<单号>`**:标记"这个单归谁做",供台账与接管使用(冲突域真不重叠时才允许两单并行)。 > - 顺序:**开工 `--claim-exec` → `--claim <单>`**;**完工 `--release <单>` → `--release-exec`**(锁最后放)。 > - ⚠️ **「无锁」的正确读法 =「你快去抢」,不是「可以开工」**(2026-09-12 实证:`handoff-guard.sh` 输出「无全局锁」被读成"环境干净", > 结果**两个会话同时改了本库** —— 无实际损害,但属**流程失效**)。**看到"无锁" ⇒ 下一个动作就是 `--claim-exec`**; > **抢不到 = 有人在跑 = 停手**。抢锁是原子的,**抢到才是开工许可**。 > - 检查:`ME="<你的会话名>" bash scripts/handoff-guard.sh <单号>` —— 【1c】会告诉你全局锁在谁手上;不设 `ME` 时**一律按"别人的锁"处理**(保守)。 > **✍️ 写者归属(每个文件只有一个写者;2026-09-12 补)** —— 「占用锁」防的是"同一单",下表防的是"跨单撞同一文件": > > | 文件 | 唯一写者 | > |---|---| > | `交接单/<单号>.md` | **该单的执行会话**(规划会话只读) | > | `交接单/README.md` §一 状态表 | **各自只改自己那一行**(规划会话加新单 = 新增一行;执行会话改状态 = 改自己那行) | > | `交接单/README.md` 其余章节(约定) | 谁改谁先读、**只用 Edit 精确替换** | > | `04-调整方案/`、`INDEX.md`、`BRIEF.md`、根 `README.md`、`03-路线图与待办.md` | **执行会话**(规划会话只读) | > | `skills/dsh-change-workflow/SKILL.md` | **其工作副本持有者**(单向往本库推进,勿反向覆盖) | > | `scripts/`、`ops/` | 谁新增谁负责(新增文件天然无冲突;改已有文件先跑 guard) | **⚠️ 两单必须串行(2026-09-12 更新)**:T01 与 T03 都要动代码与实例、都要改 `README.md` / `INDEX.md` / `03-路线图与待办.md`、都要**原子占档案号**。按 `skills/dsh-change-workflow` 的「多任务并行调度协议」(**并行度由冲突域决定,不由任务数决定**)→ **同一时刻只放一个执行会话**。(T04 已完成归档,其"基线提交触及所有人文件"的风险已消除。) **建议顺序:T03 → T01**(T04 已完成并归档,不再在序列内)。 - **T03 先做**:收益最大(7 包归 1),决策已全部拍板,只差"上传候选池 → `guest` 启用 → 验收 → 归档"。 - **T01 最后**:依赖 T03 之后的候选池 / 实例状态;决策点 1 已定,无阻塞。 > **分工边界(防双源漂移)**:`03-路线图与待办.md` 管「**平台还没做、也还没规划**的事」;本表管「**已经规划成单、等执行**的事」。同一个事项在两边都出现时,**状态以本表为准**,`03-路线图` 那行只保留指针。 --- ## 二、单子必填 8 段 | # | 段 | 写法要求 | |---|---|---| | 1 | **目标** | 一句话,可判定"做完了没有" | | 2 | **只读前置** | 执行前必须先核实的 3–5 条事实,**给命令与期望输出**,不让人推断 | | 3 | **范围** | 改哪些文件;**并明确"不动什么"**(防止顺手扩大) | | 4 | **决策点** | 已定的写「已定(谁定的/依据)」;未定的写「开跑前问用户」 | | 5 | **步骤** | 有序编号,**每步自带一次可执行的验证** | | 6 | **验收** | 命令 + 期望输出(含退出码),可被第三方复现 | | 7 | **回滚** | 具体命令或副本路径 | | 8 | **回报格式** | 执行会话必须回填的证据(命令、输出、commit) | > **判断标准**:执行会话**不读规划会话的上下文**也能开工。凡需要"你懂的"才写得通的句子,都是没写清。 > **⚠️ 写引用/数字的两个坑(2026-09-12 三次实证,写单子时必看)** > 1. **不要在「档案」二字后面直接跟一个字符类**(例:写成 `档案` + `3[78]`、`档案` + `6[01]`)—— `docs-audit.py` 的引用正则会把它们读成**裸旧号**(`3` / `6`)→ **永久悬空、audit 退出码非 0**(T02 执行会话踩 1 次、规划会话踩 2 次,**连本条警告的第一版也踩了**)。要举例请写 `档案 (37|38)`,或在中间加反斜杠阻断匹配。 > 2. **基线/阈值数字必须带"取数时间 + 复核命令",不写死绝对值** —— 会被并行改动打穿(实证:T02 里写死的 `INDEX=25,581` 在 40 分钟内变成 28,805)。 ## 三、执行会话的硬要求 0. **⚠️ 先确认没有别的会话在写同一文件(2026-09-12 新增)**:本库**多个会话并行**工作已是常态(实证:同日 T01 被两会话先后编辑、T02 与 T03 由两会话同日产出、`交接单/README.md` 被双方先后改动)。冲突域重叠的单子**必须串行**(§一),但**跨单子仍会撞同一批文件**(`INDEX.md` / `README.md` / `BRIEF.md` / `03-路线图` / 本 README / `skills/…/SKILL.md`)。开工前必须: - ① `git -C dsh-server-docs status --short` + `bash scripts/docs-sync-check.sh`(退出码 0)→ 看清**有没有不属于你的未提交改动**; - ② `ls -la --time-style=+%H:%M <要改的文件>` → **mtime 比你上次看到的新 = 别人刚动过** → **先读最新内容再改**; - ③ **共享文件只用 Edit 做"精确片段替换",禁止整文件 Write 覆盖** —— 别人改了同一处时 **Edit 会失败**,这就是**天然的冲突检测**;确需整文件重写(如 INDEX 瘦身)→ **先确认无人在改** + **先留回滚点**(`cp x x.bak-`,或先 `git commit` 留下 HEAD)+ 改完立即 commit。**注意 Write 覆盖是静默的、没有检测能力,这类操作是并行期最危险的一步**。 - ④ **改完立即 `git commit`(本机,不 push)** —— 本库目前**长期不提交**,等于**没有冲突检测能力**(无法靠 pull/merge 发现撞车)。**提交是"给下一个会话留路标",与"推送上线"是两件事**(推送仍需用户明确说)。 - ⑤ **推服务器前必须复跑 `docs-sync-check.sh`;报「仅本地」的文件若不在你本次改动清单里 → 立刻停手**(2026-09-12 事故实证:我把**已被对方归档移走**的 `T02` 单子又推回服务器,制造出"幽灵文件",靠对方后续同步才清掉)。这类"迟到的推送"是本库最容易发生的并行事故。 - ⑥ **不要"重放"别人的文件**:只推**你自己本次生成/修改**的文件。看到别人的新文件想"顺手一起推" → 先问,对方可能正处在半成品状态。 1. **开跑前拉齐**:`bash scripts/docs-sync-check.sh`(退出码 0);读单子「只读前置」与 §一 的冲突域/依赖。 2. **新增档案必须原子占号**:`mkdir <目录>/.lock-` 再写("先 ls 再写"两次撞号实证 → `skills/dsh-change-workflow/SKILL.md:250`)。 3. **收尾四件套**:`python3 scripts/docs-audit.py`(**退出码 0**)+ `python3 scripts/docs-manifest.py`(刷新机读清单)+ `bash scripts/docs-sync-check.sh`(0)+ **推送前 `MINE="<我改的文件...>" PUSH=1 bash scripts/handoff-guard.sh`(幽灵文件硬判定,**2026-09-12 因漏此步把已归档文件推回服务器**)**。 4. **回填**:§一 本行状态改 ✅;勾销 `03-路线图` 对应行;更新 `INDEX.md §二` 状态行与 `README.md` 的「下一号」。 5. **提交边界**:**推送需用户明确说"推送"**(沿用既有红线,见 `README §红线` 第 3 条与用户约定)。 6. **单子归档**:`git mv 交接单/<单> archive/交接单-已完成/<单>`(`archive/交接单-已完成/` 首次完成时创建)。 7. **服务器镜像**:本目录新增/修改的文件同样要 scp 到 `/opt/dsh/docs`(root 600,README 类保持 644)——规划会话**不 scp**,这一步一律由执行会话做。 8. **预检工具(2026-09-12 新增,把上面 0–② 变成一条命令)**:`scripts/handoff-guard.sh`(只读) - 占位 / 释放:`bash scripts/handoff-guard.sh --claim T03 "exec-session-A"` / `--release T03` - 开工检查:`MINE="交接单/README.md 交接单/T03-*.md" bash scripts/handoff-guard.sh T03` - 推送前检查:同上再加 `PUSH=1`(启用【4】的**幽灵文件硬判定**:对账结果里「仅本地」的文件若有未声明的 → 直接失败) - 判据与设计:**mtime 只作提示(分不清谁改的)**;硬判定只有两处 —— ① **别人的占用锁**;④ **「仅本地(待推送)」清单里含未声明文件**(= 幽灵文件风险,2026-09-12 就是这么把已归档的文件推回服务器的)。② 越界改动只作提示(本库长期脏,无法作为判定依据)。退出码 1 = 不可放行。 9. **会话生命周期 = 一个单(2026-09-12 新增)**:**一个执行会话只做一个单;该单 ✅ + 归档 + 双端一致之后,就地结束这个会话**,新任务开新会话。 理由(实证):会话越长寿,越容易拿**过期快照**当事实 —— 同一天里,T02 单子写死的 `INDEX=25,581` 在 40 分钟内变成 28,805;`BRIEF.md` 至今仍写 `512M` 而实际已是 384 MiB。**新会话用交接单冷启动,比老会话带着旧上下文续跑更准**。 10. **🔒 执行中冻结单子(2026-09-12 新增)**:单子被 `.doing-<单>` 持有期间,**只有持有者可以改该单子文件**;规划会话与其它执行会话**一律只读**。需要补充意见 → 写进 `.doing-<单>/OWNER` 的"待并入"段,或等锁释放后再改。**今天实测过这个风险面**:规划会话 09:20–09:45 在改 T03,执行会话 10:14 才锁它 —— 时序上是安全的(先改完再开工),但**反序就会撞**。 11. **接管必须无损:`OWNER` 是交接凭证(2026-09-12 新增,来自 T03 的 `A 卡死 → B 接管` 实战;⚠️ **「接管」这个动作本身现已受 R9 限制** —— 见第 13 条末,**不得由 AI 自行发起**)**:`OWNER` 至少写四项 —— ① 占用者 ② 开始时间 ③ **进度(做到第几步 / 已完成哪几段)** ④ **产物位置与 md5 + 下一步**。接管者**先读 OWNER 与单子回报段,再续做**,不要从头重来。示范(T03 实际写的):`exec-session-B(当前会话,接管自 exec-session-A)`,台账里补了"步骤 1–9 已完成、产物 `dsh-plugin-mcn-suite-0.3.0.tgz`(438 条目 / 1.90 MB / md5 `f98a3303…`)、待执行 = 上传→启用→验收→归档"。 12. **并行干活、串行登记(收口单点)**:确有多单并行时,各自的**档案占号**(`.lock-` 原子)与**各自 §一 行**可以并行;但 **`INDEX.md`、`03-路线图与待办.md`、根 `README.md` 的"登记动作"由单一收口会话统一做**(沿用 `skills/dsh-change-workflow` 的"收口在主会话"规则)—— 因为这几个入口文件是全库唯一的双写热点。 13. **🔐 全局执行锁:一次只允许一个执行会话(2026-09-12 新增,用户建议)** —— 单级锁只管"同一单别被两人做",**管不住跨单撞共享文件、更管不住服务器态并行**(重启/drain/改 env 会让在线用户掉线)。所以补一把**全局粗锁**: - **开工**:`bash scripts/handoff-guard.sh --claim-exec "exec-session-B" T03`(抢不到 = 已有会话在跑 → **停手**,输出会直接告诉你占用者/开始时间/在做哪单); - **完工**:`bash scripts/handoff-guard.sh --release-exec`(**放在最后**:回填 → 改自己 §一 行 → commit → 推服务器+対账 → 归档 → 再放锁); - **检查**:`ME="<会话名>"` 时 guard 会区分"自己的锁"(提示别忘释放)与"别人的锁"(硬失败);**不设 `ME` 一律按别人的处理**(保守); - **⛔ 接管:AI 不得自行接管,更不得删锁**(**R9**,2026-09-12 用户明令「严格禁止这类操作」)—— 抢不到锁 ⇒ **停手 + 报告用户**;**锁的处置权只属于用户本人**(要撤也只能用户自己动手)。 下条的「读 `OWNER` + 台账进度」**只用于**「用户已点头、且用户自己撤锁之后」的续做; **不得**以「持有者疑似已死 / 卡住 / 太久没动 / 只在只读分析没产出」为由单方面撤锁 —— 平台**无心跳机制,AI 没有任何判据**。(本条原文为「读 OWNER → **人工删锁** → 自己 `--claim-exec`」,**已作废**。) - **它同样覆盖服务器操作**:任何要重启 / drain / 改 env·quota / 铺插件 / 改 nginx·nft 的动作,都先持这把锁(与 §六 的服务器侧锁是同一件事的两种落地,先做哪个都行,别两套并存)。 ## 四、规划会话的边界(本目录的作者) - 只读**本地**文档与本地只读命令;**不 ssh、不改码、不重启服务、不 scp**。 - 产出后必须自检:`python3 scripts/docs-audit.py` 退出码 0(交接单自身也是被扫描的 md)。 - 事实一律标注单一来源(档案号 / 文件:行),不写"我记得"。 ## 五、为什么这样分(2026-09-11 实证) | 原因 | 证据 | |---|---| | **上下文挤** | 一次改造的规划要读 5–10 万 tokens,执行要读源码 + 日志 + 复跑;同一会话混做,两头都慢 | | **并行踩坑** | 同一天两次「两通道并行改同一批文件」造成损失:`03-路线图` 被旧快照覆盖跳号;**两个编号各被两份档案占用**(37/38,→ T02) | | **交付面单一** | 单子成为唯一传递面,两边都不需要对方的历史;也让"做没做"可被第三方核对 | **与既有机制的关系**:`skills/dsh-change-workflow` 的六阶段中,**阶段 0–2(需求/调研/规划)留在规划会话,阶段 3–5(开发/验证/归档)交执行会话**;冲突域与并行度规则仍按该 skill 的「多任务并行调度协议」执行。 ## 六、**服务器侧也要锁**(2026-09-12 新增;比文档冲突严重,待落地) 前面 §一–§三 治的是**文档冲突**(丢的是文字,可重写)。但所有会话**共用一台服务器**,且下面这些操作**跨会话没有任何互斥**: | 高危操作 | 影响 | 现状 | |---|---|---| | `systemctl restart dshs` / `drain` / 停 `dsh-*.scope` | **在线用户当场掉线**(档案 58/59 已两次引发报障) | ✅ 已加锁(须先占位) | | 改实例 env / `MemoryMax` / bwrap 参数 | 全部实例行为变化,用户无感知到异常 | ✅ 已加锁(须先占位) | | 批量铺插件 / 改 profile patch / `/opt/dsh/docs` 之外的生产文件 | 可能触发崩溃循环(档案 25 前例) | ✅ 已加锁(须先占位) | | 改 nginx vhost / 证书 / nft | 全站可达性 | ✅ 已加锁(须先占位) | **✅ 已实施(2026-09-12,见 `交接单/T04-*.md` 与 `scripts/op-lock.sh`)**:加第二把锁,**粒度到"平台操作"而不是"文件"**: - 约定文件 `/.doing-platform`(或服务器侧 `/opt/dsh/state/.op-lock`,取"跨机可见"之利); - 内容 = 占用者 + 操作摘要 + 影响面(谁会被断、断多久)+ 预计时长; - **凡 §六 表里任一类操作,开工前必须先占位**;占位失败 = 有别的会话正在动线上,**停手**; - 与 §三 第 0 条的差别:文档冲突靠 `git status/mtime` 能看出来,**服务器态变更看不出来**(`systemctl` 不会告诉你 10 分钟前谁重启过)→ 只能靠显式锁。 > **✅ 落地记录(2026-09-12 15:07,T04)**:锁根 `/opt/dsh/state/.op-lock/`(root 700,内含使用约定 `README`)已建立;工具 `bash scripts/op-lock.sh {claim|release|status}` 已就位并**实测往返通过**(占位 → status 显示 🔴+OWNER → 释放 → 无人占用 ✓)。 > **开工前必做**:`bash scripts/op-lock.sh status` 无人占用才继续;占位失败 = 有会话在动线上 → **停手**。 > 顺序仍为:**先抢文档库全局锁 `--claim-exec` → 再占服务器侧锁 `op-lock.sh claim`**;完工反序释放。