@sema-agent/server 7.131.0 → 7.133.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 (509) hide show
  1. package/MIGRATION.md +575 -0
  2. package/README.md +12 -9
  3. package/README.zh-CN.md +9 -6
  4. package/USAGE.md +326 -98
  5. package/deploy/sema-up/README.md +19 -1
  6. package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -2
  7. package/deploy/sema-up/chart/templates/server.yaml +5 -2
  8. package/deploy/sema-up/stack/compose.yaml +3 -0
  9. package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
  10. package/dist/adoption/plan.d.ts +3 -2
  11. package/dist/adoption/plan.js +7 -5
  12. package/dist/adoption/runner.js +3 -10
  13. package/dist/adoption/sql.d.ts +3 -2
  14. package/dist/adoption/sql.js +3 -5
  15. package/dist/adoption/wire.d.ts +4 -1
  16. package/dist/adoption/wire.js +1 -0
  17. package/dist/approval-ask-audit-store.d.ts +31 -13
  18. package/dist/approval-ask-audit-store.js +272 -74
  19. package/dist/approval-ask-machine.d.ts +15 -0
  20. package/dist/approval-ask-machine.js +6 -0
  21. package/dist/approval-ask-retention.d.ts +136 -0
  22. package/dist/approval-ask-retention.js +102 -0
  23. package/dist/approval-card.d.ts +82 -20
  24. package/dist/approval-card.js +46 -16
  25. package/dist/approval-deny-reasons.d.ts +1 -1
  26. package/dist/approval.d.ts +9 -0
  27. package/dist/approval.js +24 -3
  28. package/dist/audit.d.ts +33 -19
  29. package/dist/audit.js +12 -16
  30. package/dist/auth-bridge.d.ts +4 -0
  31. package/dist/auth-bridge.js +10 -11
  32. package/dist/bake-runner/main.js +3 -2
  33. package/dist/boot/deferred-sandbox-path-env.js +1 -1
  34. package/dist/boot/deployment-mods.d.ts +31 -0
  35. package/dist/boot/deployment-mods.js +26 -0
  36. package/dist/boot/execution-env.d.ts +1 -1
  37. package/dist/boot/execution-env.js +27 -12
  38. package/dist/boot/execution-lane.js +11 -0
  39. package/dist/boot/leader.js +2 -0
  40. package/dist/boot/memory-boundary.d.ts +2 -2
  41. package/dist/boot/memory-boundary.js +2 -2
  42. package/dist/boot/memory-consolidation.d.ts +5 -4
  43. package/dist/boot/memory-consolidation.js +7 -6
  44. package/dist/boot/org-delivery.d.ts +28 -0
  45. package/dist/boot/org-delivery.js +20 -0
  46. package/dist/boot/read-deny-anchor-audit.d.ts +17 -0
  47. package/dist/boot/read-deny-anchor-audit.js +36 -0
  48. package/dist/boot/reapers.d.ts +3 -0
  49. package/dist/boot/reapers.js +21 -1
  50. package/dist/boot/resolve-spec.d.ts +4 -5
  51. package/dist/boot/resolve-spec.js +74 -123
  52. package/dist/boot/runner-deps.d.ts +19 -8
  53. package/dist/boot/runner-deps.js +15 -2
  54. package/dist/boot/session-faces.d.ts +2 -7
  55. package/dist/boot/session-faces.js +4 -2
  56. package/dist/boot/stage-02-web-admin-pull.js +4 -1
  57. package/dist/boot/stage-03-store-backend.d.ts +1 -1
  58. package/dist/boot/stage-03-store-backend.js +2 -2
  59. package/dist/boot/stage-04-stores.d.ts +1 -1
  60. package/dist/boot/stage-05-execution-env.d.ts +4 -4
  61. package/dist/boot/stage-05-execution-env.js +7 -10
  62. package/dist/boot/stage-06-runners.d.ts +4 -2
  63. package/dist/boot/stage-06-runners.js +11 -7
  64. package/dist/boot/stage-07-capability-layer.d.ts +4 -2
  65. package/dist/boot/stage-07-capability-layer.js +27 -6
  66. package/dist/boot/stage-08-reapers.d.ts +4 -2
  67. package/dist/boot/stage-08-reapers.js +2 -2
  68. package/dist/boot/stage-09-leader.d.ts +6 -9
  69. package/dist/boot/stage-10-http-server.d.ts +6 -9
  70. package/dist/boot/stage-10-http-server.js +7 -9
  71. package/dist/boot/stores.d.ts +1 -1
  72. package/dist/boot/stores.js +7 -8
  73. package/dist/boot/web-admin.d.ts +4 -3
  74. package/dist/boot/web-admin.js +186 -98
  75. package/dist/boot/workflow-orchestration.d.ts +2 -0
  76. package/dist/boot/workflow-orchestration.js +2 -1
  77. package/dist/brain.js +25 -25
  78. package/dist/breaker-key.d.ts +6 -0
  79. package/dist/breaker-key.js +29 -0
  80. package/dist/budget.js +5 -4
  81. package/dist/caller-text-echo.d.ts +23 -0
  82. package/dist/caller-text-echo.js +21 -0
  83. package/dist/capabilities/brand-identity.d.ts +26 -0
  84. package/dist/capabilities/brand-identity.js +27 -0
  85. package/dist/capabilities/center-plugins.d.ts +7 -0
  86. package/dist/capabilities/center-plugins.js +1 -1
  87. package/dist/capabilities/center-prompts.d.ts +32 -59
  88. package/dist/capabilities/center-prompts.js +18 -32
  89. package/dist/capabilities/composite-members.d.ts +1 -1
  90. package/dist/capabilities/composite-members.js +1 -1
  91. package/dist/capabilities/engine-capabilities.js +2 -1
  92. package/dist/capabilities/execution-lane.js +2 -2
  93. package/dist/capabilities/hands-lane.d.ts +30 -6
  94. package/dist/capabilities/hands-lane.js +11 -1
  95. package/dist/capabilities/mcp-probe.d.ts +48 -3
  96. package/dist/capabilities/mcp-probe.js +47 -135
  97. package/dist/capabilities/scenarios.d.ts +95 -45
  98. package/dist/capabilities/scenarios.js +53 -38
  99. package/dist/capabilities/skills.d.ts +19 -4
  100. package/dist/capabilities/skills.js +30 -10
  101. package/dist/capability-facts.d.ts +34 -4
  102. package/dist/capability-facts.js +28 -2
  103. package/dist/center-config-tier.d.ts +69 -0
  104. package/dist/center-config-tier.js +42 -0
  105. package/dist/checkpoint-identity.d.ts +16 -0
  106. package/dist/checkpoint-identity.js +19 -0
  107. package/dist/config-catalog.d.ts +17 -10
  108. package/dist/config-catalog.js +47 -32
  109. package/dist/config-d-migration.d.ts +3 -1
  110. package/dist/config-d-migration.js +2 -2
  111. package/dist/config-dir-trust.d.ts +114 -0
  112. package/dist/config-dir-trust.js +388 -0
  113. package/dist/config-invariants.d.ts +18 -5
  114. package/dist/config-invariants.js +35 -3
  115. package/dist/config-lkg.d.ts +9 -9
  116. package/dist/config-lkg.js +20 -4
  117. package/dist/config-provider.d.ts +9 -2
  118. package/dist/config-provider.js +18 -6
  119. package/dist/config-types.d.ts +75 -20
  120. package/dist/config-types.js +8 -0
  121. package/dist/config.d.ts +13 -0
  122. package/dist/config.js +137 -62
  123. package/dist/delegated-session-owner.d.ts +185 -0
  124. package/dist/delegated-session-owner.js +119 -0
  125. package/dist/device-protocol.d.ts +5 -3
  126. package/dist/device-protocol.js +1 -1
  127. package/dist/device-ws-hub.js +21 -2
  128. package/dist/device-ws-protocol.d.ts +70 -6
  129. package/dist/device-ws-protocol.js +50 -22
  130. package/dist/elicitation.js +3 -2
  131. package/dist/entry-problems.d.ts +34 -0
  132. package/dist/entry-problems.js +14 -0
  133. package/dist/env-name-allowlist-knobs.d.ts +12 -2
  134. package/dist/env-name-allowlist-knobs.js +5 -4
  135. package/dist/exec-bounds.d.ts +15 -3
  136. package/dist/exec-bounds.js +4 -0
  137. package/dist/execution-lane-caps.d.ts +56 -10
  138. package/dist/execution-lane-caps.js +50 -0
  139. package/dist/field-conflict.d.ts +43 -0
  140. package/dist/field-conflict.js +20 -0
  141. package/dist/fleet/fleet-bus.d.ts +80 -6
  142. package/dist/fleet/fleet-bus.js +41 -9
  143. package/dist/hooks/classic-stations.d.ts +91 -0
  144. package/dist/hooks/classic-stations.js +27 -0
  145. package/dist/hooks/command-spawn.d.ts +57 -0
  146. package/dist/hooks/command-spawn.js +139 -0
  147. package/dist/hooks/hook-llm.d.ts +8 -5
  148. package/dist/hooks/hook-llm.js +79 -36
  149. package/dist/hooks/hook-runner.d.ts +349 -95
  150. package/dist/hooks/hook-runner.js +855 -568
  151. package/dist/hooks/hook-source.d.ts +44 -0
  152. package/dist/hooks/hook-source.js +40 -0
  153. package/dist/http/active-run-conflict.d.ts +5 -13
  154. package/dist/http/active-run-conflict.js +17 -27
  155. package/dist/http/admission.d.ts +8 -2
  156. package/dist/http/admission.js +188 -101
  157. package/dist/http/approval-sweeps.js +99 -21
  158. package/dist/http/caller-trust.d.ts +77 -0
  159. package/dist/http/caller-trust.js +143 -0
  160. package/dist/http/checkpoint-ctx.d.ts +41 -24
  161. package/dist/http/checkpoint-ctx.js +23 -16
  162. package/dist/http/claimed-run.d.ts +14 -0
  163. package/dist/http/claimed-run.js +15 -0
  164. package/dist/http/device-placement.d.ts +2 -4
  165. package/dist/http/device-placement.js +7 -11
  166. package/dist/http/dispatch.d.ts +0 -4
  167. package/dist/http/dispatch.js +15 -13
  168. package/dist/http/durable-run-leg.d.ts +6 -33
  169. package/dist/http/durable-run-leg.js +36 -10
  170. package/dist/http/health-self-report.d.ts +7 -5
  171. package/dist/http/health-self-report.js +4 -18
  172. package/dist/http/owner-access.d.ts +56 -0
  173. package/dist/http/owner-access.js +42 -0
  174. package/dist/http/principal-gate.d.ts +70 -28
  175. package/dist/http/principal-gate.js +61 -15
  176. package/dist/http/readiness.d.ts +11 -5
  177. package/dist/http/readiness.js +10 -3
  178. package/dist/http/refusal-body.d.ts +21 -0
  179. package/dist/http/refusal-body.js +4 -0
  180. package/dist/http/request-guards.d.ts +43 -23
  181. package/dist/http/request-guards.js +53 -17
  182. package/dist/http/resume-ctx-read.d.ts +2 -5
  183. package/dist/http/resume-ctx-read.js +7 -4
  184. package/dist/http/resume-legs.d.ts +28 -4
  185. package/dist/http/resume-legs.js +169 -91
  186. package/dist/http/retired-service-deps.d.ts +43 -0
  187. package/dist/http/retired-service-deps.js +18 -0
  188. package/dist/http/route-ctx.d.ts +44 -28
  189. package/dist/http/route-ctx.js +4 -0
  190. package/dist/http/route-table.js +2 -0
  191. package/dist/http/routes/a2a-serve.js +3 -4
  192. package/dist/http/routes/admin-config-refresh.js +1 -1
  193. package/dist/http/routes/admin-drain.js +1 -1
  194. package/dist/http/routes/admin-memory-optout.js +5 -1
  195. package/dist/http/routes/adoption.js +2 -9
  196. package/dist/http/routes/approvals-assistant.js +49 -48
  197. package/dist/http/routes/background.js +3 -2
  198. package/dist/http/routes/capabilities.js +21 -5
  199. package/dist/http/routes/config-catalog.d.ts +3 -3
  200. package/dist/http/routes/config-catalog.js +1 -1
  201. package/dist/http/routes/devices.js +3 -17
  202. package/dist/http/routes/diagnostics.js +6 -2
  203. package/dist/http/routes/images.js +6 -7
  204. package/dist/http/routes/leader.js +1 -8
  205. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  206. package/dist/http/routes/mcp-reconnect.js +3 -2
  207. package/dist/http/routes/memory-bundle.js +1 -1
  208. package/dist/http/routes/memory-compliance.js +1 -1
  209. package/dist/http/routes/memory-consolidation.js +1 -1
  210. package/dist/http/routes/memory-origin.js +1 -1
  211. package/dist/http/routes/memory-policy.d.ts +1 -1
  212. package/dist/http/routes/memory-policy.js +3 -2
  213. package/dist/http/routes/notify-wake.js +8 -21
  214. package/dist/http/routes/observability.js +2 -2
  215. package/dist/http/routes/principal-inbox.d.ts +39 -0
  216. package/dist/http/routes/principal-inbox.js +76 -0
  217. package/dist/http/routes/retention-ops.js +2 -9
  218. package/dist/http/routes/rules.js +5 -18
  219. package/dist/http/routes/runs.d.ts +5 -0
  220. package/dist/http/routes/runs.js +34 -107
  221. package/dist/http/routes/session-sync.js +15 -26
  222. package/dist/http/routes/sessions.js +30 -40
  223. package/dist/http/routes/shared-memory.js +2 -13
  224. package/dist/http/routes/side-query.js +8 -7
  225. package/dist/http/routes/tasks.js +67 -21
  226. package/dist/http/routes/workflows.d.ts +351 -0
  227. package/dist/http/routes/workflows.js +153 -119
  228. package/dist/http/send.d.ts +33 -10
  229. package/dist/http/send.js +21 -4
  230. package/dist/http/server.d.ts +27 -18
  231. package/dist/http/server.js +34 -6
  232. package/dist/http/stored-body-replay.js +17 -4
  233. package/dist/http/submit-ctx.d.ts +25 -0
  234. package/dist/http/submit-ctx.js +40 -0
  235. package/dist/http/submit-replay.d.ts +4 -3
  236. package/dist/http/submit-replay.js +5 -4
  237. package/dist/http/wire-types.d.ts +11 -8
  238. package/dist/index.d.ts +2 -2
  239. package/dist/index.js +1 -2
  240. package/dist/lane-home-probe.d.ts +112 -0
  241. package/dist/lane-home-probe.js +101 -0
  242. package/dist/leader/endpoint.d.ts +4 -1
  243. package/dist/leader/endpoint.js +11 -10
  244. package/dist/limit-refusal.d.ts +59 -0
  245. package/dist/limit-refusal.js +15 -0
  246. package/dist/main.js +1 -1
  247. package/dist/mcp-assertion-header.d.ts +32 -19
  248. package/dist/mcp-assertion-header.js +10 -9
  249. package/dist/mcp-tool-faces.d.ts +5 -0
  250. package/dist/mcp-tool-faces.js +6 -4
  251. package/dist/memory-project-layer.d.ts +37 -0
  252. package/dist/memory-project-layer.js +46 -0
  253. package/dist/memory-scope.d.ts +24 -17
  254. package/dist/memory-scope.js +24 -8
  255. package/dist/memory-sync-client.d.ts +27 -13
  256. package/dist/memory-sync-client.js +107 -18
  257. package/dist/model-entry-refusal.d.ts +9 -1
  258. package/dist/model-entry-refusal.js +6 -1
  259. package/dist/model-plane-face.d.ts +51 -0
  260. package/dist/model-plane-face.js +24 -0
  261. package/dist/model-provider.d.ts +44 -12
  262. package/dist/model-provider.js +21 -2
  263. package/dist/model-route-endpoint.d.ts +9 -12
  264. package/dist/model-route-endpoint.js +8 -11
  265. package/dist/model-route-env.d.ts +22 -0
  266. package/dist/model-route-env.js +2 -0
  267. package/dist/model-route-gap.d.ts +60 -30
  268. package/dist/model-route-gap.js +21 -15
  269. package/dist/observability/corrupt-read-seat.d.ts +7 -0
  270. package/dist/observability/corrupt-read-seat.js +9 -0
  271. package/dist/observability/cost-taxonomy.d.ts +7 -7
  272. package/dist/observability/err-text.d.ts +6 -0
  273. package/dist/observability/err-text.js +18 -4
  274. package/dist/observability/fail-open.d.ts +76 -14
  275. package/dist/observability/fail-open.js +76 -14
  276. package/dist/observability/metrics.js +4 -1
  277. package/dist/observability/prompt-manifest.d.ts +33 -82
  278. package/dist/observability/prompt-manifest.js +122 -17
  279. package/dist/observability/run-terminal.js +14 -6
  280. package/dist/observability/secret-env-scrub.d.ts +13 -1
  281. package/dist/observability/secret-env-scrub.js +13 -1
  282. package/dist/observability/tool-trace.d.ts +16 -21
  283. package/dist/observability/tool-trace.js +58 -49
  284. package/dist/operator-ask.d.ts +10 -0
  285. package/dist/operator-ask.js +3 -0
  286. package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
  287. package/dist/orchestration/workflow-agent-session-index.js +9 -13
  288. package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
  289. package/dist/orchestration/workflow-completion-inbox.js +13 -0
  290. package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
  291. package/dist/orchestration/workflow-notify-journal.js +27 -34
  292. package/dist/orchestration/workflow-park-decision.d.ts +89 -0
  293. package/dist/orchestration/workflow-park-decision.js +118 -0
  294. package/dist/org-delivery-gate.d.ts +81 -0
  295. package/dist/org-delivery-gate.js +59 -0
  296. package/dist/panel-tool-names.d.ts +23 -0
  297. package/dist/panel-tool-names.js +8 -0
  298. package/dist/parked-decide.d.ts +39 -6
  299. package/dist/parked-decide.js +98 -51
  300. package/dist/parked-revive-surface.d.ts +9 -2
  301. package/dist/parked-revive-surface.js +11 -8
  302. package/dist/per-task-image.d.ts +7 -1
  303. package/dist/per-task-image.js +3 -3
  304. package/dist/permission-rule-list.d.ts +1 -1
  305. package/dist/permission-rule-list.js +2 -2
  306. package/dist/plain-string-record.d.ts +25 -0
  307. package/dist/plain-string-record.js +32 -0
  308. package/dist/plugins/approval-ask-store-file.d.ts +16 -1
  309. package/dist/plugins/approval-ask-store-file.js +21 -0
  310. package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
  311. package/dist/plugins/approval-ask-store-memory.js +34 -2
  312. package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
  313. package/dist/plugins/approval-ask-store-sql.js +37 -1
  314. package/dist/plugins/blob-backend.d.ts +83 -15
  315. package/dist/plugins/blob-backend.js +68 -15
  316. package/dist/plugins/breaker-state-sql.d.ts +2 -2
  317. package/dist/plugins/breaker-state-sql.js +4 -4
  318. package/dist/plugins/caching-session-store.d.ts +3 -0
  319. package/dist/plugins/caching-session-store.js +3 -0
  320. package/dist/plugins/checkpoint-store-sql.d.ts +28 -4
  321. package/dist/plugins/checkpoint-store-sql.js +59 -28
  322. package/dist/plugins/file-history-store-sql.d.ts +5 -2
  323. package/dist/plugins/file-history-store-sql.js +3 -1
  324. package/dist/plugins/file-run-store.d.ts +5 -13
  325. package/dist/plugins/file-run-store.js +9 -0
  326. package/dist/plugins/fork-routing-session-store.d.ts +9 -1
  327. package/dist/plugins/fork-routing-session-store.js +12 -1
  328. package/dist/plugins/host-platform.d.ts +2 -0
  329. package/dist/plugins/host-platform.js +2 -1
  330. package/dist/plugins/k8s-bg-scripts.d.ts +11 -0
  331. package/dist/plugins/k8s-bg-scripts.js +22 -0
  332. package/dist/plugins/local-checkpoint-store.d.ts +2 -0
  333. package/dist/plugins/local-checkpoint-store.js +11 -3
  334. package/dist/plugins/local-session-store.d.ts +1 -1
  335. package/dist/plugins/local-session-store.js +1 -1
  336. package/dist/plugins/local-session-window.d.ts +39 -0
  337. package/dist/plugins/local-session-window.js +54 -0
  338. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
  339. package/dist/plugins/mailbox-store-sql.d.ts +30 -48
  340. package/dist/plugins/mailbox-store-sql.js +77 -52
  341. package/dist/plugins/memory-embedder-fingerprint.js +2 -1
  342. package/dist/plugins/memory-run-store.d.ts +5 -13
  343. package/dist/plugins/memory-run-store.js +8 -0
  344. package/dist/plugins/one-time-migrations.d.ts +245 -93
  345. package/dist/plugins/one-time-migrations.js +668 -207
  346. package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
  347. package/dist/plugins/org-delivery-quota-store.js +228 -0
  348. package/dist/plugins/permission-rule-store-sql.d.ts +13 -7
  349. package/dist/plugins/permission-rule-store-sql.js +4 -18
  350. package/dist/plugins/pg-pool.js +39 -7
  351. package/dist/plugins/pg-session-storage.d.ts +20 -8
  352. package/dist/plugins/pg-session-storage.js +34 -21
  353. package/dist/plugins/remote-env-adb.d.ts +12 -12
  354. package/dist/plugins/remote-env-adb.js +21 -6
  355. package/dist/plugins/remote-env-device.js +3 -0
  356. package/dist/plugins/remote-env-e2b.d.ts +1 -1
  357. package/dist/plugins/remote-env-e2b.js +21 -9
  358. package/dist/plugins/remote-env-host.d.ts +9 -9
  359. package/dist/plugins/remote-env-host.js +10 -32
  360. package/dist/plugins/remote-env-k8s.d.ts +103 -38
  361. package/dist/plugins/remote-env-k8s.js +288 -95
  362. package/dist/plugins/remote-env-local-docker.d.ts +27 -13
  363. package/dist/plugins/remote-env-local-docker.js +82 -11
  364. package/dist/plugins/remote-env-ssh.d.ts +21 -12
  365. package/dist/plugins/remote-env-ssh.js +117 -5
  366. package/dist/plugins/remote-shell.d.ts +0 -1
  367. package/dist/plugins/remote-shell.js +1 -2
  368. package/dist/plugins/retention-store-sql.js +6 -2
  369. package/dist/plugins/run-store-sql.d.ts +16 -14
  370. package/dist/plugins/run-store-sql.js +22 -2
  371. package/dist/plugins/schema-consistency.d.ts +54 -0
  372. package/dist/plugins/schema-consistency.js +52 -0
  373. package/dist/plugins/schema-indexes.js +2 -0
  374. package/dist/plugins/send-user-file.js +2 -2
  375. package/dist/plugins/session-epoch-anchor.d.ts +39 -0
  376. package/dist/plugins/session-epoch-anchor.js +22 -0
  377. package/dist/plugins/session-store.d.ts +18 -8
  378. package/dist/plugins/session-store.js +15 -4
  379. package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
  380. package/dist/plugins/shared-memory-store-sql.js +5 -16
  381. package/dist/plugins/sql-driver.d.ts +205 -1
  382. package/dist/plugins/sql-driver.js +325 -13
  383. package/dist/plugins/sql-errors.d.ts +64 -0
  384. package/dist/plugins/sql-errors.js +57 -0
  385. package/dist/plugins/store-backend.d.ts +36 -1
  386. package/dist/plugins/store-backend.js +42 -15
  387. package/dist/plugins/store-contracts.d.ts +42 -0
  388. package/dist/plugins/store-contracts.js +1 -0
  389. package/dist/plugins/tidb-pool.d.ts +6 -1
  390. package/dist/plugins/tidb-pool.js +44 -10
  391. package/dist/plugins/tidb-session-storage.d.ts +8 -11
  392. package/dist/plugins/tidb-session-storage.js +6 -16
  393. package/dist/plugins/tidb-session-store.d.ts +24 -4
  394. package/dist/plugins/tidb-session-store.js +29 -5
  395. package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
  396. package/dist/plugins/workflow-journal-store-sql.js +19 -6
  397. package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
  398. package/dist/plugins/workflow-run-store-sql.js +50 -9
  399. package/dist/posture-source.d.ts +18 -10
  400. package/dist/posture-source.js +4 -1
  401. package/dist/project-identity.d.ts +45 -6
  402. package/dist/project-identity.js +162 -8
  403. package/dist/project-layer-key.d.ts +28 -0
  404. package/dist/project-layer-key.js +29 -0
  405. package/dist/prompts-domain-validate.d.ts +17 -61
  406. package/dist/prompts-domain-validate.js +9 -119
  407. package/dist/question.js +3 -2
  408. package/dist/read-deny-entry.d.ts +25 -0
  409. package/dist/read-deny-entry.js +12 -0
  410. package/dist/read-face-posture.d.ts +37 -11
  411. package/dist/read-face-posture.js +32 -3
  412. package/dist/request-key-closure.d.ts +9 -2
  413. package/dist/request-key-closure.js +11 -5
  414. package/dist/request-value-closure.d.ts +5 -0
  415. package/dist/request-value-closure.js +11 -3
  416. package/dist/rule-entry-list.d.ts +38 -11
  417. package/dist/rule-entry-list.js +106 -30
  418. package/dist/rules-consent.js +3 -4
  419. package/dist/run-acceptance.d.ts +19 -3
  420. package/dist/run-acceptance.js +13 -1
  421. package/dist/run-local.js +54 -24
  422. package/dist/runs.d.ts +15 -8
  423. package/dist/runs.js +35 -1
  424. package/dist/runtime-caps-resolver.d.ts +16 -6
  425. package/dist/runtime-caps-resolver.js +18 -5
  426. package/dist/sandbox-pkg-source.d.ts +19 -1
  427. package/dist/sandbox-pkg-source.js +29 -7
  428. package/dist/security.d.ts +87 -9
  429. package/dist/security.js +52 -9
  430. package/dist/server-secret-env.d.ts +44 -18
  431. package/dist/server-secret-env.js +49 -8
  432. package/dist/session-error-wire.d.ts +19 -2
  433. package/dist/session-error-wire.js +5 -1
  434. package/dist/session-incarnation.d.ts +15 -5
  435. package/dist/session-incarnation.js +16 -9
  436. package/dist/session-titled-frame.d.ts +33 -0
  437. package/dist/session-titled-frame.js +4 -0
  438. package/dist/session-titler.d.ts +9 -1
  439. package/dist/session-titler.js +27 -6
  440. package/dist/spec-fields.d.ts +28 -16
  441. package/dist/spec-fields.js +66 -54
  442. package/dist/sql-engine-posture.d.ts +31 -4
  443. package/dist/sql-engine-posture.js +36 -1
  444. package/dist/stored-request-tool-axes-m19.d.ts +19 -4
  445. package/dist/stored-request-tool-axes-m19.js +30 -2
  446. package/dist/task-a2a.d.ts +9 -1
  447. package/dist/task-a2a.js +73 -47
  448. package/dist/task-cwd.d.ts +1 -1
  449. package/dist/task-mcp.d.ts +46 -58
  450. package/dist/task-mcp.js +82 -107
  451. package/dist/task-settings.d.ts +95 -108
  452. package/dist/task-settings.js +77 -98
  453. package/dist/text-bidi.d.ts +1 -48
  454. package/dist/text-bidi.js +3 -5
  455. package/dist/tighten-only-seats.d.ts +150 -0
  456. package/dist/tighten-only-seats.js +196 -0
  457. package/dist/tool-approval.d.ts +304 -88
  458. package/dist/tool-approval.js +623 -239
  459. package/dist/trace/core-keyset-guard.d.ts +122 -20
  460. package/dist/trace/engine-notice-wire.d.ts +11 -3
  461. package/dist/trace/engine-notice-wire.js +8 -1
  462. package/dist/trace/exit-seat.d.ts +28 -0
  463. package/dist/trace/exit-seat.js +76 -0
  464. package/dist/trace/ledger-events.d.ts +6 -3
  465. package/dist/trace/ledger-sink.js +4 -1
  466. package/dist/trace/model-segment.js +1 -1
  467. package/dist/trace/project.d.ts +98 -17
  468. package/dist/trace/project.js +98 -50
  469. package/dist/trace/projection-table.d.ts +100 -0
  470. package/dist/trace/projection-table.js +130 -0
  471. package/dist/trace/redact.d.ts +54 -0
  472. package/dist/trace/redact.js +778 -152
  473. package/dist/trace/self-minted-wire.d.ts +345 -1
  474. package/dist/trace/self-minted-wire.js +117 -1
  475. package/dist/trace/wire-projection-faces.d.ts +377 -3
  476. package/dist/trace/wire-projection-faces.js +164 -1
  477. package/dist/url-refusal.js +2 -0
  478. package/dist/web-admin-client/apply-effective.d.ts +12 -0
  479. package/dist/web-admin-client/apply-effective.js +56 -5
  480. package/dist/web-admin-client/candidate-gate.d.ts +6 -6
  481. package/dist/web-admin-client/candidate-gate.js +3 -3
  482. package/dist/web-admin-client/facade.d.ts +1 -1
  483. package/dist/web-admin-client/facade.js +1 -1
  484. package/dist/web-admin-client/http-client.js +0 -6
  485. package/dist/web-admin-client/read-face.js +5 -9
  486. package/dist/web-admin-client/read-warnings.d.ts +13 -0
  487. package/dist/web-admin-client/read-warnings.js +10 -0
  488. package/dist/web-admin-client/skills-mcp.d.ts +3 -0
  489. package/dist/web-admin-client/skills-mcp.js +11 -9
  490. package/dist/web-admin-client/types.d.ts +2 -3
  491. package/dist/workspace-cache.d.ts +35 -0
  492. package/dist/workspace-cache.js +36 -0
  493. package/dist/workspace-space.d.ts +3 -2
  494. package/dist/workspace-space.js +2 -0
  495. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +65 -10
  496. package/package.json +8 -4
  497. package/scripts/drain-check-local.mjs +34 -1
  498. package/scripts/drain-check.mysql.sql +30 -2
  499. package/scripts/drain-check.pg.sql +29 -2
  500. package/dist/capabilities/memory-notice.d.ts +0 -138
  501. package/dist/capabilities/memory-notice.js +0 -64
  502. package/dist/capabilities/prompt.d.ts +0 -17
  503. package/dist/capabilities/prompt.js +0 -6
  504. package/dist/mcp-content-origin.d.ts +0 -34
  505. package/dist/mcp-content-origin.js +0 -10
  506. package/dist/tool-axis-words.d.ts +0 -27
  507. package/dist/tool-axis-words.js +0 -9
  508. package/dist/wire-name-bound.d.ts +0 -14
  509. package/dist/wire-name-bound.js +0 -13
package/MIGRATION.md CHANGED
@@ -7,6 +7,581 @@
7
7
  > ⚠️ 完整清单在仓库根 `CHANGELOG.md`——它**不随 npm tarball 出包**(本文件随包)。看完整迁移窗的
8
8
  > 权威姿势是源码 tag diff:`git diff v<旧>..v<新>`(每版都推 `v<版本>` tag);npm 包页也镜像 CHANGELOG。
9
9
 
10
+ ## 7.133.0 —— `SANDBOX_PKG_SOURCE=custom` 的包源 / 镜像地址带 userinfo 起服拒启(安全) · 删包根导出 `judgeModelRouteGap`(BREAKING;壳 / 包改读 `GET /v1/models` 的 `modelPlane`) · 审批帧一条腿一个帧族(BREAKING,wire;消费方按 `approvalFrameFamilies` 分派) · 坏 JSON 体统一答 `400 request.invalid_json`、读体超限统一答 `413`(BREAKING,wire 码 / 状态码变更;此前多数口答 `request.rejected`,一批口把超限折成 `400 request.invalid_json`) · device 车道四根数值旋钮越界起服拒启、协议修订号抬到 2(结局码集随修订号) · acceptEdits 的免问写域改为引擎的写根(行为变更;沙箱车道上不再等同 `default`) · 审批列表面同族、`approvalId` = 行的键、已决卡再应答回放首决(BREAKING,wire 值变更) · 委派子代会话的属主随委派树写入、无主的委派子代行不对具名主体放行、SQL 后端存量子代行每次起服回填(安全) · 嵌入方 `ServiceKnobDeps.snapshotBlobSqlCap` 读口退役(BREAKING;零别名;要固定帽设 `SNAPSHOT_BLOB_SQL_MAX_BYTES`) · 子代转录读法 = 同一会话读面 + 终态帧 `transcriptId`、会话视图体顶层加性键 `agent`(消费方读法) · 没声明 `REMOTE_EXEC_HOME_DIR` 的 k8s / local-docker / ssh / adb 车道自己实测执行环境的家目录(行为变更;声明仍胜;起服 warn `execution_lane_home_undeclared` 只留给 device) · SQL 后端 workflow 续跑日志的属主 scope 搬进新表 `workflow_journal_owner`、`workflow_journal` 起服一次性按新主键重建(持久数据;🔴 先停旧副本再起新;收编回执腿名随表改) · workflow 子代的审批决定落盘:宿主会话的每一跑都带着它、同一决定重投回同一张回执(行为变更;SQL 后端起服多建一张表、整队一次切;SQL 后端配 `WORKFLOW_RUN_STORE=file|memory` 且开自编排起服拒) · 审批账本有了保留窗:结了且挂靠的东西都已终局的问安静超过 30 天就整问删掉(行为变更;要永久保留设 `APPROVAL_ASK_RETENTION_MS=0`,且要在升级后的第一次清扫之前) · 多租部署上请求 `settings.permissions.allow` 与按名点用的自带技能 `allowedTools` 按调用方信任档受理(安全,行为变更;低角色 / 不带角色的登录令牌带非空的 ⇒ `400`,能力位 `settings.permissions.callerTrust`) · 本地配置源 `config.d` 读之前判目录信任:别人改得动就拒启(安全;升级前自查权限;新旋钮 `CONFIG_LOCAL_OWNER_UID`) · 单用户记忆项目层换键形 `userrepo:<属主>/<档>.<摘要>`(带主体、跨设备;开记忆同步的部署项目层也同步;先升中心;存量项目层第一次在该项目跑任务时自动折进新键) · SQL 后端断路器键换成路由身份摘要、写新表 `breaker_state`,退役表 `circuit_breaker` 起服删掉(持久数据;无需动手) · `settings.hooks` 的 `source` / `plugin` / `args` 被读(不带且不引用插件变量零动作;托管组独立车道、跑不成即折 ask;exec 形不再被剥参数;引用不在场的插件变量的命令起不来) · 名单为空的单用户部署:审批队列不再把每个调用方当运维,要当自己的运维写一行 `OPERATOR_SINGLE_USER=true`(行为变更) · 隔离型车道(e2b / k8s / local-docker)的读面缺省 `READ_FACE` 缺席时从 `roots` 变 `open`(行为变更;把宿主目录或共享卷挂进沙箱的部署升级前写 `READ_FACE=roots`) · center 的 `allowBypassPermissions` / `allowAutoMode` 两键开始生效:组织关掉的模式由引擎折回 `default`(安全;行为变更) · 模式缺席的请求也问 `Workflow`(行为变更;要清掉这一问用 `settings.permissions.allow:["Workflow"]`) · 中心凭证换人:server 自己降到「无中心配置」档、当场拉取,`/health` 多一键 `centerIdentityNotice`(行为变更;没有 env 模型的部署在换人窗口里没有可派发模型) · 嵌入方:`StoreBackend.orgDeliveryQuota()` / `StoreBackend.checkpointReadView()` 必选(BREAKING,类型面;`orgDeliveryQuota()` 的返回型从包根导出,读口按 `StoreBackend` 成员型读) · SQL 后端收件箱里身份键过不了判官的存量行起服删掉(持久数据;无需动手)
11
+
12
+ 1. **`SANDBOX_PKG_SOURCE=custom` 的六只显式地址不得带 userinfo,带的起服拒**(安全):`SEMA_APT_MIRROR` / `SEMA_PIP_INDEX` / `SEMA_UV_INDEX` / `SEMA_UV_PY_MIRROR` /
13
+ `SEMA_NPM_REGISTRY` / `SEMA_NODE_MIRROR` 这六只地址原样写进沙箱(e2b VM / k8s pod)的环境,模型驱动的 Bash 里 `env` 读得到 —— `https://user:pass@mirror/…`
14
+ 把部署的包源凭据交给了模型。7.132.x 及以前起服无告警、凭据照交;现在起服失败,拒句点名那只 env 名,只回显 `scheme://host[:port]`(不含用户名与口令),并写出两条出路。
15
+ 无 scheme 的 `令牌:口令@host:端口` 这类不透明形、`file://` 与无 scheme 的 `host:port`、值里带反斜杠的形(`https://用户\:口令@host/…`:URL 标准把 `\` 读成 `/`,判官因此读不出 userinfo,pip 一类却读得出)
16
+ 也一并拒(这个座位只收层级式 http(s) 地址,且读法要唯一)。**只在 `SANDBOX_PKG_SOURCE=custom` 时判**
17
+ (`global` / `cn` / `none` 不注入这六只);请求面没有包源地址键。**升级前做**:
18
+ - 带凭据的地址:① 把地址改成不带凭据的形,凭据走包管理器自己的通道 —— 沙箱名单旋钮 `E2B_SANDBOX_ENV` / `K8S_SANDBOX_ENV` 点名一个令牌变量(点名即承担:沙箱里所有进程含模型都读得到),
19
+ 或把**按主机记凭据**的文件烤进镜像(npm 的 `.npmrc` 里 `//主机/:_authToken=…`、pip / uv / curl 的 `.netrc`;**别**把凭据写进 `pip.conf` 的 `index-url` ——
20
+ 注入的 `PIP_INDEX_URL` 环境变量比配置文件优先,会把它盖掉);② 源本身不需要认证就去掉 userinfo。
21
+ - `file://` / 无 scheme 地址:改成 `http(s)://host[:port]/…`。
22
+ `E2B_SANDBOX_ENV` / `K8S_SANDBOX_ENV` 点名放行的变量值不受这条影响(照旧原样交出,部署方显式承担);**例外**:名单点名的恰是这六只 `SEMA_*` 之一、
23
+ 且 profile 为 `custom` 时,读口照判环境里的值(带 userinfo 的 `SEMA_NPM_REGISTRY` 写进名单也一样起服拒)。
24
+ 2. **嵌入方(BREAKING;零别名):包根不再导出 `judgeModelRouteGap`,连同型 `ModelRouteGapReading` / `ModelRouteGapOptions`;`ModelRouteGap` 型收成缺口两词(`"endpoint_missing"` | `"lane_credential_missing"`,`"none"` 退役)。** 删即删,零别名、零过渡。
25
+ 它是 env 腿的纯判官 —— 只答「没有目录在管时,这份 env 交给引擎起不起得来」;起服的路由判官自 7.131.0 起判的是**将要服务的那张表**(目录被采纳时判目录表,env 的 `MODEL_ID` 不参与),所以它答的是起服已不再问的问题。
26
+ **谁受伤**:`import { judgeModelRouteGap } from "@sema-agent/server"` 的代码(tsc 红;已编译的 ESM 在模块加载期抛 `SyntaxError … does not provide an export named 'judgeModelRouteGap'`,命名空间导入则取到 `undefined`);对 `ModelRouteGap` 写了 `"none"` 臂的穷举 switch(该臂不再属于这个型)。
27
+ **出路二选一**:
28
+ ① 想知道**一台在跑的引擎**服务哪张模型表、目录采纳了没有、起服判官怎么说:读 `GET /v1/models` 的顶层 `modelPlane`(`servedTable` / `catalog` / 条件键 `refusalCode` + `gap`;键恒在场,见 USAGE 的模型目录段与契约 §A.1d)。
29
+ 这条是读面,**只在引擎起来之后可答** —— 起服之前没有「将要服务的表」可判,也就没有起服前的预判口(壳在引擎起来之前仍只能自己预测;引擎起来后以这一格为准,不再自判);
30
+ ② 自建装配(`loadConfig()` + 自己的配置源应用 + `createHttpServer`):在**自己的**目录应用之后调包根的 `judgeServedModelRoute(config, { envTableIsPlaceholder })`,返回 `{ code, gap, reason }` 或 `undefined`(通过)。
31
+ `GET /v1/models` 是加性改动(新键追加在应答最末),按顶层键集精确比对该体的消费方多读到一个键;零动作升级。
32
+ 3. **审批帧一条腿一个帧族(BREAKING,wire)**:`GET /v1/capabilities` 的 `streamApproval` 为真的 worker 上,工具审批只发呈卡族 ——
33
+ `approval_request`(开卡)/ `approval_complete`(单卡消卡,新帧)/ `approval_revoke`(批级撤卡);`tool_approval` / `tool_approval_complete` 不再发(bg / resume 腿账本里也没有)。
34
+ 为假的 worker 只发旧族(不变)。**消费方(壳 / SDK / 读账本的客户端)要做**:
35
+ - 按 `capabilities.approvalFrameFamilies`(闭集词数组,`("tool_approval" | "approval_request")[]`,至多一员)分派帧族,不嗅 server 版本:含 `approval_request` 时渲它,
36
+ 按 `approval_complete` 消单张卡(`outcome` / `cause` / `parked` 与旧族闭合帧同义同值)、按 `approval_revoke` 批撤;含 `tool_approval` 时走旧族;空数组 = 这台 worker 不呈审批卡。
37
+ `streamApproval` 词义不变(= 呈卡族可用),照旧可读;但 7.131.x / 7.132.0 上 `streamApproval:true` 的腿是两族并发、7.133.0 起是单族,同一个词的帧族含义随版本变,
38
+ 所以**不要再拿它反推帧族**。读不到 `approvalFrameFamilies` 键 = 7.132.x 及以前的 worker:保持旧读法(为真的腿两族并发,按 `approvalId` 去重);两族去重只在读得到该键的 worker 上才可以去掉。
39
+ - 此前只从 `tool_approval` 读的十位(`mandated` / `mandate` / `origin` / `boundGrantDigest` / `boundGrants` / `classifierNoRuling` / `boundGrantAbsence` / `approvalCard` /
40
+ `readRootCandidate` / `probeReason`)改读 `approval_request` 顶层,同名同值;只在活铸的帧上,断连重放帧上缺席(与旧帧一样)。`requiresRealApproval` 读 `card.risk.requiresRealApproval`。
41
+ - 应答口不变(`POST /v1/tool-approvals/:id/respond` 用呈卡帧的 `approvalId`;`POST /v1/tasks/:taskId/asks/:askId/decision` 用 `askId`)。
42
+ - 一时还不能消费呈卡族的接入方:该 worker 显式 `STREAM_APPROVAL_ENABLED=false`(呈卡协议整体不上场,`streamApproval` 读作假,`approvalFrameFamilies` 读作 `["tool_approval"]`,只发旧族)。
43
+ 运维:日志 `approver_unavailable` 的 `arm` 词 `unreached_no_row` 改名 `no_row_no_presenter`,按旧词过滤的告警改词。
44
+ 4. **请求体不是合法 JSON ⇒ 恒答 `400 request.invalid_json`(体带 `reason:"not_json"`);读体撞帽 ⇒ 恒答 `413 request.payload_too_large`(BREAKING,wire 码 / 状态码变更)。** 全仓只有一只请求体读取器,它此前抛的是无码的 `HttpError(400)`:
45
+ 没有自己 catch 的口(提交口 `POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs`、steer / interrupt / compact 与各决定口、规则 / 记忆 / 能力探测 / 排空等管理口 …)的坏 JSON 体表面是
46
+ `request.rejected`(状态派生的粗码);另有一批口(leader 提交、设备、保留、领养、会话策略 `PUT`、同步 push / plan、workflow steer)在本地 catch 里自铸 `request.invalid_json`,并把读取器的
47
+ **413 一并折成这个 400**(一份 9 MiB 的合法 JSON 被报「JSON 非法」);`notify` / `wake` / 权限规则三口则在本地 catch 里把坏 JSON **和** 413 都说成 `400 request.body_shape`(句子 `body must be JSON: …` / `body must be valid JSON`)。现在读取器铸这个码(句子 `invalid JSON body` 不变),本地铸点全部删除,各口同一个体
48
+ `{ error, errorCode: "request.invalid_json", reason: "not_json" }`;超 8 MiB 在所有口答 `413`,体带 `field:"body"` / `reason:"too_large"` / `cap`(没有 `count`:体没读完,量不出送来多少)。
49
+ `POST /v1/runs/:id/compact` 收到合法 JSON 的非对象体,码不变、体多 `reason:"not_object"`。
50
+ **谁受伤**:① 按 `errorCode === "request.rejected"` 识别「坏 JSON」的客户端(这一形现在是 `request.invalid_json`;`request.rejected` 回到它的本义 —— 无自带码的 400),或在 `notify` / `wake` / 权限规则三口上按 `request.body_shape` 识别坏 JSON 的客户端(现在也是 `request.invalid_json`;`request.body_shape` 只剩「JSON 合法、形不对」);
51
+ ② 在 leader / 设备 / 保留 / 领养 / 会话策略 / 同步 / workflow steer / `notify` / `wake` / 权限规则这批口上把超限体当 `400` 处理的客户端(现在是 `413`)。
52
+ **出路**:坏 JSON 按 `errorCode === "request.invalid_json"`(想区分「不是 JSON」与「不是对象」读 `reason`)判;体超限按 `413` / `request.payload_too_large` + `field` / `reason` / `cap` 判。状态码对前一类不变(400),只有后一批口的超限状态码变了(400 → 413)。
53
+ 5. **`REMOTE_EXEC=device`:四根数值旋钮越界起服拒启;协议修订号抬到 2(结局码集随修订号)**:
54
+ - **升级前检查部署 env**:`DEVICE_RECONNECT_GRACE_MS` ∈ `[0, 2147483647]`、`DEVICE_DELIVERY_TIMEOUT_MS` ∈ `[0, 2147483647]`、`DEVICE_EXEC_TIMEOUT_MS` ∈ `[1, 2147483647]`、
55
+ `DEVICE_MAX_INFLIGHT_PER_DEVICE` ≥ 1,且都必须是规范十进制整数串(无符号 / 前导零 / 小数点 / 指数 / 十六进制 / 空白 / 单位;此前收任何有限数:分数 / 负数 / `0` 的在途上限 / `04` / `1e3` / `0x10` 都起得来,原样下发给 executor)。越界或奇形 ⇒ 起服拒启,
56
+ 拒句点名旋钮与合法域;去掉旋钮即回缺省(120000 / 10000 / 1800000 / 4)。未设与空串(compose `${X:-}` 透传)不变。
57
+ - **嵌入方**:`createDeviceWsHub` 的 `heartbeatIntervalMs`(≥ 1)/ `maxInflightPerDevice`(≥ 1)/ `reconnectGraceMs` / `cancelGraceMs` / `chunkGapTimeoutMs` / `execGraceMs`(都 `[0, 2147483647]`)
58
+ 越界时创建汇聚端即抛(此前原样用);config 的 `remoteExec`(device 臂)里的 `reconnectGraceMs` / `maxInflightPerDevice` 经装配进同一道检查。`deliveryTimeoutMs` / `execTimeoutMs` 的界只在 env 解析处判。
59
+ - **executor(cli / 第三方)**:`challenge.protocolVersion` 与 `GET /v1/capabilities` 的 `deviceExecutor.protocolVersion` 现为 `2`;hello 的 `protocolVersion` 取「自己实现的最高修订号与 challenge 的较小者」,
60
+ 只发该修订号的 `errorCode` 词(修订号 2 起含 `liveness_no_output`;`@sema-agent/server/device-protocol` 的 `deviceOutcomeErrorCodesAt(revision)` 给集合,表见随包 `docs/DEVICE-EXECUTOR-PROTOCOL.md` §2.1);
61
+ 受理窗 `[1, 2]`,不升级的老 executor 照连。helloAck 的数值位恒在界(协议文档 §1.5):读到越界值 ⇒ 当协议违例关连接,不读成缺省。
62
+ 6. **acceptEdits 的免问写域改为引擎的写根;沙箱车道上 acceptEdits 不再等同 `default`**(行为变更):本服务自己给 acceptEdits 装的那只写门(免问域只认会话工作目录)删除,
63
+ acceptEdits 能免问写哪里只由引擎答 —— 写根(任务根 + 请求的 `additionalDirectories`)内的写免问,写根外照问。变化落在三处:host 车道写 `additionalDirectories` 不再出卡;
64
+ host 车道没登记工作目录时任务根内的写不再出卡;沙箱车道(e2b / k8s / ssh / adb / local-docker)上任务根内的写不再出卡(此前与 `default` 一样每次都问)。
65
+ **要保留「每次写都问」的部署做**:设 `APPROVAL_REQUIRE=Write,Edit,NotebookEdit`(人写的 ask 规则,任何模式都放不掉、会话放行照样可用;名单门要耐久审批在场 —— `DURABLE_APPROVAL=true` + 有检查点面的后端),或让请求方改发 `permissionMode: "default"`。
66
+ 写根外的写照问(不变);请求与部署的 `deny` / `ask` 规则、`SENSITIVE_WRITE_PATTERNS` 守卫集不受影响。
67
+ 7. **审批的列表面与身份同律(BREAKING,wire 值变更;`streamApproval` 为真的 worker)**:
68
+ - `GET /v1/approvals` 的 `livePending[].frame` 与 `/v1/approvals/stream` 的 `live_pending` 帧里的 `frame` 改成 `approval_request` 帧(卡内事实在 `card`,卡外事实在帧顶层);
69
+ **从这一格读旧族键(`frame.args` / `frame.message` / `frame.ruleOffers` / `frame.inputHasBidi` ……)的消费方改读 `frame.card.*`**,按 `frame.type` 判别(旧族 worker 上照旧是 `tool_approval`)。
70
+ - `approvalId` = ask 行的键 `askId`(64 位十六进制串,不再是 uuid;本就不透明,把它当 uuid 解析的代码要改)。同一只 ask 列表一行。
71
+ - 对一只已决的卡再应答(重试 / 别处已决 / 本副本的残留登记 CAS 输)从 `404 tool_approval.not_pending` 改为 **`200 idempotent:true` 回放首决**(按回体的 `decision` 渲);
72
+ 停驻卡在别的副本 / 重启之后按 Yes 照样受理。把「再应答 = 404」当作「卡已消失」信号的消费方改读回体。
73
+ 运维:计数 `server.approval.park-tombstone-global-cap-refused` 改名 `server.approval.park-redemption-cap-refused`(按旧名的看板改名)。
74
+ 8. **委派子代的会话只对发起它的主体可读:无主的委派子代行不对具名主体放行,SQL 后端每次起服回填存量子代行的属主(安全)**:7.132.x 及以前,`DB_BACKEND=mysql` / `pg`
75
+ 为委派子代建的会话行没有属主,而会话面对无主行放行 —— 拿到子代会话 id(子代帧上的 `transcriptId`)的任何主体都读得到整段子代转录。本版起写下那一行的那一笔写入
76
+ **铸行那一刻委派树根会话的属主**(判断时读到的;判断之后根会话被删、同 id 重新登记不改变写进去的值);**属主为空的委派子代行只对 fleet 调用方放行**
77
+ (出示 service 凭据、不带主体头的调用方;dev-open 照旧),任何具名主体、没有 service 凭据的无身份调用方答 `404 not_found.session`(与不存在同体)——
78
+ fork / 删除对 `default` 主的存量无主会话互认、审批豁免的列表 / 撤销、外部 notify 对这些行同样不放行;**存量行每次起服回填**(窗内):
79
+ - 根会话的行在 ⇒ 写它的属主(根会话无主 ⇒ 子代仍无主,不写);根行已不在 ⇒ 写**它记录的**父会话的;两者都已不在 ⇒ 写一只任何调用方都不可能匹配的 `_orphan:<会话 id>`(它下面的子代继承同一只);
80
+ - 起服读数行多三键 `placedSessionOwnersInherited` / `placedSessionOwnersOrphaned` / `placedSessionOwnersRemaining`;孤行非零另打一行 warn `placed_session_owners_orphaned`(点名条数,两种成因分开说)。
81
+ 每次起服**扫一趟**、按原文条件写,写成的第二次起服不再命中;`placedSessionOwnersRemaining` = 这一趟判不出的行(它读到的父会话本身还是一只待回填的子代行),读数行因此是 warn,
82
+ **不拒启**:它们只对 fleet 调用方放行,之后的起服(或它们下一次停驻)按同一条律补上 —— 一次起服至少再定下一层,层层待回填的链要多起几次,读数逐次变小。
83
+ 滚动升级里旧副本在窗内新建的无主子代行同样由之后的起服补上。
84
+ 扫到会话住客记号为空的子代行 ⇒ 起服拒(与全仓「读到空住客记号」同一条律)。窗 = 本版发布日 + 30 天,之后的 minor 删回填码 —— **至少起一次本版**再越过它升级。
85
+ **升级前做**:`DB_BACKEND=local` 且带身份(中心鉴权桥 / 主体头)的部署,先把停驻待批的子代审批处理完 —— 升级前停驻的子代在宿主店里的那一行无主,升级后被批准、
86
+ 复活后再次需要审批时属主对不上,停驻被否决、那一只子代以失败收尾。**升级后看**:`placed_session_owners_orphaned` 那一行 —— 被写成 `_orphan:` 的子代转录只有 fleet-wide / operator 面读得到;要让某位主体读,
87
+ 在会话店里把那一行的 `owner` 改成该主体(`session_meta.owner`);`placedSessionOwnersRemaining` 非零 ⇒ 再起,直到它为 0(或等那些子代下一次停驻)。**拿另一位主体的身份读子代转录的集成**:读面现在答 `404 not_found.session`
88
+ (与不存在同体),改用发起子代的主体读;根会话本就无主的子代转录(无身份调用方的委派树)只有 fleet 调用方读得到 —— 没配 service 凭据、又不是 dev-open 的部署上,
89
+ 给它配 service 凭据(或身份来源)再读。
90
+ `_orphan:` 进保留主体前缀:身份来源报出以它开头的主体 ⇒ `400 principal_reserved`(哪位租户的主体名恰以 `_orphan:` 开头,升级后它的请求被拒,先给它换名)。
91
+ `DB_BACKEND=local`:不涉及回填(子代住私店);停驻时拷进宿主店的子代行本版起带委派树根会话的属主(这一处只按根判:拷进去那一刻根会话已不在 ⇒ `_orphan:`),升级前拷进去的那些仍无主
92
+ (local 后端不记委派树,不补;它们再次停驻时按上面「升级前做」那一形被否决)。local 后端的子代转录行是普通的有主会话行
93
+ (属主的会话列表里列得出、能 `PATCH`、能经 `/sync` 整段换装);「不进列表 / `PATCH` 404 / 换装被拒」只对 SQL 后端的子代行成立。
94
+ 9. **嵌入方(自建 `ServiceDeps` 的进程):`snapshotBlobSqlCap` 读口退役(BREAKING;零别名)**:包根导出型 `ServiceKnobDeps` 少一个座 —— 7.132.0 的 `snapshotBlobSqlCap`(`() => { capBytes, source } | undefined`,7.131.x 数字键 `snapshotBlobSqlCapBytes` 的换形,见 7.132.0 节第 59 条)
95
+ 删了。原因:SQL 快照 blob 的帽依赖语句上限 `max_allowed_packet`,它是**连接的会话值**,只有将要执行写入的那条连接自己说得准;HTTP 面手里没有那条连接,它的前置判读的是池级读数,
96
+ 与店的判决会在库调墙后的过渡窗口里分歧。现在 `PUT /v1/sessions/:id/sync/blobs/:hash` 的 `413 blob_too_large_for_sql` 来自店在写入连接上的判决(码、状态与体上的 `wallSource` 不变,句子仍是 7.132.0 的三形)。
97
+ **谁受伤**:① 传了 `snapshotBlobSqlCap` 的 TypeScript 嵌入方(tsc 红);② JS 嵌入方 / 类型之外的装配照传 ⇒ **起服拒**(`createHttpServer` 装配期;起服拒句点名键、退役版本与出路,退役的座不静默忽略;7.132.0 退的 `snapshotBlobSqlCapBytes` / `sqlEngineFacts` 两个旧键同一张表同一只判官,放在 `knobs` 组里的同样拒;值是 `undefined` 不算传);
98
+ ③ 自建 `fileHistoryStore`(不是本仓的 `TiDBFileHistoryStore` / `PgFileHistoryStore`)又靠这个读口拿 413 的:读口没了 ⇒ 超帽的 blob 回到店的既有失败面(`putBlob` 的 `ok:false` ⇒ 502,对端会重试)。
99
+ **出路**:要固定帽 ⇒ 设 `SNAPSHOT_BLOB_SQL_MAX_BYTES`(店的显式旋钮,两方言都生效;机读位 `wallSource: "operator"`);自建店 ⇒ 让 `putBlob` 超帽时交回
100
+ `{ ok: false, error: { code: "blob_too_large_for_sql", message, wallSource } }`(`wallSource` ∈ `"operator"` | `"reported"` | `"assumed"`),路由据此答 413 并原样转出 `message` 与 `wallSource`;
101
+ `message` 可以直接用包根导出的 `BlobTooLargeError` 的句子。`sqlEngine`(引擎读口)座不变 —— 提交受理口的墙仍读它(SQL 后端在场 ⇒ 必填,7.132.0 节第 61 条的要求不变)。
102
+ 10. **子代转录的读法(消费方;加性,无需升级动作)**:终端侧链投影方按 fleet 帧(`bg_notification` 终态帧,或 `task` 行)上的 `transcriptId` 读子代整段 —— **只有一只读口,同一会话读面**,没有 `/v1/subagents/…` 一类的端点:
103
+ - **读**:用**发起委派的那位主体**调 `GET /v1/sessions/<transcriptId>`(视图;未压缩过的子代 `messages[0]` 的用户消息带委派 prompt,压缩过的子代视图是压缩后的当前窗;子代跑过的工具是 assistant 消息里的
104
+ `toolCall` 段 + 同 `toolCallId` 的 `toolResult` 行)与 `GET /v1/sessions/<transcriptId>/sync/entries`(整段存档逐条,含停驻那一拍的占位 `toolResult` 与复活后的真结果);视图口上别的主体读到
105
+ `404 not_found.session`,与不存在的 id 同体(`/sync/*` 对带 service 凭据的调用方另说,见最后一条)。
106
+ - **子代是哪只**:视图体顶层新 additive 键 `agent: { id?, parentSessionId?, rootSessionId? }` —— `id` 与 fleet 行的 `id`、`GET /v1/agents/roster` 的 `handle` 同一个串。**键缺席**有三种成因,一律按「这台 server 没有存」读,
107
+ 回落 fleet 行 / `GET /v1/agents/roster` 的 `handle`:老 server(≤ 7.132.x,没有此键)· 普通会话 · local 后端(不存委派元组)。不要把缺席读成「不是子代」。
108
+ - **范围**:SQL 后端上只有**后台**委派子代有会话元组(会话是宿主店里的 placed 行);同步委派的子代转录不落宿主店,没有元组。
109
+ - **local 后端的两处差别(如实)**:不停驻直接收尾的子代,转录一直住私有短 TTL 店,视图与 `/sync/entries` 都读不到(404,发起它的主体也一样)—— 要读它的整段,等 local 声明 placements 或改用 SQL 后端;
110
+ 撞审批门停驻的子代,拷进宿主店之后读得到(视图 200、无 `agent` 键);拷贝落下之前(待批卡先于拷贝可见的那一小段)属主读也是 404,稍后重读即 200。
111
+ - **带 service 凭据的调用方**:视图口按它的主体头判(没带主体头 ⇒ 404);`/sync/*` 把带凭据的调用方读成 fleet-wide,任何主体头都读得到 —— 与会话视图是两只判据,现状如此,不在本条。
112
+ sdk 的会话视图类型目前没有 `agent` 字段(待 sdk 同步补可选键);自己按白名单解析会话视图体的消费方放行这一个键。
113
+ 11. **没声明 `REMOTE_EXEC_HOME_DIR` 的 k8s / local-docker / ssh / adb 车道:执行环境开起来那一拍自己读一次 `$HOME`、填引擎的家目录座(行为变更;k8s 部署升级前核一遍声明)**:此前这四条车道不声明家目录就恒不知道它,
114
+ 引擎的家锚拒读行放不下,每一次泄内容的递归读(`grep -r` / `rg` / `git grep` / `tar c`)在全 shell 面恒问人、只读面直接拒。现在取值律是:**声明在场 ⇒ 声明(原样);否则 ⇒ 车道建环境时实测的 `$HOME`(绝对路径才收);实测也缺席 ⇒ 座缺席(与此前一致)**。
115
+ 声明在场时:local-docker / ssh 的行为一个字没变(本来就把声明与 `$HOME` 对证);**k8s 现在也对证**(同一只判官、同一句拒;**行为变更**:此前照单全收)—— `REMOTE_EXEC_HOME_DIR` 与 pod 里的 `$HOME` 不一致(去掉尾斜杠后逐字比)、或 `$HOME` 读不出绝对路径时,那只 pod 不开(`connect_failed`,拒句点名两个值与改法),
116
+ adb 仍照单全收。**升级前对 k8s 部署核一遍**:在镜像里跑 `printf %s "$HOME"`,与声明值比;对不上的按拒句改声明(或让镜像以声明的用户运行)。**谁受影响**:① 此前为了消掉起服 warn 而手填了 `REMOTE_EXEC_HOME_DIR` 的部署 —— 不必改,声明仍胜;想让车道自己测就删掉它,**但**用了 `~/` 形权限规则的部署必须保留声明:
117
+ `~/` 形规则的下单门与规则基仍只认声明(提交任务那一刻执行环境还没开),没声明 ⇒ 照旧 `422`;② 按起服行 `execution_lane_home_undeclared` 配了告警的运维 —— 这一行现在只在 device 车道起服时响;k8s / local-docker / ssh / adb 没声明时起服不再响,
118
+ 改成**某只环境实测缺席时**响同一只事件码(字段仍是 `provider` + `note`,note 点名读到了什么;同一部署同一句只响一次),把告警条件从「起服出现」改成「运行期出现」;③ 没声明的部署上引擎对这四条车道的家锚拒读行落位变了
119
+ (由「没有家目录时在任何位置按路径段判」落到实测的家目录下,并另锚引擎宿主的账户家、每条 run 的落位多一次经该车道 `canonicalPath` 的账户家探针,上限 2 s —— 引擎对「声明了家」的远端车道的既有口径,见部署前置文档(仓库 docs 目录下 DEPLOY-PREREQS)该节;本版未在真集群上实测)。
120
+ **做法**:k8s 部署核声明与镜像用户的 `$HOME`(上一段);其余无需动手;想看到实测值是否生效,看运行期是否出现 `execution_lane_home_undeclared`(出现 = 那只环境的 `$HOME` 读不出绝对路径:修环境的 `HOME`,adb 上也可以声明;k8s / local-docker / ssh 上声明替代不了一个读不出的 `$HOME`,会被拒)。
121
+ 12. **SQL 后端(`DB_BACKEND=mysql` / `pg`):workflow 续跑日志(journal)的属主 scope 搬进新表 `workflow_journal_owner`,`workflow_journal` 起服一次性按新主键重建(持久数据;🔴 先停旧副本再起新)**:
122
+ 7.132.x 及以前 scope 是 journal **每一行**上的一列,读面按它判、写面不判(别的 scope 能往一条 run 里写)。本版起一条 run 的属主 scope 只记在 `workflow_journal_owner` 一行(主键 `run_id`,
123
+ 这条 run 的第一次 append 认领,带认领时铸的令牌 `incarnation`);journal 行改带写下它的那只记录的令牌,主键 `(run_id, incarnation, ordinal)`,店的写面与读面都经属主记录判;
124
+ 别的 scope 的 append 被拒(`workflow journal: runId <id> already recorded under a different scope — refusing the append; nothing was written`),什么都不写。
125
+ - **自动(起服,一次性)**:`workflow_journal` 上 scope 列在场 ⇒ ① 每条 run 回填一行属主(scope = 该 run 最小序数那一行的;属主行的回收时钟 = 该 run 最晚一行的时刻)② 照新形建暂存表
126
+ `workflow_journal_m24`,按主键分批(每批的结果字节有界、各自提交)搬与属主同 scope 的行(带属主令牌)③ 原子换名(旧表改名 `workflow_journal_m24_old` 后删掉)—— scope ≠ 属主的行(旧写面放进别人 run 里的写)不搬,
127
+ 写它们的 scope 续跑时那几步改为活跑。起服读数行 `one_time_migrations_applied` 多三键:`workflowJournalScopeColumn: "moved"`(第二次起是 `current`)/
128
+ `workflowJournalOwnersBackfilled` / `workflowJournalForeignScopeRowsRemoved`;丢了行另有一行 warn `workflow_journal_foreign_scope_rows_removed`(条数)。换名之前任何一步被打断,旧表原样、
129
+ 下一次起服从头重来(残留的暂存表删掉重建,属主只补缺的);库里看到 `workflow_journal_m24` / `workflow_journal_m24_old` 而服务没在起动 = 上一次迁移被打断,起一次服就收掉。
130
+ - **升级顺序**:**先停 7.132.x 副本,再起本版** —— 换名之后,仍在跑的旧副本的 journal 读写点名不存在的列而失败(那一刻在跑的 workflow 那一步失败;旧二进制起服被列集对账拒启);
131
+ 复制与换名之间旧副本写进旧表的行随旧表删掉(那几步续跑时活跑)。
132
+ - **直接查这张表的运维 SQL**:`SELECT … FROM workflow_journal WHERE run_id = ? AND scope = ?` 改成 `SELECT … FROM workflow_journal JOIN workflow_journal_owner USING (run_id, incarnation) WHERE run_id = ? AND scope = ?`;
133
+ 按 scope 列 run 的改查 `workflow_journal_owner`(一行一条 run)。
134
+ - **收编(form b)回执**:`legs[].store` 的 `workflow_journal#scope` 换成 `workflow_journal_owner#scope`(腿标识 = 表名#列名);按旧名对账的消费方改读新名,改绑语义不变(与 run 行同事务)。
135
+ - **窗**:本版发布日 + 30 天,之后的 minor 删迁移码 —— **至少起一次本版**再越过它升级;跳过本版直接升的库(`workflow_journal` 上仍有 scope 列、没有 `incarnation` 列)被起服列集对账拒启(`config.schema_mismatch`,点名两列)。
136
+ - `DB_BACKEND=local`:不涉及(journal 是引擎的文件店,一条 run 的属主就是它的 journal 文件首行,一直只记在一处、一直拒别的 scope 的写)。
137
+
138
+ 13. **workflow 子代的审批决定落盘(行为变更;SQL 后端起服多建一张表;SQL 后端配 `WORKFLOW_RUN_STORE=file|memory` 且开自编排起服拒)**:决一张 workflow 子代卡,投递那一跑开跑之前决定写进部署的店,宿主会话之后的每一跑都带着它,直到引擎用掉它或卡到期。
139
+ - 🔴 **要动手的一种部署**:`DB_BACKEND=mysql` / `pg` + `SELF_ORCHESTRATION_ENABLED` + `WORKFLOW_RUN_STORE=file` 或 `memory` ⇒ 本版**起服拒**,读完配置即拒、在一次性迁移之前(那一次起服不动库,
140
+ 改完配置直接再起):决定行写在会话认领的同一个原子步骤里,认领在库里,决定行就得在同一个库里,而库里的决定行随库里的 workflow 记录收割 —— workflow 记录不在库里时没有一只店两头都满足。
141
+ 出路二选一:去掉 `WORKFLOW_RUN_STORE`(缺省 `auto` = 有 SQL 用 SQL,workflow 记录进同一只库),或关掉自编排(`SELF_ORCHESTRATION_ENABLED=false`)。这一形本来只在单机上通(park 指针按箱存,多副本上 `/decide` 路由不到)。
142
+ 嵌入方:`runStore` 与 `workflowParkDecisions` 从同一只 store backend 取(`run()` / `workflowParkDecisions()`,两只都无参、恒交同一只);决定店绑的不是 `runStore` 这一只、漏了这一座、
143
+ 或没装 workflow park 车道却给了决定店 ⇒ 起服拒。local 后端的账本由后端自己放:`<数据根>/workflows/workflow-park-decisions/decisions.jsonl`;`WORKFLOW_RUN_STORE=memory` ⇒ 纯内存,重启即失。
144
+ - **建表**:`DB_BACKEND=mysql` / `pg` 起服时由中央建表语句建 `workflow_park_decision`(加法 DDL,不改写任何存量行);local 车道是数据根下 `workflows/workflow-park-decisions/decisions.jsonl`。无需动手。
145
+ - **消费方**:同一决定重投,在投递的那一跑结束之前回同一张回执(不再起一跑),结束之后再投递一次;另一个决定在宿主会话有一跑在跑时答既有的 `409 conflict.session_active_run`,
146
+ 没有时受理并取代前一个。投递被拒(会话忙 / 配额 / 会话的续跑输入已被回收)时拒体与此前相同,什么都没有记下。决定没落成(部署的店写不进,或投递那一跑在落盘那一拍已不占着宿主会话 ——
147
+ 它的心跳停满 `REAP_RUN_STALE_SEC` 被收走)⇒ `500`,那一跑不开,重投即可;续上宿主停驻(wake)那一形里引擎已认领掉那张停驻,重投改在宿主会话上新起一跑 ——
148
+ 宿主会话空闲超过 `REAP_RUN_STALE_SEC` 时那一形答既有的 `409 conflict.resume_context_unavailable`(去续跑那条 workflow run)。
149
+ 取消落在落盘进行中、落盘随后成功:wake 那一形答那一跑的取消终局;新起一跑那一形答照常的 200 受理回执,那一跑开跑后最多 30 秒被叫停。没有新的错误码。
150
+ - **运维**:fail-open 计数 `server.workflow-park-index.sync-failed` 退役(按它配的告警可删);park 指针写失败现在表现为那次 workflow run 记录写失败(引擎的 run 日志一行),不再是「记录照写、指针缺」。
151
+ 新计数 `server.workflow-park-decision.card-unreadable`:某一跑开跑时读不出一条已受理决定的那张卡 ⇒ 这一跑不带它(下一跑照带)。
152
+ 新计数 `server.workflow-park-decision.store-unreadable`:开跑时决定店读不出(local 账本中间有一行读不出 / SQL 这个会话某一行决定体坏)⇒ 这一跑不带这个会话已受理的决定,照常起跑。
153
+ local 车道决定账本中间有一行读不出 ⇒ 决 workflow 子代卡被拒(`workflow_park_decisions_corrupt_read`),直到有人处理那只文件;起跑不受牵连(不带账本里的决定)。移开它再重启是安全的(其中已受理的决定对应的卡仍待批,可再决)。
154
+ - **SQL 多副本整队一次切**:混跑窗里 7.132.x 副本不读决定行(在它上面起的宿主跑不带已受理的决定,与升级前同),也不写(在它上面受理的决定只活在那一跑里)。先停光 7.132.x 再起本版即无此窗。
155
+ - **回滚到 7.132.x**:表留着无害(旧版不读它);回滚后已受理、未用掉的决定不再随宿主跑走 —— 回到升级前的行为(卡仍待批,重新决即可)。
156
+ 14. **审批账本有了保留窗:结了的问安静超过 `APPROVAL_ASK_RETENTION_MS`(缺省 30 天)就从三本账里整问删掉(行为变更)**:此前 SQL 车道的 `approval_ask` / `approval_batch` 两张表、
157
+ local 车道的问账 `approval-asks/asks.jsonl` 与审计账 `approval-ask-audit/ledger.jsonl` 都只增不删。现在维护 tick 首拍即清扫一次、之后每小时至多一次:终态且不是 provisional 的问行、
158
+ 问走光了的批行、以及审计账里不再欠起服收敛答案的问,最后一次动静早于 `now − APPROVAL_ASK_RETENTION_MS` 的整问删掉;没结的问(`STREAM_PENDING` / `PARKING`、活卡、批了但腿还没闭)多老都不删,
159
+ 发起它的 run、宿主会话或发问那条腿的会话还挂着在跑 / 停驻的 run、后台子代或待决 checkpoint 的问也不删(每次清扫先从 run 账、后台子代账与 checkpoint 店列出这些东西);
160
+ 审计账留下的行逐字节不变。起服日志一行 `approval_ask_retention`(生效窗或关),真删了东西时一行 `approval_ask_retention_swept`(带各账删掉的数)。**谁受影响**:① 把审批账本当永久取证记录的部署;
161
+ ② run 结束超过窗之后才对它的卡作答的客户端:决断口与流内审批口答 404(此前回放首决 / 答 409、410);③ local 部署删过问行之后再降级到
162
+ 不认问账动词 `reapSettledAsks` / `reapEmptyBatches` 的旧版本,local 问账起服拒启(拒句点名出路)。**做法**:要永久保留 ⇒ 升级时同时设 `APPROVAL_ASK_RETENTION_MS=0`(首拍即扫,事后再设已经删掉的回不来);
163
+ 要别的窗 ⇒ 设毫秒数(正值低于 1 天钳到 1 天并在启动告警里点名;负值 / 非整数拒启);其余部署零动作。
164
+ 15. **多租部署(`REQUIRE_PRINCIPAL=true`):请求体 `settings.permissions.allow` 按调用方的信任档受理(安全;行为变更)**:档只由这次请求验过的凭据推 —— 部署的 service 凭据 ⇒ `global`;
165
+ 中心登录令牌在活动 scope 里的角色 ≥ 治理写角色(settings-schema `domainWriteRole("governance")`,今天 `editor`)⇒ `global`;角色更低 / 令牌不带角色 / 直连门 principal 令牌 / 没有验过的凭据 ⇒ `project`。
166
+ `allow` 要 `global`(settings-schema 成员阶梯),所以 `project` 档的调用方带非空 `allow`、或用 `userInvokedSkills` 按名点用带 `allowedTools` 的自带技能(不出 `Skill` 卡,同一成员的孪生)⇒ `400 request.field_invalid`(`detail.problems[].reason: "below_trust_floor"`、`detail.callerTrust`);`deny` / `ask` 照收。
167
+ 单用户 turnkey 与持 service 凭据的前端零变化。**谁要动手**:让 scope 里 `viewer`(或拿不带角色的令牌)直连提交、又靠请求体 `allow` 免问的部署 —— 三选一:scope 管理员把这些成员抬到 `editor` 或以上;
168
+ 把规则放进运维的 `APPROVAL_GRANT`(部署级);或让这些调用方去掉 `allow`、开跑时答卡(点用的技能从 `userInvokedSkills` 拿掉,模型仍可在 `Skill` 卡后激活它)。**壳 / 客户端**:提交前读 `GET /v1/capabilities` 的 `settings.permissions.callerTrust`(按调用方;缺席 = 老 server,
169
+ 不按档受理),把契约 floor 高于它的成员留在本地同意出口、不上 wire;收到上面这只 400 时按 `detail.problems` 逐条提示,不解析句子。升级前已受理、仍在停驻的任务照旧续跑。
170
+
171
+ 16. **本地配置源(HTTP 服务设了 `CONFIG_PROVIDER=local`;`run-local` 与壳起的本机引擎恒是):`config.d` 读之前判目录信任,别人改得动就拒启(安全;升级前自查一遍)**:
172
+ 从 `/` 走到 `config.d`、再到读者会读的每一份文档(链接照跟),路径上每一级的属主只能是本服务的用户、root 或 `CONFIG_LOCAL_OWNER_UID` 声明的那一个 uid,且不得组 / 他人可写
173
+ (属主可信的粘滞目录如 `/tmp` 除外 —— 但要读的一项缺在这样的开放目录里同样拒,别人能先建出来);文档必须是常规文件且 ≤ 16 MiB;链接合计 ≤ 40 跳、不得指向 procfs 一类内核对象。
174
+ 7.132.x 及以前不判。配置根直接放在 `/tmp` 下的,先把根与 `config.d` 建好(属于服务用户),否则起服拒。升级前在服务用户下跑一遍(`<根>` = `CONFIG_LOCAL_DIR`,没设则 `AGENT_DATA_DIR`,再没设则 `~/.ai-agent`):
175
+ ```sh
176
+ find "<根>/config.d" \( -perm -g+w -o -perm -o+w \) ! -type l -print # 有输出 ⇒ 对每一行 chmod go-w
177
+ find "<根>/config.d" ! -user "$(id -u)" ! -user 0 -print # 有输出 ⇒ chown,或设 CONFIG_LOCAL_OWNER_UID=<那个 uid>
178
+ d="<根>/config.d"; while [ "$d" != / ]; do ls -ld "$d"; d=$(dirname "$d"); done # 每一级:属主是你或 root,且无 g/o 写位(粘滞目录 t 除外)
179
+ ```
180
+ Debian / Ubuntu 的用户私有组 + umask 002 会建出 0775 目录 —— 本版起即拒启,`chmod go-w` 即可。userns-remap 容器 bind-mount 的配置在容器里常呈现为 uid 65534:设 `CONFIG_LOCAL_OWNER_UID=65534`
181
+ 或在镜像 / initContainer 里改属主;rootless 容器里宿主用户映射为容器 root,零动作;k8s ConfigMap 卷挂成 `config.d`(或挂在它上面一级)零动作 ——
182
+ kubelet 把卷根建成 0777,判官认这一形:卷根下只有 kubelet 的链接农场(`..data` / `..<时间戳>/` / `<键> -> ..data/<键>`)、属主 root、它是一只只读挂载的 kubelet ConfigMap 卷
183
+ (本进程 `/proc/self/mountinfo` 里那只挂载带 `ro`、来源是 kubelet 的 configMap 卷目录),且来源没有经可写挂载露在本服务的挂载命名空间里(露出来 ⇒ 拒,拒句点名那条路径与那只挂载;
184
+ hostPath 挂了节点目录的 pod 即此形 —— 撤掉拒句点名的那只可写挂载:别把节点根 / kubelet 数据目录或它的任何祖先可写挂进 pod,配置用 `subPath` 或不挂那个祖先;别去放宽节点上 kubelet 目录的权限;
185
+ 只读挂载盖住的露出不算,但祖先的只读挂载不递归 —— 它下面单独挂进来的可写文件系统照样露出、照样拒);认它时每个进程一行 fail-open 告警(`server.config-dir-trust.kubelet-volume-node-side-unverifiable`:来源在节点那一侧的目录本服务看不见),不是错误。这条认臂取决于容器里 `/proc/self/mountinfo` 那一行的形,**未在真集群实测**;读到的形与上面所述不符 ⇒ 该部署照旧起服拒(失效关闭,不会静默放行)。
186
+ `defaultMode` 别给组 / 他人写位(那会让 `..<时间戳>/` 里的文档可写 ⇒ 拒)。
187
+ **Secret / projected / downwardAPI 卷**(内存介质,mountinfo 里认不出来源)、把卷挂成可写、往卷根里另放文件、或把一只普通目录只读 bind 进来的形都不认,照拒 —— 改用 `subPath` 逐文件挂或烤进镜像;
188
+ 挂了 `fsGroup` 的 emptyDir 是组可写的 ⇒ 拒,改用 ConfigMap 或在 initContainer 里 `chmod go-w`。
189
+ 拒的样子:起服 fatal 标题带 `[config.dir_untrusted]`(`run-local` 退 2),句子点名那一个路径、实测值与改法;起服之后才变坏的 ⇒ 每一拍 `web_admin_refresh_failed` 带同一句,已应用的配置不动。
190
+ Windows 上属主与模式位不可判:只判结构,另有一次 fail-open 告警(`server.config-dir-trust.win32-owner-mode-unverifiable`),零动作。中心配置源(舰队形)不读 `config.d`,零动作。回滚:零动作(旧版不判)。
191
+ 17. **单用户记忆的项目层换键形,开了记忆同步的部署项目层也同步了(键值变、形不变;先升中心)**:项目层键从 `repo:<24 hex>`(本机项目根路径的哈希,不带主体)换成
192
+ `userrepo:<属主段>/<档>.<24 hex>` —— 属主 = 全局层(`MEMORY_SCOPE`,run-local 是 `--user`,缺省 `local`)的属主(`user:<P>` 取 P,其余取名字本身);档 `r` = 仓库 `origin` 远端
193
+ URL 归一后的哈希(同一仓在不同机器、不同写法克隆都是同一把键),`p` = 没有 origin(或 origin 是本地路径)时的项目根路径哈希(只在本机稳定)。**升级做法**:
194
+ - **先升中心再升客户端**:旧中心对 `userrepo:` 键答 404,新客户端会在每轮同步对那一层打一行 warn `memory_sync_layer_failed`(同步层本身照常);
195
+ - **只在本机用记忆、不开同步**:无需动手。存量 `repo:` 层的条目在**该项目第一次跑任务时**自动折进新键(日志 info `memory_project_layer_folded`);**窗约 30 天**,窗关之后的版本不再折 ——
196
+ 窗内一次都没打开过的项目,旧层留在库里但不再进任何读列表。想全部带过来:窗内在每个项目里跑一次任务;
197
+ - **开了记忆同步**:同步层与全局层同属主(例 `MEMORY_SCOPE=user:alice` 不设 `MEMORY_SYNC_SCOPE`,或两者都写 `user:alice`)⇒ 项目层不再让位,随同步推拉;启动通知 `memory_project_scope_yields_to_sync`
198
+ 不再出现。缺省 `MEMORY_SCOPE=local` + `MEMORY_SYNC_SCOPE=user:<你>` 的部署仍让位、仍什么都不同步(与此前同),通知改成一句并点名出路:把 `MEMORY_SCOPE` 设成同步层那把 user 键
199
+ (代价如实:换全局层名字之后,原 `local` 全局层与它名下的项目层不在读列表里 —— 与此前改 `MEMORY_SCOPE` 同一种代价,盘上数据不删)。同步腿的旧游标文件 `sync-cursor-<peer>.json`
200
+ 第一轮自动收编(info `memory_sync_cursor_adopted`),此后每层一只 `sync-cursors/<peer>/<scope 摘要>.json`;
201
+ - **起服拒**:`MEMORY_SCOPE` / `MEMORY_SYNC_SCOPE` / run-local `--user` 写成 `userrepo:…` 或 `repo:…` 键 ⇒ 拒(项目层由本服务按任务派生,不能被点名);属主编码超过 64 字符 ⇒ 拒。
202
+ 这样写过的部署改成一把 `user:<主体>` 键或一个普通名字;
203
+ - **中心侧**:`POST /v1/memory/sync/:scope` 与 `GET /v1/memory/export` 放行主体**自己的**项目层(属主段 = 已验主体),别人的照旧 404(与其余拒绝同体);`/v1/adoption` 改名时项目层键的属主段一并改写
204
+ (SQL 文本变,双库都已覆盖);
205
+ - **仓搬家 / 改 origin**:`r` 档键随远端变;先 `git init` 用着、之后才加 origin 的项目,`p` 档条目在加了 origin 之后第一次跑任务时自动折进 `r` 档(常设,不随窗删);反方向(删掉 origin)不折。
206
+ 18. **SQL 后端(`DB_BACKEND=mysql` / `pg`)开了 `MODEL_CIRCUIT_BREAKER`:断路器键换形,写新表 `breaker_state`,退役表 `circuit_breaker` 起服删掉(持久数据;无需动手)**:
207
+ 键从 `<provider>:<模型>@<网关根原串>` 换成 `<provider>:<模型>@<路由身份摘要,24 hex>`(键里不再有 URL;原串会把网关根 query 里的凭据带进共享库)。
208
+ 新一代键写新表 `breaker_state`(起服由中央建表语句建,加法 DDL);一次性迁移把退役表 `circuit_breaker` 整只删掉(不按键形挑行 —— 旧形是开放串,任何认当前形的判据都有一种带凭据的旧行长得像它;
209
+ 启动读数 `retiredBreakerTablesDropped`),新表里的状态它一位不碰,第二次起服起零动作。升级后每条路由的断路器在新表里从关闭态开始计数(旧键没有读者,不做改写)。
210
+ 升级序与第 12 条同一个:先停光 ≤7.132.x 副本,再起本版。没停光时还在跑的旧副本写旧表会失败(建议性写穿,吞掉;旧副本连续 3 次失败打一行 warn `breaker_writethrough_degraded`,
211
+ `counter_flush_fail_streak{table="circuit_breaker"}` 升高),退回各自进程内的断路器;对着已迁移的库重启的旧副本先按旧 DDL 建回一只空的旧表、随即起服拒(`config.schema_mismatch`),
212
+ 那只空表下一次本版起服再删。新副本这只量表的 `table` 标签是 `breaker_state`(按 `table="circuit_breaker"` 配的告警改标签)。
213
+ 按 `circuit open for …` 文本里的 URL 认路由的告警规则,改读启动日志 `listening` 行 `brain.circuitBreakerRoutes` 的「摘要 → 路由展示串」对照表。
214
+ 19. **`settings.hooks`:组上的 `source`、command 条目上的 `plugin` / `args` 被读了;托管组跑在独立车道上(壳 / 嵌入方:不带这三只键、命令里也不引用 `${CLAUDE_PLUGIN_ROOT}` / `${CLAUDE_PLUGIN_DATA}` 的请求零动作)**:
215
+ 三只键此前被契约分类器静默剥掉,现在本服务在同一坐标上读,形错 ⇒ `400 request.field_invalid`(`detail.reason: "wire_key_invalid"`,`detail.key` 点名那只键)。
216
+ - **不带 `source`**:缺席 = 非托管;没有托管组时执行路径与 7.132.0 同一条,判词的读法有两处变了:① 工具输入超载荷上限(`tool_input` 超 262 144 字,hook 只拿到截断标记)时,
217
+ 非托管 `PreToolUse` hook 给的 `allow` / `updatedInput` 不再作数(同组别的条目与引擎门照常裁决 —— 同组另有可信放行 ⇒ 照放行,没有 ⇒ 由引擎门裁决,default 档上是问人;每次一行 warn `hook_verdict_not_honored` + 一帧 `hook_notice` / `hook_verdict_untrusted{lane:"unmanaged"}` 点名那一条,帧不断言这次调用怎么收场);
218
+ ② 同一组里前一条改写、后一条交回与输入同值的 `updatedInput` ⇒ 执行前一条的改写(此前后一条的回显把它盖回原输入)。判据只看载荷是否被截断、不看 hook 读了什么 —— 按工具名放行的 hook 遇到超大输入也一样不作数;这类调用要免问,写审批规则(`settings.permissions.allow` / 部署的放行规则),不靠 hook 的放行。要让组织策略的 hook 守得住,壳在见到能力位 `taskSettings.managedHookGroups` 之后给托管组标
219
+ `source: "managedPolicy"`(托管设置启用的插件标 `managedPlugin:<name>`):托管组在非托管之后、于最终输入上跑,跑不成 ⇒ `hook_notice` 第三族 `hook_managed_unrun`,判词不可信 ⇒ 第四族 `hook_verdict_untrusted{lane:"managed"}`,两种都让 `PreToolUse` 在没有否决时折 `ask`
220
+ (消费端按 `kind` 分派、未知 kind 别崩);托管车道多一只 120 s 的事件墙钟(只门新条目起跑),两车道共用引擎的 handler 预算 `HOOKS_TIMEOUT_MS`。
221
+ 托管 PreToolUse hook 匹配上的超大工具输入(`tool_input` 超载荷上限,hook 只拿到截断标记)在没有否决时变成问人。
222
+ - **exec 形 `args`**:此前被剥掉、只剩可执行名以 shell 形去跑;现在按 exec 形跑(不过 shell)。存量体里有 `args` 的续跑腿同样改按 exec 形跑 —— 这正是写的人的本意;若某条曾「碰巧能跑」只因参数丢了,改写那一条。
223
+ - **命令里引用 `${CLAUDE_PLUGIN_ROOT}` / `${CLAUDE_PLUGIN_DATA}` 而条目没带对应的 `plugin` / `dataDir`、同请求的 `settings.env` 也没给这个变量的非空值**:此前展开成空串照跑,现在这一条起不来(`spawn_failed`;托管组上即没跑成)。
224
+ 设置文件里抄来的插件 hook 删掉这一引用,或改由壳带 `plugin` 投(见能力位 `taskSettings.pluginHooks`)。请求 `settings.env` 给了同名变量的(非空)不在此列 —— 那一形有值,照常起跑(shell 形由 shell 展开、exec 形替成它),靠这条 env 给根的守卫 hook 行为不变。exec 形的替换一趟完成:替进去的值里若带别的占位字面,原样留着不再换(参照实现按序逐名替换,前一个名的值里的字面占位会被排在后面的名再换一次)。不带花括号的 `$CLAUDE_PLUGIN_ROOT` 不在判据里。与参照实现的差:参照实现的 hook 环境同样含 `settings.env`,仍按条目是否带插件上下文一律拒;本服务多读一层请求 `settings.env`,是为了 7.132.0 下靠它给根、确实有值能跑的配置继续能跑。
225
+ - **`plugin.options`** 只放非敏感值(请求体随任务落库,本服务不做 `${user_config.*}` 替换);带敏感选项的插件 hook 留在壳侧执行。
226
+ 20. **名单为空的单用户部署:审批队列不再把每个调用方当运维 —— 要当自己的运维写一行 `OPERATOR_SINGLE_USER=true`(行为变更)**:「谁是运维」只剩一条读法,空的 `OPERATOR_PRINCIPALS` 在每个运维面上都是
227
+ 「没有人是」。此前审批四个读面(`GET /v1/approvals`、`GET /v1/approvals/stream`、`GET /v1/assistant/inbox`、`GET /v1/assistant/tasks`)在名单为空时把每个调用方当运维(看全部主体的待批、`?owner=` 生效);
228
+ 升级后同一台部署上,带主体的调用方只看到自己的待批、不带主体的调用方只看到匿名卡(不带主体提交的任务停下的那几张 —— 正是决断口对它开放的那几张;主体名下的卡它看不到)、`?owner=` 不生效。起服时这一形打一行 warn `operator_undeclared_single_user`。**升级做法**(只对 `REQUIRE_PRINCIPAL` 未开、
229
+ `OPERATOR_PRINCIPALS` 为空的部署):
230
+ - 想保留修前的审批视图 ⇒ 加一行 `OPERATOR_SINGLE_USER=true`。它的意思是「这台单用户部署的每个调用方都是运维」,对全部运维面生效(审批队列之外,记忆运维口、配置目录、身份收编、排空这些此前在名单为空时答 `501` 的口也一并打开);
231
+ 没配服务凭据(`SERVICE_AUTH_TOKEN` 等)的部署上,能连上端口的都是运维 —— 要收窄先配凭据;
232
+ - 只想让某几个主体当运维 ⇒ 写 `OPERATOR_PRINCIPALS=<主体,…>`(二者只能选一,同时写起服拒);
233
+ - 不需要跨主体的审批视图(例:壳只发自己的主体、只看自己的待批)⇒ 无需动手。
234
+ `OPERATOR_SINGLE_USER=true` 与 `REQUIRE_PRINCIPAL=true` 同在也起服拒(多租部署用名单)。声明之后不带主体的调用方是运维、但没有身份可记:记「谁改的」的写面
235
+ (`PUT /v1/admin/memory-optout[/:principal]`)要带主体,否则 `401 auth.principal_required`。
236
+ 21. **隔离型车道(`e2b` / `k8s` / `local-docker`)上 `READ_FACE` 缺席时,读面缺省从 `roots` 变 `open`(行为变更;把宿主目录或共享卷挂进沙箱的部署升级前写 `READ_FACE=roots`)**:此前 `READ_FACE` 缺席时的缺省只按部署形分两种 ——
237
+ 单用户 ⇒ `open`,多租户 ⇒ 不铸、引擎默认 `roots`。现在车道契约行显式声明读面缺省:隔离型三车道 `open`,`host` / `ssh` / `adb` / `device` 一个字节不变;读的是**最终生效的车道**
238
+ (`config.d/remote-exec.json` 换车道之后按最终车道重派)。`READ_FACE` 显式值(env 或中心发布)永远胜,原样不动;单用户沙箱部署读面本来就是 `open`,只有 `GET /v1/diagnostics/wiring` 的 `readFace.source` 从 `posture` 变 `lane`。
239
+ **谁受影响**:把宿主目录(`hostPath` / bind mount)或共享卷挂进沙箱的多租部署 —— 那些宿主文件在 `roots` 面上本有强制问,`open` 面零问可读;读 `readFace.source` 的消费方(web-admin、运维脚本)要按开集处理新词 `lane`
240
+ (来源闭集五词,优先序 `env` > `center` > `lane` > `posture` > `engine-default`)。**谁受益**:团队沙箱上要 `auto` 连续干活的部署(不用再靠 web-admin 向导往 env 写 `READ_FACE=open` 那一行,向导里这一行随本版退为冗余)。
241
+ **做法**:要保留 `roots` ⇒ 升级前写 `READ_FACE=roots`(显式值恒赢);要放开读面又不想让那些挂载可读 ⇒ 给那些路径加读拒行 `READ_DENY_PATTERNS`(`open` 面上读拒表照样拦);升级后看诊断面的 `readFace.source: "lane"`(指路句带挂载告诫)
242
+ 与 boot 期 info 行 `config_knob_posture_derived`;没挂宿主目录的隔离型车道部署无需动手。
243
+ 22. **center 的 `runtimeCaps.allowBypassPermissions` / `allowAutoMode` 两键开始生效:组织关掉的模式由引擎折回 `default`(安全;行为变更)**:center 下发的 per-principal entitlement 里这两键此前被服务端丢掉 —— 组织在 web-admin 里关了 bypass,
244
+ 这个人提交 `permissionMode:"bypassPermissions"` 照样跑在 bypass 下;关 auto 只有 `runtimeCaps.autoMode:false` 一键管用。现在 `allowBypassPermissions:false` ⇒ 引擎的 bypass 拒位,`allowAutoMode:false` ⇒ 与 `autoMode:false` 同一只 auto 拒位
245
+ (两键任一为 `false` 即拒,另一键的 `true` 不覆盖;`true` / 缺席 = 不拒)。被拒的请求**不是 4xx**:受理照常,这条腿跑在 `default`,流上一帧 `engine_notice` `config.permission_mode_unavailable`(`detail.by:"operator_deny"`),
246
+ 实际模式见 `wiring_manifest.permissionMode`;两键的值不是布尔 ⇒ 这个 principal 的放大面整份 fail-closed;center 取数硬失败的降级项也多拒 bypass(降级窗最长约 10 秒,之后整份重抓)。
247
+ **谁受影响**:在 web-admin 里把这两键设成 `false` 的组织下请求 bypass / auto 的人 —— run 改跑 `default`(写会问);center 故障窗里请求 bypass 的 run 同样折回。已知残余:能力位 `taskWriteFaceOpen` 是部署级的,
248
+ 看不到 per-principal 的 bypass 拒,被拒的人读到的仍可能是 `true` ⇒ 壳读回执 / 通告,不要读能力位。**做法**:组织其实想让人用这两个模式 ⇒ 在 web-admin 把键改回 `true` 或删掉(升级前先看这两键现在设的是什么:此前设了不生效,升级后即生效);其余部署无需动手。
249
+ 23. **模式缺席的请求也问 `Workflow`(行为变更)**:本服务给动态工作流(`Workflow` 工具)的那一问由 settings 折叠按模式装,此前请求没带模式词(也没带 `settings.permissions.defaultMode`)时不装 ——
250
+ 引擎把缺席读成 `default`、写照问,而工作流不问。现在这条 run 挂得出 `Workflow`(请求开了自编排 `selfOrchestration: true`,部署也开着;单用户部署缺省开)就装这一问,不看模式:`default` / `auto` / `plan` / `acceptEdits` / 缺席 ⇒ 问
251
+ (`auto` 再交分类器),`dontAsk` ⇒ 由模式拒,`bypassPermissions` ⇒ 放行并披露(`tool_end.gate.disposition.released`,每个 run 每个(模式, 类)一条通告 `permission.ask_released_by_mode`;此前 bypass 下这一问根本不装,调用不经记录直接放行)。
252
+ **谁受影响**:开了自编排而不带模式词的调用方 —— 调 `Workflow` 时多一张卡;有活体审批席的部署上是一张卡,没有人可问(无审批席又无停驻,或同步请求无人附着又没开停驻)时这次调用被拒、写进转录;
253
+ 按通告条数断言的消费方(bypass 下调过 `Workflow` 的 run 多一条)。**做法**:不想被问 ⇒ 请求的 `settings.permissions.allow: ["Workflow"]`(引擎的 allow 层清得掉这一问),或对这一问点「本会话不再询问」;显式发模式词只改处置、不免问(`default` / `plan` / `acceptEdits` / `auto` 仍问,
254
+ `bypassPermissions` 放行并披露,`dontAsk` 由模式拒);不开自编排的调用方无需动手。
255
+ 24. **中心凭证换人:server 自己降到「无中心配置」档、当场拉取、通告两态(行为变更;`/health` 新增一键 `centerIdentityNotice`)**:此前同机换账号(凭据文件被改写成另一个人)之后,在用的中心配置仍是上一个人的,直到下一个 60 s 拍拉成;
256
+ 现在引擎读凭据文件时判出凭证身份与在用中心配置的身份不是同一个人 ⇒ server 把在用的中心配置降到「无中心配置」档(模型目录 / 缺省模型 / 限额 / 审批名单 / autonomy / 读面 / 中心提示词层等热面回 env 底,`GET /v1/models` 立刻是 env 的那一张),
257
+ 当场发起一次拉取,并铸通告 `center_identity_demoted`;新身份的候选落地后通告 `center_identity_landed`。拉取成功之前**不回退**到上一个人的任何东西(两个例外:降档没能降到底的组 —— 例如 env 的审批名单在这台部署上无处可服务 —— 活值仍是上一个人下发的,`centerIdentityNotice.retained` 点名这些组;降档自己失败,即 Runner 拒收 env 表 ⇒ 这一拍整体失败、不采用新身份的候选、不铸通告,按定时拍 / 下一次凭证读重试);拉取失败 ⇒ 停在降档档、通告停在 `demoted`、下一拍再拉。
258
+ **谁受影响**:① 依赖「新身份的候选到达前,上一个人的配置继续跑」的部署 —— 现在换人到新配置落地之间跑在 env 底上(在飞的 run 照旧,新任务用 env 模型 / env 限额),**没有 env 模型(`MODEL_ID` 缺席)的部署在这个窗口里没有可派发的模型**,
259
+ 中心不可达时窗口就是不可达多久;② 令牌里取不出 `sub` 的用户 JWT(身份是令牌自身摘要)—— 每次续期读成「换人」、降档 + 重拉一次(中心签发的 JWT 恒带 `sub`,不受影响);③ 读 `/health.configAppliedVersion` 的编排器 —— 降档那一代记为 version 0;
260
+ ④ 按 `config_env_set_but_ineffective` 配告警的运维 —— 降档后新身份第一份目录落地时这一行会再响一次。**不在射程内**:技能 / MCP 服务器表 / A2A / 场景仍是启动时那个人的,直到重启(`/health` 照旧据差异报 `restartRequired`)。
261
+ **做法**:没有开关、不留旧读法;按部署事实配上 `MODEL_ID`,让降档窗口里仍有模型可用;壳按 `/health.centerIdentityNotice` 的 `code` 转述「现在用的是基础配置」/「新账号的配置已换上」,`retained` 非空时那几组不适用这句冻结句,读 `retained`;不再靠重启引擎补偿;其余部署无需动手。
262
+ 25. **嵌入方(自建 `StoreBackend`、不走 `createStoreBackend` 的进程):`StoreBackend.orgDeliveryQuota()` 与 `StoreBackend.checkpointReadView()` 是必选成员(BREAKING,类型面;零别名)**:跨主体投递门的配额店(三张小时窗计数表的那一只店)
263
+ 挂在后端上,`StoreBackend` 多一个必选方法 `orgDeliveryQuota(): OrgDeliveryQuotaStore` —— 自建后端 tsc 红即通知。返回型 `OrgDeliveryQuotaStore`(`admitAttempt(fromScope, policy)` / `take(fromScope, toScope, policy)`,
264
+ 店读不出 / 写不进 ⇒ 抛,绝不当成放行)与参数型 `OrgDeliveryQuotaPolicy` 自本版从包根导出;经 `createStoreBackend()` 带起后端的嵌入方与部署零动作(SQL 后端起服自建三张配额表)。
265
+ 同一类:`StoreBackend.checkpointReadView()` 也是必选成员(BREAKING,类型面;零别名)—— 待决 checkpoint 的只读读口(审批账本留存读它列「还有哪些会话停驻着」,它不牵动任何别的店),返回型 `ReturnType<StoreBackend["checkpointReadView"]>`(只有 `listPendingSessionIds()`)。
266
+ 有 checkpoint 店的自建后端交与 `checkpoint()` 同一只店的读法;没有 checkpoint 店的自建后端交一只恒空读口 `() => ({ listPendingSessionIds: async () => [] })`。此前它是可选成员,漏实现在留存清扫里读成「没有停驻」(删除方向),现在是 tsc 红即通知;经 `createStoreBackend()` 带起后端的嵌入方零动作。
267
+ 26. **SQL 后端(`DB_BACKEND=mysql` / `pg`):收件箱里身份键过不了判官的存量行,起服一次性删掉(持久数据;无需动手)**:收件箱(跨会话信箱与 principal 收件箱)的键本版只有一只判官
268
+ (良构 Unicode、不含控制字符、UTF-8 ≤ 190 字节、scope 非空),判官拒的键没有箱 —— 每一只入口对它答「箱不在」,会话删除的打标 / 丢箱两步也不再碰它。7.132.x 及以前的
269
+ PostgreSQL 部署收下过主体 / 会话 handle 里带控制字符(HTAB 等)的箱(可信主体头与 JWT `sub` 都不拦这类串),那样的箱升级后谁都够不着。
270
+ - **自动(起服,窗内每次)**:三张收件箱表(`mailbox` / `mailbox_message` / `mailbox_tombstone`)里键过不了判官的行删掉,一只键整箱删(与会话删除丢箱同三句);
271
+ 条数进起动日志行 `one_time_migrations_applied` 的 `mailboxRejectedKeyRowsRemoved`(删了行时这一行是 warn,键一只都不进日志);第二次起服起是 0。
272
+ - **想先留底**:升级前自行导出收件箱表里键会被拒的行(含控制字符 / 含孤立代理 / UTF-8 超 190 字节 / 空 scope,两方言同判);迁移只删这些行、只在首次起服删一次。
273
+ - **不在这一步里**:MySQL 协议部署上主体带孤立代理、升级前写下的箱 —— 驱动早已把孤立代理换成 U+FFFD,库里的键与字面带 U+FFFD 的那只主体的键是同一串,判官收它,迁移不删。
274
+ - 回滚到 ≤7.132.x:零动作(删掉的行在本版下谁都够不着)。`DB_BACKEND=local`:不涉及(local 用引擎自己的文件信箱)。
275
+
276
+ ## 7.132.0 —— 引擎 7.52.0 → 7.53.0 提货:升级前停驻的子代腿 / Skill 卡在认领前被拒(先排空:随包两条新判据)· `settings.hooks` 换成引擎的扩展注册链(`wiring_manifest.hooks[]` → `mods[]`、`HOOKS_TIMEOUT_MS` 新读法)· 执行车道静默切断换码 `liveness_no_output` · 凭据按值也扣 · 一枚运维通告码退役 · 清单 `prompt_assembled` 换成 v3、`prompt_constitution_total` 下线 · `settings.hooks` 的 matcher 编不过任一事件 400、受理总额度 `budget_exceeded` · 技能 frontmatter 读不了拒载、空正文条目不装 · 标题腿 fail-open 标签按成因族分 · 投递腿不再重投提交时的图 · k8s 车道加固(两处新的起服拒)· 请求体 `mcpServers` 列表级坏形整份 400、沙箱车道的受理拒各带机读码 · 升级前停驻问答的起服一次性迁移 · 宿主 CLI 与 `LSP_ENV_ALLOW` / `BAKE_ENV_ALLOW` 的凭据边界、`REMOTE_EXEC_HOME_DIR` 与实测家目录对证、中心鉴权桥的身份边界(安全)· 受理面拒句与拒体机读位 · 引擎收紧的会话规则与工具清单(放行侧近似名开跑前拒、规则名文法拒、存量会话规则行读不出即拒一切)· 递归读只按点名的根判(放宽;起服点名非锚定读拒行) · 子代工具清单近似名与存量会话规则孪生行的同步腿 200 + failed 改 400(码不变) · 一次性迁移 M17 遇读不出的 deny 行不改写、不盖戳 · 更正 7.131.0 第 8 条对请求体规则表的陈述(新拒的只有大小写孪生;文字更正) · 引擎 7.53.0:hook / 标题腿的 per-model 凭据绑首个发出的主机 · 请求体 `a2aPeers[].toolAxes` 与 MCP env / headers 两处收紧 · 任务流新帧 `compaction_started` 与几处随引擎变的 wire 值 · 中心提示层只有一种 wire 形 `{ schemaVersion: 2, artifact }`(web-admin 与本服务同窗升级,先中心后服务)· 场景名进 `promptBinding` · 品牌行由部署座 overlay 承载 · 「无持久记忆」披露由引擎渲染(委派子代不再带)· LKG 信封 5 · `Artifact(action:<词>)` 是规则(放行侧放宽)· 嵌入方 `snapshotBlobSqlCapBytes` → 读口 `snapshotBlobSqlCap { capBytes, source }`、`sqlEngineFacts` → `sqlEngine { dialect, facts }`(SQL 后端在场必填、值形起服判)(BREAKING)· `READ_DENY_BUILTIN_EXCLUDE` 写 `.npmrc` / `.pypirc` 起服拒
277
+
278
+ 1. **升级前先排空:7.131.x 停驻的子代腿与 Skill 卡,升级后续跑可能在认领前被拒**(零 DDL;卡留 pending,行留停驻)。引擎 7.52.0 在认领前按规范拼写读停驻行记下的工具名清单:
279
+ 子代的工具天花板里记着 `Bash(*)` / `Tool()` / 内容形 / 读不出的名 / deny `*`(7.131.x 的受理口收下 `excludeTools:["Bash(*)"]` 这类写法,引擎 7.51 按原拼写记进子代行)⇒
280
+ `409 checkpoint.config_refused`,`blockedBy: "config.tool_face_control"`、`field: "inheritedGate"`、`reason` 点名哪一臂;名字集记着重复条目(`excludeTools:["Read","Read"]`)⇒
281
+ `409 resume.parent_constraint_mismatch`;Skill 卡的清单里有读作空的条目 ⇒ `409 resume_outcome_invalid` + `field: "boundGrantDigest"`。
282
+ **怎么查**:升级**之前**、对 7.131.x 的数据跑随包排空脚本(`psql … -f node_modules/@sema-agent/server/scripts/drain-check.pg.sql` /
283
+ `mysql … < node_modules/@sema-agent/server/scripts/drain-check.mysql.sql`;`DB_BACKEND=local` 用 `node node_modules/@sema-agent/server/scripts/drain-check-local.mjs`),
284
+ 读 `parked-tool-lists` 那一行 —— 它数的是**候选**(天花板键在场且不是空数组 / 冻结约束链非空 / Skill 卡带绑定的停驻行;SQL 判不了引擎的拼写,所以是超集)。
285
+ **出路**:升级前让这些行在 7.131.x 上跑完 / 决完;已经升级的,在一台 7.131.x 的副本上续跑它们,或取消那条 run(`POST /v1/runs/:id/cancel`)后作为新任务重提
286
+ (新任务由 7.52.0 写下规范拼写,照常续跑)。拒的 409 体带 `blockedBy` / `field` / `reason`(见下一条),句子是引擎的原句。
287
+ **例外**:后台停驻的子代腿(经 parked 车道赎回)被同一类认领前拒时,引擎的回执只交成因词,本服务答 `422 parked_resume.startup_failed`(行回停驻、可再决),体只带 `cause`,
288
+ 不带 `blockedBy` / `field` / `reason`,句子仍是引擎的原句(到引擎的回执带上这三位为止)。
289
+ 2. **续跑被引擎拒的 409 体多两个键**(加性):引擎 `CheckpointError.detail.code` ⇒ `blockedBy`(挡住它的准入码,与 `409 resume_blocked_by_policy` 的同名键同义)、`detail.reason` ⇒ `reason`
290
+ (每一个引擎码都过境,含 `checkpoint.unsupported_version` 的 `version_newer` 等);`field` 照旧。`retriable` 的意思不变(卡仍 pending,不是「原样重试会成功」);
291
+ 本服务自己在重放存量体之前拒的 `409 resume_blocked_by_policy` 此版起同样带 `retriable: true`(此前缺席,把缺席读作终局的客户端会对同一处境读出相反结论)。
292
+ 后台停驻的子代腿是例外:答 `422 parked_resume.startup_failed`,体只带 `cause`,没有 `blockedBy` / `field` / `reason` / `retriable`(见上一条)。
293
+ 终态 run 的 `POST /v1/runs/:id/steer` 在铸唤醒卡之前的同类拒没有卡,体不带 `retriable`(此前 allow 读法 / 模式词读法两臂在那条路径上也带 `true`);其余键与续跑入口逐字相同。
294
+ 按 409 体键集精确比对的客户端请放宽。SLA 拒扫腿对同一张卡同一拒因只落第一条 `deny_sweep_resume_blocked`,之后看计数器 `deny_sweep_resume_blocked_total`。
295
+ 3. **回滚(7.132.0 → 7.131.x)前也先排空**:7.52.0 停驻的子代行带 `state.ownToolLists`(行上的读方要求词 `own_tool_lists`),7.131.x 读不了 ⇒ 续跑
296
+ `409 checkpoint.unsupported_version`(`writerVersion` 比 `readerVersion` 新)、卡留 pending。回滚前对 7.132.0 的数据跑同一个脚本,读 `own-tool-lists-rollback` 那一行(精确);出路 = 回滚前让它们跑完,或取消重提。
297
+ 4. **执行车道的静默切断换码**:一条命令因为没有输出被切(调用方的 `readTimeoutMs`,或 `K8S_LIVENESS_MS` / `E2B_LIVENESS_MS` 兜底)⇒ 码 `liveness_no_output` + 窗口秒数
298
+ (Bash 工具结果 `livenessNoOutput: true` / `noOutputSec: N`);墙钟到点仍是 `timeout`。7.129.1–7.131.x 两种切断同报 `timeout`。按 `timeout` 一个码判「时间切断」的读者,
299
+ 把 `liveness_no_output` 并进同一支(两词都可重试)。设备端的结局帧也可以报这一词(文件面读作 `unknown`)。
300
+ 5. **本部署的凭据按值也扣**(引擎 7.52.0 `declareWithheldEnv({ names, values })`;零配置):配置目录 secret 型变量与模型条目 `apiKeyEnv` 指的变量,它们此刻的值也交给引擎扣 ——
301
+ 同一把钥匙被抄进别的变量名,`inheritEnv:"all"` 下也不进子进程。值不是凭据(不足 8 字符 / 占位词 / 一个字符重复)的,那个值不扣、名照扣、起服不拒,起服日志点名那个变量一次;
302
+ `GET /v1/capabilities` 的新顶层布尔 `inherit_env.own_credential_values_withheld` 此时答 `false`。要它 `true`:给那个变量一个真凭据值。
303
+ 6. **auto 模式的配额烧得更快**(计费口径,零配置):引擎 7.52.0 起权限分类器与扩展的模型调用计进 run 的花费(`costMicroUsd`,「其中」行 `stats.costBreakdown.sideCallMicroUsd`),
304
+ 本服务的成本配额 / 用量批报 / 租约照记;延迟直方图只收主循环的调用。
305
+ 7. **一枚运维通告码退役**:`route.base_url_changed_key_unchanged`(目录换了主机、凭据没换)随引擎 7.52.0 退役 —— 换主机的那次请求被拒,告知改为会话流上的
306
+ `engine_notice` `route.credential_origin_mismatch`(受众 user)。按旧码过滤运维日志的告警请改读新码;`config.credential_not_withheld` 只进运维日志。
307
+ 8. **请求体 `mcpServers[i].startupTimeoutMs` 受理**(这一只 server 自己的启动界,毫秒整数;引擎 7.52.0):原样交给引擎,值形的判官只在引擎 —— 数字串 / 小数 / 越界 ⇒
308
+ 引擎拨号时只拒这一只 server(`config.mcp_startup_timeout_invalid`,兄弟照挂),不在受理口 400。7.131.x 受理口把它当表外键丢掉;升级前存下的请求体里若带着它,续跑起开始按它生效。
309
+ 9. **会话规则存量行**(只影响 7.128.x 及更早写下、还没改写过的行):`toolAllow` 里的 `*` 由引擎读成只作废它自己,名单其余照放;7.129.0–7.131.x 起服日志里
310
+ `session_rule_row_old_grammar_entries` 带 `wildcardMasked` 的行,升级后不必再手工去掉 `*`。
311
+
312
+ 10. **`wiring_manifest`:`hooks[]` 由 `mods[]` 取代**(租户面与 operator 面、live 帧与 durable 账本行同一构造器)。`mods[]` 一行 = 这条腿准入的一张扩展注册:
313
+ 挂上的 `{ name, seat, tier, events, observe?, skipped? }`,被拒的 `{ name, seat, tier, refusedBy, reason }`。本服务恒挂 `server.permission-denied-meter`(部署座),
314
+ `TOOL_TRACE=true` 时加 `server.tool-trace`,品牌部署加 `server.brand-identity`(第 55 条),请求的 `settings.hooks` 在本车道被采纳时加 `settings.hooks`(任务座)。`hooks[]` 不再发送。
315
+ **出路**:读 `mods[]`;`name` / `seat` / `tier` 按开集读,`observe` / `skipped` 缺席不折 false。缺席读作「这条腿没有注册」,不是「没有扩展判这条腿的调用」。
316
+ `name` / `refusedBy` / `reason` 与 `skipped[]` 里的串是注册方写的文本:凭据形已换成记号、超过 1000 字已截断(与通告 `mods.registration_refused` 的 `detail` 同一读法),按展示文本读,不要当可信输入。
317
+ 同批:引擎通告 `mods.registration_refused`(一张注册在准入时被判拒、没挂上;`detail: { name, seat, tier, refusedBy, reason, sessionId }`)进会话通告流的白名单;本部署今天发不出它。
318
+ 11. **`HOOKS_TIMEOUT_MS`** 是 `settings.hooks` 那张注册每个 handler 的时间预算(一个事件跑一遍本请求的钩子条目)。**未设 = 600000 ms**,即此前请求钩子所受的界;
319
+ `0` 按字面(零预算)。超预算时 `PreToolUse` 上该调用、`UserPromptSubmit` 上该提交被 fail-closed 拒,其余事件跳过这一轮。它不再约束本服务自己的两张观察注册
320
+ (拒绝计量 / 工具追踪,同步返回)。升级零动作。
321
+ 12. **审批卡 `allowRuleShadowed` 里 `member: "hook"` 的一行**,`entries` 现在点名放行的那张注册(请求自己的钩子 = `settings.hooks`);此前恒为空表。
322
+ 13. **请求钩子在审查工具调用或提交时失败**(钩子执行器自身出错、超预算),模型读到的拒句点名扩展(`extension "settings.hooks"`)。
323
+ 14. 请求 `settings.hooks` 的 `Stop` 条目在主任务结束时、也在委派子代结束时跑 —— 与此前同触达。`PermissionDenied` / `SubagentStop` / 两个 model-switch 事件仍由壳跑,服务端不跑。
324
+ 15. **本服务不再合成钩子记录**:部署座的两张注册只观察(判词不采纳、不进委派子代的约束),链里唯一的答者是请求钩子;请求钩子的答案在每个 handler 边界由引擎屏
325
+ (越约成员、读不出词的载体 ⇒ 该调用 fail-closed 拒,与此前读数相同)。
326
+ 16. 升级前记下的 run 的 `wiring_manifest` 行保留 `hooks[]`;本服务从不回读它,也不改写。停驻任务续跑零动作:续跑时请求钩子从存下的请求体照常重新铸出。
327
+ 17. **升级前钉在中心提示上的会话,下一次跑由中心源的状态决定**(零配置;所有会话后端)。7.131.x 及更早写下的会话 epoch 记录是退役形,升级后
328
+ 不改写,引擎按字段名认出它(连同它有没有钉一份中心提示)。钉了中心提示的会话(顶层会话;委派子代用父会话的中心层)下一次跑:中心源 `active` ⇒ 用当前候选组装,另记一条
329
+ `code_change` + `changed: ["published_schema"]`(对话中途换了中心文本,有记录;提示前缀缓存失效一次);`disabled` ⇒ 空中心层,同样记一条;
330
+ `unavailable`(或本部署没有中心源)⇒ 这次跑以 `prompt.snapshot_unavailable` 失败,旧记录保留,中心源有了已核状态后再试即可。
331
+ 没钉中心提示的旧记录 ⇒ `code_change`,在下一次压缩采用中心候选之前不带中心层。MySQL 协议 / PostgreSQL 后端上,记录落在加载 floor 之下
332
+ 的会话此前被读成「没有记录」(照跑并另记一条),本版起与其余会话同读。**出路**:让中心源发布一份本引擎可用的中心提示(`active`)或显式停用
333
+ (`disabled`);或者让这只会话的调用方开新会话(新会话没有旧记录)。
334
+ 18. **`GET /v1/sessions/:id` 的 `promptEpoch` 换形**(BREAKING):`{ kind: "pin", descriptor }`(`descriptor` = `{ epoch, identity, layers, activatedBy, changed?, sourceRevision? }`)
335
+ 或 `{ kind: "legacy", centerPinned }`;旧的 `artifactDigest` / `packId` / `assemblyApi` 不再出现,`activatedBy` 的 `legacy_migration` 并入 `code_change`。
336
+ **出路**:按 `kind` 分支读;键缺席仍是「这只会话没有记录」。
337
+ 19. **清单 `prompt_assembled` 换成引擎的清单 v3;计数器 `prompt_constitution_total` 下线**(账本行、`GET /v1/tasks/:id/turns` 的 `prompt-assembled` 块、trace SSE 的同名帧同一形)。键对照(v2 → v3):
338
+ `constitution` → 删(这条腿是哪一份提示读 `identity`:`artifact` / `layers` / `epoch` / `activatedBy`;选择器值读 `selectors`:`binding?` / `traits` / `host` / `facts`);
339
+ `blocks[]` 不变(`id` / `chars` / `hash`);`sections[]` 的 `slot` / `carrier` / `cadence` / `cacheClass` → 删(按 `band` 分组,`rank` 是档内次序),`hash` → `contentHash`
340
+ (`sha256:` = 发布文本,`salted:` = 带本任务 / 本 run 输入的文本),新增 `variant?` / `renderer?` / `locale` / `chain`(文本来源与施加过的 overlay);新增顶层 `superseded?`(被取代的 overlay);
341
+ `tools` / `toolDisclosure` / `totalChars` 不变。可选成员缺席即「没有」,不折成空值;在场却读不出的成员不上行(本服务计 `server.trace.projection-input-malformed`)。
342
+ `prompt_constitution_total{mode}` 不再注册:它要看的那件事(宪法层丢了)在引擎 7.52.0 下不会发生 —— 宪法档锁定、只由引擎组,逐字含锁定段的提示在开跑前被拒
343
+ (`prompt.assembled_role_refused`);抓它的看板 / 告警请删掉,没有替代计数器。升级前写下的 `prompt_assembled` 行保留 v2 形,本服务不回读、不改写,读腿原样交出;
344
+ 一条升级前停驻、升级后续跑的 run,账本里两形并存 —— 带 `constitution` 的是旧行(旧行恒带它,v3 行永不带);其余都是 v3 行,
345
+ v3 行上缺 `identity` = 引擎交出的身份读不出(已丢弃并计数),不是旧行。
346
+ 20. **`settings.hooks` 里编不过的正则 matcher,写在任一契约事件上都 `400`**(受理面收紧;行为变更)。7.126.0–7.131.x 只对 `PreToolUse` / `PostToolUse` / `PostToolUseFailure` 判,写在 `StopFailure`(`error` 词)、
347
+ `PreCompact` / `PostCompact`(`trigger` 词)上的同一串被受理,运行期该组静默不跑(只落 `hook_matcher_invalid` 日志);写在壳跑的事件(如 `SessionStart`)上同样被受理,处置归壳。现在 33 个契约事件同一判 —— 含 matcher 被忽略的 `Stop` / `UserPromptSubmit` / `PostToolBatch`
348
+ (「这一串读不读得了」是串的形问题,不分事件类)。体 `detail: { reason: "invalid_regex", event, groupIndex, path }`(`path` 是加性坐标,见受理面拒句改写那一条),`event` 现在可以是任一契约事件。「选中别名而选不中正名」(`dead_alias`)仍只属三个工具事件。
349
+ **谁受伤**:提交里在任一事件上带编不过 matcher 的客户端(此前 `202`,现在 `400`)。**做法**:修正则,或改成工具名列表(`A|B`),或删掉那个无用的 `matcher`。
350
+ 续跑重放不判(存量里的坏 matcher 照旧采纳:读 matcher 的引擎事件上那一组不跑并记 `hook_matcher_invalid`,matcher 被忽略的 `Stop` / `UserPromptSubmit` / `PostToolBatch` 照旧跑条目);多租户车道(`settings.hooks` 整只被忽略)不判。受理线程上解析 matcher 的数量上界由 48 组升到 33 事件 × 16 组(只解析不执行,每串 ≤ 8 192 字符,实测毫秒以下)。
351
+ 21. **`settings.hooks` 受理总额度:`400` 多一个 `detail.reason` 词 `budget_exceeded`**(加性)。每次求值的 `1 000 ms` 额度之外,一次受理里所有已完成的正则形求值的耗时之和超过 `5 000 ms` ⇒ `400 request.field_invalid`,
352
+ `detail: { reason: "budget_exceeded", event, groupIndex, totalMs, path }`(`groupIndex` = 越线的那一组,`path` 是它的坐标)。此前没有总界:每只都刚好低于单次额度的病态 matcher 最多(3 事件 × 16 组 × 1 别名 × 2 = 96 次)可占住事件循环近 100 s。
353
+ 良性设置不受影响(最大的良性配置总耗时在毫秒级)。**做法**:按 `detail.reason` 穷举读的消费方放行第四个词;用户侧把慢的 matcher 改成工具名列表或简化正则。
354
+ 22. **技能 frontmatter 读不了的技能不再静默变成全局技能**(`SKILLS_DIR` 与插件带的技能)。① 开头围栏行 `---` 现在容尾随空格 / 制表(此前 `--- ` 开头的文件整块读不出,`scenarios` 场景限制被丢);
355
+ ② 文件第一行是围栏而块没有收尾 ⇒ 这一条被拒载(一行 warn `skill_refused`,点名技能与文件,`reason: frontmatter_unclosed`),不再装成每个场景都有的全局技能,兄弟技能照装。第一行不是围栏的文件没有 frontmatter,仍是全局技能。
356
+ **谁受伤**:靠「开头围栏不收尾」碰巧被当作全局技能的技能文件(现在不装)。**做法**:补上收尾的 `---`,或删掉开头那行。
357
+ 23. **正文为空串的技能条目不再装成空正文技能**(`CONFIG_PROVIDER=local` 的 `config.d/skills.json` 与中心的技能域同判)。条目缺 `content` 或写成 `""` ⇒ 一行 `web_admin_skill_failed`(`reason: "body_absent"`),不装、同名出厂技能保留;
358
+ 此前名册里有这个技能、调用回空、零行日志。**做法**:给条目写上正文,或把它 `enabled: false`。
359
+ 24. **自动会话标题腿的 fail-open 标签按成因族分**(运维遥测;零配置)。此前除「端点回 3xx 被拒」外,标题那一次模型调用的所有失败都记成 `server.session-titler.gateway-unreachable`。现在:
360
+ `gateway-unreachable` 只数真不可达(连不上 / 网络层失败 / 超时);新增 `…model-unresolved`(选不出模型)· `…route-refused`(路由核验拒)· `…credential-custody-failed`(per-model key 托管读不出)· `…bad-response`(端点答了非 2xx 或 body 不是 JSON)·
361
+ `…no-content`(空应答)· `…unclassified`(失败码缺席)。**做法**:按旧 tag 统计「标题腿失败总数」的看板 / 告警把新增六只并进去;`session_title_total{outcome="llm_failed"}` 照旧逐次记账。
362
+ 25. **投递腿不再重投提交时的图**:提交体的 `images` 与 `userAttachments` 同律,是「这条目标」的一次性输入。在宿主会话上新起的一跑(workflow 决定的投递腿)与续跑腿(审批 / 资源停车 / wake / plan_review)重建配置时不再带它,
363
+ 此前宿主当初提交的图会随指路文本再投一遍。**做法**:要让模型再看一遍图,在新的提交里重新带上 `images`。
364
+ 26. **k8s 车道:两处新的起服拒、其余行为只收窄**(只在 `REMOTE_EXEC=k8s` 时求值;零 DDL)。
365
+ ① `WORKSPACE_CACHE_MOUNT`(只在 `WORKSPACE_CACHE=volume` 时读)落在保留的镜像目录闭集 `/bin /boot /dev /etc /home/sandbox /lib /lib64 /opt/sema /proc /root /run /sbin /sys /tmp /usr /var`
366
+ **上 / 之下 / 之上**(挂在 `/opt` 或 `/home` 这类祖先上也算)⇒ 起服即拒,拒句点名那一项与闭集;缺省 `/cache` 与不碰闭集的路径不受影响。**出路**:把挂载点改到别的绝对路径(如 `/cache`、`/data/cache`)。
367
+ ② `WORKSPACE_SNAPSHOT_EXCLUDE` 里只由 `*` / `?` 组成的项(`*`、`**`、`?`)⇒ 起服即拒并点名第几项(码 `config.workspace_snapshot_exclude_invalid`);`*.log`、`build-*` 这类带字面部分的项照旧。**出路**:删掉那一项,或写成真名。
368
+ ③ 行为修复(升级零动作):会话店读住客有了时限(`rpcTimeoutMs`,缺省 30 秒),超时按住客读故障拒这条 run,`workspace_space_unreadable_occupant` 的 `code` 是 `incarnation_read_timeout`;run 末快照保存前一律先停 pod 里的进程并确认(与那一刻有没有命令在飞无关:命令结束不等于它起的进程结束),
369
+ run 结束时还在飞的命令先被等(最长 `rpcTimeoutMs`);等不到的断开套接字、照样保存并出运维行 `workspace_snapshot_commands_cut`;没能确认进程停下(杀进程失败 / 复查仍有活进程)则不保存(`command_in_flight`),有没有命令在飞、等到与否都一样;`command_in_flight` 的拒还留给停驻挂起;被集群在准入时拒的 pod(`Failed`)记成这只环境的拒、不再每次操作重建,新增运维行 `sandbox_pod_refused`;
370
+ 绑不上的缓存卷按空间记一个快照时限、窗内不再等;回收座同一时刻最多 4 个空间在收,同类失败一次调用只出一行(`workspace_space_reclaim_failed` / `workspace_cache_reclaim_failed` 多一个 `count`,`space` / `sessionId` 点名调用里排第一的)。
371
+ **出路**:按这些行里的 `count` 与样本查;计数器 `server.workspace-space.reclaim-failed` / `server.workspace-cache.reclaim-failed` 仍逐空间计,抓它们的告警不用改。
372
+ 27. **请求体 `mcpServers` 的列表级坏形与词表外的键,新提交整份 400;探测口与新提交同一个答案**(受理面收紧,BREAKING)。`POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs`:
373
+ `mcpServers` 在场却不是数组 / 超过 32 条 / 某一条不是对象 ⇒ `400 request.field_invalid`(此前 `200`:整只忽略 / 挂前 32 条 / 摘掉那一条);条目层或 `transport` 层的词表外的键 ⇒
374
+ `400 request.body_shape` + `unknownKeys`(此前悄悄不读)。`POST /v1/capabilities/mcp/probe` 问同一只判官,码与句同新提交:列表不是数组、条目不是对象由 `request.body_shape`
375
+ 改为 `request.field_invalid`(缺席 / `null` 仍是 `request.body_shape`);`toolFaces[].pathTarget.skillScopeEligible: false` 一类判官的合法归一不再被拒;
376
+ 坏 URL 的拒句不再回显 URL;声明了 `transport.assertionHeader` 的条目探测口照旧整条拒(新提交照挂,本版承载、不发送)。
377
+ **谁撞**:发多于 32 台、或列表里夹着非对象 / 多余键的调用方;按探测口码分支的客户端。**出路**:把列表改成数组、删掉第 33 条起的条目与非对象条目、改正或删掉
378
+ `unknownKeys` 点名的键;探测口客户端把这两形改读 `request.field_invalid`。耐久 resume 重放存量请求不拒、处置不变。`mcpServers: null` 照常受理(与缺席同义)。
379
+ 28. **MCP `toolFaces` 的工具名不能是 `__proto__`**(所有腿;`constructor` / `toString` 等其余名字照收)。此前判合形而那份面静默消失、server 照挂;
380
+ 现在判不出形:中心 / config.d 腿跳过这条 server 并点名 warn `web_admin_mcp_tool_faces_invalid`,新提交与探测口 `400 request.field_invalid` 点名 `mcpServers[i].toolFaces`,
381
+ 重放腿整条不进。**出路**:去掉那一只工具的面(远端工具真叫这个名字时,它只能无面挂载)。
382
+ 29. **带 `sandboxImageProfile` 的提交被拒时带机读码**:执行车道不是 k8s ⇒ `501 capability.k8s_lane_required`(此前 `400`、无码);本部署没有镜像索引 ⇒
383
+ `501 capability.image_index_required`(此前 `400`、无码);没有解析出会话 ⇒ `400 request.precondition_unmet`;没有可见的已发布镜像 / 缺所需能力 ⇒ `404 not_found.image`;
384
+ 不认识的能力词 ⇒ `400 request.field_invalid`。**谁撞**:按「状态 400 + 句子子串」认前两形的客户端。**出路**:改按 `errorCode` 判(上面五个码),不读句子。
385
+
386
+ 30. **升级前停驻的问答,升级后卡、到期、决断口三处都按问答读(SQL 部署,起服一次性迁移 M21,零动作)**:7.125.x 及更早停驻、升级时还挂着的问答(7.126.0 第 22 条那一类)门上没有卡词 ——
387
+ 7.126.0–7.131.x 上队列行不标问答、到点被 SLA 拒扫(模型读到「拒」)、决断口却按工具名要 `answer`。本版第一次起服给这些行的门补上卡词 `question`(引擎今天在铸点写的那个词):
388
+ 队列行带 `approvalCard: "question"`,到点**作废**(不再当成「拒」),决断口照旧要 `answer`(`approve` 带 `answer`,拒绝照常)。引擎行摘要封过的行不改写(按构造都已带卡;有的话计数
389
+ `parkedQuestionRowsLeftAsWritten`)。**例外**:`DB_BACKEND=local` 的停驻行在引擎自己的文件店里,本服务改写不到 —— 那里的这类问答照旧按 7.126.0 第 22 条读;介意的话升级前答完或拒掉。
390
+ 31. **`GET /v1/approvals` / `/v1/approvals/stream` 的 `pending[]` 行 `gateKind` 恒在场**(此前「`gate_kind` 列诞生前停驻的旧 SQL 行」可缺席)。每次停驻都盖这一列;同一次迁移 M21
391
+ 把列为 NULL 的存量停驻行从门子树补齐,门子树里读不出登记门型的行(引擎续不了)置 expired。按 `gateKind` 路由的客户端可以删掉缺键的旧行为臂:缺键 = 读不出,按 fail-closed 处置。
392
+ 若库里仍有一行 pending 且 `gate_kind` 为 NULL(写口恒盖、迁移补齐之后不可达 —— 手改的行),队列不列它(计数 `fail_open_total` 的 `server.approvals.queue-row-gate-kind-missing`),
393
+ 与各决断口同一个读法(按门型取行的决断口本来就不认它);出路是把那一行置 expired 或删掉会话。
394
+ **怎么查**:`SELECT session_id FROM checkpoint WHERE status = 'pending' AND gate_kind IS NULL`(应为零行)。
395
+ 32. **起服一次性迁移半途失败时,拒因与起服日志带上本次已提交的全部读数**:`one_time_migrations_interrupted` 那一行的读数键与 `one_time_migrations_applied` 同名(各步骤的计数、
396
+ 落定了的形读数),随后是逐行的那几种(`permission_rule_row_removed` / `permission_rule_bucket_unreadable` / `session_rule_row_old_grammar_entries` / `session_rule_row_retired_bucket`)。
397
+ 持久规则 scope 清理半途失败不再自铸「…failed AFTER removing N row(s) — record them before retrying: …」那句拒因,已删的行在被打断的那一行与逐行 warn 里。
398
+ 按旧拒因句文字或 `one_time_migrations_interrupted` 旧键集(只有 `sessionRuleColumn` / `sessionRuleRowsWithOldGrammarEntries`;前者此前在没发布终名时写 `"in-progress"`,现在缺席)解析日志的脚本请改按读数键读。
399
+ 这一次起服的日志是这些读数唯一的出处(重试的起服看见的是已改完的行),请保存。
400
+ 33. **SLA 拒扫腿读过期审批行失败时响亮**:每次一行 warn `deny_sweep_list_failed` + 计数器 `deny_sweep_list_failed_total`,那一拍不扫(此前静默当成没有过期行)。
401
+ 34. **跳版升级库的拒启判据在 PostgreSQL 上按 `search_path` 读**(与起服列册对账同一读法):退役表 `snapshot_manifest` / 退役列 `checkpoint.pending_steer` 住在 `search_path` 后段、
402
+ 裸表名会解析到它的部署,此前不拒、本版起拒(`config.schema_mismatch`)。**出路**:7.125.x 的迁移只看 `current_schema()`,照「先在 7.125.x 起服一次」直接跑看不见后段 schema 里的那两件 ——
403
+ 用 `SELECT table_schema FROM information_schema.columns WHERE table_name = 'checkpoint' AND column_name = 'pending_steer'`(表同理查 `information_schema.tables`)找到它住的 schema,
404
+ 让 7.125.x 起服时把那一个 schema 排在 `search_path` 第一位(如 `ALTER ROLE <角色> SET search_path = <那个 schema>, <其余>`),跑完改回再起本版。其余部署零变化。
405
+ 35. **宿主上的 `docker` / `adb` CLI 不再继承本服务的凭据**(安全,零配置):local-docker / adb 车道起这两只 CLI 时,env = 整份进程环境**减**本服务凭据(配置目录 secret 型变量、
406
+ 模型条目 `apiKeyEnv` 指的变量,按名与值);`DOCKER_*` / `AWS_*` / `ADB_VENDOR_KEYS` 这类 CLI 与凭据助手要读的变量照交。7.131.x 原样继承整份环境(adb 首次调用起的常驻
407
+ adb server 也带着它)。**受伤方**:宿主上读本服务某个凭据变量的 docker 凭据助手 / CLI 插件 —— 换了名的副本也扣(按值比),所以出路是给它**一枚自己的凭据**
408
+ (值与本服务的任何凭据都不同),或改用 docker 自己的凭据存储(`docker login` / `credHelpers`)。
409
+ settings hooks 的命令腿同批改走同一只组合(严格名单十二名不变,零动作)。
410
+ 36. **剥除留痕现场改名(BREAKING,告警规则)**:host shell 那条腿 `site="server.remote-env-host.inherit-scrub"` → `site="server.remote-env-host.spawn-env"`(计数器
411
+ `secret_env_scrubbed_total{site}` 与日志行 `secret_env_scrubbed` 的 `site` 同改,无别名);新增三个现场 `server.remote-env-local-docker.spawn-env` /
412
+ `server.remote-env-adb.spawn-env` / `server.hooks.spawn-env`。**做法**:按旧标签值写的告警 / 过滤改一个值。
413
+ 37. **`LSP_ENV_ALLOW` / `BAKE_ENV_ALLOW` 点名本服务自有凭据名 ⇒ 起服拒**(安全):例如 `LSP_ENV_ALLOW=SERVICE_AUTH_TOKEN` / `BAKE_ENV_ALLOW=MODEL_API_KEY`,拒句点名旋钮与段号、
414
+ 带引擎拒白名单的同一句(`… which is this deployment's own credential …`)。点到的变量**值**是本服务凭据的副本(换了个名)⇒ 放回时被扣下(7.131.x 照放)。
415
+ **做法**:语言服务器 / 配方脚本要凭据 ⇒ 给它一枚自己的(值与本服务的任何凭据都不同),点那个变量名。
416
+ 三只沙箱名单(`E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` / `K8S_SANDBOX_ENV`)不受这一条影响。
417
+ 38. **装了中心鉴权桥、没配 service token 的部署有身份边界**(安全,行为收紧;中心鉴权桥 = `SEMA_WEB_ADMIN_URL` 在位即默认开,或 `AUTH_BRIDGE_ISSUER`):不带任何凭据的
418
+ `GET /v1/sessions` ⇒ `401 auth.unauthorized`(7.131.x:200,列全部会话;trace / 用量列表、fleet 读面、发出的文件链接列表同读),带登录令牌只看得到自己的行
419
+ (别人的会话 ⇒ `404 not_found.session`),`/metrics` 族匿名 ⇒ `401`。
420
+ 只配了 `TRACE_TOKEN` 的部署上 `/metrics` 族匿名同样 ⇒ `401`(7.131.x:200)。判据一句:dev-open ⇔ `/health.auth.kinds` 为空 ∧ 没配 `TRACE_TOKEN` ∧ 没开 `REQUIRE_PRINCIPAL`。
421
+ **做法**:本机工具读会话带登录令牌(Bearer);免凭据抓 `/metrics` 的采集设 `METRICS_TOKEN`。仍成立的边界:没配 service token 时,不带登录令牌的请求自报的主体头仍按身份读 ——
422
+ 要「没令牌就没有身份」配 `SERVICE_AUTH_TOKEN`。
423
+ 39. **`REMOTE_EXEC_HOME_DIR` 在 local-docker / ssh 车道上与执行环境的 `$HOME` 对证**(安全):每只执行环境开起来那一拍问一次 `$HOME`,与声明不一致(去尾斜杠后逐字比)、
424
+ 不是绝对路径或问不出 ⇒ 那只环境不开,工具结果的拒句点名两个值;7.131.x 照开、按声明守错目录。**升级前**:在这两条车道上核一遍声明 = 执行环境里 `printf %s "$HOME"`
425
+ 的输出(`docker run --rm <镜像> sh -c 'printf %s "$HOME"'` / `ssh <目标> 'printf %s "$HOME"'`);不一致就改声明,或让环境以声明的那个用户运行。没声明的部署零动作。
426
+ 40. **没有家目录的执行车道起服一行 warn `execution_lane_home_undeclared`**(随引擎 7.52.0):k8s / local-docker / ssh / adb / device 车道没设 `REMOTE_EXEC_HOME_DIR` 时,
427
+ 每一次泄内容的递归读(`grep -r` / `rg` / `git grep` / `tar c` …)全 shell 面真人问(allow / 模式 / bypass 都放不掉)、只读面拒,无人值守任务检索不了代码。
428
+ **做法**:声明 `REMOTE_EXEC_HOME_DIR=<执行环境里 $HOME 读出的绝对路径>`(local-docker / ssh 上会被对证,见上一条)。
429
+ 41. **受理面的几句拒句改写,拒体多机读位**(码都不变,`request.field_invalid`;新键加性)。锚拒句全文的客户端请改按 `errorCode` + 机读位分支;下面是改了的句子(左 = 7.131.x,右 = 7.132.0):
430
+ - 技能清单超帽:`skill.allowedTools has 1001 entries — …` → `skills[1].allowedTools has 1001 entries — …`;子代技能 `agents[0]: skills[1]: skill.disallowedTools has …` →
431
+ `agents[0].skills[1].disallowedTools has …`(句子与 `field` 点同一个体内坐标)。体加 `field` / `reason: "over_cap"` / `count` / `cap`。
432
+ - 子代定义超限:`agents[i]: agent.<键> must be …` 里**撞帽**的那几形 → `agents[i]: agent.<键>[…] has <n> entries|characters — at most <cap> are accepted`
433
+ (`name` > 64 字、`whenToUse` / `whenToUseLean` / `observer` / `observerMessage` > 4096 字、`systemPrompt` > 65536 字、`allowTools` / `denyTools` > 64 条或单条 > 128 字);
434
+ `at most 32 agents per request` → `agents has 33 entries — at most 32 are accepted`。体加 `field`(`agents[i].<键>[…]` / `agents`)/ `reason`(`over_cap` 条数 · `too_long` 字符数)/ `count` / `cap`;
435
+ 形错(不是串、空串条目)仍是原句、不带机读位。
436
+ - `additionalDirectories` / `additionalReadDirectories`:`each additionalDirectories entry must be a non-empty absolute host path (no '..' segments)` →
437
+ `additionalDirectories[i] must be a non-empty absolute host path (no '..' segments) — got "<原值>"`(体加 `field` / `reason: "bad_entry"` / `index`);
438
+ `additionalDirectories must have at most 64 entries` → `additionalDirectories has 65 entries — at most 64 are accepted`(体加 `field` / `reason: "over_cap"` / `count` / `cap`)。
439
+ - 拒句里回显调用方的串换成一只口径(剥控制与双向字符、截到 64 字 + `…`、引号形):`mcpServers[i]` 写坏的 `name` 值由 32 字变 64 字,`contentOrigin` 坏值不再是 JSON 转义形,
440
+ `toolFaces` 点名的工具名截长;子代定义的未知键 / 重名、`settings.hooks` 拒句里的坐标串段与坏键,正常长度的不变、超长或夹控制字符的按这一口径回显。
441
+ - `settings.hooks`:句子骨架不变;每一只 400 都带 `field: "settings.hooks"` + `detail`(`reason` + 坐标 `path`,见契约附录 A 的 `request.field_invalid` 行),matcher 四形(含第 21 条的 `budget_exceeded`)的 `detail` 多一个 `path`。
442
+ - 射程:请求体上其余的帽(`systemPrompt` / `appendSystemPrompt`、`settings.outputStyle` / `settings.env`、`jobId`、`clientContext`、`sandboxImageProfile`、`outputSchema`、`resumeAt`、技能 `content`、`images`)仍只有句子。
443
+ **出路**:按 `reason` 分支(`over_cap` / `too_long` 读 `field` + `count` + `cap`;`bad_entry` 读 `field` + `index`;`settings.hooks` 读 `detail.reason` + `detail.path`),句子只作展示。
444
+ 42. **工具清单写成已挂载工具的另一种拼法,放行侧也开跑前拒**(随引擎 7.52.0;更正 7.131.0 第 8 条「放行侧的退役名照 7.130.0 受理、交引擎既有通告」—— 有后继的退役名不再照跑):
445
+ 根 `allowTools: ["Task"]` / `["bash"]` ⇒ `400 config.tool_face_control`,句子 `TaskSpec.allowTools declares tool "Task" (tool_name: a retired tool name, now "Agent") in its allowed tools …`;
446
+ 子代定义 `agents[].allowTools` 同两名 ⇒ 同步腿 `400 config.agent.unknown_tool`(体 `{ errorCode, error }`,第 46 条)。两腿零模型调用。改法:写现名(`Agent` / `Bash`)。
447
+ 没有后继的退役名(`MultiEdit`)与内容形(`Agent(Explore)` / `Bash(npm:*)` / `Write(*)`)照旧照跑。
448
+ 43. **规则名在名字层读不出 ⇒ 规则文法拒,句子换成 `invalid.tool_name`**(随引擎 7.52.0)。逐入口:
449
+ - 请求 `settings.permissions.ask` / `deny`(`422`):名字以 `.` 收尾(`mcp__srv.`)、两侧带空白(`" Bash"` / `"mcp__x "`)、名字被读作 `*`(`*` / `*()` / `*(*)`)⇒ `→ invalid.tool_name`。
450
+ 此前:`mcp__srv.` 已拒(句子给铸出写法 `mcp__srv__`);带空白的修剪后照编(`deny: ["mcp__x "]` 读成整台服务器的覆盖规则);`ask: ["*"]` 收下、编出一条永不命中的规则。`allow` 照旧交引擎。
451
+ - 运维三表 `APPROVAL_REQUIRE` / `APPROVAL_DENY` / `APPROVAL_NEVER_AUTO`(起服拒)与中心 `governance.approvalRequire`(整组拒、保前值):`mcp__srv.` 与裸 `*` ⇒ `→ invalid.tool_name`
452
+ (带括号的 `*()` / `*(*)` 在三张运维表上先撞本服务「CC 形规则写法」的拒,原句);`APPROVAL_GRANT` ⇒ `reads as nothing (grammar)` / `(wildcard_all)`。
453
+ 这几个入口按逗号拆、逐项修剪空白 ⇒ 两侧带空白的名照收修剪后的名(不是这一版的变化)。
454
+ - 会话规则写口(`PUT /v1/sessions/:id/policy` 与 `sync/import` 同一只判官):`400 rules.inert_entry`,`reason` 由「这份值按哪一版文法读」定 —— 值带文法戳(`grammar`)按戳读;
455
+ 缺戳而带行 `rev` 的按最早的文法(0)读;两者都不带是新写,按本引擎文法(2)读。读不出的名字(尾 `.`、两侧空白):文法 2 ⇒ `grammar`,更早(戳 0 / 1,或缺戳带 `rev`)⇒ `earlier_grammar`;
456
+ `toolDeny` 的通配名恒 `wildcard_all`;`toolAllow` 的通配名文法 0 ⇒ `earlier_grammar`、文法 1 / 2 ⇒ `wildcard_all`。尾 `.` 此前同码、句子给铸出写法。
457
+ 锚旧句「对端段铸不出 / 写成 `mcp__srv__`」的客户端改按 `errorCode` 与 `reason` 分支。
458
+ 44. **存量会话规则行的 deny 桶带读不出的条目(空串等)⇒ 这一会话每一次调用都拒;非 operator 的规则写 `403 loosen_forbidden`**(随引擎 7.52.0,行为收紧):
459
+ 此前(7.129.0–7.131.x)非 operator 推一份更紧的规则可直接替换这样的行;现在旧行被读作「拒一切」,任何非 operator 的写都算放宽,句子
460
+ `the prior rules refuse every call — their toolDeny holds "" (grammar), which no grammar reads`,行原样不动。出路:operator 写一份不带行 rev 的新值(`PUT /v1/sessions/:id/policy`,operator 身份)。
461
+ 45. **递归读只按它点名的根判(放宽)**(随引擎 7.52.0):`grep -r x sub` 下面有被 `READ_DENY_PATTERNS` 拼写行(`**/secrets/**`)或内建档位(`wallet.dat`)命中的文件时,
462
+ 命令照跑、内容回来(此前点名拒);根点名那个目录 / 文件照拒(`grep -r x sub/secrets`)。目录多于 256 的树不再买待批卡。要护住根下面的目录:把行写成根锚(`<工作区根>/secrets/**`)或家锚(`~/secrets/**`)。
463
+ **根锚 / 家锚护不住的两类**:① 根下面链出工作区的链接被跟随(`grep -R`;BSD 上 `grep -RS`),链接目标(工作区外的文件,包括家目录下的凭据文件)的内容照样回来,`READ_FACE=roots` 也不问 ——
464
+ 容纳判断同样只按根做(点名那只链接本身,如 `cat sub/link`,照旧按根外读问);家目录被 bind 挂进工作区时同理。② 只有拼写行覆盖的凭据类文件(`.ssh/`、`id_rsa*`、`.netrc`、`.git-credentials`)
465
+ 在根下面时随遍历读到(直接点名照拒)。没有恢复旧枚举保护的开关;剩下的护法:结构化 Grep 工具(先按路径剪再读)、点名子目录作根、工作区里不链出去、不把家目录挂进工作区。
466
+ **起服与中心热发会点名你写的非锚定行**:日志一行 warn `read_deny_unanchored_rows` 列出 `READ_DENY_PATTERNS` 与中心 read-face 里既不是根锚也不是家锚的行(起服一次 —— server 与 `run-local` 同一处告知;中心热发的读拒行换了值时再一次;只告知,不改放行 / 拒绝、不拒启;内建档位的行是引擎自己的表,不在其列)。
467
+ 46. **同一类「请求 / 存量写错」的拒,同步腿只剩一种 HTTP 形(wire,码不变只换档)**:下面两码在同步腿(`POST /v1/tasks`)由 HTTP `200` + 终局 `failed` 体改答 **`400`**,
468
+ 体 `{ errorCode, error }`(与受理口先发现时同一键集;`errorCode` = 原 `terminal.code`,`error` = 原 `terminal.message`;`terminal.detail.detail.reason` 不再上 wire,原因词在句子里):
469
+ - `config.agent.unknown_tool`:子代定义 `agents[].allowTools` 里受理口放行、引擎才发现的几形 —— 有后继的退役名(`Task` · `bash`)与文法读不出的拼法(`Bash(`);受理口先拒的几形(拒侧全部、放行侧的大小写孪生)此前就是 `400`。
470
+ - `config.legacy_tool_name`:所在会话的存量规则行(升级前写口收下的)带近似名(`BASH`)· 退役名 · 无前缀 `__` 名 · 工具段为空的协议名 —— 这一会话的每一次提交在准备阶段被引擎拒,此前同样答 `200` + `failed`。
471
+ 只在零 turn、零 token 时答 `400`(verify / cascade 前几轮已经跑过的,照旧 `200` + `failed`);异步 / 活流腿的 HTTP 状态与终态体不变(2xx,同码落在终态 run 行);三条提交腿一致地不占提交幂等键(同一 `Idempotency-Key` 重发按新请求受理,此前这两码的失败占键并回放)。
472
+ **已知边界**(`config.tool_face_control` 此前即如此):引擎在 prepare 里先还原文件(请求键 `rewindFilesTo`,或 `resumeAt` 加 `restoreFiles: true`)、后判工具清单与规则名 ⇒ 带文件还原且清单 / 规则行写错的提交会先还原、再被拒,同键重发会再还原一次;请先改清单(或改写会话规则)再发还原。
473
+ 按 `terminal.code` 读 `200` 体的消费方改读 `400` 体的 `errorCode`。**出路**:子代清单写现名;存量规则行 ⇒ operator 改写那一会话的规则(`PUT /v1/sessions/:id/policy`,operator 身份,写一份读得出的新值)。
474
+ 47. **一次性迁移 M17 遇读不出的 deny 行不改写、不盖戳**(更正 7.129.0 节「`toolDeny` 一个字节不动、不点名」;只影响从 7.128.x 及更早直升 7.132.0 的 SQL 部署):M17 在改列名那一拍给每一行盖当前文法戳,盖之前先问引擎;`toolDeny` 里有引擎读不出的条目
475
+ (空串、`-deploy`、非 ASCII 名、`(` 前带不可见空白 ……)的行**整行原样留**(同行 `toolAllow` 里该删的条目也不动),起服日志逐行一条 warn `session_rule_row_unreadable_deny`
476
+ (`policyKey` / `sessionId` / `toolDenyUnreadable: [{ entry, reason }]`,`reason` 是引擎读者的原因词),读数行 `one_time_migrations_applied` 多一键 `sessionRuleRowsWithUnreadableDeny`。
477
+ 这样的会话引擎本来就每一次工具调用都拒(第 44 条);不盖戳让引擎对它继续发旧文法通告 `config.session_rules_earlier_grammar`(盖了戳,拒一切照旧、通告却消失)。
478
+ 读得出的行照改照盖戳,与此前逐字相同(`BASH` 这类读得出、只是没有对应工具的 deny 条目不算读不出)。**出路**:按点名的行(`policyKey` ↔ `sessionId`)用 operator 身份 `PUT /v1/sessions/:id/policy`
479
+ 写一份读得出的新值(不带行 rev),或删该会话(删会话即删规则)。**同一行还带退役命令桶**(`commandAllow` / `commandDeny`;该行的 warn 多一键 `retiredBuckets`,另有 `session_rule_row_retired_bucket` 点名同一行)
480
+ 的,会话规则的 `PUT` 读不了这样的行(退役桶读成 `corrupt`,operator 也一样,答 `500`):出路是在库里按新文法改写那一行(`rev` / `gen` 不动)或删会话。这条收据只在改名那一次起服的日志里,请保存;之后起服不再列出,引擎的旧文法通告仍在每一跑发。
481
+ 48. **更正 7.131.0 第 8 条对请求体规则表的陈述:`settings.permissions.deny` / `ask` 上那四族写法 7.129.1 时就已 `422`,7.131.0 在这两张表上新拒的只有大小写孪生**(文字更正;行为不变,升级零动作):
482
+ 7.131.0 第 8 条把请求体 `settings.permissions.deny` / `ask` 与工具名选择器清单并在同一节里写,标题括号里的「7.129.0–7.130.x 只告运维」读起来对它们同样成立,条目清单也像是一并新拒 —— 对这两张规则表不成立。
483
+ 下表是在 7.129.1 与 7.131.0 的代码上对同一组条目逐条实跑的读数(`deny` 与 `ask` 两桶读数一致;`422` 的句首是 `request settings cannot be applied as written: …`):
484
+
485
+ | 写法(例) | 7.129.1 | 7.131.0 | 7.132.0 |
486
+ | --- | --- | --- | --- |
487
+ | 退役名:`bash` · `Task` · `KillShell` · `MultiEdit` | `422` | `422` | `422` |
488
+ | 协议名写不成现役工具:`figma__x`(无协议前缀)· `mcp__figma__`(缺工具段)· `mcp__git*__x` · `mcp__*` · `a2a__*`(对端段带通配) | `422` | `422` | `422` |
489
+ | 协议名的对端段写成域名形:`mcp__github.com__x`(引擎铸的对端段是 `github_com`) | `422` | `422` | `422` |
490
+ | 内容文法写坏(引擎的规则文法编不出):`Bash(ps` · `Bashps)` · `Bash(echo $HOME)` · `Bash(rm * -rf)` · `Agent(x)`(缺 `param:pattern`;`Agent(agentType:*)` 受理)· `Monitor(touch:*)`(命令规则要写成 `Bash(touch:*)`) | `422` | `422` | `422` |
491
+ | **大小写孪生**:`BASH` · `BASH(*)` · `SENDUSERFILE` · `write` | 受理(名册为空,读不出孪生) | **`422`(7.131.0 新拒)** | `422` |
492
+ | 首尾空白:`" Bash"` · `"mcp__x "`;裸 `*` · `*()` | 受理 | 受理 | `422`(第 43 条) |
493
+
494
+ 所以从 7.129.x–7.130.x 升到 7.131.0,这两张规则表上**唯一**新被拒的是大小写孪生(此前名册是空的,孪生读不出、什么也不拒;7.131.0 起名册是引擎目录加本服务自铸工具名的那一张);前四族早就拒,不是 7.131.0 的行为变化。
495
+ 第 8 条「文法读不出」括号里的首尾空白与 `*`,在这两张规则表上 7.131.0 同样受理,到 7.132.0 才拒(第 43 条)。其余各表(根 / 子代工具名清单、技能清单、`permissions.allow`)不在本条射程。
496
+ **出路**:无需动手。核对自己的请求体时,孪生写现名(`BASH(*)` ⇒ `Bash(*)`),其余按拒句改。
497
+ 49. **hook / 标题腿的直连请求:per-model 凭据绑它第一次发出去的主机**(引擎 7.53.0,安全,行为收紧):直连腿(prompt 型 hook 条目与会话标题)改过引擎一方 brain 的同一只请求门 ——
498
+ 一把 per-model 凭据(`apiKeyEnv` / 托管密钥)第一次随请求发往哪台主机,本进程里它就只认那台;之后同一把凭据要发往另一台主机 ⇒ 拒,失败码 `route_refused`,
499
+ 句首带 `route.credential_origin_mismatch`,一个字节不出门(主路由的 brain 早已如此,直连腿此前只问只读判官、什么都不绑)。同主机换路径不算。
500
+ **谁要动手**:把目录条目的 `baseUrl` 换到另一台主机、凭据引用却没换的部署。**出路**:换主机的同一步换凭据引用(新凭据是新绑定),或重启本服务(绑定只活在进程里)。
501
+ 50. **请求体两处受理面收紧**(引擎 7.53.0):
502
+ - `a2aPeers[i].toolAxes` 的读者是引擎的判官(与 `mcpServers[i].toolAxes` 同一只):每只 skill 的记录里多一个成员(笔误)、出现 `__proto__` 键、不是纯数据 ⇒ 那一条对端整条不挂,
503
+ 运维 warn `a2a_injection_dropped` 点名,任务照跑;此前未知成员静默忽略、照挂。**升级前停驻的任务不受影响**:续跑重放存下的请求体时,一次性迁移 M19(与 7.130.0 节
504
+ `mcpServers[].toolAxes` 同一只、同一个窗)把判官判不过的那一格按 7.131.x 的 A2A 读法重读一次 —— 只多了成员的对端照挂、一行运维 warn `a2a_tool_axes_read_as_before_upgrade`;
505
+ 已知轴写坏(`effect` / `irreversibility` 出词表、`egress` 非布尔、某只 skill 的值不是对象、整份不是对象)的对端 7.131.x 当时就整条丢了,续跑照旧整条不挂(`a2a_injection_dropped` 点名),
506
+ 不会因迁移多挂上;窗关(2026-11-15)之后才续跑的这类停驻行回到「整条不挂」—— 停驻在那条对端 skill 上的审批请在窗内决掉。
507
+ - `mcpServers[i].transport.env` / `transport.headers` 与 `a2aPeers[i].headers` 里名叫 `__proto__` 的键 ⇒ MCP 那两键新提交 `400 request.field_invalid`,拒句点名那个成员
508
+ (`mcpServers[i].transport.headers.__proto__`);A2A 对端整条不挂。此前原样交给引擎,引擎 7.53.0 对这样的声明整单拒、一轮不跑。直接调用请求腿读器的嵌入方:
509
+ `Map`、类实例、`process.env` 作 env / headers 同判(拒句点名那个键;拷成普通对象:`{ ...process.env }`);不可枚举的自有成员也是成员(与引擎同读)。
510
+ **续跑重放存量体**(MCP 两键与 A2A `headers` 同一只读法;存体是 JSON 铸出来的,等价只对 JSON 存体成立 —— 7.131.x 的判据对带自有串属性的类实例也收,上一句的更严处置对直接递对象的嵌入方生效):复现 7.131.x —— 记录里有值不是串的成员 ⇒ 照旧不交(MCP 整键不交、server 照挂;A2A 对端照旧不挂);
511
+ 只有 `__proto__` 名的成员坏、其余全是串 ⇒ 剔掉它、其余照交、server / 对端照挂(7.131.x 整张照收;此前同版本续跑 MCP 整张不交、A2A 整条不挂)。
512
+ 真挂上的那一台一行运维 warn:`mcp_transport_members_dropped { server, lost, lostTotal?, note }` / `a2a_peer_headers_members_dropped { peer, lost, note }`,点名没交出去的键或成员,不带值。
513
+ **出路**:按拒句 / warn 点名的那一格改写声明。
514
+ 51. **消费方(壳 / SDK)要跟的 wire 变化**(引擎 7.53.0;键名不变的值变化与加性帧):
515
+ - 任务流新帧 `compaction_started { trigger, pass, startedAt }`(live 流与 `GET /v1/runs/:id/events`;trace 流不投):对帧类型穷尽分派的消费方加一臂;
516
+ 「压缩中」从它起,到同一个 `pass` 的 `compacted` / `compaction_outcome` 收(两只结束帧多一个可选 `pass`),不按「下一只 `compacted`」收。
517
+ - 通告 `config.session_rules_earlier_grammar` 进会话流(白名单 41 码,契约附录 D.3);从运维日志 `runner_config_advisory` 读它的不再读得到。
518
+ - `permission.rule_row_dropped` 的 `detail.rows[].rule` 是规则原串(至多 1 024 码点 + 截断记号,控制字符随行):渲染前自己中和,同 `entries[].entry`。
519
+ - MCP 重拨回执的 `toolCount` / `added` / `removed` / `toolNames` 与 `wiring_manifest.mcp[].toolCount` 是 run 名册的读数(阀门与部署工具面覆盖之后,`toolCount === toolNames.length`),
520
+ 不是服务器清单;服务器清单读 `POST /v1/capabilities/mcp/probe`。
521
+ - 续跑拒(409)的 `blockedBy` 闭集 9 → 40 词,`field` 多 `deps`(修部署后同一张卡再决),`reason` 多 `unknown_model_ref` / `not_a_model_ref`:把这几位钉成闭集的消费方加词。
522
+ - `config.user_attachment_invalid` 的终局 `terminal.detail` = `{ kind: "coded", detail: { path, index? } }`,同步腿 400 体多一键 `detail`(同一份 `{ path, index? }`):
523
+ `index` 在场 ⇔ 句子点名一只附件,可据它指向那一条。
524
+ - Artifact 工具的审批卡(引擎 7.53.0):带规则席的腿上卡带 `ruleOffers: [{ kind: "single", rule: "Artifact(action:<词>)", match: "name", command: "<词>" }]`,
525
+ 或在强制问等门下带一个 `ruleOffersAbsence` 词;此前两席都缺席。渲染审批卡的消费方(cli / client-core / web-client / sdk)照 Skill 卡那样渲这一条「不再问」,
526
+ 兑付时 `command` 取 offer 的 `command`;把 Artifact 卡当「没有 offer」的界面要改。
527
+ - 提交口库墙门的 `413 request.payload_too_large` 体多一键 `wallSource`(只看「拒它的那堵墙的数字是不是库自己报的」):`"reported"` = 库报的墙(句子点名库的上限与旋钮,缩小或请运维抬);
528
+ `"assumed"` = 不是库报的、按最保守的缺省墙拒 —— 引擎事实还没读到,或事实在场但这一堵墙读失败退了文档缺省(TiDB < 7.6 又无 `CONFIG` 权限读不到单行上限;`max_allowed_packet` 读不出)
529
+ (句子说「the database's … limit was not read … retry shortly; if it persists, ask the operator …」;事实没读到的窗口里稍后重试按库报的墙重判,读失败退缺省的要运维让服务读得到那个上限)——
530
+ 按它分「先重试 / 请运维」与「缩小」,不解析句子。`GET /v1/diagnostics/wiring` 的 `sqlEngine` 段多一键 `wallSources`(两堵墙各自的出处,operator 面,加性)。
531
+ `PUT /v1/sessions/:id/sync/blobs/:hash` 超帽的 `413 blob_too_large_for_sql` 同样带 `wallSource`,词多一个 `"operator"`(帽是运维设的 `SNAPSHOT_BLOB_SQL_MAX_BYTES`),句子按三形分。
532
+ 52. **中心提示层只有一种 wire 形:`{ schemaVersion: 2, artifact }`(BREAKING;settings-schema 14.0.0 + 引擎 7.53.0)**。中心下发的 `prompts` 键与本地 `config.d/prompts.json` 读出的中心层,
533
+ 判官只有一只:契约包的 `EffectivePromptsWire` 先过,再交引擎 `verifyPromptArtifact`(artifact 是引擎当期 schema 3)。下面这些 ⇒ **整份候选拒**(一个域都不应用,停在上一份好配置 / LKG / env),
534
+ `config_candidate_rejected` 点名 `prompts`,`errors` 是契约包 / 引擎的原句:
535
+ - 13.x 的两轴 wire(`{ schemaVersion: 1, declarations?, catalog? }`)—— 句:`prompts wire schemaVersion: this contract carries {schemaVersion: 2, artifact} only — the declarations / catalog axes were retired in settings-schema 14.0.0; the center serves its center artifact (upgrade the center)`;
536
+ - 外壳对、内层是 v2 artifact —— 句:`artifact payload schemaVersion: this contract carries schemaVersion 3 only — rebuild the artifact with the engine's buildPromptArtifact (an overlay's "scope": {"binding": b} becomes "when": {"binding": {"anyOf": [b]}})`;
537
+ - 同一目标一条无条件 `replace` 与一条按场景的 `replace`(可同真)—— 引擎句:`overlays "<p>" and "<q>" both replace "<target>" under one condition that can hold in the same run (write exclusive binding conditions: "noneOf": [x] beside "anyOf": [x])`;
538
+ - digest 与载荷对不上;**存储原文**放上 wire(`{ artifact }` / 13.x 的物化底座 `{ bindings: [] }` / `{}`);`null`。
539
+ **生效时序**:新会话即生效;在飞会话钉着首跑时的 artifact,到压缩 / 新会话才换(引擎按会话钉住首跑时的中心层,续跑按 digest 解析那一份)—— 发布之后已在跑的会话不立刻换。
540
+ 中心不带 `prompts` 键 = 不下发中心层,已采纳的中心层撤下(与此前同)。此前边界上的三只归一臂(两轴形 / 平铺三键 / 存储形投影 `catalog`)删除 —— 不带 worker 的拉取发来的存储原文不再被当作中心层收下。
541
+ **部署序**:web-admin(中心)与本服务**同一维护窗**升级,**先 web-admin 后本服务**;回滚**先 web-admin 后本服务**。窗内两端互拒对方的形(新服务收到旧中心的两轴 wire 或不带 worker 的拉取里的
542
+ 存储原文 / 旧服务收到新中心的 v2 外壳 ⇒ 都是整份候选拒,停在 LKG,刷新拍持续点名到另一端升级)。中心须在本服务升级前把中心 artifact 全部重发成 schema 3。
543
+ **本地 `config.d/prompts.json`**:形是 `{ artifact?, workers? }`(`artifact` = 中心编辑器导出的 artifact 身份 `{ payload, artifactDigest }`);本地腿没有 worker 身份 ⇒ 恒读 `artifact`,
544
+ 发布出处记 `local:r<配置版本>`。还带 `bindings` / `catalog` 的文件被契约包的墓碑拒(整份本地候选拒,句点名一次性迁移 SS-M10)⇒ 跑 `npx @sema-agent/settings-schema migrate <config.d 目录>`
545
+ (空的 `bindings: []` 删掉;非空的 `bindings` 本地从来没生效过,删掉;`catalog` 从中心重新导出)。
546
+ **运维日志**:`center_prompts_adopted` 只带 `phase` / `artifactDigest` / `sourceRevision` / `note`(`axes` / `packId` / `contentDigest` / `sections` / `scenarioOverrides` / `catalogDigest` 删);
547
+ 中心源启动恢复读到一份引擎拒的 / 读不出的副本 ⇒ 一行 `prompt_composition_warning`(`classification: "center-source-restore"`,句子说是哪份、为什么、之后怎样)。
548
+ 53. **钉着 v2 artifact digest 的会话没有退路**(引擎 7.53.0 原话):`a session whose record pins a v2 digest fails prompt.snapshot_unavailable on its next run, the failure's sentence and one operator line saying the copy is refused and how to republish it (no converter, no dual read)`;
549
+ `Publish v3 only and never put a v2 artifact into production — a session pinned to a v2 digest has no way back.` 7.131.x 的引擎读写的是 v1(第 17 条那一族,由中心源三态处置),v2 从未上线过的部署这一族为空。
550
+ **谁要动手**:曾在生产里发布过 v2 artifact 的中心。**出路**:只发 v3;撞上的会话重新开一只。
551
+ 54. **场景名写进 `promptBinding`**(每个请求;HTTP 腿与 `run-local` 同一写点):中心 artifact 里按场景写的段用 `when: { binding: { anyOf: ["<场景名>"] } }`(或 `noneOf`)表达,
552
+ 一条通用的 `replace` 旁边要写场景的那一条时,通用那条写 `noneOf: ["<场景名>"]`、场景那条写 `anyOf`(否则第 52 条第三形整拒)。委派子代经父 spec 座继承同一个场景名。
553
+ 55. **品牌部署的品牌行**(`CONFIG_PROVIDER=local` 与 `run-local`):`default` / `code` 两场景模型收到的 role 层以品牌行开头,字节与 7.131.0 相同;改由部署座一条 overlay 承载 ——
554
+ 清单 `prompt_assembled` 的 role 档多一段 `sema/identity`(排在 `core/role.base` 之前)。`code-review` / `scan` / 中心声明的场景与委派子代不带。按段 id 统计的消费方注意这一段。
555
+ 56. **「本会话没有持久记忆」由引擎判、引擎渲染**(零配置):目录条目 `core/memory.no-persistent-store`,条件 = 记忆面没挂 ∧ 名册不能持久(部署声明 `MEMORY_PERSISTENCE_CAPABLE` 优先,
556
+ 否则引擎按阀门留下的名册推断:本机可写的 `Write` / `Edit` / shell 才算)∧ 不是委派子代。本服务的每请求判别式退役;`MEMORY_PERSISTENCE_CAPABLE=true` 照旧撤回披露,host 车道的自动声明照旧。
557
+ **行为变化**:委派子代不再带这段披露。**谁受伤**:挂了 MCP 记忆服务器(写工具不带 `pathTarget` 面)而本机没挂记忆面的部署 —— 引擎照样说「没有持久记忆」(与 7.131.x 的判别同判)。
558
+ **出路**:`MEMORY_PERSISTENCE_CAPABLE=true`,或给那只写工具声明 `toolFaces.<tool>.pathTarget`(`access: "create"`,仅本机手带时有效)。
559
+ 57. **盘上 LKG 信封 `formatVersion` 5**(载荷的 `prompts` 是第 52 条那一种形):升级后第一次读回 4(及更早)—— 载荷不带 `prompts` ⇒ 照读,按 5 写回,一行 `config_lkg_migrated`;
560
+ 带 `prompts`(13.x 的两轴 wire)⇒ 不读回(`config_lkg_unusable` 点名 formatVersion 与 prompts),中心可达照拉、断着 env 兜底。回滚到 7.131.x 读 5 ⇒ `unknown formatVersion 5`(不可用、响亮)。
561
+ 58. **`Artifact(action:<词>)` 是一条规则**(引擎 7.53.0;行为变化,放宽 + 收紧各一面):`<词>` 取 Artifact 工具声明的动作集(精确词,不收 `*`),请求 `settings.permissions` 的
562
+ deny / ask / allow 与引擎的规则店同一读法。**限制侧**(deny / ask):7.131.x 读成「内容形工具带了内容」(`content_unsupported`)⇒ 受理口 400;现在受理并生效(deny 拒那一个动作、ask 问)。
563
+ **放行侧**(allow):7.131.x 受理但什么都不放(读成空);现在**生效** —— 一条 allow 清掉那一个动作的普通问(从不消音强制问)⇒ 升级后存量请求 / 设置里的这类 allow 条目开始放行(权限面放宽)。
564
+ Artifact 审批卡随之带 `ruleOffers`(见消费方 wire 变化那一条)。**谁要动手**:把 allow 侧这类条目的惰性当成保护的部署 —— 升级前核自己的 allow 表,不想放行的删掉;
565
+ 集外词 / 通配照旧读不成规则(限制侧 400、放行侧读成空)。
566
+ 59. **嵌入方(自建 `ServiceDeps` 的进程):`snapshotBlobSqlCapBytes`(数字)→ `snapshotBlobSqlCap`(读口 `() => { capBytes, source } | undefined`)**(包根导出型 `ServiceKnobDeps` 的座;平铺形与 `knobs` 组同判)。
567
+ 本服务每个 `PUT /v1/sessions/:id/sync/blobs/:hash` 调一次它、按答案前置 413(`undefined` = 此刻没有帽)—— 门限随库报的墙走,不再是起服时算好的一个数;`source` 说帽从哪来
568
+ (`"operator"` = 你自己设的固定帽 / `"reported"` = 由库报的墙推出 / `"assumed"` = 库的上限没读到、按最保守的缺省墙推出),413 的句子与体上的机读位 `wallSource` 同词分三形。
569
+ **改法**:固定帽 `snapshotBlobSqlCapBytes: N` → `snapshotBlobSqlCap: () => ({ capBytes: N, source: "operator" })`;按你的库事实现算的函数答对应的 `source`;不需要前置 413 就不传。
570
+ 照旧传 `snapshotBlobSqlCapBytes` ⇒ `createHttpServer` **起服拒**,拒句点名新键与新形(TypeScript 嵌入方在编译期就红);`snapshotBlobSqlCap` 不是函数 ⇒ 同样起服拒。没有兼容臂:数字不会被当成固定帽收下。
571
+ 60. **`READ_DENY_BUILTIN_EXCLUDE` 里写 `.npmrc` / `.pypirc` ⇒ 起服拒**(引擎 7.52.0;部署面 BREAKING):内建读拒表 `credentials` 档里这两行换成家锚的 `~/.npmrc` / `~/.pypirc` ——
572
+ 家目录里那一对照旧拒,项目里自带的同名文件在每种权限模式下读得到(读到即交给模型;执行环境没声明家目录时仍拒)。7.131.x 的旧行名不再是表里的行名:server 与 `run-local`
573
+ 起服拒,拒句点名新行名;中心 `readFace` 域发同一值 ⇒ 那一份发布整域拒(`web_admin_read_face_invalid`,读面停在上一份合法姿态)。
574
+ **改法**:删掉这两个值(家目录那一对仍由内建行护着,项目里那一对已不在表里);确要让模型读家目录那一只 ⇒ 改写成 `~/.npmrc` / `~/.pypirc`;
575
+ 要项目里那一对照旧拒 ⇒ 把 `.npmrc` / `.pypirc` 加进 `READ_DENY_PATTERNS`。
576
+ 61. **嵌入方(自建 `ServiceDeps` 的进程):`sqlEngineFacts` → `sqlEngine`**(`ServiceDeps` 平铺形的座):由「只给事实」的读口 `() => SqlEngineFacts | null` 改成本池的引擎读口
577
+ `{ dialect: "tidb" | "pg", facts }` —— `facts` 活读(池重连后随连接初始化刷新),`null` = 事实此刻没建立。提交受理口的库墙门、诊断面 `sqlEngine` 段与能力位 `store.sql`
578
+ 读它(`PUT /sync/blobs` 的前置帽仍是你自己传的 `snapshotBlobSqlCap` 读口,见第 59 条);墙的方言只从这里来(此前受理口另从店后端 `backend.kind` 取方言)。没有 SQL 后端就不传;**SQL 后端在场 ⇒ `sqlEngine` 必填**(你递的 `backend` 交出了 `mysqlPool()` / `pgPool()`,MySQL 协议与 PostgreSQL 同一条律):
579
+ 没给 ⇒ `createHttpServer` **起服拒**,拒句点名 `sqlEngine` 与它的形 —— 席缺席只表示「没有 SQL 后端」,不会被读成「没有墙」而放行超出库墙的体(本服务自己的装配有池就给读口)。
580
+ **改法**:把 `sqlEngineFacts: () => f()` 换成 `sqlEngine: { dialect, get facts() { return f(); } }`(`dialect`:MySQL 协议 = `"tidb"`,PostgreSQL = `"pg"`)。照旧传 `sqlEngineFacts` ⇒
581
+ `createHttpServer` **起服拒**,拒句点名新键与它的形(TypeScript 嵌入方在编译期就红)。没有兼容臂。**`sqlEngine` 的值形也在起服时判**:`{ dialect: "tidb" | "pg", facts }`,`facts` 是 `null` 或带 `maxRowBytes` / `maxPacketBytes` / `wallSources`
582
+ 的引擎事实;只改了键名、值还是 7.131.x 的 `() => facts`(或缺 `facts`、方言词出闭集、事实缺 `wallSources`)⇒ 起服拒,拒句点名键与形(此前:起得来,之后每一次提交 500)。自己手铸引擎事实的嵌入方:事实多了必填的 `wallSources`
583
+ (`{ maxRowBytes, maxPacketBytes }`,各为 `"reported"` | `"assumed"`;读到的 / 按构造没有的墙是 `"reported"`,读失败退缺省的墙是 `"assumed"`)。
584
+
10
585
  ## 7.131.0 —— hooks 配置受理收紧(两类此前受理的坏形 400 · 本仓不执行的条目类型整份拒)· 模型能力位 `reasoning` / `vision` 三态(env 缺省与中心回落退役)· settings-schema 13.0.1 精确钉 · 写错的工具名恢复开跑前拒并点名现名(限制侧四类全拒、放行侧只拒近似名;一张名册;拒句有界;续跑按方向分流)
11
586
 
12
587
  1. **`settings.hooks` 只有一只读者,两类此前受理的坏形现在 `400 request.field_invalid`**(零 DDL):新提交(`POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs`)里