@sema-agent/server 4.2.0 → 5.0.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 (176) hide show
  1. package/USAGE.md +5 -3
  2. package/dist/approval-hmac.js +1 -1
  3. package/dist/approval.d.ts +5 -37
  4. package/dist/approval.js +12 -112
  5. package/dist/auth-bridge.d.ts +0 -1
  6. package/dist/auth-bridge.js +0 -1
  7. package/dist/auth-keys.d.ts +1 -1
  8. package/dist/auth-keys.js +1 -1
  9. package/dist/bench/s1/run-firm.js +1 -1
  10. package/dist/boot/config-center.d.ts +1 -1
  11. package/dist/boot/config-center.js +3 -2
  12. package/dist/boot/execution-env.js +8 -1
  13. package/dist/boot/reapers.d.ts +1 -2
  14. package/dist/boot/reapers.js +4 -5
  15. package/dist/boot/resolve-spec.d.ts +1 -3
  16. package/dist/boot/resolve-spec.js +21 -35
  17. package/dist/boot/stores.js +1 -1
  18. package/dist/brain.js +3 -1
  19. package/dist/capabilities/center-prompts.d.ts +2 -3
  20. package/dist/capabilities/center-prompts.js +2 -3
  21. package/dist/capabilities/sandbox-file-send.d.ts +0 -2
  22. package/dist/capabilities/sandbox-file-send.js +2 -5
  23. package/dist/capabilities/scenarios.d.ts +0 -9
  24. package/dist/capabilities/scenarios.js +1 -20
  25. package/dist/capabilities/send-user-file-tool.js +3 -3
  26. package/dist/config-center/apply-effective.js +8 -8
  27. package/dist/config-center/types.d.ts +10 -3
  28. package/dist/config-provider.js +6 -11
  29. package/dist/config-types.d.ts +12 -26
  30. package/dist/config.js +95 -68
  31. package/dist/fleet/fleet-bus.js +25 -33
  32. package/dist/fleet-client.js +1 -1
  33. package/dist/http/active-run-conflict.d.ts +2 -0
  34. package/dist/http/active-run-conflict.js +1 -0
  35. package/dist/http/routes/approvals-assistant.d.ts +2 -1
  36. package/dist/http/routes/approvals-assistant.js +10 -96
  37. package/dist/http/routes/capabilities.js +6 -5
  38. package/dist/http/routes/fleet.js +4 -1
  39. package/dist/http/routes/images.js +10 -4
  40. package/dist/http/routes/runs.js +34 -49
  41. package/dist/http/routes/session-sync.d.ts +1 -1
  42. package/dist/http/routes/session-sync.js +2 -1
  43. package/dist/http/routes/tasks.js +7 -7
  44. package/dist/http/routes/trace-usage.js +1 -1
  45. package/dist/http/server.d.ts +18 -7
  46. package/dist/http/server.js +25 -14
  47. package/dist/http/verify-rounds.d.ts +2 -2
  48. package/dist/http/wire-types.d.ts +1 -1
  49. package/dist/images/bake-validate.d.ts +0 -22
  50. package/dist/images/bake-validate.js +0 -4
  51. package/dist/index.d.ts +4 -4
  52. package/dist/index.js +2 -5
  53. package/dist/lsp/e2b-bridge.d.ts +36 -3
  54. package/dist/lsp/e2b-bridge.js +94 -7
  55. package/dist/lsp/e2b-manager.d.ts +64 -1
  56. package/dist/lsp/e2b-manager.js +197 -28
  57. package/dist/lsp/manager.d.ts +71 -4
  58. package/dist/lsp/manager.js +149 -29
  59. package/dist/lsp/ws-transport.d.ts +1 -1
  60. package/dist/lsp/ws-transport.js +4 -1
  61. package/dist/main.js +5 -9
  62. package/dist/memory-scope.js +2 -2
  63. package/dist/observability/metrics.js +6 -0
  64. package/dist/orchestration/workflow-completion-inbox.d.ts +6 -4
  65. package/dist/orchestration/workflow-completion-inbox.js +6 -4
  66. package/dist/plugins/breaker-state-sql.d.ts +2 -3
  67. package/dist/plugins/image-index-sql.d.ts +0 -1
  68. package/dist/plugins/image-index-sql.js +0 -1
  69. package/dist/plugins/local-checkpoint-store.d.ts +1 -1
  70. package/dist/plugins/local-checkpoint-store.js +1 -1
  71. package/dist/plugins/memory-engine-pg.js +2 -1
  72. package/dist/plugins/memory-engine-tidb.js +1 -1
  73. package/dist/plugins/memory-engine-vector-util.d.ts +2 -3
  74. package/dist/plugins/memory-engine-vector-util.js +2 -3
  75. package/dist/plugins/memory-run-store.d.ts +1 -1
  76. package/dist/plugins/memory-session-policy-store.d.ts +1 -1
  77. package/dist/plugins/memory-session-policy-store.js +1 -1
  78. package/dist/plugins/memory-sync-store-pg.js +1 -1
  79. package/dist/plugins/pg-pool.js +8 -10
  80. package/dist/plugins/pg-rate-limiter.d.ts +1 -4
  81. package/dist/plugins/pg-rate-limiter.js +0 -1
  82. package/dist/plugins/roster-store-sql.d.ts +1 -3
  83. package/dist/plugins/roster-store-sql.js +3 -5
  84. package/dist/plugins/store-backend.d.ts +7 -17
  85. package/dist/plugins/store-backend.js +14 -30
  86. package/dist/plugins/tidb-pool.js +4 -28
  87. package/dist/plugins/workflow-journal-store-sql.d.ts +1 -1
  88. package/dist/plugins/workflow-journal-store-sql.js +1 -1
  89. package/dist/principal-jwt.js +2 -2
  90. package/dist/prompts-domain-validate.d.ts +4 -3
  91. package/dist/prompts-domain-validate.js +7 -8
  92. package/dist/router/route-orchestration.js +3 -3
  93. package/dist/run-local.js +5 -4
  94. package/dist/runs.js +8 -6
  95. package/dist/runtime-caps-resolver.d.ts +3 -2
  96. package/dist/runtime-caps-resolver.js +4 -4
  97. package/dist/runtime-governance.d.ts +4 -7
  98. package/dist/runtime-governance.js +12 -17
  99. package/dist/sealed-key.d.ts +1 -1
  100. package/dist/sealed-key.js +1 -1
  101. package/dist/security.d.ts +0 -5
  102. package/dist/security.js +8 -12
  103. package/dist/session-sync.d.ts +0 -2
  104. package/dist/session-sync.js +10 -17
  105. package/dist/spec-fields.js +6 -6
  106. package/dist/task-settings.js +7 -7
  107. package/dist/tool-approval.d.ts +3 -3
  108. package/dist/tool-approval.js +10 -10
  109. package/dist/trace/artifacts.d.ts +11 -0
  110. package/dist/trace/artifacts.js +8 -19
  111. package/dist/trace/ledger-sink.js +7 -1
  112. package/dist/trace/project.d.ts +17 -0
  113. package/dist/trace/project.js +55 -5
  114. package/package.json +2 -2
  115. package/dist/capabilities/oa-tools.d.ts +0 -15
  116. package/dist/capabilities/oa-tools.js +0 -54
  117. package/dist/plugins/approval-store-sql.d.ts +0 -116
  118. package/dist/plugins/approval-store-sql.js +0 -150
  119. package/dist/plugins/file-workflow-journal-store.d.ts +0 -12
  120. package/dist/plugins/file-workflow-journal-store.js +0 -12
  121. package/dist/plugins/pg-approval-store.d.ts +0 -9
  122. package/dist/plugins/pg-approval-store.js +0 -9
  123. package/dist/plugins/pg-breaker-state.d.ts +0 -8
  124. package/dist/plugins/pg-breaker-state.js +0 -8
  125. package/dist/plugins/pg-checkpoint-store.d.ts +0 -10
  126. package/dist/plugins/pg-checkpoint-store.js +0 -10
  127. package/dist/plugins/pg-file-snapshot-store.d.ts +0 -8
  128. package/dist/plugins/pg-file-snapshot-store.js +0 -8
  129. package/dist/plugins/pg-image-bake.d.ts +0 -12
  130. package/dist/plugins/pg-image-bake.js +0 -11
  131. package/dist/plugins/pg-image-index.d.ts +0 -12
  132. package/dist/plugins/pg-image-index.js +0 -11
  133. package/dist/plugins/pg-outcome-ledger.d.ts +0 -12
  134. package/dist/plugins/pg-outcome-ledger.js +0 -11
  135. package/dist/plugins/pg-resume-anchor-store.d.ts +0 -7
  136. package/dist/plugins/pg-resume-anchor-store.js +0 -7
  137. package/dist/plugins/pg-run-store.d.ts +0 -9
  138. package/dist/plugins/pg-run-store.js +0 -9
  139. package/dist/plugins/pg-session-policy-store.d.ts +0 -7
  140. package/dist/plugins/pg-session-policy-store.js +0 -7
  141. package/dist/plugins/pg-session-store.d.ts +0 -12
  142. package/dist/plugins/pg-session-store.js +0 -12
  143. package/dist/plugins/pg-tool-result-store.d.ts +0 -9
  144. package/dist/plugins/pg-tool-result-store.js +0 -9
  145. package/dist/plugins/pg-workflow-journal-store.d.ts +0 -9
  146. package/dist/plugins/pg-workflow-journal-store.js +0 -9
  147. package/dist/plugins/pg-workflow-run-store.d.ts +0 -9
  148. package/dist/plugins/pg-workflow-run-store.js +0 -9
  149. package/dist/plugins/tidb-approval-store.d.ts +0 -8
  150. package/dist/plugins/tidb-approval-store.js +0 -8
  151. package/dist/plugins/tidb-breaker-state.d.ts +0 -7
  152. package/dist/plugins/tidb-breaker-state.js +0 -7
  153. package/dist/plugins/tidb-checkpoint-store.d.ts +0 -9
  154. package/dist/plugins/tidb-checkpoint-store.js +0 -9
  155. package/dist/plugins/tidb-file-snapshot-store.d.ts +0 -8
  156. package/dist/plugins/tidb-file-snapshot-store.js +0 -8
  157. package/dist/plugins/tidb-image-bake.d.ts +0 -12
  158. package/dist/plugins/tidb-image-bake.js +0 -11
  159. package/dist/plugins/tidb-image-index.d.ts +0 -12
  160. package/dist/plugins/tidb-image-index.js +0 -11
  161. package/dist/plugins/tidb-outcome-ledger.d.ts +0 -12
  162. package/dist/plugins/tidb-outcome-ledger.js +0 -12
  163. package/dist/plugins/tidb-resume-anchor-store.d.ts +0 -7
  164. package/dist/plugins/tidb-resume-anchor-store.js +0 -7
  165. package/dist/plugins/tidb-run-store.d.ts +0 -10
  166. package/dist/plugins/tidb-run-store.js +0 -9
  167. package/dist/plugins/tidb-session-policy-store.d.ts +0 -7
  168. package/dist/plugins/tidb-session-policy-store.js +0 -7
  169. package/dist/plugins/tidb-tool-result-store.d.ts +0 -8
  170. package/dist/plugins/tidb-tool-result-store.js +0 -10
  171. package/dist/plugins/tidb-workflow-journal-store.d.ts +0 -9
  172. package/dist/plugins/tidb-workflow-journal-store.js +0 -9
  173. package/dist/plugins/tidb-workflow-run-store.d.ts +0 -10
  174. package/dist/plugins/tidb-workflow-run-store.js +0 -10
  175. package/dist/plugins/workflow-journal-limits.d.ts +0 -12
  176. package/dist/plugins/workflow-journal-limits.js +0 -12
@@ -209,7 +209,7 @@ export class WsLspTransport {
209
209
  * Returns `undefined` on any failure (→ the manager degrades that language gracefully). `wsUrl` is the
210
210
  * `wss://…e2b.dev` URL from `sandbox.getHost(port)`; `rootPath` is the in-sandbox workspace root.
211
211
  */
212
- export async function connectWsLspTransport(wsUrl, rootPath, signal) {
212
+ export async function connectWsLspTransport(wsUrl, rootPath, signal, initializationOptions) {
213
213
  let socket;
214
214
  try {
215
215
  socket = new WebSocket(wsUrl);
@@ -245,6 +245,9 @@ export async function connectWsLspTransport(wsUrl, rootPath, signal) {
245
245
  processId: null,
246
246
  rootUri: pathToUri(rootPath),
247
247
  capabilities: { textDocument: { definition: {}, references: {}, hover: {}, documentSymbol: {}, implementation: {}, callHierarchy: {} }, workspace: { symbol: {} } },
248
+ // #96 真机门:tls 的 tsserver 路径只能走这里(v4 移除了 CLI 旗);非 tls 服务器按 LSP 规范忽略
249
+ // 未知 initializationOptions。缺席时不发键(老行为逐字保持)。
250
+ ...(initializationOptions !== undefined ? { initializationOptions } : {}),
248
251
  }, signal);
249
252
  transport.notify("initialized", {});
250
253
  return transport;
package/dist/main.js CHANGED
@@ -390,12 +390,10 @@ async function main() {
390
390
  maxOutputTokens: capEnv("TASK_MAX_OUTPUT_TOKENS_MAX"),
391
391
  maxTurns: capEnv("TASK_MAX_TURNS_MAX"),
392
392
  };
393
- // F4: human-in-the-loop approval gate (pending state durable so any instance can decide).
394
- const approvalStore = backend?.approval ? backend.approval() : undefined; // local omits approval() → legacy poll-gate off (durable HITL needs checkpoint anyway)
395
- const approvalEnabled = approvalStore && config.approvalRequire.length > 0;
393
+ // [2354]/[2356] A-5(5.0.0):F4 轮询门(approvalStore pending 行)整体退役——durable checkpoint 是唯一门形。
396
394
  // Finding #2 (edge case): the single-user auto-accept tool-policy BASELINE applies ONLY when the operator
397
395
  // expressed NO gate intent. If they SET approval flags (APPROVAL_REQUIRE/APPROVAL_DENY/DURABLE_APPROVAL) but no
398
- // backing store is wired (e.g. DB_BACKEND=local → no approvalStore/checkpointStore ⇒ approvalEnabled/durableEnabled
396
+ // backing store is wired (e.g. DB_BACKEND=local → no checkpointStore ⇒ durableEnabled
399
397
  // false), that is a MISCONFIG — do NOT mask it with allow-all; leave toolPolicy undefined so core's UNGATED warning
400
398
  // still surfaces it. So the baseline needs single-user turnkey ∧ zero expressed gate intent.
401
399
  // 单源在 approval.ts(与 inv#2 同文件)—— 这里原是内联的三格枚举,漏了 approvalNeverAuto,详见该函数顶注。
@@ -585,7 +583,6 @@ async function main() {
585
583
  // 构造区上方 const)同实例;ensureChildSessionDurable 见上方构造闭包注释。
586
584
  checkpointStore: checkpointStore ? checkpointStore : undefined,
587
585
  ensureChildSessionDurable: ensureChildSessionDurable ? ensureChildSessionDurable : undefined,
588
- oaApiBaseUrl: config.oaApiBaseUrl, oaServiceToken: config.oaServiceToken, oaIssue: config.oaIssue,
589
586
  brandIdentity: config.configProvider === "local",
590
587
  // core 1.287 extraTools seam ([802]③ server half): SendUserFile reaches the delegated-child roster. SAME
591
588
  // existence gate as the top-level mount (the one sendUserFileToolSpec built above — lane/tenancy/config
@@ -646,7 +643,7 @@ async function main() {
646
643
  let runDenySweep;
647
644
  // design/158 A10:reaper 段搬到 src/boot/reapers.ts(逐字;deny-sweep 晚绑改取值,见该文件头注)。
648
645
  const reaper = startReapers({
649
- config, logger, metrics, localRoot, backend, subRunner, runStore, checkpointStore, approvalStore,
646
+ config, logger, metrics, localRoot, backend, subRunner, runStore, checkpointStore,
650
647
  rateLimiter, costQuota, toolResultStore, fileSnapshotStore, taskAttachmentStore, imageBakes, worktreeReap,
651
648
  workflowNotifyGate, workflowJournalStore, sqlWorkflowRunStore, workflowNotifyJournal, rosterStore,
652
649
  backgroundAgentStore, mailboxStore,
@@ -704,7 +701,6 @@ async function main() {
704
701
  const stores = {
705
702
  runStore,
706
703
  resumeAnchorStore: resumeAnchorStore ? resumeAnchorStore : undefined, // E18 resume-at eventId→entryId map (tidb/pg/local)
707
- approvalStore,
708
704
  approvalExemptionStore: approvalExemptionStore ? approvalExemptionStore : undefined, // decide remember="session" + list/revoke
709
705
  checkpointStore,
710
706
  sessionPolicyStore: sessionPolicyStore ? sessionPolicyStore : undefined, // E6 operator session-rule store (PUT/GET /v1/sessions/:id/policy)
@@ -856,8 +852,8 @@ async function main() {
856
852
  getKeyResolver: () => configCenter.getKeyResolver(),
857
853
  taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv,
858
854
  hookLlm, hookAgent, fleetBus, hookWakeBus, resumeAnchorStore, ownerAware, taskLimitCaps, taskTimeoutSec,
859
- selectEnvTool, sendUserFileToolSpec, memoryEngine, durableEnabled, approvalExemptionStore, approvalEnabled,
860
- approvalStore, singleUserAutoAcceptBaseline, checkpointStore, deploymentHooks, imageIndex, perTaskImage,
855
+ selectEnvTool, sendUserFileToolSpec, memoryEngine, durableEnabled, approvalExemptionStore,
856
+ singleUserAutoAcceptBaseline, checkpointStore, deploymentHooks, imageIndex, perTaskImage,
861
857
  sessionEnvSelection,
862
858
  });
863
859
  const server = createHttpServer({ runner, config, resolveSpec, stores, coordinators, seams, observability, governance, deployment, knobs });
@@ -1,7 +1,7 @@
1
1
  // design/158 N17: the memory-plane resolvers moved VERBATIM out of security.ts (lens4 §4.1 — "budget.ts"'s
2
2
  // sibling finding: security.ts's name says auth, but ~110 of its 765 lines were memory-scope config
3
- // resolution with nothing to do with authentication). security.ts re-exports all four for compat (its own
4
- // createAuthorizer still calls memoryScopeFor); index.ts's npm-facing re-export is unaffected (package.json
3
+ // resolution with nothing to do with authentication). security.ts imports memoryScopeFor for its own
4
+ // createAuthorizer; consumers import all four from HERE ([2354] 兼容面全清 — the security.ts compat re-export is gone); index.ts's npm-facing re-export is unaffected (package.json
5
5
  // "exports" only ever exposed "." and "./main" — dist/security.js was never a reachable deep-import path).
6
6
  import { join } from "node:path";
7
7
  import { FileMemoryEngineBackend, resolveMemoryEngineRoot, deriveControlPlaneDir, formatUserScope, formatProjScope } from "@sema-agent/core";
@@ -295,6 +295,12 @@ export function createMetrics() {
295
295
  // LOCAL floor(now/windowMs); replica clock skew splits a fleet window into disjoint buckets (soft-limit leak).
296
296
  m.gauge("fleet_counter_bucket_skew_ms", "DB clock minus local clock in ms (S10) — skew splits cross-replica counter windows");
297
297
  m.gauge("fleet_clock_probe_ok", "1 = last DB clock probe succeeded, 0 = failing (skew gauge is stale while 0)");
298
+ // #96 redesign⑤ (§DESIGN-V2 E): LSP sandbox-bridge lifecycle + session outcomes — previously zero metrics
299
+ // existed for the whole subsystem (a dead bridge or a stuck restart budget had no fleet-level signal).
300
+ m.counter("lsp_bridge_start_total", "LSP sandbox bridge (re)starts attempted, by provider and generation");
301
+ m.counter("lsp_bridge_dead_total", "LSP sandbox bridge generations that died, by reason (the word IS the model-facing unavailableReason)");
302
+ m.counter("lsp_session_open_total", "LSP session opens, by language and outcome (ok/failed)");
303
+ m.counter("lsp_session_heal_total", "LSP session heals (dead-transport reopen), by outcome (ok/failed)");
298
304
  // S21 — which backend snapshot blobs actually land on (minio|sql). Partial MINIO_* config silently falls to sql.
299
305
  m.gauge("snapshot_blob_backend", "1 on the active snapshot-blob backend series (S21), by backend (minio|sql)");
300
306
  // S22 — memory embed/KNN runtime failures (boot said vector; runtime silently degrades to lexical).
@@ -77,7 +77,7 @@ export declare const SERVED_FENCE_MS: number;
77
77
  *
78
78
  * 编码=防碰撞元组:域/taskId/status 走 JSON 数组(调用方自由串伪造不了分隔符);`#seq` 尾折在 JSON 之外
79
79
  * ——JSON 段恒以 `"]` 结尾,`#digits` 尾无歧义,于是 {@link foldKeyFamily} 的剥尾语义 AND SQL 双生子
80
- * (tidb/pg-workflow-run-store 的 `regexp_replace(run_id, '#[0-9]+$', '')` 家族比对)原样成立——把 seq 折进
80
+ * (workflow-run-store-sql 的 `regexp_replace(run_id, '#[0-9]+$', '')` 家族比对)原样成立——把 seq 折进
81
81
  * JSON 元组会让 SQL 侧家族 ack/fence 永 miss(那是另一批的真库改动面,本修有意不碰)。
82
82
  * seq 折入=逐停机周期各自成键(1.283 起 background_agent 四腿 notify 铸 cycleSeq);无 seq=单周期旧键
83
83
  * (bash/monitor terminal/retain 降级,诚实语义)。serve-fence 侧必须用同一函数(或其家族前缀)构造,
@@ -97,9 +97,11 @@ export declare function taskNotificationFoldKey(n: {
97
97
  * task 的 Monitor event 批与 failed 终态在一条腿上互吞;wire 去重要的是逐帧身份,不是 inbox 的双终态列。
98
98
  * `seq` 折入 = 停→唤→停的第二周期同 status 帧各自成键(core 1.283 起 background_agent 四腿 notify 铸
99
99
  * cycleSeq;缺 seq 时旧键曾把二周期 completed 帧在 observer 臂反向吞掉——core [784]④a);无 seq 的帧
100
- * (bash/monitor terminal/retain 降级)保持单周期旧键=同键第二帧吞,诚实语义。task_type 缺席(旧 core
101
- * 内部帧)归 "task" 域——external 帧的 task_type 三来源齐备(notify 端点 core 铸 / inbox entry extras 存
102
- * / drain spread 复原),不会漏域。observer / stream 臂 / turn-open drain 登记三处必须用本函数
100
+ * (bash/monitor terminal/retain 降级)保持单周期旧键=同键第二帧吞,诚实语义。[2373]B-10:core 4.0.0
101
+ * task_type 是必填闭合枚举——`task_type?` 可选性**不再对应旧 core 帧**,它活着只为家族前缀构造
102
+ * (server.ts fleet `taskNotificationFoldKey({task_id,status})` 同款用法);缺席归 "task" 域的语义
103
+ * 只在前缀用途下生效。external 帧三来源齐备(notify 端点 core 铸 / inbox entry extras 存 / drain 帧
104
+ * spread 复原),不会漏域。observer 臂 / stream 臂 / turn-open drain 登记三处必须用本函数
103
105
  * 构键且都传 task_type,键形漂移=去重永 miss。 */
104
106
  export declare function taskNotificationStreamKey(n: {
105
107
  task_type?: string;
@@ -69,7 +69,7 @@ export const SERVED_FENCE_MS = 30 * 60 * 1000;
69
69
  *
70
70
  * 编码=防碰撞元组:域/taskId/status 走 JSON 数组(调用方自由串伪造不了分隔符);`#seq` 尾折在 JSON 之外
71
71
  * ——JSON 段恒以 `"]` 结尾,`#digits` 尾无歧义,于是 {@link foldKeyFamily} 的剥尾语义 AND SQL 双生子
72
- * (tidb/pg-workflow-run-store 的 `regexp_replace(run_id, '#[0-9]+$', '')` 家族比对)原样成立——把 seq 折进
72
+ * (workflow-run-store-sql 的 `regexp_replace(run_id, '#[0-9]+$', '')` 家族比对)原样成立——把 seq 折进
73
73
  * JSON 元组会让 SQL 侧家族 ack/fence 永 miss(那是另一批的真库改动面,本修有意不碰)。
74
74
  * seq 折入=逐停机周期各自成键(1.283 起 background_agent 四腿 notify 铸 cycleSeq);无 seq=单周期旧键
75
75
  * (bash/monitor terminal/retain 降级,诚实语义)。serve-fence 侧必须用同一函数(或其家族前缀)构造,
@@ -87,9 +87,11 @@ export function taskNotificationFoldKey(n) {
87
87
  * task 的 Monitor event 批与 failed 终态在一条腿上互吞;wire 去重要的是逐帧身份,不是 inbox 的双终态列。
88
88
  * `seq` 折入 = 停→唤→停的第二周期同 status 帧各自成键(core 1.283 起 background_agent 四腿 notify 铸
89
89
  * cycleSeq;缺 seq 时旧键曾把二周期 completed 帧在 observer 臂反向吞掉——core [784]④a);无 seq 的帧
90
- * (bash/monitor terminal/retain 降级)保持单周期旧键=同键第二帧吞,诚实语义。task_type 缺席(旧 core
91
- * 内部帧)归 "task" 域——external 帧的 task_type 三来源齐备(notify 端点 core 铸 / inbox entry extras 存
92
- * / drain spread 复原),不会漏域。observer / stream 臂 / turn-open drain 登记三处必须用本函数
90
+ * (bash/monitor terminal/retain 降级)保持单周期旧键=同键第二帧吞,诚实语义。[2373]B-10:core 4.0.0
91
+ * task_type 是必填闭合枚举——`task_type?` 可选性**不再对应旧 core 帧**,它活着只为家族前缀构造
92
+ * (server.ts fleet `taskNotificationFoldKey({task_id,status})` 同款用法);缺席归 "task" 域的语义
93
+ * 只在前缀用途下生效。external 帧三来源齐备(notify 端点 core 铸 / inbox entry extras 存 / drain 帧
94
+ * spread 复原),不会漏域。observer 臂 / stream 臂 / turn-open drain 登记三处必须用本函数
93
95
  * 构键且都传 task_type,键形漂移=去重永 miss。 */
94
96
  export function taskNotificationStreamKey(n) {
95
97
  const domain = n.task_type === "external" ? "external" : "task";
@@ -1,8 +1,7 @@
1
1
  /**
2
2
  * Cross-replica circuit-breaker state (core 1.38 `BreakerState`) — SINGLE-FILE DUAL-DIALECT
3
3
  * (design/158 A12 定型半场). ONE implementation, TWO dialects; the historical `TiDBBreakerState` /
4
- * `PgBreakerState` class names survive as thin ctor subclasses (src/plugins/tidb-breaker-state.ts +
5
- * src/plugins/pg-breaker-state.ts are now re-export shims) so every consumer (store-backend.ts, the
4
+ * `PgBreakerState` class names survive as thin ctor subclasses in THIS file ([2354]: the old per-dialect shim files are deleted) so every consumer (store-backend.ts, the
6
5
  * fake-pool unit suites, the real dual-DB integration suite) is untouched.
7
6
  *
8
7
  * core's `createCircuitBreakerBrain` defaults to a per-PROCESS Map → on a multi-replica deployment
@@ -26,7 +25,7 @@
26
25
  * - upsert form: `ON DUPLICATE KEY UPDATE … VALUES(col)` vs `ON CONFLICT (breaker_key) DO UPDATE SET
27
26
  * … EXCLUDED.col`
28
27
  * - schema ownership: TiDB DDL lives centrally in tidb-pool.ts; PG DDL is self-contained here
29
- * (`PG_BREAKER_STATE_SCHEMA` / `ensureSchema`, re-exported off pg-breaker-state.ts) — disjoint table,
28
+ * (`PG_BREAKER_STATE_SCHEMA` / `ensureSchema`, exported from THIS file) — disjoint table,
30
29
  * so a standalone idempotent apply is safe (no central-schema shadowing), mirroring every other PG store.
31
30
  * Everything else (write-through logic, the pending-guard race fix, refresh/prune, row→snapshot mapping,
32
31
  * opened_at Date handling) is IDENTICAL — the SqlDriver seam (result unwrapping) is what let the row
@@ -3,7 +3,6 @@ import type { Pool as PgPool, PoolClient } from "pg";
3
3
  import { type ImageStatus, type ImageIndexEntry, type ImageIndexUpsert, type ImageViewer, type ImageListFilter } from "./store-contracts.js";
4
4
  import { type SqlDriver } from "./sql-driver.js";
5
5
  export type { ImageNestedBuildMode, ImageCapabilities, ImagePodContract, ImageStatus, ImageVisibility, ImageIndexEntry, ImageIndexUpsert, ImageViewer, ImageListFilter, ImageRow, } from "./store-contracts.js";
6
- export { mapImageRow as mapRow } from "./store-contracts.js";
7
6
  /** PG translation of the `sandbox_image_index` DDL in tidb-pool.ts (JSON→JSONB, DATETIME(3)→TIMESTAMPTZ(3),
8
7
  * TINYINT(1)→SMALLINT(布尔列 PG 映射归一,clay 批 2026-07-26 —— 两方言读回同为 number,写入 0/1,
9
8
  * 读侧 `!!` 保持,出口 JS 类型不变), inline UNIQUE KEY/KEY → separate CREATE UNIQUE INDEX / CREATE INDEX). */
@@ -47,7 +47,6 @@ import {
47
47
  // backend-neutral store-contracts.ts (design/158 A3 沉底; no adapter imports its twin).
48
48
  mapImageRow as mapRow, } from "./store-contracts.js";
49
49
  import { mysqlDriver, pgDriver } from "./sql-driver.js";
50
- export { mapImageRow as mapRow } from "./store-contracts.js";
51
50
  /** PG translation of the `sandbox_image_index` DDL in tidb-pool.ts (JSON→JSONB, DATETIME(3)→TIMESTAMPTZ(3),
52
51
  * TINYINT(1)→SMALLINT(布尔列 PG 映射归一,clay 批 2026-07-26 —— 两方言读回同为 number,写入 0/1,
53
52
  * 读侧 `!!` 保持,出口 JS 类型不变), inline UNIQUE KEY/KEY → separate CREATE UNIQUE INDEX / CREATE INDEX). */
@@ -1,5 +1,5 @@
1
1
  import { type Checkpoint, type CheckpointSummary, type CheckpointToken, type ReopenReason, type ResolveExpectation, type ResumeOutcome } from "@sema-agent/core";
2
- import { type PendingCheckpoint } from "./tidb-checkpoint-store.js";
2
+ import { type PendingCheckpoint } from "./checkpoint-store-sql.js";
3
3
  export interface LocalCheckpointStoreOptions {
4
4
  /** taskId join for the pending card (the local FileRunStore's `getActiveTaskId`). Absent ⇒ `taskId: null`. */
5
5
  getActiveTaskId?: (sessionId: string) => Promise<string | undefined>;
@@ -24,7 +24,7 @@ import { createHash } from "node:crypto";
24
24
  import { existsSync, readFileSync, readdirSync, renameSync, unlinkSync, mkdirSync } from "node:fs";
25
25
  import { join } from "node:path";
26
26
  import { FileCheckpointStore, atomicWriteFile, sanitizePathComponent, } from "@sema-agent/core";
27
- import { boundedToolInput, TERMINAL_BACKSTOP_MS, TERMINAL_GRACE_MS } from "./tidb-checkpoint-store.js";
27
+ import { boundedToolInput, TERMINAL_BACKSTOP_MS, TERMINAL_GRACE_MS } from "./checkpoint-store-sql.js";
28
28
  /** design/80 D-D read-time twin of the TiDB put-time `terminal_at` column (same formula — anti-drift). */
29
29
  function terminalAtOf(cp) {
30
30
  return Math.max(cp.createdAt + TERMINAL_BACKSTOP_MS, (cp.deadline ?? 0) + TERMINAL_GRACE_MS);
@@ -19,7 +19,8 @@
19
19
  // Vector rungs (design/81, re-mounted here per §4): lexical (jaccard, byte-equal to FileBackend) →
20
20
  // portable (jsonb vectors, in-process cosine) → native (pgvector `<=>` SQL). All three share the
21
21
  // cosine-distance contract score ∈ [0,2] — upgrading recall is a config change, not a recalibration.
22
- import { cosineDistance, jaccardDistance, termSet, isUniqueViolation } from "./memory-engine-vector-util.js";
22
+ import { cosineDistance, jaccardDistance, termSet } from "@sema-agent/core";
23
+ import { isUniqueViolation } from "./memory-engine-vector-util.js";
23
24
  import { computeEntryRev, serializeEntryFile } from "@sema-agent/core";
24
25
  import { pgSafeJsonStringify, pgHasUnstorable } from "./pg-safe-json.js";
25
26
  /** Table names (single source). Deliberately DISJOINT from the legacy `agent_memory*` tables —
@@ -21,7 +21,7 @@
21
21
  // - v1 lexical only:embedder/vector 面无 TiDB 对应(Pg 的 pgvector rung 是 Pg 专属);构造签名保留
22
22
  // opts 但传入 embedder=fail-loud 拒绝,search 恒走 jaccard 词面,haystack 与 Pg/File 逐字节同构
23
23
  // (`${name ?? slug} ${description} ${body}`——memoryBackendContract 的 search 等价断言依赖)。
24
- import { jaccardDistance, termSet } from "./memory-engine-vector-util.js";
24
+ import { jaccardDistance, termSet } from "@sema-agent/core";
25
25
  import { computeEntryRev, serializeEntryFile } from "@sema-agent/core";
26
26
  import { pgHasUnstorable } from "./pg-safe-json.js";
27
27
  /** Table names (single source) — SAME names as PG_MEMORY_ENGINE_TABLES (the two dialects never share
@@ -1,8 +1,7 @@
1
- /** memory-engine 方言实现共用的纯工具函数。三个距离/词集函数 re-export 自 core(1.268.0 起公开导出,
2
- * 单一语义源;memoryBackendContract search 等价断言依赖同源 haystack 距离)。
1
+ /** memory-engine 方言实现共用的纯工具函数。三个距离/词集函数(termSet/jaccardDistance/cosineDistance)
2
+ * core(1.268.0 起公开导出,单一语义源)——消费者直引 core([2354] 兼容面全清:此处转口已删)。
3
3
  * `isUniqueViolation` 重新内联:它当年随 core 的 pg **示例适配器**导出面走,core 1.424 按 clay 包卫生令
4
4
  * 把整个 examples 面退出 npm 包([1803] BREAKING)⇒ re-export 断源。逐字抄自 core 1.423
5
5
  * `examples/adapters/pg-adapter.js`(纯谓词,无 byte-equal 契约约束)。 */
6
- export { termSet, jaccardDistance, cosineDistance } from "@sema-agent/core";
7
6
  export declare function isUniqueViolation(err: unknown): boolean;
8
7
  //# sourceMappingURL=memory-engine-vector-util.d.ts.map
@@ -1,9 +1,8 @@
1
- /** memory-engine 方言实现共用的纯工具函数。三个距离/词集函数 re-export 自 core(1.268.0 起公开导出,
2
- * 单一语义源;memoryBackendContract search 等价断言依赖同源 haystack 距离)。
1
+ /** memory-engine 方言实现共用的纯工具函数。三个距离/词集函数(termSet/jaccardDistance/cosineDistance)
2
+ * core(1.268.0 起公开导出,单一语义源)——消费者直引 core([2354] 兼容面全清:此处转口已删)。
3
3
  * `isUniqueViolation` 重新内联:它当年随 core 的 pg **示例适配器**导出面走,core 1.424 按 clay 包卫生令
4
4
  * 把整个 examples 面退出 npm 包([1803] BREAKING)⇒ re-export 断源。逐字抄自 core 1.423
5
5
  * `examples/adapters/pg-adapter.js`(纯谓词,无 byte-equal 契约约束)。 */
6
- export { termSet, jaccardDistance, cosineDistance } from "@sema-agent/core";
7
6
  export function isUniqueViolation(err) {
8
7
  if (typeof err !== "object" || err === null)
9
8
  return false;
@@ -22,7 +22,7 @@ import type { RunRecord, SessionSummary, RunEvent } from "./store-contracts.js";
22
22
  * injects this probe so the reapers get the SAME two predicates the SQL twins express as EXISTS subqueries:
23
23
  * - hasPending = EXISTS (checkpoint c WHERE c.session_id = ? AND c.status = 'pending') — the design/80 D-D
24
24
  * NOT-EXISTS-pending guard: a row whose checkpoint is STILL pending is owned by the checkpoint-state-driven
25
- * sweeps and must NEVER be time-reaped (else two-runs-one-session, see tidb-run-store.ts reapSuspended doc).
25
+ * sweeps and must NEVER be time-reaped (else two-runs-one-session, see run-store-sql.ts reapSuspended doc).
26
26
  * - hasExpired = EXISTS (checkpoint ce WHERE ce.session_id = ? AND ce.status = 'expired') — the
27
27
  * failSuspendedWithExpiredCheckpoint driver (checkpoint-STATE-driven, not time-driven).
28
28
  * Probe ABSENT (old assembly / no checkpoint store wired) ⇒ the reapers stay honest NO-OPs — without the
@@ -4,7 +4,7 @@
4
4
  * WHY THIS EXISTS (and not core's `InMemorySessionPolicyStore`): core's in-memory/file policy stores implement only
5
5
  * the core interface (getRules/putRules/listBySession) — they have NO deletion seam, so neither the E21 session purge
6
6
  * nor the 2c `overwrite-dst` subsystem wipe can remove policy rows on a backend that uses them (the SQL twins carry
7
- * `deleteBySession` as a service extension; see tidb/pg-session-policy-store.ts). This store is the delete-capable
7
+ * `deleteBySession` as a service extension; see session-policy-store-sql.ts). This store is the delete-capable
8
8
  * in-memory twin. The seam itself is also requested upstream (core: optional `deleteBySession?` on the interface +
9
9
  * the File/InMemory impls) — if core lands it, this class can retire in favor of core's.
10
10
  *
@@ -4,7 +4,7 @@
4
4
  * WHY THIS EXISTS (and not core's `InMemorySessionPolicyStore`): core's in-memory/file policy stores implement only
5
5
  * the core interface (getRules/putRules/listBySession) — they have NO deletion seam, so neither the E21 session purge
6
6
  * nor the 2c `overwrite-dst` subsystem wipe can remove policy rows on a backend that uses them (the SQL twins carry
7
- * `deleteBySession` as a service extension; see tidb/pg-session-policy-store.ts). This store is the delete-capable
7
+ * `deleteBySession` as a service extension; see session-policy-store-sql.ts). This store is the delete-capable
8
8
  * in-memory twin. The seam itself is also requested upstream (core: optional `deleteBySession?` on the interface +
9
9
  * the File/InMemory impls) — if core lands it, this class can retire in favor of core's.
10
10
  *
@@ -27,7 +27,7 @@ export async function ensurePgMemorySyncSchema(query) {
27
27
  await query(`CREATE INDEX IF NOT EXISTS ${PG_MEMORY_SYNC_TABLES.pushQueue}_next_attempt_idx ON ${PG_MEMORY_SYNC_TABLES.pushQueue} (next_attempt_at)`);
28
28
  }
29
29
  /** jsonb defense: node-pg hands back parsed objects, but a text-typed round-trip (or a foreign
30
- * writer) may yield a string — same posture as parseJson in pg-run-store.ts. */
30
+ * writer) may yield a string — same posture as parseJson in run-store-sql.ts. */
31
31
  function fromJsonb(v) {
32
32
  if (typeof v === "string")
33
33
  return JSON.parse(v);
@@ -28,14 +28,13 @@ import pg from "pg";
28
28
  // Each PG store owns its own (disjoint) tables' DDL via a standalone idempotent ensureSchema; the central apply
29
29
  // composes them so production wires ONE ensurePgSchema (the PG twin of tidb-pool's single ensureSchema).
30
30
  import { ensureSchema as ensureSessionSchema } from "./pg-session-storage.js";
31
- import { ensureSchema as ensureToolResultSchema } from "./pg-tool-result-store.js";
31
+ import { ensureSchema as ensureToolResultSchema } from "./tool-result-store-sql.js";
32
32
  import { ensureSchema as ensureCostQuotaSchema } from "./pg-cost-quota.js";
33
33
  import { ensureSchema as ensureRateLimitSchema } from "./pg-rate-limiter.js";
34
- import { ensureSchema as ensureBreakerStateSchema } from "./pg-breaker-state.js";
35
- import { ensureSchema as ensureApprovalSchema } from "./pg-approval-store.js";
36
- import { ensureSchema as ensureOutcomeLedgerSchema } from "./pg-outcome-ledger.js";
37
- import { ensureSchema as ensureImageIndexSchema } from "./pg-image-index.js";
38
- import { ensureSchema as ensureImageBakeSchema } from "./pg-image-bake.js";
34
+ import { ensureSchema as ensureBreakerStateSchema } from "./breaker-state-sql.js";
35
+ import { ensurePgOutcomeLedgerSchema as ensureOutcomeLedgerSchema } from "./outcome-ledger-sql.js";
36
+ import { ensureSchema as ensureImageIndexSchema } from "./image-index-sql.js";
37
+ import { ensurePgImageBakeSchema as ensureImageBakeSchema } from "./image-bake-store-sql.js";
39
38
  export const PG_SCHEMA_STATEMENTS = [
40
39
  `CREATE TABLE IF NOT EXISTS task_run (
41
40
  task_id VARCHAR(64) NOT NULL,
@@ -145,7 +144,7 @@ export const PG_SCHEMA_STATEMENTS = [
145
144
  `CREATE INDEX IF NOT EXISTS idx_sendfile_link_scope ON sendfile_link (scope, id)`,
146
145
  // E6 durable SessionPolicyStore (the PG twin of the TiDB session_policy table; policy_key = sha256(JSON.stringify(
147
146
  // [sessionId, principal ?? null])) = a fixed 64-char hash PK; rules JSONB; CAS-versioned tighten-only — see
148
- // tidb-pool.ts / tidb-session-policy-store.ts).
147
+ // tidb-pool.ts / session-policy-store-sql.ts).
149
148
  `CREATE TABLE IF NOT EXISTS session_policy (
150
149
  policy_key CHAR(64) NOT NULL,
151
150
  session_id VARCHAR(64) NOT NULL,
@@ -186,7 +185,7 @@ export const PG_SCHEMA_STATEMENTS = [
186
185
  // SVC-2 (core CORE-7) durable WorkflowJournalStore — the PG twin of the TiDB workflow_journal table (cross-replica
187
186
  // resume journal; (run_id, ordinal) PK = idempotent OVERWRITE upsert; `result` = JSON.stringify(TaskResult)). `result`
188
187
  // is TEXT, NOT JSONB — the byte-match contract is "string in, string out" (the store JSON.parses on load); JSONB would
189
- // make `pg` auto-parse the row back to an object and break the twin's String()→JSON.parse path. See pg-workflow-journal-store.ts.
188
+ // make `pg` auto-parse the row back to an object and break the twin's String()→JSON.parse path. See workflow-journal-store-sql.ts.
190
189
  `CREATE TABLE IF NOT EXISTS workflow_journal (
191
190
  run_id VARCHAR(191) NOT NULL,
192
191
  ordinal INT NOT NULL,
@@ -210,7 +209,7 @@ export const PG_SCHEMA_STATEMENTS = [
210
209
  claimed_at BIGINT NOT NULL,
211
210
  PRIMARY KEY (source_run_id, scope)
212
211
  )`,
213
- // P1 (fleet failover): WorkflowRunStore + completion-inbox PG twins (design doc in tidb-workflow-run-store.ts).
212
+ // P1 (fleet failover): WorkflowRunStore + completion-inbox PG twins (design doc in workflow-run-store-sql.ts).
214
213
  // `run` is TEXT not jsonb (node-pg auto-parse would break the shared String()→JSON.parse path).
215
214
  `CREATE TABLE IF NOT EXISTS workflow_run (
216
215
  id VARCHAR(191) NOT NULL,
@@ -332,7 +331,6 @@ export async function ensurePgSchema(pool) {
332
331
  await ensureCostQuotaSchema(client);
333
332
  await ensureRateLimitSchema(client);
334
333
  await ensureBreakerStateSchema(client);
335
- await ensureApprovalSchema(client);
336
334
  await ensureOutcomeLedgerSchema(client);
337
335
  await ensureImageIndexSchema(client);
338
336
  await ensureImageBakeSchema(client);
@@ -8,8 +8,7 @@
8
8
  *
9
9
  * design/158 A12 C1b: the `PgWriteBehindCounter` this file used to define inline now lives in
10
10
  * write-behind-counter.ts as the PG binding of ONE dialect-parameterized counter (the mysql2 twin is
11
- * `WriteBehindCounter`); the SQL-dialect deltas are documented and branched there. It is re-exported here
12
- * so the historical import path keeps working.
11
+ * `WriteBehindCounter`); the SQL-dialect deltas are documented and branched there.
13
12
  *
14
13
  * Schema: this store's `rate_limit` table is DISJOINT from the other PG stores' tables, so a
15
14
  * self-contained {@link PG_RATE_LIMITER_SCHEMA} + {@link ensureSchema} is safe (no shadowing).
@@ -17,8 +16,6 @@
17
16
  import type { Pool, PoolClient } from "pg";
18
17
  import type { RateDecision, RateGate } from "../observability/rate-limit.js";
19
18
  import { type CounterDegradeHook } from "./write-behind-counter.js";
20
- export { PgWriteBehindCounter } from "./write-behind-counter.js";
21
- export type { CounterTable } from "./write-behind-counter.js";
22
19
  export declare class PgRateLimiter implements RateGate {
23
20
  private readonly limit;
24
21
  private readonly counter;
@@ -1,5 +1,4 @@
1
1
  import { PgWriteBehindCounter } from "./write-behind-counter.js";
2
- export { PgWriteBehindCounter } from "./write-behind-counter.js";
3
2
  /** The counter's table binding for the per-key request rate limit (mirror of the TiDB twin's binding). */
4
3
  const RATE_LIMIT_TABLE = { table: "rate_limit", keyCol: "limit_key", valCol: "n" };
5
4
  export class PgRateLimiter {
@@ -21,11 +21,9 @@
21
21
  * 是「core 变语义必须先过迁移裁量」的告警钉)。
22
22
  */
23
23
  import type { Pool } from "mysql2/promise";
24
- import { normalizeAgentName, type RosterStore, type RosterEntry } from "@sema-agent/core";
24
+ import { type RosterStore, type RosterEntry } from "@sema-agent/core";
25
25
  type RosterAccess = Parameters<RosterStore["resolve"]>[1];
26
26
  import type { PgQueryFn } from "./pg-query.js";
27
- /** 兼容名保留(测试/历史引用),现=core 导出直引(私拷已删)。 */
28
- export declare const normalizeAgentNameLocal: typeof normalizeAgentName;
29
27
  export declare const ROSTER_TABLE = "agent_roster";
30
28
  export declare function ensureTiDBRosterSchema(pool: Pool): Promise<void>;
31
29
  export declare function ensurePgRosterSchema(q: PgQueryFn): Promise<void>;
@@ -1,6 +1,4 @@
1
1
  import { normalizeAgentName } from "@sema-agent/core";
2
- /** 兼容名保留(测试/历史引用),现=core 导出直引(私拷已删)。 */
3
- export const normalizeAgentNameLocal = normalizeAgentName;
4
2
  export const ROSTER_TABLE = "agent_roster";
5
3
  /** 行 → RosterEntry(缺席键省略,core 形逐字;session_scoped 数值/布尔双方言归一)。
6
4
  * core 1.365 BREAKING:owner/scope 升类型必填——两方言 CREATE 直接建成 NOT NULL(当年的「清死行 +
@@ -114,7 +112,7 @@ export async function ensurePgRosterSchema(q) {
114
112
  /** upsert 参数序(两方言共用;core 1.365 起 owner/scope 类型必填——键列直取,与 core upsertKey 同键)。 */
115
113
  function upsertParams(entry, now) {
116
114
  return [
117
- normalizeAgentNameLocal(entry.name),
115
+ normalizeAgentName(entry.name),
118
116
  entry.owner,
119
117
  entry.scope,
120
118
  entry.name,
@@ -148,7 +146,7 @@ export class TiDBRosterStore {
148
146
  session_scoped = VALUES(session_scoped), root_session_id = VALUES(root_session_id), model = VALUES(model), created_at_ms = VALUES(created_at_ms), recorded_at_ms = VALUES(recorded_at_ms)`, p.map((v) => (typeof v === "boolean" ? (v ? 1 : 0) : v)));
149
147
  }
150
148
  async resolve(name, access) {
151
- const key = normalizeAgentNameLocal(name);
149
+ const key = normalizeAgentName(name);
152
150
  if (key === "")
153
151
  return undefined;
154
152
  const [rows] = (await this.pool.query(`SELECT ${COLS} FROM ${ROSTER_TABLE} WHERE ${RESOLVE_WHERE_TIDB} ORDER BY created_at_ms DESC, recorded_at_ms DESC, agent_id DESC LIMIT 1`, [key, access.scope ?? null, access.owner ?? null, access.sessionId ?? null, access.sessionId ?? null]));
@@ -185,7 +183,7 @@ export class PgRosterStore {
185
183
  recorded_at_ms = EXCLUDED.recorded_at_ms`, upsertParams(entry, this.clock()));
186
184
  }
187
185
  async resolve(name, access) {
188
- const key = normalizeAgentNameLocal(name);
186
+ const key = normalizeAgentName(name);
189
187
  if (key === "")
190
188
  return undefined;
191
189
  const { rows } = await this.q(`SELECT ${COLS} FROM ${ROSTER_TABLE} WHERE ${RESOLVE_WHERE_PG} ORDER BY created_at_ms DESC, recorded_at_ms DESC, agent_id DESC LIMIT 1`, [key, access.scope ?? null, access.owner ?? null, access.sessionId ?? null, access.sessionId ?? null]);
@@ -3,27 +3,19 @@ import type { Pool as PgPool } from "pg";
3
3
  import type { SessionStore, SessionPolicyStore, FileSnapshotStore, WorkflowJournalStore, ToolResultStore } from "@sema-agent/core";
4
4
  import { type FileSnapshotBounds } from "@sema-agent/core";
5
5
  import { type OutcomeSink } from "./file-outcome-sink.js";
6
- import { type InboxWarn } from "./tidb-workflow-run-store.js";
6
+ import { type InboxWarn } from "./workflow-run-store-sql.js";
7
7
  import { FileRunStore } from "./file-run-store.js";
8
8
  import { LocalCheckpointStore } from "./local-checkpoint-store.js";
9
9
  import { FileResumeAnchorStore } from "./file-resume-anchor-store.js";
10
10
  import { type ApprovalExemptionStore } from "./approval-exemption-store.js";
11
11
  import { type SendFileLedger } from "./send-file-ledger.js";
12
- import { TiDBResumeAnchorStore } from "./tidb-resume-anchor-store.js";
13
- import { PgResumeAnchorStore } from "./pg-resume-anchor-store.js";
12
+ import { TiDBResumeAnchorStore, PgResumeAnchorStore } from "./resume-anchor-store-sql.js";
14
13
  import type { ServiceConfig } from "../config-types.js";
15
- import { TiDBRunStore } from "./tidb-run-store.js";
16
- import { PgRunStore } from "./pg-run-store.js";
17
- import { TiDBCheckpointStore } from "./tidb-checkpoint-store.js";
18
- import { PgCheckpointStore } from "./pg-checkpoint-store.js";
19
- import { TiDBApprovalStore } from "./tidb-approval-store.js";
20
- import { PgApprovalStore } from "./pg-approval-store.js";
21
- import { TiDBImageIndex } from "./tidb-image-index.js";
22
- import { PgImageIndex } from "./pg-image-index.js";
23
- import { TiDBImageBake } from "./tidb-image-bake.js";
24
- import { PgImageBake } from "./pg-image-bake.js";
25
- import { TiDBBreakerState } from "./tidb-breaker-state.js";
26
- import { PgBreakerState } from "./pg-breaker-state.js";
14
+ import { TiDBRunStore, PgRunStore } from "./run-store-sql.js";
15
+ import { TiDBCheckpointStore, PgCheckpointStore } from "./checkpoint-store-sql.js";
16
+ import { TiDBImageIndex, PgImageIndex } from "./image-index-sql.js";
17
+ import { TiDBImageBake, PgImageBake } from "./image-bake-store-sql.js";
18
+ import { TiDBBreakerState, PgBreakerState } from "./breaker-state-sql.js";
27
19
  import { TiDBCostQuota } from "./tidb-cost-quota.js";
28
20
  import { PgCostQuota } from "./pg-cost-quota.js";
29
21
  import { TiDBRateLimiter } from "./tidb-rate-limiter.js";
@@ -79,7 +71,6 @@ export type ServiceWorkflowJournalStore = WorkflowJournalStore & {
79
71
  * TaskResult-bearing table (the per-run deleteByRun has no run-store reap hook). Local InMemory omits it. */
80
72
  reapExpired?(now: number, maxAgeMs: number): Promise<number>;
81
73
  };
82
- export type ApprovalStore = TiDBApprovalStore | PgApprovalStore;
83
74
  export type ImageIndex = TiDBImageIndex | PgImageIndex;
84
75
  export type ImageBake = TiDBImageBake | PgImageBake;
85
76
  /** The FULL checkpoint store (core CheckpointStore + the service operator-queue/ctx methods listPending/
@@ -155,7 +146,6 @@ export interface StoreBackend {
155
146
  checkpoint?(logger?: {
156
147
  info?(msg: string, meta?: unknown): void;
157
148
  }): CheckpointStoreFull;
158
- approval?(): ApprovalStore;
159
149
  toolResult?(): ToolResultStoreFull;
160
150
  imageIndex?(): ImageIndex;
161
151
  imageBake?(): ImageBake;
@@ -4,48 +4,34 @@
4
4
  * subsystem. main.ts wires through this instead of `new TiDB*(pool)` so `DB_BACKEND=pg` boots the whole service on
5
5
  * PG with zero call-site churn. The twins are interchangeable behaviourally (one shared real-DB integration suite
6
6
  * keeps them in lock-step); the unions below exist only because TS private fields make the concrete classes
7
- * nominally distinct (run/approval/imageIndex/imageBake have no core interface — the rest implement one).
7
+ * nominally distinct (run/imageIndex/imageBake have no core interface — the rest implement one).
8
8
  */
9
9
  import { homedir } from "node:os";
10
10
  import { join } from "node:path";
11
11
  import { FileStorageBackend, FileSessionRepo, DEFAULT_SNAPSHOT_BOUNDS } from "@sema-agent/core";
12
- import { FileWorkflowJournalStore } from "./file-workflow-journal-store.js";
13
- import { TiDBOutcomeLedger } from "./tidb-outcome-ledger.js";
14
- import { PgOutcomeLedger } from "./pg-outcome-ledger.js";
12
+ import { FileWorkflowJournalStore } from "@sema-agent/core";
13
+ import { TiDBOutcomeLedger, PgOutcomeLedger } from "./outcome-ledger-sql.js";
15
14
  import { FileOutcomeSink } from "./file-outcome-sink.js";
16
- import { TiDBWorkflowRunStore, TiDBWorkflowCompletionInbox, TiDBWorkflowNotifyJournalStore } from "./tidb-workflow-run-store.js";
17
- import { PgWorkflowRunStore, PgWorkflowCompletionInbox, PgWorkflowNotifyJournalStore } from "./pg-workflow-run-store.js";
15
+ import { TiDBWorkflowRunStore, TiDBWorkflowCompletionInbox, TiDBWorkflowNotifyJournalStore, PgWorkflowRunStore, PgWorkflowCompletionInbox, PgWorkflowNotifyJournalStore } from "./workflow-run-store-sql.js";
18
16
  import { FileRunStore } from "./file-run-store.js";
19
17
  import { LocalSessionStore } from "./local-session-store.js";
20
18
  import { LocalCheckpointStore } from "./local-checkpoint-store.js";
21
19
  import { FileResumeAnchorStore } from "./file-resume-anchor-store.js";
22
20
  import { TiDBApprovalExemptionStore, PgApprovalExemptionStore, FileApprovalExemptionStore } from "./approval-exemption-store.js";
23
21
  import { TiDBSendFileLedger, PgSendFileLedger, FileSendFileLedger } from "./send-file-ledger.js";
24
- import { TiDBResumeAnchorStore } from "./tidb-resume-anchor-store.js";
25
- import { PgResumeAnchorStore } from "./pg-resume-anchor-store.js";
26
- import { TiDBSessionPolicyStore } from "./tidb-session-policy-store.js";
27
- import { PgSessionPolicyStore } from "./pg-session-policy-store.js";
28
- import { TiDBWorkflowJournalStore } from "./tidb-workflow-journal-store.js";
29
- import { PgWorkflowJournalStore } from "./pg-workflow-journal-store.js";
30
- import { TiDBFileSnapshotStore } from "./tidb-file-snapshot-store.js";
31
- import { PgFileSnapshotStore } from "./pg-file-snapshot-store.js";
22
+ import { TiDBResumeAnchorStore, PgResumeAnchorStore } from "./resume-anchor-store-sql.js";
23
+ import { TiDBSessionPolicyStore, PgSessionPolicyStore } from "./session-policy-store-sql.js";
24
+ import { TiDBWorkflowJournalStore, PgWorkflowJournalStore } from "./workflow-journal-store-sql.js";
25
+ import { TiDBFileSnapshotStore, PgFileSnapshotStore } from "./file-snapshot-store-sql.js";
32
26
  import { MinioBlobBackend, SqlBlobBackend } from "./blob-backend.js";
33
27
  import { createTidbPool, ensureSchema as ensureTidbSchema } from "./tidb-pool.js";
34
28
  import { createPgPool, ensurePgSchema, pgPoolOptions } from "./pg-pool.js";
35
- import { TiDBRunStore } from "./tidb-run-store.js";
36
- import { PgRunStore } from "./pg-run-store.js";
37
- import { TiDBCheckpointStore } from "./tidb-checkpoint-store.js";
38
- import { PgCheckpointStore } from "./pg-checkpoint-store.js";
39
- import { TiDBApprovalStore } from "./tidb-approval-store.js";
40
- import { PgApprovalStore } from "./pg-approval-store.js";
41
- import { TiDBToolResultStore } from "./tidb-tool-result-store.js";
42
- import { PgToolResultStore } from "./pg-tool-result-store.js";
43
- import { TiDBImageIndex } from "./tidb-image-index.js";
44
- import { PgImageIndex } from "./pg-image-index.js";
45
- import { TiDBImageBake } from "./tidb-image-bake.js";
46
- import { PgImageBake } from "./pg-image-bake.js";
47
- import { TiDBBreakerState } from "./tidb-breaker-state.js";
48
- import { PgBreakerState } from "./pg-breaker-state.js";
29
+ import { TiDBRunStore, PgRunStore } from "./run-store-sql.js";
30
+ import { TiDBCheckpointStore, PgCheckpointStore } from "./checkpoint-store-sql.js";
31
+ import { TiDBToolResultStore, PgToolResultStore } from "./tool-result-store-sql.js";
32
+ import { TiDBImageIndex, PgImageIndex } from "./image-index-sql.js";
33
+ import { TiDBImageBake, PgImageBake } from "./image-bake-store-sql.js";
34
+ import { TiDBBreakerState, PgBreakerState } from "./breaker-state-sql.js";
49
35
  import { TiDBCostQuota } from "./tidb-cost-quota.js";
50
36
  import { PgCostQuota } from "./pg-cost-quota.js";
51
37
  import { TiDBRateLimiter } from "./tidb-rate-limiter.js";
@@ -117,7 +103,6 @@ class TiDBBackend {
117
103
  completionInbox(onWarn) { return new TiDBWorkflowCompletionInbox(this.pool, onWarn); } // P1: cross-replica push half
118
104
  notifyJournal() { return new TiDBWorkflowNotifyJournalStore(this.pool); } // 1.108: cross-replica at-least-once notify
119
105
  checkpoint(logger) { return new TiDBCheckpointStore(this.pool, logger); }
120
- approval() { return new TiDBApprovalStore(this.pool); }
121
106
  toolResult() { return new TiDBToolResultStore(this.pool); }
122
107
  imageIndex() { return new TiDBImageIndex(this.pool); }
123
108
  imageBake() { return new TiDBImageBake(this.pool); }
@@ -151,7 +136,6 @@ class PgBackend {
151
136
  completionInbox(onWarn) { return new PgWorkflowCompletionInbox(this.pool, onWarn); } // P1: cross-replica push half
152
137
  notifyJournal() { return new PgWorkflowNotifyJournalStore(this.pool); } // 1.108: cross-replica at-least-once notify
153
138
  checkpoint(logger) { return new PgCheckpointStore(this.pool, logger); }
154
- approval() { return new PgApprovalStore(this.pool); }
155
139
  toolResult() { return new PgToolResultStore(this.pool); }
156
140
  imageIndex() { return new PgImageIndex(this.pool); }
157
141
  imageBake() { return new PgImageBake(this.pool); }