Flip the agent-skill default from mono (single dws/ dir) to multi (per-product dingtalk-* + dws-shared) across all distribution faces, and fix the upgrade path so it no longer re-installs mono alongside multi (mono+multi co-existence bug). - upgrade: LocateSkillsRoot prefers the zip multi/ tree; multi refresh removes mono leftovers and stale skills, refreshes the multi cache - install.sh/ps1/install-skills.sh/npm install.js: multi real-install (was print-only), default flipped, mono stays opt-in via DWS_SKILL_MODE - skill setup: non-interactive default multi; full installs now clean stale dingtalk-*/dws-shared with confirm-preview disclosure, filtered (-s/-x) installs stay additive - mutual exclusion is symmetric and includes dws-shared (previously leaked through the dingtalk- prefix) on all faces - install.js: guard empty/corrupt multi trees (fall back to mono), validate SKILL.md on the mono branch, guard cache refreshes - docs: roadmap (8/30 back-schedule), migration plan, distribution mechanism, rollout capability, capability completion, architecture optimization, wukong comparison (archived; line retired) Co-authored-by: Cursor <cursoragent@cursor.com>
273 lines
21 KiB
Markdown
273 lines
21 KiB
Markdown
# Skill 分发/安装架构优化方案
|
||
|
||
> 目标:把 DWS Agent skill 的"装在哪、怎么装、装完记什么"从 7+ 个安装面的
|
||
> N 份漂移拷贝,收敛为 **Go 侧单一事实源 + 单一安装引擎 + 脚本侧 bootstrap**。
|
||
> 本文基于 feat/skill-mode-migration 工作区(multi 化落地后)的代码级盘点
|
||
> (2026-08-05),所有锚点均可跳转验证。
|
||
> 前置文档:[skill-multi-migration-plan.md](skill-multi-migration-plan.md)(下称《迁移计划》)、
|
||
> [skill-distribution-mechanism.md](skill-distribution-mechanism.md)。
|
||
|
||
## 1. 问题量化
|
||
|
||
### 1.1 复制矩阵(能力 × 面)
|
||
|
||
multi 化之后,同一块逻辑在各安装面的拷贝数(✓ = 独立拷贝一份,数字 = 份数):
|
||
|
||
| 能力 \ 面 | install.sh | install.ps1 | npm install.js | install-skills.sh | install-event.sh | install-devapp.sh(+ps1) | Homebrew caveats | `dws skill setup` (Go) | `dws upgrade` (Go) |
|
||
|---|---|---|---|---|---|---|---|---|---|
|
||
| agent home 清单 | ✓×3 | ✓ | ✓ | ✓×2 | ✓ | ✓×2 | — | ✓ | ✓ |
|
||
| 互斥清理(mono↔multi) | ✓×2(其中 1 份死代码) | ✓ | ✓ | ✓ | — | — | — | ✓ | ✓ |
|
||
| mode 解析(env/flag/交互) | ✓ | ✓ | ✓ | — | — | — | — | ✓ | 布局嗅探 |
|
||
| stale `dingtalk-*` 清理 | ✓ | ✓ | ✓ | ✓ | — | — | — | ✗(additive,不清) | ✓ |
|
||
| `~/.dws/skills` 缓存写 | ✓ | ✓ | ✓ | — | ✓ | ✓ | — | —(只读回退) | ✓(仅 multi) |
|
||
| 安装状态(state.json) | 无 | 无 | 无 | 无 | 无 | 无 | — | 无 | 无 |
|
||
|
||
清单锚点(agent home 清单,全仓共 **15 份**):
|
||
|
||
| # | 位置 | 备注 |
|
||
|---|---|---|
|
||
| 1 | `internal/app/skill_setup.go:20-37` | `skillSetupAgentHomes`,16 项,**无 opencode** |
|
||
| 2 | `internal/app/skill_command.go:119-141` | `agentSkillPaths`,17 项,含 opencode(`:129`) |
|
||
| 3 | `internal/upgrade/paths.go:35-52` | `knownSkillDirs`,16 项,**无 opencode** |
|
||
| 4 | `scripts/install.sh:370-386` | mono 安装循环内联清单 |
|
||
| 5 | `scripts/install.sh:439-455` | multi 清单(**死代码**,见 1.2) |
|
||
| 6 | `scripts/install.sh:516-532` | multi 清单(生效) |
|
||
| 7 | `scripts/install.ps1:44-61` | `$AgentDirs` |
|
||
| 8 | `build/npm/install.js:11-28` | `AGENT_DIRS` |
|
||
| 9 | `scripts/install-skills.sh:166-182` | multi 清单 |
|
||
| 10 | `scripts/install-skills.sh:247-261` | mono 清单 |
|
||
| 11 | `scripts/install-event.sh:103-107` | 17 项,**含 `.config/opencode/skills`**(`:107`) |
|
||
| 12 | `scripts/install-devapp.sh:87-91` | 含 opencode(`:91`) |
|
||
| 13 | `scripts/install-devapp.ps1:106` | 含 opencode |
|
||
| 14 | `test/scripts/package_script_test.go` | `expectedPackagedSkillTargets` |
|
||
| 15 | `scripts/release/verify-package-managers.sh:75-76` | `HOME_AGENT_PARENTS` / `HOME_SKILL_TARGETS` |
|
||
|
||
互斥清理逻辑共 **≥8 份**:`skill_setup.go:570-608`、`paths.go:306-327` +
|
||
`paths.go:163-179`(mono 分支内联)、`install.sh:394-399` + `install.sh:557-570`
|
||
+ 死代码 `install.sh:477-486`、`install.ps1:488-498` + `install.ps1:562-570`、
|
||
`install.js:130-137` + `install.js:165-178`、`install-skills.sh:207-220`。
|
||
|
||
mode 解析共 **4 份**:`skill_setup.go:343-376`、`install.sh:220-257`、
|
||
`install.ps1:293-332`、`install.js:197-214`(各自实现 env 优先级、非法值报错、
|
||
TTY 交互、非 TTY 默认值,措辞与行为细节已不完全一致)。
|
||
|
||
stale `dingtalk-*` 清理共 **5 份**:`paths.go:317-325`、`install.sh:561-567`、
|
||
`install.ps1:562-570`、`install.js:168-172`、`install-skills.sh:211-220`。
|
||
|
||
缓存写共 **6 份**:`install.sh:326-344`(multi)+ `install.sh:349-360`(mono)、
|
||
`install.ps1:446-471`、`install.js:221-237`、`install-event.sh:165-169`、
|
||
`install-devapp.sh:82-84`、`paths.go:290-296`(upgrade 只刷 multi)。
|
||
|
||
### 1.2 已发生的漂移实例(不是假设,是现状)
|
||
|
||
1. **opencode 清单漂移**:`dws skill install` 支持 opencode 目标
|
||
(`skill_command.go:129`),install-event / install-devapp 也往
|
||
`~/.config/opencode/skills` 装(`install-event.sh:107`、
|
||
`install-devapp.sh:91`),但 `dws skill setup --target all` 与
|
||
`dws upgrade` 的清单都不含它(`skill_setup.go:20-37`、
|
||
`paths.go:35-52`)。结果:opencode 用户能收到 event/dev skill,
|
||
却永远收不到内置 skill 的安装与升级。
|
||
2. **install.sh 死代码**:`install_multi_skills_to_homes` 定义了两次
|
||
(`install.sh:434` 与 `install.sh:511`),`_install_multi_to_base`
|
||
同样两次(`install.sh:473` 与 `install.sh:549`)。bash 后定义覆盖先定义,
|
||
第一对(434-505)整体是死代码——本次 multi 化自己引入的重复。
|
||
3. **"镜像"注释与实现已不符**:`install.sh:507-510` 注释声称 multi 安装
|
||
"mirroring `dws skill setup --mode multi`",但脚本会删除 bundle 里不存在
|
||
的 stale `dingtalk-*`(`install.sh:561-567`),而 setup 是 additive 语义、
|
||
只清 `dws/`(`skill_setup.go:587-593`)。注释说镜像,行为已分叉。
|
||
4. **互斥语义自相矛盾**:install-event.sh 把 multi 的 `dingtalk-event` 和
|
||
mono 的 `dws` **同时**装进同一批 agent home(`install-event.sh:171-172`),
|
||
与其他所有面"mono/multi 互斥"的语义直接冲突。
|
||
5. **缓存只写不读、版本不可见**:`dws skill setup` 默认走二进制 embed
|
||
(`skill_setup_embed.go:50-59`),`~/.dws/skills` 只是 legacy 回退候选
|
||
(`skill_setup.go:442-447`);6 个写入方没有任何版本戳,upgrade 只刷
|
||
multi 不刷 mono(`paths.go:292-296`),缓存与 embed 漂移不可见。
|
||
6. **保留前缀规则已双份**:`dingtalk-` / `dws-shared` 的保留约定在
|
||
`skill_setup.go:199`(`multiSkillPrefix`)、`skill_setup.go:205`
|
||
(`multiSharedSkill`)与 `paths.go:332-334`(`isMultiSkillDirName`)
|
||
各写一份,互斥清理依赖"市场 skill 不用该前缀"这一隐性约定。
|
||
|
||
### 1.3 维护成本论证(本次 multi 化实证)
|
||
|
||
本次"把 7 个面全部 multi 化"这一个语义变更,工作区改动为 **13 个文件、
|
||
+759/−166 行**(`git diff --stat`),横跨 Go / POSIX sh / PowerShell /
|
||
JavaScript 四种语言:
|
||
|
||
| 文件 | 改动量 | 改了什么 |
|
||
|---|---|---|
|
||
| `scripts/install.sh` | +256/−… | mode 解析、multi 安装×2(含死代码)、互斥清理、缓存写 |
|
||
| `scripts/install.ps1` | +169 | 同上,PowerShell 再写一遍 |
|
||
| `build/npm/install.js` | +87 | 同上,JavaScript 再写一遍 |
|
||
| `scripts/install-skills.sh` | +101 | multi 安装 + stale 清理 |
|
||
| `internal/upgrade/paths.go` | +206 | upgrade multi 刷新 + 互斥清理 + 缓存 |
|
||
| `internal/app/skill_setup.go` 等 Go 侧 | ~+50 | setup multi 语义 |
|
||
| 测试与文档 | 其余 | 4 个测试文件 + README×2 + SKILL.md |
|
||
|
||
即:**一个语义变更 = 4 种语言 × 7+ 处同步编辑**,且仍然漏了 opencode、
|
||
制造了死代码、留下了语义分叉(1.2)。新增一个 agent home 今天要改 15 份
|
||
清单中的至少 11 份(另 4 份是测试/校验)。这不是"以后会漂移",而是
|
||
**每一次改动都在当场制造漂移**。
|
||
|
||
## 2. 目标架构
|
||
|
||
### 2.1 分层总览
|
||
|
||
```text
|
||
┌──────────────────────────────────────────────────────────────────┐
|
||
│ L3 分发面(7 个,全部退化为 bootstrap) │
|
||
│ install.sh / install.ps1 / npm install.js / install-skills.sh /│
|
||
│ install-event.sh / install-devapp.sh / Homebrew caveats │
|
||
│ 职责:装二进制 → exec `dws skill setup --mode X --yes` │
|
||
│ └─ 失败 → 冻结的内嵌 fallback 拷贝(一档,不再演进) │
|
||
├──────────────────────────────────────────────────────────────────┤
|
||
│ L2 单一安装引擎(Go,唯二入口) │
|
||
│ dws skill setup ─┐ │
|
||
│ dws upgrade ─┴─► 共用同一 install 实现(含互斥清理/记账) │
|
||
├──────────────────────────────────────────────────────────────────┤
|
||
│ L1 单一事实源:internal/skillhome(新共享包) │
|
||
│ AgentHomes() 清单 + 布局规则(mono→<home>/dws,multi→平铺) │
|
||
│ + 互斥/ stale 清理规则 + 保留前缀常量 + state.json 读写 │
|
||
├──────────────────────────────────────────────────────────────────┤
|
||
│ L0 事实数据 │
|
||
│ //go:embed skills/{mono,multi}(skills_embed.go:28,默认源) │
|
||
│ ~/.dws/skills/state.json(权威安装状态) │
|
||
│ ~/.dws/skills/{mono,multi}(显式回退源,带版本戳,唯一写方=Go) │
|
||
└──────────────────────────────────────────────────────────────────┘
|
||
▲ 门禁:scripts/policy/check-agent-homes-sync.sh(进 make policy)
|
||
比对各脚本可解析清单块 ↔ skillhome 导出清单
|
||
```
|
||
|
||
### 2.2 单一事实源:`internal/skillhome` 共享包
|
||
|
||
新建 `internal/skillhome`,把今天散在 3 处 Go 代码里的规则合并导出,
|
||
setup / upgrade / 测试共用(对应《迁移计划》P0c-1):
|
||
|
||
| 导出物 | 收敛的现有拷贝 |
|
||
|---|---|
|
||
| `AgentHomes()`(含 opencode,带"首项必装/其余父目录门控"元数据) | `skill_setup.go:20-37`、`paths.go:35-52`,并与 `skill_command.go:119-141` 互相断言 |
|
||
| `HomeForMode(base, mode)` 布局规则 | `skill_setup.go:502-507`(`agentHomeForMode`) |
|
||
| `MutualExclusionVictims(home, mode)` / stale 判定 | `skill_setup.go:570-596`、`paths.go:306-327` |
|
||
| `ReservedSkillPrefixes` / `ReservedSkillNames` 常量 | `skill_setup.go:199/205`、`paths.go:332-334` |
|
||
| `State` 读写(state.json,见 2.4) | 新增(《迁移计划》P0b-1) |
|
||
|
||
脚本侧不生成代码(sh/ps1/js 三语言片段生成成本高、措辞差异大),改为
|
||
**可解析标记块 + policy 比对**:每个脚本的清单包在
|
||
`# DWS-AGENT-HOMES-BEGIN` / `# DWS-AGENT-HOMES-END` 注释块内,新增
|
||
`scripts/policy/check-agent-homes-sync.sh` 提取 7 个脚本块与
|
||
`skillhome` 导出清单(`go run ./internal/skillhome/cmd/dump` 或
|
||
`dws skill setup --print-agent-homes` 之类调试出口)逐一比对,挂进
|
||
`make policy`(Makefile:86-97 现有政策链)。对应《迁移计划》P0c-2。
|
||
|
||
### 2.3 安装逻辑单引擎化:脚本退化为 bootstrap
|
||
|
||
**终态形态**:每个安装脚本只做两件事——装二进制、执行
|
||
`dws skill setup --mode <resolved> --yes`(mode 解析仍允许脚本做,因为它
|
||
要处理自己的 env/flag;也可以更进一步把 `DWS_SKILL_MODE` 透传给 setup)。
|
||
执行失败(二进制跑不起来、setup 非 0 退出)时,降级到**冻结的内嵌
|
||
fallback 拷贝逻辑一档**——即今天的拷贝实现原样保留但标记"不再演进",
|
||
语义变更只改 Go 引擎。
|
||
|
||
各面降级可行性分析:
|
||
|
||
| 面 | 二进制可得性 | 可行性 | 风险与对策 |
|
||
|---|---|---|---|
|
||
| install.sh | `main` 先 `install_binary` 后 `install_skills`(`install.sh:830-831`),二进制就在 `$INSTALL_DIR` | ✅ 直接调 `"$INSTALL_DIR/dws" skill setup --mode "$SKILL_MODE" --yes` | `DWS_SKILLS_ONLY=1` 时不装二进制 → 先 `command -v dws`,无则走 fallback。curl 下载不带 quarantine 属性,macOS 可直接执行。风险低 |
|
||
| install.ps1 | 同序(`Install-Binary`:337 → `Install-Skills`:622,main 入口 `:700`) | ✅ 调 `& $installDir\dws.exe skill setup ...` | ExecutionPolicy 约束的是 .ps1 脚本本身,**子进程 dws.exe 不受其限制**;AppLocker/WDAC 环境可能拦未签名二进制——但那种环境 dws 本身也跑不了,fallback 拷贝仍必要。风险低-中 |
|
||
| npm install.js | postinstall 已把平台二进制解到 `vendor/`(`install.js:260`)再装 skill(`:271-280`) | ✅ `execFileSync(path.join(vendorDir,'dws'), ['skill','setup','--mode',m,'--yes'])` | `npm i --ignore-scripts` 时 postinstall 整体不跑(现状如此,非新增风险);部分 CI 以 root 跑生命周期脚本权限怪异;Windows 用 `dws.exe`。风险中,fallback 必须保留 |
|
||
| install-skills.sh | skills-only 面,不装二进制 | ✅ `command -v dws` 有则调引擎,无则 fallback | 本质是"刷新 skill"路径,有 dws 才谈得上刷新。风险低 |
|
||
| install-event.sh | 装二进制 + 单 skill(dingtalk-event + mono dws) | ⚠️ 有条件 | `EVENT_VERSION` 可与已装二进制版本不同(尤其 `DWS_SKILLS_ONLY=1`),embed 与目标 zip 可能错配;且当前同时装 mono+multi 的语义(`:171-172`)需先按 1.2-4 收敛。**最后迁移**,迁移前先把 dingtalk-event 纳入 embed 并改成 `-s event` 调引擎 |
|
||
| install-devapp.sh(+ps1) | 同上(dingtalk-dev) | ⚠️ 有条件 | 同 install-event。风险中-高,最后迁移 |
|
||
| Homebrew caveats | 只打印提示 | ✅ 已是终态 | `homebrew.rb.tmpl:33-36` 现状就是"Run `dws skill setup`",无需改,是其他面的样板 |
|
||
|
||
配套收益:《迁移计划》P2-2(sh/ps1 的 multi 分支真装,1.5d)与 P2-3
|
||
(install.js / install-skills.sh 加 mode 支持,1d)在单引擎方案下**大幅
|
||
缩水**——脚本只需把 mode 透传给引擎,不再在 sh/ps1/js 里写安装逻辑。
|
||
|
||
### 2.4 状态与缓存
|
||
|
||
- **state.json 权威化**(《迁移计划》P0b 原样采纳):
|
||
`~/.dws/skills/state.json` 记录 `schema_version / mode / cli_version /
|
||
installed / agent_homes / previous`,写方只有 `dws skill setup` 与
|
||
`dws upgrade`(脚本侧不再各自写状态——它们调引擎,引擎记账);缺失/损坏
|
||
时按磁盘形态反推(有 `dws/` → mono;有 `dingtalk-*` → multi;都有 →
|
||
报 drift 要求显式收敛)。
|
||
- **`~/.dws/skills` 缓存收敛**:二选一,本文建议后者——
|
||
1. ~~被 state 取代,删除缓存~~:激进;embed 之外的"无源码机回退源"场景
|
||
(`skill_setup.go:442-447` 注释描述的场景)会断。
|
||
2. **明确为 setup 回退源 + 版本戳**(采纳):缓存目录写入
|
||
`cli_version` 戳文件(或并入 state.json 的 `cache_version` 字段);
|
||
**写缓存收敛到 Go 侧唯一实现**(setup/upgrade 共用),install.sh /
|
||
ps1 / js / event / devapp 的 6 份缓存写逻辑(1.1 矩阵)随 P1/P3 删除;
|
||
upgrade 补齐 mono 缓存刷新(修 `paths.go:292-296` 只刷 multi 的不对称)。
|
||
mono 下线版本再评估整体废弃缓存。
|
||
|
||
### 2.5 市场 skill 边界正式化
|
||
|
||
把"`dingtalk-*` 前缀与 `dws-shared` / `dws` 名称为 DWS 内置保留"从隐性约定
|
||
变成共享常量 + 测试:
|
||
|
||
- `skillhome.ReservedSkillPrefixes = ["dingtalk-"]`、
|
||
`skillhome.ReservedSkillNames = ["dws-shared", "dws"]`,替换
|
||
`skill_setup.go:199/205` 与 `paths.go:332-334` 两份私有拷贝;所有互斥/
|
||
stale 清理只认这两个常量。
|
||
- 测试一:扫描 `skills/multi/` 实际目录名,断言全部命中保留规则(防新增
|
||
产品 skill 破坏前缀约定)。
|
||
- 测试二:市场 skill 安装路径(`skill_command.go:488-498` 的目标解析)若
|
||
产物名命中保留名则拒绝安装——把"市场无同名前缀"从祈祷变成门禁。
|
||
|
||
## 3. 迁移步骤(渐进、不破坏存量用户)
|
||
|
||
| 阶段 | 内容 | 风险 |
|
||
|---|---|---|
|
||
| **P0 清单 + policy** | 建 `internal/skillhome`:AgentHomes(**补 opencode**,修 1.2-1)、布局/互斥/保留名常量;setup/upgrade 切到共享包;脚本清单包标记块;新增 `check-agent-homes-sync.sh` 进 `make policy`;删 install.sh 死代码(1.2-2) | 低。纯收敛不改行为;policy 脚本初期可能误报 → 先 warn-only 跑一个版本再转 hard-fail |
|
||
| **P1 setup 单引擎 + 脚本降级** | setup/upgrade 安装实现合一(互斥清理、stale 语义统一为"引擎内一种",修 1.2-3);install.sh / install.ps1 / install.js / install-skills.sh 改为 bootstrap + 冻结 fallback;install-event/devapp 暂不动 | 中。bootstrap 首版要在三语言 CI 矩阵上验证"引擎失败→fallback"链路;fallback 标记冻结,防止继续演进出第 9 份拷贝 |
|
||
| **P2 state 权威 + 缓存收敛** | state.json 读写进 skillhome,setup/upgrade 记账;缓存加版本戳、写方收敛到 Go、upgrade 补刷 mono 缓存;install-event/devapp 语义收敛(mono+multi 双装改为引擎语义)后同样 bootstrap 化 | 中。存量机器无 state → 磁盘反推逻辑必须有故障注入测试;event/devapp 版本错配场景需保留 zip 直装逃生门 |
|
||
| **P3 删除遗留拷贝** | 删除:脚本侧 6 份缓存写、install.sh/ps1/js 内被引擎接管的安装函数(保留冻结 fallback 一档)、Go 侧 `mutualExclusionVictims` 等被 skillhome 吸收的私有拷贝;观察一个版本后评估 fallback 是否可再降档 | 低-中。每删一处先确认 policy 与测试不再引用;fallback 删除是独立决策,不与本阶段捆绑 |
|
||
|
||
与《迁移计划》的先后关系:本文 P0 即计划 P0c,应**最先做**;P1 与计划
|
||
P0a/P0b 并行不冲突(引擎合一会让 P0a 的 mode-aware upgrade 少写一份代码);
|
||
P2 吸收计划 P0b;P3 在计划 P2 切默认之后执行。
|
||
|
||
## 4. 明确不做
|
||
|
||
- **不重写成 symlink canonical**(canonical 一份 + 各 agent home 软链):
|
||
已随生态分发通道一并评估否决,决策与实测原因见
|
||
《迁移计划》[§7.3](skill-multi-migration-plan.md)(无版本固定、依赖
|
||
Node/GitHub 可达、mono 会被一起发现、悟空 bundled/离线预装覆盖不了;
|
||
其中悟空分发线已于 2026-08-05 下线,该条约束随之消失)。
|
||
本地 symlink 模式(`setup --link`)同样维持计划 §8.2"可选/后置"定位,
|
||
不在本方案内。
|
||
- **不动 `dws-skills.zip` 产物布局**:zip 根 mono 副本 + `mono/` + `multi/`
|
||
双树保持不变(`scripts/release/post-goreleaser.sh:220-248`)。
|
||
- **不动市场 skill**:`dws skill install` 的安装语义、目标解析
|
||
(`skill_command.go:488-498`)不变;2.5 只新增保留名拒绝门禁与测试,
|
||
不改变既有安装行为。
|
||
- **不删 fallback**:脚本侧内嵌拷贝逻辑降级为冻结档保留,不追求"脚本零
|
||
拷贝"的纯净化。
|
||
|
||
## 5. 收益/成本与任务映射
|
||
|
||
### 5.1 收益/成本表
|
||
|
||
| 项 | 现状 | 目标 | 量化收益 |
|
||
|---|---|---|---|
|
||
| agent home 清单 | 15 份拷贝,已漂移(opencode) | 1 份 Go 源 + policy 比对 | 新增 agent 从"改 11 处"变"改 1 处" |
|
||
| 安装/互斥/stale 逻辑 | ≥8 份,4 种语言,语义已分叉 | 1 个 Go 引擎 | 语义变更从 4 语言 × 7 面(本次实证 13 文件 +759 行)变 1 包 |
|
||
| mode 解析 | 4 份,行为细节不一 | 脚本只做透传,引擎一处实现 | 非法值/默认值行为天然一致 |
|
||
| 缓存写 | 6 份,无版本戳,只写不读 | Go 唯一写方 + 版本戳 | 缓存漂移可观测、可判废 |
|
||
| 安装状态 | 无 | state.json 权威 | upgrade 粘性、回滚、drift 检测的前提 |
|
||
| 市场边界 | 隐性约定,2 份前缀拷贝 | 共享常量 + 2 个测试 | 互斥清理误伤市场 skill 的风险归零 |
|
||
| 成本 | — | P0≈1.5d,P1≈3-4d,P2≈2d,P3≈1d | 合计 7.5-8.5 人日;其中 P0/P2 与《迁移计划》P0b/P0c 重叠,净新增约 4-5 人日 |
|
||
|
||
### 5.2 与《迁移计划》§8 任务 ID 映射
|
||
|
||
| 本文阶段 | 对应计划任务 | 关系 |
|
||
|---|---|---|
|
||
| P0 清单 + policy | P0c-1(清单下沉共享包+补 opencode)、P0c-2(check-agent-homes-sync.sh) | 原样采纳,包名定为 `internal/skillhome` |
|
||
| P1 引擎合一 | P0a-1(UpgradeSkillLocations mode-aware)的前置简化 | 引擎合一后 P0a-1 不复写互斥/清理逻辑 |
|
||
| P1 脚本 bootstrap | **取代** P2-2(sh/ps1 multi 真装,1.5d)、P2-3(install.js/install-skills.sh mode 支持,1d) | 脚本不再写安装逻辑,两个任务缩水为"透传 mode + 调引擎 + 冻结 fallback",合计从 2.5d 降至 ~1d |
|
||
| P2 state 权威 | P0b-1(state.json schema+setup 写入)、P0b-2(磁盘反推) | 原样采纳;缓存版本戳与写方收敛为本文新增 |
|
||
| P2 event/devapp 收敛 | 新增(修 1.2-4 语义矛盾) | 依赖 P1 引擎稳定 |
|
||
| P3 删除遗留 | 新增 | 在计划 P2 切默认之后执行 |
|
||
| (不在本文) | P0-3 备份式安装、P0-4 请求头、P1-1 `dws skill mode`、P1-2/P2-1 默认翻转、P2-4 文案 | 仍按计划执行,与本文正交;备份式安装落地时直接写进引擎,天然覆盖所有面 |
|