@sema-agent/server 7.139.0 → 7.141.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 (328) hide show
  1. package/MIGRATION.md +471 -0
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/USAGE.md +94 -26
  5. package/dist/adoption/runner.js +1 -1
  6. package/dist/adoption/sql.js +1 -1
  7. package/dist/approval-batch-census.d.ts +27 -0
  8. package/dist/approval-batch-census.js +27 -0
  9. package/dist/approval-card.d.ts +37 -22
  10. package/dist/approval-card.js +6 -3
  11. package/dist/approval.d.ts +15 -0
  12. package/dist/approval.js +10 -0
  13. package/dist/audit.d.ts +4 -2
  14. package/dist/audit.js +2 -2
  15. package/dist/bench/s1/live-deps.js +3 -2
  16. package/dist/bench/s1/row.d.ts +5 -2
  17. package/dist/bench/s1/row.js +2 -22
  18. package/dist/boot/adoption.js +1 -1
  19. package/dist/boot/device-lane.d.ts +11 -0
  20. package/dist/boot/device-lane.js +16 -0
  21. package/dist/boot/engine-lease.d.ts +24 -3
  22. package/dist/boot/engine-lease.js +9 -2
  23. package/dist/boot/execution-env.js +18 -12
  24. package/dist/boot/execution-lane.d.ts +8 -0
  25. package/dist/boot/execution-lane.js +6 -1
  26. package/dist/boot/memory-boundary.d.ts +16 -53
  27. package/dist/boot/memory-boundary.js +10 -20
  28. package/dist/boot/memory-consolidation.d.ts +16 -12
  29. package/dist/boot/memory-consolidation.js +24 -13
  30. package/dist/boot/reapers.d.ts +2 -2
  31. package/dist/boot/resolve-spec.d.ts +3 -5
  32. package/dist/boot/resolve-spec.js +9 -8
  33. package/dist/boot/runner-deps.d.ts +3 -3
  34. package/dist/boot/runner-deps.js +1 -0
  35. package/dist/boot/session-faces.d.ts +1 -1
  36. package/dist/boot/session-faces.js +4 -3
  37. package/dist/boot/shutdown.js +5 -0
  38. package/dist/boot/stage-03-store-backend.d.ts +2 -6
  39. package/dist/boot/stage-03-store-backend.js +2 -3
  40. package/dist/boot/stage-04-stores.d.ts +2 -6
  41. package/dist/boot/stage-04-stores.js +5 -5
  42. package/dist/boot/stage-05-execution-env.d.ts +2 -6
  43. package/dist/boot/stage-05-execution-env.js +3 -1
  44. package/dist/boot/stage-06-runners.d.ts +2 -8
  45. package/dist/boot/stage-06-runners.js +3 -3
  46. package/dist/boot/stage-07-capability-layer.d.ts +2 -7
  47. package/dist/boot/stage-07-capability-layer.js +8 -10
  48. package/dist/boot/stage-08-reapers.d.ts +2 -7
  49. package/dist/boot/stage-09-leader.d.ts +2 -7
  50. package/dist/boot/stage-10-http-server.d.ts +2 -7
  51. package/dist/boot/stage-10-http-server.js +6 -4
  52. package/dist/boot/stores.d.ts +3 -6
  53. package/dist/boot/stores.js +37 -44
  54. package/dist/boot/task-list-lane.d.ts +1 -1
  55. package/dist/boot/task-list-lane.js +1 -1
  56. package/dist/boot/web-admin.js +36 -9
  57. package/dist/capabilities/execution-lane.d.ts +2 -2
  58. package/dist/capabilities/scenarios.d.ts +1 -1
  59. package/dist/capability-facts.d.ts +9 -0
  60. package/dist/capability-facts.js +9 -0
  61. package/dist/card-void.d.ts +38 -0
  62. package/dist/card-void.js +23 -0
  63. package/dist/config-catalog.js +12 -8
  64. package/dist/config-provider.d.ts +18 -17
  65. package/dist/config-provider.js +28 -36
  66. package/dist/config-types.d.ts +36 -9
  67. package/dist/config.js +56 -46
  68. package/dist/delegated-session-owner.d.ts +23 -20
  69. package/dist/delegated-session-owner.js +2 -2
  70. package/dist/deployment-shape.d.ts +9 -8
  71. package/dist/deployment-shape.js +4 -4
  72. package/dist/device-store.d.ts +7 -0
  73. package/dist/device-store.js +3 -0
  74. package/dist/execution-config-root.d.ts +22 -0
  75. package/dist/execution-config-root.js +35 -0
  76. package/dist/execution-lane-caps.d.ts +145 -107
  77. package/dist/execution-lane-caps.js +144 -83
  78. package/dist/execution-placement.d.ts +3 -0
  79. package/dist/execution-placement.js +7 -0
  80. package/dist/fleet/drain-entry.d.ts +3 -0
  81. package/dist/hosted-posture.d.ts +8 -0
  82. package/dist/hosted-posture.js +4 -0
  83. package/dist/http/admission.js +3 -3
  84. package/dist/http/caller-trust.d.ts +3 -2
  85. package/dist/http/caller-trust.js +2 -1
  86. package/dist/http/dispatch.js +4 -0
  87. package/dist/http/live-frame.d.ts +24 -0
  88. package/dist/http/live-frame.js +16 -0
  89. package/dist/http/memory-compliance-failure-reply.d.ts +3 -1
  90. package/dist/http/memory-compliance-failure-reply.js +5 -0
  91. package/dist/http/memory-layer-reply.d.ts +30 -0
  92. package/dist/http/memory-layer-reply.js +24 -0
  93. package/dist/http/resume-legs.js +49 -35
  94. package/dist/http/retired-service-deps.d.ts +1 -1
  95. package/dist/http/retired-service-deps.js +1 -1
  96. package/dist/http/route-table.js +2 -0
  97. package/dist/http/routes/adoption.js +1 -1
  98. package/dist/http/routes/approvals-assistant.js +1 -0
  99. package/dist/http/routes/capabilities.js +5 -4
  100. package/dist/http/routes/diagnostics.d.ts +0 -19
  101. package/dist/http/routes/diagnostics.js +16 -2
  102. package/dist/http/routes/memory-bundle.d.ts +2 -2
  103. package/dist/http/routes/memory-bundle.js +4 -1
  104. package/dist/http/routes/memory-compliance.js +9 -2
  105. package/dist/http/routes/memory-consolidation.js +12 -1
  106. package/dist/http/routes/memory-origin.js +14 -2
  107. package/dist/http/routes/memory-policy.js +7 -2
  108. package/dist/http/routes/run-permission-mode.d.ts +75 -0
  109. package/dist/http/routes/run-permission-mode.js +170 -0
  110. package/dist/http/routes/session-sync.d.ts +3 -6
  111. package/dist/http/routes/session-sync.js +7 -2
  112. package/dist/http/routes/sessions.js +33 -15
  113. package/dist/http/routes/tasks.js +67 -68
  114. package/dist/http/run-read-face.js +3 -3
  115. package/dist/http/send.d.ts +1 -1
  116. package/dist/http/send.js +2 -2
  117. package/dist/http/server.d.ts +14 -27
  118. package/dist/http/server.js +2 -2
  119. package/dist/http/sse-log.d.ts +3 -8
  120. package/dist/http/stored-body-replay.d.ts +3 -3
  121. package/dist/http/stored-body-replay.js +3 -1
  122. package/dist/identity-source.d.ts +1 -1
  123. package/dist/identity-source.js +1 -1
  124. package/dist/instruction-source-notice.d.ts +7 -0
  125. package/dist/instruction-source-notice.js +6 -6
  126. package/dist/lane-home-probe.d.ts +68 -42
  127. package/dist/lane-home-probe.js +53 -30
  128. package/dist/leader/wire.js +5 -4
  129. package/dist/mcp-assertion-header.d.ts +4 -0
  130. package/dist/mcp-assertion-header.js +5 -0
  131. package/dist/memory-bundle-engine.d.ts +16 -9
  132. package/dist/memory-bundle-engine.js +29 -6
  133. package/dist/memory-operator-faces.d.ts +85 -30
  134. package/dist/memory-operator-faces.js +136 -30
  135. package/dist/memory-posture.d.ts +1 -1
  136. package/dist/memory-project-layer.d.ts +3 -21
  137. package/dist/memory-project-layer.js +11 -8
  138. package/dist/memory-scope-stores.d.ts +73 -0
  139. package/dist/memory-scope-stores.js +86 -0
  140. package/dist/memory-scope.d.ts +33 -9
  141. package/dist/memory-scope.js +17 -5
  142. package/dist/memory-sync-client.d.ts +34 -9
  143. package/dist/memory-sync-client.js +108 -28
  144. package/dist/observability/fail-open.d.ts +30 -2
  145. package/dist/observability/fail-open.js +30 -2
  146. package/dist/observability/metrics.js +0 -1
  147. package/dist/observability/run-terminal.d.ts +6 -2
  148. package/dist/observability/run-terminal.js +25 -26
  149. package/dist/observability/secret-env-scrub.d.ts +20 -1
  150. package/dist/observability/secret-env-scrub.js +14 -0
  151. package/dist/orchestration/workflow-completion-inbox.d.ts +5 -2
  152. package/dist/orchestration/workflow-completion-inbox.js +13 -5
  153. package/dist/orchestration/workflow-notify-journal.d.ts +5 -3
  154. package/dist/orchestration/workflow-notify-journal.js +2 -1
  155. package/dist/permission-mode-admission.d.ts +68 -0
  156. package/dist/permission-mode-admission.js +23 -0
  157. package/dist/permission-rule-list.d.ts +55 -6
  158. package/dist/permission-rule-list.js +52 -5
  159. package/dist/plugins/adoption-log-sql.js +4 -4
  160. package/dist/plugins/approval-ask-store-sql.js +14 -14
  161. package/dist/plugins/approval-nonce-store.js +4 -4
  162. package/dist/plugins/blob-backend.d.ts +4 -4
  163. package/dist/plugins/blob-backend.js +7 -7
  164. package/dist/plugins/breaker-state-sql.js +2 -2
  165. package/dist/plugins/caching-session-store.d.ts +6 -0
  166. package/dist/plugins/caching-session-store.js +3 -0
  167. package/dist/plugins/checkpoint-index-columns.js +2 -2
  168. package/dist/plugins/checkpoint-store-sql.d.ts +65 -17
  169. package/dist/plugins/checkpoint-store-sql.js +90 -19
  170. package/dist/plugins/device-store-sql.d.ts +5 -2
  171. package/dist/plugins/device-store-sql.js +23 -20
  172. package/dist/plugins/ensure-index.d.ts +1 -2
  173. package/dist/plugins/execution-placement-sql.d.ts +19 -9
  174. package/dist/plugins/execution-placement-sql.js +20 -9
  175. package/dist/plugins/file-history-store-sql.d.ts +2 -2
  176. package/dist/plugins/file-history-store-sql.js +4 -4
  177. package/dist/plugins/file-run-store.d.ts +2 -2
  178. package/dist/plugins/file-run-store.js +1 -1
  179. package/dist/plugins/fork-routing-session-store.d.ts +10 -32
  180. package/dist/plugins/fork-routing-session-store.js +2 -61
  181. package/dist/plugins/image-bake-store-sql.js +9 -9
  182. package/dist/plugins/image-index-sql.js +11 -11
  183. package/dist/plugins/k8s-exec-protocol.d.ts +4 -1
  184. package/dist/plugins/k8s-exec-protocol.js +6 -1
  185. package/dist/plugins/leader-run-store-sql.js +4 -4
  186. package/dist/plugins/local-checkpoint-store.d.ts +10 -1
  187. package/dist/plugins/local-checkpoint-store.js +22 -0
  188. package/dist/plugins/local-session-store.d.ts +227 -35
  189. package/dist/plugins/local-session-store.js +518 -37
  190. package/dist/plugins/local-session-window.d.ts +17 -3
  191. package/dist/plugins/local-session-window.js +7 -13
  192. package/dist/plugins/mailbox-store-sql.d.ts +2 -1
  193. package/dist/plugins/mailbox-store-sql.js +4 -4
  194. package/dist/plugins/memory-engine-tidb.js +5 -5
  195. package/dist/plugins/memory-optout-grant-store-sql.js +1 -1
  196. package/dist/plugins/memory-run-store.d.ts +2 -2
  197. package/dist/plugins/memory-run-store.js +1 -1
  198. package/dist/plugins/memory-sync-store-tidb.js +3 -3
  199. package/dist/plugins/one-time-migrations.d.ts +52 -11
  200. package/dist/plugins/one-time-migrations.js +101 -39
  201. package/dist/plugins/org-delivery-quota-store.js +2 -2
  202. package/dist/plugins/outcome-ledger-sql.js +2 -2
  203. package/dist/plugins/permission-rule-store-sql.d.ts +4 -4
  204. package/dist/plugins/permission-rule-store-sql.js +16 -16
  205. package/dist/plugins/pg-pool.js +3 -2
  206. package/dist/plugins/pg-session-storage.d.ts +2 -0
  207. package/dist/plugins/pg-session-storage.js +3 -2
  208. package/dist/plugins/remote-env-adb.d.ts +7 -24
  209. package/dist/plugins/remote-env-adb.js +22 -5
  210. package/dist/plugins/remote-env-device.d.ts +2 -28
  211. package/dist/plugins/remote-env-device.js +2 -1
  212. package/dist/plugins/remote-env-e2b.d.ts +40 -27
  213. package/dist/plugins/remote-env-e2b.js +180 -20
  214. package/dist/plugins/remote-env-file-error.d.ts +1 -1
  215. package/dist/plugins/remote-env-file-error.js +8 -2
  216. package/dist/plugins/remote-env-host.d.ts +19 -35
  217. package/dist/plugins/remote-env-host.js +26 -3
  218. package/dist/plugins/remote-env-k8s.d.ts +22 -14
  219. package/dist/plugins/remote-env-k8s.js +150 -26
  220. package/dist/plugins/remote-env-local-docker.d.ts +27 -24
  221. package/dist/plugins/remote-env-local-docker.js +91 -24
  222. package/dist/plugins/remote-env-ssh.d.ts +4 -24
  223. package/dist/plugins/remote-env-ssh.js +4 -3
  224. package/dist/plugins/resume-anchor-store-sql.js +2 -2
  225. package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
  226. package/dist/plugins/retention-lane-store-sql.js +2 -2
  227. package/dist/plugins/retention-store-sql.d.ts +1 -1
  228. package/dist/plugins/retention-store-sql.js +6 -6
  229. package/dist/plugins/run-store-sql.d.ts +3 -3
  230. package/dist/plugins/run-store-sql.js +19 -18
  231. package/dist/plugins/sandbox-read-floor.d.ts +273 -0
  232. package/dist/plugins/sandbox-read-floor.js +608 -0
  233. package/dist/plugins/schema-consistency.d.ts +6 -6
  234. package/dist/plugins/schema-consistency.js +1 -1
  235. package/dist/plugins/schema-ensure-legs.d.ts +2 -3
  236. package/dist/plugins/schema-ensure-legs.js +2 -2
  237. package/dist/plugins/schema-live-columns.d.ts +1 -1
  238. package/dist/plugins/session-capture-record-store-sql.js +1 -1
  239. package/dist/plugins/session-ownership.d.ts +2 -1
  240. package/dist/plugins/session-placement.d.ts +17 -4
  241. package/dist/plugins/session-placement.js +2 -1
  242. package/dist/plugins/session-rules-column.d.ts +1 -1
  243. package/dist/plugins/session-rules-column.js +1 -1
  244. package/dist/plugins/session-store.d.ts +18 -20
  245. package/dist/plugins/session-store.js +4 -12
  246. package/dist/plugins/session-workspace-cell.d.ts +1 -1
  247. package/dist/plugins/session-workspace-cell.js +1 -1
  248. package/dist/plugins/shared-memory-store-sql.js +2 -2
  249. package/dist/plugins/sql-driver.d.ts +10 -5
  250. package/dist/plugins/sql-driver.js +6 -6
  251. package/dist/plugins/sql-errors.js +1 -1
  252. package/dist/plugins/store-backend.d.ts +35 -6
  253. package/dist/plugins/store-backend.js +27 -10
  254. package/dist/plugins/store-contracts.d.ts +9 -2
  255. package/dist/plugins/task-list-store-sql.js +11 -11
  256. package/dist/plugins/tidb-pool.js +7 -6
  257. package/dist/plugins/tidb-session-storage.js +4 -4
  258. package/dist/plugins/tidb-session-store.d.ts +4 -1
  259. package/dist/plugins/tidb-session-store.js +16 -15
  260. package/dist/plugins/tool-result-store-sql.d.ts +2 -2
  261. package/dist/plugins/tool-result-store-sql.js +3 -3
  262. package/dist/plugins/user-input-ledger-sql.js +2 -2
  263. package/dist/plugins/workflow-journal-store-sql.js +5 -5
  264. package/dist/plugins/workflow-run-store-sql.js +19 -19
  265. package/dist/plugins/write-behind-counter.d.ts +2 -3
  266. package/dist/plugins/write-behind-counter.js +5 -5
  267. package/dist/resource-suspend.d.ts +14 -12
  268. package/dist/resource-suspend.js +1 -1
  269. package/dist/resource-window.d.ts +4 -3
  270. package/dist/run-cancel-context.d.ts +34 -0
  271. package/dist/run-cancel-context.js +7 -0
  272. package/dist/run-local.js +14 -19
  273. package/dist/runs.d.ts +47 -16
  274. package/dist/runs.js +112 -113
  275. package/dist/security.d.ts +2 -2
  276. package/dist/server-secret-env.d.ts +2 -1
  277. package/dist/server-secret-env.js +2 -4
  278. package/dist/session-error-wire.d.ts +22 -4
  279. package/dist/session-error-wire.js +16 -0
  280. package/dist/session-incarnation.d.ts +10 -4
  281. package/dist/session-incarnation.js +1 -1
  282. package/dist/session-policy-wire.d.ts +1 -1
  283. package/dist/session-sync-kernel.d.ts +42 -1
  284. package/dist/session-sync-kernel.js +17 -0
  285. package/dist/session-sync.js +16 -4
  286. package/dist/sql-engine-coordinates.d.ts +49 -0
  287. package/dist/sql-engine-coordinates.js +27 -0
  288. package/dist/sql-engine-posture.d.ts +1 -1
  289. package/dist/sql-engine-posture.js +1 -1
  290. package/dist/standing-answer-grant.d.ts +31 -2
  291. package/dist/standing-answer-grant.js +14 -2
  292. package/dist/store-posture.d.ts +1 -1
  293. package/dist/{plugins → stores-sql}/background-agent-store-sql.d.ts +2 -2
  294. package/dist/{plugins → stores-sql}/background-agent-store-sql.js +8 -8
  295. package/dist/{plugins → stores-sql}/session-policy-store-sql.d.ts +7 -5
  296. package/dist/{plugins → stores-sql}/session-policy-store-sql.js +12 -12
  297. package/dist/{plugins → stores-sql}/usage-window-store-sql.d.ts +1 -1
  298. package/dist/{plugins → stores-sql}/usage-window-store-sql.js +3 -3
  299. package/dist/task-a2a.d.ts +1 -1
  300. package/dist/task-a2a.js +5 -6
  301. package/dist/task-mcp.d.ts +21 -8
  302. package/dist/task-mcp.js +17 -9
  303. package/dist/task-settings.d.ts +52 -25
  304. package/dist/task-settings.js +91 -28
  305. package/dist/terminal.d.ts +103 -19
  306. package/dist/terminal.js +72 -20
  307. package/dist/trace/core-keyset-guard.d.ts +79 -2
  308. package/dist/trace/exit-seat.d.ts +7 -0
  309. package/dist/trace/exit-seat.js +1 -0
  310. package/dist/trace/model-segment.d.ts +2 -2
  311. package/dist/trace/redact.d.ts +3 -1
  312. package/dist/trace/redact.js +395 -110
  313. package/dist/trace/self-minted-wire.d.ts +226 -2
  314. package/dist/trace/self-minted-wire.js +79 -0
  315. package/dist/verifier-pause-card.d.ts +8 -0
  316. package/dist/verifier-pause-card.js +19 -0
  317. package/dist/web-admin-client/apply-effective.d.ts +5 -7
  318. package/dist/web-admin-client/apply-effective.js +2 -2
  319. package/dist/web-admin-client/candidate-gate.d.ts +11 -7
  320. package/dist/web-admin-client/candidate-gate.js +1 -1
  321. package/dist/web-admin-client/http-client.d.ts +5 -4
  322. package/dist/web-admin-client/http-client.js +2 -2
  323. package/dist/web-admin-client/read-warnings.d.ts +7 -17
  324. package/dist/web-admin-client/read-warnings.js +5 -9
  325. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -2
  326. package/package.json +2 -2
  327. package/wire-changes/server@7.140.0.json +184 -0
  328. package/wire-changes/server@7.141.0.json +367 -0
@@ -41,7 +41,7 @@ export declare const FAIL_OPEN_TAGS: {
41
41
  };
42
42
  readonly "server.tool-end-media.live-backlog-degraded": {
43
43
  readonly cls: "F";
44
- readonly note: "core 7.50.0 媒体块提货(`trace/tool-output-media.ts` 的 `liveToolEndForBacklog`,三处活面写口共用的那一只判据 —— 同步流出口 `sseData`、子代 tail 路由写环、tail 总线每订阅者队列):本帧媒体字节(`output` 媒体块的 `data` 与 `structured` 媒体卡的 `file.base64` 一起计)+ 这条连接 / 这个订阅者还没送出去的字节 > 上界(64 MiB)⇒ 本帧媒体降成持久面那只形(媒体块换描述符 `{ type, mimeType?, bytes, truncated: true }`,帧级 `truncated` + `totalChars`;媒体卡去掉 `file.base64`)。每降一帧记一次,只在这只函数里记(三处写口不各记)。放行的最坏后果 = 一个读得慢的观众在 SSE 上看不到这张图,只见「这里有一张多大的什么图、没送达」(账本面本就恒是描述符),不是门、不是凭据、不改任何裁决;反方向(不降)让一条停读的连接随帧数线性压住几百 MiB。帧上它与引擎自己的媒体预算降级同形不可分,所以计数是运维唯一能看出「多少观众丢了图」的位;计数持续非零 = 有消费端读流太慢(或网络瓶颈),去看那几条连接。detail = `backlog=<待发字节> media=<本帧媒体字节>`。";
44
+ readonly note: "core 7.50.0 媒体块提货(`trace/tool-output-media.ts` 的 `liveToolEndForBacklog`,三处活面写口共用的那一只判据 —— 同步流出口 `writeLiveFrame`、子代 tail 路由写环、tail 总线每订阅者队列):本帧媒体字节(`output` 媒体块的 `data` 与 `structured` 媒体卡的 `file.base64` 一起计)+ 这条连接 / 这个订阅者还没送出去的字节 > 上界(64 MiB)⇒ 本帧媒体降成持久面那只形(媒体块换描述符 `{ type, mimeType?, bytes, truncated: true }`,帧级 `truncated` + `totalChars`;媒体卡去掉 `file.base64`)。每降一帧记一次,只在这只函数里记(三处写口不各记)。放行的最坏后果 = 一个读得慢的观众在 SSE 上看不到这张图,只见「这里有一张多大的什么图、没送达」(账本面本就恒是描述符),不是门、不是凭据、不改任何裁决;反方向(不降)让一条停读的连接随帧数线性压住几百 MiB。帧上它与引擎自己的媒体预算降级同形不可分,所以计数是运维唯一能看出「多少观众丢了图」的位;计数持续非零 = 有消费端读流太慢(或网络瓶颈),去看那几条连接。detail = `backlog=<待发字节> media=<本帧媒体字节>`。";
45
45
  };
46
46
  readonly "server.memory-consolidation.operator-valve-layers-unfed": {
47
47
  readonly cls: "P-DEBT";
@@ -171,6 +171,10 @@ export declare const FAIL_OPEN_TAGS: {
171
171
  readonly cls: "F";
172
172
  readonly note: "design/382 §3.5(S-44;core 7.55.0 #1468 P1 阶段二起读者是 core `readRuleOffers`,经 `approval-card.ts` 的 `readRuleOfferList`,两条腿同调):batch offer 的 `uncoveredDetail` 明细座不是「每个计数段一行良构行」(集外 reason / 非数组 / 行数与 count 座不等 —— core 读者判丢、读数带 `uncoveredDetailDropped`)或行数超本仓展示帽 MAX_UNCOVERED_DETAIL_ROWS ⇒ 只丢这一座、batch 本体照投。放行的最坏后果 = 卡上少几行「这段为什么还会问」的解释(count 座仍在,core 契约明写明细缺席不是断言);把整只 batch 判假才是错的方向(一只真可兑的合取批从卡上消失)。纯展示轴 ⇒ F 类;必须留痕,否则上游明细座漂形在遥测里零痕迹。detail = `index=<core 列表里的下标>` + 丢的缘由(不带段文本)。";
173
173
  };
174
+ readonly "server.approval-batch.kindless-row": {
175
+ readonly cls: "F";
176
+ readonly note: "起服普查(`approval-batch-census.ts`;SQL 两方言同一只读口 `SqlCheckpointStore.scanKindlessBatchRows`):一行审批停驻行(`checkpoint` 表,所有状态)的规则提议里,有 batch offer 带着**无 `kind` 的存量成员** —— 引擎读者(`readRuleOffers`)为这个旧形留着一条存量读臂(无 `kind`、四个命令文本键齐的成员读成 `command`,并给那只 offer 打 `kindlessForm` 记号),本仓用 `countKindlessBatchOffers` 数这个记号。载体两个:`rule_suggestions` 列、blob 里的 `pendingAction.ruleOffers`(detail 的 `carriers=` 点名是哪个)。每个带旧形成员的行记一次(逐次计数 + 探针行 + 每进程一次 warn),起服另出一行 info `approval_batch_kindless_rows { count }`。放行的最坏后果 = 无新增放行:这是读侧存量兼容臂被数的位,读法本来就是『旧形读成 command』,普查不改任何一行的读法、不翻行、不删臂;留痕的唯一目的是让『还有几行靠这条臂』可证 —— 计数为零(整个部署的每个副本起服都是零)才能由后续一版删那条存量臂;非零 = 还有行靠它,不可删,detail 的 `row=` 是行指纹(不是 token)。F 类(读侧兼容、纯展示轴:这条臂读出的是「不再询问」候选的卡面,不是门)。逐页读、不是原子快照(页间别的副本的写入可以让一行被漏数或多数一行);滚动升级窗里停在旧版本的副本之后写的旧形行,下次起服才数得到。后台跑、不挡起服就绪。";
177
+ };
174
178
  readonly "server.checkpoint.inbox-risk-axes-damaged": {
175
179
  readonly cls: "F";
176
180
  readonly note: "core 7.55.0 `summarizeCheckpoint` 的第二参(`plugins/checkpoint-store-sql.ts` 的 `listByScope`:supervisor inbox / 调度视图的按 scope 待决投影):一行审批门的风险描述符读穿了一格坏轴 —— `axes` 不是普通对象,或某个标记(`egress` / `irreversible` / `shell`)在场却不是布尔(手改 / 第三方写者;引擎铸的行没有这一形)⇒ 行照投,`severity` 取有效标记给出的下界,证不出就缺席;core 交一句话给店的座,本座逐行计一次。放行的最坏后果 = 这一行在按 severity 倒排的 inbox 里排位偏低或无档(分诊材料,不是门;resume 的判据不读它)。不放行的代价是一行坏描述符打掉整个 scope 的 inbox(修前:非对象描述符抛 TypeError 出投影)。修前不传座 ⇒ 降档是静默的。detail = core 的句子(按 checkpoint id 与会话 JSON 点名、按形说成员,不带令牌、不带值);每次列 inbox 都会再说一次,直到那一行被修或被决。LOCAL 车道的同一句经 backend 的 `file_store_corrupt_read` 座(core File 店自带),不走本 tag。";
@@ -193,7 +197,7 @@ export declare const FAIL_OPEN_TAGS: {
193
197
  };
194
198
  readonly "server.approvals.park-row-blob-unreadable": {
195
199
  readonly cls: "F";
196
- readonly note: "S-700(`plugins/checkpoint-store-sql.ts` 的 `readParkRowActionCell`):运维待批队列(`GET /v1/approvals` / `/stream`)的某一行,`checkpoint` 列里寄存行的 **`pendingAction` 子树**(NP-3 / 7.100.0 起引擎内只取这一棵、整只快照不出库;只为 park 行事实 `requiresRealApproval` / `ruleOffersAbsence` / `mandated`(S-663 二段,core #1079)/ `mandate`(S-721)/ `origin`(S-755)而读 —— 事实位的真源是 `approval-card.ts` 的 `ParkRowFacts`)**在场却不是一只对象**(JSON `null` 字面 / 串 / 数 —— 手改 / 迁移脚本改过)。子树**缺席**(SQL NULL:成员不在,或整只文档不是对象 —— 后者 `get()` 照旧拒;MariaDB 文本承载上的非 JSON 字节同样答 SQL NULL)⇒ 事实缺席、不计数。放行的最坏后果 = **这一行**的 park 行事实(`ParkRowFacts` 各位)缺席(展示/分诊材料;core 定性 display metadata,resume 的带子读 gate 自己的位),队列其余部分照常 —— 而这一行本来就 resume 不了(`get()` 对同一格拒)。不放行的代价是整只 `rows.map` 抛出 ⇒ 一行坏 blob 打掉整个租户的队列(列表 500、SSE 心跳照常而队列永远空),与同一 `rows.map` 里 `rule_suggestions` / `risk_descriptor` 两格同族同判。故 F 类;tag 与那两格**分开计**(哪一格在坏要读得出来)。计数非零 = 这一行的 decide 同样读不动(`get()` 对同一格拒),去按 session 查那一行。 (`member=gate` 那第二座随 core 7.55.0 #1468 P1 阶段二退役:队列行的卡与到期分法改读 `approval_card` / `gate_kind` 两列 —— 写口与 M29 回填同一只派生落下的格 —— 本读面不再读 blob 的 `gate` 子树。)S-2076 起同 tag 另有两座同判据的臂(`SqlCheckpointStore.readParkedSkillCardFacts`:对行上真带技能卡三位之一的行,整只快照读回的体坏、或体是对象但 core 的摘要读不动它 ⇒ 只丢**这一行**的三位〔`boundGrantDigest` / `boundGrants` / `classifierNoRuling`〕,队列照常;`not-text` 同样原样抛)—— 计数非零的处置同上:去按 session 查那一行。";
200
+ readonly note: "S-700(`plugins/checkpoint-store-sql.ts` 的 `readParkRowActionCell`):运维待批队列(`GET /v1/approvals` / `/stream`)的某一行,`checkpoint` 列里寄存行的 **`pendingAction` 子树**(NP-3 / 7.100.0 起引擎内只取这一棵、整只快照不出库;只为 park 行事实 `requiresRealApproval` / `ruleOffersAbsence` / `mandated`(S-663 二段,core #1079)/ `mandate`(S-721)/ `origin`(S-755)而读 —— 事实位的真源是 `approval-card.ts` 的 `ParkRowFacts`)**在场却不是一只对象**(JSON `null` 字面 / 串 / 数 —— 手改 / 迁移脚本改过)。子树**缺席**(SQL NULL:成员不在,或整只文档不是对象 —— 后者 `get()` 照旧拒;MariaDB 文本承载上的非 JSON 字节同样答 SQL NULL)⇒ 事实缺席、不计数。放行的最坏后果 = **这一行**的 park 行事实(`ParkRowFacts` 各位)缺席(展示/分诊材料;core 定性 display metadata,resume 的带子读 gate 自己的位),队列其余部分照常 —— 而这一行本来就 resume 不了(`get()` 对同一格拒)。不放行的代价是整只 `rows.map` 抛出 ⇒ 一行坏 blob 打掉整个租户的队列(列表 500、SSE 心跳照常而队列永远空),与同一 `rows.map` 里 `rule_suggestions` / `risk_descriptor` 两格同族同判。故 F 类;tag 与那两格**分开计**(哪一格在坏要读得出来)。计数非零 = 这一行的 decide 同样读不动(`get()` 对同一格拒),去按 session 查那一行。 (`member=gate` 那第二座随 core 7.55.0 #1468 P1 阶段二退役:队列行的卡与到期分法改读 `approval_card` / `gate_kind` 两列 —— 写口与 M29 回填同一只派生落下的格 —— 本读面不再读 blob 的 `gate` 子树。)S-2076 起同 tag 另有两座同判据的臂(`SqlCheckpointStore.readParkedSkillCardFacts`:对行上可能带技能卡两位之一的行,整只快照读回的体坏、或体是对象但 core 的摘要读不动它 ⇒ 只丢**这一行**的两位〔`boundGrants` / `classifierNoRuling`〕,授予绑定那一臂〔`boundGrantDigest` / `boundGrantAbsence`〕读自子树、照在(S-1612),队列照常;`not-text` 同样原样抛)—— 计数非零的处置同上:去按 session 查那一行。";
197
201
  };
198
202
  readonly "server.approvals.durable-row-checkpoint-id-missing": {
199
203
  readonly cls: "F";
@@ -287,6 +291,14 @@ export declare const FAIL_OPEN_TAGS: {
287
291
  readonly cls: "F";
288
292
  readonly note: "会话行的位置与项目那一格(`session_meta.workspace` / local `session-workspaces.json`;唯一写者 `session-workspace.ts` 的腿记录座,唯一列属主 `plugins/session-workspace-cell.ts`;detail 的 `op` 点名哪一步):`op=write` 一次写失败(库抖 / 盘满 / 锁等待超时)⇒ 行停在上一帧,下一帧照写;`op=read` 一格读不出(被带外改坏)⇒ 读作没有记录,下一帧整格重写;`op=frame` 一帧投不成存储形(引擎不会铸出这种帧)⇒ 这一帧不记。这一格是宿主对**引擎判过的答案**的记录,不是判据 —— 引擎每条腿都重判项目(有记号就判记号,声明不等响亮拒)。放行的最坏后果 = 这只会话的下一条不带 `projectId` 的提交续声明的是旧的项目或不声明(没有记号的检出里这只会话少一次续声明);不放行的代价是把一条在跑的腿、或这只会话往后的每一次提交,为一份记录摔掉。计数非零 = 这台部署的会话店写不动 / 有人改过库。";
289
293
  };
294
+ readonly "server.local-session-row.created-at-absent": {
295
+ readonly cls: "F";
296
+ readonly note: "local 会话店(`plugins/local-session-store.ts` 的 `rowCreatedAtOf`,行上建档时刻的唯一读法 —— 列表行 `firstActivityAt`、会话视图的 `createdAt`、交给引擎的会话元数据同读它):会话元数据边档的那一格没有建档时刻(补铸的格:盘上有存档而边档里没有它的格;或一次性迁移 M33 没走过的数据根 —— 跳版升上来的,或窗关之后才出现的这一形)⇒ 读作纪元(1970-01-01T00:00:00.000Z),与修前「存档头没有建档时刻」那一降级同值;不读存档头(那是同一事实的第二个读者)。放行的最坏后果 = 这只会话在按建档时刻排的列表里落到最后、视图上的建档时刻是纪元 —— 装饰性读数,不开任何门、不进任何判据。**计数单位 = 一次读到缺席**(同一只会话每次被列出 / 打开再数一次;累计计数是本进程的观察次数,现存多少读边档),探针行带 `session=<id>`。";
297
+ };
298
+ readonly "server.session-sync.dangling-anchor-export": {
299
+ readonly cls: "F";
300
+ readonly note: "会话同步的 manifest 导出(`session-sync.ts` 的 `exportSessionManifest`,`GET /v1/sessions/:id/sync/manifest` 与对等同步的一切 manifest 读者共用):源店里存着一条续跑锚,它指向的条目不在这份 manifest 自己的 `entryIds` 里(悬空锚 —— 一个更早的版本在导入口收下过指向声明集外的锚;现行导入口已不再写出这种锚)⇒ 这一条不进导出体,店里的行不动。判的是入口门用的同一只谓词(`session-sync-kernel.ts` 的 `anchorEntryDeclared`)。放行的最坏后果 = 对端少收一条本来就解不到条目的锚(续跑到它只会落到「没有这个条目」);不丢的代价是这份 manifest 原样推回时被导入口点名拒、这只会话从此推不出去。**计数单位 = 一条被丢掉的锚的一次导出**(累计计数是本进程自起动以来的观察次数;同一条存量悬空锚行留着、没有单条删除口,每次导出再数一次),探针行带 `sessionId` / `eventId` / `entryId`(JSON 引号包住、各截到 96 字,存量里的 id 是任意串);计数非零 = 本进程导出时碰到过存量悬空锚,现存多少读锚表,不读计数。";
301
+ };
290
302
  readonly "server.engine-notice.wire-sink-threw": {
291
303
  readonly cls: "F";
292
304
  readonly note: "#310:`engine_notice` 分流器把一条白名单通告投给某条 run 腿的登记口时,那只口抛了(live 口写向已断/已撕裂的 SSE socket,或 durable 口的账本写同步抛)。放行的最坏后果 = **这一条通告的这一个终点**缺席:①日志终点在分流之前已经逐字打过(事实一条不丢);②两个终点注册成两只独立 sink ⇒ live 抛不牵连 durable(断连后仍看得见的那半保住);③同会话其余口照投。故 F 类。不放行的代价是把异常回抛给 core 的 `deliverEngineNotice` —— 它会吞掉,于是同一次失败**既没有留痕也没有第二只口**,正是本 tag 要根除的形。留痕是承重的:静默吞掉之后「wire 腿为什么总有几条通告不到」在遥测里与「core 本来就没发」同形。";
@@ -557,10 +569,26 @@ export declare const FAIL_OPEN_TAGS: {
557
569
  readonly cls: "F";
558
570
  readonly note: "远端五条车道的写(`plugins/remote-shell.ts` 的暂存编排):准备 / 提交脚本删一只私有暂存目录(`.<名>.stage-<十六进制>/`,生来 0700;只删这次写放进去的 `data` 与这只空目录,从不递归删)没删掉、在 stdout 写一条记录点名 —— 五处:`mv` 已把暂存件换到目标上之后删当前那只;跟一跳到别的目录重新暂存成功之后删原来那只;重新暂存却没用上(收紧不成 / 拷不成)的那一只;就地拷入 / 追加时删暂存名失败、或写完关掉 fd 后删私有目录失败(有的文件系统为仍打开着的文件留隐藏项:NFS / libfuse / SMB);准备时收不成私有 / 里面已有 `data` 的那一只。目录里多出了不是这次写放进去的东西(同一身份或 root 的别的进程往里写过 / 收紧之前别人放进来的)、目录被换成了符号链接、或文件系统拒删。写照它自己的结局答(提交已成 ⇒ 成功:答失败会让调用方以为目标没变),残留只在这里留痕。放行的最坏后果 = 目标(或链接所指)目录里多一只隐藏目录(空的,或装着别人放进去的东西;重新暂存没用上的那只可能装着这次写的半份新内容),只有写入方进得去;不是门、不是凭据、不碰目标内容。计数非零 = 那台目标机上有东西在往别人的暂存目录里写,或删不动,去看那只目录。detail = 残留目录的路径(一次写最多两只,逐只计)。";
559
571
  };
572
+ readonly "server.resume-anchor.capture-failed": {
573
+ readonly cls: "F";
574
+ readonly note: "回退锚(`resumeAt` 的提示词 / 助手文本手柄)写入失败 —— 三条腿同一只写法 `runs.ts` 的 `settleResumeAnchor`:流式腿(`POST /v1/tasks/stream`,done 帧之前 / 断连收尾时 await)、后台腿(`POST /v1/runs`)、续跑腿。锚店写抛(库抖 / 表缺 / 盘满),或单行店操作期限(`BASELINE_IO_DEADLINE_MS`,2 s;与项目指令基线读写同一只数、同一只 `withinIoDeadline`)内没落定(锚店挂住:锚店的写口自己不带期限)⇒ 这一次提示词(或这一轮助手文本)此刻没有回退手柄,run 照常收尾、终帧照发、不改任何终局;到期只放手不取消,那次写照常在飞、迟到落定的锚照样可用(迟到的失败被吞,不重复计数)。放行的最坏后果 = 用户拿这次 run 的 taskId 去 `resumeAt` 得 404 `resume_at.unknown_event`、会话视图里那条用户消息行不带 `taskId` 手柄(用户面的读数只有这一处真源,本臂不另铸第二份);不是门、不是凭据。不放行(抛)的代价是让一次锚写失败把整条已经跑完的 run 判成失败。计数持续非零 = 锚店写不进(去看库)。计数里 `reason=timeout` 占多数 = 锚店慢到秒级(去看库的锁 / 连接池)。detail = `leg=<stream|bg|resume> kind=<prompt|turn> reason=error error=<写口的错误句>` 或 `… reason=timeout boundMs=<期限>`。";
575
+ };
560
576
  readonly "server.remote-write.stage-seal-fallback": {
561
577
  readonly cls: "F";
562
578
  readonly note: "远端五条车道的写(`plugins/remote-shell.ts` 的暂存编排):准备脚本把刚建的私有暂存目录收成 0700 并读回核实(`chmod 700` 退出 0 ∧ `stat` 读回的模式低三位恰是 700 ∧ 属主 = 本身份),任一步不成 —— `chmod` 被文件系统 / 内核拒;退出 0 却没生效(不认权限位的文件系统);父目录带缺省 ACL 而掩码收不下来;目标机上没有 `stat` —— 准备退出 4、这次写**不暂存**,两只文件面、五条腿一律改为直接写目标(与「目标目录不收新名字」同一条回落;能追加写的腿直接追加,e2b / adb 的追加 = 读旧 + 拼 + 整份写目标 —— adb 的这一形就是 7.138.x 的追加,push 没有追加写)。修前这一步是 `chmod 700 … || :`:加固失败照样放行上传,字节落在一只别的身份可能读得到的目录里(P 轴 fail-open),那一臂已删,字节从不进一只没核成私有的目录。放行的最坏后果 = 这一次写失去「整旧或整新」(非原子:中途断 / 取消 ⇒ 目标可能只写了一半,整份写目标的 e2b / adb 上可能没了或只剩半份;写目标那一步因取消中断答 `unknown`,那一步开始之前取消答 `aborted`、目标未碰,那一步不收取消(ssh 的 sftp)照样写完);ssh / local-docker / k8s 写进原 inode、权限位不变,e2b 的 `files.write` 与 adb 的 push 整份写目标、inode / 权限位由对端定(adbd 不保,与 7.138.x 同形);不是门、不是凭据。Android 共享存储(`/sdcard` 一类:权限位由挂载派生、不认 chmod)上 adb 的写按 sdcardfs / MediaProvider FUSE 的权限语义**推断**每一次都走这里(未上真机,真机读数候 test;结构性,运维修不掉;工作区放在 `/data/local/tmp` 一类认权限位的目录就不走)。计数非零 = 这台目标机的这个目录上私有目录收不成私有(文件系统不认权限位 / 缺省 ACL 掩码收不下来 / 缺 `stat`),写在走非原子的退路,去看那个目录。detail = `<目标路径>: <准备脚本写的原因句>`。";
563
579
  };
580
+ readonly "server.park.held-card-void-failed": {
581
+ readonly cls: "F";
582
+ 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=<原句>]`(不含凭据)。";
583
+ };
584
+ readonly "server.verifier-pause.card-void-failed": {
585
+ readonly cls: "F";
586
+ readonly note: "验证门结算(`verifier-pause-card.ts` 的 `voidVerifierPauseCard`;三处结算点:bg 组合腿、同步提交腿、续跑 verify 臂):验证器自己的停驻卡(结果上 `verification.verifierPause`)是本服务兑现不了的卡(它在验证器现铸的会话上,`/decide` 读不到续跑输入),结算时按卡自己的 scope 走店级 `expire` 当场作废;作废没做成 —— 店读 / 作废抛错(`store_error`)、卡的会话与停驻报的验证器会话不一致(`card_mismatch`,只作废那一张,对不上就不动)、本部署没接 checkpoint 店却收到了带凭据的验证器停驻(`no_checkpoint_store`)。每次记一次。放行的最坏后果 = 那张卡回到修前的形:留在待决面上点不动(`/decide` 答 409),由审批兜底收割收走;不是门、不是凭据(凭据由出口封口摘,与本臂无关)、不改 run 的判词。计数非零 = 这台部署的 checkpoint 店在出错,或引擎交回的停驻与店里的卡对不上(去看那只会话)。detail = `reason=<词> [err=<原句>]`(不含凭据)。引擎给出「作废验证器卡并释放其会话」的动词后本臂改调它,本 tag 随臂删或改写。";
587
+ };
588
+ readonly "server.run-permission-mode.write-back-unpersisted": {
589
+ readonly cls: "F";
590
+ readonly note: "在飞 run 的切档口(`http/routes/run-permission-mode.ts`,`POST /v1/runs/:id/permission-mode`):引擎已经收下新档(本腿下一次工具调用按它仲裁),把准入的词写回这条 run 存储体(run 模式词的唯一来源,续跑腿按它重建 spec)没有落定 —— 这一刻这条 run 已不持有会话认领或已不在跑(`claim_released`:切档与停驻 / 终局同时到;认领栅栏拒写,不会拿旧 run 的体盖掉同会话新 run 的)、会话没有存储体行(`context_absent`)、店写抛(`store_failed`:库抖 / 一行装不下 / 封签失败)。每次记一次 + 一行 warn,回执 `persisted:false` + `persistMiss` 照实告诉壳。放行的最坏后果 = 下一条腿(停驻后续跑 / 重启后续跑)回到切档前的词:切松了 ⇒ 续跑回到更严的档(多问);切严了 ⇒ 续跑回到切档前更松的档 —— 那一档是这条 run 提交时受理过的,受理判官当时判过,不越过任何部署拒;不是门、不是凭据。计数非零 = 切档常与停驻相撞或 checkpoint 店在出错;壳据 `persisted` 在续跑后重切。detail = `miss=<词> mode=<词>`。";
591
+ };
564
592
  };
565
593
  /** 词表键推导的闭集类型——未登记的 tag 传不进 {@link recordFailOpen}(编译期拒)。 */
566
594
  export type FailOpenTag = keyof typeof FAIL_OPEN_TAGS;
@@ -22,7 +22,7 @@ export const FAIL_OPEN_TAGS = {
22
22
  },
23
23
  "server.tool-end-media.live-backlog-degraded": {
24
24
  cls: "F",
25
- note: "core 7.50.0 媒体块提货(`trace/tool-output-media.ts` 的 `liveToolEndForBacklog`,三处活面写口共用的那一只判据 —— 同步流出口 `sseData`、子代 tail 路由写环、tail 总线每订阅者队列):本帧媒体字节(`output` 媒体块的 `data` 与 `structured` 媒体卡的 `file.base64` 一起计)+ 这条连接 / 这个订阅者还没送出去的字节 > 上界(64 MiB)⇒ 本帧媒体降成持久面那只形(媒体块换描述符 `{ type, mimeType?, bytes, truncated: true }`,帧级 `truncated` + `totalChars`;媒体卡去掉 `file.base64`)。每降一帧记一次,只在这只函数里记(三处写口不各记)。放行的最坏后果 = 一个读得慢的观众在 SSE 上看不到这张图,只见「这里有一张多大的什么图、没送达」(账本面本就恒是描述符),不是门、不是凭据、不改任何裁决;反方向(不降)让一条停读的连接随帧数线性压住几百 MiB。帧上它与引擎自己的媒体预算降级同形不可分,所以计数是运维唯一能看出「多少观众丢了图」的位;计数持续非零 = 有消费端读流太慢(或网络瓶颈),去看那几条连接。detail = `backlog=<待发字节> media=<本帧媒体字节>`。",
25
+ note: "core 7.50.0 媒体块提货(`trace/tool-output-media.ts` 的 `liveToolEndForBacklog`,三处活面写口共用的那一只判据 —— 同步流出口 `writeLiveFrame`、子代 tail 路由写环、tail 总线每订阅者队列):本帧媒体字节(`output` 媒体块的 `data` 与 `structured` 媒体卡的 `file.base64` 一起计)+ 这条连接 / 这个订阅者还没送出去的字节 > 上界(64 MiB)⇒ 本帧媒体降成持久面那只形(媒体块换描述符 `{ type, mimeType?, bytes, truncated: true }`,帧级 `truncated` + `totalChars`;媒体卡去掉 `file.base64`)。每降一帧记一次,只在这只函数里记(三处写口不各记)。放行的最坏后果 = 一个读得慢的观众在 SSE 上看不到这张图,只见「这里有一张多大的什么图、没送达」(账本面本就恒是描述符),不是门、不是凭据、不改任何裁决;反方向(不降)让一条停读的连接随帧数线性压住几百 MiB。帧上它与引擎自己的媒体预算降级同形不可分,所以计数是运维唯一能看出「多少观众丢了图」的位;计数持续非零 = 有消费端读流太慢(或网络瓶颈),去看那几条连接。detail = `backlog=<待发字节> media=<本帧媒体字节>`。",
26
26
  },
27
27
  "server.memory-consolidation.operator-valve-layers-unfed": {
28
28
  cls: "P-DEBT",
@@ -152,6 +152,10 @@ export const FAIL_OPEN_TAGS = {
152
152
  cls: "F",
153
153
  note: "design/382 §3.5(S-44;core 7.55.0 #1468 P1 阶段二起读者是 core `readRuleOffers`,经 `approval-card.ts` 的 `readRuleOfferList`,两条腿同调):batch offer 的 `uncoveredDetail` 明细座不是「每个计数段一行良构行」(集外 reason / 非数组 / 行数与 count 座不等 —— core 读者判丢、读数带 `uncoveredDetailDropped`)或行数超本仓展示帽 MAX_UNCOVERED_DETAIL_ROWS ⇒ 只丢这一座、batch 本体照投。放行的最坏后果 = 卡上少几行「这段为什么还会问」的解释(count 座仍在,core 契约明写明细缺席不是断言);把整只 batch 判假才是错的方向(一只真可兑的合取批从卡上消失)。纯展示轴 ⇒ F 类;必须留痕,否则上游明细座漂形在遥测里零痕迹。detail = `index=<core 列表里的下标>` + 丢的缘由(不带段文本)。",
154
154
  },
155
+ "server.approval-batch.kindless-row": {
156
+ cls: "F",
157
+ note: "起服普查(`approval-batch-census.ts`;SQL 两方言同一只读口 `SqlCheckpointStore.scanKindlessBatchRows`):一行审批停驻行(`checkpoint` 表,所有状态)的规则提议里,有 batch offer 带着**无 `kind` 的存量成员** —— 引擎读者(`readRuleOffers`)为这个旧形留着一条存量读臂(无 `kind`、四个命令文本键齐的成员读成 `command`,并给那只 offer 打 `kindlessForm` 记号),本仓用 `countKindlessBatchOffers` 数这个记号。载体两个:`rule_suggestions` 列、blob 里的 `pendingAction.ruleOffers`(detail 的 `carriers=` 点名是哪个)。每个带旧形成员的行记一次(逐次计数 + 探针行 + 每进程一次 warn),起服另出一行 info `approval_batch_kindless_rows { count }`。放行的最坏后果 = 无新增放行:这是读侧存量兼容臂被数的位,读法本来就是『旧形读成 command』,普查不改任何一行的读法、不翻行、不删臂;留痕的唯一目的是让『还有几行靠这条臂』可证 —— 计数为零(整个部署的每个副本起服都是零)才能由后续一版删那条存量臂;非零 = 还有行靠它,不可删,detail 的 `row=` 是行指纹(不是 token)。F 类(读侧兼容、纯展示轴:这条臂读出的是「不再询问」候选的卡面,不是门)。逐页读、不是原子快照(页间别的副本的写入可以让一行被漏数或多数一行);滚动升级窗里停在旧版本的副本之后写的旧形行,下次起服才数得到。后台跑、不挡起服就绪。",
158
+ },
155
159
  "server.checkpoint.inbox-risk-axes-damaged": {
156
160
  cls: "F",
157
161
  note: "core 7.55.0 `summarizeCheckpoint` 的第二参(`plugins/checkpoint-store-sql.ts` 的 `listByScope`:supervisor inbox / 调度视图的按 scope 待决投影):一行审批门的风险描述符读穿了一格坏轴 —— `axes` 不是普通对象,或某个标记(`egress` / `irreversible` / `shell`)在场却不是布尔(手改 / 第三方写者;引擎铸的行没有这一形)⇒ 行照投,`severity` 取有效标记给出的下界,证不出就缺席;core 交一句话给店的座,本座逐行计一次。放行的最坏后果 = 这一行在按 severity 倒排的 inbox 里排位偏低或无档(分诊材料,不是门;resume 的判据不读它)。不放行的代价是一行坏描述符打掉整个 scope 的 inbox(修前:非对象描述符抛 TypeError 出投影)。修前不传座 ⇒ 降档是静默的。detail = core 的句子(按 checkpoint id 与会话 JSON 点名、按形说成员,不带令牌、不带值);每次列 inbox 都会再说一次,直到那一行被修或被决。LOCAL 车道的同一句经 backend 的 `file_store_corrupt_read` 座(core File 店自带),不走本 tag。",
@@ -174,7 +178,7 @@ export const FAIL_OPEN_TAGS = {
174
178
  },
175
179
  "server.approvals.park-row-blob-unreadable": {
176
180
  cls: "F",
177
- note: "S-700(`plugins/checkpoint-store-sql.ts` 的 `readParkRowActionCell`):运维待批队列(`GET /v1/approvals` / `/stream`)的某一行,`checkpoint` 列里寄存行的 **`pendingAction` 子树**(NP-3 / 7.100.0 起引擎内只取这一棵、整只快照不出库;只为 park 行事实 `requiresRealApproval` / `ruleOffersAbsence` / `mandated`(S-663 二段,core #1079)/ `mandate`(S-721)/ `origin`(S-755)而读 —— 事实位的真源是 `approval-card.ts` 的 `ParkRowFacts`)**在场却不是一只对象**(JSON `null` 字面 / 串 / 数 —— 手改 / 迁移脚本改过)。子树**缺席**(SQL NULL:成员不在,或整只文档不是对象 —— 后者 `get()` 照旧拒;MariaDB 文本承载上的非 JSON 字节同样答 SQL NULL)⇒ 事实缺席、不计数。放行的最坏后果 = **这一行**的 park 行事实(`ParkRowFacts` 各位)缺席(展示/分诊材料;core 定性 display metadata,resume 的带子读 gate 自己的位),队列其余部分照常 —— 而这一行本来就 resume 不了(`get()` 对同一格拒)。不放行的代价是整只 `rows.map` 抛出 ⇒ 一行坏 blob 打掉整个租户的队列(列表 500、SSE 心跳照常而队列永远空),与同一 `rows.map` 里 `rule_suggestions` / `risk_descriptor` 两格同族同判。故 F 类;tag 与那两格**分开计**(哪一格在坏要读得出来)。计数非零 = 这一行的 decide 同样读不动(`get()` 对同一格拒),去按 session 查那一行。 (`member=gate` 那第二座随 core 7.55.0 #1468 P1 阶段二退役:队列行的卡与到期分法改读 `approval_card` / `gate_kind` 两列 —— 写口与 M29 回填同一只派生落下的格 —— 本读面不再读 blob 的 `gate` 子树。)S-2076 起同 tag 另有两座同判据的臂(`SqlCheckpointStore.readParkedSkillCardFacts`:对行上真带技能卡三位之一的行,整只快照读回的体坏、或体是对象但 core 的摘要读不动它 ⇒ 只丢**这一行**的三位〔`boundGrantDigest` / `boundGrants` / `classifierNoRuling`〕,队列照常;`not-text` 同样原样抛)—— 计数非零的处置同上:去按 session 查那一行。",
181
+ note: "S-700(`plugins/checkpoint-store-sql.ts` 的 `readParkRowActionCell`):运维待批队列(`GET /v1/approvals` / `/stream`)的某一行,`checkpoint` 列里寄存行的 **`pendingAction` 子树**(NP-3 / 7.100.0 起引擎内只取这一棵、整只快照不出库;只为 park 行事实 `requiresRealApproval` / `ruleOffersAbsence` / `mandated`(S-663 二段,core #1079)/ `mandate`(S-721)/ `origin`(S-755)而读 —— 事实位的真源是 `approval-card.ts` 的 `ParkRowFacts`)**在场却不是一只对象**(JSON `null` 字面 / 串 / 数 —— 手改 / 迁移脚本改过)。子树**缺席**(SQL NULL:成员不在,或整只文档不是对象 —— 后者 `get()` 照旧拒;MariaDB 文本承载上的非 JSON 字节同样答 SQL NULL)⇒ 事实缺席、不计数。放行的最坏后果 = **这一行**的 park 行事实(`ParkRowFacts` 各位)缺席(展示/分诊材料;core 定性 display metadata,resume 的带子读 gate 自己的位),队列其余部分照常 —— 而这一行本来就 resume 不了(`get()` 对同一格拒)。不放行的代价是整只 `rows.map` 抛出 ⇒ 一行坏 blob 打掉整个租户的队列(列表 500、SSE 心跳照常而队列永远空),与同一 `rows.map` 里 `rule_suggestions` / `risk_descriptor` 两格同族同判。故 F 类;tag 与那两格**分开计**(哪一格在坏要读得出来)。计数非零 = 这一行的 decide 同样读不动(`get()` 对同一格拒),去按 session 查那一行。 (`member=gate` 那第二座随 core 7.55.0 #1468 P1 阶段二退役:队列行的卡与到期分法改读 `approval_card` / `gate_kind` 两列 —— 写口与 M29 回填同一只派生落下的格 —— 本读面不再读 blob 的 `gate` 子树。)S-2076 起同 tag 另有两座同判据的臂(`SqlCheckpointStore.readParkedSkillCardFacts`:对行上可能带技能卡两位之一的行,整只快照读回的体坏、或体是对象但 core 的摘要读不动它 ⇒ 只丢**这一行**的两位〔`boundGrants` / `classifierNoRuling`〕,授予绑定那一臂〔`boundGrantDigest` / `boundGrantAbsence`〕读自子树、照在(S-1612),队列照常;`not-text` 同样原样抛)—— 计数非零的处置同上:去按 session 查那一行。",
178
182
  },
179
183
  "server.approvals.durable-row-checkpoint-id-missing": {
180
184
  cls: "F",
@@ -268,6 +272,14 @@ export const FAIL_OPEN_TAGS = {
268
272
  cls: "F",
269
273
  note: "会话行的位置与项目那一格(`session_meta.workspace` / local `session-workspaces.json`;唯一写者 `session-workspace.ts` 的腿记录座,唯一列属主 `plugins/session-workspace-cell.ts`;detail 的 `op` 点名哪一步):`op=write` 一次写失败(库抖 / 盘满 / 锁等待超时)⇒ 行停在上一帧,下一帧照写;`op=read` 一格读不出(被带外改坏)⇒ 读作没有记录,下一帧整格重写;`op=frame` 一帧投不成存储形(引擎不会铸出这种帧)⇒ 这一帧不记。这一格是宿主对**引擎判过的答案**的记录,不是判据 —— 引擎每条腿都重判项目(有记号就判记号,声明不等响亮拒)。放行的最坏后果 = 这只会话的下一条不带 `projectId` 的提交续声明的是旧的项目或不声明(没有记号的检出里这只会话少一次续声明);不放行的代价是把一条在跑的腿、或这只会话往后的每一次提交,为一份记录摔掉。计数非零 = 这台部署的会话店写不动 / 有人改过库。",
270
274
  },
275
+ "server.local-session-row.created-at-absent": {
276
+ cls: "F",
277
+ note: "local 会话店(`plugins/local-session-store.ts` 的 `rowCreatedAtOf`,行上建档时刻的唯一读法 —— 列表行 `firstActivityAt`、会话视图的 `createdAt`、交给引擎的会话元数据同读它):会话元数据边档的那一格没有建档时刻(补铸的格:盘上有存档而边档里没有它的格;或一次性迁移 M33 没走过的数据根 —— 跳版升上来的,或窗关之后才出现的这一形)⇒ 读作纪元(1970-01-01T00:00:00.000Z),与修前「存档头没有建档时刻」那一降级同值;不读存档头(那是同一事实的第二个读者)。放行的最坏后果 = 这只会话在按建档时刻排的列表里落到最后、视图上的建档时刻是纪元 —— 装饰性读数,不开任何门、不进任何判据。**计数单位 = 一次读到缺席**(同一只会话每次被列出 / 打开再数一次;累计计数是本进程的观察次数,现存多少读边档),探针行带 `session=<id>`。",
278
+ },
279
+ "server.session-sync.dangling-anchor-export": {
280
+ cls: "F",
281
+ note: "会话同步的 manifest 导出(`session-sync.ts` 的 `exportSessionManifest`,`GET /v1/sessions/:id/sync/manifest` 与对等同步的一切 manifest 读者共用):源店里存着一条续跑锚,它指向的条目不在这份 manifest 自己的 `entryIds` 里(悬空锚 —— 一个更早的版本在导入口收下过指向声明集外的锚;现行导入口已不再写出这种锚)⇒ 这一条不进导出体,店里的行不动。判的是入口门用的同一只谓词(`session-sync-kernel.ts` 的 `anchorEntryDeclared`)。放行的最坏后果 = 对端少收一条本来就解不到条目的锚(续跑到它只会落到「没有这个条目」);不丢的代价是这份 manifest 原样推回时被导入口点名拒、这只会话从此推不出去。**计数单位 = 一条被丢掉的锚的一次导出**(累计计数是本进程自起动以来的观察次数;同一条存量悬空锚行留着、没有单条删除口,每次导出再数一次),探针行带 `sessionId` / `eventId` / `entryId`(JSON 引号包住、各截到 96 字,存量里的 id 是任意串);计数非零 = 本进程导出时碰到过存量悬空锚,现存多少读锚表,不读计数。",
282
+ },
271
283
  "server.engine-notice.wire-sink-threw": {
272
284
  cls: "F",
273
285
  note: "#310:`engine_notice` 分流器把一条白名单通告投给某条 run 腿的登记口时,那只口抛了(live 口写向已断/已撕裂的 SSE socket,或 durable 口的账本写同步抛)。放行的最坏后果 = **这一条通告的这一个终点**缺席:①日志终点在分流之前已经逐字打过(事实一条不丢);②两个终点注册成两只独立 sink ⇒ live 抛不牵连 durable(断连后仍看得见的那半保住);③同会话其余口照投。故 F 类。不放行的代价是把异常回抛给 core 的 `deliverEngineNotice` —— 它会吞掉,于是同一次失败**既没有留痕也没有第二只口**,正是本 tag 要根除的形。留痕是承重的:静默吞掉之后「wire 腿为什么总有几条通告不到」在遥测里与「core 本来就没发」同形。",
@@ -517,10 +529,26 @@ export const FAIL_OPEN_TAGS = {
517
529
  cls: "F",
518
530
  note: "远端五条车道的写(`plugins/remote-shell.ts` 的暂存编排):准备 / 提交脚本删一只私有暂存目录(`.<名>.stage-<十六进制>/`,生来 0700;只删这次写放进去的 `data` 与这只空目录,从不递归删)没删掉、在 stdout 写一条记录点名 —— 五处:`mv` 已把暂存件换到目标上之后删当前那只;跟一跳到别的目录重新暂存成功之后删原来那只;重新暂存却没用上(收紧不成 / 拷不成)的那一只;就地拷入 / 追加时删暂存名失败、或写完关掉 fd 后删私有目录失败(有的文件系统为仍打开着的文件留隐藏项:NFS / libfuse / SMB);准备时收不成私有 / 里面已有 `data` 的那一只。目录里多出了不是这次写放进去的东西(同一身份或 root 的别的进程往里写过 / 收紧之前别人放进来的)、目录被换成了符号链接、或文件系统拒删。写照它自己的结局答(提交已成 ⇒ 成功:答失败会让调用方以为目标没变),残留只在这里留痕。放行的最坏后果 = 目标(或链接所指)目录里多一只隐藏目录(空的,或装着别人放进去的东西;重新暂存没用上的那只可能装着这次写的半份新内容),只有写入方进得去;不是门、不是凭据、不碰目标内容。计数非零 = 那台目标机上有东西在往别人的暂存目录里写,或删不动,去看那只目录。detail = 残留目录的路径(一次写最多两只,逐只计)。",
519
531
  },
532
+ "server.resume-anchor.capture-failed": {
533
+ cls: "F",
534
+ note: "回退锚(`resumeAt` 的提示词 / 助手文本手柄)写入失败 —— 三条腿同一只写法 `runs.ts` 的 `settleResumeAnchor`:流式腿(`POST /v1/tasks/stream`,done 帧之前 / 断连收尾时 await)、后台腿(`POST /v1/runs`)、续跑腿。锚店写抛(库抖 / 表缺 / 盘满),或单行店操作期限(`BASELINE_IO_DEADLINE_MS`,2 s;与项目指令基线读写同一只数、同一只 `withinIoDeadline`)内没落定(锚店挂住:锚店的写口自己不带期限)⇒ 这一次提示词(或这一轮助手文本)此刻没有回退手柄,run 照常收尾、终帧照发、不改任何终局;到期只放手不取消,那次写照常在飞、迟到落定的锚照样可用(迟到的失败被吞,不重复计数)。放行的最坏后果 = 用户拿这次 run 的 taskId 去 `resumeAt` 得 404 `resume_at.unknown_event`、会话视图里那条用户消息行不带 `taskId` 手柄(用户面的读数只有这一处真源,本臂不另铸第二份);不是门、不是凭据。不放行(抛)的代价是让一次锚写失败把整条已经跑完的 run 判成失败。计数持续非零 = 锚店写不进(去看库)。计数里 `reason=timeout` 占多数 = 锚店慢到秒级(去看库的锁 / 连接池)。detail = `leg=<stream|bg|resume> kind=<prompt|turn> reason=error error=<写口的错误句>` 或 `… reason=timeout boundMs=<期限>`。",
535
+ },
520
536
  "server.remote-write.stage-seal-fallback": {
521
537
  cls: "F",
522
538
  note: "远端五条车道的写(`plugins/remote-shell.ts` 的暂存编排):准备脚本把刚建的私有暂存目录收成 0700 并读回核实(`chmod 700` 退出 0 ∧ `stat` 读回的模式低三位恰是 700 ∧ 属主 = 本身份),任一步不成 —— `chmod` 被文件系统 / 内核拒;退出 0 却没生效(不认权限位的文件系统);父目录带缺省 ACL 而掩码收不下来;目标机上没有 `stat` —— 准备退出 4、这次写**不暂存**,两只文件面、五条腿一律改为直接写目标(与「目标目录不收新名字」同一条回落;能追加写的腿直接追加,e2b / adb 的追加 = 读旧 + 拼 + 整份写目标 —— adb 的这一形就是 7.138.x 的追加,push 没有追加写)。修前这一步是 `chmod 700 … || :`:加固失败照样放行上传,字节落在一只别的身份可能读得到的目录里(P 轴 fail-open),那一臂已删,字节从不进一只没核成私有的目录。放行的最坏后果 = 这一次写失去「整旧或整新」(非原子:中途断 / 取消 ⇒ 目标可能只写了一半,整份写目标的 e2b / adb 上可能没了或只剩半份;写目标那一步因取消中断答 `unknown`,那一步开始之前取消答 `aborted`、目标未碰,那一步不收取消(ssh 的 sftp)照样写完);ssh / local-docker / k8s 写进原 inode、权限位不变,e2b 的 `files.write` 与 adb 的 push 整份写目标、inode / 权限位由对端定(adbd 不保,与 7.138.x 同形);不是门、不是凭据。Android 共享存储(`/sdcard` 一类:权限位由挂载派生、不认 chmod)上 adb 的写按 sdcardfs / MediaProvider FUSE 的权限语义**推断**每一次都走这里(未上真机,真机读数候 test;结构性,运维修不掉;工作区放在 `/data/local/tmp` 一类认权限位的目录就不走)。计数非零 = 这台目标机的这个目录上私有目录收不成私有(文件系统不认权限位 / 缺省 ACL 掩码收不下来 / 缺 `stat`),写在走非原子的退路,去看那个目录。detail = `<目标路径>: <准备脚本写的原因句>`。",
523
539
  },
540
+ "server.park.held-card-void-failed": {
541
+ cls: "F",
542
+ 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=<原句>]`(不含凭据)。",
543
+ },
544
+ "server.verifier-pause.card-void-failed": {
545
+ cls: "F",
546
+ note: "验证门结算(`verifier-pause-card.ts` 的 `voidVerifierPauseCard`;三处结算点:bg 组合腿、同步提交腿、续跑 verify 臂):验证器自己的停驻卡(结果上 `verification.verifierPause`)是本服务兑现不了的卡(它在验证器现铸的会话上,`/decide` 读不到续跑输入),结算时按卡自己的 scope 走店级 `expire` 当场作废;作废没做成 —— 店读 / 作废抛错(`store_error`)、卡的会话与停驻报的验证器会话不一致(`card_mismatch`,只作废那一张,对不上就不动)、本部署没接 checkpoint 店却收到了带凭据的验证器停驻(`no_checkpoint_store`)。每次记一次。放行的最坏后果 = 那张卡回到修前的形:留在待决面上点不动(`/decide` 答 409),由审批兜底收割收走;不是门、不是凭据(凭据由出口封口摘,与本臂无关)、不改 run 的判词。计数非零 = 这台部署的 checkpoint 店在出错,或引擎交回的停驻与店里的卡对不上(去看那只会话)。detail = `reason=<词> [err=<原句>]`(不含凭据)。引擎给出「作废验证器卡并释放其会话」的动词后本臂改调它,本 tag 随臂删或改写。",
547
+ },
548
+ "server.run-permission-mode.write-back-unpersisted": {
549
+ cls: "F",
550
+ note: "在飞 run 的切档口(`http/routes/run-permission-mode.ts`,`POST /v1/runs/:id/permission-mode`):引擎已经收下新档(本腿下一次工具调用按它仲裁),把准入的词写回这条 run 存储体(run 模式词的唯一来源,续跑腿按它重建 spec)没有落定 —— 这一刻这条 run 已不持有会话认领或已不在跑(`claim_released`:切档与停驻 / 终局同时到;认领栅栏拒写,不会拿旧 run 的体盖掉同会话新 run 的)、会话没有存储体行(`context_absent`)、店写抛(`store_failed`:库抖 / 一行装不下 / 封签失败)。每次记一次 + 一行 warn,回执 `persisted:false` + `persistMiss` 照实告诉壳。放行的最坏后果 = 下一条腿(停驻后续跑 / 重启后续跑)回到切档前的词:切松了 ⇒ 续跑回到更严的档(多问);切严了 ⇒ 续跑回到切档前更松的档 —— 那一档是这条 run 提交时受理过的,受理判官当时判过,不越过任何部署拒;不是门、不是凭据。计数非零 = 切档常与停驻相撞或 checkpoint 店在出错;壳据 `persisted` 在续跑后重切。detail = `miss=<词> mode=<词>`。",
551
+ },
524
552
  };
525
553
  export function failOpenTagForDroppedFrame(frameType) {
526
554
  switch (frameType) {
@@ -259,7 +259,6 @@ export function createMetrics() {
259
259
  m.counter("remote_env_suspend_total", "E2B remote-env suspendVM outcomes (v1.5, provider/result)");
260
260
  m.counter("remote_env_resume_total", "E2B remote-env resumeVM outcomes (v1.5, provider/result)");
261
261
  m.counter("remote_env_exec_stream_read_timeout_total", "E2B execStream idle read-timeouts (#1128, provider)");
262
- m.counter("resume_anchor_capture_failed", "E18 resume-at per-turn anchor captures that failed (best-effort, run unaffected)");
263
262
  m.counter("brain_retry_total", "Brain-layer status events (S4), by phase (rate_limited/retrying/reconnecting/circuit_open/waiting_first_token/recovered/gave_up)");
264
263
  m.gauge("store_backend_degraded", "1 when the auto DB probe failed at boot and this replica degraded to in-memory (S5)");
265
264
  m.counter("runs_reaped_total", "Run rows flipped by the background reapers (S7), by kind (stale/suspended/expired_checkpoint)");
@@ -1,4 +1,5 @@
1
1
  import { type PersistedTaskResult, type RunRecord } from "../plugins/store-contracts.js";
2
+ import { type StoredResultReadSeat } from "../terminal.js";
2
3
  /** 一次终局写口交给观测面的原料(store 侧装配,**未脱敏** —— 脱敏在本模块内做,见 {@link notifyRunTerminal})。 */
3
4
  export interface RunTerminalRecord {
4
5
  /** 这条 run 的账本 id = `GET /v1/runs/:id` 的 id(本仓 run 行主键名为 taskId,同一个值)。 */
@@ -205,8 +206,11 @@ export declare function redactTerminalResult<T extends {
205
206
  * 所以调用点已封过口的腿零行为变化。
206
207
  *
207
208
  * `null` 原样(= 这条腿没有结果可落:引擎没给终局就收流 / 断连竞态 park / 重开 re-park)。
209
+ *
210
+ * `readSeat`:读面借这同一只组合读存量行时(`GET /v1/runs/:id` 的非终态臂)给出读座 —— 只决定折码运维行是「一件新的失败」还是「同一行的再观看」
211
+ * (见 `sealResultForExit`);店的写口不给。
208
212
  */
209
- export declare function sealRunRowResult(result: PersistedTaskResult | null): PersistedTaskResult | null;
213
+ export declare function sealRunRowResult(result: PersistedTaskResult | null, readSeat?: StoredResultReadSeat): PersistedTaskResult | null;
210
214
  /** [ref](第五轮合并重扫 wf_f00c00bc 两根 [high]):同一个 `TaskResult` 除 run 行外还被逐字追加进 run_events 的 `done` 行
211
215
  * (bg/verify/cascade/stream/resume 五腿),`failed` 行带原文 `errorMessage`,`GET /v1/runs/:id/events` 原样回放。
212
216
  * 三孪生 `appendEvent` 入口 + 事件读面(旧行纵深)同调本函数:只认 `done.result`(整块走 `redactTerminalResult`)与
@@ -262,7 +266,7 @@ export declare function memoRedactedRead<T>(seat: string, raw: T, redact: (v: T)
262
266
  * `memoRedactTerminalResult` 会对它 O(1) 直返明文,读面纵深对这一叶恒不生效(这正是 [ref] 立案时
263
267
  * `editedFiles` 那一格的病)。读数:8MB result 的一次摘要 ~10ms 量级,远小于一次全扫;干净行仍只摘要
264
268
  * 一次即进 clean 集,脏行超过 {@link READ_MEMO_DIRTY_MAX_ENTRY_BYTES} 时退化为每次重扫(既有形)。 */
265
- export declare function memoRedactTerminalResult<T extends Parameters<typeof redactTerminalResult>[0]>(seat: string, result: T): T;
269
+ export declare function memoRedactTerminalResult<T extends Parameters<typeof redactTerminalResult>[0]>(seat: StoredResultReadSeat, raw: T): T;
266
270
  /**
267
271
  * 🔴 **账本行的读面口 —— 全部耐久读腿共用这一只**([ref],7.105.0)。
268
272
  *
@@ -3,7 +3,7 @@ import { redactSecrets } from "../trace/redact.js";
3
3
  import { isProviderEchoShape } from "@sema-agent/core";
4
4
  import { isModelTextLedgerEventType, isParkLedgerEventType } from "../trace/ledger-events.js";
5
5
  import { isUnsuccessfulRunStatus } from "../plugins/store-contracts.js";
6
- import { sealResultForExit } from "../terminal.js";
6
+ import { mapPauseSeats, PAUSE_SEATS, sealResultForExit } from "../terminal.js";
7
7
  import { errorText } from "./err-text.js";
8
8
  import { recordFailOpen } from "./fail-open.js";
9
9
  import { toolEndMediaAsDescriptors } from "../trace/tool-output-media.js";
@@ -295,8 +295,11 @@ const PROVIDER_ECHO_SHAPERS = {
295
295
  }
296
296
  const LEGACY_RESULT_LEAVES = ["errorMessage", "blockedReason", "checkpointGate"];
297
297
  export const TREATED_RESULT_LEAVES = [
298
- ...Object.entries(RESULT_KEY_TREATMENT).filter(([, t]) => t !== "verbatim").map(([k]) => k),
299
- ...LEGACY_RESULT_LEAVES,
298
+ ...new Set([
299
+ ...Object.entries(RESULT_KEY_TREATMENT).filter(([, t]) => t !== "verbatim").map(([k]) => k),
300
+ ...LEGACY_RESULT_LEAVES,
301
+ ...PAUSE_SEATS.map((seat) => seat.path[0]),
302
+ ]),
300
303
  ];
301
304
  export function redactTerminalResult(result) {
302
305
  if (result === undefined || result === null)
@@ -333,24 +336,8 @@ export function redactTerminalResult(result) {
333
336
  if (shaped !== detail)
334
337
  nt = { ...cur, detail: shaped };
335
338
  }
336
- const gateOf = (cause) => {
337
- if (cause === null || typeof cause !== "object" || !("gate" in cause))
338
- return undefined;
339
- const g = cause.gate;
340
- const ng = redactCheckpointGate(g);
341
- return { gate: ng, changed: ng !== g };
342
- };
343
339
  const base = nt ?? t;
344
- if (t.kind === "paused") {
345
- const g = gateOf(base);
346
- if (g?.changed === true)
347
- nt = { ...base, gate: g.gate };
348
- }
349
- else if (t.kind === "failed") {
350
- const np = base.nestedPause;
351
- const g = gateOf(np);
352
- if (g?.changed === true)
353
- nt = { ...base, nestedPause: { ...np, gate: g.gate } };
340
+ if (t.kind === "failed") {
354
341
  const cur = nt ?? base;
355
342
  const detail = cur.detail;
356
343
  const shaped = shapeTerminalFailureDetail(detail);
@@ -362,6 +349,17 @@ export function redactTerminalResult(result) {
362
349
  changed = true;
363
350
  }
364
351
  }
352
+ const gated = mapPauseSeats(out, (seat, keys) => {
353
+ if (!Object.hasOwn(seat, keys.gate))
354
+ return seat;
355
+ const g = seat[keys.gate];
356
+ const ng = redactCheckpointGate(g);
357
+ return ng === g ? seat : { ...seat, [keys.gate]: ng };
358
+ });
359
+ if (gated !== out) {
360
+ Object.assign(out, gated);
361
+ changed = true;
362
+ }
365
363
  if (r.remoteEnvFailures !== undefined) {
366
364
  out.remoteEnvFailures = Array.isArray(r.remoteEnvFailures)
367
365
  ? r.remoteEnvFailures.map((f) => (f && typeof f === "object" && typeof f.message === "string" ? { ...f, message: redactErrorMessage(f.message) } : f))
@@ -429,8 +427,8 @@ export function redactTerminalResult(result) {
429
427
  }
430
428
  return changed ? out : result;
431
429
  }
432
- export function sealRunRowResult(result) {
433
- return result === null ? null : redactTerminalResult(sealResultForExit(result));
430
+ export function sealRunRowResult(result, readSeat) {
431
+ return result === null ? null : redactTerminalResult(sealResultForExit(result, readSeat));
434
432
  }
435
433
  export function redactLedgerEventData(type, data) {
436
434
  if (data === null || typeof data !== "object" || Array.isArray(data))
@@ -439,7 +437,7 @@ export function redactLedgerEventData(type, data) {
439
437
  const result = data.result;
440
438
  if (result === null || typeof result !== "object")
441
439
  return data;
442
- return { ...data, result: redactTerminalResult(result) };
440
+ return { ...data, result: sealRunRowResult(result) };
443
441
  }
444
442
  if (type === "failed") {
445
443
  const msg = data.errorMessage;
@@ -896,9 +894,10 @@ export function memoRedactedRead(seat, raw, redact) {
896
894
  }
897
895
  return out;
898
896
  }
899
- export function memoRedactTerminalResult(seat, result) {
900
- if (result === undefined || result === null)
901
- return result;
897
+ export function memoRedactTerminalResult(seat, raw) {
898
+ if (raw === undefined || raw === null)
899
+ return raw;
900
+ const result = sealResultForExit(raw, seat);
902
901
  const r = result;
903
902
  if (TREATED_RESULT_LEAVES.every((k) => r[k] === undefined))
904
903
  return result;
@@ -31,9 +31,16 @@
31
31
  * git 腿是自由函数 / 闭包)。7.103.0 起各腿不再直接调本函数 —— 只经 `server-secret-env.ts` 的唯一组合 `hostSubprocessEnv`。
32
32
  * 装配层用 {@link installSecretEnvScrubRecorder} 把句柄接上,装配之前命中的次数不会丢(计数照常累加,
33
33
  * install 时一次性补进 metrics),披露行则在下一次命中时补发(未成功披露的 key 不进 `disclosed` 集)。
34
+ *
35
+ * ## 同族的第二件:自有凭据**值**没被引擎收下的点名({@link recordOwnCredentialValueNotWithheld})
36
+ * 起服第一步(三个进程入口在任何 logger 之前)把本进程自有凭据名与值交给引擎声明;引擎判「这不是一个凭据值」的那一个不扣、名照扣、不拒启,
37
+ * 需要一条运维看得见的行。它与上面的披露同一类东西(子进程 env 保护「没有按预期生效」的留痕),所以住同一个座:同一只 logger 句柄、同一条「装配之前不丢」纪律。
38
+ * 这一件的做法比披露行更简单:logger 已接上 ⇒ 走它;还没接上(起服第一步)⇒ **当拍**经一只进程默认的 JSON 行日志器(与进程入口自己建的日志器同一实现、同一行形)写 stderr ——
39
+ * 不缓冲、不补发:缓冲会在「接上 logger 之前就致命退出」的起服路径上把这一行吞掉(修前的裸 `console.warn` 当拍就出),而当拍写没有这一形。
40
+ * 判官只在引擎一处 —— 本座只转述引擎的拒句,不判。
34
41
  */
35
42
  import { type SecretEnvFinding } from "@sema-agent/core";
36
- import type { Logger } from "./logger.js";
43
+ import { type Logger } from "./logger.js";
37
44
  import type { Metrics } from "./metrics.js";
38
45
  /**
39
46
  * 一个剥除现场的登记:`note` = 这条腿上泄漏意味着什么;`remedy` = 部署方能不能自己把某个被剥的键放回来。
@@ -92,6 +99,13 @@ interface Sink {
92
99
  logger?: Logger;
93
100
  metrics?: Metrics;
94
101
  }
102
+ /** 自有凭据值没被引擎收下的一次点名(引擎的拒句从不回显值,本件也不带值)。 */
103
+ export interface OwnCredentialValueRefusal {
104
+ /** 持有这个值的变量名。 */
105
+ readonly name: string;
106
+ /** 引擎拒这个值的原句(引擎是「什么不算凭据值」的唯一判官;本仓只转述)。 */
107
+ readonly reason: string;
108
+ }
95
109
  /**
96
110
  * 记一次剥除。**总不抛** —— 观测本身绝不能变成故障(同 `recordFailOpen` / reapers 的判据)。
97
111
  * `findings` 为空(这一次没丢任何 key)时什么也不做:那不是事件,是常态。
@@ -99,6 +113,11 @@ interface Sink {
99
113
  * `allowed` = 这一次生效的点名放行名单([ref]),只在有出路的现场(`remedy` 在场)写进披露行;没有放行面的腿传 `[]`。
100
114
  */
101
115
  export declare function recordSecretEnvScrub(site: SecretEnvScrubSite, findings: readonly SecretEnvFinding[], allowed: readonly string[]): void;
116
+ /**
117
+ * 记一次「自有凭据值没被引擎收下」(`declareServerWithheldEnv` 值臂,引擎拒句原文进 `reason`)。**总不抛**(观测绝不能变成故障)。
118
+ * 一条 `warn` 结构化行,**当拍**写:logger 已接上 ⇒ 走它;还没接上(起服第一步)⇒ 走进程默认的 JSON 行日志器(同一行形,stderr)。
119
+ */
120
+ export declare function recordOwnCredentialValueNotWithheld(refusal: OwnCredentialValueRefusal): void;
102
121
  /** 装配层把 logger/metrics 接上(main.ts,与 `installFailOpenRecorder` 同一处)。装配前累计的次数在此补进 metrics。 */
103
122
  export declare function installSecretEnvScrubRecorder(deps: Sink): void;
104
123
  /** 已留驻的「现场×键」条数(测试/诊断读面)。恒 ≤ {@link DISCLOSED_CAP}。 */
@@ -1,5 +1,6 @@
1
1
  import { summarizeRedactions } from "@sema-agent/core";
2
2
  import { describeAllowlistPostures } from "../env-name-allowlist-knobs.js";
3
+ import { createLogger } from "./logger.js";
3
4
  export const SECRET_ENV_SCRUB_SITES = {
4
5
  "server.remote-env-host.spawn-env": {
5
6
  note: "模型可驱动的 host shell 继承 env(`inheritEnv` 三词任一,缺省 `\"scrub\"`;`\"all\"` 词下扣的只有本服务自己的凭据名)——这条腿上的一次泄漏等于把编排器的脑钥/仓库令牌交给模型选的命令",
@@ -43,6 +44,7 @@ const SCRUB_COUNTER_HELP = "secret env entries not handed on as written (dropped
43
44
  const DISCLOSED_CAP = 512;
44
45
  const SEP = "=";
45
46
  let sink = {};
47
+ let preInstallLogger;
46
48
  let counts = new Map();
47
49
  let pushed = new Map();
48
50
  let disclosed = new Set();
@@ -101,6 +103,18 @@ export function recordSecretEnvScrub(site, findings, allowed) {
101
103
  catch {
102
104
  }
103
105
  }
106
+ const OWN_CREDENTIAL_VALUE_NOT_WITHHELD = "own_credential_value_not_withheld";
107
+ function emitValueRefusal(logger, r) {
108
+ logger.warn(OWN_CREDENTIAL_VALUE_NOT_WITHHELD, { name: r.name, reason: r.reason });
109
+ }
110
+ export function recordOwnCredentialValueNotWithheld(refusal) {
111
+ try {
112
+ const logger = sink.logger ?? (preInstallLogger ??= createLogger("warn"));
113
+ emitValueRefusal(logger, refusal);
114
+ }
115
+ catch {
116
+ }
117
+ }
104
118
  export function installSecretEnvScrubRecorder(deps) {
105
119
  sink = { ...deps };
106
120
  deps.metrics?.counter(SCRUB_COUNTER, SCRUB_COUNTER_HELP);
@@ -18,8 +18,8 @@ export interface WorkflowCompletionInboxEntry {
18
18
  * is the deployment's job). `runId` then holds the core task_id (disjoint id spaces). */
19
19
  kind?: "workflow_complete" | "task_notification";
20
20
  /** The per-kind extras as a JSON text — bounded + redacted AT ENQUEUE (the store carries only egress-safe bytes).
21
- * `task_notification`: {task_type, toolUseId?, result?, output_file?, …}. `workflow_complete`: at most `{"completionId": …}`
22
- * (see {@link buildWorkflowCompleteInboxEntry}; absent when the engine minted none). The SQL stores' existing `payload`
21
+ * `task_notification`: {task_type, toolUseId?, result?, output_file?, …}. `workflow_complete`: at most `{"completionId": …, "diagnostics": …}`
22
+ * (see {@link buildWorkflowCompleteInboxEntry}; each key absent when the engine minted none). The SQL stores' existing `payload`
23
23
  * column carries it verbatim for both kinds — no DDL. */
24
24
  payload?: string;
25
25
  }
@@ -203,6 +203,8 @@ export declare class FileWorkflowCompletionInbox extends InMemoryWorkflowComplet
203
203
  /**
204
204
  * 一次 workflow 完成 → 入箱条目(`workflow_complete` 家族;启动期投递闭包的**唯一**构造点)。`summary` 在 core 的 notifier seam 上已脱敏 + 限长,这里原样入箱;
205
205
  * `completionId`(引擎铸,`WorkflowCompletionPayload` 上在场 iff 引擎给了)逐字落进 `payload` 列 —— 同一次完成的补投帧与 live 帧同一个相关 id,本服务零自铸。
206
+ * `diagnostics`(引擎铸的诊断教学文本,在场 iff 引擎给了)是自由文本:**这里**过出口座(`inbox-diagnostics-text` 行 —— 与 live `task_notification.diagnostics` 同一个脱敏 scope,
207
+ * 加一条界)再落 `payload` 列,drain 逐字带出;店里不放未洗的字节。
206
208
  */
207
209
  export declare function buildWorkflowCompleteInboxEntry(route: {
208
210
  sessionId: string;
@@ -212,6 +214,7 @@ export declare function buildWorkflowCompleteInboxEntry(route: {
212
214
  status: "completed" | "failed";
213
215
  summary: string;
214
216
  completionId?: string;
217
+ diagnostics?: string;
215
218
  }, enqueuedAt: number): WorkflowCompletionInboxEntry;
216
219
  /**
217
220
  * P1 ①② delivery half, TWO-PHASE since 1.80: read the session's pending completions, emit
@@ -1,6 +1,7 @@
1
1
  import { mkdirSync, openSync, writeSync, fsyncSync, closeSync, renameSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { redactSecrets } from "../trace/redact.js";
4
+ import { seatText } from "../trace/exit-seat.js";
4
5
  import { replayJsonlSkipping } from "../observability/corrupt-read-seat.js";
5
6
  import { injectionTierOrAbsent } from "../trace/injection-tier.js";
6
7
  import { semaProvenanceOrAbsent } from "../trace/sema-provenance.js";
@@ -273,12 +274,19 @@ function readEntryExtras(payload) {
273
274
  }
274
275
  return typeof extras === "object" && extras !== null && !Array.isArray(extras) ? extras : {};
275
276
  }
276
- function encodeWorkflowCompleteExtras(completionId) {
277
- return completionId ? { payload: JSON.stringify({ completionId }) } : {};
277
+ function encodeWorkflowCompleteExtras(extras) {
278
+ const body = {
279
+ ...(extras.completionId ? { completionId: extras.completionId } : {}),
280
+ ...(extras.diagnostics ? { diagnostics: extras.diagnostics } : {}),
281
+ };
282
+ return Object.keys(body).length > 0 ? { payload: JSON.stringify(body) } : {};
278
283
  }
279
284
  function workflowCompleteFrameExtras(payload) {
280
- const id = readEntryExtras(payload).completionId;
281
- return typeof id === "string" && id !== "" ? { completionId: id } : {};
285
+ const { completionId, diagnostics } = readEntryExtras(payload);
286
+ return {
287
+ ...(typeof completionId === "string" && completionId !== "" ? { completionId } : {}),
288
+ ...(typeof diagnostics === "string" && diagnostics !== "" ? { diagnostics } : {}),
289
+ };
282
290
  }
283
291
  export function buildWorkflowCompleteInboxEntry(route, p, enqueuedAt) {
284
292
  return {
@@ -288,7 +296,7 @@ export function buildWorkflowCompleteInboxEntry(route, p, enqueuedAt) {
288
296
  status: p.status,
289
297
  summary: p.summary,
290
298
  enqueuedAt,
291
- ...encodeWorkflowCompleteExtras(p.completionId),
299
+ ...encodeWorkflowCompleteExtras({ completionId: p.completionId, diagnostics: p.diagnostics ? seatText("inbox-diagnostics-text", p.diagnostics) : undefined }),
292
300
  };
293
301
  }
294
302
  export async function emitPendingWorkflowCompletions(inbox, sessionId, callerPrincipal, emit, diag) {
@@ -6,8 +6,10 @@ import { type WorkflowAgentSessionIndex } from "./workflow-agent-session-index.j
6
6
  * core 给 `WorkflowCompletionNotifier.notify` 的入参加一个键 ⇒ 这里编译红(缺一行),逼人对「它上不上这条链」表态;core 删 / 改名一个键 ⇒ 同样红(多一行)。
7
7
  * · `carry`:搬运到投递(journal 门 → 收件箱 → `workflow_complete` 帧 / 账本行)。`runId` / `status` / `summary` 必带;其余可选键引擎没给(或空串)⇒ 载荷上缺席。
8
8
  * `completionId` = 引擎的一次完成的相关 id(fill-once,终态转换上铸):逐字、不脱敏、本服务零自铸。
9
- * · `drop`:这条持久链只搬运一句受限摘要 + 路由键 —— `task_id` / `task_type` / `toolUseId` 是 live `task_notification` 帧的键(那条路径自带),`result` / `usage` /
10
- * `diagnostics` 是完整结果 / 计量 / 诊断路由(终态轮询 `TaskOutput` / `WorkflowStatus` 读得到),不进补投帧。
9
+ * `diagnostics` = 引擎在完成通知上铸的诊断教学文本(未完成 agent 的摘要行、完整记录的读取手柄、journal 坐标、续跑句):补投路径是它在原腿已不在(断线重连 / 重启)时唯一的去处,
10
+ * 所以搬运;它是自由文本,出门前在入箱处过出口座(见 `buildWorkflowCompleteInboxEntry`),载荷上仍是引擎值。**崩溃恢复臂不带**:`WorkflowRun` 行上没有这一位,本服务不编。
11
+ * · `drop`:这条持久链只搬运一句受限摘要 + 诊断文本 + 路由键 —— `task_id` / `task_type` / `toolUseId` 是 live `task_notification` 帧的键(那条路径自带),`result` / `usage` 是完整结果 / 计量
12
+ * (`WorkflowStatus` 读得到),不进补投帧。
11
13
  * 键名直呼 core 的入参型(型文本里就有 core 名)⇒ 读表的 literals 段收得到这些键。
12
14
  */
13
15
  export declare const WORKFLOW_NOTIFY_KEY_DISPOSITION: {
@@ -18,12 +20,12 @@ export declare const WORKFLOW_NOTIFY_KEY_DISPOSITION: {
18
20
  readonly principal: "carry";
19
21
  readonly originatingSessionId: "carry";
20
22
  readonly completionId: "carry";
23
+ readonly diagnostics: "carry";
21
24
  readonly task_id: "drop";
22
25
  readonly task_type: "drop";
23
26
  readonly toolUseId: "drop";
24
27
  readonly result: "drop";
25
28
  readonly usage: "drop";
26
- readonly diagnostics: "drop";
27
29
  };
28
30
  type NotifyKeyDisposition = typeof WORKFLOW_NOTIFY_KEY_DISPOSITION;
29
31
  /** 处置表里 `carry` 的键。 */
@@ -13,12 +13,12 @@ export const WORKFLOW_NOTIFY_KEY_DISPOSITION = {
13
13
  principal: "carry",
14
14
  originatingSessionId: "carry",
15
15
  completionId: "carry",
16
+ diagnostics: "carry",
16
17
  task_id: "drop",
17
18
  task_type: "drop",
18
19
  toolUseId: "drop",
19
20
  result: "drop",
20
21
  usage: "drop",
21
- diagnostics: "drop",
22
22
  };
23
23
  const SUMMARY_MAX = 500;
24
24
  export function recoverySummary(status, error) {
@@ -81,6 +81,7 @@ export class WorkflowNotifyGate {
81
81
  ...(input.principal ? { principal: input.principal } : {}),
82
82
  ...(input.originatingSessionId ? { originatingSessionId: input.originatingSessionId } : {}),
83
83
  ...(input.completionId ? { completionId: input.completionId } : {}),
84
+ ...(input.diagnostics ? { diagnostics: input.diagnostics } : {}),
84
85
  }, input.scope ?? input.principal ?? "default");
85
86
  },
86
87
  };