@sema-agent/server 7.133.0 → 7.135.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 +221 -0
  2. package/README.md +2 -2
  3. package/README.zh-CN.md +2 -2
  4. package/USAGE.md +222 -36
  5. package/deploy/sema-up/README.md +16 -0
  6. package/deploy/sema-up/chart/Chart.yaml +1 -1
  7. package/deploy/sema-up/chart/templates/NOTES.txt +15 -0
  8. package/deploy/sema-up/chart/templates/_helpers.tpl +129 -0
  9. package/deploy/sema-up/chart/templates/sealed-key.yaml +24 -0
  10. package/deploy/sema-up/chart/templates/server-v4pro.yaml +14 -0
  11. package/deploy/sema-up/chart/templates/server.yaml +14 -0
  12. package/deploy/sema-up/chart/values-full-single.yaml +5 -1
  13. package/deploy/sema-up/chart/values.yaml +34 -0
  14. package/dist/adoption/plan.d.ts +1 -1
  15. package/dist/approval-ask-audit-store.d.ts +25 -25
  16. package/dist/approval-ask-machine.d.ts +2 -2
  17. package/dist/approval-card.d.ts +66 -154
  18. package/dist/approval-card.js +33 -52
  19. package/dist/approval-content-kind.d.ts +26 -6
  20. package/dist/approval-content-kind.js +23 -3
  21. package/dist/approval-deny-reasons.d.ts +1 -1
  22. package/dist/approval-gate-currency.d.ts +91 -0
  23. package/dist/approval-gate-currency.js +120 -0
  24. package/dist/approval-hmac.d.ts +7 -7
  25. package/dist/approval-policy-settlement.d.ts +2 -2
  26. package/dist/approval-reconciler.d.ts +3 -3
  27. package/dist/approval.d.ts +14 -8
  28. package/dist/approval.js +35 -16
  29. package/dist/auth-bridge.d.ts +1 -1
  30. package/dist/auto-mode-face.d.ts +4 -4
  31. package/dist/background-session-reap.d.ts +2 -2
  32. package/dist/bake-runner/main.d.ts +2 -2
  33. package/dist/bake-runner/runner.d.ts +4 -4
  34. package/dist/bench/s1/live-deps.d.ts +1 -1
  35. package/dist/bench/s1/run-firm.d.ts +1 -1
  36. package/dist/boot/coordinators.d.ts +7 -2
  37. package/dist/boot/coordinators.js +8 -5
  38. package/dist/boot/deferred-sandbox-path-env.d.ts +0 -6
  39. package/dist/boot/deferred-sandbox-path-env.js +0 -5
  40. package/dist/boot/engine-lease.d.ts +5 -5
  41. package/dist/boot/execution-env.d.ts +16 -15
  42. package/dist/boot/execution-env.js +19 -21
  43. package/dist/boot/fatal-exit.d.ts +2 -2
  44. package/dist/boot/late-binds.d.ts +1 -1
  45. package/dist/boot/leader.d.ts +2 -0
  46. package/dist/boot/leader.js +2 -1
  47. package/dist/boot/memory-boundary.d.ts +2 -2
  48. package/dist/boot/memory-consolidation.d.ts +15 -15
  49. package/dist/boot/parked-revive-gate.d.ts +3 -3
  50. package/dist/boot/parked-revive-gate.js +3 -2
  51. package/dist/boot/read-deny-anchor-audit.js +2 -2
  52. package/dist/boot/reapers.d.ts +4 -4
  53. package/dist/boot/resolve-spec.d.ts +1 -1
  54. package/dist/boot/resolve-spec.js +28 -24
  55. package/dist/boot/runner-deps.d.ts +29 -16
  56. package/dist/boot/runner-deps.js +12 -2
  57. package/dist/boot/session-faces.d.ts +3 -3
  58. package/dist/boot/session-faces.js +11 -30
  59. package/dist/boot/shutdown.d.ts +5 -5
  60. package/dist/boot/side-query-lane.d.ts +2 -2
  61. package/dist/boot/stage-05-execution-env.js +4 -4
  62. package/dist/boot/stage-06-runners.d.ts +4 -3
  63. package/dist/boot/stage-06-runners.js +15 -4
  64. package/dist/boot/stage-07-capability-layer.d.ts +2 -1
  65. package/dist/boot/stage-08-reapers.d.ts +2 -1
  66. package/dist/boot/stage-09-leader.d.ts +2 -1
  67. package/dist/boot/stage-09-leader.js +2 -2
  68. package/dist/boot/stage-10-http-server.d.ts +2 -1
  69. package/dist/boot/stage-10-http-server.js +2 -1
  70. package/dist/boot/stores.d.ts +8 -0
  71. package/dist/boot/stores.js +10 -13
  72. package/dist/boot/web-admin.d.ts +21 -15
  73. package/dist/boot/web-admin.js +16 -12
  74. package/dist/boot/workflow-orchestration.js +2 -9
  75. package/dist/brain.d.ts +11 -11
  76. package/dist/budget.d.ts +4 -4
  77. package/dist/budget.js +5 -1
  78. package/dist/caller-text-echo.d.ts +2 -0
  79. package/dist/caller-text-echo.js +2 -1
  80. package/dist/canonical-json.d.ts +2 -41
  81. package/dist/canonical-json.js +2 -13
  82. package/dist/capabilities/approvals-push.d.ts +4 -4
  83. package/dist/capabilities/builtin-tools.d.ts +5 -5
  84. package/dist/capabilities/center-plugins.d.ts +5 -5
  85. package/dist/capabilities/center-plugins.js +1 -1
  86. package/dist/capabilities/center-prompts.d.ts +1 -1
  87. package/dist/capabilities/center-wiring.d.ts +1 -1
  88. package/dist/capabilities/composite-members.d.ts +2 -2
  89. package/dist/capabilities/composite-members.js +1 -1
  90. package/dist/capabilities/execution-lane.d.ts +5 -5
  91. package/dist/capabilities/execution-lane.js +2 -2
  92. package/dist/capabilities/hands-lane.d.ts +5 -5
  93. package/dist/capabilities/mcp-probe.d.ts +10 -7
  94. package/dist/capabilities/mcp-probe.js +2 -2
  95. package/dist/capabilities/sandbox-file-send.d.ts +1 -18
  96. package/dist/capabilities/sandbox-file-send.js +0 -7
  97. package/dist/capabilities/scenarios.d.ts +28 -10
  98. package/dist/capabilities/scenarios.js +15 -5
  99. package/dist/capabilities/send-user-file-tool.d.ts +1 -1
  100. package/dist/capabilities/skills.d.ts +31 -12
  101. package/dist/capabilities/skills.js +23 -17
  102. package/dist/capabilities/tool-defer.d.ts +1 -1
  103. package/dist/capability-facts.d.ts +27 -24
  104. package/dist/capability-facts.js +18 -20
  105. package/dist/center-config-tier.d.ts +1 -1
  106. package/dist/center-credential.d.ts +4 -4
  107. package/dist/checkpoint-ctx-seal-m28.d.ts +42 -0
  108. package/dist/checkpoint-ctx-seal-m28.js +19 -0
  109. package/dist/checkpoint-identity.d.ts +5 -0
  110. package/dist/checkpoint-identity.js +14 -0
  111. package/dist/config-catalog.d.ts +12 -12
  112. package/dist/config-invariants.d.ts +4 -4
  113. package/dist/config-invariants.js +3 -2
  114. package/dist/config-lkg.d.ts +1 -1
  115. package/dist/config-provider.d.ts +13 -13
  116. package/dist/config-provider.js +2 -1
  117. package/dist/config-types.d.ts +83 -83
  118. package/dist/config.d.ts +26 -24
  119. package/dist/config.js +12 -10
  120. package/dist/cross-session-settings.d.ts +1 -1
  121. package/dist/delegated-session-owner.d.ts +16 -13
  122. package/dist/delegated-session-owner.js +9 -10
  123. package/dist/deployment-governance.d.ts +16 -16
  124. package/dist/deployment-shape.d.ts +127 -0
  125. package/dist/deployment-shape.js +72 -0
  126. package/dist/device-store.d.ts +1 -1
  127. package/dist/device-ws-hub.d.ts +1 -1
  128. package/dist/egress-redirect.d.ts +1 -1
  129. package/dist/entry-mode-clamp-notice.d.ts +2 -2
  130. package/dist/env-facts.d.ts +10 -9
  131. package/dist/env-facts.js +1 -1
  132. package/dist/env-name-allowlist-knobs.d.ts +5 -5
  133. package/dist/exec-bounds.d.ts +2 -2
  134. package/dist/execution-lane-caps.d.ts +31 -43
  135. package/dist/execution-lane-caps.js +0 -13
  136. package/dist/field-conflict.d.ts +2 -1
  137. package/dist/field-conflict.js +1 -0
  138. package/dist/file-history-capture.d.ts +9 -9
  139. package/dist/file-history-disclosure.d.ts +50 -9
  140. package/dist/file-history-disclosure.js +8 -13
  141. package/dist/fleet/drain-entry.d.ts +2 -2
  142. package/dist/fleet/fleet-bus.d.ts +26 -14
  143. package/dist/fleet/fleet-bus.js +6 -5
  144. package/dist/fleet/fleet-reconciler.d.ts +9 -9
  145. package/dist/fleet/subagent-tail-bus.d.ts +4 -4
  146. package/dist/fleet-client.d.ts +13 -13
  147. package/dist/fleet-lease.d.ts +16 -16
  148. package/dist/governance-http-status.d.ts +2 -2
  149. package/dist/hooks/hook-llm.d.ts +7 -7
  150. package/dist/hooks/hook-runner.d.ts +57 -30
  151. package/dist/hooks/hook-runner.js +38 -20
  152. package/dist/host-decision.d.ts +5 -5
  153. package/dist/host-lsp-manager.d.ts +5 -5
  154. package/dist/hosted-posture.d.ts +23 -13
  155. package/dist/hosted-posture.js +4 -9
  156. package/dist/http/admission.d.ts +2 -2
  157. package/dist/http/admission.js +28 -5
  158. package/dist/http/approval-sweeps.d.ts +1 -1
  159. package/dist/http/approval-sweeps.js +5 -2
  160. package/dist/http/checkpoint-ctx.d.ts +183 -2
  161. package/dist/http/checkpoint-ctx.js +197 -2
  162. package/dist/http/dispatch.d.ts +3 -3
  163. package/dist/http/dispatch.js +3 -3
  164. package/dist/http/durable-run-leg.js +7 -5
  165. package/dist/http/idempotency.d.ts +4 -4
  166. package/dist/http/idempotency.js +2 -2
  167. package/dist/http/mcp-dial-deadline.d.ts +7 -5
  168. package/dist/http/memory-compliance-failure-reply.d.ts +4 -4
  169. package/dist/http/owner-access.d.ts +4 -6
  170. package/dist/http/owner-access.js +1 -1
  171. package/dist/http/principal-gate.d.ts +39 -13
  172. package/dist/http/principal-gate.js +30 -6
  173. package/dist/http/readiness.d.ts +1 -1
  174. package/dist/http/refusal-body.d.ts +12 -0
  175. package/dist/http/refusal-body.js +11 -0
  176. package/dist/http/request-guards.d.ts +4 -13
  177. package/dist/http/request-guards.js +4 -17
  178. package/dist/http/resume-ctx-read.d.ts +53 -6
  179. package/dist/http/resume-ctx-read.js +26 -3
  180. package/dist/http/resume-legs.d.ts +5 -4
  181. package/dist/http/resume-legs.js +47 -29
  182. package/dist/http/route-ctx.d.ts +29 -38
  183. package/dist/http/route-table.d.ts +9 -9
  184. package/dist/http/routes/agents-roster.d.ts +1 -1
  185. package/dist/http/routes/agents-roster.js +2 -3
  186. package/dist/http/routes/approvals-assistant.d.ts +5 -5
  187. package/dist/http/routes/approvals-assistant.js +91 -17
  188. package/dist/http/routes/background.d.ts +3 -3
  189. package/dist/http/routes/background.js +2 -2
  190. package/dist/http/routes/capabilities.d.ts +1 -1
  191. package/dist/http/routes/capabilities.js +16 -8
  192. package/dist/http/routes/config-catalog.d.ts +1 -1
  193. package/dist/http/routes/devices.d.ts +1 -1
  194. package/dist/http/routes/diagnostics.d.ts +6 -6
  195. package/dist/http/routes/diagnostics.js +1 -1
  196. package/dist/http/routes/fleet.d.ts +1 -1
  197. package/dist/http/routes/fleet.js +5 -4
  198. package/dist/http/routes/mcp-reconnect.d.ts +4 -4
  199. package/dist/http/routes/mcp-reconnect.js +3 -3
  200. package/dist/http/routes/memory-consolidation.d.ts +1 -1
  201. package/dist/http/routes/memory-origin.d.ts +1 -1
  202. package/dist/http/routes/notify-wake.d.ts +1 -1
  203. package/dist/http/routes/notify-wake.js +2 -2
  204. package/dist/http/routes/rules.d.ts +1 -1
  205. package/dist/http/routes/rules.js +4 -4
  206. package/dist/http/routes/runs.js +44 -11
  207. package/dist/http/routes/session-sync.d.ts +3 -2
  208. package/dist/http/routes/session-sync.js +109 -62
  209. package/dist/http/routes/sessions-list.d.ts +1 -1
  210. package/dist/http/routes/sessions-list.js +4 -5
  211. package/dist/http/routes/sessions.js +34 -48
  212. package/dist/http/routes/tasks.d.ts +1 -1
  213. package/dist/http/routes/tasks.js +21 -16
  214. package/dist/http/routes/trace-usage.d.ts +1 -1
  215. package/dist/http/routes/trace-usage.js +7 -9
  216. package/dist/http/routes/workflows.d.ts +3 -0
  217. package/dist/http/routes/workflows.js +31 -28
  218. package/dist/http/send.d.ts +5 -5
  219. package/dist/http/server.d.ts +39 -33
  220. package/dist/http/server.js +5 -2
  221. package/dist/http/session-inherit-env.d.ts +3 -3
  222. package/dist/http/sse-lifecycle.d.ts +1 -1
  223. package/dist/http/sse-log.d.ts +2 -2
  224. package/dist/http/submit-ctx.d.ts +4 -3
  225. package/dist/http/submit-ctx.js +19 -3
  226. package/dist/http/sync-submit-body.d.ts +1 -1
  227. package/dist/http/verify-rounds.d.ts +1 -1
  228. package/dist/http/wire-types.d.ts +35 -24
  229. package/dist/index.d.ts +2 -0
  230. package/dist/index.js +1 -0
  231. package/dist/instruction-source-notice.d.ts +2 -2
  232. package/dist/key-resolver.d.ts +3 -3
  233. package/dist/lane-home-probe.d.ts +1 -1
  234. package/dist/leader/diffout.d.ts +1 -1
  235. package/dist/leader/diffup.d.ts +2 -2
  236. package/dist/leader/endpoint.d.ts +1 -1
  237. package/dist/leader/fanout.d.ts +1 -1
  238. package/dist/leader/leader.d.ts +4 -4
  239. package/dist/leader/merge.d.ts +3 -3
  240. package/dist/leader/repair-wire.d.ts +1 -1
  241. package/dist/leader/wire.d.ts +9 -5
  242. package/dist/leader/wire.js +8 -7
  243. package/dist/list-entry-display.d.ts +1 -1
  244. package/dist/lsp-evict.d.ts +1 -1
  245. package/dist/main.js +1 -1
  246. package/dist/mcp-assertion-header.d.ts +1 -1
  247. package/dist/memory-layer-legacy-lock.d.ts +1 -1
  248. package/dist/memory-operator-faces.d.ts +1 -1
  249. package/dist/memory-origin-fence.js +2 -2
  250. package/dist/memory-posture.js +4 -2
  251. package/dist/memory-project-layer.d.ts +1 -1
  252. package/dist/memory-scope.d.ts +19 -19
  253. package/dist/memory-store-refusal.d.ts +4 -4
  254. package/dist/model-compat.d.ts +1 -1
  255. package/dist/model-entry-headers.d.ts +2 -2
  256. package/dist/model-entry-refusal.d.ts +17 -17
  257. package/dist/model-provider.d.ts +10 -10
  258. package/dist/model-reach-scope.d.ts +1 -1
  259. package/dist/model-route-endpoint.d.ts +6 -6
  260. package/dist/model-route-url.d.ts +5 -5
  261. package/dist/model-select.d.ts +15 -6
  262. package/dist/model-select.js +5 -0
  263. package/dist/model-unreachable-notice.d.ts +3 -3
  264. package/dist/namespaced-rule-name.d.ts +15 -5
  265. package/dist/namespaced-rule-name.js +3 -2
  266. package/dist/observability/corrupt-read-seat.d.ts +9 -9
  267. package/dist/observability/cost-taxonomy.d.ts +1 -1
  268. package/dist/observability/err-text.d.ts +1 -1
  269. package/dist/observability/fail-open.d.ts +12 -8
  270. package/dist/observability/fail-open.js +12 -8
  271. package/dist/observability/metrics.d.ts +3 -3
  272. package/dist/observability/prompt-manifest.d.ts +19 -8
  273. package/dist/observability/prompt-manifest.js +9 -8
  274. package/dist/observability/run-terminal.d.ts +36 -36
  275. package/dist/observability/secret-env-scrub.d.ts +3 -3
  276. package/dist/observability/tool-trace.d.ts +1 -1
  277. package/dist/observability/tool-trace.js +8 -9
  278. package/dist/operator-ask.d.ts +4 -4
  279. package/dist/orchestration/workflow-agent-session-index.d.ts +3 -3
  280. package/dist/orchestration/workflow-completion-inbox.d.ts +20 -5
  281. package/dist/orchestration/workflow-completion-inbox.js +29 -7
  282. package/dist/orchestration/workflow-notify-journal.d.ts +43 -19
  283. package/dist/orchestration/workflow-notify-journal.js +17 -0
  284. package/dist/orchestration/workflow-park-decision.d.ts +1 -1
  285. package/dist/orchestration/workflow-park-decision.js +1 -0
  286. package/dist/outbound-dispatcher.d.ts +4 -4
  287. package/dist/parent-watch.d.ts +4 -4
  288. package/dist/parked-decide.d.ts +20 -20
  289. package/dist/parked-decide.js +8 -5
  290. package/dist/parked-revive-surface.d.ts +7 -7
  291. package/dist/parked-revive-surface.js +2 -3
  292. package/dist/peer-directory.d.ts +3 -3
  293. package/dist/peer-directory.js +1 -1
  294. package/dist/permission-rule-list.d.ts +10 -1
  295. package/dist/permission-rule-list.js +7 -5
  296. package/dist/permission-rule-vocab.d.ts +3 -25
  297. package/dist/permission-rule-vocab.js +0 -13
  298. package/dist/plugins/adoption-log-sql.d.ts +1 -1
  299. package/dist/plugins/approval-ask-store-file.d.ts +8 -1
  300. package/dist/plugins/approval-ask-store-file.js +6 -3
  301. package/dist/plugins/approval-ask-store-memory.d.ts +11 -7
  302. package/dist/plugins/approval-ask-store-memory.js +11 -7
  303. package/dist/plugins/approval-ask-store-sql.d.ts +34 -15
  304. package/dist/plugins/approval-ask-store-sql.js +18 -5
  305. package/dist/plugins/approval-exemption-store.d.ts +3 -3
  306. package/dist/plugins/approval-nonce-store.d.ts +3 -3
  307. package/dist/plugins/approval-payload-fingerprint.d.ts +14 -6
  308. package/dist/plugins/approval-payload-fingerprint.js +1 -1
  309. package/dist/plugins/background-agent-store-sql.d.ts +1 -1
  310. package/dist/plugins/background-shell-support.d.ts +2 -2
  311. package/dist/plugins/blob-backend.d.ts +1 -1
  312. package/dist/plugins/caching-session-store.d.ts +24 -33
  313. package/dist/plugins/caching-session-store.js +8 -19
  314. package/dist/plugins/checkpoint-index-columns.d.ts +81 -0
  315. package/dist/plugins/checkpoint-index-columns.js +62 -0
  316. package/dist/plugins/checkpoint-store-sql.d.ts +66 -67
  317. package/dist/plugins/checkpoint-store-sql.js +100 -103
  318. package/dist/plugins/device-store-sql.d.ts +7 -6
  319. package/dist/plugins/e2b-orphan-reclaim.d.ts +1 -1
  320. package/dist/plugins/ensure-schema-lock-policy.d.ts +1 -1
  321. package/dist/plugins/file-history-store-sql.d.ts +9 -7
  322. package/dist/plugins/file-history-store-sql.js +27 -15
  323. package/dist/plugins/file-run-store.d.ts +8 -8
  324. package/dist/plugins/fork-routing-session-store.d.ts +2 -2
  325. package/dist/plugins/fork-routing-session-store.js +1 -1
  326. package/dist/plugins/host-platform.d.ts +10 -10
  327. package/dist/plugins/image-bake-store-sql.d.ts +1 -1
  328. package/dist/plugins/image-index-sql.d.ts +1 -1
  329. package/dist/plugins/leader-run-store-sql.d.ts +1 -1
  330. package/dist/plugins/local-checkpoint-store.d.ts +23 -12
  331. package/dist/plugins/local-checkpoint-store.js +29 -4
  332. package/dist/plugins/local-session-store.d.ts +44 -45
  333. package/dist/plugins/local-session-store.js +42 -52
  334. package/dist/plugins/local-session-window.d.ts +12 -6
  335. package/dist/plugins/local-session-window.js +1 -17
  336. package/dist/plugins/mailbox-store-sql.d.ts +2 -2
  337. package/dist/plugins/memory-engine-pg.d.ts +1 -1
  338. package/dist/plugins/memory-run-store.d.ts +4 -4
  339. package/dist/plugins/memory-sync-store-pg.d.ts +3 -3
  340. package/dist/plugins/one-time-migrations.d.ts +76 -39
  341. package/dist/plugins/one-time-migrations.js +127 -34
  342. package/dist/plugins/outcome-ledger-sql.d.ts +1 -1
  343. package/dist/plugins/park-commit-watch.d.ts +3 -3
  344. package/dist/plugins/permission-rule-store-file.d.ts +5 -5
  345. package/dist/plugins/permission-rule-store-file.js +16 -19
  346. package/dist/plugins/permission-rule-store-sql.d.ts +38 -4
  347. package/dist/plugins/permission-rule-store-sql.js +74 -31
  348. package/dist/plugins/pg-cost-quota.d.ts +1 -1
  349. package/dist/plugins/pg-pool.d.ts +2 -2
  350. package/dist/plugins/pg-pool.js +5 -2
  351. package/dist/plugins/pg-rate-limiter.d.ts +1 -1
  352. package/dist/plugins/pg-session-storage.d.ts +9 -21
  353. package/dist/plugins/pg-session-storage.js +51 -42
  354. package/dist/plugins/remote-env-adb.d.ts +10 -10
  355. package/dist/plugins/remote-env-device.d.ts +22 -14
  356. package/dist/plugins/remote-env-device.js +28 -16
  357. package/dist/plugins/remote-env-e2b.d.ts +3 -3
  358. package/dist/plugins/remote-env-host.d.ts +16 -16
  359. package/dist/plugins/remote-env-k8s.d.ts +8 -8
  360. package/dist/plugins/remote-env-local-docker.d.ts +2 -2
  361. package/dist/plugins/remote-env-ssh.d.ts +4 -4
  362. package/dist/plugins/remote-scratchpad.d.ts +2 -3
  363. package/dist/plugins/remote-scratchpad.js +0 -4
  364. package/dist/plugins/remote-shell.d.ts +6 -6
  365. package/dist/plugins/retention-lane-store-sql.d.ts +4 -4
  366. package/dist/plugins/retention-store-sql.d.ts +4 -4
  367. package/dist/plugins/roster-store-sql.d.ts +1 -1
  368. package/dist/plugins/run-store-sql.d.ts +8 -8
  369. package/dist/plugins/schema-consistency.d.ts +2 -2
  370. package/dist/plugins/schema-ensure-legs.d.ts +3 -3
  371. package/dist/plugins/schema-indexes.d.ts +1 -1
  372. package/dist/plugins/schema-live-columns.d.ts +1 -1
  373. package/dist/plugins/session-event-payload.d.ts +4 -4
  374. package/dist/plugins/session-fork.d.ts +34 -0
  375. package/dist/plugins/session-fork.js +29 -0
  376. package/dist/plugins/session-ownership.d.ts +11 -0
  377. package/dist/plugins/session-ownership.js +11 -0
  378. package/dist/plugins/session-placement.d.ts +12 -14
  379. package/dist/plugins/session-placement.js +2 -15
  380. package/dist/plugins/session-policy-store-sql.d.ts +12 -12
  381. package/dist/plugins/session-store.d.ts +2 -2
  382. package/dist/plugins/session-store.js +2 -2
  383. package/dist/plugins/shared-memory-store-sql.d.ts +2 -2
  384. package/dist/plugins/sql-driver.d.ts +8 -8
  385. package/dist/plugins/sql-errors.d.ts +1 -1
  386. package/dist/plugins/sql-json-column.d.ts +21 -21
  387. package/dist/plugins/sql-row-helpers.d.ts +2 -2
  388. package/dist/plugins/store-backend.d.ts +17 -16
  389. package/dist/plugins/store-backend.js +3 -3
  390. package/dist/plugins/store-contracts.d.ts +21 -21
  391. package/dist/plugins/task-attachment-store.d.ts +2 -2
  392. package/dist/plugins/task-list-store-sql.d.ts +1 -1
  393. package/dist/plugins/tidb-pool.d.ts +2 -2
  394. package/dist/plugins/tidb-pool.js +9 -2
  395. package/dist/plugins/tidb-session-store.d.ts +17 -27
  396. package/dist/plugins/tidb-session-store.js +52 -42
  397. package/dist/plugins/tool-result-store-sql.d.ts +1 -1
  398. package/dist/plugins/usage-window-store-sql.d.ts +3 -3
  399. package/dist/plugins/user-input-ledger-file.d.ts +1 -1
  400. package/dist/plugins/user-input-ledger-sql.d.ts +3 -3
  401. package/dist/plugins/web-search.d.ts +19 -5
  402. package/dist/plugins/web-search.js +19 -4
  403. package/dist/{orchestration/workflow-journal-entry.d.ts → plugins/workflow-journal-payload.d.ts} +23 -32
  404. package/dist/plugins/workflow-journal-payload.js +32 -0
  405. package/dist/plugins/workflow-journal-store-sql.d.ts +28 -14
  406. package/dist/plugins/workflow-journal-store-sql.js +34 -15
  407. package/dist/plugins/workflow-run-store-sql.d.ts +4 -4
  408. package/dist/posture-source.d.ts +11 -11
  409. package/dist/principal-jwt.d.ts +6 -6
  410. package/dist/project-identity.d.ts +3 -3
  411. package/dist/project-memory.d.ts +4 -4
  412. package/dist/read-face-posture.d.ts +7 -7
  413. package/dist/request-key-closure.d.ts +1 -1
  414. package/dist/request-key-closure.js +1 -1
  415. package/dist/request-tool-axes.d.ts +12 -0
  416. package/dist/request-tool-axes.js +20 -0
  417. package/dist/request-value-closure.d.ts +15 -8
  418. package/dist/request-value-closure.js +2 -0
  419. package/dist/router/route-orchestration.d.ts +11 -16
  420. package/dist/router/route-orchestration.js +2 -12
  421. package/dist/rule-entry-list.d.ts +8 -7
  422. package/dist/rule-entry-list.js +2 -9
  423. package/dist/rules-consent.d.ts +6 -6
  424. package/dist/rules-consent.js +2 -0
  425. package/dist/run-cancel-context.d.ts +5 -5
  426. package/dist/run-local.d.ts +10 -10
  427. package/dist/run-local.js +1 -0
  428. package/dist/runs.d.ts +15 -12
  429. package/dist/runs.js +19 -4
  430. package/dist/runtime-caps-resolver.d.ts +6 -6
  431. package/dist/runtime-governance.d.ts +9 -9
  432. package/dist/sandbox-pkg-source.d.ts +9 -31
  433. package/dist/sandbox-pkg-source.js +14 -8
  434. package/dist/sealed-key.d.ts +34 -2
  435. package/dist/sealed-key.js +55 -1
  436. package/dist/security.d.ts +31 -32
  437. package/dist/security.js +12 -9
  438. package/dist/server-secret-env.d.ts +10 -10
  439. package/dist/session-children-retire.d.ts +1 -1
  440. package/dist/session-error-wire.d.ts +19 -12
  441. package/dist/session-error-wire.js +4 -1
  442. package/dist/session-incarnation.d.ts +52 -35
  443. package/dist/session-incarnation.js +23 -8
  444. package/dist/session-policy-wire.d.ts +27 -5
  445. package/dist/session-policy-wire.js +15 -1
  446. package/dist/session-records-skipped-notice.d.ts +1 -1
  447. package/dist/session-sync-kernel.d.ts +38 -11
  448. package/dist/session-sync-kernel.js +10 -0
  449. package/dist/session-sync.d.ts +49 -6
  450. package/dist/session-sync.js +52 -10
  451. package/dist/session-titler.d.ts +7 -6
  452. package/dist/session-titler.js +8 -13
  453. package/dist/session-watch.d.ts +3 -3
  454. package/dist/session-watch.js +4 -4
  455. package/dist/sighup-idle.d.ts +2 -2
  456. package/dist/spec-fields.d.ts +4 -4
  457. package/dist/sql-engine-posture.d.ts +3 -3
  458. package/dist/store-posture.d.ts +2 -2
  459. package/dist/stored-request-tool-axes-m19.d.ts +1 -1
  460. package/dist/task-a2a.d.ts +3 -1
  461. package/dist/task-a2a.js +38 -5
  462. package/dist/task-cwd.d.ts +7 -88
  463. package/dist/task-cwd.js +2 -15
  464. package/dist/task-mcp.d.ts +14 -10
  465. package/dist/task-mcp.js +39 -12
  466. package/dist/task-settings.d.ts +34 -18
  467. package/dist/task-settings.js +34 -4
  468. package/dist/task-workflow.d.ts +0 -24
  469. package/dist/task-workflow.js +2 -1
  470. package/dist/terminal.d.ts +5 -5
  471. package/dist/tighten-only-seats.d.ts +7 -6
  472. package/dist/tighten-only-seats.js +1 -1
  473. package/dist/tool-approval.d.ts +273 -228
  474. package/dist/tool-approval.js +125 -47
  475. package/dist/tool-rule-names.d.ts +7 -1
  476. package/dist/trace/core-keyset-guard.d.ts +15 -9
  477. package/dist/trace/engine-notice-wire.d.ts +5 -5
  478. package/dist/trace/engine-notice-wire.js +1 -0
  479. package/dist/trace/exit-seat.d.ts +40 -1
  480. package/dist/trace/exit-seat.js +46 -14
  481. package/dist/trace/ledger-events.d.ts +6 -4
  482. package/dist/trace/ledger-sink.d.ts +1 -1
  483. package/dist/trace/model-segment.d.ts +3 -3
  484. package/dist/trace/project.d.ts +65 -46
  485. package/dist/trace/project.js +49 -5
  486. package/dist/trace/redact.d.ts +44 -27
  487. package/dist/trace/redact.js +343 -73
  488. package/dist/trace/self-minted-wire.d.ts +39 -14
  489. package/dist/trace/self-minted-wire.js +9 -0
  490. package/dist/trace/sema-provenance.d.ts +1 -1
  491. package/dist/trace/task-notification-facets.d.ts +4 -4
  492. package/dist/trace/wire-projection-faces.d.ts +9 -3
  493. package/dist/trace/wire-projection-faces.js +7 -1
  494. package/dist/unattended-permission-mode.d.ts +5 -5
  495. package/dist/url-credential.d.ts +52 -0
  496. package/dist/url-credential.js +49 -0
  497. package/dist/url-refusal.d.ts +6 -2
  498. package/dist/url-refusal.js +8 -1
  499. package/dist/usage-analytics.d.ts +2 -2
  500. package/dist/user-input-ledger.d.ts +23 -23
  501. package/dist/web-admin-client/apply-effective.d.ts +5 -5
  502. package/dist/web-admin-client/apply-effective.js +2 -1
  503. package/dist/web-admin-client/apply-ledger.d.ts +2 -2
  504. package/dist/web-admin-client/center-request.d.ts +2 -2
  505. package/dist/web-admin-client/facade.d.ts +5 -5
  506. package/dist/web-admin-client/facade.js +1 -1
  507. package/dist/web-admin-client/hot-keys-registry.d.ts +2 -2
  508. package/dist/web-admin-client/http-client.d.ts +4 -4
  509. package/dist/web-admin-client/mcp-revocation.d.ts +1 -1
  510. package/dist/web-admin-client/pull-state.d.ts +1 -1
  511. package/dist/web-admin-client/read-face.d.ts +2 -2
  512. package/dist/web-admin-client/read-warnings.d.ts +5 -5
  513. package/dist/web-admin-client/restart-signal.d.ts +6 -6
  514. package/dist/web-admin-client/skills-mcp.d.ts +29 -4
  515. package/dist/web-admin-client/skills-mcp.js +31 -4
  516. package/dist/web-admin-client/types.d.ts +17 -10
  517. package/dist/workspace-space.d.ts +5 -3
  518. package/dist/write-protection.d.ts +2 -2
  519. package/package.json +4 -3
  520. package/scripts/drain-check-local.mjs +35 -2
  521. package/scripts/drain-check.mysql.sql +22 -2
  522. package/scripts/drain-check.pg.sql +22 -2
  523. package/skills/loop.md +1 -1
  524. package/dist/mcp-tool-faces.d.ts +0 -69
  525. package/dist/mcp-tool-faces.js +0 -104
  526. package/dist/orchestration/workflow-journal-entry.js +0 -27
@@ -63,13 +63,13 @@ export declare const ENSURE_SCHEMA_LOCK = "sema_ensure_schema";
63
63
  * lock row — which both exhausts TiDB's "pessimistic lock retry limit" (surfacing as a thrown error) AND starves the
64
64
  * app's OWN `SELECT … FOR UPDATE` paths (image-bake admission/lease) of pessimistic-lock budget. So we acquire
65
65
  * NON-BLOCKING (GET_LOCK(name, 0) returns 0 immediately if held) and POLL with jittered backoff: one holder, the
66
- * rest sleeping (not blocked in-DB). Polls until acquired (7.83.0: never degrades to unserialized — the S-287
66
+ * rest sleeping (not blocked in-DB). Polls until acquired (7.83.0: never degrades to unserialized — the [ref]
67
67
  * `ADD INDEX` leg is not race-safe); a connection whose probe keeps throwing surfaces as a boot failure. */
68
68
  export declare function acquireEnsureSchemaLock(conn: PoolConnection, tag?: string): Promise<void>;
69
69
  /** Release {@link ENSURE_SCHEMA_LOCK} on `conn` (best-effort — the lock also auto-frees when the connection closes). */
70
70
  export declare function releaseEnsureSchemaLock(conn: PoolConnection, tag?: string): Promise<void>;
71
71
  /**
72
- * S-287:`SCHEMA_STATEMENTS` 建的那批表**在存量库上可能缺的索引**(声明与 PG 侧逐条共用同一份 —— 见
72
+ * [ref]:`SCHEMA_STATEMENTS` 建的那批表**在存量库上可能缺的索引**(声明与 PG 侧逐条共用同一份 —— 见
73
73
  * `plugins/ensure-index.ts` 头注与 `plugins/schema-indexes.ts`)。
74
74
  *
75
75
  * 组合口径与 `SCHEMA_STATEMENTS` **一一对应**:凡是它建的表,索引声明就进这个数组;它不建的表
@@ -286,6 +286,13 @@ export const SCHEMA_STATEMENTS = [
286
286
  -- NULL (a PRE-MIGRATION row, or a gate carrying no kind) ⇒ the LEGACY UNIFORM expire() path: the deny split
287
287
  -- is NEW-ROWS-ONLY. See tidb-checkpoint-store.ts reapExpired / listExpiredApprovalGates.
288
288
  gate_kind VARCHAR(32) NULL,
289
+ -- approval_card(core 7.55.0 #1468 P1 阶段二):门上的卡词**照存**(core checkpointIndexFacts(cp).approvalCard:TOOL_APPROVAL_CARDS 的词,或本引擎不认的串 ——
290
+ -- 留着,更晚的引擎读得对);非审批门 / 无卡 / 非串 = NULL。写口与一次性迁移 M29 的存量回填同一只派生(plugins/checkpoint-index-columns.ts)。
291
+ -- 读者:到期 facet 的生成谓词(由 core CARD_FACET_OVERRIDES + PAUSE_REGISTRY 生成;**不存 facet 本身** —— 存一份会在 core 改表那天陈旧)、运维队列行的卡。
292
+ -- 本仓不发 ALTER:存量库缺这一列 ⇒ 起服列册对账拒启并给 ADD COLUMN 句(持久数据:表里是在飞的停驻,不删表重建)。
293
+ -- 列型 TEXT 而不是定长 VARCHAR:引擎照存集外词,长度不由本仓定(191 字的集外词照存)。TEXT 自己的容量是 65,535 **字节**(plugins/checkpoint-index-columns.ts 的
294
+ -- APPROVAL_CARD_COLUMN_MAX_BYTES):引擎铸的卡词是闭集短词,超出只会是手改 / 外来写者的存量行 —— M29 回填对这样的行计数 + 点名跳过,不写、不挡起服。
295
+ approval_card TEXT NULL,
289
296
  -- bound_input_hash (design/80 D-1): the server-minted opaque boundInputHash, stamped at put() from
290
297
  -- pendingAction.boundInputHash, surfaced via listPending so the operator/portal can ECHO it on /decide (the
291
298
  -- D-1 TOCTOU binding guard is UNREACHABLE by the portal without it — it can then only do the unbound legacy
@@ -605,8 +612,8 @@ export const SCHEMA_STATEMENTS = [
605
612
  -- tidb-workflow-run-store.ts projects kind only when non-null and workflow-completion-inbox.ts routes
606
613
  -- kind === "task_notification" vs everything-else. Do NOT "tidy" this into NOT NULL DEFAULT.
607
614
  kind VARCHAR(24) NULL,
608
- -- payload: bounded + redacted JSON extras (task_type / result / …) for the task_notification family.
609
- -- NULL for legacy / plain workflow_complete rows.
615
+ -- payload: bounded + redacted JSON extras of the entry's kind. task_notification: task_type / result / …;
616
+ -- workflow_complete: at most {"completionId": …} (the engine's own correlation id, verbatim; NULL when the engine minted none).
610
617
  payload TEXT NULL,
611
618
  PRIMARY KEY (session_id, run_id),
612
619
  UNIQUE KEY uq_wfinbox_seq (seq),
@@ -8,9 +8,9 @@
8
8
  * on acquire (core's F1).
9
9
  *
10
10
  * Persistence only. **Tenant authorization (who may wake which session) lives in the service layer**
11
- * (`src/security.ts`), which uses `ownerOf` / `register` below. The store does not infer identity.
11
+ * (`src/security.ts`), which uses `headOf` (the one by-id read of a row) / `register` below. The store does not infer identity.
12
12
  */
13
- import { type AcquiredSession, type PlacedSessionRow, type SessionPlacementRecord, type SessionStore, type SessionTreeEntry } from "@sema-agent/core";
13
+ import { type AcquiredSession, type PlacedSessionRow, type SessionHead, type SessionPlacementRecord, type SessionStore, type SessionTreeEntry } from "@sema-agent/core";
14
14
  import type { Pool } from "mysql2/promise";
15
15
  import { type InstructionSourceBaseline } from "../instruction-source-notice.js";
16
16
  import { type SessionFace } from "../session-incarnation.js";
@@ -45,21 +45,21 @@ export declare class TiDBSessionStore implements SessionStore {
45
45
  register(sessionId: string, owner: string | null): Promise<void>;
46
46
  /**
47
47
  * acquire 的建行(唯一一处):普通会话 ⇒ 无主(按 id 首建的既有读法);placed 会话 ⇒ 属主按委派继承律在**这一笔**里写入
48
- * (S-1770:根会话的属主,根行不在取父,都不在 ⇒ 孤行哨兵 + warn;属主 = 判断时见证到的,读来源 → 判 → INSERT —— 读法与顺序只住在
48
+ * ([ref]:根会话的属主,根行不在取父,都不在 ⇒ 孤行哨兵 + warn;属主 = 判断时见证到的,读来源 → 判 → INSERT —— 读法与顺序只住在
49
49
  * `delegated-session-owner.ts` 的 `createPlacedSessionRow`,本店只交既有读写口,PG 孪生同调)。
50
50
  */
51
51
  private createOnAcquire;
52
52
  /**
53
- * S-1770 委派继承律的**认领口**:这只会话的那一位住客(判断时读到的化身)仍是无主的 placed 行 ⇒ 写 `owner`,返回是否写成
53
+ * [ref] 委派继承律的**认领口**:这只会话的那一位住客(判断时读到的化身)仍是无主的 placed 行 ⇒ 写 `owner`,返回是否写成
54
54
  * (句 = `CLAIM_OWNERLESS_PLACED_SQL`,只 CAS 子行自己,与停驻挂点 / M23 同一只;规则在 `delegated-session-owner.ts`)。普通会话行不在射程(placed 判别位)。
55
55
  */
56
56
  claimOwnerless(sessionId: string, incarnation: string, owner: string): Promise<boolean>;
57
- /** 若干来源行的会话面(属主 + 化身)一次读回(委派继承律的来源读;本店没有的 id 不在表里;化身经与 {@link sessionFaceOf} 同一只解码,空 ⇒ 响亮拒)。 */
57
+ /** 若干来源行的会话面(属主 + 化身)一次读回(委派继承律的来源读;本店没有的 id 不在表里;活住客的投影 `sessionFaceFromRow`,空化身 ⇒ 响亮拒)。 */
58
58
  private sourceFaces;
59
59
  /** The one session_meta INSERT. Existing owner is never overwritten.
60
60
  * [ref]:`placement` 在场时与行同一条 INSERT 落六列;ON DUPLICATE 臂是 no-op ⇒ 已存在的行的元组
61
61
  * **永不被重写**(first-write 不可变,义务 5 的写侧半场)。
62
- * S-790:化身与属主同一条 first-write 律 —— 新行铸一只(`mintSessionIncarnation`),已存在的行 no-op 臂一个字节不动。 */
62
+ * [ref]:化身与属主同一条 first-write 律 —— 新行铸一只(`mintSessionIncarnation`),已存在的行 no-op 臂一个字节不动。 */
63
63
  private insertMeta;
64
64
  /**
65
65
  * [ref] 义务 6 的廉价探针 —— 一行 PK SELECT:`undefined` = 普通会话或无此行。
@@ -78,25 +78,15 @@ export declare class TiDBSessionStore implements SessionStore {
78
78
  olderThanMs?: number;
79
79
  scope?: string;
80
80
  }): Promise<PlacedSessionRow[]>;
81
- /** Owner principal of a session, `null` if registered ownerless, `undefined` if no such session. */
82
- ownerOf(sessionId: string): Promise<string | null | undefined>;
83
- /** S-790:属主 + 化身**一次读**(单行单 SELECT —— 两次独立读在删除 / 重登记的缝里能拼出混世代组合)。`undefined` = 无此会话;
84
- * 行在而化身为空 ⇒ `SessionIncarnationMissingError`(响亮拒,判据唯一属主 `sessionFaceFromRow`)。 */
85
- sessionFaceOf(sessionId: string): Promise<SessionFace | undefined>;
86
- /** core `SessionStore.incarnationOf`(按 id 读住客,给没取会话的那一侧):{@link sessionFaceOf} 的化身那一半 —— 同一次读、同一只解码。 */
87
- incarnationOf(sessionId: string): Promise<string | undefined>;
81
+ /**
82
+ * core `SessionStore.headOf` —— 这一行的属主、住客、叶子,**一条 PK SELECT、一行**(两次独立读在删除 / 重登记的缝里能拼出混世代组合;
83
+ * 单行单读天然一致)。`undefined` = 无此会话。本店按 id 问这一行的**唯一**读口:授权口的属主、parked 两读的住客、SSE 探针的叶子、
84
+ * resume-at 的叶子都是它的投影(此前的 `ownerOf` / `sessionFaceOf` / `incarnationOf` / `getLeafId` / `getHead` 五只读全部并进来;规则见
85
+ * `session-incarnation.ts` 头注)。化身那一格经 `headFromRow` 的 `absent` 读法(空 ⇒ 住客未知);要一位活住客的读者经 `sessionFaceOfHead` 响亮拒空。
86
+ * 只读、不取会话、不上锁、绕过暖缓存 —— 跑到一半读也安全(写的安全是追加时的 CAS)。
87
+ */
88
+ headOf(sessionId: string): Promise<SessionHead | undefined>;
88
89
  touch(sessionId: string): Promise<void>;
89
- /** E18 — the session's current leaf `SessionTreeEntry.id` (`session_meta.leaf_id`, set transactionally on every
90
- * persist). A single SELECT, NO acquire/lock/CAS — safe to call mid-run (write-safety is the append-time CAS, not
91
- * an acquire lease) and cache-bypassing (the resume-at turn-capture reads it without touching the warm session).
92
- * Returns the leaf id, or null when the session has none / no such session. */
93
- getLeafId(sessionId: string): Promise<string | null>;
94
- /** [ref] 六轮复审:owner+leafId **单行原子快照**(SSE watch 探针的租户围栏读)——两独立 SELECT 在
95
- * delete/reclaim 缝里可拼出「旧 owner+新 leaf」混世代组合;单 SELECT 单行=天然一致。undefined=无此会话。 */
96
- getHead(sessionId: string): Promise<{
97
- owner: string | null;
98
- leafId: string | null;
99
- } | undefined>;
100
90
  /**
101
91
  * Durable history is retained; just drop any in-flight cache entry.
102
92
  *
@@ -164,12 +154,12 @@ export declare class TiDBSessionStore implements SessionStore {
164
154
  * writer order: `src/session-row.ts`). Returns whether this call set it. */
165
155
  setTitleIfNull(sessionId: string, title: string): Promise<boolean>;
166
156
  /**
167
- * S-690 —— 换源通告的基线读(一行 PK SELECT;列的三态读法见 `tidb-pool.ts` 的列注)。行不在 ⇒ 读作「没记过」
157
+ * [ref] —— 换源通告的基线读(一行 PK SELECT;列的三态读法见 `tidb-pool.ts` 的列注)。行不在 ⇒ 读作「没记过」
168
158
  * (loader 跑在 acquire 之后,行恒在;不在 = 被带外删了,没有下一 run 可比)。
169
159
  */
170
160
  readInstructionSource(sessionId: string): Promise<InstructionSourceBaseline>;
171
161
  /**
172
- * S-690 —— CAS 覆写基线(期望值 = 调用方读到的那一份;不符 ⇒ 0 行、不抛 —— 契约见 `InstructionSourceStore`)。
162
+ * [ref] —— CAS 覆写基线(期望值 = 调用方读到的那一份;不符 ⇒ 0 行、不抛 —— 契约见 `InstructionSourceStore`)。
173
163
  * **不**碰 `updated_at`(那是会话活动时刻,留存腿按它判龄;记基线不是一次会话活动)。
174
164
  * 两条基线查询都带每查询超时(`BASELINE_IO_DEADLINE_MS`,mysql2 的 `{sql, timeout}` 形):被行锁卡住的写由查询自己
175
165
  * 在期限内拒。⚠️ mysql2 的超时是客户端侧的 —— 拒之后那条连接仍被挂着的命令占到服务端结束(S-9 同形,如实披露)。
@@ -187,7 +177,7 @@ export declare class TiDBSessionStore implements SessionStore {
187
177
  * We instead SELECT the entire `session_event` log ordered by seq — every durable entry, compaction floor
188
178
  * bypassed — and re-seq it dense from 0 into the new session, ids/parents/payload byte-verbatim.
189
179
  */
190
- fork(sourceId: string, owner: string | null): Promise<string | null>;
180
+ fork(sourceId: string, owner?: string | null): Promise<string | null>;
191
181
  /**
192
182
  * 2c session-sync — EXPORT a session's full durable entry log for cross-backend migration. This is the
193
183
  * READ half of {@link fork}, surfaced as the core `SessionRepo.exportEntries` seam: the WHOLE `session_event` log,
@@ -1,16 +1,18 @@
1
- import { StoredSession, SessionError, uuidv7, validateEntriesForImport, leafIdAfterEntry } from "@sema-agent/core";
1
+ import { StoredSession, SessionError, uuidv7, validateEntriesForImport, leafIdAfterEntry, admitSessionPlacement } from "@sema-agent/core";
2
2
  import { TiDBSessionStorage } from "./tidb-session-storage.js";
3
3
  import { decodeSessionEventPayload } from "./session-event-payload.js";
4
4
  import { jsonColumnText } from "./sql-json-column.js";
5
5
  import { escapeLike } from "./sql-escape.js";
6
6
  import { BASELINE_IO_DEADLINE_MS, decodeInstructionSource, encodeInstructionSource } from "../instruction-source-notice.js";
7
7
  import { MANAGED_RETENTION } from "./retention-store-sql.js";
8
- import { carriedIncarnation, mintSessionIncarnation, sessionFaceFromRow } from "../session-incarnation.js";
8
+ import { carriedIncarnation, headFromRow, mintSessionIncarnation, sessionFaceFromRow } from "../session-incarnation.js";
9
9
  import { contentForkRelation, fastForwardSharedContentDiverged } from "../session-sync-content.js";
10
10
  import { CLAIM_OWNERLESS_PLACED_SQL, claimOwnerlessParams, createPlacedSessionRow } from "../delegated-session-owner.js";
11
11
  import { createLogger } from "../observability/logger.js";
12
- import { assertPlacementAdmission, LIST_PLACED_BATCH, PLACEMENT_SELECT_COLUMNS, placedRowFromRow, placementFromRow, placementInsertValues, SQL_SESSION_PLACEMENTS, } from "./session-placement.js";
13
- import { classifySyncRelationshipByIds, SyncConflictError, stagingIdFor, STAGING_ID_MARKER, STAGING_GC_GRACE_MS, } from "../session-sync-kernel.js";
12
+ import { placementCapabilityOf, LIST_PLACED_BATCH, PLACEMENT_SELECT_COLUMNS, placedRowFromRow, placementFromRow, placementInsertValues, SQL_SESSION_PLACEMENTS, } from "./session-placement.js";
13
+ import { classifySyncRelationshipByIds, SyncConflictError, StagedCommitOwnerChangedError, stagingIdFor, STAGING_ID_MARKER, STAGING_GC_GRACE_MS, } from "../session-sync-kernel.js";
14
+ import { assertFirstOwnerWritable, forkOwnerOf } from "./session-ownership.js";
15
+ import { forkCopyOf, forkPointOf } from "./session-fork.js";
14
16
  export class TiDBSessionStore {
15
17
  pool;
16
18
  retention = MANAGED_RETENTION;
@@ -32,7 +34,7 @@ export class TiDBSessionStore {
32
34
  const inflight = this.pending.get(sessionId);
33
35
  if (inflight) {
34
36
  const acquired = await inflight;
35
- assertPlacementAdmission(sessionId, await this.placementOf(sessionId), opts);
37
+ admitSessionPlacement(sessionId, await this.placementOf(sessionId), opts ?? {}, placementCapabilityOf(this));
36
38
  return acquired;
37
39
  }
38
40
  const p = this.load(sessionId, false, opts).finally(() => this.pending.delete(sessionId));
@@ -42,7 +44,7 @@ export class TiDBSessionStore {
42
44
  async load(sessionId, requireExisting = false, opts) {
43
45
  let storage = await TiDBSessionStorage.wake(this.pool, sessionId);
44
46
  if (storage) {
45
- assertPlacementAdmission(sessionId, (await storage.getMetadata()).placement, opts);
47
+ admitSessionPlacement(sessionId, (await storage.getMetadata()).placement, opts ?? {}, placementCapabilityOf(this));
46
48
  return { session: new StoredSession(storage), sessionId };
47
49
  }
48
50
  if (requireExisting)
@@ -52,10 +54,15 @@ export class TiDBSessionStore {
52
54
  if (!storage) {
53
55
  throw new SessionError("storage", `session ${sessionId} vanished between register and wake (a concurrent purge won the race) — retry`);
54
56
  }
55
- assertPlacementAdmission(sessionId, (await storage.getMetadata()).placement, opts);
57
+ admitSessionPlacement(sessionId, (await storage.getMetadata()).placement, opts ?? {}, placementCapabilityOf(this));
56
58
  return { session: new StoredSession(storage), sessionId };
57
59
  }
58
60
  async register(sessionId, owner) {
61
+ if (typeof owner !== "string" && owner !== null) {
62
+ if ((await this.headOf(sessionId)) !== undefined)
63
+ return;
64
+ assertFirstOwnerWritable(sessionId, owner);
65
+ }
59
66
  await this.insertMeta(sessionId, owner, undefined);
60
67
  }
61
68
  async createOnAcquire(sessionId, placement) {
@@ -64,7 +71,7 @@ export class TiDBSessionStore {
64
71
  await createPlacedSessionRow(sessionId, placement, {
65
72
  readFaces: (ids) => this.sourceFaces(ids),
66
73
  insert: (owner) => this.insertMeta(sessionId, owner, placement),
67
- readOwner: () => this.ownerOf(sessionId),
74
+ readOwner: async () => (await this.headOf(sessionId))?.owner,
68
75
  }, this.log);
69
76
  }
70
77
  async claimOwnerless(sessionId, incarnation, owner) {
@@ -101,20 +108,12 @@ export class TiDBSessionStore {
101
108
  const [rows] = await this.pool.query(sql, params);
102
109
  return rows.map((r) => placedRowFromRow(String(r.session_id), r, r.updated_at instanceof Date ? r.updated_at.getTime() : undefined));
103
110
  }
104
- async ownerOf(sessionId) {
105
- const [rows] = await this.pool.query("SELECT owner FROM session_meta WHERE session_id = ?", [sessionId]);
111
+ async headOf(sessionId) {
112
+ const [rows] = await this.pool.query("SELECT owner, incarnation, leaf_id FROM session_meta WHERE session_id = ?", [sessionId]);
106
113
  if (rows.length === 0)
107
114
  return undefined;
108
- return rows[0].owner ?? null;
109
- }
110
- async sessionFaceOf(sessionId) {
111
- const [rows] = await this.pool.query("SELECT owner, incarnation FROM session_meta WHERE session_id = ?", [sessionId]);
112
- if (rows.length === 0)
113
- return undefined;
114
- return sessionFaceFromRow(sessionId, rows[0].owner ?? null, rows[0].incarnation);
115
- }
116
- async incarnationOf(sessionId) {
117
- return (await this.sessionFaceOf(sessionId))?.incarnation;
115
+ const r = rows[0];
116
+ return headFromRow(sessionId, r.owner ?? null, r.incarnation, r.leaf_id ?? null);
118
117
  }
119
118
  async touch(sessionId) {
120
119
  await this.pool.query("UPDATE session_meta SET updated_at = ? WHERE session_id = ?", [
@@ -122,16 +121,6 @@ export class TiDBSessionStore {
122
121
  sessionId,
123
122
  ]);
124
123
  }
125
- async getLeafId(sessionId) {
126
- const [rows] = await this.pool.query("SELECT leaf_id FROM session_meta WHERE session_id = ?", [sessionId]);
127
- return rows[0] ? (rows[0].leaf_id ?? null) : null;
128
- }
129
- async getHead(sessionId) {
130
- const [rows] = await this.pool.query("SELECT owner, leaf_id FROM session_meta WHERE session_id = ?", [sessionId]);
131
- if (rows.length === 0)
132
- return undefined;
133
- return { owner: rows[0].owner ?? null, leafId: rows[0].leaf_id ?? null };
134
- }
135
124
  async release(sessionId) {
136
125
  this.pending.delete(sessionId);
137
126
  const placed = await this.placementOf(sessionId);
@@ -259,11 +248,17 @@ export class TiDBSessionStore {
259
248
  }
260
249
  }
261
250
  async fork(sourceId, owner) {
262
- const [metaRows] = await this.pool.query("SELECT leaf_id FROM session_meta WHERE session_id = ?", [sourceId]);
251
+ const [metaRows] = await this.pool.query("SELECT leaf_id, owner FROM session_meta WHERE session_id = ?", [sourceId]);
263
252
  if (!metaRows[0])
264
253
  return null;
265
254
  const leafId = metaRows[0].leaf_id ?? null;
266
- const [eventRows] = await this.pool.query(`SELECT entry_id, parent_id, type, ${jsonColumnText("tidb", "payload")}, ts FROM session_event WHERE session_id = ? ORDER BY seq ASC`, [sourceId]);
255
+ const forkOwner = forkOwnerOf(owner, metaRows[0].owner ?? null) ?? null;
256
+ const storage = await TiDBSessionStorage.wake(this.pool, sourceId);
257
+ if (storage === null)
258
+ return null;
259
+ const point = await forkPointOf(storage);
260
+ const [allRows] = await this.pool.query(`SELECT entry_id, parent_id, type, ${jsonColumnText("tidb", "payload")}, ts FROM session_event WHERE session_id = ? ORDER BY seq ASC`, [sourceId]);
261
+ const { rows: eventRows, leafId: forkLeafId } = forkCopyOf(allRows, leafId, point);
267
262
  const newId = uuidv7();
268
263
  const now = new Date();
269
264
  const conn = await this.pool.getConnection();
@@ -274,7 +269,7 @@ export class TiDBSessionStore {
274
269
  const payload = String(r.payload);
275
270
  await conn.query("INSERT INTO session_event (session_id, seq, entry_id, parent_id, type, payload, ts) VALUES (?,?,?,?,?,?,?)", [newId, seq, r.entry_id, r.parent_id ?? null, r.type, payload, r.ts]);
276
271
  }
277
- await conn.query("INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation) VALUES (?,?,?,?,?,?,?)", [newId, owner, now, now, leafId, eventRows.length, mintSessionIncarnation()]);
272
+ await conn.query("INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation) VALUES (?,?,?,?,?,?,?)", [newId, forkOwner, now, now, forkLeafId, eventRows.length, mintSessionIncarnation()]);
278
273
  await conn.commit();
279
274
  return newId;
280
275
  }
@@ -476,6 +471,23 @@ class TiDBStagingHandle {
476
471
  const conn = await this.pool.getConnection();
477
472
  try {
478
473
  await conn.beginTransaction();
474
+ const now = new Date();
475
+ const minted = mintSessionIncarnation();
476
+ if (opts.expectedOwner !== undefined) {
477
+ const [cas] = await conn.query("UPDATE session_meta SET leaf_seq = leaf_seq + 1 WHERE session_id = ? AND owner <=> ?", [this.realSessionId, opts.expectedOwner]);
478
+ if (cas.affectedRows !== 1) {
479
+ await conn.rollback();
480
+ throw new StagedCommitOwnerChangedError(this.realSessionId);
481
+ }
482
+ }
483
+ else {
484
+ await conn.query("INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation) VALUES (?,?,?,?,NULL,0,?) ON DUPLICATE KEY UPDATE session_id = session_id", [this.realSessionId, owner, now, now, minted]);
485
+ const [claimed] = await conn.query("SELECT incarnation FROM session_meta WHERE session_id = ? FOR UPDATE", [this.realSessionId]);
486
+ if (String(claimed[0]?.incarnation) !== minted) {
487
+ await conn.rollback();
488
+ throw new StagedCommitOwnerChangedError(this.realSessionId);
489
+ }
490
+ }
479
491
  const [stagedRows] = await conn.query("SELECT entry_id FROM session_event WHERE session_id = ? ORDER BY seq ASC FOR UPDATE", [this.stagingId]);
480
492
  const [dstRows] = await conn.query("SELECT entry_id FROM session_event WHERE session_id = ? ORDER BY seq ASC FOR UPDATE", [this.realSessionId]);
481
493
  const [dstMeta] = await conn.query("SELECT placement_kind FROM session_meta WHERE session_id = ?", [this.realSessionId]);
@@ -484,15 +496,15 @@ class TiDBStagingHandle {
484
496
  throw new SessionError("placement_refused", `session ${this.realSessionId} belongs to the ${String(dstMeta[0].placement_kind)} placement partition — a session-sync staged commit cannot overwrite a delegation transcript`);
485
497
  }
486
498
  const srcIds = stagedRows.map((r) => String(r.entry_id));
487
- const dstIds = dstMeta[0] ? dstRows.map((r) => String(r.entry_id)) : null;
499
+ const dstIds = opts.expectedOwner !== undefined ? dstRows.map((r) => String(r.entry_id)) : null;
488
500
  const rel = classifySyncRelationshipByIds(srcIds, dstIds);
489
- if ((rel.relation === "fork" || rel.relation === "stale") && opts?.resolution !== "overwrite-dst") {
501
+ if ((rel.relation === "fork" || rel.relation === "stale") && opts.resolution !== "overwrite-dst") {
490
502
  await conn.rollback();
491
503
  throw new SyncConflictError(this.realSessionId, rel);
492
504
  }
493
- if (rel.relation === "fast_forward" && opts?.resolution !== "overwrite-dst" && dstIds !== null && dstIds.length > 0) {
494
- const [dstFull] = await conn.query(`SELECT seq, ${jsonColumnText("tidb", "payload")} FROM session_event WHERE session_id = ? ORDER BY seq ASC`, [this.realSessionId]);
495
- const [stagedFull] = await conn.query(`SELECT entry_id, ${jsonColumnText("tidb", "payload")} FROM session_event WHERE session_id = ? ORDER BY seq ASC`, [this.stagingId]);
505
+ if (rel.relation === "fast_forward" && opts.resolution !== "overwrite-dst" && dstIds !== null && dstIds.length > 0) {
506
+ const [dstFull] = await conn.query(`SELECT seq, ${jsonColumnText("tidb", "payload")} FROM session_event WHERE session_id = ? ORDER BY seq ASC FOR UPDATE`, [this.realSessionId]);
507
+ const [stagedFull] = await conn.query(`SELECT entry_id, ${jsonColumnText("tidb", "payload")} FROM session_event WHERE session_id = ? ORDER BY seq ASC FOR UPDATE`, [this.stagingId]);
496
508
  const dstSet = new Set(dstIds);
497
509
  const dstEntries = dstFull.map((r) => decodeSessionEventPayload(r.payload, this.realSessionId, r.seq));
498
510
  const stagedShared = stagedFull
@@ -506,13 +518,11 @@ class TiDBStagingHandle {
506
518
  }
507
519
  await conn.query("DELETE FROM session_event WHERE session_id = ?", [this.realSessionId]);
508
520
  await conn.query("UPDATE session_event SET session_id = ? WHERE session_id = ?", [this.realSessionId, this.stagingId]);
509
- const [lastRow] = await conn.query(`SELECT ${jsonColumnText("tidb", "payload")} FROM session_event WHERE session_id = ? ORDER BY seq DESC LIMIT 1`, [this.realSessionId]);
521
+ const [lastRow] = await conn.query(`SELECT ${jsonColumnText("tidb", "payload")} FROM session_event WHERE session_id = ? ORDER BY seq DESC LIMIT 1 FOR UPDATE`, [this.realSessionId]);
510
522
  let leafId = null;
511
523
  if (lastRow[0])
512
524
  leafId = leafIdAfterEntry(decodeSessionEventPayload(lastRow[0].payload, this.realSessionId, "last staged row"));
513
- const now = new Date();
514
- await conn.query("INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation) VALUES (?,?,?,?,?,?,?) " +
515
- "ON DUPLICATE KEY UPDATE owner = VALUES(owner), updated_at = VALUES(updated_at), leaf_id = VALUES(leaf_id), leaf_seq = VALUES(leaf_seq)", [this.realSessionId, owner, now, now, leafId, srcIds.length, mintSessionIncarnation()]);
525
+ await conn.query("UPDATE session_meta SET owner = ?, updated_at = ?, leaf_id = ?, leaf_seq = ? WHERE session_id = ?", [owner, now, leafId, srcIds.length, this.realSessionId]);
516
526
  const [afterMeta] = await conn.query("SELECT placement_kind, owner, incarnation FROM session_meta WHERE session_id = ?", [this.realSessionId]);
517
527
  if (afterMeta[0]?.placement_kind != null) {
518
528
  await conn.rollback();
@@ -7,7 +7,7 @@ import { type IndexSpec } from "./ensure-index.js";
7
7
  * (LONGTEXT→TEXT, DATETIME(3)→TIMESTAMPTZ(3), inline KEY→separate CREATE INDEX). Disjoint from other stores'
8
8
  * tables, so a self-contained ensureSchema is safe (central pg-pool aggregation is done separately). */
9
9
  export declare const PG_TOOL_RESULT_SCHEMA: string[];
10
- /** S-287:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensureSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
10
+ /** [ref]:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensureSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
11
11
  export declare const TOOL_RESULT_INDEXES: readonly IndexSpec[];
12
12
  /** Idempotent schema apply for the tool_result table (for the integration test to call). */
13
13
  export declare function ensureSchema(pool: PgPool | PgPoolClient): Promise<void>;
@@ -8,10 +8,10 @@
8
8
  *
9
9
  * 并发正确性(本 store 的靶心;两副本同 key 并发 charge 绝不能丢账——丢账方向=治理窗漏放):
10
10
  * - **ensure-first + 行锁**(mailbox twin 正字先例,[ref] 复审靶1):事务内先幂等建空行
11
- * (形 A,S-127:MySQL `ON DUPLICATE KEY UPDATE <pk> = <pk>` / PG `ON CONFLICT DO NOTHING`)⇒
11
+ * (形 A,[ref]:MySQL `ON DUPLICATE KEY UPDATE <pk> = <pk>` / PG `ON CONFLICT DO NOTHING`)⇒
12
12
  * `SELECT … FOR UPDATE` 时行恒在,「无行 FOR UPDATE + INSERT」的并发死锁/dup 撞车形整个消掉。
13
13
  * MySQL 侧动词**不能**是 `INSERT IGNORE`:InnoDB 对重复键的 IGNORE 取 S 锁,随后的 FOR UPDATE 要升 X,
14
- * 两个并发 charge 各持一把 S 互等 ⇒ ER_LOCK_DEADLOCK(B-013);ON DUPLICATE 的重复键取的就是 X。
14
+ * 两个并发 charge 各持一把 S 互等 ⇒ ER_LOCK_DEADLOCK([ref]);ON DUPLICATE 的重复键取的就是 X。
15
15
  * - charge 频率低(core 只在任务进场/turn 边界/收尾 delta 提交),悲观锁简单正确,不用乐观 CAS。
16
16
  * - `read` 无锁单 SELECT(readUsageRecord 纯函数);行缺席 = EMPTY_USAGE_WINDOW_RECORD。
17
17
  * - record JSON 坏形(手工污染)= **fail-loud throw**:治理窗算错=计费面撒谎,不 fail-open。
@@ -29,7 +29,7 @@ import type { UsageWindow, UsageWindowReading, UsageWindowRecord, UsageWindowSto
29
29
  import { type JsonColumnShape } from "./sql-json-column.js";
30
30
  export declare const USAGE_WINDOW_TABLE = "usage_window";
31
31
  /**
32
- * `usage_window.record` 的**形读者**(S-550 车③a:本店既有的那一份深度判据逐字搬进来,一个字没改判)。
32
+ * `usage_window.record` 的**形读者**([ref] 车③a:本店既有的那一份深度判据逐字搬进来,一个字没改判)。
33
33
  *
34
34
  * 判据深到内层元素:非数值 tokens 参与累加会得到 `"0oops"` ⇒ `exhausted:false` ⇒ **超额账户被判未耗尽**
35
35
  * (与 core `FileUsageWindowStore` 的 validateSlots/validateBuckets 同轴)。
@@ -15,7 +15,7 @@ export declare class MemoryUserInputLedgerStore implements UserInputLedgerStore
15
15
  listOpen(after?: OpenScanCursor, limit?: number): Promise<OpenScanPage>;
16
16
  listCrashed(sessionId: string): Promise<UserInputAcceptance[]>;
17
17
  listUnannounced(sessionId: string, limit: number): Promise<UserInputAcceptance[]>;
18
- /** S-965:会话树删除 = 一行会话级墓碑(守卫:该会话此刻有行 ⇒ 落;否则零写、回 0)。写抛 ⇒ 原样抛(协调器据此不删会话本体)。 */
18
+ /** [ref]:会话树删除 = 一行会话级墓碑(守卫:该会话此刻有行 ⇒ 落;否则零写、回 0)。写抛 ⇒ 原样抛(协调器据此不删会话本体)。 */
19
19
  deleteBySession(sessionId: string): Promise<number>;
20
20
  }
21
21
  /** local 车道(File)孪生。 */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * S-928 用户输入受理账本的 **SQL** 孪生(单文件双方言,[ref] A12 收拢形;两条语句并排写死,方言差异显式)。
2
+ * [ref] 用户输入受理账本的 **SQL** 孪生(单文件双方言,[ref] A12 收拢形;两条语句并排写死,方言差异显式)。
3
3
  * 语义属主 = `src/user-input-ledger.ts`;File / Memory 两只在 `user-input-ledger-file.ts`。四只孪生吃同一组试剂盒断言
4
4
  * (`test/helpers/user-input-ledger-kit.ts`;本孪生的真双库腿在 `test/store-contract-kit-db-integration.test.ts`)。
5
5
  *
@@ -13,12 +13,12 @@
13
13
  * 无 owner / principal / scope 列(行随它挂靠的会话走 —— 收编形Ⅲ);`writer` 是受理进程的 `instanceId`(随进程消亡,不是租户轴)。
14
14
  * 行里不存输入正文(只有身份与时刻)。
15
15
  *
16
- * ## 会话树删除(S-965)
16
+ * ## 会话树删除([ref])
17
17
  * `deleteBySession` = `DELETE … WHERE session_id = ?`(真删行;File 孪生是一行会话级墓碑,同义)。两条删会话树的级联各有一臂:在线删除协调器
18
18
  * 经本动词;托管留存的事务化孪生(`retention-store-sql.ts` `purgeSessionTrees` ④)在**自己的事务**里对本表发同一只谓词(`session_id` 单键,
19
19
  * 多值集合按方言)—— 它不调店,理由见该文件顶注的布局裁定(一个事务 ⇒ 一条连接 ⇒ 一个属主)。谓词走 `(session_id, state, accepted_at_ms)` 索引的前缀。
20
20
  *
21
- * ## 读不出的行(S-969 L6):逐行跳过,游标按原始行推进
21
+ * ## 读不出的行([ref] L6):逐行跳过,游标按原始行推进
22
22
  * 三只读口都按 `state` 列取行(`= 'open'` / `= 'converged'`),所以 `state` 词表外的行任何读口都取不到;被取到的行上读不出的列 —— `input_kind`
23
23
  * 词表外(新版本写的输入族:滚动发布 / 回滚的混版窗)、收敛行缺 `state_at_ms` —— 由 {@link readRows} 逐行跳过 + 计 F 类 tag
24
24
  * `server.user-input-ledger.corrupt-record-skipped`(File 孪生重放坏行的同一只登记座),其余行照交。修前一行读不出 ⇒ 整页抛:收敛断点不前进
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Multi-provider, picked by `WEB_SEARCH_PROVIDER`:
7
7
  * - `brave` — Brave Web Search API (GET, `X-Subscription-Token` header); with `WEB_SEARCH_ENDPOINT` set to a
8
- * Brave-compatible gateway's full search URL (e.g. a self-hosted Nólë gateway, S-669) the same leg
8
+ * Brave-compatible gateway's full search URL (e.g. a self-hosted Nólë gateway, [ref]) the same leg
9
9
  * serves that backend — no new provider word, `capabilities.webSearch.backend` still reads `brave`
10
10
  * - `tavily` — Tavily Search API (POST, `Authorization: Bearer`, native include/exclude_domains)
11
11
  * - `searxng` — a self-hosted SearXNG instance (GET `?format=json`, no auth)
@@ -54,6 +54,7 @@
54
54
  * 验证搜索配对不对。挂哪儿(boot 期一次性 warn / `/health` 子字段 / 显式端点)未定 ——
55
55
  * 注意 boot 期探活会给每次启动加一次出网,多租/离线部署要能关。
56
56
  */
57
+ import { type UrlCredentialFacts } from "../url-credential.js";
57
58
  /**
58
59
  * Search providers this backend speaks —— **词表的唯一属主**(运行期与类型同一份)。
59
60
  * Absent `WEB_SEARCH_PROVIDER` ⇒ no backend ⇒ WebSearch is not assembled.
@@ -69,7 +70,7 @@
69
70
  export declare const WEB_SEARCH_PROVIDERS: readonly ["brave", "tavily", "searxng"];
70
71
  export type WebSearchProvider = (typeof WEB_SEARCH_PROVIDERS)[number];
71
72
  /**
72
- * S-382:`GET /v1/capabilities` 的 `webSearch` 位 —— **部署默认后端**的闭集自述。
73
+ * [ref]:`GET /v1/capabilities` 的 `webSearch` 位 —— **部署默认后端**的闭集自述。
73
74
  *
74
75
  * ## 病
75
76
  * 「这台 worker 的搜索走哪只后端」此前只在 operator 面可知(`GET /v1/config/catalog` 的
@@ -159,7 +160,7 @@ export declare function setWebSearchBadPayloadObserver(fn: ((provider: string) =
159
160
  /**
160
161
  * Build the `WebSearchConfig` (a `search` fn + `maxResults`) for `assembleFullBodyTools({ webSearch })`. The API key
161
162
  * stays captured in this closure — it is never surfaced to the model or the tool args. Every error a leg throws leaves
162
- * through {@link redactedBackendFailure} (S-716 ③).
163
+ * through {@link redactedBackendFailure} ([ref] ③).
163
164
  */
164
165
  export declare function createWebSearchBackend(cfg: WebSearchBackendConfig): WebSearchBackend;
165
166
  /**
@@ -195,7 +196,7 @@ export declare function webSearchConfigFromEnv(env?: NodeJS.ProcessEnv): WebSear
195
196
  * · `absent` —— 没带(或 `null`)⇒ 用部署后端;
196
197
  * · `honored` —— 每个字段形对,且 `provider` 点名了一只本部署会说的后端 ⇒ 这次调用用它;
197
198
  * · `malformed` —— 任一字段形错 ⇒ 受理面 400 `request.field_invalid`(`issue` 逐字点名字段)。
198
- * **`provider` 缺席或不在词表里也是形错**(S-199 主会话改判,codex 验修 V1 [high]):一段 `settings.webSearch` 就是
199
+ * **`provider` 缺席或不在词表里也是形错**([ref] 主会话改判,codex 验修 V1 [high]):一段 `settings.webSearch` 就是
199
200
  * 调用方在点名目的地(`endpoint` / `apiKey` 都挂在它点名的那只后端上),认不出就拒,不静默换成部署后端 —— 改判前
200
201
  * 这一形回落部署后端,`{provider:"searx", endpoint:<私有地址>}` 的查询于是发到了部署配的后端。env 腿的同一只
201
202
  * {@link isWebSearchProvider} 守卫对**部署**的词表外答「不装配」,那是部署自己的缺席,不是换别人的目的地。
@@ -210,9 +211,22 @@ export type RequestWebSearchVerdict = {
210
211
  } | {
211
212
  readonly kind: "honored";
212
213
  readonly config: WebSearchBackendConfig;
213
- } | {
214
+ }
215
+ /** `facts` = 拒体的机读位(`field` + `reason`;只有「endpoint 带凭据」这一族在场,与 MCP / A2A / http 钩子三座同一只铸点)。 */
216
+ | {
214
217
  readonly kind: "malformed";
215
218
  readonly issue: string;
219
+ readonly facts?: UrlCredentialFacts;
216
220
  };
217
221
  export declare function judgeRequestWebSearch(raw: unknown): RequestWebSearchVerdict;
222
+ /**
223
+ * **fresh 提交门**读的判决([ref],受理面 `admission.ts` 独有):{@link judgeRequestWebSearch}(装配点读的那一只,续跑重放也走)+ 一条只属于新提交的 ——
224
+ * 采纳下来的 `endpoint` 带凭据(userinfo 一形已在上面的判官里拒,句子不变;这里补凭据名参数:名字在日志脱敏器凭据名表里的 query / fragment 参数)⇒ `malformed`,
225
+ * 拒句说出路,机读位 `field` + `reason` 与 MCP / A2A / http 钩子三座同一只铸点。
226
+ *
227
+ * 为什么不并进 {@link judgeRequestWebSearch}:那一只被装配点读(续跑重放存量 body),在那里答 `malformed` 的后果是「这次调用不装配 WebSearch」(见 `capabilities/scenarios.ts`)——
228
+ * 升级前停驻的任务会悄悄卸载这个工具,比不拒更糟;已落盘的字节也不因拒而消失。与 MCP 条目门 / A2A 对端门 / hooks matcher 判据同一条 `fresh` 限定律。
229
+ * 部署 env 的 `WEB_SEARCH_ENDPOINT` 同理不判:那是运维的配置,不进任何请求的停驻 ctx。
230
+ */
231
+ export declare function judgeFreshRequestWebSearch(raw: unknown): RequestWebSearchVerdict;
218
232
  //# sourceMappingURL=web-search.d.ts.map
@@ -2,6 +2,7 @@ import { validateHeaderValue } from "node:http";
2
2
  import { createSearxngSearchBackend } from "@sema-agent/core";
3
3
  import { isHierarchicalUrl } from "@sema-agent/settings-schema";
4
4
  import { redactSecrets } from "../trace/redact.js";
5
+ import { buildRequestUrlCredentialRefusal, findUrlCredential, findUrlUserinfo, urlCredentialFacts } from "../url-credential.js";
5
6
  export const WEB_SEARCH_PROVIDERS = ["brave", "tavily", "searxng"];
6
7
  function isWebSearchProvider(word) {
7
8
  return WEB_SEARCH_PROVIDERS.includes(word);
@@ -201,8 +202,8 @@ function judgeEndpoint(raw) {
201
202
  return ABSENT;
202
203
  if (!isHierarchicalUrl(raw))
203
204
  return { ok: false, issue: ENDPOINT_FORM };
204
- const url = new URL(raw);
205
- return url.username !== "" || url.password !== "" ? { ok: false, issue: ENDPOINT_USERINFO } : { ok: true, value: raw };
205
+ const credential = findUrlUserinfo(raw);
206
+ return credential !== undefined ? { ok: false, issue: ENDPOINT_USERINFO, credential } : { ok: true, value: raw };
206
207
  }
207
208
  const COUNT_FORM = "must be a number ≥ 1";
208
209
  function judgeCount(raw) {
@@ -320,8 +321,10 @@ export function judgeRequestWebSearch(raw) {
320
321
  maxResults: judgeCount(s.maxResults),
321
322
  };
322
323
  for (const [field, j] of Object.entries(fields)) {
323
- if (!j.ok)
324
- return { kind: "malformed", issue: `settings.webSearch.${field} ${j.issue}` };
324
+ if (!j.ok) {
325
+ const at = `settings.webSearch.${field}`;
326
+ return { kind: "malformed", issue: `${at} ${j.issue}`, ...(j.credential === undefined ? {} : { facts: urlCredentialFacts(at, j.credential) }) };
327
+ }
325
328
  }
326
329
  return {
327
330
  kind: "honored",
@@ -333,4 +336,16 @@ export function judgeRequestWebSearch(raw) {
333
336
  }),
334
337
  };
335
338
  }
339
+ const ENDPOINT_CREDENTIAL_EXIT = "settings.webSearch.apiKey is stored sealed: send the credential as settings.webSearch.apiKey (brave and tavily send it as a request header; " +
340
+ "the searxng backend sends no credential from a request, so a searxng instance that needs one is declared in the deployment's WEB_SEARCH_ENDPOINT instead)";
341
+ export function judgeFreshRequestWebSearch(raw) {
342
+ const verdict = judgeRequestWebSearch(raw);
343
+ if (verdict.kind !== "honored" || verdict.config.endpoint === undefined)
344
+ return verdict;
345
+ const credential = findUrlCredential(verdict.config.endpoint);
346
+ if (credential === undefined)
347
+ return verdict;
348
+ const refusal = buildRequestUrlCredentialRefusal("settings.webSearch.endpoint", credential, ENDPOINT_CREDENTIAL_EXIT);
349
+ return { kind: "malformed", issue: refusal.message, facts: refusal.facts };
350
+ }
336
351
  //# sourceMappingURL=web-search.js.map
@@ -1,5 +1,6 @@
1
1
  /**
2
- * S-185(core 7.10.0 [ref] / B-049)—— `WorkflowJournalEntry` **两臂**的单点读写。
2
+ * [ref](core 7.10.0 [ref] / [ref])—— `WorkflowJournalEntry` **两臂**的单点读写;`workflow_journal.result` 这一列的**单一属主叶**(写腿编码、读腿解码与判官
3
+ * 都在这里 —— SQL 店与 journal HTTP 读面的 SQL 分页腿共读,core 7.55.0 T3 起从 `orchestration/workflow-journal-entry.ts` 搬到列属主的家)。
3
4
  *
4
5
  * core 7.10.0 把 journal 记录从一个 interface 换成了判别联合:
5
6
  * `{ callKey, result }` —— 这一序数的子代跑完了,`result` 是它的 `TaskResult`;
@@ -15,17 +16,17 @@
15
16
  * 承重记录**——而 journal 是 LOAD-BEARING(丢一条 = 一次已完成的子代被当成没跑过而重跑,外部副作用重复)。
16
17
  * 收敛到这里之后,第三臂到货 ⇒ 本文件**一处**编译红。
17
18
  *
18
- * 🔴 **park 臂的形是 fail-closed 的**:core 的类型要求 `parked.terminal.kind === "paused"`。从盘上读回来的
19
- * 字节没有类型,所以 {@link readJournalRowBody} 在铸 park 臂时**亲验**这一位,不合就判坏——它是 LOAD-BEARING
20
- * 面上的坏行(一条说自己 park 了却拿不出暂停终局的记录,既不能驱动、也不能当成跑完),吞掉它会让 resume
21
- * 在一个被钉住的子代 session 旁边重新起一只活跑,正是 core 那条「一次性、响亮」的 schema 台阶要防的形。
19
+ * 🔴 **读回一行的判官是 core 的那一只**(core 7.55.0 [ref] T3 `readWorkflowJournalEntry`):从盘上读回来的字节没有类型,一条
20
+ * 「说自己 park 了却拿不出带令牌的暂停终局」的记录、一条完成臂不是对象的记录,既不能驱动、也不能当成跑完 —— 吞掉它会让 resume 在一个被
21
+ * 钉住的子代 session 旁边重新起一只活跑。本仓此前自判 park 臂的 `terminal.kind`(漏了 checkpoint 令牌那一条);现在本仓只做**信封解码**
22
+ * ({@link journalLogicalRow}:`{"parked": …}` 判别位活在载荷里),臂的判定全交 core,坏行 ⇒ `WorkflowJournalIncompatibleError`
23
+ * (码 `workflow.journal_incompatible`,点名序数)—— core 的两只内置 journal 与它的店契约盒对坏行要的就是这一只拒绝。
22
24
  *
23
25
  * 🔴 **盘上的编码是那道台阶的一部分**,不是实现细节:见 {@link journalRowPayloadOf} 的顶注(park 载荷走
24
26
  * `{"parked": …}` 信封,好让**回滚/混版**的老读者拿到一个没有 `terminal` 的对象、落进 core 的响亮拒绝臂,
25
27
  * 而不是把一个暂停终局当成可重放结果)。
26
28
  */
27
- import type { TaskResult, WorkflowJournalEntry } from "@sema-agent/core";
28
- import type { JsonColumnReader } from "../plugins/sql-json-column.js";
29
+ import { type TaskResult, type WorkflowJournalEntry } from "@sema-agent/core";
29
30
  /** park 臂的载荷型(core 的 `WorkflowJournalEntry` park 成员逐字):一只 `terminal` 收敛到 `paused` 的 `TaskResult`。 */
30
31
  export type ParkedTaskResult = TaskResult & {
31
32
  terminal: Extract<TaskResult["terminal"], {
@@ -64,33 +65,23 @@ export declare function journalEntryPayload(entry: WorkflowJournalEntry): {
64
65
  */
65
66
  export declare function journalRowPayloadOf(entry: WorkflowJournalEntry): string;
66
67
  /**
67
- * 盘上一行 payload 的**形读者**(S-550 车③a:`workflow_journal.result` 这一列的唯一判据)。
68
- *
69
- * 判别式 = 解出来的对象上有没有**自有** `parked` 键。它与 `TaskResult` 结构上不相交(core 的 `TaskResult`
70
- * 没有这个成员),所以历史字节(裸 TaskResult)恒判 result 臂 —— 不需要任何「老字节 = result」的兼容规则,
71
- * 判别式自己就说清了。
72
- *
73
- * park 臂验 `terminal.kind === "paused"`;不合 ⇒ 判坏,由 LOAD-BEARING 的读腿把它当店故障传上去。
74
- * 一条「说自己 park 了却拿不出暂停终局」的行既驱动不了、也不能当跑完,吞掉它会让 resume 在被钉住的子代
75
- * session 旁边重新起一只活跑 —— 与 {@link journalRowPayloadOf} 那道信封屏障要防的是同一件事。
76
- *
77
- * 🔴 **「一只 JSON 对象」这一条也必须判**(S-550):此前回装点是裸 `JSON.parse` + `as TaskResult`,于是
78
- * 一行 `null` 字面 / JSON 字符串标量 / 双重编码的 `result` 会被当成一条**合法的已完成记录**端给 resume
79
- * (`{callKey, result: null}`)—— 那正是「一次已完成的子代被当成跑过而不再跑」与「一条坏行冒充跑完」
80
- * 两种最坏形的同一个入口。
68
+ * 盘上一行 payload 的**信封解码**(本仓唯一自判的部分;{@link journalRowPayloadOf} 的逆):载荷是一只对象且带**自有** `parked` 键 ⇒ 停驻臂(值 = 信封里那一份),
69
+ * 否则整份载荷是完成臂 —— `parked` 与 core 的 `TaskResult` 结构上不相交,所以历史字节(裸 TaskResult)恒判完成臂,不需要任何「老字节 = result」的兼容规则。
70
+ * 交出的是 core `readWorkflowJournalEntry` 要的**逻辑行**(`callKey` + 两臂之一);两臂里装的东西拿不拿得出续跑要读的(完成臂是对象 / 停驻臂是带令牌的
71
+ * paused 终局)归 core 判。
81
72
  */
82
- export declare const readJournalRowBody: JsonColumnReader<JournalRowBody>;
83
- /** {@link readJournalRowBody} 收窄出来的两臂(判别位已定,载荷已验形)。 */
84
- export type JournalRowBody = {
85
- parked: true;
86
- payload: ParkedTaskResult;
73
+ export declare function journalLogicalRow(callKey: string, payload: unknown): {
74
+ readonly callKey: string;
75
+ readonly parked: unknown;
87
76
  } | {
88
- parked: false;
89
- payload: TaskResult;
77
+ readonly callKey: string;
78
+ readonly result: unknown;
90
79
  };
91
80
  /**
92
- * {@link journalRowPayloadOf} 的逆的**后半**:已解码、已验形的载荷 → 记录。**唯一**的铸点(SQL 店的 `load`
93
- * 与 HTTP journal 读面共读它;两处各自经 `decodeJsonColumn(text, readJournalRowBody, …)` 把文本收成这只体)。
81
+ * 一格 `workflow_journal.result` 读回一条记录的**唯一读法**(SQL 店的 `load` 与 HTTP journal 读面的 SQL 分页腿共读它):JSON 解码 → 信封解码
82
+ * ({@link journalLogicalRow})→ core `readWorkflowJournalEntry`。判官说坏 ⇒ 抛 `WorkflowJournalIncompatibleError`(码 `workflow.journal_incompatible`,
83
+ * 序数 = core 对 `callKey` 的解析;拒句是 core 判官的定句,不引存下的值)。读不成 JSON 的格是一条读不成对象的行(同判坏,同一只拒绝);
84
+ * 投影漏了的格(`not-text`,读腿写错)原样抛 —— 那是程序错,不是坏数据。
94
85
  */
95
- export declare function journalEntryOfBody(callKey: string, body: JournalRowBody): WorkflowJournalEntry;
96
- //# sourceMappingURL=workflow-journal-entry.d.ts.map
86
+ export declare function journalEntryOfCell(runId: string, callKey: string, cell: unknown, where: string): WorkflowJournalEntry;
87
+ //# sourceMappingURL=workflow-journal-payload.d.ts.map