@dsh-enhanced/plugin-control-plane 0.1.48 → 0.1.49

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 (167) hide show
  1. package/README.md +183 -15
  2. package/bin/dsh-live-qualification-authority.js +15 -0
  3. package/bin/dsh-local-release-adapter.js +328 -8
  4. package/bin/dsh-systemd-host-attestor.js +359 -9
  5. package/bin/dsh-systemd-host-authority.js +12 -0
  6. package/lib/adoption-coordinator.d.ts +3 -1
  7. package/lib/adoption-coordinator.d.ts.map +1 -1
  8. package/lib/adoption-coordinator.js +24 -9
  9. package/lib/adoption-coordinator.js.map +1 -1
  10. package/lib/cli.d.ts.map +1 -1
  11. package/lib/cli.js +33 -14
  12. package/lib/cli.js.map +1 -1
  13. package/lib/creation-capability-feedback.d.ts +23 -0
  14. package/lib/creation-capability-feedback.d.ts.map +1 -0
  15. package/lib/creation-capability-feedback.js +132 -0
  16. package/lib/creation-capability-feedback.js.map +1 -0
  17. package/lib/creation-capability-journal.d.ts +66 -0
  18. package/lib/creation-capability-journal.d.ts.map +1 -0
  19. package/lib/creation-capability-journal.js +751 -0
  20. package/lib/creation-capability-journal.js.map +1 -0
  21. package/lib/creation-capability-runtime.d.ts +63 -0
  22. package/lib/creation-capability-runtime.d.ts.map +1 -0
  23. package/lib/creation-capability-runtime.js +564 -0
  24. package/lib/creation-capability-runtime.js.map +1 -0
  25. package/lib/creation-capability-source.d.ts +37 -0
  26. package/lib/creation-capability-source.d.ts.map +1 -0
  27. package/lib/creation-capability-source.js +328 -0
  28. package/lib/creation-capability-source.js.map +1 -0
  29. package/lib/creation-capability-types.d.ts +252 -0
  30. package/lib/creation-capability-types.d.ts.map +1 -0
  31. package/lib/creation-capability-types.js +2 -0
  32. package/lib/creation-capability-types.js.map +1 -0
  33. package/lib/deployment-readiness.d.ts +16 -0
  34. package/lib/deployment-readiness.d.ts.map +1 -1
  35. package/lib/deployment-readiness.js +48 -1
  36. package/lib/deployment-readiness.js.map +1 -1
  37. package/lib/effect-blocked-replay.js +2 -2
  38. package/lib/effect-blocked-replay.js.map +1 -1
  39. package/lib/foreground-deployment-runtime.d.ts +3 -0
  40. package/lib/foreground-deployment-runtime.d.ts.map +1 -1
  41. package/lib/foreground-deployment-runtime.js +55 -13
  42. package/lib/foreground-deployment-runtime.js.map +1 -1
  43. package/lib/foreground-deployment.d.ts.map +1 -1
  44. package/lib/foreground-deployment.js +5 -0
  45. package/lib/foreground-deployment.js.map +1 -1
  46. package/lib/host-attestor.d.ts +2 -0
  47. package/lib/host-attestor.d.ts.map +1 -1
  48. package/lib/host-attestor.js +8 -1
  49. package/lib/host-attestor.js.map +1 -1
  50. package/lib/host-inputs.d.ts +13 -0
  51. package/lib/host-inputs.d.ts.map +1 -0
  52. package/lib/host-inputs.js +162 -0
  53. package/lib/host-inputs.js.map +1 -0
  54. package/lib/host-maintenance.d.ts +61 -0
  55. package/lib/host-maintenance.d.ts.map +1 -0
  56. package/lib/host-maintenance.js +158 -0
  57. package/lib/host-maintenance.js.map +1 -0
  58. package/lib/host-readiness.d.ts +5 -0
  59. package/lib/host-readiness.d.ts.map +1 -0
  60. package/lib/host-readiness.js +22 -0
  61. package/lib/host-readiness.js.map +1 -0
  62. package/lib/index.d.ts +16 -0
  63. package/lib/index.d.ts.map +1 -1
  64. package/lib/index.js +7 -0
  65. package/lib/index.js.map +1 -1
  66. package/lib/live-qualification-authority.d.ts +32 -0
  67. package/lib/live-qualification-authority.d.ts.map +1 -0
  68. package/lib/live-qualification-authority.js +280 -0
  69. package/lib/live-qualification-authority.js.map +1 -0
  70. package/lib/live-qualification-client.d.ts +4 -0
  71. package/lib/live-qualification-client.d.ts.map +1 -0
  72. package/lib/live-qualification-client.js +22 -0
  73. package/lib/live-qualification-client.js.map +1 -0
  74. package/lib/live-qualification-runtime.d.ts +78 -0
  75. package/lib/live-qualification-runtime.d.ts.map +1 -0
  76. package/lib/live-qualification-runtime.js +367 -0
  77. package/lib/live-qualification-runtime.js.map +1 -0
  78. package/lib/live-qualification.d.ts +73 -0
  79. package/lib/live-qualification.d.ts.map +1 -0
  80. package/lib/live-qualification.js +164 -0
  81. package/lib/live-qualification.js.map +1 -0
  82. package/lib/owner-task-gaps.d.ts +2 -0
  83. package/lib/owner-task-gaps.d.ts.map +1 -1
  84. package/lib/owner-task-gaps.js +9 -1
  85. package/lib/owner-task-gaps.js.map +1 -1
  86. package/lib/runtime-epoch.d.ts +69 -0
  87. package/lib/runtime-epoch.d.ts.map +1 -0
  88. package/lib/runtime-epoch.js +139 -0
  89. package/lib/runtime-epoch.js.map +1 -0
  90. package/lib/runtime-observer.d.ts.map +1 -1
  91. package/lib/runtime-observer.js +42 -6
  92. package/lib/runtime-observer.js.map +1 -1
  93. package/lib/service.d.ts +247 -4
  94. package/lib/service.d.ts.map +1 -1
  95. package/lib/service.js +1332 -27
  96. package/lib/service.js.map +1 -1
  97. package/lib/source-adoption-authority.d.ts +3 -0
  98. package/lib/source-adoption-authority.d.ts.map +1 -1
  99. package/lib/source-adoption-authority.js +13 -3
  100. package/lib/source-adoption-authority.js.map +1 -1
  101. package/lib/source-adoption-runner.d.ts +3 -0
  102. package/lib/source-adoption-runner.d.ts.map +1 -1
  103. package/lib/source-adoption-runner.js +16 -4
  104. package/lib/source-adoption-runner.js.map +1 -1
  105. package/lib/source-baseline.d.ts +37 -0
  106. package/lib/source-baseline.d.ts.map +1 -0
  107. package/lib/source-baseline.js +250 -0
  108. package/lib/source-baseline.js.map +1 -0
  109. package/lib/source-build.d.ts +17 -1
  110. package/lib/source-build.d.ts.map +1 -1
  111. package/lib/source-build.js +501 -7
  112. package/lib/source-build.js.map +1 -1
  113. package/lib/source-context.d.ts +18 -0
  114. package/lib/source-context.d.ts.map +1 -1
  115. package/lib/source-context.js +85 -11
  116. package/lib/source-context.js.map +1 -1
  117. package/lib/source-creation.d.ts +106 -0
  118. package/lib/source-creation.d.ts.map +1 -0
  119. package/lib/source-creation.js +664 -0
  120. package/lib/source-creation.js.map +1 -0
  121. package/lib/source-job-types.d.ts +19 -0
  122. package/lib/source-job-types.d.ts.map +1 -1
  123. package/lib/source-jobs.d.ts +30 -3
  124. package/lib/source-jobs.d.ts.map +1 -1
  125. package/lib/source-jobs.js +382 -40
  126. package/lib/source-jobs.js.map +1 -1
  127. package/lib/source-maintenance.d.ts +66 -0
  128. package/lib/source-maintenance.d.ts.map +1 -0
  129. package/lib/source-maintenance.js +177 -0
  130. package/lib/source-maintenance.js.map +1 -0
  131. package/lib/source-revision.d.ts +57 -0
  132. package/lib/source-revision.d.ts.map +1 -0
  133. package/lib/source-revision.js +175 -0
  134. package/lib/source-revision.js.map +1 -0
  135. package/lib/source-workspace.d.ts +19 -14
  136. package/lib/source-workspace.d.ts.map +1 -1
  137. package/lib/source-workspace.js +90 -17
  138. package/lib/source-workspace.js.map +1 -1
  139. package/lib/sqlite.d.ts +13 -3
  140. package/lib/sqlite.d.ts.map +1 -1
  141. package/lib/sqlite.js +362 -1
  142. package/lib/sqlite.js.map +1 -1
  143. package/lib/store.d.ts +258 -3
  144. package/lib/store.d.ts.map +1 -1
  145. package/lib/store.js +2211 -95
  146. package/lib/store.js.map +1 -1
  147. package/lib/systemd-host-authority.d.ts +68 -0
  148. package/lib/systemd-host-authority.d.ts.map +1 -0
  149. package/lib/systemd-host-authority.js +424 -0
  150. package/lib/systemd-host-authority.js.map +1 -0
  151. package/lib/task-observation-evidence.d.ts +32 -0
  152. package/lib/task-observation-evidence.d.ts.map +1 -0
  153. package/lib/task-observation-evidence.js +62 -0
  154. package/lib/task-observation-evidence.js.map +1 -0
  155. package/lib/task-observation-runtime.d.ts +2 -3
  156. package/lib/task-observation-runtime.d.ts.map +1 -1
  157. package/lib/task-observation-runtime.js +7 -39
  158. package/lib/task-observation-runtime.js.map +1 -1
  159. package/lib/task-observation-store.js +1 -1
  160. package/lib/trust.d.ts.map +1 -1
  161. package/lib/trust.js +0 -0
  162. package/lib/trust.js.map +1 -1
  163. package/lib/types.d.ts +43 -6
  164. package/lib/types.d.ts.map +1 -1
  165. package/lib/version.d.ts +1 -1
  166. package/lib/version.js +1 -1
  167. package/package.json +21 -14
package/README.md CHANGED
@@ -4,6 +4,8 @@
4
4
 
5
5
  可选 `runtimeObserver` 提供 owner-only、HMAC 认证的本地 Unix socket,读取实际 Loader/Fiber 与服务归属;socket、连接和密钥缓冲区由 Cordis 注入 Fiber 管理。该配置会读取私有认证 key 并创建本地 socket,不新增模型工具或签名权限;调用方与 Host 共享受信 owner 身份,不构成同 UID/同进程隔离。详见[配置、权限与证据](../../docs/runtime-observer.md)。
6
6
 
7
+ 运行在提供原生 `appReady` 服务的 Host 内时,插件在 launcher 完成 Loader 激活审计并发出就绪回调后,向 stderr 输出 `dsh-enhanced host ready: v1`;每个 peer 代次最多输出一次,避免污染 headless/ACP 的 stdout 协议流。监听器由 Control Plane 的 Cordis Fiber 管理;没有 `appReady` 的嵌入式 Host 仍可激活,但不会输出此标记。旧版 cohort 可能没有该通知。此标记只表示该 Host 的启动就绪,不证明用户任务或自迭代结果。
8
+
7
9
  ## 安装
8
10
 
9
11
  ```sh
@@ -142,10 +144,12 @@ request 固定:installation id、ledger id/path、plan id/digest、activation
142
144
 
143
145
  Host attestor 与 release adapter 的每次命令共用受控进程组:超时、输出超限及主进程正常/异常退出都会清理同组后代,核对主进程退出,并有界排空 stdout。清理无法证实时返回失败,不以遗留管道的 `close` 无限等待。该机制依赖 runner 存活,不能包含主动 `setsid()` 脱组进程,也不撤回远端已接受的操作;具体期限、恢复边界与回归证据见 [adapter 生命周期](../../docs/control-plane-adapter-lifetime.md)。
144
146
 
145
- 随包的 `bin/dsh-systemd-host-attestor.js`(v5)提供 Linux/systemd 的 **reload、readiness 与物理 rollback** 适配:先用 `probe --prepare-only` 取得确切持久请求,再由主人私有配置授权其摘要;重启前记录操作,重复调用仅重放或观测对账。它核验 fresh InvocationID/MainPID 与稳定窗口,按 installation 共享 Host 代次,reload 推进至 `awaiting-readiness`;readiness 再绑定最新已签重启、实际 Loader/Fiber 与服务实例,多次稳定观测后签名,重复请求不重启 Host。稳定、认证通过且身份匹配的 inactive 候选签为 failed readiness;认证错误或状态漂移不签发回执。rollback 在 CLI 恢复原 profile 文件后证明原 Host 就绪,或原本不存在的 profile 已停服;缺少物理恢复凭证时继续保持 pending。部署配置、权限和未覆盖阶段见 [systemd Host attestor](../../docs/systemd-host-attestor.md)。
147
+ 随包的 `bin/dsh-systemd-host-attestor.js`(v8)提供 Linux/systemd 的 **reload、readiness 与物理 rollback** 适配:可用 schema4 与随包 `dsh-systemd-host-authority` 按安装期有限授权自动生成精确请求配置,或用 `probe --prepare-only` 取得请求后显式配置其摘要;重启前记录操作,重复调用仅重放或观测对账。它核验 fresh InvocationID/MainPID 与稳定窗口,按 installation 共享 Host 代次,reload 推进至 `awaiting-readiness`;readiness 再绑定最新已签重启、实际 Loader/Fiber 与服务实例,多次稳定观测后签名,重复请求不重启 Host。稳定、认证通过且身份匹配的 inactive 候选签为 failed readiness;认证错误或状态漂移不签发回执。rollback 在 CLI 恢复原 profile 文件后证明原 Host 就绪,或原本不存在的 profile 已停服;缺少物理恢复凭证时继续保持 pending。部署配置、权限和未覆盖阶段见 [systemd Host attestor](../../docs/systemd-host-attestor.md)。
146
148
 
147
149
  phase operation 和派发 claim 在子进程启动前持久化。外部执行期间不持有控制面 SQLite 写锁,其他任务可继续写入;同一 operation 的并发或重启调用由持久 claim 拒绝。退出、验签失败或回执丢失后保留 unknown,不自动再次调用通用 attestor。取得原请求的精确签名回执后,用下述 `attest` 对账;未结算的派发也会阻止同计划换代回退,避免旧外部动作与恢复并行。
148
150
 
151
+ 成功部署重启后,目标 Host 在当前 owner 来源保护下登记独立 runtime epoch 请求,由既有协调器 Automation 获取新的签名实例证明。它不重启服务,不改旧 plan、watch 或原始 readiness;新证明到达前的任务不回填。schema 26 为此新增独立记录;schema 27 另保存原 Host 身份签名的维护链,供受管更新后投影当前部署和回滚基线,原计划及验收历史保持不变。维护协议见 [Host 迁移](../../docs/systemd-host-attestor.md#continuity-through-managed-host-maintenance),详细授权、计数与恢复边界见 [重启后的持续观察](../../docs/systemd-host-attestor.md#runtime-continuity-after-restart)。
152
+
149
153
  ## Phase proof,而不是命令标签
150
154
 
151
155
  退出码、命令名称和 `--dump-config` 都不构成 phase 成功证据。v2 receipt 对完整的结构化 evidence 签名,并绑定 request digest:
@@ -220,7 +224,7 @@ sourceBuild:
220
224
 
221
225
  同一基准的多个候选会得到相同下一版本,不提供覆盖已发布版本的权限。后续采用流程须串行推进获准源码基准;现有 registry/catalog 冲突检查继续拒绝版本复用。此选项只准备可区分版本的候选,自动发布和采用需显式启用下述有限授权与执行配置,不会为每次修复发布公共 npm 包。
222
226
 
223
- `sourceBuild.profile` defaults to `standard`, whose existing maximum build timeout is 4 minutes and whose `/tmp` tmpfs is fixed at 32 MiB. An owner may explicitly set `profile: repository` for a full repository `pnpm check`; only that profile permits a timeout up to 30 minutes, memory up to 16 GiB, 16 CPUs, 1024 PIDs, an 8 GiB workspace tmpfs and a 4 GiB `/tmp` tmpfs (default 2 GiB). The repository profile explicitly permits execution from both bounded tmpfs mounts, needed by native build tools and temporary executable test fixtures; the standard profile retains Docker’s default no-exec mounts. The repository profile also fixes `CI=true` and `VITEST_MAX_WORKERS=1` inside the container. The caller cannot select a profile or increase these limits: its timeout is capped by the owner configuration. Cancellation, deadline expiry, output overflow, or Fiber disposal kills the preparation client, waits for archive/build processes, and proves named-container absence before any pending plan is stored. Interrupted builds are never automatically replayed; the optional durable Host lane below records their status and resource identity.
227
+ `sourceBuild.profile` defaults to `standard`, whose existing maximum build timeout is 4 minutes and whose `/tmp` tmpfs is fixed at 32 MiB. An owner may explicitly set `profile: repository` for a full repository `pnpm check`; only that profile permits a timeout up to 30 minutes, memory up to 16 GiB, 16 CPUs, 1024 PIDs, an 8 GiB workspace tmpfs and a 4 GiB `/tmp` tmpfs (default 2 GiB). The repository profile explicitly permits execution from both bounded tmpfs mounts, needed by native build tools and temporary executable test fixtures; the standard profile retains Docker’s default no-exec mounts. The repository profile fixes `CI=true` and sets `VITEST_MAX_WORKERS` from the frozen configured CPUs (floor, clamped to 1–4) inside the container. The caller cannot select a profile or increase these limits: its timeout is capped by the owner configuration. Cancellation, deadline expiry, output overflow, or Fiber disposal kills the preparation client, waits for archive/build processes, and proves named-container absence before any pending plan is stored. Interrupted builds are never automatically replayed; the optional durable Host lane below records their status and resource identity.
224
228
 
225
229
  `repositorySandbox: { seccompPath: /absolute/owner/path/source-builder-seccomp.json }` is a separate repository-only opt-in for the existing nested Bubblewrap integration tests. It requires the approved profile digest and Docker Server `29.4.1/linux/amd64`; other bytes or runtimes fail before candidate execution. It permits additional namespace/mount syscalls, removes Docker's masked/read-only system-path lists, and hides `/sys` behind an empty read-only tmpfs. This expands the outer container's `/proc` visibility and kernel surface; it is not equivalent to Docker's default policy. UID 65534, zero capabilities, no-new-privileges, offline execution, read-only root, and no Host bind mounts remain mandatory. See the [profile provenance and limits](../../scripts/isolation/README.md#nested-sandbox-profile). Omitting this option retains Docker's default system-path restrictions, including in repository mode.
226
230
 
@@ -228,6 +232,16 @@ sourceBuild:
228
232
 
229
233
  完整仓库镜像的 owner 构建脚本见 [source builder](../../scripts/isolation/README.md)。它只传入依赖清单和 lockfile,在联网构建阶段预取依赖;候选源码进入容器时仍禁网、无 Host 挂载。`repository` profile 仅扩大 owner 配置的检查预算,不延长 Growth Driver 的 5 分钟授权。长检查可通过下述持久 Host 任务提交;入队不代表检查通过或源码已改进。
230
234
 
235
+ Host-only `inspectSourceTargets({ repository, baseCommit? })` 返回当前受信源码基线与最多 128 个已提交、可修改插件的名称及可选简短描述,供当前来源的 Growth 选择读取目标。目录仅从 canonical Git 仓库的正规 `plugins/<name>/package.json` blob 形成;保护根、符号链接、submodule、脏工作树和未跟踪目录不进入结果,manifest 非法或超过限制会拒绝整次查询。每个 manifest 最多 16 KiB,合计最多 512 KiB,描述最多 512 UTF-8 字节;`baseCommit` 不匹配当前受信基线时拒绝。目录不授予源码修改、创建、审批或采用权限,后续源码读取与准备仍核对原有来源及基线。
236
+
237
+ 源码检查在离线安装前核对归档输入,并仅按归档内根目录及直接插件/库包的 `bin` 声明,将已在 Git 中标为可执行的现有 bin 文件预设为 `0755`,以匹配固定 pnpm 的链接行为;声明的非可执行文件会被拒绝,尚未生成的 `lib/` bin 文件由构建产生。其余原始输入的内容和权限继续逐次精确核验。
238
+
239
+ 检查实际 tgz 的 manifest 时,控制面从不可变归档推导 pnpm 11.7.0 的出版形式:`packageManager` 和 `pnpm` 字段不入包,`scripts` 仅剔除六个发布生命周期钩子并移到顶层末尾,catalog/workspace 依赖按冻结清单解析;其余字段及对象键顺序须与预期精确一致。
240
+
241
+ Host 可在调用源码检查时单独请求 `capturePack`,从同一次已核验的 tgz 读取中取回最多 32 MiB 的原始制品字节,供后续独立行为验收。容器用有版本的单帧传输;Host 严格核对帧、大小及 SHA-256,并保留原有取消、清理和源码快照栅栏。默认检查不传输制品,持久 evidence 只记录摘要,不保存制品内容;该开关不向候选或模型工具开放。
242
+
243
+ 普通 owner 失败触发的持久创建任务会自动捕获包,并在同一 SQLite 事务中保存字节、pending 计划和任务终态;旧计划与手工来源保持兼容,不因此获得验收资格。schema 30 的私有 BLOB 账本按 SHA-256 去重,限制 256 件、总计 128 MiB,读写均核对真实字节;额度耗尽拒绝提交,不丢弃在用制品。Host-only `inspectPreparedCreation(planId)` 在当前 owner 与 canonical writer fence 内返回绑定的计划、持久任务、真实 Delivery 来源和包;过期、纠正、换 owner、缺包或损坏均拒绝,不向模型状态工具返回正文。现有 Host/CLI 过期 worktree 维护在完成清理后回收 orphan 或仅被已过期计划引用的包;计划与摘要历史保留。这只提供独立观察的交接,创建计划仍不能走旧修改审批、发布或采用;独立验收与有限工具采用另见下文。
244
+
231
245
  ### 持久源码检查任务(可选)
232
246
 
233
247
  Growth Driver 设置 `pluginSourceProposals.preparationMode: durable` 后,`plugin_source_prepare` 只提交任务,`plugin_source_job_status` 回读当前 owner 的状态。控制面还必须配置独立于模型回合的有限 Host 授权:
@@ -250,6 +264,26 @@ sourceJobs:
250
264
 
251
265
  任务先冻结完整 Delivery v2 回执、trust 摘要、gap revision/digest、read base、文件内容及构建配置,再以 **paused → 绑定规范化 definition hash → active** 注册到 Automations 的一次性 Host executor。源码只存控制面私有 SQLite;Automation definition 和模型状态投影不包含文件内容。相同 authority 的期限、配置和累计提交上限不可重置;同 key 不同内容拒绝。全账本同时最多一个 `queued/running/unknown` 任务。
252
266
 
267
+ 本地发布需要持续生成下一版本时,可在 `sourceJobs` 下配置受管源码基线:
268
+
269
+ ```yaml
270
+ baseline:
271
+ ref: refs/dsh-source/repairs
272
+ remote: /absolute/canonical/private/releases.git
273
+ targetBranch: repairs
274
+ initialCommit: 0123456789abcdef0123456789abcdef01234567
275
+ ```
276
+
277
+ `initialCommit` 是 owner 明确批准的初始提交,`remote` 是本地发布适配器使用的私有 bare 仓库,分支初值须与该提交一致。`ref` 限于 `refs/dsh-source/<简单小写名称>`;`targetBranch` 也使用简单小写名称。读取、入队和准备会从账本核对完整 `release-complete` 发布链,重验当前 installation/ledger 下已应用的合并签名,并核对 bare 分支精确落在链末端,再导入对应 Git 对象并以 CAS 推进专用 ref。用户 checkout 的 HEAD、索引与工作文件保持不变;下一次候选的版本递增和构建均从新基线开始。历史签发公钥须保留在 trust 中。
278
+
279
+ 专用 ref 不能被主工作区或关联 worktree 的 HEAD 直接或间接引用,也不能是符号引用。同步会反复核对这些条件并以 `--no-deref` 更新。该检查不与同 UID 外部 Git 进程构成原子事务;安装管理的仓库不应同时由外部进程重指 HEAD 或改写引用。
280
+
281
+ schema 28 支持在原发布链中追加 Host 签名的源码维护记录,保留 `initialCommit`、原发布收据与授权用量。读取和后续发布同时验签两类记录;维护写入会重验历史,并在数据库事务内核对历史未变。安装前的签名历史可在首次创建 owner 账本时导入,已有账本重试只核对,不补写缺失历史。停服维护可通过 `ControlPlaneStore({ path, readOnly: true })` 读取已 checkpoint 的当前 schema 账本,不创建 WAL/SHM 或迁移数据库;非空 WAL/回滚日志须先对账,调用方必须保证所有写者已停止。激活预检允许同一 profile 下已关闭且绑定完整的历史观察,但当前观察必须唯一并对应最新成功 checkpoint;缺失或不一致的证据会拒绝迁移。当前只提供源码、账本与资源副本迁移组件,尚未接通冻结本地安装的完整停服升级事务;边界见[源码维护兼容协议](../../docs/compatibility.md#本地源码维护历史control-plane-schema-28)。
282
+
283
+ 每次最多核对同仓库 1000 条已启动发布记录和 128 个 worktree;超过上限会停止同步,不会截断历史后猜测基线。
284
+
285
+ 同仓库的持久修复按发布终态串行衔接。未结束或结果未知的发布、已合并后失败的发布、分叉或被外部推进的分支会暂缓新修复,需要先核对既有操作结果;不会自动跟随任意远端 HEAD。任务仍冻结入队时的基线,执行前发现变化会拒绝旧候选。发布启动时的基线链检查绑定到持久作业;手工直接计划仍由本地适配器核对精确 base,不能绕过正在进行的受管作业。专用 ref 可在重启后根据相同账本幂等恢复;同步本身最多 30 秒,仍受调用方取消和 owner fence 约束。此设置不增加提交额度或延长授权,修改配置须换 `authorityId`。未配置时保留原有 HEAD 行为;supervised 安装器已自动准备私有源码与 bare 仓库,并在 owner 配置阶段接入基线,见[安装指南](../lark-channel/docs/rsi-setup.md)。
286
+
253
287
  模型回合结束不会取消已接受的 Host 任务。Host 自己受授权绝对期限、构建时限、Automations lease、取消和 Cordis provider 生命周期约束。成功时,job `prepared`、gap claim 和已有 `pending-approval` plan 在同一 SQLite 事务提交。原模型授权仍最多 300 秒;不新增模型循环或调度器。
254
288
 
255
289
  配置审批、发布或采用后,临时失败的 `prepared` 作业由原生每分钟 cron 接续,无须重启 Host。独立 Host executor `plugin-control-plane-source-continuations-v1` 使用同一 system owner,持久 automation ID 为 `source-job-prepared-continuations`;如 Policy 采用精确 ID 规则,须覆盖它。每轮最多处理一个当前可推进作业,仍走生产 Policy/预算准入、原 owner/反馈/trust 校验和既有外部操作 claim。重启只注册恢复任务,不在启动时直接调用授权器;unknown 外部动作不重新派发。无可推进作业时暂停,新的已检查候选可重新激活。卸载暂停当前代次、取消并等待已有调用;旧代次不能暂停新实例。
@@ -260,8 +294,136 @@ sourceJobs:
260
294
 
261
295
  默认只准备待审批提案;配置下述有限审批后,真实 owner 失败来源的持久作业可继续审批。工程层 native scheduler/Policy/SQLite 集成测试不等于真实模型执行整仓修复或生产发布验收。
262
296
 
297
+ ### 自动创建新插件候选
298
+
299
+ 创建新插件是独立的 owner 授权。除原有 `sourceJobs` owner、期限、预算与提交上限外,显式配置:
300
+
301
+ ```yaml
302
+ sourceJobs:
303
+ # 保留前文完整 sourceJobs 配置
304
+ creation:
305
+ id: owner-plugin-creation-1
306
+ expiresAt: 1800000000000 # 替换为实际有限期限
307
+ maxCreates: 3
308
+ namePrefix: owner-tool-
309
+ ```
310
+
311
+ Growth Driver 同时启用 `pluginSourceProposals.allowCreation: true` 与 `preparationMode: durable`。Host 公开有效 `namePrefix`,模型只能选择该命名空间内尚不存在的插件,不能更改授权。读取和入队冻结实际 base、公共生成器及模板摘要、来源 owner、反馈修订与构建配置。候选只提交 `README.md`、`src/`(不含 `src/version.ts`)和 `tests/`;单文件 64 KiB、合计 256 KiB、最多 64 个文件,最终插件也包含模板保留文件计算此上限,受原有来源及取消 fence 约束。
312
+
313
+ 普通 owner 任务驱动的创建还须由 Growth Host 注册私有 run producer,冻结其持久 Usage 中的实际模型、模型来源、预算、原生 Automation occurrence、Agent session、工具/执行合同和任务来源。入队、原生 claim、构建检查点及独立验收读取均重新查询 producer,并比对当前 owner 与 Evaluation 来源;模型工具传入的字段只作为预期值。生成截止仅限制模型提交与同步入队,后续隔离构建仍使用独立的 Control Plane Policy 预算,并须处在原 Usage 来源窗口和创建授权期限内。producer 暂未就绪时未 claim 的创建保持 queued,Host 就绪时唤醒既有原生调度;注销会中止并排空已 claim 的创建,状态转为 unknown,不自动重放。旧任务创建行缺少 run binding 时仍可读取原字节和摘要,但不能继续派发或作为新验收包;旧手动创建不需要该字段。
314
+
315
+ Host 在私有 worktree 使用该基线的 `scripts/create-plugin.mjs`,生成 manifest、patch、许可证、版本和构建配置,登记目录行,并只为新包追加锁文件 importer。依赖只能复用基线 catalog 的唯一既有解析,不进行网络解析、不改变已有 importers/packages/snapshots。生成器以固定 Node 执行路径、清理后的环境及有限运行时限运行;这属于可信基线的 Host 子进程,临时目录本身不构成操作系统沙箱。候选源码在原离线 Docker 构建器中检查;Host 在检查后重建生成器输出,复验保留文件、catalog 和 lock 字节。
316
+
317
+ 创建检查需要包含已验证基线锁文件的新构建镜像(运行 `node scripts/isolation/build-source-image.mjs`)。Host 复核实际归档的创建范围,容器核对原 Git 基线锁摘要与只读镜像 `/opt/dsh-source-baseline/pnpm-lock.yaml` 一致,才在 pnpm 11.7.0 的首次离线 frozen install 使用 `--trust-lockfile`。该选项跳过锁文件解析与供应链策略复核;已有解析已在镜像构建时通过策略验证,新 importer 不引入新解析。普通修改不使用此选项,旧镜像或不同基线均拒绝此创建检查。构建证据保留实际 Docker 参数及基线锁摘要。
318
+
319
+ `creation.id` 对应的授权定义不可变,累计用量独立持久保存;更换 `sourceJobs.authorityId`、重启或修改构建配置不会重置同一创建授权。接受的失败/unknown 尝试仍消费创建额度,同一幂等请求不重复扣取。实际创建同时受 `maxSubmissions`、Policy 预算及全账本单 outstanding job 上限约束。
320
+
321
+ 成功仅产生 `prepared-create`、`pending-approval` 的检查候选。现有修改签名器、发布与采用接续不会推进它;工程检查和候选测试不能代替独立行为验收。TTL 到期后,`source gc` 以 CAS 释放该计划的 gap 并仅清理可证明归属的注册 worktree,不返还额度。unknown 必须先按现有资源协议对账,不能直接重放或当作过期计划清理。旧手动 `create` 和现有 `modify` 流程保持原语义。
322
+
323
+ 仅配置创建授权不授予采用权限;后续真实任务收益与部署闭环仍须验收。
324
+
325
+ 可选 `creationVerifications: { authority, publicKey }` 接续[Verifier 的普通任务创建验收](../assistant-verifier/README.md#普通任务产生的新插件验收)。公开字段由其 `compileCreationReviewConfig` 生成;控制面不接收私有密钥或期望用例。authority 须匹配创建命名空间且不能超过创建/SourceJobs 授权期限。Growth 在作者模型开始前冻结引用,prepared 后沿原生续跑自动验收;历史缺少引用的候选保持原状态。
326
+
327
+ 验收 dispatch 与结果使用独立 SQLite 记录;已 claim 的未知派发不再自动调用模型。签名落账前重读真实工作树、检查 tree/patch、不可变包、当前 owner/反馈与 Growth run,最终持有 Evaluation writer fence。`inspectVerifiedCreation(planId)` 只读验签并检查当前来源和封存制品,证明历史检查快照,不能证明可变工作树此刻未变化;后续采用须先 await `inspectPreparedCreationReviewContext` 异步复验并消费精确制品。该凭证不会把计划改为 approved,也不会绕过既有修改计划的审批、发布与采用门。
328
+
263
329
  成功准备返回 `pending-approval`,不会自动发布。普通 gap 可用已有签名审批流程;owner 任务来源必须通过 Host 当前来源 fence 审批,离线 CLI 签名本身不能代替该校验。审批后,普通 gap 用 `dsh-plugin-control source verify-prepared --plan-id <id> --expected-revision <revision>` 重读同一 worktree 并核对 digest;owner 来源由下述 Host 发布接续入口完成复核,才能进入 review/release。修改 worktree 会使复核失败;旧 `create` 计划仍走 `scaffold`。`dsh-plugin-control source gc` 将已过 TTL、仍 pending/approved 的计划以版本 CAS 转为 `expired`,释放该计划的 gap 占用,再清理控制面登记的 modify worktree;已经 `expired` 的计划可重试物理清理,已经进入 review/release 的 worktree 保留。
264
330
 
331
+ ### 已采用工具的有限源码修订
332
+
333
+ 新的认证失败任务可引用同一当前 owner 已采用的精确源码,生成独立修订候选。旧创建来源可以已更正、撤回或到期;它只证明历史父版本,不授予新任务权限。修订默认关闭,Growth 须显式设置 `pluginSourceProposals.allowRevision: true`、`preparationMode: durable` 并启用 `usageLearning`;Control Plane 还须配置独立授权:
334
+
335
+ ```yaml
336
+ sourceJobs:
337
+ # 保留完整 sourceJobs 配置;沿用其提交上限、原生 Policy 预算与 owner
338
+ revision:
339
+ id: owner-plugin-revision-1
340
+ expiresAt: 1800000000000 # 替换为 owner 批准的有限绝对期限
341
+ maxRevisions: 3
342
+ namePrefix: owner-tool-
343
+ revisionVerifications:
344
+ authority: # 来自同批 Verifier compileRevisionReviewConfig 的公开引用
345
+ protocol: assistant-growth/revision-acceptance-authority/v1
346
+ authorityId: owner-revision-review
347
+ keyId: revision-review-key
348
+ authorityDigest: <实际编译摘要>
349
+ namePrefix: owner-tool-
350
+ expiresAt: 1800000000000
351
+ publicKey: <Verifier 的 Ed25519 公钥 PEM>
352
+ ```
353
+
354
+ 此路径要求既有 `creationCapabilities` 的 owner 和已签名源码归档、独立 Verifier 修订配置及当前 Growth Usage producer;验收密钥须与采用密钥不同。模型从 Host-only 清单投影选父计划和名称,不能传入归档、授权或验收用例;三个模型工具是 `plugin_source_revision_targets`、`plugin_source_revision_inspect`、`plugin_source_revise`,失败 gap 由 Host 从本轮当前任务推导。新任务的实际 supplier、预算、原生身份、修订验收引用在首个作者模型请求前冻结,每个派发与检查点重验新任务和父版本绑定。
355
+
356
+ Host 从当前受信任基线生成同名 scaffold,将父归档的候选文件叠加后应用新文件;manifest、patch、版本、许可证及构建配置须与当前生成器精确一致。README、非保留 `src/`、`tests/` 的边界与创建相同,至少一个真实变化,不支持删除或可执行文件。生成器或保留文件不兼容、当前基线已有同名包时拒绝,不把旧 Git OID 写入新基线。受管基线只允许精确证书和制品绑定的已采用父 `prepared-create` 计划让位于自己的修订;其他未结束或 unknown 作业仍阻止推进。
357
+
358
+ 同一 `revision.id` 的累计额度独立保存,失败/unknown 不返还,幂等请求不重复扣取;同时消费既有 `maxSubmissions` 和 Policy 预算。成功构建产生 `prepared-revise`。原生续跑仅调用独立修订验收;新证书以专用签名域绑定父证书、制品、签名归档与源码摘要及新任务/model/run。claimed unknown 不自动重验;验证结果与精确 staged 源码在同一事务落账。
359
+
360
+ Host-only `inspectCreatedCapabilityRevisionCandidate(planId)` 验签并核对当前 owner,可在来源更正/撤回、授权和证书到期、制品/worktree 回收及 Host 冷启动后读取历史候选。该候选没有执行回执,不注册工具、不替换父版本、不扩大或续期旧创建/采用额度;后续版本切换须另有有限授权和父版本回归验证。旧配置不会自动获得修订能力,owner 安装器目前不生成这一授权。
361
+
362
+ ### 修订候选的独立父行为回归门
363
+
364
+ 可选 `revisionRegressions: { authority, publicKey }` 使用 Verifier `revisionRegressions` 编译出的专用 `assistant-growth/revision-regression-acceptance-authority/v1` 引用。它要求既有有限修订与独立修订验收配置,命名空间相同、期限不超过这些新授权,验收公钥与采用密钥分离;Growth 在首次作者模型请求前把引用冻结进新任务 run,缺失或改变时不能恢复派发。未配置的新旧 provider 保留仅生成 pending 修订候选的行为,不回填授权。
365
+
366
+ 候选先通过新任务独立验收,再由原生 SourceJobs 接续私有 `verifyPluginRevisionRegression`:Verifier 从旧创建审查账本读取精确签名父证书对应的 held-out cases,不能从候选源码或新模型重新生成。两侧分别在新的有限隔离授权下 discover/invoke,工具名和参数 schema 投影、SDK 环境必须兼容,每个父用例分别比较独立 expected;结果原始摘要无需相同。历史父数据可以过期,但不能把旧创建/采用授权当作执行许可。缺失或篡改私有用例、未知观察、来源更正或写入失败保留独立 claim,不重放。
367
+
368
+ Host-only `inspectPreparedRevisionRegression` 提供精确父/候选不可变制品;`withPreparedRevisionRegressionFence` 核对当前新任务、model/run、父归档、候选验收、源码与回归引用后同步落账。主账本 schema 34 的 `source_revision_regressions` 独立保存结果,冷启动不重派 settled/claimed 操作;旧计划和额度不改写。`inspectVerifiedRevisionRegression` 只在新窗口与当前来源有效时返回签名证书。成功仍为 `pending-approval`,没有工具、采用收据或版本切换;稳定入口切换与回退必须另外获得有限授权。配置和私有用例读取细节见 [Verifier](../assistant-verifier/README.md)。
369
+
370
+ ### 新工具插件的有限动态采用
371
+
372
+ 可选 `creationCapabilities` 是一次配置的独立 owner 采用授权,必须与 `sourceJobs.creation`、`creationVerifications` 一起启用。其 owner 的七个稳定字段须匹配实际 Delivery owner 来源,命名空间须一致;采用 Ed25519 私钥与验收器私钥的实际 material 和 key id 均须不同。旧 peer 缺少 live Agent 校验或 Evaluation 变化订阅时拒绝启动此能力。示例中的路径、身份、摘要、期限和镜像须替换为实际授权:
373
+
374
+ ```yaml
375
+ creationCapabilities:
376
+ authorityId: owner-created-tools-1
377
+ keyId: owner-adoption-key
378
+ keyPath: /private/owner/adoption.pem
379
+ owner:
380
+ authorityId: configured-delivery-owner-route
381
+ authorityHash: <delivery-route-sha256>
382
+ principalId: configured-principal
383
+ principalRecordId: <delivery-principal-record>
384
+ principalVersion: 1
385
+ workspace: /absolute/owner/workspace
386
+ agentPreset: primary
387
+ namePrefix: owner-tool-
388
+ expiresAt: 1800000000000
389
+ maxAdoptions: 3
390
+ maxTools: 2
391
+ maxCallsPerAdoption: 20
392
+ maxCallRecords: 60
393
+ maxInputBytes: 4096
394
+ retention:
395
+ maximumLifetimeMs: 2592000000 # optional: 30 days after adoption
396
+ runner:
397
+ stateRoot: /private/owner/capability-runner
398
+ image: sha256:<64-hex-plugin-verifier-image-id>
399
+ dockerPath: /usr/bin/docker
400
+ expiresAt: 1800000000000
401
+ maxRuns: 63
402
+ maxTotalDurationMs: 600000
403
+ maxDurationMs: 30000
404
+ maxOutputBytes: 65536
405
+ ```
406
+
407
+ 原生 SourceJobs 续跑自动消费精确验收凭证、复验工作树和当前 canonical 来源,先持久 claim,再独立发现工具 schema,签发绑定制品、来源、schema、别名、授权和期限的采用回执。`retention` 是显式可选授权,取值为 1 ms 至 30 天;仅对已完成首次采用的版本生效。首次采用仍须新鲜验收凭证、创建授权和完整源码复验。配置 retention 时采用回执使用 v2,使用截止时间固定为采用时刻加 `maximumLifetimeMs`、`creationCapabilities.expiresAt`、`runner.expiresAt` 三者最早者;重启不重新计时。没有 retention 的旧配置和 v1 回执继续在原验收窗口结束时失效。`statePath/creation-adoptions.sqlite` 保存不可变授权、512 KiB 内精确包及累计额度;更换 runner 状态目录不能重置采用额度,修改同一 ledger 的授权定义会拒绝。失败或 unknown 消费额度,不自动重放;重启只恢复已授权的同一凭证和制品,不重新发现或签发。模型没有采用、签名或账本工具。
408
+
409
+ Host 用真实 Cordis Fiber 动态注册受控 `evolved_<插件名>_<plan hash>_<序号>` 原生工具入口。候选代码在每次 discovery/invoke 的独立离线 Docker 子进程中创建自己的 Cordis Context 并挂载;Host 不导入候选代码。当前只支持原生 Tools/SystemPrompt 服务的有界纯工具插件;每次调用新建 candidate Context,不支持跨调用候选内存状态或任意 Host 服务桥接。包读取、临时制品、容器、Docker 子进程、私有 ledger 和密钥读取属于本授权;容器无 Host 挂载、网络或凭据,不执行包安装脚本。限制详见 [行为执行器](../../scripts/isolation/README.md#plugin-behavior-verifier-image)。
410
+
411
+ 调用经过原生 ToolRuntime/Policy,须由 Delivery 证明当前注册的真实 Agent、Session 和 owner lineage;Policy 还须允许该 owner scope 下的准确工具别名或有限别名模式。输入、结果和累计调用均有界;同一 Agent Session/call id/参数的已完成调用回读缓存,unknown 不再派发。候选注释不进入 Host 描述,输出作为不可信数据。每次异步检查后、派发前和落账前重验真实调用者与 canonical 来源,撤权或纠正期间的迟到结果不能变成成功。
412
+
413
+ 新调用在 claim 事务中保存冻结工具别名与可选的 Delivery 原生前台调用证明。Host-only `inspectCreatedCapabilityCalls(planId)` 返回有界的采用回执、制品和 schema 摘要、原始工具名、调用状态及具体 Inbox/turn/事件证明,不返回参数或结果。只有准确 owner/Session/工具/参数匹配的证明才标记 `foreground`;无证明的新调用为 `unattributed`。调用账本 schema v2 为旧行保留空证据列,标记 `legacy-unattributed`,不按不可逆 call key 猜测任务或补写历史;额度、缓存与 unknown 状态保留。旧 controller 不支持 schema v2 时会拒绝打开;不能靠删除或回退账本重置额度或重放 unknown。已有前台证明的同 key 重试须提供完全相同的证明,缺失证明或指向不同 Inbox/事件均拒绝,不能回读另一任务的结果;旧行仍保留原缓存语义且不获归因。`foreground` 证明调用尝试所属的真实任务;仍须区分 `completed` 和 `unknown`,后者不能证明候选代码已执行或完成。尚未据此自动判断质量、因果收益、成本或晋升;后续收益须联接认证 canonical 任务修订并按任务去重。
414
+
415
+ Host-only `inspectCreatedCapabilityTaskAssociations(planId)` 将精确采用版本的 `completed` 前台调用关联到后续 Inbox 的当前认证 canonical 结果。它排除原创建任务、unknown、旧记录和无前台证明的调用;同一 plan/Inbox 合并调用 key,不推断不同 Inbox 是同一语义任务。关联同时复验历史证书、冻结来源、当前 owner/会话绑定及 Delivery 的真实任务证据,并在 Evaluation writer fence 内重读原任务和后续任务;更正更新结果版本,撤回、来源漂移或 owner 换代使关联失效。查询返回摘要和认证 `achieved`/`not-achieved` 判断,不返回任务文本、参数或结果,不创建第二份结果账本。
416
+
417
+ 关联是查询时刻的只读快照,后续采用或晋升决策仍须重新取得当前认证证据;它不能证明因果收益、成本或延迟改善。`adoptionStatus` 是账本状态,`withinSignedUseWindow` 只比较原签名期限,不能代替当前挂载、owner 和剩余额度校验。在运行时成功启动的前提下,终止或过期版本及重启后的历史调用仍可关联当前反馈,不重新激活入口或恢复额度;运行时不可用或来源无法复验时返回空;空结果不能解释为负面收益或撤权决定。
418
+
419
+ 新 controller 在首次采用 claim 前,从同一个私有 Git index 采集精确 staged 源码,核对独立证书的 tree/patch 摘要,并在采用事务内保存独立签名的源码快照。仅保存插件文本(至多 64 文件、单文件 64 KiB、总计 256 KiB),catalog/lock 只保留索引 OID,不能据此重建整个 workspace。读取 Git blobs 而非工作文件,保留 staged 字节及 BOM;不执行候选脚本。离线读取复验源码字节、Git blob OID、tree 摘要与采用密钥签名;patch 摘要与冻结证书相等,但不声称能在缺少原 base/patch 时重新计算。采用账本 schema v3 将源码独立存储,常规恢复不加载源码;v1/v2 迁移保留旧授权、凭证、调用缓存、unknown 和额度,旧行没有源码且不会推测或补写。旧 controller 不得写 v3,升级须停止旧 writer。
420
+
421
+ Host-only `inspectCreatedCapabilitySource(planId)` 返回冻结的历史源码数据,要求同一配置/密钥和当前 Delivery 认证 owner continuation,并复验 Store 中原计划、作业、来源、Growth run、模型与历史证书。已采用版本在工作区/准备制品清理、执行期限结束、入口关闭或原反馈更正/撤回后仍可读;owner 换代、授权哈希漂移、代次倒退或证据篡改拒绝。运行时必须成功启动;旧行或不可复验状态返回缺失,不能解释为允许重建历史。读取不激活插件、不延续原任务、不恢复额度、不授予替换版本权限;后续修复必须使用当前触发任务和新的有限授权。
422
+
423
+ 同一主人 `/new` 后的新任务可在使用授权截止前调用已有入口。任务来源保留原执行绑定,源码作业、Growth run、验收与采用凭证的完整摘要不改写;当前 route 必须仍属于同一主人记录、版本和授权,且会话代次不能倒退。已采用 v2 版本在单个创建作业、计划 TTL、Growth run 和证书到期后,仍可在原使用授权期限内,从冻结的签名 journal 和 Store 计划/作业/来源核对历史证据,并继续检查当前主人和 canonical 纠正/撤回;即使原准备制品被 GC,也只执行 journal 中冻结的包。切换 Session 不续期、不补充额度、不重新派发 unknown,也不授予版本替换权限。
424
+
425
+ Evaluation 纠正/撤回通知自动重验并卸载对应入口;到期、来源漂移也关闭该版本,其他 Host 插件保留。旧 v1 模式的源码 producer 暂缺时只暂停入口,恢复原来源后可重新挂同一凭证。v2 已采用版本不依赖过期的原 Growth producer;其历史验签时间固定为采用时刻,不可用于首次采用或新签收据。源计划可以按原规则从 `pending-approval` 过期并清理原制品;旧修改审批、PR、npm 发布和整 profile 采用门不变。Host-only `inspectCreatedCapability(planId)` 返回采用状态和别名。动态卸载是本能力的撤销路径,真实后续收益、版本替换回退和普通使用部署仍属完整目标的下一次验收。
426
+
265
427
  ### 普通任务修复的有限审批
266
428
 
267
429
  可选 `sourceApprovals` 将持久 `sourceJobs` 的准备结果接到 owner 配置的有限签名器:
@@ -313,7 +475,7 @@ sourceApprovals:
313
475
 
314
476
  在 Control Plane trust 的 `approvalKeys` 登记对应 Ed25519 公钥;该 key 不用于 release authorization、发布或 Host attestation。owner 字段取实际 Delivery 回执,不由模型生成。grant id 的配置与 key 指纹不可变,额度和已签回执落入独立 SQLite;重启及同一请求重试不重置额度、不延长签名期限。
315
477
 
316
- 签名器只读当前 schema 20 控制面库,重新验证完整来源摘要、owner、期限、仓库及 worktree 归属、检查证据和当前 tree/patch。默认只允许白名单非保护插件 `src/` 下的普通 `.ts/.js/.mts/.mjs` 源文件修改;`grant.versioning: "patch"` 仅额外允许上述 Host 管理的 manifest 版本变化。测试目录、其他 manifest 字段、脚本、lockfile 和保护插件不在授权范围。工程检查证据不构成业务目标达成证明。
478
+ 签名器只读当前 schema 29 控制面库,重新验证完整来源摘要、owner、期限、仓库及 worktree 归属、检查证据和当前 tree/patch。默认只允许白名单非保护插件 `src/` 下的普通 `.ts/.js/.mts/.mjs` 源文件修改;`grant.versioning: "patch"` 仅额外允许上述 Host 管理的 manifest 版本变化。测试目录、其他 manifest 字段、脚本、lockfile 和保护插件不在授权范围。工程检查证据不构成业务目标达成证明。
317
479
 
318
480
  持久作业在 `prepared` 落账后调用审批,Host 在验签后以 Delivery/Evaluation 当前来源 writer fence 提交 `approved`。纠正、撤回、身份/会话换代、取消或 trust 变化均阻止提交。审批失败保留 pending 计划和已完成构建;重启恢复最多 1000 个 pending 的 owner 作业,仍核对原 sourceJobs 授权和 owner,只重试审批。单次 helper 至多 10 秒;卸载会等待子进程清理并丢弃迟到结果。Host 可调用 `requestOwnerSourceApproval({planId, signal?})` 显式重试;该方法不暴露为模型工具。inline 准备仍只返回 pending。
319
481
 
@@ -370,7 +532,7 @@ sourceReleaseExecution:
370
532
  independentReview: true # 可选;需另配 assistant-verifier.sourceReviews
371
533
  ```
372
534
 
373
- 此配置依赖 `sourceReleases`,沿用 trust schema v4 中八个固定 `releaseAdapters` 和本地 `file:` registry。原生 Automations 作业获批后,Host 依次接续 PR、review、merge、build、sign、publish、registry verify 与 catalog admission;最多推进八个既有阶段,不创建额外定时器。`timeoutMs` 为本次接续总上限(1 秒至 30 分钟),各 adapter 保留自身时限。源码检查和 release 构建是两个原有检查阶段,恢复不会重做已完成阶段。
535
+ 此配置依赖 `sourceReleases`,沿用 trust schema v4 中八个固定 `releaseAdapters` 和本地 `file:` registry。 trust loader 接受指向已存在、canonical、owner-private 目录的精确 `file:` URL,协议只能省略或为 `dsh`,不携带 CA/token 配置;URL 别名、符号链接和其他用户可访问的目录会被拒绝。schema v3 与 `protocol: "npm"` 仍要求 HTTPS。原生 Automations 作业获批后,Host 依次接续 PR、review、merge、build、sign、publish、registry verify 与 catalog admission;最多推进八个既有阶段,不创建额外定时器。`timeoutMs` 为本次接续总上限(1 秒至 30 分钟),各 adapter 保留自身时限。源码检查和 release 构建是两个原有检查阶段,恢复不会重做已完成阶段。
374
536
 
375
537
  review decision 仍由独立审查方产生:Host 只读 canonical、无 symlink、owner 私有目录下的 `<prId>.json`,其内容须符合现有 local adapter 的 `dsh-local-review-decision` 格式并精确绑定 PR id、base/head commit 和 PR evidence digest。配置的 `reviewDecisionRoot` 须与 review adapter 读取目录一致。缺失时保持 `awaiting-review`,不派发 review;格式错误或绑定变化则拒绝。独立审查方完成后调用 Host-only `advanceOwnerSourceRelease({ planId, signal?, expectedTrustDigest? })` 即可在当前进程继续,不要求重启。该入口不是模型工具;decision 由独立 Verifier 或外部审查方生成。部署须把 decision 写权限、审查输入和审查执行环境与候选写权限分开;同 UID 的目录权限本身不证明进程隔离。
376
538
 
@@ -412,7 +574,7 @@ handoff:
412
574
  commit: target-host
413
575
  ```
414
576
 
415
- 这些条款进入不可变计划摘要,由现有采用审批签名覆盖。目标在当前 owner 反馈写入屏障内创建持久交接;期限取计划、审批回执和窗口上限的最小值,恢复或重复调用不会续期。外部 Host 共享精确 ledger/trust,单独配置:
577
+ 这些条款进入不可变计划摘要,由现有采用审批签名覆盖。目标在当前 owner 反馈写入屏障内创建持久交接;期限取计划、审批回执和窗口上限的最小值,恢复或重复调用不会续期。外部 Host 由 owner-private trust 指定目标 ledger,单独配置;交接仍受签名 handoff、owner 审批和操作 fence 约束:
416
578
 
417
579
  ```yaml
418
580
  adoptionCoordinator:
@@ -427,19 +589,21 @@ adoptionCoordinator:
427
589
  timeoutMs: 300000
428
590
  ```
429
591
 
430
- 协调器必须运行在另一进程和独立 systemd unit;它不能同时配置目标的 `sourceJobs`、`sourceAdoptions`、`runtimeObserver` 或 `replayEndpoint`。只需连接所在 Host 的 Automations,复用原生每分钟调度、owner/Policy 和预算,每轮至多推进一个交接;空队列仍消耗一次配置的调度预算。`budgetId/budgetAmount` 必填,对应 Policy budget 使用 `automation-runs` metric 与有限周期额度,建议 `subject` scope,以稳定的协调器 automation id 聚合。Policy 账本按 scope、metric 和周期计量,仅换 budget id 不会分池;同一 Host 的其他任务应明确选择共用或分开额度。旧配置升级时须补齐,不能打开 `allowUnbudgetedExecution` 代替。`coordinatorId` 是绑定标识,不提供 OS 隔离或替代 ledger 文件权限。停用调度或耗尽原生预算也会暂停自动恢复,恢复前需先核对未知外部操作。
592
+ 协调器必须运行在另一进程和独立 systemd unit;它不能同时配置目标的 `sourceJobs`、`sourceAdoptions`、`runtimeObserver` 或 `replayEndpoint`。协调器的 `statePath/control.sqlite` 必须独立于 owner-private trust 指定的目标 ledger;普通控制面的本地账本仍须与 trust ledger 相同。只需连接所在 Host 的 Automations,复用原生每分钟调度、owner/Policy 和预算,每轮至多推进一个交接;空队列仍消耗一次配置的调度预算。`budgetId/budgetAmount` 必填,对应 Policy budget 使用 `automation-runs` metric 与有限周期额度,建议 `subject` scope,以稳定的协调器 automation id 聚合。Policy 账本按 scope、metric 和周期计量,仅换 budget id 不会分池;同一 Host 的其他任务应明确选择共用或分开额度。旧配置升级时须补齐,不能打开 `allowUnbudgetedExecution` 代替。`coordinatorId` 是绑定标识,不提供 OS 隔离或替代 ledger 文件权限。停用调度或耗尽原生预算也会暂停自动恢复,恢复前需先核对未知外部操作。
593
+
594
+ 协调器把关闭动作登记到同批 Automations 的 Host 停用屏障:正常卸载、provider 替换及 Host 退出时,在 Automations 存储关闭前暂停本代原生登记,再释放执行器与控制面连接。该屏障要求成套更新 Automations 与 Control Plane;不改变强制终止后的 unknown 执行对账语义。
431
595
 
432
596
  协调器沿现有安装和签名检查路径推进,到 `commit-pending` 停止。目标恢复后由其原生源码 continuation 重验当前 owner、反馈和信任,再完成启用;已撤销或过期交接只能进入既有回退。目标卸载不会撤销已交出的任务;未知 Host 派发仍须精确签名对账,不能自动重派。目标离线期间无法即时获知反馈纠正,允许暴露的最长授权窗口由上述期限限制;回退完成时间仍取决于协调器可用性和签名服务。
433
597
 
434
- 当前安装器尚未提供这个双 Host 配置。现有 systemd attestor 只签发 reload/readiness/rollback;其余行为验收阶段仍需要真实独立观测,不能用进程就绪代替。组件接线不等于生产自动采用闭环,npm 发布仍须等待实际部署验收。
598
+ `dsh-rsi-setup` 已提供双 Host 合同编译与校验,实际部署验收尚未完成。现有 systemd attestor 只签发 reload/readiness/rollback;缺省严格合同的其余行为验收阶段仍需要真实独立观测,不能用进程就绪代替。可显式配置下述有限试用合同,由普通任务证据独立签发资格。组件接线不等于生产自动采用闭环,npm 发布仍须等待实际部署验收。
435
599
 
436
600
  这提供自动采用的执行链。目标 Host 可另配 `foregroundDeployments: { attestorJournalPath: /srv/dsh-owner/supervisor/reload.sqlite }`,同时启用 `runtimeObserver`,并挂载 Delivery。路径须指向 systemd attestor 实际的私有 SQLite journal;配置只授予读取已签名 readiness 记录的权限,不包含签名密钥。目标 Host 与外部部署协调器需使用同一精确控制面账本和 trust 绑定;当前实现要求同 UID 的私有文件读取,不能据此声称独立 UID 隔离。
437
601
 
438
602
  schema 20 的 `foreground_deployments` 在真实 owner 前台任务开始和完成时保存身份及运行实例。采样复用认证 observer 的同一实例,核对已应用 readiness 的签名、保留观测摘要、PID/InvocationID、profile、Fiber/依赖/服务代次,并关联精确 package/version/integrity。只接受当前最近一次成功部署、已完成 owner 源码采用、且属于同一 owner/workspace/preset 的新任务;未结算部署、重载、实例变化或非静止完成均不产生有效观察。注销/重启中断的记录保持 pending,历史任务不回填。trust 文件改变后需重载配置;观察失败不会中断正常对话。
439
603
 
440
- Host 可用 `inspectOwnerForegroundDeployment()` 按与 Delivery 学习来源查询相同的参数读取归因;它重验当前可信任务,保持原学习来源摘要不变。记录证明该任务处于这一部署实例下,不证明调用过某个工具或该版本导致了结果,也不会把正常结束计作质量成功。读取结果作为质量依据仍需消费当前 canonical 反馈与撤回,并在最终写入时使用 writer fence。可选 `taskObservations` 已接通有限批次的当前反馈、签名观察与物理回退;可安装日常使用配置及端到端部署验收仍待完成,此能力不代表 npm 发布验收通过。
604
+ Host 可用 `inspectOwnerForegroundDeployment()` 按与 Delivery 学习来源查询相同的参数读取归因;它重验当前可信任务,保持原学习来源摘要不变。记录证明该任务处于这一部署实例下,不证明调用过某个工具或该版本导致了结果,也不会把正常结束计作质量成功。读取结果作为质量依据仍需消费当前 canonical 反馈与撤回,并在最终写入时使用 writer fence。可选 `taskObservations` 已接通有限批次的当前反馈、签名观察与物理回退;日常使用配置已可编译,端到端部署验收仍待完成,此能力不代表 npm 发布验收通过。
441
605
 
442
- 单个 Service 最多准备一条提案。Cordis 卸载先取消并等待所有准备步骤和容器/worktree 清理,再关闭 SQLite。数据库 schema 23 保留旧 create 摘要和 release 外键;modify 的审批摘要另外绑定 mode、检查结果及构建证据。构建证据证明配置镜像中的检查过程,不证明候选业务质量或独立隐藏评测通过;正式 release 仍需要原有审批、独立 review、构建和签名。
606
+ 单个 Service 最多准备一条提案。Cordis 卸载先取消并等待所有准备步骤和容器/worktree 清理,再关闭 SQLite。数据库 schema 25 保留旧 create 摘要和 release 外键;modify 的审批摘要另外绑定 mode、检查结果及构建证据。构建证据证明配置镜像中的检查过程,不证明候选业务质量或独立隐藏评测通过;正式 release 仍需要原有审批、独立 review、构建和签名。
443
607
 
444
608
  非 owner-task 来源的计划可用 `release-request` 导出当前 durable phase request、用 `release-step` 调用已固定 adapter 并应用 receipt,或用 `release-attest` 应用 owner-controlled 外部系统生成的同协议 receipt。phase 不能由调用者选择,而由 durable source plan 状态决定。adapter 返回签名 publish 歧义回执后进入 `publish-ambiguous`,再由独立 registry verifier 的签名 reconciliation receipt 决定继续验证、以新 fence 重试,或 fail closed。派发后没有签名回执则保持 unknown,不自动重跑;普通 owner-task 来源的全部阶段必须通过 Host 当前来源校验。
445
609
 
@@ -450,7 +614,7 @@ Host 可用 `inspectOwnerForegroundDeployment()` 按与 Delivery 学习来源查
450
614
  随包发布的 `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。它实现:
451
615
 
452
616
  - local bare Git remote 上的 immutable PR ref、由 owner-private exact review decision 驱动的独立 review receipt,以及 target-ref compare-and-swap merge;
453
- - 从 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;
617
+ - 从 exact merge commit 做至少两次独立 checkout,并分别复制为新的可写 sandbox workspace;owner 配置固定 Linux bubblewrap、Node、pnpm runtime tree、离线 store、可选策略元数据 cache 与 tar executable 的 canonical path/摘要。sandbox 使用空 HOME/tmp、无网络的新 user/mount/PID namespace,固定执行 `pnpm install --offline --frozen-lockfile --frozen-store --ignore-scripts --package-import-method=copy`、工作区根目录的可选 `build`、目标包 `build` 与 `pnpm pack`,最终 artifact 使用 package manager 的 pack lifecycle/packlist;仅固定打包清单中四个 dependency map 的键顺序,保留 exports/imports 条件顺序及其他文件、tar header 和条目顺序,再进行确定性 gzip 压缩,生成 CycloneDX SBOM 和 SLSA provenance。这样避免 pnpm 异步转换 workspace/catalog 依赖引入顺序差异;两次完整制品摘要及逐文件 inventory 仍须一致,真实内容差异仍拒绝发布。规范化接受常规文件/目录 tar 条目和 pnpm 标准两空格 JSON;未知扩展格式、重复 manifest 或不完整归档会被拒绝;
454
618
  - 独立 signer 对 exact artifact statement 签名;
455
619
  - local filesystem registry 的 package/version immutable publication;
456
620
  - 在独立 download root 复制并重新验证 registry bytes;
@@ -464,26 +628,26 @@ adapter 的 stdout 只有一个签名 JSON receipt,stderr 不打印 request
464
628
 
465
629
  Host-only `recordOwnerTaskFailureGap(source)` 将经 Delivery 再验证的 foreground `not-achieved` 结果,在 Evaluation canonical writer fence 中原子写入 gap 和私有来源引用。schema 16 从 v15 保留原有计划并增加 sidecar;引用只保存完整 owner receipt、outcome/canonical 修订和 source digest,gap 使用固定说明且 ROI 为未知占位 0。模型自报、调用方文案、未结束或截断来源均不能登记,接口不注册为 CLI/模型工具。
466
630
 
467
- 这些 gap 不出现在全局 `gaps()` 中。Growth 自动复盘仅看本次来源的 exact gap;同步准备必须提供当前 owner,durable source job 绑定相同 owner。每个检查边界与最终计划提交重新验证来源,最终写入同时持有 Evaluation writer fence 和同步 Store admission;普通 CLI 不能凭 gap id 绕过来源检查。`/new` 的 binding/generation 改变、纠正、撤回或依赖服务不可用会拒绝旧任务,已派发而中断的 job 保留 unknown。历史引用保留以供审计,不自动重放。
631
+ 这些 gap 不出现在全局 `gaps()` 中。Growth 自动复盘仅看本次来源的 exact gap;同步准备必须提供当前 owner,durable source job 冻结原任务 owner。每个检查边界与最终计划提交重新验证来源,最终写入同时持有 Evaluation writer fence 和同步 Store admission;普通 CLI 不能凭 gap id 绕过来源检查。同主人 `/new` 保留原任务证据和授权窗口;身份或授权变化、纠正、撤回或依赖服务不可用会拒绝旧任务,已派发而中断的 job 保留 unknown。历史引用保留以供审计,不自动重放。
468
632
 
469
633
  该 Host API 使用同批 `assistant-delivery` 与可选 `assistant-evaluation >=0.1.33` 的精确接口;不要求手工 gap 部署安装 Evaluation。它只授权来源绑定的候选准备,pending plan 的后续授权采用、发布与观测仍走独立控制链。
470
634
 
471
635
  ## 权限
472
636
 
473
- - 插件 Host service:启用 `sourceApprovals` 时执行固定的 owner helper(可读其配置、私钥和私有审批账本),Host 只消费签名回执;读取 catalog/trust,写 owner-private SQLite/WAL;启用源码读取或准备时执行受限 Git,启用 `sourceBuild`/`sourceJobs` 时创建隔离 worktree 并调用 owner 配置的离线容器构建。模型不能选择可执行文件、网络或凭据;Host 不使用浏览器。
637
+ - 插件 Host service:启用 `sourceApprovals` 时执行固定的 owner helper(可读其配置、私钥和私有审批账本),Host 只消费签名回执;读取 catalog/trust,写 owner-private SQLite/WAL;启用源码读取或准备时执行受限 Git,启用 `sourceJobs.baseline` 时还会从指定本地 bare 仓库导入对象并写入专用 `refs/dsh-source/` 引用;启用 `sourceJobs.creation` 时执行冻结基线的公共生成器并写临时模板目录、私有 worktree、目录行和新锁文件 importer;启用 `sourceBuild`/`sourceJobs` 时调用 owner 配置的离线容器构建。模型不能选择可执行文件、网络或凭据;Host 不使用浏览器。
474
638
  - owner CLI `activate`:读取/复制/rename/恢复 DSH profile,并执行固定 DSH executable。
475
639
  - owner CLI `probe`:执行固定 Host attestor,只有严格 allowlist 环境;不读取 attestation 私钥,不使用 shell或网络客户端。
476
640
  - owner CLI `scaffold`:仅在审批绑定的 linked worktree 中运行固定边界内的 `git` / `pnpm`。
477
641
  - owner CLI release 命令:读取 owner-private release authorization 或人工签名 receipt,写 release operation SQLite 状态,并只执行 trust 中固定的 adapter executable;publish reconciliation 只接受独立 registry verifier 的签名 receipt,不接受裸 observation。
478
- - 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 会执行。
479
- - 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。
642
+ - 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,安装之后执行精确提交中的工作区根 build(若存在)以及目标包 build/pack lifecycle,以便先构建工作区依赖。
643
+ - build adapter 不接受调用方或通用 config 注入任意命令/argv;它只运行固定的 offline frozen install、可选 workspace root build、package build 与 `pnpm pack` 流程。pnpm runtime tree 必须在根目录提供 config 分别固定的 `node` 与 `pnpm` 原生 executable;整棵 runtime tree、离线 store 和可选 `build.cacheRoot: { path, sha256 }` 策略元数据目录再以 canonical owner/root-owned、非 group/world-writable 的递归 inventory digest 固定并只读挂载,因此不依赖宿主 `PATH` 中是否存在 Node。存在 cacheRoot 时固定挂到只读 `/cache` 并设置 pnpm 的 cache 路径;它保留供应链策略校验,不允许缺少缓存时联网补齐。旧的六字段配置仍可用于不需要元数据缓存的依赖集合。沙箱内 `/bin` 指向只读 `/usr/bin`,支持包管理器生成的 shell shebang。每轮只给 disposable workspace 与 pack output 写权限。私钥路径与 config path 不出现在 durable request。生产部署应为 PR/review、review/merge、build/sign、sign/publish 和 publish/registry-verify 配置独立 executable identity、进程状态目录及 signing authority/key。
480
644
  - 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 到签名进程。
481
645
  - 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 父目录无写权限。
482
646
  - local artifact activation 在安装期间持续持有已验证 cache inode,并把 `/proc/<control-plane-pid>/fd/<n>` reference 交给 DSH;registered DSH executor 及其解释器也从已验证 descriptor 启动。该路径是 Linux-only,且不会把 `release-complete` 视为 activation。
483
647
 
484
648
  兼容性见仓库 [compatibility baseline](../../docs/compatibility.md)。Node.js 要求 `^22.19.0 || >=24.0.0`(使用 `node:sqlite`)。
485
649
 
486
- 物理 Host 回退使用随包 systemd attestor v5 的 schema-3 配置与 schema-2 请求,复用 `probe --prepare-only` / `probe`。回退前固定原始三份 core 文件摘要;文件恢复后固定 fence,重试同一个持久化操作只重新观察,不再次 restart/stop。原 profile 不存在时只允许 stop。详情与环境约束见[操作文档](../../docs/systemd-host-attestor.md#physical-rollback)。
650
+ 物理 Host 回退使用随包 systemd attestor v6 的 schema-3 配置与 schema-2 请求,复用 `probe --prepare-only` / `probe`。回退前固定原始三份 core 文件摘要;文件恢复后固定 fence,重试同一个持久化操作只重新观察,不再次 restart/stop。原 profile 不存在时只允许 stop。详情与环境约束见[操作文档](../../docs/systemd-host-attestor.md#physical-rollback)。
487
651
 
488
652
  ## 原生阻断回放组件
489
653
 
@@ -532,3 +696,7 @@ taskObservations:
532
696
  每个批次包含同一实际部署下、不同真实任务的当前 `achieved/not-achieved` owner 反馈或独立 verifier 结果;unknown、撤回、截断或非静止任务不计票。批次内任一失败触发 `regressed`,否则为 `healthy`。这是 owner 明确选择的部署任务组策略,不能证明某个工具被调用或该版本造成结果。相同任务的相同 canonical revision 只落账一次;后续纠正可形成新观察。批次身份、grant/key 指纹、签名次数和回执持久化,重启重试复用原回执,不延长期限。政策最多 1,000 次观察、每批 1–32 个任务、回看 1 秒至 30 天。
533
697
 
534
698
  Host 在冻结批次、签名前后与最终落账时重读来源;最终 Evaluation writer fence 包裹控制面 SQLite 事务,同步写入 watch 和 applied 状态。签名器验证有限策略及已记录部署事实,可信任务质量来自 Host 当前 canonical 读取;它不是另一次独立模型评分,也不构成同 UID 文件隔离。签名期间纠正、撤回或部署变化阻止旧观察落账。已落账的回滚决定保留审计,后续反馈变更不取消恢复义务;cron 复用现有物理恢复/Host attestor 回执链,失败保留待恢复状态。进程重启可继续,主动卸载会暂停对应 cron、取消并等待在途执行,再关闭连接。owner/trust 被撤销、目标 Host 自身重启或资源无法释放时仍需外部控制面/CLI 完成恢复,不能承诺目标 Host 单独完成自重启恢复。
699
+
700
+ ### 有限真实任务试用采用
701
+
702
+ 可显式配置 `sourceAdoptions.liveQualification` 与 `liveQualification`,经独立源码审查和真实 reload/readiness 后,用当前 owner 的普通任务反馈决定采用或回退。合同、独立签名、原生预算、期限、最终 canonical 复核及运行边界见[有限试用采用](../../docs/bounded-live-adoption.md)。缺省严格验收顺序不变;新模式不签发 shadow/零副作用凭证,不限制整个 profile 的曝光次数。
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { realpathSync } from 'node:fs'
4
+ import { dirname, join } from 'node:path'
5
+ import { pathToFileURL } from 'node:url'
6
+
7
+ try {
8
+ const wrapper = realpathSync(process.argv[1])
9
+ const modulePath = join(dirname(wrapper), '../lib/live-qualification-authority.js')
10
+ const { runLiveQualificationAuthority } = await import(pathToFileURL(modulePath).href)
11
+ await runLiveQualificationAuthority()
12
+ } catch {
13
+ process.stderr.write('live qualification authority refused the request\n')
14
+ process.exitCode = 1
15
+ }