@sema-agent/server 7.148.0 → 7.149.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 (247) hide show
  1. package/MIGRATION.md +429 -0
  2. package/README.md +16 -1
  3. package/README.zh-CN.md +4 -0
  4. package/USAGE.md +89 -55
  5. package/dist/adoption/wire.d.ts +3 -3
  6. package/dist/approval-card.d.ts +32 -32
  7. package/dist/approval-leg-origin.d.ts +33 -0
  8. package/dist/approval-leg-origin.js +4 -0
  9. package/dist/auth-bridge.d.ts +9 -1
  10. package/dist/auth-bridge.js +4 -4
  11. package/dist/auth-keys.d.ts +10 -1
  12. package/dist/auth-keys.js +8 -0
  13. package/dist/boot/execution-env.js +10 -11
  14. package/dist/boot/execution-lane.d.ts +6 -4
  15. package/dist/boot/execution-lane.js +3 -1
  16. package/dist/boot/org-delivery.d.ts +3 -2
  17. package/dist/boot/resolve-spec.js +6 -4
  18. package/dist/boot/runner-deps.js +3 -1
  19. package/dist/boot/stage-01-config.d.ts +1 -0
  20. package/dist/boot/stage-01-config.js +4 -3
  21. package/dist/boot/stage-02-web-admin-pull.d.ts +1 -0
  22. package/dist/boot/stage-02-web-admin-pull.js +10 -2
  23. package/dist/boot/stage-03-store-backend.d.ts +1 -0
  24. package/dist/boot/stage-03-store-backend.js +2 -2
  25. package/dist/boot/stage-04-stores.d.ts +1 -0
  26. package/dist/boot/stage-05-execution-env.d.ts +1 -0
  27. package/dist/boot/stage-06-runners.d.ts +2 -1
  28. package/dist/boot/stage-07-capability-layer.d.ts +2 -1
  29. package/dist/boot/stage-08-reapers.d.ts +2 -1
  30. package/dist/boot/stage-09-leader.d.ts +2 -1
  31. package/dist/boot/stage-10-http-server.d.ts +2 -1
  32. package/dist/boot/stores.d.ts +3 -0
  33. package/dist/boot/stores.js +22 -19
  34. package/dist/capabilities/tool-defer.d.ts +1 -1
  35. package/dist/capability-facts.d.ts +5 -4
  36. package/dist/capability-facts.js +3 -14
  37. package/dist/card-settle-stored-scope.d.ts +56 -0
  38. package/dist/card-settle-stored-scope.js +27 -0
  39. package/dist/card-void.d.ts +7 -12
  40. package/dist/card-void.js +2 -7
  41. package/dist/config-catalog.d.ts +12 -0
  42. package/dist/config-catalog.js +36 -32
  43. package/dist/config-invariants.d.ts +5 -4
  44. package/dist/config-invariants.js +4 -4
  45. package/dist/config-types.d.ts +37 -5
  46. package/dist/config.d.ts +6 -5
  47. package/dist/config.js +35 -24
  48. package/dist/context-window-notice.d.ts +31 -0
  49. package/dist/context-window-notice.js +28 -0
  50. package/dist/deployment-shape.d.ts +20 -11
  51. package/dist/deployment-shape.js +1 -0
  52. package/dist/env-name-allowlist-knobs.d.ts +6 -5
  53. package/dist/env-name-allowlist-knobs.js +5 -0
  54. package/dist/execution-lane-caps.d.ts +20 -5
  55. package/dist/execution-lane-caps.js +18 -4
  56. package/dist/hooks/command-spawn.d.ts +7 -2
  57. package/dist/hooks/command-spawn.js +13 -6
  58. package/dist/hooks/hook-runner.d.ts +5 -0
  59. package/dist/hooks/hook-runner.js +11 -7
  60. package/dist/http/admission.js +3 -3
  61. package/dist/http/approval-sweeps.js +3 -2
  62. package/dist/http/claim-heartbeat.d.ts +3 -3
  63. package/dist/http/claim-heartbeat.js +3 -3
  64. package/dist/http/claimed-run.d.ts +16 -9
  65. package/dist/http/claimed-run.js +8 -0
  66. package/dist/http/dispatch.js +5 -3
  67. package/dist/http/durable-run-leg.d.ts +8 -1
  68. package/dist/http/durable-run-leg.js +30 -11
  69. package/dist/http/execution-context.d.ts +115 -14
  70. package/dist/http/execution-context.js +130 -40
  71. package/dist/http/owner-access.d.ts +3 -2
  72. package/dist/http/owner-access.js +2 -3
  73. package/dist/http/principal-gate.d.ts +18 -11
  74. package/dist/http/principal-gate.js +3 -1
  75. package/dist/http/resume-ctx-read.d.ts +14 -3
  76. package/dist/http/resume-ctx-read.js +8 -2
  77. package/dist/http/resume-legs.d.ts +35 -3
  78. package/dist/http/resume-legs.js +244 -92
  79. package/dist/http/route-ctx.d.ts +6 -0
  80. package/dist/http/routes/a2a-serve.js +2 -0
  81. package/dist/http/routes/approvals-assistant.js +3 -2
  82. package/dist/http/routes/capabilities.js +1 -1
  83. package/dist/http/routes/diagnostics.d.ts +3 -1
  84. package/dist/http/routes/diagnostics.js +30 -5
  85. package/dist/http/routes/principal-inbox.d.ts +3 -1
  86. package/dist/http/routes/principal-inbox.js +3 -2
  87. package/dist/http/routes/runs.js +10 -7
  88. package/dist/http/routes/session-sync.d.ts +24 -5
  89. package/dist/http/routes/session-sync.js +46 -34
  90. package/dist/http/routes/sessions-list.d.ts +1 -1
  91. package/dist/http/routes/tasks.js +127 -93
  92. package/dist/http/server.d.ts +4 -5
  93. package/dist/http/server.js +30 -5
  94. package/dist/http/submit-ctx.d.ts +1 -0
  95. package/dist/http/submit-ctx.js +2 -3
  96. package/dist/index.d.ts +3 -1
  97. package/dist/index.js +1 -0
  98. package/dist/leg-facts.d.ts +7 -2
  99. package/dist/leg-facts.js +1 -0
  100. package/dist/local-store-declaration.d.ts +54 -0
  101. package/dist/local-store-declaration.js +59 -0
  102. package/dist/mcp-assertion-header.d.ts +1 -1
  103. package/dist/mcp-assertion-header.js +1 -1
  104. package/dist/memory-project-layer.js +1 -1
  105. package/dist/memory-scope.d.ts +4 -4
  106. package/dist/memory-scope.js +4 -4
  107. package/dist/memory-sync-client.js +2 -2
  108. package/dist/model-context-window.d.ts +50 -11
  109. package/dist/model-context-window.js +20 -1
  110. package/dist/model-entry-refusal.d.ts +5 -4
  111. package/dist/model-entry-refusal.js +17 -3
  112. package/dist/model-reach-scope.d.ts +2 -1
  113. package/dist/observability/fail-open.d.ts +14 -2
  114. package/dist/observability/fail-open.js +14 -2
  115. package/dist/observability/metrics.js +1 -1
  116. package/dist/observability/run-terminal.js +1 -0
  117. package/dist/observability/secret-env-scrub.d.ts +1 -1
  118. package/dist/observability/secret-env-scrub.js +1 -1
  119. package/dist/org-delivery-gate.d.ts +31 -6
  120. package/dist/org-delivery-gate.js +7 -4
  121. package/dist/owner-faces.d.ts +3 -2
  122. package/dist/park-row-commit.d.ts +67 -0
  123. package/dist/park-row-commit.js +76 -0
  124. package/dist/parked-decide.d.ts +9 -7
  125. package/dist/parked-decide.js +25 -6
  126. package/dist/peer-directory.d.ts +1 -1
  127. package/dist/plugins/adoption-log-sql.d.ts +3 -3
  128. package/dist/plugins/adoption-log-sql.js +19 -19
  129. package/dist/plugins/approval-ask-store-sql.d.ts +1 -1
  130. package/dist/plugins/approval-ask-store-sql.js +3 -5
  131. package/dist/plugins/approval-exemption-skill-cutoff.d.ts +64 -0
  132. package/dist/plugins/approval-exemption-skill-cutoff.js +122 -0
  133. package/dist/plugins/approval-exemption-skill-m46.d.ts +0 -6
  134. package/dist/plugins/approval-exemption-skill-m46.js +6 -10
  135. package/dist/plugins/approval-exemption-store.d.ts +26 -1
  136. package/dist/plugins/approval-exemption-store.js +28 -19
  137. package/dist/plugins/ensure-schema-lock-policy.d.ts +36 -3
  138. package/dist/plugins/ensure-schema-lock-policy.js +75 -9
  139. package/dist/plugins/file-run-store.d.ts +22 -9
  140. package/dist/plugins/file-run-store.js +50 -22
  141. package/dist/plugins/local-checkpoint-store.d.ts +4 -0
  142. package/dist/plugins/local-checkpoint-store.js +2 -1
  143. package/dist/plugins/local-data-root-admission.d.ts +52 -0
  144. package/dist/plugins/local-data-root-admission.js +100 -0
  145. package/dist/plugins/local-engine-high-water.d.ts +28 -7
  146. package/dist/plugins/local-engine-high-water.js +27 -22
  147. package/dist/plugins/local-session-store.d.ts +134 -49
  148. package/dist/plugins/local-session-store.js +149 -108
  149. package/dist/plugins/memory-run-store.d.ts +14 -9
  150. package/dist/plugins/memory-run-store.js +47 -21
  151. package/dist/plugins/one-time-migration-marker.d.ts +19 -3
  152. package/dist/plugins/one-time-migration-marker.js +7 -1
  153. package/dist/plugins/one-time-migrations.d.ts +46 -20
  154. package/dist/plugins/one-time-migrations.js +102 -79
  155. package/dist/plugins/org-delivery-quota-store.d.ts +34 -11
  156. package/dist/plugins/org-delivery-quota-store.js +29 -14
  157. package/dist/plugins/permission-rule-store-sql.d.ts +1 -1
  158. package/dist/plugins/permission-rule-store-sql.js +5 -9
  159. package/dist/plugins/pg-pool.d.ts +1 -1
  160. package/dist/plugins/pg-pool.js +10 -12
  161. package/dist/plugins/remote-env-device.d.ts +3 -2
  162. package/dist/plugins/remote-env-e2b.d.ts +1 -7
  163. package/dist/plugins/remote-env-e2b.js +10 -7
  164. package/dist/plugins/remote-env-host.d.ts +50 -9
  165. package/dist/plugins/remote-env-host.js +77 -20
  166. package/dist/plugins/remote-env-k8s.js +4 -2
  167. package/dist/plugins/remote-env-local-docker.d.ts +6 -3
  168. package/dist/plugins/remote-env-local-docker.js +8 -23
  169. package/dist/plugins/run-store-sql.d.ts +26 -7
  170. package/dist/plugins/run-store-sql.js +44 -16
  171. package/dist/plugins/scenario-prefix-switch-m42.d.ts +3 -1
  172. package/dist/plugins/scenario-prefix-switch-m42.js +4 -3
  173. package/dist/plugins/schema-consistency.d.ts +89 -5
  174. package/dist/plugins/schema-consistency.js +176 -7
  175. package/dist/plugins/schema-drift-sentence.d.ts +6 -5
  176. package/dist/plugins/schema-drift-sentence.js +13 -5
  177. package/dist/plugins/session-placement.d.ts +5 -4
  178. package/dist/plugins/shell-sentinel-owner-m48.d.ts +22 -0
  179. package/dist/plugins/shell-sentinel-owner-m48.js +6 -0
  180. package/dist/plugins/stop-then-start-sentence.d.ts +16 -0
  181. package/dist/plugins/stop-then-start-sentence.js +7 -0
  182. package/dist/plugins/store-backend.d.ts +22 -8
  183. package/dist/plugins/store-backend.js +58 -24
  184. package/dist/plugins/store-contracts.d.ts +33 -3
  185. package/dist/plugins/store-contracts.js +16 -0
  186. package/dist/plugins/tidb-pool.d.ts +11 -6
  187. package/dist/plugins/tidb-pool.js +18 -12
  188. package/dist/plugins/workspace-custody.d.ts +44 -0
  189. package/dist/plugins/workspace-custody.js +47 -0
  190. package/dist/project-identity.d.ts +8 -7
  191. package/dist/project-identity.js +40 -17
  192. package/dist/project-layer-key.d.ts +13 -2
  193. package/dist/project-layer-key.js +9 -1
  194. package/dist/read-deny-floor-notice.d.ts +36 -0
  195. package/dist/read-deny-floor-notice.js +40 -0
  196. package/dist/{plain-string-record.d.ts → request-declaration-disposition.d.ts} +9 -23
  197. package/dist/request-declaration-disposition.js +39 -0
  198. package/dist/run-cancel-card.d.ts +28 -0
  199. package/dist/run-cancel-card.js +19 -0
  200. package/dist/run-cancel-context.d.ts +10 -0
  201. package/dist/run-cancel-context.js +1 -0
  202. package/dist/run-local.js +28 -13
  203. package/dist/runs.d.ts +31 -7
  204. package/dist/runs.js +34 -16
  205. package/dist/security.d.ts +2 -2
  206. package/dist/server-secret-env.d.ts +34 -20
  207. package/dist/server-secret-env.js +61 -18
  208. package/dist/session-agent.d.ts +3 -2
  209. package/dist/session-children-retire.d.ts +6 -3
  210. package/dist/session-children-retire.js +2 -5
  211. package/dist/session-workspace.d.ts +3 -3
  212. package/dist/store-admission.d.ts +33 -0
  213. package/dist/store-admission.js +49 -0
  214. package/dist/store-posture.d.ts +5 -0
  215. package/dist/store-posture.js +18 -1
  216. package/dist/stores-sql/checkpoint-store-sql.d.ts +1 -1
  217. package/dist/stores-sql/checkpoint-store-sql.js +3 -5
  218. package/dist/stores-sql/file-history-store-sql.d.ts +1 -1
  219. package/dist/stores-sql/file-history-store-sql.js +3 -5
  220. package/dist/stores-sql/tool-result-store-sql.d.ts +1 -1
  221. package/dist/stores-sql/tool-result-store-sql.js +4 -6
  222. package/dist/task-a2a.d.ts +3 -8
  223. package/dist/task-a2a.js +25 -27
  224. package/dist/task-cwd.d.ts +23 -7
  225. package/dist/task-cwd.js +3 -0
  226. package/dist/task-mcp.d.ts +3 -3
  227. package/dist/task-mcp.js +1 -1
  228. package/dist/task-settings.js +1 -0
  229. package/dist/terminal.d.ts +2 -0
  230. package/dist/terminal.js +21 -6
  231. package/dist/tool-approval.d.ts +44 -36
  232. package/dist/tool-approval.js +66 -47
  233. package/dist/trace/engine-notice-wire.d.ts +24 -21
  234. package/dist/trace/engine-notice-wire.js +7 -3
  235. package/dist/trace/ledger-sink.d.ts +3 -1
  236. package/dist/trace/project.d.ts +4 -2
  237. package/dist/trace/project.js +8 -7
  238. package/dist/trace/redact.d.ts +12 -0
  239. package/dist/trace/redact.js +5 -1
  240. package/dist/trace/self-minted-wire.d.ts +131 -52
  241. package/dist/trace/self-minted-wire.js +71 -39
  242. package/dist/web-admin-client/apply-effective.js +22 -9
  243. package/docs/error-text-lexicon.json +317 -0
  244. package/package.json +3 -1
  245. package/scripts/embed-minimal.mjs +183 -0
  246. package/wire-changes/server@7.149.0.json +372 -0
  247. package/dist/plain-string-record.js +0 -70
@@ -1,3 +1,4 @@
1
+ import { LOCAL_STORE_DECLARATION_WORDS } from "./local-store-declaration.js";
1
2
  import { CROSS_SESSION_INBOUND_SETTINGS, CROSS_SESSION_DIALOG_EXPIRY_VALUES } from "@sema-agent/core";
2
3
  import { GLOBAL_SCOPE } from "@sema-agent/settings-schema/api/scopes";
3
4
  import { DEVICE_RELAY_NONE, WEB_ADMIN_ENV, DOMAIN_SCHEMAS, buildRetiredEnvWire } from "@sema-agent/settings-schema";
@@ -27,6 +28,7 @@ export const CATALOG_VALUE_TYPES = ["boolean", "number", "string", "enum", "csv"
27
28
  export const CATALOG_TIMINGS = ["hot", "restart", "deploy", "inert"];
28
29
  export const CATALOG_DANGER_AXES = ["security", "billing", "data"];
29
30
  export const URL_CREDENTIAL_POLICIES = ["refuse", "mask"];
31
+ export const SECRET_CREDENTIAL_FORMS = ["whole", "token-table", "key-set"];
30
32
  const RESTART_SLICE_SET = {
31
33
  skills: true,
32
34
  mcp: true,
@@ -69,8 +71,8 @@ export const CONFIG_CATALOG = [
69
71
  r("ADOPTION_IMPORT_MAX_SESSION_BYTES", "limitsHttp", "number", `收编批量导入每个会话信封最多多少字节(信封 JSON 的 UTF-8 字节;超了只拒那一个元素 rejected/too_large,带 count 与 cap;合法域 [${ADOPTION_IMPORT_MAX_SESSION_BYTES_FLOOR}, ${ADOPTION_IMPORT_MAX_SESSION_BYTES_CEILING}] —— 上帽 = JSON 体上限减空批包络,再大的值够不着,越界夹取 + 点名,小数拒启);当前值经能力位 adoptionImport.maxSessionBytes 交给已收编的源主体`, { staticDefault: String(ADOPTION_IMPORT_MAX_SESSION_BYTES_DEFAULT), configKey: "adoptionImportMaxSessionBytes" }),
70
72
  r("AGENT_DATA_DIR", "store", "path", "本机数据根回落链一环(LOCAL_DATA_ROOT → CONFIG_LOCAL_DIR → AGENT_DATA_DIR → ~/.ai-agent);记忆引擎缺省根同链", { danger: DATA, derivedDefaultNote: "缺席 ⇒ 链上下一环,最终 ~/.ai-agent" }),
71
73
  r("ALLOW_UNAUTHED_WRITES", "auth", "boolean", "无 service token 时仍接受任务提交(本地开发逃生口;缺省 fail-closed 拒提交)", { staticDefault: "false", danger: SEC, configKey: "allowUnauthedWrites" }),
72
- r("ANTHROPIC_API_KEY", "modelPlane", "secret", "Anthropic 协议路线的 x-api-key 凭据(只发 x-api-key 头;与 ANTHROPIC_AUTH_TOKEN 互斥 —— 同设拒启,机读码 `config.anthropic_credential_conflict`;与 BASE_URL 同在时可推断 provider)", { danger: [...SEC, ...BILL] }),
73
- r("ANTHROPIC_AUTH_TOKEN", "modelPlane", "secret", "Anthropic 兼容生态的 Bearer 凭据(只发 Authorization: Bearer 头;与 ANTHROPIC_API_KEY 互斥 —— 同设拒启,机读码 `config.anthropic_credential_conflict`)", { danger: [...SEC, ...BILL] }),
74
+ r("ANTHROPIC_API_KEY", "modelPlane", "secret", "Anthropic 协议路线的 x-api-key 凭据(只发 x-api-key 头;与 ANTHROPIC_AUTH_TOKEN 互斥 —— 同设拒启,机读码 `config.anthropic_credential_conflict`;与 BASE_URL 同在时可推断 provider)", { credentialForm: "whole", danger: [...SEC, ...BILL] }),
75
+ r("ANTHROPIC_AUTH_TOKEN", "modelPlane", "secret", "Anthropic 兼容生态的 Bearer 凭据(只发 Authorization: Bearer 头;与 ANTHROPIC_API_KEY 互斥 —— 同设拒启,机读码 `config.anthropic_credential_conflict`)", { credentialForm: "whole", danger: [...SEC, ...BILL] }),
74
76
  r("ANTHROPIC_BASE_URL", "modelPlane", "url", "Anthropic 协议路线 base URL(与凭据同在且 MODEL_PROVIDER 未设 ⇒ 推断 provider=anthropic 并 boot notice;带 userinfo 拒启,机读码 `config.gateway_url_userinfo`;解析不动/不透明形拒启,机读码 `config.model_route_url_invalid`;带 `#fragment` 拒启,机读码 `config.model_route_url_fragment` —— fragment 从不上线,后缀会落进被丢弃的那一半)", { credentialPolicy: "refuse" }),
75
77
  r("ANTHROPIC_CACHE_BREAKPOINTS", "modelPlane", "boolean", "Anthropic 路线 prompt-cache breakpoints 开关", { staticDefault: "true" }),
76
78
  r("ANTHROPIC_MAX_RETRIES", "modelPlane", "number", "Anthropic 路线 SDK 每次调用重试上限", { derivedDefaultNote: "缺席 ⇒ 不传引擎,core/SDK 默认当家" }),
@@ -79,7 +81,7 @@ export const CONFIG_CATALOG = [
79
81
  r("APPROVAL_AUTO_BUDGET", "approval", "number", "每 run-leg 自动放行的普通门控工具调用数上限(0=关;防审批循环的熔断,不是安全 ask 的帽)", { staticDefault: "0", danger: SEC, configKey: "approvalAutoBudget" }),
80
82
  r("APPROVAL_DENY", "approval", "csv", "始终拒绝的工具名单(装配期拒不可匹配名)", { danger: SEC, configKey: "approvalDeny" }),
81
83
  r("APPROVAL_GRANT", "approval", "csv", "运维的 allow 表(引擎 allow 层的部署成员 RunnerDeps.allowedTools,每只 Runner 同一席:HTTP 提交 / 续跑 / 停驻赎回 / run-local / leader 一律;规则文法 = 引擎的:工具名 / mcp__<server>__* / a2a__<peer>__* / Bash(<命令>) / Bash(<前缀>:*) / Read(//<dir>/**);命中 = 免问,清普通问与没人表态两类,内置工具也在内;清不掉任何一层的 deny / ask 规则、APPROVAL_NEVER_AUTO、shell 地板、写保护、治理、hook 的问、plan;不是白名单;引擎读成空的条目 / 服务器段铸不出 ⇒ 拒启)", { danger: SEC, configKey: "approvalGrant", derivedDefaultNote: "缺席 = 空表(本层不表态,折叠与未设逐字同)" }),
82
- r("APPROVAL_HMAC_KEYS", "approval", "secret", "直连门(D-G)HMAC 完整性密钥集(空=直连门不激活)", { danger: SEC }),
84
+ r("APPROVAL_HMAC_KEYS", "approval", "secret", "直连门(D-G)HMAC 完整性密钥集(空=直连门不激活)", { credentialForm: "key-set", danger: SEC }),
83
85
  r("APPROVAL_NEVER_AUTO", "approval", "csv", "永不被 AUTO_BUDGET 自动放行的工具集(不可逆动作恒要人)", { danger: SEC, configKey: "approvalNeverAuto" }),
84
86
  r("APPROVAL_REQUIRE", "approval", "csv", "必须人审的工具名单(部署名单门;center 腿热:refresh 拍整表换代,无 checkpoint 店的部署发非空名单 ⇒ 审批组整组拒)", { danger: SEC, configKey: "approvalRequire", center: cGov("approvalRequire") }),
85
87
  r("APPROVAL_TERMINAL_BACKSTOP_MS", "approval", "number", "checkpoint 店(SQL 与 local 文件孪生同一公式)pending 行的 crash-safe 绝对 GC 上限(ms;下限 60s,非有限值落默认)", { staticDefault: String(30 * 86_400_000), danger: DATA }),
@@ -118,7 +120,7 @@ export const CONFIG_CATALOG = [
118
120
  r("CONFIG_LKG_PATH", "integrations", "path", "LKG 落盘路径(设了 ⇒ 派生一条读拒行 = 这条绝对路径:根锚定,只守这一个文件,经符号链接的目录时引擎沿链连目标一起守;大小写不敏感;用户仓里同尾的路径读得到;空串拒启)", { derivedDefaultNote: "缺席 ⇒ 配置根(SEMA_CONFIG_DIR,缺省 ~/.sema)下按 worker + 凭证身份分箱派生", configKey: "configLkgPath" }),
119
121
  r("CONFIG_LOCAL_DIR", "integrations", "path", "本地配置源根(config.d/<domain>.json);兼作数据根回落链一环", { configKey: "configLocalDir", danger: DATA }),
120
122
  r("CONFIG_LOCAL_OWNER_UID", "integrations", "number", "目录信任判官(本地配置源读之前;LKG 读回与调度共享店读写之前同一只)多信的那一个属主 uid(本服务用户与 root 之外 —— userns-remap 的 bind-mount、运维用户持有的配置);只放宽属主判据,组 / 他人可写照拒;形错拒启", { configKey: "configLocalOwnerUid", danger: SEC, derivedDefaultNote: "缺席 = config.d 路径上的目录与文档只许属于本服务用户或 root" }),
121
- r("CONFIG_PROVIDER", "integrations", "enum", `配置源双模选择(闭集,逐字比较;认不出的词 ⇒ 拒启;remote 而 ${WEB_ADMIN_ENV.url} 缺席 ⇒ 拒启 —— remote 的配置只来自那只中心)`, { enumValues: CONFIG_PROVIDER_WORDS, derivedDefaultNote: `缺席:${WEB_ADMIN_ENV.url} 在场 ⇒ remote,否则纯 env(无管道)`, configKey: "configProvider" }),
123
+ r("CONFIG_PROVIDER", "integrations", "enum", `配置源双模选择(闭集,逐字比较;认不出的词 ⇒ 拒启;remote 而 ${WEB_ADMIN_ENV.url} 缺席 ⇒ 拒启 —— remote 的配置只来自那只中心)`, { enumValues: CONFIG_PROVIDER_WORDS, danger: SEC, derivedDefaultNote: `缺席:${WEB_ADMIN_ENV.url} 在场 ⇒ remote,否则纯 env(无管道)`, configKey: "configProvider" }),
122
124
  r("CONFIG_REQUIRE_ROSTER", "integrations", "boolean", "远程 registry 非 dryRun 时布防 ready 门:roster 未落地 ⇒ 计费提交 503 + /health ready:false(严格 'true')", { staticDefault: "false" }),
123
125
  r("CORS_ORIGIN", "auth", "csv", "CORS 白名单(单值 v1 兼容回显;多值按请求 Origin 匹配 + Vary;未设=无 CORS 面)", { danger: SEC, configKey: "corsOrigins" }),
124
126
  r("COST_QUOTA_WINDOW_SEC", "limitsHttp", "number", "per-principal 成本配额窗长(秒);SQL 腿窗长进桶主键 ⇒ center 腿显式 deferred(重启生效)", { staticDefault: "86400", danger: BILL, configKey: "costQuotaWindowSec", center: cLimits("costQuotaWindowSec", { timing: "restart", restartReason: "cost-quota-window" }) }),
@@ -150,19 +152,19 @@ export const CONFIG_CATALOG = [
150
152
  r("DOCKER_NETWORK", "orchestration", "enum", "local-docker 容器网络模式", { enumValues: ["none", "bridge", "host"], staticDefault: "bridge", danger: SEC }),
151
153
  r("DOCKER_PATH", "orchestration", "path", "docker 二进制路径"),
152
154
  r("DOCKER_PIDS_LIMIT", "orchestration", "number", "local-docker fork-bomb 背栓(--pids-limit;非法值回 adapter 默认 512+warn)", { danger: SEC, derivedDefaultNote: "缺席 ⇒ adapter 默认 512" }),
153
- r("DOCKER_SANDBOX_ENV", "orchestration", "secret", "local-docker 车道每条 docker exec 以 -e 注入的本进程 env 点名表(NAME,NAME;点到的键从 worker env 原样取,值不进 spec/center/日志;与 LSP_ENV_ALLOW / E2B_SANDBOX_ENV 同一只解析器与「点名放行」谓词:形错 / 点名名单型旋钮 / 点名本服务自有凭据名(会把本服务的凭据装进模型读得到的沙箱;判官 = 引擎拒白名单的同一只)拒启且不回显值;本进程环境里没有的名按序号 warn、不转发;只在本车道被选中时求值;原文按凭据类对待:只回在场位、不进任何子进程)", { danger: SEC }),
155
+ r("DOCKER_SANDBOX_ENV", "orchestration", "secret", "local-docker 车道每条 docker exec 以 -e 注入的本进程 env 点名表(NAME,NAME;点到的键从 worker env 原样取,值不进 spec/center/日志;与 LSP_ENV_ALLOW / E2B_SANDBOX_ENV 同一只解析器与「点名放行」谓词:形错 / 点名名单型旋钮 / 点名本服务自有凭据 —— 名是,或值是本服务的某一枚凭据(另一个名下的副本)—— (会把本服务的凭据装进模型读得到的沙箱;判官 = 引擎此刻的自有凭据声明)拒启且不回显值;本进程环境里没有的名按序号 warn、不转发;只在本车道被选中时求值;原文按凭据类对待:只回在场位、不进任何子进程)", { credentialForm: "whole", danger: SEC }),
154
156
  r("DRAIN_GRACE_MS", "limitsHttp", "number", "SIGTERM 优雅排空窗(ms;期间新计费提交 503+Retry-After)。出厂默认是**服务器部署**的取值;壳自 spawn 的引擎会被壳注入更短的窗 ⇒ 排壳形关机预算时按壳自己注入的值算(壳读不到本目录:它是 operator-only),排空开始后本次排空定死的到期点读 GET /health 的 engineSignal.draining.deadlineAt,从信号到进程退出的上界见 USAGE 的「停机上界(契约句)」;不照抄 staticDefault", { staticDefault: String(10 * 60 * 1000), configKey: "drainGraceMs", center: cLimits("drainGraceMs") }),
155
157
  r("DRAIN_SECOND_SIGNAL_MIN_GAP_MS", "limitsHttp", "number", `排空期「第二发信号 = 硬停」的最小间隔(ms;锚 = 本次排空的第一发停止信号 —— SIGTERM / SIGHUP 升级进的排空,入口那一发就是它;排空口 / 租约被拒 / 附着租约自退进的排空,到达的第一发被吸收、不缩短期限。SIGTERM / SIGINT 与锚相隔不足 ⇒ 同一拍的重复投递,一行 drain_duplicate_signal_ignored 后忽略、排空继续;0 = 关,恒按第二发硬停;须为 [${DRAIN_SECOND_SIGNAL_MIN_GAP_BOUNDS.minMs}, ${DRAIN_SECOND_SIGNAL_MIN_GAP_BOUNDS.maxMs}] 内十进制整数(上界 = DRAIN_GRACE_MS 地板),小数 / 负数 / 越界拒启)`, { staticDefault: String(DRAIN_SECOND_SIGNAL_MIN_GAP_DEFAULT_MS), configKey: "drainSecondSignalMinGapMs" }),
156
158
  r("DURABLE_APPROVAL", "approval", "boolean", "durable suspend/resume HITL(需 SQL 店;决定 checkpointStore 与 /v1/approvals 面的存在性)", { danger: SEC, derivedDefaultNote: "posture 三态:显式词恒赢,缺席 = 单用户(REQUIRE_PRINCIPAL≠true)且有耐久店 ⇒ on / 多租户或无耐久店 ⇒ off;生效来源见 GET /v1/diagnostics/wiring 的 serverGates.durableApproval.source", configKey: "durableApproval" }),
157
159
  r("E2B_ALLOW_NET", "orchestration", "boolean", "e2b 沙箱出网许可", { danger: SEC, derivedDefaultNote: "缺席 ⇒ 不铸键(adapter 默认允许)" }),
158
- r("E2B_API_KEY", "orchestration", "secret", "E2B 车道 API 凭据(REMOTE_EXEC=e2b 必需件)", { danger: [...SEC, ...BILL] }),
160
+ r("E2B_API_KEY", "orchestration", "secret", "E2B 车道 API 凭据(REMOTE_EXEC=e2b 必需件)", { credentialForm: "whole", danger: [...SEC, ...BILL] }),
159
161
  r("E2B_BG_DEFAULT_TIMEOUT_SEC", "orchestration", "number", "e2b 后台 shell 缺省超时(秒)", { staticDefault: "300" }),
160
162
  r("E2B_BG_MAX_CONCURRENT", "orchestration", "number", "e2b 后台 shell 并发帽", { staticDefault: "8" }),
161
163
  r("E2B_BG_MAX_TIMEOUT_SEC", "orchestration", "number", "e2b 后台 shell 超时上限(秒)", { staticDefault: "1800" }),
162
164
  r("E2B_LIVENESS_MS", "orchestration", "number", LIVENESS_KNOB_SEMANTICS("e2b"), { derivedDefaultNote: LIVENESS_KNOB_DEFAULT_NOTE }),
163
165
  r("E2B_MOUNT_PATH", "orchestration", "path", "e2b 工作区根(resume 用当前值,改前先 drain 挂起任务)"),
164
166
  r("E2B_ORPHAN_RECLAIM", "orchestration", "boolean", "崩溃遗留沙盒回收腿(boot 一次+周期;判据保守,拿不准恒不杀)", { staticDefault: "true", danger: BILL }),
165
- r("E2B_SANDBOX_ENV", "orchestration", "secret", "转发进 e2b 沙箱的本进程 env 点名表(NAME,NAME;点到的键从 worker env 原样取,值不进 spec/center/事件日志;与 LSP_ENV_ALLOW / DOCKER_SANDBOX_ENV 同一只解析器与「点名放行」谓词:形错 / 点名名单型旋钮 / 点名本服务自有凭据名(会把本服务的凭据装进模型读得到的沙箱;判官 = 引擎拒白名单的同一只)拒启且不回显值;本进程环境里没有的名按序号 warn、不转发;只在本车道被选中时求值;原文按凭据类对待:只回在场位、不进任何子进程)", { danger: SEC }),
167
+ r("E2B_SANDBOX_ENV", "orchestration", "secret", "转发进 e2b 沙箱的本进程 env 点名表(NAME,NAME;点到的键从 worker env 原样取,值不进 spec/center/事件日志;与 LSP_ENV_ALLOW / DOCKER_SANDBOX_ENV 同一只解析器与「点名放行」谓词:形错 / 点名名单型旋钮 / 点名本服务自有凭据 —— 名是,或值是本服务的某一枚凭据(另一个名下的副本)—— (会把本服务的凭据装进模型读得到的沙箱;判官 = 引擎此刻的自有凭据声明)拒启且不回显值;本进程环境里没有的名按序号 warn、不转发;只在本车道被选中时求值;原文按凭据类对待:只回在场位、不进任何子进程)", { credentialForm: "whole", danger: SEC }),
166
168
  r("E2B_SANDBOX_MAX_MS", "orchestration", "number", "e2b 沙箱最长存活(ms)", { staticDefault: "3600000", danger: BILL }),
167
169
  r("E2B_TEMPLATE", "orchestration", "string", "e2b 模板名(缺省 adapter 基础模板)"),
168
170
  r("E2B_TIMEOUT_MS", "orchestration", "number", "e2b 单命令总超时(ms)"),
@@ -187,8 +189,9 @@ export const CONFIG_CATALOG = [
187
189
  }),
188
190
  r("GIT_API_BASEURL", "integrations", "url", "repo 工具的 Git host API base", { credentialPolicy: "refuse", configKey: "gitApiBaseUrl" }),
189
191
  r("GIT_API_KIND", "integrations", "enum", "Git host API 方言", { enumValues: ["gitea", "github"], staticDefault: "gitea", configKey: "gitApiKind" }),
190
- r("GIT_API_TOKEN", "integrations", "secret", "repo 工具的 Git host 凭据", { danger: SEC }),
192
+ r("GIT_API_TOKEN", "integrations", "secret", "repo 工具的 Git host 凭据", { credentialForm: "whole", danger: SEC }),
191
193
  r("HOOKS_TIMEOUT_MS", "orchestration", "number", "请求 hooks 的每张车道注册(settings.hooks / settings.hooks.managed,各一份同值)每个 handler 的时间预算(ms;0=零预算是合法值)", { derivedDefaultNote: "缺席 ⇒ 不铸键,读法 settingsHooksBudgetMs 取 600000" }),
194
+ r("HOOK_ENV_ALLOW", "orchestration", "secret", `settings hook 环境的点名放回名单(点到的键从服务进程环境原样放回 hook 环境、部署方显式承担:命令 hook 的子进程 env 与 http hook 头的 $NAME 插值读同一份;服务进程变量进 hook 环境只有这一个来源,请求的 allowedEnvVars / settings.httpHookAllowedEnvVars 只收窄、不授予;形错 / 点名任一只名单型旋钮(含自己)/ 点名本服务自有凭据 —— 名是,或值是本服务的某一枚凭据(另一个名下的副本;列表形凭据逐枚比)—— (判官 = 引擎此刻的自有凭据声明)拒启且不回显值;本进程环境里没有的名按序号 warn、不放回、不回显;多租户姿态(忽略时起服 warn 一次):${describeAllowlistPostures()};原文按凭据类对待:只回在场位、不进任何子进程)`, { credentialForm: "whole", danger: SEC, derivedDefaultNote: "缺席 / 空串 ⇒ 空名单 = 不放回(hook 环境 = 十二名基础名单 + 请求 settings.env)" }),
192
195
  r("HOST_BG_DEFAULT_TIMEOUT_SEC", "orchestration", "number", "host 后台 shell 缺省超时(秒)", { staticDefault: "300" }),
193
196
  r("HOST_BG_ENABLED", "orchestration", "boolean", "host 车道后台 shell 开关", { staticDefault: "true" }),
194
197
  r("HOST_BG_FILE_CAP", "orchestration", "number", "host 后台 shell 磁盘护栏(字节;失控输出被 reap)", { staticDefault: String(64 * 1024 * 1024) }),
@@ -224,11 +227,11 @@ export const CONFIG_CATALOG = [
224
227
  r("K8S_NAMESPACE", "orchestration", "string", "沙箱 pod 所在的 namespace(REMOTE_EXEC=k8s 必需件,与 K8S_SANDBOX_IMAGE 同级:缺席、空串或只有空白 ⇒ 起服拒,拒句点名本旋钮;服务不带内置缺省 —— 部署的声明是唯一来源,随包 chart 已显式设为 sandbox.namespace;只在 REMOTE_EXEC=k8s 被选中时求值)"),
225
228
  r("K8S_RUNTIME_CLASS", "orchestration", "string", "沙箱 pod runtimeClass(Kata 等)"),
226
229
  r("K8S_SANDBOX_BROKER_IMAGE", "orchestration", "string", "成员 git 凭据代理容器的镜像(k8s 沙箱 pod 的 containers[1],只挂在成员 run 的 pod 上;建议填本引擎自身镜像 —— 代理是本包里固定路径的一只程序,命令固定);不设 ⇒ 成员 git 凭据平面关(GET /v1/capabilities 的 credentialPlane.sandboxGit = broker_image_unset),任何 pod 都不挂代理,pod 形逐字节同不设时;只在 REMOTE_EXEC=k8s 被选中时求值"),
227
- r("K8S_SANDBOX_ENV", "orchestration", "secret", `转发进 k8s 沙箱 pod 容器 env 的本进程 env 点名表(NAME,NAME;点到的键从 worker env 原样取,值只进该 pod 自己的 Secret —— pod spec 的容器 env 只带 secretKeyRef 引用、不带值,Secret 随 pod 由集群回收;不进工作区 / 快照 / center / 事件日志;沙箱命名空间的 Role 要 secrets ${SANDBOX_SECRET_SEAT_VERBS.env.join(" / ")},起服问不许即拒启;与 LSP_ENV_ALLOW / E2B_SANDBOX_ENV / DOCKER_SANDBOX_ENV 同一只解析器与「点名放行」谓词:形错 / 点名名单型旋钮 / 点名本服务自有凭据名(会把本服务的凭据装进模型读得到的沙箱;判官 = 引擎拒白名单的同一只)拒启且不回显值;本进程环境里没有的名按序号 warn、不转发;与包源派生 env 撞名时显式名单胜;只在本车道被选中时求值;原文按凭据类对待:只回在场位、不进任何子进程)`, { danger: SEC }),
230
+ r("K8S_SANDBOX_ENV", "orchestration", "secret", `转发进 k8s 沙箱 pod 容器 env 的本进程 env 点名表(NAME,NAME;点到的键从 worker env 原样取,值只进该 pod 自己的 Secret —— pod spec 的容器 env 只带 secretKeyRef 引用、不带值,Secret 随 pod 由集群回收;不进工作区 / 快照 / center / 事件日志;沙箱命名空间的 Role 要 secrets ${SANDBOX_SECRET_SEAT_VERBS.env.join(" / ")},起服问不许即拒启;与 LSP_ENV_ALLOW / E2B_SANDBOX_ENV / DOCKER_SANDBOX_ENV 同一只解析器与「点名放行」谓词:形错 / 点名名单型旋钮 / 点名本服务自有凭据 —— 名是,或值是本服务的某一枚凭据(另一个名下的副本)—— (会把本服务的凭据装进模型读得到的沙箱;判官 = 引擎此刻的自有凭据声明)拒启且不回显值;本进程环境里没有的名按序号 warn、不转发;与包源派生 env 撞名时显式名单胜;只在本车道被选中时求值;原文按凭据类对待:只回在场位、不进任何子进程)`, { credentialForm: "whole", danger: SEC }),
228
231
  r("K8S_SANDBOX_IMAGE", "orchestration", "string", "k8s 车道沙箱镜像(REMOTE_EXEC=k8s 必需件)"),
229
232
  r("K8S_SANDBOX_IPV6", "orchestration", "enum", "k8s 沙箱 pod 的 IPv6:disabled = pod 级 sysctl 关 IPv6(net.ipv6.conf.all / default.disable_ipv6=1;两只都不在 k8s 的 safe sysctl 表里 ⇒ 每个节点 kubelet 要 --allowed-unsafe-sysctls 点名,否则 pod 起不来;沙箱 ns 不能 enforce PodSecurity baseline / restricted);enabled = 不动 pod(pod 保留平台给的 IPv6,只执行 IPv4 的出网策略管不到它,起服自检每次一行 sandbox_egress_policy_gap{kind: ipv6_enabled});词表外拒启", { enumValues: SANDBOX_IPV6_WORDS, staticDefault: SANDBOX_IPV6_DEFAULT, danger: SEC }),
230
233
  r("K8S_TIMEOUT_MS", "orchestration", "number", "k8s 沙箱 pod 寿命(activeDeadlineSeconds,ms;整只 pod 的泄漏护栏,后台任务超时也被它钳;各条命令的超时见工具超时)"),
231
- r("K8S_TOKEN", "orchestration", "secret", "k8s API token(缺席走 in-cluster SA)", { danger: SEC }),
234
+ r("K8S_TOKEN", "orchestration", "secret", "k8s API token(缺席走 in-cluster SA)", { credentialForm: "whole", danger: SEC }),
232
235
  r("KUBERNETES_SERVICE_HOST", "orchestration", "string", "平台注入的 in-cluster k8s API host(K8S_API_URL 缺席时用)"),
233
236
  r("KUBERNETES_SERVICE_PORT", "orchestration", "string", "平台注入的 in-cluster k8s API 端口(缺省 443)"),
234
237
  r("LEADER_BUDGET_USD", "orchestration", "number", "leader replan-lite 扇出花费帽(USD)", { danger: BILL, derivedDefaultNote: "缺席 ⇒ replan-lite 自默认" }),
@@ -247,9 +250,10 @@ export const CONFIG_CATALOG = [
247
250
  r("LEADER_WORKER_MAX_TURNS", "orchestration", "number", "leader 每 worker 轮数帽", { staticDefault: "10000", danger: BILL }),
248
251
  r("LEADER_WORKER_SLICE_BUDGET_USD", "orchestration", "number", "leader worker 单分片花费帽(USD)", { danger: BILL, derivedDefaultNote: "缺席 ⇒ max(1, workerBudgetUsd/4)" }),
249
252
  r("LOCAL_DATA_ROOT", "store", "path", "file 店数据根的最高优先覆写(配置根不跟着走;`CONFIG_LOCAL_DIR` 没设而数据根 ≠ 推导出的配置根时,boot 出一行 `local_roots_split`;给了 `CONFIG_LOCAL_DIR` 即视作表过态,不出声)", { danger: DATA }),
253
+ r("LOCAL_STORE_DURABILITY", "store", "enum", "运维声明 local 店易失(词闭集只有 ephemeral):local 后端交给会话店与检查点店两半的引擎声明都降为 process-local(委派分区不降:后台子代照旧能停驻) ⇒ 数据根落在易失介质(容器可写层 / tmpfs / emptyDir)上不再拒启 config.store_not_durable,起服 warn 一行;后果 = 店里的会话、停驻审批与记忆不随容器 / Pod 替换保留(进程重启照旧活过)。读面 store.durability 照旧按介质如实报。SQL / memory 后端不读。部署者自己设,壳 / 编排器不代写", { enumValues: LOCAL_STORE_DECLARATION_WORDS, danger: DATA, derivedDefaultNote: "缺席 ⇒ 店型的设计声明(活过进程重启);店落在调用方自己的盘上(host 车道单主)且数据根介质易失时,同样降为 process-local", configKey: "localStoreDurability" }),
250
254
  r("LOCKED_CONFIG_KEYS", "auth", "csv", "管理员锁定层声明(词表=core 闭集注册表,未知键拒启)", { danger: SEC, configKey: "lockedConfigKeys" }),
251
255
  r("LOG_LEVEL", "observability", "string", "日志档位", { staticDefault: "info", configKey: "logLevel" }),
252
- r("LSP_ENV_ALLOW", "orchestration", "secret", `host 腿语言服务器子进程 env 的点名放行名单(点到的键从服务 env 原样放回、部署方显式承担;没点到的照剥;与 host shell inheritEnv:[names] 同一只谓词;形错 / 点名任一只名单型旋钮(含自己)/ 点名本服务自有凭据名(剥后放回会把引擎刚扣下的凭据交回去;判官 = 引擎拒白名单的同一只)拒启且不回显值;本进程环境里没有的名按序号 warn、不放行、不回显;多租户姿态(忽略时起服 warn 一次):${describeAllowlistPostures()};原文按凭据类对待:只回在场位、不进任何子进程,生效名单见起服披露行 allowed)`, { danger: SEC, derivedDefaultNote: "缺席 / 空串 ⇒ 空名单 = 全剥(7.100.0 行为)" }),
256
+ r("LSP_ENV_ALLOW", "orchestration", "secret", `host 腿语言服务器子进程 env 的点名放行名单(点到的键从服务 env 原样放回、部署方显式承担;没点到的照剥;与 host shell inheritEnv:[names] 同一只谓词;形错 / 点名任一只名单型旋钮(含自己)/ 点名本服务自有凭据 —— 名是,或值是本服务的某一枚凭据(另一个名下的副本)—— (剥后放回会把引擎刚扣下的凭据交回去;判官 = 引擎此刻的自有凭据声明)拒启且不回显值;本进程环境里没有的名按序号 warn、不放行、不回显;多租户姿态(忽略时起服 warn 一次):${describeAllowlistPostures()};原文按凭据类对待:只回在场位、不进任何子进程,生效名单见起服披露行 allowed)`, { credentialForm: "whole", danger: SEC, derivedDefaultNote: "缺席 / 空串 ⇒ 空名单 = 全剥(7.100.0 行为)" }),
253
257
  r("LSP_HOST_ENABLED", "orchestration", "boolean", "本机语言服务器开关(只在 host 车道且单主时挂;本机 language server,优雅降级)", { staticDefault: "true", configKey: "lspHostEnabled" }),
254
258
  r("MANUAL_MODE_SHELL_GATE", "approval", "enum", "手动模式 shell 门收紧腿(off=no-op 非放松 —— 本键只有收紧半场;拼错拒启;classify 档已退役 = 拒启指路)", { danger: SEC, enumValues: ["always", "off"], echoWords: ["always"], resolve: (c) => c.manualModeShellGate ?? null, derivedDefaultNote: "off/未设 ⇒ 本键不贡献任何东西(归一成键缺席)⇒ 回显 null;真姿态只有 always 一个(core 7.34.0 起形状档在每一种模式下都装,classify 不再是运维选的档)" }),
255
259
  r("MAX_PRINCIPAL_COST_USD", "limitsHttp", "number", "per-principal 窗内成本天花板(0=关)", { staticDefault: "0", danger: BILL, configKey: "maxPrincipalCostUsd", center: cLimits("maxPrincipalCostUsd") }),
@@ -266,7 +270,7 @@ export const CONFIG_CATALOG = [
266
270
  r("MEMORY_CONSOLIDATION_INTERVAL_SEC", "memory", "number", "折叠周期腿节律(秒;本 build 任何正值拒启 —— 周期腿未落地,恒 0)", { staticDefault: "0" }),
267
271
  r("MEMORY_CONSOLIDATION_SCOPES", "memory", "csv", "折叠阀门 scope 表(恰一条时=admin 口缺省;不是授权边界)"),
268
272
  r("MEMORY_DELEGATION_EVIDENCE", "memory", "enum", "委派臂污染标记的证据标准", { enumValues: ["static-face", "attested-only"], staticDefault: "static-face", danger: SEC, configKey: "memoryDelegationEvidence" }),
269
- r("MEMORY_EMBEDDER_API_KEY", "memory", "secret", "记忆向量面 embeddings 端点凭据", { danger: SEC }),
273
+ r("MEMORY_EMBEDDER_API_KEY", "memory", "secret", "记忆向量面 embeddings 端点凭据", { credentialForm: "whole", danger: SEC }),
270
274
  r("MEMORY_EMBEDDER_DIM", "memory", "number", "embeddings 维度声明"),
271
275
  r("MEMORY_EMBEDDER_ENDPOINT", "memory", "url", "OpenAI 兼容 /embeddings 端点(pg 记忆后端的向量面)", { credentialPolicy: "refuse" }),
272
276
  r("MEMORY_EMBEDDER_MODEL", "memory", "string", "embeddings 模型名"),
@@ -287,15 +291,15 @@ export const CONFIG_CATALOG = [
287
291
  r("MEMORY_SYNC_MAX_PUSH_ENTRIES", "memory", "number", "TOC 同步单轮 push 条数帽(设了必须 ≥1 整数)", { derivedDefaultNote: "缺席 ⇒ 键缺席,core 默认" }),
288
292
  r("MEMORY_SYNC_SCOPE", "memory", "string", "TOC 同步 scope 覆写(本服务铸的项目键族 `userrepo:` / `repo:` 拒启:项目层由同步腿按属主自己选)", { derivedDefaultNote: "缺席 ⇒ = MEMORY_SCOPE,仅当它已是 typed 键;非 typed 键拒启" }),
289
293
  r("MEMORY_SYNC_SERVE_IDENTITY", "memory", "url", "记忆同步中心(DB 记忆平面)声明的同步身份 = 客户端用来到达本中心同步口的基址;必须已是规范形(小写协议与主机、无缺省端口、无尾斜杠、无查询串 / 片段 / 凭据),否则拒启并给出规范形;能力位 `memorySyncServe.identity` 逐字公开,入站 `peer` 按串与它比", { credentialPolicy: "refuse", derivedDefaultNote: "缺席 ⇒ 本中心不服务同步(501 feature.memory_sync_serve_disabled)", configKey: "memorySyncServeIdentity" }),
290
- r("MEMORY_SYNC_TOKEN", "memory", "secret", "TOC 同步中心面的 Bearer(URL 设了它必须在,半配拒启)", { danger: SEC }),
294
+ r("MEMORY_SYNC_TOKEN", "memory", "secret", "TOC 同步中心面的 Bearer(URL 设了它必须在,半配拒启)", { credentialForm: "whole", danger: SEC }),
291
295
  r("MEMORY_SYNC_URL", "memory", "url", "TOC 同步中心地址(设了=开;file 记忆形专用,DB 后端配了拒启;同步覆盖同步层与同属主的项目层 `userrepo:<属主>/…` ⇒ 同步层与 MEMORY_SCOPE 同属主时单用户任务照常按项目键控并随同步推拉;不同属主 ⇒ 写家落全局层,启动通知 `memory_project_scope_yields_to_sync`)", { credentialPolicy: "refuse" }),
292
- r("METRICS_TOKEN", "observability", "secret", "/metrics 只读令牌", { danger: SEC }),
293
- r("MINIO_ACCESS_KEY", "store", "secret", "对象存储 access key(快照 blob/leader 工作区/公链签发共用)", { danger: SEC }),
296
+ r("METRICS_TOKEN", "observability", "secret", "/metrics 只读令牌", { credentialForm: "whole", danger: SEC }),
297
+ r("MINIO_ACCESS_KEY", "store", "secret", "对象存储 access key(快照 blob/leader 工作区/公链签发共用)", { credentialForm: "whole", danger: SEC }),
294
298
  r("MINIO_BUCKET", "store", "string", "leader 编排的 diff-out 桶:工厂模式下 worker 把补丁自传到本桶的 leader-diff/ 前缀下、leader 用同桶取回(用同一套 MINIO_ENDPOINT / ACCESS / SECRET;server 不建桶,起服不核它)。与 WORKSPACE_SNAPSHOT_BUCKET 是两根独立旋钮:只改了工作区快照桶的部署,leader 的补丁仍落本键那一只 —— 要同桶就两根同设", { derivedDefaultNote: `缺席 ⇒ ${WORKSPACE_SNAPSHOT_BUCKET_DEFAULT}(工作区快照桶的缺省名;不跟随 WORKSPACE_SNAPSHOT_BUCKET 的显式值)` }),
295
299
  r("MINIO_ENDPOINT", "store", "url", "对象存储 endpoint(三键齐 ⇒ 快照 blob 走 MinIO,否则 SQL 行)", { credentialPolicy: "mask", danger: DATA }),
296
300
  r("MINIO_REGION", "store", "string", "对象存储 region"),
297
- r("MINIO_SECRET_KEY", "store", "secret", "对象存储 secret key", { danger: SEC }),
298
- r("MODEL_API_KEY", "modelPlane", "secret", "网关腿共享 API key(per-model 覆写在 center 侧;只与 MODEL_GATEWAY_BASEURL 配对 —— 网关未设时不装载、不发往任何路由,启动通知 `model_gateway_key_unpaired`)", { danger: [...SEC, ...BILL] }),
301
+ r("MINIO_SECRET_KEY", "store", "secret", "对象存储 secret key", { credentialForm: "whole", danger: SEC }),
302
+ r("MODEL_API_KEY", "modelPlane", "secret", "网关腿共享 API key(per-model 覆写在 center 侧;只与 MODEL_GATEWAY_BASEURL 配对 —— 网关未设时不装载、不发往任何路由,启动通知 `model_gateway_key_unpaired`)", { credentialForm: "whole", danger: [...SEC, ...BILL] }),
299
303
  r("MODEL_AUTO_COMPACT_TOKENS", "modelPlane", "number", "主槽 dual-window 触发阈(1M 窗不再隐式 967000,缺席则用普通触发几何)", { derivedDefaultNote: "缺席 ⇒ 不铸键(core W-33000 几何)" }),
300
304
  r("MODEL_CASCADE_LADDER", "modelPlane", "csv", "质量门级联梯(目录名 cheapest→strongest;opt-in per-task cascade:true)", { danger: BILL, configKey: "cascadeLadder" }),
301
305
  r("MODEL_CB_COOLDOWN_MS", "modelPlane", "number", "熔断冷却窗(ms)", { staticDefault: String(RESILIENCE_DEFAULTS.cooldownMs.value) }),
@@ -374,7 +378,7 @@ export const CONFIG_CATALOG = [
374
378
  r("MODS_ROOT", "integrations", "path", "声明的 mod 包允许所在的根(绝对路径;包的真实路径按路径分量严格落在它的真实路径之下 —— 符号链接出根、前缀相似目录、.. 遍历、根本身都拒启;建议只读物料树)。声明了包而没设它 ⇒ 拒启;单设它而不声明包 = 无事(形照判)", { danger: SEC, configKey: "modsDeclaration", derivedDefaultNote: "缺席 ⇒ 不许声明任何包", resolve: (c) => c.modsDeclaration.root ?? null }),
375
379
  r("MYSQL_DATABASE", "store", "string", "MySQL 协议库名(选中该引擎时必填)", { danger: DATA }),
376
380
  r("MYSQL_HOST", "store", "string", "MySQL 协议主机(在场即算 SQL 信号,参与 DB_BACKEND 默认推导)", { danger: DATA }),
377
- r("MYSQL_PASSWORD", "store", "secret", "MySQL 协议口令", { danger: SEC }),
381
+ r("MYSQL_PASSWORD", "store", "secret", "MySQL 协议口令", { credentialForm: "whole", danger: SEC }),
378
382
  r("MYSQL_POOL_SIZE", "store", "number", "MySQL 连接池上限(坏值回 driver 默认+warn)", { derivedDefaultNote: "缺席 ⇒ driver 默认池" }),
379
383
  r("MYSQL_PORT", "store", "number", "MySQL 协议端口", { staticDefault: "3306" }),
380
384
  r("MYSQL_USER", "store", "string", "MySQL 协议用户", { danger: DATA }),
@@ -382,14 +386,14 @@ export const CONFIG_CATALOG = [
382
386
  r("OPERATOR_PRINCIPALS", "auth", "csv", "operator 名单(全部运维面同一条读法:名单内的验过主体是运维;空名单 = 谁都不是;与 OPERATOR_SINGLE_USER 互斥;单用户部署与 OPERATOR_SINGLE_USER 二者必写其一,都不写则拒启 —— 服务进程起服第 1 段即拒,直接调 `createHttpServer` 的嵌入方装配时拒)", { danger: SEC, configKey: "operatorPrincipals" }),
383
387
  r("OPERATOR_SINGLE_USER", "auth", "boolean", "单用户形当自己运维的显式声明(true ⇒ 这台部署的每个调用方在全部运维面都是运维;只在 REQUIRE_PRINCIPAL 未开且 OPERATOR_PRINCIPALS 为空时成立,否则拒启;单用户部署与具名 OPERATOR_PRINCIPALS 二者必写其一 —— 都不写则拒启(服务进程起服第 1 段;嵌入方装配运维面时),false 与缺席同判;起服冻结)", { staticDefault: "false", danger: SEC, configKey: "operatorSingleUser" }),
384
388
  r("OTEL_EXPORTER_OTLP_ENDPOINT", "observability", "url", "OTLP 出口(设了=开 otel)", { credentialPolicy: "mask" }),
385
- r("OTEL_EXPORTER_OTLP_HEADERS", "observability", "secret", "OTLP 出口头(k=v CSV;常载鉴权头 ⇒ 按凭据处置)", { danger: SEC }),
389
+ r("OTEL_EXPORTER_OTLP_HEADERS", "observability", "secret", "OTLP 出口头(k=v CSV;常载鉴权头 ⇒ 按凭据处置)", { credentialForm: "whole", danger: SEC }),
386
390
  r("OTEL_EXPORT_INTERVAL_MS", "observability", "number", "OTLP 批报周期(ms)", { staticDefault: "15000" }),
387
391
  r("OTEL_SERVICE_NAME", "observability", "string", "OTLP service.name", { staticDefault: "sema-server" }),
388
392
  r("PERMISSIONS_DISABLE_AUTO_MODE", "approval", "boolean", "auto 模式本地 org deny(CC/center/settings 键名 permissions.disableAutoMode 的 env 腿;tighten-only:每 principal caps.autoMode 折 false,center 授予翻不回;未设=不动 caps;词表外拒启)", { staticDefault: "false", danger: SEC, configKey: "permissionsDisableAutoMode" }),
389
393
  r("PERMISSION_RULES_ENABLED", "approval", "boolean", "持久化权限规则车道总开关(撤销面已建 ⇒ 默认 ON)", { staticDefault: "true", danger: SEC, configKey: "permissionRulesEnabled" }),
390
394
  r("PG_DATABASE", "store", "string", "PostgreSQL 库名", { danger: DATA }),
391
395
  r("PG_HOST", "store", "string", "PostgreSQL 主机(在场即算 SQL 信号)", { danger: DATA }),
392
- r("PG_PASSWORD", "store", "secret", "PostgreSQL 口令", { danger: SEC }),
396
+ r("PG_PASSWORD", "store", "secret", "PostgreSQL 口令", { credentialForm: "whole", danger: SEC }),
393
397
  r("PG_POOL_SIZE", "store", "number", "PostgreSQL 连接池上限", { derivedDefaultNote: "缺席 ⇒ driver 默认池" }),
394
398
  r("PG_PORT", "store", "number", "PostgreSQL 端口", { staticDefault: "5432" }),
395
399
  r("PG_USER", "store", "string", "PostgreSQL 用户", { danger: DATA }),
@@ -409,7 +413,7 @@ export const CONFIG_CATALOG = [
409
413
  r("RATE_LIMIT_RPM", "limitsHttp", "number", "计费提交每分钟限流(0=关)", { staticDefault: "0", danger: BILL, configKey: "rateLimitPerMin", center: cLimits("rateLimitPerMin") }),
410
414
  r("READ_DENY_BUILTIN_EXCLUDE", "orchestration", "csv", "按行名删内建 deny 条目(档位之后生效;绝不削任务显式 deny)", { danger: SEC, configKey: "readDenyBuiltinExclude" }),
411
415
  r("READ_DENY_BUILTIN_TIERS", "orchestration", "csv", "内建 deny 表档位选择(闭集五档 credentials/shell-history/browser/wallet/agent-config;none=显式空姿态)", { danger: SEC, derivedDefaultNote: "缺席 ⇒ 出厂两档在岗 **credentials,agent-config**(core 7.34.0 R-2 起;7.22.0–7.33.x 曾为 OFF)。要全关显式写 none;要全五档显式写 credentials,shell-history,browser,wallet,agent-config;空值拒启(手滑与显式意图不许同形)", configKey: "readDenyBuiltinTiers" }),
412
- r("READ_DENY_FLOOR_REQUIRED", "orchestration", "boolean", "要求读拒表的字节地板:true ⇒ 读拒表有行而执行环境不守地板(起服行 remote_exec_enabled.keepsReadFloor=false;此时另有起服 warn read_deny_floor_required_unkept)的 run 在准备期拒(config.read_deny_floor_unkept,一个命令都不起;同步提交 409)。出厂读拒档在岗 ⇒ 不守地板的车道(主机 / ssh / adb / device,以及读地板模块尚未服务或 SANDBOX_READ_FLOOR=off 的沙箱车道)上带手的 run 一律拒起", { staticDefault: "false", danger: SEC, derivedDefaultNote: "缺席 ⇒ 不要求:run 照跑,每 run 一条 operator 通告 config.read_deny_floor_unkept(engine_notice 日志;递归读照读表里的文件,通告不是保护)", configKey: "readDenyFloorRequired" }),
416
+ r("READ_DENY_FLOOR_REQUIRED", "orchestration", "boolean", "要求读拒表的字节地板:true ⇒ 读拒表有行而执行环境不守地板(起服行 remote_exec_enabled.keepsReadFloor=false;此时另有起服 warn read_deny_floor_required_unkept)的 run 在准备期拒(config.read_deny_floor_unkept,一个命令都不起;同步提交 409)。出厂读拒档在岗 ⇒ 不守地板的车道(主机 / ssh / adb / device,以及读地板模块尚未服务或 SANDBOX_READ_FLOOR=off 的沙箱车道)上带手的 run 一律拒起", { staticDefault: "false", danger: SEC, derivedDefaultNote: "缺席 ⇒ 不要求:run 照跑,每 run 一条通告 config.read_deny_floor_unkept —— run 事件流一帧 engine_notice、终局结果 readDenyFloor、运维 engine_notice 日志一行,同一句点名 REMOTE_EXEC=<车道> 与本旋钮(递归读照读表里的文件,通告不是保护)", configKey: "readDenyFloorRequired" }),
413
417
  r("READ_DENY_PATTERNS", "orchestration", "csv", "READ 面额外 deny pattern 表", { danger: SEC, configKey: "readDenyPatterns" }),
414
418
  r("READ_FACE", "orchestration", "enum", "READ 容纳面档位(env 逐键恒赢 center —— 部署主权表达)", { enumValues: ["open", "roots"], danger: SEC, derivedDefaultNote: "缺席 ⇒ 按 posture 派生:单用户 turnkey(REQUIRE_PRINCIPAL 未设)铸 open;多租户不铸键、core 默认 roots。生效来源见 GET /v1/diagnostics/wiring 的 readFace.source 四词", configKey: "readFace" }),
415
419
  r("REAP_INTERVAL_SEC", "limitsHttp", "number", "reaper 周期(秒)", { staticDefault: "60", configKey: "reapIntervalSec" }),
@@ -443,7 +447,7 @@ export const CONFIG_CATALOG = [
443
447
  r("SCHEDULER_SESSION_WAKEUP", "orchestration", "boolean", "session 唤醒 host-signal(无常驻 daemon 的壳注 false)", { staticDefault: "true", configKey: "schedulerSessionWakeup" }),
444
448
  r("SCHEDULER_STORE_PATH", "orchestration", "path", "scheduler 共享店路径(server 写者与壳 daemon 读者必须一致)", { derivedDefaultNote: "缺席 ⇒ SEMA_CONFIG_DIR(~/.sema)/scheduled_tasks.json", configKey: "schedulerStorePath" }),
445
449
  r("SCRATCHPAD_SWEEP_TTL_MS", "limitsHttp", "number", "per-session scratchpad 目录 sweep TTL(ms;≤0=关,<1m 夹到 1m 点名)", { staticDefault: String(7 * 24 * 60 * 60 * 1000), danger: DATA, configKey: "scratchpadSweepTtlMs" }),
446
- r("SEALED_KEY_DIR", "store", "path", "模型钥匙保管目录(sealed 形的 X25519 钥匙对 `<publicKeyId>.json` 与停驻行封签子目录 `checkpoint-ctx-keys/`;文件 0600、目录 0700)。sealed 条目绑定钥匙身份(publicKeyId),共享同一份 config.d 的每台引擎都须持钥:数据根不同的多台引擎指向同一目录 ⇒ 同一把钥。绝对路径(相对路径拒启);设了 ⇒ 唯一保管目录,起服在它上面建不了保管店 ⇒ 拒启", { danger: [...SEC, ...DATA], derivedDefaultNote: "缺席 ⇒ <数据根>/sealed-key(建不了只告警,sealed 模型逐个 no_key_store)", configKey: "sealedKeyDir" }),
450
+ r("SEALED_KEY_DIR", "store", "path", "模型钥匙保管目录(sealed 形的 X25519 钥匙对 `<publicKeyId>.json` 与停驻行封签子目录 `checkpoint-ctx-keys/`;文件 0600、目录 0700)。sealed 条目绑定钥匙身份(publicKeyId),共享同一份 config.d 的每台引擎都须持钥:数据根不同的多台引擎指向同一目录 ⇒ 同一把钥。绝对路径(相对路径拒启);设了 ⇒ 唯一保管目录,起服在它上面建不了保管店 ⇒ 拒启;设了 ∧ 停驻审批耐久 ∧ 它落在易失介质上(tmpfs / 容器可写层 / emptyDir)⇒ 拒启(停驻行活过替换而封它凭据的钥匙不活)", { danger: [...SEC, ...DATA], derivedDefaultNote: "缺席 ⇒ <数据根>/sealed-key(建不了只告警,sealed 模型逐个 no_key_store)", configKey: "sealedKeyDir" }),
447
451
  r("SELECT_ENVIRONMENT_TOOL", "orchestration", "boolean", "SelectEnvironment 工具挂载(另需 k8s+镜像目录活链)", { staticDefault: "true", configKey: "selectEnvironmentTool" }),
448
452
  r("SELF_ORCHESTRATION_ENABLED", "orchestration", "boolean", "run_workflow 自编排(硬化 vm 沙箱)", { derivedDefaultNote: "posture 三态:缺席 = 单用户 ⇒ on / 多租户 ⇒ off", configKey: "selfOrchestrationEnabled" }),
449
453
  r("SELF_ORCHESTRATION_MODELS", "orchestration", "csv", "workflow agent({modelName}) 显式词表(恒赢;缺席单用户=目录键全集/多租户 fail-closed)", { configKey: "selfOrchestrationModels" }),
@@ -457,19 +461,19 @@ export const CONFIG_CATALOG = [
457
461
  r("SEMA_PIP_INDEX", "orchestration", "url", "SANDBOX_PKG_SOURCE=custom 的显式 pip index 地址", { credentialPolicy: "refuse" }),
458
462
  r("SEMA_UV_INDEX", "orchestration", "url", "SANDBOX_PKG_SOURCE=custom 的显式 uv index 地址", { credentialPolicy: "refuse" }),
459
463
  r("SEMA_UV_PY_MIRROR", "orchestration", "url", "SANDBOX_PKG_SOURCE=custom 的显式 uv python 分发镜像地址", { credentialPolicy: "refuse" }),
460
- r(WEB_ADMIN_ENV.adminToken, "integrations", "secret", "写 web-admin 的管理凭证(仅 boot 上报执行公钥用;刻意不入 ServiceConfig —— 不进 configHash/日志面)", { danger: SEC, scope: "bootstrap-only" }),
461
- r(WEB_ADMIN_ENV.dryRun, "integrations", "boolean", "web-admin 腿 dry-run(拉而不应用)", { staticDefault: "false" }),
462
- r(WEB_ADMIN_ENV.liveUrl, "integrations", "url", `fleet 活性组(心跳 / 注销、服务租约 = settings-schema FLEET_LIVE_PATHS)的 web-admin 基址:给管理面在就绪门后、活性面另走一条不看就绪的入口的部署。缺席 = ${WEB_ADMIN_ENV.url}。传输地址,不参与中心身份互证。${CENTER_BASE_URL_RULE}`, { credentialPolicy: "refuse" }),
463
- r(WEB_ADMIN_ENV.token, "integrations", "secret", `center 拉取凭据(值形;与 ${WEB_ADMIN_ENV.tokenFile} 二选一,都设=拒启)`, { danger: SEC }),
464
+ r(WEB_ADMIN_ENV.adminToken, "integrations", "secret", "写 web-admin 的管理凭证(仅 boot 上报执行公钥用;刻意不入 ServiceConfig —— 不进 configHash/日志面)", { credentialForm: "whole", danger: SEC, scope: "bootstrap-only" }),
465
+ r(WEB_ADMIN_ENV.dryRun, "integrations", "boolean", "web-admin 腿 dry-run(拉而不应用)", { staticDefault: "false", danger: SEC }),
466
+ r(WEB_ADMIN_ENV.liveUrl, "integrations", "url", `fleet 活性组(心跳 / 注销、服务租约 = settings-schema FLEET_LIVE_PATHS)的 web-admin 基址:给管理面在就绪门后、活性面另走一条不看就绪的入口的部署。缺席 = ${WEB_ADMIN_ENV.url}。传输地址,不参与中心身份互证。${CENTER_BASE_URL_RULE}`, { credentialPolicy: "refuse", danger: SEC }),
467
+ r(WEB_ADMIN_ENV.token, "integrations", "secret", `center 拉取凭据(值形;与 ${WEB_ADMIN_ENV.tokenFile} 二选一,都设=拒启)`, { credentialForm: "whole", danger: SEC }),
464
468
  r(WEB_ADMIN_ENV.tokenFile, "integrations", "path", `center 拉取凭据文件(每条中心请求都重读 ⇒ 轮换 / 换账号不重启;与 ${WEB_ADMIN_ENV.token} 二选一,都设=拒启;内容两种类:裸行 = 静态 bearer / JSON 信封 user-session = 人的登录会话(可续签);文件不可读 / 为空 = 响亮 + 健康态 unreadable,不当作无凭证;内容读不成 / 多租户读到信封 = 拒启)`, { danger: SEC }),
465
- r(WEB_ADMIN_ENV.url, "integrations", "url", `web-admin 基址(设了=remote 配置源开关;传输地址 —— 编排器注入的可以是集群内地址;AUTH_BRIDGE_ISSUER 缺席时它也是中心身份)。${CENTER_BASE_URL_RULE}`, { credentialPolicy: "refuse" }),
469
+ r(WEB_ADMIN_ENV.url, "integrations", "url", `web-admin 基址(设了=remote 配置源开关;传输地址 —— 编排器注入的可以是集群内地址;AUTH_BRIDGE_ISSUER 缺席时它也是中心身份)。${CENTER_BASE_URL_RULE}`, { credentialPolicy: "refuse", danger: SEC }),
466
470
  r(WEB_ADMIN_ENV.webUrl, "integrations", "url", `web-admin 人用界面的固定基址:引擎原样转述到 /health 的 center.webBaseUrl,壳按它拼会话深链(路径归壳)。缺席即缺席(引擎不拼不猜);只在接了中心(${WEB_ADMIN_ENV.url})时挂;必须与中心身份(AUTH_BRIDGE_ISSUER,缺席 = ${WEB_ADMIN_ENV.url})同主机同端口(http ↔ https 同族),否则拒启。${CENTER_BASE_URL_RULE}`, { credentialPolicy: "refuse" }),
467
471
  r(WEB_ADMIN_ENV.worker, "integrations", "string", "本 worker 在 web-admin 上的名字(per-worker effective)"),
468
472
  r("SEND_USER_FILE_SANDBOX_PUT_ENDPOINT", "store", "url", "沙箱侧 presigned PUT Host 绑定 endpoint(in-cluster 可用内网面)", { credentialPolicy: "mask", derivedDefaultNote: "缺席 ⇒ publicEndpoint" }),
469
473
  r("SEND_USER_FILE_URL_TTL", "store", "number", "公链 TTL(秒;非法值回 0=永久轨,绝不 NaN 进签名)", { staticDefault: "0" }),
470
474
  r("SENSITIVE_WRITE_PATTERNS", "approval", "csv", "敏感路径写 deny 集(unset=core 推荐集;显式值整表替换;off/空=关 —— 真放松杆)。拒的是文件工具(Write / Edit / NotebookEdit,按路径);shell 命令写同一路径(重定向 / tee / cp …)不被这个集拒绝,走普通审批问", { danger: SEC, derivedDefaultNote: "缺席 ⇒ core RECOMMENDED_SENSITIVE_PATTERNS", configKey: "sensitiveWritePatterns" }),
471
- r("SERVICE_AUTH_TOKEN", "auth", "secret", "共享 service token(写面门;缺席且未开 ALLOW_UNAUTHED_WRITES ⇒ 拒提交)", { danger: SEC }),
472
- r("SERVICE_AUTH_TOKENS", "auth", "secret", "per-system 凭据表(tok=system CSV;source 从凭据派生,绝不自报)", { danger: SEC }),
475
+ r("SERVICE_AUTH_TOKEN", "auth", "secret", "共享 service token(写面门;缺席且未开 ALLOW_UNAUTHED_WRITES ⇒ 拒提交)", { credentialForm: "whole", danger: SEC }),
476
+ r("SERVICE_AUTH_TOKENS", "auth", "secret", "per-system 凭据表(tok=system CSV;source 从凭据派生,绝不自报)", { credentialForm: "token-table", danger: SEC }),
473
477
  r("SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT", "auth", "boolean", "出示 service 凭据、不报主体的调用方代不代部署本人(true ⇒ 代:fleet 读面看全舰队、运维聚合口照放;false ⇒ 它是无身份调用方:fleet 读面 401、运维聚合口只认只读令牌、写档 401;带主体头的请求两形都是那位主体;GET /health 的 auth.serviceTokenActsForDeployment 自报;词表外拒启;起服冻结)", { staticDefault: "true", danger: SEC, configKey: "serviceTokenActsForDeployment" }),
474
478
  r("SESSION_AUTO_TITLE", "orchestration", "boolean", "首次提交自动铸 session 标题(一次 cheap 调用)", { staticDefault: "true", danger: BILL, configKey: "sessionAutoTitle" }),
475
479
  r("SESSION_BACKEND", "store", "enum", "session 店引擎(auto=配了该引擎的坐标就用那只库、没配就是内存;配了而此刻连不上 ⇒ 在 STORE_LOCK_WAIT_MS 窗内重试、到窗拒启,绝不落内存;回显=boot 解析后的真引擎)", { enumValues: SESSION_BACKENDS, danger: DATA, derivedDefaultNote: "缺席:显式 DB_BACKEND=mysql|pg ⇒ mysql,否则 memory", configKey: "sessionBackend", resolve: (c) => (c.sessionBackend === "tidb" ? "mysql" : c.sessionBackend) }),
@@ -490,7 +494,7 @@ export const CONFIG_CATALOG = [
490
494
  r("SSH_KNOWN_HOSTS", "orchestration", "path", "known_hosts 路径(坏路径拒启)", { danger: SEC }),
491
495
  r("SSH_MOUNT_PATH", "orchestration", "path", "ssh 车道工作区路径"),
492
496
  r("SSH_PORT", "orchestration", "number", "ssh 端口", { derivedDefaultNote: "缺席 ⇒ 22" }),
493
- r("SSH_PRIVATE_KEY", "orchestration", "secret", "ssh 私钥(adapter 持有,绝不进 workspace)", { danger: SEC }),
497
+ r("SSH_PRIVATE_KEY", "orchestration", "secret", "ssh 私钥(adapter 持有,绝不进 workspace)", { credentialForm: "whole", danger: SEC }),
494
498
  r("SSH_USER", "orchestration", "string", "ssh 用户(必需件)"),
495
499
  r("STORE_LOCK_WAIT_MS", "store", "number", "store 启动期的有界等待窗(ms):local 数据根 LOCK 撞上活持锁人,或已配置的 SQL 库此刻连不上 / 建表失败;0=当场拒;到窗仍开不了 ⇒ 拒启(local 保持原码,永不放行第二个写者;SQL 点名后端与 host:port,永不退成内存)", { staticDefault: "60000", danger: DATA, configKey: "storeLockWaitMs" }),
496
500
  r("STORE_PROBE_INTERVAL_MS", "store", "number", "/health 活体 store 后台探针间隔(ms;0=显式关;仅 SQL 后端挂环)", { staticDefault: "15000", configKey: "storeProbeIntervalMs" }),
@@ -515,11 +519,11 @@ export const CONFIG_CATALOG = [
515
519
  r("TOOL_RESULT_TTL_SEC", "limitsHttp", "number", "工具结果店 TTL(秒)", { staticDefault: "86400", danger: DATA, configKey: "toolResultTtlSec", center: cLimits("toolResultTtlSec") }),
516
520
  r("TOOL_TRACE", "observability", "boolean", "逐工具调用 trace 日志(诊断用)", { staticDefault: "false", configKey: "toolTrace" }),
517
521
  r("TRACE_THINKING", "observability", "boolean", "思考轨迹入 durable 事件日志(敏感部署可关;落盘前脱敏)", { staticDefault: "true", danger: DATA, configKey: "traceThinking" }),
518
- r("TRACE_TOKEN", "observability", "secret", "Task Trace API 只读令牌(fleet 拉轨迹,不授任务/配置权)", { danger: SEC }),
522
+ r("TRACE_TOKEN", "observability", "secret", "Task Trace API 只读令牌(fleet 拉轨迹,不授任务/配置权)", { credentialForm: "whole", danger: SEC }),
519
523
  r("UNATTENDED_APPROVAL_POLICY", "approval", "enum", "无人能答的治理 ask 终局(park=durable 等人;deny=当场拒 —— 自声明无人值守)", { enumValues: ["park", "deny"], staticDefault: "park", danger: SEC, configKey: "unattendedApprovalPolicy" }),
520
524
  r("UNREACHED_ASK_TTL_MS", "approval", "number", "零活流铸造的 ask 悬挂窗(ms;[60s,24h] 拒启带界)", { staticDefault: "3600000" }),
521
525
  r("USAGE_WINDOWS", "orchestration", "opaque", "部署级治理窗(JSON 数组;滑动窗内跨任务 token/$ 预算,key=principal)", { danger: BILL }),
522
- r("WEB_SEARCH_API_KEY", "orchestration", "secret", "web search 后端 API 凭据(brave/tavily)", { danger: [...SEC, ...BILL] }),
526
+ r("WEB_SEARCH_API_KEY", "orchestration", "secret", "web search 后端 API 凭据(brave/tavily)", { credentialForm: "whole", danger: [...SEC, ...BILL] }),
523
527
  r("WEB_SEARCH_ENDPOINT", "orchestration", "url", "web search 后端 endpoint 覆写(searxng 实例地址;brave 下可指向 Brave 兼容网关的完整搜索 URL,如 Nólë;空 = 未设;不是 scheme://host 形的绝对 URL、或带 userinfo(user[:password]@host —— 运行时 fetch 本就拒这一形)⇒ 拒启)", { credentialPolicy: "refuse" }),
524
528
  r("WEB_SEARCH_MAX_RESULTS", "orchestration", "number", "web search 单次结果数上限(非数 / < 1 ⇒ 拒启;> 20 夹到 20)", { derivedDefaultNote: "缺席/空 ⇒ backend 默认 10" }),
525
529
  r("WEB_SEARCH_PROBE_ON_BOOT", "orchestration", "boolean", "boot 期 web search 连通性探测(只认 true/1;含糊值当没开——猜错方向是凭空出网)", { staticDefault: "false" }),
@@ -123,15 +123,16 @@ type AnonymousBoundaryView = Pick<CrossInvariantView, (typeof ANONYMOUS_BOUNDARY
123
123
  */
124
124
  export declare function singleUserAnonymousBoundaryRefusal(v: AnonymousBoundaryView): string | undefined;
125
125
  /**
126
- * `a2a-audience-identity-boundary` —— **受限技能只在有身份边界的部署上成立**。`A2A_SERVE_SKILLS` 的条目写了 `audience`(只发布给点名的调用方),而这台部署
127
- * 没有身份边界 = 配置**没接任何已验身份来源**(`identity-source.ts` 的 `configuredIdentitySources` 为空 —— 「这台部署接了哪几个身份来源」的唯一读法:
126
+ * `a2a-audience-verified-source` —— **受限技能只在接了已验身份来源的部署上成立**。`A2A_SERVE_SKILLS` 的条目写了 `audience`(只发布给点名的调用方),而这台部署
127
+ * 没有已验身份来源 = 配置**没接任何一个**(`identity-source.ts` 的 `configuredIdentitySources` 为空 —— 「这台部署接了哪几个身份来源」的唯一读法:
128
128
  * 没配服务凭据、没配鉴权桥 issuer(含中心回退)、没开直连门)。卡谓词只读**验过的**来源(`a2a-serve.ts` 的 `cardReaderOf` 先问 `verifiedIdentitySource`,匿名自报的主体头读成匿名),
129
129
  * 所以这一形上**没有任何调用方能被名单点中** —— 照装就是一份静默失效的名单。只设 trace 凭据(只读凭据,不是身份来源)或只开 `REQUIRE_PRINCIPAL`(要求主体在场,
130
- * 不验它)都不接来源,同判。起服拒,拒句一行给两条出路(接一个已验身份来源 / 删掉 `audience`),与 `operatorDeclarationRefusal` 同形。不回显名单里的名字。
130
+ * 不验它)都不接来源,同判。这是**另一问**,不是部署形表行 `identityBoundary` 那一问:那一行把这两样也算数(属主门据此不再当 dev-open),本函数问的是更严的「有没有来源能验出人」,
131
+ * 两问各用各的词、各读各的读数,不互借。起服拒,拒句一行给两条出路(接一个已验身份来源 / 删掉 `audience`),与 `operatorDeclarationRefusal` 同形。不回显名单里的名字。
131
132
  * 座在装配路由的地方(`createHttpServer`,装路由之前;与 `operator-declaration-required` 的兜底座相邻,服务入口与嵌入方都过这一座)。
132
133
  * 判据收座上对 `configuredIdentitySources(config)` 的读数,本函数不另写一份「有没有凭据」。热路径不必判:`A2A_SERVE_SKILLS` 与身份键都只来自 env、起服冻结。
133
134
  */
134
- export declare function a2aAudienceIdentityBoundaryRefusal(a2aServe: A2aServeConfig | undefined, noVerifiedSource: boolean): string | undefined;
135
+ export declare function a2aAudienceVerifiedSourceRefusal(a2aServe: A2aServeConfig | undefined, noVerifiedSource: boolean): string | undefined;
135
136
  /** `bake-operator-principals`(IMAGE-API-DESIGN §P2.4a):bake 门是 build-host 无限制执行面,要**具名**运维 —— 空名单下要么没人用得了,要么(单用户声明)人人用得了。 */
136
137
  export declare function bakeOperatorPrincipalsRefusal(v: Pick<CrossInvariantView, "imageBakes" | "operatorPrincipals">): string | undefined;
137
138
  /**
@@ -102,17 +102,17 @@ export function singleUserAnonymousBoundaryRefusal(v) {
102
102
  "an unauthenticated write face then listens on 127.0.0.1 by itself; a container whose port is published to other hosts needs a credential instead) " +
103
103
  "(MIGRATION.md, invariant single-user-anonymous-boundary). Refusing to boot.");
104
104
  }
105
- export function a2aAudienceIdentityBoundaryRefusal(a2aServe, noVerifiedSource) {
105
+ export function a2aAudienceVerifiedSourceRefusal(a2aServe, noVerifiedSource) {
106
106
  if (!noVerifiedSource || a2aServe === undefined)
107
107
  return undefined;
108
108
  const restricted = a2aServe.skills.filter((s) => s.audience !== undefined).length;
109
109
  if (restricted === 0)
110
110
  return undefined;
111
- return (`A2A_SERVE_SKILLS declares ${restricted} skill${restricted === 1 ? "" : "s"} with an "audience", but this deployment has no identity boundary: ` +
112
- `it wires no verified identity source (no service credential, no SSO bridge, no direct-door principal JWT; a trace token or REQUIRE_PRINCIPAL alone verifies nobody), ` +
111
+ return (`A2A_SERVE_SKILLS declares ${restricted} skill${restricted === 1 ? "" : "s"} with an "audience", but this deployment has no verified identity source: ` +
112
+ `no service credential, no SSO bridge and no direct-door principal JWT is wired (a trace token or REQUIRE_PRINCIPAL alone verifies nobody), ` +
113
113
  `so a caller's principal header is only a self-asserted label and no caller could ever be matched against an audience. ` +
114
114
  `Wire one verified identity source (SERVICE_AUTH_TOKEN / SERVICE_AUTH_TOKENS, the SSO bridge, or the direct door) or remove the "audience" entries from A2A_SERVE_SKILLS ` +
115
- `(MIGRATION.md, invariant a2a-audience-identity-boundary). Refusing to boot.`);
115
+ `(MIGRATION.md, invariant a2a-audience-verified-source). Refusing to boot.`);
116
116
  }
117
117
  function sameOperatorDeclaration(a, b) {
118
118
  return (DEPLOYMENT_SHAPE_PREDICATES.multiTenant.holds(a) === DEPLOYMENT_SHAPE_PREDICATES.multiTenant.holds(b) &&
@@ -5,10 +5,12 @@
5
5
  * in config.ts, which re-exports these names so existing `from "./config.js"` importers keep
6
6
  * compiling unchanged. All imports below are top-level `import type` (erased — never a load edge,
7
7
  * see test/module-cycle-gate.test.ts header on verbatimModuleSyntax). */
8
+ import type { LocalStoreDeclarationWord } from "./local-store-declaration.js";
8
9
  import type { ReadFaceSource } from "./read-face-posture.js";
9
10
  import type { PostureSource } from "./posture-source.js";
10
11
  import type { SealedCustodyPoison } from "./key-resolver.js";
11
12
  import type { ModelEntryRefusal } from "./model-entry-refusal.js";
13
+ import type { ContextWindowSource } from "./model-context-window.js";
12
14
  import type { DroppedCatalogEntry } from "./web-admin-client/read-warnings.js";
13
15
  import type { A2aServerSpec, CompliancePosture, CrossSessionDialogExpiry, CrossSessionInboundSetting, FileHistoryRetentionPolicy, LockedKey, McpServerSpec, Model, ModelRoles, RetentionPolicy, ShellGateDoctrine, WriteProtectedEntry } from "@sema-agent/core";
14
16
  import type { ApprovalHmacKey, PrincipalJwtKey } from "./auth-keys.js";
@@ -768,9 +770,23 @@ export interface ServiceConfigFlat {
768
770
  * 源码钉(`test/served-model-route.test.ts` 的类钉)把这两处写口列成白名单。
769
771
  */
770
772
  envModel: Model;
773
+ /**
774
+ * `envModel.contextWindow` 的来源(`declared` = `MODEL_CONTEXT_WINDOW` 声明了;`assumed` = 没声明、落假定值)。`loadConfig` 与 `envModel` 同一次解出
775
+ * (`model-context-window.ts` 的 `resolveContextWindow`),此后永不换。唯一读者:中心腿的 BL-8 继承 —— 目录条目没写窗 ⇒ 继承 `envModel` 的窗,
776
+ * 来源随之(env 声明了 ⇒ 条目也是 declared)。不从 env 再读一遍:「声明了没有」只在解窗的那一处判。
777
+ */
778
+ envModelContextWindowSource: ContextWindowSource;
771
779
  /** Model catalog by name (1.24): always `default` + the main model's id, plus an optional cheap model.
772
780
  * Used to resolve roles and to allow-list `@-model` mentions. */
773
781
  models: Record<string, Model>;
782
+ /**
783
+ * 每个目录名的上下文窗来源(`declared` / `assumed`,闭集;值 = `models[name].contextWindow` 那个数是谁写的)。**与 `models` 同键**(别名 `default` 随它指的条目)、
784
+ * 同世代同 commit:env 腿与 `models` 经同一只组法铸(`envLaneTable`),applyEffective 在铸目录模型的同一圈里铸、与 `models` 一起整表换。
785
+ * 数住在 `Model.contextWindow`(引擎的席),来源住这里 —— 两者出自同一次解(`resolveContextWindow`),没有第二个判点。
786
+ * 读者:`GET /v1/models` 行的 `contextWindowSource`、运维通告 `model_context_window_assumed` 的唯一发声器(`context-window-notice.ts`:模型表定形之后 / 每次模型面落地之后)。
787
+ * 名不在表里 ⇒ 读者不答来源(行不带该键):只有绕过两条铸腿手写 `models` 的嵌入方 / 夹具会落到这里。
788
+ */
789
+ contextWindowSources: Readonly<Record<string, ContextWindowSource>>;
774
790
  /** Per-model API-key override: catalog model NAME → the env var NAME holding that model's key (from
775
791
  * web-admin `apiKeyEnv`). Drives the spec's `getApiKeyAndHeaders` so each model/rung authenticates
776
792
  * with its own upstream account; a model absent here falls back to the gateway key. Env path: empty. */
@@ -1135,6 +1151,7 @@ export interface ServiceConfigFlat {
1135
1151
  * `SEALED_KEY_DIR` —— 模型钥匙保管目录(sealed 形的 X25519 钥匙对 `<publicKeyId>.json`,连同停驻行封签那一域的子目录 `checkpoint-ctx-keys/`)。
1136
1152
  * **缺席不铸键** ⇒ 保管目录 = `<localDataRoot>/sealed-key`(今天的行为;建不了只是一行 warn,sealed 模型逐个 `no_key_store`)。
1137
1153
  * 给了 ⇒ 绝对路径(相对路径 loadConfig 拒启),该目录是**唯一**保管目录;起服在它上面建不了保管店 ⇒ 拒启(fail-closed:运维点名了目录)。
1154
+ * 给了 ∧ 停驻审批耐久(`DURABLE_APPROVAL` ∧ 检查点店耐久)∧ 它的介质判 `ephemeral` ⇒ 起服第 2 段店的持久性准入拒启(`store-admission.ts`;缺席时的缺省目录不进这一判)。
1138
1155
  * 谁需要:读同一份 `config.d` 而数据根不同的多台引擎(终端 × 桌面端默认形)—— sealed 条目绑定的是钥匙身份(`publicKeyId` → 钥匙对),指到同一目录 ⇒ 同一把钥。
1139
1156
  */
1140
1157
  sealedKeyDir?: string;
@@ -1151,6 +1168,14 @@ export interface ServiceConfigFlat {
1151
1168
  * 只有 `local`(file)后端读它;SQL 后端的 hydrate 不经这条路。
1152
1169
  */
1153
1170
  runStoreStrictHydrate: boolean;
1171
+ /**
1172
+ * `LOCAL_STORE_DURABILITY=ephemeral` —— 运维**声明**这台部署的 local 店易失(闭集只有这一个词;缺席 = 店型的设计声明「活过进程重启」)。
1173
+ * 唯一读者 `local-store-declaration.ts` 的 `localStoreDeclarationOf`:声明之后 local 后端交给**两半**店(会话店顶层、检查点店)的引擎声明都是
1174
+ * `process-local` ⇒ 起服布线审计的拒启臂(声明 durable ∧ 数据根介质易失)不再咬,数据根落在容器可写层 / tmpfs / emptyDir 上照常起服,起服 warn 一行。
1175
+ * 后果 = 店里的会话、停驻审批与记忆不随容器 / Pod 替换保留(进程重启照旧活过:文件还在同一只容器里)。读面的持久性读数(`store.durability`)照旧按介质如实报。
1176
+ * 部署者自己设 —— 壳 / 编排器不替用户写(写了就是替用户放弃这份承诺)。SQL / memory 后端不读它。
1177
+ */
1178
+ localStoreDurability: LocalStoreDeclarationWord | undefined;
1154
1179
  /** PostgreSQL connection (used iff dbBackend === "pg"). Mirror of `tidb`. Env: PG_HOST/PG_PORT/PG_USER/
1155
1180
  * PG_PASSWORD/PG_DATABASE/PG_POOL_SIZE. */
1156
1181
  pg?: {
@@ -1370,7 +1395,7 @@ export interface ServiceConfigFlat {
1370
1395
  * `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT` —— 「出示这台部署的 service 凭据、不报主体的调用方是谁」的**唯一声明座**。缺省 `true`(不设 = 今天的读法):
1371
1396
  * 它代部署本人说话(fleet 调用方,运维聚合口的 service 臂);`false` ⇒ 它是**无身份调用方**,各面按既有的「过了凭据门、没有主体」那一臂答
1372
1397
  * (fleet 读面 401 identity、运维聚合口 401 operator、舰队流多租 401 principal_required / 单用户落 `default`、写档 401 identity、无主 placed 子代 404)。
1373
- * 只改一处:`http/principal-gate.ts` 的 `actsForDeployment` 多这一个合取项 —— 它的两个读者(fleet 调用方的凭据臂、`/metrics*` 的 service 臂)一次继承,
1398
+ * 只改一处:`http/principal-gate.ts` 的 `actsForDeployment` 多这一个合取项 —— 它的两个读者(fleet 调用方的那一格、`/metrics*` 族)一次继承,
1374
1399
  * 零新拒码、零新闸点;自报位 `/health.auth.serviceTokenActsForDeployment` = 配了 service 凭据 ∧ 本位。没配 service 凭据的部署上声明 `false` 是空真(那一臂本来就够不着)。
1375
1400
  * env 独有(词表布尔,词表外拒启;没有 `config.d` 文件形、没有中心写位),起服读一次、热路径够不着(不是热键)。
1376
1401
  */
@@ -1892,6 +1917,13 @@ export interface ServiceConfigFlat {
1892
1917
  * make it into this list (an absent name is a per-index boot warn) — so every downstream echo of it (the scrub
1893
1918
  * disclosure's `allowed`, the config catalog) carries real key names only, never a value pasted in place of a name. */
1894
1919
  lspEnvAllow: readonly string[];
1920
+ /** settings hook 环境的**点名放回**(`HOOK_ENV_ALLOW=NAME,NAME`;名单型 env 旋钮族,渠道 `host-put-back`)。hook 环境只有一只组合(`hooks/hook-runner.ts` `hookChildEnv`):
1921
+ * 继承 = 十二名基础名单(引擎严格名单臂)∪ 本名单点到的变量(从本服务进程环境原样放回,同一条严格名单臂 —— 本服务自有凭据拒 —— 名是,或值是本服务的某一枚凭据(列表形凭据逐枚比);组合这一刻引擎照样扣下值副本),
1922
+ * 之上叠请求的有效环境层(`settings.env` + hook 自己的变量)。命令腿的子进程 env 与 http 条目 header 的 `$NAME` 插值读同一份;能插哪些名仍由条目 `allowedEnvVars`
1923
+ * ∩ 准入层 `httpHookAllowedEnvVars` 定(只收窄)。服务进程变量进 hook 环境**只有这一个来源**(部署方声明),请求层任何键都授予不了。
1924
+ * `[]` = 缺省(未设 / 空串):不放回任何变量。形错 / 点名名单型旋钮 / 点名本服务自有凭据名 ⇒ 拒启点名第几段、不回显值;本进程环境里没有的名按序号 warn、不进名单;
1925
+ * `REQUIRE_PRINCIPAL=true` ⇒ 恒 `[]`(请求的 settings hooks 在该姿态下不跑;起服 warn 一次)。 */
1926
+ hookEnvAllow: readonly string[];
1895
1927
  /** Graceful drain: how long SIGTERM waits for in-flight turns (live streams + bg/resume legs on this
1896
1928
  * instance) to finish before the hard shutdown. During drain, new billable submissions get 503+Retry-After and
1897
1929
  * /health carries `draining:true`. Default 10min (an interactive turn is minutes, not seconds — a
@@ -2179,7 +2211,7 @@ export interface ServiceConfigFlat {
2179
2211
  /** 部署**要不要求**读拒表的字节地板(`READ_DENY_FLOOR_REQUIRED`,布尔,缺省 false)—— 交引擎 `RunnerDeps.readDenyFloorRequired`
2180
2212
  * (部署姿态座席族的一席,唯一取值点 `buildDeploymentPostureSeats`)。判官是引擎:一个 run 的读拒表有行、而它的执行环境块
2181
2213
  * `keepsReadFloor` 不为真时 —— true ⇒ 准备期拒(`config.read_deny_floor_unkept`,一个命令都不起;同步腿 409);false ⇒ run 照跑,
2182
- * 每 run 一条 operator 通告同码(递归读照读表里的文件,通告不是保护)。出厂读拒档(credentials / agent-config)在岗时每条带手 run 的表都有行;
2214
+ * 每 run 一条同码通告(run 事件流一帧 + 终局结果 `readDenyFloor` + 运维日志一行,同一句点名 `REMOTE_EXEC=<车道>` 与本旋钮;递归读照读表里的文件,通告不是保护)。出厂读拒档(credentials / agent-config)在岗时每条带手 run 的表都有行;
2183
2215
  * 本仓七车道的块今天都不守地板 ⇒ 设 true 的部署上带手 run 一律拒起(起服 warn `read_deny_floor_required_unkept` 先说)。
2184
2216
  * **仅 deployment 席**:TaskSpec 上没有同名键,任务无法放宽自己的部署。 */
2185
2217
  readDenyFloorRequired: boolean;
@@ -2362,9 +2394,9 @@ export interface ServiceConfigFlat {
2362
2394
  configLocalOwnerUid?: number;
2363
2395
  }
2364
2396
  /** 组:store(持久化)—— DB 引擎三态、session 后端、SQL coords、快照 BLOB / SendUserFile 对象存储。 */
2365
- export type ServiceStoreConfig = Pick<ServiceConfigFlat, "sessionBackend" | "sessionCacheTtlSec" | "storeProbeIntervalMs" | "storeLockWaitMs" | "dbBackend" | "dbBackendExplicit" | "localDataRoot" | "sealedKeyDir" | "runStoreStrictHydrate" | "tidb" | "pg" | "dbQueryTimeoutMs" | "snapshotBlobStore" | "snapshotBlobSqlMaxBytes" | "snapshotBlobAllowSql" | "fileHistory" | "fileHistoryCapture" | "sendUserFile">;
2397
+ export type ServiceStoreConfig = Pick<ServiceConfigFlat, "sessionBackend" | "sessionCacheTtlSec" | "storeProbeIntervalMs" | "storeLockWaitMs" | "dbBackend" | "dbBackendExplicit" | "localDataRoot" | "sealedKeyDir" | "runStoreStrictHydrate" | "localStoreDurability" | "tidb" | "pg" | "dbQueryTimeoutMs" | "snapshotBlobStore" | "snapshotBlobSqlMaxBytes" | "snapshotBlobAllowSql" | "fileHistory" | "fileHistoryCapture" | "sendUserFile">;
2366
2398
  /** 组:modelPlane(模型面)—— 网关坐标、Anthropic 路线、韧性旋钮、主/廉价 model entry、role 表、降级梯。 */
2367
- export type ServiceModelPlaneConfig = Pick<ServiceConfigFlat, "gatewayBaseUrl" | "gatewayApiKey" | "gatewayFallbackUrls" | "gatewayMaxRetries" | "anthropic" | "resilience" | "model" | "envModel" | "models" | "modelApiKeyEnv" | "modelApiKeys" | "modelRefusals" | "droppedCatalogEntries" | "modelQuotaWeights" | "tiers" | "projects" | "roles" | "atMention" | "cascadeLadder" | "degrade">;
2399
+ export type ServiceModelPlaneConfig = Pick<ServiceConfigFlat, "gatewayBaseUrl" | "gatewayApiKey" | "gatewayFallbackUrls" | "gatewayMaxRetries" | "anthropic" | "resilience" | "model" | "envModel" | "envModelContextWindowSource" | "models" | "contextWindowSources" | "modelApiKeyEnv" | "modelApiKeys" | "modelRefusals" | "droppedCatalogEntries" | "modelQuotaWeights" | "tiers" | "projects" | "roles" | "atMention" | "cascadeLadder" | "degrade">;
2368
2400
  /** 组:approval(审批 / HITL 门)。`directDoorActive` 无 env 解析腿(装配层三域合取的产物),但语义上
2369
2401
  * 就是本组的门状态,故进组;`parseApprovalDomain` 的返回类型相应是 `Omit<…, "directDoorActive">`。 */
2370
2402
  export type ServiceApprovalConfig = Pick<ServiceConfigFlat, "approvalRequire" | "approvalDeny" | "approvalTimeoutSec" | "approvalAskRetentionMs" | "approvalAutoBudget" | "approvalNeverAuto" | "approvalGrant" | "approvalHmacKeys" | "durableApproval" | "durableApprovalSource" | "streamAskWindowMsSource" | "directApprovalDoor" | "directDoorActive" | "resourceSuspend" | "resourceSuspendTtlSec" | "resourceSuspendTotalTokens" | "resourceSuspendTotalBudgetUsd" | "resourceSuspendMaxSlices" | "askQuestionEnabled" | "questionThrottle" | "toolApprovalEnabled" | "permissionRulesEnabled" | "permissionRulesEnabledExplicit" | "streamAskWindowMarginMs" | "streamApproval" | "unattendedApprovalPolicy" | "mcpElicitation" | "sensitiveWritePatterns" | "writeProtectedPaths" | "manualModeShellGate" | "permissionsDisableAutoMode" | "autoModeClassifierFallback" | "autoModeClassifierTimeoutMs" | "crossSessionInbound" | "crossSessionDialogExpiry" | "principalInboxAssistant">;
@@ -2378,7 +2410,7 @@ export type ServiceMemoryConfig = Pick<ServiceConfigFlat, "memoryEngineEnabled"
2378
2410
  * config 这一层它只是一句声明。 */
2379
2411
  export type ServiceAuthConfig = Pick<ServiceConfigFlat, "authToken" | "authTokens" | "allowUnauthedWrites" | "corsOrigins" | "principalHeader" | "requirePrincipal" | "autonomy" | "commandPolicy" | "compliancePosture" | "lockedConfigKeys" | "configCatalogEnabled" | "retentionPolicy" | "retentionSweep" | "operatorPrincipals" | "operatorSingleUser" | "serviceTokenActsForDeployment" | "principalJwtPubkeys" | "principalJwtIss" | "principalJwtAud" | "authBridgeIssuer" | "principalJwtMaxTtlSec" | "bindHost" | "bindHostSource">;
2380
2412
  /** 组:orchestration(编排 + 执行车道 + 沙箱面 + workflow/后台 agent 存留)。 */
2381
- export type ServiceOrchestrationConfig = Pick<ServiceConfigFlat, "sandboxGit" | "remoteExec" | "remoteExecHomeDir" | "worktreeIsolation" | "leaderEnabled" | "leaderFanoutEnabled" | "routerEnabled" | "selfOrchestrationEnabled" | "selfOrchestrationModels" | "selfOrchestrationWorkerIsolation" | "forkEnabled" | "experimentalObserverAgents" | "schedulerEnabled" | "schedulerSessionWakeup" | "schedulerSessionLifetime" | "schedulerStorePath" | "planModeEnabled" | "hooksTimeoutMs" | "workflowRunStoreBackend" | "workflowOrphanGraceMs" | "workflowJournalRetentionMs" | "workflowRunRetentionMs" | "usageWindows" | "workflowAgentsReadOnly" | "workflowSizeGuideline" | "backgroundAgentRetentionMs" | "backgroundAgentStaleRunningMs" | "backgroundAgentStallMs" | "backgroundAgentParkClaimStaleMs" | "delegationEntryCaps" | "rosterRetentionMs" | "leaderRunStaleMs" | "scratchpadSweepTtlMs" | "sandboxPkgSource" | "sandboxPkgSourceCustom" | "sessionAutoTitle" | "sessionAutoTitleSource" | "selectEnvironmentTool" | "envFactsEnabled" | "toolDeferLongtail" | "lspHostEnabled" | "lspEnvAllow" | "autoBackgroundOnTimeout" | "imageBakes" | "readFace" | "readFaceSource" | "taskWriteFaceEscalation" | "readDenyPatterns" | "readDenyBuiltinTiers" | "readDenyBuiltinExclude" | "readDenyFloorRequired" | "sandboxReadFloor" | "agentConfigDir" | "configLkgPath" | "configLkgEnabled">;
2413
+ export type ServiceOrchestrationConfig = Pick<ServiceConfigFlat, "sandboxGit" | "remoteExec" | "remoteExecHomeDir" | "worktreeIsolation" | "leaderEnabled" | "leaderFanoutEnabled" | "routerEnabled" | "selfOrchestrationEnabled" | "selfOrchestrationModels" | "selfOrchestrationWorkerIsolation" | "forkEnabled" | "experimentalObserverAgents" | "schedulerEnabled" | "schedulerSessionWakeup" | "schedulerSessionLifetime" | "schedulerStorePath" | "planModeEnabled" | "hooksTimeoutMs" | "workflowRunStoreBackend" | "workflowOrphanGraceMs" | "workflowJournalRetentionMs" | "workflowRunRetentionMs" | "usageWindows" | "workflowAgentsReadOnly" | "workflowSizeGuideline" | "backgroundAgentRetentionMs" | "backgroundAgentStaleRunningMs" | "backgroundAgentStallMs" | "backgroundAgentParkClaimStaleMs" | "delegationEntryCaps" | "rosterRetentionMs" | "leaderRunStaleMs" | "scratchpadSweepTtlMs" | "sandboxPkgSource" | "sandboxPkgSourceCustom" | "sessionAutoTitle" | "sessionAutoTitleSource" | "selectEnvironmentTool" | "envFactsEnabled" | "toolDeferLongtail" | "lspHostEnabled" | "lspEnvAllow" | "hookEnvAllow" | "autoBackgroundOnTimeout" | "imageBakes" | "readFace" | "readFaceSource" | "taskWriteFaceEscalation" | "readDenyPatterns" | "readDenyBuiltinTiers" | "readDenyBuiltinExclude" | "readDenyFloorRequired" | "sandboxReadFloor" | "agentConfigDir" | "configLkgPath" | "configLkgEnabled">;
2382
2414
  /** 组:limitsHttp(HTTP 面 + 各类上限/配额/回收窗)。 */
2383
2415
  export type ServiceLimitsHttpConfig = Pick<ServiceConfigFlat, "port" | "attachmentOrphanGraceMs" | "workspaceFileMaxBytes" | "attachmentMaxBytes" | "attachmentMimeAllowlist" | "attachmentUnboundTtlMs" | "adoptionImportMaxSessions" | "adoptionImportMaxSessionBytes" | "infraCostRates" | "drainGraceMs" | "drainSecondSignalMinGapMs" | "sighupIdleGraceMs" | "parentPid" | "engineAutoExit" | "engineLingerMs" | "engineOrphanLingerMs" | "engineFirstAttachMs" | "engineHandoverLingerMs" | "rateLimitPerMin" | "runMaxConcurrent" | "runMaxConcurrentPerPrincipal" | "maxTaskCostUsd" | "maxTaskTokens" | "maxPrincipalCostUsd" | "costQuotaWindowSec" | "reapIntervalSec" | "runStaleSec" | "toolResultTtlSec">;
2384
2416
  /** 组:observability(可观测)。 */
package/dist/config.d.ts CHANGED
@@ -235,22 +235,23 @@ export declare function configKnobTable(): ConfigKnobRecord[];
235
235
  export declare const hostBackgroundShellEnabled: () => boolean;
236
236
  /** The `host` exec lane's spool-file stdio form; false ⇒ the pre-1.226 pipe fallback (read per exec). */
237
237
  export declare const hostExecSpoolEnabled: () => boolean;
238
- /** 名单在活配置里的落点(服务进程四只旋钮;bake-runner 那只在它自己的进程里,不在 `ServiceConfig`)。 */
239
- export type EnvNameAllowlistSeats = Pick<ServiceConfig, "lspEnvAllow" | "remoteExec">;
238
+ /** 名单在活配置里的落点(服务进程五只旋钮;bake-runner 那只在它自己的进程里,不在 `ServiceConfig`)。 */
239
+ export type EnvNameAllowlistSeats = Pick<ServiceConfig, "lspEnvAllow" | "hookEnvAllow" | "remoteExec">;
240
240
  /**
241
241
  * 沙箱名单(表列 `channel: "sandbox-grant"` 的服务侧旋钮,表派生)此刻交出去的名 —— 起服行 `remote_exec_enabled.sandboxEnvKeys` 读它(`boot/execution-env.ts`,
242
242
  * 排序后只出键名)。只有被选中车道的那一只有落点;e2b / k8s 报的是名单点到的键,不含 `SANDBOX_PKG_SOURCE` 推导出的包源变量(那一组是区域常量,装配点另并)。
243
243
  */
244
244
  export declare function sandboxEnvNamesInForce(seats: EnvNameAllowlistSeats): readonly string[];
245
- /** 声明增长后重判的一处命中:哪只旋钮、它交出去的哪个名、判官的拒因({@link ownCredentialNameProblem} 那一句,只回显名)。 */
245
+ /** 声明增长后重判的一处命中:哪只旋钮、它交出去的哪个名、判官的拒因({@link ownCredentialProblem} 那一句,只回显名)。 */
246
246
  export interface OwnCredentialInForce {
247
247
  readonly knob: ServerEnvNameAllowlistKnob;
248
248
  readonly name: string;
249
249
  readonly problem: string;
250
250
  }
251
251
  /**
252
- * 解析器头注 ② 那条不变量在**声明增长**那一刻的半边:对活配置里每只名单此刻交出去的名问**同一只**判官({@link ownCredentialNameProblem} → 引擎
253
- * `inheritEnvPolicyProblem`,读引擎此刻的声明)。读活配置的落点,不重读 env(名单是起服输入;解析那一刻已判过形与当时的声明)。返回每一处命中,空 = 不相交。
252
+ * 解析器头注 ② 那条不变量在**声明增长**那一刻的半边:对活配置里每只名单此刻交出去的名问**同一只**判官({@link ownCredentialProblem} → `ownCredentialVariable`,
253
+ * 读引擎此刻的声明:增长并进的名,与增长并进的值 —— 新条目 `apiKeyEnv` 的值等于名单交出去的某个变量的值,同样命中)。读活配置的落点(名单是起服输入;
254
+ * 解析那一刻已判过形与当时的声明)。返回每一处命中,空 = 不相交。
254
255
  * 调用点只有一处 = 声明增长的那一处(`apply-effective.ts` 的换代声明,真声明之后、席位换装之前)。
255
256
  */
256
257
  export declare function ownCredentialHitsInForce(seats: EnvNameAllowlistSeats): OwnCredentialInForce[];