@sema-agent/server 7.148.0 → 7.150.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 (360) hide show
  1. package/MIGRATION.md +551 -9
  2. package/README.md +17 -2
  3. package/README.zh-CN.md +5 -1
  4. package/USAGE.md +126 -68
  5. package/dist/adoption/wire.d.ts +3 -3
  6. package/dist/approval-card.d.ts +33 -33
  7. package/dist/approval-gate-currency.d.ts +1 -1
  8. package/dist/approval-leg-origin.d.ts +33 -0
  9. package/dist/approval-leg-origin.js +4 -0
  10. package/dist/audit.d.ts +1 -1
  11. package/dist/audit.js +2 -2
  12. package/dist/auth-bridge.d.ts +9 -1
  13. package/dist/auth-bridge.js +4 -4
  14. package/dist/auth-keys.d.ts +10 -1
  15. package/dist/auth-keys.js +8 -0
  16. package/dist/background-session-reap.d.ts +1 -1
  17. package/dist/boot/deferred-sandbox-path-env.d.ts +5 -3
  18. package/dist/boot/deferred-sandbox-path-env.js +1 -2
  19. package/dist/boot/execution-env.js +10 -11
  20. package/dist/boot/execution-lane.d.ts +6 -4
  21. package/dist/boot/execution-lane.js +3 -1
  22. package/dist/boot/org-delivery.d.ts +3 -2
  23. package/dist/boot/parked-revive-gate.d.ts +5 -5
  24. package/dist/boot/parked-revive-gate.js +2 -3
  25. package/dist/boot/resolve-spec.d.ts +4 -5
  26. package/dist/boot/resolve-spec.js +66 -28
  27. package/dist/boot/retention-lane.d.ts +1 -1
  28. package/dist/boot/runner-deps.js +3 -1
  29. package/dist/boot/session-faces.js +21 -21
  30. package/dist/boot/stage-01-config.d.ts +1 -0
  31. package/dist/boot/stage-01-config.js +4 -3
  32. package/dist/boot/stage-02-web-admin-pull.d.ts +1 -0
  33. package/dist/boot/stage-02-web-admin-pull.js +10 -2
  34. package/dist/boot/stage-03-store-backend.d.ts +1 -0
  35. package/dist/boot/stage-03-store-backend.js +4 -4
  36. package/dist/boot/stage-04-stores.d.ts +1 -0
  37. package/dist/boot/stage-05-execution-env.d.ts +1 -0
  38. package/dist/boot/stage-06-runners.d.ts +2 -1
  39. package/dist/boot/stage-06-runners.js +1 -2
  40. package/dist/boot/stage-07-capability-layer.d.ts +2 -1
  41. package/dist/boot/stage-07-capability-layer.js +1 -1
  42. package/dist/boot/stage-08-reapers.d.ts +2 -1
  43. package/dist/boot/stage-09-leader.d.ts +2 -1
  44. package/dist/boot/stage-10-http-server.d.ts +35 -2
  45. package/dist/boot/stage-10-http-server.js +9 -4
  46. package/dist/boot/stores.d.ts +3 -0
  47. package/dist/boot/stores.js +22 -19
  48. package/dist/boot/web-admin.d.ts +1 -1
  49. package/dist/capabilities/tool-defer.d.ts +1 -1
  50. package/dist/capability-facts.d.ts +70 -60
  51. package/dist/capability-facts.js +45 -49
  52. package/dist/card-settle-stored-scope.d.ts +56 -0
  53. package/dist/card-settle-stored-scope.js +27 -0
  54. package/dist/card-void.d.ts +7 -12
  55. package/dist/card-void.js +2 -7
  56. package/dist/config-catalog.d.ts +12 -0
  57. package/dist/config-catalog.js +37 -33
  58. package/dist/config-invariants.d.ts +5 -4
  59. package/dist/config-invariants.js +4 -4
  60. package/dist/config-types.d.ts +49 -16
  61. package/dist/config.d.ts +6 -5
  62. package/dist/config.js +35 -24
  63. package/dist/context-window-notice.d.ts +31 -0
  64. package/dist/context-window-notice.js +28 -0
  65. package/dist/deployment-governance.d.ts +7 -28
  66. package/dist/deployment-governance.js +1 -14
  67. package/dist/deployment-shape.d.ts +20 -11
  68. package/dist/deployment-shape.js +1 -0
  69. package/dist/device-ws-hub.d.ts +1 -0
  70. package/dist/device-ws-hub.js +64 -28
  71. package/dist/device-ws-protocol.d.ts +20 -6
  72. package/dist/device-ws-protocol.js +9 -2
  73. package/dist/engine-identity.d.ts +7 -1
  74. package/dist/engine-identity.js +5 -0
  75. package/dist/env-name-allowlist-knobs.d.ts +6 -5
  76. package/dist/env-name-allowlist-knobs.js +5 -0
  77. package/dist/execution-lane-caps.d.ts +20 -5
  78. package/dist/execution-lane-caps.js +18 -4
  79. package/dist/field-conflict.d.ts +2 -2
  80. package/dist/fleet/engine-signal.d.ts +14 -1
  81. package/dist/fleet/engine-signal.js +5 -1
  82. package/dist/fleet/fleet-reconciler.d.ts +1 -1
  83. package/dist/fleet/serving-lease.d.ts +18 -3
  84. package/dist/fleet/serving-lease.js +81 -35
  85. package/dist/fleet-client.d.ts +13 -11
  86. package/dist/fleet-client.js +53 -33
  87. package/dist/history-anchor.js +1 -1
  88. package/dist/hitl-delivery.d.ts +1 -3
  89. package/dist/hitl-delivery.js +1 -1
  90. package/dist/hooks/command-spawn.d.ts +7 -2
  91. package/dist/hooks/command-spawn.js +13 -6
  92. package/dist/hooks/hook-runner.d.ts +5 -0
  93. package/dist/hooks/hook-runner.js +11 -7
  94. package/dist/http/active-run-conflict.d.ts +3 -7
  95. package/dist/http/active-run-conflict.js +2 -2
  96. package/dist/http/admission.js +5 -5
  97. package/dist/http/approval-sweeps.js +5 -3
  98. package/dist/http/caller-trust.d.ts +2 -2
  99. package/dist/http/caller-trust.js +3 -3
  100. package/dist/http/checkpoint-ctx.d.ts +18 -63
  101. package/dist/http/checkpoint-ctx.js +1 -24
  102. package/dist/http/claim-heartbeat.d.ts +6 -6
  103. package/dist/http/claim-heartbeat.js +6 -6
  104. package/dist/http/claimed-run.d.ts +16 -9
  105. package/dist/http/claimed-run.js +8 -0
  106. package/dist/http/dispatch.js +7 -5
  107. package/dist/http/durable-run-leg.d.ts +8 -1
  108. package/dist/http/durable-run-leg.js +34 -15
  109. package/dist/http/execution-context.d.ts +115 -14
  110. package/dist/http/execution-context.js +130 -40
  111. package/dist/http/owner-access.d.ts +246 -21
  112. package/dist/http/owner-access.js +186 -8
  113. package/dist/http/principal-gate.d.ts +18 -11
  114. package/dist/http/principal-gate.js +3 -1
  115. package/dist/http/readiness.d.ts +4 -2
  116. package/dist/http/resume-ctx-read.d.ts +14 -3
  117. package/dist/http/resume-ctx-read.js +24 -3
  118. package/dist/http/resume-legs.d.ts +35 -3
  119. package/dist/http/resume-legs.js +262 -106
  120. package/dist/http/route-ctx.d.ts +29 -11
  121. package/dist/http/routes/a2a-serve.js +17 -14
  122. package/dist/http/routes/approvals-assistant.d.ts +3 -2
  123. package/dist/http/routes/approvals-assistant.js +11 -11
  124. package/dist/http/routes/capabilities.js +5 -4
  125. package/dist/http/routes/config-catalog.d.ts +1 -1
  126. package/dist/http/routes/diagnostics.d.ts +3 -1
  127. package/dist/http/routes/diagnostics.js +30 -5
  128. package/dist/http/routes/mcp-reconnect.js +2 -2
  129. package/dist/http/routes/memory-origin.d.ts +1 -1
  130. package/dist/http/routes/notify-wake.js +2 -3
  131. package/dist/http/routes/principal-inbox.d.ts +3 -1
  132. package/dist/http/routes/principal-inbox.js +3 -2
  133. package/dist/http/routes/projects.d.ts +1 -0
  134. package/dist/http/routes/projects.js +5 -3
  135. package/dist/http/routes/retention-ops.d.ts +1 -1
  136. package/dist/http/routes/run-permission-mode.d.ts +1 -1
  137. package/dist/http/routes/run-permission-mode.js +2 -2
  138. package/dist/http/routes/runs.d.ts +1 -1
  139. package/dist/http/routes/runs.js +33 -37
  140. package/dist/http/routes/session-memory-sync.js +4 -5
  141. package/dist/http/routes/session-sync.d.ts +24 -5
  142. package/dist/http/routes/session-sync.js +45 -37
  143. package/dist/http/routes/sessions-list.d.ts +1 -1
  144. package/dist/http/routes/sessions.d.ts +1 -1
  145. package/dist/http/routes/sessions.js +18 -44
  146. package/dist/http/routes/tasks.js +136 -101
  147. package/dist/http/routes/trace-usage.js +14 -14
  148. package/dist/http/routes/workflows.d.ts +1 -0
  149. package/dist/http/routes/workflows.js +20 -38
  150. package/dist/http/server.d.ts +12 -9
  151. package/dist/http/server.js +35 -6
  152. package/dist/http/stored-body-replay.d.ts +3 -24
  153. package/dist/http/stored-body-replay.js +2 -12
  154. package/dist/http/submit-ctx.d.ts +2 -2
  155. package/dist/http/submit-ctx.js +5 -5
  156. package/dist/http/submit-replay.d.ts +15 -2
  157. package/dist/http/submit-replay.js +10 -4
  158. package/dist/http/wire-types.d.ts +6 -3
  159. package/dist/index.d.ts +3 -1
  160. package/dist/index.js +1 -0
  161. package/dist/leader/endpoint.js +9 -8
  162. package/dist/leg-facts.d.ts +13 -2
  163. package/dist/leg-facts.js +2 -0
  164. package/dist/local-store-declaration.d.ts +54 -0
  165. package/dist/local-store-declaration.js +59 -0
  166. package/dist/mcp-assertion-header.d.ts +1 -1
  167. package/dist/mcp-assertion-header.js +1 -1
  168. package/dist/mcp-authorization-face.d.ts +18 -14
  169. package/dist/mcp-authorization-face.js +3 -2
  170. package/dist/memory-project-layer.js +1 -1
  171. package/dist/memory-scope.d.ts +4 -4
  172. package/dist/memory-scope.js +4 -4
  173. package/dist/memory-store-refusal.d.ts +1 -1
  174. package/dist/memory-sync-client.js +2 -2
  175. package/dist/model-context-window.d.ts +50 -11
  176. package/dist/model-context-window.js +20 -1
  177. package/dist/model-entry-refusal.d.ts +5 -4
  178. package/dist/model-entry-refusal.js +17 -3
  179. package/dist/model-reach-scope.d.ts +2 -1
  180. package/dist/observability/corrupt-read-seat.d.ts +1 -1
  181. package/dist/observability/fail-open.d.ts +19 -7
  182. package/dist/observability/fail-open.js +19 -7
  183. package/dist/observability/logger.d.ts +7 -0
  184. package/dist/observability/logger.js +3 -1
  185. package/dist/observability/metrics.js +1 -1
  186. package/dist/observability/run-terminal.d.ts +1 -1
  187. package/dist/observability/run-terminal.js +1 -0
  188. package/dist/observability/secret-env-scrub.d.ts +1 -1
  189. package/dist/observability/secret-env-scrub.js +1 -1
  190. package/dist/org-delivery-gate.d.ts +31 -6
  191. package/dist/org-delivery-gate.js +7 -4
  192. package/dist/owner-faces.d.ts +30 -5
  193. package/dist/owner-faces.js +2 -0
  194. package/dist/park-row-commit.d.ts +67 -0
  195. package/dist/park-row-commit.js +76 -0
  196. package/dist/parked-decide.d.ts +9 -7
  197. package/dist/parked-decide.js +25 -6
  198. package/dist/peer-directory.d.ts +1 -1
  199. package/dist/peer-seat.d.ts +1 -1
  200. package/dist/peer-seat.js +52 -59
  201. package/dist/plugins/adoption-log-sql.d.ts +3 -3
  202. package/dist/plugins/adoption-log-sql.js +19 -19
  203. package/dist/plugins/approval-ask-store-sql.d.ts +1 -1
  204. package/dist/plugins/approval-ask-store-sql.js +3 -5
  205. package/dist/plugins/approval-exemption-skill-cutoff.d.ts +64 -0
  206. package/dist/plugins/approval-exemption-skill-cutoff.js +122 -0
  207. package/dist/plugins/approval-exemption-skill-m46.d.ts +0 -6
  208. package/dist/plugins/approval-exemption-skill-m46.js +6 -10
  209. package/dist/plugins/approval-exemption-store.d.ts +26 -1
  210. package/dist/plugins/approval-exemption-store.js +28 -19
  211. package/dist/plugins/ensure-schema-lock-policy.d.ts +36 -3
  212. package/dist/plugins/ensure-schema-lock-policy.js +75 -9
  213. package/dist/plugins/exec-path-law.d.ts +34 -0
  214. package/dist/plugins/exec-path-law.js +13 -0
  215. package/dist/plugins/file-run-store.d.ts +22 -9
  216. package/dist/plugins/file-run-store.js +51 -23
  217. package/dist/plugins/local-checkpoint-store.d.ts +8 -1
  218. package/dist/plugins/local-checkpoint-store.js +5 -1
  219. package/dist/plugins/local-data-root-admission.d.ts +52 -0
  220. package/dist/plugins/local-data-root-admission.js +100 -0
  221. package/dist/plugins/local-engine-high-water.d.ts +28 -7
  222. package/dist/plugins/local-engine-high-water.js +27 -22
  223. package/dist/plugins/local-session-store.d.ts +134 -49
  224. package/dist/plugins/local-session-store.js +149 -108
  225. package/dist/plugins/memory-run-store.d.ts +14 -9
  226. package/dist/plugins/memory-run-store.js +48 -22
  227. package/dist/plugins/one-time-migration-marker.d.ts +19 -3
  228. package/dist/plugins/one-time-migration-marker.js +7 -1
  229. package/dist/plugins/one-time-migrations.d.ts +110 -59
  230. package/dist/plugins/one-time-migrations.js +224 -136
  231. package/dist/plugins/org-delivery-quota-store.d.ts +34 -11
  232. package/dist/plugins/org-delivery-quota-store.js +29 -14
  233. package/dist/plugins/permission-rule-store-sql.d.ts +1 -1
  234. package/dist/plugins/permission-rule-store-sql.js +5 -9
  235. package/dist/plugins/pg-pool.d.ts +1 -1
  236. package/dist/plugins/pg-pool.js +14 -12
  237. package/dist/plugins/posix-shell-fs.js +4 -2
  238. package/dist/plugins/remote-env-adb.js +3 -2
  239. package/dist/plugins/remote-env-device.d.ts +3 -2
  240. package/dist/plugins/remote-env-device.js +8 -6
  241. package/dist/plugins/remote-env-e2b.d.ts +4 -8
  242. package/dist/plugins/remote-env-e2b.js +21 -15
  243. package/dist/plugins/remote-env-host.d.ts +51 -10
  244. package/dist/plugins/remote-env-host.js +97 -31
  245. package/dist/plugins/remote-env-k8s.js +7 -4
  246. package/dist/plugins/remote-env-local-docker.d.ts +6 -3
  247. package/dist/plugins/remote-env-local-docker.js +11 -25
  248. package/dist/plugins/remote-env-ssh.js +4 -3
  249. package/dist/plugins/remote-shell.d.ts +3 -1
  250. package/dist/plugins/remote-shell.js +3 -3
  251. package/dist/plugins/replica-registration.d.ts +35 -0
  252. package/dist/plugins/replica-registration.js +48 -0
  253. package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
  254. package/dist/plugins/run-store-sql.d.ts +27 -8
  255. package/dist/plugins/run-store-sql.js +46 -18
  256. package/dist/plugins/scenario-prefix-switch-m42.d.ts +8 -12
  257. package/dist/plugins/scenario-prefix-switch-m42.js +9 -6
  258. package/dist/plugins/schema-consistency.d.ts +91 -5
  259. package/dist/plugins/schema-consistency.js +189 -7
  260. package/dist/plugins/schema-drift-sentence.d.ts +6 -5
  261. package/dist/plugins/schema-drift-sentence.js +13 -5
  262. package/dist/plugins/serving-requirement.d.ts +49 -0
  263. package/dist/plugins/serving-requirement.js +53 -0
  264. package/dist/plugins/session-placement.d.ts +5 -4
  265. package/dist/plugins/shell-sentinel-owner-m48.d.ts +22 -0
  266. package/dist/plugins/shell-sentinel-owner-m48.js +6 -0
  267. package/dist/plugins/stop-then-start-sentence.d.ts +55 -0
  268. package/dist/plugins/stop-then-start-sentence.js +51 -0
  269. package/dist/plugins/store-backend.d.ts +23 -9
  270. package/dist/plugins/store-backend.js +58 -24
  271. package/dist/plugins/store-contracts.d.ts +45 -5
  272. package/dist/plugins/store-contracts.js +19 -0
  273. package/dist/plugins/tidb-pool.d.ts +11 -6
  274. package/dist/plugins/tidb-pool.js +22 -12
  275. package/dist/plugins/workspace-custody.d.ts +44 -0
  276. package/dist/plugins/workspace-custody.js +47 -0
  277. package/dist/process-instance.d.ts +3 -0
  278. package/dist/process-instance.js +7 -0
  279. package/dist/project-context.d.ts +66 -0
  280. package/dist/project-context.js +70 -0
  281. package/dist/project-identity.d.ts +8 -7
  282. package/dist/project-identity.js +40 -17
  283. package/dist/project-layer-key.d.ts +13 -2
  284. package/dist/project-layer-key.js +9 -1
  285. package/dist/question.d.ts +9 -21
  286. package/dist/question.js +28 -19
  287. package/dist/read-deny-floor-notice.d.ts +36 -0
  288. package/dist/read-deny-floor-notice.js +40 -0
  289. package/dist/{plain-string-record.d.ts → request-declaration-disposition.d.ts} +9 -23
  290. package/dist/request-declaration-disposition.js +39 -0
  291. package/dist/run-cancel-card.d.ts +28 -0
  292. package/dist/run-cancel-card.js +20 -0
  293. package/dist/run-cancel-context.d.ts +10 -0
  294. package/dist/run-cancel-context.js +1 -0
  295. package/dist/run-local.js +28 -13
  296. package/dist/runs.d.ts +31 -7
  297. package/dist/runs.js +34 -16
  298. package/dist/security.d.ts +3 -3
  299. package/dist/server-secret-env.d.ts +34 -20
  300. package/dist/server-secret-env.js +61 -18
  301. package/dist/session-agent.d.ts +4 -12
  302. package/dist/session-agent.js +0 -6
  303. package/dist/session-children-retire.d.ts +6 -3
  304. package/dist/session-children-retire.js +2 -5
  305. package/dist/session-incarnation.d.ts +18 -4
  306. package/dist/session-incarnation.js +4 -1
  307. package/dist/session-notify-door.d.ts +4 -4
  308. package/dist/session-notify-door.js +5 -6
  309. package/dist/session-rules-seat.d.ts +4 -3
  310. package/dist/session-rules-seat.js +3 -11
  311. package/dist/session-sync.js +3 -3
  312. package/dist/session-workspace.d.ts +3 -3
  313. package/dist/store-admission.d.ts +33 -0
  314. package/dist/store-admission.js +49 -0
  315. package/dist/store-posture.d.ts +5 -0
  316. package/dist/store-posture.js +18 -1
  317. package/dist/stores-sql/checkpoint-store-sql.d.ts +22 -3
  318. package/dist/stores-sql/checkpoint-store-sql.js +109 -23
  319. package/dist/stores-sql/file-history-store-sql.d.ts +1 -1
  320. package/dist/stores-sql/file-history-store-sql.js +3 -5
  321. package/dist/stores-sql/retention-store-sql.d.ts +1 -1
  322. package/dist/stores-sql/tool-result-store-sql.d.ts +1 -1
  323. package/dist/stores-sql/tool-result-store-sql.js +4 -6
  324. package/dist/task-a2a.d.ts +3 -8
  325. package/dist/task-a2a.js +25 -27
  326. package/dist/task-cwd.d.ts +27 -10
  327. package/dist/task-cwd.js +3 -0
  328. package/dist/task-mcp.d.ts +3 -3
  329. package/dist/task-mcp.js +1 -1
  330. package/dist/task-settings.d.ts +13 -0
  331. package/dist/task-settings.js +14 -7
  332. package/dist/terminal.d.ts +2 -0
  333. package/dist/terminal.js +21 -6
  334. package/dist/tool-approval.d.ts +50 -41
  335. package/dist/tool-approval.js +96 -73
  336. package/dist/trace/engine-notice-wire.d.ts +38 -21
  337. package/dist/trace/engine-notice-wire.js +25 -4
  338. package/dist/trace/ledger-sink.d.ts +3 -1
  339. package/dist/trace/project.d.ts +8 -5
  340. package/dist/trace/project.js +11 -9
  341. package/dist/trace/projection-table.d.ts +33 -2
  342. package/dist/trace/redact.d.ts +12 -0
  343. package/dist/trace/redact.js +5 -1
  344. package/dist/trace/self-minted-wire.d.ts +268 -56
  345. package/dist/trace/self-minted-wire.js +110 -40
  346. package/dist/trace/tool-card.d.ts +3 -0
  347. package/dist/trace/tool-card.js +24 -0
  348. package/dist/trace/tool-output-media.d.ts +2 -1
  349. package/dist/unattended-permission-mode.d.ts +1 -1
  350. package/dist/web-admin-client/apply-effective.d.ts +1 -1
  351. package/dist/web-admin-client/apply-effective.js +22 -9
  352. package/dist/web-admin-client/effective-keys.d.ts +1 -1
  353. package/dist/web-admin-client/skills-mcp.d.ts +1 -1
  354. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -29
  355. package/docs/error-text-lexicon.json +317 -0
  356. package/package.json +4 -2
  357. package/scripts/embed-minimal.mjs +183 -0
  358. package/wire-changes/server@7.149.0.json +372 -0
  359. package/wire-changes/server@7.150.0.json +335 -0
  360. package/dist/plain-string-record.js +0 -70
@@ -197,7 +197,7 @@ export declare const FAIL_OPEN_TAGS: {
197
197
  };
198
198
  readonly "server.approvals.queue-row-agent-unreadable": {
199
199
  readonly cls: "F";
200
- readonly note: "S-3000(`routes/approvals-assistant.ts` 的 `sessionAgentsOf`):运维待批队列(`GET /v1/approvals` 的 `pending[]` 与 `/v1/approvals/stream` 的 `pending` 帧)每一只停驻行带它那只会话在委派树里的位置 `agent`(会话视图的同名键,唯一读口 `session-agent.ts` 的 `readSessionAgent` = 会话店的 `placementOf` 一读)。某一只会话那一读抛(店瞬断 / 超时 / local 后端的会话存档行头读不出)⇒ **这只会话的行**缺 `agent` 键,列表其余照常。放行的最坏后果 = 这一行这一次没有委派归属线索:壳的归属判官认不到它(行照列、人从队列照样决得了 —— 与本键存在之前同形);`agent` 不是授权事实(队列行本就只列调用方 scope 的卡,决断口另有属主门)。不放行的代价是一只读不出的会话打掉整张待批列表(订阅流上每一拍都是读失败)。故 F 类;必须留痕,否则「这一次没读成」与「这不是一只 placed 委派子代」在 wire 上同形。detail = 会话 id 与经出口座的错误句。计数按次(订阅流每一拍各计一次)。";
200
+ readonly note: "S-3000(`routes/approvals-assistant.ts` 的 `sessionAgentsOf`):运维待批队列(`GET /v1/approvals` 的 `pending[]` 与 `/v1/approvals/stream` 的 `pending` 帧)每一只停驻行带它那只会话在委派树里的位置 `agent`(会话视图的同名键,唯一读口 `http/owner-access.ts` 的 `readSessionAgent` = 会话店的 `placementOf` 一读)。某一只会话那一读抛(店瞬断 / 超时 / local 后端的会话存档行头读不出)⇒ **这只会话的行**缺 `agent` 键,列表其余照常。放行的最坏后果 = 这一行这一次没有委派归属线索:壳的归属判官认不到它(行照列、人从队列照样决得了 —— 与本键存在之前同形);`agent` 不是授权事实(队列行本就只列调用方 scope 的卡,决断口另有属主门)。不放行的代价是一只读不出的会话打掉整张待批列表(订阅流上每一拍都是读失败)。故 F 类;必须留痕,否则「这一次没读成」与「这不是一只 placed 委派子代」在 wire 上同形。detail = 会话 id 与经出口座的错误句。计数按次(订阅流每一拍各计一次)。";
201
201
  };
202
202
  readonly "server.approvals.durable-row-checkpoint-id-missing": {
203
203
  readonly cls: "F";
@@ -303,6 +303,10 @@ export declare const FAIL_OPEN_TAGS: {
303
303
  readonly cls: "F";
304
304
  readonly note: "`memory-incident-sink.ts` 的 `createMemoryEngineIncidentSink`(两只宿主 `onError` 的 `memory` 相共用的落点):记忆相上到达店形拒族(`STORE_FORM_REFUSAL_CODES`,按族读;引擎 7.65.0 起含控制面所在文件系统不能建硬链接的 `memory.control_plane_links_unsupported`)的码 ⇒ 引擎的一步记忆活被店拒、会话照跑:mount 时开店被拒 ⇒ 这一跑记忆面读作 `memoryless`(`mount-failed`);mount 之后的整理 / 收割撞上 ⇒ 那一步没做(席只认码与相,不分哪一步 —— 是哪一步看同一行 `memory_engine_incident` 的句子)。放行的最坏后果 = 这一跑没有记忆或少做一步记忆活(不召回、不采集、不收割、不整理)—— 少做,不是错做:不开门、不放宽任何判据,模型读不到的是记忆不是别的;不放行的代价是记忆盘一个挂载面的形不对就让每一跑都失败。留痕是因为「这台部署的记忆从来没挂上」与「会话里本来没东西可记」在外部同形:逐次计数 + 探针 + 每进程一次 warn,detail `code=<店形拒码>`(运维行 `memory_engine_incident` 另带码与经出口座的句子);出路 = 把记忆控制面放到支持硬链接的卷上(或按码修挂载形)后重启。";
305
305
  };
306
+ readonly "server.memory.project-marker-unreadable": {
307
+ readonly cls: "F";
308
+ readonly note: "单用户记忆项目层的身份(`project-identity.ts` 的 `markerFact`,唯一读者 `projectLayerIdentityOf`;装配期每个任务读一次):检出的 `.sema/project` 记号**读不出** —— 坏记号(`config.memory_project_marker`)、嵌套在仓根之下的记号(`config.memory_project_marker_nested`)、存在性查询或读本身失败 ⇒ 这一任务**没有项目层**(声明席 `{ absent: \"unreadable\" }`):写家落全局层,引擎同拍铸 operator 通知 `memory.project_scope_absent`,并在每条腿上自己报一次记号的错(`onError`,相 `config`)。**不**退回 git 根档 —— 那会在记号读得出之后静默换键。放行的最坏后果 = 这一任务的项目记忆写进全局层(同一用户的其它项目也读得到,单用户部署内,不越属主),记号修好之后 git 根档折进记号档、全局层里这段时间写下的条目不回项目层;不是门、不是凭据、不改任何裁决。反方向(拒整条 run)为一只坏记号打死用户的任务,且引擎自己对不消费项目身份的腿也照跑。detail = `code=<引擎的记号码 | ->`(句子与路径在引擎那一行里)。计数持续非零 = 有检出带着坏 / 嵌套记号,去修记号。";
309
+ };
306
310
  readonly "server.memory.locked-layer-probe-partial": {
307
311
  readonly cls: "F";
308
312
  readonly note: "O2(7.101.0 合并复审,`memory-layer-legacy-lock.ts announceLockedLegacyMemoryLayers`,boot 期锁住记忆层探测;detail 只报 `unreadable=<条数>`):挂载面或某个层里的目录**读不出**(EACCES 之类 —— 不是 ≤7.30.x 引擎的锁形,那种 0555 目录可读)⇒ 那棵子树看不全,照常起服。放行的最坏后果 = 一个锁住的层在 boot 日志里没被点名 —— 探测是**披露**面,不参与任何门 / 裁决;core 在真正失败的那一次删除上仍给出自己的 `chmod -R u+w` 补救句。不放行的代价严重不对称:为一条 warn 打死起服(混跑窗里能服务的副本)。计数让「这台部署的记忆树有读不出的目录」显形。";
@@ -409,7 +413,7 @@ export declare const FAIL_OPEN_TAGS: {
409
413
  };
410
414
  readonly "server.runs.terminal-ledger-write-failed": {
411
415
  readonly cls: "F";
412
- readonly note: "S-107(全量门 silent-degradation 棘轮抓出的五处静默 `catch {}`):run 终局链里**账本腿**(flush 缓冲 text/reasoning、append `failed` 行)与终态翻转(setTerminal)已不共命运——账本 INSERT 抛不再让 run 卡 running 到 reaper;但那条抛掉的账本行之前是**静默**吞的。detail `arm=` 四臂(flush-clean-cancel / append-clean-cancel / flush-catch / append-thrown-cancel / append-failed);S-947 起续跑腿(`http/resume-legs.ts`)两座同 tag:resume-append-resume-aborted / resume-append-thrown-cancel(取消抛出两臂的 `failed` 行,修前那两臂根本不落账本终局行):缺的是 run_events 尾巴(缓冲文本或 failed 事件),run 行本身仍是 durable truth,读面/reaper 容忍缺失,故 F 类;计数=多少次终局账本写失败。";
416
+ readonly note: "S-107(全量门 silent-degradation 棘轮抓出的五处静默 `catch {}`):run 终局链里**账本腿**(flush 缓冲 text/reasoning、append `failed` 行)与终态翻转(setTerminal)已不共命运——账本 INSERT 抛不再让 run 卡 running 到 reaper;但那条抛掉的账本行之前是**静默**吞的。detail `arm=` 四臂(flush-clean-cancel / append-clean-cancel / flush-catch / append-thrown-cancel / append-failed);S-947 起续跑腿(`http/resume-legs.ts`)两座同 tag:resume-append-resume-aborted / resume-append-thrown-cancel(取消抛出两臂的 `failed` 行,修前那两臂根本不落账本终局行);停驻帧同一条律(卡已提交之后,停驻的账本投影写不下不改判词,行的停驻写是唯一提交点 —— `park-row-commit.ts`):park-usage / park-row(park 行唯一写口 `trace/project.ts` 的 `appendParkRow`,三条腿同经)、park-held(后台腿停驻结果到手之后、进停驻臂之前一笔簿记写抛 ⇒ 照常停驻)、resume-park-projection(续跑 verify 臂停驻形的清单 / 用量 / 停驻帧那一段)、resume-park-held(续跑腿再停结果到手之后一笔簿记写抛 ⇒ 本腿照常再停,detail 带那一抛的原句):缺的是 run_events 尾巴(缓冲文本、failed 事件或停驻帧),run 行本身仍是 durable truth,读面/reaper 容忍缺失,故 F 类;计数=多少次状态帧(终局 / 停驻)账本写失败。";
413
417
  };
414
418
  readonly "server.live-text.hold-diverged": {
415
419
  readonly cls: "P-DEBT";
@@ -565,13 +569,13 @@ export declare const FAIL_OPEN_TAGS: {
565
569
  readonly cls: "R";
566
570
  readonly ruling: "C-R296";
567
571
  readonly bound: "FLEET_LEASE_OUTAGE_MAX_MS";
568
- readonly note: "`fleet/serving-lease.ts` 的 `renewOnce`(租约生效时每一次续租;detail = `worker=<w> generation=<g> why=<不可达句 | verdict=unknown>`):中心这一次**没有确认**本实例该不该服务 —— 不可达 / 超时 / 非 2xx / 答复读不成判决,或答 `unknown`(此刻没有本实例的生命周期对象)。按设计**什么都不改**(规则 2 第三臂):到期之前照常 `granted`,过期后 `expired` 照常接单,直到过期满 `FLEET_LEASE_OUTAGE_MAX_MS`(`T_max`)才拒新工作(503 `state.lease_expired`,在飞不动、永不自停)。归 R:方向与上界由裁定写定 —— 实例只在中心权威终止(`denied`)或运维覆盖时被替换,`T_max` 只是引擎自己「失联后最多再接单多久」的准入上界,不是替换依据;没确认不是被拒。放行的最坏后果 = 一只其实已被取代的实例在中心失联期间多服务至多「租约剩余 + `T_max`」(中心的代际下限持久,恢复后第一次续租即拒)。计数长期保留:持续非零 = 中心长时间没确认本实例,去看 detail 的 why(连不上 / 中心不认识这只实例)。";
572
+ readonly note: "`fleet/serving-lease.ts` 的「没确认」一段(两个调用点一只函数、一行 warn `fleet_serving_lease_unconfirmed`、一只连败计数;detail = `worker=<w> generation=<g> why=<…>`):① `renewOnce`(中心宣告了位之后每一次续租;`why=<不可达句 | HTTP <状态> | verdict=unknown>`)—— 中心这一次**没有确认**本实例该不该服务:不可达 / 超时 / 非 2xx / 答复读不成判决,或答 `unknown`(此刻没有本实例的生命周期对象);② `noteHeartbeat` 的沉默臂(fleet 成员还没听到任何声明的推定期,每一拍心跳;`why=heartbeat:<HTTP <状态> | 请求抛出的那句 | reply-unreadable:<因> | not-sent:<那句>>`,不带中心体片段)—— 成员起步即推定在围栏内,心跳没换来中心的声明。按设计**什么都不改**(规则 2 第三臂):到期之前照常 `granted`,过期后 / 推定期 `expired` 照常接单,直到最后一次授予的到期(没有授予 ⇒ 围栏在本进程生效的时刻,推定 = 本进程起点)满 `FLEET_LEASE_OUTAGE_MAX_MS`(`T_max`)才拒新工作(503 `state.lease_expired`,在飞不动、永不自停)。只在围栏生效时计(中心以不带位的声明解除围栏之后,在飞续租迟到的失败不计)。一段的收尾 = 续租判决(`granted` / `denied`)或中心以不带位的声明解除围栏,一行 `fleet_serving_lease_recovered`(`by: verdict | not-enforced`);宣告本身不是确认。归 R:方向与上界由裁定写定 —— 实例只在中心权威终止(`denied`)或运维覆盖时被替换,`T_max` 只是引擎自己「失联后最多再接单多久」的准入上界,不是替换依据;没确认不是被拒。放行的最坏后果 = 一只其实已被取代的实例在中心失联期间多服务至多「租约剩余 + `T_max`」(中心的代际下限持久,恢复后第一次续租即拒);从起步起一直没听到中心的成员**每个不间断进程**至多服务 `T_max`(钟不跨重启:重启即重计)。计数长期保留:持续非零 = 中心长时间没确认本实例,去看 detail 的 why(连不上 / 令牌被拒 / 中心不认识这只实例 / 答复不是声明)。";
569
573
  };
570
574
  readonly "server.fleet.serving-lease-capability-absent": {
571
575
  readonly cls: "R";
572
576
  readonly ruling: "C-R296";
573
577
  readonly bound: "FLEET_LEASE_OUTAGE_MAX_MS";
574
- readonly note: "`fleet/serving-lease.ts` 的 `noteCenterCapabilities`(fleet 成员每一次中心能力读数;detail = `worker=<w> generation=<g> was=<enabled|none>`):中心答复体读得出、却**没有宣告** `servingLease`(老中心 `{ ok: true }` / 降级中心 / 位撤掉)⇒ 规则 1:租约不生效,`leaseState: none`,零续租、零 503 —— 这只 fleet 成员此刻**不受围栏**。答复体读不出不进这一臂(那是「没有读数」,上一次的位与钟原样,`fleet-client.ts` `capabilityReadingOf`);已被拒的实例不进(拒是黏的,位消失不复活)。归 R:能力门控是契约规则(中心不宣告 = 中心不执行围栏),裁定写定替换只来自中心权威终止或运维覆盖;位只开关围栏、不碰钟 —— 位缺席期间 `T_max` 的钟照走(最后一次授予的到期 / 本进程第一次见到位的时刻),位一回来即按它判,所以位的抖动绕不过 `FLEET_LEASE_OUTAGE_MAX_MS`。放行的最坏后果 = 中心不执行围栏期间,一只被取代的实例照常服务(这一段由中心的选择定界,不由引擎)。计数长期保留:非零 = 这台中心没宣告租约能力。";
578
+ readonly note: "`fleet/serving-lease.ts` 的 `noteHeartbeat` 读数臂(fleet 成员每一次中心能力声明;detail = `worker=<w> generation=<g> was=<presumed|on|off>`):中心心跳答复里**显式的** `capabilities` 声明对象在、却**没有宣告** `servingLease`(中心关着围栏开关 / 共享令牌 / 降级中心 / 位撤掉)⇒ 规则 1:租约不生效,`leaseState: none`,零续租、零 503 —— 这只 fleet 成员此刻**不受围栏**。推定期的第一条声明就不带位(`was=presumed`)⇒ 推定作废(`expired → none`),钟不起,之后不限时(直到中心第一次宣告,那一拍起钟)。不是声明的答复不进这一臂(体读不出 / 不是对象 / 没有 `capabilities` 键 / 形坏 —— 那是沉默,推定、位与钟原样,`fleet-client.ts` `capabilityReadingOf`);已被拒的实例不进(拒是黏的,位消失不复活)。归 R:能力门控是契约规则(中心声明不执行 = 中心不执行围栏),裁定写定替换只来自中心权威终止或运维覆盖;位只开关围栏、不碰钟 —— 位缺席期间 `T_max` 的钟照走(最后一次授予的到期 / 围栏在本进程第一次生效的时刻),位一回来即按它判,所以位的抖动绕不过 `FLEET_LEASE_OUTAGE_MAX_MS`。放行的最坏后果 = 中心声明不执行围栏期间,一只被取代的实例照常服务(这一段由中心的选择定界,不由引擎)。计数长期保留:非零 = 这台中心没宣告租约能力。";
575
579
  };
576
580
  readonly "server.workspace-cache.unavailable": {
577
581
  readonly cls: "F";
@@ -607,11 +611,11 @@ export declare const FAIL_OPEN_TAGS: {
607
611
  };
608
612
  readonly "server.fleet.announce-reply-unreadable": {
609
613
  readonly cls: "P-DEBT";
610
- readonly note: "7.121.0 修复验证轮(`fleet-client.ts` 的公告环,fleet 成员每一拍心跳 2xx 答复;detail = `why=<body|not-an-object|invalid-capabilities> leaseState=<此刻的租约态>`):答复不是能力读数(体读不出 / 不是对象 / `capabilities` 键在场而形坏 —— settings-schema 9.0.0 `readCapabilityReading` 的 `unreadable`,外加本仓的 `body`)⇒ 当作没有这一拍答复,租约的状态与钟原样。**一律**计数(不论租约生效与否):租约还没生效(`leaseState=none`)时这只成员**一直不受围栏**,而修前这一形零计数(中心每拍答 `<html>` ⇒ 成员恒 none、零痕迹);租约已生效时计数说明中心的答复在坏、围栏靠的是上一次读数。归 P 类:围栏轴;归 DEBT:本进程判不出中心为什么答坏体,收口条件 = 中心契约 / 监控(中心侧对心跳答复形的执法)落地。每段连拍另有一行 warn `fleet_announce_reply_unreadable`(带 `why`)。";
614
+ readonly note: "7.121.0 修复验证轮(`fleet-client.ts` 的公告环,fleet 成员每一拍心跳 2xx 答复;detail = `why=<body|not-an-object|capabilities-absent|invalid-capabilities> leaseState=<此刻的租约态>`):答复不是能力声明(体读不出 / 不是对象 / 没有 `capabilities` 键 / `capabilities` 键在场而形坏 —— settings-schema `readCapabilityReading` 的 `unreadable`〔没有键那一因自 25.0.0 起〕,外加本仓的 `body`)⇒ 这一拍是沉默(交租约客户端 `silent`,`why=reply-unreadable:<因>`),推定、租约的状态与钟原样。**一律**计数(不论租约此刻什么态):推定期(成员还没听到任何声明,`leaseState=expired`)的坏答复同时是一拍「没确认」(另计 `server.fleet.serving-lease-unconfirmed`),推定与钟照走、满 `T_max` 拒新工作;租约已生效时计数说明中心的答复在坏、围栏靠的是上一次声明。归 P 类:围栏轴;归 DEBT:本进程判不出中心为什么答坏体,收口条件 = 中心契约 / 监控(中心侧对心跳答复形的执法)落地。每段连拍另有一行 warn `fleet_announce_reply_unreadable`(带 `why`)。";
611
615
  };
612
616
  readonly "server.fleet.denied-marker-unpersisted": {
613
617
  readonly cls: "P-DEBT";
614
- readonly note: "7.121.0(`fleet/serving-lease.ts` 的 `enterDenied`,中心以正面证据拒了本实例的服务租约那一拍;detail = `worker=<w> generation=<g>`):拒要落成数据根下一只文件(重启后起步即排空),而这一次**没落下** —— 没有数据根,或写失败(盘满 / 只读挂载 / 目录不在)。本进程照样被拒、照样当拍排空、到期自停;放行的是**重启之后**:同代际重启的实例不记得被拒,在第一次续租得到答复之前会接新工作(中心宣告了能力位时,第一次续租就再被拒一次 —— 中心的代际下限是持久的;中心那时不可达则一直接单到过期满 `FLEET_LEASE_OUTAGE_MAX_MS`)。归 P 类:这是围栏的记忆;归 DEBT:进程内无法把「记不住」变成 fail-closed(起步不接单直到第一次答复,是对租约不可达容忍规则的改动,另案)。denied 行的 `sticky` 同拍说 `process-only`,不声称跨重启记得。计数非零 = 这台机器的数据根写不进,或部署没有数据根。";
618
+ readonly note: "7.121.0(`fleet/serving-lease.ts` 的 `enterDenied`,中心以正面证据拒了本实例的服务租约那一拍;detail = `worker=<w> generation=<g>`):拒要落成数据根下一只文件(重启后起步即排空),而这一次**没落下** —— 没有数据根,或写失败(盘满 / 只读挂载 / 目录不在)。本进程照样被拒、照样当拍排空、到期自停;放行的是**重启之后**:同代际重启的实例不记得被拒,在第一次续租得到答复之前会接新工作(中心宣告了能力位时,第一次续租就再被拒一次 —— 中心的代际下限是持久的;中心那时不可达 / 心跳一直不通则按推定围栏接单到本进程起点满 `FLEET_LEASE_OUTAGE_MAX_MS`,每个进程各一段;重启后第一条声明就不带位 ⇒ 中心的话,不限时)。归 P 类:这是围栏的记忆;归 DEBT:进程内无法把「记不住」变成 fail-closed(「起步首次答复之前零容忍」形已否决:中心宕几秒 + 一次重启就停数据面),收口条件 = 契约给出持久拒位的公告位(心跳 / `/health` 上说「这一次拒只在本进程」,中心据此对该实例下一次续租照拒、并能看见它)。denied 行的 `sticky` 同拍说 `process-only`,不声称跨重启记得。计数非零 = 这台机器的数据根写不进,或部署没有数据根。";
615
619
  };
616
620
  readonly "server.sql.tidb-row-cap-unread": {
617
621
  readonly cls: "F";
@@ -657,7 +661,15 @@ export declare const FAIL_OPEN_TAGS: {
657
661
  };
658
662
  readonly "server.park.held-card-void-failed": {
659
663
  readonly cls: "F";
660
- readonly note: "停驻没落定就以失败收场的腿(`runs.ts` 的 `voidHeldParkCard`;两处:后台腿 catch 的失败臂 `leg=bg`、续跑腿 catch 放认领的取消 / 普通异常两臂 `leg=resume`):手里的结果是宿主层停驻(引擎交回之前已把卡落进 checkpoint 店,卡在本 run 的会话上),而停驻行 / 用量行 / 结果到手之后的账本写抛 ⇒ 腿以 `failed` 收场、放认领;放认领之前先按卡自己的 scope 店级 `expire` 作废那张卡(动词 = `card-void.ts` 的结算作废)。作废没做成 —— 店读 / 作废抛错(`store_error`)、卡的会话与本 run 的会话对不上(`card_mismatch`,只作废那一张,对不上就不动)、本部署没接 checkpoint 店(`no_checkpoint_store`)—— 照样以 `failed` 收场、放认领,每次记一次。放行的最坏后果 = 那张卡回到修前的形:留在待决面上,兑现它的 run 已经 `failed`、认领已放,决定口照样受理、续跑在没有认领的会话上驱动(`resume-legs.ts` 认领缺席成因 ②),由审批兜底收割收走;前提是停驻簿记写失败,并且这张卡没作废成(三个 reason 任一:checkpoint 店这一笔也失败 / 卡与本 run 的会话对不上 / 没接店 —— 后两者不需要第二次写失败)。不是门、不是凭据、不改 run 的判词。计数非零 = 有一次停驻没落定的失败收场留下了一张卡:按 reason 看 —— `store_error` = checkpoint 店在同一拍也出错,`card_mismatch` = 结果里的卡与本 run 的会话对不上,`no_checkpoint_store` = 这台部署没接 checkpoint 店;去看那只会话。detail = `reason=<词> leg=<bg|resume> [err=<原句>]`(不含凭据)。";
664
+ readonly note: "卡已提交(引擎交回停驻之前已把卡落进 checkpoint 店,卡在本 run 的会话上)而兑现它的 run 不再等它,本服务按卡自己的 scope 店级 `expire` 作废那张卡(动词 = `card-void.ts` 的结算作废)—— 两个产地:① 手里握着停驻结果、却以终局收场的腿(`runs.ts` 的 `voidHeldParkCard`:后台腿 catch 的失败臂 `leg=bg` —— 取消落在结果到手之后、或结果不是停驻词;续跑腿 catch 放认领的取消 / 普通异常两臂 `leg=resume`),卡的命运先于认领释放;② 停驻的唯一提交点(`park-row-commit.ts` 的 `commitParkRow`,`leg=bg|resume|sync`,detail 多一位 `at=<park_commit_refused|park_commit_cancelled>`):行的停驻写被店答出「不」而读到的行不在或已终局(被收割 / 别处终结 / 接手腿收场)⇒ `park_commit_refused`,卡跟着行作废;读到行归本腿、在跑、挂着取消请求 ⇒ `park_commit_cancelled`,先作废卡、再落取消终局。停驻簿记(账本帧 / 用量差)写不下与行的停驻写撞店故障**都不是**产地(前者只留痕、后者续写,见 `server.park.row-commit-deferred`)。作废没做成 —— 店读 / 作废抛错(`store_error`)、卡的会话与本 run 的会话对不上(`card_mismatch`,只作废那一张,对不上就不动)、本部署没接 checkpoint 店(`no_checkpoint_store`)—— 收场照走,每次记一次。放行的最坏后果 = 那张卡留在待决面上,兑现它的 run 已经终局、认领已放:决定口照样受理、续跑在没有认领的会话上驱动(`resume-legs.ts` 认领缺席成因),由审批兜底收割按卡的截止收走。不是门、不是凭据、不改 run 的判词。计数非零 = 留下了一张兑现不了的卡:按 reason 看 —— `store_error` = checkpoint 店在同一拍也出错,`card_mismatch` = 卡与本 run 的会话对不上,`no_checkpoint_store` = 这台部署没接 checkpoint 店;去看那只会话。detail = `reason=<词> leg=<bg|resume|sync>[ at=<park_commit_refused|park_commit_cancelled>][ err=<原句>]`(不含凭据)。";
665
+ };
666
+ readonly "server.park.row-commit-deferred": {
667
+ readonly cls: "F";
668
+ readonly note: "停驻的唯一提交点(`park-row-commit.ts` 的 `commitParkRow`;三条腿同经:后台腿 `leg=bg`、续跑腿的再停 / 重开 / 放回 `leg=resume`、同步 detach 腿 `leg=sync`):卡已提交之后 run 行的停驻写(`setSuspended` / `setNeedsReview`)撞店故障(抛:连接 / 超时 / 程序错)。规则「店的故障不是答案」⇒ 不收场:行不落 failed、卡不作废、认领留着,同一笔停驻再提交 —— 当拍一次,仍没答出 ⇒ 按心跳节拍续,店答出即收。停驻写的 CAS = 行仍归本腿(持有腿 `leg_id`,认领铸、交给本腿)∧ 在跑(或已停在本词上)∧ 没挂取消请求;第一笔与每一次再提交是同一个形(一笔抛了的写结局未知,同词重写幂等):写,店答出「不」⇒ 读行、由行答 —— 行不在 / 已终局 ⇒ 卡跟着作废;归别的腿、还活着 ⇒ 接手腿已接走,不再写;归本腿、停在本词上 ⇒ 停驻成立;归本腿、在跑、挂着取消请求 ⇒ 先作废卡、再落取消终局(码 `cancelled`;作废见 `server.park.held-card-void-failed`)。上界 = 两个判活窗(`REAP_RUN_STALE_SEC`);到上界仍没答 ⇒ 停手、交既有出路:行由失联收割按判活窗收成 failed 并放认领,卡由审批兜底收割按它的截止 / 绝对兜底时刻作废。放行的最坏后果 = 续写期间行停在 `running`(没有心跳):这一窗里决定那张卡答 409 `conflict.not_resumable`(行还没落到停驻词),落下之后同一决定照常受理;进程在续写期间退出 ⇒ 直接交既有出路(行被失联收割、卡由兜底收割)。不是门、不是凭据。detail = `leg=<bg|resume|sync> step=<first|again|retry|gave_up> err=<原句>`(不含凭据);计数 = 停驻提交失败的次数(第一笔写 / 再提交的读、写、取消终局写),`gave_up` 非零 = 有一次停驻交给了既有出路,去看那只会话与店。";
669
+ };
670
+ readonly "server.park.row-commit-contradicted": {
671
+ readonly cls: "F";
672
+ readonly note: "停驻的唯一提交点(`park-row-commit.ts` 的 `commitParkRow`,`leg=bg|resume|sync`)的拒后判之外的那一格:停驻写被店答出「不」,随后读到的行却归本腿、在跑、没挂取消请求 —— CAS 的三件(持有腿 · 在跑或已停在本词上 · 没挂取消)读来都成立而写被拒,店自相矛盾,是不变量破,不是店抖动。本格不猜:当一次店故障处置(不收场、不作废卡、认领留着),交同一条再提交路(当拍一次、心跳节拍续、上界两个判活窗,`server.park.row-commit-deferred` 同计),店答出别的读数即按拒后判收场;一直矛盾 ⇒ 到上界停手、交既有出路(失联收割收行、审批兜底收割收卡)。放行的最坏后果 = 行在续写期间停在 `running`、卡待决到上界。不是门、不是凭据。计数非零 = 本库对同一行的 UPDATE 与 SELECT 答得不一致(读到的不是写判的那一份:读副本 / 隔离级别 / 店的缺陷),去查那只库。detail = `leg=<bg|resume|sync> taskId=<id> word=<suspended|needs_review> status=<读到的词> holder=self cancel=false`(不含凭据)。";
661
673
  };
662
674
  readonly "server.verifier-pause.card-void-failed": {
663
675
  readonly cls: "F";
@@ -178,7 +178,7 @@ export const FAIL_OPEN_TAGS = {
178
178
  },
179
179
  "server.approvals.queue-row-agent-unreadable": {
180
180
  cls: "F",
181
- note: "S-3000(`routes/approvals-assistant.ts` 的 `sessionAgentsOf`):运维待批队列(`GET /v1/approvals` 的 `pending[]` 与 `/v1/approvals/stream` 的 `pending` 帧)每一只停驻行带它那只会话在委派树里的位置 `agent`(会话视图的同名键,唯一读口 `session-agent.ts` 的 `readSessionAgent` = 会话店的 `placementOf` 一读)。某一只会话那一读抛(店瞬断 / 超时 / local 后端的会话存档行头读不出)⇒ **这只会话的行**缺 `agent` 键,列表其余照常。放行的最坏后果 = 这一行这一次没有委派归属线索:壳的归属判官认不到它(行照列、人从队列照样决得了 —— 与本键存在之前同形);`agent` 不是授权事实(队列行本就只列调用方 scope 的卡,决断口另有属主门)。不放行的代价是一只读不出的会话打掉整张待批列表(订阅流上每一拍都是读失败)。故 F 类;必须留痕,否则「这一次没读成」与「这不是一只 placed 委派子代」在 wire 上同形。detail = 会话 id 与经出口座的错误句。计数按次(订阅流每一拍各计一次)。",
181
+ note: "S-3000(`routes/approvals-assistant.ts` 的 `sessionAgentsOf`):运维待批队列(`GET /v1/approvals` 的 `pending[]` 与 `/v1/approvals/stream` 的 `pending` 帧)每一只停驻行带它那只会话在委派树里的位置 `agent`(会话视图的同名键,唯一读口 `http/owner-access.ts` 的 `readSessionAgent` = 会话店的 `placementOf` 一读)。某一只会话那一读抛(店瞬断 / 超时 / local 后端的会话存档行头读不出)⇒ **这只会话的行**缺 `agent` 键,列表其余照常。放行的最坏后果 = 这一行这一次没有委派归属线索:壳的归属判官认不到它(行照列、人从队列照样决得了 —— 与本键存在之前同形);`agent` 不是授权事实(队列行本就只列调用方 scope 的卡,决断口另有属主门)。不放行的代价是一只读不出的会话打掉整张待批列表(订阅流上每一拍都是读失败)。故 F 类;必须留痕,否则「这一次没读成」与「这不是一只 placed 委派子代」在 wire 上同形。detail = 会话 id 与经出口座的错误句。计数按次(订阅流每一拍各计一次)。",
182
182
  },
183
183
  "server.approvals.durable-row-checkpoint-id-missing": {
184
184
  cls: "F",
@@ -284,6 +284,10 @@ export const FAIL_OPEN_TAGS = {
284
284
  cls: "F",
285
285
  note: "`memory-incident-sink.ts` 的 `createMemoryEngineIncidentSink`(两只宿主 `onError` 的 `memory` 相共用的落点):记忆相上到达店形拒族(`STORE_FORM_REFUSAL_CODES`,按族读;引擎 7.65.0 起含控制面所在文件系统不能建硬链接的 `memory.control_plane_links_unsupported`)的码 ⇒ 引擎的一步记忆活被店拒、会话照跑:mount 时开店被拒 ⇒ 这一跑记忆面读作 `memoryless`(`mount-failed`);mount 之后的整理 / 收割撞上 ⇒ 那一步没做(席只认码与相,不分哪一步 —— 是哪一步看同一行 `memory_engine_incident` 的句子)。放行的最坏后果 = 这一跑没有记忆或少做一步记忆活(不召回、不采集、不收割、不整理)—— 少做,不是错做:不开门、不放宽任何判据,模型读不到的是记忆不是别的;不放行的代价是记忆盘一个挂载面的形不对就让每一跑都失败。留痕是因为「这台部署的记忆从来没挂上」与「会话里本来没东西可记」在外部同形:逐次计数 + 探针 + 每进程一次 warn,detail `code=<店形拒码>`(运维行 `memory_engine_incident` 另带码与经出口座的句子);出路 = 把记忆控制面放到支持硬链接的卷上(或按码修挂载形)后重启。",
286
286
  },
287
+ "server.memory.project-marker-unreadable": {
288
+ cls: "F",
289
+ note: "单用户记忆项目层的身份(`project-identity.ts` 的 `markerFact`,唯一读者 `projectLayerIdentityOf`;装配期每个任务读一次):检出的 `.sema/project` 记号**读不出** —— 坏记号(`config.memory_project_marker`)、嵌套在仓根之下的记号(`config.memory_project_marker_nested`)、存在性查询或读本身失败 ⇒ 这一任务**没有项目层**(声明席 `{ absent: \"unreadable\" }`):写家落全局层,引擎同拍铸 operator 通知 `memory.project_scope_absent`,并在每条腿上自己报一次记号的错(`onError`,相 `config`)。**不**退回 git 根档 —— 那会在记号读得出之后静默换键。放行的最坏后果 = 这一任务的项目记忆写进全局层(同一用户的其它项目也读得到,单用户部署内,不越属主),记号修好之后 git 根档折进记号档、全局层里这段时间写下的条目不回项目层;不是门、不是凭据、不改任何裁决。反方向(拒整条 run)为一只坏记号打死用户的任务,且引擎自己对不消费项目身份的腿也照跑。detail = `code=<引擎的记号码 | ->`(句子与路径在引擎那一行里)。计数持续非零 = 有检出带着坏 / 嵌套记号,去修记号。",
290
+ },
287
291
  "server.memory.locked-layer-probe-partial": {
288
292
  cls: "F",
289
293
  note: "O2(7.101.0 合并复审,`memory-layer-legacy-lock.ts announceLockedLegacyMemoryLayers`,boot 期锁住记忆层探测;detail 只报 `unreadable=<条数>`):挂载面或某个层里的目录**读不出**(EACCES 之类 —— 不是 ≤7.30.x 引擎的锁形,那种 0555 目录可读)⇒ 那棵子树看不全,照常起服。放行的最坏后果 = 一个锁住的层在 boot 日志里没被点名 —— 探测是**披露**面,不参与任何门 / 裁决;core 在真正失败的那一次删除上仍给出自己的 `chmod -R u+w` 补救句。不放行的代价严重不对称:为一条 warn 打死起服(混跑窗里能服务的副本)。计数让「这台部署的记忆树有读不出的目录」显形。",
@@ -373,7 +377,7 @@ export const FAIL_OPEN_TAGS = {
373
377
  "server.run-terminal.diag-capped": { cls: "F", note: "S-107:诊断文本座(merge details/measure/grader trace、leader 日志座、planner 样本、journal 预览、workflow_run error cut)长度 > DIAG_INPUT_CAP(256KB)⇒ 整段换 «redacted:oversized-diagnostic» [len=N](fail-closed 取证丢弃;固定窗不 fail-closed 故不开窗);计数=多少段诊断文本被整段丢弃" },
374
378
  "server.run-terminal.output-truncated": { cls: "F", note: "S-107:持久 error 脱后 UTF-8 字节 > 65,000(TiDB TEXT 65,535 字节)⇒ 脱后切并带标记(切在占位里不是泄漏);计数=多少条终态文案被字节封顶截断" },
375
379
  "server.runs.abort-cause-missing": { cls: "F", note: "S-947 候裁 ⑤(主会话裁:默认值保留,miss 臂必须响):续跑腿 `http/resume-legs.ts` 的 `checkpoint.resume_aborted` 臂 —— core 只在本腿递进去的信号**已中止**时铸该码,而那只信号唯一的写者是取消动词(快路 / 耐久旗轮询,句柄登记 `cancel_verb`),所以**只有 core 契约外的形**(桩 / 非 core Runner 直接抛该码,本腿句柄从未中止)才到得了「句柄上读不到成因」这一臂。取消终局照铸,成因取本腿唯一的中止词 `cancel_verb`(取消终局恒带成因由铸点签名保证,不让它缺);detail `task=<taskId>`;计数 = 多少次取消成因是默认值而不是句柄登记的。生产上恒零是证据,不归零 = 有一条不走 core 契约的 Runner 在跑续跑腿。" },
376
- "server.runs.terminal-ledger-write-failed": { cls: "F", note: "S-107(全量门 silent-degradation 棘轮抓出的五处静默 `catch {}`):run 终局链里**账本腿**(flush 缓冲 text/reasoning、append `failed` 行)与终态翻转(setTerminal)已不共命运——账本 INSERT 抛不再让 run 卡 running 到 reaper;但那条抛掉的账本行之前是**静默**吞的。detail `arm=` 四臂(flush-clean-cancel / append-clean-cancel / flush-catch / append-thrown-cancel / append-failed);S-947 起续跑腿(`http/resume-legs.ts`)两座同 tag:resume-append-resume-aborted / resume-append-thrown-cancel(取消抛出两臂的 `failed` 行,修前那两臂根本不落账本终局行):缺的是 run_events 尾巴(缓冲文本或 failed 事件),run 行本身仍是 durable truth,读面/reaper 容忍缺失,故 F 类;计数=多少次终局账本写失败。" },
380
+ "server.runs.terminal-ledger-write-failed": { cls: "F", note: "S-107(全量门 silent-degradation 棘轮抓出的五处静默 `catch {}`):run 终局链里**账本腿**(flush 缓冲 text/reasoning、append `failed` 行)与终态翻转(setTerminal)已不共命运——账本 INSERT 抛不再让 run 卡 running 到 reaper;但那条抛掉的账本行之前是**静默**吞的。detail `arm=` 四臂(flush-clean-cancel / append-clean-cancel / flush-catch / append-thrown-cancel / append-failed);S-947 起续跑腿(`http/resume-legs.ts`)两座同 tag:resume-append-resume-aborted / resume-append-thrown-cancel(取消抛出两臂的 `failed` 行,修前那两臂根本不落账本终局行);停驻帧同一条律(卡已提交之后,停驻的账本投影写不下不改判词,行的停驻写是唯一提交点 —— `park-row-commit.ts`):park-usage / park-row(park 行唯一写口 `trace/project.ts` 的 `appendParkRow`,三条腿同经)、park-held(后台腿停驻结果到手之后、进停驻臂之前一笔簿记写抛 ⇒ 照常停驻)、resume-park-projection(续跑 verify 臂停驻形的清单 / 用量 / 停驻帧那一段)、resume-park-held(续跑腿再停结果到手之后一笔簿记写抛 ⇒ 本腿照常再停,detail 带那一抛的原句):缺的是 run_events 尾巴(缓冲文本、failed 事件或停驻帧),run 行本身仍是 durable truth,读面/reaper 容忍缺失,故 F 类;计数=多少次状态帧(终局 / 停驻)账本写失败。" },
377
381
  "server.live-text.hold-diverged": {
378
382
  cls: "P-DEBT",
379
383
  note: "live 面模型文本的流式口(`trace/model-segment.ts` 的 `createLiveModelText`,三条 live 腿共用;流式口 = `trace/redact.ts` 的 `createRedactionStream`:喂入 / 取已判定前缀 / 收尾冲刷):一段冲刷时,已取出去的逐块字节与整段读法在那一截上的渲染对不上,或有一条整段读法的跨度横跨放行位 —— 流式口的律被打破(某条判定读到了文本之后才定的东西,却没被读口闭集算作开着 —— 交出点 = 读口闭集的交出点,`trace/redact.ts` 的 `FRONTIER_TERMS`)。处置:余下的字节照整段读法出(横跨放行位的跨度整枚换记号,不再出它的原文字节),段末帧照发整段脱敏的正文、消费端按它整段替换;但**已经出门**的那几块收不回 —— 其中可能有整段读法会遮的字节(这就是 P 族的理由)。债:编译期管不到的两处 —— 扫描器「每次尝试的头上都设一次寄存器」靠人审(一次都没设的那一形另记 `server.redact.scan-view-unattributed`),取证级数封顶从整条臂的足迹包络起补遮(另记 `server.redact.forensic-level-cap`)。钉 = 基线语料全前缀两块喂入 + 逐条按块流过流式口拼接 = 整段脱敏 + 判定距离最远的几形逐码元。detail `family=<text|reasoning> len=<段长>`;计数 = 多少段的律被打破(期望恒 0)。",
@@ -516,13 +520,13 @@ export const FAIL_OPEN_TAGS = {
516
520
  cls: "R",
517
521
  ruling: "C-R296",
518
522
  bound: "FLEET_LEASE_OUTAGE_MAX_MS",
519
- note: "`fleet/serving-lease.ts` 的 `renewOnce`(租约生效时每一次续租;detail = `worker=<w> generation=<g> why=<不可达句 | verdict=unknown>`):中心这一次**没有确认**本实例该不该服务 —— 不可达 / 超时 / 非 2xx / 答复读不成判决,或答 `unknown`(此刻没有本实例的生命周期对象)。按设计**什么都不改**(规则 2 第三臂):到期之前照常 `granted`,过期后 `expired` 照常接单,直到过期满 `FLEET_LEASE_OUTAGE_MAX_MS`(`T_max`)才拒新工作(503 `state.lease_expired`,在飞不动、永不自停)。归 R:方向与上界由裁定写定 —— 实例只在中心权威终止(`denied`)或运维覆盖时被替换,`T_max` 只是引擎自己「失联后最多再接单多久」的准入上界,不是替换依据;没确认不是被拒。放行的最坏后果 = 一只其实已被取代的实例在中心失联期间多服务至多「租约剩余 + `T_max`」(中心的代际下限持久,恢复后第一次续租即拒)。计数长期保留:持续非零 = 中心长时间没确认本实例,去看 detail 的 why(连不上 / 中心不认识这只实例)。",
523
+ note: "`fleet/serving-lease.ts` 的「没确认」一段(两个调用点一只函数、一行 warn `fleet_serving_lease_unconfirmed`、一只连败计数;detail = `worker=<w> generation=<g> why=<…>`):① `renewOnce`(中心宣告了位之后每一次续租;`why=<不可达句 | HTTP <状态> | verdict=unknown>`)—— 中心这一次**没有确认**本实例该不该服务:不可达 / 超时 / 非 2xx / 答复读不成判决,或答 `unknown`(此刻没有本实例的生命周期对象);② `noteHeartbeat` 的沉默臂(fleet 成员还没听到任何声明的推定期,每一拍心跳;`why=heartbeat:<HTTP <状态> | 请求抛出的那句 | reply-unreadable:<因> | not-sent:<那句>>`,不带中心体片段)—— 成员起步即推定在围栏内,心跳没换来中心的声明。按设计**什么都不改**(规则 2 第三臂):到期之前照常 `granted`,过期后 / 推定期 `expired` 照常接单,直到最后一次授予的到期(没有授予 ⇒ 围栏在本进程生效的时刻,推定 = 本进程起点)满 `FLEET_LEASE_OUTAGE_MAX_MS`(`T_max`)才拒新工作(503 `state.lease_expired`,在飞不动、永不自停)。只在围栏生效时计(中心以不带位的声明解除围栏之后,在飞续租迟到的失败不计)。一段的收尾 = 续租判决(`granted` / `denied`)或中心以不带位的声明解除围栏,一行 `fleet_serving_lease_recovered`(`by: verdict | not-enforced`);宣告本身不是确认。归 R:方向与上界由裁定写定 —— 实例只在中心权威终止(`denied`)或运维覆盖时被替换,`T_max` 只是引擎自己「失联后最多再接单多久」的准入上界,不是替换依据;没确认不是被拒。放行的最坏后果 = 一只其实已被取代的实例在中心失联期间多服务至多「租约剩余 + `T_max`」(中心的代际下限持久,恢复后第一次续租即拒);从起步起一直没听到中心的成员**每个不间断进程**至多服务 `T_max`(钟不跨重启:重启即重计)。计数长期保留:持续非零 = 中心长时间没确认本实例,去看 detail 的 why(连不上 / 令牌被拒 / 中心不认识这只实例 / 答复不是声明)。",
520
524
  },
521
525
  "server.fleet.serving-lease-capability-absent": {
522
526
  cls: "R",
523
527
  ruling: "C-R296",
524
528
  bound: "FLEET_LEASE_OUTAGE_MAX_MS",
525
- note: "`fleet/serving-lease.ts` 的 `noteCenterCapabilities`(fleet 成员每一次中心能力读数;detail = `worker=<w> generation=<g> was=<enabled|none>`):中心答复体读得出、却**没有宣告** `servingLease`(老中心 `{ ok: true }` / 降级中心 / 位撤掉)⇒ 规则 1:租约不生效,`leaseState: none`,零续租、零 503 —— 这只 fleet 成员此刻**不受围栏**。答复体读不出不进这一臂(那是「没有读数」,上一次的位与钟原样,`fleet-client.ts` `capabilityReadingOf`);已被拒的实例不进(拒是黏的,位消失不复活)。归 R:能力门控是契约规则(中心不宣告 = 中心不执行围栏),裁定写定替换只来自中心权威终止或运维覆盖;位只开关围栏、不碰钟 —— 位缺席期间 `T_max` 的钟照走(最后一次授予的到期 / 本进程第一次见到位的时刻),位一回来即按它判,所以位的抖动绕不过 `FLEET_LEASE_OUTAGE_MAX_MS`。放行的最坏后果 = 中心不执行围栏期间,一只被取代的实例照常服务(这一段由中心的选择定界,不由引擎)。计数长期保留:非零 = 这台中心没宣告租约能力。",
529
+ note: "`fleet/serving-lease.ts` 的 `noteHeartbeat` 读数臂(fleet 成员每一次中心能力声明;detail = `worker=<w> generation=<g> was=<presumed|on|off>`):中心心跳答复里**显式的** `capabilities` 声明对象在、却**没有宣告** `servingLease`(中心关着围栏开关 / 共享令牌 / 降级中心 / 位撤掉)⇒ 规则 1:租约不生效,`leaseState: none`,零续租、零 503 —— 这只 fleet 成员此刻**不受围栏**。推定期的第一条声明就不带位(`was=presumed`)⇒ 推定作废(`expired → none`),钟不起,之后不限时(直到中心第一次宣告,那一拍起钟)。不是声明的答复不进这一臂(体读不出 / 不是对象 / 没有 `capabilities` 键 / 形坏 —— 那是沉默,推定、位与钟原样,`fleet-client.ts` `capabilityReadingOf`);已被拒的实例不进(拒是黏的,位消失不复活)。归 R:能力门控是契约规则(中心声明不执行 = 中心不执行围栏),裁定写定替换只来自中心权威终止或运维覆盖;位只开关围栏、不碰钟 —— 位缺席期间 `T_max` 的钟照走(最后一次授予的到期 / 围栏在本进程第一次生效的时刻),位一回来即按它判,所以位的抖动绕不过 `FLEET_LEASE_OUTAGE_MAX_MS`。放行的最坏后果 = 中心声明不执行围栏期间,一只被取代的实例照常服务(这一段由中心的选择定界,不由引擎)。计数长期保留:非零 = 这台中心没宣告租约能力。",
526
530
  },
527
531
  "server.workspace-cache.unavailable": {
528
532
  cls: "F",
@@ -558,11 +562,11 @@ export const FAIL_OPEN_TAGS = {
558
562
  },
559
563
  "server.fleet.announce-reply-unreadable": {
560
564
  cls: "P-DEBT",
561
- note: "7.121.0 修复验证轮(`fleet-client.ts` 的公告环,fleet 成员每一拍心跳 2xx 答复;detail = `why=<body|not-an-object|invalid-capabilities> leaseState=<此刻的租约态>`):答复不是能力读数(体读不出 / 不是对象 / `capabilities` 键在场而形坏 —— settings-schema 9.0.0 `readCapabilityReading` 的 `unreadable`,外加本仓的 `body`)⇒ 当作没有这一拍答复,租约的状态与钟原样。**一律**计数(不论租约生效与否):租约还没生效(`leaseState=none`)时这只成员**一直不受围栏**,而修前这一形零计数(中心每拍答 `<html>` ⇒ 成员恒 none、零痕迹);租约已生效时计数说明中心的答复在坏、围栏靠的是上一次读数。归 P 类:围栏轴;归 DEBT:本进程判不出中心为什么答坏体,收口条件 = 中心契约 / 监控(中心侧对心跳答复形的执法)落地。每段连拍另有一行 warn `fleet_announce_reply_unreadable`(带 `why`)。",
565
+ note: "7.121.0 修复验证轮(`fleet-client.ts` 的公告环,fleet 成员每一拍心跳 2xx 答复;detail = `why=<body|not-an-object|capabilities-absent|invalid-capabilities> leaseState=<此刻的租约态>`):答复不是能力声明(体读不出 / 不是对象 / 没有 `capabilities` 键 / `capabilities` 键在场而形坏 —— settings-schema `readCapabilityReading` 的 `unreadable`〔没有键那一因自 25.0.0 起〕,外加本仓的 `body`)⇒ 这一拍是沉默(交租约客户端 `silent`,`why=reply-unreadable:<因>`),推定、租约的状态与钟原样。**一律**计数(不论租约此刻什么态):推定期(成员还没听到任何声明,`leaseState=expired`)的坏答复同时是一拍「没确认」(另计 `server.fleet.serving-lease-unconfirmed`),推定与钟照走、满 `T_max` 拒新工作;租约已生效时计数说明中心的答复在坏、围栏靠的是上一次声明。归 P 类:围栏轴;归 DEBT:本进程判不出中心为什么答坏体,收口条件 = 中心契约 / 监控(中心侧对心跳答复形的执法)落地。每段连拍另有一行 warn `fleet_announce_reply_unreadable`(带 `why`)。",
562
566
  },
563
567
  "server.fleet.denied-marker-unpersisted": {
564
568
  cls: "P-DEBT",
565
- note: "7.121.0(`fleet/serving-lease.ts` 的 `enterDenied`,中心以正面证据拒了本实例的服务租约那一拍;detail = `worker=<w> generation=<g>`):拒要落成数据根下一只文件(重启后起步即排空),而这一次**没落下** —— 没有数据根,或写失败(盘满 / 只读挂载 / 目录不在)。本进程照样被拒、照样当拍排空、到期自停;放行的是**重启之后**:同代际重启的实例不记得被拒,在第一次续租得到答复之前会接新工作(中心宣告了能力位时,第一次续租就再被拒一次 —— 中心的代际下限是持久的;中心那时不可达则一直接单到过期满 `FLEET_LEASE_OUTAGE_MAX_MS`)。归 P 类:这是围栏的记忆;归 DEBT:进程内无法把「记不住」变成 fail-closed(起步不接单直到第一次答复,是对租约不可达容忍规则的改动,另案)。denied 行的 `sticky` 同拍说 `process-only`,不声称跨重启记得。计数非零 = 这台机器的数据根写不进,或部署没有数据根。",
569
+ note: "7.121.0(`fleet/serving-lease.ts` 的 `enterDenied`,中心以正面证据拒了本实例的服务租约那一拍;detail = `worker=<w> generation=<g>`):拒要落成数据根下一只文件(重启后起步即排空),而这一次**没落下** —— 没有数据根,或写失败(盘满 / 只读挂载 / 目录不在)。本进程照样被拒、照样当拍排空、到期自停;放行的是**重启之后**:同代际重启的实例不记得被拒,在第一次续租得到答复之前会接新工作(中心宣告了能力位时,第一次续租就再被拒一次 —— 中心的代际下限是持久的;中心那时不可达 / 心跳一直不通则按推定围栏接单到本进程起点满 `FLEET_LEASE_OUTAGE_MAX_MS`,每个进程各一段;重启后第一条声明就不带位 ⇒ 中心的话,不限时)。归 P 类:这是围栏的记忆;归 DEBT:进程内无法把「记不住」变成 fail-closed(「起步首次答复之前零容忍」形已否决:中心宕几秒 + 一次重启就停数据面),收口条件 = 契约给出持久拒位的公告位(心跳 / `/health` 上说「这一次拒只在本进程」,中心据此对该实例下一次续租照拒、并能看见它)。denied 行的 `sticky` 同拍说 `process-only`,不声称跨重启记得。计数非零 = 这台机器的数据根写不进,或部署没有数据根。",
566
570
  },
567
571
  "server.sql.tidb-row-cap-unread": {
568
572
  cls: "F",
@@ -608,7 +612,15 @@ export const FAIL_OPEN_TAGS = {
608
612
  },
609
613
  "server.park.held-card-void-failed": {
610
614
  cls: "F",
611
- note: "停驻没落定就以失败收场的腿(`runs.ts` 的 `voidHeldParkCard`;两处:后台腿 catch 的失败臂 `leg=bg`、续跑腿 catch 放认领的取消 / 普通异常两臂 `leg=resume`):手里的结果是宿主层停驻(引擎交回之前已把卡落进 checkpoint 店,卡在本 run 的会话上),而停驻行 / 用量行 / 结果到手之后的账本写抛 ⇒ 腿以 `failed` 收场、放认领;放认领之前先按卡自己的 scope 店级 `expire` 作废那张卡(动词 = `card-void.ts` 的结算作废)。作废没做成 —— 店读 / 作废抛错(`store_error`)、卡的会话与本 run 的会话对不上(`card_mismatch`,只作废那一张,对不上就不动)、本部署没接 checkpoint 店(`no_checkpoint_store`)—— 照样以 `failed` 收场、放认领,每次记一次。放行的最坏后果 = 那张卡回到修前的形:留在待决面上,兑现它的 run 已经 `failed`、认领已放,决定口照样受理、续跑在没有认领的会话上驱动(`resume-legs.ts` 认领缺席成因 ②),由审批兜底收割收走;前提是停驻簿记写失败,并且这张卡没作废成(三个 reason 任一:checkpoint 店这一笔也失败 / 卡与本 run 的会话对不上 / 没接店 —— 后两者不需要第二次写失败)。不是门、不是凭据、不改 run 的判词。计数非零 = 有一次停驻没落定的失败收场留下了一张卡:按 reason 看 —— `store_error` = checkpoint 店在同一拍也出错,`card_mismatch` = 结果里的卡与本 run 的会话对不上,`no_checkpoint_store` = 这台部署没接 checkpoint 店;去看那只会话。detail = `reason=<词> leg=<bg|resume> [err=<原句>]`(不含凭据)。",
615
+ note: "卡已提交(引擎交回停驻之前已把卡落进 checkpoint 店,卡在本 run 的会话上)而兑现它的 run 不再等它,本服务按卡自己的 scope 店级 `expire` 作废那张卡(动词 = `card-void.ts` 的结算作废)—— 两个产地:① 手里握着停驻结果、却以终局收场的腿(`runs.ts` 的 `voidHeldParkCard`:后台腿 catch 的失败臂 `leg=bg` —— 取消落在结果到手之后、或结果不是停驻词;续跑腿 catch 放认领的取消 / 普通异常两臂 `leg=resume`),卡的命运先于认领释放;② 停驻的唯一提交点(`park-row-commit.ts` 的 `commitParkRow`,`leg=bg|resume|sync`,detail 多一位 `at=<park_commit_refused|park_commit_cancelled>`):行的停驻写被店答出「不」而读到的行不在或已终局(被收割 / 别处终结 / 接手腿收场)⇒ `park_commit_refused`,卡跟着行作废;读到行归本腿、在跑、挂着取消请求 ⇒ `park_commit_cancelled`,先作废卡、再落取消终局。停驻簿记(账本帧 / 用量差)写不下与行的停驻写撞店故障**都不是**产地(前者只留痕、后者续写,见 `server.park.row-commit-deferred`)。作废没做成 —— 店读 / 作废抛错(`store_error`)、卡的会话与本 run 的会话对不上(`card_mismatch`,只作废那一张,对不上就不动)、本部署没接 checkpoint 店(`no_checkpoint_store`)—— 收场照走,每次记一次。放行的最坏后果 = 那张卡留在待决面上,兑现它的 run 已经终局、认领已放:决定口照样受理、续跑在没有认领的会话上驱动(`resume-legs.ts` 认领缺席成因),由审批兜底收割按卡的截止收走。不是门、不是凭据、不改 run 的判词。计数非零 = 留下了一张兑现不了的卡:按 reason 看 —— `store_error` = checkpoint 店在同一拍也出错,`card_mismatch` = 卡与本 run 的会话对不上,`no_checkpoint_store` = 这台部署没接 checkpoint 店;去看那只会话。detail = `reason=<词> leg=<bg|resume|sync>[ at=<park_commit_refused|park_commit_cancelled>][ err=<原句>]`(不含凭据)。",
616
+ },
617
+ "server.park.row-commit-deferred": {
618
+ cls: "F",
619
+ note: "停驻的唯一提交点(`park-row-commit.ts` 的 `commitParkRow`;三条腿同经:后台腿 `leg=bg`、续跑腿的再停 / 重开 / 放回 `leg=resume`、同步 detach 腿 `leg=sync`):卡已提交之后 run 行的停驻写(`setSuspended` / `setNeedsReview`)撞店故障(抛:连接 / 超时 / 程序错)。规则「店的故障不是答案」⇒ 不收场:行不落 failed、卡不作废、认领留着,同一笔停驻再提交 —— 当拍一次,仍没答出 ⇒ 按心跳节拍续,店答出即收。停驻写的 CAS = 行仍归本腿(持有腿 `leg_id`,认领铸、交给本腿)∧ 在跑(或已停在本词上)∧ 没挂取消请求;第一笔与每一次再提交是同一个形(一笔抛了的写结局未知,同词重写幂等):写,店答出「不」⇒ 读行、由行答 —— 行不在 / 已终局 ⇒ 卡跟着作废;归别的腿、还活着 ⇒ 接手腿已接走,不再写;归本腿、停在本词上 ⇒ 停驻成立;归本腿、在跑、挂着取消请求 ⇒ 先作废卡、再落取消终局(码 `cancelled`;作废见 `server.park.held-card-void-failed`)。上界 = 两个判活窗(`REAP_RUN_STALE_SEC`);到上界仍没答 ⇒ 停手、交既有出路:行由失联收割按判活窗收成 failed 并放认领,卡由审批兜底收割按它的截止 / 绝对兜底时刻作废。放行的最坏后果 = 续写期间行停在 `running`(没有心跳):这一窗里决定那张卡答 409 `conflict.not_resumable`(行还没落到停驻词),落下之后同一决定照常受理;进程在续写期间退出 ⇒ 直接交既有出路(行被失联收割、卡由兜底收割)。不是门、不是凭据。detail = `leg=<bg|resume|sync> step=<first|again|retry|gave_up> err=<原句>`(不含凭据);计数 = 停驻提交失败的次数(第一笔写 / 再提交的读、写、取消终局写),`gave_up` 非零 = 有一次停驻交给了既有出路,去看那只会话与店。",
620
+ },
621
+ "server.park.row-commit-contradicted": {
622
+ cls: "F",
623
+ note: "停驻的唯一提交点(`park-row-commit.ts` 的 `commitParkRow`,`leg=bg|resume|sync`)的拒后判之外的那一格:停驻写被店答出「不」,随后读到的行却归本腿、在跑、没挂取消请求 —— CAS 的三件(持有腿 · 在跑或已停在本词上 · 没挂取消)读来都成立而写被拒,店自相矛盾,是不变量破,不是店抖动。本格不猜:当一次店故障处置(不收场、不作废卡、认领留着),交同一条再提交路(当拍一次、心跳节拍续、上界两个判活窗,`server.park.row-commit-deferred` 同计),店答出别的读数即按拒后判收场;一直矛盾 ⇒ 到上界停手、交既有出路(失联收割收行、审批兜底收割收卡)。放行的最坏后果 = 行在续写期间停在 `running`、卡待决到上界。不是门、不是凭据。计数非零 = 本库对同一行的 UPDATE 与 SELECT 答得不一致(读到的不是写判的那一份:读副本 / 隔离级别 / 店的缺陷),去查那只库。detail = `leg=<bg|resume|sync> taskId=<id> word=<suspended|needs_review> status=<读到的词> holder=self cancel=false`(不含凭据)。",
612
624
  },
613
625
  "server.verifier-pause.card-void-failed": {
614
626
  cls: "F",
@@ -1,4 +1,11 @@
1
1
  export type LogLevel = "debug" | "info" | "warn" | "error";
2
+ /**
3
+ * **启动协议行**(闭集):起本进程的那一方(壳 / 嵌入宿主 / 测试夹具)从 stdout 读这几行起步 —— `listening` 带内核分给本进程的口(`port`)与
4
+ * 实绑地址(`boundAddress`),读者拿它们找到并认出自己起的这只引擎。它们是协议,不是诊断:**在不在不随 `LOG_LEVEL`**(档位只滤诊断行;
5
+ * 档位调高而协议行跟着消失 ⇒ 读者要么拒起、要么各自替部署把档位压回 info,同一个事实多出几份读法)。除此之外与任何一行同路:同一只出口座
6
+ * (脱敏)、同一条流(按行上的 `level` 分流)、行上的 `level` 照写 —— 按 `level` 字段筛日志的管道照旧筛得掉它。
7
+ */
8
+ export declare const STARTUP_PROTOCOL_EVENTS: readonly ["listening"];
2
9
  export interface Logger {
3
10
  debug(msg: string, fields?: Record<string, unknown>): void;
4
11
  info(msg: string, fields?: Record<string, unknown>): void;
@@ -3,6 +3,8 @@ import { OVERSIZED_REDACTION_PLACEHOLDER, seatText } from "../trace/exit-seat.js
3
3
  import { errorKindOf } from "./err-text.js";
4
4
  import { buildFailOpenAnchor, installFailOpenAnnounceExit } from "./fail-open.js";
5
5
  const ORDER = { debug: 0, info: 1, warn: 2, error: 3 };
6
+ export const STARTUP_PROTOCOL_EVENTS = ["listening"];
7
+ const STARTUP_PROTOCOL = new Set(STARTUP_PROTOCOL_EVENTS);
6
8
  const LOG_LINE_WITHHELD = "log_line_withheld";
7
9
  const SECRET_SCREEN_FAILED = "secret_screen_failed";
8
10
  const UNFORMATTABLE = "unformattable";
@@ -61,7 +63,7 @@ const diagnosticStream = (stream) => (stdoutReservedForAnswer ? "stderr" : strea
61
63
  export function createLogger(minLevel = "info") {
62
64
  swallowStdioErrors();
63
65
  const emit = (level, msg, fields) => {
64
- if (ORDER[level] < ORDER[minLevel])
66
+ if (ORDER[level] < ORDER[minLevel] && !STARTUP_PROTOCOL.has(msg))
65
67
  return;
66
68
  const ts = new Date().toISOString();
67
69
  const line = serializeEntry({ ts, level, msg }, fields);
@@ -239,7 +239,7 @@ export function createMetrics() {
239
239
  m.counter("cost_quota_rejected_total", "Tasks refused because the principal is over its cumulative cost quota");
240
240
  m.counter("deny_sweep_resume_blocked_total", "SLA deny-sweep resumes the resume leg refused (every attempt; the deny_sweep_resume_blocked warn is logged once per row and refusal)");
241
241
  m.counter("deny_sweep_policy_blocked_expired_total", "approvals the SLA deny-sweep expired because the resume leg refused them for an admission-policy reason (resume_blocked_by_policy: the stored request is refused in this version for good, so the model-continuing deny cannot be delivered; counted once per card, only when this sweep won the settle)");
242
- m.counter("submit_ctx_run_release_failed_total", "Submissions whose resume-input write failed AND whose just-claimed run could not be released, by step (terminal|idem_key); the session stays held until REAP_RUN_STALE_SEC (one submit_ctx_run_release_failed warn per failure)");
242
+ m.counter("submit_ctx_run_release_failed_total", "Submissions whose resume-input write failed AND whose just-claimed run could not be withdrawn (step=withdraw: the store did not delete the run this submission minted); the session stays held until REAP_RUN_STALE_SEC (one submit_ctx_run_release_failed warn per failure)");
243
243
  m.counter("deny_sweep_list_failed_total", "SLA deny-sweep ticks whose read of the expired approvals failed (that tick denies nothing; one deny_sweep_list_failed warn per failure)");
244
244
  m.counter("deny_sweep_row_failed_total", "SLA deny-sweep rows whose stored request could not be read this tick (a projection-drift throw); that row is not resumed this tick, the rest of the page is swept (one deny_sweep_row_failed warn per failure)");
245
245
  m.counter("degraded_total", "Tasks degraded to a cheaper model (1.40), by reason (budget/rate_limit/breaker_open)");
@@ -132,7 +132,7 @@ export declare function redactModelText(raw: string, before?: string): string;
132
132
  * 它进引擎之前已**准入一次**:三只 brain 在建调用的那一行(`brain/tool-call-id.js` 的 `admitToolCallId`)—— 缺席 ⇒ 车道兜底铸;
133
133
  * 在形(可见 ASCII 1–128 且不含 `~`)⇒ 原样;越界 ⇒ 单射折叠成引擎 id(`<前 32 码元,越界字符记 `-`>~<sha256 前 32 hex>`),原字节只挂在
134
134
  * 转录的 `ToolCall.wireId` 上、只回给 provider。⇒ 一方 brain 在 7.107.0 起新铸的调用,到达本仓任何一张脸的 `toolCallId` 恒在形。
135
- * 残余两条([ref],如实):① ≤7.106.0 写下的存量行(待批 park 行 `boundCallId` / 检查点 `pendingAction.toolCallId` / 转录)是服务商原串逐字 —— 新版不对存量行二次准入(e2e G4 钉);② 宿主自己的 `Brain`(不经三只一方 adapter)铸的 id 不准入(core KL-1207-a;本仓生产装配的 brain 恒是 `createBrain` 的一方 adapter 外套委托装饰,这一形只经嵌入 / 测试注入的 brain 到达)。两条残余里的 id 仍是跨面 join 键、每张脸同值,只是形状不保证(本闸照旧不动它们:动一张脸 = join 断)。
135
+ * 残余两条([ref],如实):① ≤7.106.0 写下的存量行(待批 park 行 `boundCallId` / 检查点 `pendingAction.toolCallId` / 转录)是服务商原串逐字 —— 新版不对存量行二次准入(e2e G4 钉);② 宿主自己的 `Brain`(不经三只一方 adapter)铸的 id 不准入(core [ref];本仓生产装配的 brain 恒是 `createBrain` 的一方 adapter 外套委托装饰,这一形只经嵌入 / 测试注入的 brain 到达)。两条残余里的 id 仍是跨面 join 键、每张脸同值,只是形状不保证(本闸照旧不动它们:动一张脸 = join 断)。
136
136
  *
137
137
  * 🔴 **本闸只施加在「这个值出现的每一张脸都被覆盖到」的回声上**(codex r1 F1,实测成立的回归后改判):工具调用 id 是
138
138
  * **跨面 join 键** —— 同一枚 id 同时逐字出现在 `tool_start` / `tool_end` / 审批卡等逐帧面上。只在结果面动它 ⇒ 结果面与逐帧面
@@ -175,6 +175,7 @@ export const RESULT_TEXT_LEAVES = {
175
175
  "cancelContext.lastEventKind": "verbatim",
176
176
  "cancelContext.lastBrainStatus.phase": "verbatim",
177
177
  "cancelContext.lastBrainStatus.errClass": "verbatim",
178
+ "readDenyFloor.message": "verbatim",
178
179
  };
179
180
  const DROP_LEAF = Symbol("drop-leaf");
180
181
  function textLeafAct(treatment) {
@@ -90,7 +90,7 @@ export declare const SECRET_ENV_SCRUB_SITES: {
90
90
  };
91
91
  readonly "server.hooks.spawn-env": {
92
92
  readonly told: "log";
93
- readonly note: "settings hooks 的命令腿(请求带来的命令跑在宿主上)的 env —— 严格名单(`PATH` / `HOME` / 终端 / locale 等十二名)经引擎的 `hostChildEnv` 组合:名单外一律不交,本服务自有凭据任何情况都不交;请求的有效环境层(`settings.env`)作授予叠在上面;请求给工具 shell 的继承词对它不作用";
93
+ readonly note: "settings hooks 的命令腿(请求带来的命令跑在宿主上)的 env —— 严格名单(`PATH` / `HOME` / 终端 / locale 等十二名)∪ 部署方 `HOOK_ENV_ALLOW` 点名放回的变量,经引擎的 `hostChildEnv` 组合:其余一律不交,本服务自有凭据(名与值副本)任何情况都不交;请求的有效环境层(`settings.env`)作授予叠在上面;请求给工具 shell 的继承词对它不作用";
94
94
  readonly remedy: null;
95
95
  };
96
96
  readonly "server.project-memory.git-subprocess": {
@@ -20,7 +20,7 @@ export const SECRET_ENV_SCRUB_SITES = {
20
20
  },
21
21
  "server.hooks.spawn-env": {
22
22
  told: "log",
23
- note: "settings hooks 的命令腿(请求带来的命令跑在宿主上)的 env —— 严格名单(`PATH` / `HOME` / 终端 / locale 等十二名)经引擎的 `hostChildEnv` 组合:名单外一律不交,本服务自有凭据任何情况都不交;请求的有效环境层(`settings.env`)作授予叠在上面;请求给工具 shell 的继承词对它不作用",
23
+ note: "settings hooks 的命令腿(请求带来的命令跑在宿主上)的 env —— 严格名单(`PATH` / `HOME` / 终端 / locale 等十二名)∪ 部署方 `HOOK_ENV_ALLOW` 点名放回的变量,经引擎的 `hostChildEnv` 组合:其余一律不交,本服务自有凭据(名与值副本)任何情况都不交;请求的有效环境层(`settings.env`)作授予叠在上面;请求给工具 shell 的继承词对它不作用",
24
24
  remedy: null,
25
25
  },
26
26
  "server.project-memory.git-subprocess": {
@@ -15,7 +15,9 @@
15
15
  * + 可选 `urgent` 与显示名;不写 `fromSession / fromMode / hopChain`)。本仓不另铸任何记录形。
16
16
  * · **限流是配额店的两个原子动作,各管一件事**:`admitAttempt` 记发件人的每一次尝试(碰目录之前;界住刷目录的速率),
17
17
  * `take` 在同一把锁下判并记 (from→to) 对偶界与收件人聚合界(投递额度)。SQL 两方言各是一个事务,见
18
- * `plugins/org-delivery-quota-store.ts` 头注;File / Memory = 单进程。
18
+ * `plugins/org-delivery-quota-store.ts` 头注;File / Memory = 单进程。两个动作的拒都带店算的重试秒数,门原样放进 `rate_limited` 的答案里。
19
+ * · **答案是 core 闭集的答案加一个本服务的成员**:core 的 `OrgDeliveryOutcome` 对 `rate_limited` 只有码与句;本服务的 wire 另带 `retryAfterSec`,
20
+ * 所以门交出的是 {@link ServerOrgDeliveryOutcome} —— 对 core 的类型结构上是子型(多一个成员,别的词不变),`rate_limited` 一只词多一个必填成员。
19
21
  * · **收件人的 scope 就是收件人主体串本身**:本服务的引擎 scope = `spec.principal`(`resolve-spec.ts` 落
20
22
  * `auth.principal`;同一事实的推导见 `peer-directory.ts` 的「scope 轴」段)。门不另造编解码。
21
23
  *
@@ -33,7 +35,8 @@
33
35
  * 本仓不另抄宽度公式。部署没声明收件箱消费方(`no_consumer`)或别的铸信失败 ⇒ 门抛(core:「the gate maps that to its own failure」),HTTP 面答 500,同样没吃额度。
34
36
  * 3. **收件箱上界**(`peekCount` 读):满 ⇒ `inbox_full`,在吃配额之前判,满箱不烧发件人的额度。与引擎同主体车道的
35
37
  * `maxQueuedPeerMessages` 同一形(入口处读一次占用);两封并发信最多越界并发数那么多,上界由配额再界一次。
36
- * 4. **配额**(原子判并记):任一界满 ⇒ `rate_limited`,与第 0 步同一句(不让发件人从拒句里分辨出「收件人这一小时收了多少」)。
38
+ * 4. **配额**(原子判并记):任一界满 ⇒ `rate_limited`,与第 0 步同一句(不让发件人从拒句里分辨出「收件人这个窗里收了多少」);
39
+ * 同一个 `retryAfterSec` 口径 —— 配额店答的、到店钟当前窗结束的整秒数(第 0 步与第 4 步读同一口钟、同一道算式,数里也分辨不出是哪一界)。
37
40
  * 5. **追加**:`append(收件人 scope, PRINCIPAL_INBOX_HANDLE, 记录)`。店的预删除态拒码(`mailbox.recipient_tombstoned`)
38
41
  * 原样转成 `recipient_tombstoned`(core 对这只词的定义:「the store's own pre-delete code, relayed」);其余错误抛。
39
42
  * 被拒的投递在任何地方都不追加任何东西(core 契约原句);投递额度(第 4 步)在之后只有追加失败这一种「吃了额度没投到」—— 方向是收紧;
@@ -44,13 +47,14 @@
44
47
  * 跨 scope 写径:受理口(`POST /v1/principal-inbox/messages`)只调门,本仓源码里拼得出 `principal.inbox` 这只箱址的只有本文件
45
48
  * (`test/org-delivery-gate-single-path.test.ts` 按源码钉)。
46
49
  */
47
- import { type MailboxStore, type OrgDeliveryGate, type OrgDeliveryRefusalCode, type PrincipalInboxConsumer } from "@sema-agent/core";
50
+ import { type CrossPrincipalBody, type MailboxStore, type OrgAuthenticatedSender, type OrgDeliveryGate, type OrgDeliveryOutcome, type OrgDeliveryRefusalCode, type PrincipalInboxConsumer } from "@sema-agent/core";
48
51
  import type { OrgMemoryDirectory } from "./org-memory-admission.js";
49
52
  import type { OrgDeliveryQuotaPolicy, OrgDeliveryQuotaStore } from "./plugins/org-delivery-quota-store.js";
50
53
  /**
51
54
  * 跨主体配额(**唯一**的数字源;店只按它数)。默认显著紧于同主体车道(引擎 `PEER_LANE_DEFAULTS`:每发件人突发 30、
52
- * 每秒回填 0.5):同一对主体每小时 10 封,一位收件人每小时合计 30 封 —— org 里一个吵闹的主体淹不了别人的箱;
53
- * 一个发件人每小时 60 次尝试(成没成都算)—— 拿收件人串去问组织目录的速率有界(头注「次序」第 0 步)。
55
+ * 每秒回填 0.5):同一对主体每个挂钟整点桶 10 封,一位收件人每个挂钟整点桶合计 30 封 —— org 里一个吵闹的主体淹不了别人的箱;
56
+ * 一个发件人每个挂钟整点桶 60 次尝试(成没成都算)—— 拿收件人串去问组织目录的速率有界(头注「次序」第 0 步)。
57
+ * 「桶」= 店钟对齐的固定窗(窗宽一小时,`floor(店钟 / windowMs)` 一处公式,`plugins/org-delivery-quota-store.ts` 头注),不是滑动的「过去 60 分钟」。
54
58
  */
55
59
  export declare const ORG_DELIVERY_QUOTA: OrgDeliveryQuotaPolicy;
56
60
  /** 收件箱上界(在箱、未被消费方确认的信封数)。与引擎同主体车道的箱上界缺省(`maxQueuedPeerMessages`)同值。 */
@@ -61,6 +65,27 @@ export declare const PRINCIPAL_INBOX_BOUND = 50;
61
65
  * `not_member` 一句同时服务「不同 org / 查无此人 / 目录答不上来 / 收件人串不成形 / 发件人主体拼不进信封的发件人位」—— 改它要保持各臂同字节。
62
66
  */
63
67
  export declare const ORG_DELIVERY_REFUSAL_MESSAGES: Readonly<Record<OrgDeliveryRefusalCode, string>>;
68
+ /**
69
+ * 本服务的投递答案 = core 的 {@link OrgDeliveryOutcome} 加上额度拒的重试指引:`rate_limited` 一只词必带 `retryAfterSec`(配额店算的、到店钟当前窗结束的整秒数,
70
+ * ≥ 1),另三只词的答案与 core 的形逐字相同。对 core 的 `OrgDeliveryGate` 契约结构上是子型,所以这只门照样能交给任何读 core 契约的人。
71
+ * 数只在配额店算一次;HTTP 面把它投影成体里的 `retryAfterSec` 与同值 `Retry-After` 头(`routes/principal-inbox.ts`,不再算)。
72
+ */
73
+ export type ServerOrgDeliveryOutcome = Extract<OrgDeliveryOutcome, {
74
+ ok: true;
75
+ }> | {
76
+ readonly ok: false;
77
+ readonly code: Exclude<OrgDeliveryRefusalCode, "org_delivery.rate_limited">;
78
+ readonly message: string;
79
+ } | {
80
+ readonly ok: false;
81
+ readonly code: "org_delivery.rate_limited";
82
+ readonly message: string;
83
+ readonly retryAfterSec: number;
84
+ };
85
+ /** {@link createOrgDeliveryGate} 交出的门:core 契约的子型,答案是 {@link ServerOrgDeliveryOutcome}。装配点、`ServiceDeps.orgDeliveryGate` 与受理口读这一只型。 */
86
+ export interface ServerOrgDeliveryGate extends OrgDeliveryGate {
87
+ deliverCrossPrincipal(authedFrom: OrgAuthenticatedSender, toPrincipal: string, body: CrossPrincipalBody): Promise<ServerOrgDeliveryOutcome>;
88
+ }
64
89
  export interface OrgDeliveryGateDeps {
65
90
  /** org 成员目录 —— **必须**与记忆准入 seam / memory-policy / 共享记忆读面同一个实例(头注)。 */
66
91
  readonly directory: OrgMemoryDirectory;
@@ -78,7 +103,7 @@ export interface OrgDeliveryGateDeps {
78
103
  /**
79
104
  * 活对象(闭包持有目录 / 两只店 / 消费方)⇒ `create*`(CLAUDE.md 工厂命名律)。
80
105
  */
81
- export declare function createOrgDeliveryGate(deps: OrgDeliveryGateDeps): OrgDeliveryGate;
106
+ export declare function createOrgDeliveryGate(deps: OrgDeliveryGateDeps): ServerOrgDeliveryGate;
82
107
  /**
83
108
  * 箱址的读侧映射也归门(单一属主:箱址常量只在本文件出现,`test/org-delivery-gate-single-path.test.ts` ①):
84
109
  * 被扣的跨会话信在收信会话的哪条车道上 ⇄ core 队列键的 `box`。消费方 = `src/peer-inbound-face.ts`。
@@ -11,6 +11,7 @@ export const ORG_DELIVERY_REFUSAL_MESSAGES = Object.freeze({
11
11
  "org_delivery.recipient_tombstoned": "the recipient is being deleted — nothing was delivered",
12
12
  });
13
13
  const refuse = (code) => ({ ok: false, code, message: ORG_DELIVERY_REFUSAL_MESSAGES[code] });
14
+ const refuseRateLimited = (retryAfterSec) => ({ ok: false, code: "org_delivery.rate_limited", message: ORG_DELIVERY_REFUSAL_MESSAGES["org_delivery.rate_limited"], retryAfterSec });
14
15
  async function shareAnOrg(directory, a, b) {
15
16
  const [la, lb] = await Promise.all([directory.lookup(a), directory.lookup(b)]);
16
17
  if (la.kind !== "granted" || lb.kind !== "granted")
@@ -24,8 +25,9 @@ export function createOrgDeliveryGate(deps) {
24
25
  return {
25
26
  async deliverCrossPrincipal(authedFrom, toPrincipal, body) {
26
27
  const senderPerson = personOf(recoveredSubject(authedFrom.scope));
27
- if (!(await deps.quota.admitAttempt(senderPerson, ORG_DELIVERY_QUOTA)))
28
- return refuse("org_delivery.rate_limited");
28
+ const attempt = await deps.quota.admitAttempt(senderPerson, ORG_DELIVERY_QUOTA);
29
+ if (!attempt.granted)
30
+ return refuseRateLimited(attempt.retryAfterSec);
29
31
  if (!principalShaped(toPrincipal) || !(await shareAnOrg(deps.directory, senderPerson, toPrincipal))) {
30
32
  return refuse("org_delivery.not_member");
31
33
  }
@@ -42,8 +44,9 @@ export function createOrgDeliveryGate(deps) {
42
44
  }
43
45
  if ((await deps.mailbox.peekCount(toScope, PRINCIPAL_INBOX_HANDLE)) >= PRINCIPAL_INBOX_BOUND)
44
46
  return refuse("org_delivery.inbox_full");
45
- if (!(await deps.quota.take(senderPerson, toScope, ORG_DELIVERY_QUOTA)))
46
- return refuse("org_delivery.rate_limited");
47
+ const taken = await deps.quota.take(senderPerson, toScope, ORG_DELIVERY_QUOTA);
48
+ if (!taken.granted)
49
+ return refuseRateLimited(taken.retryAfterSec);
47
50
  let seq;
48
51
  try {
49
52
  seq = await deps.mailbox.append(toScope, PRINCIPAL_INBOX_HANDLE, record);
@@ -31,7 +31,7 @@ import type { SessionOwnerCell } from "./security.js";
31
31
  import { type DurableOwnerKey, type Subject } from "./owner-brands.js";
32
32
  /** 行资格:调用方对**这一行**的关系(四格,见 {@link qualsOf})。 */
33
33
  export type RowQual = "owner" | "open" | "j4" | "anon_tree";
34
- /** fleet 资格:与行无关的调用方事实 —— 没有身份边界的部署(`dev_open`)、代部署本人说话的 service 凭据(`deployment_token`)、只读 trace 凭据(`trace_read`)。 */
34
+ /** fleet 资格:与行无关的调用方事实 —— 没有身份边界的部署上不报主体的调用方(`dev_open`)、代部署本人说话的 service 凭据(`deployment_token`)、只读 trace 凭据(`trace_read`)。 */
35
35
  export type FleetQual = "dev_open" | "deployment_token" | "trace_read";
36
36
  /** 资格闭集:行资格 ∪ fleet 资格 ∪ 运维(`operator`,与行无关的调用方事实)。 */
37
37
  export type Qual = RowQual | FleetQual | "operator";
@@ -39,7 +39,8 @@ export type Qual = RowQual | FleetQual | "operator";
39
39
  * 一次判定的调用方(四格事实 + 部署两格)。铸点闭集:`http/owner-access.ts` 的 `callerOf`(请求口)/ `callerOfDecision`(决定口),`security.ts` 的 `claimCallerOf`(认领面与协议口:不放 fleet、不放运维),别处不手搓。
40
40
  * · `subject` —— 验过的主体(分区键,`owner-brands.ts`;`gatedSubject`;决定口是证明推出的人的主体);载体只带这一格,人经 `personOf(subject)` 读;
41
41
  * · `operator` —— `explicitOperatorOk(personOf(subject))`(运维名册的唯一读法:读人,不读分区),与 `subject` 同一次铸;
42
- * · `fleet` —— `dev_open`(装配没接任何身份来源)/ `deployment_token`(出示 service 凭据、不报主体、部署没声明关掉)/ 缺席;两来源互斥;
42
+ * · `fleet` —— `dev_open`(装配没接任何身份来源 ∧ 不报主体)/ `deployment_token`(出示 service 凭据、不报主体、部署没声明关掉)/ 缺席;两来源互斥,报了主体 ⇒ 恒缺席
43
+ * (唯一读法 `http/principal-gate.ts` 的 `actsForDeployment`:报了主体的调用方在每一口都是那位主体);
43
44
  * · `traceRead` —— 出示了只读 trace 凭据;
44
45
  * · `principalRequired` / `multiTenant` —— 部署形表的两只谓词(身份前门的条件 / `j4` 的条件)。
45
46
  */
@@ -111,9 +112,10 @@ export type FaceDoor = "P401" | "I401" | "I401r" | "none";
111
112
  * · `deleted_false` —— 200 `{deleted:false}`(删除口幂等形:没删到东西);
112
113
  * · `run_exists` —— 409 `conflict.run_exists`(提交重放:这把键 / 这只 taskId 已被占用);
113
114
  * · `attach_absent` —— 404 `resume.session_not_found`「requireExistingSession: session does not exist …」(提交挂接:认领面没有「没有就建」可镜像,占用 = 不存在那一体);
115
+ * · `workflow_missing` —— 404 `not_found.workflow` "workflow not found"(工作流按 id 四口;没有 / 看不见 / 会话断言不符同体);
114
116
  * · `omit` —— 本模块不下发:调用点把「看不见」当「没有」走它自己的缺席路径(协议口的 RpcError / leader 404 / 嵌套可选字段省略)。
115
117
  */
116
- export type FaceProjection = "run_missing" | "task_missing" | "decision_missing" | "session_missing" | "exemption_missing" | "deleted_false" | "run_exists" | "attach_absent" | "omit";
118
+ export type FaceProjection = "run_missing" | "task_missing" | "decision_missing" | "session_missing" | "exemption_missing" | "deleted_false" | "workflow_missing" | "run_exists" | "attach_absent" | "omit";
117
119
  /** 属主读不出(会话店交出具名拒「属主读不出」)时本口怎么读:`fold` = 读作没有这一行(同一只投影,原故障进运维日志一行);`raise` = 原故障照常上抛。 */
118
120
  export type FaceUnreadable = "fold" | "raise";
119
121
  /**
@@ -125,8 +127,8 @@ export type FaceUnreadable = "fold" | "raise";
125
127
  */
126
128
  export type FacePlacementUnreadable = "raise" | "ordinary";
127
129
  export interface Face {
128
- /** 行的种类:run / 会话行(路由经 `http/owner-access.ts` 的门判)、停驻行 scope 列(`scope`)、ask 行 / 活登记 / 活问(`ask`)、收件条目(`inbox`)、列表面(`list`)。 */
129
- readonly resource: "run" | "session" | "scope" | "ask" | "inbox" | "list";
130
+ /** 行的种类:run / 会话行(路由经 `http/owner-access.ts` 的门判)、工作流行(`workflow`:属主 = 引擎写下的 `scope` 列)、停驻行 scope 列(`scope`)、ask 行 / 活登记 / 活问(`ask`)、收件条目(`inbox`)、列表面(`list`)。 */
131
+ readonly resource: "run" | "session" | "workflow" | "scope" | "ask" | "inbox" | "list";
130
132
  /** 行资格里本口放哪几格。 */
131
133
  readonly grants: readonly RowQual[];
132
134
  /** fleet 资格里本口放哪几格(D1 列,见模块头注)。 */
@@ -384,6 +386,26 @@ export declare const FACES: {
384
386
  readonly unreadable: "raise";
385
387
  readonly placementUnreadable: "ordinary";
386
388
  };
389
+ readonly "workflow.read": {
390
+ readonly resource: "workflow";
391
+ readonly grants: readonly ["owner"];
392
+ readonly fleet: readonly [];
393
+ readonly operator: false;
394
+ readonly door: "P401";
395
+ readonly projection: "workflow_missing";
396
+ readonly unreadable: "raise";
397
+ readonly placementUnreadable: "raise";
398
+ };
399
+ readonly "workflow.steer": {
400
+ readonly resource: "workflow";
401
+ readonly grants: readonly ["owner"];
402
+ readonly fleet: readonly [];
403
+ readonly operator: false;
404
+ readonly door: "P401";
405
+ readonly projection: "workflow_missing";
406
+ readonly unreadable: "raise";
407
+ readonly placementUnreadable: "raise";
408
+ };
387
409
  readonly "scope.decide": {
388
410
  readonly resource: "scope";
389
411
  readonly grants: readonly ["owner", "open"];
@@ -455,6 +477,9 @@ export type SessionFaceId = {
455
477
  export type ListFaceId = {
456
478
  [F in FaceId]: (typeof FACES)[F]["resource"] extends "list" ? F : never;
457
479
  }[FaceId];
480
+ export type WorkflowFaceId = {
481
+ [F in FaceId]: (typeof FACES)[F]["resource"] extends "workflow" ? F : never;
482
+ }[FaceId];
458
483
  /**
459
484
  * **只看「验过的主体 + 运维位」的面**(派生型:行资格 ⊆ {owner, open} ∧ fleet 列空):这几只面的可见性与部署形、fleet 事实都无关 ——
460
485
  * 面表里给其中一行加上 `j4` / 任一 fleet 格,它就掉出本型,{@link keyAdmits} 的调用点编译红(那时它要一只完整的 {@link Caller})。
@@ -74,6 +74,8 @@ export const FACES = {
74
74
  "session.policy": { resource: "session", grants: ["owner", "open", "anon_tree"], fleet: ["dev_open"], operator: true, door: "I401r", projection: "session_missing", unreadable: "raise", placementUnreadable: "ordinary" },
75
75
  "session.notify": { resource: "session", grants: ["owner", "open", "anon_tree"], fleet: ["dev_open"], operator: true, door: "P401", projection: "session_missing", unreadable: "raise", placementUnreadable: "raise" },
76
76
  "session.attach": { resource: "session", grants: ["owner", "open"], fleet: [], operator: false, door: "none", projection: "attach_absent", unreadable: "raise", placementUnreadable: "ordinary" },
77
+ "workflow.read": { resource: "workflow", grants: ["owner"], fleet: [], operator: false, door: "P401", projection: "workflow_missing", unreadable: "raise", placementUnreadable: "raise" },
78
+ "workflow.steer": { resource: "workflow", grants: ["owner"], fleet: [], operator: false, door: "P401", projection: "workflow_missing", unreadable: "raise", placementUnreadable: "raise" },
77
79
  "scope.decide": { resource: "scope", grants: ["owner", "open"], fleet: [], operator: true, door: "none", projection: "omit", unreadable: "raise", placementUnreadable: "raise" },
78
80
  "ask.decide": { resource: "ask", grants: ["owner", "open"], fleet: [], operator: true, door: "none", projection: "omit", unreadable: "raise", placementUnreadable: "raise" },
79
81
  "ask.answer": { resource: "ask", grants: ["owner", "open"], fleet: [], operator: false, door: "none", projection: "omit", unreadable: "raise", placementUnreadable: "raise" },