@sema-agent/server 7.99.0 → 7.101.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 (174) hide show
  1. package/MIGRATION.md +35 -1
  2. package/README.md +12 -1
  3. package/README.zh-CN.md +9 -1
  4. package/USAGE.md +150 -56
  5. package/dist/approval-ask-machine.d.ts +10 -0
  6. package/dist/approval-ask-machine.js +3 -0
  7. package/dist/approval-card.d.ts +86 -1
  8. package/dist/approval-card.js +42 -8
  9. package/dist/approval-policy-settlement.d.ts +31 -0
  10. package/dist/approval-policy-settlement.js +16 -0
  11. package/dist/approval-reconciler.d.ts +8 -1
  12. package/dist/approval-reconciler.js +5 -4
  13. package/dist/approval.d.ts +44 -20
  14. package/dist/approval.js +14 -6
  15. package/dist/boot/config-center.d.ts +16 -8
  16. package/dist/boot/config-center.js +114 -90
  17. package/dist/boot/execution-env.d.ts +1 -2
  18. package/dist/boot/execution-env.js +21 -3
  19. package/dist/boot/leader.js +12 -9
  20. package/dist/boot/memory-consolidation.d.ts +38 -0
  21. package/dist/boot/memory-consolidation.js +35 -0
  22. package/dist/boot/parked-revive-gate.js +1 -0
  23. package/dist/boot/reapers.js +1 -0
  24. package/dist/boot/resolve-spec.d.ts +0 -1
  25. package/dist/boot/resolve-spec.js +28 -10
  26. package/dist/boot/runner-deps.d.ts +2 -2
  27. package/dist/boot/runner-deps.js +9 -3
  28. package/dist/boot/stage-02-registry-pull.js +9 -0
  29. package/dist/boot/stage-05-execution-env.d.ts +1 -1
  30. package/dist/boot/stage-06-runners.d.ts +2 -2
  31. package/dist/boot/stage-06-runners.js +3 -3
  32. package/dist/boot/stage-07-capability-layer.d.ts +2 -3
  33. package/dist/boot/stage-07-capability-layer.js +6 -6
  34. package/dist/boot/stage-08-reapers.d.ts +3 -4
  35. package/dist/boot/stage-08-reapers.js +2 -2
  36. package/dist/boot/stage-09-leader.d.ts +2 -3
  37. package/dist/boot/stage-10-http-server.d.ts +2 -3
  38. package/dist/boot/stage-10-http-server.js +2 -2
  39. package/dist/boot/stores.js +4 -0
  40. package/dist/capabilities/center-plugins.d.ts +14 -2
  41. package/dist/capabilities/center-plugins.js +13 -5
  42. package/dist/capabilities/hands-lane.js +2 -1
  43. package/dist/capabilities/scenarios.js +18 -5
  44. package/dist/capabilities/tool-defer.d.ts +2 -2
  45. package/dist/config-catalog.d.ts +2 -2
  46. package/dist/config-catalog.js +16 -15
  47. package/dist/config-center/apply-effective.d.ts +59 -39
  48. package/dist/config-center/apply-effective.js +231 -120
  49. package/dist/config-center/apply-ledger.d.ts +45 -16
  50. package/dist/config-center/apply-ledger.js +28 -18
  51. package/dist/config-center/facade.d.ts +12 -6
  52. package/dist/config-center/facade.js +2 -2
  53. package/dist/config-center/hot-keys-registry.d.ts +11 -4
  54. package/dist/config-center/hot-keys-registry.js +11 -7
  55. package/dist/config-center/http-client.d.ts +4 -1
  56. package/dist/config-center/http-client.js +15 -10
  57. package/dist/config-center/read-warnings.d.ts +115 -6
  58. package/dist/config-center/read-warnings.js +115 -5
  59. package/dist/config-center/restart-signal.d.ts +21 -14
  60. package/dist/config-center/restart-signal.js +16 -22
  61. package/dist/config-center/types.d.ts +9 -3
  62. package/dist/config-invariants.d.ts +2 -2
  63. package/dist/config-invariants.js +15 -0
  64. package/dist/config-provider.d.ts +4 -0
  65. package/dist/config-provider.js +64 -9
  66. package/dist/config-types.d.ts +57 -13
  67. package/dist/config.js +87 -22
  68. package/dist/cross-session-settings.js +1 -1
  69. package/dist/deployment-governance.d.ts +45 -12
  70. package/dist/deployment-governance.js +37 -9
  71. package/dist/env-name-allowlist-knobs.d.ts +37 -0
  72. package/dist/env-name-allowlist-knobs.js +24 -0
  73. package/dist/fleet-client.d.ts +2 -1
  74. package/dist/hooks/hook-llm.js +13 -4
  75. package/dist/host-lsp-manager.d.ts +41 -0
  76. package/dist/host-lsp-manager.js +15 -0
  77. package/dist/http/active-run-conflict.d.ts +2 -12
  78. package/dist/http/active-run-conflict.js +1 -6
  79. package/dist/http/admission.js +30 -7
  80. package/dist/http/memory-store-refusal-reply.d.ts +24 -0
  81. package/dist/http/memory-store-refusal-reply.js +10 -0
  82. package/dist/http/resume-legs.d.ts +1 -1
  83. package/dist/http/resume-legs.js +14 -10
  84. package/dist/http/route-ctx.d.ts +2 -2
  85. package/dist/http/routes/approvals-assistant.d.ts +1 -1
  86. package/dist/http/routes/approvals-assistant.js +3 -2
  87. package/dist/http/routes/capabilities.js +3 -3
  88. package/dist/http/routes/memory-bundle.js +3 -0
  89. package/dist/http/routes/memory-compliance.js +3 -0
  90. package/dist/http/routes/memory-origin.js +3 -0
  91. package/dist/http/routes/sessions.js +7 -0
  92. package/dist/http/routes/side-query.js +10 -4
  93. package/dist/http/routes/tasks.js +7 -6
  94. package/dist/http/server.d.ts +6 -5
  95. package/dist/http/wire-types.d.ts +6 -3
  96. package/dist/instruction-source-notice.d.ts +97 -0
  97. package/dist/instruction-source-notice.js +78 -0
  98. package/dist/leader/wire.d.ts +20 -12
  99. package/dist/leader/wire.js +7 -6
  100. package/dist/memory-layer-legacy-lock.d.ts +14 -0
  101. package/dist/memory-layer-legacy-lock.js +74 -0
  102. package/dist/memory-store-refusal.d.ts +37 -0
  103. package/dist/memory-store-refusal.js +14 -0
  104. package/dist/model-entry-refusal.d.ts +130 -0
  105. package/dist/model-entry-refusal.js +157 -0
  106. package/dist/model-provider.d.ts +9 -3
  107. package/dist/model-route-endpoint.d.ts +1 -1
  108. package/dist/model-select.d.ts +49 -4
  109. package/dist/model-select.js +48 -17
  110. package/dist/observability/corrupt-read-seat.d.ts +21 -4
  111. package/dist/observability/corrupt-read-seat.js +31 -0
  112. package/dist/observability/fail-open.d.ts +16 -4
  113. package/dist/observability/fail-open.js +16 -4
  114. package/dist/observability/metrics.js +1 -0
  115. package/dist/observability/run-terminal.js +1 -0
  116. package/dist/observability/secret-env-scrub.d.ts +27 -3
  117. package/dist/observability/secret-env-scrub.js +22 -6
  118. package/dist/orchestration/workflow-completion-inbox.d.ts +31 -23
  119. package/dist/orchestration/workflow-completion-inbox.js +8 -3
  120. package/dist/plugins/approval-ask-store-file.d.ts +20 -2
  121. package/dist/plugins/approval-ask-store-file.js +21 -3
  122. package/dist/plugins/approval-ask-store-memory.d.ts +2 -0
  123. package/dist/plugins/approval-ask-store-memory.js +39 -13
  124. package/dist/plugins/approval-ask-store-sql.d.ts +24 -5
  125. package/dist/plugins/approval-ask-store-sql.js +27 -3
  126. package/dist/plugins/caching-session-store.d.ts +6 -0
  127. package/dist/plugins/caching-session-store.js +6 -0
  128. package/dist/plugins/checkpoint-store-sql.d.ts +9 -3
  129. package/dist/plugins/checkpoint-store-sql.js +19 -2
  130. package/dist/plugins/local-checkpoint-store.js +2 -0
  131. package/dist/plugins/local-session-store.d.ts +20 -25
  132. package/dist/plugins/local-session-store.js +111 -64
  133. package/dist/plugins/mailbox-store-sql.d.ts +7 -5
  134. package/dist/plugins/mailbox-store-sql.js +6 -4
  135. package/dist/plugins/permission-rule-store-file.js +3 -2
  136. package/dist/plugins/pg-session-storage.d.ts +7 -0
  137. package/dist/plugins/pg-session-storage.js +19 -0
  138. package/dist/plugins/remote-env-host.d.ts +3 -1
  139. package/dist/plugins/remote-env-host.js +3 -6
  140. package/dist/plugins/sql-json-column.d.ts +16 -3
  141. package/dist/plugins/sql-json-column.js +15 -4
  142. package/dist/plugins/tidb-pool.js +5 -0
  143. package/dist/plugins/tidb-session-store.d.ts +13 -0
  144. package/dist/plugins/tidb-session-store.js +14 -0
  145. package/dist/plugins/web-search.d.ts +44 -23
  146. package/dist/plugins/web-search.js +161 -50
  147. package/dist/project-memory.d.ts +10 -0
  148. package/dist/project-memory.js +28 -14
  149. package/dist/run-local.d.ts +17 -15
  150. package/dist/run-local.js +119 -18
  151. package/dist/runs.js +6 -5
  152. package/dist/runtime-governance.d.ts +50 -3
  153. package/dist/runtime-governance.js +5 -0
  154. package/dist/sealed-key.d.ts +5 -2
  155. package/dist/server-secret-env.d.ts +26 -2
  156. package/dist/server-secret-env.js +9 -0
  157. package/dist/task-settings.d.ts +1 -1
  158. package/dist/tool-approval.d.ts +150 -28
  159. package/dist/tool-approval.js +150 -54
  160. package/dist/trace/core-keyset-guard.d.ts +30 -8
  161. package/dist/trace/engine-notice-wire.d.ts +27 -1
  162. package/dist/trace/engine-notice-wire.js +8 -0
  163. package/dist/trace/ledger-sink.js +2 -2
  164. package/dist/trace/project.d.ts +13 -0
  165. package/dist/trace/project.js +22 -5
  166. package/dist/trace/projection-drop.d.ts +2 -0
  167. package/dist/trace/projection-drop.js +6 -0
  168. package/dist/trace/sema-provenance.d.ts +4 -1
  169. package/dist/trace/sema-provenance.js +1 -1
  170. package/dist/trace/task-notification-facets.d.ts +65 -0
  171. package/dist/trace/task-notification-facets.js +31 -0
  172. package/dist/trace/wire-projection-faces.d.ts +3 -3
  173. package/dist/trace/wire-projection-faces.js +3 -3
  174. package/package.json +3 -3
@@ -16,6 +16,41 @@ export function resolveConsolidationDriverSeat(deps) {
16
16
  }
17
17
  return { options, seat: seatLabel(deps), model: options.model };
18
18
  }
19
+ export function createConsolidationSeatWatch(plane) {
20
+ const baked = consolidationSeatFingerprint(plane());
21
+ return { read: () => ({ baked, current: consolidationSeatFingerprint(plane()) }) };
22
+ }
23
+ function consolidationSeatFingerprint(plane) {
24
+ const stop = new Error("consolidation seat probe: stopped before any request");
25
+ const refuse = () => {
26
+ throw stop;
27
+ };
28
+ const probeBrain = { stream: refuse, complete: refuse };
29
+ const seen = {};
30
+ let options;
31
+ try {
32
+ options = resolveMemoryConsolidationDriver({
33
+ ...plane,
34
+ brain: probeBrain,
35
+ getApiKeyAndHeaders: (model) => {
36
+ seen.model = model;
37
+ throw stop;
38
+ },
39
+ });
40
+ }
41
+ catch (err) {
42
+ return { unresolvable: err instanceof Error ? err.message : String(err) };
43
+ }
44
+ void options.chat({ system: "", user: "", maxTokens: 1, temperature: 0 }).catch(() => undefined);
45
+ if (seen.model === undefined) {
46
+ throw new Error("MEMORY_CONSOLIDATION_DRIVER=on, but the consolidation seat's restart probe could not observe which model the " +
47
+ "engine's seat resolver chose (the resolved chat seat no longer asks the per-model credential seat before its " +
48
+ "first await) — refusing rather than leave this seat's restart signal blind. This is an engine-pickup defect " +
49
+ "in boot/memory-consolidation.ts (createConsolidationSeatWatch), not a deployment setting.");
50
+ }
51
+ const { cost: _cost, ...route } = seen.model;
52
+ return route;
53
+ }
19
54
  function seatLabel(deps) {
20
55
  if (deps.memoryConsolidationDriver?.chat !== undefined)
21
56
  return "explicit";
@@ -29,6 +29,7 @@ export function createParkedReviveInheritedGate(deps) {
29
29
  : { env: createHostAdjudicationEnv(config, localRoot), ...homeBase };
30
30
  const rootSessionId = row.rootSessionId;
31
31
  const baseline = createApprovalBaselinePolicy(config, {
32
+ kind: "durable",
32
33
  question,
33
34
  ...(approvalExemptionStore && rootSessionId
34
35
  ? {
@@ -120,6 +120,7 @@ export function startReapers(ctx) {
120
120
  pendingGraceMs: config.streamApproval.pendingGraceMs,
121
121
  adhocGraceMs: config.streamApproval.adhocGraceMs,
122
122
  orphanTtlMs: config.streamApproval.orphanTtlMs,
123
+ unattendedPolicy: config.unattendedApprovalPolicy,
123
124
  ...(toolApproval ? { emitRevoke: (frame, target) => void toolApproval.emitRevoke(frame, target) } : {}),
124
125
  });
125
126
  })();
@@ -79,7 +79,6 @@ export interface ResolveSpecCtx {
79
79
  */
80
80
  approverSeat: RunnerDepsOnAsk | undefined;
81
81
  approvalExemptionStore: ReturnType<StoreBackend["approvalExemption"]> | undefined;
82
- singleUserAutoAcceptBaseline: boolean;
83
82
  checkpointStore: ReturnType<NonNullable<StoreBackend["checkpoint"]>> | undefined;
84
83
  deploymentHooks: NonNullable<RunnerDeps["hooks"]>;
85
84
  imageIndex: ReturnType<NonNullable<StoreBackend["imageIndex"]>> | undefined;
@@ -10,13 +10,15 @@ import { stampHandsLane, toolPolicyForHands } from "../capabilities/hands-lane.j
10
10
  import { buildNoticeLaneFacts, shouldDiscloseNoPersistentMemory, withNoPersistentMemoryNotice } from "../capabilities/memory-notice.js";
11
11
  import { applyLongtailDefer } from "../capabilities/tool-defer.js";
12
12
  import { assertGuardPatternsUsable, buildOnlySensitiveBaselineWarning, createApprovalBaselinePolicy, createDeploymentGovernanceInputs } from "../deployment-governance.js";
13
+ import { singleUserAutoAcceptBaselineApplies } from "../approval.js";
13
14
  import { acceptShellScratchpadDir, buildEnvFacts, egressForRemoteExec, ensureScratchpadDir, resumeFactsForLane, scratchpadCoveringTaskRoot } from "../env-facts.js";
14
15
  import { FleetEventBus } from "../fleet/fleet-bus.js";
15
16
  import { composeHooks, createTaskHooks } from "../hooks/hook-runner.js";
16
17
  import { HOST_POSTURE_REFUSED_CODE, taskApproverPostureHonored, taskWriteFaceRefusal } from "../hosted-posture.js";
17
18
  import { headerStr } from "../http/principal-gate.js";
18
19
  import { explicitOperatorOk } from "../http/server.js";
19
- import { isModelAllowlisted, matchCatalogModel, modelSupportsImages, resolveTaskModel, terminalCatalogName } from "../model-select.js";
20
+ import { isModelAllowlisted, matchCatalogModel, modelSupportsImages, refusedCatalogEntry, resolveTaskModel, selectableCatalog, terminalCatalogName } from "../model-select.js";
21
+ import { modelUnavailableMessage } from "../model-entry-refusal.js";
20
22
  import { PerTaskImageRegistry, resolveSandboxImageRef } from "../per-task-image.js";
21
23
  import { isRemoteScratchpadLane, remoteScratchpadDirFor } from "../plugins/remote-scratchpad.js";
22
24
  import { bindAttachmentsForTask } from "../plugins/task-attachment-store.js";
@@ -40,9 +42,12 @@ import { executionLaneCaps, executionLaneHomeDir, executionLaneOf } from "../exe
40
42
  import { effectiveMemoryPersistenceCapable } from "./memory-boundary.js";
41
43
  import { memoryFaceMounted } from "../memory-scope.js";
42
44
  export function createResolveSpec(ctx) {
43
- const { config, logger, metrics, localRoot, scenarios, principalCaps, centerRuntimeCapsResolver, getCenterPrompts, getKeyResolver, taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv, fenceSessionOwner, hookLlm, hookAgent, fleetBus, hookWakeBus, noteSessionShellGate, resumeAnchorStore, ownerAware, taskLimitCaps, taskTimeoutSec, selectEnvTool, sendUserFileToolSpec, memoryEngine, durableEnabled, approvalExemptionStore, singleUserAutoAcceptBaseline, checkpointStore, deploymentHooks, imageIndex, perTaskImage, sessionEnvSelection, liveQuestionFace, approverSeat, lockedKeys, } = ctx;
45
+ const { config, logger, metrics, localRoot, scenarios, principalCaps, centerRuntimeCapsResolver, getCenterPrompts, getKeyResolver, taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv, fenceSessionOwner, hookLlm, hookAgent, fleetBus, hookWakeBus, noteSessionShellGate, resumeAnchorStore, ownerAware, taskLimitCaps, taskTimeoutSec, selectEnvTool, sendUserFileToolSpec, memoryEngine, durableEnabled, approvalExemptionStore, checkpointStore, deploymentHooks, imageIndex, perTaskImage, sessionEnvSelection, liveQuestionFace, approverSeat, lockedKeys, } = ctx;
44
46
  assertGuardPatternsUsable(config);
45
- const onlySensitiveBaseline = buildOnlySensitiveBaselineWarning(config, { durableEnabled, singleUserAutoAcceptBaseline });
47
+ const onlySensitiveBaseline = buildOnlySensitiveBaselineWarning(config, {
48
+ approvalSeat: durableEnabled ? "durable" : "absent",
49
+ singleUserAutoAcceptBaseline: singleUserAutoAcceptBaselineApplies(config),
50
+ });
46
51
  const realTaskRootOf = (auth) => {
47
52
  if (isSandboxPathAdjudicationLane(config.remoteExec?.provider))
48
53
  return undefined;
@@ -216,8 +221,16 @@ export function createResolveSpec(ctx) {
216
221
  if (rawAddReadDirs !== undefined && !cwdHonored(config)) {
217
222
  logger.warn("task_additional_read_directories_ignored", { honored: false, sessionId: auth?.sessionId ?? null });
218
223
  }
219
- const wireCatalog = expandTiers(config.models, config.tiers) ?? config.models;
220
- const picked = resolveTaskModel(body.model ?? parsedSettings.settings?.model, objective, wireCatalog, config.atModelAllowlist);
224
+ const wireCatalog = selectableCatalog(config.models, config.tiers, config.modelRefusals);
225
+ const picked = resolveTaskModel(body.model ?? parsedSettings.settings?.model, objective, wireCatalog, config.atModelAllowlist, config.modelRefusals);
226
+ if (picked.unavailable !== undefined) {
227
+ const { requested, name, refusal, source } = picked.unavailable;
228
+ if (opts?.leg === "fresh") {
229
+ throw new HttpError(400, modelUnavailableMessage(source === "mention" ? "@-mention" : "model", requested.slice(0, 120), name, refusal), { code: "request.model_unavailable" });
230
+ }
231
+ metrics.inc("task_model_unavailable_fallback_total");
232
+ logger.warn("task_model_unavailable_fallback", { requested: requested.slice(0, 120), name, code: refusal.code, source, fallback: picked.model, sessionId: auth?.sessionId ?? null });
233
+ }
221
234
  if (picked.notAllowed !== undefined) {
222
235
  const { requested, resolved, source } = picked.notAllowed;
223
236
  if (opts?.leg === "fresh") {
@@ -339,7 +352,11 @@ export function createResolveSpec(ctx) {
339
352
  ...((() => {
340
353
  if (typeof body.compactionModel !== "string" || body.compactionModel.length === 0)
341
354
  return {};
342
- const cm = matchCatalogModel(body.compactionModel, wireCatalog);
355
+ const cm = matchCatalogModel(body.compactionModel, wireCatalog, config.modelRefusals);
356
+ const refusedCm = cm === undefined ? refusedCatalogEntry(body.compactionModel, config.modelRefusals) : undefined;
357
+ if (refusedCm !== undefined && opts?.leg === "fresh") {
358
+ throw new HttpError(400, modelUnavailableMessage("compactionModel", body.compactionModel.slice(0, 120), refusedCm.name, refusedCm.refusal), { code: "request.model_unavailable" });
359
+ }
343
360
  if (cm === undefined) {
344
361
  if (opts?.leg === "fresh") {
345
362
  throw new HttpError(400, `unknown compactionModel "${body.compactionModel.slice(0, 120)}" — not in the configured catalog (name, tier word, or id; a catalog refresh may have removed it mid-request)`);
@@ -348,8 +365,8 @@ export function createResolveSpec(ctx) {
348
365
  logger.warn("compaction_model_unknown_fallback", { requested: body.compactionModel.slice(0, 120), sessionId: auth?.sessionId ?? null });
349
366
  return {};
350
367
  }
351
- if (!isModelAllowlisted(cm, wireCatalog, config.atModelAllowlist)) {
352
- const terminal = terminalCatalogName(cm, wireCatalog) ?? cm;
368
+ if (!isModelAllowlisted(cm, wireCatalog, config.atModelAllowlist, config.modelRefusals)) {
369
+ const terminal = terminalCatalogName(cm, wireCatalog, config.modelRefusals) ?? cm;
353
370
  if (opts?.leg === "fresh") {
354
371
  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" });
355
372
  }
@@ -413,6 +430,7 @@ export function createResolveSpec(ctx) {
413
430
  promptProvider: centerDecls ? centerPromptProvider(centerDecls, scenarioName) : cap.promptProvider,
414
431
  toolPolicy: toolPolicyForHands(hands, durableEnabled
415
432
  ? createApprovalBaselinePolicy(config, {
433
+ kind: "durable",
416
434
  question: liveQuestionFace,
417
435
  ...(approvalExemptionStore && auth?.sessionId
418
436
  ? {
@@ -421,8 +439,8 @@ export function createResolveSpec(ctx) {
421
439
  }
422
440
  : {}),
423
441
  })
424
- : singleUserAutoAcceptBaseline
425
- ? createApprovalBaselinePolicy(config)
442
+ : singleUserAutoAcceptBaselineApplies(config)
443
+ ? createApprovalBaselinePolicy(config, { kind: "absent" })
426
444
  : undefined),
427
445
  ...(durableEnabled
428
446
  ? {
@@ -5,8 +5,8 @@
5
5
  * `deps-literal-shape-gate` 的顶层条件展开门覆盖面不变);新增的只有 import 与包壳。
6
6
  *
7
7
  * ⚠️ **位置即契约**:必须晚于 stores/exec-env/coordinators/workflow 段(所有键都是它们的产物),
8
- * 且早于 `new Runner(runnerDeps)` —— Runner 构造会冻结 tier 展开后的私有目录副本
9
- * (`runnerTierFrozen` 判据就取自构造那一刻的 `config.tiers`)。
8
+ * 且早于 `new Runner(runnerDeps)` —— Runner 构造时展开 tier 表成私有目录副本(之后的换代经
9
+ * `Runner.swapDeps` 换进,见 boot/stage-08-reapers.ts)。
10
10
  * `getRunStore()` 是唯一的晚绑取值(runStore 在本段之后才构造),原文靠同作用域前向引用。
11
11
  */
12
12
  import { type CacheBreakFinding, type RunnerDeps, type WorkflowRunStore, type AskOutcome } from "@sema-agent/core";
@@ -11,9 +11,11 @@ import { resolveServedSession } from "../orchestration/workflow-completion-inbox
11
11
  import { defaultEngineNoticeRouter } from "../trace/engine-notice-wire.js";
12
12
  import { WorkflowNotifyGate } from "../orchestration/workflow-notify-journal.js";
13
13
  import { makeLoadProjectMemory, makeProbeInstructionSources } from "../project-memory.js";
14
+ import { createInstructionSourceSeat } from "../instruction-source-notice.js";
14
15
  import { workflowModelAllowlistFor } from "../task-workflow.js";
15
16
  import { buildCrossSessionInboundLayers, crossSessionDialogExpiryOf } from "../cross-session-settings.js";
16
17
  import { createPeerDirectory } from "../peer-directory.js";
18
+ import { targetOutsideStoreInIncident } from "../memory-store-refusal.js";
17
19
  export function createRunnerDepsOnAsk(toolApproval) {
18
20
  if (!toolApproval)
19
21
  return undefined;
@@ -188,8 +190,10 @@ export function createRunnerDeps(ctx) {
188
190
  metrics.inc("memory_harvest_total", { ok: String(report.ok), phase: info.phase, incident: report.incident?.kind ?? "none" });
189
191
  if (report.patches)
190
192
  metrics.inc("memory_harvest_patches_total", { phase: info.phase }, (report.patches.add ?? 0) + (report.patches.update ?? 0));
191
- if (report.incident)
192
- logger.warn("memory_harvest_incident", { kind: report.incident.kind, phase: info.phase });
193
+ if (report.incident) {
194
+ const code = targetOutsideStoreInIncident(report.incident);
195
+ logger.warn("memory_harvest_incident", { kind: report.incident.kind, phase: info.phase, ...(code !== undefined ? { code } : {}) });
196
+ }
193
197
  const byCode = new Map();
194
198
  for (const r of [...(report.rejections ?? []), ...(report.inboundFindings ?? [])])
195
199
  byCode.set(r.code, (byCode.get(r.code) ?? 0) + 1);
@@ -209,7 +213,9 @@ export function createRunnerDeps(ctx) {
209
213
  fileHistoryStore: fileHistoryStore ? fileHistoryStore : undefined,
210
214
  permissionRuleStore: permissionRuleStore ? permissionRuleStore : undefined,
211
215
  onBackgroundChildEvent: fleetBackgroundChildPublisher(fleetBus, (msg, fields) => logger.info(msg, fields)),
212
- loadProjectMemory: config.requirePrincipal !== true && config.projectMemoryEnabled ? makeLoadProjectMemory({ logger }) : undefined,
216
+ loadProjectMemory: config.requirePrincipal !== true && config.projectMemoryEnabled
217
+ ? makeLoadProjectMemory({ logger, instructionSource: createInstructionSourceSeat(sessionStore, sharedRunnerDeps.onNotice) })
218
+ : undefined,
213
219
  probeInstructionSources: config.remoteExec?.provider === "host" && config.requirePrincipal !== true && config.projectMemoryEnabled
214
220
  ? makeProbeInstructionSources()
215
221
  : undefined,
@@ -1,8 +1,17 @@
1
1
  import { createUnpricedCeilingVerdict } from "./unpriced-ceiling-verdict.js";
2
2
  import { createConfigCenterRuntime } from "./config-center.js";
3
+ import { defaultModelRefusal, refusedNameMintedRefusal } from "../model-entry-refusal.js";
3
4
  export async function runStage02(ctx) {
4
5
  const { config, localRoot, logger, metrics } = ctx;
5
6
  const configCenter = await createConfigCenterRuntime({ config, logger, metrics, localRoot });
7
+ const noDefaultModel = defaultModelRefusal(config, "env");
8
+ if (noDefaultModel !== undefined) {
9
+ throw new Error(noDefaultModel);
10
+ }
11
+ const mintedRefused = refusedNameMintedRefusal(config);
12
+ if (mintedRefused !== undefined) {
13
+ throw new Error(mintedRefused);
14
+ }
6
15
  await configCenter.applyLocalRemoteExec();
7
16
  const ceilingVerdict = createUnpricedCeilingVerdict({ config, logger });
8
17
  ceilingVerdict.judge();
@@ -5,7 +5,7 @@ export declare function runStage05(ctx: Awaited<ReturnType<typeof runStage04>>):
5
5
  dropSessionScoped: (sid: string) => void;
6
6
  executionEnvFactory: import("@sema-agent/core").ExecutionEnvFactory | undefined;
7
7
  fenceSessionOwner: (sid: string, owner: string | null) => void;
8
- lspManager: import("../lsp/manager.js").E2bLspManager | import("@sema-agent/core").NodeLspManager | undefined;
8
+ lspManager: import("@sema-agent/core").NodeLspManager | import("../lsp/manager.js").E2bLspManager | undefined;
9
9
  perSessionCwd: Map<string, string>;
10
10
  perTaskImage: import("../per-task-image.js").PerTaskImageRegistry;
11
11
  sendUserFileTaskEnvs: import("../capabilities/sandbox-file-send.js").TaskEnvRegistry | undefined;
@@ -13,6 +13,7 @@ export declare function runStage06(ctx: Awaited<ReturnType<typeof runStage05>>):
13
13
  approvalAskAudit: import("../approval-ask-audit-store.js").FileApprovalAskAuditStore | undefined;
14
14
  centerRuntimeCapsResolver: ((principal: string | undefined) => Promise<import("@sema-agent/core").RuntimeCaps | undefined>) | undefined;
15
15
  checkpointStore: import("../plugins/store-backend.js").CheckpointStoreFull | undefined;
16
+ consolidationSeatWatch: import("./memory-consolidation.js").ConsolidationSeatWatch | undefined;
16
17
  durableEnabled: boolean;
17
18
  elicitation: import("../elicitation.js").ElicitationCoordinator | undefined;
18
19
  fleetBus: import("../fleet/fleet-bus.js").FleetEventBus;
@@ -33,7 +34,6 @@ export declare function runStage06(ctx: Awaited<ReturnType<typeof runStage05>>):
33
34
  retentionLaneStore: import("../plugins/retention-lane-store-sql.js").RetentionLaneStore | undefined;
34
35
  runner: Runner;
35
36
  runnerDeps: import("@sema-agent/core").RunnerDeps;
36
- runnerTierFrozen: boolean;
37
37
  runtimeCapsPeekResolver: import("../runtime-caps-resolver.js").EntitlementsResolverFn | undefined;
38
38
  sendFileLedger: import("../plugins/send-file-ledger.js").SendFileLedger | undefined;
39
39
  sendUserFileEmitter: import("../capabilities/send-user-file-tool.js").SendUserFileEmitter | undefined;
@@ -66,7 +66,7 @@ export declare function runStage06(ctx: Awaited<ReturnType<typeof runStage05>>):
66
66
  dropSessionScoped: (sid: string) => void;
67
67
  executionEnvFactory: import("@sema-agent/core").ExecutionEnvFactory | undefined;
68
68
  fenceSessionOwner: (sid: string, owner: string | null) => void;
69
- lspManager: import("../lsp/manager.js").E2bLspManager | import("@sema-agent/core").NodeLspManager | undefined;
69
+ lspManager: import("@sema-agent/core").NodeLspManager | import("../lsp/manager.js").E2bLspManager | undefined;
70
70
  perSessionCwd: Map<string, string>;
71
71
  perTaskImage: import("../per-task-image.js").PerTaskImageRegistry;
72
72
  sendUserFileTaskEnvs: import("../capabilities/sandbox-file-send.js").TaskEnvRegistry | undefined;
@@ -10,7 +10,7 @@ import { workflowModelAllowlistFor } from "../task-workflow.js";
10
10
  import { backendOwnsControlPlane } from "../memory-operator-faces.js";
11
11
  import { createHookLlm, buildHookFailureText } from "../hooks/hook-llm.js";
12
12
  import { assertRetentionLaneWirable } from "./retention-lane.js";
13
- import { assertConsolidationDriverWirable, buildConsolidationValveAudit, createMemoryConsolidationFaces, resolveConsolidationDriverSeat } from "./memory-consolidation.js";
13
+ import { assertConsolidationDriverWirable, buildConsolidationValveAudit, createConsolidationSeatWatch, createMemoryConsolidationFaces, resolveConsolidationDriverSeat } from "./memory-consolidation.js";
14
14
  import { createPerModelAuthSeat } from "./side-query-lane.js";
15
15
  import { createWorkflowOrchestration } from "./workflow-orchestration.js";
16
16
  import { createLiveCoordinators } from "./coordinators.js";
@@ -72,6 +72,7 @@ export function runStage06(ctx) {
72
72
  getApiKeyAndHeaders: createPerModelAuthSeat(() => configCenter.getKeyResolver()),
73
73
  })
74
74
  : undefined;
75
+ const consolidationSeatWatch = consolidationSeat ? createConsolidationSeatWatch(() => ({ models: config.models, tiers: config.tiers, roles: config.roles })) : undefined;
75
76
  const memoryConsolidationFaces = consolidationSeat && memoryEngine
76
77
  ? createMemoryConsolidationFaces(memoryEngine, {
77
78
  seat: consolidationSeat,
@@ -130,7 +131,6 @@ export function runStage06(ctx) {
130
131
  });
131
132
  const runner = new Runner(runnerDeps);
132
133
  const handslessRunner = new Runner(withoutExecutionEnv(runnerDeps));
133
- const runnerTierFrozen = Object.keys(config.tiers).length > 0;
134
134
  const { hookModelFor, hookLlm } = createHookLlm({ config, getKeyResolver: () => configCenter.getKeyResolver(), metrics });
135
135
  const hookAgentRunner = new Runner({ ...runnerDeps, sessionStore: new TtlSessionStore({ defaultTtlDays: 1 / 24 }) });
136
136
  const agentHookCall = async ({ prompt, model, timeoutMs, system }) => {
@@ -212,6 +212,6 @@ export function runStage06(ctx) {
212
212
  };
213
213
  const subRunner = new Runner(subRunnerDeps);
214
214
  const handslessSubRunner = new Runner(withoutExecutionEnv(subRunnerDeps));
215
- return { ...ctx, approvalAskAudit, centerRuntimeCapsResolver, checkpointStore, durableEnabled, elicitation, fleetBus, governanceSeams, handslessRunner, handslessSubRunner, hookAgent, hookAgentRunner, hookLlm, mcpRevocations, memoryConsolidationFaces, memoryOptOutGrantStore, orgMemoryAdmission, outcomeSink, principalCaps, question, retentionExecutor, retentionLaneStore, runner, runnerDeps, runnerTierFrozen, runtimeCapsPeekResolver, sendFileLedger, sendUserFileEmitter, sendUserFileToolSpec, sessionShellGateRegistry, sessionTitler, sharedMemoryStore, sqlWorkflowRunStore, streamApprovalGate, subRunner, subRunnerSessions, subagentSteerRegistry, toolApproval, workflowAgentRegistry, workflowAgentSessionIndex, workflowCompletionInbox, workflowJournalStore, workflowModelAllowlistSnapshot, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, workflowRunStore, workflowsCapable };
215
+ return { ...ctx, approvalAskAudit, centerRuntimeCapsResolver, checkpointStore, consolidationSeatWatch, durableEnabled, elicitation, fleetBus, governanceSeams, handslessRunner, handslessSubRunner, hookAgent, hookAgentRunner, hookLlm, mcpRevocations, memoryConsolidationFaces, memoryOptOutGrantStore, orgMemoryAdmission, outcomeSink, principalCaps, question, retentionExecutor, retentionLaneStore, runner, runnerDeps, runtimeCapsPeekResolver, sendFileLedger, sendUserFileEmitter, sendUserFileToolSpec, sessionShellGateRegistry, sessionTitler, sharedMemoryStore, sqlWorkflowRunStore, streamApprovalGate, subRunner, subRunnerSessions, subagentSteerRegistry, toolApproval, workflowAgentRegistry, workflowAgentSessionIndex, workflowCompletionInbox, workflowJournalStore, workflowModelAllowlistSnapshot, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, workflowRunStore, workflowsCapable };
216
216
  }
217
217
  //# sourceMappingURL=stage-06-runners.js.map
@@ -17,7 +17,6 @@ export declare function runStage07(ctx: Awaited<ReturnType<typeof runStage06>>):
17
17
  scenarioDetails: Record<string, import("../capabilities/scenarios.js").ScenarioDetail>;
18
18
  scenarios: Record<string, import("../capabilities/scenarios.js").Scenario>;
19
19
  selectEnvTool: import("@sema-agent/core").ToolSpec<import("@sema-agent/core").TSchema> | undefined;
20
- singleUserAutoAcceptBaseline: boolean;
21
20
  taskLimitCaps: {
22
21
  timeoutSec: number | undefined;
23
22
  maxOutputTokens: number | undefined;
@@ -28,6 +27,7 @@ export declare function runStage07(ctx: Awaited<ReturnType<typeof runStage06>>):
28
27
  approvalAskAudit: import("../approval-ask-audit-store.js").FileApprovalAskAuditStore | undefined;
29
28
  centerRuntimeCapsResolver: ((principal: string | undefined) => Promise<import("@sema-agent/core").RuntimeCaps | undefined>) | undefined;
30
29
  checkpointStore: import("../plugins/store-backend.js").CheckpointStoreFull | undefined;
30
+ consolidationSeatWatch: import("./memory-consolidation.js").ConsolidationSeatWatch | undefined;
31
31
  durableEnabled: boolean;
32
32
  elicitation: import("../elicitation.js").ElicitationCoordinator | undefined;
33
33
  fleetBus: import("../fleet/fleet-bus.js").FleetEventBus;
@@ -48,7 +48,6 @@ export declare function runStage07(ctx: Awaited<ReturnType<typeof runStage06>>):
48
48
  retentionLaneStore: import("../plugins/retention-lane-store-sql.js").RetentionLaneStore | undefined;
49
49
  runner: import("@sema-agent/core").Runner;
50
50
  runnerDeps: import("@sema-agent/core").RunnerDeps;
51
- runnerTierFrozen: boolean;
52
51
  runtimeCapsPeekResolver: import("../runtime-caps-resolver.js").EntitlementsResolverFn | undefined;
53
52
  sendFileLedger: import("../plugins/send-file-ledger.js").SendFileLedger | undefined;
54
53
  sendUserFileEmitter: import("../capabilities/send-user-file-tool.js").SendUserFileEmitter | undefined;
@@ -81,7 +80,7 @@ export declare function runStage07(ctx: Awaited<ReturnType<typeof runStage06>>):
81
80
  dropSessionScoped: (sid: string) => void;
82
81
  executionEnvFactory: import("@sema-agent/core").ExecutionEnvFactory | undefined;
83
82
  fenceSessionOwner: (sid: string, owner: string | null) => void;
84
- lspManager: import("../lsp/manager.js").E2bLspManager | import("@sema-agent/core").NodeLspManager | undefined;
83
+ lspManager: import("@sema-agent/core").NodeLspManager | import("../lsp/manager.js").E2bLspManager | undefined;
85
84
  perSessionCwd: Map<string, string>;
86
85
  perTaskImage: import("../per-task-image.js").PerTaskImageRegistry;
87
86
  sendUserFileTaskEnvs: import("../capabilities/sandbox-file-send.js").TaskEnvRegistry | undefined;
@@ -6,7 +6,7 @@ import { parseCapEnv, parseNumOrFailNonNegative } from "../config.js";
6
6
  import { ensureChildSessionDurableWithPromotion } from "../plugins/session-store.js";
7
7
  import { webSearchConfigFromEnv, createWebSearchBackend, shouldProbeWebSearchOnBoot } from "../plugins/web-search.js";
8
8
  import { createAuthorizer } from "../security.js";
9
- import { assertGateIntentServiceable, buildForceDurableGateInertNotice, buildNoResponderBootWarns, hasOperatorGateIntent } from "../approval.js";
9
+ import { buildForceDurableGateInertNotice, buildNoResponderBootWarns, gateIntentUnserviceableReason, singleUserAutoAcceptBaselineApplies } from "../approval.js";
10
10
  import { executionLaneOf } from "../execution-lane-caps.js";
11
11
  import { loadDeploymentSkills } from "../capabilities/skills.js";
12
12
  import { createRepoClient } from "../capabilities/repo-tools.js";
@@ -46,9 +46,9 @@ export async function runStage07(ctx) {
46
46
  maxOutputTokens: capEnv("TASK_MAX_OUTPUT_TOKENS_MAX"),
47
47
  maxTurns: capEnv("TASK_MAX_TURNS_MAX"),
48
48
  };
49
- const operatorGateIntent = hasOperatorGateIntent(config);
50
- assertGateIntentServiceable(config, checkpointStore !== undefined);
51
- const singleUserAutoAcceptBaseline = config.requirePrincipal !== true && !operatorGateIntent;
49
+ const gateRefusal = gateIntentUnserviceableReason(config, checkpointStore !== undefined);
50
+ if (gateRefusal !== undefined)
51
+ throw new Error(gateRefusal);
52
52
  await reclaimOrphansAtBoot(runStore, checkpointStore, logger);
53
53
  const imageIndex = backend?.imageIndex ? backend.imageIndex() : undefined;
54
54
  const selectEnvTool = config.selectEnvironmentTool && config.remoteExec?.provider === "k8s" && imageIndex
@@ -79,7 +79,7 @@ export async function runStage07(ctx) {
79
79
  approvalFaceWired: toolApproval !== undefined || durableEnabled,
80
80
  }))
81
81
  logger.warn(w.event, w.fields);
82
- if (singleUserAutoAcceptBaseline) {
82
+ if (singleUserAutoAcceptBaselineApplies(config)) {
83
83
  logger.info("tool_policy_single_user_default", {
84
84
  posture: "adjudicated auto-accept — ALL write/hand/MCP tool surfaces auto-allowed (core per-surface UNGATED enumeration suppressed for single-user turnkey)",
85
85
  tighten: "APPROVAL_REQUIRE / AUTONOMY / commandPolicy (re-surfaces + gates specific surfaces)",
@@ -155,6 +155,6 @@ export async function runStage07(ctx) {
155
155
  const builtinScenarioNames = Object.keys(scenarioDetails);
156
156
  configCenter.applyCenterScenarios({ scenarioDeps, scenarios, scenarioDetails, builtinScenarioNames });
157
157
  logger.info("capabilities", { skills: skills.length, scenarios: Object.keys(scenarios), repoTools: Boolean(repoClient) });
158
- return { ...ctx, approvalExemptionStore, approvalNonceStore, authorize, imageBakes, imageIndex, parkedReviveInheritedGate, parkedReviveTool, rateLimiter, resumeAnchorStore, runStore, scenarioDetails, scenarios, selectEnvTool, singleUserAutoAcceptBaseline, taskLimitCaps, taskTimeoutSec, webSearchProvider: webSearchCfg?.provider };
158
+ return { ...ctx, approvalExemptionStore, approvalNonceStore, authorize, imageBakes, imageIndex, parkedReviveInheritedGate, parkedReviveTool, rateLimiter, resumeAnchorStore, runStore, scenarioDetails, scenarios, selectEnvTool, taskLimitCaps, taskTimeoutSec, webSearchProvider: webSearchCfg?.provider };
159
159
  }
160
160
  //# sourceMappingURL=stage-07-capability-layer.js.map
@@ -2,7 +2,7 @@
2
2
  * 装配第 8 段 —— **后台 reaper**(§3-8)。
3
3
  * 维护 tick(startReapers)+ 托管留存 lane(独立定时器)+ OTLP 导出 + 限额座换代口 + 五只 boot Runner 的
4
4
  * 原子换代闭包 + config-center 刷新环与 key resolver 首建。
5
- * ⚠️ 位置即契约:刷新环必须在 `new Runner` 之后(runnerTierFrozen 与构造函数读同一 config 代际);
5
+ * ⚠️ 位置即契约:刷新环必须在 `new Runner` 之后(它要五只 boot Runner 的换代口 `swapRunnerDeps`);
6
6
  * key resolver 首建读的必须是 boot apply 之后的 config。
7
7
  * 🔴 `runDenySweep` 的 holder 住在 `late-binds.ts`(赋值点在第十段的 server 之后)。
8
8
  */
@@ -30,7 +30,6 @@ export declare function runStage08(ctx: Awaited<ReturnType<typeof runStage07>>):
30
30
  scenarioDetails: Record<string, import("../capabilities/scenarios.js").ScenarioDetail>;
31
31
  scenarios: Record<string, import("../index.js").Scenario>;
32
32
  selectEnvTool: import("@sema-agent/core").ToolSpec<import("@sema-agent/core").TSchema> | undefined;
33
- singleUserAutoAcceptBaseline: boolean;
34
33
  taskLimitCaps: {
35
34
  timeoutSec: number | undefined;
36
35
  maxOutputTokens: number | undefined;
@@ -41,6 +40,7 @@ export declare function runStage08(ctx: Awaited<ReturnType<typeof runStage07>>):
41
40
  approvalAskAudit: import("../approval-ask-audit-store.js").FileApprovalAskAuditStore | undefined;
42
41
  centerRuntimeCapsResolver: ((principal: string | undefined) => Promise<import("@sema-agent/core").RuntimeCaps | undefined>) | undefined;
43
42
  checkpointStore: import("../plugins/store-backend.js").CheckpointStoreFull | undefined;
43
+ consolidationSeatWatch: import("./memory-consolidation.js").ConsolidationSeatWatch | undefined;
44
44
  durableEnabled: boolean;
45
45
  elicitation: import("../elicitation.js").ElicitationCoordinator | undefined;
46
46
  fleetBus: import("../fleet/fleet-bus.js").FleetEventBus;
@@ -61,7 +61,6 @@ export declare function runStage08(ctx: Awaited<ReturnType<typeof runStage07>>):
61
61
  retentionLaneStore: import("../plugins/retention-lane-store-sql.js").RetentionLaneStore | undefined;
62
62
  runner: Runner;
63
63
  runnerDeps: import("@sema-agent/core").RunnerDeps;
64
- runnerTierFrozen: boolean;
65
64
  runtimeCapsPeekResolver: import("../runtime-caps-resolver.js").EntitlementsResolverFn | undefined;
66
65
  sendFileLedger: import("../plugins/send-file-ledger.js").SendFileLedger | undefined;
67
66
  sendUserFileEmitter: import("../capabilities/send-user-file-tool.js").SendUserFileEmitter | undefined;
@@ -94,7 +93,7 @@ export declare function runStage08(ctx: Awaited<ReturnType<typeof runStage07>>):
94
93
  dropSessionScoped: (sid: string) => void;
95
94
  executionEnvFactory: import("@sema-agent/core").ExecutionEnvFactory | undefined;
96
95
  fenceSessionOwner: (sid: string, owner: string | null) => void;
97
- lspManager: import("../lsp/manager.js").E2bLspManager | import("@sema-agent/core").NodeLspManager | undefined;
96
+ lspManager: import("@sema-agent/core").NodeLspManager | import("../lsp/manager.js").E2bLspManager | undefined;
98
97
  perSessionCwd: Map<string, string>;
99
98
  perTaskImage: import("../per-task-image.js").PerTaskImageRegistry;
100
99
  sendUserFileTaskEnvs: import("../capabilities/sandbox-file-send.js").TaskEnvRegistry | undefined;
@@ -5,7 +5,7 @@ import { startRetentionLane, RETENTION_LEASE_TTL_FACTOR } from "./retention-lane
5
5
  import { createLimitSync } from "./limit-sync.js";
6
6
  import { runDenySweep } from "./late-binds.js";
7
7
  export function runStage08(ctx) {
8
- const { approvalNonceStore, backend, backgroundAgentStore, ceilingVerdict, checkpointStore, config, configCenter, costQuota, fileHistoryErasure, handslessRunner, handslessSubRunner, hookAgentRunner, imageBakes, instanceId, localRoot, logger, mailboxStore, metrics, permissionRuleStores, pricing, rateLimiter, retentionExecutor, retentionLaneStore, rosterStore, runStore, runner, runnerTierFrozen, sqlWorkflowRunStore, subRunner, taskAttachmentStore, toolApproval, toolResultStore, workflowJournalStore, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, worktreeReap } = ctx;
8
+ const { approvalNonceStore, backend, backgroundAgentStore, ceilingVerdict, checkpointStore, config, configCenter, consolidationSeatWatch, costQuota, fileHistoryErasure, handslessRunner, handslessSubRunner, hookAgentRunner, imageBakes, instanceId, localRoot, logger, mailboxStore, metrics, permissionRuleStores, pricing, rateLimiter, retentionExecutor, retentionLaneStore, rosterStore, runStore, runner, sqlWorkflowRunStore, subRunner, taskAttachmentStore, toolApproval, toolResultStore, workflowJournalStore, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, worktreeReap } = ctx;
9
9
  const reaper = startReapers({
10
10
  config, logger, metrics, localRoot, backend, subRunner, runStore, checkpointStore,
11
11
  rateLimiter, costQuota, toolResultStore, fileHistoryErasure, taskAttachmentStore, imageBakes, worktreeReap,
@@ -71,7 +71,7 @@ export function runStage08(ctx) {
71
71
  }
72
72
  }
73
73
  };
74
- configCenter.startRefreshLoop({ runnerTierFrozen, pricing, limitSync, swapRunnerDeps, ceilingVerdict });
74
+ configCenter.startRefreshLoop({ pricing, limitSync, swapRunnerDeps, ceilingVerdict, checkpointStorePresent: checkpointStore !== undefined, ...(consolidationSeatWatch !== undefined ? { consolidationSeat: consolidationSeatWatch } : {}) });
75
75
  configCenter.initKeyResolver();
76
76
  return { ...ctx, otelExporter, reaper, retentionLaneStarted };
77
77
  }
@@ -64,7 +64,6 @@ export declare function runStage09(ctx: Awaited<ReturnType<typeof runStage08>>):
64
64
  scenarioDetails: Record<string, import("../capabilities/scenarios.js").ScenarioDetail>;
65
65
  scenarios: Record<string, import("../index.js").Scenario>;
66
66
  selectEnvTool: import("@sema-agent/core").ToolSpec<import("@sema-agent/core").TSchema> | undefined;
67
- singleUserAutoAcceptBaseline: boolean;
68
67
  taskLimitCaps: {
69
68
  timeoutSec: number | undefined;
70
69
  maxOutputTokens: number | undefined;
@@ -75,6 +74,7 @@ export declare function runStage09(ctx: Awaited<ReturnType<typeof runStage08>>):
75
74
  approvalAskAudit: import("../approval-ask-audit-store.js").FileApprovalAskAuditStore | undefined;
76
75
  centerRuntimeCapsResolver: ((principal: string | undefined) => Promise<import("@sema-agent/core").RuntimeCaps | undefined>) | undefined;
77
76
  checkpointStore: import("../plugins/store-backend.js").CheckpointStoreFull | undefined;
77
+ consolidationSeatWatch: import("./memory-consolidation.js").ConsolidationSeatWatch | undefined;
78
78
  durableEnabled: boolean;
79
79
  elicitation: import("../elicitation.js").ElicitationCoordinator | undefined;
80
80
  fleetBus: import("../fleet/fleet-bus.js").FleetEventBus;
@@ -95,7 +95,6 @@ export declare function runStage09(ctx: Awaited<ReturnType<typeof runStage08>>):
95
95
  retentionLaneStore: import("../plugins/retention-lane-store-sql.js").RetentionLaneStore | undefined;
96
96
  runner: import("@sema-agent/core").Runner;
97
97
  runnerDeps: import("@sema-agent/core").RunnerDeps;
98
- runnerTierFrozen: boolean;
99
98
  runtimeCapsPeekResolver: import("../runtime-caps-resolver.js").EntitlementsResolverFn | undefined;
100
99
  sendFileLedger: import("../plugins/send-file-ledger.js").SendFileLedger | undefined;
101
100
  sendUserFileEmitter: import("../capabilities/send-user-file-tool.js").SendUserFileEmitter | undefined;
@@ -128,7 +127,7 @@ export declare function runStage09(ctx: Awaited<ReturnType<typeof runStage08>>):
128
127
  dropSessionScoped: (sid: string) => void;
129
128
  executionEnvFactory: import("@sema-agent/core").ExecutionEnvFactory | undefined;
130
129
  fenceSessionOwner: (sid: string, owner: string | null) => void;
131
- lspManager: import("../lsp/manager.js").E2bLspManager | import("@sema-agent/core").NodeLspManager | undefined;
130
+ lspManager: import("@sema-agent/core").NodeLspManager | import("../lsp/manager.js").E2bLspManager | undefined;
132
131
  perSessionCwd: Map<string, string>;
133
132
  perTaskImage: import("../per-task-image.js").PerTaskImageRegistry;
134
133
  sendUserFileTaskEnvs: import("../capabilities/sandbox-file-send.js").TaskEnvRegistry | undefined;
@@ -64,7 +64,6 @@ export declare function runStage10(ctx: Awaited<ReturnType<typeof runStage09>>):
64
64
  scenarioDetails: Record<string, import("../capabilities/scenarios.js").ScenarioDetail>;
65
65
  scenarios: Record<string, import("../index.js").Scenario>;
66
66
  selectEnvTool: import("@sema-agent/core").ToolSpec<import("@sema-agent/core").TSchema> | undefined;
67
- singleUserAutoAcceptBaseline: boolean;
68
67
  taskLimitCaps: {
69
68
  timeoutSec: number | undefined;
70
69
  maxOutputTokens: number | undefined;
@@ -75,6 +74,7 @@ export declare function runStage10(ctx: Awaited<ReturnType<typeof runStage09>>):
75
74
  approvalAskAudit: import("../approval-ask-audit-store.js").FileApprovalAskAuditStore | undefined;
76
75
  centerRuntimeCapsResolver: ((principal: string | undefined) => Promise<import("@sema-agent/core").RuntimeCaps | undefined>) | undefined;
77
76
  checkpointStore: import("../plugins/store-backend.js").CheckpointStoreFull | undefined;
77
+ consolidationSeatWatch: import("./memory-consolidation.js").ConsolidationSeatWatch | undefined;
78
78
  durableEnabled: boolean;
79
79
  elicitation: import("../elicitation.js").ElicitationCoordinator | undefined;
80
80
  fleetBus: import("../fleet/fleet-bus.js").FleetEventBus;
@@ -95,7 +95,6 @@ export declare function runStage10(ctx: Awaited<ReturnType<typeof runStage09>>):
95
95
  retentionLaneStore: import("../plugins/retention-lane-store-sql.js").RetentionLaneStore | undefined;
96
96
  runner: import("@sema-agent/core").Runner;
97
97
  runnerDeps: import("@sema-agent/core").RunnerDeps;
98
- runnerTierFrozen: boolean;
99
98
  runtimeCapsPeekResolver: import("../runtime-caps-resolver.js").EntitlementsResolverFn | undefined;
100
99
  sendFileLedger: import("../plugins/send-file-ledger.js").SendFileLedger | undefined;
101
100
  sendUserFileEmitter: import("../capabilities/send-user-file-tool.js").SendUserFileEmitter | undefined;
@@ -128,7 +127,7 @@ export declare function runStage10(ctx: Awaited<ReturnType<typeof runStage09>>):
128
127
  dropSessionScoped: (sid: string) => void;
129
128
  executionEnvFactory: import("@sema-agent/core").ExecutionEnvFactory | undefined;
130
129
  fenceSessionOwner: (sid: string, owner: string | null) => void;
131
- lspManager: import("../lsp/manager.js").E2bLspManager | import("@sema-agent/core").NodeLspManager | undefined;
130
+ lspManager: import("@sema-agent/core").NodeLspManager | import("../lsp/manager.js").E2bLspManager | undefined;
132
131
  perSessionCwd: Map<string, string>;
133
132
  perTaskImage: import("../per-task-image.js").PerTaskImageRegistry;
134
133
  sendUserFileTaskEnvs: import("../capabilities/sandbox-file-send.js").TaskEnvRegistry | undefined;
@@ -23,7 +23,7 @@ import { bindServerLateSeats } from "./late-binds.js";
23
23
  import { serviceVersion } from "../service-version.js";
24
24
  import { buildDisplaySafeUrl } from "../trace/redact.js";
25
25
  export async function runStage10(ctx) {
26
- const { approvalAskAudit, approvalExemptionStore, approvalNonceStore, authorize, backend, backgroundAgentStore, brain, breakerState, centerRuntimeCapsResolver, checkpointStore, config, configCenter, costQuota, deploymentHooks, deviceLane, drainState, durableEnabled, elicitation, fenceSessionOwner, fileHistoryStore, fleetBus, fleetLease, fleetUsage, governanceSeams, handslessRunner, hookAgent, hookLlm, hookWakeBus, imageBakes, imageIndex, instanceId, instrumentDegenerate, leaderEndpoint, localRoot, logger, lspManager, mcpRevocations, memoryBundleFaces, memoryComplianceFaces, memoryConsolidationFaces, memoryEngine, memoryExportBackend, memoryOptOutGrantStore, memoryOriginFaces, memoryPosture, memorySyncCursors, metrics, modelUsageTracker, orgMemoryAdmission, otelExporter, outcomeSink, ownerAware, parkedReviveInheritedGate, parkedReviveTool, perSessionCwd, perTaskImage, planCacheProbe, pricing, principalCaps, promptManifestTracker, purgeSession, question, rateLimiter, reaper, registryJwtVerifier, resumeAnchorStore, retentionLaneStarted, retentionLaneStore, ruleConsent, runStore, runner, runnerDeps, runtimeCapsPeekResolver, scenarioDetails, scenarios, selectEnvTool, sendFileLedger, sendUserFileEmitter, sendUserFileToolSpec, sessionAudit, sessionEnvSelection, sessionMemoryStatusFace, sessionPolicyStore, sessionShellGateRegistry, sessionTitler, sessionWatchRegistry, setSessionCwd, setSessionShellEnv, sharedMemoryStore, sideQueryAccounting, singleUserAutoAcceptBaseline, sqlEngineFacts, sqlWorkflowRunStore, staticWiring, storeBackendDegraded, subRunner, subagentSteerRegistry, taskAttachmentStore, taskLimitCaps, taskTimeoutSec, toolApproval, toolResultStore, usageWindowStore, webSearchProvider, workflowAgentRegistry, workflowAgentSessionIndex, workflowCompletionInbox, workflowJournalStore, workflowModelAllowlistSnapshot, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, workflowRunStore, workflowsCapable } = ctx;
26
+ const { approvalAskAudit, approvalExemptionStore, approvalNonceStore, authorize, backend, backgroundAgentStore, brain, breakerState, centerRuntimeCapsResolver, checkpointStore, config, configCenter, costQuota, deploymentHooks, deviceLane, drainState, durableEnabled, elicitation, fenceSessionOwner, fileHistoryStore, fleetBus, fleetLease, fleetUsage, governanceSeams, handslessRunner, hookAgent, hookLlm, hookWakeBus, imageBakes, imageIndex, instanceId, instrumentDegenerate, leaderEndpoint, localRoot, logger, lspManager, mcpRevocations, memoryBundleFaces, memoryComplianceFaces, memoryConsolidationFaces, memoryEngine, memoryExportBackend, memoryOptOutGrantStore, memoryOriginFaces, memoryPosture, memorySyncCursors, metrics, modelUsageTracker, orgMemoryAdmission, otelExporter, outcomeSink, ownerAware, parkedReviveInheritedGate, parkedReviveTool, perSessionCwd, perTaskImage, planCacheProbe, pricing, principalCaps, promptManifestTracker, purgeSession, question, rateLimiter, reaper, registryJwtVerifier, resumeAnchorStore, retentionLaneStarted, retentionLaneStore, ruleConsent, runStore, runner, runnerDeps, runtimeCapsPeekResolver, scenarioDetails, scenarios, selectEnvTool, sendFileLedger, sendUserFileEmitter, sendUserFileToolSpec, sessionAudit, sessionEnvSelection, sessionMemoryStatusFace, sessionPolicyStore, sessionShellGateRegistry, sessionTitler, sessionWatchRegistry, setSessionCwd, setSessionShellEnv, sharedMemoryStore, sideQueryAccounting, sqlEngineFacts, sqlWorkflowRunStore, staticWiring, storeBackendDegraded, subRunner, subagentSteerRegistry, taskAttachmentStore, taskLimitCaps, taskTimeoutSec, toolApproval, toolResultStore, usageWindowStore, webSearchProvider, workflowAgentRegistry, workflowAgentSessionIndex, workflowCompletionInbox, workflowJournalStore, workflowModelAllowlistSnapshot, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, workflowRunStore, workflowsCapable } = ctx;
27
27
  const stores = {
28
28
  runStore,
29
29
  resumeAnchorStore: resumeAnchorStore ? resumeAnchorStore : undefined,
@@ -171,7 +171,7 @@ export async function runStage10(ctx) {
171
171
  hookLlm, hookAgent, fleetBus, hookWakeBus, resumeAnchorStore, ownerAware, taskLimitCaps, taskTimeoutSec,
172
172
  noteSessionShellGate: sessionShellGateRegistry.note,
173
173
  selectEnvTool, sendUserFileToolSpec, memoryEngine, durableEnabled, approvalExemptionStore,
174
- singleUserAutoAcceptBaseline, checkpointStore, deploymentHooks, imageIndex, perTaskImage,
174
+ checkpointStore, deploymentHooks, imageIndex, perTaskImage,
175
175
  sessionEnvSelection,
176
176
  lockedKeys: governanceSeams.lockedKeys,
177
177
  liveQuestionFace: question,
@@ -24,6 +24,8 @@ import { assertDeviceAuditRebindEventSchema, ensurePgDeviceSchema, ensureTiDBDev
24
24
  import { mysqlDriver, pgDriver } from "../plugins/sql-driver.js";
25
25
  import { assertCloudSnapshotBlobPosture, openStoreBackendWithFallback } from "../plugins/store-backend.js";
26
26
  import { createMemoryEngineIncidentSink } from "../memory-incident-sink.js";
27
+ import { announceLockedLegacyMemoryLayers } from "../memory-layer-legacy-lock.js";
28
+ import { createEngineNoticeForwarder } from "./runner-deps.js";
27
29
  import { buildMemoryRemoteLaneWarn, memoryEngineBackendFor, memoryEngineRemoteLanePosture, memoryEngineRootFor, memoryMountRootOf } from "../memory-scope.js";
28
30
  import { assertToolResultProvenanceSchema } from "../plugins/tool-result-store-sql.js";
29
31
  import { assertPermissionRuleApprovalSchema, assertPermissionRuleTicketSchema } from "../plugins/permission-rule-store-sql.js";
@@ -186,6 +188,8 @@ export async function openStores(ctx) {
186
188
  }
187
189
  else {
188
190
  memoryEngine = memoryEngineBackendFor(config, undefined, createMemoryEngineIncidentSink({ logger, metrics }));
191
+ if (memoryEngine)
192
+ announceLockedLegacyMemoryLayers(memoryMountRootOf(memoryEngine.backend, memoryEngine.root), createEngineNoticeForwarder(logger));
189
193
  if (memoryEngine && process.env.LOCAL_DATA_ROOT && !config.memoryEngineDir) {
190
194
  logger.warn("memory_engine_dir_defaulted", {
191
195
  root: memoryEngine.root,
@@ -78,8 +78,20 @@ export interface ApplyPluginsResult {
78
78
  /** 本轮拉取失败、沿用上次成功物化的插件名。 */
79
79
  lkgUsed: string[];
80
80
  }
81
- /** 总入口(条款 3/7/8):逐条物化 + 装载 + 让位合并。materialize 盘位 = `<cacheRoot>/<name>/live`
82
- * (成功后原子 rename 替换,失败保留旧盘位 = LKG)。 */
81
+ /**
82
+ * 装载器**会物化**的插件(按声明序)—— 每条声明过**同一只**判定 {@link validatePluginDecl},只留 `ok` 的
83
+ * `{name, url, sha?}`。restart 指纹(`config-center/restart-signal.ts` 的 skills 片,S-668 波 0)读的就是它:
84
+ * 装载器不读的字段(notes / version)、整条跳过的声明(`enabled:false` / marketplace 源 / 白名单外 host / 坏形)
85
+ * 在这里一并消失,于是「重启之后什么都不会变」的发布不签重启(codex 对抗复审 r1 [medium]);顺序保留 ——
86
+ * 撞名让位按声明序,对调两条是真变化。`allowHosts` 与装载时同一份(部署事实 `PLUGINS_ALLOW_HOSTS`)。
87
+ */
88
+ export declare function materializablePlugins(eff: {
89
+ plugins?: unknown;
90
+ }, allowHosts: readonly string[]): Array<{
91
+ name: string;
92
+ url: string;
93
+ sha?: string;
94
+ }>;
83
95
  export declare function applyCenterPlugins(baseline: LoadedSkill[], eff: {
84
96
  plugins?: unknown;
85
97
  }, opts: {
@@ -113,12 +113,20 @@ export function resolvePluginSkillsRoot(cloneRoot) {
113
113
  }
114
114
  return { ok: true, dir: candidate };
115
115
  }
116
+ function declaredPlugins(eff) {
117
+ if (Array.isArray(eff.plugins))
118
+ return eff.plugins;
119
+ const wrapped = eff.plugins?.plugins;
120
+ return Array.isArray(wrapped) ? wrapped : [];
121
+ }
122
+ export function materializablePlugins(eff, allowHosts) {
123
+ return declaredPlugins(eff).flatMap((decl) => {
124
+ const v = validatePluginDecl(decl, allowHosts);
125
+ return v.ok ? [{ name: v.name, url: v.url, ...(v.sha !== undefined ? { sha: v.sha } : {}) }] : [];
126
+ });
127
+ }
116
128
  export async function applyCenterPlugins(baseline, eff, opts) {
117
- const declared = Array.isArray(eff.plugins)
118
- ? (eff.plugins)
119
- : Array.isArray(eff.plugins?.plugins)
120
- ? (eff.plugins.plugins)
121
- : [];
129
+ const declared = declaredPlugins(eff);
122
130
  const out = { skills: [...baseline], failures: [], letGo: [], lkgUsed: [] };
123
131
  if (declared.length === 0)
124
132
  return out;