@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
@@ -1,12 +1,13 @@
1
- import { PAUSE_REGISTRY, SESSION_RULES_GRAMMAR, compileSessionRuleBucket, isGateKind, readSessionRulesShape, unreadableDenyEntries } from "@sema-agent/core";
2
- import { ASK_USER_QUESTION_TOOL_NAME } from "../approval-content-kind.js";
1
+ import { SESSION_RULES_GRAMMAR, compileSessionRuleBucket, isGateKind, readSessionRulesShape, unreadableDenyEntries } from "@sema-agent/core";
2
+ import { APPROVAL_GATE_KINDS, ASK_USER_QUESTION_TOOL_NAME, isApprovalGateKind } from "../approval-content-kind.js";
3
+ import { judgeCheckpointIndexCells } from "./checkpoint-index-columns.js";
3
4
  import { dialectProtocolJsonEncoder } from "./sql-driver.js";
4
5
  import { SCHEMA_STATEMENTS, acquireEnsureSchemaLock, releaseEnsureSchemaLock } from "./tidb-pool.js";
5
6
  import { PG_SCHEMA_STATEMENTS, acquirePgEnsureSchemaLock, releasePgEnsureSchemaLock } from "./pg-pool.js";
6
7
  import { CENTRAL_SCHEMA_INDEXES } from "./schema-indexes.js";
7
8
  import { ensureIndexes } from "./ensure-index.js";
8
9
  import { createObjectColumnReader, decodeJsonColumn, decodeNullableJsonColumn, isJsonColumnBodyProblem, jsonColumnText, jsonColumnTextExpr, readNonNullJsonValueColumn, readOpaqueJsonValueColumn, } from "./sql-json-column.js";
9
- import { SESSION_META_INCARNATION_COLUMN, incarnationFromCell, mintSessionIncarnation, sessionFaceFromRow } from "../session-incarnation.js";
10
+ import { incarnationFromCell, sessionFaceFromRow } from "../session-incarnation.js";
10
11
  import { RUN_HOLDER_DEATH_CODES, RUN_ORPHANED_ERROR, RUN_STALLED_ERROR } from "./store-contracts.js";
11
12
  import { PERMISSION_RULE_TABLE, purgeUndurableScopeRows } from "./permission-rule-store-sql.js";
12
13
  import { SESSION_RULES_COLUMN } from "./session-rules-column.js";
@@ -18,8 +19,6 @@ import { MAILBOX_KEYED_TABLES, mailboxKeyDeleteSql, storedMailboxKeyless } from
18
19
  const RETIRED_SESSION_RULE_BUCKETS = ["commandAllow", "commandDeny"];
19
20
  export function buildMigrationReceipts() {
20
21
  return {
21
- auditDetailJsonNullRows: 0,
22
- sessionIncarnationsBackfilled: 0,
23
22
  holderDeathCodeRowsBackfilled: 0,
24
23
  allowRuleShadowRowsMigrated: 0,
25
24
  allowRuleShadowRowsUnreadable: 0,
@@ -43,20 +42,20 @@ export function buildMigrationReceipts() {
43
42
  workflowJournalForeignScopeRowsRemoved: 0,
44
43
  retiredBreakerTablesDropped: 0,
45
44
  mailboxRejectedKeyRowsRemoved: 0,
45
+ parkedApprovalCardsBackfilled: 0,
46
+ parkedApprovalCardRowsUnreadable: [],
47
+ parkedApprovalCardRowsTooLong: [],
46
48
  };
47
49
  }
48
50
  function completedReport(r) {
49
- const { sessionIncarnationColumn, workflowParkIndexKey, sessionRuleColumn, workflowJournalScopeColumn } = r;
50
- if (sessionIncarnationColumn === undefined || workflowParkIndexKey === undefined || sessionRuleColumn === undefined || workflowJournalScopeColumn === undefined) {
51
- throw new Error(`one-time migrations finished without settling a shape reading (M5 ${String(sessionIncarnationColumn)} / M9 ${String(workflowParkIndexKey)} / M17 ${String(sessionRuleColumn)} / M24 ${String(workflowJournalScopeColumn)}) — a step did not record it`);
51
+ const { workflowParkIndexKey, sessionRuleColumn, workflowJournalScopeColumn } = r;
52
+ if (workflowParkIndexKey === undefined || sessionRuleColumn === undefined || workflowJournalScopeColumn === undefined) {
53
+ throw new Error(`one-time migrations finished without settling a shape reading (M9 ${String(workflowParkIndexKey)} / M17 ${String(sessionRuleColumn)} / M24 ${String(workflowJournalScopeColumn)}) — a step did not record it`);
52
54
  }
53
- return { ...r, sessionIncarnationColumn, workflowParkIndexKey, sessionRuleColumn, workflowJournalScopeColumn };
55
+ return { ...r, workflowParkIndexKey, sessionRuleColumn, workflowJournalScopeColumn };
54
56
  }
55
57
  function changedAnything(r) {
56
- return (r.auditDetailJsonNullRows > 0 ||
57
- r.sessionIncarnationColumn === "added" ||
58
- r.sessionIncarnationsBackfilled > 0 ||
59
- r.holderDeathCodeRowsBackfilled > 0 ||
58
+ return (r.holderDeathCodeRowsBackfilled > 0 ||
60
59
  r.allowRuleShadowRowsMigrated > 0 ||
61
60
  r.allowRuleShadowRowsUnreadable > 0 ||
62
61
  r.workflowParkIndexKey === "reshaped" ||
@@ -81,7 +80,10 @@ function changedAnything(r) {
81
80
  r.workflowJournalOwnersBackfilled > 0 ||
82
81
  r.workflowJournalForeignScopeRowsRemoved > 0 ||
83
82
  r.retiredBreakerTablesDropped > 0 ||
84
- r.mailboxRejectedKeyRowsRemoved > 0);
83
+ r.mailboxRejectedKeyRowsRemoved > 0 ||
84
+ r.parkedApprovalCardsBackfilled > 0 ||
85
+ r.parkedApprovalCardRowsUnreadable.length > 0 ||
86
+ r.parkedApprovalCardRowsTooLong.length > 0);
85
87
  }
86
88
  function readingsSnapshot(r) {
87
89
  return {
@@ -91,6 +93,8 @@ function readingsSnapshot(r) {
91
93
  sessionRuleRowsWithRetiredBuckets: [...r.sessionRuleRowsWithRetiredBuckets],
92
94
  sessionRuleRowsWithOldGrammarEntries: [...r.sessionRuleRowsWithOldGrammarEntries],
93
95
  sessionRuleRowsWithUnreadableDeny: [...r.sessionRuleRowsWithUnreadableDeny],
96
+ parkedApprovalCardRowsUnreadable: [...r.parkedApprovalCardRowsUnreadable],
97
+ parkedApprovalCardRowsTooLong: [...r.parkedApprovalCardRowsTooLong],
94
98
  };
95
99
  }
96
100
  function receiptSentence(r) {
@@ -115,29 +119,6 @@ export class OneTimeMigrationInterruptedError extends Error {
115
119
  }
116
120
  }
117
121
  export const ONE_TIME_MIGRATIONS = [
118
- {
119
- id: "M4",
120
- introducedIn: "7.93.5",
121
- releasedOn: "2026-09-21",
122
- removableAfter: "2026-10-21",
123
- removal: "删 migrateOn 的 M4 步(`device_audit` 在场探针 + `UPDATE … SET detail = NULL`)与 `AUDIT_TABLE` / `AUDIT_DETAIL_COLUMN`;" +
124
- "报告、日志行与 `NO_SQL_MIGRATIONS` 的 `auditDetailJsonNullRows`;它若是表里最后一条,按头注「窗」一节整个文件一起删",
125
- afterRemoval: "`device-store-sql.ts` `listAudit` 的读形拒(S-550:一行读不出形 ⇒ 整页拒,刻意不逐行隔离):含一行 JSON 文本 `null` 的那一页" +
126
- "读不出来,拒句点名行 id —— 响亮,但那一页会一直读不出来,直到运维手工把那些行的 `detail` 置成 SQL NULL",
127
- reportKeys: ["auditDetailJsonNullRows"],
128
- },
129
- {
130
- id: "M5",
131
- introducedIn: "7.104.0",
132
- releasedOn: "2026-09-28",
133
- removableAfter: "2026-10-28",
134
- removal: "删 migrateOn 的 M5 步(`session_meta` 在场探针、`incarnation` 列在场探针 + `ADD COLUMN`、空化身回填循环)与 `backfillSessionIncarnations`;" +
135
- "报告、日志行与 `NO_SQL_MIGRATIONS` 的 `sessionIncarnationColumn` / `sessionIncarnationsBackfilled`;**列本身留在中央 DDL 里**(它不是迁移的一部分)",
136
- afterRemoval: "① 列不在的存量库:起服列册探针 `schema-consistency.ts`(S-547)的缺列臂拒启 `config.schema_mismatch`,拒句里的 `ALTER TABLE … ADD COLUMN` " +
137
- "由同一份 DDL 生成(响亮);② 列在但行上仍是空化身(跳过了带 M5 的版本直接升):会话店读口 `sessionFaceOf` 对那一行响亮拒 " +
138
- "`session.incarnation_missing`(parked 决定腿因此拒、记忆座退回按 id 绑定并 warn)—— 运维手工给那些行填一只随机令牌即可",
139
- reportKeys: ["sessionIncarnationColumn", "sessionIncarnationsBackfilled"],
140
- },
141
122
  {
142
123
  id: "M6",
143
124
  introducedIn: "7.116.0",
@@ -202,7 +183,7 @@ export const ONE_TIME_MIGRATIONS = [
202
183
  "`http/routes/sessions.ts` 409 `conflict.session_ownerless` 句里「Ways out: on the local backend, during the upgrade window …」那半句(连同冻结表 " +
203
184
  "`test/api-error-text-freeze.test.ts` 那一行、契约码目录 `docs/ASSISTANT-WIRE-CONTRACT.md` 那一行);本文件的 `migrationWindowOpen`(若再无别的读者)",
204
185
  afterRemoval: "没有响亮臂(删码本身零行为变化:窗关那一刻起认领臂已经不生效):属主从没被记下的存量会话(边档那一格只有化身 —— 跳过了带本条的版本直接升," +
205
- "或窗内从没被带 principal 提交过)照旧答无主(`ownerOf` = null):它的会话规则这条路由读不了也改不了(409 `conflict.session_ownerless`)," +
186
+ "或窗内从没被带 principal 提交过)照旧答无主(`headOf(id)?.owner` = null):它的会话规则这条路由读不了也改不了(409 `conflict.session_ownerless`)," +
206
187
  "已存的规则对写下它们的 principal 的 run 照旧生效;出路 = 删会话(`DELETE /v1/sessions/:id`,规则随之删)",
207
188
  reportKeys: [],
208
189
  },
@@ -241,26 +222,13 @@ export const ONE_TIME_MIGRATIONS = [
241
222
  removableAfter: "2026-11-09",
242
223
  removal: "删 `config-lkg.ts` 的 formatVersion 2 读回迁移:`migrateV2Lkg` / `migrateDroppedIdentityRow` / `RETIRED_CATALOG_COORDINATE` 与其上的窗注;`loadLkg` 的 2 臂" +
243
224
  "(版本判据里的 `2` 与 `formatVersion === 2 ? migrateV2Lkg(…)` 那一支 —— 2 回到「unknown formatVersion」拒)、返回型的 `migrated` 位与 JSDoc 里说它的那一行、" +
244
- "文件头注「2 读回时一次性迁移」那一句;`boot/web-admin.ts` 读 `read.migrated` 打 `config_lkg_migrated` 的那一行(formatVersion 1 迁移的同名事件那一行留);" +
245
- "`migrateV1Lkg` 里不带 v1 的 etag 那一句旁注对 `migrateV2Lkg` 的引用(不带 etag 的规则本身留 —— v1 载荷同样没有完整的被丢条目记录);契约 §A.1d " +
225
+ "文件头注「2 读回时一次性迁移」那一句;`boot/web-admin.ts` 读 `read.migrated` 打 `config_lkg_migrated` 的那一行(这一行与 M15 / M22 的读回迁移共用 —— 三条都删完才整段删,先删 M13 时只去掉信封 2 → 3 那一路的 `migrated` 来源);契约 §A.1d " +
246
226
  "`droppedEntries` 一节「升级窗(如实)」那一条与 §A.1d `[config.model_refused_name_minted]` 那一条里「LKG 载体 `droppedIdentities` 读回时一次性迁移」那半句;手写 formatVersion 2 信封的测试夹具" +
247
227
  "(`test/config-lkg.test.ts`、`test/config-hot/batch1-version-ordinal.test.ts` 改写成 3;`test/models-dropped-entries-s1295.test.ts` 的旧 LKG 迁移格改钉 2 读回不可用)",
248
228
  afterRemoval: "既有响亮臂 `config_lkg_unusable`(`loadLkg` 对 2 答「unknown formatVersion 2」):2 读回 ⇒ 不可用,中心可达照拉(整拉,读腿铸出完整载体,新 LKG 按 3 覆盖)、" +
249
229
  "断着则 env 兜底,下一份干净候选重写 —— 与回滚到 7.122.0 读 3 同一种处置",
250
230
  reportKeys: [],
251
231
  },
252
- {
253
- id: "M14",
254
- introducedIn: "7.99.0",
255
- releasedOn: "2026-09-24",
256
- removableAfter: "2026-10-24",
257
- removal: "删 `config-lkg.ts` 的 formatVersion 1 迁移:`legacyV1LkgPath` / `migrateV1Lkg` 与其上的窗注(`loadLkg` 的 1 臂今天已是拒句,不动);" +
258
- "`boot/web-admin.ts` `bootFromLkg` 里调用 `migrateV1Lkg` 的那一段(含它打 `config_lkg_migrated` / 推不出身份时响亮拒的那两行);" +
259
- "`migrateV1Lkg` 的测试格(`test/config-lkg.test.ts` v1 迁移组)",
260
- afterRemoval: "既有响亮臂 `config_lkg_unusable`(`loadLkg` 对 1 答「pre-identity LKG (formatVersion 1) — not read back …」):旧默认路径上的 v1 文件不再被迁进箱、" +
261
- "原样留在盘上;中心可达照拉(整拉,新 LKG 按现行箱名落盘)、断着则 env 兜底",
262
- reportKeys: [],
263
- },
264
232
  {
265
233
  id: "M15",
266
234
  introducedIn: "7.124.0",
@@ -326,10 +294,15 @@ export const ONE_TIME_MIGRATIONS = [
326
294
  releasedOn: "2026-10-16",
327
295
  removableAfter: "2026-11-15",
328
296
  removal: "删 `src/stored-request-tool-axes-m19.ts` 整只文件(`storedToolAxesRereadM19` / `readToolAxesAsServer7129M19` / `readA2aToolAxesAsServer7131M19` / `StoredToolAxesRereadM19`);" +
329
- "`boot/resolve-spec.ts` 里两条请求腿共用的那一行(`const storedToolAxes = opts?.leg === \"fresh\" ? undefined : storedToolAxesRereadM19(…)`)、递给 `resolveRequestMcp` / `resolveRequestA2a` 的两处实参与它的 import;" +
297
+ "`boot/resolve-spec.ts` 里两条请求腿共用的那一行(`const storedToolAxes = opts?.leg === \"fresh\" ? undefined : storedToolAxesRereadM19(…)`,在腿首、A2A 快照之前求值)、" +
298
+ "`snapshotRequestA2a(…, { reread: storedToolAxes !== undefined })` 的第二实参、`parts` 里的 `storedToolAxes`(类型与解构)、递给 `resolveRequestMcp` / `resolveRequestA2a` 的两处实参与它的 import;" +
330
299
  "`task-mcp.ts` 里 `resolveRequestMcp` / `classifyRequestMcp` / `classifyHonored` / `validateRequestMcpEntries` / `normalizeServer` 的 `storedToolAxes` 形参、" +
331
300
  "`toolAxesReread` 事实与运维行 `mcp_tool_axes_read_as_before_upgrade`,以及对本模块的型 import(升级前读法的词表与两只谓词住在本模块里,随它一起删);" +
332
- "`task-a2a.ts` 里 `resolveRequestA2a` / `validateRequestA2aEntries` / `normalizeA2aPeer` 的 `storedToolAxes` 形参、`toolAxesReread` 事实与运维行 `a2a_tool_axes_read_as_before_upgrade`、对本模块的型 import;" +
301
+ "`task-a2a.ts` 里 `resolveRequestA2a` / `validateRequestA2aEntries` / `normalizeA2aPeer` 的 `storedToolAxes` 形参、`toolAxesReread` 事实与运维行 `a2a_tool_axes_read_as_before_upgrade`、对本模块的型 import," +
302
+ "以及只为重读座存在的克隆机器的全部名字:`cloneDeclaration` / `DeclarationClone` / `CloneFrame` / `openCloneNode` / `putCloneMember`、快照类型 `PeerSnapshot` 的字段 `toolAxesDeclared` 与 `mintPeerSnapshot` / `snapshotPeer` / `snapshotRequestA2a` 的 `reread` 形参、`toolAxesNotCloneableIssue`、读器里 `declared` 那一臂(`node:util` 的 `types` 与 `errorKindOf` 的 import 若再无别的读者一并删);" +
303
+ "随克隆一起退役的两句例外文字:`USAGE.md` 里 `a2a_injection_dropped` 条目 `reason` 那句「只有一臂例外 … `declaration not cloneable (<because>) — …`」与 `task-a2a.ts` 里 `A2aInjectionDrop.reason` 注的同一句例外(删后 `reason` 恒与 400 拒句同一句,回到「逐字同一句」不带例外);" +
304
+ "`test/task-a2a.test.ts` 里的克隆钉(标题去掉开头的 `🔴 ` 后以 `克隆钉:` 开头的各格,整格删;按这个精确前缀删,不按标题里的「M19 重读」之类泛词删 —— 那会误删同文件里的通用不变式钉),以及三格不带前缀、删码后要改写的钉:`需要「读」的两个键…` 那格的 `readRequestToolAxes` 调用方名单(`normalizeA2aPeer` 只在 M19 重读臂里调它,删后名单只剩 `mintPeerSnapshot`,标题里「与读器里 M19 重读产物的那一次」半句同删)、`读器与门的差别只有三格…` 改成两格(删 ③ 的注释行与标题里的 ③)、`请求入口快照的形…` 里 `snapshotRequestA2a(…, { reread: false })` 的第二实参(删 `reread` 形参后改成单参);" +
305
+ "`test/one-time-migration-window-gate.test.ts` 里 M19 一节中与克隆有关的三格(声明抽取器正负控 · 删法条与克隆名字两向对账 · 克隆钉标题前缀对账)与它们共用的帮手 `declaredNames`;" +
333
306
  "`test/mcp-tool-axes-m19.test.ts`(窗关那一格 —— 存量坏形整条不进、warn 与通告点名 `field: toolAxes` —— 改钉到 `test/task-mcp.test.ts`);" +
334
307
  "本文件的 `migrationWindowOpen`(若再无别的读者)",
335
308
  afterRemoval: "没有新的臂,接住它的是今天的读法(删码零行为变化:窗关那一刻起重读臂已经不生效):升级前存下的请求体里引擎判官判不过的 `toolAxes`,续跑重放时这一条 server 整条不进," +
@@ -360,7 +333,7 @@ export const ONE_TIME_MIGRATIONS = [
360
333
  releasedOn: "2026-10-18",
361
334
  removableAfter: "2026-11-17",
362
335
  removal: "删 migrateOn 的 M21 步(`repairParkedRows`:pending 候选分页扫描、门型回填、续不了的置 expired、问答卡词的整只文档读 + CAS 回写)与 `parkedRowRepairOf` / `ParkedRowRepair` / " +
363
- "`M21_GATE` / `M21_PENDING_ACTION` / `PARKED_ROW_REPAIR_PAGE` / `QUESTION_CARD` / `PARKED_APPROVAL_GATE_KINDS` / `readM21Subtree` / `readM21Document` / `m21Subtree`;" +
336
+ "`M21_GATE` / `M21_PENDING_ACTION` / `PARKED_ROW_REPAIR_PAGE` / `QUESTION_CARD` / `readM21Subtree` / `readM21Document` / `m21Subtree`;" +
364
337
  "报告、日志行与 `NO_SQL_MIGRATIONS` 的 `parkedQuestionCardsWritten` / `parkedQuestionRowsLeftAsWritten` / `parkedRowGateKindsBackfilled` / `parkedRowsUnresumableExpired`;" +
365
338
  "`test/one-time-migrations.test.ts` 的 M21 组与 `test/one-time-migrations-db-integration.test.ts` 的 M21 格",
366
339
  afterRemoval: "① 门上没有卡词的存量问答行(跳过了带本条的版本直接升的库、把 `APPROVAL_TERMINAL_BACKSTOP_MS` 调长的部署、local 车道 —— 那一车道本条从来够不着):没有新的臂,回到本条之前的读法 —— " +
@@ -462,14 +435,23 @@ export const ONE_TIME_MIGRATIONS = [
462
435
  "行字节不动 —— 出路 = 作为新任务重提(仍停驻的先取消),或升级时先过一次带本条的版本",
463
436
  reportKeys: [],
464
437
  },
438
+ {
439
+ id: "M29",
440
+ introducedIn: "7.135.0",
441
+ releasedOn: "2026-10-22",
442
+ removableAfter: "2026-11-21",
443
+ removal: "删 migrateOn 的 M29 步(`backfillParkedApprovalCards`:列在场探针、pending 候选分页扫描、整只文档读 + 写口那一只判官 + CAS 写列)与 `PARKED_CARD_BACKFILL_PAGE` / `readM29Document` / `m29Judge`;" +
444
+ "报告、日志行(含逐行的 `parked_approval_card_row_unreadable` / `parked_approval_card_row_too_long`)与 `NO_SQL_MIGRATIONS` 的 `parkedApprovalCardsBackfilled` / `parkedApprovalCardRowsUnreadable` / `parkedApprovalCardRowsTooLong`;`test/one-time-migrations.test.ts` 的 M29 组与 " +
445
+ "`test/checkpoint-index-columns-db-integration.test.ts` 的 M29 格。**不随本条删**:`approval_card` 列、写口的派生、到期 facet 的生成谓词(常设)",
446
+ afterRemoval: "没有新的臂(如实):跳过了带本条的版本直接升的库,升级前停驻、升级后仍挂着的行卡列是 NULL —— 生成谓词读门型的 facet(审批门 ⇒ SLA 拒扫腿),问答行到期被拒扫" +
447
+ "(引擎对问答拒收 `sla_timeout`,拒扫腿每拍一条失败,由 `terminal_at_ms` 兜底收割);运维队列行不带卡词。出路 = 升级前答完 / 拒掉停驻的问答,或升级时先过一次带本条的版本",
448
+ reportKeys: ["parkedApprovalCardsBackfilled", "parkedApprovalCardRowsUnreadable", "parkedApprovalCardRowsTooLong"],
449
+ },
465
450
  ];
466
451
  export function migrationWindowOpen(window, today) {
467
452
  return window.removableAfter === null || today <= window.removableAfter;
468
453
  }
469
454
  export const NO_SQL_MIGRATIONS = {
470
- auditDetailJsonNullRows: 0,
471
- sessionIncarnationColumn: "lazy-on-read",
472
- sessionIncarnationsBackfilled: 0,
473
455
  allowRuleShadowRowsMigrated: 0,
474
456
  allowRuleShadowRowsUnreadable: 0,
475
457
  workflowParkIndexKey: "file-ledger",
@@ -495,9 +477,10 @@ export const NO_SQL_MIGRATIONS = {
495
477
  workflowJournalForeignScopeRowsRemoved: 0,
496
478
  retiredBreakerTablesDropped: 0,
497
479
  mailboxRejectedKeyRowsRemoved: 0,
480
+ parkedApprovalCardsBackfilled: 0,
481
+ parkedApprovalCardRowsUnreadable: [],
482
+ parkedApprovalCardRowsTooLong: [],
498
483
  };
499
- const AUDIT_TABLE = "device_audit";
500
- const AUDIT_DETAIL_COLUMN = "detail";
501
484
  function mysqlDb(conn) {
502
485
  return {
503
486
  async rows(sql, params) {
@@ -584,10 +567,6 @@ async function migrateOn(db, dialect) {
584
567
  return completedReport(receipts);
585
568
  }
586
569
  async function migrateStepsOn(db, dialect, receipts) {
587
- if (await tableExists(db, dialect, AUDIT_TABLE)) {
588
- receipts.auditDetailJsonNullRows += await db.exec(`UPDATE ${AUDIT_TABLE} SET ${AUDIT_DETAIL_COLUMN} = NULL ` + `WHERE ${AUDIT_DETAIL_COLUMN} IS NOT NULL AND ${jsonColumnTextExpr(dialect, AUDIT_DETAIL_COLUMN)} = 'null'`);
589
- }
590
- await migrateSessionIncarnations(db, dialect, receipts);
591
570
  receipts.holderDeathCodeRowsBackfilled += await db.exec(dialect === "tidb"
592
571
  ? "UPDATE task_run SET error_code = ? WHERE status = 'failed' AND error_code IS NULL AND error = ?"
593
572
  : "UPDATE task_run SET error_code = $1 WHERE status = 'failed' AND error_code IS NULL AND error = $2", [RUN_HOLDER_DEATH_CODES.stalled, RUN_STALLED_ERROR]);
@@ -599,9 +578,10 @@ async function migrateStepsOn(db, dialect, receipts) {
599
578
  await reshapeWorkflowParkIndex(db, dialect, receipts);
600
579
  await migrateSessionRuleGrammar(db, dialect, receipts);
601
580
  await repairParkedRows(db, dialect, receipts);
581
+ await backfillParkedApprovalCards(db, dialect, receipts);
602
582
  if (await tableExists(db, dialect, "session_meta"))
603
583
  await inheritPlacedSessionOwners(db, dialect, receipts);
604
- if (await tableExists(db, dialect, PERMISSION_RULE_TABLE))
584
+ if ((await tableExists(db, dialect, PERMISSION_RULE_TABLE)) && (await columnExists(db, dialect, PERMISSION_RULE_TABLE, "grammar")))
605
585
  await purgeUndurableScopeRows(db, dialect, receipts);
606
586
  await moveWorkflowJournalScope(db, dialect, receipts);
607
587
  if (await tableExists(db, dialect, RETIRED_BREAKER_TABLE))
@@ -1010,7 +990,6 @@ const M21_GATE = { key: "gate", as: "m21_gate" };
1010
990
  const M21_PENDING_ACTION = { key: "pendingAction", as: "m21_pending_action" };
1011
991
  const PARKED_ROW_REPAIR_PAGE = 200;
1012
992
  const QUESTION_CARD = "question";
1013
- const PARKED_APPROVAL_GATE_KINDS = Object.keys(PAUSE_REGISTRY).filter((k) => PAUSE_REGISTRY[k].pending === "tool_approval");
1014
993
  const readM21Subtree = createObjectColumnReader();
1015
994
  const readM21Document = createObjectColumnReader();
1016
995
  export function parkedRowRepairOf(gateKindCell, gate, pendingAction) {
@@ -1020,7 +999,7 @@ export function parkedRowRepairOf(gateKindCell, gate, pendingAction) {
1020
999
  const kind = columnKind ?? documentKind;
1021
1000
  const pa = pendingAction !== null && typeof pendingAction === "object" && !Array.isArray(pendingAction) ? pendingAction : undefined;
1022
1001
  const questionCard = kind !== undefined &&
1023
- PARKED_APPROVAL_GATE_KINDS.includes(kind) &&
1002
+ isApprovalGateKind(kind) &&
1024
1003
  gateObj !== undefined &&
1025
1004
  !Object.hasOwn(gateObj, "approvalCard") &&
1026
1005
  pa?.kind === "tool_approval" &&
@@ -1040,7 +1019,7 @@ function m21Subtree(cell, where) {
1040
1019
  }
1041
1020
  export async function repairParkedRows(db, dialect, receipts) {
1042
1021
  const ph = (n) => (dialect === "tidb" ? "?" : `$${n}`);
1043
- const kinds = PARKED_APPROVAL_GATE_KINDS;
1022
+ const kinds = APPROVAL_GATE_KINDS;
1044
1023
  const kindSlots = kinds.map((_, i) => ph(i + 1)).join(", ");
1045
1024
  const scan = `SELECT token, session_id, gate_kind, ${jsonColumnText(dialect, "checkpoint", M21_GATE)}, ${jsonColumnText(dialect, "checkpoint", M21_PENDING_ACTION)} FROM checkpoint ` +
1046
1025
  `WHERE status = 'pending' AND (gate_kind IS NULL OR (gate_kind IN (${kindSlots}) AND tool_name = ${ph(kinds.length + 1)})) AND token > ${ph(kinds.length + 2)} ` +
@@ -1090,6 +1069,61 @@ export async function repairParkedRows(db, dialect, receipts) {
1090
1069
  return;
1091
1070
  }
1092
1071
  }
1072
+ const PARKED_CARD_BACKFILL_PAGE = 200;
1073
+ const readM29Document = createObjectColumnReader();
1074
+ export async function backfillParkedApprovalCards(db, dialect, receipts) {
1075
+ if (!(await columnExists(db, dialect, "checkpoint", "approval_card")))
1076
+ return;
1077
+ const ph = (n) => (dialect === "tidb" ? "?" : `$${n}`);
1078
+ const kinds = APPROVAL_GATE_KINDS;
1079
+ const scan = `SELECT token FROM checkpoint WHERE status = 'pending' AND approval_card IS NULL AND gate_kind IN (${kinds.map((_, i) => ph(i + 1)).join(", ")}) ` +
1080
+ `AND token > ${ph(kinds.length + 1)} ORDER BY token LIMIT ${PARKED_CARD_BACKFILL_PAGE}`;
1081
+ let after = "";
1082
+ for (;;) {
1083
+ const page = await db.rows(scan, [...kinds, after]);
1084
+ for (const r of page) {
1085
+ const token = String(r.token);
1086
+ after = token;
1087
+ const [full] = await db.rows(`SELECT session_id, ${jsonColumnText(dialect, "checkpoint")} FROM checkpoint WHERE token = ${ph(1)} AND status = 'pending'`, [token]);
1088
+ if (full === undefined)
1089
+ continue;
1090
+ const reading = m29Judge(full.checkpoint, dialect);
1091
+ switch (reading.kind) {
1092
+ case "unreadable":
1093
+ receipts.parkedApprovalCardRowsUnreadable.push({ sessionId: String(full.session_id) });
1094
+ continue;
1095
+ case "card_too_long":
1096
+ receipts.parkedApprovalCardRowsTooLong.push({ sessionId: String(full.session_id), bytes: reading.bytes });
1097
+ continue;
1098
+ case "cells": {
1099
+ const card = reading.cells.approval_card;
1100
+ if (card === null)
1101
+ continue;
1102
+ receipts.parkedApprovalCardsBackfilled += await db.exec(`UPDATE checkpoint SET approval_card = ${ph(1)} WHERE token = ${ph(2)} AND status = 'pending' AND approval_card IS NULL`, [card, token]);
1103
+ continue;
1104
+ }
1105
+ default: {
1106
+ const unhandled = reading;
1107
+ throw new Error(`M29: unhandled judgement ${JSON.stringify(unhandled)}`);
1108
+ }
1109
+ }
1110
+ }
1111
+ if (page.length < PARKED_CARD_BACKFILL_PAGE)
1112
+ return;
1113
+ }
1114
+ }
1115
+ function m29Judge(cell, dialect) {
1116
+ let doc;
1117
+ try {
1118
+ doc = decodeJsonColumn(cell, readM29Document, "checkpoint.checkpoint (M29 approval-card backfill)");
1119
+ }
1120
+ catch (e) {
1121
+ if (!isJsonColumnBodyProblem(e))
1122
+ throw e;
1123
+ return { kind: "unreadable" };
1124
+ }
1125
+ return judgeCheckpointIndexCells(doc, dialect);
1126
+ }
1093
1127
  const PLACED_OWNER_SCAN_PAGE = 500;
1094
1128
  function placedOwnerScanSql(dialect) {
1095
1129
  return ("SELECT c.session_id, c.incarnation, r.session_id AS root_row, r.owner AS root_owner, r.incarnation AS root_incarnation, r.placement_kind AS root_kind, " +
@@ -1150,69 +1184,8 @@ export async function inheritPlacedSessionOwners(db, dialect, receipts) {
1150
1184
  return;
1151
1185
  }
1152
1186
  }
1153
- const INCARNATION_BACKFILL_BATCH = 500;
1154
- async function migrateSessionIncarnations(db, dialect, receipts) {
1155
- if (!(await tableExists(db, dialect, "session_meta"))) {
1156
- receipts.sessionIncarnationColumn = "no-table";
1157
- return;
1158
- }
1159
- const col = SESSION_META_INCARNATION_COLUMN;
1160
- let column = "present";
1161
- if (!(await columnExists(db, dialect, "session_meta", col.name))) {
1162
- try {
1163
- await db.exec(`ALTER TABLE session_meta ADD COLUMN ${dialect === "tidb" ? col.tidb : col.pg}`);
1164
- column = "added";
1165
- }
1166
- catch (e) {
1167
- if (!(await columnExists(db, dialect, "session_meta", col.name)))
1168
- throw e;
1169
- }
1170
- }
1171
- receipts.sessionIncarnationColumn = column;
1172
- await backfillSessionIncarnations(db, dialect, receipts);
1173
- }
1174
- async function backfillSessionIncarnations(db, dialect, receipts) {
1175
- const remaining = async () => Number((await db.rows("SELECT COUNT(*) AS n FROM session_meta WHERE incarnation = ''"))[0]?.n ?? 0);
1176
- const initial = await remaining();
1177
- if (initial === 0)
1178
- return;
1179
- const ceiling = Math.ceil(initial / INCARNATION_BACKFILL_BATCH) * 2 + 2;
1180
- let written = 0;
1181
- let after;
1182
- for (let round = 0; round < ceiling; round++) {
1183
- const ids = (after === undefined
1184
- ? await db.rows(`SELECT session_id FROM session_meta WHERE incarnation = '' ORDER BY session_id LIMIT ${INCARNATION_BACKFILL_BATCH}`)
1185
- : await db.rows(`SELECT session_id FROM session_meta WHERE incarnation = '' AND session_id > ${dialect === "pg" ? "$1" : "?"} ORDER BY session_id LIMIT ${INCARNATION_BACKFILL_BATCH}`, [after])).map((r) => String(r.session_id));
1186
- if (ids.length === 0) {
1187
- if (after === undefined)
1188
- return;
1189
- after = undefined;
1190
- continue;
1191
- }
1192
- const params = [];
1193
- const bind = (v) => {
1194
- params.push(v);
1195
- return dialect === "pg" ? `$${params.length}` : "?";
1196
- };
1197
- const cases = ids.map((id) => `WHEN ${bind(id)} THEN ${bind(mintSessionIncarnation())}`).join(" ");
1198
- const inList = ids.map((id) => bind(id)).join(", ");
1199
- const landed = await db.exec(`UPDATE session_meta SET incarnation = CASE session_id ${cases} END WHERE incarnation = '' AND session_id IN (${inList})`, params);
1200
- written += landed;
1201
- receipts.sessionIncarnationsBackfilled += landed;
1202
- after = ids.length < INCARNATION_BACKFILL_BATCH ? undefined : ids[ids.length - 1];
1203
- }
1204
- const left = await remaining();
1205
- if (left > 0) {
1206
- throw new Error(`one-time migration M5: ${left} session_meta row(s) still carry an empty incarnation after ${ceiling} backfill round(s) ` +
1207
- `(${written} written) — refusing to start rather than serve sessions whose occupant cannot be told apart. Retry the boot; ` +
1208
- `if it repeats, something keeps writing rows without an incarnation (an older replica still inserting?).`);
1209
- }
1210
- }
1211
1187
  function readingFields(r) {
1212
1188
  return {
1213
- auditDetailJsonNullRows: r.auditDetailJsonNullRows,
1214
- ...(r.sessionIncarnationColumn !== undefined ? { sessionIncarnationColumn: r.sessionIncarnationColumn } : {}),
1215
- sessionIncarnationsBackfilled: r.sessionIncarnationsBackfilled,
1216
1189
  holderDeathCodeRowsBackfilled: r.holderDeathCodeRowsBackfilled,
1217
1190
  allowRuleShadowRowsMigrated: r.allowRuleShadowRowsMigrated,
1218
1191
  allowRuleShadowRowsUnreadable: r.allowRuleShadowRowsUnreadable,
@@ -1239,6 +1212,9 @@ function readingFields(r) {
1239
1212
  workflowJournalForeignScopeRowsRemoved: r.workflowJournalForeignScopeRowsRemoved,
1240
1213
  retiredBreakerTablesDropped: r.retiredBreakerTablesDropped,
1241
1214
  mailboxRejectedKeyRowsRemoved: r.mailboxRejectedKeyRowsRemoved,
1215
+ parkedApprovalCardsBackfilled: r.parkedApprovalCardsBackfilled,
1216
+ parkedApprovalCardRowsUnreadable: r.parkedApprovalCardRowsUnreadable.length,
1217
+ parkedApprovalCardRowsTooLong: r.parkedApprovalCardRowsTooLong.length,
1242
1218
  };
1243
1219
  }
1244
1220
  export function logOneTimeMigrations(log, backend, report) {
@@ -1246,9 +1222,7 @@ export function logOneTimeMigrations(log, backend, report) {
1246
1222
  backend,
1247
1223
  ...readingFields(report),
1248
1224
  removableAfter: Object.fromEntries(ONE_TIME_MIGRATIONS.map((w) => [w.id, w.removableAfter])),
1249
- note: "one-time persisted-data migrations (M4: audit details written as the JSON " +
1250
- "text `null` by an earlier version folded to a SQL NULL, so \"no detail\" has exactly one on-disk spelling; M5: the " +
1251
- "session incarnation column added and every session row without one minted its own token; M6: run rows failed by a " +
1225
+ note: "one-time persisted-data migrations (M6: run rows failed by a " +
1252
1226
  "holder-death verdict written by an earlier version with only the sentence got the machine-readable code run.stalled / " +
1253
1227
  "run.orphaned; M7 writes nothing — it is the window of the refusal that keeps a suspended task whose stored allow list was written " +
1254
1228
  "under an earlier reading from resuming under the current one; M8: parked rows' allow-layer disclosure written by an earlier engine " +
@@ -1282,7 +1256,10 @@ export function logOneTimeMigrations(log, backend, report) {
1282
1256
  "the breakers live in the new table breaker_state, which this step never touches; only the count is logged, never a key; M27: rows of the three " +
1283
1257
  "mailbox tables (mailbox / mailbox_message / mailbox_tombstone) whose key — scope or handle — the mailbox key judge refuses (control characters, " +
1284
1258
  "malformed Unicode, wider than 190 UTF-8 bytes, empty scope) removed, a whole box at a time: no entry point reaches such a key any more, so neither " +
1285
- "delivery, reading nor session deletion would ever have touched them again; only the count is logged, never a key). Each step " +
1259
+ "delivery, reading nor session deletion would ever have touched them again; only the count is logged, never a key; M29: suspended rows " +
1260
+ "parked before the checkpoint column approval_card existed and still pending get that column — the approval card word on their gate, " +
1261
+ "derived by the same function the write path uses (the engine's checkpointIndexFacts); a row whose document cannot be read as a checkpoint " +
1262
+ "is left NULL and counted, named by a parked_approval_card_row_unreadable line, and so is a row whose card word is longer than the column can hold, named by a parked_approval_card_row_too_long line). Each step " +
1286
1263
  "runs on every boot until its window closes (the release that introduced it + 30 days; the per-step date is in " +
1287
1264
  "removableAfter, null while that release is not published yet) and is deleted in the first minor after that — start a " +
1288
1265
  "version that still carries a step at least once before upgrading past its deletion.",
@@ -1290,6 +1267,26 @@ export function logOneTimeMigrations(log, backend, report) {
1290
1267
  logReceiptRows(log, backend, report);
1291
1268
  }
1292
1269
  function logReceiptRows(log, backend, r) {
1270
+ for (const row of r.parkedApprovalCardRowsUnreadable) {
1271
+ log.warn("parked_approval_card_row_unreadable", {
1272
+ backend,
1273
+ sessionId: row.sessionId,
1274
+ note: "a suspended approval row's checkpoint document cannot be read as a checkpoint the engine can resume (the body is not a JSON object, or the gate / pending-action member is missing), so its approval card " +
1275
+ "could not be derived. The row was not backfilled and not touched: the checkpoint.approval_card column stays NULL and the document is exactly as it was. Such a row cannot be resumed either; " +
1276
+ "find it by its session id and repair or remove the checkpoint document, or delete the session. The row is named on every boot until then",
1277
+ });
1278
+ }
1279
+ for (const row of r.parkedApprovalCardRowsTooLong) {
1280
+ log.warn("parked_approval_card_row_too_long", {
1281
+ backend,
1282
+ sessionId: row.sessionId,
1283
+ bytes: row.bytes,
1284
+ note: "a suspended approval row's gate carries an approval card word longer than the checkpoint.approval_card column can hold (the MySQL-protocol column is TEXT: 65,535 UTF-8 bytes). " +
1285
+ "The engine mints short card words only, so this row was edited by hand or written by something other than the engine. It was not backfilled and not truncated: the " +
1286
+ "column stays NULL and the read paths read the row as carrying no card (its document is untouched). Find the row by its session id and shorten " +
1287
+ "or remove the approvalCard member of its gate in the checkpoint document (the next boot then backfills it), or delete the session. The row is named on every boot until then",
1288
+ });
1289
+ }
1293
1290
  if (r.workflowJournalForeignScopeRowsRemoved > 0) {
1294
1291
  log.warn("workflow_journal_foreign_scope_rows_removed", {
1295
1292
  backend,
@@ -1382,7 +1379,7 @@ function logOneTimeMigrationsInterrupted(log, backend, error) {
1382
1379
  ...readingFields(error.receipts),
1383
1380
  note: "the one-time migrations failed after committing changes: the readings on this line and the lines that follow are what this boot already committed — a retried " +
1384
1381
  "boot finds that work done and does not report it again, so these lines are the only record of them, written once by this boot — save them. The failure itself follows " +
1385
- "as this boot's refusal. A shape reading absent from this line (sessionIncarnationColumn / workflowParkIndexKey / sessionRuleColumn / workflowJournalScopeColumn) belongs to a step that did not " +
1382
+ "as this boot's refusal. A shape reading absent from this line (workflowParkIndexKey / sessionRuleColumn / workflowJournalScopeColumn) belongs to a step that did not " +
1386
1383
  "finish; sessionRuleColumn absent after session_rule_row_old_grammar_entries lines means the column still carries its in-progress name — the next boot rewrites the " +
1387
1384
  "remaining rows (rows already rewritten are left alone) and publishes the final name",
1388
1385
  });
@@ -89,7 +89,7 @@ export declare function coreOutcomeToLedgerRow(o: CoreTaskOutcome): TaskOutcome;
89
89
  * drop-and-recreate, and NO new `ALTER TABLE` seams are added here; fold into the CREATE instead.
90
90
  */
91
91
  export declare const PG_OUTCOME_LEDGER_SCHEMA: string[];
92
- /** S-287:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensurePgOutcomeLedgerSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
92
+ /** [ref]:本 store 的索引**声明**(两方言共用一份)。PG 侧由下面的 `ensurePgOutcomeLedgerSchema` 应用,MySQL 侧由 `tidb-pool.ts` 的中央 `ensureSchema` 应用(那里内联 `KEY` 已在 `CREATE TABLE` 里 ⇒ 新建库探到即零 DDL,存量库缺谁补谁)。加索引以外的 schema 变更仍归运维,见 `plugins/ensure-index.ts` 头注。 */
93
93
  export declare const OUTCOME_LEDGER_INDEXES: readonly IndexSpec[];
94
94
  /** Idempotent self-contained PG schema apply (for the integration test; central aggregation via pg-pool.ts). */
95
95
  export declare function ensurePgOutcomeLedgerSchema(pool: PgPool | PoolClient): Promise<void>;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * 🔴 **S-929 F1(7.108.0 [ref] 合并复审 codex 腿 A ①,[high] 回归修)—— park 提交的唯一观察点。**
2
+ * 🔴 **[ref] F1(7.108.0 [ref] 合并复审 codex 腿 A ①,[high] 回归修)—— park 提交的唯一观察点。**
3
3
  *
4
4
  * core 的 durable park 就是对本仓 checkpoint 店的一次 `put`(SQL 孪生 / 本地文件店都是本仓的 `CheckpointStore` 实现,
5
5
  * 一只实例、四个消费点 —— 见 `boot/stage-06-runners.ts` 的构造注)。审批协调器交出 park 路由(ask 回调返回 `"unavailable"`)
@@ -19,7 +19,7 @@
19
19
  * **已提交**的 park 报成失败;一只不收尾的订阅者会把 core 的停驻挂住(订阅者自己给自己的工作上墙钟上限)。
20
20
  * 两个订阅者,各管一件「这只停车行提交了」之后的事:
21
21
  * · 审批协调器 —— 有序关停下写候着的审计 settle 行(sink 自吞失败并按 [ref] 留痕,同 tag 扩射程,见协调器);
22
- * · 对账收敛器 —— S-1280:这次调用的 `PARKING` 行在这一拍收口成 `PARKED`(判据 1 那一只判官的即时调用,`approval-reconciler.ts`
22
+ * · 对账收敛器 —— [ref]:这次调用的 `PARKING` 行在这一拍收口成 `PARKED`(判据 1 那一只判官的即时调用,`approval-reconciler.ts`
23
23
  * `bindCommittedPark`;它自带墙钟预算、失败只留痕,周期扫兜底)。`put` 等它(至多到它的预算)⇒ 健康时 core 的停驻返回之时行已收口;
24
24
  * 预算到点它就交还 `put`、不再发新的店调用,已发出的那一次经 {@link ParkCommitWatch.track} 留在在飞里 ⇒ 收尾链的 `quiesce`
25
25
  * 在 `backend.close()` 之前等到它落定。
@@ -46,7 +46,7 @@ export interface ParkCommitWatch {
46
46
  onParkCommitted(listener: ParkCommittedListener): void;
47
47
  /**
48
48
  * 把订阅者在 `put` 交还之后**仍可能在跑**的那段工作记进在飞:`quiesce` 等它落定(成功或失败都算落定),返回同一个 promise。
49
- * 用途(S-1280):订阅者给自己的工作上了墙钟预算,到点就把 `put` 交还 core —— 而此刻已经发出的那次店调用还没回来;不记进来,
49
+ * 用途([ref]):订阅者给自己的工作上了墙钟预算,到点就把 `put` 交还 core —— 而此刻已经发出的那次店调用还没回来;不记进来,
50
50
  * 收尾链会读到「静默」并在它底下关池。
51
51
  */
52
52
  track<T>(work: Promise<T>): Promise<T>;
@@ -12,9 +12,9 @@ import { type RuleCandidate } from "@sema-agent/core";
12
12
  export declare class FileRuleApprovalRecordStore implements RuleApprovalRecordStore {
13
13
  private readonly rows;
14
14
  private readonly log;
15
- /** 本面的损坏闸(S-582 起由重放属主交回;置位后每个方法第一行响亮拒)。 */
15
+ /** 本面的损坏闸([ref] 起由重放属主交回;置位后每个方法第一行响亮拒)。 */
16
16
  private readonly gate;
17
- /** @param warn 腐读披露座(S-582;缺席 ⇒ 属主退回 `console.warn`)。 */
17
+ /** @param warn 腐读披露座([ref];缺席 ⇒ 属主退回 `console.warn`)。 */
18
18
  constructor(dir: string, warn?: Logger["warn"]);
19
19
  /** 取证/自证用:本面是否因内部损坏而 fail-closed。 */
20
20
  get corrupt(): boolean;
@@ -42,11 +42,11 @@ export declare class FileRuleApprovalRecordStore implements RuleApprovalRecordSt
42
42
  export declare class FileRuleImportTicketStore {
43
43
  private readonly rows;
44
44
  private readonly log;
45
- /** 本面的损坏闸(S-582 起由重放属主交回)。 */
45
+ /** 本面的损坏闸([ref] 起由重放属主交回)。 */
46
46
  private readonly gate;
47
47
  /** 单调钟(判定用)。与 {@link now}(墙钟,记账用)是两只不同的钟,别混。 */
48
48
  private readonly monotonic;
49
- /** @param warn 腐读披露座(S-582;缺席 ⇒ 属主退回 `console.warn`)。 */
49
+ /** @param warn 腐读披露座([ref];缺席 ⇒ 属主退回 `console.warn`)。 */
50
50
  constructor(dir: string, now?: () => number, warn?: Logger["warn"], monotonic?: () => number);
51
51
  private readonly now;
52
52
  /** 取证/自证用:本面是否因内部损坏而 fail-closed。 */
@@ -105,7 +105,7 @@ export interface FilePermissionRuleStores extends PermissionRuleStoreBundle {
105
105
  * `onError` 接的是 core 规则文件的**披露面**(读不出来 / 校验和不符 / 撞上符号链接时它答零规则并
106
106
  * 说出来)。接住它打一条 warn 是**必须**的:那条路径上「零规则」与「真的没有规则」在读面上同形,
107
107
  * 不留痕就变成一次静默的 fail-closed(用户会突然被反复询问,却没有任何线索)。
108
- * `warn`(S-582)接的是本仓审批记录 / 导入票两份日志的**腐读座**(逐行披露 + 计数;缺席 ⇒ `console.warn`)。
108
+ * `warn`([ref])接的是本仓审批记录 / 导入票两份日志的**腐读座**(逐行披露 + 计数;缺席 ⇒ `console.warn`)。
109
109
  */
110
110
  export declare function createFilePermissionRuleStores(root: string, opts?: {
111
111
  onError?: (message: string) => void;
@@ -4,28 +4,19 @@ import { readdirSync } from "node:fs";
4
4
  import { performance } from "node:perf_hooks";
5
5
  import { FileDurableRulePartitionProvider, AppendLog, ensureDir, } from "@sema-agent/core";
6
6
  import { z } from "zod";
7
- import { DurableRuleScopeSchema, buildRulePayloadHash } from "./permission-rule-store-sql.js";
7
+ import { DurableRuleScopeSchema, RuleOffer2Schema, buildRulePayloadHash, recordOwnerOf, refusedOwnerSentence } from "./permission-rule-store-sql.js";
8
8
  import { replayJsonlGuarded } from "../observability/corrupt-read-seat.js";
9
- import { EDITED_RULE_BREADTH_WARNING_CODES, RULE_APPROVAL_KINDS, RULE_APPROVAL_RECORD_SCHEMA, RULE_APPROVAL_STATES, RULE_BEHAVIORS, RULE_OWNER_KINDS, UNCOVERED_SEGMENT_REASONS } from "@sema-agent/core";
9
+ import { EDITED_RULE_BREADTH_WARNING_CODES, RULE_APPROVAL_KINDS, RULE_APPROVAL_RECORD_SCHEMA, RULE_APPROVAL_STATES, RULE_BEHAVIORS, readRuleOwner } from "@sema-agent/core";
10
10
  const RuleDotSchema = z.object({ actor: z.string().min(1), counter: z.number().int().nonnegative().safe() }).strict();
11
11
  const RuleCandidateSchema = z.object({ behavior: z.enum(RULE_BEHAVIORS), rule: z.string(), scope: DurableRuleScopeSchema }).strict();
12
- const RuleOffer2Schema = z.union([
13
- z.object({ kind: z.literal("single"), candidate: z.number().int().nonnegative().safe() }).strict(),
14
- z
15
- .object({
16
- kind: z.literal("batch"),
17
- candidates: z.array(z.number().int().nonnegative().safe()),
18
- segments: z.array(z.string()).optional(),
19
- uncoveredSegments: z.number().int().nonnegative().safe().optional(),
20
- uncoveredDetail: z.array(z.object({ segment: z.string(), reason: z.enum(UNCOVERED_SEGMENT_REASONS) }).strict()).optional(),
21
- })
22
- .strict(),
23
- ]);
24
- const OWNER_SHAPE_BY_KIND = {
25
- principal: z.object({ kind: z.literal("principal"), principal: z.string() }).strict(),
26
- "local-owner": z.object({ kind: z.literal("local-owner") }).strict(),
27
- };
28
- const RuleOwnerSchema = z.union([OWNER_SHAPE_BY_KIND.principal, OWNER_SHAPE_BY_KIND["local-owner"]]);
12
+ const RuleOwnerSchema = z.unknown().transform((raw, ctx) => {
13
+ const owner = readRuleOwner(raw);
14
+ if (owner === undefined) {
15
+ ctx.addIssue({ code: "custom", message: "not a rule owner (the engine's readRuleOwner reads none: a plain record whose kind is a member and, for a principal, whose name is not empty or whitespace-only)" });
16
+ return z.NEVER;
17
+ }
18
+ return owner;
19
+ });
29
20
  const ApprovalRecordSchema = z
30
21
  .object({
31
22
  id: z.string().min(1),
@@ -163,6 +154,8 @@ export class FileRuleApprovalRecordStore {
163
154
  }
164
155
  async create(record) {
165
156
  this.gate.assertUsable();
157
+ if (recordOwnerOf(record) === undefined)
158
+ throw new Error(refusedOwnerSentence(record.id));
166
159
  if (this.rows.has(record.id))
167
160
  throw new Error(`rule approval record ${record.id} already exists`);
168
161
  this.log.append({ op: "put", record }, true);