@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
@@ -172,16 +172,12 @@ export declare function runStage09(ctx: Awaited<ReturnType<typeof runStage08>>):
172
172
  instanceId: string;
173
173
  mailboxRecipientLifecycle: import("../plugins/mailbox-recipient-lifecycle.js").MailboxRecipientLifecycle | undefined;
174
174
  mailboxStore: import("@sema-agent/core").MailboxStore | undefined;
175
- memoryEngine: {
176
- backend: import("@sema-agent/core").MemoryBackend;
177
- root: string;
178
- } | undefined;
179
- memoryExportBackend: import("@sema-agent/core").MemoryBackend | undefined;
175
+ memoryEngine: import("../memory-scope-stores.js").MemoryScopeStores | undefined;
176
+ memoryExportStores: import("../memory-scope-stores.js").MemoryScopeStores | undefined;
180
177
  memoryPosture: import("../memory-posture.js").MemoryPosture;
181
178
  memorySyncCursors: import("../plugins/memory-sync-store-pg.js").MemorySyncStore | undefined;
182
179
  memorySyncRunner: import("../memory-sync-client.js").MemorySyncRunner | undefined;
183
180
  rosterStore: import("@sema-agent/core").RosterStore | undefined;
184
- sessionCaptureRecordStore: import("@sema-agent/core").SessionCaptureRecordStore | undefined;
185
181
  sessionCaptureRecords: import("../index.js").SessionCaptureRecordSource | undefined;
186
182
  sessionStore: import("@sema-agent/core").SessionStore<import("@sema-agent/core").SessionStoreSummary, import("@sema-agent/core").SessionListQuery>;
187
183
  sqlEngine: import("../plugins/sql-driver.js").SqlEngineReading | undefined;
@@ -171,16 +171,12 @@ export declare function runStage10(ctx: Awaited<ReturnType<typeof runStage09>>):
171
171
  instanceId: string;
172
172
  mailboxRecipientLifecycle: import("../plugins/mailbox-recipient-lifecycle.js").MailboxRecipientLifecycle | undefined;
173
173
  mailboxStore: import("@sema-agent/core").MailboxStore | undefined;
174
- memoryEngine: {
175
- backend: import("@sema-agent/core").MemoryBackend;
176
- root: string;
177
- } | undefined;
178
- memoryExportBackend: import("@sema-agent/core").MemoryBackend | undefined;
174
+ memoryEngine: import("../memory-scope-stores.js").MemoryScopeStores | undefined;
175
+ memoryExportStores: import("../memory-scope-stores.js").MemoryScopeStores | undefined;
179
176
  memoryPosture: import("../memory-posture.js").MemoryPosture;
180
177
  memorySyncCursors: import("../plugins/memory-sync-store-pg.js").MemorySyncStore | undefined;
181
178
  memorySyncRunner: import("../memory-sync-client.js").MemorySyncRunner | undefined;
182
179
  rosterStore: import("@sema-agent/core").RosterStore | undefined;
183
- sessionCaptureRecordStore: import("@sema-agent/core").SessionCaptureRecordStore | undefined;
184
180
  sessionCaptureRecords: import("../plugins/store-backend.js").SessionCaptureRecordSource | undefined;
185
181
  sessionStore: import("@sema-agent/core").SessionStore<import("@sema-agent/core").SessionStoreSummary, import("@sema-agent/core").SessionListQuery>;
186
182
  sqlEngine: import("../plugins/sql-driver.js").SqlEngineReading | undefined;
@@ -7,6 +7,7 @@ import { isPricingConfigured } from "../budget.js";
7
7
  import { createHandsRunnerSelector } from "../capabilities/hands-lane.js";
8
8
  import { createHttpServer } from "../http/server.js";
9
9
  import { exportMemoryScope } from "../memory-export.js";
10
+ import { memoryStoreForRequest } from "../memory-scope-stores.js";
10
11
  import { performMemorySync } from "../memory-sync.js";
11
12
  import { backgroundAgentOutput, taskHandleOutput, taskHandleStop } from "../runs.js";
12
13
  import { createStoreLiveProbe } from "../store-live-probe.js";
@@ -29,7 +30,7 @@ import { bindServerLateSeats } from "./late-binds.js";
29
30
  import { serviceVersion } from "../service-version.js";
30
31
  import { buildDisplaySafeUrl } from "../trace/redact.js";
31
32
  export async function runStage10(ctx) {
32
- const { peerDesk, approvalAskAudit, approvalExemptionStore, approvalNonceStore, authorize, backend, backgroundAgentStore, brain, breakerState, centerRuntimeCapsResolver, checkpointStore, checkpointCtxSealing, parkCommits, config, webAdmin, consolidationValve, costQuota, deploymentModsLoaded, deviceLane, drainState, durableEnabled, elicitation, fenceSessionOwner, fileHistoryStore, fleetBus, fleetLease, fleetUsage, governanceSeams, handslessRunner, hookAgent, hookLlm, hookWakeBus, imageBakes, imageIndex, instanceId, instrumentDegenerate, leaderEndpoint, loadedSkills, localRoot, logger, lspManager, mcpRevocations, memoryBundleFaces, memoryComplianceFaces, memoryConsolidationFaces, memoryEngine, memoryExportBackend, memoryOptOutGrantStore, memoryOriginFaces, memoryPosture, memorySyncCursors, memorySyncRunner, metrics, modelUsageTracker, orgMemoryAdmission, otelExporter, outcomeSink, ownerAware, parkedReviveInheritedGate, parkedReviveSurface, perSessionCwd, perTaskImage, planCacheProbe, pricing, principalCaps, promptManifestTracker, purgeSession, question, rateLimiter, reaper, webAdminJwtVerifier, resumeAnchorStore, retentionLaneStarted, retentionLaneStore, ruleConsent, runStore, runner, runnerDeps, runtimeCapsPeekResolver, sandboxGitPlane, scenarioDetails, scenarios, selectEnvTool, sendFileLedger, sendUserFileEmitter, sendUserFileToolSpec, sessionAudit, sessionEnvSelection, sessionMemoryStatusFace, sessionPolicyStore, sessionTitler, sessionWatchRegistry, setSessionCwd, setSessionInheritEnv, setSessionShellEnv, sharedMemoryStore, sideQueryAccounting, sqlEngine, sqlWorkflowRunStore, staticWiring, storePosture, subRunner, subagentSteerRegistry, taskAttachmentStore, taskLimitCaps, taskTimeoutSec, toolApproval, toolResultStore, usageWindowStore, userInputLedger, webSearchProvider, workflowAgentRegistry, workflowAgentSessionIndex, workflowParkDecisions, workflowCompletionInbox, workflowJournalStore, workflowModelAllowlistSnapshot, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, workflowRunStore, workflowsCapable, orgDeliveryGate } = ctx;
33
+ const { peerDesk, approvalAskAudit, approvalExemptionStore, approvalNonceStore, authorize, backend, backgroundAgentStore, brain, breakerState, centerRuntimeCapsResolver, checkpointStore, checkpointCtxSealing, parkCommits, config, webAdmin, consolidationValve, costQuota, deploymentModsLoaded, deviceLane, drainState, durableEnabled, elicitation, fenceSessionOwner, fileHistoryStore, fleetBus, fleetLease, fleetUsage, governanceSeams, handslessRunner, hookAgent, hookLlm, hookWakeBus, imageBakes, imageIndex, instanceId, instrumentDegenerate, leaderEndpoint, loadedSkills, localRoot, logger, lspManager, mcpRevocations, memoryBundleFaces, memoryComplianceFaces, memoryConsolidationFaces, memoryEngine, memoryExportStores, memoryOptOutGrantStore, memoryOriginFaces, memoryPosture, memorySyncCursors, memorySyncRunner, metrics, modelUsageTracker, orgMemoryAdmission, otelExporter, outcomeSink, ownerAware, parkedReviveInheritedGate, parkedReviveSurface, perSessionCwd, perTaskImage, planCacheProbe, pricing, principalCaps, promptManifestTracker, purgeSession, question, rateLimiter, reaper, webAdminJwtVerifier, resumeAnchorStore, retentionLaneStarted, retentionLaneStore, ruleConsent, runStore, runner, runnerDeps, runtimeCapsPeekResolver, sandboxGitPlane, scenarioDetails, scenarios, selectEnvTool, sendFileLedger, sendUserFileEmitter, sendUserFileToolSpec, sessionAudit, sessionEnvSelection, sessionMemoryStatusFace, sessionPolicyStore, sessionTitler, sessionWatchRegistry, setSessionCwd, setSessionInheritEnv, setSessionShellEnv, sharedMemoryStore, sideQueryAccounting, sqlEngine, sqlWorkflowRunStore, staticWiring, storePosture, subRunner, subagentSteerRegistry, taskAttachmentStore, taskLimitCaps, taskTimeoutSec, toolApproval, toolResultStore, usageWindowStore, userInputLedger, webSearchProvider, workflowAgentRegistry, workflowAgentSessionIndex, workflowParkDecisions, workflowCompletionInbox, workflowJournalStore, workflowModelAllowlistSnapshot, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, workflowRunStore, workflowsCapable, orgDeliveryGate } = ctx;
33
34
  const stores = {
34
35
  runStore,
35
36
  resumeAnchorStore: resumeAnchorStore ? resumeAnchorStore : undefined,
@@ -86,9 +87,9 @@ export async function runStage10(ctx) {
86
87
  subagentTaskOutput: (handle, access) => backgroundAgentOutput(defaultTaskRegistry, handle, access, backgroundAgentStore),
87
88
  taskHandleOutput: (handle, access) => taskHandleOutput(defaultTaskRegistry, handle, access, backgroundAgentStore),
88
89
  taskHandleStop: (handle, access) => taskHandleStop(defaultTaskRegistry, handle, access, backgroundAgentStore),
89
- memoryExport: memoryExportBackend ? (scope) => exportMemoryScope(memoryExportBackend, scope) : undefined,
90
- memorySync: memoryExportBackend && memorySyncCursors
91
- ? (scope, syncReq) => performMemorySync(memoryExportBackend, memorySyncCursors, scope, syncReq)
90
+ memoryExport: memoryExportStores ? (scope) => exportMemoryScope(memoryStoreForRequest(memoryExportStores, [scope]), scope) : undefined,
91
+ memorySync: memoryExportStores && memorySyncCursors
92
+ ? (scope, syncReq) => performMemorySync(memoryStoreForRequest(memoryExportStores, [scope]), memorySyncCursors, scope, syncReq)
92
93
  : undefined,
93
94
  memoryBundleExport: memoryBundleFaces ? memoryBundleFaces.exportScopes : undefined,
94
95
  memoryBundleImport: memoryBundleFaces ? memoryBundleFaces.importBundle : undefined,
@@ -1,4 +1,3 @@
1
- import { type MemoryBackend } from "@sema-agent/core";
2
1
  import type { ServiceConfig } from "../config.js";
3
2
  import { type MemorySyncRunner } from "../memory-sync-client.js";
4
3
  import type { Logger } from "../observability/logger.js";
@@ -7,6 +6,7 @@ import { type MemorySyncStore } from "../plugins/memory-sync-store-pg.js";
7
6
  import { type MailboxRecipientLifecycle } from "../plugins/mailbox-recipient-lifecycle.js";
8
7
  import { type TaskAttachmentStore } from "../plugins/task-attachment-store.js";
9
8
  import { type StoreBackend } from "../plugins/store-backend.js";
9
+ import { type MemoryScopeStores } from "../memory-scope-stores.js";
10
10
  export interface OpenStoresCtx {
11
11
  config: ServiceConfig;
12
12
  logger: Logger;
@@ -24,10 +24,7 @@ export declare function assertApprovalAskRuleMaterialOnBackend(backend: StoreBac
24
24
  export declare function openStores(ctx: OpenStoresCtx): Promise<{
25
25
  backend: StoreBackend | undefined;
26
26
  storePosture: import("../store-posture.js").StorePosture;
27
- memoryEngine: {
28
- backend: MemoryBackend;
29
- root: string;
30
- } | undefined;
27
+ memoryEngine: MemoryScopeStores | undefined;
31
28
  engineDataRoot: string;
32
29
  memorySyncCursors: MemorySyncStore | undefined;
33
30
  rosterStore: import("@sema-agent/core").RosterStore | undefined;
@@ -35,7 +32,7 @@ export declare function openStores(ctx: OpenStoresCtx): Promise<{
35
32
  mailboxRecipientLifecycle: MailboxRecipientLifecycle | undefined;
36
33
  taskAttachmentStore: TaskAttachmentStore | undefined;
37
34
  mailboxStore: import("@sema-agent/core").MailboxStore | undefined;
38
- memoryExportBackend: MemoryBackend | undefined;
35
+ memoryExportStores: MemoryScopeStores | undefined;
39
36
  memorySyncRunner: MemorySyncRunner | undefined;
40
37
  sessionStore: import("@sema-agent/core").SessionStore<import("@sema-agent/core").SessionStoreSummary, import("@sema-agent/core").SessionListQuery>;
41
38
  breakerState: import("../plugins/breaker-state-sql.js").TiDBBreakerState | import("../plugins/breaker-state-sql.js").PgBreakerState | undefined;
@@ -1,7 +1,7 @@
1
1
  import { join } from "node:path";
2
2
  import { FileBackgroundAgentStore, FileMailboxStore, FileRosterStore, InMemoryUsageWindowStore, mailboxCrossProcessMountVerdict } from "@sema-agent/core";
3
3
  import { createCorruptReadFailOpenSeat } from "../observability/corrupt-read-seat.js";
4
- import { buildMemorySyncEnabledFields, createMemorySyncRunner, createMemorySyncTransport } from "../memory-sync-client.js";
4
+ import { startMemorySyncRunner } from "../memory-sync-client.js";
5
5
  import { memoryEmbedderFor } from "../plugins/memory-embedder.js";
6
6
  import { ensurePgMemoryEmbedderMetaSchema, reconcileEmbedderFingerprint } from "../plugins/memory-embedder-fingerprint.js";
7
7
  import { PgMemoryEngineBackend, ensurePgMemoryEngineSchema } from "../plugins/memory-engine-pg.js";
@@ -10,10 +10,10 @@ import { PgMemoryHistoryStore, PgMemorySyncStore, ensurePgMemoryHistorySchema, e
10
10
  import { TiDBMemoryHistoryStore, TiDBMemorySyncStore, ensureTiDBMemoryHistorySchema, ensureTiDBMemorySyncSchema } from "../plugins/memory-sync-store-tidb.js";
11
11
  import { MinioBlobBackend } from "../plugins/blob-backend.js";
12
12
  import { ensureSnapshotBuckets } from "../plugins/snapshot-bucket-presence.js";
13
- import { PgBackgroundAgentStore, TiDBBackgroundAgentStore, ensurePgBackgroundAgentSchema, ensureTiDBBackgroundAgentSchema } from "../plugins/background-agent-store-sql.js";
13
+ import { PgBackgroundAgentStore, TiDBBackgroundAgentStore, ensurePgBackgroundAgentSchema, ensureTiDBBackgroundAgentSchema } from "../stores-sql/background-agent-store-sql.js";
14
14
  import { PgMailboxStore, TiDBMailboxStore, ensurePgMailboxSchema, ensureTiDBMailboxSchema } from "../plugins/mailbox-store-sql.js";
15
15
  import { createDropOnlyRecipientLifecycle } from "../plugins/mailbox-recipient-lifecycle.js";
16
- import { PgUsageWindowStore, TiDBUsageWindowStore, ensurePgUsageWindowSchema, ensureTiDBUsageWindowSchema } from "../plugins/usage-window-store-sql.js";
16
+ import { PgUsageWindowStore, TiDBUsageWindowStore, ensurePgUsageWindowSchema, ensureTiDBUsageWindowSchema } from "../stores-sql/usage-window-store-sql.js";
17
17
  import { PgRosterStore, TiDBRosterStore, ensurePgRosterSchema, ensureTiDBRosterSchema } from "../plugins/roster-store-sql.js";
18
18
  import { LocalTaskAttachmentStore } from "../plugins/local-task-attachment-store.js";
19
19
  import { PgTaskAttachmentStore, TiDBTaskAttachmentStore, ensurePgTaskAttachmentSchema, ensureTiDBTaskAttachmentSchema } from "../plugins/task-attachment-store.js";
@@ -27,14 +27,15 @@ import { assertCloudSnapshotBlobPosture, openStoreBackendWithFallback } from "..
27
27
  import { createMemoryEngineIncidentSink } from "../memory-incident-sink.js";
28
28
  import { announceLockedLegacyMemoryLayers } from "../memory-layer-legacy-lock.js";
29
29
  import { createEngineNoticeForwarder } from "./runner-deps.js";
30
- import { buildMemoryRemoteLaneWarn, memoryEngineBackendFor, memoryEngineRemoteLanePosture, memoryEngineRootFor, memoryMountRootOf } from "../memory-scope.js";
30
+ import { buildMemoryRemoteLaneWarn, memoryEngineBackendFor, memoryEngineRemoteLanePosture, memoryEngineRootFor, memoryLayersNamedBy, memoryMountRootOf } from "../memory-scope.js";
31
+ import { createMemoryScopeStores } from "../memory-scope-stores.js";
31
32
  import { assertToolResultProvenanceSchema } from "../plugins/tool-result-store-sql.js";
32
33
  import { assertPermissionRuleApprovalSchema, assertPermissionRuleTicketSchema } from "../plugins/permission-rule-store-sql.js";
33
34
  import { assertApprovalAskRuleMaterialSchema } from "../plugins/approval-ask-store-sql.js";
34
35
  import { assertSchemaMatchesCode } from "../plugins/schema-consistency.js";
35
36
  import { assertCheckpointColumnSchema } from "../plugins/checkpoint-store-sql.js";
36
37
  import { assertFileHistorySchema } from "../plugins/file-history-store-sql.js";
37
- import { buildMemoryBoundaryLaneFacts, buildMemoryWriteBoundaryAudit, effectiveMemoryPersistenceCapable } from "./memory-boundary.js";
38
+ import { buildMemoryBoundaryLaneFacts, buildMemoryWriteBoundaryAudit } from "./memory-boundary.js";
38
39
  import { buildMemoryPosture } from "../memory-posture.js";
39
40
  import { headReadOf } from "../session-incarnation.js";
40
41
  import { establishSqlEnginePosture, sqlPoolsOf } from "../sql-engine-posture.js";
@@ -50,7 +51,7 @@ export async function assertApprovalAskRuleMaterialOnBackend(backend) {
50
51
  if (pgPool)
51
52
  await assertApprovalAskRuleMaterialSchema(async (sql) => ({ rows: (await pgPool.query(sql)).rows }), "pg");
52
53
  else if (mysqlPool)
53
- await assertApprovalAskRuleMaterialSchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "tidb");
54
+ await assertApprovalAskRuleMaterialSchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "mysql");
54
55
  }
55
56
  export async function openStores(ctx) {
56
57
  const { config, logger, metrics, localRoot } = ctx;
@@ -74,25 +75,25 @@ export async function openStores(ctx) {
74
75
  if (pgPool)
75
76
  await assertToolResultProvenanceSchema(async (sql) => ({ rows: (await pgPool.query(sql)).rows }), "pg");
76
77
  else if (mysqlPool)
77
- await assertToolResultProvenanceSchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "tidb");
78
+ await assertToolResultProvenanceSchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "mysql");
78
79
  if (pgPool)
79
80
  await assertCheckpointColumnSchema(async (sql) => ({ rows: (await pgPool.query(sql)).rows }), "pg");
80
81
  else if (mysqlPool)
81
- await assertCheckpointColumnSchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "tidb");
82
+ await assertCheckpointColumnSchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "mysql");
82
83
  if (config.permissionRulesEnabled) {
83
84
  if (pgPool)
84
85
  await assertPermissionRuleApprovalSchema(async (sql) => ({ rows: (await pgPool.query(sql)).rows }), "pg");
85
86
  else if (mysqlPool)
86
- await assertPermissionRuleApprovalSchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "tidb");
87
+ await assertPermissionRuleApprovalSchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "mysql");
87
88
  if (pgPool)
88
89
  await assertPermissionRuleTicketSchema(async (sql) => ({ rows: (await pgPool.query(sql)).rows }), "pg");
89
90
  else if (mysqlPool)
90
- await assertPermissionRuleTicketSchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "tidb");
91
+ await assertPermissionRuleTicketSchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "mysql");
91
92
  }
92
93
  if (pgPool)
93
94
  await assertFileHistorySchema(async (sql) => ({ rows: (await pgPool.query(sql)).rows }), "pg");
94
95
  else if (mysqlPool)
95
- await assertFileHistorySchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "tidb");
96
+ await assertFileHistorySchema(async (sql) => ({ rows: (await mysqlPool.query(sql))[0] }), "mysql");
96
97
  }
97
98
  if (backend)
98
99
  await runAndLogOneTimeMigrations(logger, backend);
@@ -115,6 +116,8 @@ export async function openStores(ctx) {
115
116
  config.sessionBackend = "tidb";
116
117
  let memoryEngine;
117
118
  const engineDataRoot = memoryEngineRootFor(config, localRoot);
119
+ const memoryEngineIncident = createMemoryEngineIncidentSink({ logger, metrics });
120
+ const scopeStoresOver = (deployment) => createMemoryScopeStores({ backend: deployment, root: engineDataRoot, namedLayers: () => memoryLayersNamedBy(config), onIncident: memoryEngineIncident });
118
121
  let memorySyncCursors;
119
122
  let vectorMode;
120
123
  if (config.memoryEngineBackend !== "file" && config.memoryEngineEnabled) {
@@ -165,7 +168,7 @@ export async function openStores(ctx) {
165
168
  ...(embedder !== undefined ? { embedder } : {}),
166
169
  });
167
170
  vectorMode = pgMem.vectorMode;
168
- memoryEngine = { backend: pgMem, root: engineDataRoot };
171
+ memoryEngine = scopeStoresOver(pgMem);
169
172
  }
170
173
  else {
171
174
  const pool = backend?.mysqlPool();
@@ -177,7 +180,7 @@ export async function openStores(ctx) {
177
180
  memorySyncCursors = new TiDBMemorySyncStore(pool);
178
181
  const tidbMem = new TiDBMemoryEngineBackend(pool, { history: countedHistorySink(new TiDBMemoryHistoryStore(pool)) });
179
182
  vectorMode = tidbMem.vectorMode;
180
- memoryEngine = { backend: tidbMem, root: engineDataRoot };
183
+ memoryEngine = scopeStoresOver(tidbMem);
181
184
  }
182
185
  logger.info("memory_engine_enabled", {
183
186
  enabled: true,
@@ -189,7 +192,8 @@ export async function openStores(ctx) {
189
192
  });
190
193
  }
191
194
  else {
192
- memoryEngine = memoryEngineBackendFor(config, undefined, createMemoryEngineIncidentSink({ logger, metrics }));
195
+ const fileEngine = memoryEngineBackendFor(config, undefined, memoryEngineIncident);
196
+ memoryEngine = fileEngine !== undefined ? scopeStoresOver(fileEngine.backend) : undefined;
193
197
  if (memoryEngine)
194
198
  announceLockedLegacyMemoryLayers(memoryMountRootOf(memoryEngine.backend, memoryEngine.root), createEngineNoticeForwarder(logger));
195
199
  if (memoryEngine && process.env.LOCAL_DATA_ROOT && !config.memoryEngineDir) {
@@ -205,17 +209,11 @@ export async function openStores(ctx) {
205
209
  const audit = buildMemoryWriteBoundaryAudit({
206
210
  memoryRoot: memoryMountRoot,
207
211
  ...laneFacts,
208
- declaredCapable: effectiveMemoryPersistenceCapable(config),
212
+ declaredCapable: config.memoryPersistenceCapable,
209
213
  engineBackend: config.memoryEngineBackend,
210
214
  });
211
215
  for (const w of audit.warnings)
212
216
  logger.warn(w.tag, { detail: w.detail, lane: laneFacts.lane, root: memoryMountRoot ?? null });
213
- if (config.memoryPersistenceCapable === undefined && effectiveMemoryPersistenceCapable(config) === true) {
214
- logger.info?.("memory_persistence_capable_auto_declared", {
215
- lane: laneFacts.lane,
216
- detail: "REMOTE_EXEC=host: file tools run on this machine's filesystem, so the assembler declares memoryPersistenceCapable=true (the core-side remote-env withhold would otherwise silently drop the memory WRITE instruction on this lane). Override with MEMORY_PERSISTENCE_CAPABLE=true|false.",
217
- });
218
- }
219
217
  }
220
218
  let rosterStore;
221
219
  {
@@ -236,7 +234,7 @@ export async function openStores(ctx) {
236
234
  });
237
235
  }
238
236
  if (rosterStore)
239
- logger.info("roster_store_enabled", { backend: pgPool ? "pg" : mysqlPool ? "tidb" : "file" });
237
+ logger.info("roster_store_enabled", { backend: pgPool ? "pg" : mysqlPool ? "mysql" : "file" });
240
238
  }
241
239
  let backgroundAgentStore;
242
240
  {
@@ -255,7 +253,7 @@ export async function openStores(ctx) {
255
253
  backgroundAgentStore = new FileBackgroundAgentStore(config.localDataRoot ?? localRoot);
256
254
  }
257
255
  if (backgroundAgentStore)
258
- logger.info("background_agent_store_enabled", { backend: pgPool ? "pg" : mysqlPool ? "tidb" : "file" });
256
+ logger.info("background_agent_store_enabled", { backend: pgPool ? "pg" : mysqlPool ? "mysql" : "file" });
259
257
  }
260
258
  let taskAttachmentStore;
261
259
  {
@@ -285,7 +283,7 @@ export async function openStores(ctx) {
285
283
  taskAttachmentStore = new LocalTaskAttachmentStore(config.localDataRoot ?? localRoot);
286
284
  }
287
285
  if (taskAttachmentStore)
288
- logger.info("task_attachment_store_enabled", { backend: pgPool ? "pg+minio" : mysqlPool ? "tidb+minio" : "file", maxBytes: config.attachmentMaxBytes });
286
+ logger.info("task_attachment_store_enabled", { backend: pgPool ? "pg+minio" : mysqlPool ? "mysql+minio" : "file", maxBytes: config.attachmentMaxBytes });
289
287
  }
290
288
  let mailboxStore;
291
289
  let mailboxRecipientLifecycle;
@@ -313,7 +311,7 @@ export async function openStores(ctx) {
313
311
  if (mailboxStore) {
314
312
  const laneVerdict = mailboxCrossProcessMountVerdict(mailboxStore);
315
313
  logger.info("mailbox_store_enabled", {
316
- backend: pgPool ? "pg" : mysqlPool ? "tidb" : "file",
314
+ backend: pgPool ? "pg" : mysqlPool ? "mysql" : "file",
317
315
  crossProcessSafe: mailboxStore.crossProcessSafe,
318
316
  recipientTombstones: pgPool !== undefined || mysqlPool !== undefined,
319
317
  peerLaneMountable: laneVerdict.ok,
@@ -339,9 +337,9 @@ export async function openStores(ctx) {
339
337
  else {
340
338
  usageWindowStore = new InMemoryUsageWindowStore();
341
339
  }
342
- logger.info("usage_window_store_enabled", { backend: pgPool ? "pg" : mysqlPool ? "tidb" : backend?.fileUsageWindowStore !== undefined ? "file" : "memory", windows: config.usageWindows.length });
340
+ logger.info("usage_window_store_enabled", { backend: pgPool ? "pg" : mysqlPool ? "mysql" : backend?.fileUsageWindowStore !== undefined ? "file" : "memory", windows: config.usageWindows.length });
343
341
  }
344
- const memoryExportBackend = config.memoryEngineBackend !== "file" ? memoryEngine?.backend : undefined;
342
+ const memoryExportStores = config.memoryEngineBackend !== "file" ? memoryEngine : undefined;
345
343
  const memoryLane = memoryEngineRemoteLanePosture(config);
346
344
  const memoryPosture = buildMemoryPosture({
347
345
  config,
@@ -363,18 +361,7 @@ export async function openStores(ctx) {
363
361
  let memorySyncRunner;
364
362
  if (config.memorySync) {
365
363
  if (memoryEngine) {
366
- const transport = createMemorySyncTransport({ url: config.memorySync.url, token: config.memorySync.token });
367
- memorySyncRunner = createMemorySyncRunner({
368
- backend: memoryEngine.backend,
369
- scope: config.memorySync.scope,
370
- memoryRoot: memoryEngine.root,
371
- transport,
372
- log: logger,
373
- ...(config.memorySync.maxPushEntries !== undefined ? { maxPushEntries: config.memorySync.maxPushEntries } : {}),
374
- ...(config.memorySync.maxPullEntries !== undefined ? { maxPullEntries: config.memorySync.maxPullEntries } : {}),
375
- });
376
- logger.info("memory_sync_enabled", buildMemorySyncEnabledFields(transport.peer, config.memorySync.scope, memorySyncRunner.cursorPathFor(config.memorySync.scope)));
377
- memorySyncRunner.trigger("boot");
364
+ memorySyncRunner = startMemorySyncRunner({ sync: config.memorySync, stores: memoryEngine, log: logger });
378
365
  }
379
366
  else {
380
367
  logger.warn("memory_sync_configured_but_memory_dark", { note: "MEMORY_SYNC_URL is set but the file memory engine is dark (multi-tenant / MEMORY_ENGINE=off / remote exec lane) — no sync rounds will run" });
@@ -444,7 +431,7 @@ export async function openStores(ctx) {
444
431
  : undefined;
445
432
  return {
446
433
  backend, storePosture, memoryEngine, engineDataRoot, memorySyncCursors, rosterStore, backgroundAgentStore, mailboxRecipientLifecycle,
447
- taskAttachmentStore, mailboxStore, memoryExportBackend, memorySyncRunner, sessionStore, breakerState,
434
+ taskAttachmentStore, mailboxStore, memoryExportStores, memorySyncRunner, sessionStore, breakerState,
448
435
  usageWindowStore, memoryPosture, taskListLane, sqlEngine,
449
436
  };
450
437
  }
@@ -38,7 +38,7 @@ import type { Logger } from "../observability/logger.js";
38
38
  /** 同时活着的会话清单实例上限(LRU,逐最老)。与 perSessionCwd/perSessionShellEnv 同量级。 */
39
39
  export declare const MAX_TASK_LIST_SESSIONS = 4096;
40
40
  /** 车道实际落到哪个后端(启动日志 + 测试对表)。 */
41
- export type TaskListLaneBackend = "tidb" | "pg" | "memory";
41
+ export type TaskListLaneBackend = "mysql" | "pg" | "memory";
42
42
  export interface TaskListLane {
43
43
  /** `sessionId ↦ 该会话的任务清单店`。同 sessionId 恒解析到同一份清单(SQL 形 = 同一批行;
44
44
  * memory 形 = 同一只实例)。 */
@@ -16,7 +16,7 @@ export function createTaskListLane(opts = {}) {
16
16
  purge = (sessionId) => deletePgTaskList(pgPool, taskListKeyFor(sessionId));
17
17
  }
18
18
  else if (mysqlPool) {
19
- backend = "tidb";
19
+ backend = "mysql";
20
20
  mint = (sessionId) => createTiDBTaskListStore(mysqlPool, taskListKeyFor(sessionId));
21
21
  purge = (sessionId) => deleteTiDBTaskList(mysqlPool, taskListKeyFor(sessionId));
22
22
  }
@@ -31,6 +31,14 @@ import { SHA256_HEX_RE } from "../digest-form.js";
31
31
  import { BOOT_REJUDGE_OF_REFUSED_GROUP, createConfigApplyLedger, modelPlaneCommitted, refusedGroups } from "../web-admin-client/apply-ledger.js";
32
32
  import { announceReadDenyRows, buildDeploymentPostureSeats } from "./runner-deps.js";
33
33
  import { echoCallerText } from "../caller-text-echo.js";
34
+ const MODELS_REJECTION_PHRASE = {
35
+ domain_invalid: "models 域判形失败",
36
+ empty: "读不出(空 / 纯空白:半写或截断)",
37
+ invalid_json: "读不出(不是合法的 JSON)",
38
+ not_object: "读不出(解析出来不是 JSON 对象:null / 数组 / 标量)",
39
+ io: "读不出(文件读失败:权限、路径是目录或 I/O 错误)",
40
+ retired_domain: "是带事实的退役域文档",
41
+ };
34
42
  function lkgReadNote(scope) {
35
43
  switch (scope) {
36
44
  case "whole":
@@ -202,6 +210,22 @@ export async function createWebAdminRuntime(ctx) {
202
210
  noteCandidateVerdict(ordinal, candidateRejectionOf(r, verdict, candidateSource().kind, Date.now()));
203
211
  logger.warn("config_candidate_rejected", buildCandidateRejectedFields(r, verdict, leg, { lkgVersion: latestEffective?.version ?? "(env)", ...localDirField }));
204
212
  };
213
+ const noteSourceAtApplied = () => {
214
+ const rejected = candidateRejection;
215
+ const appliedVersion = applyLedger.view().configAppliedVersion;
216
+ if (rejected === undefined || rejected.version === appliedVersion)
217
+ return;
218
+ const gen = generationOf(appliedVersion);
219
+ noteCandidateVerdict(gen, undefined);
220
+ if (!cc?.dryRun)
221
+ applyLedger.applied(gen, appliedVersion);
222
+ logger.info("config_source_back_to_applied", {
223
+ appliedVersion,
224
+ rejectedVersion: rejected.version,
225
+ domains: rejected.domains.join(","),
226
+ note: "the config source serves the applied generation again (unchanged-since-applied reply) — the rejected candidate is no longer its current one: candidateRejected cleared, target back to applied; the same breakage again is announced again",
227
+ });
228
+ };
205
229
  const selfReportListeners = [];
206
230
  const notifySelfReport = (changed) => {
207
231
  for (const listener of selfReportListeners) {
@@ -540,18 +564,18 @@ export async function createWebAdminRuntime(ctx) {
540
564
  logger.warn("config_lkg_apply_failed", { err: String(applyErr), note: "persisted LKG failed to apply — env fallback serves; the cache rewrites on the next clean candidate" });
541
565
  }
542
566
  };
543
- const warnLocalNoModels = (r, rejected) => {
544
- const modelsDomainErr = (r.domainErrors ?? []).find((de) => de.domain === "models");
567
+ const warnLocalNoModels = (r, verdict) => {
568
+ const modelsRejection = verdict.verdict === "rejected" ? verdict.errors.find((e) => e.domain === "models") : undefined;
545
569
  const modelsDropped = (r.droppedEntries ?? []).filter((d) => d.domain === "models");
546
570
  const totalModels = (r.effective.models?.models ?? []).length;
547
571
  logger.warn("config_local_no_models", {
548
572
  ...localDirField,
549
- ...(modelsDomainErr ? { domainError: modelsDomainErr.error } : {}),
573
+ ...(modelsRejection ? { reason: modelsRejection.reason, domainError: modelsRejection.error } : {}),
550
574
  ...(modelsDropped.length > 0 ? { droppedEntries: modelsDropped.map((d) => d.entry) } : {}),
551
- hint: rejected && modelsDomainErr
552
- ? "config.d/models.json 在场但 models 域判形失败,整份本地候选被拒(真因见本行 domainError)— 模型继续走 env 兜底"
553
- : rejected
554
- ? "config.d 里别的域让整份本地候选被拒(判形失败,或带事实的退役域文档;坏域与真因见 config_candidate_rejected)— config.d/models.json 的模型不用,继续走 env 兜底"
575
+ hint: modelsRejection
576
+ ? `config.d/models.json 在场但${MODELS_REJECTION_PHRASE[modelsRejection.reason]},整份本地候选被拒(成因词见本行 reason,真因见本行 domainError)— 模型继续走 env 兜底`
577
+ : verdict.verdict === "rejected"
578
+ ? "config.d 里别的域让整份本地候选被拒(坏域、成因词与真因见 config_candidate_rejected)— config.d/models.json 的模型不用,继续走 env 兜底"
555
579
  : modelsDropped.length > 0 && totalModels === 0
556
580
  ? "config.d/models.json 的条目全部被逐条丢弃(逐条真因见 config_entry_dropped)— 模型继续走 env 兜底"
557
581
  : totalModels > 0
@@ -600,7 +624,7 @@ export async function createWebAdminRuntime(ctx) {
600
624
  applyLedger.seenTarget(rejectedGen, r.effective.version);
601
625
  announceCandidateRejected(r, bootVerdict, "boot", rejectedGen);
602
626
  if (configProvider.kind === "local")
603
- warnLocalNoModels(r, true);
627
+ warnLocalNoModels(r, bootVerdict);
604
628
  }
605
629
  else {
606
630
  warnReadNotices(r, "boot");
@@ -645,7 +669,7 @@ export async function createWebAdminRuntime(ctx) {
645
669
  const cfgModels = (r.effective.models?.models ?? []).filter((m) => m.enabled !== false).length;
646
670
  logger.info("config_loaded", { source: configProvider.kind, version: r.effective.version, worker: cc?.worker ?? "(global)", models: cfgModels, ...localDirField });
647
671
  if (configProvider.kind === "local" && cfgModels === 0)
648
- warnLocalNoModels(r, false);
672
+ warnLocalNoModels(r, bootVerdict);
649
673
  }
650
674
  }
651
675
  if (configProvider.kind === "remote")
@@ -959,6 +983,8 @@ export async function createWebAdminRuntime(ctx) {
959
983
  logger.warn("models_tiers_deferred_no_handoff", { version: planeDeferredNoHandoff.version, since: planeDeferredNoHandoff.since, note: "candidate still retained without a next-boot handoff — mount restart-surviving LKG storage + CONFIG_LKG_DURABLE=true, or restart manually after ensuring the candidate is re-pulled at boot" });
960
984
  }
961
985
  const r = arrival !== undefined ? arrival.result : await pullEffective(configProvider, ccEtag);
986
+ if (r === null)
987
+ noteSourceAtApplied();
962
988
  if (r === null && planeDeferredNoHandoff) {
963
989
  const skillsDebt = (planeDeferredNoHandoff.blocked ?? []).includes("skills");
964
990
  const promoted = lkgSurvivesRestart || skillsDebt ? await persistLkgDurable(planeDeferredNoHandoff.candidate, planeDeferredNoHandoff.candidateEtag) : false;
@@ -5,8 +5,8 @@ export interface ExecutionLaneCapability {
5
5
  /** 工具跑的那台机器就是本进程这台吗(= server 盘上的绝对路径对模型的工具有没有意义)。
6
6
  * 属主 = 部署形表行 `toolsOnThisHost`,与 `skills[].baseDir` 的铸点同一行。 */
7
7
  readonly toolsOnThisHost: boolean;
8
- /** [ref]:手在不在 OS 级隔离边界里(容器 / microVM / Kata pod)。**present-iff 本车道有手**(能力表 `coreRemoteExecutionEnv`);
9
- * 值 = {@link laneIsolated}(能力表 `isolation` 位,与 boot `remote_exec_enabled.isolated` 同一只)。见头注 [ref] 段。 */
8
+ /** 手在不在 OS 级隔离边界里(容器 / microVM / Kata pod)。**present-iff 本车道有手**(执行环境块 `io`);
9
+ * 值 = {@link laneIsolated}(执行环境块 `isolation`,与 boot `remote_exec_enabled.isolated` 同一只)。见头注第三键段。 */
10
10
  readonly isolated?: boolean;
11
11
  }
12
12
  /**
@@ -395,12 +395,13 @@ export const CONFIG_CATALOG = [
395
395
  r("RATE_LIMIT_RPM", "limitsHttp", "number", "计费提交每分钟限流(0=关)", { staticDefault: "0", danger: BILL, configKey: "rateLimitPerMin", center: cLimits("rateLimitPerMin") }),
396
396
  r("READ_DENY_BUILTIN_EXCLUDE", "orchestration", "csv", "按行名删内建 deny 条目(档位之后生效;绝不削任务显式 deny)", { danger: SEC, configKey: "readDenyBuiltinExclude" }),
397
397
  r("READ_DENY_BUILTIN_TIERS", "orchestration", "csv", "内建 deny 表档位选择(闭集五档 credentials/shell-history/browser/wallet/agent-config;none=显式空姿态)", { danger: SEC, derivedDefaultNote: "缺席 ⇒ 出厂两档在岗 **credentials,agent-config**(core 7.34.0 R-2 起;7.22.0–7.33.x 曾为 OFF)。要全关显式写 none;要全五档显式写 credentials,shell-history,browser,wallet,agent-config;空值拒启(手滑与显式意图不许同形)", configKey: "readDenyBuiltinTiers" }),
398
+ r("READ_DENY_FLOOR_REQUIRED", "orchestration", "boolean", "要求读拒表的字节地板:true ⇒ 读拒表有行而执行环境不守地板(起服行 remote_exec_enabled.keepsReadFloor=false;此时另有起服 warn read_deny_floor_required_unkept)的 run 在准备期拒(config.read_deny_floor_unkept,一个命令都不起;同步提交 409)。出厂读拒档在岗 ⇒ 这类车道上带手的 run 一律拒起", { staticDefault: "false", danger: SEC, derivedDefaultNote: "缺席 ⇒ 不要求:run 照跑,每 run 一条 operator 通告 config.read_deny_floor_unkept(engine_notice 日志;递归读照读表里的文件,通告不是保护)", configKey: "readDenyFloorRequired" }),
398
399
  r("READ_DENY_PATTERNS", "orchestration", "csv", "READ 面额外 deny pattern 表", { danger: SEC, configKey: "readDenyPatterns" }),
399
400
  r("READ_FACE", "orchestration", "enum", "READ 容纳面档位(env 逐键恒赢 center —— 部署主权表达)", { enumValues: ["open", "roots"], danger: SEC, derivedDefaultNote: "缺席 ⇒ 按 posture 派生(S-167):单用户 turnkey(REQUIRE_PRINCIPAL 未设)铸 open;多租户不铸键、core 默认 roots。生效来源见 GET /v1/diagnostics/wiring 的 readFace.source 四词", configKey: "readFace" }),
400
401
  r("REAP_INTERVAL_SEC", "limitsHttp", "number", "reaper 周期(秒)", { staticDefault: "60", configKey: "reapIntervalSec" }),
401
402
  r("REAP_RUN_STALE_SEC", "limitsHttp", "number", "run 活性判陈旧阈(秒)", { staticDefault: "120", configKey: "runStaleSec", center: cLimits("runStaleSec") }),
402
403
  r("REMOTE_EXEC", "orchestration", "enum", "执行车道选择(点名而配不齐/认不出 ⇒ 拒启,绝不静默降级到 host/stub)", { enumValues: REMOTE_EXEC_PROVIDER_WORDS, danger: SEC, derivedDefaultNote: "缺席:CONFIG_PROVIDER=local ⇒ host;其余 ⇒ 进程内 stub(手带整族不挂;残余名册看活体 wiring_manifest 里 mountedBy=hands 的条目数,不按工具名点。想让这一形拒启见 REQUIRE_EXECUTION_LANE)", configKey: "remoteExec", resolve: (c) => c.remoteExec?.provider ?? null }),
403
- r("REMOTE_EXEC_HOME_DIR", "orchestration", "path", "执行环境的 home 目录(`~/` 形权限规则的基、引擎家锚拒读行的落点;core ExecutionEnv.homeDir 座)。声明优先:不声明时 k8s / local-docker / ssh / adb 车道建环境那一拍实测执行环境自己的 $HOME 填引擎手里的座(`~/` 形规则的下单门仍只认声明);k8s / local-docker / ssh 车道的声明会在每只执行环境开起来时与它的 $HOME 对证(同一只判官、同一句拒),不一致或问不出 ⇒ 那只环境不开", { danger: SEC, derivedDefaultNote: "缺席:host/in-process ⇒ os.homedir();e2b ⇒ /home/user;k8s/local-docker/ssh/adb ⇒ 建环境时实测 $HOME(实测缺席 ⇒ 那只环境的座缺席:泄内容的递归读全 shell 面真人问、只读面拒,并响 warn execution_lane_home_undeclared);device ⇒ 无(设备协议没有家目录读数:起服 warn execution_lane_home_undeclared);`~/` 形规则的下单门恒只认声明(无声明即 422 响亮拒)", configKey: "remoteExecHomeDir", resolve: (c) => c.remoteExecHomeDir ?? null }),
404
+ r("REMOTE_EXEC_HOME_DIR", "orchestration", "path", "执行环境的 home 目录(`~/` 形权限规则的基、引擎家锚拒读行的落点;core ExecutionEnv.homeDir 座)。声明与车道出厂答案(host ⇒ 本进程家目录,e2b ⇒ /home/user)都是主张:读得出家目录的车道(k8s / local-docker / ssh / adb / e2b / host)在每只执行环境开起来时拿环境里命令看到的 $HOME 证它(同一只判官、同一句拒),不一致或问不出 ⇒ 那只环境不开;不声明且车道没有出厂答案时,建环境那一拍实测 $HOME 填引擎手里的座(`~/` 形规则的下单门仍只认 boot 期答案);device 读不了 ⇒ 声明即座、起服 warn execution_lane_home_unmeasured 披露未实测", { danger: SEC, derivedDefaultNote: "缺席:host/in-process ⇒ os.homedir();e2b ⇒ /home/user(两者都在环境开起来时与 $HOME 对证);k8s/local-docker/ssh/adb ⇒ 建环境时实测 $HOME(实测缺席 ⇒ 那只环境的座缺席:泄内容的递归读全 shell 面真人问、只读面拒,并响 warn execution_lane_home_undeclared);device ⇒ 无(设备协议没有家目录读数:起服 warn execution_lane_home_undeclared);`~/` 形规则的下单门恒只认声明(无声明即 422 响亮拒)", configKey: "remoteExecHomeDir", resolve: (c) => c.remoteExecHomeDir ?? null }),
404
405
  r("REQUIRE_EXECUTION_LANE", "orchestration", "boolean", "开了之后:REMOTE_EXEC 未点名 ∧ CONFIG_PROVIDER≠local ⇒ **拒启**并点名该设什么。默认关 = 照旧启动,但执行环境是进程内 stub、**零手带工具**(手带整族不挂;活体读数:mountedBy=hands 条目 10 → 0),名册里其余工具照常执行,任务仍回 status=completed —— 凡需要手的请求,与「模型不肯用工具」在用户面同形。判据 = 活体 wiring_manifest 里 mountedBy=hands 的条目数,不按工具名点;名册总条数随 core 版本走,不写死。托管/云部署推荐开(docs/DEPLOY-PREREQS.md)", { staticDefault: "false", danger: SEC, configKey: "requireExecutionLane" }),
405
406
  r("REQUIRE_PRINCIPAL", "auth", "boolean", "多租户开关(posture 判别位:true ⇒ CC 能力族默认收紧)", { staticDefault: "false", danger: SEC, configKey: "requirePrincipal" }),
406
407
  r("RESOURCE_SUSPEND", "approval", "boolean", "durable 路径 opt-in core resourceSuspend(预算/preempt ⇒ 可恢复挂起)", { staticDefault: "false", configKey: "resourceSuspend" }),
@@ -1,15 +1,12 @@
1
- import { type DroppedConfigEntry, type RetiredDomainFinding, type UnreadConfigFile, type UnreadConfigKey } from "./web-admin-client/read-warnings.js";
2
- import { FileConfigStore } from "@sema-agent/settings-schema/node";
3
- import { type EffectiveConfig as AgentConfigEffective, type EffectiveReadWarning } from "@sema-agent/settings-schema";
1
+ import { type DroppedConfigEntry, type UnreadConfigFile, type UnreadConfigKey } from "./web-admin-client/read-warnings.js";
2
+ import { type ConfigDocumentRefusal, type EffectiveConfig as AgentConfigEffective, type EffectiveReadWarning } from "@sema-agent/settings-schema";
4
3
  import { fetchEffective as remoteFetchEffective, fetchSkillContent as remoteFetchSkillContent, type EffectiveConfig } from "./web-admin-client/facade.js";
5
4
  import type { CenterEndpoint } from "./web-admin-client/center-request.js";
6
5
  import type { ConfigProviderWord } from "./config-types.js";
7
6
  /** Result of a `fetchEffective` — EXACTLY the web-admin's return: the effective config + its etag, or
8
7
  * `null` for "unchanged" (remote 304; local: the version matched the caller's prior etag).
9
- * `domainErrors`([ref] registry-core 0.10.12 tolerant seam,local lane only):catalog 域坏文件不再
10
- * 连坐全包回落 env——坏域按该域 schema default 落+错误单列,好域照常生效;caller(main.ts)对每条打
11
- * per-domain warn 点名坏域。gate 域(governance/rosters/…)坏文件 tolerant 仍 throw(READ 容错不放宽
12
- * gate fail-loud,registry-core 半场精化)——那条路走既有的整包 catch。 */
8
+ * `domainErrors`:某个**读得出**的域判形失败(schema 坏形 / 拼错键 / 悬空引用;那个域已按契约的域档位落缺省或被逐条判过)—— 候选判官以
9
+ * `domain_invalid` 整拒;缺席 = 没有。读不出的**文档**不在这里(见 `refusedDocuments`)。 */
13
10
  /** 壳写在 `config.d/models.json` 条目上的装饰键(`sema*`)自 settings-schema 1.5.0 起是**声明过的扩展命名空间**
14
11
  * (`EXTENSION_NAMESPACES`):schema 照旧 strip、但不再报「未知键」,所以本函数收到的每一个未知键都是拼错/越界 ⇒ 候选门错误。
15
12
  * 此前把这类键当「通知」放行的整套下游机制(域豁免/键路径闭集/满额特判/单独的通知面)已全部撤回——意图在声明处说,消费方不猜。 */
@@ -25,9 +22,10 @@ import type { ConfigProviderWord } from "./config-types.js";
25
22
  * `effective.models.droppedCatalogEntries`(`GET /v1/models.droppedEntries` 的源,与 `models` 同世代)。 */
26
23
  /** `unreadFiles`:`config.d` 里读腿根本不读的文件(不是域 / 不是便携域)—— **不**进候选门(不是读的域判形失败),调用方一份一行
27
24
  * `config_unread_file` 点名、其余照用;缺席 = 没有(本地读腿才会有)。 */
28
- /** `retiredDomains`([ref]):带事实的退役域文档(契约包的墓碑)—— 读腿不抛,交成发现,候选判官以成因 `retired_domain` 整拒这份候选(与域判形失败
29
- * 同一条回落链、同一行拒判);缺席 = 没有。远端腿:那一键不进 effective、其余域照读;本地腿:契约读腿在读便携域之前就拒,交出的候选只有版本
30
- * (这棵树的内容版本,哈希含退役文件 ⇒ 改 / 删它版本即变),内容是空的 effective(被整拒,不会被应用)。 */
25
+ /** `refusedDocuments`:被拒文档 —— 契约的类型 `ConfigDocumentRefusal`(`{ document, reason, error }`,墓碑另带 `migration`;`reason` 是契约闭集
26
+ * `CONFIG_DOCUMENT_REFUSAL_REASONS`:`empty` / `invalid_json` / `not_object` / `io` 文件层,`retired_domain` 墓碑)。读腿不抛,交成发现,候选判官以发现自带的词整拒这份候选
27
+ * (与域判形失败同一条回落链、同一行拒判);缺席 = 没有。远端腿:wire 上只有墓碑一种,那一键不进 effective、其余域照读、版本照读;本地腿:契约的严读拒了这棵树 ⇒
28
+ * 被拒文档 = 契约整目录拒单 `inspectBundle` 的原样,什么内容都没读到 —— 候选是空的 effective(被整拒,不会被应用),版本 = 拒单那一读的契约版本(按文档内容寻址)。 */
31
29
  /** `unreadKeys`:本地读腿读了那份文件、却结构上不读其中一键(`prompts.json` 的 `workers`)—— 同 `unreadFiles`,不进候选门,调用方一键一行 `config_unread_key`。 */
32
30
  export type FetchEffectiveResult = {
33
31
  effective: EffectiveConfig;
@@ -39,7 +37,7 @@ export type FetchEffectiveResult = {
39
37
  droppedEntries?: DroppedConfigEntry[];
40
38
  unreadFiles?: UnreadConfigFile[];
41
39
  unreadKeys?: UnreadConfigKey[];
42
- retiredDomains?: RetiredDomainFinding[];
40
+ refusedDocuments?: ConfigDocumentRefusal[];
43
41
  readWarnings: readonly EffectiveReadWarning[];
44
42
  credentialIdentity?: string;
45
43
  } | null;
@@ -159,16 +157,19 @@ export declare class RemoteConfigProvider implements ConfigProvider {
159
157
  * stable change-detector. We map that down to the service-local `EffectiveConfig` shape and surface the
160
158
  * version as the etag (so the caller's "skip re-apply if etag unchanged" works locally too).
161
159
  */
160
+ /** 本地读腿对契约文件店只有一种读法 —— 严读 `getEffective()`。注入缝(测试)按这一形给;容错档位不在这条腿的类型里。 */
161
+ export interface StrictConfigStore {
162
+ getEffective(): Promise<AgentConfigEffective>;
163
+ }
162
164
  export declare class LocalConfigProvider implements ConfigProvider {
163
165
  #private;
164
166
  readonly kind: "local";
165
167
  /** 本地配置源不留正文盘缓存:正文就内联在 config.d 里(同一块盘),缓存它是第二份真源。 */
166
168
  readonly skillBodyCacheDir: undefined;
167
- private readonly store;
168
169
  /** [ref]b 可观测性:config_loaded 日志要能回答「到底读的哪个目录」——复验实录:只设 LOCAL_DATA_ROOT 时
169
170
  * config.d 静默读不到且 0 模型无告警(CONFIG_LOCAL_DIR 才是本 lane 的选目录旋钮)。 */
170
171
  readonly root: string;
171
- constructor(root: string, store?: FileConfigStore, trust?: {
172
+ constructor(root: string, store?: StrictConfigStore, trust?: {
172
173
  readonly declaredOwnerUid: number | undefined;
173
174
  });
174
175
  fetchEffective(etag: string | undefined): Promise<FetchEffectiveResult>;