release-skill 0.1.1 → 0.1.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 +2 -2
- package/.codex-plugin/plugin.json +3 -3
- package/CHANGELOG.md +89 -0
- package/INSTALL.md +216 -5
- package/INSTALL.zh-CN.md +358 -0
- package/README.md +411 -67
- package/README.zh-CN.md +377 -59
- 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 +79284 -0
- package/adapters/claude/bin/release-skill.mjs +34 -0
- package/adapters/claude/native/safe-write/binding.gyp +40 -0
- package/adapters/claude/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
- package/adapters/claude/native/safe-write/prebuilds.json +24 -0
- package/adapters/claude/native/safe-write/src/safe_write.cc +2032 -0
- package/adapters/claude/schemas/.render-manifest.json +37 -0
- package/adapters/claude/schemas/approval-record.schema.json +115 -0
- package/adapters/claude/schemas/artifact-lock.schema.json +111 -0
- package/adapters/claude/schemas/artifact-plan.schema.json +52 -0
- package/adapters/claude/schemas/artifact-policy.schema.json +76 -0
- package/adapters/claude/schemas/evidence-event.schema.json +89 -0
- package/adapters/claude/schemas/release-plan.schema.json +860 -0
- package/adapters/claude/schemas/release-project.schema.json +736 -0
- package/adapters/claude/schemas/release-run.schema.json +342 -0
- package/adapters/claude/skills/release-assess/SKILL.md +5 -6
- package/adapters/claude/skills/release-help/SKILL.md +14 -18
- package/adapters/claude/skills/release-prepare/SKILL.md +16 -6
- package/adapters/claude/skills/release-publish/SKILL.md +7 -7
- package/adapters/claude/skills/release-reconcile/SKILL.md +6 -6
- package/adapters/claude/skills/release-setup/SKILL.md +95 -0
- package/adapters/claude/skills/release-verify/SKILL.md +7 -7
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +79284 -0
- package/adapters/codex/bin/release-skill.mjs +34 -0
- package/adapters/codex/native/safe-write/binding.gyp +40 -0
- package/adapters/codex/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
- package/adapters/codex/native/safe-write/prebuilds.json +24 -0
- package/adapters/codex/native/safe-write/src/safe_write.cc +2032 -0
- package/adapters/codex/schemas/.render-manifest.json +37 -0
- package/adapters/codex/schemas/approval-record.schema.json +115 -0
- package/adapters/codex/schemas/artifact-lock.schema.json +111 -0
- package/adapters/codex/schemas/artifact-plan.schema.json +52 -0
- package/adapters/codex/schemas/artifact-policy.schema.json +76 -0
- package/adapters/codex/schemas/evidence-event.schema.json +89 -0
- package/adapters/codex/schemas/release-plan.schema.json +860 -0
- package/adapters/codex/schemas/release-project.schema.json +736 -0
- package/adapters/codex/schemas/release-run.schema.json +342 -0
- package/adapters/codex/skills/release-assess/SKILL.md +12 -6
- package/adapters/codex/skills/release-help/SKILL.md +21 -18
- package/adapters/codex/skills/release-prepare/SKILL.md +23 -6
- package/adapters/codex/skills/release-publish/SKILL.md +14 -7
- package/adapters/codex/skills/release-reconcile/SKILL.md +13 -6
- package/adapters/codex/skills/release-setup/SKILL.md +102 -0
- package/adapters/codex/skills/release-verify/SKILL.md +14 -7
- package/bin/release-skill-cli.mjs +807 -0
- package/bin/release-skill.bundle.mjs +79284 -0
- package/bin/release-skill.mjs +23 -732
- package/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
- package/native/safe-write/prebuilds.json +22 -2
- package/native/safe-write/src/safe_write.cc +11 -2
- package/package.json +8 -2
- package/references/02-project-config.md +55 -4
- package/references/05-evidence-and-errors.md +6 -2
- package/schemas/release-plan.schema.json +556 -65
- package/schemas/release-project.schema.json +406 -29
- package/schemas/release-run.schema.json +165 -18
- package/scripts/build-bundle.mjs +133 -0
- package/skills/release-assess/SKILL.md +5 -6
- package/skills/release-help/SKILL.md +14 -18
- package/skills/release-prepare/SKILL.md +16 -6
- package/skills/release-publish/SKILL.md +7 -7
- package/skills/release-reconcile/SKILL.md +6 -6
- package/skills/release-setup/SKILL.md +95 -0
- package/skills/release-verify/SKILL.md +7 -7
- package/skills-src/release-assess/SKILL.md +5 -6
- package/skills-src/release-help/SKILL.md +14 -18
- package/skills-src/release-prepare/SKILL.md +16 -6
- package/skills-src/release-publish/SKILL.md +7 -7
- package/skills-src/release-reconcile/SKILL.md +6 -6
- package/skills-src/release-setup/SKILL.md +95 -0
- package/skills-src/release-verify/SKILL.md +7 -7
- package/src/adapters/contract.mjs +3 -0
- package/src/adapters/git-github.mjs +84 -2
- package/src/adapters/npm.mjs +5 -13
- package/src/adapters/plugin-marketplace.mjs +132 -52
- package/src/adapters/push-snapshot.mjs +84 -17
- package/src/artifacts/policy.mjs +4 -7
- package/src/artifacts/safe-fs-backend-internal.mjs +69 -21
- package/src/commands/prepare.mjs +244 -20
- package/src/commands/publish.mjs +46 -0
- package/src/commands/reconcile.mjs +152 -0
- package/src/commands/setup.mjs +1525 -0
- package/src/commands/verify.mjs +122 -26
- package/src/core/approval.mjs +4 -6
- package/src/core/config.mjs +42 -8
- package/src/core/errors.mjs +4 -0
- package/src/core/pkg-root.mjs +22 -0
- package/src/core/plan.mjs +132 -4
- package/src/core/previous-public-baseline.mjs +21 -1
- package/src/core/run.mjs +4 -4
- package/src/core/trusted-resource.mjs +96 -0
- package/src/core/verification-gates.mjs +451 -0
- package/src/docs/version-gate.mjs +164 -0
- package/src/producers/build-adapters.mjs +512 -55
- package/src/snapshot/frozen.mjs +221 -7
- package/src/snapshot/public-map.mjs +7 -4
- package/src/snapshot/scan.mjs +2 -1
package/README.zh-CN.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# release-skill
|
|
2
2
|
|
|
3
|
-
[English](README.md)
|
|
3
|
+
[English](README.md) · 安装指南:[中文](INSTALL.zh-CN.md) / [English](INSTALL.md)
|
|
4
4
|
|
|
5
|
+
<!-- release-skill:release-version: 0.1.4 -->
|
|
5
6
|
面向 Claude Code 和 Codex 的发布准备工具,完整保留人工维护的文件内容。
|
|
6
7
|
|
|
7
8
|
release-skill 帮助维护者回答三个问题:准备发布什么、还有哪些检查未通过、最终
|
|
@@ -9,23 +10,24 @@ release-skill 帮助维护者回答三个问题:准备发布什么、还有哪
|
|
|
9
10
|
最后一步重新生成 README、重新打包活动工作区或覆盖人工内容。
|
|
10
11
|
|
|
11
12
|
<!-- release-skill:capability:external-write-boundary -->
|
|
12
|
-
> **当前边界:**
|
|
13
|
-
>
|
|
14
|
-
>
|
|
15
|
-
>
|
|
16
|
-
>
|
|
17
|
-
>
|
|
18
|
-
>
|
|
19
|
-
>
|
|
20
|
-
>
|
|
13
|
+
> **当前边界:** v0.1.4 是当前发布版本。v0.1.1 已完成 GitHub 与 npm 的
|
|
14
|
+
> 真实生产发布,是首次生产验证的历史里程碑,并从冻结 Git ref 完成精确 npm
|
|
15
|
+
> 安装及 Claude/Codex 消费者安装验证;“当前发布版本”与“首次生产验证里程碑”
|
|
16
|
+
> 是两个不同的事实,不得混写成同一含义。同一工作流还通过了本地
|
|
17
|
+
> 生产等价协议套件:测试运行真实 release-skill CLI 和冻结制品,Git 目标是
|
|
18
|
+
> 本地 bare remote,`gh`、`npm`、Claude、Codex 使用协议级 fake。该套件没有
|
|
19
|
+
> 提供 OS 级网络隔离,也不能证明其他项目的认证、权限、限流和最终一致性行为
|
|
20
|
+
> 与本次发布相同;每个项目的第一次生产发布仍应作为受监控 canary。
|
|
21
|
+
> `prepare --online` 观察 bound 前序公开基线,漂移或不可观察时失败关闭;
|
|
22
|
+
> 远端唯一性检查在 `publish` 全局预检执行。
|
|
21
23
|
|
|
22
24
|
<!-- release-skill:capability:safe-first-command -->
|
|
23
|
-
>
|
|
24
|
-
>
|
|
25
|
+
> **生产路径自 v0.1.1 里程碑起已完成真实生产验证;v0.1.4 是当前发布版本。**
|
|
26
|
+
> npm 安装的 CLI 是受支持的用户入口;源码 checkout 保留为开发/贡献者路径。
|
|
25
27
|
>
|
|
26
28
|
> **第一条命令:**
|
|
27
|
-
> - npm
|
|
28
|
-
> -
|
|
29
|
+
> - npm 安装:`npm install -g release-skill` → `release-skill help`
|
|
30
|
+
> - 源码 checkout:`node "$RELEASE_SKILL_HOME/packages/release-skill/bin/release-skill.mjs" help`
|
|
29
31
|
|
|
30
32
|
<!-- release-skill:maturity:v0.1-boundary -->
|
|
31
33
|
<!-- release-skill:maturity:boundary -->
|
|
@@ -49,6 +51,11 @@ release-skill 不重新生成、也不回写项目源文件。`prepare` 从当
|
|
|
49
51
|
- 远端 branch、tag、Release 或 npm 版本冲突时交给人工;系统不 force、不覆盖。
|
|
50
52
|
- 只有 `publicFiles` 明确列出的文件会被复制;需要发布的翻译 README、图片、
|
|
51
53
|
演示文件和链接文档都要显式加入配置。
|
|
54
|
+
- 发布只冻结当前真相:`prepare` 不会刷新或重写人工文档。维护者必须先更新
|
|
55
|
+
README、INSTALL 与 CHANGELOG(包括必须与 `package.json` 版本一致的机器可读
|
|
56
|
+
`release-skill:release-version` 标记,以及当前包版本的正式 CHANGELOG 标题),
|
|
57
|
+
再 prepare、审阅和批准。任一文档版本标记或 CHANGELOG 当前版本条目漂移时,
|
|
58
|
+
发布前门禁失败关闭。
|
|
52
59
|
|
|
53
60
|
保护规则只有一句话:**复制当前事实,冻结已审阅事实,不重写人工事实。**
|
|
54
61
|
|
|
@@ -60,11 +67,7 @@ release-skill 不重新生成、也不回写项目源文件。`prepare` 从当
|
|
|
60
67
|
- Git 2.30+
|
|
61
68
|
- 至少已有一个提交的目标 Git 仓库
|
|
62
69
|
|
|
63
|
-
|
|
64
|
-
> 请使用下方源码 checkout。只有当 `npm view release-skill version` 返回 `0.1.1`
|
|
65
|
-
> 后,npm 安装的 CLI 才是受支持的用户入口;源码 checkout 仅作为开发回退。
|
|
66
|
-
|
|
67
|
-
**从 npm 安装(v0.1.1 发布后受支持):**
|
|
70
|
+
**从 npm 安装(推荐):**
|
|
68
71
|
|
|
69
72
|
```bash
|
|
70
73
|
npm install -g release-skill
|
|
@@ -82,7 +85,7 @@ npx release-skill help
|
|
|
82
85
|
release-skill help
|
|
83
86
|
```
|
|
84
87
|
|
|
85
|
-
|
|
88
|
+
**开发安装(贡献者回退,从源码 checkout):**
|
|
86
89
|
|
|
87
90
|
设置源码路径并安装依赖:
|
|
88
91
|
|
|
@@ -94,8 +97,6 @@ npm exec --yes pnpm@10.17.1 -- install --frozen-lockfile
|
|
|
94
97
|
|
|
95
98
|
然后通过 `node "$RELEASE_SKILL_HOME/packages/release-skill/bin/release-skill.mjs"` 调用 CLI。
|
|
96
99
|
|
|
97
|
-
在目标项目创建 `.release-skill/project.yaml`:
|
|
98
|
-
|
|
99
100
|
先保护本地运行数据,避免把计划、审批和冻结制品提交进仓库:
|
|
100
101
|
|
|
101
102
|
```gitignore
|
|
@@ -103,7 +104,184 @@ npm exec --yes pnpm@10.17.1 -- install --frozen-lockfile
|
|
|
103
104
|
!.release-skill/project.yaml
|
|
104
105
|
```
|
|
105
106
|
|
|
106
|
-
|
|
107
|
+
### 首次接入:不加载完整报告的确定性流程
|
|
108
|
+
|
|
109
|
+
setup 默认只读。可能很大的完整报告只写入临时文件;用户和 Agent 只查看确定性的
|
|
110
|
+
`compactSummary`(紧凑摘要)审阅视图。紧凑摘要不能替代授权:`setupDigest` 仍绑定
|
|
111
|
+
完整事实、候选和 answers。
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
PROJECT=/absolute/path/to/my-project
|
|
115
|
+
SETUP_SESSION="$(mktemp -d "${TMPDIR:-/tmp}/release-setup.XXXXXX")"
|
|
116
|
+
REPORT="$SETUP_SESSION/discovery.json"
|
|
117
|
+
ANSWERS="$SETUP_SESSION/answers.json"
|
|
118
|
+
BOUND_REPORT="$SETUP_SESSION/bound.json"
|
|
119
|
+
printf 'SETUP_SESSION=%s\nPROJECT=%s\n' "$SETUP_SESSION" "$PROJECT"
|
|
120
|
+
|
|
121
|
+
release-skill setup --root "$PROJECT" --json > "$REPORT" || test "$?" -eq 2
|
|
122
|
+
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"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`NEEDS_INPUT` 和 `LOCAL_ONLY_DETECTED` 按设计返回退出码 2。若
|
|
126
|
+
`proposalConflicts` 非空,包括 `PUBLIC_REPO_AUTHORITY_CONFLICT` 或公开文件映射冲突,
|
|
127
|
+
必须停止自动路径,由人工修正冲突的仓库或映射权威事实后重新运行 setup,不得猜测选边。
|
|
128
|
+
|
|
129
|
+
没有冲突时,只能机械提取机器提案;Agent 不得重写或逐项抄写:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
SETUP_SESSION='/上一步打印的会话目录绝对路径'
|
|
133
|
+
PROJECT='/上一步打印的项目绝对路径'
|
|
134
|
+
REPORT="$SETUP_SESSION/discovery.json"
|
|
135
|
+
ANSWERS="$SETUP_SESSION/answers.json"
|
|
136
|
+
BOUND_REPORT="$SETUP_SESSION/bound.json"
|
|
137
|
+
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"
|
|
138
|
+
|
|
139
|
+
release-skill setup --root "$PROJECT" --answers "$ANSWERS" --json > "$BOUND_REPORT"
|
|
140
|
+
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"
|
|
141
|
+
printf 'SETUP_SESSION=%s\nPROJECT=%s\n' "$SETUP_SESSION" "$PROJECT"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
只审阅这份绑定摘要和精确摘要值,并由用户确认一次。确认后使用其字面量首次创建配置:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
SETUP_SESSION=<上一步打印的会话目录绝对路径>
|
|
148
|
+
PROJECT=<上一步打印的项目绝对路径>
|
|
149
|
+
ANSWERS="$SETUP_SESSION/answers.json"
|
|
150
|
+
CREATED_REPORT="$SETUP_SESSION/created.json"
|
|
151
|
+
POST_REPORT="$SETUP_SESSION/post-setup.json"
|
|
152
|
+
ASSESS_REPORT="$SETUP_SESSION/assess.json"
|
|
153
|
+
release-skill setup --root "$PROJECT" --answers "$ANSWERS" \
|
|
154
|
+
--write --confirm-setup <已确认的 setupDigest> --json > "$CREATED_REPORT"
|
|
155
|
+
release-skill setup --root "$PROJECT" --json > "$POST_REPORT"
|
|
156
|
+
set +e
|
|
157
|
+
release-skill assess --root "$PROJECT" --offline --json > "$ASSESS_REPORT"
|
|
158
|
+
ASSESS_EXIT=$?
|
|
159
|
+
set -e
|
|
160
|
+
[ "$ASSESS_EXIT" -eq 0 ] || [ "$ASSESS_EXIT" -eq 1 ] || exit "$ASSESS_EXIT"
|
|
161
|
+
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"
|
|
162
|
+
node -e 'require("node:fs").rmSync(process.argv[1],{recursive:true,force:false})' "$SETUP_SESSION"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
写入必须返回 `CONFIG_CREATED`,下一次 setup 必须返回 `ALREADY_CONFIGURED`。已有配置
|
|
166
|
+
永不重新生成,后续只做经审阅的增量编辑。解释器/包管理器间接脚本会以
|
|
167
|
+
`SIDE_EFFECTS_UNPROVEN` 排除,不会自动选择;项目特有 hook/gate 只有人工审阅后才
|
|
168
|
+
增量加入:hook 编辑 `projectConfig.hooks`;gate 编辑 `verificationGates` 并将同一 id
|
|
169
|
+
加入 `selectedGateIds`,随后重新运行绑定 dry-run。人工文件保持 `mode: preserve`;只有显式跨单元共享源才使用
|
|
170
|
+
`sourceScope: workspace`。
|
|
171
|
+
|
|
172
|
+
#### 进阶 schema 参考——不是首次接入主路径
|
|
173
|
+
|
|
174
|
+
下面只说明 schema 形状。正常 setup 不应手写,而应按上文机械提取
|
|
175
|
+
`recommendedAnswers`。
|
|
176
|
+
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"projectConfig": {
|
|
180
|
+
"apiVersion": "release-skill/v1",
|
|
181
|
+
"kind": "ReleaseProject",
|
|
182
|
+
"project": { "name": "my-project", "defaultBranch": "main" },
|
|
183
|
+
"releaseUnits": [{
|
|
184
|
+
"id": "my-project",
|
|
185
|
+
"source": ".",
|
|
186
|
+
"publicRepo": "owner/my-project",
|
|
187
|
+
"version": { "source": "package.json", "tagTemplate": "v{version}" },
|
|
188
|
+
"distributions": [{
|
|
189
|
+
"type": "npm",
|
|
190
|
+
"package": "my-project",
|
|
191
|
+
"access": "public",
|
|
192
|
+
"provenance": false,
|
|
193
|
+
"tag": "latest",
|
|
194
|
+
"registry": "https://registry.npmjs.org",
|
|
195
|
+
"publisher": "my-npm-username"
|
|
196
|
+
}],
|
|
197
|
+
"publicFiles": [
|
|
198
|
+
{ "from": "README.md", "to": "README.md", "mode": "preserve" },
|
|
199
|
+
{ "from": "package.json", "to": "package.json", "mode": "preserve" }
|
|
200
|
+
],
|
|
201
|
+
"requiredPublicFiles": ["README.md", "package.json"],
|
|
202
|
+
"previousPublicBaseline": { "mode": "none" },
|
|
203
|
+
"production": {
|
|
204
|
+
"branchTemplate": "release/{tag}",
|
|
205
|
+
"branchStrategy": "create-release-branch"
|
|
206
|
+
}
|
|
207
|
+
}]
|
|
208
|
+
},
|
|
209
|
+
"selectedGateIds": []
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
这是 schema 参考,不是接入模板。正常 setup 必须使用机器提案;只有确认不存在任何
|
|
214
|
+
历史公开版本时才可使用 `mode: none`。
|
|
215
|
+
|
|
216
|
+
下面的参考只说明人工审阅过的 gate 与 `selectedGateIds` 的精确对应关系。需要时仅对
|
|
217
|
+
已提取的机器提案做这一处增量编辑:
|
|
218
|
+
|
|
219
|
+
```json
|
|
220
|
+
{
|
|
221
|
+
"projectConfig": {
|
|
222
|
+
"apiVersion": "release-skill/v1",
|
|
223
|
+
"kind": "ReleaseProject",
|
|
224
|
+
"project": { "name": "my-project", "defaultBranch": "main" },
|
|
225
|
+
"releaseUnits": [{
|
|
226
|
+
"id": "my-project",
|
|
227
|
+
"source": ".",
|
|
228
|
+
"publicRepo": "owner/my-project",
|
|
229
|
+
"version": { "source": "package.json", "tagTemplate": "v{version}" },
|
|
230
|
+
"distributions": [{
|
|
231
|
+
"type": "npm",
|
|
232
|
+
"package": "my-project",
|
|
233
|
+
"access": "public",
|
|
234
|
+
"provenance": false,
|
|
235
|
+
"tag": "latest",
|
|
236
|
+
"registry": "https://registry.npmjs.org",
|
|
237
|
+
"publisher": "my-npm-username"
|
|
238
|
+
}],
|
|
239
|
+
"publicFiles": [
|
|
240
|
+
{ "from": "package.json", "to": "package.json", "mode": "preserve" }
|
|
241
|
+
],
|
|
242
|
+
"requiredPublicFiles": ["package.json"],
|
|
243
|
+
"previousPublicBaseline": { "mode": "none" },
|
|
244
|
+
"production": {
|
|
245
|
+
"branchTemplate": "release/{tag}",
|
|
246
|
+
"branchStrategy": "create-release-branch"
|
|
247
|
+
}
|
|
248
|
+
}],
|
|
249
|
+
"verificationGates": [{
|
|
250
|
+
"id": "my-project-script-test",
|
|
251
|
+
"phase": "snapshot-verify",
|
|
252
|
+
"scope": { "unit": "my-project" },
|
|
253
|
+
"command": ["node", "-e", "const p=require('./package.json');if(!p.name)process.exit(1)"],
|
|
254
|
+
"cwd": ".",
|
|
255
|
+
"timeoutMs": 30000,
|
|
256
|
+
"envAllowlist": []
|
|
257
|
+
}]
|
|
258
|
+
},
|
|
259
|
+
"selectedGateIds": ["my-project-script-test"]
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
id 必须复制自当前 `gateCandidates`,不得自创。示例命令只依赖公开快照中的
|
|
264
|
+
`package.json`。如果改用项目脚本,该脚本及其全部依赖必须包含在 `publicFiles` 中;
|
|
265
|
+
snapshot gate 看不到父工作空间的测试、开发依赖或 `node_modules`,除非它们本来就是
|
|
266
|
+
显式公开内容。
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
release-skill setup --root /absolute/path/to/my-project \
|
|
270
|
+
--answers /absolute/path/to/setup-answers.json --json
|
|
271
|
+
release-skill setup --root /absolute/path/to/my-project \
|
|
272
|
+
--answers /absolute/path/to/setup-answers.json \
|
|
273
|
+
--write --confirm-setup <setupDigest> --json
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
setup 只会原子创建不存在的 `.release-skill/project.yaml`。v0.1.3 的 create-once
|
|
277
|
+
写入使用随包提供、带摘要登记的 `darwin-arm64` 原生预构建;
|
|
278
|
+
不支持的平台会以 `SAFE_WRITE_UNAVAILABLE` 失败关闭,不会退回存在路径竞态的写法。
|
|
279
|
+
已有配置返回 `ALREADY_CONFIGURED`/`CONFIG_EXISTS`,后续由人工增量编辑;README、slogan、
|
|
280
|
+
CHANGELOG 和业务脚本不会被生成或覆盖。没有远端渠道时会返回
|
|
281
|
+
`LOCAL_ONLY_DETECTED`,表示生产渠道仍需人工建立或明确放弃。
|
|
282
|
+
|
|
283
|
+
下面是人工配置的最小示例;npm 可见性、公开文件边界和远端目标必须显式选择,
|
|
284
|
+
不能依赖工具猜测:
|
|
107
285
|
|
|
108
286
|
```yaml
|
|
109
287
|
apiVersion: release-skill/v1
|
|
@@ -151,6 +329,7 @@ releaseUnits:
|
|
|
151
329
|
# status: READY
|
|
152
330
|
production:
|
|
153
331
|
branchTemplate: release/{tag}
|
|
332
|
+
branchStrategy: create-release-branch
|
|
154
333
|
releaseTitleTemplate: "{unit} {version}"
|
|
155
334
|
releaseNotes: "人工维护的发布说明"
|
|
156
335
|
```
|
|
@@ -177,6 +356,55 @@ diff unavailable。发生漂移时先停止发布,由人工取得并审阅真
|
|
|
177
356
|
把 `previousPublicBaseline` 重新绑定到人工接受的不可变 `repo`/`ref`/`commit`,再运行
|
|
178
357
|
新的 `prepare --online --production`、审阅和 approve。
|
|
179
358
|
|
|
359
|
+
分支策略也必须符合真实仓库语义:
|
|
360
|
+
|
|
361
|
+
- `create-release-branch`:创建不存在的独立发布分支;同名分支存在即停止。
|
|
362
|
+
- `advance-existing-branch`:在 `previousPublicBaseline` 精确提交上创建单父提交,
|
|
363
|
+
只允许普通 fast-forward push;远端并发漂移时交由人工。
|
|
364
|
+
- `initialize-default-branch`:受控创建不存在的标准分支;只有显式配置
|
|
365
|
+
`setAsDefaultBranch` 和 `expectedCurrentDefaultBranch` 时,默认分支切换才成为
|
|
366
|
+
计划中可批准、可观察、可 reconcile 的独立动作。
|
|
367
|
+
|
|
368
|
+
三种策略的最小配置如下:
|
|
369
|
+
|
|
370
|
+
```yaml
|
|
371
|
+
# 新建不可变 release 分支;目标必须不存在。
|
|
372
|
+
previousPublicBaseline: { mode: none } # 仅限真正的首次公开发布
|
|
373
|
+
production:
|
|
374
|
+
branchTemplate: release/{tag}
|
|
375
|
+
branchStrategy: create-release-branch
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
```yaml
|
|
379
|
+
# 推进 main;绑定的 ref 必须与目标分支精确一致。
|
|
380
|
+
previousPublicBaseline:
|
|
381
|
+
mode: bound
|
|
382
|
+
repo: owner/my-project
|
|
383
|
+
ref: refs/heads/main
|
|
384
|
+
commit: 0123456789abcdef0123456789abcdef01234567
|
|
385
|
+
production:
|
|
386
|
+
branchTemplate: main
|
|
387
|
+
branchStrategy: advance-existing-branch
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
```yaml
|
|
391
|
+
# 一次性创建尚不存在的 main,并显式切换默认分支。
|
|
392
|
+
previousPublicBaseline:
|
|
393
|
+
mode: bound
|
|
394
|
+
repo: owner/my-project
|
|
395
|
+
ref: refs/heads/old-public-branch
|
|
396
|
+
commit: 0123456789abcdef0123456789abcdef01234567
|
|
397
|
+
production:
|
|
398
|
+
branchTemplate: main
|
|
399
|
+
branchStrategy: initialize-default-branch
|
|
400
|
+
setAsDefaultBranch: true
|
|
401
|
+
expectedCurrentDefaultBranch: old-public-branch
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
后两种策略必须运行 `prepare --online --production`。如果观察到的分支、commit、
|
|
405
|
+
目标不存在性或当前默认分支与预期不符,先停止并审阅真实远端状态,再人工更新权威
|
|
406
|
+
源文件/配置;禁止 force push 或弱化基线。
|
|
407
|
+
|
|
180
408
|
这只是解释机制的本地示例,不是完整的 npm 发布清单。真实发布前必须枚举全部
|
|
181
409
|
公开运行时代码、可执行文件、类型声明、图片和链接文档。monorepo 应把 `source`
|
|
182
410
|
设为 `packages/my-plugin` 之类的子目录;每个 `from` 仍相对工作空间根,例如
|
|
@@ -188,47 +416,69 @@ diff unavailable。发生漂移时先停止发布,由人工取得并审阅真
|
|
|
188
416
|
|
|
189
417
|
### 主流程
|
|
190
418
|
|
|
191
|
-
按以下顺序执行。步骤 1–
|
|
419
|
+
按以下顺序执行。步骤 1–4 是安全默认(只读或仅本地);步骤 5–9 是需要显式
|
|
192
420
|
人工门禁的生产发布。
|
|
193
421
|
|
|
194
422
|
```bash
|
|
195
|
-
#
|
|
196
|
-
CLI=(
|
|
423
|
+
# npm 安装的 CLI(推荐):
|
|
424
|
+
CLI=(release-skill)
|
|
197
425
|
PROJECT=/absolute/path/to/my-project
|
|
198
|
-
|
|
199
|
-
#
|
|
426
|
+
ACTOR=your-name
|
|
427
|
+
# 开发回退(源码 checkout):
|
|
428
|
+
# CLI=(node "$RELEASE_SKILL_HOME/packages/release-skill/bin/release-skill.mjs")
|
|
200
429
|
```
|
|
201
430
|
|
|
202
|
-
|
|
203
|
-
|
|
431
|
+
v0.1.1 生产发布验证完成后,npm 安装的 CLI 是受支持的用户入口;
|
|
432
|
+
源码 checkout 保留为开发/贡献者路径。
|
|
204
433
|
|
|
205
434
|
1. **环境检查:**
|
|
206
435
|
```bash
|
|
207
436
|
"${CLI[@]}" help
|
|
208
437
|
```
|
|
209
|
-
2.
|
|
438
|
+
2. **首次接入(仅缺少配置时,只读):**
|
|
439
|
+
```bash
|
|
440
|
+
"${CLI[@]}" setup --root "$PROJECT" --json
|
|
441
|
+
```
|
|
442
|
+
按上文机械提取 `compactSummary` 与 `recommendedAnswers`,只确认一次绑定后的
|
|
443
|
+
`setupDigest`;配置已存在时跳过。
|
|
444
|
+
3. **就绪评估(只读):**
|
|
210
445
|
```bash
|
|
211
446
|
"${CLI[@]}" assess --root "$PROJECT" --offline --json
|
|
212
447
|
```
|
|
213
|
-
|
|
448
|
+
4. **本地快照与计划冻结:**
|
|
214
449
|
```bash
|
|
215
|
-
"${CLI[@]}" prepare --root "$PROJECT" --offline
|
|
450
|
+
"${CLI[@]}" prepare --root "$PROJECT" --offline \
|
|
451
|
+
--acknowledge-hook-side-effects \
|
|
452
|
+
--acknowledge-gate-side-effects --json
|
|
216
453
|
```
|
|
217
|
-
|
|
454
|
+
只有项目配置没有对应 hook 或 snapshot gate 时,才省略相应授权参数。授权前
|
|
455
|
+
必须审阅可执行文件、参数、工作目录和副作用,不能把授权参数当固定样板。
|
|
456
|
+
5. **人工审阅:** 检查返回的 `planPath`、`externalActions`、
|
|
218
457
|
`units[].targetVersion` 和 `planDigest`。每个发布单元的快照位于
|
|
219
|
-
`<evidenceDir>/snapshots/<unit-id
|
|
220
|
-
|
|
458
|
+
`<evidenceDir>/snapshots/<unit-id>/`。release-skill 自身只把数据写入
|
|
459
|
+
`.release-skill/`;获得授权的项目 hook/gate 是无沙箱进程,可能写入其他位置或
|
|
460
|
+
访问网络。
|
|
461
|
+
6. **生产计划冻结:**
|
|
221
462
|
```bash
|
|
222
|
-
"${CLI[@]}" prepare --root "$PROJECT" --online --production
|
|
463
|
+
PRODUCTION_JSON=$("${CLI[@]}" prepare --root "$PROJECT" --online --production \
|
|
464
|
+
--acknowledge-hook-side-effects \
|
|
465
|
+
--acknowledge-gate-side-effects --json)
|
|
466
|
+
printf '%s\n' "$PRODUCTION_JSON" | jq .
|
|
467
|
+
PLAN_PATH=$(printf '%s\n' "$PRODUCTION_JSON" | jq -r '.planPath')
|
|
468
|
+
PLAN_DIGEST=$(printf '%s\n' "$PRODUCTION_JSON" | jq -r '.planDigest')
|
|
223
469
|
```
|
|
470
|
+
同样,只省略配置不需要的授权,并在授权前逐项审阅项目进程。
|
|
224
471
|
审阅新 plan 的 externalActions、npm access/provenance/tag、branch/tag 和冻结摘要。
|
|
225
472
|
`prepare --json` 返回的生产权威 `planPath` 指向
|
|
226
473
|
`<项目>/.release-skill/plans/<planDigest>.json`,后续必须始终沿用这个返回值。
|
|
227
474
|
`.release-skill/release-plan.json` 只是可变便利副本,不得传给生产
|
|
228
475
|
approve/publish/reconcile。
|
|
229
|
-
|
|
476
|
+
7. **批准:**
|
|
230
477
|
```bash
|
|
231
|
-
"${CLI[@]}" approve --plan
|
|
478
|
+
APPROVAL_JSON=$("${CLI[@]}" approve --plan "$PLAN_PATH" \
|
|
479
|
+
--digest "$PLAN_DIGEST" --actor "$ACTOR" --json)
|
|
480
|
+
printf '%s\n' "$APPROVAL_JSON" | jq .
|
|
481
|
+
APPROVAL_PATH=$(printf '%s\n' "$APPROVAL_JSON" | jq -r '.approvalPath')
|
|
232
482
|
```
|
|
233
483
|
返回的生产权威 `approvalPath` 指向
|
|
234
484
|
`<项目>/.release-skill/approvals/<planDigest>/<approvalDigest>.json`。
|
|
@@ -236,22 +486,30 @@ npm 安装入口才是受支持的用户默认路径。
|
|
|
236
486
|
副本,不得传给生产 publish/reconcile。批准 24 小时失效;PARTIAL 恢复可为同一
|
|
237
487
|
plan 重新批准,同时逐字节保留全部旧批准。后续必须使用返回的 immutable
|
|
238
488
|
`approvalPath` 和 `expiresAt`。
|
|
239
|
-
|
|
489
|
+
8. **发布(从此开始写远端):**
|
|
240
490
|
```bash
|
|
241
|
-
"${CLI[@]}" publish --root "$PROJECT" \
|
|
242
|
-
--plan
|
|
243
|
-
--confirm-production
|
|
491
|
+
PUBLISH_JSON=$("${CLI[@]}" publish --root "$PROJECT" \
|
|
492
|
+
--plan "$PLAN_PATH" --approval "$APPROVAL_PATH" \
|
|
493
|
+
--confirm-production "$PLAN_DIGEST" --json)
|
|
494
|
+
printf '%s\n' "$PUBLISH_JSON" | jq .
|
|
495
|
+
PUBLISH_RUN_PATH=$(printf '%s\n' "$PUBLISH_JSON" | jq -r '.runPath')
|
|
244
496
|
```
|
|
245
497
|
保存返回的 `runPath`。`PUBLISHED` **不是**终态。
|
|
246
|
-
|
|
498
|
+
9. **验证(消费者安装检查):**
|
|
247
499
|
```bash
|
|
248
500
|
"${CLI[@]}" verify --root "$PROJECT" \
|
|
249
|
-
--plan
|
|
501
|
+
--plan "$PLAN_PATH" --run "$PUBLISH_RUN_PATH" \
|
|
502
|
+
--acknowledge-gate-side-effects --json
|
|
250
503
|
```
|
|
504
|
+
只有计划既没有 consumer gate,也没有 npm `smokeBin` 时才省略授权。两者都会
|
|
505
|
+
执行已安装的项目代码,而且没有操作系统或网络沙箱。
|
|
506
|
+
|
|
507
|
+
以上返回值交接示例依赖 `jq`。没有 `jq` 时必须从 JSON 原样复制这四个字段;不要把
|
|
508
|
+
文档其他位置的尖括号标签直接当作 shell 语法。
|
|
251
509
|
|
|
252
510
|
生产 prepare 会把每个公开快照封存为独立 Git commit/tree,并为 npm 单元生成固定
|
|
253
511
|
tarball。`publish` 先对所有动作做只读预检,再按“公开快照 branch → tag → npm →
|
|
254
|
-
GitHub Release → Claude/Codex marketplace
|
|
512
|
+
GitHub Release → Claude/Codex 插件市场(marketplace)安装”执行并逐项观察。`verify` 在隔离目录
|
|
255
513
|
安装每一个精确 npm `package@version`;配置 `smokeBin` 后还会运行 CLI 并校验输出。
|
|
256
514
|
只有全部证据与冻结计划一致才进入 `VERIFIED`。真实发布前运行 `gh auth login`、
|
|
257
515
|
`gh auth setup-git` 和 `npm login`,同时确认 Git HTTPS credential 能访问目标仓库。
|
|
@@ -382,17 +640,23 @@ unpublish 已发布的包)。
|
|
|
382
640
|
使用 `reconcile` 检查实际远端状态,跳过已一致的步骤,安全重试未完成的动作:
|
|
383
641
|
|
|
384
642
|
```bash
|
|
385
|
-
"${CLI[@]}" reconcile --root "$PROJECT" \
|
|
386
|
-
--run
|
|
387
|
-
--plan
|
|
388
|
-
--approval
|
|
389
|
-
--confirm-production
|
|
390
|
-
|
|
643
|
+
RECONCILE_JSON=$("${CLI[@]}" reconcile --root "$PROJECT" \
|
|
644
|
+
--run "$PUBLISH_RUN_PATH" \
|
|
645
|
+
--plan "$PLAN_PATH" \
|
|
646
|
+
--approval "$APPROVAL_PATH" \
|
|
647
|
+
--confirm-production "$PLAN_DIGEST" --json)
|
|
648
|
+
printf '%s\n' "$RECONCILE_JSON" | jq .
|
|
649
|
+
RECONCILE_RUN_PATH=$(printf '%s\n' "$RECONCILE_JSON" | jq -r '.runPath')
|
|
391
650
|
# 保存 reconcile 返回的新 runPath,再执行全新的安装验证。
|
|
392
651
|
"${CLI[@]}" verify --root "$PROJECT" \
|
|
393
|
-
--plan
|
|
652
|
+
--plan "$PLAN_PATH" --run "$RECONCILE_RUN_PATH" \
|
|
653
|
+
--acknowledge-gate-side-effects --json
|
|
394
654
|
```
|
|
395
655
|
|
|
656
|
+
只有冻结计划既没有 consumer gate,也没有 npm `smokeBin` 时才省略 verify 授权。
|
|
657
|
+
以上变量沿用主流程从 JSON 提取的精确值;如果恢复期间批准已过期,应为同一个不可变
|
|
658
|
+
计划重新批准,并在 reconcile 前替换 `APPROVAL_PATH`。
|
|
659
|
+
|
|
396
660
|
`reconcile` 查询实际远端状态(Git refs、npm 版本、GitHub Release、
|
|
397
661
|
marketplace 安装),跳过证据已匹配冻结计划的步骤,只重试安全且未完成的
|
|
398
662
|
步骤。远端冲突(例如意外的 tag 或 npm 版本)需要人工判断,无法自动解决。
|
|
@@ -404,6 +668,8 @@ reconcile 成功只返回 `PUBLISHED`,不会返回 `VERIFIED`;只有全新
|
|
|
404
668
|
- 验证项目配置和发布单元;
|
|
405
669
|
- `assess` 在不修改项目的前提下报告就绪度;
|
|
406
670
|
- 把配置的公开文件复制到隔离快照;
|
|
671
|
+
- 只读发现首次接入候选,经精确 `setupDigest` 确认后仅首次创建配置;
|
|
672
|
+
- 在冻结快照副本和精确消费者安装根运行经人工选择的项目 gate;
|
|
407
673
|
- 检查必需文件、路径安全、精确字节/权限和明显泄漏;
|
|
408
674
|
- 记录 Git/工作区身份,冻结绑定 digest 的发布计划;
|
|
409
675
|
- 用计划摘要、有效期和显式 action allowlist 绑定人工批准;
|
|
@@ -412,6 +678,47 @@ reconcile 成功只返回 `PUBLISHED`,不会返回 `VERIFIED`;只有全新
|
|
|
412
678
|
- 明确区分 `PUBLISHED`(外写完成)与 `VERIFIED`(远端和消费者安装证据完成);
|
|
413
679
|
- 中途失败停止后续动作,记录独立 run;不修改冻结 plan,不自动撤销已成功动作。
|
|
414
680
|
|
|
681
|
+
## 个性化验证:hook 与 gate
|
|
682
|
+
|
|
683
|
+
`hooks.docs/build/test/typecheck/lint` 在冻结前运行,适合确实需要生成源文件或依赖
|
|
684
|
+
父工作区的步骤。它们可能修改项目或访问网络,prepare 必须显式传入
|
|
685
|
+
`--acknowledge-hook-side-effects`。
|
|
686
|
+
|
|
687
|
+
`verificationGates` 是更适合发布校准的受控扩展点:
|
|
688
|
+
|
|
689
|
+
```yaml
|
|
690
|
+
verificationGates:
|
|
691
|
+
- id: package-contract
|
|
692
|
+
phase: snapshot-verify
|
|
693
|
+
scope: { unit: my-project }
|
|
694
|
+
command:
|
|
695
|
+
- node
|
|
696
|
+
- -e
|
|
697
|
+
- "const p=require('./package.json'); if (!p.name) process.exit(1)"
|
|
698
|
+
cwd: .
|
|
699
|
+
timeoutMs: 120000
|
|
700
|
+
envAllowlist: [CI]
|
|
701
|
+
- id: installed-help
|
|
702
|
+
phase: consumer-verify
|
|
703
|
+
scope: { unit: my-project, distribution: npm }
|
|
704
|
+
command: [node, scripts/check-installed-help.mjs]
|
|
705
|
+
cwd: .
|
|
706
|
+
timeoutMs: 30000
|
|
707
|
+
envAllowlist: []
|
|
708
|
+
expectedJson: { status: READY }
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
snapshot 示例刻意设计为自包含,只读取已映射的公开文件。若替换成项目脚本,该脚本
|
|
712
|
+
及其全部依赖必须存在于冻结公开快照;consumer 脚本也必须存在于精确安装的发行物。
|
|
713
|
+
gate 不能借用父工作空间中的测试、开发依赖或 `node_modules`。
|
|
714
|
+
|
|
715
|
+
`snapshot-verify` 在冻结公开快照的一次性可写副本中执行;`consumer-verify` 在精确
|
|
716
|
+
npm/Claude/Codex 隔离安装根执行。两者都使用命令数组而非 shell 字符串,定义和
|
|
717
|
+
结果会进入摘要证据,并要求 prepare/verify 显式传入
|
|
718
|
+
`--acknowledge-gate-side-effects`。gate 仍是无网络沙箱的项目进程,release-skill
|
|
719
|
+
无法保证它不会写文件或访问网络。push、tag、默认分支切换、GitHub Release 和
|
|
720
|
+
npm publish 不能放进 hook/gate,只能由冻结计划的受控动作执行。
|
|
721
|
+
|
|
415
722
|
## 当前不会做什么
|
|
416
723
|
|
|
417
724
|
<!-- release-skill:capability:unsupported-scope -->
|
|
@@ -420,28 +727,38 @@ reconcile 成功只返回 `PUBLISHED`,不会返回 `VERIFIED`;只有全新
|
|
|
420
727
|
- 不声称已经替项目完成真实生产 canary;
|
|
421
728
|
- `prepare --online` 只观察 bound 前序基线的 ref→commit 映射;目标唯一性由
|
|
422
729
|
publish 全局预检完成;
|
|
423
|
-
-
|
|
730
|
+
- 不覆盖已有 branch/tag/Release,不 unpublish npm;新建 ref 仅使用
|
|
731
|
+
`--force-with-lease=<ref>:` 作为“目标必须不存在”的原子比较并设置断言,推进已有
|
|
732
|
+
分支使用普通非 force push;
|
|
424
733
|
- 不承诺 Windows 或广泛的跨平台原生写入;
|
|
425
734
|
- 不会隐藏地 commit、push、打 tag、创建 Release 或发布包。
|
|
426
735
|
|
|
427
736
|
### 写入安全
|
|
428
737
|
|
|
429
|
-
`
|
|
738
|
+
`setup` 默认只读,写入只允许精确摘要确认后首次创建配置。`assess` 默认只读,
|
|
739
|
+
只有显式指定报告输出时才写报告。`prepare` 会在
|
|
430
740
|
`.release-skill/` 下写本地文件,但不会写项目源文件或远端服务。如果配置了
|
|
431
741
|
hook,它就是任意本地进程,必须使用 `--acknowledge-hook-side-effects` 明确授权;
|
|
432
|
-
|
|
742
|
+
gate 同样是项目进程,必须使用 `--acknowledge-gate-side-effects` 明确授权。它们
|
|
743
|
+
可能自行产生文件系统或网络副作用。`publish` 是唯一生产外写入口,必须同时
|
|
433
744
|
提供 approval 和当前 plan digest。最小安全演练应省略 hook,并在本地沙箱目标运行。
|
|
434
745
|
|
|
435
746
|
### 失败时怎么办
|
|
436
747
|
|
|
437
748
|
| 结果 | 下一步 |
|
|
438
749
|
|---|---|
|
|
750
|
+
| `NEEDS_INPUT` | 补齐 setup 列出的仓库、tag、渠道、基线和 gate 人工决策。 |
|
|
751
|
+
| `LOCAL_ONLY_DETECTED` | 决定建立远端渠道或仅保留本地配置设计;不得冒充生产就绪。 |
|
|
752
|
+
| `SETUP_DIGEST_MISMATCH` | 项目事实或 answers 已变化;重新 dry-run、审阅并确认新摘要。 |
|
|
753
|
+
| `CONFIG_EXISTS` | setup 不覆盖已有配置;运行 assess 后人工增量修改。 |
|
|
754
|
+
| `SAFE_WRITE_UNAVAILABLE` | 当前平台不支持自动 create-once;保留只读报告,由人工首次创建经审阅的配置,且不得覆盖已有文件。 |
|
|
439
755
|
| `CONFIG_INVALID` | 修正 `.release-skill/project.yaml`,重新运行 `assess`。 |
|
|
440
756
|
| `PUBLIC_FILE_MISSING` | 添加或修正配置中的公开文件。 |
|
|
441
757
|
| `FORBIDDEN_CONTENT_DETECTED` | 移除泄漏或私有内容,再次 prepare。 |
|
|
442
758
|
| `SNAPSHOT_FIDELITY_FAILED` | 检查源文件和快照路径,重新运行 `prepare`。 |
|
|
443
759
|
| `BASELINE_CHANGED` | 保留人工修改,重新 prepare、审阅和 approve。 |
|
|
444
|
-
| `GATE_FAILED` |
|
|
760
|
+
| `prepare` 阶段 `GATE_FAILED` | 修复 snapshot gate 或冻结公开制品,再生成一份新 plan;失败 plan 不得批准。 |
|
|
761
|
+
| `verify` 阶段 `GATE_FAILED` | 若是消费者环境失败,修复环境后从同一 `PUBLISHED` run 重跑 verify;若是已发布制品缺陷,发布新的补丁版本,不覆盖旧制品。 |
|
|
445
762
|
| `PARTIAL` | 不重跑整套发布、不删除远端;审阅返回的 `runPath` 并运行 `reconcile`(见上文)。 |
|
|
446
763
|
| `PUBLISHED` | 运行 `verify --plan <planPath> --run <publishRunPath>`;此时还不是终态。 |
|
|
447
764
|
| `VERIFIED` | 远端状态、精确 npm 安装和插件消费者安装都与冻结计划一致。 |
|
|
@@ -449,14 +766,15 @@ hook 可能自行产生文件系统或网络副作用。`publish` 是唯一生
|
|
|
449
766
|
## Skills
|
|
450
767
|
|
|
451
768
|
- `release-help`:环境检查和下一步引导。
|
|
769
|
+
- `release-setup`:首次接入的只读发现、人工校准和 create-once 配置创建。
|
|
452
770
|
- `release-assess`:只读发布就绪度报告。
|
|
453
771
|
- `release-prepare`:本地快照和可审阅发布计划。
|
|
454
772
|
- `release-publish`:经批准、摘要确认的冻结 GitHub+npm 发布。
|
|
455
773
|
- `release-reconcile`:基于证据恢复 PARTIAL;冲突时人工介入。
|
|
456
774
|
- `release-verify`:发布后验证;只有 `VERIFIED` 才是 happy end。
|
|
457
775
|
|
|
458
|
-
冲突默认仍由人工介入。v0.1.1
|
|
459
|
-
|
|
776
|
+
冲突默认仍由人工介入。v0.1.1 生产发布后,受支持的用户入口是 npm 安装的
|
|
777
|
+
`release-skill` CLI;源码 checkout 保留为开发/贡献者路径。
|
|
460
778
|
|
|
461
779
|
## 许可证
|
|
462
780
|
|