@sema-agent/server 7.134.0 → 7.136.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 (550) hide show
  1. package/MIGRATION.md +197 -1
  2. package/USAGE.md +147 -42
  3. package/deploy/sema-up/README.md +1 -1
  4. package/deploy/sema-up/chart/templates/NOTES.txt +1 -1
  5. package/deploy/sema-up/chart/values.yaml +1 -1
  6. package/dist/adoption/plan.d.ts +1 -1
  7. package/dist/approval-ask-audit-store.d.ts +24 -24
  8. package/dist/approval-ask-machine.d.ts +2 -2
  9. package/dist/approval-card.d.ts +122 -154
  10. package/dist/approval-card.js +50 -51
  11. package/dist/approval-content-kind.d.ts +23 -5
  12. package/dist/approval-content-kind.js +8 -1
  13. package/dist/approval-deny-reasons.d.ts +1 -1
  14. package/dist/approval-gate-currency.d.ts +22 -3
  15. package/dist/approval-gate-currency.js +44 -18
  16. package/dist/approval-hmac.d.ts +7 -7
  17. package/dist/approval-policy-settlement.d.ts +2 -2
  18. package/dist/approval-reconciler.d.ts +3 -3
  19. package/dist/approval.d.ts +8 -8
  20. package/dist/approval.js +4 -2
  21. package/dist/auth-bridge.d.ts +35 -6
  22. package/dist/auth-bridge.js +20 -3
  23. package/dist/auto-mode-face.d.ts +4 -4
  24. package/dist/background-session-reap.d.ts +2 -2
  25. package/dist/bake-runner/main.d.ts +2 -2
  26. package/dist/bake-runner/runner.d.ts +4 -4
  27. package/dist/bench/s1/live-deps.d.ts +1 -1
  28. package/dist/bench/s1/run-firm.d.ts +1 -1
  29. package/dist/boot/budget-tracing.d.ts +1 -2
  30. package/dist/boot/budget-tracing.js +2 -2
  31. package/dist/boot/coordinators.d.ts +2 -2
  32. package/dist/boot/coordinators.js +2 -2
  33. package/dist/boot/deferred-sandbox-path-env.d.ts +0 -6
  34. package/dist/boot/deferred-sandbox-path-env.js +0 -5
  35. package/dist/boot/engine-lease.d.ts +5 -5
  36. package/dist/boot/execution-env.d.ts +16 -15
  37. package/dist/boot/execution-env.js +19 -21
  38. package/dist/boot/fatal-exit.d.ts +2 -2
  39. package/dist/boot/late-binds.d.ts +1 -1
  40. package/dist/boot/leader.d.ts +1 -1
  41. package/dist/boot/memory-boundary.d.ts +2 -2
  42. package/dist/boot/memory-consolidation.d.ts +15 -15
  43. package/dist/boot/org-memory.js +1 -1
  44. package/dist/boot/parked-revive-gate.d.ts +3 -3
  45. package/dist/boot/parked-revive-gate.js +3 -2
  46. package/dist/boot/reapers.d.ts +4 -4
  47. package/dist/boot/resolve-spec.d.ts +1 -1
  48. package/dist/boot/resolve-spec.js +36 -29
  49. package/dist/boot/runner-deps.d.ts +11 -11
  50. package/dist/boot/runner-deps.js +7 -4
  51. package/dist/boot/session-faces.d.ts +3 -3
  52. package/dist/boot/session-faces.js +11 -30
  53. package/dist/boot/shutdown.d.ts +5 -5
  54. package/dist/boot/side-query-lane.d.ts +2 -2
  55. package/dist/boot/stage-04-stores.d.ts +1 -1
  56. package/dist/boot/stage-05-execution-env.d.ts +1 -1
  57. package/dist/boot/stage-05-execution-env.js +4 -4
  58. package/dist/boot/stage-06-runners.d.ts +1 -1
  59. package/dist/boot/stage-06-runners.js +0 -2
  60. package/dist/boot/stage-07-capability-layer.d.ts +1 -1
  61. package/dist/boot/stage-08-reapers.d.ts +1 -1
  62. package/dist/boot/stage-09-leader.d.ts +1 -1
  63. package/dist/boot/stage-10-http-server.d.ts +1 -1
  64. package/dist/boot/stores.js +4 -4
  65. package/dist/boot/web-admin.d.ts +17 -17
  66. package/dist/boot/web-admin.js +15 -27
  67. package/dist/boot/workflow-orchestration.js +2 -9
  68. package/dist/brain.d.ts +11 -11
  69. package/dist/brain.js +12 -3
  70. package/dist/budget.d.ts +7 -7
  71. package/dist/budget.js +4 -0
  72. package/dist/capabilities/approvals-push.d.ts +4 -4
  73. package/dist/capabilities/builtin-tools.d.ts +5 -5
  74. package/dist/capabilities/center-plugins.d.ts +5 -5
  75. package/dist/capabilities/center-plugins.js +1 -1
  76. package/dist/capabilities/center-prompts.d.ts +1 -1
  77. package/dist/capabilities/center-wiring.d.ts +1 -1
  78. package/dist/capabilities/composite-members.d.ts +1 -1
  79. package/dist/capabilities/execution-lane.d.ts +5 -5
  80. package/dist/capabilities/execution-lane.js +2 -2
  81. package/dist/capabilities/hands-lane.d.ts +5 -5
  82. package/dist/capabilities/mcp-probe.d.ts +11 -7
  83. package/dist/capabilities/sandbox-file-send.d.ts +1 -18
  84. package/dist/capabilities/sandbox-file-send.js +0 -7
  85. package/dist/capabilities/scenarios.d.ts +28 -10
  86. package/dist/capabilities/scenarios.js +15 -5
  87. package/dist/capabilities/send-user-file-tool.d.ts +1 -1
  88. package/dist/capabilities/skills.d.ts +31 -12
  89. package/dist/capabilities/skills.js +23 -17
  90. package/dist/capabilities/tool-defer.d.ts +1 -1
  91. package/dist/capability-facts.d.ts +29 -32
  92. package/dist/capability-facts.js +17 -21
  93. package/dist/center-config-tier.d.ts +1 -1
  94. package/dist/center-credential.d.ts +22 -8
  95. package/dist/center-credential.js +18 -3
  96. package/dist/checkpoint-identity.d.ts +5 -0
  97. package/dist/checkpoint-identity.js +14 -0
  98. package/dist/config-catalog.d.ts +12 -12
  99. package/dist/config-catalog.js +12 -10
  100. package/dist/config-d-migration.js +1 -1
  101. package/dist/config-invariants.d.ts +5 -5
  102. package/dist/config-invariants.js +11 -2
  103. package/dist/config-lkg.d.ts +1 -39
  104. package/dist/config-lkg.js +1 -83
  105. package/dist/config-provider.d.ts +13 -13
  106. package/dist/config-provider.js +2 -1
  107. package/dist/config-types.d.ts +95 -87
  108. package/dist/config.d.ts +26 -24
  109. package/dist/config.js +38 -18
  110. package/dist/cross-session-settings.d.ts +1 -1
  111. package/dist/delegated-session-owner.d.ts +16 -13
  112. package/dist/delegated-session-owner.js +9 -10
  113. package/dist/deployment-governance.d.ts +16 -16
  114. package/dist/deployment-shape.d.ts +127 -0
  115. package/dist/deployment-shape.js +72 -0
  116. package/dist/device-store.d.ts +1 -1
  117. package/dist/device-ws-hub.d.ts +1 -1
  118. package/dist/egress-redirect.d.ts +1 -1
  119. package/dist/elicitation.d.ts +8 -7
  120. package/dist/elicitation.js +9 -8
  121. package/dist/entry-mode-clamp-notice.d.ts +2 -2
  122. package/dist/env-facts.d.ts +10 -9
  123. package/dist/env-facts.js +1 -1
  124. package/dist/env-name-allowlist-knobs.d.ts +5 -5
  125. package/dist/exec-bounds.d.ts +2 -2
  126. package/dist/execution-lane-caps.d.ts +31 -43
  127. package/dist/execution-lane-caps.js +0 -13
  128. package/dist/file-history-capture.d.ts +9 -9
  129. package/dist/file-history-disclosure.d.ts +25 -11
  130. package/dist/file-history-disclosure.js +25 -14
  131. package/dist/fleet/drain-entry.d.ts +2 -2
  132. package/dist/fleet/fleet-bus.d.ts +22 -14
  133. package/dist/fleet/fleet-bus.js +5 -5
  134. package/dist/fleet/fleet-reconciler.d.ts +9 -9
  135. package/dist/fleet/subagent-tail-bus.d.ts +4 -4
  136. package/dist/fleet-client.d.ts +45 -14
  137. package/dist/fleet-client.js +24 -4
  138. package/dist/fleet-lease.d.ts +23 -19
  139. package/dist/fleet-lease.js +31 -23
  140. package/dist/governance-http-status.d.ts +2 -2
  141. package/dist/hooks/hook-llm.d.ts +7 -7
  142. package/dist/hooks/hook-llm.js +14 -8
  143. package/dist/hooks/hook-runner.d.ts +58 -31
  144. package/dist/hooks/hook-runner.js +37 -19
  145. package/dist/host-decision.d.ts +5 -5
  146. package/dist/host-lsp-manager.d.ts +5 -5
  147. package/dist/hosted-posture.d.ts +23 -13
  148. package/dist/hosted-posture.js +4 -9
  149. package/dist/http/admission.d.ts +2 -2
  150. package/dist/http/admission.js +20 -5
  151. package/dist/http/approval-sweeps.d.ts +1 -1
  152. package/dist/http/approval-sweeps.js +2 -1
  153. package/dist/http/checkpoint-ctx.d.ts +62 -17
  154. package/dist/http/checkpoint-ctx.js +78 -35
  155. package/dist/http/dispatch.d.ts +3 -3
  156. package/dist/http/dispatch.js +9 -9
  157. package/dist/http/durable-run-leg.js +4 -3
  158. package/dist/http/idempotency.d.ts +2 -2
  159. package/dist/http/mcp-dial-deadline.d.ts +7 -5
  160. package/dist/http/memory-compliance-failure-reply.d.ts +4 -4
  161. package/dist/http/owner-access.d.ts +4 -6
  162. package/dist/http/owner-access.js +1 -1
  163. package/dist/http/principal-gate.d.ts +7 -7
  164. package/dist/http/principal-gate.js +3 -2
  165. package/dist/http/readiness.d.ts +1 -1
  166. package/dist/http/request-guards.d.ts +4 -4
  167. package/dist/http/request-guards.js +2 -1
  168. package/dist/http/resume-ctx-read.d.ts +9 -23
  169. package/dist/http/resume-ctx-read.js +2 -3
  170. package/dist/http/resume-legs.d.ts +3 -3
  171. package/dist/http/resume-legs.js +11 -8
  172. package/dist/http/route-ctx.d.ts +29 -29
  173. package/dist/http/route-table.d.ts +9 -9
  174. package/dist/http/routes/agents-roster.d.ts +1 -1
  175. package/dist/http/routes/approvals-assistant.d.ts +5 -7
  176. package/dist/http/routes/approvals-assistant.js +101 -26
  177. package/dist/http/routes/background.d.ts +3 -3
  178. package/dist/http/routes/background.js +2 -2
  179. package/dist/http/routes/capabilities.d.ts +1 -1
  180. package/dist/http/routes/capabilities.js +16 -8
  181. package/dist/http/routes/config-catalog.d.ts +1 -1
  182. package/dist/http/routes/devices.d.ts +1 -1
  183. package/dist/http/routes/diagnostics.d.ts +3 -3
  184. package/dist/http/routes/fleet.d.ts +1 -1
  185. package/dist/http/routes/fleet.js +2 -1
  186. package/dist/http/routes/mcp-reconnect.d.ts +4 -4
  187. package/dist/http/routes/mcp-reconnect.js +3 -3
  188. package/dist/http/routes/memory-consolidation.d.ts +1 -1
  189. package/dist/http/routes/notify-wake.d.ts +1 -1
  190. package/dist/http/routes/notify-wake.js +2 -2
  191. package/dist/http/routes/rules.d.ts +1 -1
  192. package/dist/http/routes/runs.js +23 -11
  193. package/dist/http/routes/session-sync.d.ts +1 -1
  194. package/dist/http/routes/session-sync.js +97 -46
  195. package/dist/http/routes/sessions-list.js +1 -1
  196. package/dist/http/routes/sessions.js +43 -53
  197. package/dist/http/routes/tasks.d.ts +1 -1
  198. package/dist/http/routes/trace-usage.d.ts +1 -1
  199. package/dist/http/routes/workflows.d.ts +3 -0
  200. package/dist/http/routes/workflows.js +31 -28
  201. package/dist/http/send.d.ts +5 -5
  202. package/dist/http/server.d.ts +34 -34
  203. package/dist/http/session-inherit-env.d.ts +3 -3
  204. package/dist/http/sse-lifecycle.d.ts +1 -1
  205. package/dist/http/sse-log.d.ts +2 -2
  206. package/dist/http/submit-ctx.js +1 -1
  207. package/dist/http/sync-submit-body.d.ts +1 -1
  208. package/dist/http/verify-rounds.d.ts +1 -1
  209. package/dist/http/wire-types.d.ts +33 -24
  210. package/dist/index.d.ts +1 -0
  211. package/dist/index.js +1 -0
  212. package/dist/instruction-source-notice.d.ts +2 -2
  213. package/dist/key-resolver.d.ts +3 -3
  214. package/dist/lane-home-probe.d.ts +1 -1
  215. package/dist/leader/diffout.d.ts +1 -1
  216. package/dist/leader/diffup.d.ts +2 -2
  217. package/dist/leader/endpoint.d.ts +1 -1
  218. package/dist/leader/fanout.d.ts +1 -1
  219. package/dist/leader/leader.d.ts +4 -4
  220. package/dist/leader/merge.d.ts +3 -3
  221. package/dist/leader/repair-wire.d.ts +1 -1
  222. package/dist/leader/wire.d.ts +6 -6
  223. package/dist/list-entry-display.d.ts +1 -1
  224. package/dist/lsp-evict.d.ts +1 -1
  225. package/dist/mcp-assertion-header.d.ts +1 -1
  226. package/dist/memory-layer-legacy-lock.d.ts +1 -1
  227. package/dist/memory-operator-faces.d.ts +1 -1
  228. package/dist/memory-posture.js +4 -2
  229. package/dist/memory-project-layer.d.ts +1 -1
  230. package/dist/memory-scope.d.ts +19 -19
  231. package/dist/memory-store-refusal.d.ts +4 -4
  232. package/dist/model-entry-headers.d.ts +2 -2
  233. package/dist/model-entry-refusal.d.ts +17 -17
  234. package/dist/model-provider.d.ts +10 -10
  235. package/dist/model-reach-scope.d.ts +1 -1
  236. package/dist/model-route-endpoint.d.ts +6 -6
  237. package/dist/model-route-gap.d.ts +49 -4
  238. package/dist/model-route-gap.js +34 -1
  239. package/dist/model-route-url.d.ts +5 -5
  240. package/dist/model-select.d.ts +15 -6
  241. package/dist/model-select.js +5 -0
  242. package/dist/model-unreachable-notice.d.ts +3 -3
  243. package/dist/namespaced-rule-name.d.ts +15 -5
  244. package/dist/namespaced-rule-name.js +3 -2
  245. package/dist/object-store-buckets.d.ts +13 -0
  246. package/dist/object-store-buckets.js +3 -0
  247. package/dist/observability/corrupt-read-seat.d.ts +9 -9
  248. package/dist/observability/cost-taxonomy.d.ts +1 -1
  249. package/dist/observability/err-text.d.ts +1 -1
  250. package/dist/observability/fail-open.d.ts +17 -13
  251. package/dist/observability/fail-open.js +17 -13
  252. package/dist/observability/metrics.d.ts +3 -3
  253. package/dist/observability/metrics.js +1 -1
  254. package/dist/observability/principal-context.d.ts +4 -1
  255. package/dist/observability/principal-context.js +6 -1
  256. package/dist/observability/run-terminal.d.ts +36 -36
  257. package/dist/observability/secret-env-scrub.d.ts +3 -3
  258. package/dist/observability/tool-trace.d.ts +1 -1
  259. package/dist/operator-ask.d.ts +4 -4
  260. package/dist/orchestration/workflow-agent-session-index.d.ts +3 -3
  261. package/dist/orchestration/workflow-completion-inbox.d.ts +20 -5
  262. package/dist/orchestration/workflow-completion-inbox.js +29 -7
  263. package/dist/orchestration/workflow-notify-journal.d.ts +43 -19
  264. package/dist/orchestration/workflow-notify-journal.js +17 -0
  265. package/dist/outbound-dispatcher.d.ts +4 -4
  266. package/dist/parent-watch.d.ts +4 -4
  267. package/dist/parked-decide.d.ts +20 -18
  268. package/dist/parked-decide.js +31 -11
  269. package/dist/parked-revive-surface.d.ts +7 -7
  270. package/dist/parked-revive-surface.js +2 -3
  271. package/dist/peer-directory.d.ts +5 -4
  272. package/dist/peer-directory.js +6 -6
  273. package/dist/permission-rule-list.d.ts +10 -1
  274. package/dist/permission-rule-list.js +7 -5
  275. package/dist/permission-rule-vocab.d.ts +2 -2
  276. package/dist/plugins/adoption-log-sql.d.ts +1 -1
  277. package/dist/plugins/approval-ask-store-file.d.ts +8 -1
  278. package/dist/plugins/approval-ask-store-file.js +6 -3
  279. package/dist/plugins/approval-ask-store-memory.d.ts +11 -7
  280. package/dist/plugins/approval-ask-store-memory.js +11 -7
  281. package/dist/plugins/approval-ask-store-sql.d.ts +42 -15
  282. package/dist/plugins/approval-ask-store-sql.js +21 -5
  283. package/dist/plugins/approval-exemption-store.d.ts +3 -3
  284. package/dist/plugins/approval-nonce-store.d.ts +3 -3
  285. package/dist/plugins/background-agent-store-sql.d.ts +1 -1
  286. package/dist/plugins/background-shell-support.d.ts +2 -2
  287. package/dist/plugins/blob-backend.d.ts +1 -1
  288. package/dist/plugins/blob-backend.js +2 -1
  289. package/dist/plugins/caching-session-store.d.ts +23 -32
  290. package/dist/plugins/caching-session-store.js +5 -17
  291. package/dist/plugins/checkpoint-index-columns.d.ts +130 -0
  292. package/dist/plugins/checkpoint-index-columns.js +90 -0
  293. package/dist/plugins/checkpoint-store-sql.d.ts +71 -69
  294. package/dist/plugins/checkpoint-store-sql.js +109 -127
  295. package/dist/plugins/device-store-sql.d.ts +7 -6
  296. package/dist/plugins/e2b-orphan-reclaim.d.ts +1 -1
  297. package/dist/plugins/ensure-schema-lock-policy.d.ts +1 -1
  298. package/dist/plugins/file-history-store-sql.d.ts +15 -7
  299. package/dist/plugins/file-history-store-sql.js +55 -36
  300. package/dist/plugins/file-run-store.d.ts +8 -8
  301. package/dist/plugins/fork-routing-session-store.d.ts +2 -2
  302. package/dist/plugins/fork-routing-session-store.js +1 -1
  303. package/dist/plugins/host-platform.d.ts +10 -10
  304. package/dist/plugins/image-bake-store-sql.d.ts +1 -1
  305. package/dist/plugins/image-index-sql.d.ts +1 -1
  306. package/dist/plugins/leader-run-store-sql.d.ts +1 -1
  307. package/dist/plugins/local-checkpoint-store.d.ts +10 -10
  308. package/dist/plugins/local-checkpoint-store.js +7 -7
  309. package/dist/plugins/local-session-store.d.ts +34 -38
  310. package/dist/plugins/local-session-store.js +20 -39
  311. package/dist/plugins/local-session-window.d.ts +1 -1
  312. package/dist/plugins/mailbox-store-sql.d.ts +2 -2
  313. package/dist/plugins/memory-engine-pg.d.ts +1 -1
  314. package/dist/plugins/memory-run-store.d.ts +4 -4
  315. package/dist/plugins/memory-sync-store-pg.d.ts +3 -3
  316. package/dist/plugins/one-time-migrations.d.ts +73 -54
  317. package/dist/plugins/one-time-migrations.js +131 -134
  318. package/dist/plugins/outcome-ledger-sql.d.ts +1 -1
  319. package/dist/plugins/park-commit-watch.d.ts +3 -3
  320. package/dist/plugins/permission-rule-store-file.d.ts +5 -5
  321. package/dist/plugins/permission-rule-store-file.js +12 -19
  322. package/dist/plugins/permission-rule-store-sql.d.ts +38 -4
  323. package/dist/plugins/permission-rule-store-sql.js +67 -24
  324. package/dist/plugins/pg-cost-quota.d.ts +1 -1
  325. package/dist/plugins/pg-pool.d.ts +2 -2
  326. package/dist/plugins/pg-pool.js +5 -2
  327. package/dist/plugins/pg-rate-limiter.d.ts +1 -1
  328. package/dist/plugins/pg-session-storage.d.ts +8 -20
  329. package/dist/plugins/pg-session-storage.js +14 -27
  330. package/dist/plugins/remote-env-adb.d.ts +10 -10
  331. package/dist/plugins/remote-env-device.d.ts +10 -9
  332. package/dist/plugins/remote-env-device.js +6 -2
  333. package/dist/plugins/remote-env-e2b.d.ts +3 -3
  334. package/dist/plugins/remote-env-host.d.ts +16 -16
  335. package/dist/plugins/remote-env-k8s.d.ts +26 -13
  336. package/dist/plugins/remote-env-k8s.js +24 -7
  337. package/dist/plugins/remote-env-local-docker.d.ts +2 -2
  338. package/dist/plugins/remote-env-ssh.d.ts +4 -4
  339. package/dist/plugins/remote-scratchpad.d.ts +2 -3
  340. package/dist/plugins/remote-scratchpad.js +0 -4
  341. package/dist/plugins/remote-shell.d.ts +6 -6
  342. package/dist/plugins/retention-lane-store-sql.d.ts +4 -4
  343. package/dist/plugins/retention-store-sql.d.ts +4 -4
  344. package/dist/plugins/roster-store-sql.d.ts +1 -1
  345. package/dist/plugins/run-store-sql.d.ts +8 -8
  346. package/dist/plugins/s3-answer.d.ts +15 -0
  347. package/dist/plugins/s3-answer.js +5 -0
  348. package/dist/plugins/schema-consistency.d.ts +2 -2
  349. package/dist/plugins/schema-ensure-legs.d.ts +3 -3
  350. package/dist/plugins/schema-indexes.d.ts +1 -1
  351. package/dist/plugins/schema-live-columns.d.ts +1 -1
  352. package/dist/plugins/session-event-payload.d.ts +4 -4
  353. package/dist/plugins/session-fork.d.ts +34 -0
  354. package/dist/plugins/session-fork.js +29 -0
  355. package/dist/plugins/session-ownership.js +1 -1
  356. package/dist/plugins/session-placement.d.ts +1 -1
  357. package/dist/plugins/session-policy-store-sql.d.ts +12 -12
  358. package/dist/plugins/session-store.d.ts +2 -2
  359. package/dist/plugins/session-store.js +2 -2
  360. package/dist/plugins/shared-memory-store-sql.d.ts +2 -2
  361. package/dist/plugins/snapshot-bucket-presence.d.ts +39 -4
  362. package/dist/plugins/snapshot-bucket-presence.js +35 -7
  363. package/dist/plugins/sql-driver.d.ts +8 -8
  364. package/dist/plugins/sql-errors.d.ts +40 -1
  365. package/dist/plugins/sql-errors.js +49 -1
  366. package/dist/plugins/sql-json-column.d.ts +21 -21
  367. package/dist/plugins/sql-row-helpers.d.ts +2 -2
  368. package/dist/plugins/store-backend.d.ts +17 -16
  369. package/dist/plugins/store-backend.js +3 -3
  370. package/dist/plugins/store-contracts.d.ts +21 -21
  371. package/dist/plugins/store-fault.d.ts +4 -0
  372. package/dist/plugins/store-fault.js +8 -0
  373. package/dist/plugins/task-attachment-store.d.ts +2 -2
  374. package/dist/plugins/task-list-store-sql.d.ts +1 -1
  375. package/dist/plugins/tidb-pool.d.ts +2 -2
  376. package/dist/plugins/tidb-pool.js +10 -3
  377. package/dist/plugins/tidb-session-store.d.ts +16 -26
  378. package/dist/plugins/tidb-session-store.js +15 -27
  379. package/dist/plugins/tool-result-store-sql.d.ts +1 -1
  380. package/dist/plugins/usage-window-store-sql.d.ts +3 -3
  381. package/dist/plugins/user-input-ledger-file.d.ts +1 -1
  382. package/dist/plugins/user-input-ledger-sql.d.ts +3 -3
  383. package/dist/plugins/web-search.d.ts +19 -5
  384. package/dist/plugins/web-search.js +20 -5
  385. package/dist/{orchestration/workflow-journal-entry.d.ts → plugins/workflow-journal-payload.d.ts} +23 -32
  386. package/dist/plugins/workflow-journal-payload.js +32 -0
  387. package/dist/plugins/workflow-journal-store-sql.d.ts +28 -14
  388. package/dist/plugins/workflow-journal-store-sql.js +34 -15
  389. package/dist/plugins/workflow-run-store-sql.d.ts +4 -4
  390. package/dist/posture-source.d.ts +11 -11
  391. package/dist/principal-jwt.d.ts +6 -6
  392. package/dist/project-identity.d.ts +3 -3
  393. package/dist/project-memory.d.ts +4 -4
  394. package/dist/read-face-posture.d.ts +7 -7
  395. package/dist/request-declaration-refusal.d.ts +94 -0
  396. package/dist/request-declaration-refusal.js +78 -0
  397. package/dist/request-image-urls.d.ts +6 -0
  398. package/dist/request-image-urls.js +27 -0
  399. package/dist/request-key-closure.d.ts +6 -1
  400. package/dist/request-key-closure.js +5 -2
  401. package/dist/request-value-closure.d.ts +15 -8
  402. package/dist/request-value-closure.js +2 -0
  403. package/dist/router/route-orchestration.d.ts +11 -16
  404. package/dist/router/route-orchestration.js +2 -12
  405. package/dist/rule-entry-list.d.ts +8 -7
  406. package/dist/rule-entry-list.js +2 -9
  407. package/dist/rules-consent.d.ts +6 -6
  408. package/dist/rules-consent.js +2 -0
  409. package/dist/run-cancel-context.d.ts +5 -5
  410. package/dist/run-local.d.ts +10 -10
  411. package/dist/runs.d.ts +13 -11
  412. package/dist/runs.js +15 -1
  413. package/dist/runtime-caps-resolver.d.ts +6 -6
  414. package/dist/runtime-caps-resolver.js +1 -1
  415. package/dist/runtime-governance.d.ts +9 -9
  416. package/dist/sandbox-pkg-source.d.ts +17 -12
  417. package/dist/sandbox-pkg-source.js +14 -9
  418. package/dist/sealed-key.d.ts +22 -3
  419. package/dist/sealed-key.js +47 -4
  420. package/dist/security.d.ts +23 -26
  421. package/dist/security.js +12 -9
  422. package/dist/server-secret-env.d.ts +10 -10
  423. package/dist/session-children-retire.d.ts +1 -1
  424. package/dist/session-error-wire.d.ts +7 -7
  425. package/dist/session-incarnation.d.ts +65 -37
  426. package/dist/session-incarnation.js +30 -12
  427. package/dist/session-policy-wire.d.ts +27 -5
  428. package/dist/session-policy-wire.js +15 -1
  429. package/dist/session-records-skipped-notice.d.ts +1 -1
  430. package/dist/session-row.d.ts +3 -17
  431. package/dist/session-row.js +4 -0
  432. package/dist/session-sync-kernel.d.ts +4 -4
  433. package/dist/session-sync.d.ts +61 -6
  434. package/dist/session-sync.js +55 -10
  435. package/dist/session-titler.d.ts +7 -6
  436. package/dist/session-titler.js +8 -13
  437. package/dist/session-watch.d.ts +3 -3
  438. package/dist/session-watch.js +4 -4
  439. package/dist/sighup-idle.d.ts +2 -2
  440. package/dist/spec-fields.d.ts +4 -4
  441. package/dist/sql-engine-posture.d.ts +3 -3
  442. package/dist/store-posture.d.ts +2 -2
  443. package/dist/stored-request-tool-axes-m19.d.ts +1 -1
  444. package/dist/task-a2a.d.ts +52 -79
  445. package/dist/task-a2a.js +224 -62
  446. package/dist/task-cwd.d.ts +7 -88
  447. package/dist/task-cwd.js +2 -15
  448. package/dist/task-mcp.d.ts +13 -17
  449. package/dist/task-mcp.js +29 -49
  450. package/dist/task-settings.d.ts +30 -18
  451. package/dist/task-settings.js +33 -3
  452. package/dist/task-workflow.d.ts +0 -24
  453. package/dist/task-workflow.js +2 -1
  454. package/dist/terminal.d.ts +5 -5
  455. package/dist/tighten-only-seats.d.ts +7 -6
  456. package/dist/tighten-only-seats.js +1 -1
  457. package/dist/tool-approval.d.ts +166 -207
  458. package/dist/tool-approval.js +61 -61
  459. package/dist/tool-rule-names.d.ts +2 -2
  460. package/dist/trace/core-keyset-guard.d.ts +13 -8
  461. package/dist/trace/engine-notice-wire.d.ts +5 -5
  462. package/dist/trace/engine-notice-wire.js +1 -0
  463. package/dist/trace/exit-seat.d.ts +31 -4
  464. package/dist/trace/exit-seat.js +69 -67
  465. package/dist/trace/ledger-events.d.ts +3 -3
  466. package/dist/trace/ledger-sink.d.ts +1 -1
  467. package/dist/trace/model-segment.d.ts +3 -3
  468. package/dist/trace/project.d.ts +47 -45
  469. package/dist/trace/project.js +33 -1
  470. package/dist/trace/redact.d.ts +61 -31
  471. package/dist/trace/redact.js +394 -153
  472. package/dist/trace/self-minted-wire.d.ts +302 -14
  473. package/dist/trace/self-minted-wire.js +87 -0
  474. package/dist/trace/sema-provenance.d.ts +1 -1
  475. package/dist/trace/task-notification-facets.d.ts +4 -4
  476. package/dist/trace/wire-projection-faces.d.ts +3 -3
  477. package/dist/trace/wire-projection-faces.js +1 -1
  478. package/dist/unattended-permission-mode.d.ts +5 -5
  479. package/dist/url-credential-refusal.d.ts +52 -0
  480. package/dist/url-credential-refusal.js +14 -0
  481. package/dist/url-refusal.d.ts +16 -3
  482. package/dist/url-refusal.js +15 -2
  483. package/dist/usage-analytics.d.ts +2 -2
  484. package/dist/user-input-ledger.d.ts +23 -23
  485. package/dist/web-admin-client/apply-effective.d.ts +5 -5
  486. package/dist/web-admin-client/apply-effective.js +2 -1
  487. package/dist/web-admin-client/apply-ledger.d.ts +2 -2
  488. package/dist/web-admin-client/center-request.d.ts +2 -2
  489. package/dist/web-admin-client/facade.d.ts +5 -5
  490. package/dist/web-admin-client/facade.js +1 -1
  491. package/dist/web-admin-client/hot-keys-registry.d.ts +2 -2
  492. package/dist/web-admin-client/http-client.d.ts +4 -4
  493. package/dist/web-admin-client/mcp-revocation.d.ts +1 -1
  494. package/dist/web-admin-client/pull-state.d.ts +1 -1
  495. package/dist/web-admin-client/read-face.d.ts +2 -2
  496. package/dist/web-admin-client/read-warnings.d.ts +5 -5
  497. package/dist/web-admin-client/restart-signal.d.ts +6 -6
  498. package/dist/web-admin-client/skills-mcp.d.ts +28 -3
  499. package/dist/web-admin-client/skills-mcp.js +29 -1
  500. package/dist/web-admin-client/types.d.ts +16 -9
  501. package/dist/workspace-space.d.ts +32 -3
  502. package/dist/workspace-space.js +26 -0
  503. package/dist/write-protection.d.ts +2 -2
  504. package/package.json +5 -3
  505. package/scripts/drain-check-local.mjs +4 -2
  506. package/scripts/drain-check.mysql.sql +6 -2
  507. package/scripts/drain-check.pg.sql +6 -2
  508. package/skills/loop.md +1 -1
  509. package/skills/schedule.md +1 -1
  510. package/wire-changes/server@7.104.0.json +134 -0
  511. package/wire-changes/server@7.105.0.json +53 -0
  512. package/wire-changes/server@7.106.0.json +475 -0
  513. package/wire-changes/server@7.107.0.json +64 -0
  514. package/wire-changes/server@7.108.0.json +153 -0
  515. package/wire-changes/server@7.109.0.json +46 -0
  516. package/wire-changes/server@7.110.0.json +90 -0
  517. package/wire-changes/server@7.111.0.json +86 -0
  518. package/wire-changes/server@7.112.0.json +60 -0
  519. package/wire-changes/server@7.113.0.json +26 -0
  520. package/wire-changes/server@7.114.0.json +26 -0
  521. package/wire-changes/server@7.115.0.json +97 -0
  522. package/wire-changes/server@7.116.0.json +218 -0
  523. package/wire-changes/server@7.116.1.json +26 -0
  524. package/wire-changes/server@7.117.0.json +65 -0
  525. package/wire-changes/server@7.118.0.json +129 -0
  526. package/wire-changes/server@7.119.0.json +65 -0
  527. package/wire-changes/server@7.120.0.json +89 -0
  528. package/wire-changes/server@7.121.0.json +219 -0
  529. package/wire-changes/server@7.122.0.json +54 -0
  530. package/wire-changes/server@7.123.0.json +26 -0
  531. package/wire-changes/server@7.124.0.json +336 -0
  532. package/wire-changes/server@7.124.1.json +26 -0
  533. package/wire-changes/server@7.125.0.json +111 -0
  534. package/wire-changes/server@7.126.0.json +285 -0
  535. package/wire-changes/server@7.127.0.json +77 -0
  536. package/wire-changes/server@7.127.1.json +26 -0
  537. package/wire-changes/server@7.127.2.json +53 -0
  538. package/wire-changes/server@7.128.0.json +26 -0
  539. package/wire-changes/server@7.129.0.json +106 -0
  540. package/wire-changes/server@7.129.1.json +26 -0
  541. package/wire-changes/server@7.130.0.json +26 -0
  542. package/wire-changes/server@7.131.0.json +118 -0
  543. package/wire-changes/server@7.132.0.json +226 -0
  544. package/wire-changes/server@7.133.0.json +1155 -0
  545. package/wire-changes/server@7.134.0.json +107 -0
  546. package/wire-changes/server@7.135.0.json +174 -0
  547. package/wire-changes/server@7.136.0.json +448 -0
  548. package/dist/http/run-declared-families.d.ts +0 -16
  549. package/dist/http/run-declared-families.js +0 -12
  550. package/dist/orchestration/workflow-journal-entry.js +0 -27
@@ -31,6 +31,23 @@ export declare function writerOfSqlRuleStore(store: DurableRulePartition): Permi
31
31
  * (下方 `RuleCandidateSchema`;File 店的审批记录读同一只)。
32
32
  */
33
33
  export declare const DurableRuleScopeSchema: z.ZodType<RuleScope>;
34
+ export declare const RuleOffer2Schema: z.ZodUnion<readonly [z.ZodObject<{
35
+ kind: z.ZodLiteral<"single">;
36
+ candidate: z.ZodNumber;
37
+ }, z.core.$strict>, z.ZodObject<{
38
+ kind: z.ZodLiteral<"batch">;
39
+ candidates: z.ZodArray<z.ZodNumber>;
40
+ segments: z.ZodOptional<z.ZodArray<z.ZodString>>;
41
+ uncoveredSegments: z.ZodOptional<z.ZodNumber>;
42
+ uncoveredDetail: z.ZodOptional<z.ZodArray<z.ZodObject<{
43
+ segment: z.ZodString;
44
+ reason: z.ZodEnum<{
45
+ redirection: "redirection";
46
+ no_rule_form: "no_rule_form";
47
+ cap_overflow: "cap_overflow";
48
+ }>;
49
+ }, z.core.$strict>>>;
50
+ }, z.core.$strict>]>;
34
51
  export declare const PERMISSION_RULE_TABLE = "permission_rule";
35
52
  export declare const PERMISSION_RULE_APPROVAL_TABLE = "permission_rule_approval";
36
53
  export declare const PERMISSION_RULE_TICKET_TABLE = "permission_rule_ticket";
@@ -112,7 +129,7 @@ export declare function assertPermissionRuleApprovalSchema(query: (sql: string)
112
129
  export declare function assertPermissionRuleTicketSchema(query: (sql: string) => Promise<{
113
130
  rows: Record<string, unknown>[];
114
131
  }>, dialect: "tidb" | "pg"): Promise<void>;
115
- /** S-287:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensurePgPermissionRuleSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
132
+ /** [ref]:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensurePgPermissionRuleSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
116
133
  export declare const PERMISSION_RULE_INDEXES: readonly IndexSpec[];
117
134
  export declare function ensurePgPermissionRuleSchema(q: PgQueryFn): Promise<void>;
118
135
  /**
@@ -124,9 +141,14 @@ export declare function ensurePgPermissionRuleSchema(q: PgQueryFn): Promise<void
124
141
  * 种别前缀让两族键不可能相撞(`principal:` vs `local-owner`)。
125
142
  */
126
143
  export declare function buildRuleOwnerKey(owner: RuleOwner): string;
127
- /** 内容三列 + 观测向量的完整性指纹(core `ruleStoreChecksum` 同精神;**不含** rev/counter —— 那两样
144
+ /** 内容三列 + 观测向量 + **文法戳**(非 NULL 时)的完整性指纹(core `ruleStoreChecksum` 同精神;**不含** rev/counter —— 那两样
128
145
  * 是元数据轴,`nextDot` 只动 counter 就不该迫使重算内容指纹)。
129
146
  *
147
+ * 🔴 戳在指纹里(`grammar` 在场 ⇒ 进规范体;缺席 ⇒ 键不在,字节与 7.134.0 的算法逐字节相同 —— 存量无戳行的指纹一个字节不变,
148
+ * 升级不重写任何存量桶)。为什么要进:7.134.x / 引擎 7.54.x 的副本不读戳,若戳在指纹外,它们会把本版新文法写下的 deny 读成「无形」、
149
+ * 什么也不拒就放行;戳进指纹后,它们对带戳桶按旧算法重算比不上、**整桶拒(响亮)**。代价与推论:戳列与指纹必须**同一条语句**写
150
+ * (建行的 INSERT、整桶回写的 UPDATE),所以取 dot 的计数 UPDATE 不碰戳 —— 它不读桶体、没法重算指纹。
151
+ *
130
152
  * 导出(纯数据 ⇒ `build*`)是为了让**取证测试**能造一条「指纹自洽但语义矛盾」的行 —— 那正是
131
153
  * codex round1 [high] 二的形:一条只靠指纹是拦不住的坏行,必须由语义筛拦。 */
132
154
  export declare function buildRuleBucketChecksum(body: {
@@ -134,6 +156,8 @@ export declare function buildRuleBucketChecksum(body: {
134
156
  tombstones: readonly unknown[];
135
157
  quarantined: readonly unknown[];
136
158
  observedVector?: RuleSyncFrontier;
159
+ /** 这只桶的行写在哪一版规则文法里(`SESSION_RULES_GRAMMAR` 的数);缺席 = 存量无戳行(列 NULL)。 */
160
+ grammar?: number;
137
161
  }): string;
138
162
  /**
139
163
  * SQL 双方言的 {@link DurableRulePartitionProvider} —— [ref] 里的 **durable 分区后端**
@@ -151,6 +175,16 @@ export declare class SqlDurableRulePartitionProvider implements DurableRuleParti
151
175
  forPrincipal(principal: string | undefined): DurableRulePartition;
152
176
  forLocalOwner(): DurableRulePartition;
153
177
  }
178
+ /**
179
+ * 一条审批记录的属主 —— 记录自带的 `owner`,缺席时是 v1 记录的 `principal`;读法只有引擎的 `readRuleOwner`(两只店的写口与 SQL 店读口同用):
180
+ * 读不出 ⇒ `undefined`(闭集外的种类、缺 / 纯空白的主体名)。写口据此「只写读得回来的属主」—— 否则落下的行会在读口 / 重放时才被拒(SQL 一行读不出,File 日志重放整面 fail-closed)。
181
+ */
182
+ export declare function recordOwnerOf(record: {
183
+ readonly owner?: unknown;
184
+ readonly principal?: unknown;
185
+ }): RuleOwner | undefined;
186
+ /** 写口拒句(两只店同一句):属主引擎读不出,记录不落。 */
187
+ export declare function refusedOwnerSentence(recordId: string): string;
154
188
  /**
155
189
  * durable 审批记录。CAS **按 rev**,不按 state —— core 的原话:批记录的第二个候选会 redeemed→redeemed,
156
190
  * 只比 state 的两次并发重试会**都**认为自己看到了预期状态,各铸一个 dot、各写一次,后者静默覆盖前者的
@@ -439,7 +473,7 @@ export interface UnreadableRuleBucket {
439
473
  }
440
474
  /**
441
475
  * M11 写进的读数账 —— 三格与一次性迁移段那一只收据账(`one-time-migrations.ts` 的 `MigrationReceipts`)上的同名三格**同名同形**,迁移段把它的账直接递进来
442
- * (S-1594:一次起服一只收据账,M11 不另起第二套):删掉的行在那只桶的回写**提交的那一刻**追加,之后任何一步失败,拒因随账带走它们。
476
+ * ([ref]:一次起服一只收据账,M11 不另起第二套):删掉的行在那只桶的回写**提交的那一刻**追加,之后任何一步失败,拒因随账带走它们。
443
477
  */
444
478
  export interface UndurableScopePurgeReadings {
445
479
  /** 删掉的行(一行一条读数;每只桶的回写提交之后才追加)。 */
@@ -468,7 +502,7 @@ export interface UndurableScopePurgeDb {
468
502
  * 本店也不实现同步(见 `apply` 的 sync-join 臂)。
469
503
  * 幂等:第二跑零命中零写(读不出的桶每一跑照报,直到有人处置)。
470
504
  * 读数写进调用方递进来的账(`into`,{@link UndurableScopePurgeReadings}):删掉的行在那只桶的回写提交之后追加 ⇒ 本函数半途抛出时,已删的行已经在账上;
471
- * 错误**原样**上抛(不加工、不自铸拒因句 —— 收据由迁移段那一只收据账随拒因带走,S-1594)。
505
+ * 错误**原样**上抛(不加工、不自铸拒因句 —— 收据由迁移段那一只收据账随拒因带走,[ref])。
472
506
  */
473
507
  export declare function purgeUndurableScopeRows(db: UndurableScopePurgeDb, dialect: "tidb" | "pg", into: UndurableScopePurgeReadings, now?: () => number): Promise<void>;
474
508
  /** 三个 SQL 面的一次性装配束(one driver, three faces)。`durable` = [ref] 的 durable 分区后端;
@@ -1,6 +1,6 @@
1
1
  import { createHash, randomBytes, randomUUID } from "node:crypto";
2
2
  import { z } from "zod";
3
- import { applyTombstones, assertDeleteDeltaCarriesNoAdd, assertRedemptionNotQuarantined, assertWriteDeltaScopeDurable, foldDelta, isValidDurableScope, parseRuleText, readRowBehavior, screenRuleSyncState, PERMISSION_RULE_WRITER, RULE_ADD_ORIGINS, RULE_APPROVAL_KINDS, RULE_APPROVAL_RECORD_SCHEMA, RULE_APPROVAL_STATES, RULE_BEHAVIORS, RULE_SYNC_DROP_CODES, EDITED_RULE_BREADTH_WARNING_CODES, PERSISTED_RULE_MATCHES, UNCOVERED_SEGMENT_REASONS, EMPTY_DURABLE_RULE_PARTITION, } from "@sema-agent/core";
3
+ import { applyTombstones, assertDeleteDeltaCarriesNoAdd, assertRedemptionNotQuarantined, assertWriteDeltaScopeDurable, foldDelta, isValidDurableScope, parseRuleText, readRowBehavior, screenRuleSyncState, PERMISSION_RULE_WRITER, RULE_ADD_ORIGINS, RULE_APPROVAL_KINDS, RULE_APPROVAL_RECORD_SCHEMA, RULE_APPROVAL_STATES, RULE_BEHAVIORS, RULE_SYNC_DROP_CODES, EDITED_RULE_BREADTH_WARNING_CODES, PERSISTED_RULE_MATCHES, UNCOVERED_SEGMENT_REASONS, EMPTY_DURABLE_RULE_PARTITION, PERMISSION_RULES_LATER_GRAMMAR_CODE, RULE_OFFER_KINDS, SESSION_RULES_GRAMMAR, readRuleGrammarStamp, readRuleOwner, } from "@sema-agent/core";
4
4
  import { dialectProtocolJsonEncoder, sqlDbNowMs, SQL_DB_NOW_MS } from "./sql-driver.js";
5
5
  import { isMissingColumnError } from "./sql-errors.js";
6
6
  import { canonicalJsonStringify } from "@sema-agent/core";
@@ -64,11 +64,24 @@ function readBucketRowBehavior(raw, what, ownerKey) {
64
64
  }
65
65
  class BucketRefusedError extends Error {
66
66
  verdict;
67
- constructor(verdict, evidence) {
67
+ code;
68
+ constructor(verdict, evidence, code) {
68
69
  super(`${verdict} ${evidence}`);
69
70
  this.verdict = verdict;
71
+ if (code !== undefined)
72
+ this.code = code;
70
73
  }
71
74
  }
75
+ function readBucketStamp(ownerKey, stamp) {
76
+ const absent = stamp === null || stamp === undefined;
77
+ const read = readRuleGrammarStamp(absent ? undefined : stamp, SESSION_RULES_GRAMMAR, { rules: `the rules in permission_rule bucket ${ownerKey}`, held: "rows" });
78
+ if (!("got" in read))
79
+ return absent ? undefined : read.grammar;
80
+ if (read.later === true) {
81
+ throw new BucketRefusedError(read.sentence, "— loading zero rules and refusing every write until then; the row is left as it is", PERMISSION_RULES_LATER_GRAMMAR_CODE);
82
+ }
83
+ throw new BucketRefusedError(read.sentence, "— refusing the whole bucket; the row is left as it is");
84
+ }
72
85
  const WritablePersistedRuleSchema = PersistedRuleRowSchema.extend({ behavior: z.enum(RULE_BEHAVIORS) });
73
86
  const WritableRuleTombstoneSchema = RuleTombstoneSchema.extend({ behavior: z.enum(RULE_BEHAVIORS) });
74
87
  const FrontierSchema = z.record(z.string(), z.number().int().nonnegative().safe());
@@ -77,9 +90,9 @@ const RedeemedDotsSchema = z.record(z.string(), RuleDotSchema);
77
90
  const RuleEditedSchema = z
78
91
  .object({ index: z.number().int().nonnegative().safe(), text: z.string(), at: z.string(), warnings: z.array(z.enum(EDITED_RULE_BREADTH_WARNING_CODES)).optional() })
79
92
  .strict();
80
- const RuleOffer2Schema = z.union([
81
- z.object({ kind: z.literal("single"), candidate: z.number().int().nonnegative().safe() }).strict(),
82
- z
93
+ const RULE_OFFER2_ARMS = {
94
+ single: z.object({ kind: z.literal("single"), candidate: z.number().int().nonnegative().safe() }).strict(),
95
+ batch: z
83
96
  .object({
84
97
  kind: z.literal("batch"),
85
98
  candidates: z.array(z.number().int().nonnegative().safe()),
@@ -88,7 +101,8 @@ const RuleOffer2Schema = z.union([
88
101
  uncoveredDetail: z.array(z.object({ segment: z.string(), reason: z.enum(UNCOVERED_SEGMENT_REASONS) }).strict()).optional(),
89
102
  })
90
103
  .strict(),
91
- ]);
104
+ };
105
+ export const RuleOffer2Schema = z.union([RULE_OFFER2_ARMS.single, RULE_OFFER2_ARMS.batch]);
92
106
  export const PERMISSION_RULE_TABLE = "permission_rule";
93
107
  export const PERMISSION_RULE_APPROVAL_TABLE = "permission_rule_approval";
94
108
  export const PERMISSION_RULE_TICKET_TABLE = "permission_rule_ticket";
@@ -113,9 +127,13 @@ export const TIDB_PERMISSION_RULE_STATEMENTS = [
113
127
  observed_vector_json LONGTEXT NULL,
114
128
  last_round_at_ms BIGINT NULL,
115
129
  -- checksum:core \`ruleStoreChecksum\` 同精神的完整性指纹(覆盖内容三列 + observed_vector 在场时的
116
- -- 观测向量,不含 rev/counter——算法单点=buildRuleBucketChecksum)。
130
+ -- 观测向量 + grammar 非 NULL 时的文法戳,不含 rev/counter——算法单点=buildRuleBucketChecksum)。
117
131
  -- 读回不符 ⇒ throw(绝不静默当空店 —— core 对读失败的姿势明令如此)。
118
132
  checksum VARCHAR(190) NOT NULL,
133
+ -- grammar:这只桶的规则行写在哪一版**规则文法**里(引擎 \`SESSION_RULES_GRAMMAR\` 的数,每次写盖章;core 7.55.0 起 File 店同样每桶一戳)。
134
+ -- NULL = 戳存在之前写下的存量行,按本引擎的文法读、下一次写盖戳;晚于本引擎的戳整桶拒(码 permission_rules.later_grammar,一个字节不动)。
135
+ -- 非 NULL 的戳进 checksum(戳列与指纹同一条语句写;存量 NULL 行的指纹与升级前逐字节相同):不读戳的旧副本按旧算法重算比不上,整桶拒。可空整数:PG 的 INTEGER 驱动交回 number(BIGINT 会交回串)。
136
+ grammar INT NULL,
119
137
  created_at_ms BIGINT NOT NULL,
120
138
  updated_at_ms BIGINT NOT NULL,
121
139
  PRIMARY KEY (owner_key)
@@ -277,6 +295,7 @@ export async function ensurePgPermissionRuleSchema(q) {
277
295
  observed_vector_json TEXT COLLATE "C",
278
296
  last_round_at_ms BIGINT,
279
297
  checksum VARCHAR(190) COLLATE "C" NOT NULL,
298
+ grammar INTEGER,
280
299
  created_at_ms BIGINT NOT NULL,
281
300
  updated_at_ms BIGINT NOT NULL,
282
301
  PRIMARY KEY (owner_key)
@@ -357,15 +376,16 @@ async function refusingUnreadableColumns(what, fn) {
357
376
  }
358
377
  }
359
378
  function bucketRowColumns(dialect) {
360
- return `actor, counter, rev, ${jsonColumnText(dialect, "rules_json")}, ${jsonColumnText(dialect, "tombstones_json")}, ${jsonColumnText(dialect, "quarantined_json")}, ${jsonColumnText(dialect, "observed_vector_json")}, checksum`;
379
+ return `actor, counter, rev, ${jsonColumnText(dialect, "rules_json")}, ${jsonColumnText(dialect, "tombstones_json")}, ${jsonColumnText(dialect, "quarantined_json")}, ${jsonColumnText(dialect, "observed_vector_json")}, checksum, grammar`;
361
380
  }
362
381
  function decodeBucketRow(ownerKey, row) {
363
382
  const at = `${PERMISSION_RULE_TABLE} bucket ${ownerKey}`;
383
+ const grammar = readBucketStamp(ownerKey, row.grammar);
364
384
  const rulesRaw = decodeJsonColumn(row.rules_json, readRulesJson, `${at}.rules_json`);
365
385
  const tombstonesRaw = decodeJsonColumn(row.tombstones_json, readTombstonesJson, `${at}.tombstones_json`);
366
386
  const quarantinedRaw = decodeJsonColumn(row.quarantined_json, readQuarantinedJson, `${at}.quarantined_json`);
367
387
  const observedVector = row.observed_vector_json === null || row.observed_vector_json === undefined ? undefined : decodeJsonColumn(row.observed_vector_json, readObservedVectorJson, `${at}.observed_vector_json`);
368
- const expected = buildRuleBucketChecksum({ rules: rulesRaw, tombstones: tombstonesRaw, quarantined: quarantinedRaw, ...(observedVector !== undefined ? { observedVector } : {}) });
388
+ const expected = buildRuleBucketChecksum({ rules: rulesRaw, tombstones: tombstonesRaw, quarantined: quarantinedRaw, ...(observedVector !== undefined ? { observedVector } : {}), ...(grammar !== undefined ? { grammar } : {}) });
369
389
  if (String(row.checksum ?? "") !== expected) {
370
390
  throw new BucketRefusedError(`permission_rule bucket ${ownerKey} failed its integrity check`, `(stored ${String(row.checksum)}, computed ${expected}) — refusing the whole bucket rather than reporting a partial rule set`);
371
391
  }
@@ -392,6 +412,14 @@ function decodeBucketRow(ownerKey, row) {
392
412
  tombstones,
393
413
  quarantined,
394
414
  ...(observedVector !== undefined ? { observedVector } : {}),
415
+ ...(grammar !== undefined ? { grammar } : {}),
416
+ };
417
+ }
418
+ function fencedCasWhere(dialect, firstPlaceholder, ownerKey, cas) {
419
+ const ph = (offset) => (dialect === "tidb" ? "?" : `$${firstPlaceholder + offset}`);
420
+ return {
421
+ sql: `owner_key = ${ph(0)} AND ${cas.column} = ${ph(1)} AND (grammar IS NULL OR grammar <= ${ph(2)})`,
422
+ params: [ownerKey, cas.expected, SESSION_RULES_GRAMMAR],
395
423
  };
396
424
  }
397
425
  async function writeBucket(exec, dialect, ownerKey, cur, next, nowMs) {
@@ -401,16 +429,17 @@ async function writeBucket(exec, dialect, ownerKey, cur, next, nowMs) {
401
429
  }
402
430
  const body = { rules: next.rules, tombstones: next.tombstones, quarantined: cur.quarantined, ...(cur.observedVector !== undefined ? { observedVector: cur.observedVector } : {}) };
403
431
  const enc = dialectProtocolJsonEncoder(dialect);
432
+ const where = fencedCasWhere(dialect, 7, ownerKey, { column: "rev", expected: cur.rev });
404
433
  const affected = await exec(dialect === "tidb"
405
- ? `UPDATE ${PERMISSION_RULE_TABLE} SET rules_json = ?, tombstones_json = ?, quarantined_json = ?, checksum = ?, rev = rev + 1, updated_at_ms = ? WHERE owner_key = ? AND rev = ?`
406
- : `UPDATE ${PERMISSION_RULE_TABLE} SET rules_json = $1, tombstones_json = $2, quarantined_json = $3, checksum = $4, rev = rev + 1, updated_at_ms = $5 WHERE owner_key = $6 AND rev = $7`, [
434
+ ? `UPDATE ${PERMISSION_RULE_TABLE} SET rules_json = ?, tombstones_json = ?, quarantined_json = ?, checksum = ?, grammar = ?, rev = rev + 1, updated_at_ms = ? WHERE ${where.sql}`
435
+ : `UPDATE ${PERMISSION_RULE_TABLE} SET rules_json = $1, tombstones_json = $2, quarantined_json = $3, checksum = $4, grammar = $5, rev = rev + 1, updated_at_ms = $6 WHERE ${where.sql}`, [
407
436
  enc(next.rules, "permission_rule.rules_json"),
408
437
  enc(next.tombstones, "permission_rule.tombstones_json"),
409
438
  enc(cur.quarantined, "permission_rule.quarantined_json"),
410
- buildRuleBucketChecksum(body),
439
+ buildRuleBucketChecksum({ ...body, grammar: SESSION_RULES_GRAMMAR }),
440
+ SESSION_RULES_GRAMMAR,
411
441
  nowMs,
412
- ownerKey,
413
- cur.rev,
442
+ ...where.params,
414
443
  ]);
415
444
  return affected === 1;
416
445
  }
@@ -446,9 +475,9 @@ class SqlDurableRulePartition {
446
475
  async ensureBucket() {
447
476
  const nowMs = this.now();
448
477
  const empty = { rules: [], tombstones: [], quarantined: [] };
449
- await this.db.query(this.q(`INSERT IGNORE INTO ${PERMISSION_RULE_TABLE} (owner_key, owner_kind, principal, actor, counter, rev, rules_json, tombstones_json, quarantined_json, observed_vector_json, last_round_at_ms, checksum, created_at_ms, updated_at_ms)
450
- VALUES (?, ?, ?, ?, 0, 0, ?, ?, ?, NULL, NULL, ?, ?, ?)`, `INSERT INTO ${PERMISSION_RULE_TABLE} (owner_key, owner_kind, principal, actor, counter, rev, rules_json, tombstones_json, quarantined_json, observed_vector_json, last_round_at_ms, checksum, created_at_ms, updated_at_ms)
451
- VALUES ($1, $2, $3, $4, 0, 0, $5, $6, $7, NULL, NULL, $8, $9, $10) ON CONFLICT (owner_key) DO NOTHING`), [
478
+ await this.db.query(this.q(`INSERT IGNORE INTO ${PERMISSION_RULE_TABLE} (owner_key, owner_kind, principal, actor, counter, rev, rules_json, tombstones_json, quarantined_json, observed_vector_json, last_round_at_ms, checksum, grammar, created_at_ms, updated_at_ms)
479
+ VALUES (?, ?, ?, ?, 0, 0, ?, ?, ?, NULL, NULL, ?, ?, ?, ?)`, `INSERT INTO ${PERMISSION_RULE_TABLE} (owner_key, owner_kind, principal, actor, counter, rev, rules_json, tombstones_json, quarantined_json, observed_vector_json, last_round_at_ms, checksum, grammar, created_at_ms, updated_at_ms)
480
+ VALUES ($1, $2, $3, $4, 0, 0, $5, $6, $7, NULL, NULL, $8, $9, $10, $11) ON CONFLICT (owner_key) DO NOTHING`), [
452
481
  this.ownerKey,
453
482
  this.owner.kind,
454
483
  this.owner.kind === "principal" ? this.owner.principal : null,
@@ -456,14 +485,15 @@ class SqlDurableRulePartition {
456
485
  this.enc([], "permission_rule.rules_json"),
457
486
  this.enc([], "permission_rule.tombstones_json"),
458
487
  this.enc([], "permission_rule.quarantined_json"),
459
- buildRuleBucketChecksum(empty),
488
+ buildRuleBucketChecksum({ ...empty, grammar: SESSION_RULES_GRAMMAR }),
489
+ SESSION_RULES_GRAMMAR,
460
490
  nowMs,
461
491
  nowMs,
462
492
  ]);
463
493
  }
464
494
  async list() {
465
495
  const s = await this.read();
466
- return { rules: applyTombstones(s.rules, s.tombstones), tombstones: s.tombstones, rev: s.rev, checksum: buildRuleBucketChecksum({ rules: s.rules, tombstones: s.tombstones, quarantined: s.quarantined, ...(s.observedVector !== undefined ? { observedVector: s.observedVector } : {}) }) };
496
+ return { rules: applyTombstones(s.rules, s.tombstones), tombstones: s.tombstones, rev: s.rev, checksum: buildRuleBucketChecksum({ rules: s.rules, tombstones: s.tombstones, quarantined: s.quarantined, ...(s.observedVector !== undefined ? { observedVector: s.observedVector } : {}), ...(s.grammar !== undefined ? { grammar: s.grammar } : {}) }) };
467
497
  }
468
498
  async quarantined() {
469
499
  return (await this.read()).quarantined;
@@ -475,13 +505,15 @@ class SqlDurableRulePartition {
475
505
  nextDot: async () => {
476
506
  await this.ensureBucket();
477
507
  for (let attempt = 0; attempt < NEXT_DOT_MAX_ATTEMPTS; attempt++) {
478
- const { rows } = await this.db.query(this.q(`SELECT actor, counter FROM ${PERMISSION_RULE_TABLE} WHERE owner_key = ?`, `SELECT actor, counter FROM ${PERMISSION_RULE_TABLE} WHERE owner_key = $1`), [this.ownerKey]);
508
+ const { rows } = await this.db.query(this.q(`SELECT actor, counter, grammar FROM ${PERMISSION_RULE_TABLE} WHERE owner_key = ?`, `SELECT actor, counter, grammar FROM ${PERMISSION_RULE_TABLE} WHERE owner_key = $1`), [this.ownerKey]);
479
509
  const row = rows[0];
480
510
  if (row === undefined)
481
511
  throw new Error(`permission_rule bucket ${this.ownerKey} vanished while minting a dot`);
512
+ readBucketStamp(this.ownerKey, row.grammar);
482
513
  const cur = Number(row.counter);
483
514
  const next = cur + 1;
484
- const { affected } = await this.db.query(this.q(`UPDATE ${PERMISSION_RULE_TABLE} SET counter = ?, updated_at_ms = ? WHERE owner_key = ? AND counter = ?`, `UPDATE ${PERMISSION_RULE_TABLE} SET counter = $1, updated_at_ms = $2 WHERE owner_key = $3 AND counter = $4`), [next, this.now(), this.ownerKey, cur]);
515
+ const where = fencedCasWhere(this.db.dialect, 3, this.ownerKey, { column: "counter", expected: cur });
516
+ const { affected } = await this.db.query(this.q(`UPDATE ${PERMISSION_RULE_TABLE} SET counter = ?, updated_at_ms = ? WHERE ${where.sql}`, `UPDATE ${PERMISSION_RULE_TABLE} SET counter = $1, updated_at_ms = $2 WHERE ${where.sql}`), [next, this.now(), ...where.params]);
485
517
  if (affected === 1)
486
518
  return { actor: String(row.actor), counter: next };
487
519
  }
@@ -554,6 +586,12 @@ export class SqlDurableRulePartitionProvider {
554
586
  return new SqlDurableRulePartition(this.db, { kind: "local-owner" }, this.now);
555
587
  }
556
588
  }
589
+ export function recordOwnerOf(record) {
590
+ return readRuleOwner(record.owner ?? { kind: "principal", principal: record.principal });
591
+ }
592
+ export function refusedOwnerSentence(recordId) {
593
+ return `refusing to create approval record ${recordId}: its owner is not one the engine reads as an owner (a principal name must be a non-blank string; the kind must be a member of the owner set) — nothing was written`;
594
+ }
557
595
  export class SqlRuleApprovalRecordStore {
558
596
  db;
559
597
  now;
@@ -575,9 +613,12 @@ export class SqlRuleApprovalRecordStore {
575
613
  const row = rows[0];
576
614
  if (row === undefined)
577
615
  return undefined;
578
- const ownerKind = String(row.owner_kind);
579
616
  const principal = row.principal === null || row.principal === undefined ? undefined : String(row.principal);
580
- const identity = ownerKind === "principal" ? { principal: principal ?? "" } : { owner: { kind: "local-owner" } };
617
+ const rowOwner = readRuleOwner({ kind: row.owner_kind, ...(principal !== undefined ? { principal } : {}) });
618
+ if (rowOwner === undefined) {
619
+ throw new Error(`${PERMISSION_RULE_APPROVAL_TABLE} row ${id} carries an owner the engine does not read as an owner (owner_kind ${JSON.stringify(String(row.owner_kind))}) — refusing the record rather than reading it as another owner's`);
620
+ }
621
+ const identity = rowOwner.kind === "principal" ? { principal: rowOwner.principal } : { owner: rowOwner };
581
622
  if (Number(row.version) !== RULE_APPROVAL_RECORD_SCHEMA) {
582
623
  return { staleSchema: true, id: String(row.record_id), ...identity };
583
624
  }
@@ -612,7 +653,9 @@ export class SqlRuleApprovalRecordStore {
612
653
  }
613
654
  async create(record) {
614
655
  const nowMs = this.now();
615
- const owner = record.owner ?? { kind: "principal", principal: record.principal ?? "" };
656
+ const owner = recordOwnerOf(record);
657
+ if (owner === undefined)
658
+ throw new Error(refusedOwnerSentence(record.id));
616
659
  await this.db.query(this.q(`INSERT INTO ${PERMISSION_RULE_APPROVAL_TABLE} (record_id, owner_key, owner_kind, principal, kind, state, version, rev, candidates_json, offers_json, selected_offer, redeemed_dots_json, tool_call_id, bound_input_hash, command, edited_json, created_at_iso, created_at_ms, updated_at_ms)
617
660
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, `INSERT INTO ${PERMISSION_RULE_APPROVAL_TABLE} (record_id, owner_key, owner_kind, principal, kind, state, version, rev, candidates_json, offers_json, selected_offer, redeemed_dots_json, tool_call_id, bound_input_hash, command, edited_json, created_at_iso, created_at_ms, updated_at_ms)
618
661
  VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)`), [
@@ -36,7 +36,7 @@ export declare class PgCostQuota implements QuotaTracker {
36
36
  * DATETIME(3)→TIMESTAMPTZ(3), inline `KEY idx_window`→separate CREATE INDEX). DISJOINT from other stores'
37
37
  * tables, so a self-contained ensureSchema is safe (the central pg-pool aggregation is done separately). */
38
38
  export declare const PG_COST_QUOTA_SCHEMA: string[];
39
- /** S-287:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensureSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
39
+ /** [ref]:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensureSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
40
40
  export declare const COST_QUOTA_INDEXES: readonly IndexSpec[];
41
41
  /** Idempotent schema apply for the cost_quota table (the PG twin of tidb-pool.ts ensureSchema). */
42
42
  export declare function ensureSchema(pool: Pool | PoolClient): Promise<void>;
@@ -80,7 +80,7 @@ export declare const ENSURE_SCHEMA_LOCK_KEY = 4906;
80
80
  * `tidb-pool.ts acquireEnsureSchemaLock` 的逐条同形(循环共用 `ensure-schema-lock-policy.ts`)。轮到拿到为止;坏连接连续抛上抛
81
81
  * (每条 DDL 本来就各自幂等),而不是把启动挂死。
82
82
  *
83
- * 🔴 **为什么不能再用阻塞的 `pg_advisory_lock()`**(S-287 复审 H1,对 7.82.1 的回归):本仓自 S-287 起在
83
+ * 🔴 **为什么不能再用阻塞的 `pg_advisory_lock()`**([ref] 复审 H1,对 7.82.1 的回归):本仓自 [ref] 起在
84
84
  * 锁窗内发 `CREATE INDEX CONCURRENTLY`,而 CIC 的末相要**等掉同库里所有 xmin 比它老的运行中后端**
85
85
  * (`WaitForOlderSnapshots`)。一条卡在 `SELECT pg_advisory_lock($1)` 里的副本**正是**一条持着快照的运行中
86
86
  * 查询 —— 它等锁、锁等 CIC、CIC 等它:三方互等。命中形是「全新 PG 库 + 多副本同时起」(表刚建完 ⇒ 索引
@@ -101,7 +101,7 @@ export declare function releasePgEnsureSchemaLock(client: pg.PoolClient, tag: st
101
101
  * calls ensurePgSchema), and in production every replica calls it at boot. Concurrent DDL on the SAME table makes
102
102
  * PG raise `tuple concurrently updated` in its catalog. We serialize the entire run behind a session-level
103
103
  * advisory lock, acquired NON-BLOCKINGLY with polling ({@link acquirePgEnsureSchemaLock} — 阻塞形会与本函数
104
- * 自 S-287 起发的 `CREATE INDEX CONCURRENTLY` 三方互等,理由写在那只函数的头注里): the first caller does
104
+ * 自 [ref] 起发的 `CREATE INDEX CONCURRENTLY` 三方互等,理由写在那只函数的头注里): the first caller does
105
105
  * the real CREATE/index work, the rest poll from OUTSIDE the database then find every statement already
106
106
  * satisfied (IF NOT EXISTS ⇒ no-op), so there is no catalog race. The DDL semantics are
107
107
  * unchanged — only its timing is serialized. The advisory lock is SESSION (connection)-level, so the lock and
@@ -93,6 +93,8 @@ export const PG_SCHEMA_STATEMENTS = [
93
93
  reopen_reason VARCHAR(32) COLLATE "C",
94
94
  terminal_at_ms BIGINT,
95
95
  gate_kind VARCHAR(32) COLLATE "C",
96
+ -- approval_card(core 7.55.0 #1468 P1 阶段二):门上的卡词照存;语义、读者与「本仓不发 ALTER」见 MySQL 孪生(tidb-pool.ts 同名列的行内注)。
97
+ approval_card TEXT COLLATE "C",
96
98
  bound_input_hash VARCHAR(190) COLLATE "C",
97
99
  -- pending_steer_queue / pending_steer_rev:队列化后的 durable steering(core 5.14.0 #147)。两列的语义、
98
100
  -- 退役的单座列 pending_steer 为何删列(以及存量库里仍带着它时的拒启臂)、48000 字节预算、
@@ -340,8 +342,9 @@ export const PG_SCHEMA_STATEMENTS = [
340
342
  summary TEXT COLLATE "C" NOT NULL,
341
343
  enqueued_at_ms BIGINT NOT NULL,
342
344
  -- 1.109 delivery envelope. kind NULL = a LEGACY \`workflow_complete\` row (the shape that predates the
343
- -- envelope); readers must keep treating NULL as that kind, it is not "unknown". payload = the kind's
344
- -- body, NULL for the legacy shape.
345
+ -- envelope); readers must keep treating NULL as that kind, it is not "unknown". payload = the kind's JSON
346
+ -- extras: task_notification: task_type / result / …; workflow_complete: at most {"completionId": …} (the
347
+ -- engine's own correlation id, verbatim; NULL when the engine minted none).
345
348
  kind VARCHAR(24) COLLATE "C",
346
349
  payload TEXT COLLATE "C",
347
350
  PRIMARY KEY (session_id, run_id),
@@ -40,7 +40,7 @@ export declare class PgRateLimiter implements RateGate {
40
40
  * atomic ON CONFLICT increment.
41
41
  */
42
42
  export declare const PG_RATE_LIMITER_SCHEMA: string[];
43
- /** S-287:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensureSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
43
+ /** [ref]:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensureSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
44
44
  export declare const RATE_LIMIT_INDEXES: readonly IndexSpec[];
45
45
  /** Self-contained schema bootstrap for tests (the rate_limit table is disjoint from other stores). */
46
46
  export declare function ensureSchema(pool: Pool | PoolClient): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { BaseSessionStorage, type AcquiredSession, type PlacedSessionRow, type SessionMetadata, type SessionPlacementRecord, type SessionStore, type SessionTreeEntry, type SessionWriteOptions } from "@sema-agent/core";
1
+ import { BaseSessionStorage, type AcquiredSession, type PlacedSessionRow, type SessionHead, type SessionMetadata, type SessionPlacementRecord, type SessionStore, type SessionTreeEntry, type SessionWriteOptions } from "@sema-agent/core";
2
2
  import type { Pool, PoolClient } from "pg";
3
3
  import type { SessionSummary } from "./store-contracts.js";
4
4
  import { type SessionRowPatch } from "../session-row.js";
@@ -16,7 +16,7 @@ import { type IndexSpec } from "./ensure-index.js";
16
16
  * drop-and-recreate, and NO new `ALTER TABLE` seams are added here; fold into the CREATE instead.
17
17
  */
18
18
  export declare const PG_SESSION_SCHEMA: string[];
19
- /** S-287:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensureSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
19
+ /** [ref]:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensureSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
20
20
  export declare const SESSION_INDEXES: readonly IndexSpec[];
21
21
  /** Idempotent schema apply for this store's tables (the test calls this; production aggregation is separate). */
22
22
  export declare function ensureSchema(pool: Pool | PoolClient): Promise<void>;
@@ -51,7 +51,7 @@ export declare class PgSessionStorage extends BaseSessionStorage {
51
51
  }
52
52
  /**
53
53
  * PostgreSQL-backed {@link SessionStore} — the PG twin of {@link TiDBSessionStore}. Maps the
54
- * `SessionStore` surface (acquire / register / ownerOf / touch / release) onto {@link PgSessionStorage}.
54
+ * `SessionStore` surface (acquire / register / headOf / touch / release) onto {@link PgSessionStorage}.
55
55
  */
56
56
  export declare class PgSessionStore implements SessionStore {
57
57
  private readonly pool;
@@ -75,11 +75,11 @@ export declare class PgSessionStore implements SessionStore {
75
75
  private load;
76
76
  /** Idempotently create a session_meta row with an owner (core `SessionStore.register`). Existing owner is never overwritten. */
77
77
  register(sessionId: string, owner: string | null): Promise<void>;
78
- /** acquire 的建行(唯一一处;S-1770 委派继承律,只住在 `createPlacedSessionRow`,本店交既有读写口 —— TiDB 孪生同名方法同注)。 */
78
+ /** acquire 的建行(唯一一处;[ref] 委派继承律,只住在 `createPlacedSessionRow`,本店交既有读写口 —— TiDB 孪生同名方法同注)。 */
79
79
  private createOnAcquire;
80
- /** S-1770 委派继承律的认领口(TiDB 孪生 {@link TiDBSessionStore.claimOwnerless} 同义;句 = `CLAIM_OWNERLESS_PLACED_SQL`,规则在 `delegated-session-owner.ts`)。 */
80
+ /** [ref] 委派继承律的认领口(TiDB 孪生 {@link TiDBSessionStore.claimOwnerless} 同义;句 = `CLAIM_OWNERLESS_PLACED_SQL`,规则在 `delegated-session-owner.ts`)。 */
81
81
  claimOwnerless(sessionId: string, incarnation: string, owner: string): Promise<boolean>;
82
- /** 若干来源行的会话面(属主 + 化身)一次读回(TiDB 孪生同义;化身经与 `sessionFaceOf` 同一只解码,空 ⇒ 响亮拒)。 */
82
+ /** 若干来源行的会话面(属主 + 化身)一次读回(TiDB 孪生同义;活住客的投影 `sessionFaceFromRow`,空化身 ⇒ 响亮拒)。 */
83
83
  private sourceFaces;
84
84
  /** The one session_meta INSERT. Existing owner is never overwritten.
85
85
  * [ref]:`placement` 与行同一条 INSERT;`DO NOTHING` 臂 ⇒ 已存在行的元组永不被重写(first-write 不可变)。 */
@@ -92,21 +92,9 @@ export declare class PgSessionStore implements SessionStore {
92
92
  olderThanMs?: number;
93
93
  scope?: string;
94
94
  }): Promise<PlacedSessionRow[]>;
95
- /** Owner principal of a session, `null` if registered ownerless, `undefined` if no such session. */
96
- ownerOf(sessionId: string): Promise<string | null | undefined>;
97
- /** S-790:属主 + 化身一次读(TiDB 孪生 {@link TiDBSessionStore.sessionFaceOf} 同义;空化身 ⇒ 响亮拒)。 */
98
- sessionFaceOf(sessionId: string): Promise<SessionFace | undefined>;
99
- /** core `SessionStore.incarnationOf`:{@link sessionFaceOf} 的化身那一半(TiDB 孪生同义)。 */
100
- incarnationOf(sessionId: string): Promise<string | undefined>;
95
+ /** core `SessionStore.headOf` —— 属主、住客、叶子一条 PK SELECT 一行(TiDB 孪生 {@link TiDBSessionStore.headOf} 同义:本店按 id 读一行的唯一读口)。 */
96
+ headOf(sessionId: string): Promise<SessionHead | undefined>;
101
97
  touch(sessionId: string): Promise<void>;
102
- /** E18 — the session's current leaf SessionTreeEntry.id (session_meta.leaf_id). @see TiDBSessionStore.getLeafId
103
- * (single SELECT, no acquire/lock, cache-bypassing — safe to read mid-run for the resume-at turn-capture). */
104
- getLeafId(sessionId: string): Promise<string | null>;
105
- /** [ref] 六轮复审:owner+leafId 单行原子快照(@see TiDBSessionStore.getHead——混世代组合防)。 */
106
- getHead(sessionId: string): Promise<{
107
- owner: string | null;
108
- leafId: string | null;
109
- } | undefined>;
110
98
  /** Durable history is retained; just drop any in-flight cache entry.
111
99
  * 🔴 [ref] 义务 4:**placed 会话例外 —— release 是真删除**(理由/ABA 条件删/失败上浮三条读法逐字见
112
100
  * {@link TiDBSessionStore.release},本腿是它的 PG 孪生)。 */
@@ -15,9 +15,10 @@ import { classifySyncRelationshipByIds, SyncConflictError, StagedCommitOwnerChan
15
15
  import { isPgUniqueViolation } from "./sql-errors.js";
16
16
  import { BASELINE_IO_DEADLINE_MS, decodeInstructionSource, encodeInstructionSource } from "../instruction-source-notice.js";
17
17
  import { MANAGED_RETENTION } from "./retention-store-sql.js";
18
- import { SESSION_META_INCARNATION_COLUMN, carriedIncarnation, incarnationFromCell, mintSessionIncarnation, sessionFaceFromRow } from "../session-incarnation.js";
18
+ import { SESSION_META_INCARNATION_COLUMN, carriedIncarnation, headFromRow, incarnationFromCell, mintSessionIncarnation, sessionFaceFromRow } from "../session-incarnation.js";
19
19
  import { ensureIndexes } from "./ensure-index.js";
20
20
  import { assertFirstOwnerWritable, forkOwnerOf } from "./session-ownership.js";
21
+ import { forkCopyOf, forkPointOf } from "./session-fork.js";
21
22
  const isDupKey = isPgUniqueViolation;
22
23
  function baselineQuery(text, values) {
23
24
  return { text, values, query_timeout: BASELINE_IO_DEADLINE_MS };
@@ -219,7 +220,7 @@ export class PgSessionStore {
219
220
  }
220
221
  async register(sessionId, owner) {
221
222
  if (typeof owner !== "string" && owner !== null) {
222
- if ((await this.ownerOf(sessionId)) !== undefined)
223
+ if ((await this.headOf(sessionId)) !== undefined)
223
224
  return;
224
225
  assertFirstOwnerWritable(sessionId, owner);
225
226
  }
@@ -231,7 +232,7 @@ export class PgSessionStore {
231
232
  await createPlacedSessionRow(sessionId, placement, {
232
233
  readFaces: (ids) => this.sourceFaces(ids),
233
234
  insert: (owner) => this.insertMeta(sessionId, owner, placement),
234
- readOwner: () => this.ownerOf(sessionId),
235
+ readOwner: async () => (await this.headOf(sessionId))?.owner,
235
236
  }, this.log);
236
237
  }
237
238
  async claimOwnerless(sessionId, incarnation, owner) {
@@ -266,20 +267,12 @@ export class PgSessionStore {
266
267
  const res = await this.pool.query(sql, params);
267
268
  return res.rows.map((r) => placedRowFromRow(String(r.session_id), r, r.updated_at instanceof Date ? r.updated_at.getTime() : undefined));
268
269
  }
269
- async ownerOf(sessionId) {
270
- const res = await this.pool.query("SELECT owner FROM session_meta WHERE session_id = $1", [sessionId]);
270
+ async headOf(sessionId) {
271
+ const res = await this.pool.query("SELECT owner, incarnation, leaf_id FROM session_meta WHERE session_id = $1", [sessionId]);
271
272
  if (res.rows.length === 0)
272
273
  return undefined;
273
- return res.rows[0].owner ?? null;
274
- }
275
- async sessionFaceOf(sessionId) {
276
- const res = await this.pool.query("SELECT owner, incarnation FROM session_meta WHERE session_id = $1", [sessionId]);
277
- if (res.rows.length === 0)
278
- return undefined;
279
- return sessionFaceFromRow(sessionId, res.rows[0].owner ?? null, res.rows[0].incarnation);
280
- }
281
- async incarnationOf(sessionId) {
282
- return (await this.sessionFaceOf(sessionId))?.incarnation;
274
+ const r = res.rows[0];
275
+ return headFromRow(sessionId, r.owner ?? null, r.incarnation, r.leaf_id ?? null);
283
276
  }
284
277
  async touch(sessionId) {
285
278
  await this.pool.query("UPDATE session_meta SET updated_at = $1 WHERE session_id = $2", [
@@ -287,16 +280,6 @@ export class PgSessionStore {
287
280
  sessionId,
288
281
  ]);
289
282
  }
290
- async getLeafId(sessionId) {
291
- const r = await this.pool.query("SELECT leaf_id FROM session_meta WHERE session_id = $1", [sessionId]);
292
- return r.rows[0] ? (r.rows[0].leaf_id ?? null) : null;
293
- }
294
- async getHead(sessionId) {
295
- const r = await this.pool.query("SELECT owner, leaf_id FROM session_meta WHERE session_id = $1", [sessionId]);
296
- if (r.rows.length === 0)
297
- return undefined;
298
- return { owner: r.rows[0].owner ?? null, leafId: r.rows[0].leaf_id ?? null };
299
- }
300
283
  async release(sessionId) {
301
284
  this.pending.delete(sessionId);
302
285
  const placed = await this.placementOf(sessionId);
@@ -440,8 +423,12 @@ export class PgSessionStore {
440
423
  return null;
441
424
  const leafId = metaRes.rows[0].leaf_id ?? null;
442
425
  const forkOwner = forkOwnerOf(owner, metaRes.rows[0].owner ?? null) ?? null;
426
+ const storage = await PgSessionStorage.wake(this.pool, sourceId);
427
+ if (storage === null)
428
+ return null;
429
+ const point = await forkPointOf(storage);
443
430
  const eventRes = await this.pool.query(`SELECT entry_id, parent_id, type, ${jsonColumnText("pg", "payload")}, ts FROM session_event WHERE session_id = $1 ORDER BY seq ASC`, [sourceId]);
444
- const rows = eventRes.rows;
431
+ const { rows, leafId: forkLeafId } = forkCopyOf(eventRes.rows, leafId, point);
445
432
  const newId = uuidv7();
446
433
  const now = new Date();
447
434
  const conn = await this.pool.connect();
@@ -452,7 +439,7 @@ export class PgSessionStore {
452
439
  const payload = String(r.payload);
453
440
  await conn.query("INSERT INTO session_event (session_id, seq, entry_id, parent_id, type, payload, ts) VALUES ($1,$2,$3,$4,$5,$6::jsonb,$7)", [newId, seq, r.entry_id, r.parent_id ?? null, r.type, payload, r.ts]);
454
441
  }
455
- await conn.query("INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation) VALUES ($1,$2,$3,$4,$5,$6,$7)", [newId, forkOwner, now, now, leafId, rows.length, mintSessionIncarnation()]);
442
+ await conn.query("INSERT INTO session_meta (session_id, owner, created_at, updated_at, leaf_id, leaf_seq, incarnation) VALUES ($1,$2,$3,$4,$5,$6,$7)", [newId, forkOwner, now, now, forkLeafId, rows.length, mintSessionIncarnation()]);
456
443
  await conn.query("COMMIT");
457
444
  return newId;
458
445
  }
@@ -35,13 +35,13 @@ export interface AdbEnvDeps {
35
35
  /** [R78]#1: adb stderr markers that mean the DEVICE TRANSPORT died mid-op (not a normal command failure) —
36
36
  * typed retryable (reconnect + retry per idempotency), never a fake command result. Exported for tests.
37
37
  *
38
- * 🔴 **S-401 把这个判据的输入面改了一半(复审 F12 纠正:原来写的「此前 stderr 恒空 ⇒ 整条是死码」是
38
+ * 🔴 **[ref] 把这个判据的输入面改了一半(复审 F12 纠正:原来写的「此前 stderr 恒空 ⇒ 整条是死码」是
39
39
  * **overclaim**,被本车自己的真机读数推翻)**。`exec-out` 合流的是**设备**的 stderr;**adb 客户端自己的**
40
40
  * 诊断在两种传输下都照样走宿主 stderr。真机实测(同一台设备,拔掉 serial):
41
41
  * `adb -s BOGUS exec-out 'true'` ⇒ host exit **255** + stderr `error: device 'BOGUS' not found`;
42
42
  * `adb -s BOGUS shell -T -- 'true'` ⇒ host exit **1** + stderr `adb: device 'BOGUS' not found`。
43
- * ⇒ 本判据在 S-401 之前**对 adb 客户端级的传输故障是工作的**(这也正是原作者把词表写成这些 adb 自家
44
- * 措辞的原因);S-401 改变的是**设备侧 stderr 从此也进这条通道**。
43
+ * ⇒ 本判据在 [ref] 之前**对 adb 客户端级的传输故障是工作的**(这也正是原作者把词表写成这些 adb 自家
44
+ * 措辞的原因);[ref] 改变的是**设备侧 stderr 从此也进这条通道**。
45
45
  *
46
46
  * ⚠️ **随之而来的、如实登记的一格**:分流之后落到这里的 stderr **既有 adb 自己的诊断,也有设备命令自己的
47
47
  * 输出**(adb 客户端把两者写在同一个 fd 上,真机实测无法在传输层分开)。于是设备上一条自己打印
@@ -53,7 +53,7 @@ export interface AdbEnvDeps {
53
53
  export declare function isAdbTransportLost(stderr: string): boolean;
54
54
  export declare class RemoteAdbExecutionEnv implements RemoteExecutionEnv {
55
55
  /**
56
- * 🔴 **S-354 / core 7.20.0([ref])`canonicalPathAuthoritative: true`** —— 本适配器的 `canonicalPath`
56
+ * 🔴 **[ref] / core 7.20.0([ref])`canonicalPathAuthoritative: true`** —— 本适配器的 `canonicalPath`
57
57
  * 就是**命令真正跑的那块文件系统**的权威答案(`posix-shell-fs` 的 `canonicalPath` 原语,在设备 shell 里解到落点)。声明它 = 告诉引擎:整链答不出来是**解析器出了事**
58
58
  * (RPC 断、传输掉),不是「一个它看不见的命名空间」⇒ 读边界的执行期复核**拒**,而不是让词法判决站着。
59
59
  * 缺席是今天每个适配器的读法(整链沉默 ⇒ 词法判决成立、命令照跑),所以这一声明是**收紧**方向。
@@ -82,7 +82,7 @@ export declare class RemoteAdbExecutionEnv implements RemoteExecutionEnv {
82
82
  get homeDir(): string | undefined;
83
83
  /** 家目录的座(声明胜 · 否则首连时实测 · 实测缺席 ⇒ 缺席 + 一行 warn)。本车道**不对证**声明:Android 没有 POSIX 登录家目录,声明是运维的断言,照单全收。 */
84
84
  private readonly homeSeat;
85
- /** core 7.49.0 #1554:shell 子进程真拿到的 `CDPATH` 条目 —— 本车道的命令跑在 Android 设备的 shell 里(设备自己的 env),本类不读那份 env ⇒ `"unknown"`(core 契约:说不出就说 unknown,
85
+ /** core 7.49.0 [ref]:shell 子进程真拿到的 `CDPATH` 条目 —— 本车道的命令跑在 Android 设备的 shell 里(设备自己的 env),本类不读那份 env ⇒ `"unknown"`(core 契约:说不出就说 unknown,
86
86
  * 不许报一张没读过的空表;删除守卫因此对裸 `cd <相对名>` 之后的删除问人,而不是按「没有 CDPATH」放行)。 */
87
87
  readonly cdPath: "unknown";
88
88
  private readonly cfg;
@@ -156,7 +156,7 @@ export declare class RemoteAdbExecutionEnv implements RemoteExecutionEnv {
156
156
  joinPath(parts: string[]): Promise<Result<string, FileError>>;
157
157
  /** 文件面的门 —— 与 host/local-docker/k8s/e2b 的姿态对齐(它们的文件面在未连/已拆时都 fail-closed)。
158
158
  *
159
- * 🔴 **S-401 复审 F2:这道门此前只查 `destroyed`,不查 `connected`**,于是 `readBinaryFile` /
159
+ * 🔴 **[ref] 复审 F2:这道门此前只查 `destroyed`,不查 `connected`**,于是 `readBinaryFile` /
160
160
  * `readTextFile` / `readTextLines` / `appendFile` 能在**从没连过**的 env 上直接打一次真设备往返。
161
161
  * 在本批之前那只是个不一致;本批**新开的 `shell_v2` fail-closed 闸就长在 `connect()` 里**,
162
162
  * 所以「不查 connected」= 那道闸对整个读面**不生效** —— 而 `readTextFile` 把错误文本当文件内容返回
@@ -177,7 +177,7 @@ export declare class RemoteAdbExecutionEnv implements RemoteExecutionEnv {
177
177
  fileInfo(p: string, abortSignal?: AbortSignal): Promise<Result<FileInfo, FileError>>;
178
178
  listDir(p: string, abortSignal?: AbortSignal): Promise<Result<FileInfo[], FileError>>;
179
179
  readLink(p: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>>;
180
- /** S-362 / core 7.21.0 [ref] —— **实现**(表态:本腿实现 `canonicalChain`)。一次往返里的一个 `readlink`
180
+ /** [ref] / core 7.21.0 [ref] —— **实现**(表态:本腿实现 `canonicalChain`)。一次往返里的一个 `readlink`
181
181
  * 循环(上限 64、只锚不折、遇环即止),脚本与读法的单一属主在 `remote-shell.ts`,四条 shell 腿共用同一份。
182
182
  * 缺席读法用不上(本腿在场);`ok:false` 由 core 读作「这一次没有跳」,永不是拒绝。 */
183
183
  canonicalChain(p: string, abortSignal?: AbortSignal): Promise<Result<SymlinkChain, FileError>>;
@@ -207,7 +207,7 @@ export declare class RemoteAdbExecutionEnv implements RemoteExecutionEnv {
207
207
  /** Spawn the adb binary with the given args; collect stdout/stderr (+ raw bytes when binary), bound by timeout/abort. */
208
208
  private adb;
209
209
  /**
210
- * 🔴 **S-401 —— 本适配器跑设备命令的唯一往返形**(`exec` / `execStream` / `readBinaryFile` 三个调用点
210
+ * 🔴 **[ref] —— 本适配器跑设备命令的唯一往返形**(`exec` / `execStream` / `readBinaryFile` 三个调用点
211
211
  * 共用一只;此前 `exec-out` 写了三遍,于是「传输到底给不给退出码」这件事没有属主)。
212
212
  *
213
213
  * **`adb shell`(shell protocol v2)而不是 `adb exec-out`。** 协议出处 = adb 自己的 `adb help`:
@@ -226,7 +226,7 @@ export declare class RemoteAdbExecutionEnv implements RemoteExecutionEnv {
226
226
  * 与链原语 `remote-shell.ts` 的 `runSymlinkChain`(第 8 处)认的都是 `exitCode !== 0`,而这条传输恒答 0
227
227
  * ⇒ adb 腿上 `realpath` / `readlink` / `stat` / `ls` / `cat` **永不失败**,`canonicalPath` 把那行**错误
228
228
  * 文本**当成 canonical key 交给敏感路径门。⚠️ **复审 F15 纠正:原文写「五处」是数错了**,而且漏掉的
229
- * 第 8 处恰恰是最贵的一处 —— `canonicalChain`(S-362 / core 7.21.0 [ref],上一版刚接)在 exit 恒 0 下会把
229
+ * 第 8 处恰恰是最贵的一处 —— `canonicalChain`([ref] / core 7.21.0 [ref],上一版刚接)在 exit 恒 0 下会把
230
230
  * **合流进 stdout 的错误文本当成链上的跳**解析出来,等于给 core 的路径判官递一条**伪造的** symlink 链。
231
231
  *
232
232
  * 🔴 **`-T` 与 `--` 都是承重件,不是装饰**:
@@ -242,7 +242,7 @@ export declare class RemoteAdbExecutionEnv implements RemoteExecutionEnv {
242
242
  * {@link createCwdGuardedCall} 组出的那一串(带工作目录时含 cwd 守卫前缀:cd 失败 ⇒ 整条不跑)。
243
243
  */
244
244
  private deviceShellArgs;
245
- /** 本腿只定工作目录(缺省 cwd 规则 + 绝对化);串的形状归 {@link buildCwdEnvCommand} / {@link createCwdGuardedCall}(S-410:cwd 不可用 ⇒ 命令不跑;
245
+ /** 本腿只定工作目录(缺省 cwd 规则 + 绝对化);串的形状归 {@link buildCwdEnvCommand} / {@link createCwdGuardedCall}([ref]:cwd 不可用 ⇒ 命令不跑;
246
246
  * 车PL:buffered `exec` 上守卫触发 ⇒ `spawn_error`)。 */
247
247
  private workingDirOf;
248
248
  }