@sema-agent/server 7.123.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 (224) hide show
  1. package/MIGRATION.md +132 -0
  2. package/README.md +2 -2
  3. package/README.zh-CN.md +2 -2
  4. package/USAGE.md +53 -51
  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.js +1 -1
  18. package/dist/auth-bridge.d.ts +8 -8
  19. package/dist/auth-bridge.js +6 -6
  20. package/dist/auth-keys.d.ts +2 -2
  21. package/dist/auto-mode-face.d.ts +1 -1
  22. package/dist/boot/budget-tracing.js +1 -1
  23. package/dist/boot/execution-env.js +1 -0
  24. package/dist/boot/leader.d.ts +1 -1
  25. package/dist/boot/memory-consolidation.d.ts +4 -4
  26. package/dist/boot/org-memory.d.ts +3 -3
  27. package/dist/boot/org-memory.js +5 -5
  28. package/dist/boot/resolve-spec.js +7 -7
  29. package/dist/boot/runner-deps.d.ts +1 -1
  30. package/dist/boot/runtime-caps.d.ts +1 -1
  31. package/dist/boot/runtime-caps.js +10 -10
  32. package/dist/boot/shutdown.d.ts +2 -2
  33. package/dist/boot/shutdown.js +2 -2
  34. package/dist/boot/side-query-lane.d.ts +3 -3
  35. package/dist/boot/{stage-02-registry-pull.d.ts → stage-02-web-admin-pull.d.ts} +2 -2
  36. package/dist/boot/{stage-02-registry-pull.js → stage-02-web-admin-pull.js} +4 -4
  37. package/dist/boot/stage-03-store-backend.d.ts +2 -2
  38. package/dist/boot/stage-04-stores.d.ts +1 -1
  39. package/dist/boot/stage-05-execution-env.d.ts +1 -1
  40. package/dist/boot/stage-06-runners.d.ts +2 -2
  41. package/dist/boot/stage-06-runners.js +6 -6
  42. package/dist/boot/stage-07-capability-layer.d.ts +2 -2
  43. package/dist/boot/stage-07-capability-layer.js +6 -5
  44. package/dist/boot/stage-08-reapers.d.ts +3 -3
  45. package/dist/boot/stage-08-reapers.js +3 -3
  46. package/dist/boot/stage-09-leader.d.ts +3 -3
  47. package/dist/boot/stage-09-leader.js +7 -7
  48. package/dist/boot/stage-10-http-server.d.ts +3 -3
  49. package/dist/boot/stage-10-http-server.js +19 -19
  50. package/dist/boot/unpriced-ceiling-verdict.d.ts +1 -1
  51. package/dist/boot/{config-center.d.ts → web-admin.d.ts} +11 -11
  52. package/dist/boot/{config-center.js → web-admin.js} +38 -22
  53. package/dist/boot/webfetch-summarize-lane.d.ts +2 -2
  54. package/dist/brain.d.ts +1 -1
  55. package/dist/brain.js +1 -1
  56. package/dist/budget.d.ts +3 -3
  57. package/dist/canonical-json.d.ts +2 -2
  58. package/dist/capabilities/center-plugins.d.ts +1 -1
  59. package/dist/capabilities/center-wiring.d.ts +12 -5
  60. package/dist/capabilities/center-wiring.js +11 -2
  61. package/dist/capabilities/composite-members.d.ts +1 -1
  62. package/dist/capabilities/composite-members.js +1 -1
  63. package/dist/capabilities/scenarios.js +2 -2
  64. package/dist/capabilities/team.d.ts +1 -1
  65. package/dist/capabilities/tool-defer.d.ts +1 -1
  66. package/dist/center-credential-renewer.d.ts +1 -1
  67. package/dist/center-credential-renewer.js +7 -7
  68. package/dist/center-credential.d.ts +9 -9
  69. package/dist/center-credential.js +6 -6
  70. package/dist/config-catalog.d.ts +7 -10
  71. package/dist/config-catalog.js +15 -15
  72. package/dist/config-d-migration.d.ts +32 -0
  73. package/dist/config-d-migration.js +59 -0
  74. package/dist/config-invariants.d.ts +14 -4
  75. package/dist/config-invariants.js +31 -2
  76. package/dist/config-lkg.d.ts +26 -6
  77. package/dist/config-lkg.js +43 -14
  78. package/dist/config-provider.d.ts +23 -19
  79. package/dist/config-provider.js +24 -26
  80. package/dist/config-types.d.ts +52 -51
  81. package/dist/config.d.ts +9 -46
  82. package/dist/config.js +33 -92
  83. package/dist/execution-lane-caps.d.ts +1 -1
  84. package/dist/fleet/drain-entry.d.ts +1 -1
  85. package/dist/fleet/engine-signal.d.ts +8 -8
  86. package/dist/fleet/fleet-bus.d.ts +12 -3
  87. package/dist/fleet/fleet-bus.js +13 -9
  88. package/dist/fleet/serving-lease.d.ts +3 -3
  89. package/dist/fleet/serving-lease.js +1 -1
  90. package/dist/fleet-client.d.ts +7 -7
  91. package/dist/fleet-client.js +5 -4
  92. package/dist/fleet-lease.d.ts +3 -3
  93. package/dist/fleet-lease.js +2 -2
  94. package/dist/host-lsp-manager.d.ts +1 -1
  95. package/dist/hosted-posture.d.ts +4 -4
  96. package/dist/http/admission.js +4 -4
  97. package/dist/http/checkpoint-ctx.d.ts +20 -3
  98. package/dist/http/checkpoint-ctx.js +13 -5
  99. package/dist/http/dispatch.js +2 -2
  100. package/dist/http/durable-run-leg.js +2 -1
  101. package/dist/http/health-self-report.d.ts +4 -4
  102. package/dist/http/health-self-report.js +3 -3
  103. package/dist/http/idempotency.d.ts +1 -1
  104. package/dist/http/resume-legs.d.ts +4 -3
  105. package/dist/http/resume-legs.js +31 -18
  106. package/dist/http/route-ctx.d.ts +8 -0
  107. package/dist/http/routes/admin-config-refresh.d.ts +1 -1
  108. package/dist/http/routes/admin-config-refresh.js +1 -1
  109. package/dist/http/routes/admin-drain.d.ts +1 -1
  110. package/dist/http/routes/admin-drain.js +5 -4
  111. package/dist/http/routes/approvals-assistant.js +4 -4
  112. package/dist/http/routes/capabilities.js +5 -5
  113. package/dist/http/routes/config-catalog.js +2 -3
  114. package/dist/http/routes/diagnostics.js +1 -1
  115. package/dist/http/routes/runs.js +8 -4
  116. package/dist/http/routes/sessions-list.js +2 -1
  117. package/dist/http/routes/sessions.js +1 -1
  118. package/dist/http/routes/side-query.js +3 -3
  119. package/dist/http/routes/tasks.js +3 -2
  120. package/dist/http/run-meta.d.ts +1 -1
  121. package/dist/http/run-meta.js +2 -2
  122. package/dist/http/server.d.ts +7 -7
  123. package/dist/http/server.js +1 -1
  124. package/dist/http/stored-body-replay.js +3 -2
  125. package/dist/index.d.ts +0 -1
  126. package/dist/index.js +0 -1
  127. package/dist/key-resolver.d.ts +1 -1
  128. package/dist/leader/wire.d.ts +2 -2
  129. package/dist/leader/wire.js +2 -1
  130. package/dist/main.js +1 -1
  131. package/dist/mcp-tool-faces.d.ts +2 -2
  132. package/dist/model-entry-refusal.d.ts +3 -3
  133. package/dist/model-entry-refusal.js +4 -4
  134. package/dist/model-provider.d.ts +2 -2
  135. package/dist/model-route-endpoint.d.ts +1 -1
  136. package/dist/model-route-url.d.ts +1 -1
  137. package/dist/model-route-url.js +2 -1
  138. package/dist/model-select.d.ts +24 -21
  139. package/dist/model-select.js +22 -17
  140. package/dist/observability/metrics.d.ts +1 -1
  141. package/dist/org-memory-admission.d.ts +1 -1
  142. package/dist/plugins/approval-ask-store-file.d.ts +4 -2
  143. package/dist/plugins/approval-ask-store-file.js +3 -3
  144. package/dist/plugins/approval-ask-store-memory.d.ts +4 -3
  145. package/dist/plugins/approval-ask-store-memory.js +10 -4
  146. package/dist/plugins/approval-ask-store-sql.d.ts +16 -2
  147. package/dist/plugins/approval-ask-store-sql.js +20 -13
  148. package/dist/plugins/caching-session-store.d.ts +0 -10
  149. package/dist/plugins/caching-session-store.js +0 -3
  150. package/dist/plugins/file-run-store.js +9 -3
  151. package/dist/plugins/leader-run-store-sql.d.ts +3 -2
  152. package/dist/plugins/leader-run-store-sql.js +3 -2
  153. package/dist/plugins/local-session-store.d.ts +20 -27
  154. package/dist/plugins/local-session-store.js +19 -17
  155. package/dist/plugins/memory-run-store.js +9 -3
  156. package/dist/plugins/one-time-migrations.js +26 -2
  157. package/dist/plugins/scheduler-support.d.ts +26 -7
  158. package/dist/plugins/scheduler-support.js +96 -53
  159. package/dist/plugins/store-backend.js +1 -1
  160. package/dist/plugins/store-contracts.d.ts +20 -4
  161. package/dist/plugins/web-search.d.ts +1 -1
  162. package/dist/plugins/web-search.js +2 -1
  163. package/dist/posture-source.d.ts +1 -1
  164. package/dist/read-face-posture.d.ts +3 -3
  165. package/dist/read-face-posture.js +1 -1
  166. package/dist/run-local.js +6 -3
  167. package/dist/runtime-caps-resolver.d.ts +4 -4
  168. package/dist/runtime-caps-resolver.js +2 -2
  169. package/dist/runtime-governance.d.ts +5 -5
  170. package/dist/sealed-key.d.ts +4 -4
  171. package/dist/sealed-key.js +3 -2
  172. package/dist/security.d.ts +3 -3
  173. package/dist/service-version.d.ts +1 -1
  174. package/dist/service-version.js +5 -0
  175. package/dist/session-titler.d.ts +0 -11
  176. package/dist/session-titler.js +3 -5
  177. package/dist/shared-memory-scope-authorizer.d.ts +4 -4
  178. package/dist/task-a2a.d.ts +1 -1
  179. package/dist/tool-approval.d.ts +43 -4
  180. package/dist/tool-approval.js +147 -98
  181. package/dist/trace/core-keyset-guard.d.ts +1 -1
  182. package/dist/trace/project.d.ts +3 -3
  183. package/dist/trace/redact.d.ts +2 -23
  184. package/dist/trace/redact.js +1 -6
  185. package/dist/trace/self-minted-wire.d.ts +147 -3
  186. package/dist/trace/self-minted-wire.js +50 -9
  187. package/dist/url-refusal.d.ts +35 -0
  188. package/dist/url-refusal.js +15 -0
  189. package/dist/user-authored-text.d.ts +31 -0
  190. package/dist/user-authored-text.js +18 -0
  191. package/dist/{config-center → web-admin-client}/apply-effective.d.ts +13 -70
  192. package/dist/{config-center → web-admin-client}/apply-effective.js +100 -119
  193. package/dist/{config-center → web-admin-client}/apply-ledger.d.ts +2 -2
  194. package/dist/{config-center → web-admin-client}/center-request.d.ts +7 -7
  195. package/dist/{config-center → web-admin-client}/center-request.js +5 -4
  196. package/dist/{config-center → web-admin-client}/effective-keys.d.ts +1 -3
  197. package/dist/{config-center → web-admin-client}/effective-keys.js +0 -9
  198. package/dist/{config-center → web-admin-client}/facade.d.ts +6 -6
  199. package/dist/{config-center → web-admin-client}/facade.js +2 -2
  200. package/dist/{config-center → web-admin-client}/http-client.d.ts +6 -10
  201. package/dist/{config-center → web-admin-client}/http-client.js +12 -12
  202. package/dist/{config-center → web-admin-client}/pull-state.d.ts +1 -1
  203. package/dist/{config-center → web-admin-client}/read-face.js +4 -4
  204. package/dist/{config-center → web-admin-client}/read-warnings.d.ts +23 -16
  205. package/dist/{config-center → web-admin-client}/read-warnings.js +33 -23
  206. package/dist/{config-center → web-admin-client}/restart-signal.d.ts +5 -3
  207. package/dist/{config-center → web-admin-client}/restart-signal.js +3 -4
  208. package/dist/{config-center → web-admin-client}/skills-mcp.d.ts +1 -1
  209. package/dist/{config-center → web-admin-client}/skills-mcp.js +13 -13
  210. package/dist/{config-center → web-admin-client}/stage-limits.d.ts +1 -7
  211. package/dist/{config-center → web-admin-client}/stage-limits.js +6 -7
  212. package/dist/{config-center → web-admin-client}/types.d.ts +12 -39
  213. package/package.json +2 -2
  214. package/skills/find-skills.md +2 -2
  215. package/dist/url-shape.d.ts +0 -31
  216. package/dist/url-shape.js +0 -41
  217. /package/dist/{config-center → web-admin-client}/apply-ledger.js +0 -0
  218. /package/dist/{config-center → web-admin-client}/hot-keys-registry.d.ts +0 -0
  219. /package/dist/{config-center → web-admin-client}/hot-keys-registry.js +0 -0
  220. /package/dist/{config-center → web-admin-client}/mcp-revocation.d.ts +0 -0
  221. /package/dist/{config-center → web-admin-client}/mcp-revocation.js +0 -0
  222. /package/dist/{config-center → web-admin-client}/pull-state.js +0 -0
  223. /package/dist/{config-center → web-admin-client}/read-face.d.ts +0 -0
  224. /package/dist/{config-center → web-admin-client}/types.js +0 -0
@@ -11,14 +11,14 @@
11
11
  *
12
12
  * 于是本模块把「档位」与「档位是谁定的」拆成两个字段:值仍是 `open | roots | 缺席`,来源是本文件的
13
13
  * **四词闭集**。来源不是装饰:
14
- * ① `config-center/read-face.ts` 的 **env 恒赢**判据此前用的是「`config.readFace` 键在不在场」这个
14
+ * ① `web-admin-client/read-face.ts` 的 **env 恒赢**判据此前用的是「`config.readFace` 键在不在场」这个
15
15
  * **代理**;posture 会铸键,代理当场失真(center 的 face 会被一台从没设过 env 的机器挡掉)。
16
16
  * 换成读来源之后判据说的就是它真正想说的那件事:**这台机器的 env 显式占住了这个键吗**。
17
17
  * ② 运维面:`GET /v1/diagnostics/wiring` 报 `{face, source, note}`,「为什么这台机器是 open」有答案
18
18
  * (裁定的补偿项:升级即放开,得让运维看得见并知道怎么钉回)。
19
19
  *
20
20
  * ## 优先序(三态,与 `config.ts` 的 `postureOn` 同形)
21
- * `env 显式` > `center 发布` > `posture 派生` > `引擎默认`。env 恒赢的论证逐字见 `config-center/read-face.ts`
21
+ * `env 显式` > `center 发布` > `posture 派生` > `引擎默认`。env 恒赢的论证逐字见 `web-admin-client/read-face.ts`
22
22
  * 头注①(READ 容纳面描述的是**这台机器的磁盘上有什么**,组织的下发面不知道)。
23
23
  *
24
24
  * ## 定界
@@ -54,7 +54,7 @@ export declare function readFaceForPosture(singleUserTurnkey: boolean): ReadFace
54
54
  *
55
55
  * 🔴 `center` 那句话的事实来源是 S-174(core 7.10.0 [ref]):`RunnerDeps.readFace` 进了 core 的可换席
56
56
  * 闭集 `SWAPPABLE_DEP_SEATS` ⇒ 组织发布/撤回一个档位,**下一拍 refresh 当场换进全部 Runner**,
57
- * `config-center/restart-signal.ts` 的 `read-face` 片也不再为它签重启理由(判据同源 =
57
+ * `web-admin-client/restart-signal.ts` 的 `read-face` 片也不再为它签重启理由(判据同源 =
58
58
  * `CENTER_READ_FACE_LIVE_KEYS`,由 core 的 `isSwappableDepSeat` 派生)。本句此前逐字写着
59
59
  * 「(restart-to-apply)」—— G-7 抓获的那条过期断言,方向恰好是「让运维为一个已生效的变更重启 fleet」。
60
60
  * ⚠️ 只说 `face` 这一席:三个 deny 键仍是 boot-baked,那半场的话不在这条读面上(它们没有来源位)。 */
@@ -7,7 +7,7 @@ export function readFaceSourceNote(source) {
7
7
  return postureSourceNote({
8
8
  knob: "READ_FACE",
9
9
  source,
10
- centerMeaning: "published by the config-center and applied HOT — the containment FACE is a swappable engine seat (core 7.10.0), so the next refresh (or POST /v1/admin/config/refresh) swaps it into every Runner with NO restart; set READ_FACE on this machine to take the key back",
10
+ centerMeaning: "published by the web-admin and applied HOT — the containment FACE is a swappable engine seat (core 7.10.0), so the next refresh (or POST /v1/admin/config/refresh) swaps it into every Runner with NO restart; set READ_FACE on this machine to take the key back",
11
11
  postureMeaning: "derived from the single-user turnkey posture (REQUIRE_PRINCIPAL is not set): reads outside the workspace roots are allowed by default — set READ_FACE=roots to pin the containing posture back",
12
12
  });
13
13
  }
package/dist/run-local.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { DEFAULT_MODEL_REF, resolveTaskModel } from "./model-select.js";
2
+ import { DEFAULT_AT_MENTION, DEFAULT_MODEL_REF, resolveTaskModel } from "./model-select.js";
3
3
  import { defaultModelRefusal, modelUnavailableMessage } from "./model-entry-refusal.js";
4
4
  import { createDurableAbsenceSeat } from "./observability/corrupt-read-seat.js";
5
5
  import { outwardPlane } from "./terminal.js";
@@ -25,7 +25,8 @@ import { acquireLocalBackendWithWait } from "./plugins/store-lock-wait.js";
25
25
  import { configLocalRoot, configProviderKind, createConfigProvider } from "./config-provider.js";
26
26
  import { composeExecutionLane } from "./boot/execution-lane.js";
27
27
  import { judgeConsolidationValve } from "./boot/memory-consolidation.js";
28
- import { applyEffective, applyCenterReadFace, resolveMcpServers, mcpForScenario, resolveA2aPeers, a2aForScenario } from "./config-center/facade.js";
28
+ import { logConfigDirMigration, migrateLocalConfigDirectory } from "./config-d-migration.js";
29
+ import { applyEffective, applyCenterReadFace, resolveMcpServers, mcpForScenario, resolveA2aPeers, a2aForScenario } from "./web-admin-client/facade.js";
29
30
  import { hostExecutionEnvFactory } from "./plugins/remote-env-host.js";
30
31
  import { executionLaneHomeDir, executionLaneOf } from "./execution-lane-caps.js";
31
32
  import { makeLoadProjectMemory, makeProbeInstructionSources } from "./project-memory.js";
@@ -337,6 +338,8 @@ export async function runLocal(argv, deps = {}) {
337
338
  return 2;
338
339
  }
339
340
  const configProvider = createConfigProvider(providerInput);
341
+ if (configProvider.kind === "local")
342
+ logConfigDirMigration(logger, await migrateLocalConfigDirectory(root));
340
343
  let effective;
341
344
  try {
342
345
  const r = await configProvider.fetchEffective(undefined);
@@ -613,7 +616,7 @@ export async function runLocal(argv, deps = {}) {
613
616
  }
614
617
  throw err;
615
618
  }
616
- const mention = resolveTaskModel(undefined, args.objective, config.models, undefined, config.modelRefusals);
619
+ const mention = resolveTaskModel(undefined, args.objective, config.models, DEFAULT_AT_MENTION, config.modelRefusals);
617
620
  if (mention.unavailable !== undefined) {
618
621
  const { requested, name, refusal } = mention.unavailable;
619
622
  printErr(`cannot run: ${modelUnavailableMessage("@-mention", requested, name, refusal)}`);
@@ -65,8 +65,8 @@
65
65
  */
66
66
  import type { RuntimeCaps } from "@sema-agent/core";
67
67
  import type { EntitlementRuntimeCaps } from "@sema-agent/settings-schema";
68
- import { fetchPrincipalCaps, type ExecutionRuling } from "./config-center/facade.js";
69
- import type { CenterEndpoint } from "./config-center/center-request.js";
68
+ import { fetchPrincipalCaps, type ExecutionRuling } from "./web-admin-client/facade.js";
69
+ import type { CenterEndpoint } from "./web-admin-client/center-request.js";
70
70
  import type { ScenarioRuling } from "./capabilities/scenarios.js";
71
71
  import type { ServiceConfig } from "./config-types.js";
72
72
  import { type Logger } from "./observability/logger.js";
@@ -75,7 +75,7 @@ export declare function resetExecutionLaneDefaultTraceForTest(): void;
75
75
  export interface EntitlementsResolverOpts {
76
76
  /** S-651:中心端点(基址 + 凭证**来源**;每次抓取取一次值,不持有启动快照)。 */
77
77
  center: CenterEndpoint;
78
- /** This worker's name (`SEMA_REGISTRY_WORKER`), passed as `?worker=` so a worker-scoped `wpt_<self>` token can
78
+ /** This worker's name (`SEMA_WEB_ADMIN_WORKER`), passed as `?worker=` so a worker-scoped `wpt_<self>` token can
79
79
  * resolve its OWN worker's principal caps (caps-only); harmless on a full token (the caps value
80
80
  * is worker-independent). Omitted ⇒ no `?worker=` (a full-token, non-fleet deployment). */
81
81
  worker?: string;
@@ -135,7 +135,7 @@ export declare function toCoreRuntimeCaps(ent: EntitlementRuntimeCaps | null | u
135
135
  * (`RuntimeCaps.autoMode` 三态逐 principal 解,[ref] 起「缺席=不阻」),任何部署级布尔都对它说不了话——
136
136
  * 所以本谓词为 false **不再**意味着 auto 不武装;「会不会武装」由 `auto-mode-face.ts` 的三项合取答。
137
137
  */
138
- export declare function centerEntitlementSourceWired(config: Pick<ServiceConfig, "configCenter">): boolean;
138
+ export declare function centerEntitlementSourceWired(config: Pick<ServiceConfig, "webAdmin">): boolean;
139
139
  /** The two per-principal faces served off ONE caps fetch + cache. */
140
140
  export interface PrincipalEntitlementsClient {
141
141
  /** core's `RunnerDeps.runtimeCapsResolver` seam — FAIL-CLOSED on error (deny workflows/fork/autoMode;
@@ -1,4 +1,4 @@
1
- import { fetchPrincipalCaps } from "./config-center/facade.js";
1
+ import { fetchPrincipalCaps } from "./web-admin-client/facade.js";
2
2
  import { createIdentityBins } from "./center-credential.js";
3
3
  import { HttpError } from "./security.js";
4
4
  import { createLogger } from "./observability/logger.js";
@@ -53,7 +53,7 @@ export function toCoreRuntimeCaps(ent) {
53
53
  return Object.keys(caps).length ? caps : undefined;
54
54
  }
55
55
  export function centerEntitlementSourceWired(config) {
56
- return config.configCenter !== undefined && !config.configCenter.dryRun;
56
+ return config.webAdmin !== undefined && !config.webAdmin.dryRun;
57
57
  }
58
58
  export function gateExecutionLane(ruling, ownLane, logger = defaultLogger) {
59
59
  if (!ruling) {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Runtime governance compiler — the "second baton" (center §10, core 1.114.0): turn the
3
- * operator's declarative `runtime.autonomy` + `runtime.commandPolicy` (`@sema-agent/settings-schema`,
4
- * carried to the service via sema-registry `EffectiveConfig.runtime`) into TIGHTEN-ONLY overrides on the
3
+ * operator's declarative `governance.autonomy` + `governance.commandPolicy` (`@sema-agent/settings-schema`,
4
+ * carried to the service in the effective config's `governance` domain) into TIGHTEN-ONLY overrides on the
5
5
  * per-task `TaskSpec`. Pure so it is unit-testable in isolation (the spec is otherwise assembled inside
6
6
  * main.ts's `resolveSpec`).
7
7
  *
@@ -28,7 +28,7 @@ import { GovernanceConfig } from "@sema-agent/settings-schema";
28
28
  import { type GovernanceAskMarks } from "./governance-ask-marks.js";
29
29
  import { type GovernanceOverrides } from "./governance-overrides.js";
30
30
  /** 运维 autonomy 四档的**闭集**(同上)。`config.ts` 的 `parseAutonomy` 也从这里读 —— 四档词表全仓一份。 */
31
- export declare const AUTONOMY_MODES: ["read-only", "ask", "plan", "auto"];
31
+ export declare const AUTONOMY_MODES: ("plan" | "auto" | "ask" | "read-only")[];
32
32
  /** A per-command governance rule (registry `runtime.commandPolicy[]`) —— **型也从契约派生**:
33
33
  * 契约给 `command` 加一条 refine / 给 `decision` 加一个判词,本仓的型当场跟上(或在下面的
34
34
  * `RANK` / 穷尽 switch 上编译红),而不是靠人记得把手写联合改一遍。 */
@@ -39,7 +39,7 @@ export type Autonomy = NonNullable<GovernanceConfig["autonomy"]>;
39
39
  export declare const COARSE_SHELL_TOOLS_MIRROR: readonly string[];
40
40
  /** Validate `commandPolicy` rules — the shape (array of {command, decision}), the `command` (a bare argv[0] name,
41
41
  * see {@link VALID_COMMAND_NAME}), AND the `decision` enum. Returns the list of human-readable errors (empty =
42
- * OK). Called at config-apply (config-center/facade.ts `applyRuntimeHot`) so a malformed rule that BYPASSED the
42
+ * OK). Called at config-apply (web-admin-client/facade.ts `applyRuntimeHot`) so a malformed rule that BYPASSED the
43
43
  * registry schema (a hand-edited config.d / a non-conformant publish) is rejected LOUDLY rather than
44
44
  * silently mis-compiling — review MEDIUM: an out-of-enum `decision` (e.g. "DENY") would otherwise fall through
45
45
  * {@link compileCommandPolicyLayers}'s `decision==="deny"?…:"ask"` to ASK, silently WEAKENING an intended deny. */
@@ -176,7 +176,7 @@ export declare function autonomyKeepsOpenWriteFace(autonomy: Autonomy | undefine
176
176
  * 是 always」。`commandPolicy` 不入判据:它产的是 `toolPolicy` 的 ask,不抬 shellGate 档,与本格无关。
177
177
  *
178
178
  * ⚠️ **已知残留(codex 交叉复审 2026-08-11 逮到,如实登记而不是掩盖)**:本判据读的是**当下**的
179
- * config,而 `config.autonomy` 是**热改**的(`config-center/apply-effective.ts` 就地写 `config.autonomy`)。
179
+ * config,而 `config.autonomy` 是**热改**的(`web-admin-client/apply-effective.ts` 就地写 `config.autonomy`)。
180
180
  * 于是失真是**双向**的,不是我原先写的「只往缺席方向」:
181
181
  * · 缺席向(常见):mint 之后运维把 `AUTONOMY=ask` 撤了 ⇒ 老 park 行归不出治理出身,少标一个;
182
182
  * · **在场向**(窄):一条**纯 SUP 路由**产的门(`ROUTER_ENABLED` 开 ∧ 路由判 supervisor ∧ 当时治理层
@@ -2,7 +2,7 @@ import type { Logger } from "./observability/logger.js";
2
2
  /** Algorithm tag — MUST equal registry-core's `SEALED_BOX_ALG` (v1 sole value; a different alg on
3
3
  * the wire is a loud per-model rejection in applyEffective, never a guess). */
4
4
  export declare const SEALED_KEY_ALG = "libsodium-sealedbox-x25519";
5
- /** The subset applyEffective needs (keeps sema-registry decoupled from fs/boot concerns). */
5
+ /** The subset applyEffective needs (keeps web-admin decoupled from fs/boot concerns). */
6
6
  export interface SealedKeyOpener {
7
7
  has(publicKeyId: string): boolean;
8
8
  /** All private-key ids this host holds (surfaces in the no-private-key warn for operator triage). */
@@ -62,17 +62,17 @@ export declare function deriveKeyId(publicKeyRaw: Uint8Array): string;
62
62
  */
63
63
  export declare function ensureSealedKeyStore(dir: string, logger?: Logger): Promise<SealedKeyStore>;
64
64
  /**
65
- * Best-effort public-key registration with the sema-registry (`POST /api/config/execution-keys`).
65
+ * Best-effort public-key registration with the web-admin (`POST /api/config/execution-keys`).
66
66
  *
67
67
  * HONESTY over fake automation: that endpoint is ADMIN-gated, and a fleet worker only holds
68
68
  * SERVICE_PULL_TOKEN — so automatic registration works ONLY when the operator deliberately provides
69
- * an admin token (SEMA_REGISTRY_ADMIN_TOKEN in this service's env; the REGISTRY_ADMIN_TOKEN alias was tombstoned in 5.0.0). Without
69
+ * an admin token (SEMA_WEB_ADMIN_ADMIN_TOKEN in this service's env; its older names are settings-schema tombstones). Without
70
70
  * one we do the next-best REAL thing: print the FULL public key + id at boot (a public key is not a
71
71
  * secret) with the exact registration instructions, and warn that the web "paste key" face stays
72
72
  * dark for this host until an admin registers it. Never throws (fire-and-forget from boot).
73
73
  */
74
74
  export declare function reportExecutionPublicKey(opts: {
75
- /** sema-registry base URL (config.configCenter.baseUrl). Absent = no center → manual print only. */
75
+ /** web-admin base URL (config.webAdmin.baseUrl). Absent = no center → manual print only. */
76
76
  baseUrl?: string;
77
77
  /** Admin bearer for the center's config write face. Absent = manual print (see above). */
78
78
  adminToken?: string;
@@ -4,7 +4,8 @@ import { join } from "node:path";
4
4
  import _sodium from "libsodium-wrappers";
5
5
  import { buildDisplaySafeUrl } from "./trace/redact.js";
6
6
  import { createCenterCredentialSource } from "./center-credential.js";
7
- import { centerFetch } from "./config-center/center-request.js";
7
+ import { centerFetch } from "./web-admin-client/center-request.js";
8
+ import { WEB_ADMIN_ENV } from "@sema-agent/settings-schema";
8
9
  export const SEALED_KEY_ALG = "libsodium-sealedbox-x25519";
9
10
  const SEAL_OVERHEAD_BYTES = 48;
10
11
  const BASE64_STRICT = /^[A-Za-z0-9+/]+={0,2}$/;
@@ -101,7 +102,7 @@ export async function reportExecutionPublicKey(opts) {
101
102
  });
102
103
  };
103
104
  if (!baseUrl || !adminToken) {
104
- manual(!baseUrl ? "no registry configured (SEMA_REGISTRY_URL unset)" : "no admin token (SEMA_REGISTRY_ADMIN_TOKEN unset; the worker's pull token cannot write execution keys)");
105
+ manual(!baseUrl ? `no web-admin configured (${WEB_ADMIN_ENV.url} unset)` : `no admin token (${WEB_ADMIN_ENV.adminToken} unset; the worker's pull token cannot write execution keys)`);
105
106
  return;
106
107
  }
107
108
  try {
@@ -17,9 +17,9 @@ export interface SessionListItem {
17
17
  /** K-5c (shell §K): the latest run's task_id — the shell's one-hop live-tail re-attach anchor on resume. */
18
18
  lastRunId: string | null;
19
19
  /** [ref]([ref]/[ref]):the LATEST run's **engine run id**(`TaskResult.runId`)when known —— OMIT-when-absent,
20
- * 恒不铸 null。runs-ledger listers 从 latest run 的 `result` JSON 提取(终局与 park 时写、认领续跑即清空 —— S-173 ⇒ 在跑 latest 键诚实缺席);
21
- * local lister 走 `noteTaskRun` 席实时记录(⇒ 在跑也在场)——两面缺席集合不完全相等,读法一致:
22
- * 缺席 = 「此行无已知 engine runId」,禁读成其它含义。⚠️ 与 `lastRunId`(= latest run 的 **task_id**)
20
+ * 恒不铸 null。所有 lister(SQL 双生、local 会话店 —— 它的 run 店是必填位)从 latest run 的 `result` JSON 提取(终局与 park 时写、认领续跑即清空 —— S-173
21
+ * ⇒ 在跑 latest 键诚实缺席)。
22
+ * 读法一致:缺席 = 「此行无已知 engine runId」,禁读成其它含义。⚠️ 与 `lastRunId`(= latest run 的 **task_id**)
23
23
  * 是两条身份轴,命名对齐 core `SessionStoreSummary.lastTaskRunId`。wire:additive 键零投影透传
24
24
  * (sessions-list.ts);sema-sdk spec `SessionSummary` 闭集候 SDK 半场开键([ref]/.82 班车)。 */
25
25
  lastTaskRunId?: string;
@@ -1,5 +1,5 @@
1
1
  /** Service version for GET /v1/capabilities — read from the package.json shipped next to src/ in the
2
- * image (Dockerfile COPYs it). Best-effort: an unreadable file reports "unknown", never crashes boot. */
2
+ * image (Dockerfile COPYs it), once per process. Best-effort: an unreadable file reports "unknown", never crashes boot. */
3
3
  declare function serviceVersion(): string;
4
4
  export { serviceVersion };
5
5
  //# sourceMappingURL=service-version.d.ts.map
@@ -1,5 +1,10 @@
1
1
  import { readFileSync } from "node:fs";
2
+ let cachedServiceVersion;
2
3
  function serviceVersion() {
4
+ cachedServiceVersion ??= readServiceVersion();
5
+ return cachedServiceVersion;
6
+ }
7
+ function readServiceVersion() {
3
8
  try {
4
9
  const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
5
10
  return pkg.version ?? "unknown";
@@ -54,17 +54,6 @@ export interface SessionTitler {
54
54
  export declare const TITLE_MAX_CHARS = 80;
55
55
  /** Single line, control chars stripped, hard cap; surrounding quotes (a common LLM tic) trimmed. */
56
56
  export declare function sanitizeTitle(raw: string): string;
57
- /**
58
- * S-236 ②(7.106.0,cli L-687)—— objective 里**用户自己写的**那部分:剥掉全部 `<system-reminder>…</system-reminder>` 块(跨行、
59
- * 多块、夹在正文中间都剥;**未闭合**的块剥到末尾 —— 被截断的附件同样不是用户写的)后 trim。
60
- *
61
- * 为什么:壳把附件(技能清单一类的 `<system-reminder>` 块)拼在正文**之前**提交,标题器取前 {@link OBJECTIVE_SNIPPET_CHARS} 字
62
- * 去起名 ⇒ 标题成了技能清单。判据只认这一个**字面标签**(CC 的附件信封),不按内容猜「像不像用户写的」——
63
- * 正文里提到这个词的普通文字不是块,原样保留。剥完是空串 ⇒ 调用方走「空 objective 不起名」的既有臂。
64
- * ⚠️ 只治这一类:S-236 原件(fresh `/decide` 腿把指路文本当 objective 提交)是另一类非用户文本,没有信封可剥,本函数刻意不加
65
- * 按内容猜的第二臂(要么 fresh 腿传席,要么另立一臂 —— 候裁,见车RA 收车档)。
66
- */
67
- export declare function userAuthoredObjectiveText(objective: string): string;
68
57
  export declare function buildTitlePrompt(objective: string): string;
69
58
  export declare function createSessionTitler(deps: SessionTitlerDeps): SessionTitler;
70
59
  //# sourceMappingURL=session-titler.d.ts.map
@@ -1,6 +1,7 @@
1
1
  import { CONTROL_AND_BIDI_STRIP_RE } from "./text-bidi.js";
2
2
  import { recordFailOpen } from "./observability/fail-open.js";
3
3
  import { redactSecrets } from "./trace/redact.js";
4
+ import { userAuthoredText } from "./user-authored-text.js";
4
5
  export const TITLE_MAX_CHARS = 80;
5
6
  const OBJECTIVE_SNIPPET_CHARS = 600;
6
7
  const LLM_TIMEOUT_MS = 15_000;
@@ -12,11 +13,8 @@ export function sanitizeTitle(raw) {
12
13
  const unquoted = oneLine.replace(/^["'「『]+/, "").replace(/["'」』]+$/, "").trim();
13
14
  return unquoted.length > TITLE_MAX_CHARS ? `${unquoted.slice(0, TITLE_MAX_CHARS - 1)}…` : unquoted;
14
15
  }
15
- export function userAuthoredObjectiveText(objective) {
16
- return objective.replace(/<system-reminder>[\s\S]*?(?:<\/system-reminder>|$)/g, "").trim();
17
- }
18
16
  export function buildTitlePrompt(objective) {
19
- const text = userAuthoredObjectiveText(objective);
17
+ const text = userAuthoredText(objective);
20
18
  const snippet = text.length > OBJECTIVE_SNIPPET_CHARS ? `${text.slice(0, OBJECTIVE_SNIPPET_CHARS)}…` : text;
21
19
  const fenced = snippet.replace(/<(\/?)request>/gi, "<\u200b$1request>");
22
20
  return ("Write a short title (at most 8 words) summarizing the user request below. " +
@@ -38,7 +36,7 @@ export function createSessionTitler(deps) {
38
36
  .catch(() => ({ state: continueWord, unreadable: true }));
39
37
  return {
40
38
  maybeTitle(sessionId, objective, model) {
41
- if (!sessionId || !userAuthoredObjectiveText(objective))
39
+ if (!sessionId || !userAuthoredText(objective))
42
40
  return;
43
41
  if (seen.has(sessionId))
44
42
  return;
@@ -25,7 +25,7 @@ export interface SharedMemoryScopeAuthorizerOptions {
25
25
  * 部署自证的 org scope —— **取值口而非值**([ref])。
26
26
  *
27
27
  * 🔴 类型上是函数是刻意的,不是风格:这组 scope 的真源是 `config.projects` 的 `defaultScopes`,
28
- * 而 `config.projects` 被 config-center **就地热应用**(`mutateInPlace`,整表替换),env 腿恒空
28
+ * 而 `config.projects` 被 web-admin **就地热应用**(`mutateInPlace`,整表替换),env 腿恒空
29
29
  * ⇒ 这一域的**常态**就是运行期变更。此前这里收的是一个数组(装配点在 boot 期算一次),而且本模块
30
30
  * 还 `[...new Set(...)]` 又复制一层,连「换引用」这条后路都封死 ⇒ 两个方向都错到进程重启为止:
31
31
  * · **新登记**一个带 `org:` 的项目 ⇒ 该 org 的共享库在快照里没有 ⇒ 折成 `{state:"connected",
@@ -33,7 +33,7 @@ export interface SharedMemoryScopeAuthorizerOptions {
33
33
  * unavailable),运维以为配好了;
34
34
  * · **撤销**方向更糟:项目/scope 下架后,principal-less 的单用户请求仍按旧快照继续被放行 ——
35
35
  * 一次运维撤销动作**静默不生效**([ref] 点名的静默类型),方向是 fail-OPEN。
36
- * 而且它没被登进 `config-center/restart-signal.ts` 的 `RESTART_SLICES` ⇒ `/health` 连一句
36
+ * 而且它没被登进 `web-admin-client/restart-signal.ts` 的 `RESTART_SLICES` ⇒ `/health` 连一句
37
37
  * 「该重启了」都不会说。⇒ 收口是把读取时机对齐消费时机:每次 `resolve` 现取。
38
38
  * (缺席 = 部署没有任何自证 scope,与传 `() => []` 等价。)
39
39
  *
@@ -51,8 +51,8 @@ export interface SharedMemoryScopeAuthorizerOptions {
51
51
  * Set 建、交回来已去重,这里再包一层是纯浪费。**去重责任因此上移到取值口**(契约见下面那个字段的注),
52
52
  * principal 在场那支的合并 Set 保留(它要与目录 scope 求并,那一次是真需要的)。
53
53
  * · **具名保留**(不做 generation 缓存):`config.projects` 由 `mutateInPlace` **就地**改,对象身份恒定,
54
- * 没有可用的失效信号;而 config-center 的 `appliedGeneration` 是那个模块的私有 WeakMap,不在公面上。
55
- * 要缓存就得先给 config-center 开一只「已提交世代」读口 —— 那是别人模块的接缝件,且**缓存失效写错
54
+ * 没有可用的失效信号;而 web-admin 的 `appliedGeneration` 是那个模块的私有 WeakMap,不在公面上。
55
+ * 要缓存就得先给 web-admin 开一只「已提交世代」读口 —— 那是别人模块的接缝件,且**缓存失效写错
56
56
  * 一次,就恰好把本条 finding 刚关掉的那个陈旧窗原样放回来**(还多一层代码)。规模面亦不支持先做:
57
57
  * projects 是运维手写的登记簿(量级十几~百),而这条腿的**同一次**调用里,principal 在场那支还要
58
58
  * `await directory.lookup()`(网络/缓存),扫表在它旁边不构成瓶颈。⇒ 若哪天登记簿真长到会阻塞事件循环,
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * [DESIGN-269 车1 §2.2/§2.3 — A2A client seam] — project a caller's per-request A2A peers
3
3
  * (`TaskRequest.a2aPeers`) into the engine, so a `sema` run can talk to the agents the USER declares,
4
- * not only the ones the deployment's config center declares. Point-for-point mirror of `task-mcp.ts`
4
+ * not only the ones the deployment's web-admin declares. Point-for-point mirror of `task-mcp.ts`
5
5
  * (the MCP seam), because the trust question is the same question — and deliberately NOT a copy where
6
6
  * the two protocols differ (see 「A2A 比 MCP 窄」 below).
7
7
  *
@@ -5,6 +5,7 @@ import { type CardRulePersisted, type RuleConsentLane } from "./rules-consent.js
5
5
  import { type AllowRuleShadowProjection, type DenialLimitFallback, type RuleOffersAbsence, type ApprovalRequestFrame, type ApprovalRevokeFrame, type RuleEvidenceProjection } from "./approval-card.js";
6
6
  import { type ApprovalAskStore, type AskRow } from "./plugins/approval-ask-store-sql.js";
7
7
  import type { ApprovalAskAuditSink } from "./approval-ask-audit-store.js";
8
+ import { type AskRowEndingCause, type SettleCause, type SettleOutcome } from "./approval-deny-reasons.js";
8
9
  import type { ParkCommitWatch } from "./plugins/park-commit-watch.js";
9
10
  import { type GovernanceAskMarks } from "./governance-ask-marks.js";
10
11
  import { type GovernancePosture } from "./runtime-governance.js";
@@ -25,6 +26,38 @@ export declare const APPROVAL_GATE_KINDS_SQL_IN: string;
25
26
  * (`test/parked-late-decision.test.ts` G3-c:本函数的输出经 `lookupRoute` 落 `approval-decide`)。会话段按路由的 `safeDecode` 对称编码。
26
27
  */
27
28
  export declare function approvalDecidePath(sessionId: string): string;
29
+ /**
30
+ * [ref] 随批小件:`tool_approval.not_pending` 404 的**判别位**([ref] 排障代价实证 —— 三因合并成一句人话,现场分不出「答案没地方兑」与「打错副本了」)。
31
+ * DECIDED/PARKED 已从 404 分流(DECIDED ⇒ 200 回放首决,回执带 `decidedBy`,**不是**成因;PARKED ⇒ 赎回席),残余两类:
32
+ * · 行 `VOID` / `DENIED`(没有人决过它)—— `cause` = **行上记的那个成因词**(问账 `denied_reason` 列;与决断口 410 `gone.ask` 体的 `cause`、审计 settle 行
33
+ * 的 `cause` 同一个词,闭集 {@link SettleCause});行上没写归因(存量行)⇒ 缺席,不替没写的行编一个词;
34
+ * · {@link NOT_PENDING_UNKNOWN_CAUSE} —— 无墓碑 / 无行 / 行仍在别处活着:换副本或换端点重试才有意义(这个词只属于 404 面,不是结局成因)。
35
+ * 对齐 [ref] 反枚举语义:cause 只在**已过属主门**的面上出,不扩枚举面(属主门不过 = 与未知 id 同形)。
36
+ * **无持久店的部署上恒不带**:那台机器压根没有行可判,编一个 cause 是撒谎(D1 体逐字不变)。
37
+ */
38
+ export declare const NOT_PENDING_UNKNOWN_CAUSE: "unknown_or_other_replica";
39
+ export type NotPendingCause = AskRowEndingCause | typeof NOT_PENDING_UNKNOWN_CAUSE;
40
+ /**
41
+ * 结算一张卡的**判决** —— 判别联合,逼每个调用点说清「这次等待是怎么结束的」:
42
+ * · `by:"human"` —— 一次**决议**到了(人答,或从问账行读回来的决议,含部署政策拒落成的 `DECIDED` 行,`hostSettledBy` 记它的来源词):`allowed` 说方向;审计 settle 行
43
+ * `outcome` = `allowed` / `denied`,**没有 `cause`**;
44
+ * · `by:"system"` —— 这次等待**没有等到决议就结束了**(非人结局):必须点名一个 {@link SettleCause};审计 settle 行 `outcome:"expired"` + 该 `cause`。
45
+ * 成因**只从事实读**(窗钟到 / 中止信号 / emit 零接收 / 腿作用域退出 / 兄弟被原子撤卡 / 有序关停锁存位 / 问账行的列),不从拒句散文判;
46
+ * 没有「裸 `settle(false, "expired")`」这一形。
47
+ */
48
+ export type SettleVerdict = {
49
+ readonly by: "human";
50
+ readonly allowed: boolean;
51
+ readonly updatedInput?: unknown;
52
+ /** 宿主自报来源(见 {@link HostSettledBy};缺席 = 人)。 */
53
+ readonly hostSettledBy?: HostSettledBy;
54
+ readonly denyReason?: string;
55
+ readonly readRootGrant?: string;
56
+ } | {
57
+ readonly by: "system";
58
+ readonly cause: SettleCause;
59
+ readonly hostSettledBy?: HostSettledBy;
60
+ };
28
61
  /**
29
62
  * 🔴 [ref](案A)追记 F6 —— durable 回决口(`POST /v1/tasks/:taskId/asks/:askId/decision`)的 **200 体
30
63
  * additive 判别位**:这次决议在**本副本**上有没有被一条活着的腿消费掉。
@@ -597,7 +630,13 @@ export interface ToolApprovalFrame {
597
630
  * 成因表也补了第四支:`settleVoidedSiblings` 的撤卡兄弟走的同样是这个词,那既不是 TTL 也不是断连。
598
631
  * Cosmetic dialog-dismiss(这句仍成立——它讲的是**帧的角色**,不是终局)。
599
632
  */
600
- outcome?: "allowed" | "denied" | "expired";
633
+ outcome?: SettleOutcome;
634
+ /**
635
+ * "tool_approval_complete" only(**ADDITIVE**):`outcome:"expired"` 的**成因** —— 与审计 settle 行 `cause` 是同一个词(闭集 {@link SettleCause}:窗到期 / 广播全灭 /
636
+ * 断连 / 呈不出去 / run 取消 / run 退出 / 批撤 / 兄弟被撤 / 崩溃 / 关停 ……)。**在场 ⇔ 非人结局**;人答(`allowed` / `denied`)不带。壳据它把「卡消失了」渲成具体的话
637
+ * (「已取消」「已到期」「断连」各自一句),而不再只有 `expired` 一个词。⚠️ 缺席不是证据:旧 server 从不发这个键,人答也不发。
638
+ */
639
+ cause?: SettleCause;
601
640
  }
602
641
  /** The per-run context `ask` recovers via ALS (mirrors QuestionRunContext + sessionId, which keys the allow-all). */
603
642
  /** [ref]:`GET /v1/approvals` 第二顶层键 `livePending` 的行形(与 durable `pending` 行**分数组不混编**
@@ -1363,7 +1402,7 @@ export declare class ToolApprovalCoordinator {
1363
1402
  * 三步:
1364
1403
  * ① 本进程握着的**每一张**未决卡(可达 / 悬挂 / 委派子代,不挑)按**断连同路**收场 —— {@link PendingApproval.forceParkNow}(park 路由;
1365
1404
  * `deny` 政策下是部署政策拒;有持久 ask 店时走同一把终局 claim)。有序关停与断连是同一件事:投递面要没了,**不是**有人拒了
1366
- * (不交裸 `false`,S-689 同律)。审计 settle 行携 `cause:"shutdown_before_park"`(成因在 `settle` 咽喉读锁存位,F10);
1405
+ * (不交裸 `false`,S-689 同律)。审计 settle 行携 `cause:"shutdown_before_park"`(`forceParkNow` 的调用点点名它);
1367
1406
  * ② 在 `deadlineMs` 之前等:未决卡结清、在飞腿闭合(闭了的腿照常落 `leg_closed`)、**本次路由到 park 的卡全部结清**
1368
1407
  * (F1:观察到 core 已处置这次调用 —— 停车行提交或承载它的腿退场 ⇒ 那张卡的审计 settle 行此刻才写,见 {@link settleParksAwaitingCommit})、
1369
1408
  * 店里在飞的 `put` 静默;
@@ -1427,7 +1466,7 @@ export declare class ToolApprovalCoordinator {
1427
1466
  *
1428
1467
  * 🔴 **本口只收「行真的没了」那一类**([ref] codex R3-F2,验真后拆分;红先钉在
1429
1468
  * `test/unattended-approval-policy.test.ts`):`expireAsk` 返回的 `voidedSiblings` 的行是 **VOID**,
1430
- * 裸 `(false,"expired")` 正是它们的真终局。而**调用方自己那个 askId** 的行是 **PARKING**(已转投递
1469
+ * 非人结局的判决(`{by:"system", cause}`)正是它们的真终局。而**调用方自己那个 askId** 的行是 **PARKING**(已转投递
1431
1470
  * 面)—— 把它混进本名单会让「同 askId 的重复本地注册」拿到裸 deny,而赢家拿的是 park 路由:同一条
1432
1471
  * 持久行、两种 live 终局。那一支改走 {@link settleSameAskIdParkRoute}。 */
1433
1472
  private settleVoidedSiblings;
@@ -1592,7 +1631,7 @@ export declare class ToolApprovalCoordinator {
1592
1631
  * 条目(跨副本/无流内窗)= 正常,返回 `{ settled: 0 }`,调用方据此诚实回显 `updatedInputForwarded`。
1593
1632
  *
1594
1633
  * 🔴 与 {@link settleVoidedSiblings} 是**两个语义,禁合并**(F29):那边是撤卡收尾,结算值恒
1595
- * `(false, "expired")`——批内兄弟被原子撤卡,它们的终局就是「没了」;这边是「同一只 askId 已经有了
1634
+ * `{by:"system", cause}`(`batch_sibling_withdrawn` 等)——批内兄弟被原子撤卡,它们的终局就是「没了」;这边是「同一只 askId 已经有了
1596
1635
  * 真决议」,重复注册必须拿到**同一个**决议(approve 就是 approve)——合并会把外部批准的重复条目错
1597
1636
  * 结算成拒绝。已被结算过的条目再调 settle 天然无操作(幂等),所以本口对「赢家自己已 settle」安全。
1598
1637
  */