@sema-agent/server 7.149.0 → 7.150.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/MIGRATION.md +122 -9
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/USAGE.md +39 -15
  5. package/dist/approval-card.d.ts +1 -1
  6. package/dist/approval-gate-currency.d.ts +1 -1
  7. package/dist/audit.d.ts +1 -1
  8. package/dist/audit.js +2 -2
  9. package/dist/background-session-reap.d.ts +1 -1
  10. package/dist/boot/deferred-sandbox-path-env.d.ts +5 -3
  11. package/dist/boot/deferred-sandbox-path-env.js +1 -2
  12. package/dist/boot/parked-revive-gate.d.ts +5 -5
  13. package/dist/boot/parked-revive-gate.js +2 -3
  14. package/dist/boot/resolve-spec.d.ts +4 -5
  15. package/dist/boot/resolve-spec.js +61 -25
  16. package/dist/boot/retention-lane.d.ts +1 -1
  17. package/dist/boot/session-faces.js +21 -21
  18. package/dist/boot/stage-03-store-backend.js +2 -2
  19. package/dist/boot/stage-06-runners.js +1 -2
  20. package/dist/boot/stage-07-capability-layer.js +1 -1
  21. package/dist/boot/stage-10-http-server.d.ts +33 -1
  22. package/dist/boot/stage-10-http-server.js +9 -4
  23. package/dist/boot/web-admin.d.ts +1 -1
  24. package/dist/capability-facts.d.ts +65 -56
  25. package/dist/capability-facts.js +42 -35
  26. package/dist/config-catalog.js +1 -1
  27. package/dist/config-types.d.ts +12 -11
  28. package/dist/deployment-governance.d.ts +7 -28
  29. package/dist/deployment-governance.js +1 -14
  30. package/dist/device-ws-hub.d.ts +1 -0
  31. package/dist/device-ws-hub.js +64 -28
  32. package/dist/device-ws-protocol.d.ts +20 -6
  33. package/dist/device-ws-protocol.js +9 -2
  34. package/dist/engine-identity.d.ts +7 -1
  35. package/dist/engine-identity.js +5 -0
  36. package/dist/field-conflict.d.ts +2 -2
  37. package/dist/fleet/engine-signal.d.ts +14 -1
  38. package/dist/fleet/engine-signal.js +5 -1
  39. package/dist/fleet/fleet-reconciler.d.ts +1 -1
  40. package/dist/fleet/serving-lease.d.ts +18 -3
  41. package/dist/fleet/serving-lease.js +81 -35
  42. package/dist/fleet-client.d.ts +13 -11
  43. package/dist/fleet-client.js +53 -33
  44. package/dist/history-anchor.js +1 -1
  45. package/dist/hitl-delivery.d.ts +1 -3
  46. package/dist/hitl-delivery.js +1 -1
  47. package/dist/http/active-run-conflict.d.ts +3 -7
  48. package/dist/http/active-run-conflict.js +2 -2
  49. package/dist/http/admission.js +2 -2
  50. package/dist/http/approval-sweeps.js +2 -1
  51. package/dist/http/caller-trust.d.ts +2 -2
  52. package/dist/http/caller-trust.js +3 -3
  53. package/dist/http/checkpoint-ctx.d.ts +18 -63
  54. package/dist/http/checkpoint-ctx.js +1 -24
  55. package/dist/http/claim-heartbeat.d.ts +4 -4
  56. package/dist/http/claim-heartbeat.js +3 -3
  57. package/dist/http/dispatch.js +2 -2
  58. package/dist/http/durable-run-leg.js +4 -4
  59. package/dist/http/owner-access.d.ts +243 -19
  60. package/dist/http/owner-access.js +184 -5
  61. package/dist/http/readiness.d.ts +4 -2
  62. package/dist/http/resume-ctx-read.js +16 -1
  63. package/dist/http/resume-legs.js +18 -14
  64. package/dist/http/route-ctx.d.ts +23 -11
  65. package/dist/http/routes/a2a-serve.js +15 -14
  66. package/dist/http/routes/approvals-assistant.d.ts +3 -2
  67. package/dist/http/routes/approvals-assistant.js +8 -9
  68. package/dist/http/routes/capabilities.js +4 -3
  69. package/dist/http/routes/config-catalog.d.ts +1 -1
  70. package/dist/http/routes/mcp-reconnect.js +2 -2
  71. package/dist/http/routes/memory-origin.d.ts +1 -1
  72. package/dist/http/routes/notify-wake.js +2 -3
  73. package/dist/http/routes/projects.d.ts +1 -0
  74. package/dist/http/routes/projects.js +5 -3
  75. package/dist/http/routes/retention-ops.d.ts +1 -1
  76. package/dist/http/routes/run-permission-mode.d.ts +1 -1
  77. package/dist/http/routes/run-permission-mode.js +2 -2
  78. package/dist/http/routes/runs.d.ts +1 -1
  79. package/dist/http/routes/runs.js +23 -30
  80. package/dist/http/routes/session-memory-sync.js +4 -5
  81. package/dist/http/routes/session-sync.js +3 -7
  82. package/dist/http/routes/sessions.d.ts +1 -1
  83. package/dist/http/routes/sessions.js +18 -44
  84. package/dist/http/routes/tasks.js +9 -8
  85. package/dist/http/routes/trace-usage.js +14 -14
  86. package/dist/http/routes/workflows.d.ts +1 -0
  87. package/dist/http/routes/workflows.js +20 -38
  88. package/dist/http/server.d.ts +8 -4
  89. package/dist/http/server.js +5 -1
  90. package/dist/http/stored-body-replay.d.ts +3 -24
  91. package/dist/http/stored-body-replay.js +2 -12
  92. package/dist/http/submit-ctx.d.ts +1 -2
  93. package/dist/http/submit-ctx.js +3 -2
  94. package/dist/http/submit-replay.d.ts +15 -2
  95. package/dist/http/submit-replay.js +10 -4
  96. package/dist/http/wire-types.d.ts +6 -3
  97. package/dist/leader/endpoint.js +9 -8
  98. package/dist/leg-facts.d.ts +8 -2
  99. package/dist/leg-facts.js +1 -0
  100. package/dist/mcp-authorization-face.d.ts +18 -14
  101. package/dist/mcp-authorization-face.js +3 -2
  102. package/dist/memory-store-refusal.d.ts +1 -1
  103. package/dist/observability/corrupt-read-seat.d.ts +1 -1
  104. package/dist/observability/fail-open.d.ts +5 -5
  105. package/dist/observability/fail-open.js +5 -5
  106. package/dist/observability/logger.d.ts +7 -0
  107. package/dist/observability/logger.js +3 -1
  108. package/dist/observability/run-terminal.d.ts +1 -1
  109. package/dist/owner-faces.d.ts +27 -3
  110. package/dist/owner-faces.js +2 -0
  111. package/dist/peer-seat.d.ts +1 -1
  112. package/dist/peer-seat.js +52 -59
  113. package/dist/plugins/exec-path-law.d.ts +34 -0
  114. package/dist/plugins/exec-path-law.js +13 -0
  115. package/dist/plugins/file-run-store.js +1 -1
  116. package/dist/plugins/local-checkpoint-store.d.ts +4 -1
  117. package/dist/plugins/local-checkpoint-store.js +3 -0
  118. package/dist/plugins/memory-run-store.js +1 -1
  119. package/dist/plugins/one-time-migrations.d.ts +74 -49
  120. package/dist/plugins/one-time-migrations.js +134 -69
  121. package/dist/plugins/pg-pool.js +4 -0
  122. package/dist/plugins/posix-shell-fs.js +4 -2
  123. package/dist/plugins/remote-env-adb.js +3 -2
  124. package/dist/plugins/remote-env-device.js +8 -6
  125. package/dist/plugins/remote-env-e2b.d.ts +3 -1
  126. package/dist/plugins/remote-env-e2b.js +11 -8
  127. package/dist/plugins/remote-env-host.d.ts +1 -1
  128. package/dist/plugins/remote-env-host.js +20 -11
  129. package/dist/plugins/remote-env-k8s.js +3 -2
  130. package/dist/plugins/remote-env-local-docker.js +3 -2
  131. package/dist/plugins/remote-env-ssh.js +4 -3
  132. package/dist/plugins/remote-shell.d.ts +3 -1
  133. package/dist/plugins/remote-shell.js +3 -3
  134. package/dist/plugins/replica-registration.d.ts +35 -0
  135. package/dist/plugins/replica-registration.js +48 -0
  136. package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
  137. package/dist/plugins/run-store-sql.d.ts +1 -1
  138. package/dist/plugins/run-store-sql.js +2 -2
  139. package/dist/plugins/scenario-prefix-switch-m42.d.ts +6 -12
  140. package/dist/plugins/scenario-prefix-switch-m42.js +7 -5
  141. package/dist/plugins/schema-consistency.d.ts +7 -5
  142. package/dist/plugins/schema-consistency.js +29 -16
  143. package/dist/plugins/schema-drift-sentence.js +1 -1
  144. package/dist/plugins/serving-requirement.d.ts +49 -0
  145. package/dist/plugins/serving-requirement.js +53 -0
  146. package/dist/plugins/stop-then-start-sentence.d.ts +42 -3
  147. package/dist/plugins/stop-then-start-sentence.js +44 -0
  148. package/dist/plugins/store-backend.d.ts +1 -1
  149. package/dist/plugins/store-contracts.d.ts +12 -2
  150. package/dist/plugins/store-contracts.js +3 -0
  151. package/dist/plugins/tidb-pool.js +4 -0
  152. package/dist/process-instance.d.ts +3 -0
  153. package/dist/process-instance.js +7 -0
  154. package/dist/project-context.d.ts +66 -0
  155. package/dist/project-context.js +70 -0
  156. package/dist/question.d.ts +9 -21
  157. package/dist/question.js +28 -19
  158. package/dist/run-cancel-card.d.ts +1 -1
  159. package/dist/run-cancel-card.js +2 -1
  160. package/dist/security.d.ts +1 -1
  161. package/dist/session-agent.d.ts +1 -10
  162. package/dist/session-agent.js +0 -6
  163. package/dist/session-incarnation.d.ts +18 -4
  164. package/dist/session-incarnation.js +4 -1
  165. package/dist/session-notify-door.d.ts +4 -4
  166. package/dist/session-notify-door.js +5 -6
  167. package/dist/session-rules-seat.d.ts +4 -3
  168. package/dist/session-rules-seat.js +3 -11
  169. package/dist/session-sync.js +3 -3
  170. package/dist/stores-sql/checkpoint-store-sql.d.ts +21 -2
  171. package/dist/stores-sql/checkpoint-store-sql.js +106 -18
  172. package/dist/stores-sql/retention-store-sql.d.ts +1 -1
  173. package/dist/task-cwd.d.ts +4 -3
  174. package/dist/task-settings.d.ts +13 -0
  175. package/dist/task-settings.js +13 -7
  176. package/dist/tool-approval.d.ts +7 -6
  177. package/dist/tool-approval.js +41 -37
  178. package/dist/trace/engine-notice-wire.d.ts +14 -0
  179. package/dist/trace/engine-notice-wire.js +18 -1
  180. package/dist/trace/project.d.ts +4 -3
  181. package/dist/trace/project.js +3 -2
  182. package/dist/trace/projection-table.d.ts +33 -2
  183. package/dist/trace/self-minted-wire.d.ts +150 -17
  184. package/dist/trace/self-minted-wire.js +54 -16
  185. package/dist/trace/tool-card.d.ts +3 -0
  186. package/dist/trace/tool-card.js +24 -0
  187. package/dist/trace/tool-output-media.d.ts +2 -1
  188. package/dist/unattended-permission-mode.d.ts +1 -1
  189. package/dist/web-admin-client/apply-effective.d.ts +1 -1
  190. package/dist/web-admin-client/effective-keys.d.ts +1 -1
  191. package/dist/web-admin-client/skills-mcp.d.ts +1 -1
  192. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -29
  193. package/package.json +2 -2
  194. package/wire-changes/server@7.150.0.json +335 -0
@@ -25,7 +25,6 @@ import type { ServiceBlobExchange, ServiceFileHistoryStore } from "./plugins/sto
25
25
  import { resolveStreamApprovalGate, type ApprovalFrameFamily } from "./tool-approval.js";
26
26
  import { type WorkspaceSyncCapability } from "./workspace-space.js";
27
27
  import type { WorkspaceCacheCapability } from "./workspace-cache.js";
28
- import { type HeadRead } from "./session-incarnation.js";
29
28
  import type { HistoryAnchorReaders } from "./history-anchor.js";
30
29
  import type { EngineHandoverDoor } from "./boot/engine-lease.js";
31
30
  /** why 闭集:词 → 给运维看的一句义(诊断 / 测试读它;wire 上的拒句由各门自写)。 */
@@ -120,29 +119,40 @@ type Store<K extends keyof Deps> = NonNullable<Deps[K]>;
120
119
  type WithMethods<T, K extends keyof T> = T & {
121
120
  [P in K]-?: NonNullable<T[P]>;
122
121
  };
122
+ /**
123
+ * 见证里的 run 店 / 会话店 / 会话视图读**随调用方交来的 deps**(`D`):路由层交的是封住的视图(`route-ctx.ts` 的 `RouteDeps`:带属主的读口在型上调不了)⇒ 见证照样封着
124
+ * (方法在不在照判,见证交给属主存取器的口照读);装配层交完整的店 ⇒ 见证完整。事实不另开一扇读口(视图只在 `owner-access.ts` 的 `sealRouteDeps` 铸一次)。
125
+ */
126
+ type Held<D, K extends keyof D> = NonNullable<D[K]>;
127
+ /** 判过在场的方法(`K`)在见证上必有;封住的读口在场照样封着(`never`)。 */
128
+ type Present<T, K extends PropertyKey> = T & {
129
+ [P in K]-?: NonNullable<P extends keyof T ? T[P] : never>;
130
+ };
123
131
  /** 持久 run 账面在场 —— `/v1/runs/*` 族、trace / 用量统计、assistant 的 preempt / resume / plan-review、
124
132
  * 会话 detach、设备换绑都站在这一只事实上。 */
125
- export declare function durableRuns(d: Pick<Deps, "runStore">): Fact<"run_store_absent", {
126
- runStore: Store<"runStore">;
133
+ export declare function durableRuns<D extends Pick<Deps, "runStore">>(d: D): Fact<"run_store_absent", {
134
+ runStore: Held<D, "runStore">;
127
135
  }>;
128
- export declare function subagentSteer(d: Pick<Deps, "runStore" | "subagentSteerRegistry">): Fact<"run_store_absent" | "subagent_registry_absent", {
129
- runStore: Store<"runStore">;
136
+ export declare function subagentSteer<D extends Pick<Deps, "runStore" | "subagentSteerRegistry">>(d: D): Fact<"run_store_absent" | "subagent_registry_absent", {
137
+ runStore: Held<D, "runStore">;
130
138
  registry: Store<"subagentSteerRegistry">;
131
139
  }>;
132
- export declare function subagentOutput(d: Pick<Deps, "runStore" | "subagentTaskOutput">): Fact<"run_store_absent" | "subagent_output_face_absent", {
133
- runStore: Store<"runStore">;
140
+ export declare function subagentOutput<D extends Pick<Deps, "runStore" | "subagentTaskOutput">>(d: D): Fact<"run_store_absent" | "subagent_output_face_absent", {
141
+ runStore: Held<D, "runStore">;
134
142
  output: Store<"subagentTaskOutput">;
135
143
  }>;
136
- export declare function taskHandles(d: Pick<Deps, "runStore" | "taskHandleOutput" | "taskHandleStop">): Fact<"run_store_absent" | "task_handle_faces_absent", {
137
- runStore: Store<"runStore">;
144
+ export declare function taskHandles<D extends Pick<Deps, "runStore" | "taskHandleOutput" | "taskHandleStop">>(d: D): Fact<"run_store_absent" | "task_handle_faces_absent", {
145
+ runStore: Held<D, "runStore">;
138
146
  output: Store<"taskHandleOutput">;
139
147
  stop: Store<"taskHandleStop">;
140
148
  }>;
141
149
  /** 会话店按 id 读一行的唯一读口在场(core `headOf`:属主 / 住客 / 叶子一次读;「有没有」与 `session-incarnation.ts` 的 `headReadOf` 同判)。 */
142
- type HeadReadingSessionStore = WithMethods<OwnerAwareSessionStore, "headOf">;
150
+ type SessionDeps = Pick<Deps, "sessionStorage">;
151
+ type SessionWith<D extends SessionDeps, K extends PropertyKey> = Present<Held<D, "sessionStorage">, K>;
152
+ type HeadReadingSessionStore<D extends SessionDeps> = SessionWith<D, "headOf">;
143
153
  /** 会话属主面在场(入站 owner 门的地基;缺它,带会话的门一律 fail-closed)。属主 = `headOf(id)?.owner`。 */
144
- export declare function sessionOwnership(d: Pick<Deps, "sessionStorage">): Fact<"session_head_face_absent", {
145
- sessionStorage: HeadReadingSessionStore;
154
+ export declare function sessionOwnership<D extends SessionDeps>(d: D): Fact<"session_head_face_absent", {
155
+ sessionStorage: HeadReadingSessionStore<D>;
146
156
  }>;
147
157
  /**
148
158
  * 执行放置读面在场:会话店带执行席(`executionPlacement`:一次行读 = 住客 + 执行放置格;SQL 两孪生与 local 恒带,引擎缺省的内存会话店没有)。
@@ -151,66 +161,62 @@ export declare function sessionOwnership(d: Pick<Deps, "sessionStorage">): Fact<
151
161
  export declare function executionPlacementRead(d: Pick<Deps, "sessionStorage">): Fact<"execution_placement_seat_absent", {
152
162
  seat: NonNullable<OwnerAwareSessionStore["executionPlacement"]>;
153
163
  }>;
154
- export declare function mcpReconnect(d: Pick<Deps, "runStore" | "sessionStorage">): Fact<"run_store_absent" | "session_head_face_absent", {
155
- runStore: Store<"runStore">;
156
- sessionStorage: HeadReadingSessionStore;
164
+ export declare function mcpReconnect<D extends Pick<Deps, "runStore" | "sessionStorage">>(d: D): Fact<"run_store_absent" | "session_head_face_absent", {
165
+ runStore: Held<D, "runStore">;
166
+ sessionStorage: HeadReadingSessionStore<D>;
157
167
  }>;
158
168
  /**
159
169
  * 在飞 run 的切档口(`POST /v1/runs/:id/permission-mode`)= 持久 run 账面 ∧ checkpoint 店(ctx 面)。后一格是承重的:切档要读这条 run 的
160
170
  * **存储体**(本任务 settings 的 kill-switch 由受理判官折,与提交口同一份事实),也要把准入的词写回存储体(run 模式词的唯一来源,续跑腿读它);
161
171
  * 没有 ctx 面的部署两件都做不了 ⇒ 不提供这一口(能力位 `permissionModeWrite` 同读本事实)。
162
172
  */
163
- export declare function permissionModeWrite(d: Pick<Deps, "runStore" | "checkpointStore">): Fact<"run_store_absent" | "checkpoint_store_absent", {
164
- runStore: Store<"runStore">;
173
+ export declare function permissionModeWrite<D extends Pick<Deps, "runStore" | "checkpointStore">>(d: D): Fact<"run_store_absent" | "checkpoint_store_absent", {
174
+ runStore: Held<D, "runStore">;
165
175
  checkpointStore: Store<"checkpointStore">;
166
176
  }>;
167
- export declare function sessionAuditView(d: Pick<Deps, "sessionAudit">): Fact<"session_audit_absent", {
168
- sessionAudit: Store<"sessionAudit">;
177
+ export declare function sessionAuditView<D extends Pick<Deps, "sessionAudit">>(d: D): Fact<"session_audit_absent", {
178
+ sessionAudit: Held<D, "sessionAudit">;
169
179
  }>;
170
180
  /** 会话 SSE(watch 注册表 ∧ 头读:属主门与叶子都是 `headOf` 的投影)。 */
171
- export declare function sessionEventStream(d: Pick<Deps, "sessionWatch" | "sessionStorage">): Fact<"session_watch_absent" | "session_head_face_absent", {
181
+ export declare function sessionEventStream<D extends Pick<Deps, "sessionWatch" | "sessionStorage">>(d: D): Fact<"session_watch_absent" | "session_head_face_absent", {
172
182
  watch: Store<"sessionWatch">;
173
- sessionStorage: HeadReadingSessionStore;
183
+ sessionStorage: HeadReadingSessionStore<D>;
174
184
  }>;
175
185
  type SessionLister = NonNullable<OwnerAwareSessionStore["listSessions"]>;
176
186
  /** 会话枚举面:会话店的 `listSessions` —— 唯一的会话 lister(run 店不列会话:只有 run 行、没有会话行的面答不了「有哪些会话」)。见证 = 已绑好宿主的那一只。 */
177
187
  export declare function sessionList(d: Pick<Deps, "sessionStorage">): Fact<"session_lister_absent", {
178
188
  lister: SessionLister;
179
189
  }>;
180
- export declare function sessionFork(d: Pick<Deps, "sessionStorage">): Fact<"session_fork_face_absent" | "session_head_face_absent", {
181
- sessionStorage: WithMethods<OwnerAwareSessionStore, "headOf" | "fork">;
190
+ export declare function sessionFork<D extends SessionDeps>(d: D): Fact<"session_fork_face_absent" | "session_head_face_absent", {
191
+ sessionStorage: SessionWith<D, "headOf" | "fork">;
182
192
  }>;
183
193
  /** 会话行可写位(`PATCH /v1/sessions/:id`):会话店的头读(属主 + 化身一次读 —— 门判属主,那一读就是写原语的行期望)∧ 行格写原语(锁内判、提交后另读应答行)。
184
194
  * 三只 durable 店(SQL 双生 / local)都带;内存 dev 店没有行写口 ⇒ 501。
185
195
  * 本面**没有**独立能力位(契约附录 B.2c 登记):老 worker 对这一动词答 405,本事实为假的部署答 501;条件写也没有 —— 列表行上有 `rowTag` 即支持。 */
186
- export declare function sessionPatch(d: Pick<Deps, "sessionStorage">): Fact<"session_row_faces_absent", {
187
- sessionStorage: WithMethods<OwnerAwareSessionStore, "headOf" | "writeSessionRowCells">;
196
+ export declare function sessionPatch<D extends SessionDeps>(d: D): Fact<"session_row_faces_absent", {
197
+ sessionStorage: SessionWith<D, "headOf" | "writeSessionRowCells">;
188
198
  }>;
189
- /** 删除门读的会话店视图:按 id 读 = 删除门那一只头读,行格的 placement 问询 = 店自己的那一只。门照旧由属主存取器读头(`admitSessionById`),读的就是这一只。 */
190
- type DeletionGateStore = Pick<OwnerAwareSessionStore, "placementOf"> & {
191
- readonly headOf: HeadRead;
192
- };
193
199
  /**
194
- * 会话删除面(purge 协调器 ∧ 删除门的头读)。见证 = 协调器 + 删除门的店视图 {@link DeletionGateStore}:按 id 读是 `deletionHeadReadOf`(local 店删到一半的行也答得出属主,
195
- * 开始删它的那位重发收得完;别的店 = `headOf`)—— 与协调器围栏读同一只。
200
+ * 会话删除面(purge 协调器 ∧ 会话店的头读)。见证 = 协调器 + 判过头读在场的会话店;删除门读哪一只头(删到一半的行也答得出属主的那一只,与协调器围栏读同一只)
201
+ * 只由属主存取器的删除口判(`owner-access.ts` 的 `admitSessionForDeletion`)。
196
202
  */
197
- export declare function sessionDelete(d: Pick<Deps, "purgeSession" | "sessionStorage">): Fact<"session_purge_absent" | "session_head_face_absent", {
203
+ export declare function sessionDelete<D extends Pick<Deps, "purgeSession" | "sessionStorage">>(d: D): Fact<"session_purge_absent" | "session_head_face_absent", {
198
204
  purge: Store<"purgeSession">;
199
- gateStore: DeletionGateStore;
205
+ sessionStorage: HeadReadingSessionStore<D>;
200
206
  }>;
201
- export declare function sessionPolicy(d: Pick<Deps, "sessionPolicyStore" | "sessionStorage">): Fact<"session_policy_store_absent" | "session_head_face_absent", {
207
+ export declare function sessionPolicy<D extends Pick<Deps, "sessionPolicyStore" | "sessionStorage">>(d: D): Fact<"session_policy_store_absent" | "session_head_face_absent", {
202
208
  policyStore: Store<"sessionPolicyStore">;
203
- sessionStorage: HeadReadingSessionStore;
209
+ sessionStorage: HeadReadingSessionStore<D>;
204
210
  }>;
205
- type SyncSessionStore = WithMethods<OwnerAwareSessionStore, "exportEntries" | "exportEntriesStream" | "beginImportStaging" | "headOf" | "sessionSummaryOf" | "writeSessionRowCells">;
211
+ type SyncSessionStore<D extends SessionDeps> = SessionWith<D, "exportEntries" | "exportEntriesStream" | "beginImportStaging" | "headOf" | "sessionSummaryOf" | "writeSessionRowCells">;
206
212
  type SessionSyncWhy = "store_backend_absent" | "file_history_store_absent" | "session_export_absent" | "session_import_staging_absent" | "session_row_faces_absent" | "policy_purge_absent";
207
213
  /** 会话对等同步的**对话半族**(manifest / entries / plan / import 两相):后端 ∧ 文件历史店 ∧ 导出两面 ∧ staged 导入面 ∧
208
214
  * 会话行三口(门读头 `headOf` —— 属主 + 化身一次读,属主判门、化身给 identical 短路腿;manifest 带 `title` / `pinned`;导入经行格写原语以 `replay` 写者
209
215
  * 按导入落定的那一位住客重放它们)∧ policy 店能清(overwrite-dst 的 commit 要擦目的端旧 policy 行)。
210
216
  * 文件历史的 blob 搬运是另一只事实。 */
211
- export declare function sessionSync(d: Pick<Deps, "backend" | "sessionStorage" | "fileHistoryStore" | "sessionPolicyStore">): Fact<SessionSyncWhy, {
212
- backend: Store<"backend">;
213
- sessionStorage: SyncSessionStore;
217
+ export declare function sessionSync<D extends Pick<Deps, "backend" | "sessionStorage" | "fileHistoryStore" | "sessionPolicyStore">>(d: D): Fact<SessionSyncWhy, {
218
+ backend: Held<D, "backend">;
219
+ sessionStorage: SyncSessionStore<D>;
214
220
  historyStore: ServiceFileHistoryStore;
215
221
  }>;
216
222
  /** 会话同步的**文件历史半族**:对话半族 ∧ 文件历史店带 blob 交换组(只有 SQL 两只店有)。「店能不能交换 blob」只在 `blobExchangeOf` 判一次(core 判官),
@@ -231,10 +237,12 @@ type RewindFilesWhy = "file_history_store_absent" | "session_head_face_absent" |
231
237
  * 动词本身是引擎 `Runner` 的必有成员(型上必在),不是一格。
232
238
  * 见证 = 判过在场的设施(历史店 · 手柄翻译的两只读店 · 会话店);路由在拒臂之后只读见证。
233
239
  */
234
- export declare function sessionRewindFiles(d: Pick<Deps, "fileHistoryStore" | "resumeAnchorStore" | "runStore" | "sessionStorage" | "config" | "backend">): Fact<RewindFilesWhy, {
240
+ export declare function sessionRewindFiles<D extends Pick<Deps, "fileHistoryStore" | "resumeAnchorStore" | "runStore" | "sessionStorage" | "config" | "backend">>(d: D): Fact<RewindFilesWhy, {
235
241
  historyStore: ServiceFileHistoryStore;
236
- anchors: HistoryAnchorReaders;
237
- sessionStorage: HeadReadingSessionStore;
242
+ anchors: HistoryAnchorReaders & {
243
+ readonly runs: Held<D, "runStore">;
244
+ };
245
+ sessionStorage: HeadReadingSessionStore<D>;
238
246
  }>;
239
247
  /**
240
248
  * 同一口的 `dryRun` **带不带改动统计** —— 能力位 `sessionRewindFilesPreview`。= 立即回退可用 ∧ 店实现了 core 契约的可选座 `diffStats`
@@ -291,11 +299,11 @@ export declare function deviceLane(d: Pick<Deps, "deviceHub">): Fact<"device_hub
291
299
  hub: Store<"deviceHub">;
292
300
  }>;
293
301
  /** 设备管理三动词(列 / 读 / 换绑):hub ∧ 设备店 ∧ 入网 ∧ 持久 run 账面(换绑的「无在飞 run」门要它)。 */
294
- export declare function deviceManagement(d: Pick<Deps, "deviceHub" | "deviceStore" | "deviceEnrollment" | "runStore">): Fact<"device_hub_absent" | "device_store_absent" | "device_enrollment_absent" | "run_store_absent", {
302
+ export declare function deviceManagement<D extends Pick<Deps, "deviceHub" | "deviceStore" | "deviceEnrollment" | "runStore">>(d: D): Fact<"device_hub_absent" | "device_store_absent" | "device_enrollment_absent" | "run_store_absent", {
295
303
  hub: Store<"deviceHub">;
296
304
  store: Store<"deviceStore">;
297
305
  enrollment: Store<"deviceEnrollment">;
298
- runStore: Store<"runStore">;
306
+ runStore: Held<D, "runStore">;
299
307
  }>;
300
308
  export declare function fleetStream(d: Pick<Deps, "fleetBus">): Fact<"fleet_bus_absent", {
301
309
  fleetBus: Store<"fleetBus">;
@@ -344,10 +352,10 @@ export declare function memorySyncServe(d: Pick<Deps, "memorySync" | "config">):
344
352
  * 会话记忆同步触发口(`POST /v1/sessions/:id/memory/sync`):本机同步腿在场 ∧ 持久 run 账面(读集 = 会话最近一条已结腿的记忆观测;收割栅栏读会话的 run 认领)
345
353
  * ∧ 会话头读(属主门与 `sourceRevision` = 同一次头读的叶子)。
346
354
  */
347
- export declare function sessionMemorySync(d: Pick<Deps, "memorySyncLeg" | "runStore" | "sessionStorage">): Fact<"memory_sync_leg_absent" | "run_store_absent" | "session_head_face_absent", {
355
+ export declare function sessionMemorySync<D extends Pick<Deps, "memorySyncLeg" | "runStore" | "sessionStorage">>(d: D): Fact<"memory_sync_leg_absent" | "run_store_absent" | "session_head_face_absent", {
348
356
  leg: Store<"memorySyncLeg">;
349
- runStore: Store<"runStore">;
350
- sessionStorage: HeadReadingSessionStore;
357
+ runStore: Held<D, "runStore">;
358
+ sessionStorage: HeadReadingSessionStore<D>;
351
359
  }>;
352
360
  /** 跨主体投递门在座(`POST /v1/principal-inbox/messages` 的可用性门与能力位 `principalInboxDelivery` 同读这一只)。门的装配本身是
353
361
  * 一道合取(收件箱消费方声明 ∧ 耐久 mailbox ∧ org 成员目录 ∧ 配额店,缺一拒启 —— `boot/stage-06-runners.ts`),
@@ -368,20 +376,21 @@ export declare function engineHandover(d: Pick<Deps, "drainState">): Fact<"engin
368
376
  export declare function operatorLane(d: {
369
377
  readonly config: Pick<ServiceConfig, "operatorPrincipals" | "operatorSingleUser">;
370
378
  }): Fact<"operator_principals_empty">;
371
- type AdoptionCapableBackend = Store<"backend"> & {
379
+ /** 带收编日志的后端(见证随调用方的 deps:路由层的后端视图上店工厂照样封着)。 */
380
+ type AdoptionCapableBackend<D extends Pick<Deps, "backend">> = Held<D, "backend"> & {
372
381
  adoptionLog(): ReturnType<NonNullable<Store<"backend">["adoptionLog"]>>;
373
382
  };
374
- export declare function adoption(d: Pick<Deps, "config" | "backend">): Fact<"operator_principals_empty" | "adoption_store_absent", {
375
- backend: AdoptionCapableBackend;
383
+ export declare function adoption<D extends Pick<Deps, "config" | "backend">>(d: D): Fact<"operator_principals_empty" | "adoption_store_absent", {
384
+ backend: AdoptionCapableBackend<D>;
376
385
  }>;
377
- type AdoptionImportSessionStore = WithMethods<OwnerAwareSessionStore, "beginImportStaging">;
386
+ type AdoptionImportSessionStore<D extends SessionDeps> = SessionWith<D, "beginImportStaging">;
378
387
  /**
379
388
  * 收编批量导入(`POST /v1/adoption/:id/sessions`)与能力位 `adoptionImport` 的部署半:收编日志 ∧ 会话店的暂存导入面(派生 id 那一格占没占由提交的属主判答,不另要头读面)。
380
389
  * **不判运维名册**:这扇门不是 operator 面 —— 调用者是那条收编行的源主体本人(名单空了,已收编的行照样在)。
381
390
  */
382
- export declare function adoptionSessionImport(d: Pick<Deps, "backend" | "sessionStorage">): Fact<"adoption_store_absent" | "session_import_staging_absent", {
383
- backend: AdoptionCapableBackend;
384
- sessionStorage: AdoptionImportSessionStore;
391
+ export declare function adoptionSessionImport<D extends Pick<Deps, "backend" | "sessionStorage">>(d: D): Fact<"adoption_store_absent" | "session_import_staging_absent", {
392
+ backend: AdoptionCapableBackend<D>;
393
+ sessionStorage: AdoptionImportSessionStore<D>;
385
394
  }>;
386
395
  export declare function memoryBundle(d: Pick<Deps, "config" | "memoryBundleExport" | "memoryBundleImport">): Fact<"operator_principals_empty" | "memory_bundle_faces_absent", {
387
396
  exportScopes: Store<"memoryBundleExport">;
@@ -417,9 +426,9 @@ export declare function ruleLaneForCaller(d: Pick<Deps, "ruleConsent">, principa
417
426
  export declare function mcpInjection(d: Pick<Deps, "config">): Fact<"caller_mcp_injection_refused">;
418
427
  /** server-as-peer:旋钮开 ∧ 持久 run 账面在场。两只 JSON-RPC 方法(`message/send` / `tasks/get`)都要 run 店 ——
419
428
  * 没有它,这个 peer 什么都做不了,对外就不该存在(卡与 RPC 一起 404)。 */
420
- export declare function a2aServe(d: Pick<Deps, "config" | "runStore">): Fact<"a2a_serve_off" | "run_store_absent", {
429
+ export declare function a2aServe<D extends Pick<Deps, "config" | "runStore">>(d: D): Fact<"a2a_serve_off" | "run_store_absent", {
421
430
  serve: NonNullable<ServiceConfig["a2aServe"]>;
422
- runStore: Store<"runStore">;
431
+ runStore: Held<D, "runStore">;
423
432
  }>;
424
433
  /** 引擎能不能自编排(core 单源 `workflowsCapability`,boot 算好经 `workflowsCapable` 递来;缺席回落行店代理)。 */
425
434
  export declare function selfOrchestrationEngine(d: Pick<Deps, "workflowsCapable" | "workflowRunStore">): Fact<"workflow_engine_absent">;
@@ -7,7 +7,7 @@ import { centerEntitlementSourceWired } from "./runtime-caps-resolver.js";
7
7
  import { WEB_ADMIN_ENV } from "@sema-agent/settings-schema";
8
8
  import { blobExchangeOf, overwriteWipeIncapable } from "./session-sync.js";
9
9
  import { WORKSPACE_PERSIST_DEFAULT, WORKSPACE_SNAPSHOT_KEEP_DEFAULT, workspaceSnapshotTimeoutOf } from "./workspace-space.js";
10
- import { deletionHeadReadOf, headReadOf } from "./session-incarnation.js";
10
+ import { headReadPresent } from "./session-incarnation.js";
11
11
  import { laneWiresExecutionEnv } from "./execution-lane-caps.js";
12
12
  export const CAPABILITY_FACT_WHY = {
13
13
  run_store_absent: "no durable run store is wired (DB_BACKEND=mysql|pg|local)",
@@ -95,25 +95,28 @@ export function subagentSteer(d) {
95
95
  const runs = durableRuns(d);
96
96
  if (!runs.available)
97
97
  return runs;
98
- return d.subagentSteerRegistry !== undefined ? yes({ runStore: runs.runStore, registry: d.subagentSteerRegistry }) : no("subagent_registry_absent");
98
+ const registry = d.subagentSteerRegistry;
99
+ return registry !== undefined ? yes({ runStore: runs.runStore, registry }) : no("subagent_registry_absent");
99
100
  }
100
101
  export function subagentOutput(d) {
101
102
  const runs = durableRuns(d);
102
103
  if (!runs.available)
103
104
  return runs;
104
- return d.subagentTaskOutput !== undefined ? yes({ runStore: runs.runStore, output: d.subagentTaskOutput }) : no("subagent_output_face_absent");
105
+ const output = d.subagentTaskOutput;
106
+ return output !== undefined ? yes({ runStore: runs.runStore, output }) : no("subagent_output_face_absent");
105
107
  }
106
108
  export function taskHandles(d) {
107
109
  const runs = durableRuns(d);
108
110
  if (!runs.available)
109
111
  return runs;
110
- return d.taskHandleOutput !== undefined && d.taskHandleStop !== undefined
111
- ? yes({ runStore: runs.runStore, output: d.taskHandleOutput, stop: d.taskHandleStop })
112
+ const { taskHandleOutput: output, taskHandleStop: stop } = d;
113
+ return output !== undefined && stop !== undefined
114
+ ? yes({ runStore: runs.runStore, output, stop })
112
115
  : no("task_handle_faces_absent");
113
116
  }
114
117
  export function sessionOwnership(d) {
115
118
  const s = d.sessionStorage;
116
- return headReadOf(s) !== undefined ? yes({ sessionStorage: s }) : no("session_head_face_absent");
119
+ return headReadPresent(s) ? yes({ sessionStorage: s }) : no("session_head_face_absent");
117
120
  }
118
121
  export function executionPlacementRead(d) {
119
122
  const seat = d.sessionStorage?.executionPlacement;
@@ -141,12 +144,13 @@ export function sessionAuditView(d) {
141
144
  return d.sessionAudit !== undefined ? yes({ sessionAudit: d.sessionAudit }) : no("session_audit_absent");
142
145
  }
143
146
  export function sessionEventStream(d) {
144
- if (d.sessionWatch === undefined)
147
+ const watch = d.sessionWatch;
148
+ if (watch === undefined)
145
149
  return no("session_watch_absent");
146
150
  const owned = sessionOwnership(d);
147
151
  if (!owned.available)
148
152
  return owned;
149
- return yes({ watch: d.sessionWatch, sessionStorage: owned.sessionStorage });
153
+ return yes({ watch, sessionStorage: owned.sessionStorage });
150
154
  }
151
155
  export function sessionList(d) {
152
156
  const lister = d.sessionStorage?.listSessions?.bind(d.sessionStorage);
@@ -156,52 +160,51 @@ export function sessionFork(d) {
156
160
  const s = d.sessionStorage;
157
161
  if (s?.fork === undefined)
158
162
  return no("session_fork_face_absent");
159
- if (headReadOf(s) === undefined)
163
+ if (!headReadPresent(s))
160
164
  return no("session_head_face_absent");
161
165
  return yes({ sessionStorage: s });
162
166
  }
163
167
  export function sessionPatch(d) {
164
168
  const s = d.sessionStorage;
165
- if (headReadOf(s) === undefined || s?.writeSessionRowCells === undefined)
169
+ if (!headReadPresent(s) || s?.writeSessionRowCells === undefined)
166
170
  return no("session_row_faces_absent");
167
171
  return yes({ sessionStorage: s });
168
172
  }
169
173
  export function sessionDelete(d) {
170
- if (d.purgeSession === undefined)
174
+ const purge = d.purgeSession;
175
+ if (purge === undefined)
171
176
  return no("session_purge_absent");
172
177
  const owned = sessionOwnership(d);
173
178
  if (!owned.available)
174
179
  return owned;
175
- const store = owned.sessionStorage;
176
- const headOf = deletionHeadReadOf(store);
177
- if (headOf === undefined)
178
- return no("session_head_face_absent");
179
- const placementOf = store.placementOf?.bind(store);
180
- return yes({ purge: d.purgeSession, gateStore: { headOf, ...(placementOf !== undefined ? { placementOf } : {}) } });
180
+ return yes({ purge, sessionStorage: owned.sessionStorage });
181
181
  }
182
182
  export function sessionPolicy(d) {
183
- if (d.sessionPolicyStore === undefined)
183
+ const policyStore = d.sessionPolicyStore;
184
+ if (policyStore === undefined)
184
185
  return no("session_policy_store_absent");
185
186
  const owned = sessionOwnership(d);
186
187
  if (!owned.available)
187
188
  return owned;
188
- return yes({ policyStore: d.sessionPolicyStore, sessionStorage: owned.sessionStorage });
189
+ return yes({ policyStore, sessionStorage: owned.sessionStorage });
189
190
  }
190
191
  export function sessionSync(d) {
191
- if (d.backend === undefined)
192
+ const { fileHistoryStore: historyStore, sessionPolicyStore } = d;
193
+ const backend = d.backend;
194
+ if (backend === undefined)
192
195
  return no("store_backend_absent");
193
- if (d.fileHistoryStore === undefined)
196
+ if (historyStore === undefined)
194
197
  return no("file_history_store_absent");
195
198
  const s = d.sessionStorage;
196
199
  if (s?.exportEntries === undefined || s.exportEntriesStream === undefined)
197
200
  return no("session_export_absent");
198
201
  if (s.beginImportStaging === undefined)
199
202
  return no("session_import_staging_absent");
200
- if (headReadOf(s) === undefined || s.sessionSummaryOf === undefined || s.writeSessionRowCells === undefined)
203
+ if (!headReadPresent(s) || s.sessionSummaryOf === undefined || s.writeSessionRowCells === undefined)
201
204
  return no("session_row_faces_absent");
202
- if (overwriteWipeIncapable(d.sessionPolicyStore))
205
+ if (overwriteWipeIncapable(sessionPolicyStore))
203
206
  return no("policy_purge_absent");
204
- return yes({ backend: d.backend, sessionStorage: s, historyStore: d.fileHistoryStore });
207
+ return yes({ backend, sessionStorage: s, historyStore });
205
208
  }
206
209
  export function sessionSyncFileHistory(d) {
207
210
  const sync = sessionSync(d);
@@ -211,20 +214,22 @@ export function sessionSyncFileHistory(d) {
211
214
  return blobExchange !== undefined ? yes({ historyStore: sync.historyStore, blobExchange }) : no("blob_exchange_absent");
212
215
  }
213
216
  export function sessionRewindFiles(d) {
214
- if (d.fileHistoryStore === undefined)
217
+ const { fileHistoryStore: historyStore, resumeAnchorStore: anchors, config, backend } = d;
218
+ if (historyStore === undefined)
215
219
  return no("file_history_store_absent");
216
220
  const owned = sessionOwnership(d);
217
221
  if (!owned.available)
218
222
  return owned;
219
- if (d.resumeAnchorStore === undefined || d.runStore === undefined)
223
+ const runs = durableRuns(d);
224
+ if (anchors === undefined || !runs.available)
220
225
  return no("resume_anchor_store_absent");
221
- if (!laneWiresExecutionEnv(d.config.remoteExec.provider))
226
+ if (!laneWiresExecutionEnv(config.remoteExec.provider))
222
227
  return no("execution_lane_handless");
223
- if (!DEPLOYMENT_SHAPE_PREDICATES.rewindableWorkspace.holds(d.config))
228
+ if (!DEPLOYMENT_SHAPE_PREDICATES.rewindableWorkspace.holds(config))
224
229
  return no("workspace_rebuilt_per_task");
225
- if (d.backend?.kind !== "local")
230
+ if (backend?.kind !== "local")
226
231
  return no("session_store_shared");
227
- return yes({ historyStore: d.fileHistoryStore, anchors: { anchors: d.resumeAnchorStore, runs: d.runStore }, sessionStorage: owned.sessionStorage });
232
+ return yes({ historyStore, anchors: { anchors, runs: runs.runStore }, sessionStorage: owned.sessionStorage });
228
233
  }
229
234
  export function sessionRewindFilesPreview(d) {
230
235
  const rewind = sessionRewindFiles(d);
@@ -294,14 +299,15 @@ export function deviceManagement(d) {
294
299
  const lane = deviceLane(d);
295
300
  if (!lane.available)
296
301
  return lane;
297
- if (d.deviceStore === undefined)
302
+ const { deviceStore: store, deviceEnrollment: enrollment } = d;
303
+ if (store === undefined)
298
304
  return no("device_store_absent");
299
- if (d.deviceEnrollment === undefined)
305
+ if (enrollment === undefined)
300
306
  return no("device_enrollment_absent");
301
307
  const runs = durableRuns(d);
302
308
  if (!runs.available)
303
309
  return runs;
304
- return yes({ hub: lane.hub, store: d.deviceStore, enrollment: d.deviceEnrollment, runStore: runs.runStore });
310
+ return yes({ hub: lane.hub, store, enrollment, runStore: runs.runStore });
305
311
  }
306
312
  export function fleetStream(d) {
307
313
  return d.fleetBus !== undefined ? yes({ fleetBus: d.fleetBus }) : no("fleet_bus_absent");
@@ -341,7 +347,8 @@ export function memorySyncServe(d) {
341
347
  return identity !== undefined ? yes({ perform: d.memorySync, identity }) : no("memory_sync_identity_undeclared");
342
348
  }
343
349
  export function sessionMemorySync(d) {
344
- if (d.memorySyncLeg === undefined)
350
+ const leg = d.memorySyncLeg;
351
+ if (leg === undefined)
345
352
  return no("memory_sync_leg_absent");
346
353
  const runs = durableRuns(d);
347
354
  if (!runs.available)
@@ -349,7 +356,7 @@ export function sessionMemorySync(d) {
349
356
  const owned = sessionOwnership(d);
350
357
  if (!owned.available)
351
358
  return owned;
352
- return yes({ leg: d.memorySyncLeg, runStore: runs.runStore, sessionStorage: owned.sessionStorage });
359
+ return yes({ leg, runStore: runs.runStore, sessionStorage: owned.sessionStorage });
353
360
  }
354
361
  export function principalInboxDelivery(d) {
355
362
  return d.orgDeliveryGate !== undefined ? yes({ gate: d.orgDeliveryGate }) : no("org_delivery_gate_absent");
@@ -179,7 +179,7 @@ export const CONFIG_CATALOG = [
179
179
  r("FLEET_ADVERTISE_ADDRESS", "integrations", "url", `fleet 面向 center 公告的本 worker 可达地址(中心车道配齐 + 本键 ⇒ 公告环;空串 = 未设;用量环不看本键)。中心往它后面拼路径,与中心基址三席同一条判据:${CENTER_BASE_URL_RULE}`, { credentialPolicy: "refuse", configKey: "fleetAdvertiseAddress" }),
180
180
  r("FLEET_GENERATION", "integrations", "string", "fleet 成员的代际(配置渲染器写;引擎回声到心跳与 /health 的 generation)。缺席 ⇔ 非 fleet 成员(不续服务租约、不受围栏);在场必须是规范十进制串(\"0\" / \"7\";空串、前导零、符号、空白拒启)", { danger: SEC, configKey: "fleetGeneration" }),
181
181
  r("FLEET_LEASE_FAIL_CLOSED", "integrations", "boolean", "租约连接级失败(中心鉴权拒 / 凭证不可读 / 不可达 / 5xx / 超时 / 坏体)时计费入口拒 503 fleet.lease_unavailable(true)还是放行(false);409 not-lease 与耗尽 429 不受它管;词表外拒启", { danger: SEC, derivedDefaultNote: "缺席 ⇒ 按部署姿态派生:REQUIRE_PRINCIPAL=true ⇒ true(多租:额度是安全轴);单用户 ⇒ false(AP 姿态)。显式值压过派生。生效值见 caps centerWiring.failMode", configKey: "fleetLeaseFailClosed" }),
182
- r("FLEET_LEASE_OUTAGE_MAX_MS", "integrations", "number", "一台实例「活着而不服务」的最长时长 T_max(ms),两处读它:① 服务租约中心不可达的容忍上限 —— 租约过期满这么久 ⇒ 新计费提交 503 state.lease_expired(取消 / HITL 应答 / 续跑 / 读面照放行,在飞不动,/readyz 不翻),只在 fleet 成员 ∧ 中心宣告 servingLease 能力位时生效;② 排空口 POST /v1/admin/drain 的期限上界 —— deadlineAt 离此刻超过它 ⇒ 400 request.field_invalid,成员与非成员同读;< 60000(租约 TTL 地板)或非整数拒启", { danger: SEC, staticDefault: String(FLEET_LEASE_OUTAGE_MAX_DEFAULT_MS), configKey: "fleetLeaseOutageMaxMs" }),
182
+ r("FLEET_LEASE_OUTAGE_MAX_MS", "integrations", "number", "一台实例「活着而不服务」的最长时长 T_max(ms),两处读它:① 服务租约中心不可达的容忍上限 —— 租约过期(从没被授予过的:从围栏生效那一刻;一直没听到中心的成员从本进程起点)满这么久 ⇒ 新计费提交 503 state.lease_expired(取消 / HITL 应答 / 续跑 / 读面照放行,在飞不动,/readyz 不翻),只在 fleet 成员 ∧ 中心没有声明不执行租约(心跳答复的 capabilities 声明不带 servingLease)时生效;② 排空口 POST /v1/admin/drain 的期限上界 —— deadlineAt 离此刻超过它 ⇒ 400 request.field_invalid,成员与非成员同读;< 60000(租约 TTL 地板)或非整数拒启", { danger: SEC, staticDefault: String(FLEET_LEASE_OUTAGE_MAX_DEFAULT_MS), configKey: "fleetLeaseOutageMaxMs" }),
183
183
  r("FLEET_SCOPE", "integrations", "string", "本引擎所在的租户 scope(配置渲染器对每台受管引擎写,缺省 scope 也写;手接的引擎缺席 = 缺省 scope;唯一读者 = 排空口 POST /v1/admin/drain 的身份比对,请求不带 scope 也读成缺省 scope)。在场必须是 scope id 形(小写字母 / 数字 / 内部连字符,1–64;空串拒启);与 FLEET_GENERATION 不联动(成员缺席 ⇒ 缺省 scope)。续租体与心跳不带它(scope 由中心凭证绑定)", { danger: SEC, staticDefault: GLOBAL_SCOPE, configKey: "fleetScope" }),
184
184
  r("FORK_ENABLED", "orchestration", "boolean", "CC /fork(core Fork 工具)装配开关", { derivedDefaultNote: "posture 三态:缺席 = 单用户 ⇒ on / 多租户 ⇒ off(per-principal entitlement 另判)", configKey: "forkEnabled" }),
185
185
  r("GATEWAY_MAX_RETRIES", "modelPlane", "number", "openai 兼容腿每次调用重试上限", {
@@ -331,7 +331,7 @@ export interface CenterMcp {
331
331
  servers: ScopedMcpServer[];
332
332
  reservedNames: readonly string[];
333
333
  }
334
- /** DESIGN-269 §2.1 —— an A2A PEER resolved to a core spec (header-NAME refs already read and registered on the peer desk
334
+ /** [ref] §2.1 —— an A2A PEER resolved to a core spec (header-NAME refs already read and registered on the peer desk
335
335
  * under the roster lease: the spec carries the minted reference, never the values) plus
336
336
  * the scenarios it applies to (empty = all). Exact sibling of {@link ScopedMcpServer}: `resolveSpec`
337
337
  * filters by scenario (`a2aForScenario`) and passes `spec` to core as `TaskSpec.a2a`.
@@ -344,7 +344,7 @@ export interface ScopedA2aPeer {
344
344
  spec: A2aServerSpec;
345
345
  }
346
346
  /**
347
- * DESIGN-269 §3.1 车2 —— ONE declared skill on the agent card this deployment publishes when it acts as
347
+ * [ref] §3.1 车2 —— ONE declared skill on the agent card this deployment publishes when it acts as
348
348
  * an A2A **peer** (server-as-peer half). v1 is a **static declaration**: the operator writes the list,
349
349
  * the server never enumerates its own scenarios into it.
350
350
  *
@@ -369,7 +369,7 @@ export interface A2aServeSkill {
369
369
  audience?: readonly string[];
370
370
  }
371
371
  /**
372
- * DESIGN-269 §3.3 车2 —— the server-as-peer block. **Absence IS the OFF state** (`A2A_SERVE_ENABLED`
372
+ * [ref] §3.3 车2 —— the server-as-peer block. **Absence IS the OFF state** (`A2A_SERVE_ENABLED`
373
373
  * default OFF): with this field undefined both `/.well-known/agent-card.json` and `POST /v1/a2a` 404,
374
374
  * i.e. "卡都不发=对外不存在" — not "publish a card but refuse the calls". Modelling OFF as absence
375
375
  * (rather than an `enabled:false` member) makes the half-state structurally unrepresentable.
@@ -1108,14 +1108,14 @@ export interface ServiceConfigFlat {
1108
1108
  * present (restart-to-apply, like models/roles); undefined = no center MCP (scenarios use no MCP).
1109
1109
  * Carries both the mounted list and the full declared-name set — see {@link CenterMcp}. */
1110
1110
  mcpServers?: CenterMcp;
1111
- /** DESIGN-269 §2.1 —— A2A peers from the web-admin (`/effective.a2a`), resolved at startup
1111
+ /** [ref] §2.1 —— A2A peers from the web-admin (`/effective.a2a`), resolved at startup
1112
1112
  * (header-NAME refs → values) and filtered per scenario in `resolveSpec` (`a2aForScenario`). Same
1113
1113
  * posture as {@link mcpServers}: not env-derived (no A2A_* env leg — a peer is a structured record,
1114
1114
  * not a scalar), populated by the web-admin adapter when present, restart-to-apply.
1115
1115
  * undefined = no center peers ⇒ **the whole leg does not exist** for a task (`TaskSpec.a2a` stays
1116
1116
  * absent unless a single-user caller injects `body.a2aPeers`). */
1117
1117
  a2aPeers?: ScopedA2aPeer[];
1118
- /** DESIGN-269 §3.3 车2 —— server-as-peer. **undefined = OFF** (the default), and OFF means both the
1118
+ /** [ref] §3.3 车2 —— server-as-peer. **undefined = OFF** (the default), and OFF means both the
1119
1119
  * card and the JSON-RPC endpoint 404. See {@link A2aServeConfig}. Env-derived (`A2A_SERVE_*`), unlike
1120
1120
  * {@link a2aPeers}: the serve block is a handful of scalars an operator sets on the worker, not a
1121
1121
  * center-distributed record. */
@@ -1371,7 +1371,7 @@ export interface ServiceConfigFlat {
1371
1371
  */
1372
1372
  retentionPolicy?: RetentionPolicy;
1373
1373
  /**
1374
- * [ref] 车2 —— 托管留存 **sweep lane** 的两个旋钮(设计稿 `DESIGN-270-retention-lane.md` §3/§4)。
1374
+ * [ref] 车2 —— 托管留存 **sweep lane** 的两个旋钮(设计稿 `[ref]-retention-lane.md` §3/§4)。
1375
1375
  * `retentionPolicy` 说的是「保留多久」(一句声明),本格说的是「谁在什么节律上按那句话删」。
1376
1376
  * **恒在场**(不是可选块):两根都有文档化的缺省,而缺省本身是一条要能被读出来的姿态 ——
1377
1377
  * `{mode:"audit-only", intervalSec:0}` = 「lane 关着,真开起来也先只记账」。被要的车道必须齐(`intervalSec > 0` 或 `mode:"enforce"` ⇒
@@ -1401,7 +1401,7 @@ export interface ServiceConfigFlat {
1401
1401
  */
1402
1402
  serviceTokenActsForDeployment: boolean;
1403
1403
  /**
1404
- * DESIGN-278 §5 S2([ref])—— `GET /v1/config/catalog`(配置目录自描述端点)的显式旋钮。
1404
+ * [ref] §5 S2([ref])—— `GET /v1/config/catalog`(配置目录自描述端点)的显式旋钮。
1405
1405
  * 默认 **ON**(设计稿 §0.5:合规部署可关)。端点本身已是 operator-only(`explicitOperatorOk`,
1406
1406
  * 空名单=谁都不是),本键给的是「即便 operator 也不许从 wire 读部署事实」的合规姿态:关 ⇒ 路径
1407
1407
  * 不存在(404 族,与 memory-consolidation 阀门同判:旋钮没开 ≠ 能力缺失)、能力位 `configCatalog`
@@ -2019,7 +2019,8 @@ export interface ServiceConfigFlat {
2019
2019
  * ON; multi-tenant opt-in); `ASK_QUESTION_ENABLED=true/false` overrides. */
2020
2020
  askQuestionEnabled: boolean;
2021
2021
  /** [ref] 裁2:AskUserQuestion 的**裁量窗**——每 run 腿的并发帽 / 总量帽 / 无人应答的释放窗。窗用尽或到期
2022
- * 不是拒绝、也不是替人作答:协调器报 `unavailable`,落点(durable park / 非 durable 合成续跑)归 core。
2022
+ * 不是拒绝、也不是替人作答:协调器报 `unavailable`,落点(durable park / 非 durable 合成续跑)归 core;卡由活面呈出而窗到期 ⇒
2023
+ * 协调器抛(core 的投递失败臂,不改道)。
2023
2024
  * `QUESTION_MAX_CONCURRENT_PER_RUN`(默认 2)/ `QUESTION_MAX_TOTAL_PER_RUN`(20)/ `QUESTION_TTL_MS`
2024
2025
  * (300000),越界值启动期响亮拒(照 `MCP_ELICITATION_*` 同门,不静默夹取)。缺席 ⇒ 协调器出厂窗
2025
2026
  * {@link import("./question.js").DEFAULT_QUESTION_THROTTLE}(与本旋钮族默认逐字同值)。 */
@@ -2368,9 +2369,9 @@ export interface ServiceConfigFlat {
2368
2369
  fleetAdvertiseAddress?: string;
2369
2370
  /** 编排器片 2:一台实例「活着而不服务」的最长时长 `T_max`(ms;env `FLEET_LEASE_OUTAGE_MAX_MS`)。缺省 86 400 000(24 h);地板 = 服务租约
2370
2371
  * TTL 地板(settings-schema `SERVING_LEASE_TTL_FLOOR_MS`,60 s);不许 0 / 无穷,坏值拒启。`loadConfig` 无条件解析(成员与非成员同读)。两个读者:
2371
- * ① 服务租约**中心不可达的容忍上限**(`fleet/serving-lease.ts`;只在 fleet 成员 ∧ 中心宣告了 `servingLease` 能力位时生效):租约过期(中心
2372
- * 不可达 / 答 unknown)之后照常服务,直到过期满这么久 ⇒ 新计费提交 503 `state.lease_expired`(取消 / HITL 应答 / 续跑 / 读面照放行),在飞不动、
2373
- * 不自停;中心恢复授予即恢复。② 排空口 `POST /v1/admin/drain` 的**期限准入上界**(`fleet/drain-entry.ts` 规则 2):`deadlineAt` 离此刻超过它 ⇒
2372
+ * ① 服务租约**中心不可达的容忍上限**(`fleet/serving-lease.ts`;只在 fleet 成员 ∧ 中心没有声明不执行租约时生效 —— 没听到中心的成员也算,
2373
+ * 起步即推定在围栏内):租约过期(中心不可达 / 答 unknown;从没被授予过的,从围栏生效那一刻 —— 一直没听到中心的成员从本进程起点)之后照常服务,
2374
+ * 直到满这么久 ⇒ 新计费提交 503 `state.lease_expired`(取消 / HITL 应答 / 续跑 / 读面照放行),在飞不动、不自停;中心恢复授予即恢复。② 排空口 `POST /v1/admin/drain` 的**期限准入上界**(`fleet/drain-entry.ts` 规则 2):`deadlineAt` 离此刻超过它 ⇒
2374
2375
  * 400 `request.field_invalid`。 */
2375
2376
  fleetLeaseOutageMaxMs: number;
2376
2377
  /** [ref](design-325 §2):中心凭证**续签提前量**(ms)—— `SEMA_WEB_ADMIN_TOKEN_FILE` 指向人的登录会话信封
@@ -58,15 +58,12 @@ export interface PathAdjudication {
58
58
  * `task-settings.ts` 的 `FsWriteGateWiring.taskHome`。 */
59
59
  readonly taskHome?: string;
60
60
  }
61
- /** [ref]([ref] 案二):durable 部署上的 AskUserQuestion 门的活体面探针(QuestionCoordinator 的切面)。 */
62
- export interface LiveQuestionFace {
63
- hasLiveContext(): boolean;
64
- }
65
61
  /**
66
62
  * [ref] —— 审批基线的**席**:这条腿上「一个名单产的 `ask` 由谁来服」。闭集三形,每条腿**显式**说出自己那一形
67
63
  * ({@link createApprovalBaselinePolicy} 的席参数必填、按 `kind` 穷举 —— 闭集 +1 = 编译红):
68
- * · `durable` —— checkpoint suspend/resume 服 ask(HTTP 腿 durable 开、park 赎回腿)。AskUserQuestion 的问答门
69
- * **只**叠在这一形上(它的 `ask` 语义就是 durable park)。
64
+ * · `durable` —— checkpoint suspend/resume 服 ask(HTTP 腿 durable 开、park 赎回腿)。core 的问答策略
65
+ * (`createDurableQuestionPolicy()`,原形逐字)**只**叠在这一形上:它对引擎的问题工具答 `ask`,落点归 core 的同步优先
66
+ * (有问题席 ⇒ 先投卡、席在窗内拿到答即交答;没拿到 ⇒ 停驻 —— 卡由活面呈出而窗走完的那一问除外:席抛,引擎的投递失败臂不停驻)。
70
67
  * · `live` —— Runner 的活 onAsk 席当场服 ask(run-local 的 `createLocalApprover`:TTY 问 y/N / 无 TTY 当场拒;
71
68
  * core `isLiveApproverSeat(onAsk)` 为真时 `suspendAsk` 早退,ask 落回调)。三张名单与 durable 席**同一只**策略。
72
69
  * · `absent` —— 没有谁服 ask ⇒ adjudicated allow-all;**只**服务零名单(HTTP 腿「durable 关 ∧ 单用户零意图」)。
@@ -79,11 +76,9 @@ export interface LiveQuestionFace {
79
76
  export type ApprovalSeat = DurableApprovalSeat | LiveApprovalSeat | AbsentApprovalSeat;
80
77
  /** 席的形名(补偿 warn 等只需要「哪一形」的读者读它,不必铸整只席)。 */
81
78
  export type ApprovalSeatKind = ApprovalSeat["kind"];
82
- /** durable 席:checkpoint suspend/resume 服 ask,问答门叠在名单策略上。 */
79
+ /** durable 席:checkpoint suspend/resume 服 ask,core 的问答策略叠在名单策略上。 */
83
80
  export interface DurableApprovalSeat {
84
81
  readonly kind: "durable";
85
- /** 活体问答面;`undefined` ⇒ 恒 durable park 的原形门。 */
86
- readonly question: LiveQuestionFace | undefined;
87
82
  /** 本会话的「本会话放行」读面(部署名单那一问的站着的答案;铸点 `approval.ts` 的 `createSessionExemptionRead`)。缺席 = 这条腿没有会话 / 没有豁免店 ⇒ 名单照问。 */
88
83
  readonly exemption?: SessionExemptionRead;
89
84
  }
@@ -95,23 +90,6 @@ export interface LiveApprovalSeat {
95
90
  export interface AbsentApprovalSeat {
96
91
  readonly kind: "absent";
97
92
  }
98
- /**
99
- * [ref]([ref] 案二):durable 部署上的 AskUserQuestion 门。活体面(QuestionCoordinator)缺席 ⇒ 原形
100
- * `createDurableQuestionPolicy()`(恒 ask ⇒ 恒 durable park)。在场 ⇒ **判决时**按活流上下文分腿:
101
- * 活流腿(bg/SSE,coordinator.runWithContext 包裹且投递面此刻可达,ALS 判)allow——工具执行落到
102
- * RunnerDeps.onQuestion 的 coordinator,问正在 tail 流的活人;无活流腿(sync /v1/tasks、verify/cascade、
103
- * durable resume 驱动、断连后的 detach 腿)ask——durable park 原语义逐字保留([ref] 后无活流腿放行执行
104
- * 也不会产出空答:coordinator 无 ALS ctx ⇒ 冻结 `{kind:"unavailable"}`(src/question.ts),永不悬挂;
105
- * park 仍是把问题送到人面前的唯一那条腿,正当性不变、只是反事实前提换了)。
106
- * 「是不是引擎的问题工具」不在本层判:core 7.56.0 [ref] 起本门**组合** core 原形的答(它读调用的脸 —— 引擎挂载点 + 目录契约 id,不读名字;
107
- * 它答 `ask` ⇒ 是;本层只在那之上按活流分腿)。决断口的 pre-CAS 守卫(「批准问答必须带答」)仍按保留名读(core 同版「Not changed here」那一条)。
108
- * ⚠️ **单一属主**(复审 A2):AskUserQuestion 的 durable 判决只有这一处。任何需要「同参重建」这条判决的
109
- * 地方(main.ts 的 parkedReviveInheritedGate 父约束链)必须调本工厂,不得自折 core 原形——两份拷贝里
110
- * 只改一份正是本条 finding 的成因。**登记豁免一处**:leader worker 腿(src/leader/wire.ts provisionWorker)
111
- * 自折 core 原形——该腿无活体问答面可装且 leader 不 import boot 层(分层),core 原形+sentinel 即其完整
112
- * 语义;豁免注在彼处互指,接活体面之日必须并回本工厂。
113
- */
114
- export declare function createDurableQuestionGate(live: LiveQuestionFace | undefined): ToolPolicy;
115
93
  /**
116
94
  * 沙箱 lane 上**相对形**写目标的守卫补层用 env(codex 交叉复审 round1 finding 1,红先复现)。
117
95
  *
@@ -266,8 +244,9 @@ export declare function buildApprovalGrantNotice(config: {
266
244
  * `undefined`**:治理层是 tighten-only 的叠加层,没有基线可叠时它自己也产不出「门在场」这件事。
267
245
  *
268
246
  * 三形,按席穷举([ref],席的定义见 {@link ApprovalSeat}):
269
- * · `durable` ⇒ AskUserQuestion 判决门 + 三张名单的审批门(deny/neverAuto/预算/本会话的豁免行全在
270
- * `createDurableAskPolicy` 里)。gated `ask` 由 core 变成 durable checkpoint suspend。
247
+ * · `durable` ⇒ core 的问答策略(原形逐字,不包)+ 三张名单的审批门(deny/neverAuto/预算/本会话的豁免行全在
248
+ * `createDurableAskPolicy` 里)。gated `ask` 由 core 变成 durable checkpoint suspend;问题族的 `ask` 先过 core 的同步优先
249
+ * (问题席在窗内拿到答 ⇒ 交答;没拿到 ⇒ 停驻;活面呈出而窗走完 ⇒ 投递失败臂)—— 「有没有人」本口不预判,唯一判官是那一次投递的结局。
271
250
  * · `live` ⇒ **同一只**三张名单审批门,不叠问答门。gated `ask` 由 core 交给 Runner 的活 onAsk 席
272
251
  * (本口**不**做 ask→deny 映射:无人可问时的拒由那只席说,判据与文案都归它)。
273
252
  * · `absent` ⇒ **adjudicated allow-all**(`createAllowDenyPolicy({})`):一条**在场的**、