@sema-agent/server 7.131.0 → 7.133.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 (509) hide show
  1. package/MIGRATION.md +575 -0
  2. package/README.md +12 -9
  3. package/README.zh-CN.md +9 -6
  4. package/USAGE.md +326 -98
  5. package/deploy/sema-up/README.md +19 -1
  6. package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -2
  7. package/deploy/sema-up/chart/templates/server.yaml +5 -2
  8. package/deploy/sema-up/stack/compose.yaml +3 -0
  9. package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
  10. package/dist/adoption/plan.d.ts +3 -2
  11. package/dist/adoption/plan.js +7 -5
  12. package/dist/adoption/runner.js +3 -10
  13. package/dist/adoption/sql.d.ts +3 -2
  14. package/dist/adoption/sql.js +3 -5
  15. package/dist/adoption/wire.d.ts +4 -1
  16. package/dist/adoption/wire.js +1 -0
  17. package/dist/approval-ask-audit-store.d.ts +31 -13
  18. package/dist/approval-ask-audit-store.js +272 -74
  19. package/dist/approval-ask-machine.d.ts +15 -0
  20. package/dist/approval-ask-machine.js +6 -0
  21. package/dist/approval-ask-retention.d.ts +136 -0
  22. package/dist/approval-ask-retention.js +102 -0
  23. package/dist/approval-card.d.ts +82 -20
  24. package/dist/approval-card.js +46 -16
  25. package/dist/approval-deny-reasons.d.ts +1 -1
  26. package/dist/approval.d.ts +9 -0
  27. package/dist/approval.js +24 -3
  28. package/dist/audit.d.ts +33 -19
  29. package/dist/audit.js +12 -16
  30. package/dist/auth-bridge.d.ts +4 -0
  31. package/dist/auth-bridge.js +10 -11
  32. package/dist/bake-runner/main.js +3 -2
  33. package/dist/boot/deferred-sandbox-path-env.js +1 -1
  34. package/dist/boot/deployment-mods.d.ts +31 -0
  35. package/dist/boot/deployment-mods.js +26 -0
  36. package/dist/boot/execution-env.d.ts +1 -1
  37. package/dist/boot/execution-env.js +27 -12
  38. package/dist/boot/execution-lane.js +11 -0
  39. package/dist/boot/leader.js +2 -0
  40. package/dist/boot/memory-boundary.d.ts +2 -2
  41. package/dist/boot/memory-boundary.js +2 -2
  42. package/dist/boot/memory-consolidation.d.ts +5 -4
  43. package/dist/boot/memory-consolidation.js +7 -6
  44. package/dist/boot/org-delivery.d.ts +28 -0
  45. package/dist/boot/org-delivery.js +20 -0
  46. package/dist/boot/read-deny-anchor-audit.d.ts +17 -0
  47. package/dist/boot/read-deny-anchor-audit.js +36 -0
  48. package/dist/boot/reapers.d.ts +3 -0
  49. package/dist/boot/reapers.js +21 -1
  50. package/dist/boot/resolve-spec.d.ts +4 -5
  51. package/dist/boot/resolve-spec.js +74 -123
  52. package/dist/boot/runner-deps.d.ts +19 -8
  53. package/dist/boot/runner-deps.js +15 -2
  54. package/dist/boot/session-faces.d.ts +2 -7
  55. package/dist/boot/session-faces.js +4 -2
  56. package/dist/boot/stage-02-web-admin-pull.js +4 -1
  57. package/dist/boot/stage-03-store-backend.d.ts +1 -1
  58. package/dist/boot/stage-03-store-backend.js +2 -2
  59. package/dist/boot/stage-04-stores.d.ts +1 -1
  60. package/dist/boot/stage-05-execution-env.d.ts +4 -4
  61. package/dist/boot/stage-05-execution-env.js +7 -10
  62. package/dist/boot/stage-06-runners.d.ts +4 -2
  63. package/dist/boot/stage-06-runners.js +11 -7
  64. package/dist/boot/stage-07-capability-layer.d.ts +4 -2
  65. package/dist/boot/stage-07-capability-layer.js +27 -6
  66. package/dist/boot/stage-08-reapers.d.ts +4 -2
  67. package/dist/boot/stage-08-reapers.js +2 -2
  68. package/dist/boot/stage-09-leader.d.ts +6 -9
  69. package/dist/boot/stage-10-http-server.d.ts +6 -9
  70. package/dist/boot/stage-10-http-server.js +7 -9
  71. package/dist/boot/stores.d.ts +1 -1
  72. package/dist/boot/stores.js +7 -8
  73. package/dist/boot/web-admin.d.ts +4 -3
  74. package/dist/boot/web-admin.js +186 -98
  75. package/dist/boot/workflow-orchestration.d.ts +2 -0
  76. package/dist/boot/workflow-orchestration.js +2 -1
  77. package/dist/brain.js +25 -25
  78. package/dist/breaker-key.d.ts +6 -0
  79. package/dist/breaker-key.js +29 -0
  80. package/dist/budget.js +5 -4
  81. package/dist/caller-text-echo.d.ts +23 -0
  82. package/dist/caller-text-echo.js +21 -0
  83. package/dist/capabilities/brand-identity.d.ts +26 -0
  84. package/dist/capabilities/brand-identity.js +27 -0
  85. package/dist/capabilities/center-plugins.d.ts +7 -0
  86. package/dist/capabilities/center-plugins.js +1 -1
  87. package/dist/capabilities/center-prompts.d.ts +32 -59
  88. package/dist/capabilities/center-prompts.js +18 -32
  89. package/dist/capabilities/composite-members.d.ts +1 -1
  90. package/dist/capabilities/composite-members.js +1 -1
  91. package/dist/capabilities/engine-capabilities.js +2 -1
  92. package/dist/capabilities/execution-lane.js +2 -2
  93. package/dist/capabilities/hands-lane.d.ts +30 -6
  94. package/dist/capabilities/hands-lane.js +11 -1
  95. package/dist/capabilities/mcp-probe.d.ts +48 -3
  96. package/dist/capabilities/mcp-probe.js +47 -135
  97. package/dist/capabilities/scenarios.d.ts +95 -45
  98. package/dist/capabilities/scenarios.js +53 -38
  99. package/dist/capabilities/skills.d.ts +19 -4
  100. package/dist/capabilities/skills.js +30 -10
  101. package/dist/capability-facts.d.ts +34 -4
  102. package/dist/capability-facts.js +28 -2
  103. package/dist/center-config-tier.d.ts +69 -0
  104. package/dist/center-config-tier.js +42 -0
  105. package/dist/checkpoint-identity.d.ts +16 -0
  106. package/dist/checkpoint-identity.js +19 -0
  107. package/dist/config-catalog.d.ts +17 -10
  108. package/dist/config-catalog.js +47 -32
  109. package/dist/config-d-migration.d.ts +3 -1
  110. package/dist/config-d-migration.js +2 -2
  111. package/dist/config-dir-trust.d.ts +114 -0
  112. package/dist/config-dir-trust.js +388 -0
  113. package/dist/config-invariants.d.ts +18 -5
  114. package/dist/config-invariants.js +35 -3
  115. package/dist/config-lkg.d.ts +9 -9
  116. package/dist/config-lkg.js +20 -4
  117. package/dist/config-provider.d.ts +9 -2
  118. package/dist/config-provider.js +18 -6
  119. package/dist/config-types.d.ts +75 -20
  120. package/dist/config-types.js +8 -0
  121. package/dist/config.d.ts +13 -0
  122. package/dist/config.js +137 -62
  123. package/dist/delegated-session-owner.d.ts +185 -0
  124. package/dist/delegated-session-owner.js +119 -0
  125. package/dist/device-protocol.d.ts +5 -3
  126. package/dist/device-protocol.js +1 -1
  127. package/dist/device-ws-hub.js +21 -2
  128. package/dist/device-ws-protocol.d.ts +70 -6
  129. package/dist/device-ws-protocol.js +50 -22
  130. package/dist/elicitation.js +3 -2
  131. package/dist/entry-problems.d.ts +34 -0
  132. package/dist/entry-problems.js +14 -0
  133. package/dist/env-name-allowlist-knobs.d.ts +12 -2
  134. package/dist/env-name-allowlist-knobs.js +5 -4
  135. package/dist/exec-bounds.d.ts +15 -3
  136. package/dist/exec-bounds.js +4 -0
  137. package/dist/execution-lane-caps.d.ts +56 -10
  138. package/dist/execution-lane-caps.js +50 -0
  139. package/dist/field-conflict.d.ts +43 -0
  140. package/dist/field-conflict.js +20 -0
  141. package/dist/fleet/fleet-bus.d.ts +80 -6
  142. package/dist/fleet/fleet-bus.js +41 -9
  143. package/dist/hooks/classic-stations.d.ts +91 -0
  144. package/dist/hooks/classic-stations.js +27 -0
  145. package/dist/hooks/command-spawn.d.ts +57 -0
  146. package/dist/hooks/command-spawn.js +139 -0
  147. package/dist/hooks/hook-llm.d.ts +8 -5
  148. package/dist/hooks/hook-llm.js +79 -36
  149. package/dist/hooks/hook-runner.d.ts +349 -95
  150. package/dist/hooks/hook-runner.js +855 -568
  151. package/dist/hooks/hook-source.d.ts +44 -0
  152. package/dist/hooks/hook-source.js +40 -0
  153. package/dist/http/active-run-conflict.d.ts +5 -13
  154. package/dist/http/active-run-conflict.js +17 -27
  155. package/dist/http/admission.d.ts +8 -2
  156. package/dist/http/admission.js +188 -101
  157. package/dist/http/approval-sweeps.js +99 -21
  158. package/dist/http/caller-trust.d.ts +77 -0
  159. package/dist/http/caller-trust.js +143 -0
  160. package/dist/http/checkpoint-ctx.d.ts +41 -24
  161. package/dist/http/checkpoint-ctx.js +23 -16
  162. package/dist/http/claimed-run.d.ts +14 -0
  163. package/dist/http/claimed-run.js +15 -0
  164. package/dist/http/device-placement.d.ts +2 -4
  165. package/dist/http/device-placement.js +7 -11
  166. package/dist/http/dispatch.d.ts +0 -4
  167. package/dist/http/dispatch.js +15 -13
  168. package/dist/http/durable-run-leg.d.ts +6 -33
  169. package/dist/http/durable-run-leg.js +36 -10
  170. package/dist/http/health-self-report.d.ts +7 -5
  171. package/dist/http/health-self-report.js +4 -18
  172. package/dist/http/owner-access.d.ts +56 -0
  173. package/dist/http/owner-access.js +42 -0
  174. package/dist/http/principal-gate.d.ts +70 -28
  175. package/dist/http/principal-gate.js +61 -15
  176. package/dist/http/readiness.d.ts +11 -5
  177. package/dist/http/readiness.js +10 -3
  178. package/dist/http/refusal-body.d.ts +21 -0
  179. package/dist/http/refusal-body.js +4 -0
  180. package/dist/http/request-guards.d.ts +43 -23
  181. package/dist/http/request-guards.js +53 -17
  182. package/dist/http/resume-ctx-read.d.ts +2 -5
  183. package/dist/http/resume-ctx-read.js +7 -4
  184. package/dist/http/resume-legs.d.ts +28 -4
  185. package/dist/http/resume-legs.js +169 -91
  186. package/dist/http/retired-service-deps.d.ts +43 -0
  187. package/dist/http/retired-service-deps.js +18 -0
  188. package/dist/http/route-ctx.d.ts +44 -28
  189. package/dist/http/route-ctx.js +4 -0
  190. package/dist/http/route-table.js +2 -0
  191. package/dist/http/routes/a2a-serve.js +3 -4
  192. package/dist/http/routes/admin-config-refresh.js +1 -1
  193. package/dist/http/routes/admin-drain.js +1 -1
  194. package/dist/http/routes/admin-memory-optout.js +5 -1
  195. package/dist/http/routes/adoption.js +2 -9
  196. package/dist/http/routes/approvals-assistant.js +49 -48
  197. package/dist/http/routes/background.js +3 -2
  198. package/dist/http/routes/capabilities.js +21 -5
  199. package/dist/http/routes/config-catalog.d.ts +3 -3
  200. package/dist/http/routes/config-catalog.js +1 -1
  201. package/dist/http/routes/devices.js +3 -17
  202. package/dist/http/routes/diagnostics.js +6 -2
  203. package/dist/http/routes/images.js +6 -7
  204. package/dist/http/routes/leader.js +1 -8
  205. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  206. package/dist/http/routes/mcp-reconnect.js +3 -2
  207. package/dist/http/routes/memory-bundle.js +1 -1
  208. package/dist/http/routes/memory-compliance.js +1 -1
  209. package/dist/http/routes/memory-consolidation.js +1 -1
  210. package/dist/http/routes/memory-origin.js +1 -1
  211. package/dist/http/routes/memory-policy.d.ts +1 -1
  212. package/dist/http/routes/memory-policy.js +3 -2
  213. package/dist/http/routes/notify-wake.js +8 -21
  214. package/dist/http/routes/observability.js +2 -2
  215. package/dist/http/routes/principal-inbox.d.ts +39 -0
  216. package/dist/http/routes/principal-inbox.js +76 -0
  217. package/dist/http/routes/retention-ops.js +2 -9
  218. package/dist/http/routes/rules.js +5 -18
  219. package/dist/http/routes/runs.d.ts +5 -0
  220. package/dist/http/routes/runs.js +34 -107
  221. package/dist/http/routes/session-sync.js +15 -26
  222. package/dist/http/routes/sessions.js +30 -40
  223. package/dist/http/routes/shared-memory.js +2 -13
  224. package/dist/http/routes/side-query.js +8 -7
  225. package/dist/http/routes/tasks.js +67 -21
  226. package/dist/http/routes/workflows.d.ts +351 -0
  227. package/dist/http/routes/workflows.js +153 -119
  228. package/dist/http/send.d.ts +33 -10
  229. package/dist/http/send.js +21 -4
  230. package/dist/http/server.d.ts +27 -18
  231. package/dist/http/server.js +34 -6
  232. package/dist/http/stored-body-replay.js +17 -4
  233. package/dist/http/submit-ctx.d.ts +25 -0
  234. package/dist/http/submit-ctx.js +40 -0
  235. package/dist/http/submit-replay.d.ts +4 -3
  236. package/dist/http/submit-replay.js +5 -4
  237. package/dist/http/wire-types.d.ts +11 -8
  238. package/dist/index.d.ts +2 -2
  239. package/dist/index.js +1 -2
  240. package/dist/lane-home-probe.d.ts +112 -0
  241. package/dist/lane-home-probe.js +101 -0
  242. package/dist/leader/endpoint.d.ts +4 -1
  243. package/dist/leader/endpoint.js +11 -10
  244. package/dist/limit-refusal.d.ts +59 -0
  245. package/dist/limit-refusal.js +15 -0
  246. package/dist/main.js +1 -1
  247. package/dist/mcp-assertion-header.d.ts +32 -19
  248. package/dist/mcp-assertion-header.js +10 -9
  249. package/dist/mcp-tool-faces.d.ts +5 -0
  250. package/dist/mcp-tool-faces.js +6 -4
  251. package/dist/memory-project-layer.d.ts +37 -0
  252. package/dist/memory-project-layer.js +46 -0
  253. package/dist/memory-scope.d.ts +24 -17
  254. package/dist/memory-scope.js +24 -8
  255. package/dist/memory-sync-client.d.ts +27 -13
  256. package/dist/memory-sync-client.js +107 -18
  257. package/dist/model-entry-refusal.d.ts +9 -1
  258. package/dist/model-entry-refusal.js +6 -1
  259. package/dist/model-plane-face.d.ts +51 -0
  260. package/dist/model-plane-face.js +24 -0
  261. package/dist/model-provider.d.ts +44 -12
  262. package/dist/model-provider.js +21 -2
  263. package/dist/model-route-endpoint.d.ts +9 -12
  264. package/dist/model-route-endpoint.js +8 -11
  265. package/dist/model-route-env.d.ts +22 -0
  266. package/dist/model-route-env.js +2 -0
  267. package/dist/model-route-gap.d.ts +60 -30
  268. package/dist/model-route-gap.js +21 -15
  269. package/dist/observability/corrupt-read-seat.d.ts +7 -0
  270. package/dist/observability/corrupt-read-seat.js +9 -0
  271. package/dist/observability/cost-taxonomy.d.ts +7 -7
  272. package/dist/observability/err-text.d.ts +6 -0
  273. package/dist/observability/err-text.js +18 -4
  274. package/dist/observability/fail-open.d.ts +76 -14
  275. package/dist/observability/fail-open.js +76 -14
  276. package/dist/observability/metrics.js +4 -1
  277. package/dist/observability/prompt-manifest.d.ts +33 -82
  278. package/dist/observability/prompt-manifest.js +122 -17
  279. package/dist/observability/run-terminal.js +14 -6
  280. package/dist/observability/secret-env-scrub.d.ts +13 -1
  281. package/dist/observability/secret-env-scrub.js +13 -1
  282. package/dist/observability/tool-trace.d.ts +16 -21
  283. package/dist/observability/tool-trace.js +58 -49
  284. package/dist/operator-ask.d.ts +10 -0
  285. package/dist/operator-ask.js +3 -0
  286. package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
  287. package/dist/orchestration/workflow-agent-session-index.js +9 -13
  288. package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
  289. package/dist/orchestration/workflow-completion-inbox.js +13 -0
  290. package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
  291. package/dist/orchestration/workflow-notify-journal.js +27 -34
  292. package/dist/orchestration/workflow-park-decision.d.ts +89 -0
  293. package/dist/orchestration/workflow-park-decision.js +118 -0
  294. package/dist/org-delivery-gate.d.ts +81 -0
  295. package/dist/org-delivery-gate.js +59 -0
  296. package/dist/panel-tool-names.d.ts +23 -0
  297. package/dist/panel-tool-names.js +8 -0
  298. package/dist/parked-decide.d.ts +39 -6
  299. package/dist/parked-decide.js +98 -51
  300. package/dist/parked-revive-surface.d.ts +9 -2
  301. package/dist/parked-revive-surface.js +11 -8
  302. package/dist/per-task-image.d.ts +7 -1
  303. package/dist/per-task-image.js +3 -3
  304. package/dist/permission-rule-list.d.ts +1 -1
  305. package/dist/permission-rule-list.js +2 -2
  306. package/dist/plain-string-record.d.ts +25 -0
  307. package/dist/plain-string-record.js +32 -0
  308. package/dist/plugins/approval-ask-store-file.d.ts +16 -1
  309. package/dist/plugins/approval-ask-store-file.js +21 -0
  310. package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
  311. package/dist/plugins/approval-ask-store-memory.js +34 -2
  312. package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
  313. package/dist/plugins/approval-ask-store-sql.js +37 -1
  314. package/dist/plugins/blob-backend.d.ts +83 -15
  315. package/dist/plugins/blob-backend.js +68 -15
  316. package/dist/plugins/breaker-state-sql.d.ts +2 -2
  317. package/dist/plugins/breaker-state-sql.js +4 -4
  318. package/dist/plugins/caching-session-store.d.ts +3 -0
  319. package/dist/plugins/caching-session-store.js +3 -0
  320. package/dist/plugins/checkpoint-store-sql.d.ts +28 -4
  321. package/dist/plugins/checkpoint-store-sql.js +59 -28
  322. package/dist/plugins/file-history-store-sql.d.ts +5 -2
  323. package/dist/plugins/file-history-store-sql.js +3 -1
  324. package/dist/plugins/file-run-store.d.ts +5 -13
  325. package/dist/plugins/file-run-store.js +9 -0
  326. package/dist/plugins/fork-routing-session-store.d.ts +9 -1
  327. package/dist/plugins/fork-routing-session-store.js +12 -1
  328. package/dist/plugins/host-platform.d.ts +2 -0
  329. package/dist/plugins/host-platform.js +2 -1
  330. package/dist/plugins/k8s-bg-scripts.d.ts +11 -0
  331. package/dist/plugins/k8s-bg-scripts.js +22 -0
  332. package/dist/plugins/local-checkpoint-store.d.ts +2 -0
  333. package/dist/plugins/local-checkpoint-store.js +11 -3
  334. package/dist/plugins/local-session-store.d.ts +1 -1
  335. package/dist/plugins/local-session-store.js +1 -1
  336. package/dist/plugins/local-session-window.d.ts +39 -0
  337. package/dist/plugins/local-session-window.js +54 -0
  338. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
  339. package/dist/plugins/mailbox-store-sql.d.ts +30 -48
  340. package/dist/plugins/mailbox-store-sql.js +77 -52
  341. package/dist/plugins/memory-embedder-fingerprint.js +2 -1
  342. package/dist/plugins/memory-run-store.d.ts +5 -13
  343. package/dist/plugins/memory-run-store.js +8 -0
  344. package/dist/plugins/one-time-migrations.d.ts +245 -93
  345. package/dist/plugins/one-time-migrations.js +668 -207
  346. package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
  347. package/dist/plugins/org-delivery-quota-store.js +228 -0
  348. package/dist/plugins/permission-rule-store-sql.d.ts +13 -7
  349. package/dist/plugins/permission-rule-store-sql.js +4 -18
  350. package/dist/plugins/pg-pool.js +39 -7
  351. package/dist/plugins/pg-session-storage.d.ts +20 -8
  352. package/dist/plugins/pg-session-storage.js +34 -21
  353. package/dist/plugins/remote-env-adb.d.ts +12 -12
  354. package/dist/plugins/remote-env-adb.js +21 -6
  355. package/dist/plugins/remote-env-device.js +3 -0
  356. package/dist/plugins/remote-env-e2b.d.ts +1 -1
  357. package/dist/plugins/remote-env-e2b.js +21 -9
  358. package/dist/plugins/remote-env-host.d.ts +9 -9
  359. package/dist/plugins/remote-env-host.js +10 -32
  360. package/dist/plugins/remote-env-k8s.d.ts +103 -38
  361. package/dist/plugins/remote-env-k8s.js +288 -95
  362. package/dist/plugins/remote-env-local-docker.d.ts +27 -13
  363. package/dist/plugins/remote-env-local-docker.js +82 -11
  364. package/dist/plugins/remote-env-ssh.d.ts +21 -12
  365. package/dist/plugins/remote-env-ssh.js +117 -5
  366. package/dist/plugins/remote-shell.d.ts +0 -1
  367. package/dist/plugins/remote-shell.js +1 -2
  368. package/dist/plugins/retention-store-sql.js +6 -2
  369. package/dist/plugins/run-store-sql.d.ts +16 -14
  370. package/dist/plugins/run-store-sql.js +22 -2
  371. package/dist/plugins/schema-consistency.d.ts +54 -0
  372. package/dist/plugins/schema-consistency.js +52 -0
  373. package/dist/plugins/schema-indexes.js +2 -0
  374. package/dist/plugins/send-user-file.js +2 -2
  375. package/dist/plugins/session-epoch-anchor.d.ts +39 -0
  376. package/dist/plugins/session-epoch-anchor.js +22 -0
  377. package/dist/plugins/session-store.d.ts +18 -8
  378. package/dist/plugins/session-store.js +15 -4
  379. package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
  380. package/dist/plugins/shared-memory-store-sql.js +5 -16
  381. package/dist/plugins/sql-driver.d.ts +205 -1
  382. package/dist/plugins/sql-driver.js +325 -13
  383. package/dist/plugins/sql-errors.d.ts +64 -0
  384. package/dist/plugins/sql-errors.js +57 -0
  385. package/dist/plugins/store-backend.d.ts +36 -1
  386. package/dist/plugins/store-backend.js +42 -15
  387. package/dist/plugins/store-contracts.d.ts +42 -0
  388. package/dist/plugins/store-contracts.js +1 -0
  389. package/dist/plugins/tidb-pool.d.ts +6 -1
  390. package/dist/plugins/tidb-pool.js +44 -10
  391. package/dist/plugins/tidb-session-storage.d.ts +8 -11
  392. package/dist/plugins/tidb-session-storage.js +6 -16
  393. package/dist/plugins/tidb-session-store.d.ts +24 -4
  394. package/dist/plugins/tidb-session-store.js +29 -5
  395. package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
  396. package/dist/plugins/workflow-journal-store-sql.js +19 -6
  397. package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
  398. package/dist/plugins/workflow-run-store-sql.js +50 -9
  399. package/dist/posture-source.d.ts +18 -10
  400. package/dist/posture-source.js +4 -1
  401. package/dist/project-identity.d.ts +45 -6
  402. package/dist/project-identity.js +162 -8
  403. package/dist/project-layer-key.d.ts +28 -0
  404. package/dist/project-layer-key.js +29 -0
  405. package/dist/prompts-domain-validate.d.ts +17 -61
  406. package/dist/prompts-domain-validate.js +9 -119
  407. package/dist/question.js +3 -2
  408. package/dist/read-deny-entry.d.ts +25 -0
  409. package/dist/read-deny-entry.js +12 -0
  410. package/dist/read-face-posture.d.ts +37 -11
  411. package/dist/read-face-posture.js +32 -3
  412. package/dist/request-key-closure.d.ts +9 -2
  413. package/dist/request-key-closure.js +11 -5
  414. package/dist/request-value-closure.d.ts +5 -0
  415. package/dist/request-value-closure.js +11 -3
  416. package/dist/rule-entry-list.d.ts +38 -11
  417. package/dist/rule-entry-list.js +106 -30
  418. package/dist/rules-consent.js +3 -4
  419. package/dist/run-acceptance.d.ts +19 -3
  420. package/dist/run-acceptance.js +13 -1
  421. package/dist/run-local.js +54 -24
  422. package/dist/runs.d.ts +15 -8
  423. package/dist/runs.js +35 -1
  424. package/dist/runtime-caps-resolver.d.ts +16 -6
  425. package/dist/runtime-caps-resolver.js +18 -5
  426. package/dist/sandbox-pkg-source.d.ts +19 -1
  427. package/dist/sandbox-pkg-source.js +29 -7
  428. package/dist/security.d.ts +87 -9
  429. package/dist/security.js +52 -9
  430. package/dist/server-secret-env.d.ts +44 -18
  431. package/dist/server-secret-env.js +49 -8
  432. package/dist/session-error-wire.d.ts +19 -2
  433. package/dist/session-error-wire.js +5 -1
  434. package/dist/session-incarnation.d.ts +15 -5
  435. package/dist/session-incarnation.js +16 -9
  436. package/dist/session-titled-frame.d.ts +33 -0
  437. package/dist/session-titled-frame.js +4 -0
  438. package/dist/session-titler.d.ts +9 -1
  439. package/dist/session-titler.js +27 -6
  440. package/dist/spec-fields.d.ts +28 -16
  441. package/dist/spec-fields.js +66 -54
  442. package/dist/sql-engine-posture.d.ts +31 -4
  443. package/dist/sql-engine-posture.js +36 -1
  444. package/dist/stored-request-tool-axes-m19.d.ts +19 -4
  445. package/dist/stored-request-tool-axes-m19.js +30 -2
  446. package/dist/task-a2a.d.ts +9 -1
  447. package/dist/task-a2a.js +73 -47
  448. package/dist/task-cwd.d.ts +1 -1
  449. package/dist/task-mcp.d.ts +46 -58
  450. package/dist/task-mcp.js +82 -107
  451. package/dist/task-settings.d.ts +95 -108
  452. package/dist/task-settings.js +77 -98
  453. package/dist/text-bidi.d.ts +1 -48
  454. package/dist/text-bidi.js +3 -5
  455. package/dist/tighten-only-seats.d.ts +150 -0
  456. package/dist/tighten-only-seats.js +196 -0
  457. package/dist/tool-approval.d.ts +304 -88
  458. package/dist/tool-approval.js +623 -239
  459. package/dist/trace/core-keyset-guard.d.ts +122 -20
  460. package/dist/trace/engine-notice-wire.d.ts +11 -3
  461. package/dist/trace/engine-notice-wire.js +8 -1
  462. package/dist/trace/exit-seat.d.ts +28 -0
  463. package/dist/trace/exit-seat.js +76 -0
  464. package/dist/trace/ledger-events.d.ts +6 -3
  465. package/dist/trace/ledger-sink.js +4 -1
  466. package/dist/trace/model-segment.js +1 -1
  467. package/dist/trace/project.d.ts +98 -17
  468. package/dist/trace/project.js +98 -50
  469. package/dist/trace/projection-table.d.ts +100 -0
  470. package/dist/trace/projection-table.js +130 -0
  471. package/dist/trace/redact.d.ts +54 -0
  472. package/dist/trace/redact.js +778 -152
  473. package/dist/trace/self-minted-wire.d.ts +345 -1
  474. package/dist/trace/self-minted-wire.js +117 -1
  475. package/dist/trace/wire-projection-faces.d.ts +377 -3
  476. package/dist/trace/wire-projection-faces.js +164 -1
  477. package/dist/url-refusal.js +2 -0
  478. package/dist/web-admin-client/apply-effective.d.ts +12 -0
  479. package/dist/web-admin-client/apply-effective.js +56 -5
  480. package/dist/web-admin-client/candidate-gate.d.ts +6 -6
  481. package/dist/web-admin-client/candidate-gate.js +3 -3
  482. package/dist/web-admin-client/facade.d.ts +1 -1
  483. package/dist/web-admin-client/facade.js +1 -1
  484. package/dist/web-admin-client/http-client.js +0 -6
  485. package/dist/web-admin-client/read-face.js +5 -9
  486. package/dist/web-admin-client/read-warnings.d.ts +13 -0
  487. package/dist/web-admin-client/read-warnings.js +10 -0
  488. package/dist/web-admin-client/skills-mcp.d.ts +3 -0
  489. package/dist/web-admin-client/skills-mcp.js +11 -9
  490. package/dist/web-admin-client/types.d.ts +2 -3
  491. package/dist/workspace-cache.d.ts +35 -0
  492. package/dist/workspace-cache.js +36 -0
  493. package/dist/workspace-space.d.ts +3 -2
  494. package/dist/workspace-space.js +2 -0
  495. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +65 -10
  496. package/package.json +8 -4
  497. package/scripts/drain-check-local.mjs +34 -1
  498. package/scripts/drain-check.mysql.sql +30 -2
  499. package/scripts/drain-check.pg.sql +29 -2
  500. package/dist/capabilities/memory-notice.d.ts +0 -138
  501. package/dist/capabilities/memory-notice.js +0 -64
  502. package/dist/capabilities/prompt.d.ts +0 -17
  503. package/dist/capabilities/prompt.js +0 -6
  504. package/dist/mcp-content-origin.d.ts +0 -34
  505. package/dist/mcp-content-origin.js +0 -10
  506. package/dist/tool-axis-words.d.ts +0 -27
  507. package/dist/tool-axis-words.js +0 -9
  508. package/dist/wire-name-bound.d.ts +0 -14
  509. package/dist/wire-name-bound.js +0 -13
@@ -0,0 +1,46 @@
1
+ import { migrateScope } from "@sema-agent/core";
2
+ import { memoryProjectLayerFor } from "./memory-scope.js";
3
+ export function createMemoryProjectLayers(deps) {
4
+ const fold = async (backend, from, to) => {
5
+ let report;
6
+ try {
7
+ report = await migrateScope(backend, from, to);
8
+ }
9
+ catch (err) {
10
+ deps.log.warn("memory_project_layer_fold_failed", { from, to, err: String(err), note: "entries stay where they are; the next task in this project retries" });
11
+ return;
12
+ }
13
+ if (report.moved > 0)
14
+ deps.log.info("memory_project_layer_folded", { from, to, moved: report.moved, cursorMoved: report.cursorMoved });
15
+ if (report.conflicts.length > 0) {
16
+ deps.log.warn("memory_project_layer_fold_conflicts", { from, to, conflicts: report.conflicts.length, note: "conflicting entries stay in the old layer; the next task in this project retries" });
17
+ }
18
+ };
19
+ const occupied = async (backend, sources) => {
20
+ const out = [];
21
+ for (const from of sources) {
22
+ if ((await backend.listHeaders([from])).some((h) => h.scope === from))
23
+ out.push(from);
24
+ }
25
+ return out;
26
+ };
27
+ return {
28
+ async prepare(config, scope, taskRoot) {
29
+ const layer = memoryProjectLayerFor(config, scope, taskRoot);
30
+ const current = layer?.key.scope;
31
+ if (layer === undefined || current === undefined)
32
+ return layer?.key;
33
+ const backend = deps.backend;
34
+ if (backend !== undefined && (await occupied(backend, layer.foldFrom)).length > 0) {
35
+ const foldAll = async () => {
36
+ for (const from of await occupied(backend, layer.foldFrom))
37
+ await fold(backend, from, current);
38
+ };
39
+ await (deps.syncRunner !== undefined ? deps.syncRunner.exclusive(foldAll) : foldAll());
40
+ }
41
+ deps.syncRunner?.track(current);
42
+ return layer.key;
43
+ },
44
+ };
45
+ }
46
+ //# sourceMappingURL=memory-project-layer.js.map
@@ -1,7 +1,7 @@
1
1
  import { FileMemoryEngineBackend, type TaskSpec } from "@sema-agent/core";
2
2
  import type { ServiceConfig } from "./config-types.js";
3
3
  import { type ExecutionLane } from "./execution-lane-caps.js";
4
- import { type MemoryProjectKey } from "./project-identity.js";
4
+ import { type MemoryProjectKey, type ProjectLayerOfTask } from "./project-identity.js";
5
5
  /** 前缀词表本体(供门/诊断读;判定一律走 {@link isV2ScopeKey},别在别处重写 startsWith 链)。 */
6
6
  export declare const V2_SCOPE_PREFIXES: readonly string[];
7
7
  /**
@@ -41,17 +41,19 @@ export declare function memoryScopeFor(config: ServiceConfig, principal?: string
41
41
  * S-512 / [ref] ① —— 这一请求的**项目身份声明**(`TaskSpec.memory.projectKey`)的唯一属主。
42
42
  *
43
43
  * **一条规则,与车道无关**(主会话 09-23 裁 ②):项目根 = spec 解析出的**真任务根**(`boot/resolve-spec.ts`
44
- * 的 `realTaskRootOf`,S-177 属主;run-local 腿 = 它的 `workspaceDir`)。本进程读得到这个根 ⇒ 求 canonical
45
- * 项目根并铸 `repo:` 键(in-process 车道的真任务根是 `process.cwd()`,读得到,所以照常铸 —— 它的语义就是
46
- * 「项目 = 任务根指向的地方」,不需要另一个词);读不到(根在沙箱/设备盘上,或 host 车道会话没登记 cwd、
47
- * spec 期还不知道根)⇒ 调用方传 `undefined` ⇒ `{ absent: "unreadable" }`,core 铸 operator 通知
48
- * `memory.project_scope_absent`,写照常落全局层 —— **响亮**,不是静默落 `local`。
44
+ * 的 `realTaskRootOf`,S-177 属主;run-local 腿 = 它的 `workspaceDir`)。本进程读得到这个根 ⇒ 求项目身份并铸项目层键
45
+ * (in-process 车道的真任务根是 `process.cwd()`,读得到,所以照常铸 —— 它的语义就是「项目 = 任务根指向的地方」,不需要另一个词);
46
+ * 读不到(根在沙箱/设备盘上,或 host 车道会话没登记 cwd、spec 期还不知道根)⇒ 调用方传 `undefined` ⇒ `{ absent: "unreadable" }`,
47
+ * core 铸 operator 通知 `memory.project_scope_absent`,写照常落全局层 —— **响亮**,不是静默落 `local`。
48
+ *
49
+ * 🔴 S-640 键形:项目层 = **全局层的属主 × 项目身份**,`userrepo:<属主段>/<档>.<摘要>`(文法 `project-layer-key.ts`,身份 `project-identity.ts`);
50
+ * 属主 = `projectLayerOwnerOf(scope)`。
49
51
  *
50
52
  * 🔴 **写家只落复制路径覆盖得到的层**(7.98.0 合并复审 F1,主会话裁「统一规则,不做特判」):写家 = 读列表里、本部署
51
- * **每一条已配置的复制路径都覆盖到**的最具体的一层。项目层不在覆盖面里 ⇒ 本任务**不按项目键控**,写家落全局层,
52
- * 读列表与 7.97.0 同形 —— 否则开了 `MEMORY_SYNC_*` 的部署会把新记忆写进一个同步腿从不碰的层(静默不同步)。
53
- * 覆盖面只经 {@link memoryReplicationCoverage} 求(调用点零 `if (memorySync)`);以后项目层同步落地,只改覆盖面的
54
- * 来源,本规则不动。让位由启动通知 `memory_project_scope_yields_to_sync` 说出来(`config.ts` 记忆域,读同一只覆盖面)。
53
+ * **每一条已配置的复制路径都覆盖到**的最具体的一层。项目层不在覆盖面里 ⇒ 本任务**不按项目键控**,写家落全局层 —— 否则开了
54
+ * `MEMORY_SYNC_*` 的部署会把新记忆写进一个同步腿从不碰的层(静默不同步)。覆盖面只经 {@link memoryReplicationCoverage} 求(调用点零
55
+ * `if (memorySync)`);S-640 改的只是覆盖面的**来源**(一条复制路径复制它那一层与同属主的全部项目层),本规则一字不动。让位由启动通知
56
+ * `memory_project_scope_yields_to_sync` 说出来(`config.ts` 记忆域,读同一只覆盖面与 {@link replicatesProjectLayersOf})。
55
57
  * 缺席声明(`{ absent }`)不受覆盖面影响:它本来就写全局层,通知说的是「为什么没有项目层」。
56
58
  *
57
59
  * 返回 `undefined` 只有三形,都不是「忘了」:
@@ -60,20 +62,25 @@ export declare function memoryScopeFor(config: ServiceConfig, principal?: string
60
62
  * · 本任务的项目层不在复制覆盖面里(见上)—— 让位给全局层。
61
63
  */
62
64
  export declare function memoryProjectKeyFor(config: Pick<ServiceConfig, "requirePrincipal" | "memorySync">, scope: string | undefined, taskRoot: string | undefined): MemoryProjectKey | undefined;
65
+ /** {@link memoryProjectKeyFor} 的同一条规则,带上本 checkout 要折进当前层的旧层(`memory-project-layer.ts` 读它)。 */
66
+ export declare function memoryProjectLayerFor(config: Pick<ServiceConfig, "requirePrincipal" | "memorySync">, scope: string | undefined, taskRoot: string | undefined): ProjectLayerOfTask | undefined;
63
67
  /**
64
68
  * 本部署记忆的**复制覆盖面** —— 唯一属主(7.98.0 合并复审 F1)。「复制路径」= 把某一层记忆搬出本机的腿;今天只有一条:
65
- * TOC 同步客户端腿(`MEMORY_SYNC_*`,`memory-sync-client.ts`),它只同步**一层**(`config.memorySync.scope`,core
66
- * `syncMemoryScope` 按 `scope ===` 取条目)。没有复制路径 ⇒ `unreplicated`(没有哪一层会被复制落下)。
69
+ * TOC 同步客户端腿(`MEMORY_SYNC_*`,`memory-sync-client.ts`)。🔴 S-640:一条复制路径复制**它那一层**(`config.memorySync.scope`)
70
+ * **以及同一属主的全部项目层**(`userrepo:<属主>/…`,属主 = `projectLayerOwnerOf(那一层)`)—— 同步腿按同一判据选层
71
+ * (`memory-sync-client.ts` 读 {@link replicationCovers})。没有复制路径 ⇒ `unreplicated`(没有哪一层会被复制落下)。
67
72
  */
68
73
  export type MemoryReplicationCoverage = {
69
74
  readonly kind: "unreplicated";
70
75
  } | {
71
- readonly kind: "scopes";
72
- readonly scopes: readonly string[];
76
+ readonly kind: "layers";
77
+ readonly layers: readonly string[];
73
78
  };
74
79
  export declare function memoryReplicationCoverage(config: Pick<ServiceConfig, "memorySync">): MemoryReplicationCoverage;
75
- /** 覆盖面是否含这一层(`unreplicated` 含一切)。 */
80
+ /** 覆盖面是否含这一层(`unreplicated` 含一切;复制层本身,或它同属主的项目层)。 */
76
81
  export declare function replicationCovers(coverage: MemoryReplicationCoverage, scope: string): boolean;
82
+ /** 覆盖面复制不复制属主 `owner` 的项目层(有一条复制层与它同属主)。启动通知与 {@link replicationCovers} 读同一只判据。 */
83
+ export declare function replicatesProjectLayersOf(coverage: MemoryReplicationCoverage, owner: string): boolean;
77
84
  /**
78
85
  * N0 (通宵测试 2026-07-09,三重坐实 e2b+kata+代码): the file memory engine (core [ref]) materializes and
79
86
  * harvests via `node:fs` on the WORKER's local fs, while a remote exec lane routes the model's file tools to
@@ -242,7 +249,7 @@ export declare function memoryStoreRootMovedRefusal(e: unknown): (Error & {
242
249
  export declare function memorySpecForRequest(scope: string | undefined,
243
250
  /** S-512 / [ref] ①:本请求的项目身份声明({@link memoryProjectKeyFor} 的产物)。**必填位**(不是可选参数):
244
251
  * 每个铸点都得写出一个值 —— `undefined` 只合法地表示「本任务不按项目键控」(多租户 / 记忆暗 / 项目层不在复制覆盖面里)。
245
- * · `{ scope: repoKey }` ⇒ 读 = `[repoKey, scope, ...extras]`、`writeScope` **显式** = `repoKey`(core 缺省取末层
252
+ * · `{ scope: projectKey }`(S-640 起 `userrepo:…`)⇒ 读 = `[projectKey, scope, ...extras]`、`writeScope` **显式** = 项目层(core 缺省取末层
246
253
  * = 全局层,不钉就是 M-03 本身;core 另有 `config.memory_write_scope_mismatch` 兜这一向);
247
254
  * · `{ absent }` ⇒ 读 = `[scope, ...extras]`、`writeScope` 显式 = `scope`(全局层),core 铸 `memory.project_scope_absent`;
248
255
  * · 两形都把声明原样落 `TaskSpec.memory.projectKey`(core 的生效面回显它)。 */
@@ -286,7 +293,7 @@ declarations?: {
286
293
  /**
287
294
  * 「这一腿挂不挂记忆面」的**唯一属主**(合并复审 车HF F1,2026-09-18):与 core `prepareMemory` 的判据同源 ——
288
295
  * `normalizeMemorySpec(spec)?.enabled === true`。S-405 之后 `memory:"off"` 铸的是「键在场 + `enabled:false`」(保留事实),
289
- * 任何按「键在不在场」判挂没挂的读者从那一天起都读错(改前 `memory-notice` 正是那样,把无记忆面的披露一起吞掉)。
296
+ * 任何按「键在不在场」判挂没挂的读者从那一天起都读错(改前本仓的记忆披露判别式正是那样,把无记忆面的披露一起吞掉;那只判别式已随引擎接管披露退役)。
290
297
  * 消费方拿本函数的布尔,不拿 `spec.memory` 自己判。
291
298
  *
292
299
  * ⚠️ **本函数会抛,而「抛」本身就是一条判据**(S-424 补注)。`normalizeMemorySpec` 对两形直接 throw
@@ -2,7 +2,8 @@ import { join } from "node:path";
2
2
  import { FileMemoryEngineBackend, resolveMemoryEngineRoot, deriveControlPlaneDir, formatUserScope, formatProjScope, normalizeMemorySpec } from "@sema-agent/core";
3
3
  import { executionLaneCaps, executionLaneOf } from "./execution-lane-caps.js";
4
4
  import { assertMemoryScopeWidth } from "./plugins/memory-key-guards.js";
5
- import { projectKeyForTaskRoot } from "./project-identity.js";
5
+ import { projectLayerForTaskRoot } from "./project-identity.js";
6
+ import { parseProjectLayerKey, projectLayerOwnerOf } from "./project-layer-key.js";
6
7
  const V2_SCOPE_PREFIX_BY_KIND = {
7
8
  user: "user:",
8
9
  org: "org:",
@@ -28,22 +29,37 @@ export function memoryScopeFor(config, principal, projectId) {
28
29
  return config.memoryScope;
29
30
  }
30
31
  export function memoryProjectKeyFor(config, scope, taskRoot) {
32
+ return memoryProjectLayerFor(config, scope, taskRoot)?.key;
33
+ }
34
+ export function memoryProjectLayerFor(config, scope, taskRoot) {
31
35
  if (config.requirePrincipal === true || scope === undefined)
32
36
  return undefined;
33
- const declared = projectKeyForTaskRoot(taskRoot);
34
- if (declared.scope !== undefined && !replicationCovers(memoryReplicationCoverage(config), declared.scope))
37
+ const layer = projectLayerForTaskRoot(taskRoot, projectLayerOwnerOf(scope));
38
+ if (layer.key.scope !== undefined && !replicationCovers(memoryReplicationCoverage(config), layer.key.scope))
35
39
  return undefined;
36
- return declared;
40
+ return layer;
37
41
  }
38
42
  export function memoryReplicationCoverage(config) {
39
- return config.memorySync === undefined ? { kind: "unreplicated" } : { kind: "scopes", scopes: [config.memorySync.scope] };
43
+ return config.memorySync === undefined ? { kind: "unreplicated" } : { kind: "layers", layers: [config.memorySync.scope] };
40
44
  }
41
45
  export function replicationCovers(coverage, scope) {
42
46
  switch (coverage.kind) {
43
47
  case "unreplicated":
44
48
  return true;
45
- case "scopes":
46
- return coverage.scopes.includes(scope);
49
+ case "layers": {
50
+ if (coverage.layers.includes(scope))
51
+ return true;
52
+ const projectLayer = parseProjectLayerKey(scope);
53
+ return projectLayer !== undefined && replicatesProjectLayersOf(coverage, projectLayer.owner);
54
+ }
55
+ }
56
+ }
57
+ export function replicatesProjectLayersOf(coverage, owner) {
58
+ switch (coverage.kind) {
59
+ case "unreplicated":
60
+ return true;
61
+ case "layers":
62
+ return coverage.layers.some((layer) => projectLayerOwnerOf(layer) === owner);
47
63
  }
48
64
  }
49
65
  export function memoryEngineRemoteLanePosture(config) {
@@ -140,7 +156,7 @@ export function memorySpecForRequest(scope, projectKey, memoryWrite, defaultScop
140
156
  const projectScope = projectKey?.scope;
141
157
  if (projectScope !== undefined && projectScope === scope) {
142
158
  throw new Error(`memory project scope ${JSON.stringify(projectScope)} equals the global memory scope (MEMORY_SCOPE) — the project layer and the global layer would be one directory. ` +
143
- "Set MEMORY_SCOPE to a name outside the server-minted project-key family (see src/project-identity.ts).");
159
+ "Set MEMORY_SCOPE to a name outside the server-minted project-key families (see src/project-layer-key.ts).");
144
160
  }
145
161
  const isV2 = isV2ScopeKey;
146
162
  const extras = (defaultScopes ?? []).filter((s, i, arr) => typeof s === "string" && s.length > 0 && s !== scope && s !== projectScope && arr.indexOf(s) === i);
@@ -20,29 +20,43 @@ export declare function createMemorySyncTransport(opts: {
20
20
  timeoutMs?: number;
21
21
  fetchImpl?: typeof fetch;
22
22
  }): MemorySyncTransport;
23
- /** cursor 文件路径:`memoryRoot`(= RunnerDeps.memoryEngineDir 的 resolved config root,memory/ 目录
24
- * 旁)下的 per-peer sidecar。peer 段走 core encodeScopeSegment(文件名安全字符纪律与 scope 目录同)。 */
25
- export declare function memorySyncCursorPath(memoryRoot: string, peer: string): string;
23
+ /** cursor 文件路径:`memoryRoot`(= RunnerDeps.memoryEngineDir 的 resolved config root,memory/ 目录旁)下的
24
+ * per-(peer, scope) sidecar(`sync-cursors/<peer>/<scope 摘要>.json`)。peer 段走 core encodeScopeSegment(文件名安全字符纪律与 scope 目录同);scope 段取 sha256 前 32 hex
25
+ * (scope 键带 `:` `/` 且可长过段编码的 64 字符帽 —— 名字只需区分,内容里仍记原 scope,读时比对)。 */
26
+ export declare function memorySyncCursorPath(memoryRoot: string, peer: string, scope: string): string;
27
+ /** 一轮里一层的结果。 */
28
+ export interface MemorySyncLayerResult {
29
+ readonly scope: string;
30
+ readonly result: MemorySyncClientResult;
31
+ }
32
+ /** 一轮(按层)的结果:成功的各层,按同步序(同步层在前,项目层按键序)。 */
33
+ export interface MemorySyncRound {
34
+ readonly layers: readonly MemorySyncLayerResult[];
35
+ }
26
36
  export interface MemorySyncRunner {
27
- /** 一轮同步(串行:排在上一轮之后)。返回 core 结构化结果供调用方记 metrics/日志;transport/
28
- * 协议错误向上 throw(本地零副作用,core 契约)。cursor 读写、conflicts warn 都在轮内完成。 */
29
- syncOnce(reason: string): Promise<MemorySyncClientResult>;
37
+ /** 一轮同步(串行:排在上一轮之后),逐层一轮。任一层 transport/协议错误 ⇒ 其余层照跑,轮末汇总 reject(失败层本地零副作用,
38
+ * core 契约);cursor 读写、conflicts warn 都在层内完成。 */
39
+ syncOnce(reason: string): Promise<MemorySyncRound>;
30
40
  /** fire-and-forget 一轮:上一轮在飞(排队/执行中)则跳过(inflight 节流);失败 warn 不上抛。 */
31
41
  trigger(reason: string): void;
32
- /** cursor sidecar 的落盘路径(boot 日志/测试可见性)。 */
33
- readonly cursorPath: string;
42
+ /** 跟踪一只本层属主的项目层(本地还没有条目也每轮拉它);首次跟踪即排一轮。不是本同步腿覆盖的项目层 ⇒ 抛(调用方的错)。 */
43
+ track(scope: string): void;
44
+ /** 把一段动本地记忆面的工作排进同步的串行链(等在飞的轮落定、执行时没有轮在飞)—— 项目层折叠用(`memory-project-layer.ts`)。 */
45
+ exclusive<T>(work: () => Promise<T>): Promise<T>;
46
+ /** 某一层的 cursor sidecar 路径(boot 日志/测试可见性)。 */
47
+ cursorPathFor(scope: string): string;
34
48
  /** 排队+在飞的轮数(测试的确定性等待面;0 = 完全空闲)。 */
35
49
  pending(): number;
36
50
  }
37
- /**
38
- * 组装一个 per-(scope,peer) 的同步执行器:cursor 持久化 + core `syncMemoryScope` + conflicts 上报 +
39
- * 串行化/节流。`backend` = 本地 File authority plane(memoryEngineBackendFor 的产物);`memoryRoot` =
40
- * resolved config root(cursor sidecar 落在 memory/ 目录旁)。
41
- */
42
51
  /** S2.5 分批 loop 的轮数上限(fail-loud 警戒,防协议异常时死循环;正常收敛远低于此)。 */
43
52
  export declare const MAX_SYNC_ROUNDS = 32;
53
+ /**
54
+ * 组装同步执行器:同步层 `scope` + 同属主的项目层,逐层一轮(cursor 持久化 + core `syncMemoryScope` + conflicts 上报),串行化/节流。
55
+ * `backend` = 本地 File authority plane(memoryEngineBackendFor 的产物);`memoryRoot` = resolved config root(cursor sidecar 落在 memory/ 目录旁)。
56
+ */
44
57
  export declare function createMemorySyncRunner(opts: {
45
58
  backend: MemoryBackend;
59
+ /** 同步层(`config.memorySync.scope`);它同属主的项目层随它一起同步。 */
46
60
  scope: string;
47
61
  memoryRoot: string;
48
62
  transport: MemorySyncTransport;
@@ -1,7 +1,9 @@
1
- import { randomBytes } from "node:crypto";
1
+ import { createHash, randomBytes } from "node:crypto";
2
2
  import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
3
3
  import { dirname, join } from "node:path";
4
4
  import { encodeScopeSegment, syncMemoryScope, } from "@sema-agent/core";
5
+ import { replicationCovers } from "./memory-scope.js";
6
+ import { parseProjectLayerKey } from "./project-layer-key.js";
5
7
  export const DEFAULT_MEMORY_SYNC_PEER = "central";
6
8
  export function createMemorySyncTransport(opts) {
7
9
  const base = opts.url.replace(/\/+$/, "");
@@ -20,7 +22,10 @@ export function createMemorySyncTransport(opts) {
20
22
  return JSON.parse(text);
21
23
  };
22
24
  }
23
- export function memorySyncCursorPath(memoryRoot, peer) {
25
+ export function memorySyncCursorPath(memoryRoot, peer, scope) {
26
+ return join(memoryRoot, "sync-cursors", encodeScopeSegment(peer), `${createHash("sha256").update(scope, "utf8").digest("hex").slice(0, 32)}.json`);
27
+ }
28
+ function legacyMemorySyncCursorPath(memoryRoot, peer) {
24
29
  return join(memoryRoot, `sync-cursor-${encodeScopeSegment(peer)}.json`);
25
30
  }
26
31
  async function loadCursor(path, scope, peer, log) {
@@ -41,6 +46,13 @@ async function loadCursor(path, scope, peer, log) {
41
46
  log.warn("memory_sync_cursor_corrupt", { path, err: String(err), note: "treating as first round" });
42
47
  return undefined;
43
48
  }
49
+ const cursor = cursorOf(parsed, scope, peer);
50
+ if (cursor !== undefined)
51
+ return cursor;
52
+ log.warn("memory_sync_cursor_invalid", { path, scope, peer, note: "shape/identity mismatch — treating as first round" });
53
+ return undefined;
54
+ }
55
+ function cursorOf(parsed, scope, peer) {
44
56
  if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
45
57
  const c = parsed;
46
58
  const baseRevsRaw = c["baseRevs"];
@@ -55,9 +67,34 @@ async function loadCursor(path, scope, peer, log) {
55
67
  return { scope, peer, baseRevs: { ...baseRevsRaw }, updatedAtMs: c["updatedAtMs"] };
56
68
  }
57
69
  }
58
- log.warn("memory_sync_cursor_invalid", { path, scope, peer, note: "shape/identity mismatch — treating as first round" });
59
70
  return undefined;
60
71
  }
72
+ async function adoptLegacyCursor(memoryRoot, scope, peer, log) {
73
+ const target = memorySyncCursorPath(memoryRoot, peer, scope);
74
+ const legacy = legacyMemorySyncCursorPath(memoryRoot, peer);
75
+ const facts = await Promise.all([readFile(target, "utf8").then(() => "present", (err) => (err.code === "ENOENT" ? "absent" : "present")), readFile(legacy, "utf8").then((text) => ({ text }), (err) => ({ err }))]);
76
+ const [targetFact, legacyRead] = facts;
77
+ if (targetFact === "present")
78
+ return;
79
+ if ("err" in legacyRead) {
80
+ if (legacyRead.err.code !== "ENOENT")
81
+ log.warn("memory_sync_cursor_read_failed", { path: legacy, err: String(legacyRead.err), note: "legacy cursor not adopted — this layer starts from its own cursor" });
82
+ return;
83
+ }
84
+ let parsed;
85
+ try {
86
+ parsed = JSON.parse(legacyRead.text);
87
+ }
88
+ catch (err) {
89
+ log.warn("memory_sync_cursor_corrupt", { path: legacy, err: String(err), note: "legacy cursor not adopted" });
90
+ return;
91
+ }
92
+ if (cursorOf(parsed, scope, peer) === undefined)
93
+ return;
94
+ await mkdir(dirname(target), { recursive: true });
95
+ await rename(legacy, target);
96
+ log.info("memory_sync_cursor_adopted", { from: legacy, to: target, scope, peer });
97
+ }
61
98
  async function saveCursor(path, cursor) {
62
99
  await mkdir(dirname(path), { recursive: true });
63
100
  const tmp = `${path}.tmp.${process.pid}.${randomBytes(4).toString("hex")}`;
@@ -65,18 +102,36 @@ async function saveCursor(path, cursor) {
65
102
  await rename(tmp, path);
66
103
  }
67
104
  export const MAX_SYNC_ROUNDS = 32;
105
+ function enumerateScopes(backend) {
106
+ const face = backend.listScopes;
107
+ return typeof face === "function" ? face.call(backend) : { supported: false, reason: "the memory backend has no listScopes face" };
108
+ }
68
109
  export function createMemorySyncRunner(opts) {
69
110
  const peer = opts.peer ?? DEFAULT_MEMORY_SYNC_PEER;
70
- const cursorPath = memorySyncCursorPath(opts.memoryRoot, peer);
71
- const round = async (reason) => {
72
- let cursor = await loadCursor(cursorPath, opts.scope, peer, opts.log);
111
+ const coverage = { kind: "layers", layers: [opts.scope] };
112
+ const tracked = new Set();
113
+ let legacyCursorChecked = false;
114
+ let enumerationWarned = false;
115
+ const isCoveredProjectLayer = (scope) => scope !== opts.scope && parseProjectLayerKey(scope) !== undefined && replicationCovers(coverage, scope);
116
+ const layersOfRound = () => {
117
+ const local = enumerateScopes(opts.backend);
118
+ if (!local.supported && !enumerationWarned) {
119
+ enumerationWarned = true;
120
+ opts.log.warn("memory_sync_layer_enumeration_unsupported", { scope: opts.scope, peer, reason: local.reason, note: "only the sync layer and tracked project layers are synced" });
121
+ }
122
+ const projectLayers = new Set([...(local.supported ? local.scopes : []), ...tracked].filter(isCoveredProjectLayer));
123
+ return [opts.scope, ...[...projectLayers].sort()];
124
+ };
125
+ const syncLayer = async (scope, reason) => {
126
+ const cursorPath = memorySyncCursorPath(opts.memoryRoot, peer, scope);
127
+ let cursor = await loadCursor(cursorPath, scope, peer, opts.log);
73
128
  let result;
74
129
  let subRound = 0;
75
130
  for (;;) {
76
131
  subRound += 1;
77
132
  result = await syncMemoryScope({
78
133
  backend: opts.backend,
79
- scope: opts.scope,
134
+ scope,
80
135
  transport: opts.transport,
81
136
  peer,
82
137
  ...(cursor !== undefined ? { cursor } : {}),
@@ -85,11 +140,11 @@ export function createMemorySyncRunner(opts) {
85
140
  ...(opts.maxPullEntries !== undefined ? { maxPullEntries: opts.maxPullEntries } : {}),
86
141
  });
87
142
  for (const w of result.warnings ?? [])
88
- opts.log.warn("memory_sync_warning", { scope: opts.scope, peer, subRound, warning: w });
143
+ opts.log.warn("memory_sync_warning", { scope, peer, subRound, warning: w });
89
144
  if (!(result.pushTruncated === true || result.pullTruncated === true))
90
145
  break;
91
146
  if (subRound >= MAX_SYNC_ROUNDS) {
92
- opts.log.warn("memory_sync_rounds_exhausted", { scope: opts.scope, peer, rounds: subRound, note: "truncation flag still set at the round cap — remaining items ride the next trigger" });
147
+ opts.log.warn("memory_sync_rounds_exhausted", { scope, peer, rounds: subRound, note: "truncation flag still set at the round cap — remaining items ride the next trigger" });
93
148
  break;
94
149
  }
95
150
  if (result.cursorAdvanced && result.cursor !== undefined) {
@@ -101,11 +156,11 @@ export function createMemorySyncRunner(opts) {
101
156
  }
102
157
  }
103
158
  cursor = result.cursor ?? cursor;
104
- opts.log.info("memory_sync_continuation", { reason, scope: opts.scope, peer, subRound, pushTruncated: result.pushTruncated === true, pullTruncated: result.pullTruncated === true });
159
+ opts.log.info("memory_sync_continuation", { reason, scope, peer, subRound, pushTruncated: result.pushTruncated === true, pullTruncated: result.pullTruncated === true });
105
160
  }
106
161
  for (const c of result.conflicts) {
107
162
  opts.log.warn("memory_sync_conflict", {
108
- scope: opts.scope,
163
+ scope,
109
164
  peer,
110
165
  side: c.side,
111
166
  id: c.id,
@@ -124,7 +179,7 @@ export function createMemorySyncRunner(opts) {
124
179
  }
125
180
  opts.log.info("memory_sync_round", {
126
181
  reason,
127
- scope: opts.scope,
182
+ scope,
128
183
  peer,
129
184
  ok: result.ok,
130
185
  cursorAdvanced: result.cursorAdvanced,
@@ -136,11 +191,32 @@ export function createMemorySyncRunner(opts) {
136
191
  });
137
192
  return result;
138
193
  };
194
+ const round = async (reason) => {
195
+ if (!legacyCursorChecked) {
196
+ legacyCursorChecked = true;
197
+ await adoptLegacyCursor(opts.memoryRoot, opts.scope, peer, opts.log);
198
+ }
199
+ const layers = [];
200
+ const failures = [];
201
+ for (const scope of layersOfRound()) {
202
+ try {
203
+ layers.push({ scope, result: await syncLayer(scope, reason) });
204
+ }
205
+ catch (err) {
206
+ failures.push({ scope, err });
207
+ opts.log.warn("memory_sync_layer_failed", { reason, scope, peer, err: String(err) });
208
+ }
209
+ }
210
+ if (failures.length > 0) {
211
+ throw new Error(`memory sync round failed for ${failures.length} layer(s): ${failures.map((f) => `${f.scope}: ${f.err instanceof Error ? f.err.message : String(f.err)}`).join("; ")}`);
212
+ }
213
+ return { layers };
214
+ };
139
215
  let chain = Promise.resolve();
140
216
  let pending = 0;
141
- const syncOnce = (reason) => {
217
+ const exclusive = (work) => {
142
218
  pending += 1;
143
- const run = chain.then(() => round(reason));
219
+ const run = chain.then(work);
144
220
  chain = run.then(() => {
145
221
  pending -= 1;
146
222
  }, () => {
@@ -148,13 +224,26 @@ export function createMemorySyncRunner(opts) {
148
224
  });
149
225
  return run;
150
226
  };
151
- const trigger = (reason) => {
152
- if (pending > 0)
153
- return;
227
+ const syncOnce = (reason) => exclusive(() => round(reason));
228
+ const queueRound = (reason) => {
154
229
  void syncOnce(reason).catch((err) => {
155
230
  opts.log.warn("memory_sync_failed", { reason, scope: opts.scope, peer, err: String(err) });
156
231
  });
157
232
  };
158
- return { syncOnce, trigger, cursorPath, pending: () => pending };
233
+ const trigger = (reason) => {
234
+ if (pending > 0)
235
+ return;
236
+ queueRound(reason);
237
+ };
238
+ const track = (scope) => {
239
+ if (!isCoveredProjectLayer(scope)) {
240
+ throw new Error(`memory sync track(): ${JSON.stringify(scope)} is not a project layer of this sync leg (layer ${JSON.stringify(opts.scope)} replicates its own project layers only)`);
241
+ }
242
+ if (tracked.has(scope))
243
+ return;
244
+ tracked.add(scope);
245
+ queueRound("track");
246
+ };
247
+ return { syncOnce, trigger, track, exclusive, cursorPathFor: (scope) => memorySyncCursorPath(opts.memoryRoot, peer, scope), pending: () => pending };
159
248
  }
160
249
  //# sourceMappingURL=memory-sync-client.js.map
@@ -116,10 +116,18 @@ export declare function refusedNamesLogFields(key: string, names: readonly strin
116
116
  export declare function refusalEventOf(reason: ModelEntryRefusalReason): "web_admin_model_no_brain" | "web_admin_model_entry_invalid";
117
117
  /** warn 字段(不含值):`field` = 第一处坏字段(告警规则最常按它分组),`fields` = 全部。S-805:`model` 只在名可披露时写。 */
118
118
  export declare function refusalWarnFields(name: string, r: ModelEntryRefusal): Record<string, unknown>;
119
+ /** 调用方写的模型 ref(`model` / `compactionModel` / `agents[i].model` / `@name`)回到人面前 —— 拒句与留声日志 —— 的字符上限。 */
120
+ export declare const MODEL_REF_ECHO_CHARS = 120;
121
+ /**
122
+ * 调用方写的模型 ref 的回显形:过回显的一只口径 {@link echoCallerText}(剥控制与双向字符,截到 {@link MODEL_REF_ECHO_CHARS} 字,超出加 `…`)。
123
+ * 目录门、`resolveSpec`、side-query 的拒句,以及它们写进运维日志的 `requested` 字段,**都**调这一只 —— 不在站点手写 `slice`。
124
+ */
125
+ export declare function echoModelRef(ref: string): string;
119
126
  /**
120
127
  * 一次**显式选择**命中了不可用条目时的拒因句(HTTP `request.model_unavailable` 的 `error`、run-local 的 stderr、
121
128
  * hook 选模型的失败文案 —— 各处同一句)。`field` = 调用方的通道名(`model` / `compactionModel` / `agents[0].model` /
122
- * `@-mention`),`requested` = 调用方发来的原形(name 或 id),已由调用方截断。
129
+ * `@-mention`),`requested` = 调用方发来的**原形**(name 或 id;本函数回显它时过 {@link echoModelRef},调用方不预先截)。
130
+ * 别名段(`(catalog entry …)`)的判断读原形:ref 与条目名逐字相同 ⇒ 不带,不因回显截短而误判成「另有条目」。
123
131
  */
124
132
  export declare function modelUnavailableMessage(field: string, requested: string, name: string, r: ModelEntryRefusal): string;
125
133
  /** 缺省模型不变量读的切面(`ServiceConfig` 与 `CrossInvariantView` 都结构满足)。 */
@@ -3,6 +3,7 @@ import { ModelEntry, formatConfigPath, isReportableRefusalName } from "@sema-age
3
3
  import { catalogBrainLane } from "./model-provider.js";
4
4
  import { readCatalogEntryHeaders } from "./model-entry-headers.js";
5
5
  import { DroppedCatalogEntryRow, describeSchemaIssueFields, describeSchemaIssues } from "./web-admin-client/read-warnings.js";
6
+ import { echoCallerText } from "./caller-text-echo.js";
6
7
  import { DEFAULT_MODEL_REF } from "./model-select.js";
7
8
  export const ENTRY_REFUSAL_REASON_OF = {
8
9
  "config.model_no_brain": "no_brain",
@@ -132,9 +133,13 @@ export function refusalWarnFields(name, r) {
132
133
  hint: r.detail,
133
134
  };
134
135
  }
136
+ export const MODEL_REF_ECHO_CHARS = 120;
137
+ export function echoModelRef(ref) {
138
+ return echoCallerText(ref, { maxChars: MODEL_REF_ECHO_CHARS });
139
+ }
135
140
  export function modelUnavailableMessage(field, requested, name, r) {
136
141
  const alias = requested === name ? "" : ` (catalog entry "${name}")`;
137
- return `${field} "${requested}"${alias} is published in the catalog but unavailable on this deployment [${r.code}] — ${r.detail}`;
142
+ return `${field} "${echoModelRef(requested)}"${alias} is published in the catalog but unavailable on this deployment [${r.code}] — ${r.detail}`;
138
143
  }
139
144
  export function defaultModelRefusal(view, leg) {
140
145
  if (Object.hasOwn(view.models, DEFAULT_MODEL_REF) && view.models[DEFAULT_MODEL_REF] !== undefined)
@@ -0,0 +1,51 @@
1
+ /**
2
+ * `GET /v1/models` 顶层 `modelPlane` 的**唯一铸点** —— 壳问「这台引擎服务的是哪张模型表 / 目录采纳了没有 / 起服路由判官怎么说」读这一格,不自己预测。
3
+ *
4
+ * ## 为什么在 server 里答
5
+ * 判官的输入是服务进程的事实:采纳之后 `config.model` 是不是还是那只 env 模型(对象同一性)、anthropic 路由装没装(凭据在场性)、名册布防(env 表是占位)。
6
+ * 壳拼不出这些,只能镜像两道判(目录条目逐条合形、车道 / 端点可解析)—— 镜像会随时间与真判官漂开(同一问两份读法)。所以结论只有 server 说,壳读它。
7
+ *
8
+ * ## 四个字段,两根轴
9
+ * · `servedTable` —— **谁在服**:{@link servedModelTableLeg}(此刻服务 env 表还是目录表;同一只读法,不另记旗子)。
10
+ * · `catalog` —— **最近一份目录候选的结局**({@link CATALOG_STANCES}):
11
+ * `refused` —— 候选被整拒:候选判官整拒(`candidateRejectionState` 座),或模型面组拒(`modelRefusalsState().plane` 在场;各码见
12
+ * settings-schema `MODEL_PLANE_REFUSAL_CODES`)。没有 LKG 时服务的是 env 表,有 LKG(或上一代已采纳)时仍服目录表 —— 谁在服归 `servedTable` 答,
13
+ * 不在这一格里合并(合并 = 一个字段两个意思);逐条被拒(条目不可用,`entries`)不是整拒,那些条目之外的目录照服;
14
+ * `adopted` —— 没有整拒、且服务的是目录表;
15
+ * `absent` —— 没有整拒、且服务的是 env 表:没配目录源 / 配了但没有启用条目(候选不管模型面,不是拒)/ 纯 env 部署。
16
+ * 两个座(候选判官的结论座与模型面组拒的信号座)是候选在两道判官各自留下的事实,本格只读它们,不另算第二份。
17
+ * **不在内**:候选过了两道判官、却在装配期被引擎整份拒收(`applyEffective` 里引擎拒收 `apiKeyEnv` 声明 / Runner 拒收换装;活配置零触碰,只有日志与 `/health` 世代账的 target≠applied)——
18
+ * 这一形今天没有座,`catalog` 仍按上一代读;`adopted` 说的是「没有被判官整拒」,不是「最新候选已落地」(那一问归世代账)。要覆盖它得先给装配期拒收立一个座(另案设计)。
19
+ * · `refusalCode` / `gap` —— **起服路由判官对当前 config 的判决**:`judgeServedModelRoute` 同一只函数(装配第 2 段与 `run-local` 调的就是它),通过 ⇒ 两键缺席。
20
+ * 进程既然起来了,正常是缺席;测试夹具 / 自建装配 / 不拒启的入口可能在场 —— 如实投,不替它们编造通过。**不带句子**(拒因句只走日志与起服错误)。
21
+ *
22
+ * ## 只在起服后可答
23
+ * 读面挂在运行中的进程上;判官必须在目录应用之后调(`judgeServedModelRoute` 头注),起服前没有「将要服务的表」,所以没有起服前的预判口。
24
+ */
25
+ import type { ModelRefusalsSignal } from "@sema-agent/settings-schema";
26
+ import { type ModelRouteEndpointVerdict, type ModelRouteGap, type ServedModelRouteView } from "./model-route-endpoint.js";
27
+ import { type ModelTableLeg } from "./model-select.js";
28
+ import type { CandidateRejection } from "./web-admin-client/candidate-gate.js";
29
+ /** `modelPlane.catalog` 的闭集(消费方用穷举 switch —— 加一词不补臂 ⇒ 编译红)。 */
30
+ export declare const CATALOG_STANCES: readonly ["absent", "adopted", "refused"];
31
+ export type CatalogStance = (typeof CATALOG_STANCES)[number];
32
+ /** `GET /v1/models.modelPlane` 的 wire 形(纯数据;条件键缺席,不铸 `null` / 空串)。 */
33
+ export interface ModelPlaneFace {
34
+ readonly servedTable: ModelTableLeg;
35
+ readonly catalog: CatalogStance;
36
+ /** 起服路由判官判决的机读码(`ModelPlaneRefusalCode` 的子集:路由端点族两码)。 */
37
+ readonly refusalCode?: ModelRouteEndpointVerdict["code"];
38
+ /** 同一次判决的出路轴(缺口两词)。 */
39
+ readonly gap?: ModelRouteGap;
40
+ }
41
+ /** {@link buildModelPlaneFace} 读的进程事实(都由调用方从各自的座取,本函数不碰任何全局)。 */
42
+ export interface ModelPlaneFacts {
43
+ /** 严格名册布防(`isRosterGateArmed`):env 表是占位、不被判(装配第 2 段传的是同一只谓词)。 */
44
+ readonly envTableIsPlaceholder: boolean;
45
+ /** 候选判官最近一次整拒的结论座(`WebAdminRuntime.candidateRejectionState()`);座空 / 没有配置管道 ⇒ `undefined`。 */
46
+ readonly candidateRejection: CandidateRejection | undefined;
47
+ /** 模型拒因信号(`WebAdminRuntime.modelRefusalsState()`);`plane` 在场 ⇒ 最近一份候选的模型面被整组拒。 */
48
+ readonly modelRefusals: Pick<ModelRefusalsSignal, "plane"> | undefined;
49
+ }
50
+ export declare function buildModelPlaneFace(config: ServedModelRouteView, facts: ModelPlaneFacts): ModelPlaneFace;
51
+ //# sourceMappingURL=model-plane-face.d.ts.map
@@ -0,0 +1,24 @@
1
+ import { judgeServedModelRoute } from "./model-route-endpoint.js";
2
+ import { servedModelTableLeg } from "./model-select.js";
3
+ export const CATALOG_STANCES = ["absent", "adopted", "refused"];
4
+ function catalogStanceOf(served, wholeRefused) {
5
+ if (wholeRefused)
6
+ return "refused";
7
+ switch (served) {
8
+ case "catalog":
9
+ return "adopted";
10
+ case "env":
11
+ return "absent";
12
+ }
13
+ }
14
+ export function buildModelPlaneFace(config, facts) {
15
+ const servedTable = servedModelTableLeg(config);
16
+ const wholeRefused = facts.candidateRejection !== undefined || facts.modelRefusals?.plane !== undefined;
17
+ const verdict = judgeServedModelRoute(config, { envTableIsPlaceholder: facts.envTableIsPlaceholder });
18
+ return {
19
+ servedTable,
20
+ catalog: catalogStanceOf(servedTable, wholeRefused),
21
+ ...(verdict !== undefined ? { refusalCode: verdict.code, gap: verdict.gap } : {}),
22
+ };
23
+ }
24
+ //# sourceMappingURL=model-plane-face.js.map