@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
@@ -18,6 +18,7 @@ import { buildApprovalPreamble, buildApprovalPreambleSseFrames, readClosedWordSe
18
18
  import { heldAskOf, liveSettledBy, readDecidedBy, retiredDecisionKeyFacts, DECIDED_BY_NOT_IN_PROOF, DECIDED_BY_OUTSIDE_CLOSED_SET, POLICY_CANNOT_ALLOW_PERSON_ASK } from "../../host-decision.js";
19
19
  import { ASK_DECISION_CONSUMER_ABSENT, outcomeOfDecidedRow, resolveStreamApprovalGate } from "../../tool-approval.js";
20
20
  import { MAX_DECISION_NOTE_CHARS } from "../../approval-ask-machine.js";
21
+ import { causeOfAskRow } from "../../approval-deny-reasons.js";
21
22
  import { normalizeRunEventType, screenedStoredEventData } from "../../trace/project.js";
22
23
  import { sendJson, sendError, httpErrorCode, sseHeaders } from "../send.js";
23
24
  import { readTurnActivityMs } from "../../turn-activity.js";
@@ -34,6 +35,7 @@ import { RUN_NOT_FOUND_MESSAGE, runNotFoundMessage } from "../route-ctx.js";
34
35
  import { withPrincipal } from "../../observability/principal-context.js";
35
36
  import { readResumeCtx } from "../resume-ctx-read.js";
36
37
  import { storedBodyReplayAnswer, storedBodyReplayLogFields } from "../checkpoint-ctx.js";
38
+ import { serviceVersion } from "../../service-version.js";
37
39
  import { storedBodyReplayRefusal } from "../stored-body-replay.js";
38
40
  const STEER_PRIORITY_WORDS = INJECTION_TIERS.map((tier) => `'${tier}'`);
39
41
  const STEER_PRIORITY_UNION = STEER_PRIORITY_WORDS.join(" | ");
@@ -709,7 +711,7 @@ export async function handleRuns(req, res, match, ctx) {
709
711
  }
710
712
  if (mintResult.unservable !== undefined) {
711
713
  deps.logger?.warn?.("steer_wake_park_refused_stored_body", { taskId, sessionId: run.sessionId, ...storedBodyReplayLogFields(mintResult.unservable) });
712
- const { status, body: { error, errorCode, ...rest } } = storedBodyReplayAnswer(mintResult.unservable);
714
+ const { status, body: { error, errorCode, ...rest } } = storedBodyReplayAnswer(mintResult.unservable, serviceVersion());
713
715
  sendError(res, status, errorCode, error, rest);
714
716
  return;
715
717
  }
@@ -1485,12 +1487,14 @@ export async function handleRunVerbs(req, res, match, ctx) {
1485
1487
  });
1486
1488
  return;
1487
1489
  case "DENIED":
1488
- case "VOID":
1489
- sendError(res, 410, "gone.ask", "this ask reached a terminal state without a human decision (deniedReason says why: a routing failure, a cancellation or batch abort, or the process that held it ended) and can no longer be decided", {
1490
+ case "VOID": {
1491
+ const rowCause = causeOfAskRow(row);
1492
+ sendError(res, 410, "gone.ask", "this ask reached a terminal state without a human decision (cause says why: a routing failure, a cancellation or batch withdrawal or abort, or the process that held it ended) and can no longer be decided", {
1490
1493
  state: row.state,
1491
- ...(row.deniedReason !== null ? { deniedReason: row.deniedReason } : {}),
1494
+ ...(rowCause?.kind === "ending" ? { cause: rowCause.cause } : {}),
1492
1495
  });
1493
1496
  return;
1497
+ }
1494
1498
  case "PARKING":
1495
1499
  res.setHeader("retry-after", String(ASK_PARKING_RETRY_AFTER_SEC));
1496
1500
  sendError(res, 425, "parking.ask_retry", "this ask is mid-park — retrying tells you where it finally landed; a retry does NOT queue this decision for acceptance", {
@@ -127,7 +127,8 @@ async function handleSessionList(res, lister, query, forceOwner, includeUnowned
127
127
  const nextCursor = hasMore && last ? encodeSessionCursor({ lastActivityAt: last.lastActivityAt, sessionId: last.sessionId }, f) : undefined;
128
128
  const sessions = page.map((r) => {
129
129
  const tempo = sessionTempoOfRunStatus(r.lastStatus);
130
- return tempo === undefined ? r : { ...r, tempo };
130
+ const row = r.objectivePreview === "" ? { ...r, objectivePreview: null } : r;
131
+ return tempo === undefined ? row : { ...row, tempo };
131
132
  });
132
133
  sendJson(res, 200, { sessions, ...(nextCursor ? { nextCursor } : {}) });
133
134
  }
@@ -1,5 +1,5 @@
1
1
  import { SessionError, materializeA2aTools, materializeMcpTools, sanitizePathComponent } from "@sema-agent/core";
2
- import { a2aForScenario, mcpForScenario } from "../../config-center/facade.js";
2
+ import { a2aForScenario, mcpForScenario } from "../../web-admin-client/facade.js";
3
3
  import { isUuidV7, isUuidShape, legacyUnownedSessionOk } from "../../security.js";
4
4
  import { windowMessages, truncateMessageBlobs, redactSessionViewForRead } from "../../audit.js";
5
5
  import { redactSecrets } from "../../trace/redact.js";
@@ -794,15 +794,12 @@ export async function handleSessions(req, res, match, ctx) {
794
794
  case "not-an-object":
795
795
  sendError(res, 400, "request.body_shape", describeSessionPermissionRulesProblem(read.problem));
796
796
  return;
797
- case "field-not-string-array":
797
+ case "field-not-rule-list":
798
798
  sendError(res, 400, "request.field_invalid", describeSessionPermissionRulesProblem(read.problem));
799
799
  return;
800
800
  case "legacy-tool-name":
801
801
  sendError(res, 400, "rules.legacy_tool_name", describeSessionPermissionRulesProblem(read.problem), { ...read.problem.refusal });
802
802
  return;
803
- case "unreachable-tool-name":
804
- sendError(res, 400, "request.field_invalid", describeSessionPermissionRulesProblem(read.problem));
805
- return;
806
803
  default: {
807
804
  const unhandled = read.problem;
808
805
  throw new Error(`unhandled SessionPermissionRules problem: ${JSON.stringify(unhandled)}`);
@@ -1,6 +1,6 @@
1
1
  import { expandTiers, isThinkingLevel } from "@sema-agent/core";
2
2
  import { HttpError } from "../../security.js";
3
- import { isModelAllowlisted, matchCatalogModel, refusedCatalogEntry, selectableCatalog } from "../../model-select.js";
3
+ import { isAtMentionable, matchCatalogModel, refusedCatalogEntry, selectableCatalog } from "../../model-select.js";
4
4
  import { modelUnavailableMessage } from "../../model-entry-refusal.js";
5
5
  import { redactSecrets } from "../../trace/redact.js";
6
6
  import { admitProviderEcho, redactErrorMessage } from "../../observability/run-terminal.js";
@@ -88,8 +88,8 @@ export async function handleSideQuery(req, res, match, ctx) {
88
88
  sendError(res, 400, "request.model_unavailable", message);
89
89
  return;
90
90
  }
91
- if (!isModelAllowlisted(body.model, catalog, deps.config.atModelAllowlist, deps.config.modelRefusals)) {
92
- sendError(res, 400, "request.model_not_allowed", `model is not in this deployment's @-mention allowlist: "${body.model.slice(0, 120)}" — the allowlist is configured by the operator (config-center models.atModelAllowlist)`);
91
+ if (!isAtMentionable(body.model, catalog, deps.config.atMention, deps.config.modelRefusals)) {
92
+ sendError(res, 400, "request.model_not_allowed", `model is not @-mentionable on this deployment: "${body.model.slice(0, 120)}" — which models can be @-mentioned is configured by the operator (models.atMention)`);
93
93
  return;
94
94
  }
95
95
  }
@@ -29,6 +29,7 @@ import { buildSyncSubmitBody } from "../sync-submit-body.js";
29
29
  import { assertNever } from "../route-ctx.js";
30
30
  import * as facts from "../../capability-facts.js";
31
31
  import { buildCheckpointCtx } from "../checkpoint-ctx.js";
32
+ import { serviceVersion } from "../../service-version.js";
32
33
  import { withModelReachScope } from "../../model-reach-scope.js";
33
34
  import { createInstructionSelectionLeg } from "../../instruction-selection.js";
34
35
  const DISCONNECT_PARK_GRACE_MS = 10_000;
@@ -254,7 +255,7 @@ export async function handleTasks(req, res, match, ctx) {
254
255
  let ledgerSink;
255
256
  let ledgerTerminal = false;
256
257
  if (deps.checkpointStore && prepared.spec.sessionId) {
257
- await deps.checkpointStore.putCtx(prepared.spec.sessionId, buildCheckpointCtx({ body: prepared.body, memoryScope: prepared.auth?.memoryScope }));
258
+ await deps.checkpointStore.putCtx(prepared.spec.sessionId, buildCheckpointCtx({ body: prepared.body, memoryScope: prepared.auth?.memoryScope, writerVersion: serviceVersion() }));
258
259
  }
259
260
  if (durableTaskId && deps.runStore) {
260
261
  const rs = deps.runStore;
@@ -806,7 +807,7 @@ export async function handleTasks(req, res, match, ctx) {
806
807
  }
807
808
  commitSessionInheritEnv(deps, prepared.spec.sessionId, prepared.body);
808
809
  if (deps.checkpointStore && prepared.spec.sessionId) {
809
- await deps.checkpointStore.putCtx(prepared.spec.sessionId, buildCheckpointCtx({ body: prepared.body, memoryScope: prepared.auth?.memoryScope }));
810
+ await deps.checkpointStore.putCtx(prepared.spec.sessionId, buildCheckpointCtx({ body: prepared.body, memoryScope: prepared.auth?.memoryScope, writerVersion: serviceVersion() }));
810
811
  }
811
812
  const syncCancelCtrl = createRunAbort();
812
813
  if (prepared.spec.sessionId)
@@ -14,7 +14,7 @@ export declare function runMeta(prepared: {
14
14
  }, source: string | null): {
15
15
  jobId: string | null;
16
16
  source: string | null;
17
- objectivePreview: string | null;
17
+ objectivePreview: string;
18
18
  };
19
19
  /** Build the cascade config from the operator ladder. Default gate = `status==="completed"` (escalate
20
20
  * on a cheap-rung failure); cost-ceiling from the task's budget bounds the cold-rerun tax. */
@@ -1,10 +1,10 @@
1
- import { redactSecrets } from "../trace/redact.js";
1
+ import { buildRunObjectivePreview } from "../user-authored-text.js";
2
2
  export function runMeta(prepared, source) {
3
3
  const obj = prepared.spec.objective ?? "";
4
4
  return {
5
5
  jobId: prepared.jobId ?? null,
6
6
  source,
7
- objectivePreview: obj ? redactSecrets(obj).slice(0, 120) : null,
7
+ objectivePreview: buildRunObjectivePreview(obj),
8
8
  };
9
9
  }
10
10
  export function cascadeConfig(ladder, maxCostUsd) {
@@ -3,7 +3,7 @@ import type { IncomingMessage } from "node:http";
3
3
  import { type Runner, type TaskSpec, type TaskResult, type WorkflowRunStore, type MemoryEntry, type MemoryExportBundle, type MemoryImportReport, type EntryProvenanceAccount, type MemoryErasureAttestation, type MemoryEntryOrigin, type OriginClearanceRow, type SessionMemoryStatus, type ConsolidationRunReceipt, type ConsolidationDriverRunRow, type SideQuerySpec, type SideQueryResult, type Brain, type EngineNotice } from "@sema-agent/core";
4
4
  import type { TaskRequestBody } from "./wire-types.js";
5
5
  import type { ServiceConfig } from "../config-types.js";
6
- import { type SessionMirrorRuling } from "../config-center/facade.js";
6
+ import { type SessionMirrorRuling } from "../web-admin-client/facade.js";
7
7
  import type { RestartSignal } from "@sema-agent/settings-schema/fleet";
8
8
  import { type OwnerAwareSessionStore } from "../security.js";
9
9
  import type { RunStore, ImageIndex, ImageBake, CheckpointStoreFull, ResumeAnchorStore, ApprovalExemptionStore, ApprovalNonceStore, ServiceSessionPolicyStore, ServiceFileHistoryStore, ToolResultStoreFull, StoreBackend } from "../plugins/store-backend.js";
@@ -628,7 +628,7 @@ export interface ServiceGovernanceDeps {
628
628
  }) => Promise<RequestAuth>;
629
629
  /** 鉴权桥(registry-core api/auth-bridge):registry 用户 JWT → principal。缺席=分支不存在
630
630
  * (bearer 只认 SERVICE_AUTH_TOKEN(S),现状不变)。 */
631
- registryJwtVerifier?: {
631
+ webAdminJwtVerifier?: {
632
632
  verify: (bearer: string) => Promise<import("../auth-bridge.js").VerifyOutcome>;
633
633
  };
634
634
  /** Per-principal rate limiter for task/run endpoints. In-memory (single replica) or TiDB-backed
@@ -694,7 +694,7 @@ export interface ServiceDeploymentDeps {
694
694
  servingLease?: () => import("../fleet/engine-signal.js").ServingLeaseView;
695
695
  /** boot ready 门(b):false = 布防(`CONFIG_REQUIRE_ROSTER=true`)且首次 effective pull 尚未落 roster
696
696
  * (worker 只有占位模型)。就绪原因 `model_roster_pending`(`http/readiness.ts`):计费提交 503 + `/readyz` 503 +
697
- * /health 加性 `ready:false`。absent = 恒 ready(未布防 / 非 registry 部署),现有部署零影响。config-center 的
697
+ * /health 加性 `ready:false`。absent = 恒 ready(未布防 / 非 registry 部署),现有部署零影响。web-admin 的
698
698
  * markRosterLanded 在落模型后翻 true(one-way latch)。 */
699
699
  modelReady?: () => boolean;
700
700
  /** Sema-registry restart signal: the refresh loop sets this when a pull carries restart-to-apply
@@ -709,7 +709,7 @@ export interface ServiceDeploymentDeps {
709
709
  * (configTargetVersion / configAppliedVersion / configApplyStaleMs),`GET /v1/diagnostics/wiring` 取整份
710
710
  * (按组的 appliedVersion / deferredKeys+铸因 / lastRejected 消毒形)。缺席 = 这个进程没有配置管道
711
711
  * (纯 env 部署 / 测试夹具)⇒ 两个面的形状逐字不变(additive)。 */
712
- configApplyState?: () => import("../config-center/apply-ledger.js").ConfigApplyLedgerView | undefined;
712
+ configApplyState?: () => import("../web-admin-client/apply-ledger.js").ConfigApplyLedgerView | undefined;
713
713
  /** S-698:中心凭证健康位(`/health.centerCredential`)—— 凭证来源的健康态 + 续签器状态(`center-credential-renewer.ts`
714
714
  * `buildCenterCredentialHealthView` 铸形,只有闭集词 / 时刻 / 计数,不带路径与令牌)。缺席 / 返回 undefined = 健康或没有中心
715
715
  * ⇒ `/health` 形状逐字不变(additive)。 */
@@ -718,7 +718,7 @@ export interface ServiceDeploymentDeps {
718
718
  * (`boot/stage-10-http-server.ts` → `modelRefusals: () => deployment.modelRefusalsState?.()`)—— 一处铸、两出口。缺席 / 返回 undefined =
719
719
  * 没有可报的拒或没有配置管道 ⇒ `/health` 形状逐字不变(additive)。 */
720
720
  modelRefusalsState?: () => import("@sema-agent/settings-schema").ModelRefusalsSignal | undefined;
721
- /** `/health.configHandoff`(只上 `/health`):在场 ⇔ 部署声明了耐久接力 ∧ 应用着的那一代没被确认(config-center 接力账的 `configHandoffState()`;合成律
721
+ /** `/health.configHandoff`(只上 `/health`):在场 ⇔ 部署声明了耐久接力 ∧ 应用着的那一代没被确认(web-admin 接力账的 `configHandoffState()`;合成律
722
722
  * `fleet/engine-signal.ts` 的 `buildConfigHandoff`)。缺席 / 返回 undefined = 有接力、没有中心或本地腿 ⇒ 键缺席。 */
723
723
  configHandoffState?: () => import("../fleet/engine-signal.js").ConfigHandoff | undefined;
724
724
  /** [ref] 追加件:`POST /v1/admin/config/refresh` 的实现面 —— 触发**一次既有**的 refresh 拍(在飞则 join)。
@@ -727,7 +727,7 @@ export interface ServiceDeploymentDeps {
727
727
  /** DESIGN-278 §5 S2([ref]):center **当前在管**的 ServiceConfig 键集 —— `GET /v1/config/catalog`
728
728
  * 判 `effectiveLane`(env 占位/center 在管/默认)的 center 半场。缺席或返回 undefined = 本部署
729
729
  * 没有配置管道(纯 env worker / 测试夹具)⇒ 目录把每条 center 腿如实标「不在管」(additive)。 */
730
- configCenterManagedKeys?: () => ReadonlySet<string> | undefined;
730
+ webAdminManagedKeys?: () => ReadonlySet<string> | undefined;
731
731
  /** [ref](core 5.50 [ref]):mid-turn MCP 撤销台账读口 —— GET /v1/sessions/:id/mcp 的展示面与
732
732
  * 引擎执行面同一权威(被撤服务器的工具不再进面板)。缺席 = 无中心撤销面(pre-338 展示语义)。 */
733
733
  mcpRevocations?: {
@@ -783,7 +783,7 @@ export interface ServiceDeploymentDeps {
783
783
  * (它在场景装配里每请求现算),所以本位不会随调用方漂。 */
784
784
  webSearchProvider?: import("../plugins/web-search.js").WebSearchProvider;
785
785
  /** S-737:本进程模型钥匙保管店的**公钥面** —— `GET /v1/capabilities` 的 `sealedKey` 段唯一席位。值**逐字**取自
786
- * config-center 运行时(`boot/config-center.ts` 的 `sealedKeyPublic`,boot 期建的那一只店),路由里不再建店、不读全局。
786
+ * web-admin 运行时(`boot/web-admin.ts` 的 `sealedKeyPublic`,boot 期建的那一只店),路由里不再建店、不读全局。
787
787
  * 类型只有最新那把公钥(`sealed-key.ts` `SealedKeyPublicFace`):私钥、保管路径、持有的旧 id 列表从这一层结构上够不着。
788
788
  * 缺席 = 本进程没有保管店(boot 建店失败,或不是由 composition root 装起来的测试夹具形)⇒ caps 的 `sealedKey` 键缺席。 */
789
789
  sealedKeyPublic?: import("../sealed-key.js").SealedKeyPublicFace;
@@ -2,7 +2,7 @@ import http from "node:http";
2
2
  import { outwardPlane } from "../terminal.js";
3
3
  import { redactHead } from "../observability/run-terminal.js";
4
4
  import { validatePendingSteer } from "@sema-agent/core";
5
- import {} from "../config-center/facade.js";
5
+ import {} from "../web-admin-client/facade.js";
6
6
  import { HttpError } from "../security.js";
7
7
  import {} from "../memory-sync.js";
8
8
  import { evictIfConflict } from "../runs.js";
@@ -7,13 +7,14 @@
7
7
  * **入口地板**(`runtime-governance.ts` `autonomyModeFloor`)—— 这两只属主带着配置层的包外依赖;`checkpoint-ctx.ts` 被随包的本地排空脚本经编译产物 import,
8
8
  * 它的闭包只许 node 内建 / 引擎包根(`test/drain-check-local.test.ts` 的闭包门)。判据只有这一只,前两问的谓词照旧住在各自属主里。
9
9
  */
10
- import { type PermissionMode } from "@sema-agent/core";
10
+ import type { PermissionMode } from "@sema-agent/core";
11
11
  import { type Autonomy } from "../runtime-governance.js";
12
12
  import { type StoredBodyReplayRefusal } from "./checkpoint-ctx.js";
13
13
  import type { CheckpointCtx } from "./route-ctx.js";
14
14
  /**
15
- * 第三问:本行体里的模式词能否按当前读法重放。不能 ⇔ 本部署此刻有入口地板 ∧ 行上没有当前的模式词读法记号 ∧ 体的生效词被地板钳会变
16
- * (core `clampPermissionMode`,与提交入口的盖章同一只钳)⇒ 返回拒因的两个事实(体的词、地板);能 ⇒ `undefined`。
15
+ * 第三问:本行体里的模式词能否按当前读法重放。不能 ⇔ 本部署此刻有入口地板 ∧ 行上没有当前的模式词读法记号 ∧ 体的生效词进这块地板会变
16
+ * (`runtime-governance.ts` `entryPermissionMode`,与提交入口的盖章同一只函数;判的是「词变不变」而不是 `clamped` —— 体无词的旧行进地板取地板本身,
17
+ * 那也是变)⇒ 返回拒因的两个事实(体的词、地板);能 ⇒ `undefined`。
17
18
  */
18
19
  export declare function permissionModeReadingUnstated(ctx: CheckpointCtx, floor: PermissionMode | undefined): {
19
20
  stored: PermissionMode | undefined;
@@ -1,23 +1,23 @@
1
- import { clampPermissionMode } from "@sema-agent/core";
2
1
  import { storedBodyPermissionMode } from "../task-settings.js";
3
- import { autonomyModeFloor } from "../runtime-governance.js";
2
+ import { autonomyModeFloor, entryPermissionMode } from "../runtime-governance.js";
4
3
  import { skillDenyInertEntryOf } from "../rule-entry-list.js";
5
4
  import { allowListReadingEraOf, allowListReadingUnstated, permissionModeReadingStated } from "./checkpoint-ctx.js";
6
5
  export function permissionModeReadingUnstated(ctx, floor) {
7
6
  if (floor === undefined || permissionModeReadingStated(ctx))
8
7
  return undefined;
9
8
  const stored = storedBodyPermissionMode(ctx.body);
10
- return clampPermissionMode(stored, floor).effective === stored ? undefined : { stored, floor };
9
+ return entryPermissionMode(stored, floor).effective === stored ? undefined : { stored, floor };
11
10
  }
12
11
  export function storedBodyReplayRefusal(ctx, autonomy) {
12
+ const writer = ctx.writerVersion !== undefined ? { writerVersion: ctx.writerVersion } : {};
13
13
  if (allowListReadingUnstated(ctx))
14
- return { kind: "allow_list_reading", era: allowListReadingEraOf(ctx) };
14
+ return { kind: "allow_list_reading", era: allowListReadingEraOf(ctx), ...writer };
15
15
  const entry = skillDenyInertEntryOf(ctx.body);
16
16
  if (entry !== undefined)
17
17
  return { kind: "skill_deny_inert", entry };
18
18
  const mode = permissionModeReadingUnstated(ctx, autonomyModeFloor(autonomy));
19
19
  if (mode !== undefined)
20
- return { kind: "permission_mode_reading", ...mode };
20
+ return { kind: "permission_mode_reading", ...mode, ...writer };
21
21
  return undefined;
22
22
  }
23
23
  //# sourceMappingURL=stored-body-replay.js.map
package/dist/index.d.ts CHANGED
@@ -27,7 +27,8 @@ export { createHttpServer, type ServiceDeps, type RequestAuth, type FlatServiceD
27
27
  export { createSideQueryLane, createPerModelKeyBrain, type KeyResolver, type SideQueryLane, type SideQueryLaneCtx } from "./boot/side-query-lane.js";
28
28
  export { createKeyResolver, resolveModelApiKey, type ModelKeyRef } from "./key-resolver.js";
29
29
  export { isModelKeyPoison, ModelKeyPoisonedError, type ModelKeyPoison, type ModelKeyPoisonReason } from "./key-resolver.js";
30
- export { RETIRED_ENVS, type RetiredEnv, type RetiredEnvKind, type RetiredEnvWire } from "./config.js";
31
30
  export { CATALOG_ENTRY_HEADER_LANES, CATALOG_ENTRY_HEADER_NAMES, type CatalogEntryHeaderName } from "./model-entry-headers.js";
31
+ export { judgeModelRouteGap, type ModelRouteGapReading, type ModelRouteGapOptions } from "./model-route-gap.js";
32
+ export type { ModelRouteGap } from "./model-route-endpoint.js";
32
33
  export type { UserInputLedgerStore, UserInputAcceptance, NewUserInputAcceptance, OpenScanCursor, OpenScanPage, SettleHow, WriterGoneEvidence } from "./user-input-ledger.js";
33
34
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -24,6 +24,6 @@ export { createHttpServer, } from "./http/server.js";
24
24
  export { createSideQueryLane, createPerModelKeyBrain } from "./boot/side-query-lane.js";
25
25
  export { createKeyResolver, resolveModelApiKey } from "./key-resolver.js";
26
26
  export { isModelKeyPoison, ModelKeyPoisonedError } from "./key-resolver.js";
27
- export { RETIRED_ENVS } from "./config.js";
28
27
  export { CATALOG_ENTRY_HEADER_LANES, CATALOG_ENTRY_HEADER_NAMES } from "./model-entry-headers.js";
28
+ export { judgeModelRouteGap } from "./model-route-gap.js";
29
29
  //# sourceMappingURL=index.js.map
@@ -56,7 +56,7 @@ export declare class ModelKeyPoisonedError extends Error {
56
56
  }
57
57
  /**
58
58
  * Build a per-model API-key resolver for `TaskSpec.getApiKeyAndHeaders` from the catalog's
59
- * name → env-var-NAME map (sema-registry `apiKeyEnv`). core threads this per brain call — and per cascade
59
+ * name → env-var-NAME map (web-admin `apiKeyEnv`). core threads this per brain call — and per cascade
60
60
  * rung — so each model/rung authenticates with its OWN upstream account/key.
61
61
  *
62
62
  * A model absent from BOTH maps returns `undefined`, so core falls back to the brain's construction-time
@@ -66,8 +66,8 @@ export interface ProvisionedWorker {
66
66
  verifierTools?: ToolSpec[];
67
67
  }
68
68
  /**
69
- * 一条 leader run 的**入口体**(提交体去掉 objective 的那一半)—— 运维 `AUTONOMY` 的模式词地板在这条 run 出生的那一拍读一次、经受理门同一只盖章
70
- * 盖出来的结果(`run-entry.ts` `leaderRunEntry`);地板缺席 ⇒ `{}`。leader 请求不带调用方的模式词,所以入口词就是地板本身(与 run-local 同)。
69
+ * 一条 leader run 的**入口体**(提交体去掉 objective 的那一半)—— 运维 `AUTONOMY` 的模式词地板在这条 run 出生的那一拍读一次、经受理门同一只函数
70
+ * (`runtime-governance.ts` `entryPermissionMode`)得出的入口词(`run-entry.ts` `leaderRunEntry`);地板缺席 ⇒ `{}`。leader 请求不带调用方的模式词,所以入口词就是地板本身(与 run-local 同)。
71
71
  * 本 run 铸的每一条 spec 经 {@link withLeaderLeg} 从这一份取词;worker 的续跑体由它展开(`{ ...entry, objective }`)⇒ 首跑、续跑、修复腿同一个词。
72
72
  * 入口词是 `plan` 的 run 进不了这条车道(`run-entry.ts` `leaderEntryRefusal`:worker 会话没有计划审阅通道)—— 受理口与出生处同判,到不了 worker。
73
73
  * 热改 `AUTONOMY` 只影响之后起的 leader run:在飞的 run 保持它出生时盖下的这一份。
@@ -76,10 +76,11 @@ export interface LeaderRunEntry {
76
76
  readonly permissionMode?: PermissionMode;
77
77
  }
78
78
  /**
79
- * leader 车道铸 spec 的**唯一**合并口:入口体的词写进 spec,再交给无人值守腿的合并口(`withUnattendedLeg` 的 `default` 钳在入口词之下)。
80
- * 入口体无词 ⇒ spec 原物交给 `withUnattendedLeg`,与不经本口逐字同。本车道的 spec 自己不带模式词(子任务体只有 objective,其余并进的键是预算 / 审批 / 身份),
81
- * 所以这里是「写」而不是「钳」。五个出生点(worker 首跑的工厂 / 静态两条车道、集成修复、模块门修复、单代理修复环)都调它、不直调 `withUnattendedLeg`
82
- * (`test/leader-entry-floor.test.ts` 按语法树数调用点):「这条腿的词从哪来」只有入口体一个答案。
79
+ * leader 车道铸 spec 的**唯一**合并口:spec 的词钳在入口体的词之下(`runtime-governance.ts` `entryPermissionMode(spec 的词, 入口词)` —— 与受理门同一只函数;
80
+ * 写进 spec 的值就是它的 `effective`),再交给无人值守腿的合并口(`withUnattendedLeg` 的 `default` 钳在那个词之下)。入口体无词 ⇒ spec 原物交给
81
+ * `withUnattendedLeg`,与不经本口逐字同。本车道的 spec 今天自己不带模式词(子任务体只有 objective,其余并进的键是预算 / 审批 / 身份)⇒ 入口词在场时写下的就是它;
82
+ * 将来带了词,比入口词松的折回入口词、比它紧的留着 —— 与一条提交体过受理门同一个答案,不另写「写」的规则。五个出生点(worker 首跑的工厂 / 静态两条车道、
83
+ * 集成修复、模块门修复、单代理修复环)都调它、不直调 `withUnattendedLeg`(`test/leader-entry-floor.test.ts` 按语法树数调用点):「这条腿的词从哪来」只有入口体一个答案。
83
84
  */
84
85
  export declare function withLeaderLeg<S extends Partial<TaskSpec>>(spec: S, entry: LeaderRunEntry): S & UnattendedLegSpec;
85
86
  export interface LeaderDeps {
@@ -4,6 +4,7 @@ import { pullDiff } from "./diffout.js";
4
4
  import { mergeBranches } from "./merge.js";
5
5
  import { Runner, runWithVerification, resumeWithVerification } from "@sema-agent/core";
6
6
  import { pausedCauseOf, outwardPlane } from "../terminal.js";
7
+ import { entryPermissionMode } from "../runtime-governance.js";
7
8
  import { withUnattendedLeg } from "../unattended-permission-mode.js";
8
9
  const MAX_RESUME_SLICES = 200;
9
10
  export async function autoResumeOnResource(initial, signal, resume, maxSlices = MAX_RESUME_SLICES) {
@@ -17,7 +18,8 @@ export async function autoResumeOnResource(initial, signal, resume, maxSlices =
17
18
  return vr;
18
19
  }
19
20
  export function withLeaderLeg(spec, entry) {
20
- return withUnattendedLeg(entry.permissionMode === undefined ? spec : { ...spec, permissionMode: entry.permissionMode });
21
+ const word = entryPermissionMode(spec.permissionMode, entry.permissionMode).effective;
22
+ return withUnattendedLeg(word === undefined ? spec : { ...spec, permissionMode: word });
21
23
  }
22
24
  export async function runLeaderTask(task, durableBaseSha, deps) {
23
25
  let subs;
@@ -2,7 +2,7 @@
2
2
  * 一条 leader run 的**入口体**与「它进不进得了 leader 车道」的唯一判据。
3
3
  *
4
4
  * 规则(与受理门、run-local 同一条):运维 `AUTONOMY=plan` 是提交入口的模式词地板,盖在每一个 spec 出生点。leader 请求不带调用方的模式词,
5
- * 所以入口体是一份空体盖上地板(受理门同一只盖章 `task-settings.ts` `stampEntryPermissionMode`;地板的唯一属主 `runtime-governance.ts`
5
+ * 所以入口词 = `runtime-governance.ts` `entryPermissionMode(undefined, 地板).effective`(与受理门、run-local 同一只函数;地板的唯一属主
6
6
  * `autonomyModeFloor`)。
7
7
  *
8
8
  * `plan` 是**生命周期词**:它靠人审通道(`plan_review`)出口 —— 一个人批准计划,run 才离开 plan。leader 的 worker 会话**没有**那条通道
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import { type Autonomy } from "../runtime-governance.js";
16
16
  import type { LeaderRunEntry } from "./leader.js";
17
- /** 一条 leader run 的入口体:地板读一次、受理门同一只盖章(地板缺席 ⇒ `{}`)。调用方读**活** config(热改只影响之后起的 run)。 */
17
+ /** 一条 leader run 的入口体:地板读一次、入口词经受理门同一只函数(地板缺席 ⇒ `{}`)。调用方读**活** config(热改只影响之后起的 run)。 */
18
18
  export declare function leaderRunEntry(autonomy: Autonomy | undefined): LeaderRunEntry;
19
19
  /** 拒句:原因(运维的 plan 地板 × 这条车道没有计划审阅通道)+ 两条出路(改走有计划审阅的 run 车道 / 运维换档)。不含任何配置值之外的回显。
20
20
  * 受理口(HTTP 422 的 `error`)与 run 出生处(run 的 `error`)读的是这一份;字节由 `test/api-error-text-freeze.test.ts` 的常量锚格冻。 */
@@ -1,7 +1,7 @@
1
- import { autonomyModeFloor } from "../runtime-governance.js";
2
- import { stampEntryPermissionMode } from "../task-settings.js";
1
+ import { autonomyModeFloor, entryPermissionMode } from "../runtime-governance.js";
3
2
  export function leaderRunEntry(autonomy) {
4
- return stampEntryPermissionMode({}, autonomyModeFloor(autonomy));
3
+ const word = entryPermissionMode(undefined, autonomyModeFloor(autonomy)).effective;
4
+ return word === undefined ? {} : { permissionMode: word };
5
5
  }
6
6
  export const LEADER_PLAN_ENTRY_REFUSAL = "this deployment runs with AUTONOMY=plan, which starts every task in plan mode and lets it out of plan mode only when a person approves its plan through plan review; " +
7
7
  "a leader task's workers have no plan review channel, so they could neither write nor hand their plan to anyone who can approve it. Nothing was started. " +
@@ -65,11 +65,11 @@ export interface LeaderWireConfig {
65
65
  * 保留它准备时的那一份(core 的自然快照语义,两条腿同律)。 */
66
66
  deploymentPosture?: () => DeploymentPostureSeats;
67
67
  /**
68
- * 运维 `AUTONOMY`(活 config 的那一位)—— 本车道每条 leader run **出生那一拍**读一次,经 `run-entry.ts` 的 `leaderRunEntry`(入口地板 + 受理门同一只盖章)
69
- * 盖成这条 run 的入口体(`LeaderDeps.entry`);本 run 铸的每一条 spec 与 worker 的续跑体都从它取词。入口词是 `plan` 的 run 进不了这条车道
68
+ * 运维 `AUTONOMY`(活 config 的那一位)—— 本车道每条 leader run **出生那一拍**读一次,经 `run-entry.ts` 的 `leaderRunEntry`(入口地板 + 受理门同一只入口函数 `entryPermissionMode`)
69
+ * 得出这条 run 的入口体(`LeaderDeps.entry`);本 run 铸的每一条 spec 与 worker 的续跑体都从它取词。入口词是 `plan` 的 run 进不了这条车道
70
70
  * (`leaderEntryRefusal`:worker 会话没有计划审阅通道)⇒ 出生处即以拒句收场;HTTP 受理口用同一只判据先答 422。
71
71
  *
72
- * 🔴 **函数席**(与 `deploymentPosture` / `durable` 同一条先例):`config.autonomy` 被 config-center 原地热改,boot 期取一次值会把这条腿钉在起服那一刻。
72
+ * 🔴 **函数席**(与 `deploymentPosture` / `durable` 同一条先例):`config.autonomy` 被 web-admin 原地热改,boot 期取一次值会把这条腿钉在起服那一刻。
73
73
  * **必填**:没有 AUTONOMY 的装配递 `() => undefined` —— 缺席不是「没有地板」的合法拼法(权限轴上不许静默放宽)。
74
74
  */
75
75
  autonomy: () => Autonomy | undefined;
@@ -101,7 +101,7 @@ export interface LeaderWireConfig {
101
101
  usageWindowStore?: RunnerDeps["usageWindowStore"];
102
102
  /**
103
103
  * [ref]([ref])—— **center 发布的 prompt catalog** 席,原样递给本车道的每一只 Runner。唯一属主 =
104
- * `boot/config-center.ts` 的 `configCenter.promptSource`(主 runner / subRunner 同一只;run-local 有自己
104
+ * `boot/web-admin.ts` 的 `webAdmin.promptSource`(主 runner / subRunner 同一只;run-local 有自己
105
105
  * 的等价腿)。缺席 ⇒ leader 的 planner/worker/repair/conflict 四类**顶层**任务跑引擎内置提示词,而同一
106
106
  * 部署的 `/v1/tasks`、`/v1/runs` 跑运维发布的那一份 —— 且 core 顶层新任务走的是**静默**臂(pinned /
107
107
  * parentCenterArtifactDigest 两支才 `prompt.snapshot_unavailable` fail-loud),运维面零信号。
@@ -7,6 +7,7 @@ import { tmpdir } from "node:os";
7
7
  import { Runner, combinePolicies, createDurableQuestionPolicy, QUESTION_AWAITS_RESUME, delimitUntrusted, hasDestroy, } from "@sema-agent/core";
8
8
  import { leaderEntryRefusal, leaderRunEntry } from "./run-entry.js";
9
9
  import { buildCheckpointCtx } from "../http/checkpoint-ctx.js";
10
+ import { serviceVersion } from "../service-version.js";
10
11
  import { RemoteContainerExecutionEnv } from "../plugins/remote-env-e2b.js";
11
12
  import { E2B_SANDBOX_HOME } from "../execution-lane-caps.js";
12
13
  import { createDurableAskPolicy } from "../approval.js";
@@ -272,7 +273,7 @@ export function createLeaderRunner(cfg) {
272
273
  const provisionWorker = async (sub) => {
273
274
  const sessionId = `leader-${sub.workerId}-${Date.now()}`;
274
275
  const durable = cfg.durable?.();
275
- const resumeCtx = buildCheckpointCtx({ body: { ...entry, objective: sub.spec.objective }, unattendedLeg: true });
276
+ const resumeCtx = buildCheckpointCtx({ body: { ...entry, objective: sub.spec.objective }, unattendedLeg: true, writerVersion: serviceVersion() });
276
277
  let durableSpec = {};
277
278
  if (durable) {
278
279
  const d = durable;
package/dist/main.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { fatalExit } from "./boot/fatal-exit.js";
2
2
  import { runStage01 } from "./boot/stage-01-config.js";
3
- import { runStage02 } from "./boot/stage-02-registry-pull.js";
3
+ import { runStage02 } from "./boot/stage-02-web-admin-pull.js";
4
4
  import { runStage03 } from "./boot/stage-03-store-backend.js";
5
5
  import { runStage04 } from "./boot/stage-04-stores.js";
6
6
  import { runStage05 } from "./boot/stage-05-execution-env.js";
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * `McpServerSpec.toolFaces` —— MCP 工具的**面覆盖层**(core 7.8.0 [ref] §1.1/§2.7;声明面
3
3
  * settings-schema 1.9.0)。一条规则、三条腿共用(请求腿 `task-mcp.ts normalizeServer` / center 腿
4
- * `config-center/skills-mcp.ts resolveMcpServers` / 本地 config.d 腿 `config-provider.ts` 只做承载),
4
+ * `web-admin-client/skills-mcp.ts resolveMcpServers` / 本地 config.d 腿 `config-provider.ts` 只做承载),
5
5
  * 与 {@link import("./mcp-source-label.js").readMcpSourceLabel} 同一个「判据单点、三腿一致」的形。
6
6
  *
7
7
  * ## 分工(为什么本层**不**复述 core 的那张表)
@@ -35,7 +35,7 @@
35
35
  * 该条、兄弟 server 照挂)。代价是真的(少一套工具),但它**响亮且立刻**;反方向的代价是一条
36
36
  * **静默失效的安全声明**,而后者按 [ref] 不许存在于安全轴上;
37
37
  * ③ 拿什么补偿 —— 报出来的名字本身:请求腿 `mcp_injection_dropped{dropped:[name]}`、center 腿
38
- * `sema_registry_mcp_tool_faces_invalid{server,problem,note}` 一条点名 warn(`problem` 里带工具名与哪一段不合;运维照着改那一行即可)。
38
+ * `web_admin_mcp_tool_faces_invalid{server,problem,note}` 一条点名 warn(`problem` 里带工具名与哪一段不合;运维照着改那一行即可)。
39
39
  * 每只工具的面是**整只**判(core 明写 "applied whole or not at all");而**任一只**判不出形 ⇒ 整条 server
40
40
  * 不进 —— 「留下好的那几只」同样是让坏的那一只无面挂载,与整张丢没有区别。
41
41
  */
@@ -1,4 +1,5 @@
1
1
  import { type ModelEntryRefusalCode, type ModelPlaneRefusalCode, type ModelRefusalsSignal } from "@sema-agent/settings-schema";
2
+ import { type DroppedCatalogEntry } from "./web-admin-client/read-warnings.js";
2
3
  /**
3
4
  * 条目拒因码 → 本仓铸它的成因 —— **以码为键**(S-768):码闭集的属主是 settings-schema(`MODEL_ENTRY_REFUSAL_CODES`,6.2.0 起;此前本仓
4
5
  * 自持一份同名码表,撞名已消灭、零别名)。那边加一个条目码 ⇒ 本表缺键 ⇒ 本仓 tsc 红(只拿 `satisfies` 约束码值证明的是「子集」,
@@ -58,23 +59,31 @@ export interface CatalogEntryLike {
58
59
  * 坐标,不取它的输出(输出会补缺省、剥扩展键,那是读腿的事)。
59
60
  */
60
61
  export declare function judgeCatalogEntry(m: CatalogEntryLike, ctx: CatalogEntryVerdictCtx): ModelEntryRefusal | undefined;
61
- /** 一批已启用条目的判决:可用的(保序)、不可用的(按 catalog name)、以及形不对的被丢身份载体行(坐标)。 */
62
+ /** 一批已启用条目的判决:可用的(保序)、不可用的(按 catalog name)、被丢目录条目的载体行(形对的,保序),以及形不对的载体行(坐标)。 */
62
63
  export interface CatalogEntriesVerdict<M extends CatalogEntryLike> {
63
64
  readonly usable: readonly M[];
64
65
  /** 键 = catalog name(**每一个**名,含秘密形 / 空串 / `__proto__`:引擎自己的判决保持完整 —— S-712 不变量与选择面的「让出」都读它;
65
66
  * 名筛只在出口,见 {@link buildModelRefusalsSignal})。键以自有数据属性写入(`__proto__` 不走原型 setter)。 */
66
67
  readonly refused: Readonly<Record<string, ModelEntryRefusal>>;
67
- /** S-712:被丢身份**载体形不对**的行坐标(`models.3`;载体不是列表时是一个固定标记)。读腿只为有名的被丢条目铸载体行
68
- * (`read-warnings.ts` `DroppedModelIdentity`,`name` 必在),所以这一形只来自绕过读腿的输入被改过(盘上 LKG 被手改 / 手写
69
- * effective)。非空 ⇒ 读不出的名字无从证明它不被增广铸出 ⇒ 不变量 `refused-names-not-minted` 不成立 ⇒ 模型面组拒(fail-closed)。 */
68
+ /** S-712:被丢目录条目**载体形不对**的行坐标(`models.3`;读不出下标时是 `(unknown coordinate)`;载体不是列表时是一个固定标记)。读腿铸的每一行
69
+ * 都合 `read-warnings.ts` {@link DroppedCatalogEntryRow} 的形,所以这一形只来自绕过读腿的输入被改过(盘上 LKG 被手改 / 手写 effective)。
70
+ * 非空 ⇒ 改过的行原本代表谁说不清,无从证明它的名字不被增广铸出 ⇒ 不变量 `refused-names-not-minted` 不成立 ⇒ 模型面组拒(fail-closed)。 */
70
71
  readonly malformed: readonly string[];
72
+ /** S-1295:载体里形对的行(保序)—— 模型面 stage 把它与 `models` 同 commit 进 `config.droppedCatalogEntries`(`GET /v1/models.droppedEntries`
73
+ * 的源):载体只在这里被判形、被读一次,墓碑与 wire 读的是同一批行。 */
74
+ readonly dropped: readonly DroppedCatalogEntry[];
71
75
  }
72
76
  /**
73
77
  * 批量形(模型面 stage 与 dry-run 共用这一只 —— 报数与真 apply 永不撕裂)。
74
- * S-712:`dropped` = 读腿交出的被丢条目身份(`EffectiveConfig.models.droppedIdentities`)—— 它们与逐条判据判出的 `entry_invalid`
75
- * 是**同一件事**(条目不合 `ModelEntry` 形),只是在第一道边界就被丢了;每一行铸一块墓碑(拒因 provider 词空:告警身份不带它)。
76
- * 入参按 `unknown` 判形:载体可能来自盘上 LKG(本仓写的,但文件可被改)。**规则一条**:载体要么缺席,要么是一列带字符串 `name`
77
- * 的行;其余一律「载体形不对」进 `malformed`(fail-closed)—— 读腿自己从不铸这种形。
78
+ * S-712:`dropped` = 读腿交出的被丢目录条目载体(`EffectiveConfig.models.droppedCatalogEntries`,每一条被丢的目录条目一行)。入参按 `unknown`
79
+ * 判形:载体可能来自盘上 LKG(本仓写的,但文件可被改)。载体要么缺席,要么是一列合 {@link DroppedCatalogEntryRow} 形的行;其余一律「载体形不对」
80
+ * 进 `malformed`(fail-closed)—— 读腿自己从不铸这种形。
81
+ * **墓碑判据(一条,S-712 原样)**:行的 `identity.name` 在 ∧ `identity.enabled !== false` ⇒ 铸一块墓碑(它与逐条判据判出的 `entry_invalid`
82
+ * 是同一件事 —— 条目不合 `ModelEntry` 形,只是在第一道边界就被丢了;拒因 provider 词空:告警身份不带它)。其余行不是墓碑:
83
+ * · 停用 ⇒ 不在目录(与 7.100.0 同义);
84
+ * · 没有名 —— 原文 `name` 不是字符串,或是字符串但不能原样出门(settings-schema `isDisclosableIdentity` 说不,身份里不带)⇒ **无名可留**,
85
+ * 与停用同处置。后者对本判据同样安全:档位增广只铸闭集词(`ultra` / `max` / `pro` / `flash` / `lite`、CC 别名、`best`),没有一个是
86
+ * 秘密形或非标识符,被扣下的名字无从被铸出;代价只是显式点它的请求拿到「未知模型」而不是 `request.model_unavailable`。
78
87
  * 与一条可用 / 已判不可用条目同名时不覆盖(可用条目仍可用;同名撞车由不变量 `refused-names-not-minted` 响亮拒)。
79
88
  */
80
89
  export declare function judgeCatalogEntries<M extends CatalogEntryLike>(enabled: readonly M[], ctx: CatalogEntryVerdictCtx, dropped?: unknown): CatalogEntriesVerdict<M>;
@@ -100,10 +109,10 @@ export declare function buildModelRefusalsSignal(v: ModelRefusalVerdict | undefi
100
109
  * 不各写一份 `isReportableRefusalName` 判断。
101
110
  */
102
111
  export declare function refusedNameLogField(key: string, name: string): Record<string, unknown>;
103
- /** 一串被拒条目名的日志字段(`sema_registry_models` 行的 `unavailable`):只列可披露的名,被扣下的名**只数个数**(`<key>NamesWithheld`,0 个时键缺席)。 */
112
+ /** 一串被拒条目名的日志字段(`web_admin_models` 行的 `unavailable`):只列可披露的名,被扣下的名**只数个数**(`<key>NamesWithheld`,0 个时键缺席)。 */
104
113
  export declare function refusedNamesLogFields(key: string, names: readonly string[]): Record<string, unknown>;
105
114
  /** 成因 → 它那一条 warn 的事件名(**穷举**)。两个名字是票面点名的既有/新事件,运维的告警规则按名挂。 */
106
- export declare function refusalEventOf(reason: ModelEntryRefusalReason): "sema_registry_model_no_brain" | "sema_registry_model_entry_invalid";
115
+ export declare function refusalEventOf(reason: ModelEntryRefusalReason): "web_admin_model_no_brain" | "web_admin_model_entry_invalid";
107
116
  /** warn 字段(不含值):`field` = 第一处坏字段(告警规则最常按它分组),`fields` = 全部。S-805:`model` 只在名可披露时写。 */
108
117
  export declare function refusalWarnFields(name: string, r: ModelEntryRefusal): Record<string, unknown>;
109
118
  /**
@@ -163,6 +172,6 @@ export interface RefusedNameView {
163
172
  export declare function mintedRefusedNames(view: RefusedNameView): MintedRefusedName[];
164
173
  /** 不变量 `refused-names-not-minted` 的拒因句(`undefined` = 成立)。warn 与世代账 / 拒因同一句;逐对明细另走 {@link mintedRefusedNames}。 */
165
174
  export declare function refusedNameMintedRefusal(view: RefusedNameView): string | undefined;
166
- /** 被丢身份载体形不对的拒因句(同一不变量同一个码:读不出的名字无从证明它不被增广铸出)。 */
175
+ /** 被丢目录条目载体形不对的拒因句(同一不变量同一个码:改过的行原本代表谁说不清,无从证明它的名字不被增广铸出)。 */
167
176
  export declare function malformedDroppedCarrierRefusal(entries: readonly string[]): string;
168
177
  //# sourceMappingURL=model-entry-refusal.d.ts.map