@sema-agent/server 7.122.0 → 7.124.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 (256) hide show
  1. package/MIGRATION.md +209 -0
  2. package/README.md +7 -2
  3. package/README.zh-CN.md +5 -2
  4. package/USAGE.md +76 -56
  5. package/dist/approval-ask-audit-store.d.ts +27 -32
  6. package/dist/approval-ask-audit-store.js +10 -9
  7. package/dist/approval-crash-convergence.d.ts +2 -2
  8. package/dist/approval-crash-convergence.js +5 -5
  9. package/dist/approval-deny-reasons.d.ts +163 -51
  10. package/dist/approval-deny-reasons.js +79 -8
  11. package/dist/approval-policy-settlement.d.ts +4 -1
  12. package/dist/approval-policy-settlement.js +3 -2
  13. package/dist/approval-reconciler.d.ts +3 -3
  14. package/dist/approval-reconciler.js +10 -10
  15. package/dist/approval.d.ts +1 -1
  16. package/dist/approval.js +1 -1
  17. package/dist/audit.d.ts +1 -1
  18. package/dist/audit.js +53 -23
  19. package/dist/auth-bridge.d.ts +8 -8
  20. package/dist/auth-bridge.js +6 -6
  21. package/dist/auth-keys.d.ts +2 -2
  22. package/dist/auto-mode-face.d.ts +13 -9
  23. package/dist/auto-mode-face.js +8 -7
  24. package/dist/boot/budget-tracing.js +1 -1
  25. package/dist/boot/execution-env.js +1 -0
  26. package/dist/boot/leader.d.ts +1 -1
  27. package/dist/boot/memory-consolidation.d.ts +4 -4
  28. package/dist/boot/org-memory.d.ts +3 -3
  29. package/dist/boot/org-memory.js +5 -5
  30. package/dist/boot/resolve-spec.js +7 -7
  31. package/dist/boot/runner-deps.d.ts +1 -1
  32. package/dist/boot/runtime-caps.d.ts +1 -1
  33. package/dist/boot/runtime-caps.js +10 -10
  34. package/dist/boot/shutdown.d.ts +2 -2
  35. package/dist/boot/shutdown.js +2 -2
  36. package/dist/boot/side-query-lane.d.ts +3 -3
  37. package/dist/boot/{stage-02-registry-pull.d.ts → stage-02-web-admin-pull.d.ts} +2 -2
  38. package/dist/boot/{stage-02-registry-pull.js → stage-02-web-admin-pull.js} +4 -4
  39. package/dist/boot/stage-03-store-backend.d.ts +2 -2
  40. package/dist/boot/stage-04-stores.d.ts +1 -1
  41. package/dist/boot/stage-05-execution-env.d.ts +1 -1
  42. package/dist/boot/stage-06-runners.d.ts +2 -2
  43. package/dist/boot/stage-06-runners.js +6 -6
  44. package/dist/boot/stage-07-capability-layer.d.ts +2 -2
  45. package/dist/boot/stage-07-capability-layer.js +6 -5
  46. package/dist/boot/stage-08-reapers.d.ts +3 -3
  47. package/dist/boot/stage-08-reapers.js +3 -3
  48. package/dist/boot/stage-09-leader.d.ts +3 -3
  49. package/dist/boot/stage-09-leader.js +7 -7
  50. package/dist/boot/stage-10-http-server.d.ts +3 -3
  51. package/dist/boot/stage-10-http-server.js +19 -19
  52. package/dist/boot/unpriced-ceiling-verdict.d.ts +1 -1
  53. package/dist/boot/{config-center.d.ts → web-admin.d.ts} +11 -11
  54. package/dist/boot/{config-center.js → web-admin.js} +39 -20
  55. package/dist/boot/webfetch-summarize-lane.d.ts +2 -2
  56. package/dist/brain.d.ts +1 -1
  57. package/dist/brain.js +1 -1
  58. package/dist/budget.d.ts +3 -3
  59. package/dist/canonical-json.d.ts +2 -2
  60. package/dist/capabilities/center-plugins.d.ts +1 -1
  61. package/dist/capabilities/center-wiring.d.ts +12 -5
  62. package/dist/capabilities/center-wiring.js +11 -2
  63. package/dist/capabilities/composite-members.d.ts +1 -1
  64. package/dist/capabilities/composite-members.js +1 -1
  65. package/dist/capabilities/scenarios.js +2 -2
  66. package/dist/capabilities/team.d.ts +1 -1
  67. package/dist/capabilities/tool-defer.d.ts +1 -1
  68. package/dist/center-credential-renewer.d.ts +1 -1
  69. package/dist/center-credential-renewer.js +7 -7
  70. package/dist/center-credential.d.ts +9 -9
  71. package/dist/center-credential.js +6 -6
  72. package/dist/config-catalog.d.ts +7 -10
  73. package/dist/config-catalog.js +16 -16
  74. package/dist/config-d-migration.d.ts +32 -0
  75. package/dist/config-d-migration.js +59 -0
  76. package/dist/config-invariants.d.ts +14 -4
  77. package/dist/config-invariants.js +31 -2
  78. package/dist/config-lkg.d.ts +34 -11
  79. package/dist/config-lkg.js +76 -48
  80. package/dist/config-provider.d.ts +26 -21
  81. package/dist/config-provider.js +25 -27
  82. package/dist/config-types.d.ts +59 -50
  83. package/dist/config.d.ts +17 -54
  84. package/dist/config.js +99 -181
  85. package/dist/execution-lane-caps.d.ts +1 -1
  86. package/dist/fleet/drain-entry.d.ts +1 -1
  87. package/dist/fleet/engine-signal.d.ts +61 -30
  88. package/dist/fleet/engine-signal.js +29 -5
  89. package/dist/fleet/fleet-bus.d.ts +12 -3
  90. package/dist/fleet/fleet-bus.js +13 -9
  91. package/dist/fleet/serving-lease.d.ts +3 -3
  92. package/dist/fleet/serving-lease.js +1 -1
  93. package/dist/fleet-client.d.ts +15 -13
  94. package/dist/fleet-client.js +9 -7
  95. package/dist/fleet-lease.d.ts +3 -3
  96. package/dist/fleet-lease.js +2 -2
  97. package/dist/host-lsp-manager.d.ts +1 -1
  98. package/dist/hosted-posture.d.ts +4 -4
  99. package/dist/http/admission.js +4 -4
  100. package/dist/http/checkpoint-ctx.d.ts +20 -3
  101. package/dist/http/checkpoint-ctx.js +13 -5
  102. package/dist/http/dispatch.js +7 -16
  103. package/dist/http/durable-run-leg.js +2 -1
  104. package/dist/http/health-self-report.d.ts +7 -4
  105. package/dist/http/health-self-report.js +3 -3
  106. package/dist/http/idempotency.d.ts +1 -1
  107. package/dist/http/resume-legs.d.ts +4 -3
  108. package/dist/http/resume-legs.js +31 -18
  109. package/dist/http/route-ctx.d.ts +8 -0
  110. package/dist/http/routes/admin-config-refresh.d.ts +1 -1
  111. package/dist/http/routes/admin-config-refresh.js +1 -1
  112. package/dist/http/routes/admin-drain.d.ts +1 -1
  113. package/dist/http/routes/admin-drain.js +5 -4
  114. package/dist/http/routes/approvals-assistant.js +4 -4
  115. package/dist/http/routes/capabilities.js +6 -5
  116. package/dist/http/routes/config-catalog.js +2 -3
  117. package/dist/http/routes/diagnostics.js +1 -1
  118. package/dist/http/routes/runs.js +8 -4
  119. package/dist/http/routes/sessions-list.js +2 -1
  120. package/dist/http/routes/sessions.js +2 -5
  121. package/dist/http/routes/side-query.js +3 -3
  122. package/dist/http/routes/tasks.js +3 -2
  123. package/dist/http/run-meta.d.ts +1 -1
  124. package/dist/http/run-meta.js +2 -2
  125. package/dist/http/server.d.ts +7 -7
  126. package/dist/http/server.js +1 -1
  127. package/dist/http/stored-body-replay.d.ts +4 -3
  128. package/dist/http/stored-body-replay.js +5 -5
  129. package/dist/index.d.ts +2 -1
  130. package/dist/index.js +1 -1
  131. package/dist/key-resolver.d.ts +1 -1
  132. package/dist/leader/leader.d.ts +7 -6
  133. package/dist/leader/leader.js +3 -1
  134. package/dist/leader/run-entry.d.ts +2 -2
  135. package/dist/leader/run-entry.js +3 -3
  136. package/dist/leader/wire.d.ts +4 -4
  137. package/dist/leader/wire.js +2 -1
  138. package/dist/main.js +1 -1
  139. package/dist/mcp-tool-faces.d.ts +2 -2
  140. package/dist/model-entry-refusal.d.ts +20 -11
  141. package/dist/model-entry-refusal.js +22 -17
  142. package/dist/model-provider.d.ts +2 -2
  143. package/dist/model-route-endpoint.d.ts +22 -2
  144. package/dist/model-route-endpoint.js +9 -3
  145. package/dist/model-route-gap.d.ts +103 -0
  146. package/dist/model-route-gap.js +80 -0
  147. package/dist/model-route-url.d.ts +1 -1
  148. package/dist/model-route-url.js +2 -1
  149. package/dist/model-select.d.ts +24 -21
  150. package/dist/model-select.js +22 -17
  151. package/dist/namespaced-rule-name.d.ts +16 -30
  152. package/dist/namespaced-rule-name.js +2 -20
  153. package/dist/observability/fail-open.d.ts +0 -4
  154. package/dist/observability/fail-open.js +0 -4
  155. package/dist/observability/metrics.d.ts +1 -1
  156. package/dist/org-memory-admission.d.ts +1 -1
  157. package/dist/plugins/approval-ask-store-file.d.ts +4 -2
  158. package/dist/plugins/approval-ask-store-file.js +3 -3
  159. package/dist/plugins/approval-ask-store-memory.d.ts +4 -3
  160. package/dist/plugins/approval-ask-store-memory.js +10 -4
  161. package/dist/plugins/approval-ask-store-sql.d.ts +16 -2
  162. package/dist/plugins/approval-ask-store-sql.js +20 -13
  163. package/dist/plugins/caching-session-store.d.ts +0 -10
  164. package/dist/plugins/caching-session-store.js +0 -3
  165. package/dist/plugins/file-run-store.js +9 -3
  166. package/dist/plugins/leader-run-store-sql.d.ts +3 -2
  167. package/dist/plugins/leader-run-store-sql.js +3 -2
  168. package/dist/plugins/local-session-store.d.ts +20 -27
  169. package/dist/plugins/local-session-store.js +19 -17
  170. package/dist/plugins/memory-run-store.js +9 -3
  171. package/dist/plugins/one-time-migrations.js +51 -0
  172. package/dist/plugins/scheduler-support.d.ts +26 -7
  173. package/dist/plugins/scheduler-support.js +96 -53
  174. package/dist/plugins/session-policy-store-sql.js +1 -2
  175. package/dist/plugins/store-backend.js +1 -1
  176. package/dist/plugins/store-contracts.d.ts +20 -4
  177. package/dist/plugins/web-search.d.ts +1 -1
  178. package/dist/plugins/web-search.js +2 -1
  179. package/dist/plugins/workflow-run-store-sql.d.ts +4 -2
  180. package/dist/posture-source.d.ts +1 -1
  181. package/dist/read-face-posture.d.ts +3 -3
  182. package/dist/read-face-posture.js +1 -1
  183. package/dist/rule-entry-list.d.ts +3 -13
  184. package/dist/rule-entry-list.js +1 -12
  185. package/dist/run-local.js +10 -7
  186. package/dist/runtime-caps-resolver.d.ts +4 -4
  187. package/dist/runtime-caps-resolver.js +2 -2
  188. package/dist/runtime-governance.d.ts +36 -13
  189. package/dist/runtime-governance.js +7 -2
  190. package/dist/sealed-key.d.ts +4 -4
  191. package/dist/sealed-key.js +3 -2
  192. package/dist/security.d.ts +3 -3
  193. package/dist/service-version.d.ts +1 -1
  194. package/dist/service-version.js +5 -0
  195. package/dist/session-policy-wire.d.ts +47 -49
  196. package/dist/session-policy-wire.js +41 -36
  197. package/dist/session-sync.d.ts +5 -1
  198. package/dist/session-sync.js +2 -1
  199. package/dist/session-titler.d.ts +0 -11
  200. package/dist/session-titler.js +3 -5
  201. package/dist/shared-memory-scope-authorizer.d.ts +4 -4
  202. package/dist/spec-fields.d.ts +4 -4
  203. package/dist/spec-fields.js +1 -4
  204. package/dist/task-a2a.d.ts +1 -1
  205. package/dist/task-settings.d.ts +4 -5
  206. package/dist/task-settings.js +5 -8
  207. package/dist/tool-approval.d.ts +43 -4
  208. package/dist/tool-approval.js +147 -98
  209. package/dist/trace/core-keyset-guard.d.ts +1 -1
  210. package/dist/trace/project.d.ts +3 -3
  211. package/dist/trace/redact.d.ts +2 -23
  212. package/dist/trace/redact.js +1 -6
  213. package/dist/trace/self-minted-wire.d.ts +147 -3
  214. package/dist/trace/self-minted-wire.js +50 -9
  215. package/dist/unattended-permission-mode.d.ts +3 -3
  216. package/dist/unattended-permission-mode.js +2 -2
  217. package/dist/url-refusal.d.ts +35 -0
  218. package/dist/url-refusal.js +15 -0
  219. package/dist/user-authored-text.d.ts +31 -0
  220. package/dist/user-authored-text.js +18 -0
  221. package/dist/{config-center → web-admin-client}/apply-effective.d.ts +13 -70
  222. package/dist/{config-center → web-admin-client}/apply-effective.js +104 -121
  223. package/dist/{config-center → web-admin-client}/apply-ledger.d.ts +2 -2
  224. package/dist/{config-center → web-admin-client}/center-request.d.ts +7 -7
  225. package/dist/{config-center → web-admin-client}/center-request.js +5 -4
  226. package/dist/{config-center → web-admin-client}/effective-keys.d.ts +1 -3
  227. package/dist/{config-center → web-admin-client}/effective-keys.js +0 -9
  228. package/dist/{config-center → web-admin-client}/facade.d.ts +6 -6
  229. package/dist/{config-center → web-admin-client}/facade.js +2 -2
  230. package/dist/{config-center → web-admin-client}/http-client.d.ts +6 -10
  231. package/dist/{config-center → web-admin-client}/http-client.js +15 -15
  232. package/dist/{config-center → web-admin-client}/pull-state.d.ts +1 -1
  233. package/dist/{config-center → web-admin-client}/read-face.js +4 -4
  234. package/dist/web-admin-client/read-warnings.d.ts +137 -0
  235. package/dist/web-admin-client/read-warnings.js +168 -0
  236. package/dist/{config-center → web-admin-client}/restart-signal.d.ts +5 -3
  237. package/dist/{config-center → web-admin-client}/restart-signal.js +3 -4
  238. package/dist/{config-center → web-admin-client}/skills-mcp.d.ts +1 -1
  239. package/dist/{config-center → web-admin-client}/skills-mcp.js +13 -13
  240. package/dist/{config-center → web-admin-client}/stage-limits.d.ts +1 -7
  241. package/dist/{config-center → web-admin-client}/stage-limits.js +6 -7
  242. package/dist/{config-center → web-admin-client}/types.d.ts +19 -47
  243. package/package.json +3 -3
  244. package/skills/find-skills.md +2 -2
  245. package/dist/config-center/read-warnings.d.ts +0 -109
  246. package/dist/config-center/read-warnings.js +0 -110
  247. package/dist/url-shape.d.ts +0 -31
  248. package/dist/url-shape.js +0 -41
  249. /package/dist/{config-center → web-admin-client}/apply-ledger.js +0 -0
  250. /package/dist/{config-center → web-admin-client}/hot-keys-registry.d.ts +0 -0
  251. /package/dist/{config-center → web-admin-client}/hot-keys-registry.js +0 -0
  252. /package/dist/{config-center → web-admin-client}/mcp-revocation.d.ts +0 -0
  253. /package/dist/{config-center → web-admin-client}/mcp-revocation.js +0 -0
  254. /package/dist/{config-center → web-admin-client}/pull-state.js +0 -0
  255. /package/dist/{config-center → web-admin-client}/read-face.d.ts +0 -0
  256. /package/dist/{config-center → web-admin-client}/types.js +0 -0
package/dist/audit.js CHANGED
@@ -4,6 +4,7 @@ import { PgSessionStorage } from "./plugins/pg-session-storage.js";
4
4
  import { createLocalSessionRepo } from "./plugins/local-session-store.js";
5
5
  import { redactModelText } from "./observability/run-terminal.js";
6
6
  import { redactDeepWith } from "./trace/redact.js";
7
+ import { INJECTED_BLOCK_RE } from "./user-authored-text.js";
7
8
  export async function buildSessionAudit(pool, sessionId) {
8
9
  return auditFromStorage(await TiDBSessionStorage.wake(pool, sessionId), sessionId);
9
10
  }
@@ -45,48 +46,78 @@ async function auditFromStorage(storage, sessionId) {
45
46
  }
46
47
  const deepScrub = (v) => redactDeepWith(v, redactModelText);
47
48
  const textSlot = (v) => (typeof v === "string" ? redactModelText(v) : deepScrub(v));
48
- function scrubSlot(p, key, scan) {
49
- const v = p[key];
50
- if (v === undefined)
51
- return p;
52
- const next = scan(v);
53
- return next === v ? p : { ...p, [key]: next };
49
+ function readLeaf(treatment, v) {
50
+ switch (treatment) {
51
+ case "text": return textSlot(v);
52
+ case "structure": return deepScrub(v);
53
+ case "parts": return readParts(v);
54
+ case "verbatim": return v;
55
+ default: {
56
+ const unhandled = treatment;
57
+ throw new Error(`unhandled leaf treatment: ${String(unhandled)}`);
58
+ }
59
+ }
60
+ }
61
+ const isPlainRecord = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
62
+ function readByTable(node, table) {
63
+ let changed = false;
64
+ const entries = Object.entries(node).map(([key, v]) => {
65
+ const next = readLeaf(Object.hasOwn(table, key) ? table[key] : "structure", v);
66
+ if (next !== v)
67
+ changed = true;
68
+ return [key, next];
69
+ });
70
+ return changed ? Object.fromEntries(entries) : node;
54
71
  }
55
72
  const PART_READ_TREATMENT = {
56
- text: (p) => scrubSlot(p, "text", textSlot),
57
- thinking: (p) => scrubSlot(p, "thinking", textSlot),
58
- toolCall: (p) => scrubSlot(p, "arguments", deepScrub),
59
- image: (p) => p,
60
- document: (p) => p,
73
+ text: { type: "verbatim", text: "text" },
74
+ thinking: { type: "verbatim", thinking: "text", thinkingSignature: "verbatim", redacted: "verbatim" },
75
+ toolCall: { type: "verbatim", id: "verbatim", wireId: "verbatim", name: "verbatim", arguments: "structure", executionMode: "verbatim" },
76
+ image: { type: "verbatim", data: "verbatim", mimeType: "verbatim" },
77
+ document: { type: "verbatim", data: "verbatim", mimeType: "verbatim" },
61
78
  };
62
79
  function readParts(content) {
63
80
  if (!Array.isArray(content))
64
81
  return textSlot(content);
65
82
  const next = content.map((part) => {
66
- if (part !== null && typeof part === "object" && !Array.isArray(part)) {
83
+ if (isPlainRecord(part)) {
67
84
  const type = part.type;
68
85
  if (typeof type === "string" && Object.hasOwn(PART_READ_TREATMENT, type)) {
69
- return PART_READ_TREATMENT[type](part);
86
+ return readByTable(part, PART_READ_TREATMENT[type]);
70
87
  }
71
88
  }
72
89
  return deepScrub(part);
73
90
  });
74
91
  return next.every((x, i) => x === content[i]) ? content : next;
75
92
  }
76
- const readContent = (m) => scrubSlot(m, "content", readParts);
77
93
  const MESSAGE_READ_TREATMENT = {
78
- user: (m) => m,
79
- custom: (m) => m,
80
- assistant: (m) => readContent(m),
81
- toolResult: (m) => scrubSlot(readContent(m), "details", deepScrub),
82
- bashExecution: (m) => scrubSlot(scrubSlot(m, "command", textSlot), "output", textSlot),
83
- compactionSummary: (m) => scrubSlot(m, "summary", textSlot),
94
+ user: {
95
+ role: "verbatim", content: "verbatim", timestamp: "verbatim", enginePrefixChars: "verbatim", engineSegments: "verbatim",
96
+ engineMinted: "verbatim", engineNoteKey: "verbatim", provenance: "verbatim", actor: "verbatim",
97
+ },
98
+ custom: { role: "verbatim", customType: "verbatim", content: "verbatim", display: "verbatim", details: "verbatim", provenance: "verbatim", timestamp: "verbatim" },
99
+ assistant: {
100
+ role: "verbatim", content: "parts", errorMessage: "text", diagnostics: "structure", repetition: "structure",
101
+ api: "verbatim", provider: "verbatim", model: "verbatim", responseModel: "verbatim", responseId: "verbatim", requestId: "verbatim",
102
+ isApiErrorMessage: "verbatim", apiErrorStatus: "verbatim", apiErrorCode: "verbatim", usage: "verbatim", usageMissing: "verbatim",
103
+ stopReason: "verbatim", errorKind: "verbatim", inputTooLongRuledOut: "verbatim", partialFinalized: "verbatim",
104
+ staticReasoningCut: "verbatim", timestamp: "verbatim",
105
+ },
106
+ toolResult: { role: "verbatim", toolCallId: "verbatim", toolName: "verbatim", content: "parts", details: "structure", isError: "verbatim", timestamp: "verbatim" },
107
+ bashExecution: {
108
+ role: "verbatim", command: "text", output: "text", exitCode: "verbatim", cancelled: "verbatim", truncated: "verbatim",
109
+ fullOutputPath: "verbatim", timestamp: "verbatim", excludeFromContext: "verbatim",
110
+ },
111
+ compactionSummary: {
112
+ role: "verbatim", summary: "text", details: "structure", tokensBefore: "verbatim", timestamp: "verbatim", elidedMessages: "verbatim",
113
+ unsummarizedMessages: "verbatim", tokensAfter: "verbatim", firstKeptEntryId: "verbatim",
114
+ },
84
115
  };
85
116
  function readMessage(m) {
86
- if (m !== null && typeof m === "object" && !Array.isArray(m)) {
117
+ if (isPlainRecord(m)) {
87
118
  const role = m.role;
88
119
  if (typeof role === "string" && Object.hasOwn(MESSAGE_READ_TREATMENT, role)) {
89
- return MESSAGE_READ_TREATMENT[role](m);
120
+ return readByTable(m, MESSAGE_READ_TREATMENT[role]);
90
121
  }
91
122
  }
92
123
  return deepScrub(m);
@@ -112,7 +143,6 @@ export function windowMessages(messages, opts) {
112
143
  const offset = Math.max(0, total - tail);
113
144
  return { messages: messages.slice(offset), window: { offset, total } };
114
145
  }
115
- const INJECTED_BLOCK_RE = /<(system-reminder|task-notification)(?:\s[^>]*)?>[\s\S]*?<\/\1>\s*/g;
116
146
  function capWithInjectionAwareness(s, capBytes) {
117
147
  const total = Buffer.byteLength(s, "utf8");
118
148
  if (total <= capBytes)
@@ -4,22 +4,22 @@ import type { Metrics } from "./observability/metrics.js";
4
4
  export type { VerifiedIdentity } from "@sema-agent/settings-schema/api/auth-bridge";
5
5
  /**
6
6
  * S-866 ② —— 鉴权桥 issuer 的**唯一**取值(装配 `boot/stage-09-leader.ts` 与 caps `centerWiring.issuer` 同读,不各写一份回退):
7
- * 显式 `AUTH_BRIDGE_ISSUER`(`config.authBridgeIssuer`)恒赢 ⇒ `source:"explicit"`;缺席则回退中心基址 `configCenter.baseUrl`
7
+ * 显式 `AUTH_BRIDGE_ISSUER`(`config.authBridgeIssuer`)恒赢 ⇒ `source:"explicit"`;缺席则回退中心基址 `webAdmin.baseUrl`
8
8
  * (配了中心即默认开桥)⇒ `source:"fallback"`;两者都没有 ⇒ `undefined`(桥不装)。
9
9
  */
10
10
  export declare function authBridgeIssuerOf(config: {
11
11
  readonly authBridgeIssuer?: string | undefined;
12
- readonly configCenter?: {
12
+ readonly webAdmin?: {
13
13
  readonly baseUrl: string;
14
14
  } | undefined;
15
15
  }): {
16
16
  readonly issuer: string;
17
17
  readonly source: "explicit" | "fallback";
18
18
  } | undefined;
19
- export interface RegistryJwtVerifierOptions {
20
- /** R4 — 期望 iss(registry 的 SSO_ISSUER;默认=SEMA_REGISTRY_URL,双侧去尾斜杠比较)。 */
19
+ export interface WebAdminJwtVerifierOptions {
20
+ /** R4 — 期望 iss(registry 的 SSO_ISSUER;默认=SEMA_WEB_ADMIN_URL,双侧去尾斜杠比较)。 */
21
21
  issuer: string;
22
- /** R2 — JWKS 绝对 URL(默认=issuer + REGISTRY_JWKS_PATH)。 */
22
+ /** R2 — JWKS 绝对 URL(默认=issuer + WEB_ADMIN_JWKS_PATH)。 */
23
23
  jwksUrl?: string;
24
24
  /** R7 — 设了则 aud 必须包含它;不设=忽略 aud。 */
25
25
  audience?: string;
@@ -41,13 +41,13 @@ export type VerifyOutcome = {
41
41
  ok: false;
42
42
  error: AuthBridgeErrorCode;
43
43
  };
44
- /** The live object `createRegistryJwtVerifier` produces — a single `verify` entry point over the process-level JWKS cache. */
45
- export interface RegistryJwtVerifier {
44
+ /** The live object `createWebAdminJwtVerifier` produces — a single `verify` entry point over the process-level JWKS cache. */
45
+ export interface WebAdminJwtVerifier {
46
46
  verify: (bearer: string) => Promise<VerifyOutcome>;
47
47
  }
48
48
  /**
49
49
  * registry-JWT verifier(单例,进程级 JWKS 缓存)。`verify(bearer)` 全程不 throw——一切异常折为
50
50
  * AUTH_BRIDGE_ERROR_CODES(HTTP 面由调用方恒答 generic 401,码只进日志/metrics,R9)。
51
51
  */
52
- export declare function createRegistryJwtVerifier(opts: RegistryJwtVerifierOptions): RegistryJwtVerifier;
52
+ export declare function createWebAdminJwtVerifier(opts: WebAdminJwtVerifierOptions): WebAdminJwtVerifier;
53
53
  //# sourceMappingURL=auth-bridge.d.ts.map
@@ -1,11 +1,11 @@
1
1
  import { createPublicKey, verify as cryptoVerify } from "node:crypto";
2
- import { AUTH_BRIDGE_ALGS, DEFAULT_CLOCK_SKEW_SEC, DEFAULT_JWKS_REFRESH_MIN_INTERVAL_SEC, DEFAULT_OFFLINE_GRACE_SEC, REGISTRY_JWKS_PATH, RegistryJwks, classifyTimeClaims, jwksWithinOfflineGrace, shouldForceJwksRefresh, toVerifiedIdentity, } from "@sema-agent/settings-schema/api/auth-bridge";
2
+ import { AUTH_BRIDGE_ALGS, DEFAULT_CLOCK_SKEW_SEC, DEFAULT_JWKS_REFRESH_MIN_INTERVAL_SEC, DEFAULT_OFFLINE_GRACE_SEC, WEB_ADMIN_JWKS_PATH, WebAdminJwks, classifyTimeClaims, jwksWithinOfflineGrace, shouldForceJwksRefresh, toVerifiedIdentity, } from "@sema-agent/settings-schema/api/auth-bridge";
3
3
  import { buildDisplaySafeUrl } from "./trace/redact.js";
4
4
  export function authBridgeIssuerOf(config) {
5
5
  if (config.authBridgeIssuer !== undefined)
6
6
  return { issuer: config.authBridgeIssuer, source: "explicit" };
7
- if (config.configCenter !== undefined)
8
- return { issuer: config.configCenter.baseUrl, source: "fallback" };
7
+ if (config.webAdmin !== undefined)
8
+ return { issuer: config.webAdmin.baseUrl, source: "fallback" };
9
9
  return undefined;
10
10
  }
11
11
  const DEFAULT_JWKS_TTL_SEC = 15 * 60;
@@ -25,10 +25,10 @@ function b64urlJson(seg) {
25
25
  }
26
26
  }
27
27
  const stripSlash = (s) => s.replace(/\/+$/, "");
28
- export function createRegistryJwtVerifier(opts) {
28
+ export function createWebAdminJwtVerifier(opts) {
29
29
  const issuer = stripSlash(opts.issuer);
30
30
  const displayIssuer = buildDisplaySafeUrl(issuer);
31
- const jwksUrl = opts.jwksUrl ?? `${issuer}${REGISTRY_JWKS_PATH}`;
31
+ const jwksUrl = opts.jwksUrl ?? `${issuer}${WEB_ADMIN_JWKS_PATH}`;
32
32
  const clockSkewSec = opts.clockSkewSec ?? DEFAULT_CLOCK_SKEW_SEC;
33
33
  const refreshMin = opts.jwksRefreshMinIntervalSec ?? DEFAULT_JWKS_REFRESH_MIN_INTERVAL_SEC;
34
34
  const offlineGraceSec = opts.offlineGraceSec ?? DEFAULT_OFFLINE_GRACE_SEC;
@@ -59,7 +59,7 @@ export function createRegistryJwtVerifier(opts) {
59
59
  const buf = Buffer.from(await res.arrayBuffer());
60
60
  if (buf.byteLength > MAX_JWKS_BYTES)
61
61
  throw new Error("jwks body too large");
62
- const doc = RegistryJwks.parse(JSON.parse(buf.toString("utf8")));
62
+ const doc = WebAdminJwks.parse(JSON.parse(buf.toString("utf8")));
63
63
  const next = new Map();
64
64
  for (const k of doc.keys) {
65
65
  try {
@@ -8,7 +8,7 @@
8
8
  * (verifyApprovalHmac / verifyPrincipalJwt) stay in ./approval-hmac.ts and ./principal-jwt.ts; consumers import these four names from HERE ([ref] 兼容面全清).
9
9
  */
10
10
  /** One key in the rotating HMAC key-set. `kid` lets the verifier pick the signing key (or fall back to trying the
11
- * whole set); `status` lets sema-registry rotate without breaking in-flight approvals: `active` = sign + verify,
11
+ * whole set); `status` lets web-admin rotate without breaking in-flight approvals: `active` = sign + verify,
12
12
  * `retiring` = verify-only (kept for the overlap window so a MAC signed with the old key still verifies). */
13
13
  export interface ApprovalHmacKey {
14
14
  kid: string;
@@ -36,7 +36,7 @@ export interface KeySetRejection {
36
36
  * 门数的 SHAPE B;这两条钥又都在凭据轴上,所以由**类型**逼每个调用点当场表态,而不是靠人记得去接。
37
37
  */
38
38
  export type OnKeySetRejection = (rejection: KeySetRejection) => void;
39
- /** Parse APPROVAL_HMAC_KEYS — a sema-registry-managed, rotating key-SET, as a JSON array of {kid,key,status}.
39
+ /** Parse APPROVAL_HMAC_KEYS — a web-admin-managed, rotating key-SET, as a JSON array of {kid,key,status}.
40
40
  * Empty / unset / unparseable ⇒ `[]` ⇒ HMAC verification is OFF (D-G inactive; back-compat, BFF-only door).
41
41
  * fail-closed 语义与改前**逐字相同**;新增的只有 `onReject`([ref]:每一条被丢弃的条目都要说出来)。 */
42
42
  export declare function parseApprovalHmacKeys(raw: string | undefined, onReject: OnKeySetRejection): ApprovalHmacKey[];
@@ -15,8 +15,9 @@
15
15
  *
16
16
  * 本模块按**server 侧可知的同三项**算一份「若此刻提交会不会武装」的裁决,供壳(cli `sema doctor permissions`)
17
17
  * 与人自查。三项分别对应三个未武装原因(判序 = 谓词的合取序,先判到的先报):
18
- * · `mode_not_auto` —— 本次意图不是 auto(`?permissionMode=` 查询串给的;缺席 = 按 auto 意图答),或意图经本部署的运维入口地板
19
- * (`AUTONOMY=plan`)钳过之后不是 auto —— 与受理门同一只钳,提交时那个词到不了引擎;
18
+ * · `mode_not_auto` —— 本次意图不是 auto(`?permissionMode=` 查询串给的;缺席 = 按 auto 意图答),且原样到得了引擎(本部署的入口地板没改它);
19
+ * · `operator_floor` —— 本部署的运维入口地板(`AUTONOMY=plan`)把本次意图改成了别的词、那个词不是 auto(`runtime-governance.ts`
20
+ * `entryPermissionMode` 的 `clamped`,与受理门同一只函数)—— 到得了引擎的词由运维定,出路在运维换档,不在请求的词;
20
21
  * · `deployment_incapable` —— 装配面没挂 `RunnerDeps.autoMode` 分类器席位(生产装配恒挂;桩/一次性 CLI 不挂);
21
22
  * · `org_denied` —— per-principal caps 的 `autoMode === false` 且本地 deny 未设(center 显式 deny、center
22
23
  * 硬失败的 fail-closed 拒项);
@@ -35,7 +36,8 @@
35
36
  * 规则集少一整支;**不再读任何 dist 文本**。
36
37
  *
37
38
  * ## 闭集纪律([ref])
38
- * 六词是 core [ref] seam ⑤ + [ref] PM 裁定的闭集;`AUTO_MODE_UNARMED_REASON_SEMANTICS` 是 `Record<Reason, string>` 锁步表——
39
+ * 七词:core [ref] seam ⑤ + [ref] PM 裁定的六词 + `operator_floor`(意图被运维入口地板改词;与 `local_denied` / `org_denied` 同理按「指路不同」拆出);
40
+ * `AUTO_MODE_UNARMED_REASON_SEMANTICS` 是 `Record<Reason, string>` 锁步表——
39
41
  * 词表加员而语义表不加、或反之,都是编译红。本面**不**给壳发 prose(机器码上 wire,人话归壳),语义表只
40
42
  * 服务于文档/测试对拍。
41
43
  *
@@ -76,12 +78,13 @@ export type ClassifierRoute = {
76
78
  readonly id: undefined;
77
79
  readonly fault: string;
78
80
  };
79
- /** core [ref] seam ⑤ 的未武装原因闭集(六词,[ref] 加 settings_denied;顺序 = 判序)。 */
80
- export declare const AUTO_MODE_UNARMED_REASONS: readonly ["mode_not_auto", "deployment_incapable", "org_denied", "local_denied", "settings_denied", "resolver_fault"];
81
+ /** 未武装原因闭集(七词:core [ref] seam ⑤ + [ref] settings_denied + 入口地板改词 operator_floor;顺序 = 判序)。 */
82
+ export declare const AUTO_MODE_UNARMED_REASONS: readonly ["mode_not_auto", "operator_floor", "deployment_incapable", "org_denied", "local_denied", "settings_denied", "resolver_fault"];
81
83
  export type AutoModeUnarmedReason = (typeof AUTO_MODE_UNARMED_REASONS)[number];
82
84
  /** 锁步表:词表与语义一一对应(加员/删员任一侧不同步 = tsc 红)。语义只供文档/测试,不上 wire。 */
83
85
  export declare const AUTO_MODE_UNARMED_REASON_SEMANTICS: {
84
- readonly mode_not_auto: "本次意图不是 auto(壳发的 permissionMode 不是 \"auto\"),或意图经本部署的运维入口地板(AUTONOMY=plan)钳过之后不是 auto —— 与受理门同一只钳,提交时那个词到不了引擎";
86
+ readonly mode_not_auto: "本次意图不是 auto(壳发的 permissionMode 不是 \"auto\"),且原样到得了引擎(本部署的运维入口地板没改它)—— 出路是请求 auto";
87
+ readonly operator_floor: "本部署的运维入口地板(AUTONOMY=plan)把本次意图改成了别的词、那个词不是 auto —— 与受理门同一只函数,提交时到得了引擎的词由运维定;出路是找运维换档,改请求的词到不了 auto";
85
88
  readonly deployment_incapable: "装配面没挂 RunnerDeps.autoMode 分类器席位(本部署/本进程形不具备分类器)";
86
89
  readonly org_denied: "per-principal caps.autoMode === false 且本地 deny 未设:center 显式 deny / center 硬失败 fail-closed 拒项";
87
90
  readonly local_denied: "本地 catalog 键 PERMISSIONS_DISABLE_AUTO_MODE=true(center/settings 键名 permissions.disableAutoMode)把 caps.autoMode 折成 false";
@@ -101,7 +104,7 @@ export interface AutoModeFaceDeps {
101
104
  /** 分类器**配置**的模型路由(server 侧按 core 的 role 回落序 `classifier → summarize → default` 从
102
105
  * `config.roles` 读到的 catalog 名)。这是「配置了什么」,不是「这次真用了什么」——core 的
103
106
  * `derivedRouteFallsBack` 可能在运行期回落到主模型;真值候 core 状态座。
104
- * 🔴 codex r3 [medium]:是 **getter** 不是快照——config-center 会原地热更新 `config.roles`(Runner 每任务从活引用
107
+ * 🔴 codex r3 [medium]:是 **getter** 不是快照——web-admin 会原地热更新 `config.roles`(Runner 每任务从活引用
105
108
  * 重解),boot 期铸的字符串会在热切换后永久陈旧;生产装配递的 getter 调 `classifierRouteFor({ models: config.models, roles: config.roles })` 并把 fault 记 debug。 */
106
109
  readonly classifierModel?: (() => string | undefined) | undefined;
107
110
  }
@@ -120,8 +123,9 @@ export type AutoModeVerdict = {
120
123
  * 调用方经门验证的身份(匿名 ⇒ undefined ⇒ center 客户端答 undefined,本地 deny 层照样罩)。
121
124
  *
122
125
  * 意图那一项判的是**提交之后到得了引擎的那个词**:本次意图先过本部署的运维入口地板(`floor`,调用方传 `runtime-governance.ts`
123
- * `autonomyModeFloor(<活 config 的 AUTONOMY>)` —— 与受理门盖章读同一只属主),钳法 = core `clampPermissionMode`(受理门 `stampEntryPermissionMode`
124
- * 用的同一只钳;地板缺席 ⇒ 原样)。`AUTONOMY=plan` 部署上任何意图都被钳成 `plan` ⇒ `mode_not_auto`(闭集词复用,不另铸)。
126
+ * `autonomyModeFloor(<活 config 的 AUTONOMY>)` —— 与受理门盖章读同一只属主),经 `entryPermissionMode`(受理门盖章调的同一只函数)。
127
+ * 到得了引擎的词不是 auto ⇒ 未武装,原因按「谁定了那个词」分:地板改了词(`clamped`)⇒ `operator_floor`;词原样 ⇒ `mode_not_auto`。
128
+ * `AUTONOMY=plan` 部署上意图缺席 / auto / 任何比 plan 松的词 ⇒ `operator_floor`;意图本身是 `plan` ⇒ `mode_not_auto`。
125
129
  *
126
130
  * 🔴 resolver 抛错**不吞**:合成腿的每一层都自带 fail-closed/缺席臂(center 客户端 catch-all、grant 腿 onFault),
127
131
  * 走到这里还在抛 = 装配缺陷,读面 500 比一句编出来的 reason 诚实。
@@ -1,5 +1,6 @@
1
- import { clampPermissionMode, classifierSeatModel } from "@sema-agent/core";
1
+ import { classifierSeatModel } from "@sema-agent/core";
2
2
  import { resolveMainModel } from "./model-select.js";
3
+ import { entryPermissionMode } from "./runtime-governance.js";
3
4
  export function classifierRouteFor(deps) {
4
5
  try {
5
6
  const main = resolveMainModel(deps);
@@ -9,9 +10,10 @@ export function classifierRouteFor(deps) {
9
10
  return { id: undefined, fault: err instanceof Error ? err.message : String(err) };
10
11
  }
11
12
  }
12
- export const AUTO_MODE_UNARMED_REASONS = ["mode_not_auto", "deployment_incapable", "org_denied", "local_denied", "settings_denied", "resolver_fault"];
13
+ export const AUTO_MODE_UNARMED_REASONS = ["mode_not_auto", "operator_floor", "deployment_incapable", "org_denied", "local_denied", "settings_denied", "resolver_fault"];
13
14
  export const AUTO_MODE_UNARMED_REASON_SEMANTICS = {
14
- mode_not_auto: "本次意图不是 auto(壳发的 permissionMode 不是 \"auto\"),或意图经本部署的运维入口地板(AUTONOMY=plan)钳过之后不是 auto —— 与受理门同一只钳,提交时那个词到不了引擎",
15
+ mode_not_auto: "本次意图不是 auto(壳发的 permissionMode 不是 \"auto\"),且原样到得了引擎(本部署的运维入口地板没改它)—— 出路是请求 auto",
16
+ operator_floor: "本部署的运维入口地板(AUTONOMY=plan)把本次意图改成了别的词、那个词不是 auto —— 与受理门同一只函数,提交时到得了引擎的词由运维定;出路是找运维换档,改请求的词到不了 auto",
15
17
  deployment_incapable: "装配面没挂 RunnerDeps.autoMode 分类器席位(本部署/本进程形不具备分类器)",
16
18
  org_denied: "per-principal caps.autoMode === false 且本地 deny 未设:center 显式 deny / center 硬失败 fail-closed 拒项",
17
19
  local_denied: "本地 catalog 键 PERMISSIONS_DISABLE_AUTO_MODE=true(center/settings 键名 permissions.disableAutoMode)把 caps.autoMode 折成 false",
@@ -21,10 +23,9 @@ export const AUTO_MODE_UNARMED_REASON_SEMANTICS = {
21
23
  export async function judgeAutoModeArming(face, input) {
22
24
  const route = face?.seatMounted ? face.classifierModel?.() : undefined;
23
25
  const model = route !== undefined ? { model: route } : {};
24
- const intent = input.requestedMode ?? "auto";
25
- const entry = input.floor === undefined ? intent : clampPermissionMode(intent, input.floor).effective;
26
- if (entry !== "auto")
27
- return { armed: false, reason: "mode_not_auto", ...model };
26
+ const entry = entryPermissionMode(input.requestedMode ?? "auto", input.floor);
27
+ if (entry.effective !== "auto")
28
+ return { armed: false, reason: entry.clamped ? "operator_floor" : "mode_not_auto", ...model };
28
29
  if (face === undefined || !face.seatMounted)
29
30
  return { armed: false, reason: "deployment_incapable" };
30
31
  let caps;
@@ -2,7 +2,7 @@ import { createBrainAssembly } from "../brain.js";
2
2
  import { ModelUsageTracker, PromptManifestTracker, buildPricing, createSideQueryAccountant, createTracer } from "../budget.js";
3
3
  import { FleetUsageAccumulator } from "../fleet-client.js";
4
4
  import { createFleetLeaseFromEnv } from "../fleet-lease.js";
5
- import { centerLaneConfigured } from "../config-center/center-request.js";
5
+ import { centerLaneConfigured } from "../web-admin-client/center-request.js";
6
6
  import { CostQuota } from "../observability/cost-quota.js";
7
7
  import { buildQuotaBounds } from "./limit-sync.js";
8
8
  import { assembleFileHistory } from "../file-history-capture.js";
@@ -209,6 +209,7 @@ export function createExecutionEnv(ctx) {
209
209
  const hostScheduler = facts.hostScheduler(config).available
210
210
  ? new FileSchedulerBackend({
211
211
  storePath: schedulerStorePath,
212
+ log: logger,
212
213
  ...(config.schedulerSessionWakeup === false || config.schedulerSessionLifetime === false
213
214
  ? {
214
215
  caps: {
@@ -37,7 +37,7 @@ export interface LeaderCtx {
37
37
  /** [ref]([ref],[ref]-T1)—— 治理窗**账本店**(与 `config.usageWindows` 声明成对;声明直接从
38
38
  * 本 ctx 的 config 取,leader 不另读)。缺席 = 未配治理窗的部署。必填键,理由同 `tracer`。 */
39
39
  usageWindowStore: RunnerDeps["usageWindowStore"];
40
- /** [ref]([ref])—— center 发布的 prompt catalog(`configCenter.promptSource`,与主 runner/subRunner
40
+ /** [ref]([ref])—— center 发布的 prompt catalog(`webAdmin.promptSource`,与主 runner/subRunner
41
41
  * 同一只)。缺席 ⇒ leader 的四类顶层任务跑引擎内置提示词,而同部署其余三条腿跑运维发布的那一份,
42
42
  * 且 core 顶层新任务是**静默**落回(无 notice)。必填键,理由同 `tracer`。 */
43
43
  promptSource: RunnerDeps["promptSource"];
@@ -1,4 +1,4 @@
1
- import type { RestartSliceCtx } from "../config-center/restart-signal.js";
1
+ import type { RestartSliceCtx } from "../web-admin-client/restart-signal.js";
2
2
  import type { MemoryConsolidationDriverConfig, ServiceConfig } from "../config-types.js";
3
3
  import { type ConsolidationDriverRunRow, type ConsolidationRunReceipt, type MemoryBackend, type MemoryConsolidationDriverDeps, type RunMemoryConsolidationOptions, type SessionCaptureRecordStore } from "@sema-agent/core";
4
4
  /** D3 投影的座标签闭集。`role:<name>` 里的 name 只可能是 core 的 role 链两跳之一。 */
@@ -178,14 +178,14 @@ export declare function consolidationDriverUnwirable(input: ConsolidationWiringF
178
178
  * ({@link seatLabel} 注里同一条理由:抄一份就是第二真源,而 `ROLE_TIER_DEFAULTS` 的 flash 缺省会让手抄版答错)。
179
179
  *
180
180
  * 为什么不按 env `MODEL_CHEAP_ID` 的拼写判:它只是供座的一条路。env 角色表在它缺席时把 summarize 指回
181
- * `default`(`config.ts` 的 `cheapRef`),而目录(`config.d/models.json` / 配置中心)的 roles / 档位同样能供
181
+ * `default`(`config.ts` 的 `cheapRef`),而目录(`config.d/models.json` / web-admin)的 roles / 档位同样能供
182
182
  * consolidate / summarize 两跳 —— 判「装配后的座落不落主模型」才与计费事实同形(整理跑按座的模型计费)。
183
183
  *
184
184
  * 主模型 = 本仓给每条 task 铸的 `DEFAULT_MODEL_REF` 解到的那只(`boot/resolve-spec.ts` 每条 spec 都盖 `spec.model`),
185
185
  * **不是** core 的 `default` 角色链 —— 与 `auto-mode-face.ts` 的 `classifierRouteFor` 同一口径(共用 `model-select.ts`
186
186
  * `resolveMainModel`);喂**展开**目录,与引擎构造期 `expandTiers` 之后再解逐字同源。比的是**目录条目身份**(对象引用),
187
187
  * **不比 `Model.id` 串**(车PI 修复轮 ⑤ / codex C-2:两条不同名的条目可以共享上游 id 却各带不同的 baseUrl / 凭据 / 价,那是两只
188
- * 模型;与 `model-select.ts` `isModelAllowlisted` 同一口径)。env 的「cheap id == 主 id」不会走到这里变成两只:`config.ts` 在铸造处
188
+ * 模型;与 `model-select.ts` `isAtMentionable` 同一口径)。env 的「cheap id == 主 id」不会走到这里变成两只:`config.ts` 在铸造处
189
189
  * 就不铸那只影子条目(车PI 验修轮 B)。
190
190
  * 探针 brain 零请求:座解析只 `brainToRuntime` 它一次,真被调用 = 装配缺陷,响亮抛。
191
191
  * ⚠️ **爆炸半径**(车PI 验修轮 F10,如实登记):判决的每一臂 —— 包括未设 + 没配便宜模型的派生关(TOC 最常见的形)—— 都走
@@ -212,7 +212,7 @@ export declare function consolidationSeatBillingOf(plane: ConsolidationSeatPlane
212
212
  * 拒因说清「为什么没开」。在 `loadConfig` 判会把「未设 + scope + 便宜模型在场」这台本该派生成开的部署当场拒掉。
213
213
  *
214
214
  * ⚠️ **起服判一次**(restart-to-apply):判决落在 boot 第 4 段的装配点 {@link createConsolidationValve} —— 目录已应用
215
- * (`config.d/models.json` / 配置中心的 boot 采纳或 LKG)、记忆引擎已接线;座解析在第 6 段读这份判决。之后中心热改了 roles / 档位(或 boot 拉取超窗、目录迟到),**阀门不跟着翻**,
215
+ * (`config.d/models.json` / web-admin 的 boot 采纳或 LKG)、记忆引擎已接线;座解析在第 6 段读这份判决。之后中心热改了 roles / 档位(或 boot 拉取超窗、目录迟到),**阀门不跟着翻**,
216
216
  * 但翻的**需要**由 `memory-consolidation` 重启片报出来({@link createConsolidationValveWatch}):开着的那台盯座位漂移;
217
217
  * 派生关的那台盯「此刻重判会不会开」(codex 车内复审 F2:修前派生关没有任何读数,热加一只便宜模型零信号、阀门永远关着)。
218
218
  */
@@ -3,7 +3,7 @@
3
3
  * 的两个 seam(`RunnerDeps.memoryScopeAdmission` / `RunnerDeps.deploymentMemoryScopes`)。
4
4
  *
5
5
  * 目录源三态(单选,授权面不做双源合并):
6
- * · center 在场(configCenter 且非 dryRun)⇒ 远程腿:per-principal caps 响应的 `orgMemory` 段
6
+ * · center 在场(webAdmin 且非 dryRun)⇒ 远程腿:per-principal caps 响应的 `orgMemory` 段
7
7
  * (走 `fetchPrincipalOrgMemory` —— 与 caps 腿同一条 HTTP 请求形与同一道 principal 回声核,但**只
8
8
  * 投影 org 段**读,治理面值漂移不连坐;段键缺席=旧 center 能力握手 ⇒ 目录记 section_absent 瞬时)。
9
9
  * **独立 fetch,不复用 caps 缓存条目**(C3:org 授权段自带判别联合缓存,两张表的失败域互不干扰
@@ -17,7 +17,7 @@
17
17
  *
18
18
  * 能力探测(C12,fail-loud):多租户(requirePrincipal)部署 **且记忆面真点亮**(MEMORY_ENGINE 开 +
19
19
  * backend 非 file——见下方 `memoryPlaneLive` 注)的 projects 登记簿里挂了 org 键 ——这些键在多租户下
20
- * 按 request-origin 盖章(N2 部署形态维)——而目录源缺席(含 configCenter dryRun 形)⇒ 启动报错:
20
+ * 按 request-origin 盖章(N2 部署形态维)——而目录源缺席(含 webAdmin dryRun 形)⇒ 启动报错:
21
21
  * 该部署的每个 projectId 请求都会在 prepare 期被整拒,「audit 在跑但恒拒」不是可运行状态,响亮拒
22
22
  * 启动比静默全拒服务诚实(clay 三裁 [ref]:直接 BREAKING,不留兼容臂)。记忆面 dark 的部署里这些
23
23
  * 键根本到不了准入门,不在探测范围(复审 D-1)。
@@ -46,7 +46,7 @@ export interface OrgMemoryAdmissionWiring {
46
46
  *
47
47
  * 为什么这个消费点必须活取而上面那个可以不:共享记忆读面对 principal-less 请求**直接**把这组 scope
48
48
  * 当作全部授权事实交出去(没有第二道盖章腿能纠正它)⇒ 快照在新增方向让新登记的 org 库变成终局式
49
- * 空集、在撤销方向让已下架的 scope 继续被放行(fail-open),而 `config.projects` 恰恰是 config-center
49
+ * 空集、在撤销方向让已下架的 scope 继续被放行(fail-open),而 `config.projects` 恰恰是 web-admin
50
50
  * 标注「🟢 热生效」的字段、且 env 腿恒空(只可能由 center 灌)。判据本体与快照同源(同一个
51
51
  * `collectDeploymentOrgScopes`),差别只有取值时机。
52
52
  */
@@ -1,4 +1,4 @@
1
- import { fetchPrincipalOrgMemory } from "../config-center/http-client.js";
1
+ import { fetchPrincipalOrgMemory } from "../web-admin-client/http-client.js";
2
2
  import { createIdentityBins } from "../center-credential.js";
3
3
  import { createMemoryScopeAdmission, createOrgMemoryDirectory, parseOrgDirectoryStatic } from "../org-memory-admission.js";
4
4
  const ORG_PREFIX = "org:";
@@ -18,11 +18,11 @@ function collectDeploymentOrgScopes(config) {
18
18
  export function createOrgMemoryAdmissionWiring(opts) {
19
19
  const { config, logger, metrics } = opts;
20
20
  const deploymentMemoryScopes = collectDeploymentOrgScopes(config);
21
- const centerLeg = config.configCenter !== undefined && !config.configCenter.dryRun ? config.configCenter : undefined;
21
+ const centerLeg = config.webAdmin !== undefined && !config.webAdmin.dryRun ? config.webAdmin : undefined;
22
22
  const staticJson = config.memoryOrgDirectoryJson;
23
23
  if (centerLeg !== undefined && staticJson !== undefined) {
24
24
  logger.warn("org_memory_directory_env_ignored", {
25
- reason: "MEMORY_ORG_DIRECTORY_JSON is set but a config-center is wired — the center directory wins; the env table is IGNORED (authorization faces never merge two sources)",
25
+ reason: "MEMORY_ORG_DIRECTORY_JSON is set but a web-admin is wired — the center directory wins; the env table is IGNORED (authorization faces never merge two sources)",
26
26
  });
27
27
  }
28
28
  const directory = centerLeg !== undefined
@@ -48,8 +48,8 @@ export function createOrgMemoryAdmissionWiring(opts) {
48
48
  .map(([id]) => id);
49
49
  if (orgProjects.length > 0) {
50
50
  throw new Error(`multi-tenant deployment has org: keys in projects[${orgProjects.join(", ")}].defaultScopes but NO org-memory directory source ` +
51
- `(config-center absent/dry-run and MEMORY_ORG_DIRECTORY_JSON unset) — every request selecting these projects would be refused at prepare ` +
52
- `(memory.admission_required, fail-closed). Wire a config-center or set MEMORY_ORG_DIRECTORY_JSON, or remove the org keys.`);
51
+ `(web-admin absent/dry-run and MEMORY_ORG_DIRECTORY_JSON unset) — every request selecting these projects would be refused at prepare ` +
52
+ `(memory.admission_required, fail-closed). Wire a web-admin or set MEMORY_ORG_DIRECTORY_JSON, or remove the org keys.`);
53
53
  }
54
54
  }
55
55
  const memoryScopeAdmission = directory !== undefined
@@ -17,7 +17,7 @@ import { composeHooks, createTaskHooks } from "../hooks/hook-runner.js";
17
17
  import { HOST_POSTURE_REFUSED_CODE, taskInheritEnvRefusal, taskWriteFaceRefusal } from "../hosted-posture.js";
18
18
  import { headerStr } from "../http/principal-gate.js";
19
19
  import { explicitOperatorOk } from "../http/server.js";
20
- import { isModelAllowlisted, matchCatalogModel, modelSupportsImages, refusedCatalogEntry, resolveTaskModel, selectableCatalog, terminalCatalogName } from "../model-select.js";
20
+ import { isAtMentionable, matchCatalogModel, modelSupportsImages, refusedCatalogEntry, resolveTaskModel, selectableCatalog, terminalCatalogName } from "../model-select.js";
21
21
  import { modelUnavailableMessage } from "../model-entry-refusal.js";
22
22
  import { PerTaskImageRegistry, resolveSandboxImageRef } from "../per-task-image.js";
23
23
  import { isRemoteScratchpadLane, remoteScratchpadDirFor } from "../plugins/remote-scratchpad.js";
@@ -30,7 +30,7 @@ import { applyRuntimeGovernance } from "../runtime-governance.js";
30
30
  import { HttpError, createCodedHttpError, encodeCheckpointScope } from "../security.js";
31
31
  import { memoryProjectKeyFor, memorySpecForRequest } from "../memory-scope.js";
32
32
  import { inheritEnvFieldIssue, singleMemberOffFieldIssue } from "../request-value-closure.js";
33
- import { a2aForScenario, mcpForScenario } from "../config-center/facade.js";
33
+ import { a2aForScenario, mcpForScenario } from "../web-admin-client/facade.js";
34
34
  import { normalizeAttachments, normalizeResilience, normalizeResumeAtMode, normalizeSuggestNextPrompts, promptProfileFromBody, resolveTaskLimits, retainBackgroundProcessesFromBody, taskAgentsSpecFragment, toolMaterializeStrategyFromBody, toolNameListFromBody } from "../spec-fields.js";
35
35
  import { cwdHonored, deviceCwdHonored, effectiveHostWorkspace, inProcessSingleUserLane, isValidCwd, parseAdditionalDirectories, satisfiedByProcessCwd, shellEnvMismatchCount } from "../task-cwd.js";
36
36
  import { assertRequestA2aUnlocked, resolveRequestA2a } from "../task-a2a.js";
@@ -259,7 +259,7 @@ export function createResolveSpec(ctx) {
259
259
  logger.warn("task_additional_read_directories_ignored", { honored: false, sessionId: auth?.sessionId ?? null });
260
260
  }
261
261
  const wireCatalog = selectableCatalog(config.models, config.tiers, config.modelRefusals);
262
- const picked = resolveTaskModel(body.model ?? parsedSettings.settings?.model, objective, wireCatalog, config.atModelAllowlist, config.modelRefusals);
262
+ const picked = resolveTaskModel(body.model ?? parsedSettings.settings?.model, objective, wireCatalog, config.atMention, config.modelRefusals);
263
263
  if (picked.unavailable !== undefined) {
264
264
  const { requested, name, refusal, source } = picked.unavailable;
265
265
  if (opts?.leg === "fresh") {
@@ -271,7 +271,7 @@ export function createResolveSpec(ctx) {
271
271
  if (picked.notAllowed !== undefined) {
272
272
  const { requested, resolved, source } = picked.notAllowed;
273
273
  if (opts?.leg === "fresh") {
274
- throw new HttpError(400, `model "${requested.slice(0, 120)}" is not in this deployment's @-mention allowlist (it resolves to catalog model "${resolved}") — the allowlist is configured by the operator (config-center models.atModelAllowlist)`, { code: "request.model_not_allowed" });
274
+ throw new HttpError(400, `model "${requested.slice(0, 120)}" is not @-mentionable on this deployment (it resolves to catalog model "${resolved}") — which models can be @-mentioned is configured by the operator (models.atMention)`, { code: "request.model_not_allowed" });
275
275
  }
276
276
  metrics.inc("task_model_not_allowlisted_resume_total");
277
277
  logger.warn("task_model_not_allowlisted_resume", { requested: requested.slice(0, 120), resolved, source, sessionId: auth?.sessionId ?? null, note: "resumed leg keeps running the model it was started on — the allowlist gates fresh picks only" });
@@ -395,10 +395,10 @@ export function createResolveSpec(ctx) {
395
395
  logger.warn("compaction_model_unknown_fallback", { requested: body.compactionModel.slice(0, 120), sessionId: auth?.sessionId ?? null });
396
396
  return {};
397
397
  }
398
- if (!isModelAllowlisted(cm, wireCatalog, config.atModelAllowlist, config.modelRefusals)) {
398
+ if (!isAtMentionable(cm, wireCatalog, config.atMention, config.modelRefusals)) {
399
399
  const terminal = terminalCatalogName(cm, wireCatalog, config.modelRefusals) ?? cm;
400
400
  if (opts?.leg === "fresh") {
401
- throw new HttpError(400, `compactionModel "${body.compactionModel.slice(0, 120)}" is not in this deployment's @-mention allowlist (it resolves to catalog model "${terminal}") — the allowlist is configured by the operator (config-center models.atModelAllowlist)`, { code: "request.model_not_allowed" });
401
+ throw new HttpError(400, `compactionModel "${body.compactionModel.slice(0, 120)}" is not @-mentionable on this deployment (it resolves to catalog model "${terminal}") — which models can be @-mentioned is configured by the operator (models.atMention)`, { code: "request.model_not_allowed" });
402
402
  }
403
403
  metrics.inc("task_model_not_allowlisted_resume_total");
404
404
  logger.warn("task_model_not_allowlisted_resume", { requested: body.compactionModel.slice(0, 120), resolved: terminal, source: "compaction", sessionId: auth?.sessionId ?? null, note: "resumed leg keeps the compaction model it was started with — the allowlist gates fresh picks only" });
@@ -622,7 +622,7 @@ export function createResolveSpec(ctx) {
622
622
  throw new HttpError(400, "sandboxImageProfile is only supported on the k8s sandbox backend");
623
623
  }
624
624
  if (!imageIndex) {
625
- throw new HttpError(400, "sandboxImageProfile requires the image index (config-center backend not configured)");
625
+ throw new HttpError(400, "sandboxImageProfile requires the image index (web-admin backend not configured)");
626
626
  }
627
627
  if (!auth?.sessionId) {
628
628
  throw new HttpError(400, "sandboxImageProfile requires a resolved session");
@@ -204,7 +204,7 @@ export interface RunnerDepsCtx {
204
204
  permissionRuleStore: RunnerDeps["permissionRuleStore"];
205
205
  /** [ref](core 5.50 [ref]):mid-turn MCP 撤销台账席 —— core 每次 MCP dispatch 前同步探
206
206
  * `isRevoked(serverName)`,被撤服务器的调用结算为 coded 拒绝 `mcp.server_revoked`(known-not-executed)。
207
- * 来源=configCenter.takeMcpRevocations()(取走即声明接线,restart 豁免与承接绑同一动作)。
207
+ * 来源=webAdmin.takeMcpRevocations()(取走即声明接线,restart 豁免与承接绑同一动作)。
208
208
  * 缺席=undefined=pre-338 语义(纯 env 部署无中心撤销面)。 */
209
209
  mcpRevocations: RunnerDeps["mcpRevocations"];
210
210
  /**
@@ -23,7 +23,7 @@ export interface RuntimeCapsCtx {
23
23
  *
24
24
  * governed 的语义是「per-principal verdict **必答**」:core 对 verdict 缺席一律**拒跑**(fail-closed,部署显式
25
25
  * 选的方向)。verdict 源**两条**(析取,[ref] 起):①SQL 后端上的 `memory_optout_grant` 表(三层折叠后
26
- * 恒答显式 boolean),②非 dry-run 的 config center 发 `EntitlementRuntimeCaps.allowMemoryOptOut`。
26
+ * 恒答显式 boolean),②非 dry-run 的 web-admin 发 `EntitlementRuntimeCaps.allowMemoryOptOut`。
27
27
  * governed 而两源皆无 ⇒ 每一个 `capture:"off"` 声明都被 core 以
28
28
  * `memory.capture_optout_denied` 拒掉,而运维看到的只是一台「启动成功、opt-out 全拒」的机器 —— 正是
29
29
  * 「阀门开着而配不出来 ⇒ 悄悄读成别的」那一形。所以在**启动期**点名:接 SQL 后端(表随中央
@@ -1,6 +1,6 @@
1
1
  import { applyGovernedVerdictAbsenceWarning, applyLocalAutoModeDeny, applyMemoryOptOutGrant, applyObserverEnvOptIn, centerEntitlementSourceWired, createPrincipalEntitlementsClient, } from "../runtime-caps-resolver.js";
2
2
  import { scopedTokenNeedsWorker } from "../center-credential.js";
3
- import { CENTER_CREDENTIAL_ENV } from "@sema-agent/settings-schema";
3
+ import { WEB_ADMIN_ENV } from "@sema-agent/settings-schema";
4
4
  export function assertMemoryCapturePolicyWirable(input) {
5
5
  if (input.policy !== "governed")
6
6
  return;
@@ -13,9 +13,9 @@ export function assertMemoryCapturePolicyWirable(input) {
13
13
  `own contract), so a governed worker without a source would refuse every \`memory.capture:"off"\` declaration and the ` +
14
14
  `refusal would read as an entitlement denial rather than the misconfiguration it is. This version has TWO verdict sources ` +
15
15
  `— wire either one: (1) the \`memory_optout_grant\` table on a SQL store backend (DB_BACKEND=mysql|pg; the table is ` +
16
- `created by the central ensureSchema and administered through /v1/admin/memory-optout), or (2) a config center that ` +
17
- `EMITS \`allowMemoryOptOut\` in each principal's entitlement caps (SEMA_REGISTRY_URL + ${CENTER_CREDENTIAL_ENV.token}, ` +
18
- `SEMA_REGISTRY_DRY_RUN off — dry-run observes without applying, so it is not a source; and note the key is OPTIONAL in ` +
16
+ `created by the central ensureSchema and administered through /v1/admin/memory-optout), or (2) a web-admin that ` +
17
+ `EMITS \`allowMemoryOptOut\` in each principal's entitlement caps (${WEB_ADMIN_ENV.url} + ${WEB_ADMIN_ENV.token}, ` +
18
+ `${WEB_ADMIN_ENV.dryRun} off — dry-run observes without applying, so it is not a source; and note the key is OPTIONAL in ` +
19
19
  `the entitlement schema: a center that never emits it leaves every verdict absent, i.e. every opt-out still refused). ` +
20
20
  `Or set MEMORY_CAPTURE_POLICY=open (opt-outs take effect; only an explicit per-principal false denies) or ` +
21
21
  `MEMORY_CAPTURE_POLICY=capture-required (every opt-out declaration refused, no source consulted).`);
@@ -35,18 +35,18 @@ export function createRuntimeCaps(ctx) {
35
35
  const governedCenterOnlySource = config.memoryCapturePolicy === "governed" && !grantSourceWired && centerEntitlementSourceWired(config);
36
36
  if (governedCenterOnlySource) {
37
37
  logger.warn("memory_capture_governed_center_only_source", {
38
- reason: "MEMORY_CAPTURE_POLICY=governed with NO local memory_optout_grant table: the only verdict source is the config center, and `allowMemoryOptOut` is an OPTIONAL entitlement key — for any principal whose caps omit it the verdict is ABSENT and core refuses that session's memory.capture:\"off\" (memory.capture_optout_denied, fail-closed). ANONYMOUS/system runs are worse off still: the center source is per-principal and is never consulted without an identity, so on this shape a principal-less run can never obtain a verdict at all. Verify the center emits allowMemoryOptOut for every principal, or wire a SQL backend (DB_BACKEND=mysql|pg) so the grant table answers (its deployment-default row also covers anonymous runs).",
38
+ reason: "MEMORY_CAPTURE_POLICY=governed with NO local memory_optout_grant table: the only verdict source is the web-admin, and `allowMemoryOptOut` is an OPTIONAL entitlement key — for any principal whose caps omit it the verdict is ABSENT and core refuses that session's memory.capture:\"off\" (memory.capture_optout_denied, fail-closed). ANONYMOUS/system runs are worse off still: the center source is per-principal and is never consulted without an identity, so on this shape a principal-less run can never obtain a verdict at all. Verify the center emits allowMemoryOptOut for every principal, or wire a SQL backend (DB_BACKEND=mysql|pg) so the grant table answers (its deployment-default row also covers anonymous runs).",
39
39
  });
40
40
  }
41
- if (centerEntitlementSourceWired(config) && config.configCenter && scopedTokenNeedsWorker(config.configCenter.credential.read(), config.configCenter.worker)) {
41
+ if (centerEntitlementSourceWired(config) && config.webAdmin && scopedTokenNeedsWorker(config.webAdmin.credential.read(), config.webAdmin.worker)) {
42
42
  logger.warn("runtime_caps_scoped_token_no_worker", {
43
- reason: `${CENTER_CREDENTIAL_ENV.token} is a worker-scoped wpt_ token but SEMA_REGISTRY_WORKER is unset → center 403s per-principal caps → ALL workflow self-orchestration will be fail-closed denied. Set SEMA_REGISTRY_WORKER (the orchestrator normally injects it) or use the full SERVICE_PULL_TOKEN.`,
43
+ reason: `${WEB_ADMIN_ENV.token} is a worker-scoped wpt_ token but ${WEB_ADMIN_ENV.worker} is unset → web-admin 403s per-principal caps → ALL workflow self-orchestration will be fail-closed denied. Set ${WEB_ADMIN_ENV.worker} (the orchestrator normally injects it) or use the full SERVICE_PULL_TOKEN.`,
44
44
  });
45
45
  }
46
- const principalCaps = centerEntitlementSourceWired(config) && config.configCenter
46
+ const principalCaps = centerEntitlementSourceWired(config) && config.webAdmin
47
47
  ? createPrincipalEntitlementsClient({
48
- center: config.configCenter,
49
- ...(config.configCenter.worker ? { worker: config.configCenter.worker } : {}),
48
+ center: config.webAdmin,
49
+ ...(config.webAdmin.worker ? { worker: config.webAdmin.worker } : {}),
50
50
  onError: (err, principal) => logger.warn("runtime_caps_resolve_failed", { principal, err: String(err) }),
51
51
  })
52
52
  : undefined;
@@ -79,9 +79,9 @@ export interface ShutdownCtx {
79
79
  * HTTP 层不能自作主张。所以 `drainState.draining` 翻真的那一刻,这里同步调 `beginDrain()`。
80
80
  */
81
81
  deviceHub: import("../device-ws-hub.js").DeviceWsHub | undefined;
82
- /** [ref]-2:config 60s 刷新环(config-center startRefreshLoop)——不停的话停机中途还可能热应用
82
+ /** [ref]-2:config 60s 刷新环(web-admin startRefreshLoop)——不停的话停机中途还可能热应用
83
83
  * 一份新配置。缺席 = 纯 env 部署没起环。 */
84
- configCenter: {
84
+ webAdmin: {
85
85
  stopRefreshLoop(): void;
86
86
  } | undefined;
87
87
  /** S-929:活体审批协调器(`TOOL_APPROVAL_ENABLED` 关 ⇒ 缺席)。hardShutdown 起点调它的 `drainForShutdown`:本进程握着的活卡
@@ -17,7 +17,7 @@ export function backgroundGraceRemainingMs(a) {
17
17
  return Math.max(0, Math.min(a.softStoppedAt + a.graceMs, a.deadlineMs) - a.now);
18
18
  }
19
19
  export function installShutdownHandlers(ctx) {
20
- const { config, logger, server, reaper, fleetReconcile, retentionLane, releaseRetentionLease, otelExporter, breakerState, costQuota, rateLimiter, runner, subRunner, lspManager, workflowNotifyJournal, fleetClient, backend, drainState, storeLiveProbe, configCenter, version, deviceHub, toolApproval, parkCommits, servingLease, } = ctx;
20
+ const { config, logger, server, reaper, fleetReconcile, retentionLane, releaseRetentionLease, otelExporter, breakerState, costQuota, rateLimiter, runner, subRunner, lspManager, workflowNotifyJournal, fleetClient, backend, drainState, storeLiveProbe, webAdmin, version, deviceHub, toolApproval, parkCommits, servingLease, } = ctx;
21
21
  const dataRoot = config.localDataRoot;
22
22
  if (dataRoot) {
23
23
  const prior = readCrashLast(dataRoot);
@@ -107,7 +107,7 @@ export function installShutdownHandlers(ctx) {
107
107
  storeLiveProbe?.stop();
108
108
  servingLease?.stop();
109
109
  void deviceHub?.close().catch((err) => logger.warn("device_hub_close_failed", { err: String(err) }));
110
- configCenter?.stopRefreshLoop();
110
+ webAdmin?.stopRefreshLoop();
111
111
  otelExporter?.stop();
112
112
  breakerState?.stop();
113
113
  runner.sessions.dispose();