@dsh-enhanced/plugin-control-plane 0.1.7 → 0.1.12

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 (67) hide show
  1. package/README.md +153 -32
  2. package/bin/dsh-local-release-adapter.js +1381 -0
  3. package/cordis.patch.yml +1 -0
  4. package/lib/approval.d.ts +13 -0
  5. package/lib/approval.d.ts.map +1 -0
  6. package/lib/approval.js +79 -0
  7. package/lib/approval.js.map +1 -0
  8. package/lib/attestation.d.ts +14 -0
  9. package/lib/attestation.d.ts.map +1 -0
  10. package/lib/attestation.js +222 -0
  11. package/lib/attestation.js.map +1 -0
  12. package/lib/catalog-interpreter.d.ts +12 -0
  13. package/lib/catalog-interpreter.d.ts.map +1 -0
  14. package/lib/catalog-interpreter.js +100 -0
  15. package/lib/catalog-interpreter.js.map +1 -0
  16. package/lib/catalog.d.ts +95 -10
  17. package/lib/catalog.d.ts.map +1 -1
  18. package/lib/catalog.js +1031 -18
  19. package/lib/catalog.js.map +1 -1
  20. package/lib/cli.d.ts +9 -0
  21. package/lib/cli.d.ts.map +1 -1
  22. package/lib/cli.js +1160 -162
  23. package/lib/cli.js.map +1 -1
  24. package/lib/host-attestor.d.ts +13 -0
  25. package/lib/host-attestor.d.ts.map +1 -0
  26. package/lib/host-attestor.js +139 -0
  27. package/lib/host-attestor.js.map +1 -0
  28. package/lib/index.d.ts +9 -0
  29. package/lib/index.d.ts.map +1 -1
  30. package/lib/index.js +9 -0
  31. package/lib/index.js.map +1 -1
  32. package/lib/lockfile.d.ts +7 -0
  33. package/lib/lockfile.d.ts.map +1 -0
  34. package/lib/lockfile.js +271 -0
  35. package/lib/lockfile.js.map +1 -0
  36. package/lib/release.d.ts +51 -0
  37. package/lib/release.d.ts.map +1 -0
  38. package/lib/release.js +1188 -0
  39. package/lib/release.js.map +1 -0
  40. package/lib/service.d.ts +9 -11
  41. package/lib/service.d.ts.map +1 -1
  42. package/lib/service.js +57 -29
  43. package/lib/service.js.map +1 -1
  44. package/lib/sqlite.d.ts +9 -0
  45. package/lib/sqlite.d.ts.map +1 -0
  46. package/lib/sqlite.js +705 -0
  47. package/lib/sqlite.js.map +1 -0
  48. package/lib/store.d.ts +258 -0
  49. package/lib/store.d.ts.map +1 -0
  50. package/lib/store.js +1848 -0
  51. package/lib/store.js.map +1 -0
  52. package/lib/tools.d.ts.map +1 -1
  53. package/lib/tools.js +23 -3
  54. package/lib/tools.js.map +1 -1
  55. package/lib/trust.d.ts +79 -0
  56. package/lib/trust.d.ts.map +1 -0
  57. package/lib/trust.js +477 -0
  58. package/lib/trust.js.map +1 -0
  59. package/lib/types.d.ts +740 -0
  60. package/lib/types.d.ts.map +1 -0
  61. package/lib/types.js +2 -0
  62. package/lib/types.js.map +1 -0
  63. package/lib/version.d.ts +1 -1
  64. package/lib/version.d.ts.map +1 -1
  65. package/lib/version.js +1 -1
  66. package/lib/version.js.map +1 -1
  67. package/package.json +2 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @dsh-enhanced/plugin-control-plane
2
2
 
3
- 用于按能力发现、审批、隔离验证和原子启用 DSH bundle 的控制面。它把“Agent 发现缺口”与“修改正在运行的 profile / 源码”严格分开。
3
+ 记录能力缺口与 ROI、匹配 owner 固定的 catalog,并在权威审批后执行可恢复的隔离激活。Agent 只能发现候选、记录缺口和创建计划;签名审批、profile 变更和 Host attestation CLI 都不会注册成模型工具。
4
4
 
5
5
  ## 安装
6
6
 
@@ -9,55 +9,176 @@ dsh plugin --profile web add @dsh-enhanced/plugin-control-plane
9
9
  dsh --profile web --dump-config
10
10
  ```
11
11
 
12
- ## 配置与使用
12
+ 插件服务读取配置中的 `catalogPath`、`statePath` 和 `trustPath`。owner CLI 固定从 `$DSH_HOME/plugin-control/trust.json` 读取信任配置;`--trust`、`--state`、`--dsh-home`、公钥、authority、key id、attestor path 等命令参数都会被拒绝。trust 文件必须是 canonical、owner-owned `0600` 普通文件,其目录必须是 owner-owned `0700`,不能经过符号链接。
13
13
 
14
- 首次使用无需先下载目录:若默认路径 `~/.dsh/plugin-control/catalog.json` 不存在,运行时会使用包内的首方、只读、完整性固定目录(coding provider、health、heartbeat、event triggers、Memory/Wiki bridge、Lark 与 supervised evolution)。该目录固定到已发布的 npm `0.1.3` tarball,不是浮动的 latest 查询,也不会由 Agent 更新。
15
-
16
- owner 可在默认路径放置自己的 catalog;它会完全取代首方目录。每条记录都需要精确 npm 版本、`sha512-...` 完整性、精确 DSH baseline、能力标签和权限摘要。`requires` 可声明必须一同启用的顶层 bundle,例如 Lark channel 的 Delivery 与 credential bundle:
14
+ 基础 Host attestation 部署可使用 trust schema v2;启用 source release lane 时使用 schema v4,并额外配置 owner release-authorization 公钥、owner catalog/registry 以及八个 release adapter。每个 adapter 都固定 canonical executable/interpreter path、SHA-256、receipt authority/key、超时和唯一的 phase-specific config 环境变量,例如 DSH_RELEASE_PR_CONFIG。下面保留 Host 配置示例:
17
15
 
18
16
  ```json
19
17
  {
20
- "schemaVersion": 1,
21
- "entries": [{
22
- "id": "memory-wiki-bridge",
23
- "capabilities": ["memory knowledge promotion"],
24
- "package": "@dsh-enhanced/memory-wiki-bridge",
25
- "version": "0.1.3",
26
- "integrity": "sha512-REPLACE_WITH_NPM_DIST_INTEGRITY",
27
- "requires": [],
28
- "authorities": ["filesystem: DSH home only"],
29
- "dshBaseline": "0.1.0-rc.8"
30
- }]
18
+ "schemaVersion": 2,
19
+ "installationId": "018f4f6e-7b21-7cc8-9235-8b1c4e6d9f00",
20
+ "dshHome": "/srv/dsh",
21
+ "ledger": {
22
+ "id": "018f4f6e-7b21-7cc8-9235-8b1c4e6d9f01",
23
+ "path": "/srv/dsh/plugin-control/plans/control.sqlite"
24
+ },
25
+ "executor": {
26
+ "id": "dsh",
27
+ "version": "0.1.0-rc.8",
28
+ "path": "/usr/local/bin/dsh",
29
+ "sha256": "64-hex",
30
+ "environmentAllowlist": ["PATH"]
31
+ },
32
+ "hostPolicy": {
33
+ "readinessMinimumChecks": 2,
34
+ "effectBlockedMinimumDeliveryAttempts": 2,
35
+ "effectBlockedMinimumToolExecutionAttempts": 2,
36
+ "shadowMinimumSamples": 20,
37
+ "shadowMaximumMismatches": 0,
38
+ "canaryMinimumSamples": 5,
39
+ "canaryMaximumFailures": 0,
40
+ "soakMinimumWindowMs": 300000,
41
+ "soakMinimumSamples": 50,
42
+ "soakMaximumFailureRate": 0.01,
43
+ "healthMinimumChecks": 3,
44
+ "healthMaximumFailures": 0,
45
+ "receiptTtlMs": 30000
46
+ },
47
+ "hostAttestor": {
48
+ "id": "production-host-attestor",
49
+ "version": "1.0.0",
50
+ "path": "/usr/local/libexec/dsh-host-attestor",
51
+ "sha256": "64-hex",
52
+ "interpreter": null,
53
+ "environmentAllowlist": [],
54
+ "authority": "host-runtime",
55
+ "keyId": "host-key-1",
56
+ "timeoutMs": 60000
57
+ },
58
+ "approvalKeys": [
59
+ { "authority": "owner-policy", "keyId": "owner-key-1", "publicKeyPem": "-----BEGIN PUBLIC KEY-----..." }
60
+ ],
61
+ "hostAttestationKeys": [
62
+ { "authority": "host-runtime", "keyId": "host-key-1", "publicKeyPem": "-----BEGIN PUBLIC KEY-----..." }
63
+ ]
31
64
  }
32
65
  ```
33
66
 
34
- Agent 可调用 `plugin_discover` 自动查找候选项,或用 `plugin_activation_plan` 生成**只读待审批计划**。两个工具都不会下载、安装、修改或重启任何东西。
67
+ `hostAttestor` 可以为 `null`。这种部署只能走人工 attestation,不会自签或自动越过任何 `awaiting-*` 状态。旧 trust schema v1 仍可读取,但被规范化成保守的默认 `hostPolicy` 且不配置可执行 attestor,因此也是 manual-only。
68
+
69
+ Control Plane 只保存 Ed25519 公钥,不读取、接收、生成或持有 Host attestation / release 私钥。
70
+
71
+ ## 能力闭环
72
+
73
+ Agent 工具:
35
74
 
36
- owner 在审阅完整 package/version/integrity/authority 后,才可使用不向 Agent 注册的本地 CLI:
75
+ - `plugin_capability_gap`:用幂等键记录能力缺口、上下文、价值、频率、成本和风险。
76
+ - `plugin_gap_rankings`:读取按 ROI 排序的开放缺口。
77
+ - `plugin_discover`:只读匹配 owner-provided、完整性固定的 catalog。
78
+ - `plugin_activation_plan`:为一个精确 gap/candidate/profile 创建不可变、待审批计划,不安装任何内容。
79
+
80
+ 计划、审批、phase operation、签名 receipt 和终态 receipt 都写入 owner-private SQLite。幂等键、revision CAS、activation id 和递增 fence 共同阻止旧 worker、ABA 和跨计划重放。
81
+
82
+ ## 审批和 staging
83
+
84
+ 审批系统针对 `show` 返回的精确 plan id/digest 生成 Ed25519 receipt,然后由 owner 应用:
37
85
 
38
86
  ```sh
39
- dsh-plugin-control discover --capability 'knowledge promotion'
40
- dsh-plugin-control approve --plan ~/.dsh/plugin-control/plans/plugin-....json --approved-by owner@example
41
- dsh-plugin-control activate --plan ~/.dsh/plugin-control/plans/plugin-....json --dsh-home ~/.dsh
87
+ dsh-plugin-control show --plan-id plugin-...
88
+ dsh-plugin-control approve --kind activation \
89
+ --plan-id plugin-... --expected-revision 1 \
90
+ --approval-receipt ./owner-receipt.json
91
+ dsh-plugin-control activate \
92
+ --plan-id plugin-... --expected-revision 2
42
93
  ```
43
94
 
44
- `activate` 先核对当前 DSH 精确版本,再复制 profile 到隔离 staging profile,安装候选和全部 `requires` 的精确版本、核对 pnpm lock 中每个完整性、执行 `dsh --dump-config`,然后通过同一父目录内的 rename 原子替换目标 profile。替换后的最终组合校验失败会自动恢复原 profile;成功后仍由 owner 使用 `scripts/install/restart.sh` 重启常驻服务。
95
+ `activate` 只完成 staging:固定 DSH executable 的 canonical path、owner/root ownership、不可被 group/other 写入、inode 和 SHA-256;用无 shell 的 argv 安装 dossier 中精确 `package@version`;结构化核对 lockfile integrity;保留原 profile backup;最后停在 `awaiting-reload`。
96
+
97
+ ## 固定 Host attestor 执行契约
45
98
 
46
- 新建或修改插件绝不在生产 checkout 中进行:
99
+ 配置 `hostAttestor` 后,每个 awaited phase 由 owner CLI 单步推进:
47
100
 
48
101
  ```sh
49
- dsh-plugin-control scaffold --owner-approved --repository ../dsh-enhanced-feature-worktree --name my-plugin
50
- dsh-plugin-control verify-worktree --owner-approved --repository ../dsh-enhanced-feature-worktree
102
+ dsh-plugin-control probe \
103
+ --plan-id plugin-... --expected-revision 4 --expected-fence 1
51
104
  ```
52
105
 
53
- 两者只接受 linked Git worktree,创建要求干净 worktree;验证运行 `git diff --check` 与 `pnpm check`。之后仍需正常 code review、PR、发布和上述启用流程。
106
+ phase 不能从命令行指定,而是从 durable plan 状态推导。Control Plane 先提交唯一的 phase operation,再执行固定 executable:
107
+
108
+ 1. 校验 canonical path、权限、owner/root ownership、单链接、inode 和 SHA-256。脚本还必须使用无参数的 canonical shebang,并在 trust 中固定 interpreter path/digest;native executable 的 `interpreter` 必须为 `null`。
109
+ 2. 以严格 allowlist 环境、`shell: false` 调用 `--version`,结果必须等于 trust 中固定版本。
110
+ 3. 以同样边界调用 `attest`,在 stdin 传入一个精确 JSON request;stdout 只能返回一个有界 JSON receipt,stderr 不回显。
111
+ 4. 再次校验 executable inode 和 digest。
112
+ 5. 使用 trust 中预注册的 Ed25519 公钥验证 receipt,并以 plan revision/fence CAS 应用。
113
+
114
+ request 固定:installation id、ledger id/path、plan id/digest、activation id/fence、profile name/path、attestor identity/path/digest/key、phase、phase requirements、receipt TTL,以及一个 durable operation id。外部 attestor 必须永久把 operation id 当幂等键:相同 id + 相同 request 重放同一 receipt;相同 id + 不同 request 必须拒绝。
115
+
116
+ phase operation 在子进程启动前持久化。子进程执行期间持有 SQLite 跨进程 writer mutex;成功 receipt 在释放 mutex 前持久化。因此并发 worker 不会创建第二个 canary exposure。若进程在 receipt 提交前崩溃,恢复 worker 使用相同 operation id 重试,依赖上述外部幂等契约取回同一结果。
117
+
118
+ ## Phase proof,而不是命令标签
119
+
120
+ 退出码、命令名称和 `--dump-config` 都不构成 phase 成功证据。v2 receipt 对完整的结构化 evidence 签名,并绑定 request digest:
121
+
122
+ - `reload`:前一代和新一代 Host generation、新 profile 的 reload 证明。
123
+ - `readiness`:实际检查数和失败数。
124
+ - `effect-blocked-replay`:delivery 尝试/拦截数、tool-execution 尝试/拦截数以及外部 effect 数;通过必须同时证明两类 effect 全部被拦截且 external effects 为零。
125
+ - `shadow`:样本数、mismatch 数和 external effects。
126
+ - `canary`:唯一 exposure id、严格一次 exposure、样本数和失败数。
127
+ - `soak`:明确的窗口起止、样本、失败数和 owner policy 的失败率阈值。
128
+ - `health`:实际健康检查数和失败数。
129
+
130
+ 每类 evidence 还带有探针/回放/trace digest。Control Plane 验证签名、结构、请求绑定、TTL 和 policy 阈值;它不会假装自己能独立观察部署。真正的 reload、流量、effect interception 和健康观测由 owner/deployment-controlled attestor 实现,并由其私钥为声明负责。测试目录中的 fixture attestor 只用于真实子进程集成测试,不进入发布包,也不是生产探针。
131
+
132
+ 任一有效签名 receipt 返回 `outcome: failed` 时,计划进入 fenced `rollback-pending` 并自动恢复原 profile;只有七个 phase 全部通过,backup 清理和终态 CAS 完成后才是 `activated`。格式错误、错误 key/digest/phase/evidence、过期 receipt 或未配置 attestor 都保持当前 awaiting 状态。
133
+
134
+ ## 人工 Host attestation
135
+
136
+ 未配置可执行 attestor,或部署需要人工控制时,先生成同一个 durable request:
137
+
138
+ ```sh
139
+ dsh-plugin-control host-request \
140
+ --plan-id plugin-... --expected-revision 4 --expected-fence 1 \
141
+ > host-request.json
142
+ ```
143
+
144
+ owner-controlled 外部系统执行 request、产生相同 v2 structured evidence 并签名。receipt 文件必须是私有普通文件,然后应用:
145
+
146
+ ```sh
147
+ dsh-plugin-control attest \
148
+ --plan-id plugin-... --expected-revision 4 --expected-fence 1 \
149
+ --receipt ./host-receipt.json
150
+ ```
151
+
152
+ 人工路径使用相同 operation、evidence validator、Ed25519 verifier 和 CAS,不是弱化旁路。旧的 schema-v1 `evidenceDigest`-only Host receipt 会被拒绝,因为它不能证明 phase 语义。
153
+
154
+ ## 源码能力 lane 和边界
155
+
156
+ `source-plan` / `scaffold` 只在 owner 审批的 linked、clean worktree 和固定 generator digest 上生成插件并运行 `pnpm check`。local checks 使用临时 Git index 对 exact scope 计算 staged tree/patch digest,不污染工作树的真实 index。owner 必须在 checks 之后为 exact source digests、scope 和 release policy 签发独立 authorization,随后才能执行 `release-start`。
157
+
158
+ owner 可以用 `release-request` 导出当前 durable phase request、用 `release-step` 调用已固定 adapter 并应用 receipt,或用 `release-attest` 应用 owner-controlled 外部系统生成的同协议 receipt。phase 不能由调用者选择,而由 durable source plan 状态决定。publish 超时等不确定结果必须先进入 `publish-ambiguous`,再由独立 registry verifier 的签名 reconciliation receipt 决定继续验证、以新 fence 重试,或 fail closed。
159
+
160
+ 随包发布的 `bin/dsh-local-release-adapter.js` 是 local-only 的通用参考 adapter;trust 中每个 phase 必须安装为不同 canonical 文件/inode,并使用不同 adapter id、authority 与 receipt key;脚本副本可以共享同一个固定、只读的 Node interpreter。各副本的 owner-private config 还应给出不同 state directory。它实现:
161
+
162
+ - local bare Git remote 上的 immutable PR ref、由 owner-private exact review decision 驱动的独立 review receipt,以及 target-ref compare-and-swap merge;
163
+ - 从 exact merge commit 做至少两次独立 checkout,并分别复制为新的可写 sandbox workspace;owner 配置固定 Linux bubblewrap、Node、pnpm runtime tree、离线 store 与 tar executable 的 canonical path/摘要。sandbox 使用空 HOME/tmp、无网络的新 user/mount/PID namespace,固定执行 `pnpm install --offline --frozen-lockfile --ignore-scripts --package-import-method=copy`、目标包 `build` 与 `pnpm pack`,最终 artifact 直接采用 package manager pack lifecycle/packlist 生成的 tarball,再生成 CycloneDX SBOM 和 SLSA provenance;
164
+ - 独立 signer 对 exact artifact statement 签名;
165
+ - local filesystem registry 的 package/version immutable publication;
166
+ - 在独立 download root 复制并重新验证 registry bytes;
167
+ - 复用 Control Plane catalog helper 执行 request-bound before/after digest CAS admission。
54
168
 
55
- ## 权限与数据
169
+ adapter 的 stdout 只有一个签名 JSON receipt,stderr 不打印 request 或 secret;它还会用 config 中固定的 release-authorization 公钥重新验签。每个 phase 在 owner-private state directory 永久绑定 operationId + requestDigest:完全相同请求重放同一 receipt,同 id 不同 payload 拒绝。`registry-verify` 副本还实现 `reconcile`,同时核对 immutable tarball 和 publication record,并用自己的独立 key 签发 `exists-match` / `absent` / `unknown` / `digest-conflict` evidence。该参考实现不访问网络,也不等同于 GitHub/npm adapter;需要远端 PR/registry 的部署应提供遵循相同 request/receipt 与幂等协议的 owner adapter。
56
170
 
57
- - 运行时 plugin 只读取 owner 配置的本地 catalog,并在 `statePath` 写入受限的待审批 plan;无网络、凭据、浏览器或子进程权限。
58
- - 本地 CLI 的 `activate` 才会调用 `dsh`、复制/rename profile;它需要 owner 明确执行,且不暴露为 Agent tool。CLI 不读取或输出凭据。
59
- - `scaffold` / `verify-worktree` 只在 owner 传入 `--owner-approved` 的 linked Git worktree 中运行 pnpm/git;它们不会改动主 checkout、生产 profile 或已发布包。
171
+ ## 权限
60
172
 
61
- ## 兼容性
173
+ - 插件 Host service:读取 catalog/trust,写 owner-private SQLite/WAL;不使用网络、浏览器或子进程。
174
+ - owner CLI `activate`:读取/复制/rename/恢复 DSH profile,并执行固定 DSH executable。
175
+ - owner CLI `probe`:执行固定 Host attestor,只有严格 allowlist 环境;不读取 attestation 私钥,不使用 shell或网络客户端。
176
+ - owner CLI `scaffold`:仅在审批绑定的 linked worktree 中运行固定边界内的 `git` / `pnpm`。
177
+ - owner CLI release 命令:读取 owner-private release authorization 或人工签名 receipt,写 release operation SQLite 状态,并只执行 trust 中固定的 adapter executable;publish reconciliation 只接受独立 registry verifier 的签名 receipt,不接受裸 observation。
178
+ - local release adapter:读取一个 allowlisted、按 phase 命名的配置路径(例如 DSH_RELEASE_PR_CONFIG;连字符转换为下划线);该配置及其目录、每个 phase 的 Ed25519 私钥、release-authorization 公钥和 state directory 必须 owner-owned private。按 phase 可执行 owner 固定 SHA-256 的 local Git、Node、pnpm、tar 和 bubblewrap executable,读 approved repository/worktree 与继承的只读 artifact/SBOM/provenance fd,写 local bare Git remote、review store、isolated build root、immutable file registry、独立 download root 和 owner catalog。它不内置 key、token、credential、remote URL 或任意 shell command,也不使用 shell、浏览器或网络;依赖安装禁用 lifecycle scripts,只有 owner 固定的目标包 build/pack lifecycle 会执行。
179
+ - build adapter 不接受调用方或通用 config 注入任意命令/argv;它只运行固定的 offline frozen install、package build 与 `pnpm pack` 流程。pnpm runtime tree 必须在根目录提供 config 分别固定的 `node` 与 `pnpm` 原生 executable;整棵 runtime tree 和离线 store 再以 canonical owner/root-owned、非 group/world-writable 的递归 inventory digest 固定并只读挂载,因此不依赖宿主 `PATH` 中是否存在 Node。每轮只给 disposable workspace 与 pack output 写权限。私钥路径与 config path 不出现在 durable request。生产部署应为 PR/review、review/merge、build/sign、sign/publish 和 publish/registry-verify 配置独立 executable identity、进程状态目录及 signing authority/key。
180
+ - Linux local adapter 对 Git、tar、bubblewrap 及 catalog helper/interpreter 保持 `O_NOFOLLOW` 已验证 descriptor,并通过 `/proc/self/fd` 执行;bubblewrap 的 toolchain/store/workspace/output 也从已打开目录 descriptor 挂载。缺少 Linux `/proc/self/fd` 时 fail closed。catalog helper 在独立 pinned Node 子进程中运行,不会把 mutable helper pathname 动态 import 到签名进程。
181
+ - catalog admission 使用同一文件系统的 `O_TMPFILE`、固定系统入口 `/usr/bin/python3` 安全解析出的 Python 3.8+ canonical target,以及跨目录 `renameat2(RENAME_EXCHANGE)` 提交和可验证反向交换。它不查询 `PATH`:入口、canonical target 及目录链必须 root-owned 且不可被 group/other 写,target 以 `O_NOFOLLOW` 打开并通过保留 descriptor 执行,执行前后复验 inode、时间戳与 SHA-256。父目录 descriptor 上的内核 `flock` 覆盖整个事务且随进程崩溃释放;每次 exchange 的确定性私有目录、before/desired/stage inode 与摘要先写入并 fsync 到 request-bound v2 journal。broker 不执行 pathname cleanup,无法归类的文件原样保留供人工 reconcile。缺少 Linux procfs、`O_TMPFILE`、`renameat2`、`flock` 或安全兼容的 interpreter 时 fail closed。Unix 文件 mode 不能隔离持续恶意的同 UID 进程;生产部署必须使用独立 UID 的 commit broker,或确保 worker 对 catalog 父目录无写权限。
182
+ - local artifact activation 在安装期间持续持有已验证 cache inode,并把 `/proc/<control-plane-pid>/fd/<n>` reference 交给 DSH;registered DSH executor 及其解释器也从已验证 descriptor 启动。该路径是 Linux-only,且不会把 `release-complete` 视为 activation。
62
183
 
63
- See the repository [compatibility baseline](../../docs/compatibility.md).
184
+ 兼容性见仓库 [compatibility baseline](../../docs/compatibility.md)。Node.js 要求 `^22.19.0 || >=24.0.0`(使用 `node:sqlite`)。