skill-family-harness-node 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/CHANGELOG.zh-CN.md +44 -0
  3. package/README.md +15 -11
  4. package/README.zh-CN.md +15 -11
  5. package/candidate/mechanisms-cli.mjs +137 -21
  6. package/candidate/quickstart-profile.mjs +841 -50
  7. package/candidate/rename-directory-no-replace/NOTICE +3 -0
  8. package/candidate/rename-directory-no-replace/addon/binding.gyp +25 -0
  9. package/candidate/rename-directory-no-replace/addon/rename_directory_no_replace.c +243 -0
  10. package/candidate/rename-directory-no-replace/build-prebuild-candidate.mjs +194 -0
  11. package/candidate/rename-directory-no-replace/loader.mjs +140 -0
  12. package/candidate/rename-directory-no-replace/prebuild-manifest.json +71 -0
  13. package/candidate/rename-directory-no-replace/prebuild-release-receipt.json +36 -0
  14. package/candidate/rename-directory-no-replace/prebuild-sbom.json +35 -0
  15. package/candidate/rename-directory-no-replace/prebuilds/darwin-arm64/rename_directory_no_replace.darwin-arm64.node +0 -0
  16. package/candidate/rename-directory-no-replace/prebuilds/darwin-x64/rename_directory_no_replace.darwin-x64.node +0 -0
  17. package/candidate/rename-directory-no-replace/prebuilds/linux-arm64-gnu/rename_directory_no_replace.linux-arm64-gnu.node +0 -0
  18. package/candidate/rename-directory-no-replace/prebuilds/linux-x64-gnu/rename_directory_no_replace.linux-x64-gnu.node +0 -0
  19. package/candidate/rename-directory-no-replace/rename-directory-no-replace.mjs +289 -0
  20. package/package.json +6 -4
  21. package/release-notes/0.3.0.yaml +25 -0
  22. package/release-notes/0.4.0.yaml +27 -0
  23. package/src/atomic.mjs +448 -44
  24. package/src/baseline.mjs +200 -0
  25. package/src/budget-guard.mjs +134 -0
  26. package/src/chokepoint.mjs +111 -0
  27. package/src/errors.mjs +9 -0
  28. package/src/index.mjs +33 -1
  29. package/src/state-store.mjs +18 -1
  30. package/src/surface-scan.mjs +91 -0
  31. package/src/token-estimate.mjs +39 -0
  32. package/src/token-lock.mjs +180 -0
  33. package/src/workspace.mjs +55 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # Changelog
2
2
 
3
+ <!-- release-skill:changelog:start version=0.4.0 locale=en baseline=sha256:72d3fe048ced8eb44a84fabe6f1fdd2eb0c938b4f6bb98740474f72aec04d873 -->
4
+ ## [0.4.0] - 2026-08-16
5
+
6
+ This release adds five finite-closed-semantics mechanisms and a token-lock primitive to the stable Harness surface (FND-ADR-009), grows HARNESS_CAPABILITIES from 9 to 16 entries, and ships the rename-directory-no-replace native-prebuild candidate.
7
+
8
+ ### Added
9
+
10
+ - Adds five finite-closed-semantics mechanisms (FND-ADR-009), namely frozen-baseline materialization with contentGuard, the generic read chokepoint, strategy-driven surface scanning, deterministic token upper-bound estimation, and the generic upper-bound guard.
11
+ - Adds the token-lock primitive for exclusive token-file publication and digest verification.
12
+ - Grows HARNESS_CAPABILITIES from 9 to 16 entries for the new mechanisms.
13
+ - Adds the rename-directory-no-replace candidate, a native-prebuild addon proving no-replace directory renames on darwin-arm64, darwin-x64, linux-arm64-gnu, and linux-x64-gnu, with a release receipt and SBOM.
14
+
15
+ ### Changed
16
+
17
+ - Keeps the Quickstart Profile v2 Task/Result exchange verification delivered in 0.3.0, including real-byte recomputation for path-backed outputs and evidence, duplicate Resource id rejection, and exact evidence binding verification.
18
+ - Leaves method selection, retry policy, and domain result interpretation to the consumer.
19
+
20
+ ### Upgrade Notes
21
+
22
+ Version 0.4.0 is released on npm and the public mirror. Pin the candidate subpath to exactly 0.4.0; mechanism imports use the stable capability names published in HARNESS_CAPABILITIES.
23
+ <!-- release-skill:changelog:end version=0.4.0 locale=en -->
24
+
25
+
26
+ <!-- release-skill:changelog:start version=0.3.0 locale=en baseline=sha256:7afef97792b4714abbd0412dcb7ea76ca66260ef9f8dd2191131b7c3f8539813 -->
27
+ ## [0.3.0] - 2026-08-12
28
+
29
+ This source candidate updates the Quickstart Profile harness to verify v2 Task and Result exchanges without taking ownership of consumer semantics.
30
+
31
+ ### Added
32
+
33
+ - Recomputes real bytes for path-backed outputs and evidence, and rejects duplicate Resource ids across observations, outputs, and evidence.
34
+ - Verifies operation identity, Task digest, every run/stage/attempt field, and the exact evidence binding set.
35
+
36
+ ### Changed
37
+
38
+ - Replaces the incompatible 0.2.1 candidate surface; consumers that still require v1 must remain pinned to exactly 0.2.1.
39
+ - Leaves method selection, retry policy, and domain result interpretation to the consumer.
40
+
41
+ ### Upgrade Notes
42
+
43
+ Version 0.3.0 is a local, unpublished source candidate. Pin the candidate subpath to an exact package version and update v1 exchange producers before adopting it.
44
+ <!-- release-skill:changelog:end version=0.3.0 locale=en -->
45
+
46
+
3
47
  <!-- release-skill:changelog:start version=0.2.1 locale=en baseline=sha256:acd7d4e02eb309b149a31f4b88a8163c69ae094a53591f173c20c407e8ff4ed0 -->
4
48
  ## [0.2.1] - 2026-08-10
5
49
 
@@ -1,5 +1,49 @@
1
1
  # 变更日志
2
2
 
3
+ <!-- release-skill:changelog:start version=0.4.0 locale=zh-CN baseline=sha256:dafaa1100bf6163a28d53fc982a30e8325d8bd3cab43bbb6daf2e6002befa2c1 -->
4
+ ## [0.4.0] - 2026-08-16
5
+
6
+ 本版在稳定 Harness 面上新增五项有限封闭语义机制与 token-lock 原语(FND-ADR-009),HARNESS_CAPABILITIES 从 9 项增至 16 项,并随附 rename-directory-no-replace 原生预编译候选。
7
+
8
+ ### 新增
9
+
10
+ - 新增五项有限封闭语义机制(FND-ADR-009):冻结基线物化 + contentGuard、通用只读 chokepoint、策略化表面扫描、确定性 token 上界估算与通用上限守卫。
11
+ - 新增 token-lock 原语:独占 token 文件发布与摘要复验。
12
+ - HARNESS_CAPABILITIES 从 9 项增至 16 项,覆盖上述新机制。
13
+ - 新增 rename-directory-no-replace 候选:覆盖 darwin-arm64、darwin-x64、linux-arm64-gnu、linux-x64-gnu 的原生预编译 no-replace 目录改名 addon,附带发布 receipt 与 SBOM。
14
+
15
+ ### 变更
16
+
17
+ - 保持 0.3.0 交付的 Quickstart Profile v2 Task/Result 交换校验:path-backed output 与 evidence 重算真实字节、拒绝重复 Resource id、evidence 精确绑定逐项复验。
18
+ - 方法选择、重试策略与领域结果解释继续归消费者所有。
19
+
20
+ ### 升级说明
21
+
22
+ 0.4.0 已发布到 npm 与 public 镜像仓。candidate 子路径必须精确锁定 0.4.0;机制导入使用 HARNESS_CAPABILITIES 公布的稳定能力名。
23
+ <!-- release-skill:changelog:end version=0.4.0 locale=zh-CN -->
24
+
25
+
26
+ <!-- release-skill:changelog:start version=0.3.0 locale=zh-CN baseline=sha256:b635e4170d3f7ac634e59f612939683ab04727f87101790d9a9f5613ea38fcfe -->
27
+ ## [0.3.0] - 2026-08-12
28
+
29
+ 本源码候选版把 Quickstart Profile Harness 更新为 v2 Task/Result 交换校验,同时不接管消费者语义。
30
+
31
+ ### 新增
32
+
33
+ - 对 path-backed output 与 evidence 重算真实字节摘要,并拒绝 observation、output、evidence 之间重复的 Resource id。
34
+ - 逐项复验 operation 身份、Task digest、run/stage/attempt 字段和 evidence 精确绑定集合。
35
+
36
+ ### 变更
37
+
38
+ - 替换与 0.2.1 不兼容的 candidate 面;仍依赖 v1 的消费者必须继续精确锁定 0.2.1。
39
+ - 方法选择、重试策略与领域结果解释继续归消费者所有。
40
+
41
+ ### 升级说明
42
+
43
+ 0.3.0 当前只是本地、未发布的源码候选。candidate 子路径必须精确锁定包版本,采用前需更新 v1 交换生产方。
44
+ <!-- release-skill:changelog:end version=0.3.0 locale=zh-CN -->
45
+
46
+
3
47
  <!-- release-skill:changelog:start version=0.2.1 locale=zh-CN baseline=sha256:2f2c74ab9dcf0f1a84872743bf203eb43d15c5e722e823e670e8d81ca5f7de65 -->
4
48
  ## [0.2.1] - 2026-08-10
5
49
 
package/README.md CHANGED
@@ -4,28 +4,30 @@
4
4
 
5
5
  # skill-family-harness-node
6
6
 
7
- <!-- release-skill:release-version: 0.2.1 -->
7
+ <!-- release-skill:release-version: 0.4.0 -->
8
8
 
9
9
  The **single default Node implementation** of the Contracts mechanism protocol. This is a thin runtime: it only implements the mechanism protocol, introduces no business semantics, and does not provide a second-language implementation.
10
10
 
11
11
  <!-- release-skill:managed:start id=latest-release -->
12
- **0.2.1** (2026-08-10)
12
+ **0.4.0** (2026-08-16)
13
13
 
14
- This release adds candidate Quickstart Profile exchange helpers and makes the package release documentation available in English and Simplified Chinese.
14
+ This release adds five finite-closed-semantics mechanisms and a token-lock primitive to the stable Harness surface (FND-ADR-009), grows HARNESS_CAPABILITIES from 9 to 16 entries, and ships the rename-directory-no-replace native-prebuild candidate.
15
15
 
16
16
  **Added**
17
17
 
18
- - Adds candidate helpers that create and revalidate observation Resources, build Tasks, wrap Results, and fail closed when a Result does not bind the exact Task and correlation fields.
19
- - Adds complete English and Simplified Chinese package documentation, including an agent quick-reference section.
18
+ - Adds five finite-closed-semantics mechanisms (FND-ADR-009), namely frozen-baseline materialization with contentGuard, the generic read chokepoint, strategy-driven surface scanning, deterministic token upper-bound estimation, and the generic upper-bound guard.
19
+ - Adds the token-lock primitive for exclusive token-file publication and digest verification.
20
+ - Grows HARNESS_CAPABILITIES from 9 to 16 entries for the new mechanisms.
21
+ - Adds the rename-directory-no-replace candidate, a native-prebuild addon proving no-replace directory renames on darwin-arm64, darwin-x64, linux-arm64-gnu, and linux-x64-gnu, with a release receipt and SBOM.
20
22
 
21
23
  **Changed**
22
24
 
23
- - Manages the current README and CHANGELOG release sections from one bilingual, versioned notes source.
24
- - Distributes the project NOTICE separately from the Apache-2.0 LICENSE.
25
+ - Keeps the Quickstart Profile v2 Task/Result exchange verification delivered in 0.3.0, including real-byte recomputation for path-backed outputs and evidence, duplicate Resource id rejection, and exact evidence binding verification.
26
+ - Leaves method selection, retry policy, and domain result interpretation to the consumer.
25
27
 
26
28
  **Upgrade Notes**
27
29
 
28
- The candidate helpers do not alter the stable Harness API or add lifecycle, retry, orchestration, model-call, network, or Git-write semantics.
30
+ Version 0.4.0 is released on npm and the public mirror. Pin the candidate subpath to exactly 0.4.0; mechanism imports use the stable capability names published in HARNESS_CAPABILITIES.
29
31
  <!-- release-skill:managed:end id=latest-release -->
30
32
 
31
33
  ## Problem It Solves
@@ -39,14 +41,14 @@ The Harness consumes `skill-family-contracts` (a workspace dependency), reusing
39
41
  ## Installation and Minimal Example
40
42
 
41
43
  ```sh
42
- npm install skill-family-harness-node@0.2.1
44
+ npm install skill-family-harness-node@0.4.0
43
45
  npm info skill-family-harness-node --help
44
46
  ```
45
47
 
46
48
  The minimal example shows validating a contract document inside Node:
47
49
 
48
50
  ```js
49
- // Run from an empty directory: npm install skill-family-harness-node@0.2.1
51
+ // Run from an empty directory: npm install skill-family-harness-node@0.4.0
50
52
  import { validateContractDocument } from "skill-family-harness-node";
51
53
 
52
54
  const document = {
@@ -78,7 +80,9 @@ import {
78
80
  } from "skill-family-harness-node/candidate/quickstart-profile";
79
81
  ```
80
82
 
81
- This mechanism is intended for early integration trials of the candidate Contracts profile. It does not perform a domain audit, choose a method, retry work, or own lifecycle state. The subpath is public but **not stable** and may change or be removed in a later minor release; pin the exact package version and do not expose it through a stable consumer API.
83
+ The v2 mechanism recomputes the bytes of every path-backed output and evidence Resource. It also rejects duplicate Resource ids, correlation drift, a changed Task digest, and incomplete or mismatched evidence bindings. It does not perform a domain audit, choose a method, retry work, or own lifecycle state.
84
+
85
+ The subpath is public but **not stable** and may change or be removed in a later minor release. Pin exactly `0.4.0` for v2; integrations that still produce candidate v1 exchanges must stay pinned to exactly `0.2.1`.
82
86
 
83
87
  ## Typical Use Cases
84
88
 
package/README.zh-CN.md CHANGED
@@ -5,28 +5,30 @@
5
5
 
6
6
  # skill-family-harness-node
7
7
 
8
- <!-- release-skill:release-version: 0.2.1 -->
8
+ <!-- release-skill:release-version: 0.4.0 -->
9
9
 
10
10
  Contracts 机制协议的**唯一默认 Node 实现**。这是一个薄运行时(thin runtime):只实现机制协议,不引入业务语义,不做第二语言实现。
11
11
 
12
12
  <!-- release-skill:managed:start id=latest-release -->
13
- **0.2.1** (2026-08-10)
13
+ **0.4.0** (2026-08-16)
14
14
 
15
- 本版新增 Quickstart Profile 候选交换辅助函数,并为包发布文档提供完整英文版与简体中文版。
15
+ 本版在稳定 Harness 面上新增五项有限封闭语义机制与 token-lock 原语(FND-ADR-009),HARNESS_CAPABILITIES 从 9 项增至 16 项,并随附 rename-directory-no-replace 原生预编译候选。
16
16
 
17
17
  **新增**
18
18
 
19
- - 新增候选辅助函数,用于创建并复验 observation Resource、构造 Task、封装 Result,并在 Result 未精确绑定 Task 与关联字段时失败关闭。
20
- - 新增完整的英文与简体中文包文档,并补充智能体快速参考章节。
19
+ - 新增五项有限封闭语义机制(FND-ADR-009):冻结基线物化 + contentGuard、通用只读 chokepoint、策略化表面扫描、确定性 token 上界估算与通用上限守卫。
20
+ - 新增 token-lock 原语:独占 token 文件发布与摘要复验。
21
+ - HARNESS_CAPABILITIES 从 9 项增至 16 项,覆盖上述新机制。
22
+ - 新增 rename-directory-no-replace 候选:覆盖 darwin-arm64、darwin-x64、linux-arm64-gnu、linux-x64-gnu 的原生预编译 no-replace 目录改名 addon,附带发布 receipt 与 SBOM。
21
23
 
22
24
  **变更**
23
25
 
24
- - 使用同一份双语版本化说明源管理当前 READMECHANGELOG 的发布区域。
25
- - 项目 NOTICE 与 Apache-2.0 LICENSE 分开分发。
26
+ - 保持 0.3.0 交付的 Quickstart Profile v2 Task/Result 交换校验:path-backed output evidence 重算真实字节、拒绝重复 Resource id、evidence 精确绑定逐项复验。
27
+ - 方法选择、重试策略与领域结果解释继续归消费者所有。
26
28
 
27
29
  **升级说明**
28
30
 
29
- 候选辅助函数不改变稳定 Harness API,也不引入生命周期、重试、编排、模型调用、网络或 Git 写入语义。
31
+ 0.4.0 已发布到 npm public 镜像仓。candidate 子路径必须精确锁定 0.4.0;机制导入使用 HARNESS_CAPABILITIES 公布的稳定能力名。
30
32
  <!-- release-skill:managed:end id=latest-release -->
31
33
 
32
34
  ## 解决的问题
@@ -40,14 +42,14 @@ Harness 消费 `skill-family-contracts`(工作区依赖),复用其方言
40
42
  ## 安装和最小示例
41
43
 
42
44
  ```sh
43
- npm install skill-family-harness-node@0.2.1
45
+ npm install skill-family-harness-node@0.4.0
44
46
  npm info skill-family-harness-node --help
45
47
  ```
46
48
 
47
49
  最小示例演示在 Node 内校验一份契约文档:
48
50
 
49
51
  ```js
50
- // 从空目录运行:npm install skill-family-harness-node@0.2.1
52
+ // 从空目录运行:npm install skill-family-harness-node@0.4.0
51
53
  import { validateContractDocument } from "skill-family-harness-node";
52
54
 
53
55
  const document = {
@@ -79,7 +81,9 @@ import {
79
81
  } from "skill-family-harness-node/candidate/quickstart-profile";
80
82
  ```
81
83
 
82
- 以上机制用于 candidate Contracts Profile 的早期接入试验。它不执行领域审计,不选择 method,不编排重试,也不拥有生命周期状态。该子路径公开但**不稳定**,后续小版本可以修改或移除;调用方需要锁定精确包版本,并避免通过自身稳定 API 再导出。
84
+ v2 机制会重算每个 path-backed output evidence Resource 的真实字节摘要,并拒绝重复 Resource id、correlation 漂移、Task digest 变化,以及缺失或错配的 evidence binding。它不执行领域审计,不选择 method,不编排重试,也不拥有生命周期状态。
85
+
86
+ 该子路径公开但**不稳定**,后续小版本可以修改或移除。使用 v2 时应精确锁定 `0.4.0`;仍生产 candidate v1 交换的接入必须继续精确锁定 `0.2.1`。
83
87
 
84
88
  ## 典型使用场景
85
89
 
@@ -1,41 +1,157 @@
1
1
  #!/usr/bin/env node
2
2
  import { stdin, stdout, stderr } from "node:process";
3
+ import { realpathSync } from "node:fs";
4
+ import { fileURLToPath } from "node:url";
3
5
  import {
4
- canonicalJson,
5
- computeResourceClosure,
6
- digestDocument,
6
+ invokeFoundationMechanism,
7
+ verifyManagedBundleIdentity,
7
8
  } from "./quickstart-profile.mjs";
8
9
 
9
- async function readRequest() {
10
+ const CLI_NAME = "mechanisms-cli.mjs";
11
+
12
+ async function readRequest(input) {
10
13
  const chunks = [];
11
- for await (const chunk of stdin) chunks.push(chunk);
12
- return JSON.parse(Buffer.concat(chunks).toString("utf8"));
14
+ for await (const chunk of input) chunks.push(Buffer.from(chunk));
15
+ const text = new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(chunks));
16
+ return JSON.parse(text);
17
+ }
18
+
19
+ function errorResponse(cause) {
20
+ return {
21
+ ok: false,
22
+ error: {
23
+ name: typeof cause?.name === "string" ? cause.name : "Error",
24
+ message: cause?.message ?? String(cause),
25
+ },
26
+ };
13
27
  }
14
28
 
15
- export async function runMechanismCli() {
29
+ /**
30
+ * Fixed dispatch for the publish-fixed-set operation.
31
+ *
32
+ * This operation is fail-closed: if the native addon is unavailable or the
33
+ * platform is unsupported, the operation returns a receipt with status=refused
34
+ * and error code UNSUPPORTED_PLATFORM. No JS rename fallback is attempted.
35
+ *
36
+ * The operation takes a frozen sibling-directory source/target tuple and
37
+ * returns a receipt. It does NOT
38
+ * expose any module/function/pathToFileURL call surface.
39
+ */
40
+ async function runPublishFixedSet(params, invoke) {
41
+ if (
42
+ params === null ||
43
+ typeof params !== "object" ||
44
+ Array.isArray(params) ||
45
+ Object.keys(params).sort().join(",") !== "manifest,sourceRoot,targetParent,targetSegment" ||
46
+ typeof params.sourceRoot !== "string" ||
47
+ typeof params.targetParent !== "string" ||
48
+ typeof params.targetSegment !== "string" ||
49
+ params.manifest === null ||
50
+ typeof params.manifest !== "object"
51
+ ) {
52
+ throw new TypeError("publish-fixed-set requires exactly sourceRoot, targetParent, targetSegment, and manifest");
53
+ }
54
+
55
+ let publishFixedSet;
16
56
  try {
17
- const request = await readRequest();
57
+ const mod = await import("./rename-directory-no-replace/rename-directory-no-replace.mjs");
58
+ publishFixedSet = mod.publishFixedSet;
59
+ } catch (cause) {
60
+ const manifestDigest = await invoke({ operation: "digest-document", params: { document: params.manifest } });
61
+ return {
62
+ schemaVersion: 1,
63
+ kind: "skill-family.fixed-set-publication-receipt",
64
+ manifestDigest: manifestDigest.digest,
65
+ targetRootBinding: params.manifest?.target?.rootBinding ?? {
66
+ kind: "trusted-filesystem-root-binding", digestAlgorithm: "sha256",
67
+ basis: "canonical-realpath-device-inode-type-mode-v1", digest: "0".repeat(64),
68
+ },
69
+ platform: "other",
70
+ primitive: "none",
71
+ status: "refused",
72
+ targetState: "absent",
73
+ commitState: "not-committed",
74
+ verification: "not-run",
75
+ durability: "not-attempted",
76
+ error: {
77
+ code: "UNSUPPORTED_PLATFORM",
78
+ message: `publish-fixed-set module unavailable: ${cause?.message ?? "unknown"}`.slice(0, 300),
79
+ },
80
+ };
81
+ }
82
+
83
+ return publishFixedSet(params);
84
+ }
85
+
86
+ /** Fixed manifest construction for the same receipt-bound publication mechanism. */
87
+ async function runCreateFixedSetPublicationManifest(params) {
88
+ if (
89
+ params === null ||
90
+ typeof params !== "object" ||
91
+ Array.isArray(params) ||
92
+ Object.keys(params).sort().join(",") !== "sourceRoot,targetParent,targetSegment" ||
93
+ typeof params.sourceRoot !== "string" ||
94
+ typeof params.targetParent !== "string" ||
95
+ typeof params.targetSegment !== "string"
96
+ ) {
97
+ throw new TypeError(
98
+ "create-fixed-set-publication-manifest requires exactly sourceRoot, targetParent, and targetSegment",
99
+ );
100
+ }
101
+ const { createFixedSetPublicationManifest } = await import(
102
+ "./rename-directory-no-replace/rename-directory-no-replace.mjs"
103
+ );
104
+ return createFixedSetPublicationManifest(params);
105
+ }
106
+
107
+ /**
108
+ * One-request/one-response JSON transport for the fixed Foundation mechanism
109
+ * bridge. The offline Bundle rewrites the import above to its managed runner,
110
+ * which injects the Bundle-owned schema validator. No request can name a
111
+ * module, export, or arbitrary function.
112
+ */
113
+ export async function runMechanismCli({
114
+ input = stdin,
115
+ output = stdout,
116
+ error = stderr,
117
+ invoke = invokeFoundationMechanism,
118
+ } = {}) {
119
+ try {
120
+ const request = await readRequest(input);
18
121
  let result;
19
- if (request.operation === "canonical-json") {
20
- result = { text: canonicalJson(request.document) };
21
- } else if (request.operation === "digest-document") {
22
- result = { digest: digestDocument(request.document) };
23
- } else if (request.operation === "resource-closure") {
24
- result = await computeResourceClosure({
25
- root: request.root,
26
- resources: request.resources,
27
- });
122
+ if (request?.operation === "self-check") {
123
+ result = await runSelfCheck(request);
124
+ } else if (request?.operation === "create-fixed-set-publication-manifest") {
125
+ result = await runCreateFixedSetPublicationManifest(request.params);
126
+ } else if (request?.operation === "publish-fixed-set") {
127
+ result = await runPublishFixedSet(request.params, invoke);
28
128
  } else {
29
- throw new TypeError(`unknown Foundation mechanism: ${String(request.operation)}`);
129
+ result = await invoke(request);
30
130
  }
31
- stdout.write(`${JSON.stringify(result)}\n`);
131
+ output.write(`${JSON.stringify(result)}\n`);
32
132
  return 0;
33
133
  } catch (cause) {
34
- stderr.write(`${cause?.message ?? String(cause)}\n`);
134
+ error.write(`${JSON.stringify(errorResponse(cause))}\n`);
35
135
  return 2;
36
136
  }
37
137
  }
38
138
 
39
- if (import.meta.url === `file://${process.argv[1]}`) {
139
+ async function runSelfCheck(request) {
140
+ if (
141
+ request === null ||
142
+ typeof request !== "object" ||
143
+ Array.isArray(request) ||
144
+ Object.keys(request).sort().join(",") !== "operation,params" ||
145
+ request.params === null ||
146
+ typeof request.params !== "object" ||
147
+ Array.isArray(request.params) ||
148
+ Object.keys(request.params).length !== 0
149
+ ) {
150
+ throw new TypeError("mechanisms CLI self-check requires exactly operation and empty params");
151
+ }
152
+ return verifyManagedBundleIdentity({ cliUrl: import.meta.url, cliName: CLI_NAME });
153
+ }
154
+
155
+ if (process.argv[1] && realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1])) {
40
156
  process.exitCode = await runMechanismCli();
41
157
  }