@sema-agent/server 7.43.0 → 7.44.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 (345) hide show
  1. package/USAGE.md +18 -0
  2. package/dist/adoption/plan.js +31 -192
  3. package/dist/adoption/quiesce.js +3 -86
  4. package/dist/adoption/runner.js +3 -140
  5. package/dist/adoption/sql.js +0 -74
  6. package/dist/adoption/wire.js +0 -80
  7. package/dist/approval-ask-machine.js +0 -75
  8. package/dist/approval-card.js +0 -323
  9. package/dist/approval-deny-reasons.js +0 -42
  10. package/dist/approval-hmac.js +0 -35
  11. package/dist/approval-reconciler.js +8 -166
  12. package/dist/approval.js +4 -67
  13. package/dist/audit.js +1 -44
  14. package/dist/auth-bridge.js +4 -47
  15. package/dist/auth-keys.js +0 -23
  16. package/dist/bake-runner/main.js +4 -65
  17. package/dist/bake-runner/protocol.js +3 -58
  18. package/dist/bake-runner/runner.js +5 -91
  19. package/dist/bench/l8/artifact.js +2 -61
  20. package/dist/bench/l8/escape.js +0 -25
  21. package/dist/bench/l8/index.js +0 -14
  22. package/dist/bench/l8/probes.js +0 -60
  23. package/dist/bench/l8/run-probes.js +2 -45
  24. package/dist/bench/s1/arms.js +14 -189
  25. package/dist/bench/s1/live-deps.js +11 -253
  26. package/dist/bench/s1/oracle.js +1 -36
  27. package/dist/bench/s1/repair-oracle-adapter.js +0 -30
  28. package/dist/bench/s1/reviewer.js +0 -34
  29. package/dist/bench/s1/row.js +0 -62
  30. package/dist/bench/s1/run-firm.js +4 -70
  31. package/dist/bench/s1/runner-ctx.js +0 -40
  32. package/dist/bench/s1/tasks.js +0 -115
  33. package/dist/boot/adoption.js +0 -20
  34. package/dist/boot/budget-tracing.js +3 -55
  35. package/dist/boot/config-center.js +43 -551
  36. package/dist/boot/coordinators.js +1 -69
  37. package/dist/boot/crash-last.js +0 -18
  38. package/dist/boot/deferred-sandbox-path-env.js +3 -119
  39. package/dist/boot/execution-env.js +5 -171
  40. package/dist/boot/governance-seams.js +0 -92
  41. package/dist/boot/leader.js +0 -69
  42. package/dist/boot/limit-sync.js +0 -2
  43. package/dist/boot/memory-boundary.js +3 -91
  44. package/dist/boot/org-memory.js +1 -25
  45. package/dist/boot/parked-revive-gate.js +0 -150
  46. package/dist/boot/permission-rules-audit.js +1 -56
  47. package/dist/boot/reapers.js +15 -273
  48. package/dist/boot/resolve-spec.js +9 -768
  49. package/dist/boot/retention-lane.js +4 -87
  50. package/dist/boot/runner-deps.js +3 -297
  51. package/dist/boot/runtime-caps.js +0 -40
  52. package/dist/boot/session-faces.js +2 -133
  53. package/dist/boot/shutdown.js +9 -83
  54. package/dist/boot/side-query-lane.js +2 -137
  55. package/dist/boot/stores.js +15 -215
  56. package/dist/boot/task-list-lane.js +0 -18
  57. package/dist/boot/webfetch-summarize-lane.js +0 -47
  58. package/dist/boot/workflow-orchestration.js +3 -99
  59. package/dist/boot-reclaim.js +0 -20
  60. package/dist/bounded-session-map.js +0 -19
  61. package/dist/brain.js +2 -139
  62. package/dist/budget.js +9 -244
  63. package/dist/capabilities/builtin-tools.js +0 -3
  64. package/dist/capabilities/center-plugins.js +6 -51
  65. package/dist/capabilities/center-prompts.js +6 -71
  66. package/dist/capabilities/code-review-council.js +7 -40
  67. package/dist/capabilities/collab-workflows.js +1 -44
  68. package/dist/capabilities/hands-lane.js +0 -65
  69. package/dist/capabilities/memory-notice.js +0 -70
  70. package/dist/capabilities/prompt.js +0 -14
  71. package/dist/capabilities/prompts/code-review.js +0 -14
  72. package/dist/capabilities/prompts/identity.js +0 -6
  73. package/dist/capabilities/prompts/team.js +0 -4
  74. package/dist/capabilities/repo-tools.js +0 -34
  75. package/dist/capabilities/sandbox-file-send.js +3 -92
  76. package/dist/capabilities/scenarios.d.ts +0 -1
  77. package/dist/capabilities/scenarios.js +18 -279
  78. package/dist/capabilities/select-environment-tool.js +0 -32
  79. package/dist/capabilities/send-user-file-tool.js +2 -66
  80. package/dist/capabilities/skills.d.ts +1 -2
  81. package/dist/capabilities/skills.js +3 -21
  82. package/dist/capabilities/team.d.ts +3 -11
  83. package/dist/capabilities/team.js +3 -51
  84. package/dist/capabilities/tool-defer.js +0 -3
  85. package/dist/config-center/apply-effective.js +15 -330
  86. package/dist/config-center/apply-ledger.js +5 -38
  87. package/dist/config-center/facade.js +0 -41
  88. package/dist/config-center/hot-keys-registry.js +0 -20
  89. package/dist/config-center/http-client.js +2 -125
  90. package/dist/config-center/mcp-revocation.js +2 -34
  91. package/dist/config-center/read-face.js +0 -59
  92. package/dist/config-center/restart-signal.js +1 -85
  93. package/dist/config-center/skills-mcp.d.ts +1 -1
  94. package/dist/config-center/skills-mcp.js +9 -76
  95. package/dist/config-center/stage-limits.js +8 -35
  96. package/dist/config-invariants.js +0 -16
  97. package/dist/config-lkg.js +0 -42
  98. package/dist/config-provider.js +3 -186
  99. package/dist/config-types.js +0 -5
  100. package/dist/config.js +107 -1145
  101. package/dist/degenerate-instrument.js +3 -67
  102. package/dist/deployment-governance.js +0 -124
  103. package/dist/digest-form.js +0 -12
  104. package/dist/elicitation.js +3 -86
  105. package/dist/env-facts.js +7 -75
  106. package/dist/fleet/fleet-bus.js +34 -507
  107. package/dist/fleet/fleet-reconciler.js +9 -149
  108. package/dist/fleet/fleet-terminal-window.js +10 -178
  109. package/dist/fleet/subagent-tail-bus.js +3 -72
  110. package/dist/fleet-client.js +10 -70
  111. package/dist/fleet-lease.js +5 -79
  112. package/dist/git-api-kind.js +0 -3
  113. package/dist/governance-ask-marks.js +2 -78
  114. package/dist/hooks/branch-transcript.js +0 -74
  115. package/dist/hooks/cc-agent-hook-prompt.js +0 -29
  116. package/dist/hooks/cc-stop-prompt.js +1 -46
  117. package/dist/hooks/hook-llm.js +1 -53
  118. package/dist/hooks/hook-runner.js +20 -414
  119. package/dist/http/active-run-conflict.js +4 -129
  120. package/dist/http/cursor-fingerprint.d.ts +5 -0
  121. package/dist/http/cursor-fingerprint.js +5 -0
  122. package/dist/http/idempotency.js +0 -37
  123. package/dist/http/principal-gate.js +3 -40
  124. package/dist/http/route-ctx.js +0 -9
  125. package/dist/http/routes/a2a-serve.js +7 -319
  126. package/dist/http/routes/admin-config-refresh.js +0 -4
  127. package/dist/http/routes/admin-drain.js +0 -10
  128. package/dist/http/routes/adoption.js +1 -29
  129. package/dist/http/routes/agents-roster.js +1 -47
  130. package/dist/http/routes/approvals-assistant.js +32 -395
  131. package/dist/http/routes/attachments.js +4 -22
  132. package/dist/http/routes/capabilities.js +3 -420
  133. package/dist/http/routes/diagnostics.js +1 -81
  134. package/dist/http/routes/fleet.js +9 -185
  135. package/dist/http/routes/images.js +14 -239
  136. package/dist/http/routes/leader.js +0 -13
  137. package/dist/http/routes/memory-bundle.js +1 -61
  138. package/dist/http/routes/memory-policy.js +9 -99
  139. package/dist/http/routes/notify-wake.js +3 -37
  140. package/dist/http/routes/observability.js +2 -19
  141. package/dist/http/routes/retention-ops.js +2 -34
  142. package/dist/http/routes/rules.js +1 -93
  143. package/dist/http/routes/runs.js +64 -873
  144. package/dist/http/routes/session-sync.js +19 -258
  145. package/dist/http/routes/sessions-list.js +17 -43
  146. package/dist/http/routes/sessions.js +34 -226
  147. package/dist/http/routes/shared-memory.js +5 -36
  148. package/dist/http/routes/side-query.js +1 -87
  149. package/dist/http/routes/tasks.js +52 -722
  150. package/dist/http/routes/trace-usage.js +32 -195
  151. package/dist/http/routes/workflows.js +19 -195
  152. package/dist/http/run-meta.js +0 -6
  153. package/dist/http/send.js +0 -32
  154. package/dist/http/server.js +92 -1597
  155. package/dist/http/sse-lifecycle.js +2 -13
  156. package/dist/http/sse-log.js +3 -48
  157. package/dist/http/tar.js +5 -21
  158. package/dist/http/verify-rounds.js +0 -5
  159. package/dist/http/wire-gate.js +0 -9
  160. package/dist/http/workspace-content.js +0 -10
  161. package/dist/images/bake-validate.js +1 -70
  162. package/dist/images/manifest.js +1 -6
  163. package/dist/index.js +0 -21
  164. package/dist/key-resolver.js +2 -17
  165. package/dist/leader/diffout.js +1 -20
  166. package/dist/leader/diffup.js +0 -47
  167. package/dist/leader/endpoint.js +2 -57
  168. package/dist/leader/fanout.js +3 -45
  169. package/dist/leader/grader-env-factory.js +3 -72
  170. package/dist/leader/leader.js +5 -156
  171. package/dist/leader/merge.js +8 -115
  172. package/dist/leader/planner.js +3 -54
  173. package/dist/leader/repair-oracle.js +1 -60
  174. package/dist/leader/repair-wire.js +2 -79
  175. package/dist/leader/wire.js +8 -307
  176. package/dist/lsp/e2b-bridge.js +4 -64
  177. package/dist/lsp/e2b-manager.js +6 -94
  178. package/dist/lsp/lsp-frames.js +0 -12
  179. package/dist/lsp/manager.js +4 -96
  180. package/dist/lsp/ws-transport.js +5 -55
  181. package/dist/lsp-evict.js +1 -15
  182. package/dist/main.js +57 -765
  183. package/dist/memory-bundle-engine.js +0 -55
  184. package/dist/memory-export.js +0 -4
  185. package/dist/memory-posture.js +1 -15
  186. package/dist/memory-scope.js +11 -148
  187. package/dist/memory-sync-client.js +2 -44
  188. package/dist/memory-sync.js +1 -80
  189. package/dist/model-select.js +3 -80
  190. package/dist/observability/cost-quota.js +1 -17
  191. package/dist/observability/cost-taxonomy.js +0 -34
  192. package/dist/observability/fail-open.js +7 -86
  193. package/dist/observability/logger.js +0 -6
  194. package/dist/observability/metrics.js +0 -94
  195. package/dist/observability/otel-exporter.js +3 -13
  196. package/dist/observability/principal-context.js +0 -9
  197. package/dist/observability/prompt-manifest.js +1 -37
  198. package/dist/observability/rate-limit.js +0 -4
  199. package/dist/observability/secret-env-scrub.js +2 -56
  200. package/dist/observability/tool-trace.js +1 -70
  201. package/dist/orchestration/hardened-vm-runner.js +4 -118
  202. package/dist/orchestration/hardened-vm-worker-runner.js +1 -26
  203. package/dist/orchestration/hardened-vm-worker.js +0 -27
  204. package/dist/orchestration/subagent-steer.js +1 -45
  205. package/dist/orchestration/workflow-agent-steer.js +1 -80
  206. package/dist/orchestration/workflow-completion-inbox.js +32 -285
  207. package/dist/orchestration/workflow-notify-journal.js +16 -259
  208. package/dist/org-memory-admission.js +3 -47
  209. package/dist/parent-watch.js +2 -48
  210. package/dist/parked-decide.js +1 -109
  211. package/dist/per-task-image.js +0 -57
  212. package/dist/plan-cache-probe.js +3 -27
  213. package/dist/plugins/adoption-log-sql.js +2 -119
  214. package/dist/plugins/approval-ask-store-memory.js +3 -38
  215. package/dist/plugins/approval-ask-store-sql.js +6 -188
  216. package/dist/plugins/approval-exemption-store.js +2 -28
  217. package/dist/plugins/background-agent-store-sql.js +4 -105
  218. package/dist/plugins/background-shell-support.js +14 -122
  219. package/dist/plugins/blob-backend.js +6 -169
  220. package/dist/plugins/breaker-state-sql.js +8 -46
  221. package/dist/plugins/caching-session-store.js +4 -106
  222. package/dist/plugins/checkpoint-store-sql.js +18 -505
  223. package/dist/plugins/e2b-orphan-reclaim.js +0 -45
  224. package/dist/plugins/file-outcome-sink.js +0 -9
  225. package/dist/plugins/file-resume-anchor-store.js +4 -43
  226. package/dist/plugins/file-run-store.js +26 -364
  227. package/dist/plugins/file-snapshot-store-sql.js +10 -181
  228. package/dist/plugins/fork-routing-session-store.js +8 -111
  229. package/dist/plugins/host-platform.js +2 -91
  230. package/dist/plugins/image-bake-store-sql.js +7 -250
  231. package/dist/plugins/image-index-sql.js +4 -123
  232. package/dist/plugins/k8s-bg-scripts.js +4 -88
  233. package/dist/plugins/k8s-exec-protocol.js +0 -41
  234. package/dist/plugins/leader-run-store-sql.js +0 -101
  235. package/dist/plugins/local-checkpoint-store.js +8 -128
  236. package/dist/plugins/local-session-store.js +34 -296
  237. package/dist/plugins/local-task-attachment-store.js +2 -16
  238. package/dist/plugins/mailbox-store-sql.js +8 -65
  239. package/dist/plugins/memory-embedder-fingerprint.js +5 -166
  240. package/dist/plugins/memory-embedder.js +4 -70
  241. package/dist/plugins/memory-engine-pg.js +6 -170
  242. package/dist/plugins/memory-engine-tidb.js +7 -155
  243. package/dist/plugins/memory-engine-vector-util.js +0 -10
  244. package/dist/plugins/memory-key-guards.js +0 -34
  245. package/dist/plugins/memory-origin-law.js +0 -187
  246. package/dist/plugins/memory-resume-anchor-store.js +0 -17
  247. package/dist/plugins/memory-run-store.js +12 -89
  248. package/dist/plugins/memory-session-policy-store.js +0 -17
  249. package/dist/plugins/memory-sync-store-pg.js +4 -49
  250. package/dist/plugins/memory-sync-store-tidb.js +3 -35
  251. package/dist/plugins/outcome-ledger-sql.js +3 -97
  252. package/dist/plugins/permission-rule-store-file.js +5 -133
  253. package/dist/plugins/permission-rule-store-sql.d.ts +3 -0
  254. package/dist/plugins/permission-rule-store-sql.js +50 -307
  255. package/dist/plugins/pg-cost-quota.js +0 -7
  256. package/dist/plugins/pg-pool.js +0 -92
  257. package/dist/plugins/pg-rate-limiter.js +2 -13
  258. package/dist/plugins/pg-safe-json.js +4 -40
  259. package/dist/plugins/pg-session-storage.js +25 -189
  260. package/dist/plugins/posix-shell-fs.js +1 -31
  261. package/dist/plugins/remote-env-adb.js +12 -101
  262. package/dist/plugins/remote-env-e2b.js +40 -371
  263. package/dist/plugins/remote-env-file-error.js +0 -37
  264. package/dist/plugins/remote-env-host.js +63 -483
  265. package/dist/plugins/remote-env-k8s.js +32 -326
  266. package/dist/plugins/remote-env-local-docker.js +24 -157
  267. package/dist/plugins/remote-env-ssh.js +20 -128
  268. package/dist/plugins/remote-scratchpad.js +2 -32
  269. package/dist/plugins/remote-shell.js +1 -32
  270. package/dist/plugins/resume-anchor-store-sql.js +0 -11
  271. package/dist/plugins/retention-lane-store-sql.js +0 -108
  272. package/dist/plugins/retention-store-sql.js +4 -383
  273. package/dist/plugins/roster-store-sql.js +0 -55
  274. package/dist/plugins/run-store-sql.js +14 -251
  275. package/dist/plugins/s3-presign.js +2 -49
  276. package/dist/plugins/scheduler-support.js +3 -80
  277. package/dist/plugins/send-file-ledger.js +4 -53
  278. package/dist/plugins/send-user-file.js +4 -94
  279. package/dist/plugins/session-placement.js +1 -89
  280. package/dist/plugins/session-policy-store-sql.js +3 -81
  281. package/dist/plugins/session-store.js +0 -57
  282. package/dist/plugins/shared-memory-store-sql.js +4 -167
  283. package/dist/plugins/sql-driver.js +0 -17
  284. package/dist/plugins/sql-errors.js +0 -7
  285. package/dist/plugins/sql-escape.js +0 -8
  286. package/dist/plugins/sql-row-helpers.js +0 -25
  287. package/dist/plugins/store-backend.js +42 -222
  288. package/dist/plugins/store-contracts.js +2 -46
  289. package/dist/plugins/task-attachment-store.js +3 -49
  290. package/dist/plugins/task-list-store-sql.js +0 -79
  291. package/dist/plugins/tidb-cost-quota.js +1 -4
  292. package/dist/plugins/tidb-pool.js +1 -207
  293. package/dist/plugins/tidb-rate-limiter.js +3 -9
  294. package/dist/plugins/tidb-session-storage.js +4 -70
  295. package/dist/plugins/tidb-session-store.js +19 -341
  296. package/dist/plugins/tool-result-store-sql.js +4 -179
  297. package/dist/plugins/usage-window-store-sql.js +0 -8
  298. package/dist/plugins/web-search.js +10 -132
  299. package/dist/plugins/workflow-journal-store-sql.js +2 -58
  300. package/dist/plugins/workflow-run-store-sql.js +6 -91
  301. package/dist/plugins/worktree-isolation.js +6 -126
  302. package/dist/plugins/write-behind-counter.js +16 -75
  303. package/dist/principal-jwt.js +5 -60
  304. package/dist/project-memory.js +15 -146
  305. package/dist/prompts-domain-validate.js +1 -51
  306. package/dist/question.js +2 -111
  307. package/dist/resource-suspend.js +0 -18
  308. package/dist/router/route-orchestration.js +0 -77
  309. package/dist/rules-consent.d.ts +44 -5
  310. package/dist/rules-consent.js +75 -215
  311. package/dist/run-local.js +14 -381
  312. package/dist/runs.js +29 -617
  313. package/dist/runtime-caps-resolver.js +6 -132
  314. package/dist/runtime-governance.js +1 -232
  315. package/dist/sandbox-pkg-source.js +0 -37
  316. package/dist/sealed-key.js +3 -68
  317. package/dist/security.js +6 -291
  318. package/dist/session-leaf-bus.js +0 -32
  319. package/dist/session-sync-content.js +1 -69
  320. package/dist/session-sync-kernel.js +3 -60
  321. package/dist/session-sync.js +3 -66
  322. package/dist/session-titler.js +7 -41
  323. package/dist/session-watch.js +9 -73
  324. package/dist/shared-memory-scope-authorizer.js +0 -18
  325. package/dist/sighup-idle.js +1 -12
  326. package/dist/spec-fields.js +4 -143
  327. package/dist/store-live-probe.js +3 -49
  328. package/dist/task-a2a.js +1 -126
  329. package/dist/task-cwd.js +1 -103
  330. package/dist/task-mcp.js +1 -89
  331. package/dist/task-settings.js +10 -300
  332. package/dist/task-workflow.js +8 -75
  333. package/dist/tool-approval.d.ts +28 -1
  334. package/dist/tool-approval.js +70 -1430
  335. package/dist/trace/artifacts.js +5 -20
  336. package/dist/trace/engine-notice-wire.js +6 -138
  337. package/dist/trace/ledger-sink.js +7 -96
  338. package/dist/trace/project.js +4 -448
  339. package/dist/trace/redact.js +9 -77
  340. package/dist/turn-activity.js +1 -27
  341. package/dist/usage-analytics.js +4 -34
  342. package/dist/wall-clock-jump-guard.js +1 -68
  343. package/package.json +3 -3
  344. package/dist/capabilities/scenario-alias.d.ts +0 -27
  345. package/dist/capabilities/scenario-alias.js +0 -61
@@ -1,47 +1,15 @@
1
1
  import { mysqlDriver, pgDriver } from "./sql-driver.js";
2
2
  import { RETENTION_AUDIT_TABLE, RETENTION_HOLD_TABLE, RETENTION_LEASE_TABLE } from "./retention-store-sql.js";
3
- /** 审计读面的单页上界(与 roster 名册窗同姿势:读面要有界)。 */
4
3
  export const RETENTION_AUDIT_MAX_LIMIT = 200;
5
- /** 审计读面的缺省页大小。 */
6
4
  export const RETENTION_AUDIT_DEFAULT_LIMIT = 50;
7
- /**
8
- * 执行面的非破坏性 SQL 三组口(双方言;绑定类在文件底部)。
9
- *
10
- * 🔴 本类**删不掉任何业务数据** —— 它写的只有 `retention_lease` 的一行、`retention_hold` 的一列、
11
- * 与 `retention_audit` 的追加行。破坏性的三条腿在车1 的 `SqlRetentionStore` 上,拿本对象够不着。
12
- */
13
5
  export class SqlRetentionLaneStore {
14
6
  db;
15
7
  constructor(db) {
16
8
  this.db = db;
17
9
  }
18
- /** 方言取文(两条语句都写在调用点;A12 判据)。 */
19
10
  q(tidb, pg) {
20
11
  return this.db.dialect === "tidb" ? tidb : pg;
21
12
  }
22
- // ───────────────────────────── ① sweep 租约(§3)─────────────────────────────
23
- /**
24
- * 抢/续租一次(单行 CAS)。抢到 ⇒ `{held:true, fencingToken}`;别人正持着 ⇒ `{held:false}`,调用方
25
- * **本 tick 零写静默跳过**。
26
- *
27
- * 事务三步,一步不能省:
28
- * ① `INSERT IGNORE`(PG:`ON CONFLICT DO NOTHING`)一条 `expires_at_ms = 0` 的**哨兵行** —— 它永远
29
- * 不会改写一条既存租约(两方言的这两个动词都只在缺行时写);
30
- * ② `SELECT … FOR UPDATE` —— 行现在必定存在,锁真的拿得到;
31
- * ③ 判 + `UPDATE`,同事务提交。
32
- *
33
- * 🔴 为什么必须先造行、而不是「一条 `UPDATE … WHERE expires_at_ms < now OR holder = self`」了事
34
- * (设计稿 §3 写的正是那条裸 UPDATE,本实现是它的**收口**,与车1 hold 哨兵是同一条教训):裸 UPDATE
35
- * 在**空表**上影响 0 行 —— 于是首启的两个副本都读到「没抢到」,lane 在一个从没跑过的部署上**永远不
36
- * 起**(静默,读数是"每 tick 跳过",看上去像"别人在跑")。补一条无条件 INSERT 又会在两副本同拍首启时
37
- * 撞 PK。哨兵 + 行锁把两件事一次解决,并且顺带让 fencing token 的自增判据可以在应用层算。
38
- *
39
- * 🔴 fencing token 只在**抢租**(holder 变了)时自增,续租不动它:token 的语义是「第几轮**执行权**」,
40
- * 一个持续持租的副本跑的是同一段连续执行,给它每 tick 换号会让审计上「同一轮的行」看起来跨了很多轮。
41
- *
42
- * @param holder 本副本的身份(instanceId);同一 holder 再来 = 续租。
43
- * @param ttlMs 租约时长 = 2× sweep 间隔(§3)。
44
- */
45
13
  async acquire(holder, ttlMs, nowMs) {
46
14
  const conn = await this.db.connect();
47
15
  try {
@@ -52,8 +20,6 @@ export class SqlRetentionLaneStore {
52
20
  const curHolder = String(cur?.holder ?? "");
53
21
  const curToken = Number(cur?.fencing_token ?? 0);
54
22
  const expiresAtMs = Number(cur?.expires_at_ms ?? 0);
55
- // 别人持着且还没过期 ⇒ 不抢(**过期判据用 `>` 而不是 `>=`**:恰好到点的那一刻租约已经不再有效,
56
- // 而 `>=` 会让两个副本在同一毫秒上各自认为对方还持着 —— 都不抢,lane 停摆一拍)。
57
23
  if (curHolder !== holder && curHolder !== "" && expiresAtMs > nowMs) {
58
24
  await conn.commit();
59
25
  return { held: false, holder: curHolder, expiresAtMs };
@@ -72,56 +38,16 @@ export class SqlRetentionLaneStore {
72
38
  conn.release();
73
39
  }
74
40
  }
75
- /**
76
- * 「这一轮的执行权还在我手上吗」**并同时续租** —— 每 domain 处理前调一次(§3 丢租即停)。
77
- * 返回 `false` = 不再属于我 ⇒ 调用方当场中止本轮。
78
- *
79
- * 判据三合取写进**一条 CAS 的 WHERE**:holder 是我 ∧ fencing token 还是本轮那个 ∧ **尚未过期**。
80
- * · 第三项是承重的:租约过期而 holder 还写着我,必须读成**不再属于我**(fail-closed)——另一个副本
81
- * 随时可能抢走,两个副本同时跑三方法是这条腿最不能出的事。
82
- * · 「复核」与「续租」合成一条语句而不是先读后写(codex 对抗复审 R1-[high],验真后改):
83
- * ① 读+写两条语句之间有窗口,而 CAS 的谓词与更新在引擎里是原子的;
84
- * ② 更要紧的是**续租本身**:`startRetentionLane` 的重入守卫会跳过下一 tick,于是一轮的续租机会
85
- * 只有轮首那一次 —— 一轮跑满 2×interval 之后租约自己到期,而本副本毫不知情、继续删下去。
86
- * 轮子转多久租约就跟着延多久,那个窗口才真正关上。
87
- *
88
- * ⚠️ **如实登记的残余**(设计稿 §3 已成文接受,本实现不假装消灭):本调用返回 true 之后、本 domain 的
89
- * 破坏性事务提交之前,仍有一个「租约在这中间被别人接管」的理论窗口 —— 关它需要把 fencing token 的
90
- * 校验下推进**每一个破坏性事务的 WHERE**(车1 的三只方法),那是跨车的契约改动。补偿按设计稿:
91
- * 每条破坏性审计行都带 fencing token,旧轮的写因此**可判别**(§6 的那一列正是为此存在)。
92
- * 续租之后,这个窗口的宽度从「一整轮」缩到「一个 domain 的耗时」,且要求租约恰在这段内到期。
93
- */
94
41
  async renew(holder, fencingToken, ttlMs, nowMs) {
95
42
  const { affected } = await this.db.query(this.q(`UPDATE ${RETENTION_LEASE_TABLE} SET expires_at_ms = ? WHERE singleton = 'x' AND holder = ? AND fencing_token = ? AND expires_at_ms > ?`, `UPDATE ${RETENTION_LEASE_TABLE} SET expires_at_ms = $1 WHERE singleton = 'x' AND holder = $2 AND fencing_token = $3 AND expires_at_ms > $4`), [nowMs + ttlMs, holder, fencingToken, nowMs]);
96
43
  return affected > 0;
97
44
  }
98
- /**
99
- * 主动让租(优雅停机)——把到期时间归零,**保留 holder 与 token**(它们是审计线索,不是锁本身)。
100
- * 谓词带 `holder = ?`:一个已经丢了租的副本在退出时不许把**别人**的租约推倒。
101
- */
102
45
  async release(holder) {
103
46
  await this.db.query(this.q(`UPDATE ${RETENTION_LEASE_TABLE} SET expires_at_ms = 0 WHERE singleton = 'x' AND holder = ?`, `UPDATE ${RETENTION_LEASE_TABLE} SET expires_at_ms = 0 WHERE singleton = 'x' AND holder = $1`), [holder]);
104
47
  }
105
- // ───────────────────────────── ② legal-hold 的放置/解除(§5)─────────────────────────────
106
- /**
107
- * 放置或解除一个域的 legal hold —— **同一 PK 的 upsert 改 `held` 列,绝不 INSERT/DELETE 行**
108
- * (车1 交接件②,逐字)。
109
- *
110
- * 🔴 为什么删行是**拆锁**而不是"解除":`retention_hold` 的行同时是**域级互斥哨兵** —— 车1 的三条破坏性
111
- * 事务首步就是锁读这一行(`INSERT IGNORE` 补哨兵 → `SELECT … FOR UPDATE`),而 `FOR UPDATE`
112
- * **锁不住一条不存在的行**(TiDB 无 gap lock;PG READ COMMITTED 同病)。删掉行 = 下一个 PUT 与一条
113
- * 在飞的删除事务又可以同时读到"没有 hold",于是 operator 拿到成功回执之后数据仍被删 —— 那正是 §5 F2
114
- * 要消灭的那件事。upsert 让两者抢**同一把行锁**,「PUT 提交完成 ⇒ 其后每个破坏性事务的首读必见
115
- * held=1」这句承诺才成立。
116
- *
117
- * 解除时把 `placed_by/placed_at_ms/note` 一并清空:这张表存的是**当前状态**不是历史,历史在
118
- * `retention_audit` 的 `hold_placed`/`hold_released` 行上(追加不更新)。留一个「谁放的」在一条
119
- * held=0 的行上,读它的人分不清那是"现在冻结着"还是"上次谁冻过"。
120
- */
121
48
  async setHold(input) {
122
49
  await this.setHoldOn(this.db, input);
123
50
  }
124
- /** upsert 的**唯一** SQL 文本(自动提交口与事务口共用;见 {@link setHoldAudited} 的头注)。 */
125
51
  async setHoldOn(exec, input) {
126
52
  const held = input.held ? 1 : 0;
127
53
  const by = input.held ? (input.placedBy ?? null) : null;
@@ -131,18 +57,6 @@ export class SqlRetentionLaneStore {
131
57
  `ON DUPLICATE KEY UPDATE held = VALUES(held), placed_by = VALUES(placed_by), placed_at_ms = VALUES(placed_at_ms), note = VALUES(note)`, `INSERT INTO ${RETENTION_HOLD_TABLE} (domain, held, placed_by, placed_at_ms, note) VALUES ($1,$2,$3,$4,$5) ` +
132
58
  `ON CONFLICT (domain) DO UPDATE SET held = EXCLUDED.held, placed_by = EXCLUDED.placed_by, placed_at_ms = EXCLUDED.placed_at_ms, note = EXCLUDED.note`), [input.domain, held, by, at, note]);
133
59
  }
134
- /**
135
- * 放置/解除 **+ 治理审计行,同一个事务**(codex 对抗复审 R1-[high],验真后加)。
136
- *
137
- * 🔴 为什么必须原子(与 §6 F5 的「删除与审计同事务」是同一条判据,只是换了一张表):两次独立提交下,
138
- * 第二步失败会留下一次**无审计的状态变更**。PUT 那一支是「冻结了但账上没有」;**DELETE 那一支更重**
139
- * —— 冻结已经解除、sweep 从下一拍起就能删这个域的数据,而审计里没有任何 `hold_released` 行说明是谁
140
- * 在什么时候解的;客户端只看到一个 500,重试之前发生的删除再也无法从账本上追溯回那次释放。
141
- * 一张表两条语句、同库同连接 ⇒ 原子性零分布式代价,没有不做的理由。
142
- *
143
- * `protected` 的两条私有腿(`setHoldOn` / `appendAuditOn`)让本方法与 {@link setHold} /
144
- * {@link appendAudit} 共用**同一份 SQL 文本** —— 两处手抄一份 upsert,迟早只改一处。
145
- */
146
60
  async setHoldAudited(input) {
147
61
  const conn = await this.db.connect();
148
62
  try {
@@ -159,36 +73,16 @@ export class SqlRetentionLaneStore {
159
73
  conn.release();
160
74
  }
161
75
  }
162
- /** 「这个域现在冻结着吗」—— lane 的**省调**预检(§5 v1.3:降级为优化,**不承重**;承重判在车1 的
163
- * 店事务内)。零写。 */
164
76
  async holdInForce(domain) {
165
77
  const { rows } = await this.db.query(this.q(`SELECT held FROM ${RETENTION_HOLD_TABLE} WHERE domain = ?`, `SELECT held FROM ${RETENTION_HOLD_TABLE} WHERE domain = $1`), [domain]);
166
78
  return Number(rows[0]?.held ?? 0) === 1;
167
79
  }
168
- // ───────────────────────────── ③ 审计:非破坏行的写 + 读面(§6)─────────────────────────────
169
- /** 非破坏性审计行的追加(属主 = lane / 路由)。破坏性三词由车1 的店在删除同事务内写。 */
170
80
  async appendAudit(row, nowMs) {
171
81
  await this.appendAuditOn(this.db, row, nowMs);
172
82
  }
173
- /** 追加的**唯一** SQL 文本(同上)。 */
174
83
  async appendAuditOn(exec, row, nowMs) {
175
84
  await exec.query(this.q(`INSERT INTO ${RETENTION_AUDIT_TABLE} (domain, action, mode, policy_days, fencing_token, deleted, skipped, tombstones, executed_at_ms, error) VALUES (?,?,?,?,?,?,?,?,?,?)`, `INSERT INTO ${RETENTION_AUDIT_TABLE} (domain, action, mode, policy_days, fencing_token, deleted, skipped, tombstones, executed_at_ms, error) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)`), [row.domain, row.action, row.mode, row.policyDays, row.fencingToken, row.deleted, row.skipped, row.tombstones, nowMs, row.error ?? null]);
176
85
  }
177
- /**
178
- * 审计读面(keyset 分页,`id` 降序)。
179
- *
180
- * 排序键 = **自增 `id` 单列**,而不是 roster 那样的 `(时间戳, 次键)` 二元组:`id` 本身就是全序且唯一,
181
- * 二元组存在的全部理由(同毫秒兄弟行无 tiebreak ⇒ 漏页/重页)在这里结构上不存在。索引
182
- * `idx_retention_audit_domain (domain, id)` 正是为这条查询建的。
183
- *
184
- * `before` = 上一页最后一行的 `id`(严格小于)。
185
- *
186
- * 🔴 读上限是 `MAX_LIMIT + 1` 而不是 `MAX_LIMIT`(codex 对抗复审 R1-[medium],验真属实):调用方要判
187
- * 「还有没有下一页」就得多取一行,而**页**的上限是 `MAX_LIMIT`。旧形把 limit 无条件夹到 `MAX_LIMIT`
188
- * ⇒ 请求 `limit=200` 时 scanned 恒 ≤ 200 ⇒ `hasMore` 恒 false ⇒ **第 201 行之后的审计对这条分页链
189
- * 永久不可达**。这一格是「窗的上限」与「探路的那一行」两个不同的数被写成同一个数造成的,
190
- * 修法是让它们各是各的:页 ≤ MAX_LIMIT(路由侧保证),读 ≤ MAX_LIMIT+1(本方法)。
191
- */
192
86
  async listAudit(input) {
193
87
  const limit = Math.min(Math.max(1, Math.floor(input.limit)), RETENTION_AUDIT_MAX_LIMIT + 1);
194
88
  const where = [];
@@ -221,13 +115,11 @@ export class SqlRetentionLaneStore {
221
115
  }));
222
116
  }
223
117
  }
224
- /** MySQL-protocol (TiDB) binding。 */
225
118
  export class TiDBRetentionLaneStore extends SqlRetentionLaneStore {
226
119
  constructor(pool) {
227
120
  super(mysqlDriver(pool));
228
121
  }
229
122
  }
230
- /** PostgreSQL binding。 */
231
123
  export class PgRetentionLaneStore extends SqlRetentionLaneStore {
232
124
  constructor(pool) {
233
125
  super(pgDriver(pool));