@sema-agent/server 7.145.0 → 7.147.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 (526) hide show
  1. package/MIGRATION.md +876 -0
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/USAGE.md +374 -99
  5. package/deploy/facts/CHANGES.json +25 -0
  6. package/deploy/facts/README.md +57 -0
  7. package/deploy/facts/lanes.json +61 -0
  8. package/deploy/facts/lanes.schema.json +57 -0
  9. package/deploy/facts/sandbox-rbac.json +113 -0
  10. package/deploy/facts/sandbox-rbac.schema.json +74 -0
  11. package/deploy/facts/sealed-key.json +9 -0
  12. package/deploy/facts/sealed-key.schema.json +52 -0
  13. package/deploy/sema-up/README.md +2 -2
  14. package/deploy/sema-up/chart/templates/_helpers.tpl +41 -0
  15. package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +47 -7
  16. package/deploy/sema-up/chart/templates/server-v4pro.yaml +9 -4
  17. package/deploy/sema-up/chart/templates/server.yaml +9 -4
  18. package/deploy/sema-up/chart/values.yaml +8 -1
  19. package/deploy/sema-up/cluster-up.sh +2 -1
  20. package/deploy/sema-up/lib/flagshape.sh +4 -0
  21. package/deploy/sema-up/lib/lanes.json +2 -5
  22. package/deploy/sema-up/sema-up.sh +12 -9
  23. package/deploy/sema-up/stack/compose.yaml +5 -4
  24. package/deploy/sema-up/stack/sema-stack-cluster.yaml +34 -17
  25. package/dist/adoption/import-limits.d.ts +6 -0
  26. package/dist/adoption/import-limits.js +7 -0
  27. package/dist/adoption/import.d.ts +62 -0
  28. package/dist/adoption/import.js +107 -0
  29. package/dist/adoption/wire.d.ts +52 -0
  30. package/dist/adoption/wire.js +9 -0
  31. package/dist/approval-ask-machine.d.ts +2 -2
  32. package/dist/approval-card.d.ts +7 -16
  33. package/dist/approval-card.js +0 -4
  34. package/dist/approval-gate-currency.d.ts +1 -1
  35. package/dist/approval-gate-currency.js +1 -1
  36. package/dist/approval-reconciler.d.ts +1 -1
  37. package/dist/approval.d.ts +3 -3
  38. package/dist/audit.js +2 -2
  39. package/dist/bench/s1/live-deps.js +3 -1
  40. package/dist/boot/crash-last.js +2 -1
  41. package/dist/boot/deployment-mods.d.ts +11 -1
  42. package/dist/boot/deployment-mods.js +15 -2
  43. package/dist/boot/device-lane.js +7 -5
  44. package/dist/boot/engine-lease.d.ts +195 -22
  45. package/dist/boot/engine-lease.js +146 -20
  46. package/dist/boot/execution-env.d.ts +5 -0
  47. package/dist/boot/execution-env.js +57 -33
  48. package/dist/boot/execution-lane.d.ts +37 -9
  49. package/dist/boot/execution-lane.js +74 -20
  50. package/dist/boot/exit-boundary.d.ts +50 -0
  51. package/dist/boot/exit-boundary.js +32 -0
  52. package/dist/boot/exit-last.d.ts +20 -4
  53. package/dist/boot/exit-last.js +23 -5
  54. package/dist/boot/governance-seams.d.ts +2 -2
  55. package/dist/boot/governance-seams.js +1 -0
  56. package/dist/boot/leader.js +1 -1
  57. package/dist/boot/memory-boundary.d.ts +11 -11
  58. package/dist/boot/memory-boundary.js +3 -3
  59. package/dist/boot/memory-consolidation.d.ts +42 -41
  60. package/dist/boot/memory-consolidation.js +26 -28
  61. package/dist/boot/org-memory.js +3 -2
  62. package/dist/boot/parked-revive-gate.d.ts +1 -1
  63. package/dist/boot/parked-revive-gate.js +1 -1
  64. package/dist/boot/reapers.d.ts +12 -4
  65. package/dist/boot/reapers.js +40 -16
  66. package/dist/boot/resolve-spec.d.ts +2 -0
  67. package/dist/boot/resolve-spec.js +126 -123
  68. package/dist/boot/retention-lane.d.ts +4 -42
  69. package/dist/boot/runner-deps.js +1 -1
  70. package/dist/boot/session-faces.d.ts +1 -0
  71. package/dist/boot/session-faces.js +11 -3
  72. package/dist/boot/shutdown.js +27 -9
  73. package/dist/boot/stage-01-config.d.ts +1 -1
  74. package/dist/boot/stage-01-config.js +7 -3
  75. package/dist/boot/stage-02-web-admin-pull.d.ts +1 -1
  76. package/dist/boot/stage-02-web-admin-pull.js +10 -8
  77. package/dist/boot/stage-03-store-backend.d.ts +2 -1
  78. package/dist/boot/stage-03-store-backend.js +2 -2
  79. package/dist/boot/stage-04-stores.d.ts +2 -1
  80. package/dist/boot/stage-05-execution-env.d.ts +4 -1
  81. package/dist/boot/stage-05-execution-env.js +6 -6
  82. package/dist/boot/stage-06-runners.d.ts +5 -2
  83. package/dist/boot/stage-06-runners.js +12 -13
  84. package/dist/boot/stage-07-capability-layer.d.ts +5 -2
  85. package/dist/boot/stage-07-capability-layer.js +7 -7
  86. package/dist/boot/stage-08-reapers.d.ts +5 -2
  87. package/dist/boot/stage-08-reapers.js +3 -3
  88. package/dist/boot/stage-09-leader.d.ts +6 -2
  89. package/dist/boot/stage-10-http-server.d.ts +6 -2
  90. package/dist/boot/stage-10-http-server.js +5 -3
  91. package/dist/boot/stores.d.ts +10 -0
  92. package/dist/boot/stores.js +53 -26
  93. package/dist/boot/web-admin.js +3 -3
  94. package/dist/boot/workflow-orchestration.d.ts +1 -1
  95. package/dist/boot/workflow-orchestration.js +2 -1
  96. package/dist/capabilities/center-plugins.d.ts +2 -0
  97. package/dist/capabilities/center-plugins.js +6 -2
  98. package/dist/capabilities/composite-members.d.ts +4 -1
  99. package/dist/capabilities/composite-members.js +4 -1
  100. package/dist/capabilities/execution-lane.d.ts +7 -7
  101. package/dist/capabilities/execution-lane.js +2 -2
  102. package/dist/capabilities/hands-lane.d.ts +1 -1
  103. package/dist/capabilities/scenarios.d.ts +34 -20
  104. package/dist/capabilities/scenarios.js +13 -9
  105. package/dist/capabilities/settings-contract.d.ts +29 -0
  106. package/dist/capabilities/settings-contract.js +14 -0
  107. package/dist/capabilities/skills.d.ts +5 -5
  108. package/dist/capability-facts.d.ts +56 -1
  109. package/dist/capability-facts.js +59 -8
  110. package/dist/center-credential-renewer.js +3 -2
  111. package/dist/checkpoint-ctx-seal-m28.d.ts +1 -1
  112. package/dist/config-catalog.js +19 -9
  113. package/dist/config-invariants.d.ts +18 -3
  114. package/dist/config-invariants.js +36 -19
  115. package/dist/config-lkg.d.ts +1 -1
  116. package/dist/config-lkg.js +5 -6
  117. package/dist/config-provider.d.ts +2 -2
  118. package/dist/config-provider.js +2 -0
  119. package/dist/config-types.d.ts +228 -185
  120. package/dist/config.d.ts +74 -6
  121. package/dist/config.js +146 -64
  122. package/dist/degenerate-instrument.js +1 -1
  123. package/dist/deleted-session-ids.d.ts +19 -0
  124. package/dist/deleted-session-ids.js +26 -0
  125. package/dist/deploy-facts.d.ts +155 -0
  126. package/dist/deploy-facts.js +95 -0
  127. package/dist/deployment-shape.d.ts +21 -12
  128. package/dist/deployment-shape.js +24 -6
  129. package/dist/device-ws-hub.d.ts +48 -3
  130. package/dist/device-ws-hub.js +48 -2
  131. package/dist/env-facts.d.ts +7 -5
  132. package/dist/env-facts.js +10 -6
  133. package/dist/error-code-family.d.ts +35 -0
  134. package/dist/error-code-family.js +26 -0
  135. package/dist/execution-config-root.d.ts +5 -5
  136. package/dist/execution-config-root.js +5 -5
  137. package/dist/execution-env-purpose.d.ts +14 -0
  138. package/dist/execution-env-purpose.js +29 -0
  139. package/dist/execution-lane-caps.d.ts +49 -86
  140. package/dist/execution-lane-caps.js +52 -62
  141. package/dist/execution-placement.d.ts +18 -2
  142. package/dist/execution-placement.js +19 -0
  143. package/dist/file-history-disclosure.d.ts +2 -2
  144. package/dist/fleet/drain-entry.d.ts +46 -3
  145. package/dist/fleet/drain-entry.js +6 -0
  146. package/dist/fleet/fleet-bus.d.ts +2 -1
  147. package/dist/fleet/serving-lease.js +3 -4
  148. package/dist/history-anchor.d.ts +22 -0
  149. package/dist/history-anchor.js +14 -0
  150. package/dist/hooks/branch-transcript.d.ts +1 -1
  151. package/dist/hooks/branch-transcript.js +1 -0
  152. package/dist/hooks/classic-stations.d.ts +25 -8
  153. package/dist/hooks/classic-stations.js +29 -3
  154. package/dist/hooks/command-spawn.d.ts +1 -4
  155. package/dist/hooks/command-spawn.js +0 -11
  156. package/dist/hooks/hook-runner.d.ts +85 -24
  157. package/dist/hooks/hook-runner.js +326 -109
  158. package/dist/hooks/hook-source.d.ts +14 -2
  159. package/dist/hooks/hook-source.js +8 -0
  160. package/dist/http/active-run-conflict.d.ts +1 -1
  161. package/dist/http/active-run-conflict.js +1 -1
  162. package/dist/http/admission.js +11 -1
  163. package/dist/http/approval-sweeps.d.ts +2 -5
  164. package/dist/http/approval-sweeps.js +3 -2
  165. package/dist/http/checkpoint-ctx.d.ts +76 -71
  166. package/dist/http/checkpoint-ctx.js +40 -40
  167. package/dist/http/claim-latency.d.ts +10 -0
  168. package/dist/http/claim-latency.js +12 -0
  169. package/dist/http/dispatch.js +19 -3
  170. package/dist/http/durable-run-leg.d.ts +5 -0
  171. package/dist/http/durable-run-leg.js +3 -1
  172. package/dist/http/execution-context.d.ts +7 -1
  173. package/dist/http/execution-context.js +13 -0
  174. package/dist/http/health-self-report.d.ts +6 -2
  175. package/dist/http/health-self-report.js +3 -2
  176. package/dist/http/memory-compliance-failure-reply.d.ts +2 -2
  177. package/dist/http/memory-compliance-failure-reply.js +5 -15
  178. package/dist/http/memory-control-plane-corrupt-reply.d.ts +25 -0
  179. package/dist/http/memory-control-plane-corrupt-reply.js +19 -0
  180. package/dist/http/memory-store-refusal-reply.d.ts +3 -3
  181. package/dist/http/memory-store-refusal-reply.js +3 -0
  182. package/dist/http/owner-access.d.ts +11 -0
  183. package/dist/http/owner-access.js +7 -4
  184. package/dist/http/principal-gate.d.ts +28 -16
  185. package/dist/http/principal-gate.js +10 -19
  186. package/dist/http/request-guards.d.ts +2 -2
  187. package/dist/http/request-guards.js +5 -5
  188. package/dist/http/resume-legs.d.ts +29 -10
  189. package/dist/http/resume-legs.js +94 -56
  190. package/dist/http/rewind-files-reply.d.ts +34 -0
  191. package/dist/http/rewind-files-reply.js +36 -0
  192. package/dist/http/route-ctx.d.ts +43 -26
  193. package/dist/http/route-table.js +4 -0
  194. package/dist/http/routes/adoption.d.ts +11 -0
  195. package/dist/http/routes/adoption.js +80 -6
  196. package/dist/http/routes/agents-roster.js +1 -0
  197. package/dist/http/routes/approvals-assistant.js +7 -26
  198. package/dist/http/routes/background.js +1 -0
  199. package/dist/http/routes/capabilities.js +12 -3
  200. package/dist/http/routes/devices.js +1 -1
  201. package/dist/http/routes/diagnostics.d.ts +9 -14
  202. package/dist/http/routes/diagnostics.js +10 -20
  203. package/dist/http/routes/engine.d.ts +31 -0
  204. package/dist/http/routes/engine.js +81 -0
  205. package/dist/http/routes/memory-bundle.js +3 -0
  206. package/dist/http/routes/memory-consolidation.js +3 -5
  207. package/dist/http/routes/memory-origin.d.ts +2 -2
  208. package/dist/http/routes/memory-origin.js +2 -4
  209. package/dist/http/routes/memory-policy.js +5 -1
  210. package/dist/http/routes/notify-wake.js +2 -1
  211. package/dist/http/routes/observability.js +3 -6
  212. package/dist/http/routes/projects.d.ts +70 -0
  213. package/dist/http/routes/projects.js +86 -0
  214. package/dist/http/routes/rules.js +30 -2
  215. package/dist/http/routes/runs.js +15 -11
  216. package/dist/http/routes/session-sync.js +39 -35
  217. package/dist/http/routes/sessions-list.d.ts +1 -1
  218. package/dist/http/routes/sessions.d.ts +7 -1
  219. package/dist/http/routes/sessions.js +108 -2
  220. package/dist/http/routes/tasks.js +32 -8
  221. package/dist/http/routes/trace-usage.js +1 -1
  222. package/dist/http/run-concurrency-cap.d.ts +86 -0
  223. package/dist/http/run-concurrency-cap.js +54 -0
  224. package/dist/http/server.d.ts +31 -14
  225. package/dist/http/server.js +29 -3
  226. package/dist/http/stored-body-replay.d.ts +12 -7
  227. package/dist/http/stored-body-replay.js +28 -5
  228. package/dist/http/wire-types.d.ts +27 -13
  229. package/dist/index.d.ts +2 -2
  230. package/dist/index.js +1 -1
  231. package/dist/instruction-source-notice.d.ts +1 -1
  232. package/dist/json-body-limit.d.ts +8 -0
  233. package/dist/json-body-limit.js +2 -0
  234. package/dist/leader/diffout.d.ts +1 -1
  235. package/dist/local-data-root.d.ts +2 -2
  236. package/dist/memory-embedder-reembed.d.ts +38 -0
  237. package/dist/memory-embedder-reembed.js +20 -0
  238. package/dist/memory-incident-sink.d.ts +0 -28
  239. package/dist/memory-incident-sink.js +5 -0
  240. package/dist/memory-operator-faces.d.ts +9 -4
  241. package/dist/memory-scope-stores.d.ts +9 -7
  242. package/dist/memory-scope-stores.js +3 -14
  243. package/dist/memory-scope.d.ts +38 -2
  244. package/dist/memory-scope.js +33 -2
  245. package/dist/memory-store-refusal.d.ts +17 -4
  246. package/dist/memory-store-refusal.js +1 -1
  247. package/dist/memory-sync-client.d.ts +2 -0
  248. package/dist/memory-sync-client.js +13 -11
  249. package/dist/memory-sync.js +1 -1
  250. package/dist/model-compat.d.ts +35 -21
  251. package/dist/model-compat.js +49 -21
  252. package/dist/model-entry-refusal.d.ts +11 -1
  253. package/dist/model-entry-refusal.js +7 -0
  254. package/dist/namespaced-rule-name.d.ts +18 -1
  255. package/dist/namespaced-rule-name.js +12 -0
  256. package/dist/net-address.d.ts +53 -0
  257. package/dist/net-address.js +111 -0
  258. package/dist/observability/fail-open.d.ts +29 -17
  259. package/dist/observability/fail-open.js +29 -17
  260. package/dist/observability/metrics.d.ts +2 -0
  261. package/dist/observability/metrics.js +2 -0
  262. package/dist/observability/secret-env-scrub.d.ts +30 -4
  263. package/dist/observability/secret-env-scrub.js +15 -3
  264. package/dist/orchestration/workflow-agent-session-index.d.ts +7 -12
  265. package/dist/orchestration/workflow-agent-session-index.js +1 -6
  266. package/dist/orchestration/workflow-completion-inbox.d.ts +26 -6
  267. package/dist/orchestration/workflow-completion-inbox.js +63 -45
  268. package/dist/orchestration/workflow-notify-journal.js +2 -3
  269. package/dist/org-delivery-gate.js +1 -1
  270. package/dist/org-memory-admission.d.ts +5 -2
  271. package/dist/org-memory-admission.js +25 -10
  272. package/dist/parked-decide.d.ts +33 -26
  273. package/dist/parked-decide.js +36 -44
  274. package/dist/peer-directory.d.ts +6 -12
  275. package/dist/peer-directory.js +5 -1
  276. package/dist/plugins/approval-ask-store-file.d.ts +10 -2
  277. package/dist/plugins/approval-ask-store-file.js +37 -4
  278. package/dist/plugins/approval-ask-store-memory.d.ts +5 -3
  279. package/dist/plugins/approval-ask-store-memory.js +11 -2
  280. package/dist/plugins/approval-ask-store-sql.d.ts +3 -0
  281. package/dist/plugins/approval-ask-store-sql.js +3 -1
  282. package/dist/plugins/blob-backend.d.ts +38 -195
  283. package/dist/plugins/blob-backend.js +33 -229
  284. package/dist/plugins/caching-session-store.d.ts +12 -5
  285. package/dist/plugins/caching-session-store.js +3 -0
  286. package/dist/plugins/checkpoint-index-columns.d.ts +1 -1
  287. package/dist/plugins/checkpoint-index-columns.js +3 -2
  288. package/dist/plugins/checkpoint-store-face.d.ts +426 -0
  289. package/dist/plugins/checkpoint-store-face.js +152 -0
  290. package/dist/plugins/device-store-sql.d.ts +2 -2
  291. package/dist/plugins/device-store-sql.js +5 -10
  292. package/dist/plugins/execution-lane-rename-m40.d.ts +20 -0
  293. package/dist/plugins/execution-lane-rename-m40.js +10 -0
  294. package/dist/plugins/execution-placement-sql.d.ts +63 -88
  295. package/dist/plugins/execution-placement-sql.js +94 -54
  296. package/dist/plugins/file-run-store.d.ts +26 -18
  297. package/dist/plugins/file-run-store.js +64 -75
  298. package/dist/plugins/fork-routing-session-store.d.ts +6 -2
  299. package/dist/plugins/fork-routing-session-store.js +2 -2
  300. package/dist/plugins/imported-layer-root-retirement.d.ts +22 -11
  301. package/dist/plugins/imported-layer-root-retirement.js +4 -8
  302. package/dist/plugins/inbox-payload-column.d.ts +14 -0
  303. package/dist/plugins/inbox-payload-column.js +13 -0
  304. package/dist/plugins/local-checkpoint-store.d.ts +7 -2
  305. package/dist/plugins/local-checkpoint-store.js +13 -8
  306. package/dist/plugins/local-data-dir-modes-m39.d.ts +48 -0
  307. package/dist/plugins/local-data-dir-modes-m39.js +182 -0
  308. package/dist/plugins/local-engine-high-water.d.ts +11 -0
  309. package/dist/plugins/local-engine-high-water.js +59 -0
  310. package/dist/plugins/local-session-store.d.ts +119 -30
  311. package/dist/plugins/local-session-store.js +156 -53
  312. package/dist/plugins/local-task-attachment-store.d.ts +2 -0
  313. package/dist/plugins/local-task-attachment-store.js +10 -11
  314. package/dist/plugins/memory-embedder-fingerprint.d.ts +33 -10
  315. package/dist/plugins/memory-embedder-fingerprint.js +52 -12
  316. package/dist/plugins/memory-embedder.d.ts +1 -1
  317. package/dist/plugins/memory-embedder.js +2 -2
  318. package/dist/plugins/memory-engine-pg.d.ts +30 -6
  319. package/dist/plugins/memory-engine-pg.js +96 -214
  320. package/dist/plugins/memory-engine-sql-apply.d.ts +130 -0
  321. package/dist/plugins/memory-engine-sql-apply.js +358 -0
  322. package/dist/plugins/memory-engine-tidb.d.ts +38 -9
  323. package/dist/plugins/memory-engine-tidb.js +99 -230
  324. package/dist/plugins/memory-key-guards.d.ts +1 -1
  325. package/dist/plugins/memory-origin-law.d.ts +3 -3
  326. package/dist/plugins/one-time-migrations.d.ts +169 -83
  327. package/dist/plugins/one-time-migrations.js +295 -235
  328. package/dist/plugins/owner-only-file-mode.d.ts +29 -0
  329. package/dist/plugins/owner-only-file-mode.js +141 -0
  330. package/dist/plugins/permission-rule-store-file.d.ts +17 -3
  331. package/dist/plugins/permission-rule-store-file.js +20 -1
  332. package/dist/plugins/pg-pool.d.ts +2 -1
  333. package/dist/plugins/pg-pool.js +12 -5
  334. package/dist/plugins/release-version.d.ts +20 -0
  335. package/dist/plugins/release-version.js +28 -0
  336. package/dist/plugins/remote-env-adb.d.ts +20 -4
  337. package/dist/plugins/remote-env-adb.js +39 -11
  338. package/dist/plugins/remote-env-e2b.d.ts +12 -3
  339. package/dist/plugins/remote-env-e2b.js +6 -4
  340. package/dist/plugins/remote-env-host.d.ts +9 -1
  341. package/dist/plugins/remote-env-host.js +6 -5
  342. package/dist/plugins/remote-env-k8s.d.ts +5 -2
  343. package/dist/plugins/remote-env-k8s.js +15 -4
  344. package/dist/plugins/remote-env-local-docker.d.ts +4 -1
  345. package/dist/plugins/remote-env-local-docker.js +3 -3
  346. package/dist/plugins/remote-env-ssh.d.ts +8 -2
  347. package/dist/plugins/remote-env-ssh.js +26 -24
  348. package/dist/plugins/remote-shell.d.ts +59 -30
  349. package/dist/plugins/remote-shell.js +175 -62
  350. package/dist/plugins/retention-declaration.d.ts +37 -0
  351. package/dist/plugins/retention-declaration.js +9 -0
  352. package/dist/plugins/retention-deployment.d.ts +126 -0
  353. package/dist/plugins/retention-deployment.js +88 -0
  354. package/dist/plugins/retention-lane-store-sql.d.ts +74 -4
  355. package/dist/plugins/retention-lane-store-sql.js +103 -1
  356. package/dist/plugins/retention-sql.d.ts +29 -0
  357. package/dist/plugins/retention-sql.js +8 -0
  358. package/dist/plugins/run-store-sql.js +2 -2
  359. package/dist/plugins/schema-consistency.d.ts +0 -6
  360. package/dist/plugins/schema-consistency.js +1 -2
  361. package/dist/plugins/schema-ensure-legs.d.ts +1 -1
  362. package/dist/plugins/schema-ensure-legs.js +13 -3
  363. package/dist/plugins/session-ext-table.d.ts +74 -0
  364. package/dist/plugins/session-ext-table.js +121 -0
  365. package/dist/plugins/session-fork.d.ts +31 -9
  366. package/dist/plugins/session-fork.js +3 -2
  367. package/dist/plugins/session-placement.d.ts +4 -2
  368. package/dist/plugins/session-row-sql.d.ts +8 -7
  369. package/dist/plugins/session-row-sql.js +15 -7
  370. package/dist/plugins/session-store-sql.d.ts +131 -0
  371. package/dist/plugins/session-store-sql.js +298 -0
  372. package/dist/plugins/session-workspace-cell.d.ts +2 -2
  373. package/dist/plugins/session-workspace-cell.js +2 -2
  374. package/dist/plugins/shared-memory-store-sql.d.ts +10 -0
  375. package/dist/plugins/shared-memory-store-sql.js +13 -13
  376. package/dist/plugins/snapshot-bucket-presence.js +1 -1
  377. package/dist/plugins/sql-driver.d.ts +23 -7
  378. package/dist/plugins/sql-driver.js +41 -8
  379. package/dist/plugins/sql-errors.d.ts +5 -2
  380. package/dist/plugins/sql-errors.js +4 -0
  381. package/dist/plugins/sql-json-column.d.ts +5 -1
  382. package/dist/plugins/store-backend.d.ts +46 -16
  383. package/dist/plugins/store-backend.js +192 -69
  384. package/dist/plugins/store-contracts.d.ts +10 -13
  385. package/dist/plugins/store-contracts.js +1 -9
  386. package/dist/plugins/store-sweep.d.ts +63 -0
  387. package/dist/plugins/store-sweep.js +48 -0
  388. package/dist/plugins/task-attachment-store.d.ts +6 -8
  389. package/dist/plugins/task-attachment-store.js +15 -10
  390. package/dist/plugins/task-list-store-sql.d.ts +1 -1
  391. package/dist/plugins/text-column-capacity.d.ts +21 -0
  392. package/dist/plugins/text-column-capacity.js +5 -0
  393. package/dist/plugins/tidb-pool.d.ts +3 -2
  394. package/dist/plugins/tidb-pool.js +20 -32
  395. package/dist/plugins/user-input-ledger-sql.d.ts +1 -1
  396. package/dist/prompt-screen.d.ts +6 -9
  397. package/dist/prompt-screen.js +2 -5
  398. package/dist/read-face-posture.d.ts +6 -6
  399. package/dist/read-face-posture.js +2 -2
  400. package/dist/request-value-closure.d.ts +5 -5
  401. package/dist/request-value-closure.js +1 -1
  402. package/dist/rules-consent.d.ts +48 -27
  403. package/dist/rules-consent.js +147 -23
  404. package/dist/run-cancel-context.d.ts +4 -1
  405. package/dist/run-cancel-context.js +2 -1
  406. package/dist/run-local.js +17 -13
  407. package/dist/runs.d.ts +48 -30
  408. package/dist/runs.js +27 -17
  409. package/dist/runtime-caps-resolver.d.ts +15 -8
  410. package/dist/runtime-caps-resolver.js +14 -10
  411. package/dist/sandbox-egress-policy.js +6 -11
  412. package/dist/sandbox-rbac-rules.d.ts +88 -0
  413. package/dist/sandbox-rbac-rules.js +80 -0
  414. package/dist/sealed-key-layout.d.ts +16 -0
  415. package/dist/sealed-key-layout.js +3 -0
  416. package/dist/sealed-key.js +8 -6
  417. package/dist/security.d.ts +43 -9
  418. package/dist/security.js +9 -2
  419. package/dist/sema-config-dir.js +2 -2
  420. package/dist/server-secret-env.d.ts +2 -0
  421. package/dist/service-version.d.ts +2 -1
  422. package/dist/service-version.js +2 -2
  423. package/dist/session-error-wire.d.ts +1 -1
  424. package/dist/session-incarnation.d.ts +8 -5
  425. package/dist/session-notify-door.d.ts +5 -3
  426. package/dist/session-resident-background.d.ts +110 -0
  427. package/dist/session-resident-background.js +88 -0
  428. package/dist/session-row.d.ts +1 -1
  429. package/dist/session-sync-kernel.d.ts +53 -14
  430. package/dist/session-sync-kernel.js +70 -1
  431. package/dist/session-sync.d.ts +5 -3
  432. package/dist/session-workspace.d.ts +12 -2
  433. package/dist/session-workspace.js +6 -0
  434. package/dist/sighup-idle.d.ts +9 -7
  435. package/dist/sighup-idle.js +4 -5
  436. package/dist/spec-fields.d.ts +16 -0
  437. package/dist/spec-fields.js +7 -0
  438. package/dist/store-posture.d.ts +2 -1
  439. package/dist/stored-request-env-credentials-m38.d.ts +3 -0
  440. package/dist/stored-request-env-credentials-m38.js +8 -0
  441. package/dist/stored-request-hooks-m20.d.ts +3 -2
  442. package/dist/stored-request-hooks-m20.js +19 -14
  443. package/dist/stored-request-prompt-profile-m30.d.ts +1 -1
  444. package/dist/stores-sql/blob-index-sql.d.ts +148 -0
  445. package/dist/stores-sql/blob-index-sql.js +154 -0
  446. package/dist/{plugins → stores-sql}/checkpoint-store-sql.d.ts +14 -428
  447. package/dist/{plugins → stores-sql}/checkpoint-store-sql.js +43 -220
  448. package/dist/{plugins → stores-sql}/file-history-store-sql.d.ts +23 -11
  449. package/dist/{plugins → stores-sql}/file-history-store-sql.js +23 -18
  450. package/dist/{plugins → stores-sql}/mailbox-store-sql.d.ts +2 -2
  451. package/dist/{plugins → stores-sql}/mailbox-store-sql.js +4 -4
  452. package/dist/{plugins → stores-sql}/pg-session-storage.d.ts +27 -67
  453. package/dist/{plugins → stores-sql}/pg-session-storage.js +82 -207
  454. package/dist/{plugins → stores-sql}/retention-store-sql.d.ts +123 -217
  455. package/dist/{plugins → stores-sql}/retention-store-sql.js +66 -190
  456. package/dist/{plugins → stores-sql}/roster-store-sql.d.ts +2 -2
  457. package/dist/{plugins → stores-sql}/roster-store-sql.js +1 -1
  458. package/dist/{plugins → stores-sql}/session-event-payload.d.ts +1 -1
  459. package/dist/{plugins → stores-sql}/session-event-payload.js +1 -1
  460. package/dist/stores-sql/session-policy-store-sql.d.ts +1 -1
  461. package/dist/stores-sql/session-write-hooks.d.ts +59 -0
  462. package/dist/stores-sql/session-write-hooks.js +2 -0
  463. package/dist/{plugins → stores-sql}/tidb-session-storage.d.ts +10 -11
  464. package/dist/{plugins → stores-sql}/tidb-session-storage.js +10 -21
  465. package/dist/{plugins → stores-sql}/tidb-session-store.d.ts +35 -112
  466. package/dist/{plugins → stores-sql}/tidb-session-store.js +73 -169
  467. package/dist/{plugins → stores-sql}/tool-result-store-sql.d.ts +3 -3
  468. package/dist/{plugins → stores-sql}/tool-result-store-sql.js +6 -6
  469. package/dist/stores-sql/windowed-session-storage.d.ts +56 -0
  470. package/dist/stores-sql/windowed-session-storage.js +61 -0
  471. package/dist/{plugins → stores-sql}/workflow-journal-store-sql.d.ts +7 -12
  472. package/dist/{plugins → stores-sql}/workflow-journal-store-sql.js +3 -8
  473. package/dist/task-a2a.d.ts +7 -1
  474. package/dist/task-a2a.js +15 -14
  475. package/dist/task-cwd.d.ts +11 -3
  476. package/dist/task-cwd.js +17 -1
  477. package/dist/task-mcp.d.ts +10 -2
  478. package/dist/task-mcp.js +13 -16
  479. package/dist/task-settings.d.ts +68 -8
  480. package/dist/task-settings.js +63 -6
  481. package/dist/tool-approval.d.ts +23 -10
  482. package/dist/tool-approval.js +10 -6
  483. package/dist/trace/core-keyset-guard.d.ts +17 -10
  484. package/dist/trace/engine-notice-wire.d.ts +1 -1
  485. package/dist/trace/engine-notice-wire.js +4 -0
  486. package/dist/trace/exit-seat.d.ts +29 -1
  487. package/dist/trace/exit-seat.js +4 -0
  488. package/dist/trace/project.d.ts +33 -16
  489. package/dist/trace/project.js +21 -9
  490. package/dist/trace/redact.d.ts +13 -2
  491. package/dist/trace/redact.js +347 -78
  492. package/dist/trace/self-minted-wire.d.ts +587 -16
  493. package/dist/trace/self-minted-wire.js +215 -9
  494. package/dist/trace/sema-provenance.d.ts +45 -41
  495. package/dist/trace/sema-provenance.js +81 -10
  496. package/dist/trace/task-notification-facets.d.ts +70 -2
  497. package/dist/trace/task-notification-facets.js +71 -1
  498. package/dist/trace/wire-projection-faces.d.ts +39 -3
  499. package/dist/trace/wire-projection-faces.js +27 -2
  500. package/dist/unread-request-members.d.ts +66 -0
  501. package/dist/unread-request-members.js +41 -0
  502. package/dist/usage-analytics.d.ts +4 -0
  503. package/dist/user-input-ledger.d.ts +2 -2
  504. package/dist/web-admin-client/apply-effective.js +22 -26
  505. package/dist/web-admin-client/candidate-gate.d.ts +35 -3
  506. package/dist/web-admin-client/candidate-gate.js +53 -5
  507. package/dist/web-admin-client/center-request.d.ts +4 -1
  508. package/dist/web-admin-client/center-request.js +2 -1
  509. package/dist/web-admin-client/effective-keys.js +0 -1
  510. package/dist/web-admin-client/facade.d.ts +1 -1
  511. package/dist/web-admin-client/http-client.d.ts +1 -0
  512. package/dist/web-admin-client/http-client.js +17 -9
  513. package/dist/web-admin-client/restart-signal.js +5 -2
  514. package/dist/web-admin-client/skills-mcp.d.ts +20 -6
  515. package/dist/web-admin-client/skills-mcp.js +26 -21
  516. package/dist/web-admin-client/types.d.ts +34 -49
  517. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +2 -2
  518. package/package.json +22 -13
  519. package/scripts/drain-check-local.mjs +8 -55
  520. package/scripts/drain-check.mysql.sql +3 -40
  521. package/scripts/drain-check.pg.sql +3 -40
  522. package/skills/update-config.md +1 -1
  523. package/wire-changes/server@7.146.0.json +3221 -0
  524. package/wire-changes/server@7.147.0.json +813 -0
  525. package/dist/approval-batch-census.d.ts +0 -27
  526. package/dist/approval-batch-census.js +0 -27
@@ -58,7 +58,7 @@
58
58
  * core 自己响亮拒(`memory.erasure_evidence_unavailable`),那是**运行期**的诚实拒,与「换部署形态才行」
59
59
  * 不是一回事(附录 A 两条分列)。
60
60
  */
61
- import { type EntryProvenanceAccount, type MemoryBackend, type MemoryEntryOrigin, type MemoryErasureAttestation, type OriginClearanceRow, type DeploymentSessionMemoryStatus, type SessionCaptureRecordStore } from "@sema-agent/core";
61
+ import { type EntryProvenanceAccount, type MemoryBackend, type MemoryEntryOrigin, type MemoryErasureAttestation, type OriginClearanceRow, type DeploymentSessionMemoryStatus, type SessionCaptureRecordStore, type SessionMemoryStatus } from "@sema-agent/core";
62
62
  import { type MemoryScopeStores } from "./memory-scope-stores.js";
63
63
  import type { SessionCaptureRecordSource } from "./plugins/store-backend.js";
64
64
  /**
@@ -249,11 +249,16 @@ export interface SessionMemoryStatusFace {
249
249
  /** 一份会话记忆状态的读法(见 {@link SessionMemoryStatusFace.readingAt})。 */
250
250
  export interface SessionMemoryStatusReading {
251
251
  readonly key: string;
252
- /** 引擎的答案,原样(引擎不抛:读不出的源 = 缺席的键)。路由只投 wire 的五键。 */
252
+ /** 引擎的答案,原样(引擎不抛:读不出的源 = 缺席的键)。路由只投 wire 的键。 */
253
253
  status: (sessionId: string) => Promise<SessionMemoryView>;
254
254
  }
255
- /** 状态面上 wire 的五键所在的那一份:部署对象答案去掉逐店明细 `planes`(逐店明细不上 wire,见 `core-keyset-guard.ts`)。 */
256
- export type SessionMemoryView = Omit<DeploymentSessionMemoryStatus, "planes">;
255
+ /**
256
+ * 状态面上 wire 的键所在的那一份,**引擎的答案原样**:带层座 ⇒ 那只店的引擎答案(`SessionMemoryStatus`:五键 + `writeHome`,`writeHome` 是店绑定的键);
257
+ * 不带层座 ⇒ 部署对象的答案(`DeploymentSessionMemoryStatus`:引擎折好的五键 + 引擎择好的会话级 `writeHome` + 逐店明细 `planes`,每行是一只店原样的 `SessionMemoryStatus`)。
258
+ * 会话级 `writeHome` 由引擎在店之间择一(点名家的店里较新的那只的家,原样;任一店读不出 / 同刻 / 无店点名 ⇒ 缺席);本服务不折、不择一、不去重,
259
+ * 路由把顶层 `writeHome` 与每行的 `plane` / `writeHome` 原样投出(见 `core-keyset-guard.ts` ⑩e)。
260
+ */
261
+ export type SessionMemoryView = SessionMemoryStatus & Partial<Pick<DeploymentSessionMemoryStatus, "planes">>;
257
262
  /**
258
263
  * [ref] seam①([ref] §S-7,core 7.0.2 [ref] 件1)—— `GET /v1/sessions/:id/memory-status` 的引擎面。
259
264
  * 命名照 CLAUDE.md 工厂律:返回带行为的活对象 ⇒ `create*`。
@@ -2,10 +2,11 @@
2
2
  * 记忆作用域店 —— 本部署的记忆在本宿主的**唯一持有者**:「一层住在哪只店」与「本部署有哪些店」都只在这里答。
3
3
  *
4
4
  * ## 规则(一条)
5
- * 一层(scope)的平面只有引擎的纯分类函数答(`scopePlanesOf`,契约 = 本服务铸 spec 时盖在会话上的同一只判据 {@link memoryScopeContractOf});
5
+ * 一层(scope)的平面只有引擎答(`memoryScopePlaneOf`,契约 = 本服务铸 spec 时盖在会话上的同一只判据 {@link memoryScopeContractOf});
6
6
  * 一层的店 = 它那只平面的店(项目平面 = 部署的店;目录钉住的部署上个人平面是个人挂载上的另一只店,引擎的 `resolveMemoryScopeStore` 开它)。
7
- * **本部署有哪些店**只有引擎的部署对象答(`createMemoryDeployment(…).stores()`):项目店,再加上个人挂载**在盘上**的那只个人店 ——
8
- * 盘的集合,不是配置点名的层推出来的集合(配置只决定会话往哪写;换了 `MEMORY_SCOPE` 之后个人挂载上留下的那只店照样在集合里)。
7
+ * **本部署有哪些店**只有引擎的部署对象答(`createMemoryDeployment(…).stores()`,契约 `memory.deployment.store_set`):项目店,再加上个人挂载上
8
+ * **存有记录**的那只个人店 —— 盘的集合,不是配置点名的层推出来的集合(配置只决定会话往哪写;换了 `MEMORY_SCOPE` 之后个人挂载上写过的那只店照样在集合里),
9
+ * 也不是「开过」的集合(打开 / 读 / 被拒的请求只留下引擎具名的工件,不让店进集;每次从盘上读,每只部署对象答同一个集合)。
9
10
  * 本服务在会话之外读写某一层的每一条腿(同步执行器、项目层折叠、中心侧导出 / 同步、bundle 导出导入、合规抹除 / 出处、外源标记、会话记忆状态、整理)
10
11
  * 一律问**本对象**。本对象就是起服装配出来的那只记忆引擎对象(`boot/stores.ts` 的 `memoryEngine`、`run-local.ts` 的同名量):它的 `backend` / `root`
11
12
  * 正是交给 Runner 的两件事实(`RunnerDeps.memoryBackend` / `RunnerDeps.memoryEngineDir`)—— 宿主腿与会话对同一层答同一只店。每进程一只,所有腿共用。
@@ -18,7 +19,7 @@
18
19
  *
19
20
  * ## 请求的店({@link memoryStoreForRequest})
20
21
  * 点名层的动词按点名的层取店;点名的几层不在同一只店 ⇒ 响亮拒(一次请求只落一只店)。不点名层的条目 id / 店级账本动词答在**本部署唯一的那只店**上;
21
- * 部署有两只店(盘上有个人店)⇒ 不猜,响亮拒并指路「在请求里点名层」。没有部署对象的部署(SQL 记忆孪生,不钉目录 ⇒ 两个平面同一只店)恒是一只店。
22
+ * 部署有两只店(个人挂载上的店存有记录)⇒ 不猜,响亮拒并指路「在请求里点名层」。没有部署对象的部署(SQL 记忆孪生,不钉目录 ⇒ 两个平面同一只店)恒是一只店。
22
23
  */
23
24
  import { type MemoryBackend, type MemoryDeployment } from "@sema-agent/core";
24
25
  import type { SessionCaptureRecordSource } from "./plugins/store-backend.js";
@@ -29,7 +30,7 @@ export interface MemoryScopeStores {
29
30
  readonly root: string;
30
31
  /** capture opt-out 记录源(起服取一次的那一只;缺席 ⇒ 引擎各自的文件缺省)。本部署每一只记忆引擎 —— 部署对象、各操作面按店构造的引擎 —— 都只读这一格。 */
31
32
  readonly captureRecords: SessionCaptureRecordSource | undefined;
32
- /** 层 `layer` 的平面(引擎的规范化 + 纯分类函数,与引擎的店解析同一读法;零建店、零读盘)。引擎读不出的层键 ⇒ 抛引擎的 `config.memory_scope_key`,原样。 */
33
+ /** 层 `layer` 的平面(引擎的 `memoryScopePlaneOf`,与引擎的店解析同一只;零建店、零读盘)。引擎读不出的层键 ⇒ 抛引擎的 `config.memory_scope_key`,原样。 */
33
34
  planeOf(layer: string): "project" | "personal";
34
35
  /** 层 `layer` 住的那只店(先判平面、每个平面一只实例)。读不出的层键 ⇒ 同 {@link MemoryScopeStores.planeOf}。 */
35
36
  storeOf(layer: string): MemoryBackend;
@@ -37,7 +38,8 @@ export interface MemoryScopeStores {
37
38
  deployment(): MemoryDeployment | undefined;
38
39
  }
39
40
  /**
40
- * 控制面归属判据 —— 记忆操作面(合规 / 外源标记 / 会话记忆状态 / consolidation 阀门的 D1 拒启门)与部署对象共用的**同一只**谓词:
41
+ * 控制面归属判据 —— 记忆操作面(合规 / 外源标记 / 会话记忆状态)与部署对象共用的**同一只**谓词(这些部署面问「后端发不发布控制面」;
42
+ * 整理阀门问的是另一件事 —— 整理状态随不随后端走 —— 只问引擎的 `memoryGovernanceDurability`,见 `boot/memory-consolidation.ts`):
41
43
  * backend 的面上带**非空** `controlPlaneRoot` 才算归属在案。空串与缺席同判「不归属」:core 对空串会 truthy-回退到本副本盘上派生控制面
42
44
  * (engine 构造里的 `backendControl ? … : derive(…)`),对无状态多副本部署这正是 D1 要拒的那台机器(折叠账随 pod 一起死)。
43
45
  */
@@ -63,7 +65,7 @@ export declare class MemoryLayerRefusal extends Error {
63
65
  /**
64
66
  * 一次请求的记忆店。`layers` = 请求点名的层(空 = 没点名):
65
67
  * · 点名 ⇒ 它们共住的那一只店;分住两只 ⇒ 拒(一次请求只落一只店,按店拆成几次请求)。
66
- * · 没点名 ⇒ 本部署唯一的那只店(= 部署的店);部署有两只店(盘上有个人店,{@link MemoryScopeStores.deployment})⇒ 拒,指路在请求里点名层。
68
+ * · 没点名 ⇒ 本部署唯一的那只店(= 部署的店);部署有两只店(个人挂载上的店存有记录,{@link MemoryScopeStores.deployment})⇒ 拒,指路在请求里点名层。
67
69
  * `seat` = 这个动词点名层的那一处(拒句里指路用,如 `` `scope` ``;缺省 = 层座 `scope`)。
68
70
  * 拒一律 {@link MemoryLayerRefusal}(读不出的层键同码,引擎原句随句)。
69
71
  */
@@ -1,4 +1,4 @@
1
- import { createMemoryDeployment, normalizeMemorySpec, resolveMemoryScopeStore, scopePlanesOf } from "@sema-agent/core";
1
+ import { createMemoryDeployment, memoryScopePlaneOf, resolveMemoryScopeStore } from "@sema-agent/core";
2
2
  import { memoryScopeContractOf } from "./memory-scope.js";
3
3
  export function backendOwnsControlPlane(backend) {
4
4
  return controlPlaneRootOf(backend) !== undefined;
@@ -7,6 +7,7 @@ export function controlPlaneRootOf(backend) {
7
7
  const root = backend?.controlPlaneRoot;
8
8
  return typeof root === "string" && root !== "" ? root : undefined;
9
9
  }
10
+ const PLANE_FACE = "memoryScopeStores.planeOf";
10
11
  export function createMemoryScopeStores(input) {
11
12
  let personal;
12
13
  const resolve = (layer) => resolveMemoryScopeStore({
@@ -16,19 +17,7 @@ export function createMemoryScopeStores(input) {
16
17
  memoryEngineDir: input.root,
17
18
  ...(input.onIncident !== undefined ? { onIncident: input.onIncident } : {}),
18
19
  });
19
- const planeOf = (layer) => {
20
- const contract = memoryScopeContractOf([layer]);
21
- let spec;
22
- try {
23
- spec = normalizeMemorySpec({ scopes: [layer], writeScope: layer, ...(contract !== undefined ? { scopeContract: contract } : {}) });
24
- }
25
- catch {
26
- spec = undefined;
27
- }
28
- if (spec === undefined || spec.writeScope === null)
29
- return resolve(layer).plane;
30
- return scopePlanesOf(spec.scopes, spec.writeScope, spec.scopeContract)?.writePlane ?? "project";
31
- };
20
+ const planeOf = (layer) => memoryScopePlaneOf(PLANE_FACE, layer, memoryScopeContractOf([layer]));
32
21
  let deployment;
33
22
  return {
34
23
  backend: input.backend,
@@ -57,7 +57,7 @@ export declare function memoryScopeFor(config: ServiceConfig, principal?: string
57
57
  *
58
58
  * **一条规则,与车道无关**(主会话 09-23 裁 ②):项目根 = spec 解析出的**真任务根**(`boot/resolve-spec.ts`
59
59
  * 的 `realTaskRootOf`,[ref] 属主;run-local 腿 = 它的 `workspaceDir`)。本进程读得到这个根 ⇒ 求项目身份并铸项目层键
60
- * (in-process 车道的真任务根是 `process.cwd()`,读得到,所以照常铸 —— 它的语义就是「项目 = 任务根指向的地方」,不需要另一个词);
60
+ * (无手的 `none` 车道的真任务根是 `process.cwd()`,读得到,所以照常铸 —— 它的语义就是「项目 = 任务根指向的地方」,不需要另一个词);
61
61
  * 读不到(根在沙箱/设备盘上,或 host 车道会话没登记 cwd、spec 期还不知道根)⇒ 调用方传 `undefined` ⇒ `{ absent: "unreadable" }`,
62
62
  * core 铸 operator 通知 `memory.project_scope_absent`,写照常落全局层 —— **响亮**,不是静默落 `local`。
63
63
  *
@@ -106,7 +106,7 @@ export declare function replicatesProjectLayersOf(coverage: MemoryReplicationCov
106
106
  * (`MEMORY_ENGINE_REMOTE_LANE=allow`, e.g. ssh to a host on the same NFS mount).
107
107
  *
108
108
  * Pure posture probe (memoryEngineBackendFor consumes it; main.ts logs it): `undefined` = no plane split
109
- * (the lane's file plane IS this worker's fs — `in-process` / `host`), `dark` = split + fail-closed, `forced` =
109
+ * (the lane's file plane IS this worker's fs — `none` / `host`), `dark` = split + fail-closed, `forced` =
110
110
  * split + operator override.
111
111
  * The plane question reads the execution environment block (`hostLocalPaths`, sole author `capabilitiesFor`) — it used to be the
112
112
  * hand-written synonym `lane === undefined || lane === "host"`; readings are unchanged lane by lane.
@@ -173,6 +173,42 @@ export declare function memoryEngineRootFor(config: Pick<ServiceConfig, "memoryE
173
173
  * 所以它的根必须走这条链而不是 `memoryEngineRootFor` 的分派(codex 修复验证轮 [medium]:分派会把 run-local 的
174
174
  * 记忆搬到 `<localDataRoot>/memory-work`,存量记忆与控制面升级后隐形)。 */
175
175
  export declare function fileMemoryEngineRoot(config: Pick<ServiceConfig, "memoryEngineDir">, fallbackRoot?: string): string;
176
+ /**
177
+ * 一条路径的**规范形**(给 {@link judgeMemoryRootOutsideDataRoot} 的 `canonical` 座用的生产实现):
178
+ * · 既存的绝对路径 ⇒ **原样**交给 `realpath`(`.native`:大小写不敏感的文件系统上返回盘上的拼写;符号链接、macOS 的 `/var` → `/private/var` 在这一步展平)。
179
+ * 不先在字串上折 `..`:操作系统在展开符号链接**之后**才折 `..`,`/link/..` 的真身是链接目标的父目录,字串折叠会把它读成 `/`;
180
+ * · 其余(尚不存在 / 相对)⇒ 绝对化并折叠 → 取**最深既存祖先**的 `realpath` → 接回尚不存在的尾巴(尾巴只做字串规范化)。
181
+ *
182
+ * 为什么按「最深既存祖先」而不是直接 `realpath(p)`:boot 期记忆根常常还没建出来(新数据根),`realpath` 对不存在的路径抛 ENOENT,
183
+ * 而数据根那一侧已经存在、会被展平 —— 两侧拼写空间不一样,同一个目录会被读成「不在其下」。祖先用 `existsSync` 找(它对 ENOENT / ENOTDIR / EACCES / ELOOP
184
+ * 一律答 `false`,不抛),所以走到的那一级一定 stat 得动;`realpath` 仍可能在「探完到取值之间目录被挪走 / 搜索权限被收」的竞态里抛 ——
185
+ * 不在本函数里吞(吞了就是一条无声的降级臂),由 boot 调用点接住并响亮报一行(`memory_engine_dir_check_unavailable`),起服照常。
186
+ *
187
+ * 取舍:尾巴(不存在的那几段)只比规范化字串,**不折大小写**,`..` 也按字串折:两个只差大小写、且都还不存在的拼写在大小写不敏感的盘上会被读成两处 ——
188
+ * 方向是多报一条 warn(这条判据的失败方向),不会漏报。
189
+ */
190
+ export declare function canonicalPathOf(p: string): string;
191
+ /** {@link judgeMemoryRootOutsideDataRoot} 的读数:记忆引擎的根落在本机数据根**之外**。三键即 boot 日志行的字段(`hint` 是一句带两条真路径的人话)。 */
192
+ export type MemoryRootOutsideDataRoot = {
193
+ readonly root: string;
194
+ readonly dataRoot: string;
195
+ readonly hint: string;
196
+ };
197
+ /**
198
+ * 【判官】file 形记忆引擎的**已解析根**是不是落在本机数据根(`config.localDataRoot`)**之外** —— 是 ⇒ 回两条真路径(boot 打一条 warn),不是 ⇒ `undefined`。
199
+ *
200
+ * 判据只有这一条**路径包含**:`path.relative(数据根, 记忆根)` 不以 `..` 段开头、也不是绝对路径(跨盘符)⇒ 在其下(相等也算在其下)。**与 env 是否显式无关**:
201
+ * `MEMORY_ENGINE_DIR` 缺席不是判据(此前判据是「`LOCAL_DATA_ROOT` 在 ∧ `MEMORY_ENGINE_DIR` 缺席」,于是 `AGENT_DATA_DIR` 已把两者放在同一处时,
202
+ * 「正在共享全机默认库」一句不真,而显式 `MEMORY_ENGINE_DIR` 指到数据根之外的真分家反而不报)。数据根缺席 ⇒ 无从比较,不报。
203
+ *
204
+ * 纯函数:不读 env、不读盘 —— 规范化走 `canonical` 座(缺省 `path.resolve`,字串规范形;boot 递 {@link canonicalPathOf} 取符号链接 / 大小写展平后的形)。
205
+ * 读数里的两条路径是**调用方给的原样拼写**(运维认得出来的那两条),不是规范形。
206
+ */
207
+ export declare function judgeMemoryRootOutsideDataRoot(a: {
208
+ readonly memoryRoot: string;
209
+ readonly dataRoot: string | undefined;
210
+ readonly canonical?: (p: string) => string;
211
+ }): MemoryRootOutsideDataRoot | undefined;
176
212
  /** 本部署 file 记忆引擎的**平面三坐标**(根 / 记忆目录 / 控制面目录)—— {@link fileMemoryPlaneFor} 一次算齐。 */
177
213
  export interface FileMemoryPlane {
178
214
  readonly root: string;
@@ -1,4 +1,5 @@
1
- import { join } from "node:path";
1
+ import { existsSync, realpathSync } from "node:fs";
2
+ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
2
3
  import { FileMemoryEngineBackend, resolveMemoryEngineRoot, deriveControlPlaneDir, formatUserScope, formatProjScope, normalizeMemorySpec } from "@sema-agent/core";
3
4
  import { capabilitiesFor, executionLaneOf } from "./execution-lane-caps.js";
4
5
  import { assertMemoryScopeWidth } from "./plugins/memory-key-guards.js";
@@ -9,6 +10,7 @@ const V2_SCOPE_PREFIX_BY_KIND = {
9
10
  org: "org:",
10
11
  proj: "proj:",
11
12
  userproj: "userproj:",
13
+ userlocal: "userlocal:",
12
14
  };
13
15
  export const V2_SCOPE_PREFIXES = Object.freeze(Object.values(V2_SCOPE_PREFIX_BY_KIND));
14
16
  export function isV2ScopeKey(key) {
@@ -66,7 +68,7 @@ export function replicatesProjectLayersOf(coverage, owner) {
66
68
  }
67
69
  }
68
70
  export function memoryEngineRemoteLanePosture(config) {
69
- const lane = executionLaneOf(config.remoteExec?.provider);
71
+ const lane = config.remoteExec.provider;
70
72
  if (capabilitiesFor(config).hostLocalPaths)
71
73
  return undefined;
72
74
  return { lane, posture: config.memoryEngineRemoteLaneAllowed === true ? "forced" : "dark" };
@@ -108,6 +110,35 @@ export function memoryEngineRootFor(config, localRoot) {
108
110
  export function fileMemoryEngineRoot(config, fallbackRoot) {
109
111
  return resolveMemoryEngineRoot(config.memoryEngineDir ?? fallbackRoot);
110
112
  }
113
+ export function canonicalPathOf(p) {
114
+ if (isAbsolute(p) && existsSync(p))
115
+ return realpathSync.native(p);
116
+ const abs = resolve(p);
117
+ let existing = abs;
118
+ const tail = [];
119
+ while (!existsSync(existing)) {
120
+ const parent = dirname(existing);
121
+ if (parent === existing)
122
+ return abs;
123
+ tail.unshift(basename(existing));
124
+ existing = parent;
125
+ }
126
+ return join(realpathSync.native(existing), ...tail);
127
+ }
128
+ export function judgeMemoryRootOutsideDataRoot(a) {
129
+ if (!a.dataRoot)
130
+ return undefined;
131
+ const canonical = a.canonical ?? resolve;
132
+ const rel = relative(canonical(a.dataRoot), canonical(a.memoryRoot));
133
+ const inside = rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
134
+ if (inside)
135
+ return undefined;
136
+ return {
137
+ root: a.memoryRoot,
138
+ dataRoot: a.dataRoot,
139
+ hint: `memory engine root ${a.memoryRoot} is outside the local data root ${a.dataRoot}; set MEMORY_ENGINE_DIR under ${a.dataRoot} to isolate it`,
140
+ };
141
+ }
111
142
  export function fileMemoryPlaneFor(config, fallbackRoot) {
112
143
  if (config.requirePrincipal === true || !config.memoryEngineEnabled)
113
144
  return undefined;
@@ -1,13 +1,16 @@
1
1
  /**
2
- * **店形拒**(store-form refusal)在本仓的唯一读法属主(纯叶:零 http / 零 boot 依赖)—— core 一只铸点(`layout.ts` `storeFormRefusal`)的**两码一族**:
2
+ * **店形拒**(store-form refusal)在本仓的唯一读法属主(纯叶:零 http / 零 boot 依赖)—— core 店形拒**一族**(族表 `STORE_FORM_REFUSAL_CODES`,引擎 7.65.0 起三码;
3
+ * 本仓按族读,下面点名的成员只是举例与历史,不是判据):
3
4
  * · `memory.target_outside_store`(core 7.31.1 [ref]):记忆 store 里的一个目录经软链通到了 store **外**(或 store 根在 backend 打开 / 引擎首次
4
5
  * 挂载之后被改指)⇒ 引擎对落点在外的删 / 写 / 重放 / 自身写一律**不做**;
5
6
  * · `memory.scope_home_not_directory`(core 7.44.0 [ref]):一只 scope home(`<memoryDir>/<label>`)不是真目录 —— 被换成软链 / 普通文件 / 特殊文件
6
7
  * (`detail.form` ∈ `symlink` | `file` | `other`,`lstat` 判、不跟链)。修前 core 对这一形抛不带码的 `ControlPlaneCorruptError`(与真控制面损坏同类同形),
7
- * 平铺布局(条目直接住在 home 里)于是答 500,而同一换法在嵌套布局下一层答 409 —— 现在两布局同答这一码。
8
- * 两码的形相同:普通 `Error` + `.code` + `.detail`(`{ path }`;home 那一码多 `form`),**句子以码领头、不含任何宿主路径**(core 7.44.0 起,
8
+ * 平铺布局(条目直接住在 home 里)于是答 500,而同一换法在嵌套布局下一层答 409 —— 现在两布局同答这一码;
9
+ * · `memory.control_plane_links_unsupported`(core 7.65.0):记忆控制面所在的文件系统不能建硬链接 ⇒ File 记忆店在打开处被拒(构造期抛 ⇒ 起服拒;
10
+ * 引擎 mount 时开它自己的店被拒 ⇒ Runner 记忆相 fail-open,这一跑 memoryless,见 `memory-incident-sink.ts`)。
11
+ * 族里各码的形相同:普通 `Error` + `.code` + `.detail`(`{ path }`;home 那一码多 `form`),**句子以码领头、不含任何宿主路径**(core 7.44.0 起,
9
12
  * 路径只在 `detail.path`)。core 的读法:operator 要处置的盘形(去掉那只链 / 放回真目录),**不是**可重试的 IO 故障,也**不是**对调用方的裁决;
10
- * 盘形修好之前重发恒拒。本仓据此一条规则:两码同族、409、码原样;路径只进运维行(HTTP 映射一处,见 `http/memory-store-refusal-reply.ts`)。
13
+ * 盘形修好之前重发恒拒。本仓据此一条规则:族内同答、409、码原样;路径只进运维行(HTTP 映射一处,见 `http/memory-store-refusal-reply.ts`)。
11
14
  *
12
15
  * ## 两条到达车道,两个读者(本模块各给一只,别处不许再写第二份判据)
13
16
  * ① **抛出面**(抹除 / 出处 / 外源列表 / 清标 / bundle 导出导入 —— 凡触 store 树的 backend 面):`.code` 就是码
@@ -36,6 +39,16 @@
36
39
  */
37
40
  import { type ScopeHomeForm, type StoreFormRefusalCode } from "@sema-agent/core";
38
41
  import type { Logger } from "./observability/logger.js";
42
+ /**
43
+ * 词表与型全取 core 包根([ref] / core 7.45.0 [ref];此前 core 不导出,本文件自写两只码字面量与族表 —— 那份手抄随本版退役):
44
+ * · 族 = `STORE_FORM_REFUSAL_CODES`,型 `StoreFormRefusalCode`;族判只读族表、不点成员(族的成员归 core,不在这里由人裁)。HTTP 映射逐码写字面量
45
+ * (错误码目录门扫源码字面量,变量态的码对它隐形),两处穷举:`http/memory-store-refusal-reply.ts`(operator 面)与 `http/memory-compliance-failure-reply.ts`(会话所有者面)——
46
+ * 引擎加一码 ⇒ 两处编译红、各补一臂(引擎 7.65.0 的第三码 `CONTROL_PLANE_LINKS_UNSUPPORTED` 就是这样补的);记忆相上撞到它的 fail-open 臂〔mount 开店被拒 / mount 后的一步记忆活被拒〕在 `memory-incident-sink.ts` 登记;
47
+ * · 抛出面的形 = `StoreFormRefusal`(普通 `Error` + `code` + `detail: StoreFormRefusalDetail`);
48
+ * · `detail.form` 的闭集 = `SCOPE_HOME_FORMS`(型 `ScopeHomeForm`):闭集内原样读,闭集外不读(引擎说不出的词不进运维行)。
49
+ */
50
+ /** 族判(族表 `STORE_FORM_REFUSAL_CODES` 的唯一判据):{@link storeFormRefusalOf} 用它判抛出面的 `.code`;记忆事故席用它判 `codeFieldOf` 已经读出的码(那一席码只许读一次)。 */
51
+ export declare const isStoreFormRefusalCode: (code: unknown) => code is StoreFormRefusalCode;
39
52
  /** 一次店形拒的读数(纯数据)。`path` / `form` 取自 core 的 `detail`(读不出 ⇒ `undefined`,不猜、不从句子里抠)。 */
40
53
  export interface StoreFormRefusalReading {
41
54
  readonly code: StoreFormRefusalCode;
@@ -1,5 +1,5 @@
1
1
  import { SCOPE_HOME_FORMS, STORE_FORM_REFUSAL_CODES } from "@sema-agent/core";
2
- const isStoreFormRefusalCode = (code) => STORE_FORM_REFUSAL_CODES.includes(code);
2
+ export const isStoreFormRefusalCode = (code) => STORE_FORM_REFUSAL_CODES.includes(code);
3
3
  const isScopeHomeForm = (form) => SCOPE_HOME_FORMS.includes(form);
4
4
  export function storeFormRefusalOf(err) {
5
5
  if (!(err instanceof Error))
@@ -40,6 +40,8 @@ export declare function createMemorySyncTransport(opts: {
40
40
  /** 一层的游标文件路径:引擎根 `memoryEngineDir`(= `RunnerDeps.memoryEngineDir` 的那一个值)下 `sync-cursors/<scope 摘要>.json`。一层一只,不随对端变、不随店变。
41
41
  * 落在子目录里:与更早的根下一层文件名 `sync-cursor-<peer>.json` 的空间不相交。 */
42
42
  export declare function memorySyncCursorPath(memoryEngineDir: string, scope: string): string;
43
+ /** 全部游标文件的父目录 `<引擎根>/sync-cursors`(游标路径与一次性迁移 M39 的名册同读这一只;缺省 File 记忆引擎根 = 数据根 ⇒ `<数据根>/sync-cursors`)。 */
44
+ export declare function memorySyncCursorDirFor(memoryEngineDir: string): string;
43
45
  /**
44
46
  * ⑦ 停驻层的出路(闭集;今天唯一成员)。`delete_cursor` = 删掉这一层的游标文件,下一轮从空基线重收敛。读面 `memorySync.parked[].wayOut` 与运维行同读这只词;
45
47
  * 加一个词 ⇒ {@link wayOutSentence} 的穷尽 switch 编译红(句子先写好,词才上得了 wire)。
@@ -1,9 +1,10 @@
1
- import { createHash, randomBytes } from "node:crypto";
2
- import { mkdir, readFile, readdir, rename, rmdir, stat, writeFile } from "node:fs/promises";
1
+ import { createHash } from "node:crypto";
2
+ import { readFile, readdir, rename, rmdir, stat } from "node:fs/promises";
3
3
  import { dirname, join } from "node:path";
4
- import { carriesCredential, syncMemoryScope, } from "@sema-agent/core";
4
+ import { carriesCredential, ensureDir, syncMemoryScope, } from "@sema-agent/core";
5
5
  import { replicationCovers } from "./memory-scope.js";
6
6
  import { parseProjectLayerKey } from "./project-layer-key.js";
7
+ import { atomicWriteFileAsync } from "./plugins/owner-only-file-mode.js";
7
8
  import { ONE_TIME_MIGRATIONS, migrationWindowOpen } from "./plugins/one-time-migrations.js";
8
9
  import { buildMemorySyncIdentityBootRefusal, readMemorySyncIdentity } from "./memory-sync-identity.js";
9
10
  import { buildDisplaySafeUrl } from "./trace/redact.js";
@@ -44,7 +45,10 @@ function scopeDigest(scope) {
44
45
  return createHash("sha256").update(scope, "utf8").digest("hex").slice(0, 32);
45
46
  }
46
47
  export function memorySyncCursorPath(memoryEngineDir, scope) {
47
- return join(memoryEngineDir, SYNC_CURSOR_DIR, `${scopeDigest(scope)}.json`);
48
+ return join(memorySyncCursorDirFor(memoryEngineDir), `${scopeDigest(scope)}.json`);
49
+ }
50
+ export function memorySyncCursorDirFor(memoryEngineDir) {
51
+ return join(memoryEngineDir, SYNC_CURSOR_DIR);
48
52
  }
49
53
  const CURSOR_AXES = { scope: true, peer: true, store: true, incarnation: true };
50
54
  const CURSOR_FOUND = { absent: true, other: true };
@@ -142,10 +146,8 @@ async function loadLayerBaseline(path, scope) {
142
146
  return { kind: "cursor", cursor };
143
147
  }
144
148
  async function saveCursor(path, cursor) {
145
- await mkdir(dirname(path), { recursive: true });
146
- const tmp = `${path}.tmp.${process.pid}.${randomBytes(4).toString("hex")}`;
147
- await writeFile(tmp, JSON.stringify(cursor), "utf8");
148
- await rename(tmp, path);
149
+ ensureDir(dirname(path));
150
+ await atomicWriteFileAsync(path, JSON.stringify(cursor), { durability: "best-effort" });
149
151
  }
150
152
  const LEGACY_PEER_SEGMENT = "central";
151
153
  const LEGACY_ROOT_CURSOR_FILE = "sync-cursor-central.json";
@@ -191,7 +193,7 @@ export async function relocateSyncCursorsM31(memoryEngineDir, log, opts) {
191
193
  log.warn("memory_sync_cursor_not_relocated", { path: from, to, note: "this layer already has a cursor at its path, so the file written by an earlier version stays where it is and no round reads it; delete it" });
192
194
  return;
193
195
  }
194
- await mkdir(dirname(to), { recursive: true });
196
+ ensureDir(dirname(to));
195
197
  try {
196
198
  await rename(from, to);
197
199
  }
@@ -203,7 +205,7 @@ export async function relocateSyncCursorsM31(memoryEngineDir, log, opts) {
203
205
  moved += 1;
204
206
  log.info("memory_sync_cursor_relocated", { from, to });
205
207
  };
206
- const legacyDir = join(memoryEngineDir, SYNC_CURSOR_DIR, LEGACY_PEER_SEGMENT);
208
+ const legacyDir = join(memorySyncCursorDirFor(memoryEngineDir), LEGACY_PEER_SEGMENT);
207
209
  let names = [];
208
210
  try {
209
211
  names = await readdir(legacyDir);
@@ -214,7 +216,7 @@ export async function relocateSyncCursorsM31(memoryEngineDir, log, opts) {
214
216
  }
215
217
  for (const name of [...names].sort()) {
216
218
  if (/^[0-9a-f]{32}\.json$/.test(name))
217
- await move(join(legacyDir, name), join(memoryEngineDir, SYNC_CURSOR_DIR, name));
219
+ await move(join(legacyDir, name), join(memorySyncCursorDirFor(memoryEngineDir), name));
218
220
  }
219
221
  if (names.length > 0) {
220
222
  try {
@@ -219,7 +219,7 @@ export async function performMemorySync(backend, sync, scope, req, now = Date.no
219
219
  const patches = [
220
220
  ...plan.pull.map((e) => {
221
221
  const base = req.baseRevs[e.id];
222
- return base !== undefined ? { op: "update", id: e.id, entry: e, baseRev: base } : { op: "add", id: e.id, entry: e };
222
+ return base !== undefined ? { op: "update", id: e.id, entry: e, baseRev: base } : { op: "add", id: e.id, entry: e, guard: "absent" };
223
223
  }),
224
224
  ...plan.deleteLocal.map((d) => ({ op: "delete", id: d.id, baseRev: d.baseRev })),
225
225
  ];
@@ -1,6 +1,8 @@
1
1
  /**
2
- * `Model.compat` —— 一只模型对 **openai-completions 线路**的兼容声明(core `OpenAICompletionsCompat`;
3
- * 声明面 settings-schema 1.10.0 `ModelEntry.compat`)。本模块是**两条腿共用的唯一判据点 + 唯一铸点**,
2
+ * `Model.compat` —— 一只模型对**它那条线路**的兼容声明(声明面 settings-schema 1.10.0 `ModelEntry.compat`,契约包解析透明、形归本服务):
3
+ * openai-completions 条目读 core `OpenAICompletionsCompat`,anthropic-messages 条目读 core `AnthropicMessagesCompat`(**按线路读**,
4
+ * 线路 = 条目的 `api`:core 的 `Model.compat` 按 `TApi` 分型,契约 `ModelEntry` 强制 `provider:"anthropic"` ⟺ `api:"anthropic-messages"`)。
5
+ * 本模块是**两条腿共用的唯一判据点 + 唯一铸点**,
4
6
  * 与 `toolFaces` 的读法(引擎根导出的 `readToolFaces`,`task-mcp.ts` / `skills-mcp.ts` 两腿同问)同一个「判据单点、多腿一致」的形。
5
7
  *
6
8
  * ## 它治的病(1.10.0 CHANGELOG + core 型面顶注双向亲读)
@@ -11,10 +13,10 @@
11
13
  * 真需求 = vLLM / Qwen 类**缺省开思考**的网关:关思考只能靠 `chat_template_kwargs.enable_thinking=false`
12
14
  * (`thinkingFormat: "qwen-chat-template"`),否则 auto 档每一轮都白烧一段思考。
13
15
  *
14
- * ## 三张对表全部**从 core 的型面铸**,本仓一个词都不枚举
15
- * `THINKING_LEVEL_TABLE` / `THINKING_FORMAT_TABLE` / `MAX_TOKENS_FIELD_TABLE` 都是 `Record<闭集词, true>`,
16
- * `COMPAT_KEY_READERS` 是 `{ [K in keyof Required<OpenAICompletionsCompat>]: 读器 }` 的**映射型**:
17
- * core 加词/删词、加键/删键,四张表当场 tsc 红(`MODEL_DEGRADE_ON` 的 `Set<DegradeReason>` 同款纪律)。
16
+ * ## 对表全部**从 core 的型面铸**,本仓一个词都不枚举
17
+ * `THINKING_LEVEL_TABLE` / `THINKING_FORMAT_TABLE` / `MAX_TOKENS_FIELD_TABLE` / `THINKING_MODE_TABLE` 都是 `Record<闭集词, true>`,
18
+ * `COMPAT_KEY_READERS` 是 `{ [A in 线路]: { [K in keyof Required<Model<A>["compat"]>]: 读器 } }` 的**映射型**(线路 = 契约 `ModelEntry.api` 的闭集):
19
+ * core 加词/删词、加键/删键,或契约加一条线路,表当场 tsc 红(`MODEL_DEGRADE_ON` 的 `Set<DegradeReason>` 同款纪律)。
18
20
  * 映射型这一步是刻意的 —— 只钉「键集相等」会留下一个洞:core 加一键、有人把它补进白名单却忘了写读器,
19
21
  * 于是这个键被**允许但不读** = 静默丢。读器与键集是**同一张表**,那个洞在结构上不存在。
20
22
  *
@@ -27,13 +29,19 @@
27
29
  * 反方向(整只模型不进)的代价则不成比例:一个拼错的 `thinkingFormat` 会让这只模型从目录里消失,
28
30
  * 用户面直接是 `request.unknown_reference`。
29
31
  *
30
- * 判形**整只判**:任一键不合 ⇒ 整只声明不收(和 `toolFaces` 每只工具「applied whole or not at all」
32
+ * 判形**整只判**(每条线路内):任一键不合 —— 含写了另一条线路的键 —— ⇒ 整只声明不收(和 `toolFaces` 每只工具「applied whole or not at all」
31
33
  * 同律)。留下好的那几键 = 让运维以为整条声明生效了,而实际发出去的请求是半张脸。
32
34
  */
33
35
  import type { Model } from "@sema-agent/core";
34
- /** core `OpenAICompletionsCompat` —— core 的 index 没有按名导出它,从 `Model` 的**型面**取
35
- * (`Model<TApi>` 的 `compat` 按 api 分叉;openai 那支就是它)。这不是抄一份结构,是引用同一个型。 */
36
- export type OpenAICompletionsCompat = NonNullable<Model<"openai-completions">["compat"]>;
36
+ import type { ModelEntry } from "@sema-agent/settings-schema";
37
+ /** 目录条目的线路闭集 = 契约 `ModelEntry.api`(契约加一条线路 ⇒ 读器表缺一行 ⇒ tsc 红)。 */
38
+ export type CatalogApi = ModelEntry["api"];
39
+ /** 一条线路的 compat 型 —— core 的 index 没有按名导出它们,从 `Model` 的**型面**取(`Model<TApi>` 的 `compat` 按 api 分叉)。这不是抄一份结构,是引用同一个型。 */
40
+ export type CompatOf<A extends CatalogApi> = NonNullable<Model<A>["compat"]>;
41
+ /** core `OpenAICompletionsCompat`。 */
42
+ export type OpenAICompletionsCompat = CompatOf<"openai-completions">;
43
+ /** core `AnthropicMessagesCompat`。 */
44
+ export type AnthropicMessagesCompat = CompatOf<"anthropic-messages">;
37
45
  /** 六档思考梯(core `ThinkingLevel`)。`MODEL_DEFAULT_THINKING` / `MODEL_REASONING_EFFORT_LEVELS` /
38
46
  * `compat.reasoningEffortLevels` 三处共用**这一张**表 —— [ref] 件⑤ 起就是「上游加一档而这里不补 ⇒
39
47
  * 编译红」的锁步姿势,本模块只是把它挪到了它真正的家(compat 的一个键)。 */
@@ -48,34 +56,40 @@ export declare const isThinkingFormat: (w: unknown) => w is ModelThinkingFormat;
48
56
  /** `maxTokensField` 两词闭集(缺席 ⇒ core 按模型 id 推断,见 `inferMaxTokensField`)。 */
49
57
  export type ModelMaxTokensField = NonNullable<OpenAICompletionsCompat["maxTokensField"]>;
50
58
  export declare const MAX_TOKENS_FIELDS: readonly ModelMaxTokensField[];
51
- type CompatKey = keyof Required<OpenAICompletionsCompat>;
52
- /** 五键闭集(书写序取自上表),未知键拒因文案的单一真源。 */
53
- export declare const MODEL_COMPAT_KEYS: readonly CompatKey[];
59
+ /** anthropic 线路 `thinkingMode` 两词闭集(core:`budget` = `thinking:{type:"enabled",budget_tokens}`;`adaptive` = `thinking:{type:"adaptive"}`、无 budget、关不掉)。 */
60
+ export type AnthropicThinkingMode = NonNullable<AnthropicMessagesCompat["thinkingMode"]>;
61
+ export declare const ANTHROPIC_THINKING_MODES: readonly AnthropicThinkingMode[];
62
+ type CompatKey<A extends CatalogApi> = keyof Required<CompatOf<A>>;
63
+ /** 每条线路的键闭集(书写序取自上表),未知键拒因文案与铸点遍历的单一真源。 */
64
+ export declare const MODEL_COMPAT_KEYS: {
65
+ readonly [A in CatalogApi]: readonly CompatKey<A>[];
66
+ };
54
67
  /**
55
68
  * 一条目录条目的 `compat` 判形结果:
56
69
  * · `{ ok: true, compat }` —— 合形(`compat` 缺席 = 这条条目没有声明,或声明了一个**空**对象:
57
70
  * 两者对 core 同义,都不铸键);
58
71
  * · `{ ok: false, issue }` —— 判不出形,调用方**整只丢**这条声明并留一句 warn(见模块头注)。
59
- * `issue` 只带键名与哪一段不合,**不带值** —— 与 `source` / `toolFaces` 同一条留痕纪律。
72
+ * `issue` 只带线路、键名与哪一段不合,**不带值** —— 与 `source` / `toolFaces` 同一条留痕纪律。
60
73
  */
61
- export type ModelCompatRead = {
74
+ export type ModelCompatRead<A extends CatalogApi> = {
62
75
  ok: true;
63
- compat?: OpenAICompletionsCompat;
76
+ compat?: CompatOf<A>;
64
77
  } | {
65
78
  ok: false;
66
79
  issue: string;
67
80
  };
68
- /** 从任一腿的原始条目里读出 `compat` —— **本地 config.d 腿与 center 腿共用的唯一判据点**。 */
69
- export declare function readModelCompat(v: unknown): ModelCompatRead;
81
+ /** 从任一腿的原始条目里读出 `compat`(按条目的线路)—— **本地 config.d 腿与 center 腿共用的唯一判据点**。 */
82
+ export declare function readModelCompat<A extends CatalogApi>(api: A, v: unknown): ModelCompatRead<A>;
70
83
  /**
71
- * `Model.compat` 的**唯一铸点**(env 腿与目录腿都经这里)。层序 = 优先级,**前层逐键赢、后层补缺席**
84
+ * `Model.compat` 的**唯一铸点**(env 腿与目录腿都经这里;按线路)。层序 = 优先级,**前层逐键赢、后层补缺席**
72
85
  * (BL-8:目录条目声明 ?? env 缺省 —— 不是整只替换,否则一条只写了 `thinkingFormat` 的目录条目会把
73
86
  * 部署级的 `MODEL_REASONING_EFFORT_LEVELS` 静默吃掉,正是 `contextWindow`/`maxTokens` 那一族的老病)。
87
+ * 层必须是同一条线路的声明(调用方只把同线路的 env 缺省叠进来 —— 见 `toModel`)。
74
88
  *
75
89
  * 归一两条(两腿因此对同一个空值给出同一个下场):值 `undefined` = 这一层没声明这一键;
76
- * `reasoningEffortLevels` 为**空表** = 没声明这一键(env 腿的空 CSV 与目录腿的 `[]` 同义)。
90
+ * 数组值为**空表** = 没声明这一键(`reasoningEffortLevels` / `effortLevels`;env 腿的空 CSV 与目录腿的 `[]` 同义)。
77
91
  * 全空 ⇒ 回 `undefined` = **不铸这个键**(缺席 = core 走自己的推断 = 今日行为)。
78
92
  */
79
- export declare function buildModelCompat(...layers: ReadonlyArray<OpenAICompletionsCompat | undefined>): OpenAICompletionsCompat | undefined;
93
+ export declare function buildModelCompat<A extends CatalogApi>(api: A, ...layers: ReadonlyArray<CompatOf<A> | undefined>): CompatOf<A> | undefined;
80
94
  export {};
81
95
  //# sourceMappingURL=model-compat.d.ts.map
@@ -6,47 +6,75 @@ export const THINKING_FORMATS = Object.keys(THINKING_FORMAT_TABLE);
6
6
  export const isThinkingFormat = (w) => typeof w === "string" && THINKING_FORMATS.includes(w);
7
7
  const MAX_TOKENS_FIELD_TABLE = { max_tokens: true, max_completion_tokens: true };
8
8
  export const MAX_TOKENS_FIELDS = Object.keys(MAX_TOKENS_FIELD_TABLE);
9
+ const THINKING_MODE_TABLE = { budget: true, adaptive: true };
10
+ export const ANTHROPIC_THINKING_MODES = Object.keys(THINKING_MODE_TABLE);
11
+ const readBoolean = (v) => (typeof v === "boolean" ? v : undefined);
12
+ const readLadder = (v) => (Array.isArray(v) && v.every(isThinkingTier) ? v : undefined);
9
13
  const COMPAT_KEY_READERS = {
10
- supportsReasoningEffort: (v) => (typeof v === "boolean" ? v : undefined),
11
- requiresReasoningContentOnAssistantMessages: (v) => (typeof v === "boolean" ? v : undefined),
12
- maxTokensField: (v) => (typeof v === "string" && MAX_TOKENS_FIELDS.includes(v) ? v : undefined),
13
- thinkingFormat: (v) => (isThinkingFormat(v) ? v : undefined),
14
- reasoningEffortLevels: (v) => (Array.isArray(v) && v.every(isThinkingTier) ? v : undefined),
14
+ "openai-completions": {
15
+ supportsReasoningEffort: readBoolean,
16
+ requiresReasoningContentOnAssistantMessages: readBoolean,
17
+ maxTokensField: (v) => (typeof v === "string" && MAX_TOKENS_FIELDS.includes(v) ? v : undefined),
18
+ thinkingFormat: (v) => (isThinkingFormat(v) ? v : undefined),
19
+ reasoningEffortLevels: readLadder,
20
+ },
21
+ "anthropic-messages": {
22
+ thinkingMode: (v) => (typeof v === "string" && ANTHROPIC_THINKING_MODES.includes(v) ? v : undefined),
23
+ effortLevels: readLadder,
24
+ supportsTemperature: readBoolean,
25
+ contextManagement: readBoolean,
26
+ interleavedThinking: readBoolean,
27
+ },
15
28
  };
16
- export const MODEL_COMPAT_KEYS = Object.keys(COMPAT_KEY_READERS);
17
- const isCompatKey = (k) => MODEL_COMPAT_KEYS.includes(k);
18
- export function readModelCompat(v) {
29
+ export const MODEL_COMPAT_KEYS = {
30
+ "openai-completions": Object.keys(COMPAT_KEY_READERS["openai-completions"]),
31
+ "anthropic-messages": Object.keys(COMPAT_KEY_READERS["anthropic-messages"]),
32
+ };
33
+ const isKeyOf = (table, k) => Object.hasOwn(table, k);
34
+ export function readModelCompat(api, v) {
19
35
  if (v === undefined)
20
36
  return { ok: true };
21
37
  if (v === null || typeof v !== "object" || Array.isArray(v))
22
38
  return { ok: false, issue: `compat is ${v === null ? "null" : Array.isArray(v) ? "an array" : typeof v}, not an object of wire-compat keys` };
39
+ return COMPAT_LEGS[api].read(v);
40
+ }
41
+ function readCompatWith(api, readers, v) {
23
42
  const out = {};
24
43
  for (const [k, raw] of Object.entries(v)) {
25
- if (!isCompatKey(k))
26
- return { ok: false, issue: `unknown key ${JSON.stringify(k)} (valid: ${MODEL_COMPAT_KEYS.join(" | ")})` };
27
- const read = COMPAT_KEY_READERS[k](raw);
44
+ if (!isKeyOf(readers, k))
45
+ return { ok: false, issue: `unknown key ${JSON.stringify(k)} for an ${api} entry (valid: ${Object.keys(readers).join(" | ")})` };
46
+ const read = readers[k](raw);
28
47
  if (read === undefined)
29
- return { ok: false, issue: `key ${JSON.stringify(k)} does not fit the wire-compat shape` };
48
+ return { ok: false, issue: `key ${JSON.stringify(k)} does not fit the ${api} wire-compat shape` };
30
49
  out[k] = read;
31
50
  }
32
51
  return Object.keys(out).length > 0 ? { ok: true, compat: out } : { ok: true };
33
52
  }
34
- export function buildModelCompat(...layers) {
53
+ export function buildModelCompat(api, ...layers) {
54
+ return COMPAT_LEGS[api].build(layers);
55
+ }
56
+ const declaresKey = (v) => v !== undefined && !(Array.isArray(v) && v.length === 0);
57
+ function buildCompatWith(keys, layers) {
35
58
  const out = {};
36
59
  for (const layer of layers) {
37
60
  if (layer === undefined)
38
61
  continue;
39
- for (const k of MODEL_COMPAT_KEYS) {
40
- if (k in out)
62
+ for (const k of keys) {
63
+ if (Object.hasOwn(out, k) || !declaresKey(layer[k]))
41
64
  continue;
42
- const v = layer[k];
43
- if (v === undefined)
44
- continue;
45
- if (k === "reasoningEffortLevels" && Array.isArray(v) && v.length === 0)
46
- continue;
47
- out[k] = v;
65
+ out[k] = layer[k];
48
66
  }
49
67
  }
50
68
  return Object.keys(out).length > 0 ? out : undefined;
51
69
  }
70
+ const COMPAT_LEGS = {
71
+ "openai-completions": {
72
+ read: (v) => readCompatWith("openai-completions", COMPAT_KEY_READERS["openai-completions"], v),
73
+ build: (layers) => buildCompatWith(MODEL_COMPAT_KEYS["openai-completions"], layers),
74
+ },
75
+ "anthropic-messages": {
76
+ read: (v) => readCompatWith("anthropic-messages", COMPAT_KEY_READERS["anthropic-messages"], v),
77
+ build: (layers) => buildCompatWith(MODEL_COMPAT_KEYS["anthropic-messages"], layers),
78
+ },
79
+ };
52
80
  //# sourceMappingURL=model-compat.js.map
@@ -1,6 +1,7 @@
1
1
  import { type ModelEntryRefusalCode, type ModelPlaneRefusalCode, type ModelRefusalsSignal } from "@sema-agent/settings-schema";
2
2
  import { type DroppedCatalogEntry } from "./web-admin-client/read-warnings.js";
3
3
  import { type ModelTableLeg } from "./model-select.js";
4
+ import type { CandidateRejectionNote } from "./web-admin-client/candidate-gate.js";
4
5
  /**
5
6
  * 条目拒因码 → 本仓铸它的成因 —— **以码为键**([ref]):码闭集的属主是 settings-schema(`MODEL_ENTRY_REFUSAL_CODES`,6.2.0 起;此前本仓
6
7
  * 自持一份同名码表,撞名已消灭、零别名)。那边加一个条目码 ⇒ 本表缺键 ⇒ 本仓 tsc 红(只拿 `satisfies` 约束码值证明的是「子集」,
@@ -132,10 +133,17 @@ export declare function echoModelRef(ref: string): string;
132
133
  * 别名段(`(catalog entry …)`)的判断读原形:ref 与条目名逐字相同 ⇒ 不带,不因回显截短而误判成「另有条目」。
133
134
  */
134
135
  export declare function modelUnavailableMessage(field: string, requested: string, name: string, r: ModelEntryRefusal): string;
135
- /** 缺省模型不变量读的切面(`ServiceConfig` 与 `CrossInvariantView` 都结构满足)。 */
136
+ /** 缺省模型不变量读的切面(`ServiceConfig` 与 `CrossInvariantView` 都结构满足;可选成员缺席 = 没有被拒的候选)。 */
136
137
  export interface DefaultModelView {
137
138
  readonly models: Readonly<Record<string, unknown>>;
138
139
  readonly modelRefusals: Readonly<Record<string, ModelEntryRefusal>>;
140
+ /**
141
+ * [ref] ① —— **为何这张 env 表上没有目录**:候选判官整拒了最近一份候选(一个域都没应用),于是回落 env。值是判官交出的拒因列(`rejected.errors`,与 `config_candidate_rejected`
142
+ * 行体的 `errors` 同一份事实)经 `buildCandidateRejectionNotes` 投成的纯数据 —— 每个被拒文档一格:文档名 · 拒码 · 原因类词 · 文档路径(本地读腿)。**不含 `error` 原文**:
143
+ * 契约 / 读腿的原句可能点名链接指向的目标路径等操作数,只留在 warn 行(那里已过产出边界脱敏);句子函数不读日志、不读原句、不自铸第二份。
144
+ * 缺席 / 空 = 没有被拒的候选(纯 env 部署、候选被收下、dry-run)⇒ 拒因句逐字不变。只有 `env` 腿的句子读它(`catalog` 腿说的是目录候选自己没有缺省,与候选被整拒无关)。
145
+ */
146
+ readonly candidateRejectionNotes?: readonly CandidateRejectionNote[];
139
147
  }
140
148
  /**
141
149
  * 🔴 [ref] —— **这张模型表有没有一只缺省模型**(`models.default`)。`undefined` = 有。
@@ -146,6 +154,8 @@ export interface DefaultModelView {
146
154
  *
147
155
  * 拒因一句:码 + 这条腿上**真实**的出路 + 若目录在场但每条都不可用,点名它们与各自的码。env 腿句首保留 `MODEL_ID is required`
148
156
  * 这个既有的可 grep 片段(壳与运维脚本认它);目录腿不提 `MODEL_ID`(见 {@link ModelTableLeg})。
157
+ * env 腿若是因「候选被判官整拒」才回落到这张表({@link DefaultModelView.candidateRejectionNotes}),同一行再追加「回落原因」:被拒的文档名 + 拒码 + 原因类词 + 文档路径 ——
158
+ * 不带配置值、不带链接指向的目标路径、不抄任何 `error` 原文;只追加,句首的 grep 锚不动,没有被拒候选时整句逐字不变。
149
159
  */
150
160
  export declare function defaultModelRefusal(view: DefaultModelView, leg: ModelTableLeg): string | undefined;
151
161
  /** 一个被铸出的被拒名字:`name` = 被拒条目的名字,`target` = 增广把它指向的那条条目,`via` = 它是以什么身份被铸出的。 */