@sema-agent/server 7.138.0 → 7.140.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 (332) hide show
  1. package/MIGRATION.md +457 -7
  2. package/README.md +7 -4
  3. package/README.zh-CN.md +6 -4
  4. package/USAGE.md +91 -41
  5. package/deploy/sema-up/README.md +1 -1
  6. package/deploy/sema-up/lib/lanes.json +3 -2
  7. package/dist/adoption/runner.js +1 -1
  8. package/dist/adoption/sql.js +1 -1
  9. package/dist/adoption/wire.d.ts +3 -3
  10. package/dist/approval-card.d.ts +26 -26
  11. package/dist/bench/s1/arms.d.ts +1 -1
  12. package/dist/bench/s1/arms.js +1 -3
  13. package/dist/bench/s1/live-deps.js +3 -2
  14. package/dist/bench/s1/row.d.ts +5 -2
  15. package/dist/bench/s1/row.js +2 -22
  16. package/dist/bench/s1/run-firm.js +2 -2
  17. package/dist/boot/adoption.js +1 -1
  18. package/dist/boot/device-lane.d.ts +8 -3
  19. package/dist/boot/device-lane.js +7 -2
  20. package/dist/boot/execution-env.d.ts +4 -2
  21. package/dist/boot/execution-env.js +28 -34
  22. package/dist/boot/execution-lane.d.ts +9 -1
  23. package/dist/boot/execution-lane.js +6 -1
  24. package/dist/boot/governance-seams.d.ts +3 -2
  25. package/dist/boot/governance-seams.js +9 -11
  26. package/dist/boot/memory-boundary.d.ts +14 -51
  27. package/dist/boot/memory-boundary.js +10 -20
  28. package/dist/boot/memory-consolidation.d.ts +15 -11
  29. package/dist/boot/memory-consolidation.js +25 -14
  30. package/dist/boot/resolve-spec.d.ts +4 -6
  31. package/dist/boot/resolve-spec.js +10 -13
  32. package/dist/boot/retention-lane.d.ts +5 -5
  33. package/dist/boot/retention-lane.js +0 -6
  34. package/dist/boot/runner-deps.d.ts +6 -4
  35. package/dist/boot/runner-deps.js +3 -1
  36. package/dist/boot/session-faces.d.ts +0 -3
  37. package/dist/boot/session-faces.js +15 -8
  38. package/dist/boot/stage-02-web-admin-pull.js +2 -2
  39. package/dist/boot/stage-03-store-backend.d.ts +2 -6
  40. package/dist/boot/stage-03-store-backend.js +2 -3
  41. package/dist/boot/stage-04-stores.d.ts +2 -6
  42. package/dist/boot/stage-04-stores.js +5 -5
  43. package/dist/boot/stage-05-execution-env.d.ts +2 -6
  44. package/dist/boot/stage-05-execution-env.js +2 -2
  45. package/dist/boot/stage-06-runners.d.ts +2 -6
  46. package/dist/boot/stage-06-runners.js +2 -3
  47. package/dist/boot/stage-07-capability-layer.d.ts +2 -6
  48. package/dist/boot/stage-08-reapers.d.ts +2 -6
  49. package/dist/boot/stage-09-leader.d.ts +2 -6
  50. package/dist/boot/stage-09-leader.js +1 -2
  51. package/dist/boot/stage-10-http-server.d.ts +2 -6
  52. package/dist/boot/stage-10-http-server.js +7 -6
  53. package/dist/boot/stores.d.ts +3 -6
  54. package/dist/boot/stores.js +27 -40
  55. package/dist/boot/task-list-lane.d.ts +1 -1
  56. package/dist/boot/task-list-lane.js +1 -1
  57. package/dist/boot/web-admin.js +37 -11
  58. package/dist/capabilities/execution-lane.d.ts +2 -2
  59. package/dist/capabilities/mcp-probe.js +1 -1
  60. package/dist/capabilities/scenarios.d.ts +1 -1
  61. package/dist/capability-facts.d.ts +15 -7
  62. package/dist/capability-facts.js +8 -3
  63. package/dist/config-catalog.js +9 -8
  64. package/dist/config-invariants.d.ts +23 -3
  65. package/dist/config-invariants.js +42 -0
  66. package/dist/config-provider.d.ts +33 -37
  67. package/dist/config-provider.js +51 -30
  68. package/dist/config-types.d.ts +21 -7
  69. package/dist/config.d.ts +33 -0
  70. package/dist/config.js +46 -16
  71. package/dist/delegated-session-owner.d.ts +4 -3
  72. package/dist/delegated-session-owner.js +1 -1
  73. package/dist/deployment-shape.d.ts +10 -9
  74. package/dist/deployment-shape.js +4 -4
  75. package/dist/device-enrollment.d.ts +41 -2
  76. package/dist/device-enrollment.js +27 -12
  77. package/dist/device-store.d.ts +58 -85
  78. package/dist/device-store.js +19 -49
  79. package/dist/device-ws-hub.js +2 -1
  80. package/dist/env-name-allowlist-knobs.d.ts +5 -4
  81. package/dist/exec-cut.d.ts +60 -0
  82. package/dist/exec-cut.js +36 -0
  83. package/dist/execution-lane-caps.d.ts +115 -105
  84. package/dist/execution-lane-caps.js +76 -82
  85. package/dist/execution-placement.d.ts +259 -0
  86. package/dist/execution-placement.js +199 -0
  87. package/dist/field-conflict.d.ts +3 -2
  88. package/dist/field-conflict.js +1 -0
  89. package/dist/hosted-posture.d.ts +2 -2
  90. package/dist/http/admission.js +8 -19
  91. package/dist/http/checkpoint-ctx.d.ts +21 -12
  92. package/dist/http/checkpoint-ctx.js +4 -2
  93. package/dist/http/claimed-run.d.ts +1 -1
  94. package/dist/http/durable-run-leg.js +9 -5
  95. package/dist/http/execution-context.d.ts +218 -0
  96. package/dist/http/execution-context.js +330 -0
  97. package/dist/http/memory-compliance-failure-reply.d.ts +3 -1
  98. package/dist/http/memory-compliance-failure-reply.js +5 -0
  99. package/dist/http/memory-layer-reply.d.ts +30 -0
  100. package/dist/http/memory-layer-reply.js +24 -0
  101. package/dist/http/resume-legs.js +63 -36
  102. package/dist/http/retired-service-deps.d.ts +1 -1
  103. package/dist/http/retired-service-deps.js +1 -1
  104. package/dist/http/route-ctx.d.ts +14 -8
  105. package/dist/http/routes/adoption.js +1 -1
  106. package/dist/http/routes/background.d.ts +29 -1
  107. package/dist/http/routes/background.js +29 -2
  108. package/dist/http/routes/devices.d.ts +13 -19
  109. package/dist/http/routes/devices.js +21 -26
  110. package/dist/http/routes/memory-bundle.js +3 -0
  111. package/dist/http/routes/memory-compliance.js +8 -1
  112. package/dist/http/routes/memory-consolidation.js +12 -1
  113. package/dist/http/routes/memory-origin.js +14 -2
  114. package/dist/http/routes/memory-policy.js +5 -0
  115. package/dist/http/routes/session-sync.js +110 -15
  116. package/dist/http/routes/sessions.d.ts +6 -0
  117. package/dist/http/routes/sessions.js +143 -22
  118. package/dist/http/routes/side-query.d.ts +12 -4
  119. package/dist/http/routes/side-query.js +4 -5
  120. package/dist/http/routes/tasks.js +41 -33
  121. package/dist/http/server.d.ts +40 -44
  122. package/dist/http/server.js +13 -2
  123. package/dist/http/session-inherit-env.d.ts +3 -4
  124. package/dist/http/session-inherit-env.js +1 -1
  125. package/dist/http/wire-types.d.ts +8 -12
  126. package/dist/identity-source.d.ts +1 -1
  127. package/dist/identity-source.js +1 -1
  128. package/dist/index.d.ts +1 -0
  129. package/dist/lane-home-probe.d.ts +68 -42
  130. package/dist/lane-home-probe.js +53 -30
  131. package/dist/leader/wire.js +5 -4
  132. package/dist/memory-bundle-engine.d.ts +16 -9
  133. package/dist/memory-bundle-engine.js +29 -6
  134. package/dist/memory-operator-faces.d.ts +85 -30
  135. package/dist/memory-operator-faces.js +136 -30
  136. package/dist/memory-project-layer.d.ts +3 -21
  137. package/dist/memory-project-layer.js +11 -8
  138. package/dist/memory-scope-stores.d.ts +73 -0
  139. package/dist/memory-scope-stores.js +86 -0
  140. package/dist/memory-scope.d.ts +29 -5
  141. package/dist/memory-scope.js +16 -4
  142. package/dist/memory-sync-client.d.ts +70 -18
  143. package/dist/memory-sync-client.js +215 -117
  144. package/dist/memory-sync.d.ts +1 -1
  145. package/dist/memory-sync.js +3 -2
  146. package/dist/observability/cost-taxonomy.d.ts +2 -2
  147. package/dist/observability/fail-open.d.ts +12 -0
  148. package/dist/observability/fail-open.js +12 -0
  149. package/dist/observability/run-terminal.js +0 -1
  150. package/dist/orchestration/workflow-notify-journal.js +4 -4
  151. package/dist/org-memory-admission.d.ts +4 -3
  152. package/dist/org-memory-admission.js +6 -6
  153. package/dist/parked-decide.d.ts +34 -9
  154. package/dist/parked-decide.js +12 -19
  155. package/dist/parked-revive-surface.d.ts +12 -15
  156. package/dist/parked-revive-surface.js +3 -6
  157. package/dist/peer-seat.d.ts +13 -7
  158. package/dist/peer-seat.js +37 -3
  159. package/dist/plugins/adoption-log-sql.js +4 -4
  160. package/dist/plugins/approval-ask-store-file.d.ts +7 -0
  161. package/dist/plugins/approval-ask-store-file.js +11 -0
  162. package/dist/plugins/approval-ask-store-memory.d.ts +6 -0
  163. package/dist/plugins/approval-ask-store-memory.js +12 -0
  164. package/dist/plugins/approval-ask-store-sql.d.ts +22 -5
  165. package/dist/plugins/approval-ask-store-sql.js +44 -26
  166. package/dist/plugins/approval-nonce-store.js +4 -4
  167. package/dist/plugins/blob-backend.d.ts +4 -4
  168. package/dist/plugins/blob-backend.js +7 -7
  169. package/dist/plugins/breaker-state-sql.js +2 -2
  170. package/dist/plugins/caching-session-store.d.ts +6 -2
  171. package/dist/plugins/caching-session-store.js +9 -3
  172. package/dist/plugins/checkpoint-index-columns.js +2 -2
  173. package/dist/plugins/checkpoint-store-sql.d.ts +6 -5
  174. package/dist/plugins/checkpoint-store-sql.js +21 -23
  175. package/dist/plugins/device-store-sql.d.ts +25 -51
  176. package/dist/plugins/device-store-sql.js +68 -122
  177. package/dist/plugins/ensure-index.d.ts +1 -2
  178. package/dist/plugins/execution-placement-sql.d.ts +151 -0
  179. package/dist/plugins/execution-placement-sql.js +223 -0
  180. package/dist/plugins/file-history-store-sql.d.ts +9 -8
  181. package/dist/plugins/file-history-store-sql.js +9 -9
  182. package/dist/plugins/file-run-store.d.ts +6 -1
  183. package/dist/plugins/file-run-store.js +4 -0
  184. package/dist/plugins/fork-routing-session-store.d.ts +6 -0
  185. package/dist/plugins/fork-routing-session-store.js +16 -0
  186. package/dist/plugins/image-bake-store-sql.js +9 -9
  187. package/dist/plugins/image-index-sql.js +11 -11
  188. package/dist/plugins/leader-run-store-sql.js +4 -4
  189. package/dist/plugins/local-session-store.d.ts +149 -50
  190. package/dist/plugins/local-session-store.js +382 -107
  191. package/dist/plugins/mailbox-store-sql.d.ts +2 -1
  192. package/dist/plugins/mailbox-store-sql.js +4 -4
  193. package/dist/plugins/memory-engine-tidb.js +5 -5
  194. package/dist/plugins/memory-key-guards.d.ts +4 -0
  195. package/dist/plugins/memory-key-guards.js +1 -0
  196. package/dist/plugins/memory-optout-grant-store-sql.js +1 -1
  197. package/dist/plugins/memory-run-store.d.ts +1 -1
  198. package/dist/plugins/memory-sync-store-tidb.js +3 -3
  199. package/dist/plugins/one-time-migrations.d.ts +117 -8
  200. package/dist/plugins/one-time-migrations.js +408 -38
  201. package/dist/plugins/org-delivery-quota-store.js +2 -2
  202. package/dist/plugins/outcome-ledger-sql.d.ts +2 -2
  203. package/dist/plugins/outcome-ledger-sql.js +2 -2
  204. package/dist/plugins/permission-rule-store-sql.d.ts +17 -19
  205. package/dist/plugins/permission-rule-store-sql.js +29 -32
  206. package/dist/plugins/pg-pool.d.ts +7 -3
  207. package/dist/plugins/pg-session-storage.d.ts +31 -20
  208. package/dist/plugins/pg-session-storage.js +120 -52
  209. package/dist/plugins/remote-env-adb.d.ts +18 -19
  210. package/dist/plugins/remote-env-adb.js +91 -66
  211. package/dist/plugins/remote-env-device.d.ts +23 -31
  212. package/dist/plugins/remote-env-device.js +19 -17
  213. package/dist/plugins/remote-env-e2b.d.ts +27 -21
  214. package/dist/plugins/remote-env-e2b.js +91 -45
  215. package/dist/plugins/remote-env-file-error.d.ts +3 -1
  216. package/dist/plugins/remote-env-file-error.js +9 -3
  217. package/dist/plugins/remote-env-host.d.ts +31 -34
  218. package/dist/plugins/remote-env-host.js +91 -72
  219. package/dist/plugins/remote-env-k8s.d.ts +13 -29
  220. package/dist/plugins/remote-env-k8s.js +63 -55
  221. package/dist/plugins/remote-env-local-docker.d.ts +24 -12
  222. package/dist/plugins/remote-env-local-docker.js +49 -61
  223. package/dist/plugins/remote-env-ssh.d.ts +11 -19
  224. package/dist/plugins/remote-env-ssh.js +74 -57
  225. package/dist/plugins/remote-shell.d.ts +100 -3
  226. package/dist/plugins/remote-shell.js +166 -2
  227. package/dist/plugins/resume-anchor-store-sql.js +2 -2
  228. package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
  229. package/dist/plugins/retention-lane-store-sql.js +2 -2
  230. package/dist/plugins/retention-store-sql.d.ts +10 -7
  231. package/dist/plugins/retention-store-sql.js +13 -7
  232. package/dist/plugins/run-store-sql.d.ts +13 -3
  233. package/dist/plugins/run-store-sql.js +20 -15
  234. package/dist/plugins/schema-consistency.d.ts +21 -11
  235. package/dist/plugins/schema-consistency.js +15 -9
  236. package/dist/plugins/schema-drift-sentence.d.ts +27 -0
  237. package/dist/plugins/schema-drift-sentence.js +38 -0
  238. package/dist/plugins/schema-ensure-legs.d.ts +2 -3
  239. package/dist/plugins/schema-ensure-legs.js +2 -2
  240. package/dist/plugins/schema-live-columns.d.ts +1 -1
  241. package/dist/plugins/session-capture-record-store-sql.js +1 -1
  242. package/dist/plugins/session-fork.d.ts +54 -0
  243. package/dist/plugins/session-fork.js +38 -1
  244. package/dist/plugins/session-row-sql.d.ts +22 -0
  245. package/dist/plugins/session-row-sql.js +81 -0
  246. package/dist/plugins/session-rules-column.d.ts +1 -1
  247. package/dist/plugins/session-rules-column.js +1 -1
  248. package/dist/plugins/session-store.d.ts +1 -1
  249. package/dist/plugins/session-workspace-cell.d.ts +1 -1
  250. package/dist/plugins/session-workspace-cell.js +1 -1
  251. package/dist/plugins/shared-memory-store-sql.js +2 -2
  252. package/dist/plugins/sql-driver.d.ts +10 -5
  253. package/dist/plugins/sql-driver.js +6 -6
  254. package/dist/plugins/sql-errors.js +1 -1
  255. package/dist/plugins/store-backend.d.ts +5 -7
  256. package/dist/plugins/store-backend.js +23 -11
  257. package/dist/plugins/store-contracts.d.ts +25 -5
  258. package/dist/plugins/task-list-store-sql.js +11 -11
  259. package/dist/plugins/tidb-pool.d.ts +12 -7
  260. package/dist/plugins/tidb-pool.js +13 -7
  261. package/dist/plugins/tidb-session-storage.js +4 -4
  262. package/dist/plugins/tidb-session-store.d.ts +57 -26
  263. package/dist/plugins/tidb-session-store.js +127 -59
  264. package/dist/plugins/tool-result-store-sql.d.ts +5 -4
  265. package/dist/plugins/tool-result-store-sql.js +21 -13
  266. package/dist/plugins/user-input-ledger-sql.js +2 -2
  267. package/dist/plugins/workflow-journal-store-sql.js +5 -5
  268. package/dist/plugins/workflow-run-store-sql.js +19 -19
  269. package/dist/plugins/write-behind-counter.d.ts +2 -3
  270. package/dist/plugins/write-behind-counter.js +5 -5
  271. package/dist/project-memory.d.ts +9 -15
  272. package/dist/project-memory.js +5 -4
  273. package/dist/request-key-closure.js +1 -1
  274. package/dist/request-value-closure.d.ts +6 -7
  275. package/dist/request-value-closure.js +1 -3
  276. package/dist/resource-suspend.d.ts +14 -12
  277. package/dist/resource-suspend.js +1 -1
  278. package/dist/resource-window.d.ts +4 -3
  279. package/dist/run-local.d.ts +6 -0
  280. package/dist/run-local.js +34 -35
  281. package/dist/runs.d.ts +10 -5
  282. package/dist/runs.js +52 -66
  283. package/dist/security.d.ts +38 -12
  284. package/dist/security.js +8 -2
  285. package/dist/server-secret-env.d.ts +9 -5
  286. package/dist/session-children-retire.d.ts +27 -9
  287. package/dist/session-children-retire.js +9 -5
  288. package/dist/session-incarnation.d.ts +20 -10
  289. package/dist/session-incarnation.js +5 -3
  290. package/dist/session-policy-wire.d.ts +1 -1
  291. package/dist/session-row.d.ts +114 -5
  292. package/dist/session-row.js +55 -5
  293. package/dist/session-titler.d.ts +2 -2
  294. package/dist/sql-engine-posture.d.ts +1 -1
  295. package/dist/sql-engine-posture.js +1 -1
  296. package/dist/{plugins → stores-sql}/background-agent-store-sql.d.ts +2 -2
  297. package/dist/{plugins → stores-sql}/background-agent-store-sql.js +8 -8
  298. package/dist/{plugins → stores-sql}/session-policy-store-sql.d.ts +7 -5
  299. package/dist/{plugins → stores-sql}/session-policy-store-sql.js +12 -12
  300. package/dist/{plugins → stores-sql}/usage-window-store-sql.d.ts +1 -1
  301. package/dist/{plugins → stores-sql}/usage-window-store-sql.js +3 -3
  302. package/dist/task-a2a.d.ts +1 -1
  303. package/dist/task-a2a.js +5 -6
  304. package/dist/task-cwd.d.ts +6 -1
  305. package/dist/task-mcp.d.ts +22 -9
  306. package/dist/task-mcp.js +17 -9
  307. package/dist/terminal.d.ts +27 -0
  308. package/dist/terminal.js +6 -0
  309. package/dist/tool-approval.d.ts +6 -0
  310. package/dist/tool-approval.js +8 -1
  311. package/dist/trace/project.d.ts +1 -0
  312. package/dist/trace/project.js +1 -0
  313. package/dist/trace/redact.d.ts +3 -1
  314. package/dist/trace/redact.js +80 -28
  315. package/dist/trace/self-minted-wire.d.ts +169 -2
  316. package/dist/trace/self-minted-wire.js +54 -1
  317. package/dist/url-refusal.d.ts +1 -1
  318. package/dist/web-admin-client/apply-effective.d.ts +17 -3
  319. package/dist/web-admin-client/apply-effective.js +20 -10
  320. package/dist/web-admin-client/candidate-gate.d.ts +11 -7
  321. package/dist/web-admin-client/candidate-gate.js +1 -1
  322. package/dist/web-admin-client/http-client.d.ts +5 -4
  323. package/dist/web-admin-client/http-client.js +2 -2
  324. package/dist/web-admin-client/read-warnings.d.ts +7 -17
  325. package/dist/web-admin-client/read-warnings.js +5 -9
  326. package/dist/web-admin-client/skills-mcp.js +3 -2
  327. package/dist/web-admin-client/types.d.ts +6 -0
  328. package/package.json +3 -3
  329. package/wire-changes/server@7.139.0.json +348 -0
  330. package/wire-changes/server@7.140.0.json +184 -0
  331. package/dist/http/device-placement.d.ts +0 -175
  332. package/dist/http/device-placement.js +0 -145
@@ -25,7 +25,7 @@
25
25
  * 依赖纪律:本文件是**叶**(只 type-import config-types + 值引 deployment-governance 的守卫集编译门),
26
26
  * 不引 config.ts,故 config.ts / runs.ts 都可以安全引它。
27
27
  */
28
- import type { ServiceConfigFlat } from "./config-types.js";
28
+ import type { ConfigProviderWord, ServiceConfigFlat } from "./config-types.js";
29
29
  /**
30
30
  * 活体心跳周期(ms)——`runs.ts` 的 `HEARTBEAT_MS` 就是它(那边 re-export,单源在此)。
31
31
  *
@@ -34,9 +34,9 @@ import type { ServiceConfigFlat } from "./config-types.js";
34
34
  */
35
35
  export declare const LIVENESS_HEARTBEAT_MS = 30000;
36
36
  /** 闭集:新增一条不变量必须在这里加词(拼错 = 编译红,而不是运行期悄悄不判)。 */
37
- export type CrossInvariantId = "run-stale-heartbeat" | "bind-posture" | "bake-runner-credential" | "direct-door-anchors" | "operator-principals-required" | "operator-single-user" | "bake-operator-principals" | "sensitive-write-patterns" | "leader-host-lane" | "multi-tenant-shared-lane" | "leader-durable-store" | "device-durable-store" | "device-durable-approval" | "model-provider-word" | "gateway-url-userinfo" | "anthropic-credential-exclusive" | "model-route-endpoint" | "default-model-resolvable" | "refused-names-not-minted" | "require-execution-lane" | "center-one-identity" | "workflow-park-decision-domain";
37
+ export type CrossInvariantId = "run-stale-heartbeat" | "bind-posture" | "bake-runner-credential" | "direct-door-anchors" | "operator-principals-required" | "operator-single-user" | "bake-operator-principals" | "sensitive-write-patterns" | "leader-host-lane" | "multi-tenant-shared-lane" | "leader-durable-store" | "device-durable-store" | "device-durable-approval" | "model-provider-word" | "gateway-url-userinfo" | "anthropic-credential-exclusive" | "model-route-endpoint" | "default-model-resolvable" | "refused-names-not-minted" | "require-execution-lane" | "center-one-identity" | "workflow-park-decision-domain" | "remote-config-provider-url" | "retention-lane-complete";
38
38
  /** 表读的键集(取自平铺配置型 ⇒ 键名/类型永不与真配置漂)。 */
39
- export type CrossInvariantView = Readonly<Pick<ServiceConfigFlat, "runStaleSec" | "authToken" | "authTokens" | "allowUnauthedWrites" | "imageBakes" | "directApprovalDoor" | "durableApproval" | "approvalHmacKeys" | "principalJwtPubkeys" | "principalJwtIss" | "principalJwtAud" | "requirePrincipal" | "operatorPrincipals" | "operatorSingleUser" | "sensitiveWritePatterns" | "leaderEnabled" | "selfOrchestrationEnabled" | "workflowRunStoreBackend" | "remoteExec" | "requireExecutionLane" | "dbBackend" | "tidb" | "pg" | "envModel" | "gatewayBaseUrl" | "gatewayFallbackUrls" | "anthropic" | "models" | "modelRefusals" | "tiers" | "authBridgeIssuer" | "webAdmin">>;
39
+ export type CrossInvariantView = Readonly<Pick<ServiceConfigFlat, "runStaleSec" | "authToken" | "authTokens" | "allowUnauthedWrites" | "imageBakes" | "directApprovalDoor" | "durableApproval" | "approvalHmacKeys" | "principalJwtPubkeys" | "principalJwtIss" | "principalJwtAud" | "requirePrincipal" | "operatorPrincipals" | "operatorSingleUser" | "sensitiveWritePatterns" | "leaderEnabled" | "selfOrchestrationEnabled" | "workflowRunStoreBackend" | "remoteExec" | "requireExecutionLane" | "dbBackend" | "tidb" | "pg" | "envModel" | "gatewayBaseUrl" | "gatewayFallbackUrls" | "anthropic" | "models" | "modelRefusals" | "tiers" | "authBridgeIssuer" | "webAdmin" | "configProvider" | "retentionPolicy" | "retentionSweep">>;
40
40
  export interface CrossInvariantInput {
41
41
  /** 现役配置(boot 期 = 候选自身)。 */
42
42
  readonly live: CrossInvariantView;
@@ -107,6 +107,26 @@ export declare function workflowParkDecisionDomainRefusal(v: Pick<CrossInvariant
107
107
  * 标准部署形。没有 web 基址 ⇒ 无可互证,过。
108
108
  */
109
109
  export declare function centerIdentityRefusal(v: Pick<CrossInvariantView, "authBridgeIssuer" | "webAdmin">): string | undefined;
110
+ /**
111
+ * `remote-config-provider-url` —— **配置源的词要么兑现、要么拒,从不被读成另一种源**。`CONFIG_PROVIDER=remote` 说的是「这台 worker 的配置来自中心」,
112
+ * 中心就是 `WEB_ADMIN_ENV.url` 那一只;没有它,这句话无处兑现 —— 不建配置源(服务端)或读本地 `config.d`(run-local)都是把它读成了另一种源,
113
+ * 多租部署的 entitlement / 模型目录 / 治理整份缺席而进程照起。判据与拒句的唯一属主;配置源判官(`config-provider.ts` 的 `configSourceKind`)
114
+ * 收到这一组合时抛的也是这一句(到得了那里 = 有人绕过了 `loadConfig`)。状态型:两只键都只来自 env、运行期无写点 ⇒ 热路径上恒与 boot 同答。
115
+ */
116
+ export declare function remoteConfigProviderUrlRefusal(v: {
117
+ readonly configProvider?: ConfigProviderWord | undefined;
118
+ readonly webAdmin?: unknown;
119
+ }): string | undefined;
120
+ /**
121
+ * `retention-lane-complete` —— **被要的扫车道必须齐**。要车道的旋钮有两根:节律(`RETENTION_SWEEP_INTERVAL_SEC > 0`)与灰度档
122
+ * `RETENTION_MODE=enforce`(「按策略删」);齐 = 有视界(`RETENTION_MAX_AGE_DAYS`,算 cutoff)且节律 > 0(车道真在跑)。缺一 ⇒ 拒:
123
+ * enforce 而车道不跑 / 没有视界,运维以为在删而什么都没删(能力位 `retention` 只在车道齐时在场);节律在而没有视界,车道每拍枚举域、什么都算不出。
124
+ * 一条规则两种要法,拒句按要法说出路(enforce:补缺的键,或改回 audit-only —— 节律在而天数缺时连节律一起设 0;只给节律:补天数或节律设 0),
125
+ * 每条出路照做都落在本律之内(起得来)。audit-only 下「天数在、车道关」不在律内 ——
126
+ * 那只是一份声明,起服 warn `retention_policy_not_executed` 说出来(`boot/governance-seams.ts`)。车道的**接线**(执行器 / 方法 / 店声明)不是配置事实,
127
+ * 留在扫车道自持门(`boot/retention-lane.ts`)。状态型:三键都只来自 env、运行期无写点 ⇒ 热路径上恒与 boot 同答。
128
+ */
129
+ export declare function retentionLaneRefusal(v: Pick<CrossInvariantView, "retentionPolicy" | "retentionSweep">): string | undefined;
110
130
  export declare const CONFIG_CROSS_INVARIANTS: readonly CrossInvariant[];
111
131
  /**
112
132
  * 按 id 取**一条**([ref]②:boot 面的单源化出口)。
@@ -103,6 +103,34 @@ export function centerIdentityRefusal(v) {
103
103
  `the same web-admin: same host and port (http and https on one host count as one). Set ${WEB_ADMIN_ENV.webUrl} to that web-admin's console, set ` +
104
104
  `AUTH_BRIDGE_ISSUER to the web-admin's public origin, or unset ${WEB_ADMIN_ENV.webUrl}. Refusing to boot.`);
105
105
  }
106
+ export function remoteConfigProviderUrlRefusal(v) {
107
+ return v.configProvider === "remote" && v.webAdmin === undefined
108
+ ? `CONFIG_PROVIDER=remote names the web-admin center as this worker's config source, but ${WEB_ADMIN_ENV.url} is not set — there is no center to pull ` +
109
+ "from, so this worker would run without the center's configuration (tenant entitlements, model catalog, governance) while it is declared centrally managed. " +
110
+ `Set ${WEB_ADMIN_ENV.url} to the center's base URL, or set CONFIG_PROVIDER=local to read the local config directory (unset CONFIG_PROVIDER for an env-only worker). ` +
111
+ "Refusing to boot."
112
+ : undefined;
113
+ }
114
+ export function retentionLaneRefusal(v) {
115
+ const { mode, intervalSec } = v.retentionSweep;
116
+ const cadence = intervalSec > 0;
117
+ const horizon = v.retentionPolicy !== undefined;
118
+ if ((mode !== "enforce" && !cadence) || (cadence && horizon))
119
+ return undefined;
120
+ const gaps = [
121
+ ...(horizon ? [] : ["RETENTION_MAX_AGE_DAYS is unset (no horizon to compute a cutoff from)"]),
122
+ ...(cadence ? [] : ["RETENTION_SWEEP_INTERVAL_SEC is unset or 0 (the sweep lane does not run)"]),
123
+ ].join(" and ");
124
+ if (mode === "enforce") {
125
+ const needs = [...(horizon ? [] : ["RETENTION_MAX_AGE_DAYS"]), ...(cadence ? [] : ["RETENTION_SWEEP_INTERVAL_SEC above 0"])].join(" and ");
126
+ const declareOnly = cadence && !horizon ? "set RETENTION_MODE=audit-only (or unset it) and RETENTION_SWEEP_INTERVAL_SEC=0" : "set RETENTION_MODE=audit-only (or unset it)";
127
+ return (`RETENTION_MODE=enforce declares that the retention sweep lane deletes data older than the policy horizon, but ${gaps} — nothing would be deleted ` +
128
+ `while the deployment declares that it deletes. Set ${needs} (the sweep lane runs on a SQL backend), or ${declareOnly} ` +
129
+ "if this deployment is not to delete. Refusing to boot.");
130
+ }
131
+ return (`RETENTION_SWEEP_INTERVAL_SEC=${intervalSec} arms the retention sweep lane, but ${gaps} — the lane would enumerate domains every tick and compute nothing. ` +
132
+ "Set RETENTION_MAX_AGE_DAYS, or set RETENTION_SWEEP_INTERVAL_SEC=0 to leave the lane off. Refusing to boot.");
133
+ }
106
134
  export const CONFIG_CROSS_INVARIANTS = [
107
135
  {
108
136
  id: "run-stale-heartbeat",
@@ -297,6 +325,20 @@ export const CONFIG_CROSS_INVARIANTS = [
297
325
  bootAnchor: { file: "src/config.ts", marker: "CROSS-INVARIANT:center-one-identity" },
298
326
  check: ({ next }) => centerIdentityRefusal(next),
299
327
  },
328
+ {
329
+ id: "remote-config-provider-url",
330
+ keys: ["configProvider", "webAdmin"],
331
+ restartReason: "config-source",
332
+ bootAnchor: { file: "src/config.ts", marker: "CROSS-INVARIANT:remote-config-provider-url" },
333
+ check: ({ next }) => remoteConfigProviderUrlRefusal(next),
334
+ },
335
+ {
336
+ id: "retention-lane-complete",
337
+ keys: ["retentionPolicy", "retentionSweep"],
338
+ restartReason: "retention-lane",
339
+ bootAnchor: { file: "src/config.ts", marker: "CROSS-INVARIANT:retention-lane-complete" },
340
+ check: ({ next }) => retentionLaneRefusal(next),
341
+ },
300
342
  ];
301
343
  export function crossInvariant(id) {
302
344
  const inv = CONFIG_CROSS_INVARIANTS.find((i) => i.id === id);
@@ -1,15 +1,12 @@
1
- import { type DroppedConfigEntry, type RetiredDomainFinding, type UnreadConfigFile, type UnreadConfigKey } from "./web-admin-client/read-warnings.js";
2
- import { FileConfigStore } from "@sema-agent/settings-schema/node";
3
- import { type EffectiveConfig as AgentConfigEffective, type EffectiveReadWarning } from "@sema-agent/settings-schema";
1
+ import { type DroppedConfigEntry, type UnreadConfigFile, type UnreadConfigKey } from "./web-admin-client/read-warnings.js";
2
+ import { type ConfigDocumentRefusal, type EffectiveConfig as AgentConfigEffective, type EffectiveReadWarning } from "@sema-agent/settings-schema";
4
3
  import { fetchEffective as remoteFetchEffective, fetchSkillContent as remoteFetchSkillContent, type EffectiveConfig } from "./web-admin-client/facade.js";
5
4
  import type { CenterEndpoint } from "./web-admin-client/center-request.js";
6
5
  import type { ConfigProviderWord } from "./config-types.js";
7
6
  /** Result of a `fetchEffective` — EXACTLY the web-admin's return: the effective config + its etag, or
8
7
  * `null` for "unchanged" (remote 304; local: the version matched the caller's prior etag).
9
- * `domainErrors`([ref] registry-core 0.10.12 tolerant seam,local lane only):catalog 域坏文件不再
10
- * 连坐全包回落 env——坏域按该域 schema default 落+错误单列,好域照常生效;caller(main.ts)对每条打
11
- * per-domain warn 点名坏域。gate 域(governance/rosters/…)坏文件 tolerant 仍 throw(READ 容错不放宽
12
- * gate fail-loud,registry-core 半场精化)——那条路走既有的整包 catch。 */
8
+ * `domainErrors`:某个**读得出**的域判形失败(schema 坏形 / 拼错键 / 悬空引用;那个域已按契约的域档位落缺省或被逐条判过)—— 候选判官以
9
+ * `domain_invalid` 整拒;缺席 = 没有。读不出的**文档**不在这里(见 `refusedDocuments`)。 */
13
10
  /** 壳写在 `config.d/models.json` 条目上的装饰键(`sema*`)自 settings-schema 1.5.0 起是**声明过的扩展命名空间**
14
11
  * (`EXTENSION_NAMESPACES`):schema 照旧 strip、但不再报「未知键」,所以本函数收到的每一个未知键都是拼错/越界 ⇒ 候选门错误。
15
12
  * 此前把这类键当「通知」放行的整套下游机制(域豁免/键路径闭集/满额特判/单独的通知面)已全部撤回——意图在声明处说,消费方不猜。 */
@@ -25,9 +22,10 @@ import type { ConfigProviderWord } from "./config-types.js";
25
22
  * `effective.models.droppedCatalogEntries`(`GET /v1/models.droppedEntries` 的源,与 `models` 同世代)。 */
26
23
  /** `unreadFiles`:`config.d` 里读腿根本不读的文件(不是域 / 不是便携域)—— **不**进候选门(不是读的域判形失败),调用方一份一行
27
24
  * `config_unread_file` 点名、其余照用;缺席 = 没有(本地读腿才会有)。 */
28
- /** `retiredDomains`([ref]):带事实的退役域文档(契约包的墓碑)—— 读腿不抛,交成发现,候选判官以成因 `retired_domain` 整拒这份候选(与域判形失败
29
- * 同一条回落链、同一行拒判);缺席 = 没有。远端腿:那一键不进 effective、其余域照读;本地腿:契约读腿在读便携域之前就拒,交出的候选只有版本
30
- * (这棵树的内容版本,哈希含退役文件 ⇒ 改 / 删它版本即变),内容是空的 effective(被整拒,不会被应用)。 */
25
+ /** `refusedDocuments`:被拒文档 —— 契约的类型 `ConfigDocumentRefusal`(`{ document, reason, error }`,墓碑另带 `migration`;`reason` 是契约闭集
26
+ * `CONFIG_DOCUMENT_REFUSAL_REASONS`:`empty` / `invalid_json` / `not_object` / `io` 文件层,`retired_domain` 墓碑)。读腿不抛,交成发现,候选判官以发现自带的词整拒这份候选
27
+ * (与域判形失败同一条回落链、同一行拒判);缺席 = 没有。远端腿:wire 上只有墓碑一种,那一键不进 effective、其余域照读、版本照读;本地腿:契约的严读拒了这棵树 ⇒
28
+ * 被拒文档 = 契约整目录拒单 `inspectBundle` 的原样,什么内容都没读到 —— 候选是空的 effective(被整拒,不会被应用),版本 = 拒单那一读的契约版本(按文档内容寻址)。 */
31
29
  /** `unreadKeys`:本地读腿读了那份文件、却结构上不读其中一键(`prompts.json` 的 `workers`)—— 同 `unreadFiles`,不进候选门,调用方一键一行 `config_unread_key`。 */
32
30
  export type FetchEffectiveResult = {
33
31
  effective: EffectiveConfig;
@@ -39,7 +37,7 @@ export type FetchEffectiveResult = {
39
37
  droppedEntries?: DroppedConfigEntry[];
40
38
  unreadFiles?: UnreadConfigFile[];
41
39
  unreadKeys?: UnreadConfigKey[];
42
- retiredDomains?: RetiredDomainFinding[];
40
+ refusedDocuments?: ConfigDocumentRefusal[];
43
41
  readWarnings: readonly EffectiveReadWarning[];
44
42
  credentialIdentity?: string;
45
43
  } | null;
@@ -120,12 +118,12 @@ export interface ConfigProviderInput {
120
118
  };
121
119
  /** `CONFIG_PROVIDER` —— 闭集 `local` | `remote` | 缺席([ref]:词表属主 `CONFIG_PROVIDER_WORDS`,认不出的词在
122
120
  * `loadConfig` 就拒启,本层**不可能**再收到第三个词 —— 修前那条「认不出 ⇒ 当 local + warn」的臂随之删除)。
123
- * `local` forces the local backend; `remote` selects the center (falls through to local if no URL). */
121
+ * 读法只有 {@link configSourceKind} 一只:`local` 建本地源;`remote` 建中心源(没有 `webAdmin` ⇒ 抛,起服本应已拒);缺席 ⇒ 有中心建中心源、没有 ⇒ 抛(纯 env 部署不建配置源)。 */
124
122
  provider?: ConfigProviderWord;
125
123
  /** 本地配置源的根(持有 `config.d/<domain>.json`;FileConfigStore 吃根、读 `<root>/config.d`)。🔴 [ref]:**必填**,
126
124
  * 值恒来自 {@link configLocalRoot}(入口算一次,工厂与执行车道合成步读同一个)—— 修前是可选、缺席回落
127
125
  * `process.cwd()`,而工厂只在 `CONFIG_PROVIDER === "local"` 字面上递它 ⇒ 另一条走到 local 的路上配置源读 cwd、
128
- * 合成步读 localRoot,两个根分家。一个远程源也收它:`remote` 而无中心 URL 的形照样落回 local。 */
126
+ * 合成步读 localRoot,两个根分家。远程源也收它(入参形一份),只有本地源读它。 */
129
127
  localDir: string;
130
128
  /** [ref]:本地配置源的属主声明(`CONFIG_LOCAL_OWNER_UID`,配置席 `configLocalOwnerUid`)—— 每拍读 `config.d` 之前的目录信任判官与起服那一次判同一个值。
131
129
  * **必填**(值可以是 `undefined` = 没声明):两个生产构造点都必须递,漏递 = 起服判过、每拍却按「没声明」判 ⇒ 每一拍都拒(tsc 在这里挡)。 */
@@ -159,16 +157,19 @@ export declare class RemoteConfigProvider implements ConfigProvider {
159
157
  * stable change-detector. We map that down to the service-local `EffectiveConfig` shape and surface the
160
158
  * version as the etag (so the caller's "skip re-apply if etag unchanged" works locally too).
161
159
  */
160
+ /** 本地读腿对契约文件店只有一种读法 —— 严读 `getEffective()`。注入缝(测试)按这一形给;容错档位不在这条腿的类型里。 */
161
+ export interface StrictConfigStore {
162
+ getEffective(): Promise<AgentConfigEffective>;
163
+ }
162
164
  export declare class LocalConfigProvider implements ConfigProvider {
163
165
  #private;
164
166
  readonly kind: "local";
165
167
  /** 本地配置源不留正文盘缓存:正文就内联在 config.d 里(同一块盘),缓存它是第二份真源。 */
166
168
  readonly skillBodyCacheDir: undefined;
167
- private readonly store;
168
169
  /** [ref]b 可观测性:config_loaded 日志要能回答「到底读的哪个目录」——复验实录:只设 LOCAL_DATA_ROOT 时
169
170
  * config.d 静默读不到且 0 模型无告警(CONFIG_LOCAL_DIR 才是本 lane 的选目录旋钮)。 */
170
171
  readonly root: string;
171
- constructor(root: string, store?: FileConfigStore, trust?: {
172
+ constructor(root: string, store?: StrictConfigStore, trust?: {
172
173
  readonly declaredOwnerUid: number | undefined;
173
174
  });
174
175
  fetchEffective(etag: string | undefined): Promise<FetchEffectiveResult>;
@@ -186,15 +187,11 @@ export declare class LocalConfigProvider implements ConfigProvider {
186
187
  */
187
188
  export declare function mapToServiceEffective(eff: AgentConfigEffective, version: number): EffectiveConfig;
188
189
  /**
189
- * Pick the backend off a CLOSED `provider` enum (`local` | `remote` | undefined): LOCAL when
190
- * `CONFIG_PROVIDER=local`, OR when no web-admin URL is configured (a lone box with config.d/ on disk
191
- * and no control plane). REMOTE otherwise (a configured center URL, the default fleet posture). A
192
- * `CONFIG_PROVIDER=remote` with no URL is a misconfiguration — we fall through to local rather than
193
- * constructing a remote provider with no endpoint (the caller would have skipped the remote pull entirely
194
- * under the old code path; local-with-empty-config.d degrades to env the same way). An UNRECOGNIZED value
195
- * never reaches this function: `loadConfig` refuses to boot on it ([ref]), so a fat-fingered knob can
196
- * neither source config from an unintended network endpoint nor be read as "local" here while the
197
- * execution-lane default reads it as "not local".
190
+ * 建判官 {@link configSourceKind} 答出来的那一种配置源:`local` ⇒ {@link LocalConfigProvider}(根 = 递进来的 `localDir`);`remote` ⇒
191
+ * {@link RemoteConfigProvider}(中心 = `webAdmin`)。判官答「无配置源」(没写词、没配中心 = 纯 env 部署)⇒ 抛:调用方只在判官答 local / remote 时建
192
+ * (服务端第 2 段先问判官;run-local 在入口只放过 `local` 的词)。没有第三种读法 —— 「remote 而没有中心 ⇒ 落回本地」那一臂已删(配置源的词要么兑现、要么拒;
193
+ * 起服在 `loadConfig` 的配置不变量段拒这一组合,到得了这里 = 绕过了 `loadConfig`,判官抛起服拒的同一句)。认不出的词同样到不了这里:
194
+ * `loadConfig` 拒启([ref]),入参型是闭集。
198
195
  */
199
196
  export declare function createConfigProvider(input: ConfigProviderInput): ConfigProvider;
200
197
  /**
@@ -209,21 +206,20 @@ export declare function createConfigProvider(input: ConfigProviderInput): Config
209
206
  export declare function configLocalRoot(config: {
210
207
  readonly configLocalDir?: string | undefined;
211
208
  }): string;
209
+ /** 配置源的两种形态(纯 env 部署没有配置源 —— 判官答 `undefined`)。 */
210
+ export type ConfigSourceKind = "local" | "remote";
212
211
  /**
213
- * {@link createConfigProvider} 会造出**哪一种**配置源 —— 判据的唯一属主(构造器与执行车道合成步读同一只:
214
- * local 形 `config.d/remote-exec.json` 的 file-wins 覆写只在配置源是 local 时生效,车PI 修复轮 ①)。
215
- * `local` 或没配中心 ⇒ local;其余 ⇒ remote。([ref] 起入参是闭集:「认不出的词 ⇒ local」那一臂随拒启删除。)
216
- */
217
- export declare function configProviderKind(input: {
218
- readonly provider?: ConfigProviderWord | undefined;
219
- readonly webAdmin?: unknown;
220
- }): "local" | "remote";
221
- /**
222
- * HTTP 服务这一侧的配置源:web-admin 工厂**建不建** provider(`CONFIG_PROVIDER=local` 或配了中心才建)、建出来是哪一种。
223
- * `undefined` = 纯 env 部署(没有配置源)。工厂与执行车道合成步读这同一只(车PI 修复轮 ①:合成步排在工厂之前)。
212
+ * 这台进程的配置源是**哪一种** —— 判据的唯一属主(一个问题一个读者):HTTP 服务第 2 段(目录信任 + 一次性迁移、执行车道合成步)、
213
+ * web-admin 工厂与 {@link createConfigProvider}(run-local 经它;run-local 在入口只放过 `local` 的词)都问这一只。规则一条 —— 配置源的词要么兑现、要么拒:
214
+ * · `CONFIG_PROVIDER=local` ⇒ `local`(配没配中心都是;中心照样管 fleet 面);
215
+ * · `CONFIG_PROVIDER=remote` ⇒ `remote`;没有中心 ⇒ **抛**起服拒的同一句(`remoteConfigProviderUrlRefusal`;`loadConfig` 的配置不变量段本应已拒,
216
+ * 到得了这里 = 绕过了它)—— 修前这一形在两只判官里各被读成一种别的源(服务端「无配置源」、构造器「local」),零句;
217
+ * · 不写词 ⇒ 有中心 `remote`、没有 `undefined`(纯 env 部署,不建配置源)。
218
+ * 修前是两只判官(`configProviderKind` 答 local | remote、`serviceConfigSourceKind` 包一层答 local | remote | 无),对「不写词、没配中心」一只答 local、
219
+ * 一只答无;收成这一只,两名删除。
224
220
  */
225
- export declare function serviceConfigSourceKind(config: {
221
+ export declare function configSourceKind(config: {
226
222
  readonly configProvider?: ConfigProviderWord | undefined;
227
223
  readonly webAdmin?: unknown;
228
- }): "local" | "remote" | undefined;
224
+ }): ConfigSourceKind | undefined;
229
225
  //# sourceMappingURL=config-provider.d.ts.map
@@ -1,11 +1,12 @@
1
1
  import { readMcpSourceLabel } from "./mcp-source-label.js";
2
2
  import { createHmac, randomBytes } from "node:crypto";
3
- import { retiredDomainFindingOf, splitFoldedReadWarnings, withDroppedCatalogEntries } from "./web-admin-client/read-warnings.js";
4
- import { FileConfigStore } from "@sema-agent/settings-schema/node";
3
+ import { splitFoldedReadWarnings, withDroppedCatalogEntries } from "./web-admin-client/read-warnings.js";
4
+ import { FileConfigStore, inspectBundle } from "@sema-agent/settings-schema/node";
5
5
  import { assertLocalConfigDirTrusted } from "./config-dir-trust.js";
6
6
  import { danglingRefs, emptyEffective, findSkillContent, promptArtifactFor, renderRefIssue, skillContentHash, } from "@sema-agent/settings-schema";
7
7
  import { redactSecrets } from "./trace/redact.js";
8
8
  import { fetchEffective as remoteFetchEffective, fetchSkillContent as remoteFetchSkillContent, skillToolListsOf, WebAdminHttpError, } from "./web-admin-client/facade.js";
9
+ import { remoteConfigProviderUrlRefusal } from "./config-invariants.js";
9
10
  import { homedir } from "node:os";
10
11
  import { join } from "node:path";
11
12
  const OPERAND_FINGERPRINT_KEY = randomBytes(16);
@@ -24,7 +25,9 @@ export function redactConfigError(text) {
24
25
  export function fingerprintConfigOperand(operand) {
25
26
  return `#${createHmac("sha256", OPERAND_FINGERPRINT_KEY).update(operand).digest("hex").slice(0, 8)}`;
26
27
  }
27
- const redactDroppedEntry = (d) => ({ ...d, error: redactSecrets(d.error) });
28
+ const redactContractSentence = (text) => redactSecrets(text);
29
+ const redactDroppedEntry = (d) => ({ ...d, error: redactContractSentence(d.error) });
30
+ const redactRefusedDocument = (d) => ({ ...d, error: redactContractSentence(d.error) });
28
31
  export const BOOT_FETCH_DEFERRED = Symbol("boot-fetch-deferred");
29
32
  export function raceBootFetch(fetch, budgetMs) {
30
33
  if (budgetMs <= 0)
@@ -49,12 +52,13 @@ export class RemoteConfigProvider {
49
52
  async fetchEffective(etag) {
50
53
  const fn = this.deps.fetchEffective ?? remoteFetchEffective;
51
54
  const r = await fn(this.cc, etag, undefined, this.cc.worker);
52
- if (r === null || (r.domainErrors === undefined && r.droppedEntries === undefined))
55
+ if (r === null || (r.domainErrors === undefined && r.droppedEntries === undefined && r.refusedDocuments === undefined))
53
56
  return r;
54
57
  return {
55
58
  ...r,
56
59
  ...(r.domainErrors !== undefined ? { domainErrors: r.domainErrors.map((de) => ({ domain: de.domain, error: redactConfigError(de.error) })) } : {}),
57
60
  ...(r.droppedEntries !== undefined ? { droppedEntries: r.droppedEntries.map(redactDroppedEntry) } : {}),
61
+ ...(r.refusedDocuments !== undefined ? { refusedDocuments: r.refusedDocuments.map(redactRefusedDocument) } : {}),
58
62
  };
59
63
  }
60
64
  async fetchSkillContent(contentHash) {
@@ -73,14 +77,12 @@ export class LocalConfigProvider {
73
77
  kind = "local";
74
78
  skillBodyCacheDir = undefined;
75
79
  #servedSkills = { skills: [] };
76
- store;
77
80
  root;
78
81
  #injectedStore;
79
82
  #declaredOwnerUid;
80
83
  constructor(root, store, trust = { declaredOwnerUid: undefined }) {
81
84
  this.root = root;
82
85
  this.#injectedStore = store;
83
- this.store = store ?? new FileConfigStore(root);
84
86
  this.#declaredOwnerUid = trust.declaredOwnerUid;
85
87
  }
86
88
  async fetchEffective(etag) {
@@ -92,21 +94,16 @@ export class LocalConfigProvider {
92
94
  readWarnings.push(w);
93
95
  },
94
96
  });
95
- let read;
96
- let retired;
97
+ let eff;
97
98
  try {
98
- read = await store.getEffective({ tolerant: true });
99
+ eff = await store.getEffective();
99
100
  }
100
101
  catch (e) {
101
- retired = retiredDomainFindingOf(e);
102
- if (retired === undefined)
102
+ const inspection = await inspectBundle(this.root);
103
+ if (inspection.refusals.length === 0)
103
104
  throw e;
104
- const version = await store.getVersion().catch(() => {
105
- throw e;
106
- });
107
- read = { effective: { ...emptyEffective(), version }, domainErrors: [] };
105
+ return refusedRead(inspection.refusals.map(redactRefusedDocument), inspection.version, etag);
108
106
  }
109
- const { effective: eff, domainErrors } = read;
110
107
  const tag = String(eff.version);
111
108
  if (etag !== undefined && etag === tag)
112
109
  return null;
@@ -122,7 +119,7 @@ export class LocalConfigProvider {
122
119
  const folded = splitFoldedReadWarnings(readWarnings, "local");
123
120
  const parseErrors = folded.domainErrors.map((w) => ({ domain: w.domain, error: redactConfigError(w.error) }));
124
121
  const droppedEntries = folded.droppedEntries.map(redactDroppedEntry);
125
- const errors = [...domainErrors.map((de) => ({ domain: de.domain, error: redactConfigError(de.error) })), ...parseErrors, ...refErrors];
122
+ const errors = [...parseErrors, ...refErrors];
126
123
  this.#servedSkills = eff.skills;
127
124
  const unreadKeys = localUnreadPromptKeys(eff.prompts);
128
125
  return {
@@ -133,13 +130,23 @@ export class LocalConfigProvider {
133
130
  ...(droppedEntries.length > 0 ? { droppedEntries } : {}),
134
131
  ...(folded.unreadFiles.length > 0 ? { unreadFiles: folded.unreadFiles } : {}),
135
132
  ...(unreadKeys.length > 0 ? { unreadKeys } : {}),
136
- ...(retired !== undefined ? { retiredDomains: [retired] } : {}),
137
133
  };
138
134
  }
139
135
  async fetchSkillContent(contentHash) {
140
136
  return findSkillContent(this.#servedSkills, contentHash);
141
137
  }
142
138
  }
139
+ function refusedRead(refused, version, etag) {
140
+ const tag = String(version);
141
+ if (etag !== undefined && etag === tag)
142
+ return null;
143
+ return {
144
+ effective: mapToServiceEffective({ ...emptyEffective(), version }, version),
145
+ etag: tag,
146
+ readWarnings: [],
147
+ refusedDocuments: refused,
148
+ };
149
+ }
143
150
  function localUnreadPromptKeys(prompts) {
144
151
  const names = prompts?.workers === undefined ? [] : Object.keys(prompts.workers);
145
152
  return names.length === 0 ? [] : [{ file: "prompts.json", domain: "prompts", key: "workers", names }];
@@ -205,6 +212,8 @@ export function mapToServiceEffective(eff, version) {
205
212
  ...readMcpSourceLabel(s.name, s.source),
206
213
  ...(s.toolFaces !== undefined ? { toolFaces: s.toolFaces } : {}),
207
214
  ...(s.toolAxes !== undefined ? { toolAxes: s.toolAxes } : {}),
215
+ ...(s.sessionMetaKey !== undefined ? { sessionMetaKey: s.sessionMetaKey } : {}),
216
+ ...(s.startupTimeoutMs !== undefined ? { startupTimeoutMs: s.startupTimeoutMs } : {}),
208
217
  ...(s.authForm !== undefined ? { authForm: s.authForm } : {}),
209
218
  ...(s.entryKind !== undefined ? { entryKind: s.entryKind } : {}),
210
219
  };
@@ -248,21 +257,33 @@ export function mapToServiceEffective(eff, version) {
248
257
  };
249
258
  }
250
259
  export function createConfigProvider(input) {
251
- return configProviderKind(input) === "remote" && input.webAdmin !== undefined
252
- ? new RemoteConfigProvider(input.webAdmin, {}, input.skillBodyCacheDir)
253
- : new LocalConfigProvider(input.localDir, undefined, { declaredOwnerUid: input.localOwnerUid });
260
+ const kind = configSourceKind({ configProvider: input.provider, webAdmin: input.webAdmin });
261
+ if (kind === "local")
262
+ return new LocalConfigProvider(input.localDir, undefined, { declaredOwnerUid: input.localOwnerUid });
263
+ if (kind === "remote" && input.webAdmin !== undefined)
264
+ return new RemoteConfigProvider(input.webAdmin, {}, input.skillBodyCacheDir);
265
+ throw new Error(`createConfigProvider: no config source to build (CONFIG_PROVIDER is unset and no center is configured — an env-only deployment). ` +
266
+ `Build a provider only when configSourceKind answers "local" or "remote".`);
254
267
  }
255
268
  export function configLocalRoot(config) {
256
269
  return config.configLocalDir ?? process.env.AGENT_DATA_DIR ?? join(homedir(), ".ai-agent");
257
270
  }
258
- export function configProviderKind(input) {
259
- if (input.provider === "local" || input.webAdmin === undefined)
260
- return "local";
261
- return "remote";
262
- }
263
- export function serviceConfigSourceKind(config) {
264
- if (config.webAdmin === undefined && config.configProvider !== "local")
265
- return undefined;
266
- return configProviderKind({ provider: config.configProvider, webAdmin: config.webAdmin });
271
+ export function configSourceKind(config) {
272
+ switch (config.configProvider) {
273
+ case "local":
274
+ return "local";
275
+ case "remote": {
276
+ const refusal = remoteConfigProviderUrlRefusal(config);
277
+ if (refusal !== undefined)
278
+ throw new Error(refusal);
279
+ return "remote";
280
+ }
281
+ case undefined:
282
+ return config.webAdmin !== undefined ? "remote" : undefined;
283
+ default: {
284
+ const unreachable = config.configProvider;
285
+ throw new Error(`configSourceKind: CONFIG_PROVIDER word outside the closed set: ${String(unreachable)}`);
286
+ }
287
+ }
267
288
  }
268
289
  //# sourceMappingURL=config-provider.js.map
@@ -891,7 +891,9 @@ export interface ServiceConfigFlat {
891
891
  * 跑在哪个用户的 home 下」)。显式声明**恒赢**;缺席时只有 home 属于车道本身的那几条车道有答案
892
892
  * (host/in-process = `os.homedir()`、e2b = 平台固定用户),k8s/local-docker(镜像属性)、
893
893
  * ssh(目标机登录用户)、adb/device 一律缺席 ⇒ `~/` 规则在下单时被 422 响亮拒。
894
- * 派生与逐车道理由的**单一属主** = `execution-lane-caps.ts` 的 `executionLaneHomeDir`。
894
+ * 声明与出厂答案都只是**主张**:读得出家目录的车道(device 之外的六条)在每只执行环境开起来时拿环境里命令看到的 `$HOME` 证它,
895
+ * 不一致 / 读不出 ⇒ 那只环境不开(拒句点名两值与改法);device 读不了 ⇒ 声明即座,起服披露「来自声明、未实测」。
896
+ * 派生与逐车道理由的**单一属主** = `execution-lane-caps.ts` 的 `executionLaneHomeDir` / `buildLaneHomeClaim`。
895
897
  * 非绝对路径 ⇒ **拒启**([ref] A 档;core 侧同判为 `config.execution_env_home_dir_invalid`)。
896
898
  */
897
899
  remoteExecHomeDir?: string;
@@ -936,7 +938,9 @@ export interface ServiceConfigFlat {
936
938
  token?: string;
937
939
  caCert?: string;
938
940
  insecureTls?: boolean;
939
- namespace?: string;
941
+ /** `K8S_NAMESPACE` — the namespace the sandbox pods live in. REQUIRED, no default: the loader refuses to start when `REMOTE_EXEC=k8s` names the
942
+ * lane without it, so this arm never carries an absent namespace and no consumer needs a fallback of its own. */
943
+ namespace: string;
940
944
  runtimeClass?: string;
941
945
  mountPath?: string;
942
946
  timeoutMs?: number;
@@ -1312,15 +1316,16 @@ export interface ServiceConfigFlat {
1312
1316
  *
1313
1317
  * 🔴 语义边界(成文,别当成"数据会被删"):core **只**拿它做启动期能力校验(锁着 + 店未声明
1314
1318
  * `retention:"managed"` ⇒ 拒启),引擎自己在任务路径上从不删数据;真执行(调度/重试/副本协调/审计)
1315
- * 是部署侧的活,本仓**尚未**建([ref] §5.2「server 半场四件皆新建」)。所以配了策略而没有任何
1316
- * managed 店时,启动会打一条 `retention_policy_not_executed` 的响亮 warn。
1319
+ * 是部署侧的活 —— 扫车道(`retentionSweep`,`boot/retention-lane.ts`)。配了策略而扫车道关着(只可能在 `audit-only` 档:
1320
+ * `enforce` 而车道不齐起服拒,配置不变量 `retention-lane-complete`)时,启动会打一条 `retention_policy_not_executed` 的响亮 warn。
1317
1321
  */
1318
1322
  retentionPolicy?: RetentionPolicy;
1319
1323
  /**
1320
1324
  * [ref] 车2 —— 托管留存 **sweep lane** 的两个旋钮(设计稿 `DESIGN-270-retention-lane.md` §3/§4)。
1321
1325
  * `retentionPolicy` 说的是「保留多久」(一句声明),本格说的是「谁在什么节律上按那句话删」。
1322
1326
  * **恒在场**(不是可选块):两根都有文档化的缺省,而缺省本身是一条要能被读出来的姿态 ——
1323
- * `{mode:"audit-only", intervalSec:0}` = 「lane 关着,真开起来也先只记账」。
1327
+ * `{mode:"audit-only", intervalSec:0}` = 「lane 关着,真开起来也先只记账」。被要的车道必须齐(`intervalSec > 0` 或 `mode:"enforce"` ⇒
1328
+ * 视界与 > 0 的节律都在,否则起服拒 —— 配置不变量 `retention-lane-complete`)。
1324
1329
  */
1325
1330
  retentionSweep: RetentionSweepConfig;
1326
1331
  /** Tool names that require operator approval before running (F4). Empty = no approval gate. */
@@ -2115,6 +2120,13 @@ export interface ServiceConfigFlat {
2115
2120
  * `READ_DENY_BUILTIN_EXCLUDE`=逗号分隔;不在表里的行名 / 空串**启动期响亮拒**。
2116
2121
  * 🔴 不变量(判据帖 G5b):删内建**绝不**削弱任务自己显式声明的 deny —— 那是另一层(additions)。 */
2117
2122
  readDenyBuiltinExclude?: readonly string[];
2123
+ /** 部署**要不要求**读拒表的字节地板(`READ_DENY_FLOOR_REQUIRED`,布尔,缺省 false)—— 交引擎 `RunnerDeps.readDenyFloorRequired`
2124
+ * (部署姿态座席族的一席,唯一取值点 `buildDeploymentPostureSeats`)。判官是引擎:一个 run 的读拒表有行、而它的执行环境块
2125
+ * `keepsReadFloor` 不为真时 —— true ⇒ 准备期拒(`config.read_deny_floor_unkept`,一个命令都不起;同步腿 409);false ⇒ run 照跑,
2126
+ * 每 run 一条 operator 通告同码(递归读照读表里的文件,通告不是保护)。出厂读拒档(credentials / agent-config)在岗时每条带手 run 的表都有行;
2127
+ * 本仓七车道的块今天都不守地板 ⇒ 设 true 的部署上带手 run 一律拒起(起服 warn `read_deny_floor_required_unkept` 先说)。
2128
+ * **仅 deployment 席**:TaskSpec 上没有同名键,任务无法放宽自己的部署。 */
2129
+ readDenyFloorRequired: boolean;
2118
2130
  /** core 7.46.0 [ref]:部署**声明**的配置根(`SEMA_CONFIG_DIR`,绝对路径;起服的供给动作建出目录,能不能用由引擎判)—— 交引擎 `RunnerDeps.agentConfigDir`
2119
2131
  * 与守卫集 `createSensitivePathPolicy` 的同名入参:内建读拒表里以 `.sema` 开头的行在这个根下同样拒,写进根下要问一次。缺席 = 没声明
2120
2132
  * ⇒ 引擎读字面 `~/.sema`(与 LKG / skill 缓存 / scheduler 店的缺省落点同一处)。读法单一属主 `sema-config-dir.ts`。 */
@@ -2267,8 +2279,10 @@ export interface ServiceConfigFlat {
2267
2279
  * 传输上界)与 `CENTER_CREDENTIAL_RENEW_LEAD_MAX_MS`(访问令牌寿命之半)之间,坏值拒启(解析口 `parseCenterCredentialRenewLeadMs`)。
2268
2280
  * 裸行文件 / `SEMA_WEB_ADMIN_TOKEN` 值形不受它影响(不续签)。`CENTER_CREDENTIAL_RENEW_LEAD_MS`。 */
2269
2281
  centerCredentialRenewLeadMs: number;
2270
- /** Dual-mode config SOURCE (DUAL-MODE-DESIGN §4): "remote" (web-admin HTTP) | "local" (.env + config.d
2282
+ /** Dual-mode config SOURCE (DUAL-MODE-DESIGN §4): "remote" (web-admin HTTP; needs SEMA_WEB_ADMIN_URL — remote without it
2283
+ * refuses to boot, cross-invariant `remote-config-provider-url`) | "local" (.env + config.d
2271
2284
  * via @sema-agent/settings-schema FileConfigStore) | unset → remote if SEMA_WEB_ADMIN_URL is set, else pure-env.
2285
+ * One reader: `configSourceKind` (config-provider.ts).
2272
2286
  * Env: CONFIG_PROVIDER —— [ref] 起闭集 {@link CONFIG_PROVIDER_WORDS}(认不出的词拒启;空串 = 未设)。
2273
2287
  * The same resolver/EffectiveConfig either way (can't drift). */
2274
2288
  configProvider?: ConfigProviderWord;
@@ -2296,7 +2310,7 @@ export type ServiceMemoryConfig = Pick<ServiceConfigFlat, "memoryEngineEnabled"
2296
2310
  * config 这一层它只是一句声明。 */
2297
2311
  export type ServiceAuthConfig = Pick<ServiceConfigFlat, "authToken" | "authTokens" | "allowUnauthedWrites" | "corsOrigins" | "principalHeader" | "requirePrincipal" | "autonomy" | "commandPolicy" | "compliancePosture" | "lockedConfigKeys" | "configCatalogEnabled" | "retentionPolicy" | "retentionSweep" | "operatorPrincipals" | "operatorSingleUser" | "principalJwtPubkeys" | "principalJwtIss" | "principalJwtAud" | "authBridgeIssuer" | "principalJwtMaxTtlSec" | "bindHost" | "bindHostSource">;
2298
2312
  /** 组:orchestration(编排 + 执行车道 + 沙箱面 + workflow/后台 agent 存留)。 */
2299
- export type ServiceOrchestrationConfig = Pick<ServiceConfigFlat, "remoteExec" | "remoteExecHomeDir" | "requireExecutionLane" | "worktreeIsolation" | "leaderEnabled" | "leaderFanoutEnabled" | "routerEnabled" | "selfOrchestrationEnabled" | "selfOrchestrationModels" | "selfOrchestrationWorkerIsolation" | "forkEnabled" | "experimentalObserverAgents" | "schedulerEnabled" | "schedulerSessionWakeup" | "schedulerSessionLifetime" | "schedulerStorePath" | "planModeEnabled" | "hooksTimeoutMs" | "workflowRunStoreBackend" | "workflowOrphanGraceMs" | "workflowJournalRetentionMs" | "workflowRunRetentionMs" | "usageWindows" | "workflowAgentsReadOnly" | "workflowSizeGuideline" | "backgroundAgentRetentionMs" | "backgroundAgentStaleRunningMs" | "backgroundAgentParkClaimStaleMs" | "delegationEntryCaps" | "rosterRetentionMs" | "leaderRunStaleMs" | "scratchpadSweepTtlMs" | "sandboxPkgSource" | "sandboxPkgSourceCustom" | "sessionAutoTitle" | "sessionAutoTitleSource" | "selectEnvironmentTool" | "envFactsEnabled" | "toolDeferLongtail" | "lspEnabled" | "lspHostEnabled" | "lspEnvAllow" | "imageBakes" | "readFace" | "readFaceSource" | "taskWriteFaceEscalation" | "readDenyPatterns" | "readDenyBuiltinTiers" | "readDenyBuiltinExclude" | "agentConfigDir" | "configLkgPath" | "configLkgEnabled">;
2313
+ export type ServiceOrchestrationConfig = Pick<ServiceConfigFlat, "remoteExec" | "remoteExecHomeDir" | "requireExecutionLane" | "worktreeIsolation" | "leaderEnabled" | "leaderFanoutEnabled" | "routerEnabled" | "selfOrchestrationEnabled" | "selfOrchestrationModels" | "selfOrchestrationWorkerIsolation" | "forkEnabled" | "experimentalObserverAgents" | "schedulerEnabled" | "schedulerSessionWakeup" | "schedulerSessionLifetime" | "schedulerStorePath" | "planModeEnabled" | "hooksTimeoutMs" | "workflowRunStoreBackend" | "workflowOrphanGraceMs" | "workflowJournalRetentionMs" | "workflowRunRetentionMs" | "usageWindows" | "workflowAgentsReadOnly" | "workflowSizeGuideline" | "backgroundAgentRetentionMs" | "backgroundAgentStaleRunningMs" | "backgroundAgentParkClaimStaleMs" | "delegationEntryCaps" | "rosterRetentionMs" | "leaderRunStaleMs" | "scratchpadSweepTtlMs" | "sandboxPkgSource" | "sandboxPkgSourceCustom" | "sessionAutoTitle" | "sessionAutoTitleSource" | "selectEnvironmentTool" | "envFactsEnabled" | "toolDeferLongtail" | "lspEnabled" | "lspHostEnabled" | "lspEnvAllow" | "imageBakes" | "readFace" | "readFaceSource" | "taskWriteFaceEscalation" | "readDenyPatterns" | "readDenyBuiltinTiers" | "readDenyBuiltinExclude" | "readDenyFloorRequired" | "agentConfigDir" | "configLkgPath" | "configLkgEnabled">;
2300
2314
  /** 组:limitsHttp(HTTP 面 + 各类上限/配额/回收窗)。 */
2301
2315
  export type ServiceLimitsHttpConfig = Pick<ServiceConfigFlat, "port" | "attachmentOrphanGraceMs" | "workspaceFileMaxBytes" | "attachmentMaxBytes" | "attachmentMimeAllowlist" | "attachmentUnboundTtlMs" | "infraCostRates" | "drainGraceMs" | "drainSecondSignalMinGapMs" | "sighupIdleGraceMs" | "parentPid" | "engineAutoExit" | "engineLingerMs" | "engineOrphanLingerMs" | "rateLimitPerMin" | "maxTaskCostUsd" | "maxTaskTokens" | "maxPrincipalCostUsd" | "costQuotaWindowSec" | "reapIntervalSec" | "runStaleSec" | "toolResultTtlSec">;
2302
2316
  /** 组:observability(可观测)。 */
package/dist/config.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type Model, type PathRuleBases, type PermissionRule } from "@sema-agent/core";
2
+ import { type ConfigProviderWord } from "./config-types.js";
2
3
  import { type CenterEndpoint } from "./web-admin-client/center-request.js";
3
4
  import { type Autonomy } from "./runtime-governance.js";
4
5
  import { type RunnerEnvNameAllowlistKnob, type ServerEnvNameAllowlistKnob } from "./env-name-allowlist-knobs.js";
@@ -106,6 +107,19 @@ export interface ConfigNotice {
106
107
  fields: Record<string, string>;
107
108
  }
108
109
  export declare function drainConfigNotices(): ConfigNotice[];
110
+ /**
111
+ * [ref] —— `CONFIG_PROVIDER` 的**唯一**读点。闭集 {@link CONFIG_PROVIDER_WORDS};缺席 / 空串 ⇒ 未表态(`undefined`);
112
+ * 其余一律**拒启**,拒因句列合法词。逐字比较(不 trim、不折大小写)—— 与本仓其余闭集 env 同律([ref]:认不出的词
113
+ * 不许被悄悄猜成某一种意思)。
114
+ *
115
+ * 修前这根旋钮是开放词,而一个认不出的词在同一进程里被读成两种意思:配置源判官(`configProviderKind`)把它当 `local`
116
+ * (读 `config.d/`、执行车道合成步照读 `remote-exec.json`),这里的隐式 host 臂与车道落点披露却按字面 `=== "local"`
117
+ * 判它**不是** local;web-admin 工厂同样按字面只在 `"local"` 上递本地根,于是配置源的根落回 `process.cwd()`、
118
+ * 合成步读的是 `localRoot` —— 两个根分家。收成闭集 + 一个读点之后,这三处读的是同一个值。
119
+ * 调用方两处、读的是同一张闭集:`loadConfig` 开头一次;`run-local` 在 `loadConfig` 之前一次(本入口只装本地配置源,词是 `remote` 就在这里拒 ——
120
+ * 配没配中心地址都一样)。
121
+ */
122
+ export declare function parseConfigProvider(): ConfigProviderWord | undefined;
109
123
  /** F10 (codex audit): drain + log BOTH pre-logger diagnostic collectors (S20 soft-knob warnings + [ref]④ boot
110
124
  * notices) in one place. EVERY entrypoint that calls loadConfig() then builds a logger must call this right
111
125
  * after (main.ts, run-local.ts) — a new entry that forgets it would silently drop operator-facing diagnostics
@@ -212,6 +226,25 @@ export declare function configKnobTable(): ConfigKnobRecord[];
212
226
  export declare const hostBackgroundShellEnabled: () => boolean;
213
227
  /** The `host` exec lane's spool-file stdio form; false ⇒ the pre-1.226 pipe fallback (read per exec). */
214
228
  export declare const hostExecSpoolEnabled: () => boolean;
229
+ /** 名单在活配置里的落点(服务进程四只旋钮;bake-runner 那只在它自己的进程里,不在 `ServiceConfig`)。 */
230
+ export type EnvNameAllowlistSeats = Pick<ServiceConfig, "lspEnvAllow" | "remoteExec">;
231
+ /**
232
+ * 沙箱名单(表列 `channel: "sandbox-grant"` 的服务侧旋钮,表派生)此刻交出去的名 —— 起服行 `remote_exec_enabled.sandboxEnvKeys` 读它(`boot/execution-env.ts`,
233
+ * 排序后只出键名)。只有被选中车道的那一只有落点;e2b / k8s 报的是名单点到的键,不含 `SANDBOX_PKG_SOURCE` 推导出的包源变量(那一组是区域常量,装配点另并)。
234
+ */
235
+ export declare function sandboxEnvNamesInForce(seats: EnvNameAllowlistSeats): readonly string[];
236
+ /** 声明增长后重判的一处命中:哪只旋钮、它交出去的哪个名、判官的拒因({@link ownCredentialNameProblem} 那一句,只回显名)。 */
237
+ export interface OwnCredentialInForce {
238
+ readonly knob: ServerEnvNameAllowlistKnob;
239
+ readonly name: string;
240
+ readonly problem: string;
241
+ }
242
+ /**
243
+ * 解析器头注 ② 那条不变量在**声明增长**那一刻的半边:对活配置里每只名单此刻交出去的名问**同一只**判官({@link ownCredentialNameProblem} → 引擎
244
+ * `inheritEnvPolicyProblem`,读引擎此刻的声明)。读活配置的落点,不重读 env(名单是起服输入;解析那一刻已判过形与当时的声明)。返回每一处命中,空 = 不相交。
245
+ * 调用点只有一处 = 声明增长的那一处(`apply-effective.ts` 的换代声明,真声明之后、席位换装之前)。
246
+ */
247
+ export declare function ownCredentialHitsInForce(seats: EnvNameAllowlistSeats): OwnCredentialInForce[];
215
248
  /** 名单型 env 旋钮的**唯一**解析器(规则全文见上方 `ENV_NAME_ALLOWLIST_KNOBS` 头注)。`undefined` = 没配(未设 / 空串)。
216
249
  * 服务侧旋钮要交本进程的姿态(③);runner 旋钮没有姿态,签名上就不收 —— 读者与行形由叶表的类型一起定,传错是编译红。 */
217
250
  export declare function parseEnvNameAllowlist(knob: ServerEnvNameAllowlistKnob, singleUserTurnkey: boolean): readonly string[] | undefined;