@sema-agent/server 7.139.0 → 7.140.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 (194) hide show
  1. package/MIGRATION.md +181 -0
  2. package/USAGE.md +19 -13
  3. package/dist/adoption/runner.js +1 -1
  4. package/dist/adoption/sql.js +1 -1
  5. package/dist/approval-card.d.ts +6 -6
  6. package/dist/bench/s1/live-deps.js +3 -2
  7. package/dist/bench/s1/row.d.ts +5 -2
  8. package/dist/bench/s1/row.js +2 -22
  9. package/dist/boot/adoption.js +1 -1
  10. package/dist/boot/execution-env.js +12 -10
  11. package/dist/boot/execution-lane.d.ts +8 -0
  12. package/dist/boot/execution-lane.js +6 -1
  13. package/dist/boot/memory-boundary.d.ts +14 -51
  14. package/dist/boot/memory-boundary.js +10 -20
  15. package/dist/boot/memory-consolidation.d.ts +15 -11
  16. package/dist/boot/memory-consolidation.js +23 -12
  17. package/dist/boot/resolve-spec.d.ts +3 -5
  18. package/dist/boot/resolve-spec.js +2 -4
  19. package/dist/boot/runner-deps.d.ts +3 -3
  20. package/dist/boot/runner-deps.js +1 -0
  21. package/dist/boot/stage-03-store-backend.d.ts +2 -6
  22. package/dist/boot/stage-03-store-backend.js +2 -3
  23. package/dist/boot/stage-04-stores.d.ts +2 -6
  24. package/dist/boot/stage-04-stores.js +5 -5
  25. package/dist/boot/stage-05-execution-env.d.ts +2 -6
  26. package/dist/boot/stage-06-runners.d.ts +2 -6
  27. package/dist/boot/stage-06-runners.js +2 -2
  28. package/dist/boot/stage-07-capability-layer.d.ts +2 -6
  29. package/dist/boot/stage-08-reapers.d.ts +2 -6
  30. package/dist/boot/stage-09-leader.d.ts +2 -6
  31. package/dist/boot/stage-10-http-server.d.ts +2 -6
  32. package/dist/boot/stage-10-http-server.js +5 -4
  33. package/dist/boot/stores.d.ts +3 -6
  34. package/dist/boot/stores.js +27 -40
  35. package/dist/boot/task-list-lane.d.ts +1 -1
  36. package/dist/boot/task-list-lane.js +1 -1
  37. package/dist/boot/web-admin.js +35 -9
  38. package/dist/capabilities/execution-lane.d.ts +2 -2
  39. package/dist/config-catalog.js +2 -1
  40. package/dist/config-provider.d.ts +14 -13
  41. package/dist/config-provider.js +24 -18
  42. package/dist/config-types.d.ts +11 -2
  43. package/dist/config.js +2 -1
  44. package/dist/delegated-session-owner.d.ts +2 -1
  45. package/dist/delegated-session-owner.js +1 -1
  46. package/dist/deployment-shape.d.ts +9 -8
  47. package/dist/deployment-shape.js +4 -4
  48. package/dist/execution-lane-caps.d.ts +97 -106
  49. package/dist/execution-lane-caps.js +67 -83
  50. package/dist/http/memory-compliance-failure-reply.d.ts +3 -1
  51. package/dist/http/memory-compliance-failure-reply.js +5 -0
  52. package/dist/http/memory-layer-reply.d.ts +30 -0
  53. package/dist/http/memory-layer-reply.js +24 -0
  54. package/dist/http/resume-legs.js +13 -16
  55. package/dist/http/retired-service-deps.d.ts +1 -1
  56. package/dist/http/retired-service-deps.js +1 -1
  57. package/dist/http/routes/adoption.js +1 -1
  58. package/dist/http/routes/memory-bundle.js +3 -0
  59. package/dist/http/routes/memory-compliance.js +8 -1
  60. package/dist/http/routes/memory-consolidation.js +12 -1
  61. package/dist/http/routes/memory-origin.js +14 -2
  62. package/dist/http/routes/memory-policy.js +5 -0
  63. package/dist/http/routes/sessions.js +28 -11
  64. package/dist/http/routes/tasks.js +4 -2
  65. package/dist/http/server.d.ts +5 -25
  66. package/dist/http/server.js +2 -2
  67. package/dist/identity-source.d.ts +1 -1
  68. package/dist/identity-source.js +1 -1
  69. package/dist/lane-home-probe.d.ts +68 -42
  70. package/dist/lane-home-probe.js +53 -30
  71. package/dist/leader/wire.js +5 -4
  72. package/dist/memory-bundle-engine.d.ts +16 -9
  73. package/dist/memory-bundle-engine.js +29 -6
  74. package/dist/memory-operator-faces.d.ts +85 -30
  75. package/dist/memory-operator-faces.js +136 -30
  76. package/dist/memory-project-layer.d.ts +3 -21
  77. package/dist/memory-project-layer.js +11 -8
  78. package/dist/memory-scope-stores.d.ts +73 -0
  79. package/dist/memory-scope-stores.js +86 -0
  80. package/dist/memory-scope.d.ts +29 -5
  81. package/dist/memory-scope.js +16 -4
  82. package/dist/memory-sync-client.d.ts +20 -7
  83. package/dist/memory-sync-client.js +31 -13
  84. package/dist/plugins/adoption-log-sql.js +4 -4
  85. package/dist/plugins/approval-ask-store-sql.js +14 -14
  86. package/dist/plugins/approval-nonce-store.js +4 -4
  87. package/dist/plugins/blob-backend.d.ts +4 -4
  88. package/dist/plugins/blob-backend.js +7 -7
  89. package/dist/plugins/breaker-state-sql.js +2 -2
  90. package/dist/plugins/checkpoint-index-columns.js +2 -2
  91. package/dist/plugins/checkpoint-store-sql.js +16 -16
  92. package/dist/plugins/device-store-sql.js +19 -19
  93. package/dist/plugins/ensure-index.d.ts +1 -2
  94. package/dist/plugins/execution-placement-sql.d.ts +8 -8
  95. package/dist/plugins/execution-placement-sql.js +8 -8
  96. package/dist/plugins/file-history-store-sql.d.ts +2 -2
  97. package/dist/plugins/file-history-store-sql.js +4 -4
  98. package/dist/plugins/image-bake-store-sql.js +9 -9
  99. package/dist/plugins/image-index-sql.js +11 -11
  100. package/dist/plugins/leader-run-store-sql.js +4 -4
  101. package/dist/plugins/mailbox-store-sql.d.ts +2 -1
  102. package/dist/plugins/mailbox-store-sql.js +4 -4
  103. package/dist/plugins/memory-engine-tidb.js +5 -5
  104. package/dist/plugins/memory-optout-grant-store-sql.js +1 -1
  105. package/dist/plugins/memory-sync-store-tidb.js +3 -3
  106. package/dist/plugins/one-time-migrations.d.ts +10 -9
  107. package/dist/plugins/one-time-migrations.js +36 -36
  108. package/dist/plugins/org-delivery-quota-store.js +2 -2
  109. package/dist/plugins/outcome-ledger-sql.js +2 -2
  110. package/dist/plugins/permission-rule-store-sql.d.ts +4 -4
  111. package/dist/plugins/permission-rule-store-sql.js +16 -16
  112. package/dist/plugins/remote-env-adb.d.ts +7 -24
  113. package/dist/plugins/remote-env-adb.js +22 -5
  114. package/dist/plugins/remote-env-device.d.ts +2 -28
  115. package/dist/plugins/remote-env-device.js +2 -1
  116. package/dist/plugins/remote-env-e2b.d.ts +18 -26
  117. package/dist/plugins/remote-env-e2b.js +51 -4
  118. package/dist/plugins/remote-env-file-error.d.ts +1 -1
  119. package/dist/plugins/remote-env-file-error.js +8 -2
  120. package/dist/plugins/remote-env-host.d.ts +19 -35
  121. package/dist/plugins/remote-env-host.js +26 -3
  122. package/dist/plugins/remote-env-k8s.d.ts +3 -14
  123. package/dist/plugins/remote-env-k8s.js +3 -2
  124. package/dist/plugins/remote-env-local-docker.d.ts +4 -15
  125. package/dist/plugins/remote-env-local-docker.js +5 -4
  126. package/dist/plugins/remote-env-ssh.d.ts +4 -24
  127. package/dist/plugins/remote-env-ssh.js +4 -3
  128. package/dist/plugins/resume-anchor-store-sql.js +2 -2
  129. package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
  130. package/dist/plugins/retention-lane-store-sql.js +2 -2
  131. package/dist/plugins/retention-store-sql.d.ts +1 -1
  132. package/dist/plugins/retention-store-sql.js +6 -6
  133. package/dist/plugins/run-store-sql.js +15 -15
  134. package/dist/plugins/schema-consistency.d.ts +6 -6
  135. package/dist/plugins/schema-consistency.js +1 -1
  136. package/dist/plugins/schema-ensure-legs.d.ts +2 -3
  137. package/dist/plugins/schema-ensure-legs.js +2 -2
  138. package/dist/plugins/schema-live-columns.d.ts +1 -1
  139. package/dist/plugins/session-capture-record-store-sql.js +1 -1
  140. package/dist/plugins/session-rules-column.d.ts +1 -1
  141. package/dist/plugins/session-rules-column.js +1 -1
  142. package/dist/plugins/session-workspace-cell.d.ts +1 -1
  143. package/dist/plugins/session-workspace-cell.js +1 -1
  144. package/dist/plugins/shared-memory-store-sql.js +2 -2
  145. package/dist/plugins/sql-driver.d.ts +10 -5
  146. package/dist/plugins/sql-driver.js +6 -6
  147. package/dist/plugins/sql-errors.js +1 -1
  148. package/dist/plugins/store-backend.d.ts +4 -6
  149. package/dist/plugins/store-backend.js +6 -6
  150. package/dist/plugins/task-list-store-sql.js +11 -11
  151. package/dist/plugins/tidb-pool.js +5 -5
  152. package/dist/plugins/tidb-session-storage.js +4 -4
  153. package/dist/plugins/tidb-session-store.js +13 -13
  154. package/dist/plugins/tool-result-store-sql.d.ts +2 -2
  155. package/dist/plugins/tool-result-store-sql.js +3 -3
  156. package/dist/plugins/user-input-ledger-sql.js +2 -2
  157. package/dist/plugins/workflow-journal-store-sql.js +5 -5
  158. package/dist/plugins/workflow-run-store-sql.js +19 -19
  159. package/dist/plugins/write-behind-counter.d.ts +2 -3
  160. package/dist/plugins/write-behind-counter.js +5 -5
  161. package/dist/resource-suspend.d.ts +14 -12
  162. package/dist/resource-suspend.js +1 -1
  163. package/dist/resource-window.d.ts +4 -3
  164. package/dist/run-local.js +14 -19
  165. package/dist/runs.d.ts +8 -4
  166. package/dist/runs.js +49 -65
  167. package/dist/session-incarnation.d.ts +1 -1
  168. package/dist/session-incarnation.js +1 -1
  169. package/dist/session-policy-wire.d.ts +1 -1
  170. package/dist/sql-engine-posture.d.ts +1 -1
  171. package/dist/sql-engine-posture.js +1 -1
  172. package/dist/{plugins → stores-sql}/background-agent-store-sql.d.ts +2 -2
  173. package/dist/{plugins → stores-sql}/background-agent-store-sql.js +8 -8
  174. package/dist/{plugins → stores-sql}/session-policy-store-sql.d.ts +7 -5
  175. package/dist/{plugins → stores-sql}/session-policy-store-sql.js +12 -12
  176. package/dist/{plugins → stores-sql}/usage-window-store-sql.d.ts +1 -1
  177. package/dist/{plugins → stores-sql}/usage-window-store-sql.js +3 -3
  178. package/dist/task-a2a.js +5 -6
  179. package/dist/task-mcp.d.ts +20 -7
  180. package/dist/task-mcp.js +17 -9
  181. package/dist/terminal.d.ts +27 -0
  182. package/dist/terminal.js +6 -0
  183. package/dist/trace/redact.d.ts +3 -1
  184. package/dist/trace/redact.js +80 -28
  185. package/dist/trace/self-minted-wire.d.ts +58 -0
  186. package/dist/trace/self-minted-wire.js +16 -0
  187. package/dist/web-admin-client/candidate-gate.d.ts +11 -7
  188. package/dist/web-admin-client/candidate-gate.js +1 -1
  189. package/dist/web-admin-client/http-client.d.ts +5 -4
  190. package/dist/web-admin-client/http-client.js +2 -2
  191. package/dist/web-admin-client/read-warnings.d.ts +7 -17
  192. package/dist/web-admin-client/read-warnings.js +5 -9
  193. package/package.json +2 -2
  194. package/wire-changes/server@7.140.0.json +184 -0
@@ -3,6 +3,7 @@ import { logStoreFormRefusal, storeFormRefusalOf } from "../memory-store-refusal
3
3
  import { sentMemoryStoreRefusal } from "./memory-store-refusal-reply.js";
4
4
  import { sendError } from "./send.js";
5
5
  import { assertNever } from "./route-ctx.js";
6
+ import { MemoryErasureStoreUnjudged } from "../memory-operator-faces.js";
6
7
  function sentCoreCode(res, coreCode, coreMessage, audience) {
7
8
  switch (coreCode) {
8
9
  case "config.memory_erasure_request":
@@ -42,6 +43,10 @@ function codeOf(err) {
42
43
  return typeof code === "string" ? code : undefined;
43
44
  }
44
45
  export function sentMemoryComplianceFailure(res, err, audience, logger) {
46
+ if (err instanceof MemoryErasureStoreUnjudged) {
47
+ sendError(res, 409, "memory.erasure_store_unjudged", textFor(audience, err.message, "session memory erasure refused — this erasure reaches memory kept in this deployment's second memory store, which this build does not erase from (an erasure requestId is judged on the deployment's main store only); nothing was erased — it becomes available with the next engine update, or ask the operator"));
48
+ return true;
49
+ }
45
50
  const coreCode = codeOf(err);
46
51
  if (coreCode !== undefined && sentCoreCode(res, coreCode, err instanceof Error ? err.message : String(err), audience))
47
52
  return true;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * 记忆动词的**层座**与「这次请求落不到一只记忆店」的拒 —— 两件的 HTTP 半场,唯一一处。
3
+ *
4
+ * ## 规则(店的那一半在 `src/memory-scope-stores.ts`)
5
+ * 一次记忆请求只落一只店:请求点名的层住的那一只;不点名层的动词(条目 id / 店级账本)答在本部署点名的层与部署的店共处的那一只上,
6
+ * 两只店分住时不猜、拒。会话 id 的两口不点名层时不拒:记忆状态读本部署的每一只店再折成一份,按会话抹除落部署的店(`memory-operator-faces.ts`)。
7
+ * 不点名层的动词因此多一个可选的**层座** `scope`:GET 口在查询串(`?scope=<层键>`),POST 口在体里(`"scope": "<层键>"`);
8
+ * 点名的层只用来定店,动词本身的语义不变。点名层的动词(导出 / 导入 / 外源列表 / 整理 / operator 抹除的 `select.scope` 与 `expectedScopes`)
9
+ * 本来就点名,不加座。
10
+ *
11
+ * ## 层座的读法({@link readLayerSeat})
12
+ * 缺席 ⇒ 没点名;在场 ⇒ 必须是非空串,否则 400 `request.field_invalid`、面一次都不调(空串与非串不是「没点名」—— 静默当缺席会把请求答在
13
+ * 另一只店上)。
14
+ *
15
+ * ## 拒的映射({@link sentMemoryLayerRefusal})
16
+ * `MemoryLayerRefusal` ⇒ 400 `request.memory_layer`:请求可以改对(点名层 / 按店拆成几次),服务器没坏,也不是盘形问题。
17
+ * 文案按受众分(与 `memory-compliance-failure-reply.ts` 同一条规则):operator ⇒ 原句(点名部署配置的层、哪几层住在哪只店 —— 运维要的就是它);
18
+ * 会话所有者 ⇒ 固定一句(只说怎么办),原句交 `withheld` 落运维行 —— 部署配置的层键不是这个受众的材料。
19
+ */
20
+ import type { ServerResponse } from "node:http";
21
+ import type { MemoryLayerSeat } from "../memory-operator-faces.js";
22
+ import type { MemoryComplianceAudience } from "./memory-compliance-failure-reply.js";
23
+ /**
24
+ * 层座:`present` = 键在不在(查询串 `has` / 体 `in`),`value` = 它的值。缺席 ⇒ `undefined`;非空串 ⇒ `{ layer }`;
25
+ * 其余 ⇒ 已答 400 `request.field_invalid`,返回 `null`(调用方 `return`)。
26
+ */
27
+ export declare function readLayerSeat(res: ServerResponse, present: boolean, value: unknown): MemoryLayerSeat | undefined | null;
28
+ /** `err` 是本服务的层拒 ⇒ 400 `request.memory_layer`(文案按受众),返回 true;否则 false,一个字节都不写。 */
29
+ export declare function sentMemoryLayerRefusal(res: ServerResponse, err: unknown, audience: MemoryComplianceAudience): boolean;
30
+ //# sourceMappingURL=memory-layer-reply.d.ts.map
@@ -0,0 +1,24 @@
1
+ import { MemoryLayerRefusal } from "../memory-scope-stores.js";
2
+ import { sendError } from "./send.js";
3
+ export function readLayerSeat(res, present, value) {
4
+ if (!present)
5
+ return undefined;
6
+ if (typeof value === "string" && value.length > 0)
7
+ return { layer: value };
8
+ sendError(res, 400, "request.field_invalid", "scope must be a non-empty memory layer key when present — it names the layer whose memory store this request is answered on");
9
+ return null;
10
+ }
11
+ export function sentMemoryLayerRefusal(res, err, audience) {
12
+ if (!(err instanceof MemoryLayerRefusal))
13
+ return false;
14
+ switch (audience.kind) {
15
+ case "operator":
16
+ sendError(res, 400, "request.memory_layer", err.message);
17
+ return true;
18
+ case "session_owner":
19
+ audience.withheld(err.message);
20
+ sendError(res, 400, "request.memory_layer", "the memory store this request reaches cannot be told — the `scope` in the request is not a memory layer this deployment can read, or this deployment's own memory layer configuration cannot be read; resend without `scope` (or with a readable layer), or ask the operator");
21
+ return true;
22
+ }
23
+ }
24
+ //# sourceMappingURL=memory-layer-reply.js.map
@@ -1,6 +1,6 @@
1
1
  import { redactErrorMessage, redactHead } from "../observability/run-terminal.js";
2
2
  import { createHash } from "node:crypto";
3
- import { uuidv7, resumeWithVerification, CheckpointError, defaultTaskRegistry, taskNotificationDedupKey, validatePendingSteer, GLOBAL_USAGE_KEY, PAUSE_REGISTRY } from "@sema-agent/core";
3
+ import { uuidv7, resumeWithVerification, CheckpointError, defaultTaskRegistry, taskNotificationDedupKey, validatePendingSteer, GLOBAL_USAGE_KEY } from "@sema-agent/core";
4
4
  import { decideParkedAgent, denyWorkflowParkForked, denyWorkflowParksUnreadable, findParkOrigin, heldWorkflowParkDecisions, planWorkflowParkedDecide } from "../parked-decide.js";
5
5
  import { parkDecisionFingerprint } from "../orchestration/workflow-park-decision.js";
6
6
  import { headReadOf } from "../session-incarnation.js";
@@ -8,7 +8,7 @@ import { createSessionWorkspaceRecorder, legSessionWitnessOf, sessionWorkspaceSt
8
8
  const DELIVERY_NOT_RECORDED = "workflow park decide: this delivery no longer holds the host session (its claim was released) — the decision was not recorded and this delivery was not started";
9
9
  import { HttpError, decodeCheckpointScope, CHECKPOINT_PUBLIC_SCOPE } from "../security.js";
10
10
  import { graftParkToolCallId, parkToolCallId, TurnAnchorCapture, HEARTBEAT_MS, markChildrenStoppedByUserOnAbort } from "../runs.js";
11
- import { failureCodeOf, nestedPauseOf, sealResultForExit, outwardPlane } from "../terminal.js";
11
+ import { atHostBoundary, failureCodeOf, nestedPauseOf, sealResultForExit, outwardPlane } from "../terminal.js";
12
12
  import { buildCancelledLedgerRow, createRunAbort, mintCancelledResult } from "../run-cancel-context.js";
13
13
  import { isTerminalRunStatus } from "../plugins/store-contracts.js";
14
14
  import { readTurnActivityMs, recordTurnActivity } from "../turn-activity.js";
@@ -51,6 +51,7 @@ import { commitExecutionContext, isRootSessionGoneError, resolveExecutionContext
51
51
  import { commitSessionInheritEnv } from "./session-inherit-env.js";
52
52
  import { ASK_USER_QUESTION_TOOL_NAME, isApprovalGateKind, isEngineQuestionRow } from "../approval-content-kind.js";
53
53
  import { deploymentListAsks } from "../approval.js";
54
+ import { isParkLedgerEventType } from "../trace/ledger-events.js";
54
55
  import { readResumeCtx, resumeCtxCorruptAnswer, resumeCtxUnsealableAnswer } from "./resume-ctx-read.js";
55
56
  import { buildCheckpointVersionKeys, resumeBlockedByPolicyAnswer, resumeRefusalWithCard, sealCheckpointCtx, storedBodyReplayAnswer, storedBodyReplayLogFields, withPermissionModeRewritten } from "./checkpoint-ctx.js";
56
57
  import { refusalBody, resumeRefusalFacts } from "./refusal-body.js";
@@ -61,12 +62,6 @@ import { fieldConflictFacts } from "../field-conflict.js";
61
62
  function legMayHaveReopenedCheckpoint(r) {
62
63
  return r.terminal.kind === "failed" && nestedPauseOf(r.terminal) === undefined;
63
64
  }
64
- function nestedParkStatusOf(r) {
65
- const paused = nestedPauseOf(r.terminal);
66
- if (paused === undefined)
67
- return undefined;
68
- return PAUSE_REGISTRY[paused.gate.kind].taskStatus;
69
- }
70
65
  const WORKER_SWAP_REDEEMABLE = {
71
66
  version_newer: true,
72
67
  env_factory_missing: true,
@@ -855,12 +850,14 @@ export function createResumeLegs(ctx) {
855
850
  resumeLegLive = true;
856
851
  const vrEngine = await resumeWithVerification(legRunner, token, outcome, { ...resumeTaskConfig, signal: cancelCtrl.signal, preemptSignal: preemptCtrl.signal }, resumeObjective, verifyRounds, verifyInternals);
857
852
  const vrCause = cancelCtrl.cause();
858
- const vr = vrCause !== undefined && taskId !== undefined ? mintCancelledResult({ taskId, sessionId, startedAtMs: resumeLegStartedAt, message: "cancelled by user", engineResult: vrEngine, cause: vrCause }) : vrEngine;
853
+ const vrJudged = atHostBoundary(vrEngine, sessionId);
854
+ const vr = vrCause !== undefined && taskId !== undefined ? mintCancelledResult({ taskId, sessionId, startedAtMs: resumeLegStartedAt, message: "cancelled by user", engineResult: vrJudged, cause: vrCause }) : vrJudged;
859
855
  await commitResumeCtx();
860
856
  let safe = sealResultForExit(vr);
861
- const vrNested = nestedPauseOf(vr.terminal);
862
- const reParkStatus = nestedParkStatusOf(vr);
863
- const reSuspended = vrNested !== undefined;
857
+ const vrPaused = vr.terminal.kind === "paused" ? vr.terminal : undefined;
858
+ const vrParkWord = vrPaused !== undefined ? outwardPlane(vrPaused).status : undefined;
859
+ const reParkEvent = vrParkWord !== undefined && isParkLedgerEventType(vrParkWord) ? vrParkWord : undefined;
860
+ const reSuspended = reParkEvent !== undefined;
864
861
  const vrReopened = await reopenedAfterLeg(vr, vrCause !== undefined);
865
862
  if (vrReopened)
866
863
  reopenConfirmedPark = true;
@@ -871,8 +868,8 @@ export function createResumeLegs(ctx) {
871
868
  await appendPromptManifest(ap, deps.promptManifests, taskId);
872
869
  if (reSuspended || vrReopened) {
873
870
  await appendModelUsageDelta(ap, deps.modelUsage, taskId);
874
- const vrParkCallId = vrNested !== undefined ? await parkToolCallId({ terminal: vrNested }, deps.checkpointStore) : undefined;
875
- await ap(reParkStatus ?? reparkStatus, parkEventData({ terminal: vrNested, ...(vrParkCallId !== undefined ? { toolCallId: vrParkCallId } : {}) }, vrReopened ? (failureCodeOf(vr.terminal) ?? null) : undefined));
871
+ const vrParkCallId = reSuspended ? await parkToolCallId(vr, deps.checkpointStore) : undefined;
872
+ await ap(reParkEvent ?? reparkStatus, parkEventData({ terminal: vrPaused, ...(vrParkCallId !== undefined ? { toolCallId: vrParkCallId } : {}) }, vrReopened ? (failureCodeOf(vr.terminal) ?? null) : undefined));
876
873
  }
877
874
  else {
878
875
  safe = await attachModelUsage(safe, { append: ap, getEvents: (id, a) => rs2.getEvents(id, a), modelUsage: deps.modelUsage, taskId });
@@ -884,8 +881,8 @@ export function createResumeLegs(ctx) {
884
881
  throw e;
885
882
  }
886
883
  }
887
- if (vrNested !== undefined)
888
- return { ...safe, terminal: vrNested };
884
+ if (reSuspended)
885
+ return safe;
889
886
  if (vr.verification?.verdict)
890
887
  deps.metrics?.inc("verifications_total", { verdict: vr.verification.verdict });
891
888
  return safe;
@@ -22,7 +22,7 @@ export interface RetiredServiceDep {
22
22
  export declare const RETIRED_SERVICE_DEPS: {
23
23
  readonly sqlEngineFacts: {
24
24
  readonly retiredIn: "7.132.0";
25
- readonly wayOut: "replaced by sqlEngine — pass the SQL pool's engine reading as sqlEngine: `{ dialect: \"tidb\" | \"pg\", facts }` where `facts` is read live (a getter) and is null while the pool's connection setup has not succeeded, or leave both unset when there is no SQL store";
25
+ readonly wayOut: "replaced by sqlEngine — pass the SQL pool's engine reading as sqlEngine: `{ dialect: \"mysql\" | \"pg\", facts }` where `facts` is read live (a getter) and is null while the pool's connection setup has not succeeded, or leave both unset when there is no SQL store";
26
26
  };
27
27
  readonly snapshotBlobSqlCapBytes: {
28
28
  readonly retiredIn: "7.132.0";
@@ -2,7 +2,7 @@ const BLOB_CAP_WAY_OUT = "the HTTP surface no longer holds a blob cap of its own
2
2
  export const RETIRED_SERVICE_DEPS = {
3
3
  sqlEngineFacts: {
4
4
  retiredIn: "7.132.0",
5
- wayOut: "replaced by sqlEngine — pass the SQL pool's engine reading as sqlEngine: `{ dialect: \"tidb\" | \"pg\", facts }` where `facts` is read live (a getter) and is null while the pool's connection setup has not succeeded, or leave both unset when there is no SQL store",
5
+ wayOut: "replaced by sqlEngine — pass the SQL pool's engine reading as sqlEngine: `{ dialect: \"mysql\" | \"pg\", facts }` where `facts` is read live (a getter) and is null while the pool's connection setup has not succeeded, or leave both unset when there is no SQL store",
6
6
  },
7
7
  snapshotBlobSqlCapBytes: { retiredIn: "7.132.0", wayOut: BLOB_CAP_WAY_OUT },
8
8
  snapshotBlobSqlCap: { retiredIn: "7.133.0", wayOut: BLOB_CAP_WAY_OUT },
@@ -69,7 +69,7 @@ export async function handleAdoption(req, res, match, ctx) {
69
69
  }
70
70
  }
71
71
  const store = fact.backend.adoptionLog();
72
- const runner = createAdoptionRunner({ store, dialect: deps.backend?.kind === "pg" ? "pg" : "tidb", now: Date.now, logger: deps.logger });
72
+ const runner = createAdoptionRunner({ store, dialect: deps.backend?.kind === "pg" ? "pg" : "mysql", now: Date.now, logger: deps.logger });
73
73
  switch (match.decl.id) {
74
74
  case "adoption-detail": {
75
75
  const id = ctx.helpers.safeDecode(match.params.id);
@@ -4,6 +4,7 @@ import { sentMemoryStoreRefusal } from "../memory-store-refusal-reply.js";
4
4
  import { buildOriginFencedBundle, readOriginAware } from "../../memory-origin-fence.js";
5
5
  import { gatedPrincipal, explicitOperatorOk, sendOperatorPrincipalsRequired, sendPrincipalRefusal } from "../principal-gate.js";
6
6
  import { assertNever } from "../route-ctx.js";
7
+ import { sentMemoryLayerRefusal } from "../memory-layer-reply.js";
7
8
  import * as facts from "../../capability-facts.js";
8
9
  export const MEMORY_BUNDLE_EXPORT_PATH = "/v1/memory/export";
9
10
  export const MEMORY_BUNDLE_IMPORT_PATH = "/v1/memory/import";
@@ -34,6 +35,8 @@ function codeOf(err) {
34
35
  return typeof code === "string" ? code : undefined;
35
36
  }
36
37
  function sentClassifiedFailure(res, ctx, face, err) {
38
+ if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
39
+ return true;
37
40
  const code = codeOf(err);
38
41
  if (code !== undefined && sentCoreCode(res, code, err instanceof Error ? err.message : String(err)))
39
42
  return true;
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { erasureInputSmugglesPrototypeKey } from "../../memory-operator-faces.js";
3
3
  import { sentMemoryComplianceFailure } from "../memory-compliance-failure-reply.js";
4
+ import { readLayerSeat, sentMemoryLayerRefusal } from "../memory-layer-reply.js";
4
5
  import { sendJson, sendError } from "../send.js";
5
6
  import { gatedPrincipal, explicitOperatorOk, sendOperatorPrincipalsRequired, sendPrincipalRefusal } from "../principal-gate.js";
6
7
  import { assertNever } from "../route-ctx.js";
@@ -12,6 +13,8 @@ const EraseRequestSchema = z.object({
12
13
  allowUnevidenced: z.boolean().optional(),
13
14
  });
14
15
  function sentClassifiedFailure(res, ctx, face, err) {
16
+ if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
17
+ return true;
15
18
  if (sentMemoryComplianceFailure(res, err, { kind: "operator" }, ctx.deps.logger))
16
19
  return true;
17
20
  ctx.deps.logger?.warn?.(`memory_compliance_${face}_failed`, { err: String(err) });
@@ -53,8 +56,12 @@ export async function handleMemoryCompliance(req, res, match, ctx) {
53
56
  sendError(res, 400, "request.id_invalid", "invalid memory entry id");
54
57
  return;
55
58
  }
59
+ const query = new URLSearchParams(match.search);
60
+ const at = readLayerSeat(res, query.has("scope"), query.get("scope"));
61
+ if (at === null)
62
+ return;
56
63
  try {
57
- sendJson(res, 200, await faces.provenanceOf(entryId));
64
+ sendJson(res, 200, await (at !== undefined ? faces.provenanceOf(entryId, at) : faces.provenanceOf(entryId)));
58
65
  }
59
66
  catch (err) {
60
67
  if (!sentClassifiedFailure(res, ctx, "provenance", err))
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { ControlPlaneCorruptError } from "@sema-agent/core";
3
3
  import { sendJson, sendError } from "../send.js";
4
+ import { sentMemoryLayerRefusal } from "../memory-layer-reply.js";
4
5
  import { gatedPrincipal, explicitOperatorOk, sendPrincipalRefusal, sendOperatorPrincipalsRequired } from "../principal-gate.js";
5
6
  import { assertNever } from "../route-ctx.js";
6
7
  import * as facts from "../../capability-facts.js";
@@ -101,7 +102,15 @@ export async function handleMemoryConsolidation(req, res, match, ctx) {
101
102
  const q = new URLSearchParams(match.search).get("scope") ?? undefined;
102
103
  const decided = decideScope(q, faces.scopes);
103
104
  const scope = "scope" in decided ? decided.scope : undefined;
104
- const row = scope !== undefined ? faces.lastRun(scope) : undefined;
105
+ let row;
106
+ try {
107
+ row = scope !== undefined ? faces.lastRun(scope) : undefined;
108
+ }
109
+ catch (err) {
110
+ if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
111
+ return;
112
+ throw err;
113
+ }
105
114
  sendJson(res, 200, {
106
115
  enabled: true,
107
116
  seat: faces.seat,
@@ -144,6 +153,8 @@ export async function handleMemoryConsolidation(req, res, match, ctx) {
144
153
  sendJson(res, 200, buildRunSummary(r));
145
154
  }
146
155
  catch (err) {
156
+ if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
157
+ return;
147
158
  const coreCode = codeOf(err);
148
159
  if (coreCode !== undefined) {
149
160
  sendError(res, 409, "memory.consolidation_refused", `memory consolidation refused (${coreCode}): ${err instanceof Error ? err.message : String(err)}`);
@@ -3,6 +3,7 @@ import { ControlPlaneCorruptError } from "@sema-agent/core";
3
3
  import { sendJson, sendError } from "../send.js";
4
4
  import { sentMemoryStoreRefusal } from "../memory-store-refusal-reply.js";
5
5
  import { buildOriginFence, readOriginAware } from "../../memory-origin-fence.js";
6
+ import { readLayerSeat, sentMemoryLayerRefusal } from "../memory-layer-reply.js";
6
7
  import { gatedPrincipal, explicitOperatorOk, sendOperatorPrincipalsRequired, sendPrincipalRefusal } from "../principal-gate.js";
7
8
  import { assertNever } from "../route-ctx.js";
8
9
  import * as facts from "../../capability-facts.js";
@@ -49,6 +50,8 @@ function codeOf(err) {
49
50
  return typeof code === "string" ? code : undefined;
50
51
  }
51
52
  function sentClassifiedFailure(res, ctx, face, err) {
53
+ if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
54
+ return true;
52
55
  if (face === "clear") {
53
56
  const coreCode = codeOf(err);
54
57
  if (coreCode !== undefined && sentClearCode(res, coreCode, err instanceof Error ? err.message : String(err)))
@@ -157,8 +160,12 @@ export async function handleMemoryOrigin(req, res, match, ctx) {
157
160
  return;
158
161
  }
159
162
  case "memory-origin-clearances": {
163
+ const query = new URLSearchParams(match.search);
164
+ const at = readLayerSeat(res, query.has("scope"), query.get("scope"));
165
+ if (at === null)
166
+ return;
160
167
  try {
161
- sendJson(res, 200, { clearances: faces.listClearances().map(buildClearanceRowWire) });
168
+ sendJson(res, 200, { clearances: (at !== undefined ? faces.listClearances(at) : faces.listClearances()).map(buildClearanceRowWire) });
162
169
  }
163
170
  catch (err) {
164
171
  if (!sentClassifiedFailure(res, ctx, "clearances", err))
@@ -182,8 +189,13 @@ export async function handleMemoryOrigin(req, res, match, ctx) {
182
189
  sendError(res, 400, "request.body_shape", "invalid memory origin clearance request — expected an object with a non-empty `requestId` and a `reason` string (whether an EMPTY reason is acceptable is the engine's judgment, not this layer's)");
183
190
  return;
184
191
  }
192
+ const body = raw;
193
+ const at = readLayerSeat(res, Object.prototype.hasOwnProperty.call(body, "scope"), body.scope);
194
+ if (at === null)
195
+ return;
185
196
  try {
186
- const receipt = await faces.clear(entryId, { requestId: parsed.data.requestId, reason: parsed.data.reason });
197
+ const input = { requestId: parsed.data.requestId, reason: parsed.data.reason };
198
+ const receipt = await (at !== undefined ? faces.clear(entryId, input, at) : faces.clear(entryId, input));
187
199
  ctx.deps.logger?.info?.("memory_origin_cleared", {
188
200
  principal: principal ?? null,
189
201
  entryId,
@@ -5,6 +5,7 @@ import { buildOriginFence, readOriginAware } from "../../memory-origin-fence.js"
5
5
  import { parseProjectLayerKey } from "../../project-layer-key.js";
6
6
  import { gatedPrincipal, explicitOperatorOk, sendPrincipalRefusal, sendUnauthorized } from "../principal-gate.js";
7
7
  import { assertNever } from "../route-ctx.js";
8
+ import { sentMemoryLayerRefusal } from "../memory-layer-reply.js";
8
9
  const ORG_PREFIX = "org:";
9
10
  export const MEMORY_EXPORT_MAX_LIMIT = 500;
10
11
  function encodeExportCursor(c) {
@@ -121,6 +122,8 @@ export async function handleMemoryPolicy(req, res, match, ctx) {
121
122
  });
122
123
  }
123
124
  catch (err) {
125
+ if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
126
+ return;
124
127
  deps.logger?.warn?.("memory_export_failed", { scope, err: String(err) });
125
128
  sendError(res, 500, "internal.error", "memory export failed");
126
129
  }
@@ -158,6 +161,8 @@ export async function handleMemoryPolicy(req, res, match, ctx) {
158
161
  sendJson(res, 200, out);
159
162
  }
160
163
  catch (err) {
164
+ if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
165
+ return;
161
166
  deps.logger?.warn?.("memory_sync_failed", { scope, peer: parsed.value.peer, err: String(err) });
162
167
  sendError(res, 500, "internal.error", "memory sync failed");
163
168
  }
@@ -7,6 +7,8 @@ import { seatText } from "../../trace/exit-seat.js";
7
7
  import { recordFailOpen } from "../../observability/fail-open.js";
8
8
  import { MCP_DIAL_DEADLINE_MS, raceDeadline } from "../mcp-dial-deadline.js";
9
9
  import { sentMemoryComplianceFailure } from "../memory-compliance-failure-reply.js";
10
+ import { readLayerSeat, sentMemoryLayerRefusal } from "../memory-layer-reply.js";
11
+ import { foldPlaneStatuses } from "../../memory-operator-faces.js";
10
12
  import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, MAX_SETTINGS_ENV_VARS, MAX_SETTINGS_ENV_KEY_CHARS, MAX_SETTINGS_ENV_VALUE_CHARS } from "../../task-settings.js";
11
13
  import { readWritableSessionPermissionRules } from "../../session-policy-wire.js";
12
14
  import { sendJson, sendError, sendSessionError, sendSessionPolicyError, sseHeaders, httpErrorBody } from "../send.js";
@@ -551,11 +553,17 @@ export async function handleSessions(req, res, match, ctx) {
551
553
  sendError(res, 400, "request.field_invalid", "allowUnevidenced must be a boolean when present");
552
554
  return;
553
555
  }
556
+ const at = readLayerSeat(res, Object.prototype.hasOwnProperty.call(raw, "scope"), raw.scope);
557
+ if (at === null)
558
+ return;
559
+ const withheld = (coreMessage) => deps.logger?.warn?.("session_memory_erase_refused", { sessionId, err: coreMessage });
554
560
  try {
555
- sendJson(res, 200, await faces.erase({ requestId: raw.requestId, select: { sessionId }, ...(raw.allowUnevidenced !== undefined ? { allowUnevidenced: raw.allowUnevidenced } : {}) }));
561
+ const input = { requestId: raw.requestId, select: { sessionId }, ...(raw.allowUnevidenced !== undefined ? { allowUnevidenced: raw.allowUnevidenced } : {}) };
562
+ sendJson(res, 200, await (at !== undefined ? faces.erase(input, at) : faces.erase(input)));
556
563
  }
557
564
  catch (err) {
558
- const withheld = (coreMessage) => deps.logger?.warn?.("session_memory_erase_refused", { sessionId, err: coreMessage });
565
+ if (sentMemoryLayerRefusal(res, err, { kind: "session_owner", withheld }))
566
+ return;
559
567
  if (sentMemoryComplianceFailure(res, err, { kind: "session_owner", withheld }, deps.logger))
560
568
  return;
561
569
  deps.logger?.warn?.("session_memory_erase_failed", { sessionId, err: String(err) });
@@ -587,20 +595,27 @@ export async function handleSessions(req, res, match, ctx) {
587
595
  sendError(res, 501, "capability.memory_engine_required", "session memory status is not available on this deployment — it requires a wired memory engine (MEMORY_ENGINE=on) whose backend owns the engine control plane (controlPlaneRoot); the file memory backend does, the pg/tidb memory backends do not (their control plane would land on a replica's local disk)");
588
596
  return;
589
597
  }
598
+ const query = new URLSearchParams(match.search);
599
+ const at = readLayerSeat(res, query.has("scope"), query.get("scope"));
600
+ if (at === null)
601
+ return;
590
602
  try {
591
603
  const { memoryStatusCache } = ctx.local.sessions;
592
- let entry = memoryStatusCache.get(sessionId);
593
- if (!entry || Date.now() - entry.at > MEMORY_STATUS_TTL_MS) {
604
+ const statusOf = (store) => {
605
+ const cacheKey = JSON.stringify([sessionId, store.controlPlane]);
606
+ const cached = memoryStatusCache.get(cacheKey);
607
+ if (cached && Date.now() - cached.at <= MEMORY_STATUS_TTL_MS)
608
+ return cached.status;
594
609
  if (memoryStatusCache.size > 1024)
595
610
  memoryStatusCache.clear();
596
- const status = face.status(sessionId);
611
+ const status = store.status(sessionId);
597
612
  const fresh = { at: Date.now(), status };
598
- memoryStatusCache.set(sessionId, fresh);
599
- status.catch(() => { if (memoryStatusCache.get(sessionId) === fresh)
600
- memoryStatusCache.delete(sessionId); });
601
- entry = fresh;
602
- }
603
- const s = await entry.status;
613
+ memoryStatusCache.set(cacheKey, fresh);
614
+ status.catch(() => { if (memoryStatusCache.get(cacheKey) === fresh)
615
+ memoryStatusCache.delete(cacheKey); });
616
+ return status;
617
+ };
618
+ const s = foldPlaneStatuses(await Promise.all(face.storesAt(at).map(statusOf)));
604
619
  sendJson(res, 200, {
605
620
  sessionId,
606
621
  autoConsolidationArmed: deps.memoryAutoConsolidationArmed,
@@ -612,6 +627,8 @@ export async function handleSessions(req, res, match, ctx) {
612
627
  });
613
628
  }
614
629
  catch (err) {
630
+ if (sentMemoryLayerRefusal(res, err, { kind: "session_owner", withheld: (message) => deps.logger?.warn?.("session_memory_status_refused", { sessionId, err: message }) }))
631
+ return;
615
632
  deps.logger?.warn?.("session_memory_status_failed", { sessionId, err: String(err) });
616
633
  sendError(res, 500, "internal.error", "session memory status read failed");
617
634
  }
@@ -2,7 +2,7 @@ import { redactErrorMessage, redactHead, redactTerminalResult } from "../../obse
2
2
  import { runWithVerification, runCascade, taskNotificationDedupKey, uuidv7 } from "@sema-agent/core";
3
3
  import { heldFor } from "../../peer-seat.js";
4
4
  import { graftParkToolCallId, markChildrenStoppedByUserOnAbort, syncRefusalHttpStatus, zeroWorkRefusalFacts, releaseKeyIfZeroWorkRefusal, createPromptCommitReader, HEARTBEAT_MS } from "../../runs.js";
5
- import { sealResultForExit, outwardPlane } from "../../terminal.js";
5
+ import { atHostBoundary, sealResultForExit, outwardPlane } from "../../terminal.js";
6
6
  import { withPrincipal } from "../../observability/principal-context.js";
7
7
  import { fleetRunPublisher, fleetRunLabels, fleetRunResiduals, isFleetAgentTerminalNotification } from "../../fleet/fleet-bus.js";
8
8
  import { defaultSubagentTailBus } from "../../fleet/subagent-tail-bus.js";
@@ -969,7 +969,7 @@ export async function handleTasks(req, res, match, ctx) {
969
969
  }
970
970
  return stream.result();
971
971
  };
972
- result = await instructionLeg.run(prepared.spec.sessionId, () => withPrincipal(principal, () => prepared.verify ? verifyLeg(prepared.verify) : prepared.cascade ? cascadeLeg() : plainLeg()));
972
+ result = atHostBoundary(await instructionLeg.run(prepared.spec.sessionId, () => withPrincipal(principal, () => prepared.verify ? verifyLeg(prepared.verify) : prepared.cascade ? cascadeLeg() : plainLeg())), prepared.spec.sessionId);
973
973
  }
974
974
  finally {
975
975
  counters.uncountedBillableInflight--;
@@ -1006,10 +1006,12 @@ export async function handleTasks(req, res, match, ctx) {
1006
1006
  const syncPlane = outwardPlane(result.terminal);
1007
1007
  if (syncPlane.status === "suspended" && deps.checkpointStore && deps.runStore && durableTaskId) {
1008
1008
  await deps.runStore.setSuspended(durableTaskId, exitResult);
1009
+ prepared.acceptance.settle(result);
1009
1010
  return { status: 200, body: withSyncSubmitKeys(buildSyncSubmitBody(exitResult, { taskId: durableTaskId, sessionId: prepared.spec.sessionId, status: "suspended" })) };
1010
1011
  }
1011
1012
  if (syncPlane.status === "needs_review" && deps.checkpointStore && deps.runStore && durableTaskId) {
1012
1013
  await deps.runStore.setNeedsReview(durableTaskId, exitResult);
1014
+ prepared.acceptance.settle(result);
1013
1015
  return { status: 200, body: withSyncSubmitKeys(buildSyncSubmitBody(exitResult, { taskId: durableTaskId, sessionId: prepared.spec.sessionId, status: "needs_review" })) };
1014
1016
  }
1015
1017
  if (durableTaskId && deps.runStore)
@@ -1,8 +1,8 @@
1
1
  import http from "node:http";
2
- import type { MemoryComplianceFaces } from "../memory-operator-faces.js";
2
+ import type { MemoryComplianceFaces, MemoryOriginFaces, SessionMemoryStatusFace } from "../memory-operator-faces.js";
3
3
  import type { SideQueryAccounting } from "../budget.js";
4
4
  import type { IncomingMessage } from "node:http";
5
- import { type Runner, type TaskSpec, type TaskResult, type WorkflowRunStore, type MemoryEntry, type MemoryExportBundle, type MemoryImportReport, type EntryProvenanceAccount, type MemoryEntryOrigin, type OriginClearanceRow, type SessionMemoryStatus, type ConsolidationRunReceipt, type ConsolidationDriverRunRow, type SideQuerySpec, type SideQueryResult, type Brain, type EngineNotice } from "@sema-agent/core";
5
+ import { type Runner, type TaskSpec, type TaskResult, type WorkflowRunStore, type MemoryEntry, type MemoryExportBundle, type MemoryImportReport, type ConsolidationRunReceipt, type ConsolidationDriverRunRow, type SideQuerySpec, type SideQueryResult, type Brain, type EngineNotice } from "@sema-agent/core";
6
6
  import type { TaskRequestBody } from "./wire-types.js";
7
7
  import type { ServiceConfig } from "../config-types.js";
8
8
  import { type SessionMirrorRuling } from "../web-admin-client/facade.js";
@@ -518,9 +518,7 @@ export interface ServiceSeamDeps {
518
518
  * (工厂返 undefined),与 compliance/origin 两族同一条 F-9 裁。
519
519
  * 🔴 face 的五键**全可选**(core `SessionMemoryStatus`):absent = 该事实源不可读,路由逐键透传缺席,
520
520
  * 恒不铸 false/0 替身;`optOutSource:"fault"` = capture 态 indeterminate(383 片2/3 轴直投)。 */
521
- sessionMemoryStatus?: {
522
- status: (sessionId: string) => Promise<SessionMemoryStatus>;
523
- };
521
+ sessionMemoryStatus?: SessionMemoryStatusFace;
524
522
  /**
525
523
  * [ref](core 7.22.0 [ref] W1)—— 本**部署**的自动整理武装事实,`GET /v1/sessions/:id/memory-status`
526
524
  * 的 `autoConsolidationArmed` 格。
@@ -552,25 +550,7 @@ export interface ServiceSeamDeps {
552
550
  * ——落在副本本地盘上 = pod 重建即永久丢失。全文见 src/memory-operator-faces.ts 头注。
553
551
  * 🔴 `listClearances` 是**同步**的(core 的读面就是一次严格 sidecar 读),且账本损坏时**抛**
554
552
  * `ControlPlaneCorruptError` —— 那是 fail-closed 信号,不是空数组。 */
555
- memoryOriginFace?: {
556
- listExternal: (scopes: readonly string[]) => Promise<Array<{
557
- id: string;
558
- slug: string;
559
- scope: string;
560
- origin: MemoryEntryOrigin;
561
- provenance: EntryProvenanceAccount;
562
- }>>;
563
- listClearances: () => OriginClearanceRow[];
564
- clear: (entryId: string, input: {
565
- requestId: string;
566
- reason: string;
567
- }) => Promise<{
568
- entryId: string;
569
- clearanceId: string;
570
- origin: MemoryEntryOrigin;
571
- landedSlug: string;
572
- }>;
573
- };
553
+ memoryOriginFace?: MemoryOriginFaces;
574
554
  /** [ref](core 5.58.0 `runMemoryConsolidationDriver`):记忆 **consolidation 阀门**的操作面。
575
555
  * 启用 `POST /v1/admin/memory/consolidation/run` 与 `GET /v1/admin/memory/consolidation`(两口 operator-only)。
576
556
  * main.ts 把它接到 `createMemoryConsolidationFaces` 的产物上。
@@ -827,7 +807,7 @@ export interface ServiceDeploymentDeps {
827
807
  * 7.132.0 前这一席是 `sqlEngineFacts: () => SqlEngineFacts | null`(只给事实、不给方言);照旧传它 ⇒ `createHttpServer` 起服拒。
828
808
  * 🔴 **SQL 后端在场(`backend` 交出了 `mysqlPool()` / `pgPool()`)⇒ 本席必填**,缺席 ⇒ `createHttpServer` 起服拒(席缺席只表示「没有 SQL 后端」,不能是「忘了给」);
829
809
  * 本服务自己的装配(`boot/stores.ts` → `stage-10`)按同一个谓词(`sqlPoolsOf`)建立它,恒给。值形也在起服时判(同一只判官 `sqlEngineSeatIssue` 的另一臂):
830
- * `{ dialect: "tidb" | "pg", facts }`,`facts` 是 `null` 或带 `maxRowBytes` / `maxPacketBytes` / `wallSources` 的引擎事实;只改了键名的 `() => facts` 之类 ⇒ 起服拒。 */
810
+ * `{ dialect: "mysql" | "pg", facts }`,`facts` 是 `null` 或带 `maxRowBytes` / `maxPacketBytes` / `wallSources` 的引擎事实;只改了键名的 `() => facts` 之类 ⇒ 起服拒。 */
831
811
  sqlEngine?: import("../plugins/sql-driver.js").SqlEngineReading;
832
812
  /** [ref]:**写保护名表**的姿态(`write-protection.ts` 的 boot 期单一推导点 —— 与递给每只 Runner 的
833
813
  * `writeProtectedPaths` 座同一份 config 决定)。两个读面共用:`GET /v1/diagnostics/wiring` 的
@@ -76,9 +76,9 @@ export function createHttpServer(rawDeps) {
76
76
  if (issue !== undefined) {
77
77
  switch (issue) {
78
78
  case "required":
79
- throw new Error("createHttpServer: sqlEngine is required when a SQL store backend is wired (the backend hands out a SQL pool) — pass the pool's engine reading as sqlEngine: `{ dialect: \"tidb\" | \"pg\", facts }` where `facts` is read live (a getter) and is null while the pool's connection setup has not succeeded; refusing to start rather than read the database's row and statement limits as absent and admit task bodies the database cannot store");
79
+ throw new Error("createHttpServer: sqlEngine is required when a SQL store backend is wired (the backend hands out a SQL pool) — pass the pool's engine reading as sqlEngine: `{ dialect: \"mysql\" | \"pg\", facts }` where `facts` is read live (a getter) and is null while the pool's connection setup has not succeeded; refusing to start rather than read the database's row and statement limits as absent and admit task bodies the database cannot store");
80
80
  case "bad_shape":
81
- throw new Error(`createHttpServer: sqlEngine must be the SQL pool's engine reading \`{ dialect: "tidb" | "pg", facts }\` where \`facts\` is read live (a getter) and is null while the pool's connection setup has not succeeded, otherwise the engine facts object (maxRowBytes, maxPacketBytes and wallSources included) — got ${typeof deps.sqlEngine === "function" ? "a function (the 7.131.x reader \`() => facts\` goes in as \`{ dialect, get facts() { return f(); } }\`)" : describeValueShape(deps.sqlEngine)}; refusing to start rather than answer every task submission with a 500`);
81
+ throw new Error(`createHttpServer: sqlEngine must be the SQL pool's engine reading \`{ dialect: "mysql" | "pg", facts }\` where \`facts\` is read live (a getter) and is null while the pool's connection setup has not succeeded, otherwise the engine facts object (maxRowBytes, maxPacketBytes and wallSources included) — got ${typeof deps.sqlEngine === "function" ? "a function (the 7.131.x reader \`() => facts\` goes in as \`{ dialect, get facts() { return f(); } }\`)" : describeValueShape(deps.sqlEngine)}; refusing to start rather than answer every task submission with a 500`);
82
82
  default: {
83
83
  const unhandled = issue;
84
84
  throw new Error(`sqlEngine seat issue without a refusal: ${String(unhandled)}`);
@@ -43,7 +43,7 @@ export declare const RUN_IDENTITY_PRINCIPAL_INC_MAX_CHARS = 64;
43
43
  * (身份键按字节判等,与 MySQL 协议表级 `utf8mb4_bin` 同形)。
44
44
  */
45
45
  export declare const RUN_IDENTITY_COLUMNS: {
46
- readonly tidb: string;
46
+ readonly mysql: string;
47
47
  readonly pg: string;
48
48
  };
49
49
  /** 元组落盘的三格(SQL 三列 / File 车道 run.json 的三键,同名同义)。 */
@@ -2,7 +2,7 @@ export const IDENTITY_SOURCES = ["service_token", "sso", "direct_door_jwt"];
2
2
  export const RUN_IDENTITY_SCOPE_MAX_CHARS = 190;
3
3
  export const RUN_IDENTITY_PRINCIPAL_INC_MAX_CHARS = 64;
4
4
  export const RUN_IDENTITY_COLUMNS = {
5
- tidb: [
5
+ mysql: [
6
6
  "identity_source VARCHAR(32) NULL",
7
7
  `identity_scope VARCHAR(${RUN_IDENTITY_SCOPE_MAX_CHARS}) NULL`,
8
8
  `identity_principal_inc VARCHAR(${RUN_IDENTITY_PRINCIPAL_INC_MAX_CHARS}) NULL`,