skill-family-harness-node 0.3.0 → 0.5.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.
- package/CHANGELOG.md +47 -0
- package/CHANGELOG.zh-CN.md +47 -0
- package/README.md +14 -11
- package/README.zh-CN.md +14 -11
- package/candidate/mechanisms-cli.mjs +137 -21
- package/candidate/quickstart-profile.mjs +517 -0
- package/candidate/rename-directory-no-replace/NOTICE +3 -0
- package/candidate/rename-directory-no-replace/addon/binding.gyp +25 -0
- package/candidate/rename-directory-no-replace/addon/rename_directory_no_replace.c +243 -0
- package/candidate/rename-directory-no-replace/build-prebuild-candidate.mjs +194 -0
- package/candidate/rename-directory-no-replace/loader.mjs +140 -0
- package/candidate/rename-directory-no-replace/prebuild-manifest.json +71 -0
- package/candidate/rename-directory-no-replace/prebuild-release-receipt.json +36 -0
- package/candidate/rename-directory-no-replace/prebuild-sbom.json +35 -0
- package/candidate/rename-directory-no-replace/prebuilds/darwin-arm64/rename_directory_no_replace.darwin-arm64.node +0 -0
- package/candidate/rename-directory-no-replace/prebuilds/darwin-x64/rename_directory_no_replace.darwin-x64.node +0 -0
- package/candidate/rename-directory-no-replace/prebuilds/linux-arm64-gnu/rename_directory_no_replace.linux-arm64-gnu.node +0 -0
- package/candidate/rename-directory-no-replace/prebuilds/linux-x64-gnu/rename_directory_no_replace.linux-x64-gnu.node +0 -0
- package/candidate/rename-directory-no-replace/rename-directory-no-replace.mjs +289 -0
- package/package.json +7 -3
- package/release-notes/0.3.0.yaml +2 -0
- package/release-notes/0.4.0.yaml +27 -0
- package/release-notes/0.5.0.yaml +29 -0
- package/src/atomic.mjs +448 -44
- package/src/baseline.mjs +200 -0
- package/src/budget-guard.mjs +134 -0
- package/src/chokepoint.mjs +111 -0
- package/src/declared-read-surface.mjs +198 -0
- package/src/errors.mjs +13 -0
- package/src/index.mjs +39 -1
- package/src/state-store.mjs +18 -1
- package/src/structured-scan.mjs +652 -0
- package/src/surface-scan.mjs +91 -0
- package/src/token-estimate.mjs +39 -0
- package/src/token-lock.mjs +180 -0
- package/src/workspace.mjs +55 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
<!-- release-skill:changelog:start version=0.5.0 locale=en baseline=sha256:03eca87a8c9bea814e741518168696f17c869bdb71baf2046cef4c3596d9ebf3 -->
|
|
4
|
+
## [0.5.0] - 2026-08-16
|
|
5
|
+
|
|
6
|
+
This release adds the declared read surface assertion (FND-ADR-010) and the structured surface scanner (FND-ADR-011) to the stable Harness surface, growing HARNESS_CAPABILITIES from 16 to 18 entries, and adds three dependency-reviewed runtime libraries.
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Adds assertDeclaredReadSurface (FND-ADR-010): a no-execution, syntax-surface-only assertion that every node:fs named import inside a declared module set stays inside the consumer-declared read surface, with a closed violation vocabulary and a frozen declared-read-surface-result envelope.
|
|
11
|
+
- Adds scanSurfaceStructured (FND-ADR-011): the structured sibling of scanSurface. IP-shaped candidates enter a single standard parse entry (ipaddr.js) with consumer-declared CIDR approval and fail closed when unparseable; scoped and unscoped coordinates, registries and hosts need consumer-declared approval; format adapters (pnpm-lockfile via @pnpm/lockfile.fs with yaml AST comment regions, and tree-json) parse structurally with no position-level exemptions; binary and symlink policies fail closed. The closed nine-rule vocabulary travels in details.rule of the structured-scan-violation mechanism error.
|
|
12
|
+
- Adds three dependency-reviewed runtime libraries for the structured scanner, reviewed per FND-ADR-006 section-4 analogy (dependency-closure pre-review, executor self-review pending independent review): ipaddr.js 2.5.0 (MIT, zero dependencies), yaml 2.9.0 (ISC), and @pnpm/lockfile.fs 1001.1.35 (MIT, 18 transitive dependencies all inside the approved public coordinates).
|
|
13
|
+
- Grows HARNESS_CAPABILITIES from 16 to 18 entries for the two new mechanisms.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Documents the relationship of the two policy documents to workspace-private leak policies: a workspace-private leak-policy.json instance document is not a subset, not isomorphic and not a migration target of the surface-scan-policy or structured-scan-policy schemas — the documents share rule vocabulary and fail-closed semantics by design, but their byte-level shapes are independent and must not be compared for compatibility. scanSurface is the execution-core generalization projection: the public, consumer-parameterized form of the same mechanism family, without any private identity, path, or approval-list interpretation of its own.
|
|
18
|
+
- Records the cost of the dependency-review decision honestly: the harness tarball grows with the @pnpm/lockfile.fs closure, the thin-runtime property changes from zero third-party runtime dependencies to three reviewed ones, and the pnpm-lockfile adapter writes one temporary lockfile copy under the OS temp directory (removed afterwards). The engineering-kit offline-consumer verification gates now derive the complete third-party production closure of the three Foundation packages mechanically (identity-deduplicated, npm: alias-aware, range-scoped override selectors) instead of a single-package closure, so the review decision is continuously verified against the real installed bytes.
|
|
19
|
+
- Keeps mechanism purity: no execution of scanned files, no model calls, no network; symlinked entries are never followed.
|
|
20
|
+
|
|
21
|
+
### Upgrade Notes
|
|
22
|
+
|
|
23
|
+
Version 0.5.0 is the FND-ADR-010/011 harness line. Mechanism imports use the stable capability names published in HARNESS_CAPABILITIES; structured-scan policies must pass the structured-scan-policy contract validation of contract-spec 1.5.0.
|
|
24
|
+
<!-- release-skill:changelog:end version=0.5.0 locale=en -->
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
<!-- release-skill:changelog:start version=0.4.0 locale=en baseline=sha256:72d3fe048ced8eb44a84fabe6f1fdd2eb0c938b4f6bb98740474f72aec04d873 -->
|
|
28
|
+
## [0.4.0] - 2026-08-16
|
|
29
|
+
|
|
30
|
+
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.
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- 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.
|
|
35
|
+
- Adds the token-lock primitive for exclusive token-file publication and digest verification.
|
|
36
|
+
- Grows HARNESS_CAPABILITIES from 9 to 16 entries for the new mechanisms.
|
|
37
|
+
- 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.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- 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.
|
|
42
|
+
- Leaves method selection, retry policy, and domain result interpretation to the consumer.
|
|
43
|
+
|
|
44
|
+
### Upgrade Notes
|
|
45
|
+
|
|
46
|
+
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.
|
|
47
|
+
<!-- release-skill:changelog:end version=0.4.0 locale=en -->
|
|
48
|
+
|
|
49
|
+
|
|
3
50
|
<!-- release-skill:changelog:start version=0.3.0 locale=en baseline=sha256:7afef97792b4714abbd0412dcb7ea76ca66260ef9f8dd2191131b7c3f8539813 -->
|
|
4
51
|
## [0.3.0] - 2026-08-12
|
|
5
52
|
|
package/CHANGELOG.zh-CN.md
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# 变更日志
|
|
2
2
|
|
|
3
|
+
<!-- release-skill:changelog:start version=0.5.0 locale=zh-CN baseline=sha256:003472359596147fe26ad2ba53a82303a217c28cb89a6afacdaa955793001f71 -->
|
|
4
|
+
## [0.5.0] - 2026-08-16
|
|
5
|
+
|
|
6
|
+
本版在稳定 Harness 面上新增声明读取表面断言(FND-ADR-010)与结构化表面扫描器(FND-ADR-011),HARNESS_CAPABILITIES 从 16 项增至 18 项,并引入三个经依赖评审的运行时库。
|
|
7
|
+
|
|
8
|
+
### 新增
|
|
9
|
+
|
|
10
|
+
- 新增 assertDeclaredReadSurface(FND-ADR-010):不执行、仅语法面的断言,声明模块集内的每个 node:fs 具名导入必须落在消费者声明的读取表面内,违规词汇表为闭集,返回冻结的 declared-read-surface-result 信封。
|
|
11
|
+
- 新增 scanSurfaceStructured(FND-ADR-011):scanSurface 的结构化兄弟。IP 形候选统一进入单一标准解析入口(ipaddr.js),按消费者声明的 CIDR 批准,不可解析即失败关闭;坐标(scoped 与非 scoped)、注册表与主机均需消费者声明批准;格式适配器(pnpm-lockfile 经 @pnpm/lockfile.fs + yaml AST 注释区域,tree-json 经 JSON.parse)结构化解析且无位置级豁免;二进制与符号链接策略失败关闭。闭集九规则词汇表经 structured-scan-violation 机制错误的 details.rule 承载。
|
|
12
|
+
- 为结构化扫描器引入三个经依赖评审的运行时库,评审按 FND-ADR-006 第 4 节类比执行(依赖闭包预审,执行者自审,独立复核另行安排):ipaddr.js 2.5.0(MIT,零依赖)、yaml 2.9.0(ISC)、@pnpm/lockfile.fs 1001.1.35(MIT,18 个传递依赖全部在批准公共坐标内)。
|
|
13
|
+
- HARNESS_CAPABILITIES 从 16 项增至 18 项,覆盖两个新机制。
|
|
14
|
+
|
|
15
|
+
### 变更
|
|
16
|
+
|
|
17
|
+
- 显式说明两个策略文档与工作区私有 leak 策略的关系:工作区私有的 leak-policy.json 实例文档既不是 surface-scan-policy 或 structured-scan-policy schema 的子集、也不同构、更不是迁移目标——两类文档按设计共享规则词汇与失败关闭语义,但字节级形状相互独立,不得比较兼容性。scanSurface 是执行内核通用化投影:同一机制族的公开、消费者参数化形态,自身不解释任何私有身份、路径或批准清单。
|
|
18
|
+
- 如实记录依赖评审决策的成本:harness tarball 随 @pnpm/lockfile.fs 闭包扩大;薄运行时属性从零第三方运行时依赖变为三个经评审依赖;pnpm-lockfile 适配器会在 OS 临时目录写一份临时锁文件副本(用后即删)。engineering-kit 的离线消费者验证门随之把第三方闭包推导从单包闭包机械扩展为三个 Foundation 包的完整生产闭包(真实身份去重、npm: 别名感知、range-scoped override selector),使评审决策持续对着真实安装字节被验证。
|
|
19
|
+
- 保持机制纯度:不执行被扫描文件、无模型调用、无网络;永不跟随符号链接。
|
|
20
|
+
|
|
21
|
+
### 升级说明
|
|
22
|
+
|
|
23
|
+
0.5.0 是 FND-ADR-010/011 harness 线。机制导入使用 HARNESS_CAPABILITIES 公布的稳定能力名;structured-scan 策略必须通过契约规格 1.5.0 的 structured-scan-policy 契约校验。
|
|
24
|
+
<!-- release-skill:changelog:end version=0.5.0 locale=zh-CN -->
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
<!-- release-skill:changelog:start version=0.4.0 locale=zh-CN baseline=sha256:dafaa1100bf6163a28d53fc982a30e8325d8bd3cab43bbb6daf2e6002befa2c1 -->
|
|
28
|
+
## [0.4.0] - 2026-08-16
|
|
29
|
+
|
|
30
|
+
本版在稳定 Harness 面上新增五项有限封闭语义机制与 token-lock 原语(FND-ADR-009),HARNESS_CAPABILITIES 从 9 项增至 16 项,并随附 rename-directory-no-replace 原生预编译候选。
|
|
31
|
+
|
|
32
|
+
### 新增
|
|
33
|
+
|
|
34
|
+
- 新增五项有限封闭语义机制(FND-ADR-009):冻结基线物化 + contentGuard、通用只读 chokepoint、策略化表面扫描、确定性 token 上界估算与通用上限守卫。
|
|
35
|
+
- 新增 token-lock 原语:独占 token 文件发布与摘要复验。
|
|
36
|
+
- HARNESS_CAPABILITIES 从 9 项增至 16 项,覆盖上述新机制。
|
|
37
|
+
- 新增 rename-directory-no-replace 候选:覆盖 darwin-arm64、darwin-x64、linux-arm64-gnu、linux-x64-gnu 的原生预编译 no-replace 目录改名 addon,附带发布 receipt 与 SBOM。
|
|
38
|
+
|
|
39
|
+
### 变更
|
|
40
|
+
|
|
41
|
+
- 保持 0.3.0 交付的 Quickstart Profile v2 Task/Result 交换校验:path-backed output 与 evidence 重算真实字节、拒绝重复 Resource id、evidence 精确绑定逐项复验。
|
|
42
|
+
- 方法选择、重试策略与领域结果解释继续归消费者所有。
|
|
43
|
+
|
|
44
|
+
### 升级说明
|
|
45
|
+
|
|
46
|
+
0.4.0 已发布到 npm 与 public 镜像仓。candidate 子路径必须精确锁定 0.4.0;机制导入使用 HARNESS_CAPABILITIES 公布的稳定能力名。
|
|
47
|
+
<!-- release-skill:changelog:end version=0.4.0 locale=zh-CN -->
|
|
48
|
+
|
|
49
|
+
|
|
3
50
|
<!-- release-skill:changelog:start version=0.3.0 locale=zh-CN baseline=sha256:b635e4170d3f7ac634e59f612939683ab04727f87101790d9a9f5613ea38fcfe -->
|
|
4
51
|
## [0.3.0] - 2026-08-12
|
|
5
52
|
|
package/README.md
CHANGED
|
@@ -4,28 +4,31 @@
|
|
|
4
4
|
|
|
5
5
|
# skill-family-harness-node
|
|
6
6
|
|
|
7
|
-
<!-- release-skill:release-version: 0.
|
|
7
|
+
<!-- release-skill:release-version: 0.5.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.
|
|
12
|
+
**0.5.0** (2026-08-16)
|
|
13
13
|
|
|
14
|
-
This
|
|
14
|
+
This release adds the declared read surface assertion (FND-ADR-010) and the structured surface scanner (FND-ADR-011) to the stable Harness surface, growing HARNESS_CAPABILITIES from 16 to 18 entries, and adds three dependency-reviewed runtime libraries.
|
|
15
15
|
|
|
16
16
|
**Added**
|
|
17
17
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
18
|
+
- Adds assertDeclaredReadSurface (FND-ADR-010): a no-execution, syntax-surface-only assertion that every node:fs named import inside a declared module set stays inside the consumer-declared read surface, with a closed violation vocabulary and a frozen declared-read-surface-result envelope.
|
|
19
|
+
- Adds scanSurfaceStructured (FND-ADR-011): the structured sibling of scanSurface. IP-shaped candidates enter a single standard parse entry (ipaddr.js) with consumer-declared CIDR approval and fail closed when unparseable; scoped and unscoped coordinates, registries and hosts need consumer-declared approval; format adapters (pnpm-lockfile via @pnpm/lockfile.fs with yaml AST comment regions, and tree-json) parse structurally with no position-level exemptions; binary and symlink policies fail closed. The closed nine-rule vocabulary travels in details.rule of the structured-scan-violation mechanism error.
|
|
20
|
+
- Adds three dependency-reviewed runtime libraries for the structured scanner, reviewed per FND-ADR-006 section-4 analogy (dependency-closure pre-review, executor self-review pending independent review): ipaddr.js 2.5.0 (MIT, zero dependencies), yaml 2.9.0 (ISC), and @pnpm/lockfile.fs 1001.1.35 (MIT, 18 transitive dependencies all inside the approved public coordinates).
|
|
21
|
+
- Grows HARNESS_CAPABILITIES from 16 to 18 entries for the two new mechanisms.
|
|
20
22
|
|
|
21
23
|
**Changed**
|
|
22
24
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
+
- Documents the relationship of the two policy documents to workspace-private leak policies: a workspace-private leak-policy.json instance document is not a subset, not isomorphic and not a migration target of the surface-scan-policy or structured-scan-policy schemas — the documents share rule vocabulary and fail-closed semantics by design, but their byte-level shapes are independent and must not be compared for compatibility. scanSurface is the execution-core generalization projection: the public, consumer-parameterized form of the same mechanism family, without any private identity, path, or approval-list interpretation of its own.
|
|
26
|
+
- Records the cost of the dependency-review decision honestly: the harness tarball grows with the @pnpm/lockfile.fs closure, the thin-runtime property changes from zero third-party runtime dependencies to three reviewed ones, and the pnpm-lockfile adapter writes one temporary lockfile copy under the OS temp directory (removed afterwards). The engineering-kit offline-consumer verification gates now derive the complete third-party production closure of the three Foundation packages mechanically (identity-deduplicated, npm: alias-aware, range-scoped override selectors) instead of a single-package closure, so the review decision is continuously verified against the real installed bytes.
|
|
27
|
+
- Keeps mechanism purity: no execution of scanned files, no model calls, no network; symlinked entries are never followed.
|
|
25
28
|
|
|
26
29
|
**Upgrade Notes**
|
|
27
30
|
|
|
28
|
-
Version 0.
|
|
31
|
+
Version 0.5.0 is the FND-ADR-010/011 harness line. Mechanism imports use the stable capability names published in HARNESS_CAPABILITIES; structured-scan policies must pass the structured-scan-policy contract validation of contract-spec 1.5.0.
|
|
29
32
|
<!-- release-skill:managed:end id=latest-release -->
|
|
30
33
|
|
|
31
34
|
## Problem It Solves
|
|
@@ -39,14 +42,14 @@ The Harness consumes `skill-family-contracts` (a workspace dependency), reusing
|
|
|
39
42
|
## Installation and Minimal Example
|
|
40
43
|
|
|
41
44
|
```sh
|
|
42
|
-
npm install skill-family-harness-node@0.
|
|
45
|
+
npm install skill-family-harness-node@0.5.0
|
|
43
46
|
npm info skill-family-harness-node --help
|
|
44
47
|
```
|
|
45
48
|
|
|
46
49
|
The minimal example shows validating a contract document inside Node:
|
|
47
50
|
|
|
48
51
|
```js
|
|
49
|
-
// Run from an empty directory: npm install skill-family-harness-node@0.
|
|
52
|
+
// Run from an empty directory: npm install skill-family-harness-node@0.5.0
|
|
50
53
|
import { validateContractDocument } from "skill-family-harness-node";
|
|
51
54
|
|
|
52
55
|
const document = {
|
|
@@ -80,7 +83,7 @@ import {
|
|
|
80
83
|
|
|
81
84
|
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.
|
|
82
85
|
|
|
83
|
-
The subpath is public but **not stable** and may change or be removed in a later minor release. Pin exactly `0.
|
|
86
|
+
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`.
|
|
84
87
|
|
|
85
88
|
## Typical Use Cases
|
|
86
89
|
|
package/README.zh-CN.md
CHANGED
|
@@ -5,28 +5,31 @@
|
|
|
5
5
|
|
|
6
6
|
# skill-family-harness-node
|
|
7
7
|
|
|
8
|
-
<!-- release-skill:release-version: 0.
|
|
8
|
+
<!-- release-skill:release-version: 0.5.0 -->
|
|
9
9
|
|
|
10
10
|
Contracts 机制协议的**唯一默认 Node 实现**。这是一个薄运行时(thin runtime):只实现机制协议,不引入业务语义,不做第二语言实现。
|
|
11
11
|
|
|
12
12
|
<!-- release-skill:managed:start id=latest-release -->
|
|
13
|
-
**0.
|
|
13
|
+
**0.5.0** (2026-08-16)
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
本版在稳定 Harness 面上新增声明读取表面断言(FND-ADR-010)与结构化表面扫描器(FND-ADR-011),HARNESS_CAPABILITIES 从 16 项增至 18 项,并引入三个经依赖评审的运行时库。
|
|
16
16
|
|
|
17
17
|
**新增**
|
|
18
18
|
|
|
19
|
-
-
|
|
20
|
-
-
|
|
19
|
+
- 新增 assertDeclaredReadSurface(FND-ADR-010):不执行、仅语法面的断言,声明模块集内的每个 node:fs 具名导入必须落在消费者声明的读取表面内,违规词汇表为闭集,返回冻结的 declared-read-surface-result 信封。
|
|
20
|
+
- 新增 scanSurfaceStructured(FND-ADR-011):scanSurface 的结构化兄弟。IP 形候选统一进入单一标准解析入口(ipaddr.js),按消费者声明的 CIDR 批准,不可解析即失败关闭;坐标(scoped 与非 scoped)、注册表与主机均需消费者声明批准;格式适配器(pnpm-lockfile 经 @pnpm/lockfile.fs + yaml AST 注释区域,tree-json 经 JSON.parse)结构化解析且无位置级豁免;二进制与符号链接策略失败关闭。闭集九规则词汇表经 structured-scan-violation 机制错误的 details.rule 承载。
|
|
21
|
+
- 为结构化扫描器引入三个经依赖评审的运行时库,评审按 FND-ADR-006 第 4 节类比执行(依赖闭包预审,执行者自审,独立复核另行安排):ipaddr.js 2.5.0(MIT,零依赖)、yaml 2.9.0(ISC)、@pnpm/lockfile.fs 1001.1.35(MIT,18 个传递依赖全部在批准公共坐标内)。
|
|
22
|
+
- HARNESS_CAPABILITIES 从 16 项增至 18 项,覆盖两个新机制。
|
|
21
23
|
|
|
22
24
|
**变更**
|
|
23
25
|
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
+
- 显式说明两个策略文档与工作区私有 leak 策略的关系:工作区私有的 leak-policy.json 实例文档既不是 surface-scan-policy 或 structured-scan-policy schema 的子集、也不同构、更不是迁移目标——两类文档按设计共享规则词汇与失败关闭语义,但字节级形状相互独立,不得比较兼容性。scanSurface 是执行内核通用化投影:同一机制族的公开、消费者参数化形态,自身不解释任何私有身份、路径或批准清单。
|
|
27
|
+
- 如实记录依赖评审决策的成本:harness tarball 随 @pnpm/lockfile.fs 闭包扩大;薄运行时属性从零第三方运行时依赖变为三个经评审依赖;pnpm-lockfile 适配器会在 OS 临时目录写一份临时锁文件副本(用后即删)。engineering-kit 的离线消费者验证门随之把第三方闭包推导从单包闭包机械扩展为三个 Foundation 包的完整生产闭包(真实身份去重、npm: 别名感知、range-scoped override selector),使评审决策持续对着真实安装字节被验证。
|
|
28
|
+
- 保持机制纯度:不执行被扫描文件、无模型调用、无网络;永不跟随符号链接。
|
|
26
29
|
|
|
27
30
|
**升级说明**
|
|
28
31
|
|
|
29
|
-
0.
|
|
32
|
+
0.5.0 是 FND-ADR-010/011 harness 线。机制导入使用 HARNESS_CAPABILITIES 公布的稳定能力名;structured-scan 策略必须通过契约规格 1.5.0 的 structured-scan-policy 契约校验。
|
|
30
33
|
<!-- release-skill:managed:end id=latest-release -->
|
|
31
34
|
|
|
32
35
|
## 解决的问题
|
|
@@ -40,14 +43,14 @@ Harness 消费 `skill-family-contracts`(工作区依赖),复用其方言
|
|
|
40
43
|
## 安装和最小示例
|
|
41
44
|
|
|
42
45
|
```sh
|
|
43
|
-
npm install skill-family-harness-node@0.
|
|
46
|
+
npm install skill-family-harness-node@0.5.0
|
|
44
47
|
npm info skill-family-harness-node --help
|
|
45
48
|
```
|
|
46
49
|
|
|
47
50
|
最小示例演示在 Node 内校验一份契约文档:
|
|
48
51
|
|
|
49
52
|
```js
|
|
50
|
-
// 从空目录运行:npm install skill-family-harness-node@0.
|
|
53
|
+
// 从空目录运行:npm install skill-family-harness-node@0.5.0
|
|
51
54
|
import { validateContractDocument } from "skill-family-harness-node";
|
|
52
55
|
|
|
53
56
|
const document = {
|
|
@@ -81,7 +84,7 @@ import {
|
|
|
81
84
|
|
|
82
85
|
v2 机制会重算每个 path-backed output 和 evidence Resource 的真实字节摘要,并拒绝重复 Resource id、correlation 漂移、Task digest 变化,以及缺失或错配的 evidence binding。它不执行领域审计,不选择 method,不编排重试,也不拥有生命周期状态。
|
|
83
86
|
|
|
84
|
-
该子路径公开但**不稳定**,后续小版本可以修改或移除。使用 v2 时应精确锁定 `0.
|
|
87
|
+
该子路径公开但**不稳定**,后续小版本可以修改或移除。使用 v2 时应精确锁定 `0.4.0`;仍生产 candidate v1 交换的接入必须继续精确锁定 `0.2.1`。
|
|
85
88
|
|
|
86
89
|
## 典型使用场景
|
|
87
90
|
|
|
@@ -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
|
-
|
|
5
|
-
|
|
6
|
-
digestDocument,
|
|
6
|
+
invokeFoundationMechanism,
|
|
7
|
+
verifyManagedBundleIdentity,
|
|
7
8
|
} from "./quickstart-profile.mjs";
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
const CLI_NAME = "mechanisms-cli.mjs";
|
|
11
|
+
|
|
12
|
+
async function readRequest(input) {
|
|
10
13
|
const chunks = [];
|
|
11
|
-
for await (const chunk of
|
|
12
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
20
|
-
result =
|
|
21
|
-
} else if (request
|
|
22
|
-
result =
|
|
23
|
-
} else if (request
|
|
24
|
-
result = await
|
|
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
|
-
|
|
129
|
+
result = await invoke(request);
|
|
30
130
|
}
|
|
31
|
-
|
|
131
|
+
output.write(`${JSON.stringify(result)}\n`);
|
|
32
132
|
return 0;
|
|
33
133
|
} catch (cause) {
|
|
34
|
-
|
|
134
|
+
error.write(`${JSON.stringify(errorResponse(cause))}\n`);
|
|
35
135
|
return 2;
|
|
36
136
|
}
|
|
37
137
|
}
|
|
38
138
|
|
|
39
|
-
|
|
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
|
}
|