release-skill 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codebuddy-plugin/plugin.json +4 -2
- package/.codex-plugin/plugin.json +2 -2
- package/.kimi-plugin/plugin.json +1 -1
- package/CHANGELOG.md +41 -0
- package/CONTRIBUTING.md +27 -0
- package/INSTALL.md +95 -139
- package/INSTALL.zh-CN.md +70 -121
- package/README.md +265 -916
- package/README.zh-CN.md +222 -537
- package/adapters/claude/.claude-plugin/marketplace.json +1 -1
- package/adapters/claude/.claude-plugin/plugin.json +1 -1
- package/adapters/claude/bin/release-skill.bundle.mjs +18710 -16694
- package/adapters/claude/schemas/release-plan.schema.json +137 -0
- package/adapters/claude/schemas/release-project.schema.json +93 -0
- package/adapters/claude/schemas/release-run.schema.json +70 -2
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +18710 -16694
- package/adapters/codex/schemas/release-plan.schema.json +137 -0
- package/adapters/codex/schemas/release-project.schema.json +93 -0
- package/adapters/codex/schemas/release-run.schema.json +70 -2
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +18710 -16694
- package/adapters/kimi/schemas/release-plan.schema.json +137 -0
- package/adapters/kimi/schemas/release-project.schema.json +93 -0
- package/adapters/kimi/schemas/release-run.schema.json +70 -2
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +1 -1
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +18710 -16694
- package/adapters/workbuddy/schemas/release-plan.schema.json +137 -0
- package/adapters/workbuddy/schemas/release-project.schema.json +93 -0
- package/adapters/workbuddy/schemas/release-run.schema.json +70 -2
- package/bin/release-skill.bundle.mjs +18710 -16694
- package/package.json +1 -1
- package/schemas/release-plan.schema.json +137 -0
- package/schemas/release-project.schema.json +93 -0
- package/schemas/release-run.schema.json +70 -2
- package/src/adapters/plugin-marketplace.mjs +1602 -605
- package/src/commands/prepare.mjs +441 -32
- package/src/commands/publish.mjs +107 -75
- package/src/commands/reconcile.mjs +92 -327
- package/src/commands/setup.mjs +148 -20
- package/src/commands/verify.mjs +315 -25
- package/src/core/baseline.mjs +21 -1
- package/src/core/checkpoints.mjs +50 -7
- package/src/core/config.mjs +15 -0
- package/src/core/errors.mjs +2 -0
- package/src/core/installation-contract.mjs +341 -0
- package/src/core/plan.mjs +307 -6
- package/src/platforms/codebuddy.mjs +191 -238
- package/src/platforms/codex.mjs +369 -0
- package/src/platforms/kimi.mjs +164 -119
- package/src/platforms/registry.mjs +180 -4
- package/src/producers/build-adapters.mjs +9 -2
package/README.zh-CN.md
CHANGED
|
@@ -2,36 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) · 安装指南:[中文](INSTALL.zh-CN.md) / [English](INSTALL.md)
|
|
4
4
|
|
|
5
|
-
<!-- release-skill:release-version: 0.2.
|
|
6
|
-
面向 Claude Code、Codex 和 Kimi Code 的发布准备工具,完整保留人工维护的文件内容。
|
|
5
|
+
<!-- release-skill:release-version: 0.2.4 -->
|
|
6
|
+
面向 Claude Code、CodeBuddy、WorkBuddy、Codex 和 Kimi Code 的发布准备工具,完整保留人工维护的文件内容。
|
|
7
7
|
|
|
8
|
-
release-skill
|
|
8
|
+
release-skill 帮助维护者回答三个问题:准备发布什么、还有哪些检查未通过、最终发布的内容是什么。它不重新生成、也不回写项目源文件。`prepare` 把每个配置的公开文件复制到隔离快照并验证字节——先冻结并供人工审阅,再从同一份冻结产物发布。`setup` 只显示确定性的 `compactSummary` 审阅视图,完整报告保留在临时会话目录中。
|
|
9
9
|
|
|
10
10
|
<!-- release-skill:managed:start id=latest-release -->
|
|
11
|
-
**0.2.
|
|
11
|
+
**0.2.4** (2026-07-28)
|
|
12
12
|
|
|
13
|
-
v0.2.
|
|
14
|
-
|
|
15
|
-
**新增**
|
|
16
|
-
|
|
17
|
-
- **CodeBuddy 平台人工 attestation 闭环**:CodeBuddy/WorkBuddy 经与 kimi 同构的人工 attestation 闭环接入发布流水线(`publish`/`reconcile`/`verify`)。因 codebuddy CLI 的 marketplace add/install 均无法钉死冻结 ref(无 ref 选项、安装跟踪默认分支/`latest`,已实测),自动化安装检查点无法保证冻结产物同一性。execute 写手动安装 requirement,绝不 exec CLI;observe/verify 消费结构化人工 attestation 并对安装点做只读校验。缺失、过期、不匹配、路径逃逸的 attestation 一律 fail-closed,严重级别与 kimi 一致(发布后验证不可豁免)。双安装通道(均有实测落盘证据):desktop 经 WorkBuddy 桌面端统一市场 `artifact-skill-set` 安装(`installPath` 须含 `/.workbuddy/plugins/marketplaces/artifact-skill-set/plugins/<plugin>` 尾段,段级检查);cli 以隔离 `HOME=<authorityDir>/codebuddy-home` 运行捆绑 CLI(`installPath` 须 containment 于该隔离 home 的市场插件根)。attestation 增加 `installChannel` + `marketplace` 字段并按通道校验。管线路由:平台 id `codebuddy`,distributionType `codebuddy-plugin`,actionType `codebuddy-marketplace-install`,列于 Tier 3(与 kimi 同层);build adapter 保留历史目录名 `workbuddy`(`adapters/workbuddy/`、`.codebuddy-plugin/plugin.json` 清单,字节不变)。
|
|
18
|
-
- **外部独立市场分发形态**:distribution 声明 `marketplaceRepo` 时启用外部形态。prepare 生产循环经 `git ls-remote --symref` 在线冻结外部市场 HEAD(codex 强冻至 commit sha、claude 弱冻至默认分支名),并经 `gh api` 校验外部索引条目(name 匹配、恰一条、claude 形态 `entry.version == 目标版本`);非在线声明外部形态 fail-closed,外部仓库严格只读。冻结动作携带 `repo=marketplaceRepo`、`ref=add-ref`、`marketplaceCommitSha`、`marketplaceLocation=external`、`payloadContract=external-marketplace-v1`;`snapshotPath`/`manifestDigest` 仍绑本单元冻结快照(载荷权威不变)。plan 完整性校验增加外部分支(repo 匹配、`marketplaceLocation`、40-hex `marketplaceCommitSha`、ref 结构安全);kimi/codebuddy 携带 `marketplaceRepo` fail-closed。`plugin-marketplace` 新增外部形态 preflight/observe 分支:`external-marketplace-v1` 走与 `declared-manifest-v1` 相同的整树包含语义(权威为 `.`,宿主新增路径记 `extraInstalledPaths` 而非失败);preflight 跳过快照内市场段,从快照根读 plugin manifest 校验 name/version 与冻结字段;observe 复用既有 strategy 做安装侧条目观察比对(弱冻 claude 版本漂移 fail-closed)。inline/kimi/codebuddy/legacy/`declared-manifest-v1` 分支一字不变。
|
|
13
|
+
v0.2.4 是文档与市场来源整改版本。将默认市场来源纠正为 bundled-family 仓库(ifoohoo/release-skill),消除过时的 v0.1.9 残留,改善 README 双语一致性与导航,并强化版本漂移的防复发门禁。
|
|
19
14
|
|
|
20
15
|
**变更**
|
|
21
16
|
|
|
22
|
-
-
|
|
17
|
+
- **默认市场来源纠正**:所有安装文档现使用 bundled-family 仓库 `ifoohoo/release-skill`,而非外部市场 `ifoohoo/artifact-skill-set`。Claude Code 安装命令改为 `/plugin marketplace add ifoohoo/release-skill`,安装名为 `release-skill@release-skill`。
|
|
18
|
+
- **README 结构优化**:中英文 README 均增加目录、文档导航章节,并重组章节流程(快速开始移至保存契约之前)。相较此前显著缩短。
|
|
19
|
+
- **定位句补全**:README 和根工作区 README 现列出所有支持平台(Claude Code、CodeBuddy、WorkBuddy、Codex、Kimi Code)。
|
|
20
|
+
- **防复发门禁扩展**:`sync-version.mjs` TEXT_TARGETS 现覆盖中英文 README 的 safe-first-command 版本陈述,防止未来 v0.1.9 类漂移。
|
|
23
21
|
|
|
24
22
|
**修复**
|
|
25
23
|
|
|
26
|
-
-
|
|
27
|
-
-
|
|
24
|
+
- **消除 v0.1.9 残留**:两个 README 的 safe-first-command 块现正确引用当前版本(之前停留在 v0.1.9)。
|
|
25
|
+
- **移除易漂移计数**:将 'All four plugin hosts' / '四种插件宿主' 替换为 'All supported plugin hosts' / '各插件宿主'。
|
|
26
|
+
- **根 README 边界修正**:明确 README/INSTALL/CHANGELOG 是人工维护的源文件,references/schemas/adapters/skills 是生成产物。
|
|
27
|
+
- **CONTRIBUTING 更新**:新增'不要直接编辑生成物'章节,说明 references/、schemas/、adapters/、skills/ 的权威来源和再生命令。
|
|
28
|
+
- **AGENTS.md 语言规则调整**:治理规则文件可使用英文;面向用户的文档仍使用中文。
|
|
28
29
|
<!-- release-skill:managed:end id=latest-release -->
|
|
29
30
|
|
|
30
31
|
<!-- release-skill:capability:external-write-boundary -->
|
|
31
|
-
> **当前边界:** v0.2.
|
|
32
|
+
> **当前边界:** v0.2.4 是当前发布版本(v0.2.2 曾处于已发布状态,后因平台验证收敛修复而更新)。
|
|
32
33
|
> v0.1.1 已完成 GitHub 与 npm 的
|
|
33
34
|
> 真实生产发布,是首次生产验证的历史里程碑,并从冻结 Git ref 完成精确 npm
|
|
34
|
-
> 安装及 Claude/Codex
|
|
35
|
+
> 安装及 Claude/Codex 消费者安装验证;"当前发布版本"与"首次生产验证里程碑"
|
|
35
36
|
> 是两个不同的事实,不得混写成同一含义。同一工作流还通过了本地
|
|
36
37
|
> 生产等价协议套件:测试运行真实 release-skill CLI 和冻结制品,Git 目标是
|
|
37
38
|
> 本地 bare remote,`gh`、`npm`、Claude、Codex 使用协议级 fake。该套件没有
|
|
@@ -41,7 +42,7 @@ v0.2.2 闭合 CodeBuddy 平台分发链路并新增外部独立市场分发形
|
|
|
41
42
|
> 远端唯一性检查在 `publish` 全局预检执行。
|
|
42
43
|
|
|
43
44
|
<!-- release-skill:capability:safe-first-command -->
|
|
44
|
-
> **生产路径自 v0.1.1 里程碑起已完成真实生产验证;v0.
|
|
45
|
+
> **生产路径自 v0.1.1 里程碑起已完成真实生产验证;v0.2.4 是当前发布版本。**
|
|
45
46
|
> npm 安装的 CLI 是受支持的用户入口;源码 checkout 保留为开发/贡献者路径。
|
|
46
47
|
>
|
|
47
48
|
> **第一条命令:**
|
|
@@ -55,55 +56,26 @@ v0.2.2 闭合 CodeBuddy 平台分发链路并新增外部独立市场分发形
|
|
|
55
56
|
> --confirm-production <planDigest>`;`bound` 前序公开基线必须使用
|
|
56
57
|
> `prepare --online --production`。没有摘要确认就不会预检或写远端。
|
|
57
58
|
|
|
58
|
-
##
|
|
59
|
-
|
|
60
|
-
release-skill 把发布生命周期建模为一个严格状态机,让每个阶段都有明确的进入和退出条件,且任何阶段都不能跳过。规范定义见 `references/01-state-machine.md`。
|
|
61
|
-
|
|
62
|
-
```text
|
|
63
|
-
DISCOVERED -> ASSESSED -> PREPARED -> APPROVED -> PUBLISHING -> PUBLISHED -> VERIFIED
|
|
64
|
-
异常态:NEEDS_INPUT / BLOCKED / PARTIAL
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
每个 CLI 命令对应一次状态转换:
|
|
68
|
-
|
|
69
|
-
- `help` 检查环境;`setup` 发现项目,并在摘要确认后仅首次创建配置。
|
|
70
|
-
- `assess` 执行只读就绪度评估(`DISCOVERED -> ASSESSED`)。
|
|
71
|
-
- `prepare` 运行验证门、冻结一份不可变发布计划,并把配置的公开文件复制进隔离快照(`ASSESSED -> PREPARED`)。它只写入 `.release-skill/` 目录,从不触碰远端服务。
|
|
72
|
-
- `approve` 记录人工批准,绑定到计划摘要并带 24 小时有效期(`PREPARED -> APPROVED`)。计划一旦变化,批准自动失效。
|
|
73
|
-
- `publish` 按顺序执行外部写操作检查点(`APPROVED -> PUBLISHING -> PUBLISHED`)。
|
|
74
|
-
- `reconcile` 从 `PARTIAL` 恢复;`verify` 在全新隔离环境完成消费者安装验证(`PUBLISHED -> VERIFIED`)。
|
|
59
|
+
## 目录
|
|
75
60
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
release-skill 不重新生成、也不回写项目源文件。`prepare` 从当前工作区把每个公开文件复制到隔离的本地快照,并验证复制前后的字节。README 的 slogan、示例、正文、格式,以及后续任何人工修改都会作为完整文件被保留。
|
|
83
|
-
|
|
84
|
-
- 后续 prepare 重新读取当前文件,不会从模板重建。
|
|
85
|
-
- 快照必须与源文件逐字节一致。
|
|
86
|
-
- 计划变化会产生新的 digest,旧批准不能授权新内容。
|
|
87
|
-
- prepare 后再改源文件,publish 会因 baseline 变化在远端写入前停止。保留修改的正确方式是重新 prepare、重新审阅并重新 approve。
|
|
88
|
-
- 冻结制品被篡改时,publish 会因 snapshot/tarball/Git object 摘要不符停止。
|
|
89
|
-
- 远端 branch、tag、Release 或 npm 版本冲突时交给人工;系统不 force、不覆盖。
|
|
90
|
-
- 只有 `publicFiles` 明确列出的文件会被复制;需要发布的翻译 README、图片、演示文件和链接文档都要显式加入配置。
|
|
91
|
-
- 发布只冻结当前真相:`prepare` 不会刷新或重写人工文档。维护者必须先更新 README、INSTALL 与 CHANGELOG(包括必须与 `package.json` 版本一致的机器可读 `release-skill:release-version` 标记,以及当前包版本的正式 CHANGELOG 标题),再 prepare、审阅和批准。任一文档版本标记或 CHANGELOG 当前版本条目漂移时,发布前门禁失败关闭。
|
|
92
|
-
|
|
93
|
-
保护规则只有一句话:**复制当前事实,冻结已审阅事实,不重写人工事实。**
|
|
61
|
+
- [快速开始](#快速开始)
|
|
62
|
+
- [发布工作流](#发布工作流)
|
|
63
|
+
- [文档导航](#文档导航)
|
|
64
|
+
- [Skills](#skills)
|
|
65
|
+
- [平台分发](#平台分发)
|
|
66
|
+
- [许可证](#许可证)
|
|
94
67
|
|
|
95
68
|
## 快速开始
|
|
96
69
|
|
|
97
|
-
### 安装
|
|
70
|
+
### 安装
|
|
98
71
|
|
|
99
|
-
- Node.js 22
|
|
100
|
-
- Git 2.30+
|
|
101
|
-
- 至少已有一个提交的目标 Git 仓库
|
|
72
|
+
- Node.js 22+、Git 2.30+、至少已有一个提交的目标 Git 仓库。
|
|
102
73
|
|
|
103
|
-
|
|
74
|
+
**npm(推荐):**
|
|
104
75
|
|
|
105
76
|
```bash
|
|
106
77
|
npm install -g release-skill
|
|
78
|
+
release-skill help
|
|
107
79
|
```
|
|
108
80
|
|
|
109
81
|
或免安装直接运行:
|
|
@@ -112,214 +84,179 @@ npm install -g release-skill
|
|
|
112
84
|
npx release-skill help
|
|
113
85
|
```
|
|
114
86
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
release-skill help
|
|
119
|
-
```
|
|
87
|
+
**插件(Claude Code / CodeBuddy / WorkBuddy / Codex):**
|
|
120
88
|
|
|
121
|
-
|
|
89
|
+
Claude Code、CodeBuddy、WorkBuddy 和 Codex 从 bundled-family 市场
|
|
90
|
+
`ifoohoo/release-skill` 安装:
|
|
122
91
|
|
|
123
|
-
四种插件宿主都从统一市场 `ifoohoo/artifact-skill-set` 安装——以 Claude
|
|
124
|
-
Code 会话为例:
|
|
125
|
-
|
|
126
|
-
```
|
|
127
|
-
/plugin marketplace add ifoohoo/artifact-skill-set
|
|
128
|
-
/plugin install release-skill@artifact-skill-set
|
|
129
92
|
```
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
清单,marketplace 索引集中于外部市场仓库。当发布单元的插件 distribution 声明
|
|
133
|
-
`marketplaceRepo` 时,`prepare --online --production` 会冻结外部市场 HEAD
|
|
134
|
-
(Codex 钉 commit sha——强冻结;Claude 钉默认分支名——弱冻结),并以本单元自身
|
|
135
|
-
冻结快照整树校验安装载荷。**发布时序:** 须先发布外部市场索引——其条目版本须
|
|
136
|
-
等于目标发布版本——之后 `prepare` 才能冻结到含该条目的市场 sha。各平台完整命令
|
|
137
|
-
见 [INSTALL.zh-CN.md](INSTALL.zh-CN.md),契约与进阶直接仓库安装方式见
|
|
138
|
-
`references/06-adapter-contract.md` §2.3/§2.4。
|
|
139
|
-
|
|
140
|
-
**开发安装(贡献者回退,从源码 checkout):**
|
|
141
|
-
|
|
142
|
-
```bash
|
|
143
|
-
export RELEASE_SKILL_HOME=/absolute/path/to/release-skill
|
|
144
|
-
cd "$RELEASE_SKILL_HOME"
|
|
145
|
-
npm exec --yes pnpm@10.17.1 -- install --frozen-lockfile
|
|
93
|
+
/plugin marketplace add ifoohoo/release-skill
|
|
94
|
+
/plugin install release-skill@release-skill
|
|
146
95
|
```
|
|
147
96
|
|
|
148
|
-
|
|
97
|
+
> **前置条件:GitHub 访问。** `owner/repo` 简写会让 Claude Code 通过 SSH 克隆。
|
|
98
|
+
> 如不使用 SSH,可传完整 HTTPS 地址——
|
|
99
|
+
> `/plugin marketplace add https://github.com/ifoohoo/release-skill`——
|
|
100
|
+
> 或设置 `CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1`。
|
|
149
101
|
|
|
150
|
-
|
|
102
|
+
**Kimi Code:** Kimi Code 没有市场安装接口,需手动安装并钉死到特定 release
|
|
103
|
+
tag——见 [INSTALL.zh-CN.md](INSTALL.zh-CN.md#安装为-kimi-code-插件)。
|
|
151
104
|
|
|
152
|
-
|
|
153
|
-
.release-skill/*
|
|
154
|
-
!.release-skill/project.yaml
|
|
155
|
-
```
|
|
105
|
+
CodeBuddy、Codex 和 Kimi Code 的完整命令见 [INSTALL.zh-CN.md](INSTALL.zh-CN.md)。
|
|
156
106
|
|
|
157
|
-
###
|
|
107
|
+
### 主流程
|
|
158
108
|
|
|
159
|
-
|
|
109
|
+
按以下顺序执行。步骤 1-4 是安全默认(只读或仅本地);步骤 5-9 需要显式人工门禁。
|
|
160
110
|
|
|
161
111
|
```bash
|
|
112
|
+
CLI=(release-skill) # 或:CLI=(node "$RELEASE_SKILL_HOME/packages/release-skill/bin/release-skill.mjs")
|
|
162
113
|
PROJECT=/absolute/path/to/my-project
|
|
163
|
-
|
|
164
|
-
REPORT="$SETUP_SESSION/discovery.json"
|
|
165
|
-
ANSWERS="$SETUP_SESSION/answers.json"
|
|
166
|
-
BOUND_REPORT="$SETUP_SESSION/bound.json"
|
|
167
|
-
printf 'SETUP_SESSION=%s\nPROJECT=%s\n' "$SETUP_SESSION" "$PROJECT"
|
|
168
|
-
|
|
169
|
-
release-skill setup --root "$PROJECT" --json > "$REPORT" || test "$?" -eq 2
|
|
170
|
-
node -e 'const fs=require("node:fs");const r=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));if(!r.compactSummary){console.error("compactSummary missing");process.exit(2)}process.stdout.write(JSON.stringify(r.compactSummary,null,2)+"\n")' "$REPORT"
|
|
114
|
+
ACTOR=your-name
|
|
171
115
|
```
|
|
172
116
|
|
|
173
|
-
|
|
117
|
+
1. **help** — 环境检查:
|
|
118
|
+
```bash
|
|
119
|
+
"${CLI[@]}" help
|
|
120
|
+
```
|
|
121
|
+
2. **setup** — 首次接入(只读发现,然后 create-once 配置):
|
|
122
|
+
```bash
|
|
123
|
+
SETUP_SESSION="$(mktemp -d "${TMPDIR:-/tmp}/release-setup.XXXXXX")"
|
|
124
|
+
REPORT="$SETUP_SESSION/discovery.json"
|
|
125
|
+
ANSWERS="$SETUP_SESSION/answers.json"
|
|
126
|
+
printf 'SETUP_SESSION=%s\nPROJECT=%s\n' "$SETUP_SESSION" "$PROJECT"
|
|
127
|
+
"${CLI[@]}" setup --root "$PROJECT" --json > "$REPORT" || test "$?" -eq 2
|
|
128
|
+
```
|
|
129
|
+
若 `proposalConflicts` 非空,必须停止并由人工修正冲突的仓库或映射权威。无冲突时
|
|
130
|
+
机械提取 `recommendedAnswers`(不得手写完整 answers):
|
|
131
|
+
```bash
|
|
132
|
+
SETUP_SESSION='<上一步打印的会话目录绝对路径>'
|
|
133
|
+
node -e 'const fs=require("node:fs");const r=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));if((r.proposalConflicts??[]).length){console.error("proposal conflicts require human resolution");process.exit(2)}if(!r.recommendedAnswers){console.error("recommendedAnswers missing");process.exit(2)}fs.writeFileSync(process.argv[2],JSON.stringify(r.recommendedAnswers,null,2)+"\n",{flag:"wx",mode:0o600})' "$REPORT" "$ANSWERS"
|
|
134
|
+
```
|
|
135
|
+
确认绑定后的 `setupDigest` 一次,然后创建配置:
|
|
136
|
+
```bash
|
|
137
|
+
SETUP_SESSION='<会话目录绝对路径>'
|
|
138
|
+
PROJECT='<项目绝对路径>'
|
|
139
|
+
ANSWERS="$SETUP_SESSION/answers.json"
|
|
140
|
+
CREATED_REPORT="$SETUP_SESSION/created.json"
|
|
141
|
+
POST_REPORT="$SETUP_SESSION/post-setup.json"
|
|
142
|
+
ASSESS_REPORT="$SETUP_SESSION/assess.json"
|
|
143
|
+
"${CLI[@]}" setup --root "$PROJECT" --answers "$ANSWERS" \
|
|
144
|
+
--write --confirm-setup <已确认的setupDigest> --json > "$CREATED_REPORT"
|
|
145
|
+
"${CLI[@]}" setup --root "$PROJECT" --json > "$POST_REPORT"
|
|
146
|
+
set +e
|
|
147
|
+
"${CLI[@]}" assess --root "$PROJECT" --offline --json > "$ASSESS_REPORT"
|
|
148
|
+
ASSESS_EXIT=$?
|
|
149
|
+
set -e
|
|
150
|
+
[ "$ASSESS_EXIT" -eq 0 ] || [ "$ASSESS_EXIT" -eq 1 ] || exit "$ASSESS_EXIT"
|
|
151
|
+
node -e 'const fs=require("node:fs");const [c,p,a]=process.argv.slice(1).map(x=>JSON.parse(fs.readFileSync(x,"utf8")));if(c.status!=="CONFIG_CREATED"||p.status!=="ALREADY_CONFIGURED"||!["ASSESSED","NEEDS_INPUT","BLOCKED"].includes(a.status)){process.exit(2)}' "$CREATED_REPORT" "$POST_REPORT" "$ASSESS_REPORT"
|
|
152
|
+
node -e 'require("node:fs").rmSync(process.argv[1],{recursive:true,force:false})' "$SETUP_SESSION"
|
|
153
|
+
```
|
|
154
|
+
写入必须返回 `CONFIG_CREATED`,下一次 setup 必须返回 `ALREADY_CONFIGURED`。
|
|
155
|
+
已有配置永不重新生成,后续只做经审阅的增量编辑。发现的脚本标记为
|
|
156
|
+
`SIDE_EFFECTS_UNPROVEN`。只有在人工审阅之后才添加项目专属 hook 或 gate:
|
|
157
|
+
编辑 `projectConfig.hooks`,或编辑 `verificationGates` 并把同一个 id 加入
|
|
158
|
+
`selectedGateIds`,然后重新运行绑定 dry-run。配置已存在时跳过。
|
|
159
|
+
完整多步流程见 [INSTALL.zh-CN.md](INSTALL.zh-CN.md#首次接入)。
|
|
160
|
+
3. **assess** — 只读就绪评估:
|
|
161
|
+
```bash
|
|
162
|
+
"${CLI[@]}" assess --root "$PROJECT" --offline --json
|
|
163
|
+
```
|
|
164
|
+
4. **prepare** — 本地快照与计划冻结:
|
|
165
|
+
```bash
|
|
166
|
+
"${CLI[@]}" prepare --root "$PROJECT" --offline \
|
|
167
|
+
--acknowledge-hook-side-effects \
|
|
168
|
+
--acknowledge-gate-side-effects --json
|
|
169
|
+
```
|
|
170
|
+
只有项目配置没有对应 hook 或 snapshot gate 时,才省略相应授权参数。授权前必须审阅可执行文件、参数、工作目录和副作用,不能把授权参数当固定样板。
|
|
171
|
+
5. **人工审阅:** 检查 `planPath`、`externalActions`、`targetVersion` 和 `planDigest`。
|
|
172
|
+
6. **prepare --production** — 冻结生产计划:
|
|
173
|
+
```bash
|
|
174
|
+
PLAN_JSON=$("${CLI[@]}" prepare --root "$PROJECT" --online --production \
|
|
175
|
+
--acknowledge-hook-side-effects \
|
|
176
|
+
--acknowledge-gate-side-effects --json)
|
|
177
|
+
PLAN_PATH=$(printf '%s\n' "$PLAN_JSON" | jq -r '.planPath')
|
|
178
|
+
PLAN_DIGEST=$(printf '%s\n' "$PLAN_JSON" | jq -r '.planDigest')
|
|
179
|
+
```
|
|
180
|
+
7. **approve** — 人工批准(24 小时有效期):
|
|
181
|
+
```bash
|
|
182
|
+
APPROVAL_JSON=$("${CLI[@]}" approve --plan "$PLAN_PATH" \
|
|
183
|
+
--digest "$PLAN_DIGEST" --actor "$ACTOR" --json)
|
|
184
|
+
APPROVAL_PATH=$(printf '%s\n' "$APPROVAL_JSON" | jq -r '.approvalPath')
|
|
185
|
+
```
|
|
186
|
+
8. **publish** — 远端写入开始:
|
|
187
|
+
```bash
|
|
188
|
+
PUBLISH_JSON=$("${CLI[@]}" publish --root "$PROJECT" \
|
|
189
|
+
--plan "$PLAN_PATH" --approval "$APPROVAL_PATH" \
|
|
190
|
+
--confirm-production "$PLAN_DIGEST" --json)
|
|
191
|
+
PUBLISH_RUN_PATH=$(printf '%s\n' "$PUBLISH_JSON" | jq -r '.runPath')
|
|
192
|
+
```
|
|
193
|
+
`PUBLISHED` **不是**终态。
|
|
194
|
+
9. **verify** — 消费者安装检查:
|
|
195
|
+
```bash
|
|
196
|
+
"${CLI[@]}" verify --root "$PROJECT" \
|
|
197
|
+
--plan "$PLAN_PATH" --run "$PUBLISH_RUN_PATH" \
|
|
198
|
+
--acknowledge-gate-side-effects --json
|
|
199
|
+
```
|
|
174
200
|
|
|
175
|
-
|
|
201
|
+
示例需要 `jq`。没有 jq 时,直接复制返回的 JSON 字段;不要把尖括号占位符当作 shell 语法。
|
|
176
202
|
|
|
177
|
-
|
|
178
|
-
SETUP_SESSION='/上一步打印的会话目录绝对路径'
|
|
179
|
-
PROJECT='/上一步打印的项目绝对路径'
|
|
180
|
-
REPORT="$SETUP_SESSION/discovery.json"
|
|
181
|
-
ANSWERS="$SETUP_SESSION/answers.json"
|
|
182
|
-
BOUND_REPORT="$SETUP_SESSION/bound.json"
|
|
183
|
-
node -e 'const fs=require("node:fs");const r=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));if((r.proposalConflicts??[]).length){console.error("proposal conflicts require human resolution");process.exit(2)}if(!r.recommendedAnswers){console.error("recommendedAnswers missing");process.exit(2)}fs.writeFileSync(process.argv[2],JSON.stringify(r.recommendedAnswers,null,2)+"\n",{flag:"wx",mode:0o600})' "$REPORT" "$ANSWERS"
|
|
184
|
-
|
|
185
|
-
release-skill setup --root "$PROJECT" --answers "$ANSWERS" --json > "$BOUND_REPORT"
|
|
186
|
-
node -e 'const fs=require("node:fs");const r=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));if(!r.compactSummary||!r.setupDigest){console.error("bound setup report incomplete");process.exit(2)}process.stdout.write(JSON.stringify({compactSummary:r.compactSummary,setupDigest:r.setupDigest},null,2)+"\n")' "$BOUND_REPORT"
|
|
187
|
-
printf 'SETUP_SESSION=%s\nPROJECT=%s\n' "$SETUP_SESSION" "$PROJECT"
|
|
188
|
-
```
|
|
203
|
+
### PARTIAL 恢复与 reconcile
|
|
189
204
|
|
|
190
|
-
|
|
205
|
+
当 `publish` 在部分检查点成功但在其他检查点失败时,运行进入 `PARTIAL` 状态。**不要从头重跑,也不要删除远端状态。**
|
|
191
206
|
|
|
192
207
|
```bash
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
--
|
|
201
|
-
|
|
202
|
-
set +e
|
|
203
|
-
release-skill assess --root "$PROJECT" --offline --json > "$ASSESS_REPORT"
|
|
204
|
-
ASSESS_EXIT=$?
|
|
205
|
-
set -e
|
|
206
|
-
[ "$ASSESS_EXIT" -eq 0 ] || [ "$ASSESS_EXIT" -eq 1 ] || exit "$ASSESS_EXIT"
|
|
207
|
-
node -e 'const fs=require("node:fs");const [c,p,a]=process.argv.slice(1).map(x=>JSON.parse(fs.readFileSync(x,"utf8")));if(c.status!=="CONFIG_CREATED"||p.status!=="ALREADY_CONFIGURED"||!["ASSESSED","NEEDS_INPUT","BLOCKED"].includes(a.status)){process.exit(2)}process.stdout.write(JSON.stringify({created:c.status,postSetup:p.status,assessment:{status:a.status,summary:a.summary,gapCount:(a.gaps??[]).length,blockingCodes:(a.gaps??[]).filter(g=>g.severity==="error").map(g=>g.code)}},null,2)+"\n")' "$CREATED_REPORT" "$POST_REPORT" "$ASSESS_REPORT"
|
|
208
|
-
node -e 'require("node:fs").rmSync(process.argv[1],{recursive:true,force:false})' "$SETUP_SESSION"
|
|
208
|
+
RECONCILE_JSON=$("${CLI[@]}" reconcile --root "$PROJECT" \
|
|
209
|
+
--run "$PUBLISH_RUN_PATH" \
|
|
210
|
+
--plan "$PLAN_PATH" \
|
|
211
|
+
--approval "$APPROVAL_PATH" \
|
|
212
|
+
--confirm-production "$PLAN_DIGEST" --json)
|
|
213
|
+
RECONCILE_RUN_PATH=$(printf '%s\n' "$RECONCILE_JSON" | jq -r '.runPath')
|
|
214
|
+
"${CLI[@]}" verify --root "$PROJECT" \
|
|
215
|
+
--plan "$PLAN_PATH" --run "$RECONCILE_RUN_PATH" \
|
|
216
|
+
--acknowledge-gate-side-effects --json
|
|
209
217
|
```
|
|
210
218
|
|
|
211
|
-
|
|
219
|
+
`reconcile` 查询实际远端状态,跳过已一致步骤,只重试安全未完成的动作。远端冲突需人工决策。reconcile 成功只返回 `PUBLISHED`,不返回 `VERIFIED`。
|
|
212
220
|
|
|
213
|
-
|
|
221
|
+
## 发布工作流
|
|
214
222
|
|
|
215
|
-
|
|
223
|
+
release-skill 把发布生命周期建模为严格状态机(规范定义见 `references/01-state-machine.md`):
|
|
216
224
|
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
"apiVersion": "release-skill/v1",
|
|
221
|
-
"kind": "ReleaseProject",
|
|
222
|
-
"project": { "name": "my-project", "defaultBranch": "main" },
|
|
223
|
-
"releaseUnits": [{
|
|
224
|
-
"id": "my-project",
|
|
225
|
-
"source": ".",
|
|
226
|
-
"publicRepo": "owner/my-project",
|
|
227
|
-
"version": { "source": "package.json", "tagTemplate": "v{version}" },
|
|
228
|
-
"distributions": [{
|
|
229
|
-
"type": "npm",
|
|
230
|
-
"package": "my-project",
|
|
231
|
-
"access": "public",
|
|
232
|
-
"provenance": false,
|
|
233
|
-
"tag": "latest",
|
|
234
|
-
"registry": "https://registry.npmjs.org",
|
|
235
|
-
"publisher": "my-npm-username"
|
|
236
|
-
}],
|
|
237
|
-
"publicFiles": [
|
|
238
|
-
{ "from": "README.md", "to": "README.md", "mode": "preserve" },
|
|
239
|
-
{ "from": "package.json", "to": "package.json", "mode": "preserve" }
|
|
240
|
-
],
|
|
241
|
-
"requiredPublicFiles": ["README.md", "package.json"],
|
|
242
|
-
"previousPublicBaseline": { "mode": "none" },
|
|
243
|
-
"production": {
|
|
244
|
-
"branchTemplate": "release/{tag}",
|
|
245
|
-
"branchStrategy": "create-release-branch"
|
|
246
|
-
}
|
|
247
|
-
}]
|
|
248
|
-
},
|
|
249
|
-
"selectedGateIds": []
|
|
250
|
-
}
|
|
225
|
+
```text
|
|
226
|
+
DISCOVERED -> ASSESSED -> PREPARED -> APPROVED -> PUBLISHING -> PUBLISHED -> VERIFIED
|
|
227
|
+
异常态:NEEDS_INPUT / BLOCKED / PARTIAL
|
|
251
228
|
```
|
|
252
229
|
|
|
253
|
-
|
|
230
|
+
每个 CLI 命令对应一次状态转换。`PUBLISHED` **不是**终态——只有全新运行的 `verify` 确认远端状态和消费者安装与冻结计划一致时,才到达 `VERIFIED`。
|
|
254
231
|
|
|
255
|
-
|
|
232
|
+
**保存契约:** release-skill 不重新生成或回写项目源文件。`prepare` 把每个配置的公开文件复制到隔离快照并验证字节。后续 prepare 重新读取当前文件,不会从模板重建。只有 `publicFiles` 列出的文件会被复制。`prepare` 不会刷新或重写人工文档——维护者先更新 README、INSTALL 和 CHANGELOG,再 prepare、审阅和批准。
|
|
256
233
|
|
|
257
|
-
|
|
258
|
-
{
|
|
259
|
-
"projectConfig": {
|
|
260
|
-
"apiVersion": "release-skill/v1",
|
|
261
|
-
"kind": "ReleaseProject",
|
|
262
|
-
"project": { "name": "my-project", "defaultBranch": "main" },
|
|
263
|
-
"releaseUnits": [{
|
|
264
|
-
"id": "my-project",
|
|
265
|
-
"source": ".",
|
|
266
|
-
"publicRepo": "owner/my-project",
|
|
267
|
-
"version": { "source": "package.json", "tagTemplate": "v{version}" },
|
|
268
|
-
"distributions": [{
|
|
269
|
-
"type": "npm",
|
|
270
|
-
"package": "my-project",
|
|
271
|
-
"access": "public",
|
|
272
|
-
"provenance": false,
|
|
273
|
-
"tag": "latest",
|
|
274
|
-
"registry": "https://registry.npmjs.org",
|
|
275
|
-
"publisher": "my-npm-username"
|
|
276
|
-
}],
|
|
277
|
-
"publicFiles": [
|
|
278
|
-
{ "from": "package.json", "to": "package.json", "mode": "preserve" }
|
|
279
|
-
],
|
|
280
|
-
"requiredPublicFiles": ["package.json"],
|
|
281
|
-
"previousPublicBaseline": { "mode": "none" },
|
|
282
|
-
"production": {
|
|
283
|
-
"branchTemplate": "release/{tag}",
|
|
284
|
-
"branchStrategy": "create-release-branch"
|
|
285
|
-
}
|
|
286
|
-
}],
|
|
287
|
-
"verificationGates": [{
|
|
288
|
-
"id": "my-project-script-test",
|
|
289
|
-
"phase": "snapshot-verify",
|
|
290
|
-
"scope": { "unit": "my-project" },
|
|
291
|
-
"command": ["node", "-e", "const p=require('./package.json');if(!p.name)process.exit(1)"],
|
|
292
|
-
"cwd": ".",
|
|
293
|
-
"timeoutMs": 30000,
|
|
294
|
-
"envAllowlist": []
|
|
295
|
-
}]
|
|
296
|
-
},
|
|
297
|
-
"selectedGateIds": ["my-project-script-test"]
|
|
298
|
-
}
|
|
299
|
-
```
|
|
234
|
+
**写入安全:** `setup` 默认只读(摘要确认后仅首次创建配置)。`prepare` 只写 `.release-skill/`。`publish` 是生产写入入口,需要同时提供批准和当前计划摘要。项目 hook 和 gate 是已确认的本地进程,没有操作系统沙箱。
|
|
300
235
|
|
|
301
|
-
|
|
236
|
+
## 文档导航
|
|
302
237
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
238
|
+
| 文档 | 说明 |
|
|
239
|
+
|---|---|
|
|
240
|
+
| [INSTALL.md](INSTALL.md) / [INSTALL.zh-CN.md](INSTALL.zh-CN.md) | 完整安装指南:npm、插件、源码 checkout、setup 流程、分支策略 |
|
|
241
|
+
| [CHANGELOG.md](CHANGELOG.md) | 发布历史 |
|
|
242
|
+
| [CONTRIBUTING.md](CONTRIBUTING.md) | 贡献指南(含生成产物规则) |
|
|
243
|
+
| [SECURITY.md](SECURITY.md) | 安全策略 |
|
|
244
|
+
| `references/01-state-machine.md` | 规范状态机定义 |
|
|
245
|
+
| `references/02-project-config.md` | 项目配置 schema 参考 |
|
|
246
|
+
| `references/05-evidence-and-errors.md` | 证据格式和错误码 |
|
|
247
|
+
| `references/06-adapter-contract.md` | 适配器和市场契约详情 |
|
|
248
|
+
| [GitHub Issues](https://github.com/ifoohoo/release-skill/issues) | 问题报告和功能请求 |
|
|
310
249
|
|
|
311
|
-
|
|
250
|
+
## 配置
|
|
312
251
|
|
|
313
|
-
|
|
252
|
+
最小人工编写配置(完整 schema 和 setup 流程见 [INSTALL.zh-CN.md](INSTALL.zh-CN.md)):
|
|
314
253
|
|
|
315
254
|
```yaml
|
|
316
255
|
apiVersion: release-skill/v1
|
|
317
256
|
kind: ReleaseProject
|
|
318
|
-
|
|
319
257
|
project:
|
|
320
258
|
name: my-project
|
|
321
259
|
defaultBranch: main
|
|
322
|
-
|
|
323
260
|
releaseUnits:
|
|
324
261
|
- id: my-project
|
|
325
262
|
source: .
|
|
@@ -334,165 +271,23 @@ releaseUnits:
|
|
|
334
271
|
- from: package.json
|
|
335
272
|
to: package.json
|
|
336
273
|
mode: preserve
|
|
337
|
-
|
|
338
|
-
to: LICENSE
|
|
339
|
-
mode: preserve
|
|
340
|
-
requiredPublicFiles: [README.md, LICENSE, package.json]
|
|
274
|
+
requiredPublicFiles: [README.md, package.json]
|
|
341
275
|
previousPublicBaseline:
|
|
342
|
-
mode: none
|
|
276
|
+
mode: none
|
|
343
277
|
distributions:
|
|
344
278
|
- type: npm
|
|
345
279
|
package: my-project
|
|
346
|
-
access: public
|
|
347
|
-
provenance: false
|
|
280
|
+
access: public
|
|
281
|
+
provenance: false
|
|
348
282
|
tag: latest
|
|
349
283
|
registry: https://registry.npmjs.org
|
|
350
284
|
publisher: my-npm-username
|
|
351
|
-
# 可选:CLI smoke 验证。配置 smokeBin 后,verify 会在隔离目录
|
|
352
|
-
# 安装该包并运行指定二进制。不配置 smokeBin 时,verify 只确认
|
|
353
|
-
# 安装与 name/version。
|
|
354
|
-
# smokeBin: my-project
|
|
355
|
-
# smokeArgs: [help, --json]
|
|
356
|
-
# smokeExpectedJson:
|
|
357
|
-
# command: help
|
|
358
|
-
# status: READY
|
|
359
285
|
production:
|
|
360
286
|
branchTemplate: release/{tag}
|
|
361
287
|
branchStrategy: create-release-branch
|
|
362
|
-
releaseTitleTemplate: "{unit} {version}"
|
|
363
|
-
releaseNotes: "人工维护的发布说明"
|
|
364
288
|
```
|
|
365
289
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
```yaml
|
|
369
|
-
previousPublicBaseline:
|
|
370
|
-
mode: bound
|
|
371
|
-
repo: owner/my-project
|
|
372
|
-
ref: release/v0.9.0
|
|
373
|
-
commit: 0123456789abcdef0123456789abcdef01234567
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
`none` 不是绕过冲突检查的手段:publish 仍会在任何写入前检查目标 branch、tag、GitHub Release 与 npm 版本的唯一性。bound 模式的生产 prepare 必须在线运行,以便观察 ref 到 commit 的映射。默认观察器不下载远端文件内容,因此它报告映射差异并标记内容差异不可用。发生漂移时停止,由人工选择 `merge`、`adopt` 或 `reject`。先获取并审阅真实远端 commit;工具不会下载或合并其文件。`merge` 在人工所有的来源中保留本地与远端双方修改;`adopt` 把审阅过的远端字节复制进该来源;`reject` 在调查或修正远端/ref 期间停止本次发布;永远不要为了绕过漂移而改回 `mode: none`。`merge` 或 `adopt` 之后,把 `previousPublicBaseline` 重新绑定到已接受的不可变 `repo`/`ref`/`commit`,再运行新的 `prepare --online --production`、审阅并批准。
|
|
377
|
-
|
|
378
|
-
分支策略应与真实仓库匹配(`create-release-branch`、`advance-existing-branch`、`initialize-default-branch`);三种策略的最小配置示例见[英文 README](README.md)。
|
|
379
|
-
|
|
380
|
-
### 主流程
|
|
381
|
-
|
|
382
|
-
按以下顺序执行。步骤 1–4 是安全默认(只读或仅本地);步骤 5–9 是需要显式人工门禁的生产发布。
|
|
383
|
-
|
|
384
|
-
```bash
|
|
385
|
-
# npm 安装的 CLI(推荐):
|
|
386
|
-
CLI=(release-skill)
|
|
387
|
-
PROJECT=/absolute/path/to/my-project
|
|
388
|
-
ACTOR=your-name
|
|
389
|
-
# 开发回退(源码 checkout):
|
|
390
|
-
# CLI=(node "$RELEASE_SKILL_HOME/packages/release-skill/bin/release-skill.mjs")
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
1. **环境检查:**
|
|
394
|
-
```bash
|
|
395
|
-
"${CLI[@]}" help
|
|
396
|
-
```
|
|
397
|
-
2. **首次接入(仅缺少配置时,只读):**
|
|
398
|
-
```bash
|
|
399
|
-
"${CLI[@]}" setup --root "$PROJECT" --json
|
|
400
|
-
```
|
|
401
|
-
按上文机械提取 `compactSummary` 与 `recommendedAnswers`,只确认一次绑定后的 `setupDigest`;配置已存在时跳过。
|
|
402
|
-
3. **就绪评估(只读):**
|
|
403
|
-
```bash
|
|
404
|
-
"${CLI[@]}" assess --root "$PROJECT" --offline --json
|
|
405
|
-
```
|
|
406
|
-
4. **本地快照与计划冻结:**
|
|
407
|
-
```bash
|
|
408
|
-
"${CLI[@]}" prepare --root "$PROJECT" --offline \
|
|
409
|
-
--acknowledge-hook-side-effects \
|
|
410
|
-
--acknowledge-gate-side-effects --json
|
|
411
|
-
```
|
|
412
|
-
只有项目配置没有对应 hook 或 snapshot gate 时,才省略相应授权参数。授权前必须审阅可执行文件、参数、工作目录和副作用,不能把授权参数当固定样板。
|
|
413
|
-
5. **人工审阅:** 检查返回的 `planPath`、`externalActions`、`units[].targetVersion` 和 `planDigest`。每个发布单元的快照位于 `<evidenceDir>/snapshots/<unit-id>/`。
|
|
414
|
-
6. **生产计划冻结:**
|
|
415
|
-
```bash
|
|
416
|
-
PRODUCTION_JSON=$("${CLI[@]}" prepare --root "$PROJECT" --online --production \
|
|
417
|
-
--acknowledge-hook-side-effects \
|
|
418
|
-
--acknowledge-gate-side-effects --json)
|
|
419
|
-
printf '%s\n' "$PRODUCTION_JSON" | jq .
|
|
420
|
-
PLAN_PATH=$(printf '%s\n' "$PRODUCTION_JSON" | jq -r '.planPath')
|
|
421
|
-
PLAN_DIGEST=$(printf '%s\n' "$PRODUCTION_JSON" | jq -r '.planDigest')
|
|
422
|
-
```
|
|
423
|
-
同样,只省略配置不需要的授权,并在授权前逐项审阅项目进程。`prepare --json` 返回的生产权威 `planPath` 指向 `<项目>/.release-skill/plans/<planDigest>.json`,后续必须始终沿用这个返回值。`.release-skill/release-plan.json` 只是可变便利副本,不得传给生产 approve/publish/reconcile。
|
|
424
|
-
7. **批准:**
|
|
425
|
-
```bash
|
|
426
|
-
APPROVAL_JSON=$("${CLI[@]}" approve --plan "$PLAN_PATH" \
|
|
427
|
-
--digest "$PLAN_DIGEST" --actor "$ACTOR" --json)
|
|
428
|
-
printf '%s\n' "$APPROVAL_JSON" | jq .
|
|
429
|
-
APPROVAL_PATH=$(printf '%s\n' "$APPROVAL_JSON" | jq -r '.approvalPath')
|
|
430
|
-
```
|
|
431
|
-
批准 24 小时失效;`--actor` 只是未经认证的本地审计标签。后续必须使用返回的 immutable `approvalPath` 和 `expiresAt`。
|
|
432
|
-
8. **发布(从此开始写远端):**
|
|
433
|
-
```bash
|
|
434
|
-
PUBLISH_JSON=$("${CLI[@]}" publish --root "$PROJECT" \
|
|
435
|
-
--plan "$PLAN_PATH" --approval "$APPROVAL_PATH" \
|
|
436
|
-
--confirm-production "$PLAN_DIGEST" --json)
|
|
437
|
-
printf '%s\n' "$PUBLISH_JSON" | jq .
|
|
438
|
-
PUBLISH_RUN_PATH=$(printf '%s\n' "$PUBLISH_JSON" | jq -r '.runPath')
|
|
439
|
-
```
|
|
440
|
-
保存返回的 `runPath`。`PUBLISHED` **不是**终态。
|
|
441
|
-
9. **验证(消费者安装检查):**
|
|
442
|
-
```bash
|
|
443
|
-
"${CLI[@]}" verify --root "$PROJECT" \
|
|
444
|
-
--plan "$PLAN_PATH" --run "$PUBLISH_RUN_PATH" \
|
|
445
|
-
--acknowledge-gate-side-effects --json
|
|
446
|
-
```
|
|
447
|
-
只有计划既没有 consumer gate,也没有 npm `smokeBin` 时才省略授权。
|
|
448
|
-
|
|
449
|
-
生产 prepare 会把每个公开快照封存为独立 Git commit/tree,并为 npm 单元生成固定 tarball。`publish` 先对所有动作做只读预检,再按“公开快照 branch → tag → npm → GitHub Release → Claude/Codex 插件市场安装”执行并逐项观察。Kimi Code 没有可脚本化的安装接口,其检查点**失败关闭**:`publish` 在完成自动化写入后落入 `PARTIAL`,并产出版本钉死的手动安装要求。操作者随后用 requirement 给出的隔离 `KIMI_CODE_HOME` 启动 Kimi Code,运行钉死的 `/plugins install <release-tag URL>`,把可信证明(同时绑定冻结**计划**摘要与快照**载荷**摘要)写入按计划摘要命名的目录 `.release-skill/kimi-attestations/<planDigest>/<plugin>/`,再运行 `reconcile`(→ `PUBLISHED`)与 `verify`(→ `VERIFIED`);两者都从同一稳定位置读取证明。安装到日常 `~/.kimi-code` 不被接受。完整流程与证明 JSON 字段见 `INSTALL.zh-CN.md`。`verify` 在隔离目录安装每一个精确 npm `package@version`;配置 `smokeBin` 后还会运行 CLI 并校验输出。只有全部证据与冻结计划一致才进入 `VERIFIED`。默认分支名由每个 unit 的 `production.branchTemplate` 配置;同名远端对象存在时停止,交由人工判断。
|
|
450
|
-
|
|
451
|
-
### 发布文档刷新(可选)
|
|
452
|
-
|
|
453
|
-
发布单元可以声明 `releaseDocuments`,用一份结构化双语说明源确定性刷新 README 受管区域和 CHANGELOG 当前版本条目。核心 CLI 完全离线运行:不联网、不调用大模型、不自动翻译;只改写声明过的受管区域、唯一版本标记的机器值和 CHANGELOG 当前版本受管条目,区域外字节逐字保留。`prepare` 只检查新鲜度,不写工作树。
|
|
454
|
-
|
|
455
|
-
```yaml
|
|
456
|
-
# .release-skill/project.yaml(发布单元片段)
|
|
457
|
-
releaseUnits:
|
|
458
|
-
- id: my-project
|
|
459
|
-
source: .
|
|
460
|
-
releaseDocuments:
|
|
461
|
-
notesSource: release-notes/{version}.yaml
|
|
462
|
-
locales: [en, zh-CN]
|
|
463
|
-
changelogs:
|
|
464
|
-
- path: CHANGELOG.md
|
|
465
|
-
locale: en
|
|
466
|
-
readmes:
|
|
467
|
-
- path: README.md
|
|
468
|
-
locale: en
|
|
469
|
-
regions: [latest-release]
|
|
470
|
-
versionMarkers:
|
|
471
|
-
- id: current-version
|
|
472
|
-
pattern: '<!-- release-skill:version -->v{version}<!-- /release-skill:version -->'
|
|
473
|
-
- path: README.zh-CN.md
|
|
474
|
-
locale: zh-CN
|
|
475
|
-
regions: [latest-release]
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
1. **只读演练:**
|
|
479
|
-
```bash
|
|
480
|
-
"${CLI[@]}" docs refresh --root "$PROJECT" --unit my-project --json
|
|
481
|
-
```
|
|
482
|
-
2. **摘要确认的本地写入(仅在用户明确授权“本地发布文档写入”后执行):**
|
|
483
|
-
```bash
|
|
484
|
-
"${CLI[@]}" docs refresh --root "$PROJECT" --unit my-project \
|
|
485
|
-
--write --confirm-refresh <refreshDigest> \
|
|
486
|
-
--ack-local-document-write --json
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
该授权只覆盖声明的本地发布文档目标,不是 hook、Git 提交、push、publish 或安装的授权:维护者必须审阅刷新结果并提交,然后重新 `prepare`。
|
|
490
|
-
|
|
491
|
-
### 父工作空间 + npm 子单元 + 插件子单元
|
|
492
|
-
|
|
493
|
-
当 monorepo 从不同目录同时产出 npm 包和 Claude/Codex/Kimi Code 插件时,应定义独立的发布单元。只有当某个单元确实以 manifest、marketplace 和 entry Skill 的形式发布插件时,才为其添加插件分发:
|
|
494
|
-
|
|
495
|
-
这里的 `project` 是父工作空间的编排容器,不是公开发布单元。如果工作区根目录也发布自己的仓库或包,再添加一个 `source: .` 的发布单元。`version.source` 相对于该发布单元的 `source` 目录解析(`version.source` is resolved relative to that release unit's `source` directory):因此 `source: packages/app` 的单元写裸 `package.json`,而不是 `packages/app/package.json`。
|
|
290
|
+
`version.source` 相对于该发布单元的 `source` 目录解析(`version.source` is resolved relative to that release unit's `source` directory)。monorepo 中 npm 和插件分开发布时定义多个发布单元:
|
|
496
291
|
|
|
497
292
|
```yaml
|
|
498
293
|
apiVersion: release-skill/v1
|
|
@@ -500,7 +295,6 @@ kind: ReleaseProject
|
|
|
500
295
|
project:
|
|
501
296
|
name: my-workspace
|
|
502
297
|
defaultBranch: main
|
|
503
|
-
|
|
504
298
|
releaseUnits:
|
|
505
299
|
- id: my-app
|
|
506
300
|
source: packages/app
|
|
@@ -516,28 +310,16 @@ releaseUnits:
|
|
|
516
310
|
tag: latest
|
|
517
311
|
registry: https://registry.npmjs.org
|
|
518
312
|
publisher: my-npm-username
|
|
519
|
-
smokeBin: my-app
|
|
520
|
-
smokeArgs: [help, --json]
|
|
521
|
-
smokeExpectedJson:
|
|
522
|
-
command: help
|
|
523
|
-
status: READY
|
|
524
313
|
publicFiles:
|
|
525
|
-
- from: packages/app/README.md
|
|
526
|
-
to: README.md
|
|
527
|
-
mode: preserve
|
|
528
314
|
- from: packages/app/package.json
|
|
529
315
|
to: package.json
|
|
530
316
|
mode: preserve
|
|
531
|
-
|
|
532
|
-
to: LICENSE
|
|
533
|
-
mode: preserve
|
|
534
|
-
requiredPublicFiles: [README.md, package.json, LICENSE]
|
|
317
|
+
requiredPublicFiles: [package.json]
|
|
535
318
|
previousPublicBaseline:
|
|
536
319
|
mode: none
|
|
537
320
|
production:
|
|
538
321
|
branchTemplate: release/{tag}
|
|
539
|
-
|
|
540
|
-
|
|
322
|
+
branchStrategy: create-release-branch
|
|
541
323
|
- id: my-plugin
|
|
542
324
|
source: packages/plugin
|
|
543
325
|
publicRepo: owner/my-plugin
|
|
@@ -545,114 +327,63 @@ releaseUnits:
|
|
|
545
327
|
source: package.json
|
|
546
328
|
tagTemplate: my-plugin-v{version}
|
|
547
329
|
distributions:
|
|
548
|
-
# 只有当单元确实发布插件时才声明插件消费者。
|
|
549
|
-
# CLI smoke 是独立的;只有当插件包同时暴露 CLI 二进制时才声明 smokeBin。
|
|
550
330
|
- type: claude-plugin
|
|
551
331
|
plugin: my-plugin
|
|
552
332
|
marketplace: my-plugin
|
|
553
333
|
entrySkill: my-plugin-help
|
|
554
|
-
|
|
555
|
-
- type: codex-plugin
|
|
556
|
-
plugin: my-plugin
|
|
557
|
-
marketplace: my-plugin
|
|
558
|
-
entrySkill: my-plugin-help
|
|
559
|
-
timeoutMs: 300000 # 可选;范围 30000-900000;默认 300000
|
|
560
|
-
- type: kimi-plugin
|
|
561
|
-
plugin: my-plugin
|
|
562
|
-
entrySkill: my-plugin-help
|
|
563
|
-
timeoutMs: 300000 # 可选;范围 30000-900000;默认 300000(Kimi 无安装命令;仅约束只读验证)
|
|
334
|
+
marketplaceSourceType: bundled-family
|
|
564
335
|
publicFiles:
|
|
565
|
-
- from: packages/plugin/.claude-plugin/plugin.json
|
|
566
|
-
to: .claude-plugin/plugin.json
|
|
567
|
-
mode: preserve
|
|
568
|
-
- from: packages/plugin/.claude-plugin/marketplace.json
|
|
569
|
-
to: .claude-plugin/marketplace.json
|
|
570
|
-
mode: preserve
|
|
571
|
-
- from: packages/plugin/.codex-plugin/plugin.json
|
|
572
|
-
to: .codex-plugin/plugin.json
|
|
573
|
-
mode: preserve
|
|
574
|
-
- from: packages/plugin/.kimi-plugin/plugin.json
|
|
575
|
-
to: .kimi-plugin/plugin.json
|
|
576
|
-
mode: preserve
|
|
577
|
-
- from: packages/plugin/.agents/plugins/marketplace.json
|
|
578
|
-
to: .agents/plugins/marketplace.json
|
|
579
|
-
mode: preserve
|
|
580
|
-
- from: packages/plugin/skills/my-plugin-help/SKILL.md
|
|
581
|
-
to: skills/my-plugin-help/SKILL.md
|
|
582
|
-
mode: preserve
|
|
583
|
-
- from: packages/plugin/README.md
|
|
584
|
-
to: README.md
|
|
585
|
-
mode: preserve
|
|
586
336
|
- from: packages/plugin/package.json
|
|
587
337
|
to: package.json
|
|
588
338
|
mode: preserve
|
|
589
|
-
|
|
590
|
-
to: LICENSE
|
|
591
|
-
mode: preserve
|
|
592
|
-
requiredPublicFiles:
|
|
593
|
-
- .claude-plugin/plugin.json
|
|
594
|
-
- .claude-plugin/marketplace.json
|
|
595
|
-
- .codex-plugin/plugin.json
|
|
596
|
-
- .kimi-plugin/plugin.json
|
|
597
|
-
- .agents/plugins/marketplace.json
|
|
598
|
-
- skills/my-plugin-help/SKILL.md
|
|
599
|
-
- README.md
|
|
600
|
-
- package.json
|
|
601
|
-
- LICENSE
|
|
339
|
+
requiredPublicFiles: [package.json]
|
|
602
340
|
previousPublicBaseline:
|
|
603
341
|
mode: none
|
|
604
342
|
production:
|
|
605
343
|
branchTemplate: release/{tag}
|
|
606
|
-
|
|
344
|
+
branchStrategy: create-release-branch
|
|
607
345
|
```
|
|
608
346
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
插件分发可以声明 `timeoutMs`(范围 30,000–900,000 ms;默认 300,000 ms),用于 marketplace add、插件安装与插件列表命令的子进程超时。真实网络下这些命令可能需要 40–105 秒;默认 300 秒超时可以避免误报 `PARTIAL`。解析后的值会冻结进计划,并随其他动作参数一起批准。没有 `timeoutMs` 的旧计划在执行时按 300,000 ms 兼容处理。
|
|
612
|
-
|
|
613
|
-
### PARTIAL 恢复与 reconcile
|
|
614
|
-
|
|
615
|
-
当 `publish` 在部分检查点成功但在其他检查点失败时,运行进入 `PARTIAL` 状态。**不要从头重跑,也不要删除远端状态。**
|
|
347
|
+
在提取出的 `recommendedAnswers` 中添加 gate:编辑 `verificationGates` 并在 `selectedGateIds` 中绑定同一 id:
|
|
616
348
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
"
|
|
628
|
-
|
|
629
|
-
|
|
349
|
+
```json
|
|
350
|
+
{
|
|
351
|
+
"projectConfig": {
|
|
352
|
+
"apiVersion": "release-skill/v1",
|
|
353
|
+
"kind": "ReleaseProject",
|
|
354
|
+
"project": { "name": "my-project", "defaultBranch": "main" },
|
|
355
|
+
"releaseUnits": [{
|
|
356
|
+
"id": "my-project",
|
|
357
|
+
"source": ".",
|
|
358
|
+
"publicRepo": "owner/my-project",
|
|
359
|
+
"version": { "source": "package.json", "tagTemplate": "v{version}" },
|
|
360
|
+
"distributions": [{
|
|
361
|
+
"type": "npm", "package": "my-project", "access": "public",
|
|
362
|
+
"provenance": false, "tag": "latest",
|
|
363
|
+
"registry": "https://registry.npmjs.org", "publisher": "my-npm-username"
|
|
364
|
+
}],
|
|
365
|
+
"publicFiles": [{ "from": "package.json", "to": "package.json", "mode": "preserve" }],
|
|
366
|
+
"requiredPublicFiles": ["package.json"],
|
|
367
|
+
"previousPublicBaseline": { "mode": "none" },
|
|
368
|
+
"production": { "branchTemplate": "release/{tag}", "branchStrategy": "create-release-branch" }
|
|
369
|
+
}],
|
|
370
|
+
"verificationGates": [{
|
|
371
|
+
"id": "my-project-script-test",
|
|
372
|
+
"phase": "snapshot-verify",
|
|
373
|
+
"scope": { "unit": "my-project" },
|
|
374
|
+
"command": ["node", "-e", "const p=require('./package.json');if(!p.name)process.exit(1)"],
|
|
375
|
+
"cwd": ".",
|
|
376
|
+
"timeoutMs": 30000,
|
|
377
|
+
"envAllowlist": []
|
|
378
|
+
}]
|
|
379
|
+
},
|
|
380
|
+
"selectedGateIds": ["my-project-script-test"]
|
|
381
|
+
}
|
|
630
382
|
```
|
|
631
383
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
## 已验收能力
|
|
635
|
-
|
|
636
|
-
- 验证项目配置和发布单元;
|
|
637
|
-
- `assess` 在不修改项目的前提下报告就绪度;
|
|
638
|
-
- 把配置的公开文件复制到隔离快照;
|
|
639
|
-
- 只读发现首次接入候选,经精确 `setupDigest` 确认后仅首次创建配置;
|
|
640
|
-
- 在冻结快照副本和精确消费者安装根运行经人工选择的项目 gate;
|
|
641
|
-
- 检查必需文件、路径安全、精确字节/权限和明显泄漏;
|
|
642
|
-
- 记录 Git/工作区身份,冻结绑定 digest 的发布计划;
|
|
643
|
-
- 用计划摘要、有效期和显式 action allowlist 绑定人工批准;
|
|
644
|
-
- 从冻结 Git object 和 npm tarball 发布,并核对远端 commit/tree/tag/integrity;
|
|
645
|
-
- 从冻结 Git ref 安装配置的 Claude/Codex 插件,证明入口 Skill 和安装载荷摘要;对 Kimi Code(无可脚本化安装接口)产出版本钉死的手动安装要求,仅依据绑定到冻结计划摘要的可信证明来确认入口 Skill 和载荷摘要;
|
|
646
|
-
- 为 Claude/Codex distribution 支持外部独立市场(`marketplaceRepo`):`prepare --online --production` 冻结外部市场 HEAD(Codex commit sha / Claude 默认分支名),校验该 sha 处的市场索引条目,并以本单元自身冻结快照整树校验安装载荷(`external-marketplace-v1`),安装侧 CLI list 观察在版本漂移时失败关闭;
|
|
647
|
-
- 随 Claude/Codex/Kimi 适配器一并提供生成的自包含 CodeBuddy/WorkBuddy 适配器(`adapters/workbuddy/`,清单 `.codebuddy-plugin/plugin.json`,技能以 `${CODEBUDDY_PLUGIN_ROOT}` 渲染);因 codebuddy CLI 无法钉死冻结 ref 而无自动化 marketplace 安装检查点,故产出手动安装要求,仅依据绑定到冻结计划摘要的可信证明来确认入口 Skill 和载荷摘要;
|
|
648
|
-
- 明确区分 `PUBLISHED`(外写完成)与 `VERIFIED`(远端和消费者安装证据完成);
|
|
649
|
-
- 中途失败停止后续动作,记录独立 run;不修改冻结 plan,不自动撤销已成功动作。
|
|
650
|
-
|
|
651
|
-
## 个性化验证:hook 与 gate
|
|
652
|
-
|
|
653
|
-
`hooks.docs/build/test/typecheck/lint` 在冻结前运行,适合确实需要生成源文件或依赖父工作区的步骤。它们可能修改项目或访问网络,prepare 必须显式传入 `--acknowledge-hook-side-effects`。
|
|
384
|
+
### hook 与 gate
|
|
654
385
|
|
|
655
|
-
|
|
386
|
+
`hooks.docs/build/test/typecheck/lint` 在快照冻结前运行。每个 hook 是一个对象——`command` 是可执行文件/参数数组,不是 shell 字符串(`command` is an executable/argument array, not a shell string):
|
|
656
387
|
|
|
657
388
|
```yaml
|
|
658
389
|
hooks:
|
|
@@ -668,63 +399,7 @@ hooks:
|
|
|
668
399
|
envAllowlist: []
|
|
669
400
|
```
|
|
670
401
|
|
|
671
|
-
`
|
|
672
|
-
|
|
673
|
-
```yaml
|
|
674
|
-
verificationGates:
|
|
675
|
-
- id: package-contract
|
|
676
|
-
phase: snapshot-verify
|
|
677
|
-
scope: { unit: my-project }
|
|
678
|
-
command:
|
|
679
|
-
- node
|
|
680
|
-
- -e
|
|
681
|
-
- "const p=require('./package.json'); if (!p.name) process.exit(1)"
|
|
682
|
-
cwd: .
|
|
683
|
-
timeoutMs: 120000
|
|
684
|
-
envAllowlist: [CI]
|
|
685
|
-
```
|
|
686
|
-
|
|
687
|
-
`snapshot-verify` 在冻结公开快照的一次性可写副本中执行;`consumer-verify` 在精确 npm/Claude/Codex/Kimi Code 隔离安装根执行。两者都使用命令数组而非 shell 字符串,定义和结果会进入摘要证据,并要求 prepare/verify 显式传入 `--acknowledge-gate-side-effects`。
|
|
688
|
-
|
|
689
|
-
push、tag、默认分支修改、GitHub Release 和 npm publish 不能放进 hook/gate,只能由冻结计划的受控动作执行。
|
|
690
|
-
|
|
691
|
-
## 当前不会做什么
|
|
692
|
-
|
|
693
|
-
<!-- release-skill:capability:unsupported-scope -->
|
|
694
|
-
- 不自动生成 README,不覆盖项目源文件;
|
|
695
|
-
- 不自动合并冲突,也不要求回滚工作流;
|
|
696
|
-
- 不声称已经替项目完成真实生产 canary;
|
|
697
|
-
- `prepare --online` 只观察 bound 前序基线;目标唯一性由 publish 全局预检完成;
|
|
698
|
-
- 不覆盖已有 branch/tag/Release,不 unpublish npm;
|
|
699
|
-
- 不提供自动化 CodeBuddy/WorkBuddy marketplace 安装检查点——codebuddy CLI 无法钉死冻结 ref,安装为手动步骤,经与 Kimi Code 相同的可信证明闭环确认;
|
|
700
|
-
- 不承诺 Windows 或广泛的跨平台原生写入;
|
|
701
|
-
- 不会隐藏地 commit、push、打 tag、创建 Release 或发布包。
|
|
702
|
-
|
|
703
|
-
### 写入安全
|
|
704
|
-
|
|
705
|
-
`setup` 默认只读,写入只允许精确摘要确认后首次创建配置。`assess` 默认只读。`prepare` 会在 `.release-skill/` 下写本地文件,但不会写项目源文件或远端服务。如果配置了 hook,它就是任意本地进程,必须使用 `--acknowledge-hook-side-effects` 明确授权;gate 同样需要 `--acknowledge-gate-side-effects`。
|
|
706
|
-
|
|
707
|
-
`publish` 是唯一生产外写入口,必须同时提供 approval 和当前 plan digest。
|
|
708
|
-
|
|
709
|
-
### 失败时怎么办
|
|
710
|
-
|
|
711
|
-
| 结果 | 下一步 |
|
|
712
|
-
|---|---|
|
|
713
|
-
| `NEEDS_INPUT` | 补齐 setup 列出的仓库、tag、渠道、基线和 gate 人工决策。 |
|
|
714
|
-
| `LOCAL_ONLY_DETECTED` | 决定建立远端渠道或仅保留本地配置设计;不得冒充生产就绪。 |
|
|
715
|
-
| `SETUP_DIGEST_MISMATCH` | 项目事实或 answers 已变化;重新 dry-run、审阅并确认新摘要。 |
|
|
716
|
-
| `CONFIG_EXISTS` | setup 不覆盖已有配置;运行 assess 后人工增量修改。 |
|
|
717
|
-
| `SAFE_WRITE_UNAVAILABLE` | 当前平台不支持自动 create-once;保留只读报告,由人工首次创建经审阅的配置。 |
|
|
718
|
-
| `CONFIG_INVALID` | 修正 `.release-skill/project.yaml`,重新运行 `assess`。 |
|
|
719
|
-
| `PUBLIC_FILE_MISSING` | 添加或修正配置中的公开文件。 |
|
|
720
|
-
| `FORBIDDEN_CONTENT_DETECTED` | 移除泄漏或私有内容,再次 prepare。 |
|
|
721
|
-
| `SNAPSHOT_FIDELITY_FAILED` | 检查源文件和快照路径,重新运行 `prepare`。 |
|
|
722
|
-
| `BASELINE_CHANGED` | 保留人工修改,重新 prepare、审阅和 approve。 |
|
|
723
|
-
| `prepare` 阶段 `GATE_FAILED` | 修复 snapshot gate 或冻结公开制品,再生成一份新 plan。 |
|
|
724
|
-
| `verify` 阶段 `GATE_FAILED` | 若是消费者环境失败,修复环境后从同一 `PUBLISHED` run 重跑 verify;若是已发布制品缺陷,发布新的补丁版本。 |
|
|
725
|
-
| `PARTIAL` | 不重跑整套发布、不删除远端;审阅返回的 `runPath` 并运行 `reconcile`。 |
|
|
726
|
-
| `PUBLISHED` | 运行 `verify --plan <planPath> --run <publishRunPath>`;此时还不是终态。 |
|
|
727
|
-
| `VERIFIED` | 远端状态、精确 npm 安装和插件消费者安装都与冻结计划一致。 |
|
|
402
|
+
hook 仅在人工审阅后、以 `--acknowledge-hook-side-effects` 显式授权后运行。gate 是发布校准的受控扩展点(见 `references/02-project-config.md`)。
|
|
728
403
|
|
|
729
404
|
## Skills
|
|
730
405
|
|
|
@@ -738,7 +413,7 @@ push、tag、默认分支修改、GitHub Release 和 npm publish 不能放进 ho
|
|
|
738
413
|
|
|
739
414
|
## 平台分发
|
|
740
415
|
|
|
741
|
-
同一个确定性核心引擎通过 build-only 适配器闭包分发到多个目标。发布单元用 `distributions`
|
|
416
|
+
同一个确定性核心引擎通过 build-only 适配器闭包分发到多个目标。发布单元用 `distributions` 声明要发布给谁:
|
|
742
417
|
|
|
743
418
|
| `distributions` 类型 | 物理产物 | 安装方式 |
|
|
744
419
|
|---|---|---|
|
|
@@ -746,9 +421,19 @@ push、tag、默认分支修改、GitHub Release 和 npm publish 不能放进 ho
|
|
|
746
421
|
| `claude-plugin` | `adapters/claude/` 下的自包含闭包 | 自动化 marketplace 检查点 |
|
|
747
422
|
| `codex-plugin` | `adapters/codex/` 下的自包含闭包 | 自动化 marketplace 检查点 |
|
|
748
423
|
| `kimi-plugin` | 自包含闭包(无可脚本化安装接口) | 手动,需可信证明 |
|
|
749
|
-
| `codebuddy-plugin` | 生成的 `adapters/workbuddy/`,带 `.codebuddy-plugin/plugin.json
|
|
424
|
+
| `codebuddy-plugin` | 生成的 `adapters/workbuddy/`,带 `.codebuddy-plugin/plugin.json` | 手动,需可信证明 |
|
|
750
425
|
|
|
751
|
-
|
|
426
|
+
每个适配器闭包都自带 CLI、skills 和 schemas 副本,安装后无需外部依赖即可运行。Claude/Codex 验证是自动化的;Kimi Code 和 CodeBuddy/WorkBuddy 需要绑定冻结计划摘要的可信证明。
|
|
427
|
+
|
|
428
|
+
<!-- release-skill:capability:unsupported-scope -->
|
|
429
|
+
- 不自动生成 README,不覆盖项目源文件;
|
|
430
|
+
- 不自动合并冲突,也不要求回滚工作流;
|
|
431
|
+
- 不声称已经替项目完成真实生产 canary,不声称已完成真实插件市场验证;
|
|
432
|
+
- `prepare --online` 只观察 bound 前序基线;目标唯一性由 publish 全局预检完成;
|
|
433
|
+
- 不覆盖已有 branch/tag/Release,不 unpublish npm;
|
|
434
|
+
- 不提供自动化 CodeBuddy/WorkBuddy marketplace 安装检查点——codebuddy CLI 无法钉死冻结 ref,安装为手动步骤,经与 Kimi Code 相同的可信证明闭环确认;
|
|
435
|
+
- 不承诺 Windows 或广泛的跨平台原生写入;
|
|
436
|
+
- 不会隐藏地 commit、push、打 tag、创建 Release 或发布包。
|
|
752
437
|
|
|
753
438
|
## 许可证
|
|
754
439
|
|