release-skill 0.3.0 → 0.4.0

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.
Files changed (72) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codebuddy-plugin/plugin.json +1 -1
  4. package/.codex-plugin/plugin.json +2 -2
  5. package/.kimi-plugin/plugin.json +1 -1
  6. package/CHANGELOG.md +23 -3
  7. package/INSTALL.md +34 -110
  8. package/INSTALL.zh-CN.md +17 -83
  9. package/README.md +42 -65
  10. package/README.zh-CN.md +37 -57
  11. package/adapters/claude/.claude-plugin/marketplace.json +1 -1
  12. package/adapters/claude/.claude-plugin/plugin.json +1 -1
  13. package/adapters/claude/bin/release-skill.bundle.mjs +138 -231
  14. package/adapters/claude/schemas/release-plan.schema.json +7 -0
  15. package/adapters/claude/schemas/release-run.schema.json +43 -0
  16. package/adapters/claude/skills/release-help/SKILL.md +5 -5
  17. package/adapters/claude/skills/release-prepare/SKILL.md +6 -15
  18. package/adapters/claude/skills/release-publish/SKILL.md +5 -6
  19. package/adapters/claude/skills/release-reconcile/SKILL.md +2 -2
  20. package/adapters/claude/skills/release-verify/SKILL.md +4 -6
  21. package/adapters/codex/.codex-plugin/plugin.json +2 -2
  22. package/adapters/codex/bin/release-skill.bundle.mjs +138 -231
  23. package/adapters/codex/schemas/release-plan.schema.json +7 -0
  24. package/adapters/codex/schemas/release-run.schema.json +43 -0
  25. package/adapters/codex/skills/release-help/SKILL.md +5 -5
  26. package/adapters/codex/skills/release-prepare/SKILL.md +6 -15
  27. package/adapters/codex/skills/release-publish/SKILL.md +5 -6
  28. package/adapters/codex/skills/release-reconcile/SKILL.md +2 -2
  29. package/adapters/codex/skills/release-verify/SKILL.md +4 -6
  30. package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
  31. package/adapters/kimi/bin/release-skill.bundle.mjs +138 -231
  32. package/adapters/kimi/schemas/release-plan.schema.json +7 -0
  33. package/adapters/kimi/schemas/release-run.schema.json +43 -0
  34. package/adapters/kimi/skills/release-help/SKILL.md +5 -5
  35. package/adapters/kimi/skills/release-prepare/SKILL.md +6 -15
  36. package/adapters/kimi/skills/release-publish/SKILL.md +5 -6
  37. package/adapters/kimi/skills/release-reconcile/SKILL.md +2 -2
  38. package/adapters/kimi/skills/release-verify/SKILL.md +4 -6
  39. package/adapters/workbuddy/.codebuddy-plugin/plugin.json +1 -1
  40. package/adapters/workbuddy/bin/release-skill.bundle.mjs +138 -231
  41. package/adapters/workbuddy/schemas/release-plan.schema.json +7 -0
  42. package/adapters/workbuddy/schemas/release-run.schema.json +43 -0
  43. package/adapters/workbuddy/skills/release-help/SKILL.md +5 -5
  44. package/adapters/workbuddy/skills/release-prepare/SKILL.md +6 -15
  45. package/adapters/workbuddy/skills/release-publish/SKILL.md +5 -6
  46. package/adapters/workbuddy/skills/release-reconcile/SKILL.md +2 -2
  47. package/adapters/workbuddy/skills/release-verify/SKILL.md +4 -6
  48. package/bin/release-skill-cli.mjs +45 -48
  49. package/bin/release-skill.bundle.mjs +138 -231
  50. package/package.json +1 -1
  51. package/references/01-state-machine.md +1 -1
  52. package/references/06-adapter-contract.md +6 -5
  53. package/schemas/release-plan.schema.json +7 -0
  54. package/schemas/release-run.schema.json +43 -0
  55. package/skills/release-help/SKILL.md +5 -5
  56. package/skills/release-prepare/SKILL.md +6 -15
  57. package/skills/release-publish/SKILL.md +5 -6
  58. package/skills/release-reconcile/SKILL.md +2 -2
  59. package/skills/release-verify/SKILL.md +4 -6
  60. package/skills-src/release-help/SKILL.md +5 -5
  61. package/skills-src/release-prepare/SKILL.md +6 -15
  62. package/skills-src/release-publish/SKILL.md +5 -6
  63. package/skills-src/release-reconcile/SKILL.md +2 -2
  64. package/skills-src/release-verify/SKILL.md +4 -6
  65. package/src/commands/approve.mjs +8 -6
  66. package/src/commands/hooks.mjs +4 -8
  67. package/src/commands/prepare.mjs +13 -50
  68. package/src/commands/publish.mjs +0 -8
  69. package/src/commands/reconcile.mjs +3 -37
  70. package/src/commands/ship.mjs +55 -77
  71. package/src/commands/verify.mjs +56 -19
  72. package/src/core/skill-resource-closure.mjs +7 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "广州市风荷科技有限公司"
@@ -48,7 +48,7 @@
48
48
  | PUBLISHING | PUBLISHED | 所有检查点成功 |
49
49
  | PUBLISHING | PARTIAL | 至少一个检查点成功但后续失败 |
50
50
  | PUBLISHING | BLOCKED | 外部服务阻断且无法继续 |
51
- | PUBLISHED | VERIFIED | `verify` 全部通过 |
51
+ | PUBLISHED | VERIFIED | `verify` 的远端、npm、Claude/Codex 等自动化检查全部通过;新计划中的 Kimi/CodeBuddy 人工安装任务不由系统核验且不阻塞该状态 |
52
52
  | PUBLISHED | POST_PUBLISH_VERIFY_FAILED | 发布后验证失败(保留 PUBLISHED 事实但标记验证失败) |
53
53
  | NEEDS_INPUT | DISCOVERED | 用户提供输入后重新开始评估 |
54
54
  | NEEDS_INPUT | ASSESSED | 用户提供输入后恢复评估 |
@@ -108,13 +108,14 @@
108
108
  | 查询插件状态 | observe | 检查插件是否可被发现 |
109
109
  | 验证安装性 | verify | 在全新环境中安装并验证插件可调用 |
110
110
 
111
- 支持目标:Claude Code plugin marketplace、Codex plugin manifest/marketplace、Kimi Code(人工 attestation 闭环)、CodeBuddy/WorkBuddy(人工 attestation 闭环)。
111
+ 支持目标:Claude Code plugin marketplace、Codex plugin manifest/marketplace、Kimi Code(发布后人工安装任务)、CodeBuddy/WorkBuddy(发布后人工安装任务)。
112
112
 
113
- **CodeBuddy/WorkBuddy 接入形态(人工 attestation 闭环)**:目录名 `workbuddy` 与平台名 `codebuddy` 指同一目标——build adapter 目录保持 `adapters/workbuddy/`(由 build-adapters 生成的自包含分发适配器,清单 `.codebuddy-plugin/plugin.json`,组件位于插件根,技能以 `${CODEBUDDY_PLUGIN_ROOT}` 渲染),而 platform id / distributionType / actionType 分别为 `codebuddy` / `codebuddy-plugin` / `codebuddy-marketplace-install`。codebuddy CLI 的 `plugin marketplace add` 与 `plugin install` 均无 ref 选项、安装跟踪市场默认分支,**无法钉死冻结 ref**,自动化安装检查点无法保证冻结产物同一性,因此**不采用自动化安装检查点**,改与 Kimi Code 同级的人工 attestation 闭环:
113
+ **Kimi/CodeBuddy/WorkBuddy 接入形态(非阻塞人工跟进)**:目录名 `workbuddy` 与平台名 `codebuddy` 指同一目标——build adapter 目录保持 `adapters/workbuddy/`(由 build-adapters 生成的自包含分发适配器,清单 `.codebuddy-plugin/plugin.json`,组件位于插件根,技能以 `${CODEBUDDY_PLUGIN_ROOT}` 渲染),而 platform id / distributionType / actionType 分别为 `codebuddy` / `codebuddy-plugin` / `codebuddy-marketplace-install`。Kimi 没有可脚本化安装接口;codebuddy CLI 的 `plugin marketplace add` 与 `plugin install` 均无 ref 选项、安装跟踪市场默认分支,无法可靠核验冻结产物同一性。因此新计划设置 `humanConsumersStrategy: manualFollowUps`:
114
114
 
115
- - `execute` exec 任何 codebuddy 命令,写出绑定冻结计划摘要与身份的手动安装 requirement(声明桌面端/CLI 双安装通道与统一市场 `ifoohoo/artifact-skill-set`),检查点失败关闭、run `PARTIAL`(其余自动化外写先完成)。
116
- - 操作者经 **WorkBuddy 桌面端统一市场**(`ifoohoo/artifact-skill-set`,落点 `~/.workbuddy/plugins/marketplaces/artifact-skill-set/plugins/<plugin>/`)或 **codebuddy CLI**(隔离 `HOME` `plugin marketplace add https://github.com/ifoohoo/artifact-skill-set``plugin install <plugin>@artifact-skill-set`)安装;因无法钉死 ref,出具 attestation 前必须核实已安装清单版本等于冻结版本。
117
- - `observe`/`verify` 仅消费结构化人工 attestation 并只读核验安装点 manifest:校验 `planDigest`/`payloadDigest` 绑定、`consumer==='codebuddy'`、`installChannel`(`desktop`/`cli`)与 `marketplace`、按通道校验 `installPath` 布局,以及时间窗(`attestedAt` 不在未来、`expiresAt` 在 `attestedAt` 后 24 小时内且未过期),任一不符即 fail-closed;缺失或失配证明时 CodeBuddy 单元绝不进入 `VERIFIED`,与 Kimi 同阶(发布后验证不可豁免)。
115
+ - `publish` 不执行 Kimi/CodeBuddy 安装,也不因其尚未安装进入 `PARTIAL`;自动化发布完成后进入 `PUBLISHED`,并返回含平台、插件、版本和安装说明的 `manualFollowUps`。
116
+ - `verify` 跳过这两个平台的安装核验,为每个任务返回 `verifiedBySystem: false`;任务完成与否不改变自动化发布的 `VERIFIED` 状态,系统不得声称已验证其安装。
117
+ - 操作者可在发布完成后经 Kimi 交互安装、WorkBuddy 桌面市场或 codebuddy CLI 安装;这是团队待办,不是 release-skill 门禁。
118
+ - 缺少 `humanConsumersStrategy` 的旧冻结计划继续按历史 attestation 契约读取证明,避免升级后破坏进行中的旧发布;`attest` 只用于该兼容路径。
118
119
 
119
120
  **外部独立市场形态(claude/codex)**:distribution 声明可选字段 `marketplaceRepo`(`owner/name`)即启用外部形态,marketplace 索引与插件仓库解耦:
120
121
 
@@ -988,6 +988,13 @@
988
988
  "type": "string",
989
989
  "description": "Overall snapshot digest across all units"
990
990
  },
991
+ "humanConsumersStrategy": {
992
+ "type": "string",
993
+ "enum": [
994
+ "manualFollowUps"
995
+ ],
996
+ "description": "Human consumer strategy marker. 'manualFollowUps': Kimi/CodeBuddy installations are non-blocking post-release manual tasks; verify returns VERIFIED with manualFollowUps list and does not block on attestation. Absent: legacy attestation closed loop (backward compatibility)."
997
+ },
991
998
  "digest": {
992
999
  "type": "string",
993
1000
  "minLength": 1
@@ -432,6 +432,49 @@
432
432
  }
433
433
  }
434
434
  },
435
+ "manualFollowUps": {
436
+ "type": "array",
437
+ "description": "Non-blocking manual follow-up tasks for human consumer platforms (Kimi/CodeBuddy) when plan declares humanConsumersStrategy: 'manualFollowUps'",
438
+ "items": {
439
+ "type": "object",
440
+ "required": [
441
+ "actionId",
442
+ "platform",
443
+ "plugin",
444
+ "verifiedBySystem"
445
+ ],
446
+ "additionalProperties": false,
447
+ "properties": {
448
+ "actionId": {
449
+ "type": "string",
450
+ "minLength": 1
451
+ },
452
+ "platform": {
453
+ "type": "string",
454
+ "enum": [
455
+ "kimi",
456
+ "codebuddy"
457
+ ]
458
+ },
459
+ "plugin": {
460
+ "type": "string"
461
+ },
462
+ "version": {
463
+ "type": "string"
464
+ },
465
+ "unitId": {
466
+ "type": "string"
467
+ },
468
+ "verifiedBySystem": {
469
+ "const": false,
470
+ "description": "Always false — these tasks are not verified by the system"
471
+ },
472
+ "reason": {
473
+ "type": "string"
474
+ }
475
+ }
476
+ }
477
+ },
435
478
  "skillResourceClosureReceipts": {
436
479
  "type": "array",
437
480
  "description": "Per-surface skill resource closure verification receipts from verify phase",
@@ -35,12 +35,12 @@ description: "Discoverable entry point for release-skill: dependency and environ
35
35
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" help --json
36
36
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" setup --root <path> --json
37
37
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" assess --root <path> --offline --json
38
- # 日常发布快速路径:最多两个授权摘要,状态文件可恢复
38
+ # 日常发布快速路径:仅在发布前确认一次可读计划摘要,状态文件可恢复
39
39
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" ship --root <path> --target-version <version> --json
40
40
  # 开发阶段执行声明 hooks 并生成 prepare 可复用的内容绑定收据
41
- node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" hooks validate --root <path> \
42
- --acknowledge-hook-side-effects --json
43
- # Kimi/CodeBuddy 安装完成后记录人工事实,不手改 JSON
41
+ # 命令调用本身即授权执行配置中的 hooks
42
+ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" hooks validate --root <path> --json
43
+ # 仅旧冻结计划兼容:记录历史 Kimi/CodeBuddy 人工证明
44
44
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" attest --root <path> \
45
45
  --platform <kimi|codebuddy> --plugin <id> --result <passed|failed> --actor <person> --json
46
46
  # 发布文档刷新:默认只读演练
@@ -59,7 +59,7 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" docs refresh --unit <id> \
59
59
  - **只读演练**:`docs refresh --unit <id> --json` 输出逐文件相对路径、locale、新旧摘要、`version`、`locales`、`inputDigest`、`refreshDigest` 和 `nextCommand.argv`;候选无变化时 `status: "clean"`。
60
60
  - **确认写入**:必须同时提供 `--write`、精确 `--confirm-refresh <refreshDigest>` 和 `--ack-local-document-write`,全部目标作为一个事务提交;成功后立即复演必须为 `clean`。
61
61
 
62
- **授权边界**:本地发布文档写入授权只覆盖声明的本地文档目标,不是 hook、Git 提交、push、publish 或安装的授权。写入后必须审阅、提交,再重新 prepare。
62
+ **授权边界**:本地发布文档写入授权只覆盖声明的本地文档目标,不是 Git 提交、push、publish 或安装的授权。hook/gate 由对应命令调用直接授权。写入后必须审阅、提交,再重新 prepare。
63
63
 
64
64
  ## 故障路由
65
65
 
@@ -13,9 +13,7 @@ description: Freeze an immutable release plan with local configuration, document
13
13
 
14
14
  运行项目构建/测试 hook,生成公开快照并扫描泄漏,冻结不可变发布计划。prepare 自身不调用发布 adapter,但会执行用户配置的 hook。hook 是任意本地进程,不受文件系统/网络隔离,可能产生项目目录外的副作用或远端写入。
15
15
 
16
- **Hook 授权门**: 当项目配置含任何 hook 时,prepare 默认失败关闭并展示将执行的 executable/args/cwd。只有显式传入 `--acknowledge-hook-side-effects`(CLI)或 `hooksAuthorized: true`(API)才能执行。授权表示用户接受 hook 风险,不表示 hook 安全。
17
-
18
- **Gate 授权门**: 当项目含 `snapshot-verify` gate 时,prepare 同样默认失败关闭。逐项审阅后才可传入 `--acknowledge-gate-side-effects`(CLI)或 `verificationGatesAuthorized: true`(API);gate 也没有操作系统或网络沙箱。
16
+ **Hook Gate 执行**: 命令调用本身即授权执行已配置的 hook gate,不再设置额外人工授权环节。
19
17
 
20
18
  **阶段通过规则**: 本阶段的通过只能由 CLI exit code 0 和结构化状态码 `PREPARED` 确认。Agent 无权自行宣布计划冻结成功。
21
19
 
@@ -30,9 +28,8 @@ description: Freeze an immutable release plan with local configuration, document
30
28
  1. 使用插件根相对路径运行 CLI:`CLI="node ${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs"`
31
29
  2. 配置含 `releaseDocuments` 时,先运行只读演练 `${CLI} docs refresh --unit <id> --json`;`status: "changes"` 时展示逐文件路径/语种/版本/`refreshDigest`,取得"本地发布文档写入"明确授权后才执行 `nextCommand.argv` 写入,审阅并提交刷新结果后再继续;`status: "clean"` 时直接进入 prepare
32
30
  3. 运行 `${CLI} prepare --root <path> --offline --json`
33
- 4. 若遇到 hook/gate 授权门失败,分别展示命令和风险,获取授权后只增加实际需要的 `--acknowledge-hook-side-effects` / `--acknowledge-gate-side-effects`
34
- 5. 检查 exit code 0,读取 JSON 返回的 immutable `planPath=plans/<planDigest>.json`,再从该文件读取 `status`、`units`、`externalActions`
35
- 6. 向用户展示 targetVersion、externalActions、planDigest 和 planPath;后续 approve/publish 只能使用该 immutable planPath,等待确认后再 approve
31
+ 4. 检查 exit code 0,读取 JSON 返回的 immutable `planPath=plans/<planDigest>.json`,再从该文件读取 `status`、`units`、`externalActions`
32
+ 5. 向用户展示可读的 `approvalSummary`(版本、仓库/包、branch/tag、外部动作和例外);`planDigest` 仅作为内部绑定字段,不要求用户复制或确认。后续 approve/publish 只能使用该 immutable planPath,等待确认后再 approve
36
33
 
37
34
  若用户明确要求 GitHub+npm 生产发布,加入 `--production`。该模式还会封存独立
38
35
  Git commit/tree 和 npm tarball,并把路径、SHA/integrity、branch/tag 写入计划。
@@ -63,24 +60,18 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" docs refresh --unit <id> \
63
60
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" prepare --root <path> --offline --json
64
61
  # 生产 happy end:bound 基线必须 online;远端目标唯一性仍由 publish 全局预检
65
62
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" prepare --root <path> --online --production --json
66
- # 项目含 hook 时需显式授权:
67
- node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" prepare --root <path> --offline --acknowledge-hook-side-effects --json
68
- # 项目含 snapshot gate 时另行显式授权:
69
- node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" prepare --root <path> --offline --acknowledge-gate-side-effects --json
70
63
  ```
71
64
 
72
65
  ## 执行顺序
73
66
 
74
67
  1. 校验配置 schema → 2. 版本解析与发布文档新鲜度门(只读,RELEASE_DOCS_STALE)→
75
- 3. Hook 授权门 → 4. 运行 hooks 并复检文档新鲜度 → 5. 捕获 Git baseline →
76
- 6. 逐 unit 观察前序公开基线 → 7. 生成快照/扫描/README → 8. 原子写入 plan
68
+ 3. 运行 hooks 并复检文档新鲜度 → 4. 捕获 Git baseline →
69
+ 5. 逐 unit 观察前序公开基线 → 6. 生成快照/扫描/README → 7. 原子写入 plan
77
70
 
78
71
  ## 故障路由
79
72
 
80
73
  | 错误码 | 处理 |
81
74
  |---|---|
82
- | GATE_FAILED (hook 授权) | 向用户展示 hook 命令和风险,获得授权后加 `--acknowledge-hook-side-effects` 重试 |
83
- | GATE_FAILED (gate 授权) | 向用户展示 snapshot gate 命令和风险,获得授权后加 `--acknowledge-gate-side-effects` 重试 |
84
75
  | GATE_FAILED (bound + offline) | 改用 `--online --production`,不得把 unobserved-offline plan 交给 publish |
85
76
  | GATE_FAILED (前序基线漂移) | 先取得并比较实际远端内容;人工选择 merge/adopt/reject。merge/adopt 都必须把接受内容落回 human-owned 权威源,并把 `previousPublicBaseline` 更新为接受状态的精确 repo/ref/commit 后重新 online production prepare;reject 停止调查,禁止改 `mode: none` 绕过 |
86
77
  | GATE_FAILED (`npm-entry-closure`) | 修复打包内容或入口声明后重新 prepare;不得用 `requiredPublicFiles`/`smokeBin` 缺省绕过 |
@@ -94,4 +85,4 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" prepare --root <path> --offli
94
85
 
95
86
  ## 后续引导
96
87
 
97
- 计划冻结后,读取命令返回的 immutable `planPath` 展示给用户,等待确认后再 approve。`release-plan.json` 等 latest alias 只用于浏览,不得作为生产 authority 传递。
88
+ 计划冻结后,读取命令返回的 immutable `planPath` 和 `approvalSummary` 展示给用户,等待确认后再 approve。`planDigest` 由系统自动计算和绑定,不作为人工交互口令。`release-plan.json` 等 latest alias 只用于浏览,不得作为生产 authority 传递。
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: release-publish
3
- description: 从已批准且摘要确认的生产计划发布冻结 Git branch/tag、npm tarball 与 GitHub Release,并执行已配置的 Claude/Codex marketplace 隔离消费者安装检查以达到 PUBLISHED;随后必须路由 release-verify 才可能达到 VERIFIED;遇到冲突或不确定远端状态时失败关闭并要求人工介入
3
+ description: 从已批准的生产计划发布冻结 Git branch/tag、npm tarball 与 GitHub Release,并执行已配置的 Claude/Codex marketplace 隔离消费者安装检查以达到 PUBLISHED;随后必须路由 release-verify 才可能达到 VERIFIED;遇到冲突或不确定远端状态时失败关闭并要求人工介入
4
4
  ---
5
5
 
6
6
  # release-publish
@@ -25,16 +25,15 @@ description: 从已批准且摘要确认的生产计划发布冻结 Git branch/t
25
25
 
26
26
  ## 授权门
27
27
 
28
- 1. 展示 `planDigest`、版本、仓库/包名、branch/tag 和全部 actions。
29
- 2. 必须存在未过期且绑定同一 digest 的 approval record
30
- 3. 用户必须明确提供 `--confirm-production <planDigest>`;Agent 不得代替用户猜测确认值。
31
- 4. 只有 CLI exit code 0 且结构化状态为 `PUBLISHED` 才算外写阶段通过;随后必须运行 verify,只有 `VERIFIED` 才是完整终态。
28
+ 1. 展示可读的 `approvalSummary`:版本、仓库/包名、branch/tag、全部 actions 和例外。
29
+ 2. 必须存在未过期且由系统绑定同一内部 digest 的 approval record;批准后不再要求用户复制摘要做二次确认。
30
+ 3. 只有 CLI exit code 0 且结构化状态为 `PUBLISHED` 才算外写阶段通过;随后必须运行 verify,只有 `VERIFIED` 才是完整终态。
32
31
 
33
32
  ## 确定性执行
34
33
 
35
34
  ```bash
36
35
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" publish --root <path> --plan <plan-path> \
37
- --approval <approval-path> --confirm-production <planDigest> --json
36
+ --approval <approval-path> --json
38
37
  ```
39
38
 
40
39
  执行顺序:全局只读预检 → 配置的公开分支(按三种 `branchStrategy` 执行)→ 必要时
@@ -32,7 +32,7 @@ marketplace 隔离消费者 checkpoint,但只恢复到 `PUBLISHED`;最终 np
32
32
  1. 使用插件根相对路径运行 CLI,确认有 `--run` 路径(必需),且源 run 状态为 `PARTIAL`
33
33
  2. 运行 `node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" reconcile --root <path> --plan <plan-path> --run <run-path> --json`
34
34
  3. 检查 exit code 和结构化状态:`PUBLISHED`(恢复完成,待 verify)/ `PARTIAL`(需重试)/ `BLOCKED`(需人工决策)
35
- 4. 若 PARTIAL 且需重试,加 `--approval`;生产计划还必须加 `--confirm-production <planDigest>`
35
+ 4. 若 PARTIAL 且需重试,加 `--approval`;批准记录由系统核验与冻结计划的内部摘要绑定,不再要求二次摘要确认
36
36
 
37
37
  ## 确定性脚本调用
38
38
 
@@ -42,7 +42,7 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" reconcile --root <path> --pla
42
42
  # verify
43
43
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --plan <plan-path> --run <reconcile-run-path> --json
44
44
  # 重试(需 --approval)
45
- node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" reconcile --root <path> --plan <plan-path> --run <run-path> --approval <approval-path> --confirm-production <planDigest> --json
45
+ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" reconcile --root <path> --plan <plan-path> --run <run-path> --approval <approval-path> --json
46
46
  ```
47
47
 
48
48
  ## 幂等跳过逻辑
@@ -17,7 +17,7 @@ verify 只接受 `PUBLISHED` 状态的源 run;`VERIFIED` 是终态,不会再
17
17
 
18
18
  ## 职责与边界
19
19
 
20
- 验证远端所有 action 的实际状态与冻结计划一致。执行精确 `<package>@<version>` npm 安装到隔离目录,验证包名、版本、静态入口闭包,并在配置时验证 bin 路径安全和 CLI 烟雾输出。对每个声明的 marketplace distribution 执行全新隔离消费者安装验证。
20
+ 验证远端所有自动化 action 的实际状态与冻结计划一致。执行精确 `<package>@<version>` npm 安装到隔离目录,验证包名、版本、静态入口闭包,并在配置时验证 bin 路径安全和 CLI 烟雾输出。对 Claude/Codex marketplace distribution 执行全新隔离消费者安装验证。新计划中的 Kimi/CodeBuddy 安装只返回 `manualFollowUps`,明确标记 `verifiedBySystem: false`,不阻塞 `VERIFIED`;缺少该策略字段的旧冻结计划继续走历史 attestation 兼容路径。
21
21
 
22
22
  **阶段通过规则**: 只有 CLI exit code 0 和结构化状态码 `VERIFIED` 才是完整终态。
23
23
 
@@ -28,7 +28,7 @@ verify 只接受 `PUBLISHED` 状态的源 run;`VERIFIED` 是终态,不会再
28
28
  ## 正向执行路径
29
29
 
30
30
  1. 确认有 `--run` 路径(必需),且源 run 状态为 PUBLISHED
31
- 2. 使用插件根相对路径运行 CLI;若存在 consumer gate npm `smokeBin`,先逐项审阅并增加 `--acknowledge-gate-side-effects`
31
+ 2. 使用插件根相对路径运行 CLI;命令调用本身即授权执行已配置的 verification gate smoke process
32
32
  3. 检查 exit code 和结构化状态:`VERIFIED`(全部通过)/ 失败(具体错误)
33
33
  4. 只有 `VERIFIED` 才是 happy end
34
34
 
@@ -37,8 +37,6 @@ verify 只接受 `PUBLISHED` 状态的源 run;`VERIFIED` 是终态,不会再
37
37
  ```bash
38
38
  # 从插件根运行
39
39
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --plan <plan-path> --run <run-path> --json
40
- # 计划含 consumer gate 或 smokeBin 时:
41
- node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --plan <plan-path> --run <run-path> --acknowledge-gate-side-effects --json
42
40
  ```
43
41
 
44
42
  ## 验证步骤
@@ -47,7 +45,7 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --plan <
47
45
  2. 加载源 run,验证 planDigest 匹配和 checkpoint 完整性
48
46
  3. 对每个 plan action 执行 adapter.verify()(远端状态重检)
49
47
  4. 对每个 npm distribution 执行隔离安装烟雾测试
50
- 5. 对每个 marketplace distribution 执行全新隔离消费者安装验证
48
+ 5. Claude/Codex marketplace distribution 执行全新隔离消费者安装验证;收集 Kimi/CodeBuddy 的非阻塞 `manualFollowUps`
51
49
  6. 全部通过 → `VERIFIED`
52
50
 
53
51
  ## 烟雾测试
@@ -69,4 +67,4 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --plan <
69
67
  | 远端状态不匹配 | POST_PUBLISH_VERIFY_FAILED | 停止 |
70
68
  | npm 安装失败 | POST_PUBLISH_VERIFY_FAILED | 停止 |
71
69
  | CLI 烟雾输出不匹配 | POST_PUBLISH_VERIFY_FAILED | 停止 |
72
- | consumer gate / smokeBin 未授权 | GATE_FAILED | 展示命令和副作用,人工确认后加 `--acknowledge-gate-side-effects` |
70
+ | consumer gate / smokeBin 执行失败 | GATE_FAILED | 检查失败原因,修复后重试 |
@@ -35,12 +35,12 @@ description: "Discoverable entry point for release-skill: dependency and environ
35
35
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" help --json
36
36
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" setup --root <path> --json
37
37
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" assess --root <path> --offline --json
38
- # 日常发布快速路径:最多两个授权摘要,状态文件可恢复
38
+ # 日常发布快速路径:仅在发布前确认一次可读计划摘要,状态文件可恢复
39
39
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" ship --root <path> --target-version <version> --json
40
40
  # 开发阶段执行声明 hooks 并生成 prepare 可复用的内容绑定收据
41
- node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" hooks validate --root <path> \
42
- --acknowledge-hook-side-effects --json
43
- # Kimi/CodeBuddy 安装完成后记录人工事实,不手改 JSON
41
+ # 命令调用本身即授权执行配置中的 hooks
42
+ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" hooks validate --root <path> --json
43
+ # 仅旧冻结计划兼容:记录历史 Kimi/CodeBuddy 人工证明
44
44
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" attest --root <path> \
45
45
  --platform <kimi|codebuddy> --plugin <id> --result <passed|failed> --actor <person> --json
46
46
  # 发布文档刷新:默认只读演练
@@ -59,7 +59,7 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" docs refresh --unit <id> \
59
59
  - **只读演练**:`docs refresh --unit <id> --json` 输出逐文件相对路径、locale、新旧摘要、`version`、`locales`、`inputDigest`、`refreshDigest` 和 `nextCommand.argv`;候选无变化时 `status: "clean"`。
60
60
  - **确认写入**:必须同时提供 `--write`、精确 `--confirm-refresh <refreshDigest>` 和 `--ack-local-document-write`,全部目标作为一个事务提交;成功后立即复演必须为 `clean`。
61
61
 
62
- **授权边界**:本地发布文档写入授权只覆盖声明的本地文档目标,不是 hook、Git 提交、push、publish 或安装的授权。写入后必须审阅、提交,再重新 prepare。
62
+ **授权边界**:本地发布文档写入授权只覆盖声明的本地文档目标,不是 Git 提交、push、publish 或安装的授权。hook/gate 由对应命令调用直接授权。写入后必须审阅、提交,再重新 prepare。
63
63
 
64
64
  ## 故障路由
65
65
 
@@ -13,9 +13,7 @@ description: Freeze an immutable release plan with local configuration, document
13
13
 
14
14
  运行项目构建/测试 hook,生成公开快照并扫描泄漏,冻结不可变发布计划。prepare 自身不调用发布 adapter,但会执行用户配置的 hook。hook 是任意本地进程,不受文件系统/网络隔离,可能产生项目目录外的副作用或远端写入。
15
15
 
16
- **Hook 授权门**: 当项目配置含任何 hook 时,prepare 默认失败关闭并展示将执行的 executable/args/cwd。只有显式传入 `--acknowledge-hook-side-effects`(CLI)或 `hooksAuthorized: true`(API)才能执行。授权表示用户接受 hook 风险,不表示 hook 安全。
17
-
18
- **Gate 授权门**: 当项目含 `snapshot-verify` gate 时,prepare 同样默认失败关闭。逐项审阅后才可传入 `--acknowledge-gate-side-effects`(CLI)或 `verificationGatesAuthorized: true`(API);gate 也没有操作系统或网络沙箱。
16
+ **Hook Gate 执行**: 命令调用本身即授权执行已配置的 hook gate,不再设置额外人工授权环节。
19
17
 
20
18
  **阶段通过规则**: 本阶段的通过只能由 CLI exit code 0 和结构化状态码 `PREPARED` 确认。Agent 无权自行宣布计划冻结成功。
21
19
 
@@ -30,9 +28,8 @@ description: Freeze an immutable release plan with local configuration, document
30
28
  1. 使用插件根相对路径运行 CLI:`CLI="node ${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs"`
31
29
  2. 配置含 `releaseDocuments` 时,先运行只读演练 `${CLI} docs refresh --unit <id> --json`;`status: "changes"` 时展示逐文件路径/语种/版本/`refreshDigest`,取得"本地发布文档写入"明确授权后才执行 `nextCommand.argv` 写入,审阅并提交刷新结果后再继续;`status: "clean"` 时直接进入 prepare
32
30
  3. 运行 `${CLI} prepare --root <path> --offline --json`
33
- 4. 若遇到 hook/gate 授权门失败,分别展示命令和风险,获取授权后只增加实际需要的 `--acknowledge-hook-side-effects` / `--acknowledge-gate-side-effects`
34
- 5. 检查 exit code 0,读取 JSON 返回的 immutable `planPath=plans/<planDigest>.json`,再从该文件读取 `status`、`units`、`externalActions`
35
- 6. 向用户展示 targetVersion、externalActions、planDigest 和 planPath;后续 approve/publish 只能使用该 immutable planPath,等待确认后再 approve
31
+ 4. 检查 exit code 0,读取 JSON 返回的 immutable `planPath=plans/<planDigest>.json`,再从该文件读取 `status`、`units`、`externalActions`
32
+ 5. 向用户展示可读的 `approvalSummary`(版本、仓库/包、branch/tag、外部动作和例外);`planDigest` 仅作为内部绑定字段,不要求用户复制或确认。后续 approve/publish 只能使用该 immutable planPath,等待确认后再 approve
36
33
 
37
34
  若用户明确要求 GitHub+npm 生产发布,加入 `--production`。该模式还会封存独立
38
35
  Git commit/tree 和 npm tarball,并把路径、SHA/integrity、branch/tag 写入计划。
@@ -63,24 +60,18 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" docs refresh --unit <id> \
63
60
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" prepare --root <path> --offline --json
64
61
  # 生产 happy end:bound 基线必须 online;远端目标唯一性仍由 publish 全局预检
65
62
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" prepare --root <path> --online --production --json
66
- # 项目含 hook 时需显式授权:
67
- node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" prepare --root <path> --offline --acknowledge-hook-side-effects --json
68
- # 项目含 snapshot gate 时另行显式授权:
69
- node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" prepare --root <path> --offline --acknowledge-gate-side-effects --json
70
63
  ```
71
64
 
72
65
  ## 执行顺序
73
66
 
74
67
  1. 校验配置 schema → 2. 版本解析与发布文档新鲜度门(只读,RELEASE_DOCS_STALE)→
75
- 3. Hook 授权门 → 4. 运行 hooks 并复检文档新鲜度 → 5. 捕获 Git baseline →
76
- 6. 逐 unit 观察前序公开基线 → 7. 生成快照/扫描/README → 8. 原子写入 plan
68
+ 3. 运行 hooks 并复检文档新鲜度 → 4. 捕获 Git baseline →
69
+ 5. 逐 unit 观察前序公开基线 → 6. 生成快照/扫描/README → 7. 原子写入 plan
77
70
 
78
71
  ## 故障路由
79
72
 
80
73
  | 错误码 | 处理 |
81
74
  |---|---|
82
- | GATE_FAILED (hook 授权) | 向用户展示 hook 命令和风险,获得授权后加 `--acknowledge-hook-side-effects` 重试 |
83
- | GATE_FAILED (gate 授权) | 向用户展示 snapshot gate 命令和风险,获得授权后加 `--acknowledge-gate-side-effects` 重试 |
84
75
  | GATE_FAILED (bound + offline) | 改用 `--online --production`,不得把 unobserved-offline plan 交给 publish |
85
76
  | GATE_FAILED (前序基线漂移) | 先取得并比较实际远端内容;人工选择 merge/adopt/reject。merge/adopt 都必须把接受内容落回 human-owned 权威源,并把 `previousPublicBaseline` 更新为接受状态的精确 repo/ref/commit 后重新 online production prepare;reject 停止调查,禁止改 `mode: none` 绕过 |
86
77
  | GATE_FAILED (`npm-entry-closure`) | 修复打包内容或入口声明后重新 prepare;不得用 `requiredPublicFiles`/`smokeBin` 缺省绕过 |
@@ -94,4 +85,4 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" prepare --root <path> --offli
94
85
 
95
86
  ## 后续引导
96
87
 
97
- 计划冻结后,读取命令返回的 immutable `planPath` 展示给用户,等待确认后再 approve。`release-plan.json` 等 latest alias 只用于浏览,不得作为生产 authority 传递。
88
+ 计划冻结后,读取命令返回的 immutable `planPath` 和 `approvalSummary` 展示给用户,等待确认后再 approve。`planDigest` 由系统自动计算和绑定,不作为人工交互口令。`release-plan.json` 等 latest alias 只用于浏览,不得作为生产 authority 传递。
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: release-publish
3
- description: 从已批准且摘要确认的生产计划发布冻结 Git branch/tag、npm tarball 与 GitHub Release,并执行已配置的 Claude/Codex marketplace 隔离消费者安装检查以达到 PUBLISHED;随后必须路由 release-verify 才可能达到 VERIFIED;遇到冲突或不确定远端状态时失败关闭并要求人工介入
3
+ description: 从已批准的生产计划发布冻结 Git branch/tag、npm tarball 与 GitHub Release,并执行已配置的 Claude/Codex marketplace 隔离消费者安装检查以达到 PUBLISHED;随后必须路由 release-verify 才可能达到 VERIFIED;遇到冲突或不确定远端状态时失败关闭并要求人工介入
4
4
  ---
5
5
 
6
6
  # release-publish
@@ -25,16 +25,15 @@ description: 从已批准且摘要确认的生产计划发布冻结 Git branch/t
25
25
 
26
26
  ## 授权门
27
27
 
28
- 1. 展示 `planDigest`、版本、仓库/包名、branch/tag 和全部 actions。
29
- 2. 必须存在未过期且绑定同一 digest 的 approval record
30
- 3. 用户必须明确提供 `--confirm-production <planDigest>`;Agent 不得代替用户猜测确认值。
31
- 4. 只有 CLI exit code 0 且结构化状态为 `PUBLISHED` 才算外写阶段通过;随后必须运行 verify,只有 `VERIFIED` 才是完整终态。
28
+ 1. 展示可读的 `approvalSummary`:版本、仓库/包名、branch/tag、全部 actions 和例外。
29
+ 2. 必须存在未过期且由系统绑定同一内部 digest 的 approval record;批准后不再要求用户复制摘要做二次确认。
30
+ 3. 只有 CLI exit code 0 且结构化状态为 `PUBLISHED` 才算外写阶段通过;随后必须运行 verify,只有 `VERIFIED` 才是完整终态。
32
31
 
33
32
  ## 确定性执行
34
33
 
35
34
  ```bash
36
35
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" publish --root <path> --plan <plan-path> \
37
- --approval <approval-path> --confirm-production <planDigest> --json
36
+ --approval <approval-path> --json
38
37
  ```
39
38
 
40
39
  执行顺序:全局只读预检 → 配置的公开分支(按三种 `branchStrategy` 执行)→ 必要时
@@ -32,7 +32,7 @@ marketplace 隔离消费者 checkpoint,但只恢复到 `PUBLISHED`;最终 np
32
32
  1. 使用插件根相对路径运行 CLI,确认有 `--run` 路径(必需),且源 run 状态为 `PARTIAL`
33
33
  2. 运行 `node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" reconcile --root <path> --plan <plan-path> --run <run-path> --json`
34
34
  3. 检查 exit code 和结构化状态:`PUBLISHED`(恢复完成,待 verify)/ `PARTIAL`(需重试)/ `BLOCKED`(需人工决策)
35
- 4. 若 PARTIAL 且需重试,加 `--approval`;生产计划还必须加 `--confirm-production <planDigest>`
35
+ 4. 若 PARTIAL 且需重试,加 `--approval`;批准记录由系统核验与冻结计划的内部摘要绑定,不再要求二次摘要确认
36
36
 
37
37
  ## 确定性脚本调用
38
38
 
@@ -42,7 +42,7 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" reconcile --root <path> --pla
42
42
  # verify
43
43
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --plan <plan-path> --run <reconcile-run-path> --json
44
44
  # 重试(需 --approval)
45
- node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" reconcile --root <path> --plan <plan-path> --run <run-path> --approval <approval-path> --confirm-production <planDigest> --json
45
+ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" reconcile --root <path> --plan <plan-path> --run <run-path> --approval <approval-path> --json
46
46
  ```
47
47
 
48
48
  ## 幂等跳过逻辑
@@ -17,7 +17,7 @@ verify 只接受 `PUBLISHED` 状态的源 run;`VERIFIED` 是终态,不会再
17
17
 
18
18
  ## 职责与边界
19
19
 
20
- 验证远端所有 action 的实际状态与冻结计划一致。执行精确 `<package>@<version>` npm 安装到隔离目录,验证包名、版本、静态入口闭包,并在配置时验证 bin 路径安全和 CLI 烟雾输出。对每个声明的 marketplace distribution 执行全新隔离消费者安装验证。
20
+ 验证远端所有自动化 action 的实际状态与冻结计划一致。执行精确 `<package>@<version>` npm 安装到隔离目录,验证包名、版本、静态入口闭包,并在配置时验证 bin 路径安全和 CLI 烟雾输出。对 Claude/Codex marketplace distribution 执行全新隔离消费者安装验证。新计划中的 Kimi/CodeBuddy 安装只返回 `manualFollowUps`,明确标记 `verifiedBySystem: false`,不阻塞 `VERIFIED`;缺少该策略字段的旧冻结计划继续走历史 attestation 兼容路径。
21
21
 
22
22
  **阶段通过规则**: 只有 CLI exit code 0 和结构化状态码 `VERIFIED` 才是完整终态。
23
23
 
@@ -28,7 +28,7 @@ verify 只接受 `PUBLISHED` 状态的源 run;`VERIFIED` 是终态,不会再
28
28
  ## 正向执行路径
29
29
 
30
30
  1. 确认有 `--run` 路径(必需),且源 run 状态为 PUBLISHED
31
- 2. 使用插件根相对路径运行 CLI;若存在 consumer gate npm `smokeBin`,先逐项审阅并增加 `--acknowledge-gate-side-effects`
31
+ 2. 使用插件根相对路径运行 CLI;命令调用本身即授权执行已配置的 verification gate smoke process
32
32
  3. 检查 exit code 和结构化状态:`VERIFIED`(全部通过)/ 失败(具体错误)
33
33
  4. 只有 `VERIFIED` 才是 happy end
34
34
 
@@ -37,8 +37,6 @@ verify 只接受 `PUBLISHED` 状态的源 run;`VERIFIED` 是终态,不会再
37
37
  ```bash
38
38
  # 从插件根运行
39
39
  node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --plan <plan-path> --run <run-path> --json
40
- # 计划含 consumer gate 或 smokeBin 时:
41
- node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --plan <plan-path> --run <run-path> --acknowledge-gate-side-effects --json
42
40
  ```
43
41
 
44
42
  ## 验证步骤
@@ -47,7 +45,7 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --plan <
47
45
  2. 加载源 run,验证 planDigest 匹配和 checkpoint 完整性
48
46
  3. 对每个 plan action 执行 adapter.verify()(远端状态重检)
49
47
  4. 对每个 npm distribution 执行隔离安装烟雾测试
50
- 5. 对每个 marketplace distribution 执行全新隔离消费者安装验证
48
+ 5. Claude/Codex marketplace distribution 执行全新隔离消费者安装验证;收集 Kimi/CodeBuddy 的非阻塞 `manualFollowUps`
51
49
  6. 全部通过 → `VERIFIED`
52
50
 
53
51
  ## 烟雾测试
@@ -69,4 +67,4 @@ node "${CLAUDE_PLUGIN_ROOT}/bin/release-skill.mjs" verify --root <path> --plan <
69
67
  | 远端状态不匹配 | POST_PUBLISH_VERIFY_FAILED | 停止 |
70
68
  | npm 安装失败 | POST_PUBLISH_VERIFY_FAILED | 停止 |
71
69
  | CLI 烟雾输出不匹配 | POST_PUBLISH_VERIFY_FAILED | 停止 |
72
- | consumer gate / smokeBin 未授权 | GATE_FAILED | 展示命令和副作用,人工确认后加 `--acknowledge-gate-side-effects` |
70
+ | consumer gate / smokeBin 执行失败 | GATE_FAILED | 检查失败原因,修复后重试 |
@@ -54,7 +54,8 @@ function defaultClock() {
54
54
  *
55
55
  * @param {Object} options
56
56
  * @param {string} options.planPath - Absolute path to the frozen release plan.
57
- * @param {string} options.expectedDigest - Expected SHA-256 digest of the plan.
57
+ * @param {string} [options.expectedDigest] - Expected SHA-256 digest of the plan.
58
+ * When omitted, the digest is computed from the immutable plan file.
58
59
  * @param {string} options.actor - Identity of the approver.
59
60
  * @param {number} [options.expiresInMs=86400000] - Approval validity in ms (default 24h).
60
61
  * @param {() => string} [options.clock] - Clock function returning ISO-8601 strings.
@@ -70,7 +71,7 @@ function defaultClock() {
70
71
  export async function approvePlan(options) {
71
72
  const {
72
73
  planPath,
73
- expectedDigest,
74
+ expectedDigest: expectedDigestInput,
74
75
  actor,
75
76
  expiresInMs = 24 * 60 * 60 * 1000, // 24 hours
76
77
  clock,
@@ -83,9 +84,6 @@ export async function approvePlan(options) {
83
84
  if (!planPath || typeof planPath !== 'string') {
84
85
  throw new ReleaseError(PLAN_DIGEST_MISMATCH, 'planPath must be a non-empty string');
85
86
  }
86
- if (!expectedDigest || typeof expectedDigest !== 'string') {
87
- throw new ReleaseError(PLAN_DIGEST_MISMATCH, 'expectedDigest must be a non-empty string');
88
- }
89
87
  if (!actor || typeof actor !== 'string') {
90
88
  throw new ReleaseError(GATE_FAILED, 'actor must be a non-empty string');
91
89
  }
@@ -119,7 +117,11 @@ export async function approvePlan(options) {
119
117
  const actualDigest = computePlanDigest(plan);
120
118
  assertImmutablePlanAuthority(planPath, plan);
121
119
 
122
- // --- Step 3: Compare digests ---
120
+ // --- Step 3: Resolve expectedDigest ---
121
+ // When expectedDigest is omitted, auto-compute from the immutable plan file.
122
+ const expectedDigest = expectedDigestInput ?? actualDigest;
123
+
124
+ // --- Step 4: Compare digests ---
123
125
  if (actualDigest !== expectedDigest) {
124
126
  throw new ReleaseError(
125
127
  PLAN_DIGEST_MISMATCH,
@@ -4,7 +4,7 @@ import { resolve } from 'node:path';
4
4
  import { loadProjectConfig } from '../core/config.mjs';
5
5
  import { createEvidenceWriter } from '../core/evidence.mjs';
6
6
  import { runDeclaredHooks } from './prepare.mjs';
7
- import { ReleaseError, GATE_FAILED } from '../core/errors.mjs';
7
+ // ReleaseError and GATE_FAILED removed: no authorization gate remains.
8
8
 
9
9
  /**
10
10
  * Run the declared development gates and populate the exact same content-bound
@@ -14,16 +14,12 @@ import { ReleaseError, GATE_FAILED } from '../core/errors.mjs';
14
14
  export async function validateDeclaredHooks(options = {}) {
15
15
  const {
16
16
  root = process.cwd(),
17
- hooksAuthorized,
17
+ hooksAuthorized: _hooksAuthorized,
18
18
  hookCache = true,
19
19
  runDir = resolve(root, '.release-skill', 'runs', `hooks-${Date.now()}`),
20
20
  } = options;
21
- if (hooksAuthorized !== true) {
22
- throw new ReleaseError(
23
- GATE_FAILED,
24
- 'hooks validate executes declared project commands; pass --acknowledge-hook-side-effects',
25
- );
26
- }
21
+ // The command invocation itself authorizes execution of configured hooks.
22
+ // Old --acknowledge-hook-side-effects is accepted as a no-effect compatibility input.
27
23
  const { config, configDigest } = await loadProjectConfig({ root });
28
24
  await mkdir(runDir, { recursive: true });
29
25
  const evidence = createEvidenceWriter({