@sema-agent/server 7.132.0 → 7.134.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 (473) hide show
  1. package/MIGRATION.md +353 -0
  2. package/README.md +8 -9
  3. package/README.zh-CN.md +7 -6
  4. package/USAGE.md +301 -64
  5. package/deploy/sema-up/README.md +35 -1
  6. package/deploy/sema-up/chart/Chart.yaml +1 -1
  7. package/deploy/sema-up/chart/templates/NOTES.txt +15 -0
  8. package/deploy/sema-up/chart/templates/_helpers.tpl +129 -0
  9. package/deploy/sema-up/chart/templates/sealed-key.yaml +24 -0
  10. package/deploy/sema-up/chart/templates/server-v4pro.yaml +19 -2
  11. package/deploy/sema-up/chart/templates/server.yaml +19 -2
  12. package/deploy/sema-up/chart/values-full-single.yaml +5 -1
  13. package/deploy/sema-up/chart/values.yaml +34 -0
  14. package/deploy/sema-up/stack/compose.yaml +3 -0
  15. package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
  16. package/dist/adoption/plan.d.ts +3 -2
  17. package/dist/adoption/plan.js +7 -5
  18. package/dist/adoption/runner.js +3 -10
  19. package/dist/adoption/sql.d.ts +3 -2
  20. package/dist/adoption/sql.js +3 -5
  21. package/dist/adoption/wire.d.ts +4 -1
  22. package/dist/adoption/wire.js +1 -0
  23. package/dist/approval-ask-audit-store.d.ts +32 -14
  24. package/dist/approval-ask-audit-store.js +272 -74
  25. package/dist/approval-ask-machine.d.ts +15 -0
  26. package/dist/approval-ask-machine.js +6 -0
  27. package/dist/approval-ask-retention.d.ts +136 -0
  28. package/dist/approval-ask-retention.js +102 -0
  29. package/dist/approval-card.d.ts +83 -23
  30. package/dist/approval-card.js +45 -15
  31. package/dist/approval-content-kind.d.ts +5 -2
  32. package/dist/approval-content-kind.js +16 -3
  33. package/dist/approval-deny-reasons.d.ts +1 -1
  34. package/dist/approval-gate-currency.d.ts +72 -0
  35. package/dist/approval-gate-currency.js +94 -0
  36. package/dist/approval.d.ts +15 -0
  37. package/dist/approval.js +55 -17
  38. package/dist/audit.d.ts +27 -10
  39. package/dist/audit.js +12 -16
  40. package/dist/bake-runner/main.js +3 -2
  41. package/dist/boot/coordinators.d.ts +6 -1
  42. package/dist/boot/coordinators.js +6 -3
  43. package/dist/boot/deferred-sandbox-path-env.js +1 -1
  44. package/dist/boot/execution-env.js +9 -7
  45. package/dist/boot/execution-lane.js +11 -0
  46. package/dist/boot/leader.d.ts +2 -0
  47. package/dist/boot/leader.js +4 -1
  48. package/dist/boot/memory-boundary.js +2 -2
  49. package/dist/boot/memory-consolidation.d.ts +5 -4
  50. package/dist/boot/memory-consolidation.js +7 -6
  51. package/dist/boot/org-delivery.d.ts +28 -0
  52. package/dist/boot/org-delivery.js +20 -0
  53. package/dist/boot/read-deny-anchor-audit.js +2 -2
  54. package/dist/boot/reapers.d.ts +3 -0
  55. package/dist/boot/reapers.js +21 -1
  56. package/dist/boot/resolve-spec.d.ts +3 -0
  57. package/dist/boot/resolve-spec.js +60 -81
  58. package/dist/boot/runner-deps.d.ts +18 -5
  59. package/dist/boot/runner-deps.js +10 -0
  60. package/dist/boot/session-faces.d.ts +1 -0
  61. package/dist/boot/session-faces.js +4 -2
  62. package/dist/boot/stage-02-web-admin-pull.js +4 -1
  63. package/dist/boot/stage-06-runners.d.ts +6 -3
  64. package/dist/boot/stage-06-runners.js +20 -4
  65. package/dist/boot/stage-07-capability-layer.d.ts +4 -1
  66. package/dist/boot/stage-07-capability-layer.js +24 -3
  67. package/dist/boot/stage-08-reapers.d.ts +4 -1
  68. package/dist/boot/stage-08-reapers.js +2 -2
  69. package/dist/boot/stage-09-leader.d.ts +5 -1
  70. package/dist/boot/stage-09-leader.js +2 -2
  71. package/dist/boot/stage-10-http-server.d.ts +5 -1
  72. package/dist/boot/stage-10-http-server.js +6 -6
  73. package/dist/boot/stores.d.ts +8 -0
  74. package/dist/boot/stores.js +10 -14
  75. package/dist/boot/web-admin.d.ts +10 -0
  76. package/dist/boot/web-admin.js +162 -65
  77. package/dist/boot/workflow-orchestration.d.ts +2 -0
  78. package/dist/boot/workflow-orchestration.js +2 -1
  79. package/dist/brain.js +8 -3
  80. package/dist/breaker-key.d.ts +6 -0
  81. package/dist/breaker-key.js +29 -0
  82. package/dist/budget.js +5 -1
  83. package/dist/caller-text-echo.d.ts +11 -6
  84. package/dist/caller-text-echo.js +10 -12
  85. package/dist/canonical-json.d.ts +2 -41
  86. package/dist/canonical-json.js +2 -13
  87. package/dist/capabilities/center-plugins.d.ts +7 -0
  88. package/dist/capabilities/center-plugins.js +1 -1
  89. package/dist/capabilities/composite-members.d.ts +1 -1
  90. package/dist/capabilities/composite-members.js +1 -1
  91. package/dist/capabilities/execution-lane.js +2 -2
  92. package/dist/capabilities/hands-lane.d.ts +21 -0
  93. package/dist/capabilities/hands-lane.js +10 -0
  94. package/dist/capabilities/mcp-probe.d.ts +36 -4
  95. package/dist/capabilities/mcp-probe.js +29 -6
  96. package/dist/capabilities/scenarios.d.ts +63 -7
  97. package/dist/capabilities/scenarios.js +39 -7
  98. package/dist/capability-facts.d.ts +36 -4
  99. package/dist/capability-facts.js +30 -4
  100. package/dist/center-config-tier.d.ts +69 -0
  101. package/dist/center-config-tier.js +42 -0
  102. package/dist/checkpoint-ctx-seal-m28.d.ts +42 -0
  103. package/dist/checkpoint-ctx-seal-m28.js +19 -0
  104. package/dist/checkpoint-identity.d.ts +16 -0
  105. package/dist/checkpoint-identity.js +19 -0
  106. package/dist/config-catalog.d.ts +17 -10
  107. package/dist/config-catalog.js +43 -28
  108. package/dist/config-d-migration.d.ts +3 -1
  109. package/dist/config-d-migration.js +2 -2
  110. package/dist/config-dir-trust.d.ts +114 -0
  111. package/dist/config-dir-trust.js +388 -0
  112. package/dist/config-invariants.d.ts +18 -5
  113. package/dist/config-invariants.js +35 -3
  114. package/dist/config-provider.d.ts +6 -1
  115. package/dist/config-provider.js +6 -2
  116. package/dist/config-types.d.ts +71 -14
  117. package/dist/config-types.js +8 -0
  118. package/dist/config.d.ts +13 -0
  119. package/dist/config.js +121 -59
  120. package/dist/delegated-session-owner.d.ts +185 -0
  121. package/dist/delegated-session-owner.js +119 -0
  122. package/dist/device-protocol.d.ts +5 -3
  123. package/dist/device-protocol.js +1 -1
  124. package/dist/device-ws-hub.js +21 -2
  125. package/dist/device-ws-protocol.d.ts +70 -6
  126. package/dist/device-ws-protocol.js +50 -23
  127. package/dist/elicitation.js +3 -2
  128. package/dist/entry-problems.d.ts +34 -0
  129. package/dist/entry-problems.js +14 -0
  130. package/dist/execution-lane-caps.d.ts +49 -10
  131. package/dist/execution-lane-caps.js +43 -4
  132. package/dist/field-conflict.d.ts +44 -0
  133. package/dist/field-conflict.js +21 -0
  134. package/dist/file-history-disclosure.d.ts +34 -5
  135. package/dist/file-history-disclosure.js +2 -2
  136. package/dist/fleet/fleet-bus.d.ts +84 -6
  137. package/dist/fleet/fleet-bus.js +42 -9
  138. package/dist/hooks/classic-stations.d.ts +10 -5
  139. package/dist/hooks/classic-stations.js +4 -4
  140. package/dist/hooks/command-spawn.d.ts +57 -0
  141. package/dist/hooks/command-spawn.js +139 -0
  142. package/dist/hooks/hook-llm.js +2 -2
  143. package/dist/hooks/hook-runner.d.ts +127 -25
  144. package/dist/hooks/hook-runner.js +668 -287
  145. package/dist/hooks/hook-source.d.ts +44 -0
  146. package/dist/hooks/hook-source.js +40 -0
  147. package/dist/http/active-run-conflict.d.ts +5 -13
  148. package/dist/http/active-run-conflict.js +17 -27
  149. package/dist/http/admission.js +111 -60
  150. package/dist/http/approval-sweeps.js +58 -19
  151. package/dist/http/caller-trust.d.ts +77 -0
  152. package/dist/http/caller-trust.js +143 -0
  153. package/dist/http/checkpoint-ctx.d.ts +173 -18
  154. package/dist/http/checkpoint-ctx.js +171 -12
  155. package/dist/http/claimed-run.d.ts +4 -3
  156. package/dist/http/device-placement.d.ts +2 -4
  157. package/dist/http/device-placement.js +2 -1
  158. package/dist/http/dispatch.js +13 -7
  159. package/dist/http/durable-run-leg.d.ts +4 -32
  160. package/dist/http/durable-run-leg.js +37 -12
  161. package/dist/http/idempotency.d.ts +2 -2
  162. package/dist/http/idempotency.js +2 -2
  163. package/dist/http/owner-access.d.ts +56 -0
  164. package/dist/http/owner-access.js +42 -0
  165. package/dist/http/principal-gate.d.ts +78 -27
  166. package/dist/http/principal-gate.js +64 -14
  167. package/dist/http/readiness.d.ts +11 -5
  168. package/dist/http/readiness.js +10 -3
  169. package/dist/http/refusal-body.d.ts +12 -0
  170. package/dist/http/refusal-body.js +11 -0
  171. package/dist/http/request-guards.d.ts +16 -32
  172. package/dist/http/request-guards.js +31 -30
  173. package/dist/http/resume-ctx-read.d.ts +50 -6
  174. package/dist/http/resume-ctx-read.js +33 -7
  175. package/dist/http/resume-legs.d.ts +5 -5
  176. package/dist/http/resume-legs.js +163 -91
  177. package/dist/http/retired-service-deps.d.ts +43 -0
  178. package/dist/http/retired-service-deps.js +18 -0
  179. package/dist/http/route-ctx.d.ts +44 -37
  180. package/dist/http/route-ctx.js +4 -0
  181. package/dist/http/route-table.js +2 -0
  182. package/dist/http/routes/a2a-serve.js +3 -4
  183. package/dist/http/routes/admin-config-refresh.js +1 -1
  184. package/dist/http/routes/admin-drain.js +1 -1
  185. package/dist/http/routes/admin-memory-optout.js +5 -1
  186. package/dist/http/routes/adoption.js +2 -9
  187. package/dist/http/routes/agents-roster.js +2 -3
  188. package/dist/http/routes/approvals-assistant.js +91 -56
  189. package/dist/http/routes/background.js +3 -2
  190. package/dist/http/routes/capabilities.js +20 -4
  191. package/dist/http/routes/config-catalog.d.ts +3 -3
  192. package/dist/http/routes/config-catalog.js +1 -1
  193. package/dist/http/routes/devices.js +3 -17
  194. package/dist/http/routes/diagnostics.d.ts +3 -3
  195. package/dist/http/routes/diagnostics.js +6 -2
  196. package/dist/http/routes/fleet.js +4 -4
  197. package/dist/http/routes/images.js +6 -7
  198. package/dist/http/routes/leader.js +1 -8
  199. package/dist/http/routes/mcp-reconnect.d.ts +1 -1
  200. package/dist/http/routes/mcp-reconnect.js +3 -2
  201. package/dist/http/routes/memory-bundle.js +1 -1
  202. package/dist/http/routes/memory-compliance.js +1 -1
  203. package/dist/http/routes/memory-consolidation.js +1 -1
  204. package/dist/http/routes/memory-origin.d.ts +1 -1
  205. package/dist/http/routes/memory-origin.js +1 -1
  206. package/dist/http/routes/memory-policy.d.ts +1 -1
  207. package/dist/http/routes/memory-policy.js +3 -2
  208. package/dist/http/routes/notify-wake.js +8 -21
  209. package/dist/http/routes/observability.js +2 -2
  210. package/dist/http/routes/principal-inbox.d.ts +39 -0
  211. package/dist/http/routes/principal-inbox.js +76 -0
  212. package/dist/http/routes/retention-ops.js +2 -9
  213. package/dist/http/routes/rules.js +9 -22
  214. package/dist/http/routes/runs.d.ts +5 -0
  215. package/dist/http/routes/runs.js +63 -115
  216. package/dist/http/routes/session-sync.d.ts +3 -2
  217. package/dist/http/routes/session-sync.js +53 -48
  218. package/dist/http/routes/sessions-list.d.ts +1 -1
  219. package/dist/http/routes/sessions-list.js +3 -4
  220. package/dist/http/routes/sessions.js +33 -43
  221. package/dist/http/routes/side-query.js +6 -4
  222. package/dist/http/routes/tasks.js +71 -30
  223. package/dist/http/routes/trace-usage.js +7 -9
  224. package/dist/http/routes/workflows.d.ts +351 -0
  225. package/dist/http/routes/workflows.js +153 -119
  226. package/dist/http/run-declared-families.d.ts +16 -0
  227. package/dist/http/run-declared-families.js +12 -0
  228. package/dist/http/send.d.ts +24 -3
  229. package/dist/http/send.js +14 -2
  230. package/dist/http/server.d.ts +23 -18
  231. package/dist/http/server.js +20 -15
  232. package/dist/http/stored-body-replay.js +17 -4
  233. package/dist/http/submit-ctx.d.ts +4 -3
  234. package/dist/http/submit-ctx.js +23 -6
  235. package/dist/http/submit-replay.d.ts +4 -3
  236. package/dist/http/submit-replay.js +5 -4
  237. package/dist/http/wire-types.d.ts +17 -10
  238. package/dist/index.d.ts +3 -1
  239. package/dist/index.js +1 -1
  240. package/dist/lane-home-probe.d.ts +78 -9
  241. package/dist/lane-home-probe.js +78 -12
  242. package/dist/leader/endpoint.d.ts +4 -1
  243. package/dist/leader/endpoint.js +11 -10
  244. package/dist/leader/wire.d.ts +4 -0
  245. package/dist/leader/wire.js +8 -7
  246. package/dist/limit-refusal.d.ts +17 -5
  247. package/dist/limit-refusal.js +4 -1
  248. package/dist/main.js +1 -1
  249. package/dist/mcp-assertion-header.d.ts +31 -10
  250. package/dist/mcp-assertion-header.js +10 -3
  251. package/dist/memory-origin-fence.js +2 -2
  252. package/dist/memory-project-layer.d.ts +37 -0
  253. package/dist/memory-project-layer.js +46 -0
  254. package/dist/memory-scope.d.ts +23 -16
  255. package/dist/memory-scope.js +24 -8
  256. package/dist/memory-sync-client.d.ts +27 -13
  257. package/dist/memory-sync-client.js +107 -18
  258. package/dist/model-compat.d.ts +1 -1
  259. package/dist/model-entry-refusal.d.ts +9 -1
  260. package/dist/model-entry-refusal.js +6 -1
  261. package/dist/model-plane-face.d.ts +51 -0
  262. package/dist/model-plane-face.js +24 -0
  263. package/dist/model-provider.d.ts +5 -0
  264. package/dist/model-provider.js +4 -2
  265. package/dist/model-route-endpoint.d.ts +8 -11
  266. package/dist/model-route-endpoint.js +4 -7
  267. package/dist/model-route-env.d.ts +22 -0
  268. package/dist/model-route-env.js +2 -0
  269. package/dist/model-route-gap.d.ts +60 -30
  270. package/dist/model-route-gap.js +21 -15
  271. package/dist/observability/corrupt-read-seat.d.ts +7 -0
  272. package/dist/observability/corrupt-read-seat.js +9 -0
  273. package/dist/observability/err-text.d.ts +6 -0
  274. package/dist/observability/err-text.js +18 -4
  275. package/dist/observability/fail-open.d.ts +35 -9
  276. package/dist/observability/fail-open.js +35 -9
  277. package/dist/observability/metrics.js +1 -0
  278. package/dist/observability/prompt-manifest.d.ts +22 -25
  279. package/dist/observability/prompt-manifest.js +54 -50
  280. package/dist/observability/tool-trace.js +9 -10
  281. package/dist/operator-ask.d.ts +10 -0
  282. package/dist/operator-ask.js +3 -0
  283. package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
  284. package/dist/orchestration/workflow-agent-session-index.js +9 -13
  285. package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
  286. package/dist/orchestration/workflow-completion-inbox.js +13 -0
  287. package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
  288. package/dist/orchestration/workflow-notify-journal.js +27 -34
  289. package/dist/orchestration/workflow-park-decision.d.ts +89 -0
  290. package/dist/orchestration/workflow-park-decision.js +119 -0
  291. package/dist/org-delivery-gate.d.ts +81 -0
  292. package/dist/org-delivery-gate.js +59 -0
  293. package/dist/panel-tool-names.d.ts +23 -0
  294. package/dist/panel-tool-names.js +8 -0
  295. package/dist/parked-decide.d.ts +43 -11
  296. package/dist/parked-decide.js +100 -51
  297. package/dist/parked-revive-surface.d.ts +9 -2
  298. package/dist/parked-revive-surface.js +11 -8
  299. package/dist/permission-rule-list.d.ts +1 -1
  300. package/dist/permission-rule-list.js +2 -2
  301. package/dist/permission-rule-vocab.d.ts +1 -23
  302. package/dist/permission-rule-vocab.js +0 -13
  303. package/dist/plugins/approval-ask-store-file.d.ts +16 -1
  304. package/dist/plugins/approval-ask-store-file.js +21 -0
  305. package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
  306. package/dist/plugins/approval-ask-store-memory.js +34 -2
  307. package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
  308. package/dist/plugins/approval-ask-store-sql.js +37 -1
  309. package/dist/plugins/approval-payload-fingerprint.d.ts +14 -6
  310. package/dist/plugins/approval-payload-fingerprint.js +1 -1
  311. package/dist/plugins/blob-backend.d.ts +38 -25
  312. package/dist/plugins/blob-backend.js +29 -19
  313. package/dist/plugins/breaker-state-sql.d.ts +2 -2
  314. package/dist/plugins/breaker-state-sql.js +4 -4
  315. package/dist/plugins/caching-session-store.d.ts +4 -1
  316. package/dist/plugins/caching-session-store.js +7 -3
  317. package/dist/plugins/checkpoint-store-sql.d.ts +36 -1
  318. package/dist/plugins/checkpoint-store-sql.js +65 -3
  319. package/dist/plugins/file-history-store-sql.d.ts +5 -2
  320. package/dist/plugins/file-history-store-sql.js +3 -1
  321. package/dist/plugins/file-run-store.d.ts +5 -13
  322. package/dist/plugins/file-run-store.js +9 -0
  323. package/dist/plugins/fork-routing-session-store.d.ts +9 -1
  324. package/dist/plugins/fork-routing-session-store.js +12 -1
  325. package/dist/plugins/host-platform.d.ts +2 -0
  326. package/dist/plugins/host-platform.js +2 -1
  327. package/dist/plugins/local-checkpoint-store.d.ts +15 -2
  328. package/dist/plugins/local-checkpoint-store.js +32 -1
  329. package/dist/plugins/local-session-store.d.ts +13 -10
  330. package/dist/plugins/local-session-store.js +23 -14
  331. package/dist/plugins/local-session-window.d.ts +45 -0
  332. package/dist/plugins/local-session-window.js +38 -0
  333. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
  334. package/dist/plugins/mailbox-store-sql.d.ts +30 -48
  335. package/dist/plugins/mailbox-store-sql.js +77 -52
  336. package/dist/plugins/memory-embedder-fingerprint.js +2 -1
  337. package/dist/plugins/memory-run-store.d.ts +5 -13
  338. package/dist/plugins/memory-run-store.js +8 -0
  339. package/dist/plugins/one-time-migrations.d.ts +121 -5
  340. package/dist/plugins/one-time-migrations.js +332 -8
  341. package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
  342. package/dist/plugins/org-delivery-quota-store.js +228 -0
  343. package/dist/plugins/permission-rule-store-file.js +10 -6
  344. package/dist/plugins/permission-rule-store-sql.js +8 -8
  345. package/dist/plugins/pg-pool.js +39 -7
  346. package/dist/plugins/pg-session-storage.d.ts +18 -5
  347. package/dist/plugins/pg-session-storage.js +68 -23
  348. package/dist/plugins/remote-env-adb.d.ts +6 -12
  349. package/dist/plugins/remote-env-adb.js +12 -2
  350. package/dist/plugins/remote-env-device.d.ts +14 -7
  351. package/dist/plugins/remote-env-device.js +23 -15
  352. package/dist/plugins/remote-env-k8s.d.ts +8 -12
  353. package/dist/plugins/remote-env-k8s.js +23 -5
  354. package/dist/plugins/remote-env-local-docker.d.ts +10 -15
  355. package/dist/plugins/remote-env-local-docker.js +12 -9
  356. package/dist/plugins/remote-env-ssh.d.ts +10 -16
  357. package/dist/plugins/remote-env-ssh.js +17 -11
  358. package/dist/plugins/run-store-sql.d.ts +16 -14
  359. package/dist/plugins/run-store-sql.js +22 -2
  360. package/dist/plugins/schema-indexes.js +2 -0
  361. package/dist/plugins/send-user-file.js +2 -2
  362. package/dist/plugins/session-epoch-anchor.d.ts +32 -6
  363. package/dist/plugins/session-epoch-anchor.js +2 -3
  364. package/dist/plugins/session-ownership.d.ts +11 -0
  365. package/dist/plugins/session-ownership.js +11 -0
  366. package/dist/plugins/session-placement.d.ts +12 -14
  367. package/dist/plugins/session-placement.js +2 -15
  368. package/dist/plugins/session-store.d.ts +18 -8
  369. package/dist/plugins/session-store.js +15 -4
  370. package/dist/plugins/sql-driver.d.ts +74 -11
  371. package/dist/plugins/sql-driver.js +210 -12
  372. package/dist/plugins/sql-errors.d.ts +23 -0
  373. package/dist/plugins/sql-errors.js +21 -0
  374. package/dist/plugins/store-backend.d.ts +36 -1
  375. package/dist/plugins/store-backend.js +40 -14
  376. package/dist/plugins/store-contracts.d.ts +42 -0
  377. package/dist/plugins/store-contracts.js +1 -0
  378. package/dist/plugins/tidb-pool.d.ts +6 -1
  379. package/dist/plugins/tidb-pool.js +44 -10
  380. package/dist/plugins/tidb-session-storage.d.ts +3 -2
  381. package/dist/plugins/tidb-session-storage.js +2 -2
  382. package/dist/plugins/tidb-session-store.d.ts +25 -5
  383. package/dist/plugins/tidb-session-store.js +67 -21
  384. package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
  385. package/dist/plugins/workflow-journal-store-sql.js +19 -6
  386. package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
  387. package/dist/plugins/workflow-run-store-sql.js +50 -9
  388. package/dist/posture-source.d.ts +18 -10
  389. package/dist/posture-source.js +4 -1
  390. package/dist/project-identity.d.ts +45 -6
  391. package/dist/project-identity.js +162 -8
  392. package/dist/project-layer-key.d.ts +28 -0
  393. package/dist/project-layer-key.js +29 -0
  394. package/dist/question.js +3 -2
  395. package/dist/read-deny-entry.d.ts +25 -0
  396. package/dist/read-deny-entry.js +12 -0
  397. package/dist/read-face-posture.d.ts +37 -11
  398. package/dist/read-face-posture.js +32 -3
  399. package/dist/request-key-closure.d.ts +7 -0
  400. package/dist/request-key-closure.js +9 -1
  401. package/dist/request-tool-axes.d.ts +12 -0
  402. package/dist/request-tool-axes.js +20 -0
  403. package/dist/request-value-closure.d.ts +5 -0
  404. package/dist/request-value-closure.js +11 -3
  405. package/dist/rule-entry-list.d.ts +26 -2
  406. package/dist/rule-entry-list.js +72 -12
  407. package/dist/rules-consent.js +3 -4
  408. package/dist/run-acceptance.d.ts +19 -3
  409. package/dist/run-acceptance.js +13 -1
  410. package/dist/run-local.js +37 -6
  411. package/dist/runs.d.ts +12 -10
  412. package/dist/runs.js +25 -6
  413. package/dist/runtime-caps-resolver.d.ts +16 -6
  414. package/dist/runtime-caps-resolver.js +18 -5
  415. package/dist/sandbox-pkg-source.d.ts +19 -1
  416. package/dist/sandbox-pkg-source.js +29 -7
  417. package/dist/sealed-key.d.ts +32 -0
  418. package/dist/sealed-key.js +55 -1
  419. package/dist/security.d.ts +95 -15
  420. package/dist/security.js +52 -9
  421. package/dist/session-error-wire.d.ts +31 -7
  422. package/dist/session-error-wire.js +9 -2
  423. package/dist/session-sync-kernel.d.ts +37 -10
  424. package/dist/session-sync-kernel.js +10 -0
  425. package/dist/session-titled-frame.d.ts +33 -0
  426. package/dist/session-titled-frame.js +4 -0
  427. package/dist/session-titler.d.ts +9 -1
  428. package/dist/session-titler.js +15 -4
  429. package/dist/spec-fields.js +21 -2
  430. package/dist/sql-engine-posture.d.ts +3 -1
  431. package/dist/task-a2a.js +4 -3
  432. package/dist/task-cwd.d.ts +1 -1
  433. package/dist/task-mcp.d.ts +5 -5
  434. package/dist/task-mcp.js +27 -74
  435. package/dist/task-settings.d.ts +93 -88
  436. package/dist/task-settings.js +71 -63
  437. package/dist/text-bidi.d.ts +0 -4
  438. package/dist/text-bidi.js +1 -3
  439. package/dist/tighten-only-seats.d.ts +150 -0
  440. package/dist/tighten-only-seats.js +196 -0
  441. package/dist/tool-approval.d.ts +451 -136
  442. package/dist/tool-approval.js +733 -256
  443. package/dist/tool-rule-names.d.ts +6 -0
  444. package/dist/trace/core-keyset-guard.d.ts +108 -25
  445. package/dist/trace/exit-seat.d.ts +40 -0
  446. package/dist/trace/exit-seat.js +130 -0
  447. package/dist/trace/ledger-events.d.ts +6 -3
  448. package/dist/trace/project.d.ts +98 -13
  449. package/dist/trace/project.js +57 -32
  450. package/dist/trace/projection-table.d.ts +100 -0
  451. package/dist/trace/projection-table.js +130 -0
  452. package/dist/trace/redact.d.ts +57 -0
  453. package/dist/trace/redact.js +962 -168
  454. package/dist/trace/self-minted-wire.d.ts +349 -1
  455. package/dist/trace/self-minted-wire.js +118 -1
  456. package/dist/trace/wire-projection-faces.d.ts +304 -2
  457. package/dist/trace/wire-projection-faces.js +160 -13
  458. package/dist/url-refusal.js +2 -0
  459. package/dist/web-admin-client/apply-effective.d.ts +12 -0
  460. package/dist/web-admin-client/apply-effective.js +56 -5
  461. package/dist/web-admin-client/facade.d.ts +1 -1
  462. package/dist/web-admin-client/facade.js +1 -1
  463. package/dist/web-admin-client/read-face.js +5 -9
  464. package/dist/web-admin-client/skills-mcp.d.ts +1 -1
  465. package/dist/web-admin-client/skills-mcp.js +6 -8
  466. package/dist/web-admin-client/types.d.ts +1 -1
  467. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -9
  468. package/package.json +8 -4
  469. package/scripts/drain-check-local.mjs +34 -2
  470. package/scripts/drain-check.mysql.sql +20 -2
  471. package/scripts/drain-check.pg.sql +20 -2
  472. package/dist/mcp-tool-faces.d.ts +0 -69
  473. package/dist/mcp-tool-faces.js +0 -106
@@ -28,13 +28,17 @@ export const FAIL_OPEN_TAGS = {
28
28
  cls: "P-DEBT",
29
29
  note: "core 7.51.0 #1718 提货(`boot/memory-consolidation.ts` `createOperatorValveWriteJudge`):运维手动整理阀门的写判官座已是引擎的那一只构造器,但三层没喂 —— 人的持久规则层(阀门没有「库属于谁」的来源,无 principal / 不声明 local-owner)、部署的调用方策略层(`APPROVAL_REQUIRE` / `APPROVAL_DENY` / `AUTONOMY` / 敏感路径守卫集是每任务现合成的活配置、无部署级单例;敏感路径层另需引擎豁免根入参,宿主构造器输入没有这一位)、项目根(项目层 scope 键是任务根的单向散列,反推不出)。每被问一次(早问库目录一次 + 每个产物一次)记一次。放行的最坏后果 = 运维手动整理时,一条点名记忆库路径的人的持久规则或部署写策略(例如 `APPROVAL_DENY=Write`)拦不住这一轮折叠(与 7.128.x 逐字同;只是判官不再是代答);自动整理腿走引擎腿自己的判官,不在本 tag 射程。收口 = 三层各自有了来源(人:「读谁的桶」裁定;策略:一份设计 + 向 core 请托引擎豁免根入参;根:无来源则永久缺席并改写本债)那一版,本 tag 删。",
30
30
  },
31
- "server.workflow-park-index.sync-failed": {
32
- cls: "P-DEBT",
33
- note: "S-185 车CM(codex r1-F2 [high],验真后登记):workflow 出身 park 的 join 索引(`workflow_agent_session` / local 账本)在**一次成功的 run 写之后**同步失败 ⇒ 该次同步被吞,重试要等这条 run 的**下一次**写。而 park 恰好常常是这条 run 的**最后**一次写(park = run 终局 `failed`)⇒ 那条 park 可能永久 join 不到。**多数情形**是诚实 miss:这张卡没有别的指针 ⇒ `/decide` 结构性退回本批之前的行为(409 `conflict.resume_context_unavailable`),不误配、不伪造、不放行,丢的是「人能不能把这条批准送出去」这个能力。**7.118.0 起不止于此**:路由把指针候选当持有者的全集读,并有分叉门(两条同代次持有者 ⇒ 409 `decide.workflow_park_forked`);同一张卡上一枚**竞争**指针没写上(本臂的写失败,或写记录与写指针之间进程崩溃 —— 后者不经本臂、不计数)⇒ 分叉被判成唯一持有者 ⇒ 决定投给幸存的那一支(它确实持有这张卡,但另一支同样站在上面,引擎把这种形交给消费方拒)。归 P 类的理由:缺指针决定**车道选择**(缺行 ⇒ 选中 legacy 腿),且能让分叉门失效;归 DEBT 的理由是真正的解要一条**按子代 checkpoint 键的耐久决议回执 + 重启期回填**(与 codex r1-F3 同一件欠账,另车),分叉门失效那一形另有设计票。计数非零 = 有 park 可能决不掉、或这张卡的分叉门可能失效,运维要按 detail 里的 runId 去查那条 run 的续跑链。",
34
- },
35
31
  "server.workflow-park-index.parks-unreadable": {
36
32
  cls: "F",
37
- note: "S-1173(`workflow-notify-journal.ts` 的 `syncAgentSessionIndex`,与上一条 `sync-failed` 同一个写点、另一臂):workflow run 记录的 `parks[]` **读不出**(在场却不是列表 / 某条目身份位或持有者两位形坏;读者 = `workflow-agent-session-index.ts` 的 `readRunParks`,整档成败制)⇒ 这一份指针投影派生不出来 ⇒ 写者**不动**这条 run 已有的指针(上一份已知良好的投影留着)。修前这一臂静默 `return`。**`parks` 缺席不进这一臂**:那是引擎契约里的合法形(更早引擎写的记录 / 准入没走完的续跑记录),读者答 `[]`(没有条目),写者照常收敛成空指针集,不计。**与 `sync-failed` 分家的理由(后果不同句,不并成一个 tag)**:`sync-failed` 是索引**写**挂了、丢的是一份已知良好的投影(park 常常是 run 的最后一次写 ⇒ 永久 join 不到,归 P-DEBT);本臂没有丢任何一份已知良好的投影 —— 读不出的是**记录本身**,引擎对条目形坏的记录整条拒续跑(`park_binding_broken`),读口对已有指针的 run 据记录响亮拒(`unproven/unreadable`),所以无需「重试这次写」,要的是查那条记录为什么读不出(投影把它写坏 / 手改)。放行的最坏后果:这条 run 的指针不被刷新(从没写过则没有指针 ⇒ 这张卡没有别的指针时 `/decide` 落 legacy 腿、409 响亮拒),多数情形方向是 fail-closed,不误配、不放行任何东西;例外与上一条同形 —— 首写就读不出的这一支没有指针,同一张卡上另一支的指针在时分叉门判不出、决定投给那一支(引擎从不写坏形,要这一支在首写之前就被写坏,比上一条的写失败更罕见);derived cache 没更新、真源读口自带响亮拒 ⇒ F 类。detail = `runId=`;计数非零 = 有记录的 `parks[]` 读不出,按 runId 去查记录。",
33
+ note: "S-1173(`workflow-notify-journal.ts` 的 `ensurePointersFor`,park 指针的唯一写点):workflow run 记录的 `parks[]` **读不出**(在场却不是列表 / 某条目身份位或持有者两位形坏;读者 = `workflow-agent-session-index.ts` 的 `readRunParks`,整档成败制)⇒ 这一份指针投影派生不出来 ⇒ 写者这次**不写**指针,记录照写(已写过的指针只增不删,原样留着)。修前这一臂静默 `return`。**`parks` 缺席不进这一臂**:那是引擎契约里的合法形(更早引擎写的记录 / 准入没走完的续跑记录),读者答 `[]`(没有条目),没有要写的指针,不计。与指针**写**失败分家:写失败 ⇒ 记录写抛、记录不落(指针先于记录,不 fail-open);本臂没有丢任何一枚已写的指针 —— 读不出的是**记录本身**,引擎对条目形坏的记录整条拒续跑(`park_binding_broken`),读口对已有指针的 run 据记录响亮拒(`unproven/unreadable`),所以要的是查那条记录为什么读不出(投影把它写坏 / 手改)。放行的最坏后果:这条 run 首写就读不出时没有指针 ⇒ 这张卡没有别的指针时 `/decide` 落 legacy 腿、409 响亮拒,方向 fail-closed,不误配、不放行任何东西;例外 —— 同一张卡上另一支的指针在时分叉门判不出、决定投给那一支(引擎从不写坏形,要这一支在首写之前就被写坏);derived cache 没更新、真源读口自带响亮拒 ⇒ F 类。detail = `runId=`;计数非零 = 有记录的 `parks[]` 读不出,按 runId 去查记录。",
34
+ },
35
+ "server.workflow-park-decision.card-unreadable": {
36
+ cls: "F",
37
+ note: "起跑读者(`parked-decide.ts` 的 `heldWorkflowParkDecisions`,每一只起跑器开跑前一次)读某条已受理的 workflow 子代决定所属的那张卡时 checkpoint 店抛 ⇒ 这一跑**不带**这条决定,行留着给下一跑。放行的最坏后果:这一跑里宿主若续跑那条 workflow run,子代按同一个 token 再停驻一次(卡仍 pending,决定仍在,下一跑照带)—— 方向是少交付一次,不是错交付:这一读失败不代表引擎随后那一读也失败,而引擎对「卡已不 pending、却拿到一条决定」的序数会当确认结算,所以读不出时绝不照供。计数持续非零 = checkpoint 店对这张卡读不出(库故障 / 行坏 / 写者版本更新),按 detail 的 `runId=`(受理那一刻的持有者)去查。detail = `runId=<留存锚> err=<原句,经记录器脱敏>`。",
38
+ },
39
+ "server.workflow-park-decision.store-unreadable": {
40
+ cls: "F",
41
+ note: "起跑读者(`parked-decide.ts` 的 `heldWorkflowParkDecisions`,每一只起跑器开跑前一次)读这个会话的 workflow 子代决定行时**决定店抛**(local 账本中间一行读不出 ⇒ 闸合上;SQL 这个会话的某一行 `outcome` 坏体 ⇒ 行读者拒)⇒ 与同一读者读卡失败那一臂同律:这一店当「没有可供的行」,这一跑只带调用方带来的那一份(`/decide` 的投递跑带着刚受理的那一条),起跑照常。放行的最坏后果:这个会话里已受理、还没被引擎用掉的决定这一跑都不带 —— 宿主若续跑那条 workflow run,子代按同一个 token 再停驻一次,卡仍 pending、可再决;方向是少交付,不是错交付(读不出的那一行可能正是**取代**了旧决定的那一笔,所以绝不跳过坏行照供其余)。决定的写口与按 token 读(`/decide` 的回执幂等判)照旧带码拒 —— 账本修好之前决不掉 workflow 子代卡,但不再连带拒掉每一跑(修前:local 上整台部署、SQL 上该会话的每一只起跑器都拒)。计数持续非零 = 决定店读不出,local 按披露 `workflow_park_decisions_corrupt_read` 去看账本文件,SQL 按 detail 的会话去查那几行。detail = `hostSessionId=<宿主会话> err=<原句,经记录器脱敏>`。",
38
42
  },
39
43
  "server.trace.gate-outcome-defective": {
40
44
  cls: "F",
@@ -160,6 +164,10 @@ export const FAIL_OPEN_TAGS = {
160
164
  cls: "F",
161
165
  note: "S-700(`plugins/checkpoint-store-sql.ts` 的 `readParkRowFactsCell`):运维待批队列(`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`**(`readParkGateCell`:同一列的 **`gate` 子树**在场却不是一只对象 —— 队列行的卡词与到期两条腿的分法都读它):读不出 = 门上无卡,队列行不带卡词,**到期改道** —— core `facetOf` 读「无卡 = 不是一问」为 `A`,所以一张本该到期**作废**的问答行改走 SLA **拒扫腿**(模型拿到一次「拒」而不是整条 run 作废);改道后的续跑 `get()` 对同一份坏 blob 响亮拒(拒扫腿每拍一条失败),行留停驻、由 `terminal_at_ms` 兜底收割 —— 所以最坏后果**不是**「只少展示」,是一张问答行的到期去向变了、最长挂到绝对上限。放行仍对:不放行的代价与 pendingAction 座同(一行坏 blob 打掉整个租户的队列与到期读腿)。计数 detail = `member=gate` 时,去按 session 查那一行的 `checkpoint.gate`。",
162
166
  },
167
+ "server.approvals.durable-row-checkpoint-id-missing": {
168
+ cls: "F",
169
+ note: "7.133.0(`checkpoint-identity.ts` 的 `durableRowIdentity`;两只店的 `listPending` + `/v1/assistant/inbox` handler):三处 durable 读面(运维队列行 `GET /v1/approvals` 与 `/v1/approvals/stream` 的 `pending` 帧;停驻收件 `GET /v1/assistant/inbox` 的行)读到一行停驻门**没有可用的 `checkpointId`** ⇒ 这一行**照列、`checkpointId` 键缺席**(消费方按「这一行没有可 join 的身份」处理)。detail = `face=<approvals-queue|assistant-inbox> why=<absent|untrusted>`:`absent` = 行上没有这一格(core 5.42.0 之前停驻的老行 —— core 明写不回填);`untrusted` = 在场却没过信任边界(非串 / 空串 / 超长 / 含 resume token —— 数据污染;没过边界的值不上 wire)。放行(列、键缺席)的最坏后果 = 消费方对这一行做不了跨面 join(三面对账少一行)—— 行本身、决断口(`/v1/approvals/:sessionId/decide`,按会话)、到期收割都照常。不放行有两种形:整只拒的代价是一行老 / 坏行打掉整个租户的队列(列表 500、SSE 心跳照常而队列永远停在旧帧);把这一行藏起来的代价更糟 —— 人看不到要批的东西(审批面上的 fail-open,方向反了)。故 F 类;必须留痕(两种成因从此可分)。计数非零 = 有老 / 坏行在飞(列着、没身份);`/stream` 每 3s 一拍重读,同一行每拍计一次(量值 = 行 × 拍数,在场才是信号)。",
170
+ },
163
171
  "server.approvals.queue-row-gate-kind-missing": {
164
172
  cls: "F",
165
173
  note: "S-1681(`plugins/checkpoint-store-sql.ts` 的 `queueRowGateKind`,7.132.0;SQL 与 local 两只孪生的 `listPending` 同调这一只判官):运维待批队列(`GET /v1/approvals` / `/stream`)读到一行 pending 的门型(SQL 孪生:`checkpoint.gate_kind` 列;local 孪生:快照上的门)是 NULL 或不是 core 登记的门型 ⇒ 这一行**不列**。按构造不可达:每次停驻都把门型反范式进这一列,一次性迁移 M21 把没有它的存量行从门子树补齐(读不出登记门型的置 expired)。放行(不列、队列其余照常)的最坏后果 = 一行谁也决不了的行不出现在队列上 —— 它本来就不可决:每一条决断口按门型绑定取行(`gate_kind IN (…)`),证不出门型就不当它是这道门;不放行(整只拒)的代价是一行坏行打掉整个租户的队列(列表 500、SSE 心跳照常而队列永远停在旧帧)。也不按缺键投出去:消费方按 `gateKind` 路由、缺键即 fail-closed,队列行的契约是 `gateKind` 恒在场。故 F 类;计数非零 = 写腿或手改出了错,`SELECT session_id FROM checkpoint WHERE status = 'pending' AND gate_kind IS NULL` 查那一行(置 expired 或删会话)。",
@@ -268,9 +276,9 @@ export const FAIL_OPEN_TAGS = {
268
276
  cls: "P-DEBT",
269
277
  note: "#296(A-052.2,clay 裁定 C-R21):`REMOTE_EXEC=ssh` 且**两只主机密钥旋钮都缺席**(`SSH_HOST_FINGERPRINT` / `SSH_KNOWN_HOSTS`)⇒ 本次连接接受**任何**主机密钥,等价 `ssh -o StrictHostKeyChecking=no`。放行的最坏后果:一次中间人拿到这条会话的**全部命令、全部产物、以及 agent 在那台机器上的全部动作**(私钥仍在控制面手里、拿不走,design/61 §5 #2)。⇒ 保护型欠账,不是体验回退。**方向是裁定的、不是遗漏**:本 lane 的既有部署形是「AI 编排批量部署到一批 SSH 可达的机器」,那些机器的指纹通常不在任何 known_hosts 里,默认拒连 = 一次静默的可用性断裂;C-R21 裁「在场即严格,缺席即响亮」。补偿三件:①**每连接**一条 `ssh_host_key_unverified` warn(不是每进程一次 —— 一条长期裸连的 lane 必须在每条连接上都看得见);②本计数(遥测里「有多少条连接是裸连」是一个可观测的数,曲线应当只降不升);③两旋钮任一在场即**严格校验、不符拒连**(拒因带两半指纹 + `ssh-keyscan` 指路)。终局 = 部署把旋钮配上(那时本计数归零);旋钮不配而想收紧的部署级开关(「无旋钮即拒启」)是下一件,不在 C-R21 射程。",
270
278
  },
271
- "server.approval.park-tombstone-global-cap-refused": {
279
+ "server.approval.park-redemption-cap-refused": {
272
280
  cls: "F",
273
- note: "#343(黑板 [5100] Q3):park 墓碑表(#329 迟到回决的 wire approvalId → 店内坐标指路条)**全局帽已满、而本 principal 还没到自己的 per-principal 子帽** ⇒ 这条新墓碑**不落**(拒新,一格都不挤别人)。放行的最坏后果 = 这一只 ask 的 **live 腿指路便利**缺席,壳按 Yes 拿到的是 404 `unknown_or_other_replica` —— 也就是 #329 之前的那一格逐字行为,既不会错兑也不会双兑;**完整兑付面一个字节没动**(park 行本体在 durable 店未失,`GET /v1/approvals` 列表 + `/v1/approvals/:sessionId/decide` 仍可回决),故 F 类而不是保护型。为什么方向是「拒新」而不是修前的「FIFO 挤最旧」:那个形让**甲的用量决定乙的可用性**(已鉴权租户量产 park 终局 ask 即可把别家墓碑全部挤出,merge-rescan 744 confirmed),而 park 是常态路由、不需要任何异常手法。必须留痕:「表被别人打满」与「这张卡本来就没有墓碑」在 wire 上完全同形,不计数则运维只能靠「用户说按 Yes 老是 404」这种间接症状发现,而那正是 [4845] 排障代价实证过的那条路。detail 带 owner(判「压力来自谁」的第一手线索)。本 tag 有**两条臂、两个根因**,detail 判别:(a) 全局帽满且本 principal 未超子帽 ⇒ 拒新(detail 带 owner);(b) 本 principal 超子帽但名下条目**全在飞**、无一可逐 ⇒ 拒新(detail 带 `reason=all-inflight`)。超子帽且**有**可逐条目的常态臂逐自己最旧的一条(量产者自伤,设计内有界表纪律)才不走本 tag。",
281
+ note: "#329 / #343(黑板 [5100] Q3):停驻行迟到决议的**受理回执表**(本副本对「200 丢包后重试」的幂等承诺 + 重叠请求的单飞句柄;键 = 行的键 askId,只在一次赎回真开飞时开格;容量帽只数受理之后留下的回执,在飞的单飞句柄永不被逐)**拒留一张回执**。放行的最坏后果 = 这**一次**受理(照旧生效)没有本副本的回执可依:200 丢包后的重试会再进一次赎回腿、拿到那条腿的 409(那张 checkpoint 已被消费)而不是幂等 200 回放(终局恒由赎回腿的 gate CAS 定,不会错兑也不会双兑);迟到受理本身、`GET /v1/approvals` 列表与 `/v1/approvals/:sessionId/decide` 一个字节不动 ⇒ F 类。为什么方向是「拒新」而不是 FIFO 挤最旧:那个形让**甲的用量决定乙的可用性**(已鉴权租户量产受理即可把别家回执挤出,merge-rescan 744 confirmed 的同一病形)。必须留痕:「表被别人打满」与「这一次本来就没有回执」在 wire 上同形。detail 带 owner(判「压力来自谁」的第一手线索)。臂只有一条:全局回执帽满、本 principal 未到子帽、表里没有过期回执可收 ⇒ 拒留(detail 带 owner)。本 principal 到了子帽的常态臂逐自己最旧的一张回执(量产者自伤,设计内有界表纪律),不走本 tag;在飞的单飞句柄不占帽、永不被逐。",
274
282
  },
275
283
  "server.approvals.stale-echoed-token-unreadable": {
276
284
  cls: "F",
@@ -306,7 +314,7 @@ export const FAIL_OPEN_TAGS = {
306
314
  },
307
315
  "server.run-terminal.redact-threw": {
308
316
  cls: "F",
309
- note: "三个发射座(errorMessage 终态文案 / 诊断文本 diag / 工件 artifact,probe 前缀判别;普查 56 行;补丁头 patch-head 那座随 7.83.0 / S-113 的 redactPatchHead 一并退役):S-105 最终轮 [medium]:终态 errorMessage/blockedReason/remoteEnvFailures[].message 脱敏抛出(RangeError:关键字/前缀臂那一形由 S-219 的 atLeast 铸点闭掉;JSON 秘密字段臂的转义对循环与 PEM 栅栏臂的标签交替循环由 S-265 换成手写线性扫描器闭掉 —— 已知形全部闭掉,本臂留作结构性兜底,计数恒零是证据、不归零即新形)⇒ 落固定占位 «redacted:oversized»——绝不落原文(安全轴 fail-closed),也绝不阻断终态翻转与 claim 释放(可用性)。方向刻意:一条超大错误体不得把 run 卡在 running。",
317
+ note: "三个发射座(errorMessage 终态文案 / 诊断文本 diag / 工件 artifact,probe 前缀判别;普查 56 行;补丁头 patch-head 那座随 7.83.0 / S-113 的 redactPatchHead 一并退役)+ 出口座(S-485 / RH-1:`trace/exit-seat.ts` 的 `seatText`,probe 前缀 `seat=<座表行>`;trace 帧自由文本位上抛 ⇒ 这一位换同一枚占位、投影不抛):S-105 最终轮 [medium]:终态 errorMessage/blockedReason/remoteEnvFailures[].message 脱敏抛出(RangeError:关键字/前缀臂那一形由 S-219 的 atLeast 铸点闭掉;JSON 秘密字段臂的转义对循环与 PEM 栅栏臂的标签交替循环由 S-265 换成手写线性扫描器闭掉 —— 已知形全部闭掉,本臂留作结构性兜底,计数恒零是证据、不归零即新形)⇒ 落固定占位 «redacted:oversized»——绝不落原文(安全轴 fail-closed),也绝不阻断终态翻转与 claim 释放(可用性)。方向刻意:一条超大错误体不得把 run 卡在 running。",
310
318
  },
311
319
  "server.run-terminal.provider-echo-shaped": {
312
320
  cls: "F",
@@ -351,6 +359,10 @@ export const FAIL_OPEN_TAGS = {
351
359
  cls: "F",
352
360
  note: "S-582(`plugins/send-file-ledger.ts`,local 车道的发文件账本):一条账行读不出形(`42` / 缺 id·scope·objectKey 三元组 / 中间半截 JSON)⇒ 跳过它继续。最坏后果 = 那条已签发的链接在它租户的列表里**看不见**(对象本身没动;账本本来就不存 URL)。治理面少一行是可见性损失,不是放行 ⇒ F;但它恰是治理面要看的那一类事实,所以必须留痕 —— 修前零披露。",
353
361
  },
362
+ "server.approval-ask-audit.rotate-dir-fsync-failed": {
363
+ cls: "F",
364
+ note: "S-322(`approval-ask-audit-store.ts` `rotateOlderThan`,审批账本留存律的审计账半场):轮转把留下的行原字节写进暂存文件(core `writeThenLink`:数据已 fsync)并 `rename` 盖上之后,目录 fsync 失败。换文件**已经落定且可见**、内存索引与 `crashConverged` 读面已经跟上,所以不回滚(也回滚不了)、读数照交。放行的最坏后果:掉电后目录项可能还指旧账本 ⇒ 删掉的行回来(下一拍再删,无害),轮转之后追加、在下一次目录落盘之前掉电的行可能丢(与 `append-failed` 同类后果:痕迹缺几条,审批结算不受影响)。与 core 原子写对目录 fsync 的尽力而为同一姿态(core 吞掉),这里改为留痕。审计店不开门、不改任何审批结算 ⇒ F。",
365
+ },
354
366
  "server.approval-ask-audit.corrupt-record-skipped": {
355
367
  cls: "F",
356
368
  note: "S-967(`approval-ask-audit-store.ts`,local 车道 File ask 审计店的 boot 重放;登记名 `approval-ask-audit`):账本**中间**一行读不出形(`42` / 数组 / 缺键 / 词表外 `kind`·`outcome`·`orphanState` / 半截 JSON;撕尾不走本 tag)⇒ 跳过它继续。最坏后果按行种:丢 `ask` ⇒ 那只孤儿在崩溃收敛读面缺席(无身份可列);丢 `settle` ⇒ 该组按 pending 臂收(审批门在执行之前 ⇒ 若这条 settle 其实是 `allowed` 且工具已执行,`resumeSafe:true` 是错的 —— 与头注「双故障窗」同族);丢 `leg_closed` ⇒ decided 臂多收一行(保守方向);丢 `crash_converged` ⇒ 下一次 boot 重收(幂等);丢 `interrupted_by_shutdown` / `late_settle` ⇒ 成因注退回 `crashed_before_park` / 少一行取证。审计店不开门、不改任何审批结算 ⇒ F。修前:重放坏行只计入 `convergeCrashedAsks().corruptLines`(boot 日志一个数),**无逐条披露、无 tag**。",
@@ -461,7 +473,21 @@ export const FAIL_OPEN_TAGS = {
461
473
  },
462
474
  "server.sql.packet-cap-unread": {
463
475
  cls: "F",
464
- note: "MySQL 协议连接初始化读不出语句级包墙(`plugins/sql-driver.ts` `readMaxAllowedPacket`,InnoDB 与 TiDB 同一处初始化;detail = `assumed=<字节> engine=<tidb|innodb> <读不出的原因>`):会话变量 `@@max_allowed_packet` 不认识 / 读它的查询失败 / 读到的不是正整数 ⇒ 按该服务器族的文档缺省当本库的包墙(`SqlEngineFacts.maxPacketBytes`;tidb 67108864,innodb 取 MariaDB 与 MySQL 8 两个缺省里小的 16777216),SQL 快照 blob 的缺省帽据它扣语句余量(1 KiB)再折半(文本协议 2× 膨胀)后与单行墙取小。每条池连接初始化各记一次。放行的最坏后果:库的真包墙比落点小(DBA 调小而没读到)⇒ 缺省帽放进了装不进一条语句的 blob,库在写的那一刻以 `ER_NET_PACKET_TOO_LARGE` 拒,快照 blob 写走各自既有的失败面(店的 never-throw 结果形折成 502);比落点大(调大而没读到)⇒ 缺省帽多拒(413 `blob_too_large_for_sql`,出路 = 显式旋钮 `SNAPSHOT_BLOB_SQL_MAX_BYTES` 或配对象存储)。不是门、不是凭据、不改任何裁决;计数非零 = 去看库账号能不能读 `@@max_allowed_packet`(普通账号都读得到,读不出多半是代理 / 中间件拦了这句)。",
476
+ note: "MySQL 协议连接初始化读不出语句级包墙(`plugins/sql-driver.ts` `readMaxAllowedPacket`,InnoDB 与 TiDB 同一处初始化;detail = `assumed=<字节> engine=<tidb|innodb> <读不出的原因>`):会话变量 `@@max_allowed_packet` 不认识 / 读它的查询失败 / 读到的不是正整数 ⇒ 按该服务器族的文档缺省当**这条连接**的包墙(`SqlEngineFacts.maxPacketBytes`,随连接保存;tidb 67108864,innodb 取 MariaDB 与 MySQL 8 两个缺省里小的 16777216),在这条连接上写的 SQL 快照 blob 的缺省帽据它扣语句余量(1 KiB)再折半(文本协议 2× 膨胀)后与单行墙取小。每条池连接初始化各记一次。放行的最坏后果:库的真包墙比落点小(DBA 调小而没读到)⇒ 缺省帽放进了装不进一条语句的 blob,库在写的那一刻以 `ER_NET_PACKET_TOO_LARGE` 拒,快照 blob 写走各自既有的失败面(店的 never-throw 结果形折成 502);比落点大(调大而没读到)⇒ 缺省帽多拒(413 `blob_too_large_for_sql`,出路 = 显式旋钮 `SNAPSHOT_BLOB_SQL_MAX_BYTES` 或配对象存储)。不是门、不是凭据、不改任何裁决;计数非零 = 去看库账号能不能读 `@@max_allowed_packet`(普通账号都读得到,读不出多半是代理 / 中间件拦了这句)。",
477
+ },
478
+ "server.sql.packet-wall-log-unwritten": {
479
+ cls: "F",
480
+ note: "包墙连接自愈的运维日志写不出(`plugins/sql-driver.ts` `warnPacketWall`,blob 判官借出口 `connectJudged` 的两行日志共用这一只出口:旧连接被换掉的 `sql_connection_packet_wall_stale`、全局包墙查询失败的 `sql_connection_packet_wall_global_unread`;detail = `event=<事件名> err=<日志汇抛出的错误类名>`):logger 抛(日志汇坏了 / 传输断了)⇒ 那一行没写出去,判决与连接处置不动 —— 旧连接已销毁在先、写照常重判,拒照旧是 413。放行的最坏后果 = 运维少看到一行诊断:一条过时连接被换掉、或全局包墙读不出这件事没有日志痕迹(判决本身不变,413 的帽照样由那条连接的包墙折算)。不放行的代价是把一次本该是 413(或照常重判后成功)的写变成日志汇故障的 500,并且若销毁在日志之后还会漏连接。故 F 类;登记口不经那只坏掉的 logger(计数 + stderr 契约行 + 探针),所以「日志丢了」本身仍可见。计数非零 = 去看这台副本的日志汇(stdout/stderr 传输)为什么抛。",
481
+ },
482
+ "server.config-dir-trust.kubelet-volume-node-side-unverifiable": {
483
+ cls: "R",
484
+ ruling: "C-R658",
485
+ bound: "残余写者只有节点特权方(节点 root、GID 0 的进程、被授予该 kubelet 卷目录读写 hostPath 的另一只 pod):它们的权限都由节点管理方授予,本 pod 内取不到,也看不见",
486
+ note: "本地配置源 `config.d` 读之前的目录信任判官(`config-dir-trust.ts` `projectedVolumeRoot`)认了一只 kubelet ConfigMap 卷的卷根(卷根 0777 是 kubelet 包卷的磁盘 emptyDir 的模式):卷根下只有原子写者的链接农场、走路径看见的那一只挂载恰挂在这里且只读、来源(mountinfo 第 4 格)是 kubelet configMap 卷目录的整形,且来源在本进程挂载命名空间里没有可写露出(同一文件系统的可写挂载把来源映射到的路径、走那条路径看见的正是那只挂载 —— 有一处即拒 `exposed`,走不到这里;容器里通常一条都没有)。判不了的两半:来源在节点那一侧的祖先目录(kubelet 的数据目录)不在本命名空间里,本进程看不见它们的属主与模式 —— 认它靠的是「kubelet 把数据目录建成 root:root 0750,本 pod 看不见的写者都是节点管理方授予了权限的节点特权方」这一节点侧事实;另一个超级块转出同一批字节的露出(overlay 的 lower / upper 层、FUSE、网络盘)也不在视野里,同记本标签(在本命名空间建这种挂载要 root)。每次认(起服一次 + 每拍一次)记一次。归 R:方向 = 认(不拒启),上界(结构式)= 残余写者只有节点特权方(节点 root、GID 0 的进程、被授予该 kubelet 卷目录读写 hostPath 的另一只 pod):它们的权限都由节点管理方授予,本 pod 内取不到,也看不见。放行的最坏后果 = 这一类残余写者(节点特权方)在判与读之间换掉 `..data`,让本服务读到它写的 `mcp.json`、以本服务的身份起其中的命令 —— 这类写者的权限不是 pod 内的进程自己取得到的,要节点管理方先授予。照拒会让每个以 ConfigMap 卷挂配置的 k8s 部署升级即拒启(出路只剩 `subPath` 逐文件挂)。计数长期保留(它数的是有界放行实际发生了多少次,不期望归零),非零 = 这台部署以 ConfigMap 卷挂配置。detail = `volume=<卷根物理路径> source=<来源路径>`。",
487
+ },
488
+ "server.config-dir-trust.win32-owner-mode-unverifiable": {
489
+ cls: "P-DEBT",
490
+ note: "S-163(`config-dir-trust.ts` `judgeWin32`,本地配置源 `config.d` 读之前的目录信任判官在 win32 上的那一半):Node 在 win32 上 `uid` 恒 0、模式位是只读属性的投影 ⇒ 「属主 ∈ {本服务用户, root, CONFIG_LOCAL_OWNER_UID}」与「不得组 / 他人可写」两判不可做;结构判(常规文件 / 16 MiB 上界 / 链接成环)照做。每一次读照常进行(起服一次 + 每拍一次)记一次。放行的最坏后果 = 一台多用户 Windows 机器上,别的本机用户若能写这台服务的 `config.d`(缺省的用户目录 ACL 不允许),改一份 `mcp.json` 就能让本服务以它的身份起命令 —— 与 7.132.x 逐字同。照 POSIX 拒启会让每个 Windows 本机引擎(含 cli 起的)升级即起不来,而让 cli 替用户设豁免键是中间层替部署者设安全旋钮。收口 = 有了 ACL 判据或一次裁定(改 R 或改拒启)那一版,本 tag 删或改类。detail = `config.d=<物理路径>`。",
465
491
  },
466
492
  };
467
493
  export function failOpenTagForDroppedFrame(frameType) {
@@ -236,6 +236,7 @@ export function createMetrics() {
236
236
  m.counter("limit_ceiling_after_answer_total", "Runs where a walltime/turns ceiling fired AFTER the run had already answered (engine 7.13.0: these end completed with NO limits.* code). Dual of budget_exceeded_total, but NOT over the same population: this one is minted on the deps-level notice sink so it sees EVERY engine run (background children, delegated/nested legs, leader lanes); budget_exceeded_total is incremented only by the HTTP submit legs finalizeTaskResult, i.e. top-level HTTP-submitted runs. Sum them only within that narrower population; see the forwarder comment, by origin");
237
237
  m.counter("cost_quota_rejected_total", "Tasks refused because the principal is over its cumulative cost quota");
238
238
  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)");
239
+ 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)");
239
240
  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)");
240
241
  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)");
241
242
  m.counter("degraded_total", "Tasks degraded to a cheaper model (1.40), by reason (budget/rate_limit/breaker_open)");
@@ -1,4 +1,5 @@
1
1
  import type { TraceEvent } from "@sema-agent/core";
2
+ import { WIRE_PROJECTION_FACES } from "../trace/wire-projection-faces.js";
2
3
  /**
3
4
  * 引擎的清单帧 `prompt.assembled`(引擎 7.52.0 起 `version: 3`):这条腿的提示**是哪一份**(`identity` + 它的选择器值 `selectors`)、
4
5
  * 由哪些块与段组成、每一段的文本从哪里来(`chain`,被取代的 overlay 另在 `superseded`)。只有 id / 尺寸 / 摘要,没有提示正文。
@@ -7,7 +8,7 @@ export type PromptAssembledEvent = Extract<TraceEvent, {
7
8
  kind: "prompt.assembled";
8
9
  }>;
9
10
  /** 帧上**不上行**的键。唯一一簿在 `trace/wire-projection-faces.ts` 的 `prompt_manifest` 行(逐键理由在那里);这里只做类型查询。 */
10
- type NotOnTheRow = (typeof import("../trace/wire-projection-faces.js").WIRE_PROJECTION_FACES)["prompt_manifest"]["excluded"][number];
11
+ type NotOnTheRow = (typeof WIRE_PROJECTION_FACES)["prompt_manifest"]["excluded"][number];
11
12
  /** 引擎的型,**词读成开集串**:投影判形,不判词表(档名、激活方式、来源类、渲染器……每一张词表的属主都是引擎,新词原样过境)。 */
12
13
  type OpenWords<T> = T extends string ? string : T extends readonly (infer U)[] ? OpenWords<U>[] : T extends object ? {
13
14
  [K in keyof T]: OpenWords<T[K]>;
@@ -23,24 +24,9 @@ export type PromptManifestRecord = {
23
24
  export type PromptManifestInput = {
24
25
  readonly [K in keyof PromptAssembledEvent]?: unknown;
25
26
  };
26
- /** 读一个值:读得出 ⇒ 值;读不出 ⇒ `undefined`;可选成员缺席 ⇒ {@link ABSENT}(不铸、不计)。 */
27
- type Read<V> = (v: unknown) => V | undefined;
28
- declare const ABSENT: unique symbol;
29
- /** 可选格的记号:只有 {@link optional} 铸得出带它的读器 —— 一只裸读器的回值型是可选格回值型的子型,单靠回值型拦不住它。 */
30
- declare const OPTIONAL_CELL: unique symbol;
31
- type OptionalRead<V> = Read<V | typeof ABSENT> & {
32
- readonly [OPTIONAL_CELL]: true;
33
- };
34
- /**
35
- * 每张读表按引擎型的**每一个键**写一格(`-?`:可选键也必须有格,引擎给哪一层加成员 ⇒ 这里编译红);可选键的格必须经 {@link optional} —— 格型要求
36
- * {@link OPTIONAL_CELL} 记号,裸读器写进可选键 ⇒ 编译红(否则缺席的成员被裸读器读成「读不出」,整句被丢)。
37
- */
38
- export type ReadTable<T> = {
39
- [K in keyof T]-?: undefined extends T[K] ? OptionalRead<Exclude<T[K], undefined>> : Read<T[K]>;
40
- };
41
27
  /**
42
28
  * 把一帧 `prompt.assembled` 读成耐久行(记录时白名单:tracer 同步、无 IO,未来的引擎键不随帧上行)。
43
- * 规则一句:**只挑引擎型里有的键,逐层判形;在场却读不出 ⇒ 计一次 `server.trace.projection-input-malformed` 并丢;缺席从不计数**。
29
+ * 规则一句:**只挑登记表声明的键,逐层判形;在场却读不出 ⇒ 计一次 `server.trace.projection-input-malformed` 并丢;缺席从不计数**。
44
30
  * 词原样过境(不判词表);`identity` 是这条腿的提示身份的唯一读法 —— 本仓不另铸第二种(v2 的 `constitution` 随引擎退役)。
45
31
  */
46
32
  export declare function promptManifestRecordOf(e: PromptManifestInput): PromptManifestRecord;
@@ -67,12 +53,23 @@ export declare function configAssembledRecordOf(e: {
67
53
  overrideReasons?: unknown;
68
54
  ts?: unknown;
69
55
  }): Record<string, unknown> | undefined;
56
+ /**
57
+ * 一条 run 级的**伴随记录**:trace 帧在白名单读法之后要落成的那一行耐久事件(与清单行同生命周期:register 同门、drain 同拍、lease clear 同清)。
58
+ * 种类是一张闭表 —— 帧与账本行一一对应,加一种伴随记录 = 加一个词(`ledger-events.ts` 的账本行名闭集同批加),不另开一对 record / drain。
59
+ * · `config_assembled` —— [ref]③ `config.assembled` 帧(生效配置逐字段来源);
60
+ * · `cross_boundary_taint` —— core 7.54.0 [ref] O9b S1 `permission.cross_boundary_taint` 帧(设备车道发射闸:树的污染位与 governed;
61
+ * 只在执行于目标设备的树上发,宿主车道零帧;投影器 `trace/project.ts` `crossBoundaryTaintEventData`)。
62
+ */
63
+ export type RunCompanionRecordType = "config_assembled" | "cross_boundary_taint";
64
+ export interface RunCompanionRecord {
65
+ readonly type: RunCompanionRecordType;
66
+ readonly data: Record<string, unknown>;
67
+ }
70
68
  export declare class PromptManifestTracker {
71
69
  private readonly byTask;
72
- /** [ref]③:config.assembled 的同生命周期伴随记录(register 同门、drainConfig 同拍)。队列形
73
- * (codex F2):cascade 每 rung 独立解析配置,后到覆盖会把先前已计费 rung 的生效配置抹掉——与
74
- * prompt manifests 同姿势逐条保序。 */
75
- private readonly configByTask;
70
+ /** 伴随记录({@link RunCompanionRecord}):清单之外、与清单同生命周期的 run 级耐久行。**一只**按发射序的队列(codex F2 当年给 config 一族立的保序律 ——
71
+ * cascade 每 rung 各自成帧,后到覆盖会抹掉先前 rung 的那一份 —— 对每一种伴随记录同样成立,所以是一只队列,不是每种一只)。 */
72
+ private readonly companionsByTask;
76
73
  private readonly active;
77
74
  private leaseCounter;
78
75
  /** Mark a TOP-LEVEL run active (same fence as `ModelUsageTracker.register`, budget.ts). Returns this leg's
@@ -80,10 +77,10 @@ export declare class PromptManifestTracker {
80
77
  register(taskId: string): number;
81
78
  /** Queue this prepare's manifest — ONLY for a registered top-level run (else a no-op). Sync, never throws. */
82
79
  record(taskId: string, m: PromptManifestRecord): void;
83
- /** [ref]③:队一条 config.assembled 投影(同 register 门;逐条保序——cascade 每 rung 各留其形)。 */
84
- recordConfig(taskId: string, rec: Record<string, unknown>): void;
85
- /** Return-and-clear ALL pending config records in emission order; `undefined` when none. */
86
- drainConfig(taskId: string): Array<Record<string, unknown>> | undefined;
80
+ /** 队一条伴随记录(同 register 门;按发射序保序)。Sync, never throws. */
81
+ recordCompanion(taskId: string, type: RunCompanionRecordType, data: Record<string, unknown>): void;
82
+ /** Return-and-clear ALL pending companion records in emission order; `undefined` when none. */
83
+ drainCompanions(taskId: string): RunCompanionRecord[] | undefined;
87
84
  /** Return-and-clear ALL pending manifests in emission order; `undefined` when none. */
88
85
  drain(taskId: string): PromptManifestRecord[] | undefined;
89
86
  /** Drop pending + unregister (run end / abandoned leg) — but ONLY while `lease` still owns the slot;
@@ -1,21 +1,21 @@
1
1
  import { dropProjectedFace } from "../trace/projection-drop.js";
2
+ import { WIRE_PROJECTION_FACES } from "../trace/wire-projection-faces.js";
2
3
  const ABSENT = Symbol("absent");
3
- const OPTIONAL_CELL = Symbol("optional-cell");
4
4
  const text = (v) => (typeof v === "string" ? v : undefined);
5
5
  const finite = (v) => (typeof v === "number" && Number.isFinite(v) ? v : undefined);
6
6
  const flag = (v) => (typeof v === "boolean" ? v : undefined);
7
7
  const onlyTrue = (v) => (v === true ? true : undefined);
8
8
  const plainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v) ? v : undefined;
9
9
  function optional(read) {
10
- return Object.assign((v) => (v === undefined ? ABSENT : read(v)), { [OPTIONAL_CELL]: true });
10
+ return (v) => (v === undefined ? ABSENT : read(v));
11
11
  }
12
- function objectOf(table) {
12
+ function objectOf(cells) {
13
13
  return (v) => {
14
14
  const o = plainObject(v);
15
15
  if (o === undefined)
16
16
  return undefined;
17
17
  const out = {};
18
- for (const [key, read] of Object.entries(table)) {
18
+ for (const [key, read] of cells) {
19
19
  const r = read(o[key]);
20
20
  if (r === undefined)
21
21
  return undefined;
@@ -72,46 +72,49 @@ function rowsOf(member, read) {
72
72
  return v.length > 0 && out.length === 0 ? ABSENT : out;
73
73
  };
74
74
  }
75
- const readIdentity = objectOf({
76
- artifact: text,
77
- layers: objectOf({ catalog: text, renderers: entriesOf(finite), center: optional(text), deploy: optional(text), task: optional(text), binding: text }),
78
- epoch: finite,
79
- activatedBy: text,
80
- });
81
- const readSelectors = objectOf({
82
- binding: optional(text),
83
- traits: listOf(text),
84
- host: objectOf({ role: text, form: text }),
85
- facts: entriesOf(flag),
86
- });
87
- const readSection = objectOf({
88
- id: text,
89
- band: text,
90
- rank: finite,
91
- variant: optional(text),
92
- renderer: optional(objectOf({ id: text, version: finite })),
93
- chars: finite,
94
- locale: text,
95
- contentHash: text,
96
- chain: listOf(objectOf({ source: text, overlay: optional(text), op: optional(text), superseded: optional(onlyTrue) })),
97
- });
98
- const ROW = {
99
- identity: readIdentity,
100
- selectors: readSelectors,
101
- blocks: rowsOf("blocks", objectOf({ id: text, chars: finite, hash: text })),
102
- sections: rowsOf("sections", readSection),
103
- superseded: rowsOf("superseded", objectOf({ id: text, source: text, by: text, target: text, supersededBy: text })),
104
- tools: rowsOf("tools", objectOf({ wireName: text, aliases: listOf(text), contractId: text, implementationRevision: text, cardId: text, shapeDigest: text, wireSchemaDigest: text })),
105
- toolDisclosure: objectOf({ deferredTools: finite, strategy: text, source: text }),
106
- totalChars: finite,
107
- };
75
+ const FACES = WIRE_PROJECTION_FACES;
76
+ function exhausted(shape) {
77
+ throw new Error("清单行声明里有不认得的值形:" + JSON.stringify(shape));
78
+ }
79
+ function readerOfShape(shape, member, building) {
80
+ switch (shape.is) {
81
+ case "text":
82
+ return text;
83
+ case "count":
84
+ return finite;
85
+ case "flag":
86
+ return flag;
87
+ case "true":
88
+ return onlyTrue;
89
+ case "object":
90
+ return objectOf(cellsOfFace(shape.face, building));
91
+ case "list":
92
+ return listOf(readerOfShape(shape.of, member, building));
93
+ case "rows":
94
+ return rowsOf(member, readerOfShape(shape.of, member, building));
95
+ case "entries":
96
+ return entriesOf(readerOfShape(shape.of, member, building));
97
+ default:
98
+ return exhausted(shape);
99
+ }
100
+ }
101
+ function cellsOfFace(face, building) {
102
+ if (building.includes(face))
103
+ throw new Error("清单行声明成环:" + [...building, face].join(" → "));
104
+ const keys = FACES[face]?.keys;
105
+ if (keys === undefined)
106
+ throw new Error("清单行声明引用了没有 keys 的面:" + face);
107
+ return Object.entries(keys).map(([key, declared]) => {
108
+ const read = readerOfShape(declared, key, [...building, face]);
109
+ return [key, declared.optional === true ? optional(read) : read];
110
+ });
111
+ }
112
+ const ROW = cellsOfFace("prompt_manifest", []);
108
113
  export function promptManifestRecordOf(e) {
114
+ const frame = e;
109
115
  const out = {};
110
- for (const [member, read] of Object.entries(ROW)) {
111
- const v = e[member];
112
- if (v === undefined)
113
- continue;
114
- const r = read(v);
116
+ for (const [member, read] of ROW) {
117
+ const r = read(frame[member]);
115
118
  if (r === undefined)
116
119
  drop(member, "does not read as the engine's type");
117
120
  else if (r !== ABSENT)
@@ -137,7 +140,7 @@ export function configAssembledRecordOf(e) {
137
140
  }
138
141
  export class PromptManifestTracker {
139
142
  byTask = new Map();
140
- configByTask = new Map();
143
+ companionsByTask = new Map();
141
144
  active = new Map();
142
145
  leaseCounter = 0;
143
146
  register(taskId) {
@@ -156,20 +159,21 @@ export class PromptManifestTracker {
156
159
  else
157
160
  this.byTask.set(taskId, [m]);
158
161
  }
159
- recordConfig(taskId, rec) {
162
+ recordCompanion(taskId, type, data) {
160
163
  if (!taskId || !this.active.has(taskId))
161
164
  return;
162
- const q = this.configByTask.get(taskId);
165
+ const q = this.companionsByTask.get(taskId);
166
+ const rec = { type, data };
163
167
  if (q)
164
168
  q.push(rec);
165
169
  else
166
- this.configByTask.set(taskId, [rec]);
170
+ this.companionsByTask.set(taskId, [rec]);
167
171
  }
168
- drainConfig(taskId) {
169
- const q = this.configByTask.get(taskId);
172
+ drainCompanions(taskId) {
173
+ const q = this.companionsByTask.get(taskId);
170
174
  if (!q || q.length === 0)
171
175
  return undefined;
172
- this.configByTask.delete(taskId);
176
+ this.companionsByTask.delete(taskId);
173
177
  return q;
174
178
  }
175
179
  drain(taskId) {
@@ -184,7 +188,7 @@ export class PromptManifestTracker {
184
188
  return;
185
189
  this.byTask.delete(taskId);
186
190
  this.active.delete(taskId);
187
- this.configByTask.delete(taskId);
191
+ this.companionsByTask.delete(taskId);
188
192
  }
189
193
  }
190
194
  //# sourceMappingURL=prompt-manifest.js.map
@@ -1,6 +1,7 @@
1
1
  import { isClassifierDenyCause, isDeniedBy } from "@sema-agent/core";
2
2
  import { observeClassic } from "../hooks/classic-stations.js";
3
- import { redactSecrets } from "../trace/redact.js";
3
+ import { seatText } from "../trace/exit-seat.js";
4
+ import { echoCallerText } from "../caller-text-echo.js";
4
5
  export const PERMISSION_DENIED_METER_REGISTRATION = "server.permission-denied-meter";
5
6
  export const TOOL_TRACE_REGISTRATION = "server.tool-trace";
6
7
  function deniedByLabel(gate) {
@@ -50,7 +51,7 @@ export function createToolTracer(logger) {
50
51
  isError: true,
51
52
  isInterrupt: e.failure.isInterrupt,
52
53
  ...(e.failure.durationMs !== undefined ? { durationMs: e.failure.durationMs } : {}),
53
- out: clip(redactSecrets(e.failure.error), 200),
54
+ out: seatText("operator-log-text", e.failure.error),
54
55
  });
55
56
  });
56
57
  observeClassic(on, "classic.PermissionDenied", (payload) => {
@@ -61,34 +62,32 @@ export function createToolTracer(logger) {
61
62
  deniedBy: deniedByLabel(payload.gate),
62
63
  ...(payload.gate.origin === undefined ? {} : { origin: payload.gate.origin }),
63
64
  ...(payload.gate.settlement === undefined ? {} : { settlement: payload.gate.settlement.kind }),
64
- reason: clip(redactSecrets(payload.reason), 200),
65
+ reason: seatText("operator-log-text", payload.reason),
65
66
  arg: summarize(payload.input),
66
67
  });
67
68
  });
68
69
  },
69
70
  };
70
71
  }
72
+ const TRACE_KEY_ECHO_CHARS = 120;
71
73
  function summarize(input) {
72
74
  if (!input || typeof input !== "object")
73
- return { v: clip(String(input), 120) };
75
+ return { v: seatText("operator-log-arg", String(input)) };
74
76
  const o = input;
75
77
  const s = {};
76
78
  for (const k of ["path", "file_path", "command", "cmd", "pattern", "glob", "old_string", "new_string"]) {
77
79
  if (typeof o[k] === "string")
78
- s[k] = clip(redactSecrets(o[k]), 120);
80
+ s[k] = seatText("operator-log-arg", o[k]);
79
81
  }
80
82
  if (typeof o.content === "string")
81
83
  s.contentLen = o.content.length;
82
- return Object.keys(s).length ? s : { keys: Object.keys(o) };
84
+ return Object.keys(s).length ? s : { keys: Object.keys(o).map((k) => echoCallerText(k, { maxChars: TRACE_KEY_ECHO_CHARS })) };
83
85
  }
84
86
  function textOf(content) {
85
87
  const text = content
86
88
  .map((c) => (c && typeof c === "object" && typeof c.text === "string" ? c.text : ""))
87
89
  .join("")
88
90
  .trim();
89
- return clip(redactSecrets(text), 200);
90
- }
91
- function clip(s, n) {
92
- return s.length > n ? `${s.slice(0, n)}…(${s.length})` : s;
91
+ return seatText("operator-log-text", text);
93
92
  }
94
93
  //# sourceMappingURL=tool-trace.js.map
@@ -66,6 +66,16 @@ export declare function operatorAsk(rule: string, message: string): OperatorAskR
66
66
  * 名单卡要带「本会话放行」,而强制卡上没有。「恒问人」两类盖出身 ⇒ core 读 `operator_forced`、盖 `mandated`,站着的答案在哪一层都退不掉它们。
67
67
  */
68
68
  export declare function operatorAlwaysHumanAsk(rule: string, message: string): OperatorAskResult;
69
+ /**
70
+ * 🔴 **S-1351 —— 请求写下的「恒问人」**(`settings.permissions.neverAuto`):在 {@link operatorAsk} 之上再盖 `requiresRealApproval: true`(core 的治理位 ——
71
+ * 「只有判断能清它」:空白的 `onAsk: "allow"`、任何站着的答案(持久规则、会话授权)、auto 分类器都清不掉,只有**这一次**的真人应答能答),不盖部署出身。
72
+ *
73
+ * 为什么不盖 `authoredBy: "deployment"`:出身位说的是「部署自己的治理层写的」,请求里的声明不是部署写的 —— 盖了就是在审计面冒名。`requiresRealApproval` 是 core 明文开给
74
+ * 策略自报的位(顶注:自报只会把**自己的** ask 退出自动裁决,方向是收紧、冒报安全),它把这一问推进「只有判断能清」的那一门(`ruleClearanceOf` 的治理门),
75
+ * 效果与部署的 `APPROVAL_NEVER_AUTO` 同级 —— 每个权限模式词下的仲裁读数逐位相同(`test/tighten-only-seats-assembly.test.ts` 逐词钉住)。
76
+ * 出处串(`rule` 写 `settings.permissions.neverAuto(<命中的名>)`,不写成 `APPROVAL_NEVER_AUTO(…)`)进 `matchedAskRule`:引擎闸内部消费、不上卡(同部署那一条),审计 / 单测读它区分来源。
77
+ */
78
+ export declare function requestAlwaysHumanAsk(rule: string, message: string): OperatorAskResult;
69
79
  /**
70
80
  * 🔴 **S-958 —— 治理层的叶策略包装**:`leaf` 产的每一只 ask 盖部署出身(经 {@link withDeploymentAuthorship}),allow / deny 原物交回;
71
81
  * 成员(`projection` / `pathRules` / `writeTargetGuard` / `nameSets`)经 core `wrapToolPolicy` 随行(契约「包装至少拒内层所拒」:
@@ -5,6 +5,9 @@ export function operatorAsk(rule, message) {
5
5
  export function operatorAlwaysHumanAsk(rule, message) {
6
6
  return withDeploymentAuthorship(operatorAsk(rule, message));
7
7
  }
8
+ export function requestAlwaysHumanAsk(rule, message) {
9
+ return { ...operatorAsk(rule, message), requiresRealApproval: true };
10
+ }
8
11
  function withDeploymentAuthorship(ask) {
9
12
  return { ...ask, authoredBy: "deployment" };
10
13
  }
@@ -15,11 +15,12 @@ export interface WorkflowAgentSessionRow {
15
15
  /**
16
16
  * 索引面的两个动词。**写者只有一个**(见文件头),读者是判别式。
17
17
  *
18
- * `syncRun` 语义 = 「这条 run 当前的指针集**就是** rows」:多出来的旧行删,rows 里的行 upsert。幂等、可重放、与 run 的一次成功写同拍。
19
- * `listByAgentSession` = 点名这个子会话的**全部**指针(各 run 一行;顺序不承重)。
18
+ * `ensurePointers` 语义 = 「rows 里的每一枚指针此后都在」:upsert,**从不删**(唯一的删除是 run 收割的级联)。幂等、可重放;写者在记录落盘
19
+ * **之前**调它(文件头「指针先于记录」)。
20
+ * `listByAgentSession` = 点名这个子会话的**全部**指针(各 run 一行;顺序不承重)—— 点名者的超集。
20
21
  */
21
22
  export interface WorkflowAgentSessionIndex {
22
- syncRun(runId: string, rows: readonly WorkflowAgentSessionRow[]): Promise<void>;
23
+ ensurePointers(runId: string, rows: readonly WorkflowAgentSessionRow[]): Promise<void>;
23
24
  listByAgentSession(sessionId: string): Promise<WorkflowAgentSessionRow[]>;
24
25
  }
25
26
  /**
@@ -50,8 +51,8 @@ export declare function readRunParks(run: unknown): WorkflowRunParkKey[] | undef
50
51
  export declare function heldParksOf(recordId: string, parks: readonly WorkflowRunParkKey[]): WorkflowRunParkKey[];
51
52
  /**
52
53
  * 派生的**唯一属主**:一只 `WorkflowRun` 的指针行 = 它 `parks[]` 里点名的每一个子会话(一个子会话一行)。`parks` 缺席 ⇒ 零条
53
- * ({@link readRunParks}:没有条目)⇒ 写者按「这条 run 的指针集就是这一份」清掉它已有的指针。
54
- * `parks[]` 读不出 ⇒ `undefined`(**派生不出来**,不是「零条」):写者据此不动这条 run 已有的指针(文件头「单写者」段)。
54
+ * ({@link readRunParks}:没有条目)⇒ 没有要写的指针。
55
+ * `parks[]` 读不出 ⇒ `undefined`(**派生不出来**,不是「零条」):写者据此不写指针(文件头「指针先于记录」段)。
55
56
  */
56
57
  export declare function buildParkSessionRows(runId: string, run: {
57
58
  scope: string;
@@ -99,9 +100,7 @@ export type WorkflowParkRoute = {
99
100
  * 🔴 **窗与删码**:规则 ③ 的 `older_engine` 读臂是一次性迁移 M9 的读侧半场(升级那一刻还停驻着的存量记录)。窗口与删码清单见 `plugins/one-time-migrations.ts` 登记表 M9 一行,随 M9 一起删;这里不写第二份窗。
100
101
  */
101
102
  export declare function routeWorkflowPark(sessionId: string, candidates: readonly WorkflowRun[]): WorkflowParkRoute;
102
- /** 两处(装饰器的变更检测、local 后端的重放)共用的行集等值判据 —— 顺序无关的集合比较,单一属主。 */
103
- export declare function sameAgentSessionRows(a: readonly WorkflowAgentSessionRow[], b: readonly WorkflowAgentSessionRow[]): boolean;
104
- /** 账本一行的**内域形**:一次 `syncRun` 的整份行集快照(`{runId, rows}`)。 */
103
+ /** 账本一行的**内域形**:一条 run 当时的整份指针快照(`{runId, rows}`;同一条 run 后写的一行整份覆盖先写的 —— 本仓只增不删,所以后一行恒是前一行的超集)。 */
105
104
  export interface WorkflowAgentSessionLedgerLine {
106
105
  runId: string;
107
106
  rows: WorkflowAgentSessionRow[];
@@ -112,7 +111,7 @@ export interface WorkflowAgentSessionLedgerLine {
112
111
  * 姿态与 SQL 孪生逐字同源:那边 `listByAgentSession` 逐字段收窄(`String(r.session_id)` …),这边逐字段
113
112
  * 判形 —— 一张索引面、两个后端、**一种**入域姿态。
114
113
  *
115
- * **整行成败制**(与既有的撕裂行臂同一条规则):一行 = 一次 syncRun 的**整份**快照,任一位读不出来就说明
114
+ * **整行成败制**(与既有的撕裂行臂同一条规则):一行 = 一条 run 的**整份**快照,任一位读不出来就说明
116
115
  * 这份快照重建不出来 ⇒ 整行不 apply(那条 run 保留上一份已知良好的快照)。不做「丢掉坏成员、留下好成员」
117
116
  * ——那会静默铸出一份**比真相少几条 park** 的行集,而这条索引的消费面正是 park 的赎回路由。
118
117
  * 读不出来 ⇒ 调用方**响亮**记一笔([ref]:安全轴不许静默),不吞整档。
@@ -125,7 +124,7 @@ export declare function readAgentSessionLedgerLine(v: unknown): WorkflowAgentSes
125
124
  * 逐字同形:0o700 目录 + 0o600 账本、按行重放),重启后 park 仍可 join;缺席 ⇒ 纯内存
126
125
  * (`WORKFLOW_RUN_STORE=memory` 的显式易失车道,与它的 run 店同寿命)。
127
126
  *
128
- * 账本的一行 = **一次 `syncRun` 的整份行集**(按 runId 后写覆盖),所以重放即收敛,不需要压缩腿。
127
+ * 账本的一行 = **一条 run 当时的整份指针集**(按 runId 后写覆盖;指针只增不删 ⇒ 后一行恒是前一行的超集),所以重放即收敛,不需要压缩腿。
129
128
  *
130
129
  * 追加 / 重放走本仓 JSONL 店的**共用口**(S-977;此前 ctor 里自写 `truncateTornTail` + 手写 `split("\n") + JSON.parse` 重放):
131
130
  * 追加 = core `AppendLog`(惰性打开、撕尾在**打开与每次追加前**修 —— 修前只在 boot 修,运行期半写后的下一次成功写仍会被粘进残尾),
@@ -141,9 +140,10 @@ export declare class LocalWorkflowAgentSessionIndex implements WorkflowAgentSess
141
140
  private readonly bySession;
142
141
  private log;
143
142
  constructor(root?: string, fsyncEnabled?: boolean);
144
- /** 内存两张表的收敛(重放与写路径共用一份逻辑):先摘这条 run 的旧指针,再挂新的。 */
143
+ /** 内存两张表的收敛(重放与写路径共用一份逻辑):这条 run 的指针集 = 这一行的整份快照。 */
145
144
  private apply;
146
- syncRun(runId: string, rows: readonly WorkflowAgentSessionRow[]): Promise<void>;
145
+ /** 只增不删:这条 run 已有的指针 ∪ 这几枚,写成一行整份快照(盘上一行仍是「这条 run 的指针集」,与早年的账本行同一种读法)。 */
146
+ ensurePointers(runId: string, rows: readonly WorkflowAgentSessionRow[]): Promise<void>;
147
147
  listByAgentSession(sessionId: string): Promise<WorkflowAgentSessionRow[]>;
148
148
  }
149
149
  //# sourceMappingURL=workflow-agent-session-index.d.ts.map
@@ -88,16 +88,6 @@ function highestHolders(sessionId, readable) {
88
88
  }
89
89
  return top;
90
90
  }
91
- export function sameAgentSessionRows(a, b) {
92
- if (a.length !== b.length)
93
- return false;
94
- const key = (r) => `${r.sessionId}\u0000${r.runId}\u0000${r.agentKey}\u0000${r.scope}`;
95
- const left = new Set(a.map(key));
96
- for (const r of b)
97
- if (!left.has(key(r)))
98
- return false;
99
- return true;
100
- }
101
91
  export function readAgentSessionLedgerLine(v) {
102
92
  if (typeof v !== "object" || v === null)
103
93
  return undefined;
@@ -173,12 +163,18 @@ export class LocalWorkflowAgentSessionIndex {
173
163
  runs.set(runId, r);
174
164
  }
175
165
  }
176
- async syncRun(runId, rows) {
166
+ async ensurePointers(runId, rows) {
167
+ const held = this.byRun.get(runId) ?? [];
168
+ const named = new Set(held.map((r) => r.sessionId));
169
+ const added = rows.filter((r) => !named.has(r.sessionId));
170
+ if (added.length === 0)
171
+ return;
172
+ const merged = [...held, ...added];
177
173
  if (this.ledgerPath !== undefined) {
178
174
  this.log ??= new AppendLog(this.ledgerPath);
179
- this.log.append({ runId, rows }, this.fsyncEnabled);
175
+ this.log.append({ runId, rows: merged }, this.fsyncEnabled);
180
176
  }
181
- this.apply(runId, rows);
177
+ this.apply(runId, merged);
182
178
  }
183
179
  async listByAgentSession(sessionId) {
184
180
  return [...(this.bySession.get(sessionId)?.values() ?? [])];