release-skill 0.9.11 → 0.9.13

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.9.11",
3
+ "version": "0.9.13",
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.11",
3
+ "version": "0.9.13",
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.11",
3
+ "version": "0.9.13",
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.11.",
22
+ "Prepare a release plan for version 0.9.13.",
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.11",
3
+ "version": "0.9.13",
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,46 @@
1
1
  # Changelog
2
2
 
3
+ <!-- release-skill:changelog:start version=0.9.13 locale=en baseline=sha256:86e8ee0d0aeb161c7fc652f85976b300b649ee6da04d29f9274ebcc69a8eab10 -->
4
+ ## [0.9.13] - 2026-09-05
5
+
6
+ 0.9.13 is a local source candidate that prevents new CodeBuddy release configurations from silently inheriting another product family's marketplace. It also brings the README black-box scenario versions under the existing version synchronization command. The three Foundation dependencies remain pinned to the exact 0.17.0 release. This note is not evidence of publication, real-host acceptance, consumer installation verification, or independent acceptance.
7
+
8
+ ### Security
9
+
10
+ - Already-frozen historical plans without `marketplace` retain the legacy interpretation for deterministic reconcile. New configuration validation changes do not weaken frozen-plan identity, approval, publish, verification, or recovery checks. Skill Family Hub updates remain compare-and-swap operations; a partial Hub publication is never rolled back or force-pushed, and release-skill does not introduce a second Hub registry or state machine.
11
+
12
+ ### Fixed
13
+
14
+ - New `codebuddy-plugin` distributions must declare `marketplace` explicitly, so each project selects its own Hub instead of inheriting the legacy `artifact-skill-set` default.
15
+ - The first-user and security-reviewer README black-box prompts now receive their candidate version from `sync-version`, preventing their assertions from drifting behind the package version.
16
+ - The project-private postVerify hook continues to publish the verified release-skill entry and public snapshot to Skill Family Hub through GitHub's Git Data API.
17
+
18
+ ### Upgrade Notes
19
+
20
+ Upgrade from 0.9.12 before preparing a new CodeBuddy release configuration. Add the intended Hub name to every new `codebuddy-plugin` distribution through its `marketplace` field. Remove any release-skill standalone marketplace registration, add or update `ifoohoo/skill-family-hub`, and use `release-skill@skill-family-hub`. Existing frozen plans remain recoverable, and other distribution types are unaffected.
21
+ <!-- release-skill:changelog:end version=0.9.13 locale=en -->
22
+
23
+
24
+ <!-- release-skill:changelog:start version=0.9.12 locale=en baseline=sha256:c2511de86192c1798c17e579bed689c57c450516b10bd85d6a508b0b6e5e19b1 -->
25
+ ## [0.9.12] - 2026-09-04
26
+
27
+ 0.9.12 is a local source candidate that fixes the frozen postVerify execution closure used to publish verified releases into Skill Family Hub. It retains the 0.9.11 first-release baseline and GitHub-only distribution changes, with the three Foundation dependencies still pinned to the exact 0.17.0 release. This note is not evidence of publication, real-host acceptance, consumer installation verification, or independent acceptance.
28
+
29
+ ### Security
30
+
31
+ - The repair does not weaken the frozen execution-bundle boundary: the hook still runs from the verified tag plus the digest-bound private script. Hub branch updates remain compare-and-swap operations; a partial Hub publication is retained for recovery and is never rolled back or force-pushed.
32
+
33
+ ### Fixed
34
+
35
+ - The Hub postVerify hook now imports proposal projection from a dependency-free public module. A detached frozen-tag worktree can load the module without node_modules, while runtime proposal transports continue to use the same implementation through a compatibility re-export.
36
+ - The project-private postVerify hook continues to publish verified entries and public snapshots to Skill Family Hub through GitHub's Git Data API.
37
+
38
+ ### Upgrade Notes
39
+
40
+ Upgrade from 0.9.11 before relying on the bundled `hub-api-publish` postVerify hook. Remove any `release-skill` standalone marketplace registration, add or update `ifoohoo/skill-family-hub`, and use `release-skill@skill-family-hub`. Releases that do not use this hook are unaffected.
41
+ <!-- release-skill:changelog:end version=0.9.12 locale=en -->
42
+
43
+
3
44
  <!-- release-skill:changelog:start version=0.9.11 locale=en baseline=sha256:c8015d6a26b39a9056c121425b8758a108048d78815476e7bf3d2711cec6ee25 -->
4
45
  ## [0.9.11] - 2026-09-04
5
46
 
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.11 -->
5
+ <!-- release-skill:release-version: 0.9.13 -->
6
6
  ## Prerequisites
7
7
 
8
8
  - Node.js 22.0.0 or later
@@ -110,7 +110,7 @@ tag pinned to the exact version (never the bare repository URL, which installs
110
110
  the latest release or default branch), confirm the trust prompt, then reload:
111
111
 
112
112
  ```
113
- /plugins install https://github.com/ifoohoo/release-skill/releases/tag/release-skill-v0.9.11
113
+ /plugins install https://github.com/ifoohoo/release-skill/releases/tag/release-skill-v0.9.13
114
114
  /plugins reload
115
115
  ```
116
116
 
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.11 -->
5
+ <!-- release-skill:release-version: 0.9.13 -->
6
6
  ## 前置条件
7
7
 
8
8
  - Node.js 22.0.0 或更高版本
@@ -101,7 +101,7 @@ release-skill 当前只采用并验证 Kimi Code 的交互式 TUI 路径,**无
101
101
  (切勿使用裸仓库地址,它会安装最新 release 或默认分支),确认信任提示后重新加载:
102
102
 
103
103
  ```
104
- /plugins install https://github.com/ifoohoo/release-skill/releases/tag/release-skill-v0.9.11
104
+ /plugins install https://github.com/ifoohoo/release-skill/releases/tag/release-skill-v0.9.13
105
105
  /plugins reload
106
106
  ```
107
107
 
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.11 -->
5
+ <!-- release-skill:release-version: 0.9.13 -->
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,30 +14,27 @@ 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.11** (2026-09-04)
17
+ **0.9.13** (2026-09-05)
18
18
 
19
- 0.9.11 is a local source candidate that makes first-release verification advance its public baseline and permits an explicit empty distribution list for GitHub-only plugin releases. It consumes the three Foundation packages at the exact 0.17.0 release. This note is not evidence of publication, real-host acceptance, consumer installation verification, or independent acceptance.
19
+ 0.9.13 is a local source candidate that prevents new CodeBuddy release configurations from silently inheriting another product family's marketplace. It also brings the README black-box scenario versions under the existing version synchronization command. The three Foundation dependencies remain pinned to the exact 0.17.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
- - First-release baseline advancement runs only after immutable publication verification succeeds. Configuration writes are validated and atomic; restoration failures retain their phase and publication-state details in verification evidence without changing a successful publication result.
24
- - An empty distribution list does not skip the GitHub snapshot, tag, or GitHub Release actions, and it does not grant a marketplace registration.
25
- - Hub branch updates use compare-and-swap against the observed branch head. A partial Hub publication is retained for recovery and is never rolled back or force-pushed.
23
+ - Already-frozen historical plans without `marketplace` retain the legacy interpretation for deterministic reconcile. New configuration validation changes do not weaken frozen-plan identity, approval, publish, verification, or recovery checks. Skill Family Hub updates remain compare-and-swap operations; a partial Hub publication is never rolled back or force-pushed, and release-skill does not introduce a second Hub registry or state machine.
26
24
 
27
- **Changed**
25
+ **Fixed**
28
26
 
29
- - After a release reaches VERIFIED, a unit whose previous public baseline is `mode: none` is advanced to a bound baseline with the resolved repository and ref plus the exact frozen commit, tree, and manifest digest. Mixed plans and custom in-root config paths use the same existing atomic update path, preserve an explicit GitHub host, and report only units that changed.
30
- - `releaseUnits[].distributions` remains required but may now be an explicit empty list. Such a unit still freezes and publishes its GitHub snapshot, tag, and GitHub Release, while npm and marketplace actions are omitted; postPublish and postVerify hooks remain independent.
31
- - Pinned `skill-family-contracts`, `skill-family-harness-node`, and `skill-family-engineering-kit` dependencies were upgraded from 0.16.0 to the exact published 0.17.0 versions.
32
- - Skill Family Hub remains the single marketplace source. After verification, the project-private postVerify hook applies the Hub proposal and publishes its private entry and public snapshot through GitHub's Git Data API.
27
+ - New `codebuddy-plugin` distributions must declare `marketplace` explicitly, so each project selects its own Hub instead of inheriting the legacy `artifact-skill-set` default.
28
+ - The first-user and security-reviewer README black-box prompts now receive their candidate version from `sync-version`, preventing their assertions from drifting behind the package version.
29
+ - The project-private postVerify hook continues to publish the verified release-skill entry and public snapshot to Skill Family Hub through GitHub's Git Data API.
33
30
 
34
31
  **Upgrade Notes**
35
32
 
36
- Remove any `release-skill` standalone marketplace registration, add or update `ifoohoo/skill-family-hub`, and use `release-skill@skill-family-hub`. Use `distributions: []` only when the release unit is intentionally GitHub-only and marketplace registration is handled by an independent verified workflow. Existing non-empty distribution lists keep their behavior. After installing or reloading the official 0.9.11 release, a historical first release may be reverified without republishing; confirm that its configured previous public baseline changed from `none` to the verified frozen coordinates.
33
+ Upgrade from 0.9.12 before preparing a new CodeBuddy release configuration. Add the intended Hub name to every new `codebuddy-plugin` distribution through its `marketplace` field. Remove any release-skill standalone marketplace registration, add or update `ifoohoo/skill-family-hub`, and use `release-skill@skill-family-hub`. Existing frozen plans remain recoverable, and other distribution types are unaffected.
37
34
  <!-- release-skill:managed:end id=latest-release -->
38
35
 
39
36
  <!-- release-skill:capability:external-write-boundary -->
40
- > **Current boundary:** v0.9.11 is the current source candidate. This README
37
+ > **Current boundary:** v0.9.13 is the current source candidate. This README
41
38
  > records intended scope and verification boundaries; it is not evidence of
42
39
  > publication, consumer-installation verification, or independent acceptance.
43
40
  > Release availability must be established from the corresponding release records
@@ -61,7 +58,7 @@ Remove any `release-skill` standalone marketplace registration, add or update `i
61
58
  > publish global preflight.
62
59
 
63
60
  <!-- release-skill:capability:safe-first-command -->
64
- > **Production path verified since the v0.1.1 milestone; v0.9.11 is the current
61
+ > **Production path verified since the v0.1.1 milestone; v0.9.13 is the current
65
62
  > source candidate. Its README does not establish publication,
66
63
  > consumer-installation verification, or independent acceptance.**
67
64
  > The npm-installed CLI is the supported user entry. Source checkout
@@ -90,7 +87,7 @@ checkpoints remain intact and use matching-version recovery. Evidence v1 stays
90
87
  read-only; v2 uses a closed top level with phase extensions in `details`.
91
88
  Summaries and recovery suggestions are diagnostic, never publication authority.
92
89
 
93
- The current 0.9.11 candidate includes the narrow R-05 Hook cache v2 consumer
90
+ The current 0.9.13 candidate includes the narrow R-05 Hook cache v2 consumer
94
91
  path, the public `postverify` path, and the stable isolated install-tree record
95
92
  path (A2/A3). It also removes the repository's own marketplace indexes and
96
93
  uses Skill Family Hub as the single marketplace source. It still
@@ -787,10 +784,11 @@ unsupported. When a plan declares postVerify hooks, release-finish must receive
787
784
  the completed postVerify run produced by `ship`, rather than the earlier verify
788
785
  run. The core prepare, publish, and verify workflow remains cross-platform.
789
786
 
790
- A `codebuddy-plugin` distribution may optionally declare `marketplace` (and
791
- `marketplaceSource`, the URL consumers use to add the marketplace) to override
792
- the default unified marketplace `artifact-skill-set`; undeclared distributions
793
- keep the default and produce byte-identical frozen plans.
787
+ New `codebuddy-plugin` project configurations must declare `marketplace`
788
+ explicitly so product families cannot silently inherit another family's Hub.
789
+ `marketplaceSource`, the URL consumers use to add that marketplace, remains
790
+ optional. Only already-frozen historical plans that lack `marketplace` retain
791
+ the legacy `artifact-skill-set` interpretation so reconcile can replay them.
794
792
 
795
793
  For every npm distribution, `prepare` statically checks the exact packed
796
794
  tarball against concrete `package.json` entry targets. `publish` and
package/README.zh-CN.md CHANGED
@@ -2,36 +2,33 @@
2
2
 
3
3
  [English](README.md) · 安装指南:[中文](INSTALL.zh-CN.md) / [English](INSTALL.md)
4
4
 
5
- <!-- release-skill:release-version: 0.9.11 -->
5
+ <!-- release-skill:release-version: 0.9.13 -->
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.11** (2026-09-04)
11
+ **0.9.13** (2026-09-05)
12
12
 
13
- 0.9.11 是修复首次发布验证后基线推进、并允许 GitHub-only 插件发布显式使用空分发列表的本地源码候选,三项 Foundation 依赖均精确升级到已发布的 0.17.0。本说明不代表已经发布、完成真实宿主验收、完成消费者安装验证或通过独立验收。
13
+ 0.9.13 是阻止新的 CodeBuddy 发布配置静默继承其他产品线市场的本地源码候选,并把 README 黑盒场景中的候选版本交给现有版本同步命令统一维护。三项 Foundation 依赖仍精确固定在已发布的 0.17.0。本说明不代表已经发布、完成真实宿主验收、完成消费者安装验证或通过独立验收。
14
14
 
15
15
  **安全**
16
16
 
17
- - 首次发布基线只在不可变发布内容验证成功后推进。配置写入会先验证并采用原子更新;若恢复失败,验证证据会保留阶段与发布状态详情,同时不把已经成功的发布结果降级。
18
- - 空分发列表不会跳过 GitHub 快照、tag 或 GitHub Release,也不会自动获得市场登记。
19
- - Hub 分支更新以已观察的分支头做比较后写入。Hub 局部发布会保留为可恢复状态,不回滚、不覆盖,也不强推。
17
+ - 已经冻结且未携带 `marketplace` 的历史计划仍按旧语义执行,以便确定性地恢复发布。新的配置校验不放宽冻结计划身份、批准、发布、验证或恢复检查。Skill Family Hub 更新继续采用比较后写入;Hub 局部发布不回滚、不覆盖,也不强推,release-skill 中没有增加第二套 Hub Registry 或状态机。
20
18
 
21
- **变更**
19
+ **修复**
22
20
 
23
- - 发布达到 VERIFIED 后,`previousPublicBaseline` 为 `mode: none` 的单元会转为 bound 基线,写入解析后的仓库与 ref,以及本次冻结的精确 commit、tree 和 manifest digest。混合计划与根目录内的自定义配置路径复用既有原子更新路径,保留显式 GitHub host,并且只报告实际发生变化的单元。
24
- - `releaseUnits[].distributions` 仍为必填字段,但现在可以显式设置为空列表。该单元仍会冻结并发布 GitHub 快照、tag 和 GitHub Release,只省略 npm 与市场动作;postPublish 和 postVerify hook 继续独立执行。
25
- - 精确固定的 `skill-family-contracts`、`skill-family-harness-node` 和 `skill-family-engineering-kit` 依赖从 0.16.0 升级到已发布的 0.17.0。
26
- - Skill Family Hub 继续作为唯一市场来源。验证完成后,项目私有的 postVerify hook 会应用 Hub 提案,并通过 GitHub Git Data API 发布 Hub 私有条目和公开快照。
21
+ - 新的 `codebuddy-plugin` 分发必须显式声明 `marketplace`。每个项目据此选择自己的 Hub,不再继承旧的 `artifact-skill-set` 默认值。
22
+ - 首次使用者与安全审阅者的 README 黑盒提示词现在通过 `sync-version` 接收候选版本,避免其中的断言落后于包版本。
23
+ - 项目私有的 postVerify hook 继续通过 GitHub Git Data API,把已验证的 release-skill 条目和公开快照发布到 Skill Family Hub。
27
24
 
28
25
  **升级说明**
29
26
 
30
- 删除各宿主中独立的 `release-skill` 市场登记,添加或更新 `ifoohoo/skill-family-hub`,并使用 `release-skill@skill-family-hub`。仅在发布单元有意采用 GitHub-only 发布、且市场登记由独立的已验证流程处理时使用 `distributions: []`。既有非空分发列表的行为不变。安装或重新加载正式发布并已验证的 0.9.11 后,可以直接重新验证历史首次发布,无需重复发布;随后应确认配置中的上一公开基线已从 `none` 更新为本次验证的精确冻结坐标。
27
+ 准备新的 CodeBuddy 发布配置前,应从 0.9.12 升级到本版本,并在每个 `codebuddy-plugin` 分发的 `marketplace` 字段中填写目标 Hub。删除各宿主中独立的 `release-skill` 市场登记,添加或更新 `ifoohoo/skill-family-hub`,并使用 `release-skill@skill-family-hub`。已经冻结的历史计划仍可恢复,其他分发类型不受影响。
31
28
  <!-- release-skill:managed:end id=latest-release -->
32
29
 
33
30
  <!-- release-skill:capability:external-write-boundary -->
34
- > **当前边界:** v0.9.11 只是当前源码候选。本 README 记录预期范围与验证边界,
31
+ > **当前边界:** v0.9.13 只是当前源码候选。本 README 记录预期范围与验证边界,
35
32
  > 不代表已经发布、完成消费者安装验证或通过独立验收。
36
33
  > 版本可用性以对应发布记录及发布后验证结果为准。
37
34
  > v0.4.1 是更早的已发布里程碑(v0.2.2 曾处于已发布状态,后因平台验证收敛修复而更新)。
@@ -47,7 +44,7 @@ release-skill 帮助维护者回答三个问题:准备发布什么、还有哪
47
44
  > 远端唯一性检查在 `publish` 全局预检执行。
48
45
 
49
46
  <!-- release-skill:capability:safe-first-command -->
50
- > **生产路径自 v0.1.1 里程碑起已完成真实生产验证;v0.9.11 是当前源码候选,本 README 不证明该候选已经发布、完成消费者安装验证或通过独立验收。**
47
+ > **生产路径自 v0.1.1 里程碑起已完成真实生产验证;v0.9.13 是当前源码候选,本 README 不证明该候选已经发布、完成消费者安装验证或通过独立验收。**
51
48
  > npm 安装的 CLI 是受支持的用户入口;源码 checkout 保留为开发/贡献者路径。
52
49
  >
53
50
  > **第一条命令:**
@@ -65,7 +62,7 @@ marketplace 委托目标工作区发布的边界不变。
65
62
 
66
63
  旧 production 计划缺少 `sourceAuthority` 时,在外部写入前拒绝。未发生外部写入的计划必须重新 prepare 并批准新摘要,不能补写旧计划或迁移批准。已有 `PARTIAL` 保留检查点,走匹配版本的恢复路径。evidence v1 只读;v2 顶层封闭,阶段扩展放在 `details`。摘要和恢复建议只作诊断,不构成发布权威。
67
64
 
68
- 当前 0.9.11 候选包含窄范围的 R-05 Hook cache v2 消费路径、公开 `postverify`
65
+ 当前 0.9.13 候选包含窄范围的 R-05 Hook cache v2 消费路径、公开 `postverify`
69
66
  路径和稳定隔离安装树记录路径(A2/A3),并删除仓库自有市场索引,统一以
70
67
  Skill Family Hub 为市场来源。当前仍不包含 R-02 安全整树盘点、R-10 历史发布验证
71
68
  的产品实现、真实 Kimi/WorkBuddy 公开市场安装与调用门禁或 Audit 公开离线发布记录
@@ -669,7 +666,7 @@ WorkBuddy 本机更新仅支持 macOS;其他平台返回不支持并跳过。
669
666
  release-finish 必须接收 `ship` 产出的已完成 postVerify run,不能直接使用较早的
670
667
  verify run;核心 prepare、publish、verify 流程仍跨平台。
671
668
 
672
- `codebuddy-plugin` 分发可以可选地声明 `marketplace`(以及 `marketplaceSource`,即消费者添加市场所用的 URL)来覆盖默认统一市场 `artifact-skill-set`;未声明的分发保持默认值,冻结计划字节不变。
669
+ 新的 `codebuddy-plugin` 项目配置必须显式声明 `marketplace`,避免不同产品线误用同一市场;`marketplaceSource`(消费者添加市场所用的 URL)仍可按需声明。只有已经冻结、且未携带该字段的历史计划会继续按旧规则解释为 `artifact-skill-set`,以保证 reconcile 可以重放原计划。
673
670
 
674
671
  每个 npm 分发在 `prepare` 时都会针对精确封装的 tarball 静态校验
675
672
  `package.json` 声明的具体入口。`publish` 与 `reconcile` 在任何远端动作前对同一
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.9.11",
3
+ "version": "0.9.13",
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.11"});
12
+ const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.13"});
13
13
  // Build-time source digest for the BUNDLE_STALE freshness gate (see above).
14
- const __bundleSourceDigest = "42faaeb2d272e94efd6075f39b6553540afc307ce64a853a8021eb474fdb380b";
14
+ const __bundleSourceDigest = "e80838f3bb1cdc89e9112bcf4a4a9b5912c963cfb5d9ea27d692c7fb24dd48d6";
15
15
 
16
16
  var __create = Object.create;
17
17
  var __defProp = Object.defineProperty;
@@ -136313,6 +136313,49 @@ var init_notify_handoff = __esm({
136313
136313
  }
136314
136314
  });
136315
136315
 
136316
+ // src/core/proposal-document.mjs
136317
+ function proposalFileName(unitId, version) {
136318
+ if (typeof unitId !== "string" || unitId.length === 0 || typeof version !== "string" || version.length === 0) {
136319
+ throw new ReleaseError(GATE_FAILED, "proposal file name requires unitId and version", { unitId, version });
136320
+ }
136321
+ return `incoming/${unitId}-${version}.json`;
136322
+ }
136323
+ function buildProposalDocument(context) {
136324
+ const required = ["unitId", "version", "tag", "commit", "planDigest", "runId"];
136325
+ for (const field of required) {
136326
+ if (typeof context?.[field] !== "string" || context[field].length === 0) {
136327
+ throw new ReleaseError(GATE_FAILED, `proposal document requires context field "${field}"`, { field });
136328
+ }
136329
+ }
136330
+ const { unitId, version, tag, commit, tree, manifestDigest, planDigest, runId, publishedAt, verifyEvidence } = context;
136331
+ return {
136332
+ schemaVersion: PROPOSAL_SCHEMA_VERSION,
136333
+ kind: PROPOSAL_KIND,
136334
+ unitId,
136335
+ version,
136336
+ tag,
136337
+ sha: commit,
136338
+ commit,
136339
+ ...typeof tree === "string" && tree.length > 0 ? { tree } : {},
136340
+ ...typeof manifestDigest === "string" && manifestDigest.length > 0 ? { manifestDigest } : {},
136341
+ planDigest,
136342
+ runId,
136343
+ ...publishedAt !== void 0 ? { publishedAt } : {},
136344
+ ...verifyEvidence !== void 0 ? { verifyEvidence } : {},
136345
+ changeSummary: `release ${unitId} ${version} (tag ${tag}, commit ${commit})`
136346
+ };
136347
+ }
136348
+ var PROPOSAL_SCHEMA_VERSION, PROPOSAL_KIND;
136349
+ var init_proposal_document = __esm({
136350
+ "src/core/proposal-document.mjs"() {
136351
+ init_errors3();
136352
+ PROPOSAL_SCHEMA_VERSION = 1;
136353
+ PROPOSAL_KIND = "release-skill/update-proposal";
136354
+ __name(proposalFileName, "proposalFileName");
136355
+ __name(buildProposalDocument, "buildProposalDocument");
136356
+ }
136357
+ });
136358
+
136316
136359
  // src/core/proposal-inbox.mjs
136317
136360
  import { execFile as execFileCb14 } from "node:child_process";
136318
136361
  import { promisify as promisify14 } from "node:util";
@@ -136389,37 +136432,6 @@ function parseLsRemote(stdout) {
136389
136432
  }
136390
136433
  return refs;
136391
136434
  }
136392
- function proposalFileName(unitId, version) {
136393
- if (typeof unitId !== "string" || unitId.length === 0 || typeof version !== "string" || version.length === 0) {
136394
- throw new ReleaseError(GATE_FAILED, "proposal file name requires unitId and version", { unitId, version });
136395
- }
136396
- return `incoming/${unitId}-${version}.json`;
136397
- }
136398
- function buildProposalDocument(context) {
136399
- const required = ["unitId", "version", "tag", "commit", "planDigest", "runId"];
136400
- for (const field of required) {
136401
- if (typeof context?.[field] !== "string" || context[field].length === 0) {
136402
- throw new ReleaseError(GATE_FAILED, `proposal document requires context field "${field}"`, { field });
136403
- }
136404
- }
136405
- const { unitId, version, tag, commit, tree, manifestDigest, planDigest, runId, publishedAt, verifyEvidence } = context;
136406
- return {
136407
- schemaVersion: PROPOSAL_SCHEMA_VERSION,
136408
- kind: PROPOSAL_KIND,
136409
- unitId,
136410
- version,
136411
- tag,
136412
- sha: commit,
136413
- commit,
136414
- ...typeof tree === "string" && tree.length > 0 ? { tree } : {},
136415
- ...typeof manifestDigest === "string" && manifestDigest.length > 0 ? { manifestDigest } : {},
136416
- planDigest,
136417
- runId,
136418
- ...publishedAt !== void 0 ? { publishedAt } : {},
136419
- ...verifyEvidence !== void 0 ? { verifyEvidence } : {},
136420
- changeSummary: `release ${unitId} ${version} (tag ${tag}, commit ${commit})`
136421
- };
136422
- }
136423
136435
  function buildManualSyncPrompt({ remoteUrl, proposalPath, branch }) {
136424
136436
  const safeRemoteUrl = redactUrlCredentialsIfPresent(remoteUrl);
136425
136437
  return `manual sync required: review proposal ${proposalPath} in downstream repository ${safeRemoteUrl} (branch ${branch}); suggested action: open a pull request or apply the proposal through the downstream governance workflow`;
@@ -136729,15 +136741,15 @@ async function executeProposalInboxLocalFileHook(params) {
136729
136741
  })
136730
136742
  };
136731
136743
  }
136732
- var execFileAsync3, PROPOSAL_SCHEMA_VERSION, PROPOSAL_KIND, PROBE_TIMEOUT_MS, GIT_TIMEOUT_MS, TRANSFER_TIMEOUT_MS, TMP_PREFIX, SAFE_BRANCH_RE, SHA_RE2, NEVER_PROMPT_ENV, AUTH_FAILURE_PATTERNS, TRANSPORT_FAILURE_PATTERNS;
136744
+ var execFileAsync3, PROBE_TIMEOUT_MS, GIT_TIMEOUT_MS, TRANSFER_TIMEOUT_MS, TMP_PREFIX, SAFE_BRANCH_RE, SHA_RE2, NEVER_PROMPT_ENV, AUTH_FAILURE_PATTERNS, TRANSPORT_FAILURE_PATTERNS;
136733
136745
  var init_proposal_inbox = __esm({
136734
136746
  "src/core/proposal-inbox.mjs"() {
136735
136747
  init_errors3();
136736
136748
  init_presets();
136737
136749
  init_git_url_policy();
136750
+ init_proposal_document();
136751
+ init_proposal_document();
136738
136752
  execFileAsync3 = promisify14(execFileCb14);
136739
- PROPOSAL_SCHEMA_VERSION = 1;
136740
- PROPOSAL_KIND = "release-skill/update-proposal";
136741
136753
  PROBE_TIMEOUT_MS = 3e4;
136742
136754
  GIT_TIMEOUT_MS = 12e4;
136743
136755
  TRANSFER_TIMEOUT_MS = 3e5;
@@ -136779,8 +136791,6 @@ var init_proposal_inbox = __esm({
136779
136791
  __name(stderrTail, "stderrTail");
136780
136792
  __name(classifyNetFailure, "classifyNetFailure");
136781
136793
  __name(parseLsRemote, "parseLsRemote");
136782
- __name(proposalFileName, "proposalFileName");
136783
- __name(buildProposalDocument, "buildProposalDocument");
136784
136794
  __name(buildManualSyncPrompt, "buildManualSyncPrompt");
136785
136795
  __name(crossCheckPushedCommit, "crossCheckPushedCommit");
136786
136796
  __name(observeProposalInboxGitPush, "observeProposalInboxGitPush");
@@ -352,6 +352,7 @@
352
352
  "then": {
353
353
  "required": [
354
354
  "plugin",
355
+ "marketplace",
355
356
  "entrySkill"
356
357
  ]
357
358
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.9.11",
3
+ "version": "0.9.13",
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.11.",
22
+ "Prepare a release plan for version 0.9.13.",
23
23
  "Help me understand the release workflow."
24
24
  ]
25
25
  }
@@ -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.11"});
12
+ const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.13"});
13
13
  // Build-time source digest for the BUNDLE_STALE freshness gate (see above).
14
- const __bundleSourceDigest = "42faaeb2d272e94efd6075f39b6553540afc307ce64a853a8021eb474fdb380b";
14
+ const __bundleSourceDigest = "e80838f3bb1cdc89e9112bcf4a4a9b5912c963cfb5d9ea27d692c7fb24dd48d6";
15
15
 
16
16
  var __create = Object.create;
17
17
  var __defProp = Object.defineProperty;
@@ -136313,6 +136313,49 @@ var init_notify_handoff = __esm({
136313
136313
  }
136314
136314
  });
136315
136315
 
136316
+ // src/core/proposal-document.mjs
136317
+ function proposalFileName(unitId, version) {
136318
+ if (typeof unitId !== "string" || unitId.length === 0 || typeof version !== "string" || version.length === 0) {
136319
+ throw new ReleaseError(GATE_FAILED, "proposal file name requires unitId and version", { unitId, version });
136320
+ }
136321
+ return `incoming/${unitId}-${version}.json`;
136322
+ }
136323
+ function buildProposalDocument(context) {
136324
+ const required = ["unitId", "version", "tag", "commit", "planDigest", "runId"];
136325
+ for (const field of required) {
136326
+ if (typeof context?.[field] !== "string" || context[field].length === 0) {
136327
+ throw new ReleaseError(GATE_FAILED, `proposal document requires context field "${field}"`, { field });
136328
+ }
136329
+ }
136330
+ const { unitId, version, tag, commit, tree, manifestDigest, planDigest, runId, publishedAt, verifyEvidence } = context;
136331
+ return {
136332
+ schemaVersion: PROPOSAL_SCHEMA_VERSION,
136333
+ kind: PROPOSAL_KIND,
136334
+ unitId,
136335
+ version,
136336
+ tag,
136337
+ sha: commit,
136338
+ commit,
136339
+ ...typeof tree === "string" && tree.length > 0 ? { tree } : {},
136340
+ ...typeof manifestDigest === "string" && manifestDigest.length > 0 ? { manifestDigest } : {},
136341
+ planDigest,
136342
+ runId,
136343
+ ...publishedAt !== void 0 ? { publishedAt } : {},
136344
+ ...verifyEvidence !== void 0 ? { verifyEvidence } : {},
136345
+ changeSummary: `release ${unitId} ${version} (tag ${tag}, commit ${commit})`
136346
+ };
136347
+ }
136348
+ var PROPOSAL_SCHEMA_VERSION, PROPOSAL_KIND;
136349
+ var init_proposal_document = __esm({
136350
+ "src/core/proposal-document.mjs"() {
136351
+ init_errors3();
136352
+ PROPOSAL_SCHEMA_VERSION = 1;
136353
+ PROPOSAL_KIND = "release-skill/update-proposal";
136354
+ __name(proposalFileName, "proposalFileName");
136355
+ __name(buildProposalDocument, "buildProposalDocument");
136356
+ }
136357
+ });
136358
+
136316
136359
  // src/core/proposal-inbox.mjs
136317
136360
  import { execFile as execFileCb14 } from "node:child_process";
136318
136361
  import { promisify as promisify14 } from "node:util";
@@ -136389,37 +136432,6 @@ function parseLsRemote(stdout) {
136389
136432
  }
136390
136433
  return refs;
136391
136434
  }
136392
- function proposalFileName(unitId, version) {
136393
- if (typeof unitId !== "string" || unitId.length === 0 || typeof version !== "string" || version.length === 0) {
136394
- throw new ReleaseError(GATE_FAILED, "proposal file name requires unitId and version", { unitId, version });
136395
- }
136396
- return `incoming/${unitId}-${version}.json`;
136397
- }
136398
- function buildProposalDocument(context) {
136399
- const required = ["unitId", "version", "tag", "commit", "planDigest", "runId"];
136400
- for (const field of required) {
136401
- if (typeof context?.[field] !== "string" || context[field].length === 0) {
136402
- throw new ReleaseError(GATE_FAILED, `proposal document requires context field "${field}"`, { field });
136403
- }
136404
- }
136405
- const { unitId, version, tag, commit, tree, manifestDigest, planDigest, runId, publishedAt, verifyEvidence } = context;
136406
- return {
136407
- schemaVersion: PROPOSAL_SCHEMA_VERSION,
136408
- kind: PROPOSAL_KIND,
136409
- unitId,
136410
- version,
136411
- tag,
136412
- sha: commit,
136413
- commit,
136414
- ...typeof tree === "string" && tree.length > 0 ? { tree } : {},
136415
- ...typeof manifestDigest === "string" && manifestDigest.length > 0 ? { manifestDigest } : {},
136416
- planDigest,
136417
- runId,
136418
- ...publishedAt !== void 0 ? { publishedAt } : {},
136419
- ...verifyEvidence !== void 0 ? { verifyEvidence } : {},
136420
- changeSummary: `release ${unitId} ${version} (tag ${tag}, commit ${commit})`
136421
- };
136422
- }
136423
136435
  function buildManualSyncPrompt({ remoteUrl, proposalPath, branch }) {
136424
136436
  const safeRemoteUrl = redactUrlCredentialsIfPresent(remoteUrl);
136425
136437
  return `manual sync required: review proposal ${proposalPath} in downstream repository ${safeRemoteUrl} (branch ${branch}); suggested action: open a pull request or apply the proposal through the downstream governance workflow`;
@@ -136729,15 +136741,15 @@ async function executeProposalInboxLocalFileHook(params) {
136729
136741
  })
136730
136742
  };
136731
136743
  }
136732
- var execFileAsync3, PROPOSAL_SCHEMA_VERSION, PROPOSAL_KIND, PROBE_TIMEOUT_MS, GIT_TIMEOUT_MS, TRANSFER_TIMEOUT_MS, TMP_PREFIX, SAFE_BRANCH_RE, SHA_RE2, NEVER_PROMPT_ENV, AUTH_FAILURE_PATTERNS, TRANSPORT_FAILURE_PATTERNS;
136744
+ var execFileAsync3, PROBE_TIMEOUT_MS, GIT_TIMEOUT_MS, TRANSFER_TIMEOUT_MS, TMP_PREFIX, SAFE_BRANCH_RE, SHA_RE2, NEVER_PROMPT_ENV, AUTH_FAILURE_PATTERNS, TRANSPORT_FAILURE_PATTERNS;
136733
136745
  var init_proposal_inbox = __esm({
136734
136746
  "src/core/proposal-inbox.mjs"() {
136735
136747
  init_errors3();
136736
136748
  init_presets();
136737
136749
  init_git_url_policy();
136750
+ init_proposal_document();
136751
+ init_proposal_document();
136738
136752
  execFileAsync3 = promisify14(execFileCb14);
136739
- PROPOSAL_SCHEMA_VERSION = 1;
136740
- PROPOSAL_KIND = "release-skill/update-proposal";
136741
136753
  PROBE_TIMEOUT_MS = 3e4;
136742
136754
  GIT_TIMEOUT_MS = 12e4;
136743
136755
  TRANSFER_TIMEOUT_MS = 3e5;
@@ -136779,8 +136791,6 @@ var init_proposal_inbox = __esm({
136779
136791
  __name(stderrTail, "stderrTail");
136780
136792
  __name(classifyNetFailure, "classifyNetFailure");
136781
136793
  __name(parseLsRemote, "parseLsRemote");
136782
- __name(proposalFileName, "proposalFileName");
136783
- __name(buildProposalDocument, "buildProposalDocument");
136784
136794
  __name(buildManualSyncPrompt, "buildManualSyncPrompt");
136785
136795
  __name(crossCheckPushedCommit, "crossCheckPushedCommit");
136786
136796
  __name(observeProposalInboxGitPush, "observeProposalInboxGitPush");
@@ -352,6 +352,7 @@
352
352
  "then": {
353
353
  "required": [
354
354
  "plugin",
355
+ "marketplace",
355
356
  "entrySkill"
356
357
  ]
357
358
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.9.11",
3
+ "version": "0.9.13",
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.11"});
12
+ const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.13"});
13
13
  // Build-time source digest for the BUNDLE_STALE freshness gate (see above).
14
- const __bundleSourceDigest = "42faaeb2d272e94efd6075f39b6553540afc307ce64a853a8021eb474fdb380b";
14
+ const __bundleSourceDigest = "e80838f3bb1cdc89e9112bcf4a4a9b5912c963cfb5d9ea27d692c7fb24dd48d6";
15
15
 
16
16
  var __create = Object.create;
17
17
  var __defProp = Object.defineProperty;
@@ -136313,6 +136313,49 @@ var init_notify_handoff = __esm({
136313
136313
  }
136314
136314
  });
136315
136315
 
136316
+ // src/core/proposal-document.mjs
136317
+ function proposalFileName(unitId, version) {
136318
+ if (typeof unitId !== "string" || unitId.length === 0 || typeof version !== "string" || version.length === 0) {
136319
+ throw new ReleaseError(GATE_FAILED, "proposal file name requires unitId and version", { unitId, version });
136320
+ }
136321
+ return `incoming/${unitId}-${version}.json`;
136322
+ }
136323
+ function buildProposalDocument(context) {
136324
+ const required = ["unitId", "version", "tag", "commit", "planDigest", "runId"];
136325
+ for (const field of required) {
136326
+ if (typeof context?.[field] !== "string" || context[field].length === 0) {
136327
+ throw new ReleaseError(GATE_FAILED, `proposal document requires context field "${field}"`, { field });
136328
+ }
136329
+ }
136330
+ const { unitId, version, tag, commit, tree, manifestDigest, planDigest, runId, publishedAt, verifyEvidence } = context;
136331
+ return {
136332
+ schemaVersion: PROPOSAL_SCHEMA_VERSION,
136333
+ kind: PROPOSAL_KIND,
136334
+ unitId,
136335
+ version,
136336
+ tag,
136337
+ sha: commit,
136338
+ commit,
136339
+ ...typeof tree === "string" && tree.length > 0 ? { tree } : {},
136340
+ ...typeof manifestDigest === "string" && manifestDigest.length > 0 ? { manifestDigest } : {},
136341
+ planDigest,
136342
+ runId,
136343
+ ...publishedAt !== void 0 ? { publishedAt } : {},
136344
+ ...verifyEvidence !== void 0 ? { verifyEvidence } : {},
136345
+ changeSummary: `release ${unitId} ${version} (tag ${tag}, commit ${commit})`
136346
+ };
136347
+ }
136348
+ var PROPOSAL_SCHEMA_VERSION, PROPOSAL_KIND;
136349
+ var init_proposal_document = __esm({
136350
+ "src/core/proposal-document.mjs"() {
136351
+ init_errors3();
136352
+ PROPOSAL_SCHEMA_VERSION = 1;
136353
+ PROPOSAL_KIND = "release-skill/update-proposal";
136354
+ __name(proposalFileName, "proposalFileName");
136355
+ __name(buildProposalDocument, "buildProposalDocument");
136356
+ }
136357
+ });
136358
+
136316
136359
  // src/core/proposal-inbox.mjs
136317
136360
  import { execFile as execFileCb14 } from "node:child_process";
136318
136361
  import { promisify as promisify14 } from "node:util";
@@ -136389,37 +136432,6 @@ function parseLsRemote(stdout) {
136389
136432
  }
136390
136433
  return refs;
136391
136434
  }
136392
- function proposalFileName(unitId, version) {
136393
- if (typeof unitId !== "string" || unitId.length === 0 || typeof version !== "string" || version.length === 0) {
136394
- throw new ReleaseError(GATE_FAILED, "proposal file name requires unitId and version", { unitId, version });
136395
- }
136396
- return `incoming/${unitId}-${version}.json`;
136397
- }
136398
- function buildProposalDocument(context) {
136399
- const required = ["unitId", "version", "tag", "commit", "planDigest", "runId"];
136400
- for (const field of required) {
136401
- if (typeof context?.[field] !== "string" || context[field].length === 0) {
136402
- throw new ReleaseError(GATE_FAILED, `proposal document requires context field "${field}"`, { field });
136403
- }
136404
- }
136405
- const { unitId, version, tag, commit, tree, manifestDigest, planDigest, runId, publishedAt, verifyEvidence } = context;
136406
- return {
136407
- schemaVersion: PROPOSAL_SCHEMA_VERSION,
136408
- kind: PROPOSAL_KIND,
136409
- unitId,
136410
- version,
136411
- tag,
136412
- sha: commit,
136413
- commit,
136414
- ...typeof tree === "string" && tree.length > 0 ? { tree } : {},
136415
- ...typeof manifestDigest === "string" && manifestDigest.length > 0 ? { manifestDigest } : {},
136416
- planDigest,
136417
- runId,
136418
- ...publishedAt !== void 0 ? { publishedAt } : {},
136419
- ...verifyEvidence !== void 0 ? { verifyEvidence } : {},
136420
- changeSummary: `release ${unitId} ${version} (tag ${tag}, commit ${commit})`
136421
- };
136422
- }
136423
136435
  function buildManualSyncPrompt({ remoteUrl, proposalPath, branch }) {
136424
136436
  const safeRemoteUrl = redactUrlCredentialsIfPresent(remoteUrl);
136425
136437
  return `manual sync required: review proposal ${proposalPath} in downstream repository ${safeRemoteUrl} (branch ${branch}); suggested action: open a pull request or apply the proposal through the downstream governance workflow`;
@@ -136729,15 +136741,15 @@ async function executeProposalInboxLocalFileHook(params) {
136729
136741
  })
136730
136742
  };
136731
136743
  }
136732
- var execFileAsync3, PROPOSAL_SCHEMA_VERSION, PROPOSAL_KIND, PROBE_TIMEOUT_MS, GIT_TIMEOUT_MS, TRANSFER_TIMEOUT_MS, TMP_PREFIX, SAFE_BRANCH_RE, SHA_RE2, NEVER_PROMPT_ENV, AUTH_FAILURE_PATTERNS, TRANSPORT_FAILURE_PATTERNS;
136744
+ var execFileAsync3, PROBE_TIMEOUT_MS, GIT_TIMEOUT_MS, TRANSFER_TIMEOUT_MS, TMP_PREFIX, SAFE_BRANCH_RE, SHA_RE2, NEVER_PROMPT_ENV, AUTH_FAILURE_PATTERNS, TRANSPORT_FAILURE_PATTERNS;
136733
136745
  var init_proposal_inbox = __esm({
136734
136746
  "src/core/proposal-inbox.mjs"() {
136735
136747
  init_errors3();
136736
136748
  init_presets();
136737
136749
  init_git_url_policy();
136750
+ init_proposal_document();
136751
+ init_proposal_document();
136738
136752
  execFileAsync3 = promisify14(execFileCb14);
136739
- PROPOSAL_SCHEMA_VERSION = 1;
136740
- PROPOSAL_KIND = "release-skill/update-proposal";
136741
136753
  PROBE_TIMEOUT_MS = 3e4;
136742
136754
  GIT_TIMEOUT_MS = 12e4;
136743
136755
  TRANSFER_TIMEOUT_MS = 3e5;
@@ -136779,8 +136791,6 @@ var init_proposal_inbox = __esm({
136779
136791
  __name(stderrTail, "stderrTail");
136780
136792
  __name(classifyNetFailure, "classifyNetFailure");
136781
136793
  __name(parseLsRemote, "parseLsRemote");
136782
- __name(proposalFileName, "proposalFileName");
136783
- __name(buildProposalDocument, "buildProposalDocument");
136784
136794
  __name(buildManualSyncPrompt, "buildManualSyncPrompt");
136785
136795
  __name(crossCheckPushedCommit, "crossCheckPushedCommit");
136786
136796
  __name(observeProposalInboxGitPush, "observeProposalInboxGitPush");
@@ -352,6 +352,7 @@
352
352
  "then": {
353
353
  "required": [
354
354
  "plugin",
355
+ "marketplace",
355
356
  "entrySkill"
356
357
  ]
357
358
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.9.11",
3
+ "version": "0.9.13",
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.11"});
12
+ const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.13"});
13
13
  // Build-time source digest for the BUNDLE_STALE freshness gate (see above).
14
- const __bundleSourceDigest = "42faaeb2d272e94efd6075f39b6553540afc307ce64a853a8021eb474fdb380b";
14
+ const __bundleSourceDigest = "e80838f3bb1cdc89e9112bcf4a4a9b5912c963cfb5d9ea27d692c7fb24dd48d6";
15
15
 
16
16
  var __create = Object.create;
17
17
  var __defProp = Object.defineProperty;
@@ -136313,6 +136313,49 @@ var init_notify_handoff = __esm({
136313
136313
  }
136314
136314
  });
136315
136315
 
136316
+ // src/core/proposal-document.mjs
136317
+ function proposalFileName(unitId, version) {
136318
+ if (typeof unitId !== "string" || unitId.length === 0 || typeof version !== "string" || version.length === 0) {
136319
+ throw new ReleaseError(GATE_FAILED, "proposal file name requires unitId and version", { unitId, version });
136320
+ }
136321
+ return `incoming/${unitId}-${version}.json`;
136322
+ }
136323
+ function buildProposalDocument(context) {
136324
+ const required = ["unitId", "version", "tag", "commit", "planDigest", "runId"];
136325
+ for (const field of required) {
136326
+ if (typeof context?.[field] !== "string" || context[field].length === 0) {
136327
+ throw new ReleaseError(GATE_FAILED, `proposal document requires context field "${field}"`, { field });
136328
+ }
136329
+ }
136330
+ const { unitId, version, tag, commit, tree, manifestDigest, planDigest, runId, publishedAt, verifyEvidence } = context;
136331
+ return {
136332
+ schemaVersion: PROPOSAL_SCHEMA_VERSION,
136333
+ kind: PROPOSAL_KIND,
136334
+ unitId,
136335
+ version,
136336
+ tag,
136337
+ sha: commit,
136338
+ commit,
136339
+ ...typeof tree === "string" && tree.length > 0 ? { tree } : {},
136340
+ ...typeof manifestDigest === "string" && manifestDigest.length > 0 ? { manifestDigest } : {},
136341
+ planDigest,
136342
+ runId,
136343
+ ...publishedAt !== void 0 ? { publishedAt } : {},
136344
+ ...verifyEvidence !== void 0 ? { verifyEvidence } : {},
136345
+ changeSummary: `release ${unitId} ${version} (tag ${tag}, commit ${commit})`
136346
+ };
136347
+ }
136348
+ var PROPOSAL_SCHEMA_VERSION, PROPOSAL_KIND;
136349
+ var init_proposal_document = __esm({
136350
+ "src/core/proposal-document.mjs"() {
136351
+ init_errors3();
136352
+ PROPOSAL_SCHEMA_VERSION = 1;
136353
+ PROPOSAL_KIND = "release-skill/update-proposal";
136354
+ __name(proposalFileName, "proposalFileName");
136355
+ __name(buildProposalDocument, "buildProposalDocument");
136356
+ }
136357
+ });
136358
+
136316
136359
  // src/core/proposal-inbox.mjs
136317
136360
  import { execFile as execFileCb14 } from "node:child_process";
136318
136361
  import { promisify as promisify14 } from "node:util";
@@ -136389,37 +136432,6 @@ function parseLsRemote(stdout) {
136389
136432
  }
136390
136433
  return refs;
136391
136434
  }
136392
- function proposalFileName(unitId, version) {
136393
- if (typeof unitId !== "string" || unitId.length === 0 || typeof version !== "string" || version.length === 0) {
136394
- throw new ReleaseError(GATE_FAILED, "proposal file name requires unitId and version", { unitId, version });
136395
- }
136396
- return `incoming/${unitId}-${version}.json`;
136397
- }
136398
- function buildProposalDocument(context) {
136399
- const required = ["unitId", "version", "tag", "commit", "planDigest", "runId"];
136400
- for (const field of required) {
136401
- if (typeof context?.[field] !== "string" || context[field].length === 0) {
136402
- throw new ReleaseError(GATE_FAILED, `proposal document requires context field "${field}"`, { field });
136403
- }
136404
- }
136405
- const { unitId, version, tag, commit, tree, manifestDigest, planDigest, runId, publishedAt, verifyEvidence } = context;
136406
- return {
136407
- schemaVersion: PROPOSAL_SCHEMA_VERSION,
136408
- kind: PROPOSAL_KIND,
136409
- unitId,
136410
- version,
136411
- tag,
136412
- sha: commit,
136413
- commit,
136414
- ...typeof tree === "string" && tree.length > 0 ? { tree } : {},
136415
- ...typeof manifestDigest === "string" && manifestDigest.length > 0 ? { manifestDigest } : {},
136416
- planDigest,
136417
- runId,
136418
- ...publishedAt !== void 0 ? { publishedAt } : {},
136419
- ...verifyEvidence !== void 0 ? { verifyEvidence } : {},
136420
- changeSummary: `release ${unitId} ${version} (tag ${tag}, commit ${commit})`
136421
- };
136422
- }
136423
136435
  function buildManualSyncPrompt({ remoteUrl, proposalPath, branch }) {
136424
136436
  const safeRemoteUrl = redactUrlCredentialsIfPresent(remoteUrl);
136425
136437
  return `manual sync required: review proposal ${proposalPath} in downstream repository ${safeRemoteUrl} (branch ${branch}); suggested action: open a pull request or apply the proposal through the downstream governance workflow`;
@@ -136729,15 +136741,15 @@ async function executeProposalInboxLocalFileHook(params) {
136729
136741
  })
136730
136742
  };
136731
136743
  }
136732
- var execFileAsync3, PROPOSAL_SCHEMA_VERSION, PROPOSAL_KIND, PROBE_TIMEOUT_MS, GIT_TIMEOUT_MS, TRANSFER_TIMEOUT_MS, TMP_PREFIX, SAFE_BRANCH_RE, SHA_RE2, NEVER_PROMPT_ENV, AUTH_FAILURE_PATTERNS, TRANSPORT_FAILURE_PATTERNS;
136744
+ var execFileAsync3, PROBE_TIMEOUT_MS, GIT_TIMEOUT_MS, TRANSFER_TIMEOUT_MS, TMP_PREFIX, SAFE_BRANCH_RE, SHA_RE2, NEVER_PROMPT_ENV, AUTH_FAILURE_PATTERNS, TRANSPORT_FAILURE_PATTERNS;
136733
136745
  var init_proposal_inbox = __esm({
136734
136746
  "src/core/proposal-inbox.mjs"() {
136735
136747
  init_errors3();
136736
136748
  init_presets();
136737
136749
  init_git_url_policy();
136750
+ init_proposal_document();
136751
+ init_proposal_document();
136738
136752
  execFileAsync3 = promisify14(execFileCb14);
136739
- PROPOSAL_SCHEMA_VERSION = 1;
136740
- PROPOSAL_KIND = "release-skill/update-proposal";
136741
136753
  PROBE_TIMEOUT_MS = 3e4;
136742
136754
  GIT_TIMEOUT_MS = 12e4;
136743
136755
  TRANSFER_TIMEOUT_MS = 3e5;
@@ -136779,8 +136791,6 @@ var init_proposal_inbox = __esm({
136779
136791
  __name(stderrTail, "stderrTail");
136780
136792
  __name(classifyNetFailure, "classifyNetFailure");
136781
136793
  __name(parseLsRemote, "parseLsRemote");
136782
- __name(proposalFileName, "proposalFileName");
136783
- __name(buildProposalDocument, "buildProposalDocument");
136784
136794
  __name(buildManualSyncPrompt, "buildManualSyncPrompt");
136785
136795
  __name(crossCheckPushedCommit, "crossCheckPushedCommit");
136786
136796
  __name(observeProposalInboxGitPush, "observeProposalInboxGitPush");
@@ -352,6 +352,7 @@
352
352
  "then": {
353
353
  "required": [
354
354
  "plugin",
355
+ "marketplace",
355
356
  "entrySkill"
356
357
  ]
357
358
  }
@@ -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.11"});
12
+ const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.13"});
13
13
  // Build-time source digest for the BUNDLE_STALE freshness gate (see above).
14
- const __bundleSourceDigest = "42faaeb2d272e94efd6075f39b6553540afc307ce64a853a8021eb474fdb380b";
14
+ const __bundleSourceDigest = "e80838f3bb1cdc89e9112bcf4a4a9b5912c963cfb5d9ea27d692c7fb24dd48d6";
15
15
 
16
16
  var __create = Object.create;
17
17
  var __defProp = Object.defineProperty;
@@ -136313,6 +136313,49 @@ var init_notify_handoff = __esm({
136313
136313
  }
136314
136314
  });
136315
136315
 
136316
+ // src/core/proposal-document.mjs
136317
+ function proposalFileName(unitId, version) {
136318
+ if (typeof unitId !== "string" || unitId.length === 0 || typeof version !== "string" || version.length === 0) {
136319
+ throw new ReleaseError(GATE_FAILED, "proposal file name requires unitId and version", { unitId, version });
136320
+ }
136321
+ return `incoming/${unitId}-${version}.json`;
136322
+ }
136323
+ function buildProposalDocument(context) {
136324
+ const required = ["unitId", "version", "tag", "commit", "planDigest", "runId"];
136325
+ for (const field of required) {
136326
+ if (typeof context?.[field] !== "string" || context[field].length === 0) {
136327
+ throw new ReleaseError(GATE_FAILED, `proposal document requires context field "${field}"`, { field });
136328
+ }
136329
+ }
136330
+ const { unitId, version, tag, commit, tree, manifestDigest, planDigest, runId, publishedAt, verifyEvidence } = context;
136331
+ return {
136332
+ schemaVersion: PROPOSAL_SCHEMA_VERSION,
136333
+ kind: PROPOSAL_KIND,
136334
+ unitId,
136335
+ version,
136336
+ tag,
136337
+ sha: commit,
136338
+ commit,
136339
+ ...typeof tree === "string" && tree.length > 0 ? { tree } : {},
136340
+ ...typeof manifestDigest === "string" && manifestDigest.length > 0 ? { manifestDigest } : {},
136341
+ planDigest,
136342
+ runId,
136343
+ ...publishedAt !== void 0 ? { publishedAt } : {},
136344
+ ...verifyEvidence !== void 0 ? { verifyEvidence } : {},
136345
+ changeSummary: `release ${unitId} ${version} (tag ${tag}, commit ${commit})`
136346
+ };
136347
+ }
136348
+ var PROPOSAL_SCHEMA_VERSION, PROPOSAL_KIND;
136349
+ var init_proposal_document = __esm({
136350
+ "src/core/proposal-document.mjs"() {
136351
+ init_errors3();
136352
+ PROPOSAL_SCHEMA_VERSION = 1;
136353
+ PROPOSAL_KIND = "release-skill/update-proposal";
136354
+ __name(proposalFileName, "proposalFileName");
136355
+ __name(buildProposalDocument, "buildProposalDocument");
136356
+ }
136357
+ });
136358
+
136316
136359
  // src/core/proposal-inbox.mjs
136317
136360
  import { execFile as execFileCb14 } from "node:child_process";
136318
136361
  import { promisify as promisify14 } from "node:util";
@@ -136389,37 +136432,6 @@ function parseLsRemote(stdout) {
136389
136432
  }
136390
136433
  return refs;
136391
136434
  }
136392
- function proposalFileName(unitId, version) {
136393
- if (typeof unitId !== "string" || unitId.length === 0 || typeof version !== "string" || version.length === 0) {
136394
- throw new ReleaseError(GATE_FAILED, "proposal file name requires unitId and version", { unitId, version });
136395
- }
136396
- return `incoming/${unitId}-${version}.json`;
136397
- }
136398
- function buildProposalDocument(context) {
136399
- const required = ["unitId", "version", "tag", "commit", "planDigest", "runId"];
136400
- for (const field of required) {
136401
- if (typeof context?.[field] !== "string" || context[field].length === 0) {
136402
- throw new ReleaseError(GATE_FAILED, `proposal document requires context field "${field}"`, { field });
136403
- }
136404
- }
136405
- const { unitId, version, tag, commit, tree, manifestDigest, planDigest, runId, publishedAt, verifyEvidence } = context;
136406
- return {
136407
- schemaVersion: PROPOSAL_SCHEMA_VERSION,
136408
- kind: PROPOSAL_KIND,
136409
- unitId,
136410
- version,
136411
- tag,
136412
- sha: commit,
136413
- commit,
136414
- ...typeof tree === "string" && tree.length > 0 ? { tree } : {},
136415
- ...typeof manifestDigest === "string" && manifestDigest.length > 0 ? { manifestDigest } : {},
136416
- planDigest,
136417
- runId,
136418
- ...publishedAt !== void 0 ? { publishedAt } : {},
136419
- ...verifyEvidence !== void 0 ? { verifyEvidence } : {},
136420
- changeSummary: `release ${unitId} ${version} (tag ${tag}, commit ${commit})`
136421
- };
136422
- }
136423
136435
  function buildManualSyncPrompt({ remoteUrl, proposalPath, branch }) {
136424
136436
  const safeRemoteUrl = redactUrlCredentialsIfPresent(remoteUrl);
136425
136437
  return `manual sync required: review proposal ${proposalPath} in downstream repository ${safeRemoteUrl} (branch ${branch}); suggested action: open a pull request or apply the proposal through the downstream governance workflow`;
@@ -136729,15 +136741,15 @@ async function executeProposalInboxLocalFileHook(params) {
136729
136741
  })
136730
136742
  };
136731
136743
  }
136732
- var execFileAsync3, PROPOSAL_SCHEMA_VERSION, PROPOSAL_KIND, PROBE_TIMEOUT_MS, GIT_TIMEOUT_MS, TRANSFER_TIMEOUT_MS, TMP_PREFIX, SAFE_BRANCH_RE, SHA_RE2, NEVER_PROMPT_ENV, AUTH_FAILURE_PATTERNS, TRANSPORT_FAILURE_PATTERNS;
136744
+ var execFileAsync3, PROBE_TIMEOUT_MS, GIT_TIMEOUT_MS, TRANSFER_TIMEOUT_MS, TMP_PREFIX, SAFE_BRANCH_RE, SHA_RE2, NEVER_PROMPT_ENV, AUTH_FAILURE_PATTERNS, TRANSPORT_FAILURE_PATTERNS;
136733
136745
  var init_proposal_inbox = __esm({
136734
136746
  "src/core/proposal-inbox.mjs"() {
136735
136747
  init_errors3();
136736
136748
  init_presets();
136737
136749
  init_git_url_policy();
136750
+ init_proposal_document();
136751
+ init_proposal_document();
136738
136752
  execFileAsync3 = promisify14(execFileCb14);
136739
- PROPOSAL_SCHEMA_VERSION = 1;
136740
- PROPOSAL_KIND = "release-skill/update-proposal";
136741
136753
  PROBE_TIMEOUT_MS = 3e4;
136742
136754
  GIT_TIMEOUT_MS = 12e4;
136743
136755
  TRANSFER_TIMEOUT_MS = 3e5;
@@ -136779,8 +136791,6 @@ var init_proposal_inbox = __esm({
136779
136791
  __name(stderrTail, "stderrTail");
136780
136792
  __name(classifyNetFailure, "classifyNetFailure");
136781
136793
  __name(parseLsRemote, "parseLsRemote");
136782
- __name(proposalFileName, "proposalFileName");
136783
- __name(buildProposalDocument, "buildProposalDocument");
136784
136794
  __name(buildManualSyncPrompt, "buildManualSyncPrompt");
136785
136795
  __name(crossCheckPushedCommit, "crossCheckPushedCommit");
136786
136796
  __name(observeProposalInboxGitPush, "observeProposalInboxGitPush");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.9.11",
3
+ "version": "0.9.13",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "广州市风荷科技有限公司"
@@ -2,11 +2,11 @@
2
2
  "schemaVersion": "1.0.0",
3
3
  "platformId": "release-skill",
4
4
  "platformName": "release-skill Plugin Platform",
5
- "version": "0.9.11",
5
+ "version": "0.9.13",
6
6
  "logicalRoot": "skills-src/",
7
7
  "logicalRootDigest": "aec96745b30289ed48d576fbfc98ecd3aacb834f83394be76d4734d7d0fc0ad4",
8
8
  "projectionDigest": "e5117d89c9f965e15a1464cc84f542cb1e75a685f842183d0cfc7a105ace5ceb",
9
- "projectionId": "release-skill:platform:0.9.11",
9
+ "projectionId": "release-skill:platform:0.9.13",
10
10
  "manifestRequired": true,
11
11
  "projectionSources": {
12
12
  "skills-src-root": {
@@ -352,6 +352,7 @@
352
352
  "then": {
353
353
  "required": [
354
354
  "plugin",
355
+ "marketplace",
355
356
  "entrySkill"
356
357
  ]
357
358
  }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Pure proposal-document projection shared by runtime transports and frozen
3
+ * postVerify execution hooks. Keep this module free of package dependencies
4
+ * so a detached public-tag worktree can load it without node_modules.
5
+ *
6
+ * @module core/proposal-document
7
+ */
8
+
9
+ import { ReleaseError, GATE_FAILED } from './errors.mjs';
10
+
11
+ /** Proposal document identity. */
12
+ export const PROPOSAL_SCHEMA_VERSION = 1;
13
+ export const PROPOSAL_KIND = 'release-skill/update-proposal';
14
+
15
+ /** Proposal file location inside the downstream repository. */
16
+ export function proposalFileName(unitId, version) {
17
+ if (typeof unitId !== 'string' || unitId.length === 0
18
+ || typeof version !== 'string' || version.length === 0) {
19
+ throw new ReleaseError(GATE_FAILED, 'proposal file name requires unitId and version', { unitId, version });
20
+ }
21
+ return `incoming/${unitId}-${version}.json`;
22
+ }
23
+
24
+ /**
25
+ * Build the deterministic downstream proposal from a post-publish context.
26
+ * Local materialization paths are intentionally excluded.
27
+ */
28
+ export function buildProposalDocument(context) {
29
+ const required = ['unitId', 'version', 'tag', 'commit', 'planDigest', 'runId'];
30
+ for (const field of required) {
31
+ if (typeof context?.[field] !== 'string' || context[field].length === 0) {
32
+ throw new ReleaseError(GATE_FAILED, `proposal document requires context field "${field}"`, { field });
33
+ }
34
+ }
35
+ const { unitId, version, tag, commit, tree, manifestDigest, planDigest, runId, publishedAt, verifyEvidence } = context;
36
+ return {
37
+ schemaVersion: PROPOSAL_SCHEMA_VERSION,
38
+ kind: PROPOSAL_KIND,
39
+ unitId,
40
+ version,
41
+ tag,
42
+ sha: commit,
43
+ commit,
44
+ ...(typeof tree === 'string' && tree.length > 0 ? { tree } : {}),
45
+ ...(typeof manifestDigest === 'string' && manifestDigest.length > 0 ? { manifestDigest } : {}),
46
+ planDigest,
47
+ runId,
48
+ ...(publishedAt !== undefined ? { publishedAt } : {}),
49
+ ...(verifyEvidence !== undefined ? { verifyEvidence } : {}),
50
+ changeSummary: `release ${unitId} ${version} (tag ${tag}, commit ${commit})`,
51
+ };
52
+ }
@@ -53,12 +53,16 @@ import {
53
53
  describeGitRemoteUrlFailure,
54
54
  redactUrlCredentialsIfPresent,
55
55
  } from './git-url-policy.mjs';
56
+ import { buildProposalDocument, proposalFileName } from './proposal-document.mjs';
56
57
 
57
- const execFileAsync = promisify(execFileCb);
58
+ export {
59
+ PROPOSAL_SCHEMA_VERSION,
60
+ PROPOSAL_KIND,
61
+ buildProposalDocument,
62
+ proposalFileName,
63
+ } from './proposal-document.mjs';
58
64
 
59
- /** Proposal document identity. */
60
- export const PROPOSAL_SCHEMA_VERSION = 1;
61
- export const PROPOSAL_KIND = 'release-skill/update-proposal';
65
+ const execFileAsync = promisify(execFileCb);
62
66
 
63
67
  const PROBE_TIMEOUT_MS = 30_000;
64
68
  const GIT_TIMEOUT_MS = 120_000;
@@ -187,54 +191,6 @@ function parseLsRemote(stdout) {
187
191
  // Proposal document (deterministic projection of the §2.3 context)
188
192
  // ---------------------------------------------------------------------------
189
193
 
190
- /** Proposal file location inside the downstream repository. */
191
- export function proposalFileName(unitId, version) {
192
- if (typeof unitId !== 'string' || unitId.length === 0
193
- || typeof version !== 'string' || version.length === 0) {
194
- throw new ReleaseError(GATE_FAILED, 'proposal file name requires unitId and version', { unitId, version });
195
- }
196
- return `incoming/${unitId}-${version}.json`;
197
- }
198
-
199
- /**
200
- * Build the proposal document from the §2.3 context projection. Pure and
201
- * deterministic. Deliberately EXCLUDES payloadDir (a local materialization
202
- * path has no place in a downstream-facing document), and optional frozen
203
- * fields are ABSENT rather than null when the plan did not freeze them.
204
- *
205
- * Field set suffices to backfill a missing downstream hub entry:
206
- * unitId/version/tag/sha/commit/tree/manifestDigest/planDigest/runId/
207
- * publishedAt/verifyEvidence/changeSummary.
208
- *
209
- * @param {object} context - The §2.3 context projection.
210
- * @returns {object} The proposal document.
211
- */
212
- export function buildProposalDocument(context) {
213
- const required = ['unitId', 'version', 'tag', 'commit', 'planDigest', 'runId'];
214
- for (const field of required) {
215
- if (typeof context?.[field] !== 'string' || context[field].length === 0) {
216
- throw new ReleaseError(GATE_FAILED, `proposal document requires context field "${field}"`, { field });
217
- }
218
- }
219
- const { unitId, version, tag, commit, tree, manifestDigest, planDigest, runId, publishedAt, verifyEvidence } = context;
220
- return {
221
- schemaVersion: PROPOSAL_SCHEMA_VERSION,
222
- kind: PROPOSAL_KIND,
223
- unitId,
224
- version,
225
- tag,
226
- sha: commit,
227
- commit,
228
- ...(typeof tree === 'string' && tree.length > 0 ? { tree } : {}),
229
- ...(typeof manifestDigest === 'string' && manifestDigest.length > 0 ? { manifestDigest } : {}),
230
- planDigest,
231
- runId,
232
- ...(publishedAt !== undefined ? { publishedAt } : {}),
233
- ...(verifyEvidence !== undefined ? { verifyEvidence } : {}),
234
- changeSummary: `release ${unitId} ${version} (tag ${tag}, commit ${commit})`,
235
- };
236
- }
237
-
238
194
  /**
239
195
  * Deterministic manual-sync prompt (closure semantics): delivery success plus
240
196
  * this prompt in evidence IS the closed loop — downstream consumption is the