release-skill 0.9.6 → 0.9.7

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.
@@ -9,7 +9,7 @@
9
9
  {
10
10
  "name": "release-skill",
11
11
  "source": "./",
12
- "version": "0.9.6",
12
+ "version": "0.9.7",
13
13
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
14
14
  "author": {
15
15
  "name": "广州市风荷科技有限公司"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "广州市风荷科技有限公司"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "广州市风荷科技有限公司"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "广州市风荷科技有限公司"
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "defaultPrompt": [
21
21
  "Assess this project for release readiness.",
22
- "Prepare a release plan for version 0.9.6.",
22
+ "Prepare a release plan for version 0.9.7.",
23
23
  "Help me understand the release workflow."
24
24
  ]
25
25
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "广州市风荷科技有限公司"
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ <!-- release-skill:changelog:start version=0.9.7 locale=en baseline=sha256:6e411cb3026241b30954e2f23e0eadc8674b3531927e8c5069c92b46749fdb01 -->
4
+ ## [0.9.7] - 2026-09-02
5
+
6
+ 0.9.7 is a local source candidate that retains the 0.9.6 postverify and isolated install-tree safeguards and corrects verify's bundled-family install-root coordinate: when an adapter `installPath` is already the installed plugin root, manifest `skills` are interpreted relative to `.`. It consumes the three Foundation packages at the exact 0.16.0 release. This note is not evidence of publication, real-host acceptance, consumer installation verification, or independent acceptance.
7
+
8
+ ### Security
9
+
10
+ - `postverify` binds `planDigest`, the source `VERIFIED` run, each `hookId`, and its immutable hook approval; expired or mismatched approvals fail closed before hook execution, without adding a second state or authority.
11
+ - Declared payload symlinks, frozen-source symlinks, and legacy install-tree symlinks continue to fail closed; host-added symlinks are recorded as raw targets only.
12
+ - Missing paths, files, and symlinks continue to fail closed.
13
+ - Any host plan remains a qualified frozen-plan path and requires a VERIFIED-run from the same release lineage before host acceptance; this source candidate does not provide that acceptance.
14
+
15
+ ### Changed
16
+
17
+ - When an adapter `installPath` is already the installed plugin root, verify interprets the manifest's `skills` path relative to `.`. prepare and publish keep their frozen-snapshot coordinates unchanged.
18
+ - Allow multiple frozen host manifests to share one non-empty canonical source Skill surface; closure scans that surface once while host coverage retains every declared host.
19
+ - Before any external write, publish re-derives the frozen manifest claims and rechecks the closure.
20
+ - Consumer install paths remain isolated by host realpath; overlapping realpaths fail closed.
21
+ - Retain the public `postverify` path and the stable isolated install-tree record path; this candidate does not expand standalone-index or host acceptance support.
22
+ - Use Foundation 0.16.0 `createFilesystemRootBinding` and `observeFilesystemTree` in record mode for Claude and Codex marketplace install-tree observation; ordinary files keep the existing comparison, directories stay out of extra installed paths, and the frozen `manifestDigest` remains unchanged.
23
+ - Keep the narrow R-05 Hook cache v2 consumer path, the explicit CodeBuddy plugin entry (`marketplace: release-skill`), and `--root <project-root>` in release-finish local-finish examples.
24
+
25
+ ### Upgrade Notes
26
+
27
+ Prepare a new 0.9.7 plan when adopting this candidate. The `postverify` command requires the same plan digest, a source `VERIFIED` run, and an immutable approval for each declared hook; an expired or mismatched approval stops before hook execution. Real-host acceptance can begin only after 0.9.7 is officially published and VERIFIED; the official 0.9.7 entry must be installed or reloaded first. A source candidate, an older installed entry, or the mere existence of plan and run files cannot complete real-host acceptance. Each selected host must complete a first successful update. On the second run, Claude, Kimi, CodeBuddy, and WorkBuddy must report `ALREADY_CURRENT`; Codex may report `UPDATED` only when it reinstalls the same exact 0.9.7 frozen reference, payload validation passes, and `restartRequired=true` is declared. Before the official 0.9.7 release and VERIFIED result, do not claim that GLAF4 passed. After the official 0.9.7 release, the original GLAF4 0.5.4 immutable plan and PUBLISHED run can be reverified; GLAF4 does not need to be reissued. This source candidate does not claim publication, GLAF4 acceptance, or consumer-installation verification.
28
+ <!-- release-skill:changelog:end version=0.9.7 locale=en -->
29
+
30
+
3
31
  <!-- release-skill:changelog:start version=0.9.6 locale=en baseline=sha256:cc19a29543385bc4fbb52ac576b2310bca4b6963121dce82ada0ac933e237bfd -->
4
32
  ## [0.9.6] - 2026-09-02
5
33
 
package/INSTALL.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [简体中文](INSTALL.zh-CN.md)
4
4
 
5
- <!-- release-skill:release-version: 0.9.6 -->
5
+ <!-- release-skill:release-version: 0.9.7 -->
6
6
  ## Prerequisites
7
7
 
8
8
  - Node.js 22.0.0 or later
@@ -114,7 +114,7 @@ tag pinned to the exact version (never the bare repository URL, which installs
114
114
  the latest release or default branch), confirm the trust prompt, then reload:
115
115
 
116
116
  ```
117
- /plugins install https://github.com/ifoohoo/release-skill/releases/tag/release-skill-v0.9.6
117
+ /plugins install https://github.com/ifoohoo/release-skill/releases/tag/release-skill-v0.9.7
118
118
  /plugins reload
119
119
  ```
120
120
 
package/INSTALL.zh-CN.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [English](INSTALL.md)
4
4
 
5
- <!-- release-skill:release-version: 0.9.6 -->
5
+ <!-- release-skill:release-version: 0.9.7 -->
6
6
  ## 前置条件
7
7
 
8
8
  - Node.js 22.0.0 或更高版本
@@ -104,7 +104,7 @@ Kimi Code 有交互式插件市场,但**没有可脚本化的非交互安装
104
104
  (切勿使用裸仓库地址,它会安装最新 release 或默认分支),确认信任提示后重新加载:
105
105
 
106
106
  ```
107
- /plugins install https://github.com/ifoohoo/release-skill/releases/tag/release-skill-v0.9.6
107
+ /plugins install https://github.com/ifoohoo/release-skill/releases/tag/release-skill-v0.9.7
108
108
  /plugins reload
109
109
  ```
110
110
 
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [简体中文](README.zh-CN.md) · Installation: [English](INSTALL.md) / [简体中文](INSTALL.zh-CN.md)
4
4
 
5
- <!-- release-skill:release-version: 0.9.6 -->
5
+ <!-- release-skill:release-version: 0.9.7 -->
6
6
  Release preparation for Claude Code, CodeBuddy, WorkBuddy, Codex, and Kimi Code, with human-edited files kept intact.
7
7
 
8
8
  release-skill helps a maintainer answer three questions: what will be released,
@@ -14,34 +14,34 @@ Setup surfaces only the deterministic `compactSummary` review view; the full
14
14
  report stays in a temporary session directory.
15
15
 
16
16
  <!-- release-skill:managed:start id=latest-release -->
17
- **0.9.6** (2026-09-02)
17
+ **0.9.7** (2026-09-02)
18
18
 
19
- 0.9.6 is a local source candidate that adds a public `postverify` CLI for same-lineage postPublish hooks without ship state, and records host-added symlinks in Claude and Codex marketplace install trees without following them. It consumes the three Foundation packages at the exact 0.16.0 release. This note is not evidence of publication, real-host acceptance, consumer installation verification, or independent acceptance.
19
+ 0.9.7 is a local source candidate that retains the 0.9.6 postverify and isolated install-tree safeguards and corrects verify's bundled-family install-root coordinate: when an adapter `installPath` is already the installed plugin root, manifest `skills` are interpreted relative to `.`. It consumes the three Foundation packages at the exact 0.16.0 release. This note is not evidence of publication, real-host acceptance, consumer installation verification, or independent acceptance.
20
20
 
21
21
  **Security**
22
22
 
23
23
  - `postverify` binds `planDigest`, the source `VERIFIED` run, each `hookId`, and its immutable hook approval; expired or mismatched approvals fail closed before hook execution, without adding a second state or authority.
24
24
  - Declared payload symlinks, frozen-source symlinks, and legacy install-tree symlinks continue to fail closed; host-added symlinks are recorded as raw targets only.
25
+ - Missing paths, files, and symlinks continue to fail closed.
25
26
  - Any host plan remains a qualified frozen-plan path and requires a VERIFIED-run from the same release lineage before host acceptance; this source candidate does not provide that acceptance.
26
27
 
27
- **Added**
28
-
29
- - Add the public `postverify` command for phase-by-phase `prepare` → `approve` → `publish` → `distribute` → `verify` lineages that need to run approved postPublish hooks without a ship state or a second authority.
30
- - Record host-added symlinks in Claude and Codex marketplace install trees as paths and raw targets without following them, while keeping declared and frozen symlinks fail-closed.
31
-
32
28
  **Changed**
33
29
 
30
+ - When an adapter `installPath` is already the installed plugin root, verify interprets the manifest's `skills` path relative to `.`. prepare and publish keep their frozen-snapshot coordinates unchanged.
31
+ - Allow multiple frozen host manifests to share one non-empty canonical source Skill surface; closure scans that surface once while host coverage retains every declared host.
32
+ - Before any external write, publish re-derives the frozen manifest claims and rechecks the closure.
33
+ - Consumer install paths remain isolated by host realpath; overlapping realpaths fail closed.
34
+ - Retain the public `postverify` path and the stable isolated install-tree record path; this candidate does not expand standalone-index or host acceptance support.
34
35
  - Use Foundation 0.16.0 `createFilesystemRootBinding` and `observeFilesystemTree` in record mode for Claude and Codex marketplace install-tree observation; ordinary files keep the existing comparison, directories stay out of extra installed paths, and the frozen `manifestDigest` remains unchanged.
35
- - Keep the narrow R-05 Hook cache v2 consumer path and the stable isolated install-tree record path; this candidate does not expand standalone-index or host acceptance support.
36
- - Retain the explicit CodeBuddy plugin entry (`marketplace: release-skill`) and `--root <project-root>` in release-finish local-finish examples.
36
+ - Keep the narrow R-05 Hook cache v2 consumer path, the explicit CodeBuddy plugin entry (`marketplace: release-skill`), and `--root <project-root>` in release-finish local-finish examples.
37
37
 
38
38
  **Upgrade Notes**
39
39
 
40
- Prepare a new 0.9.6 plan when adopting these changes. The `postverify` command requires the same plan digest, a source `VERIFIED` run, and an immutable approval for each declared hook; an expired or mismatched approval stops before hook execution. Real-host acceptance still requires an officially published and VERIFIED release; the official 0.9.6 entry must be installed or reloaded first. A source candidate, an older installed entry, or the mere existence of plan and run files cannot complete real-host acceptance. Each selected host must complete a first successful update. On the second run, Claude, Kimi, CodeBuddy, and WorkBuddy must report `ALREADY_CURRENT`; Codex may report `UPDATED` only when it reinstalls the same exact 0.9.6 frozen reference, payload validation passes, and `restartRequired=true` is declared. This source candidate does not claim publication, GLAF4 acceptance, Hub postVerify, or consumer-installation verification.
40
+ Prepare a new 0.9.7 plan when adopting this candidate. The `postverify` command requires the same plan digest, a source `VERIFIED` run, and an immutable approval for each declared hook; an expired or mismatched approval stops before hook execution. Real-host acceptance can begin only after 0.9.7 is officially published and VERIFIED; the official 0.9.7 entry must be installed or reloaded first. A source candidate, an older installed entry, or the mere existence of plan and run files cannot complete real-host acceptance. Each selected host must complete a first successful update. On the second run, Claude, Kimi, CodeBuddy, and WorkBuddy must report `ALREADY_CURRENT`; Codex may report `UPDATED` only when it reinstalls the same exact 0.9.7 frozen reference, payload validation passes, and `restartRequired=true` is declared. Before the official 0.9.7 release and VERIFIED result, do not claim that GLAF4 passed. After the official 0.9.7 release, the original GLAF4 0.5.4 immutable plan and PUBLISHED run can be reverified; GLAF4 does not need to be reissued. This source candidate does not claim publication, GLAF4 acceptance, or consumer-installation verification.
41
41
  <!-- release-skill:managed:end id=latest-release -->
42
42
 
43
43
  <!-- release-skill:capability:external-write-boundary -->
44
- > **Current boundary:** v0.9.6 is the current source candidate. This README
44
+ > **Current boundary:** v0.9.7 is the current source candidate. This README
45
45
  > records intended scope and verification boundaries; it is not evidence of
46
46
  > publication, consumer-installation verification, or independent acceptance.
47
47
  > Release availability must be established from the corresponding release records
@@ -65,7 +65,7 @@ Prepare a new 0.9.6 plan when adopting these changes. The `postverify` command r
65
65
  > publish global preflight.
66
66
 
67
67
  <!-- release-skill:capability:safe-first-command -->
68
- > **Production path verified since the v0.1.1 milestone; v0.9.6 is the current
68
+ > **Production path verified since the v0.1.1 milestone; v0.9.7 is the current
69
69
  > source candidate. Its README does not establish publication,
70
70
  > consumer-installation verification, or independent acceptance.**
71
71
  > The npm-installed CLI is the supported user entry. Source checkout
@@ -94,7 +94,7 @@ checkpoints remain intact and use matching-version recovery. Evidence v1 stays
94
94
  read-only; v2 uses a closed top level with phase extensions in `details`.
95
95
  Summaries and recovery suggestions are diagnostic, never publication authority.
96
96
 
97
- The current 0.9.6 candidate includes the narrow R-05 Hook cache v2 consumer
97
+ The current 0.9.7 candidate includes the narrow R-05 Hook cache v2 consumer
98
98
  path, the public `postverify` path, and the stable isolated install-tree record
99
99
  path (A2/A3). It still
100
100
  excludes R-02 safe full-tree inventory, R-10 historical-release verification
package/README.zh-CN.md CHANGED
@@ -2,40 +2,40 @@
2
2
 
3
3
  [English](README.md) · 安装指南:[中文](INSTALL.zh-CN.md) / [English](INSTALL.md)
4
4
 
5
- <!-- release-skill:release-version: 0.9.6 -->
5
+ <!-- release-skill:release-version: 0.9.7 -->
6
6
  面向 Claude Code、CodeBuddy、WorkBuddy、Codex 和 Kimi Code 的发布准备工具,完整保留人工维护的文件内容。
7
7
 
8
8
  release-skill 帮助维护者回答三个问题:准备发布什么、还有哪些检查未通过、最终发布的内容是什么。它不重新生成、也不回写项目源文件。`prepare` 把每个配置的公开文件复制到隔离快照并验证字节——先冻结并供人工审阅,再从同一份冻结产物发布。`setup` 只显示确定性的 `compactSummary` 审阅视图,完整报告保留在临时会话目录中。
9
9
 
10
10
  <!-- release-skill:managed:start id=latest-release -->
11
- **0.9.6** (2026-09-02)
11
+ **0.9.7** (2026-09-02)
12
12
 
13
- 0.9.6 是当前本地源码候选,新增无需 ship 状态即可处理同一发布谱系 postPublish hook 的公开 `postverify` 命令,并在 Claude Codex 市场安装树中记录宿主新增的 symlink,不跟随链接。三项 Foundation 依赖均精确消费已发布的 0.16.0。本说明不代表已经发布、完成真实宿主验收、完成消费者安装验证或通过独立验收。
13
+ 0.9.7 是保留 0.9.6 postverify 和隔离安装树安全边界、并修正 verify bundled-family 安装根坐标的本地源码候选:当适配器的 `installPath` 已经是安装后的插件根目录时,manifest `skills` 路径按 `.` 解释。三项 Foundation 依赖均精确消费已发布的 0.16.0。本说明不代表已经发布、完成真实宿主验收、完成消费者安装验证或通过独立验收。
14
14
 
15
15
  **安全**
16
16
 
17
17
  - `postverify` 绑定 `planDigest`、源 `VERIFIED` run、每个 `hookId` 和对应的不可变 hook approval;批准过期或不匹配时,在执行 hook 前失败关闭,不增加第二状态或第二权威。
18
18
  - 声明载荷 symlink、冻结源码 symlink 和 legacy 安装树 symlink 继续失败关闭;宿主新增 symlink 只记录原始目标。
19
+ - 缺失路径、文件和 symlink 继续失败关闭。
19
20
  - 任何宿主计划都必须是合格冻结计划,并要求同一发布谱系的 VERIFIED run 才能开始宿主验收;本源码候选不提供该验收。
20
21
 
21
- **新增**
22
-
23
- - 新增公开 `postverify` 命令,支持沿 `prepare` → `approve` → `publish` → `distribute` → `verify` 阶段谱系,在没有 ship 状态或第二权威的情况下执行已批准的 postPublish hook。
24
- - Claude 和 Codex 市场安装树记录宿主新增 symlink 的路径和原始目标,不跟随链接;声明载荷和冻结源码中的 symlink 仍失败关闭。
25
-
26
22
  **变更**
27
23
 
28
- - Claude Codex 市场安装树使用 Foundation 0.16.0 的 `createFilesystemRootBinding` record 模式 `observeFilesystemTree`;普通文件继续使用现有比较,目录不进入额外安装路径,冻结的 `manifestDigest` 保持不变。
29
- - 保留窄范围的 R-05 Hook cache v2 消费路径和稳定的隔离安装树记录路径;本候选不扩展 standalone-index 或宿主验收支持。
30
- - 保留 CodeBuddy 插件显式的 `marketplace: release-skill` 条目,以及 release-finish 本机收尾示例中的 `--root <project-root>`。
24
+ - 当适配器的 `installPath` 已经是安装后的插件根目录时,verify `.` 解释 manifest 的 `skills` 路径;prepare publish 的冻结快照坐标保持不变。
25
+ - 允许多份冻结 host manifest 共享同一个非空 canonical source Skill surface;closure 只扫描一次,host coverage 保留每个已声明宿主。
26
+ - publish 在任何外部写入前按冻结 manifest 事实重新派生 claims 并重检 closure。
27
+ - 消费者安装路径继续按宿主 realpath 隔离;realpath 重合时失败关闭。
28
+ - 保留公开 `postverify` 路径和稳定的隔离安装树记录路径;本候选不扩展 standalone-index 或宿主验收支持。
29
+ - Claude 和 Codex 市场安装树继续使用 Foundation 0.16.0 的 `createFilesystemRootBinding` 与 record 模式 `observeFilesystemTree`;普通文件继续使用现有比较,目录不进入额外安装路径,冻结的 `manifestDigest` 保持不变。
30
+ - 保留窄范围的 R-05 Hook cache v2 消费路径、CodeBuddy 插件显式的 `marketplace: release-skill` 条目,以及 release-finish 本机收尾示例中的 `--root <project-root>`。
31
31
 
32
32
  **升级说明**
33
33
 
34
- 采用这些改动时请重新准备 0.9.6 计划。`postverify` 要求同一计划摘要、源 `VERIFIED` run,以及每个已声明 hook 的不可变 approval;批准过期或不匹配时会在执行 hook 前停止。真实宿主验收仍要求正式发布并达到 VERIFIED;正式的 0.9.6 入口必须先安装或重载。源码候选、旧的已安装入口,或仅存在计划和运行文件,都不能完成真实宿主验收。每个选定宿主都必须先完成首次成功更新。第二次运行时,Claude、Kimi、CodeBuddy 和 WorkBuddy 必须返回 `ALREADY_CURRENT`;Codex 可以使用 `UPDATED`,但只有在重新安装同一精确 0.9.6 冻结引用、载荷验证通过并声明 `restartRequired=true` 时才允许这样返回。本源码候选不提供该验收,也不代表已经发布、完成 GLAF4 验收、完成 Hub postVerify 或完成消费者安装验证。
34
+ 采用本候选时请重新准备 0.9.7 计划。`postverify` 要求同一计划摘要、源 `VERIFIED` run,以及每个已声明 hook 的不可变 approval;批准过期或不匹配时会在执行 hook 前停止。真实宿主验收只有在 0.9.7 正式发布并达到 VERIFIED 后才能开始;必须先安装或重载正式的 0.9.7 入口。源码候选、旧的已安装入口,或仅存在计划和运行文件,都不能完成真实宿主验收。每个选定宿主都必须先完成首次成功更新。第二次运行时,Claude、Kimi、CodeBuddy 和 WorkBuddy 必须返回 `ALREADY_CURRENT`;Codex 可以使用 `UPDATED`,但只有在重新安装同一精确 0.9.7 冻结引用、载荷验证通过并声明 `restartRequired=true` 时才允许这样返回。在 0.9.7 正式发布并达到 VERIFIED 前,不宣称 GLAF4 已通过。0.9.7 正式发布后,可以复验原 GLAF4 0.5.4 不可变计划和 PUBLISHED run;无需重新发布 GLAF4。本源码候选不代表已经发布、完成 GLAF4 验收或完成消费者安装验证。
35
35
  <!-- release-skill:managed:end id=latest-release -->
36
36
 
37
37
  <!-- release-skill:capability:external-write-boundary -->
38
- > **当前边界:** v0.9.6 只是当前源码候选。本 README 记录预期范围与验证边界,
38
+ > **当前边界:** v0.9.7 只是当前源码候选。本 README 记录预期范围与验证边界,
39
39
  > 不代表已经发布、完成消费者安装验证或通过独立验收。
40
40
  > 版本可用性以对应发布记录及发布后验证结果为准。
41
41
  > v0.4.1 是更早的已发布里程碑(v0.2.2 曾处于已发布状态,后因平台验证收敛修复而更新)。
@@ -51,7 +51,7 @@ release-skill 帮助维护者回答三个问题:准备发布什么、还有哪
51
51
  > 远端唯一性检查在 `publish` 全局预检执行。
52
52
 
53
53
  <!-- release-skill:capability:safe-first-command -->
54
- > **生产路径自 v0.1.1 里程碑起已完成真实生产验证;v0.9.6 是当前源码候选,本 README 不证明该候选已经发布、完成消费者安装验证或通过独立验收。**
54
+ > **生产路径自 v0.1.1 里程碑起已完成真实生产验证;v0.9.7 是当前源码候选,本 README 不证明该候选已经发布、完成消费者安装验证或通过独立验收。**
55
55
  > npm 安装的 CLI 是受支持的用户入口;源码 checkout 保留为开发/贡献者路径。
56
56
  >
57
57
  > **第一条命令:**
@@ -69,7 +69,7 @@ marketplace 委托目标工作区发布的边界不变。
69
69
 
70
70
  旧 production 计划缺少 `sourceAuthority` 时,在外部写入前拒绝。未发生外部写入的计划必须重新 prepare 并批准新摘要,不能补写旧计划或迁移批准。已有 `PARTIAL` 保留检查点,走匹配版本的恢复路径。evidence v1 只读;v2 顶层封闭,阶段扩展放在 `details`。摘要和恢复建议只作诊断,不构成发布权威。
71
71
 
72
- 当前 0.9.6 候选包含窄范围的 R-05 Hook cache v2 消费路径、公开 `postverify` 路径和稳定隔离安装树记录路径(A2/A3)。当前仍不包含 R-02 安全整树盘点、R-10 历史发布验证的产品实现、真实 Kimi/WorkBuddy 公开市场安装与调用门禁或 Audit 公开离线发布记录验证器。本范围说明不构成远端发布记录或消费者升级指引。
72
+ 当前 0.9.7 候选包含窄范围的 R-05 Hook cache v2 消费路径、公开 `postverify` 路径和稳定隔离安装树记录路径(A2/A3)。当前仍不包含 R-02 安全整树盘点、R-10 历史发布验证的产品实现、真实 Kimi/WorkBuddy 公开市场安装与调用门禁或 Audit 公开离线发布记录验证器。本范围说明不构成远端发布记录或消费者升级指引。
73
73
 
74
74
  Foundation 三包精确依赖已发布的 0.16.0。新生成的 Kimi/CodeBuddy 同仓计划在 verify 阶段调用正式 `runPluginVerification`,把完整冻结载荷交给 Foundation,并记录最小的 `install-only` 观察收据。Kimi 映射为 `kimi-code`,CodeBuddy 映射为兼容的 `workbuddy`。`observed` 与 `payloadMatches` 只表示机制观察结果,不代表远端已发布或 release-skill 已完成领域验证。独立市场来源、真实市场安装和宿主调用仍是人工后续任务。
75
75
 
@@ -9,7 +9,7 @@
9
9
  {
10
10
  "name": "release-skill",
11
11
  "source": "./",
12
- "version": "0.9.6",
12
+ "version": "0.9.7",
13
13
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
14
14
  "author": {
15
15
  "name": "广州市风荷科技有限公司"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "广州市风荷科技有限公司"
@@ -9,9 +9,9 @@ const __bundlePkgRoot = __bundleResolve(__bundleDirname(__bundleFileURLToPath(im
9
9
  // Provide a real require() for CJS packages bundled into ESM (e.g. yaml, ajv).
10
10
  const __bundleRealRequire = __bundleCreateRequire(import.meta.url);
11
11
  // Package identity injected at build time — closure-independent --version probe.
12
- const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.6"});
12
+ const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.7"});
13
13
  // Build-time source digest for the BUNDLE_STALE freshness gate (see above).
14
- const __bundleSourceDigest = "8fd8e6c5f7796efe9e1f7153382b50c74d78a4b5f836f872837ff2f11e4daeb5";
14
+ const __bundleSourceDigest = "938bc6828f17e2248a4fe167bcd3353b43848ec1a494dc17dc663d390847150c";
15
15
 
16
16
  var __create = Object.create;
17
17
  var __defProp = Object.defineProperty;
@@ -109520,9 +109520,27 @@ async function checkSkillResourceClosure({
109520
109520
  result2.receiptDigest = digestDocument(receiptProjection(result2));
109521
109521
  return result2;
109522
109522
  }
109523
- function evaluateDeclaredHostSurfaceCoverage(expectedHosts, surfaces) {
109523
+ function evaluateDeclaredHostSurfaceCoverage(expectedHosts, surfaces, coverageClaims = []) {
109524
109524
  const missing = [];
109525
+ const observedById = new Map((surfaces ?? []).map((surface) => [surface.id, surface]));
109526
+ const claimsByHost = /* @__PURE__ */ new Map();
109527
+ for (const claim of coverageClaims ?? []) {
109528
+ const hostClaims = claimsByHost.get(claim.host) ?? [];
109529
+ hostClaims.push(claim);
109530
+ claimsByHost.set(claim.host, hostClaims);
109531
+ }
109525
109532
  for (const expectedHost of [...new Set(expectedHosts ?? [])].sort((a, b) => a.localeCompare(b))) {
109533
+ const declaredClaims = claimsByHost.get(expectedHost) ?? [];
109534
+ if (declaredClaims.length > 0) {
109535
+ const missingClaim = declaredClaims.find((claim) => {
109536
+ const surface3 = observedById.get(claim.surfaceId);
109537
+ return !surface3 || !(surface3.skillCount >= 1);
109538
+ });
109539
+ if (!missingClaim) continue;
109540
+ const surface2 = observedById.get(missingClaim.surfaceId);
109541
+ missing.push({ host: expectedHost, skillCount: surface2?.skillCount ?? 0 });
109542
+ continue;
109543
+ }
109526
109544
  const surface = (surfaces ?? []).find((item) => item.host === expectedHost);
109527
109545
  if (!surface || !(surface.skillCount >= 1)) {
109528
109546
  missing.push({ host: expectedHost, skillCount: surface?.skillCount ?? 0 });
@@ -112496,6 +112514,23 @@ async function deriveSurfaceHostBinding({ manifest, pluginRoot, platform, snapsh
112496
112514
  const host = await normalizeHostId(platform.buildAdapter.name);
112497
112515
  return { surfaceId, host };
112498
112516
  }
112517
+ function groupSurfaceHostBindings(claims = []) {
112518
+ if (!Array.isArray(claims)) {
112519
+ throw new TypeError("surfaceHostBindings must be an array");
112520
+ }
112521
+ const bySurface = /* @__PURE__ */ new Map();
112522
+ for (const claim of claims) {
112523
+ if (!claim || typeof claim !== "object" || typeof claim.surfaceId !== "string" || typeof claim.host !== "string") {
112524
+ throw new TypeError("surfaceHostBindings entries must be objects with string surfaceId and host");
112525
+ }
112526
+ const existing = bySurface.get(claim.surfaceId) ?? [];
112527
+ existing.push({ surfaceId: claim.surfaceId, host: claim.host });
112528
+ bySurface.set(claim.surfaceId, existing);
112529
+ }
112530
+ const coverageClaims = [...bySurface.values()].flat().sort((left, right) => left.surfaceId.localeCompare(right.surfaceId) || left.host.localeCompare(right.host));
112531
+ const checkerBindings = [...bySurface.values()].filter((surfaceClaims) => surfaceClaims.length === 1).map(([claim]) => claim).sort((left, right) => left.surfaceId.localeCompare(right.surfaceId) || left.host.localeCompare(right.host));
112532
+ return { coverageClaims, checkerBindings };
112533
+ }
112499
112534
  var SKILLS_NORMALIZERS;
112500
112535
  var init_surface_host_bindings = __esm({
112501
112536
  async "src/core/surface-host-bindings.mjs"() {
@@ -112513,6 +112548,7 @@ var init_surface_host_bindings = __esm({
112513
112548
  __name(pluginRootFromManifestRelativePath, "pluginRootFromManifestRelativePath");
112514
112549
  __name(assertDeclaredSkillsDirExists, "assertDeclaredSkillsDirExists");
112515
112550
  __name(deriveSurfaceHostBinding, "deriveSurfaceHostBinding");
112551
+ __name(groupSurfaceHostBindings, "groupSurfaceHostBindings");
112516
112552
  }
112517
112553
  });
112518
112554
 
@@ -113943,11 +113979,16 @@ async function verifyRelease(options) {
113943
113979
  const unit = (plan.units ?? []).find((u) => u.id === unitId);
113944
113980
  const dist = unit?.distributions?.find((d) => d.type === platform.distributionType);
113945
113981
  let binding = null;
113982
+ let frozenPluginRoot = null;
113946
113983
  const contract2 = dist?.installationContract;
113947
113984
  if (contract2?.normalizedManifest) {
113985
+ frozenPluginRoot = pluginRootFromManifestRelativePath(contract2.manifestRelativePath);
113948
113986
  binding = await deriveSurfaceHostBinding({
113949
113987
  manifest: contract2.normalizedManifest,
113950
- pluginRoot: pluginRootFromManifestRelativePath(contract2.manifestRelativePath),
113988
+ // Adapter observations are already rooted at the installed
113989
+ // plugin. The frozen manifest's skills path is therefore
113990
+ // relative to '.', not to the snapshot-root manifest path.
113991
+ pluginRoot: ".",
113951
113992
  platform,
113952
113993
  snapshotDir: check.observation.installPath
113953
113994
  });
@@ -113960,6 +114001,7 @@ async function verifyRelease(options) {
113960
114001
  unitId,
113961
114002
  surfaceId: binding?.surfaceId ?? ".",
113962
114003
  binding,
114004
+ frozenPluginRoot,
113963
114005
  unit
113964
114006
  });
113965
114007
  }
@@ -114042,7 +114084,7 @@ async function verifyRelease(options) {
114042
114084
  );
114043
114085
  }
114044
114086
  const pluginDistCount = (surface.unit?.distributions ?? []).filter((d) => d.type !== "npm").length;
114045
- if (pluginDistCount === 1) {
114087
+ if (pluginDistCount === 1 && surface.frozenPluginRoot === ".") {
114046
114088
  const observedReceipt = createSkillResourceClosureReceipt(closureResult, {
114047
114089
  unitId: surface.unitId,
114048
114090
  preparedAt: expectedUnitReceipt.preparedAt ?? null,
@@ -129636,10 +129678,11 @@ async function runPrepareSkillResourceClosureGate({
129636
129678
  });
129637
129679
  if (binding) surfaceHostBindings.push(binding);
129638
129680
  }
129681
+ const { checkerBindings, coverageClaims } = groupSurfaceHostBindings(surfaceHostBindings);
129639
129682
  const closureResult = await checkSkillResourceClosure({
129640
129683
  snapshotDir: manifest.outputDir,
129641
129684
  host: "root",
129642
- surfaceHostBindings
129685
+ surfaceHostBindings: checkerBindings
129643
129686
  });
129644
129687
  const receipt = createSkillResourceClosureReceipt(closureResult, {
129645
129688
  unitId: unit.id,
@@ -129684,7 +129727,8 @@ async function runPrepareSkillResourceClosureGate({
129684
129727
  }
129685
129728
  const hostCoverage = evaluateDeclaredHostSurfaceCoverage(
129686
129729
  expectedHosts,
129687
- closureResult.surfaces
129730
+ closureResult.surfaces,
129731
+ coverageClaims
129688
129732
  );
129689
129733
  if (!hostCoverage.passed) {
129690
129734
  await evidence.append({
@@ -129708,7 +129752,7 @@ async function runPrepareSkillResourceClosureGate({
129708
129752
  }
129709
129753
  );
129710
129754
  }
129711
- for (const binding of surfaceHostBindings) {
129755
+ for (const binding of coverageClaims) {
129712
129756
  const boundSurface = closureResult.surfaces.find(
129713
129757
  (surface) => surface.id === binding.surfaceId
129714
129758
  );
@@ -133318,10 +133362,11 @@ async function publishRelease(options) {
133318
133362
  });
133319
133363
  if (binding) surfaceHostBindings.push(binding);
133320
133364
  }
133365
+ const { checkerBindings, coverageClaims } = groupSurfaceHostBindings(surfaceHostBindings);
133321
133366
  const closureResult = await checkSkillResourceClosure({
133322
133367
  snapshotDir,
133323
133368
  host: "root",
133324
- surfaceHostBindings
133369
+ surfaceHostBindings: checkerBindings
133325
133370
  });
133326
133371
  if (closureResult.findings.length > 0) {
133327
133372
  await evidence.append({
@@ -133337,6 +133382,31 @@ async function publishRelease(options) {
133337
133382
  { unitId, findings: closureResult.findings }
133338
133383
  );
133339
133384
  }
133385
+ const expectedHosts = [];
133386
+ for (const distribution of frozenUnit?.distributions ?? []) {
133387
+ const platform = PLATFORMS.find((item) => item.distributionType === distribution.type);
133388
+ if (platform) expectedHosts.push(await normalizeHostId(platform.buildAdapter.name));
133389
+ }
133390
+ const hostCoverage = evaluateDeclaredHostSurfaceCoverage(
133391
+ expectedHosts,
133392
+ closureResult.surfaces,
133393
+ coverageClaims
133394
+ );
133395
+ if (!hostCoverage.passed) {
133396
+ await evidence.append({
133397
+ phase: "safety-gate",
133398
+ gate: "skill-resource-closure",
133399
+ status: "failed",
133400
+ unitId,
133401
+ reason: "declared-host-surface-missing",
133402
+ missingHosts: hostCoverage.missing
133403
+ });
133404
+ throw new ReleaseError(
133405
+ GATE_FAILED,
133406
+ `skill resource closure recheck failed for unit "${unitId}": declared host surface(s) missing or empty: ${hostCoverage.missing.map((item) => item.host).join(", ")}`,
133407
+ { unitId, missingHosts: hostCoverage.missing }
133408
+ );
133409
+ }
133340
133410
  const observed = createSkillResourceClosureReceipt(closureResult, {
133341
133411
  unitId,
133342
133412
  preparedAt: expected.preparedAt ?? null,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "广州市风荷科技有限公司"
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "defaultPrompt": [
21
21
  "Assess this project for release readiness.",
22
- "Prepare a release plan for version 0.9.6.",
22
+ "Prepare a release plan for version 0.9.7.",
23
23
  "Help me understand the release workflow."
24
24
  ]
25
25
  }