@sema-agent/server 7.140.0 → 7.142.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 (296) hide show
  1. package/MIGRATION.md +505 -0
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/USAGE.md +142 -25
  5. package/dist/approval-ask-audit-store.d.ts +54 -38
  6. package/dist/approval-ask-audit-store.js +58 -39
  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 +39 -24
  10. package/dist/approval-card.js +6 -3
  11. package/dist/approval-crash-convergence.d.ts +17 -7
  12. package/dist/approval-crash-convergence.js +94 -22
  13. package/dist/approval-deny-reasons.d.ts +34 -30
  14. package/dist/approval-deny-reasons.js +21 -6
  15. package/dist/approval-policy-settlement.d.ts +1 -1
  16. package/dist/approval-reconciler.d.ts +33 -1
  17. package/dist/approval-reconciler.js +43 -40
  18. package/dist/approval.d.ts +15 -0
  19. package/dist/approval.js +10 -0
  20. package/dist/audit.d.ts +4 -2
  21. package/dist/audit.js +2 -2
  22. package/dist/auth-bridge.d.ts +9 -6
  23. package/dist/auth-bridge.js +9 -3
  24. package/dist/boot/adoption.js +2 -1
  25. package/dist/boot/budget-tracing.d.ts +16 -0
  26. package/dist/boot/budget-tracing.js +10 -6
  27. package/dist/boot/device-lane.d.ts +11 -0
  28. package/dist/boot/device-lane.js +16 -0
  29. package/dist/boot/engine-lease.d.ts +24 -3
  30. package/dist/boot/engine-lease.js +9 -2
  31. package/dist/boot/execution-env.d.ts +24 -4
  32. package/dist/boot/execution-env.js +34 -27
  33. package/dist/boot/execution-lane.js +2 -1
  34. package/dist/boot/exit-boundary.js +5 -4
  35. package/dist/boot/memory-boundary.d.ts +2 -2
  36. package/dist/boot/memory-consolidation.d.ts +1 -1
  37. package/dist/boot/memory-consolidation.js +3 -2
  38. package/dist/boot/parked-revive-gate.js +2 -1
  39. package/dist/boot/permission-rules-audit.d.ts +0 -28
  40. package/dist/boot/permission-rules-audit.js +2 -1
  41. package/dist/boot/read-deny-anchor-audit.js +2 -1
  42. package/dist/boot/reapers.d.ts +2 -2
  43. package/dist/boot/reapers.js +4 -3
  44. package/dist/boot/resolve-spec.js +18 -6
  45. package/dist/boot/retention-lane.js +5 -3
  46. package/dist/boot/runner-deps.js +16 -13
  47. package/dist/boot/runtime-caps.js +3 -2
  48. package/dist/boot/session-faces.d.ts +1 -1
  49. package/dist/boot/session-faces.js +8 -6
  50. package/dist/boot/shutdown.js +8 -2
  51. package/dist/boot/stage-04-stores.js +3 -2
  52. package/dist/boot/stage-05-execution-env.d.ts +1 -1
  53. package/dist/boot/stage-05-execution-env.js +11 -7
  54. package/dist/boot/stage-06-runners.d.ts +1 -3
  55. package/dist/boot/stage-06-runners.js +3 -2
  56. package/dist/boot/stage-07-capability-layer.d.ts +1 -2
  57. package/dist/boot/stage-07-capability-layer.js +10 -11
  58. package/dist/boot/stage-08-reapers.d.ts +1 -2
  59. package/dist/boot/stage-08-reapers.js +3 -2
  60. package/dist/boot/stage-09-leader.d.ts +1 -2
  61. package/dist/boot/stage-10-http-server.d.ts +1 -2
  62. package/dist/boot/stage-10-http-server.js +6 -4
  63. package/dist/boot/stores.js +13 -6
  64. package/dist/boot/web-admin.js +18 -17
  65. package/dist/boot/webfetch-summarize-lane.js +2 -1
  66. package/dist/boot/workflow-orchestration.js +3 -2
  67. package/dist/capabilities/builtin-tools.d.ts +2 -1
  68. package/dist/capabilities/builtin-tools.js +2 -4
  69. package/dist/capabilities/composite-members.d.ts +2 -1
  70. package/dist/capabilities/composite-members.js +2 -1
  71. package/dist/capabilities/scenarios.d.ts +1 -1
  72. package/dist/capability-facts.d.ts +33 -0
  73. package/dist/capability-facts.js +32 -0
  74. package/dist/card-void.d.ts +38 -0
  75. package/dist/card-void.js +23 -0
  76. package/dist/config-catalog.js +12 -8
  77. package/dist/config-provider.d.ts +13 -13
  78. package/dist/config-provider.js +19 -33
  79. package/dist/config-types.d.ts +39 -10
  80. package/dist/config.d.ts +6 -0
  81. package/dist/config.js +72 -49
  82. package/dist/delegated-session-owner.d.ts +21 -19
  83. package/dist/delegated-session-owner.js +1 -1
  84. package/dist/device-store.d.ts +7 -0
  85. package/dist/device-store.js +3 -0
  86. package/dist/execution-config-root.d.ts +22 -0
  87. package/dist/execution-config-root.js +35 -0
  88. package/dist/execution-lane-caps.d.ts +50 -2
  89. package/dist/execution-lane-caps.js +90 -13
  90. package/dist/execution-placement.d.ts +3 -0
  91. package/dist/execution-placement.js +7 -0
  92. package/dist/fleet/drain-entry.d.ts +3 -0
  93. package/dist/fleet/fleet-bus.d.ts +6 -3
  94. package/dist/hooks/hook-runner.d.ts +6 -0
  95. package/dist/hooks/hook-runner.js +30 -1
  96. package/dist/hosted-posture.d.ts +8 -0
  97. package/dist/hosted-posture.js +4 -0
  98. package/dist/http/admission.js +3 -3
  99. package/dist/http/caller-trust.d.ts +3 -2
  100. package/dist/http/caller-trust.js +2 -1
  101. package/dist/http/dispatch.js +8 -2
  102. package/dist/http/execution-context.d.ts +2 -2
  103. package/dist/http/idempotency.d.ts +1 -1
  104. package/dist/http/live-frame.d.ts +24 -0
  105. package/dist/http/live-frame.js +16 -0
  106. package/dist/http/principal-gate.d.ts +3 -1
  107. package/dist/http/principal-gate.js +17 -8
  108. package/dist/http/resume-legs.js +42 -29
  109. package/dist/http/route-table.js +4 -0
  110. package/dist/http/routes/approvals-assistant.js +1 -0
  111. package/dist/http/routes/attachments.js +18 -0
  112. package/dist/http/routes/capabilities.js +10 -6
  113. package/dist/http/routes/diagnostics.d.ts +0 -19
  114. package/dist/http/routes/diagnostics.js +16 -2
  115. package/dist/http/routes/memory-bundle.d.ts +2 -2
  116. package/dist/http/routes/memory-bundle.js +1 -1
  117. package/dist/http/routes/memory-compliance.js +1 -1
  118. package/dist/http/routes/memory-policy.js +27 -7
  119. package/dist/http/routes/run-permission-mode.d.ts +75 -0
  120. package/dist/http/routes/run-permission-mode.js +170 -0
  121. package/dist/http/routes/runs.js +3 -3
  122. package/dist/http/routes/session-memory-sync.d.ts +63 -0
  123. package/dist/http/routes/session-memory-sync.js +157 -0
  124. package/dist/http/routes/session-sync.d.ts +3 -6
  125. package/dist/http/routes/session-sync.js +7 -2
  126. package/dist/http/routes/sessions-list.d.ts +2 -1
  127. package/dist/http/routes/sessions.js +5 -4
  128. package/dist/http/routes/tasks.js +70 -71
  129. package/dist/http/run-read-face.d.ts +7 -0
  130. package/dist/http/run-read-face.js +10 -4
  131. package/dist/http/send.d.ts +6 -1
  132. package/dist/http/send.js +10 -3
  133. package/dist/http/server.d.ts +20 -7
  134. package/dist/http/server.js +2 -4
  135. package/dist/http/sse-log.d.ts +3 -8
  136. package/dist/http/stored-body-replay.d.ts +3 -3
  137. package/dist/http/stored-body-replay.js +3 -1
  138. package/dist/http/submit-replay.d.ts +4 -3
  139. package/dist/http/submit-replay.js +2 -2
  140. package/dist/http/sync-submit-body.d.ts +21 -4
  141. package/dist/http/sync-submit-body.js +13 -0
  142. package/dist/identity-source.d.ts +21 -2
  143. package/dist/identity-source.js +6 -0
  144. package/dist/instruction-source-notice.d.ts +7 -0
  145. package/dist/instruction-source-notice.js +6 -6
  146. package/dist/mcp-assertion-header.d.ts +4 -0
  147. package/dist/mcp-assertion-header.js +5 -0
  148. package/dist/memory-incident-sink.d.ts +19 -6
  149. package/dist/memory-incident-sink.js +8 -4
  150. package/dist/memory-posture.d.ts +1 -1
  151. package/dist/memory-scope.d.ts +4 -4
  152. package/dist/memory-scope.js +1 -1
  153. package/dist/memory-sync-client.d.ts +35 -23
  154. package/dist/memory-sync-client.js +122 -52
  155. package/dist/memory-sync-identity.d.ts +24 -0
  156. package/dist/memory-sync-identity.js +57 -0
  157. package/dist/memory-sync.d.ts +7 -1
  158. package/dist/memory-sync.js +6 -3
  159. package/dist/observability/fail-open.d.ts +57 -12
  160. package/dist/observability/fail-open.js +50 -9
  161. package/dist/observability/metrics.js +0 -1
  162. package/dist/observability/run-terminal.d.ts +93 -31
  163. package/dist/observability/run-terminal.js +175 -171
  164. package/dist/observability/secret-env-scrub.d.ts +20 -1
  165. package/dist/observability/secret-env-scrub.js +14 -0
  166. package/dist/orchestration/workflow-completion-inbox.d.ts +5 -2
  167. package/dist/orchestration/workflow-completion-inbox.js +13 -5
  168. package/dist/orchestration/workflow-notify-journal.d.ts +5 -3
  169. package/dist/orchestration/workflow-notify-journal.js +2 -1
  170. package/dist/permission-mode-admission.d.ts +68 -0
  171. package/dist/permission-mode-admission.js +23 -0
  172. package/dist/permission-rule-list.d.ts +55 -6
  173. package/dist/permission-rule-list.js +52 -5
  174. package/dist/plugins/approval-ask-store-file.d.ts +14 -4
  175. package/dist/plugins/approval-ask-store-file.js +48 -7
  176. package/dist/plugins/approval-ask-store-memory.d.ts +2 -1
  177. package/dist/plugins/approval-ask-store-memory.js +9 -8
  178. package/dist/plugins/approval-ask-store-sql.d.ts +42 -10
  179. package/dist/plugins/approval-ask-store-sql.js +49 -19
  180. package/dist/plugins/caching-session-store.d.ts +6 -0
  181. package/dist/plugins/caching-session-store.js +3 -0
  182. package/dist/plugins/checkpoint-store-sql.d.ts +65 -17
  183. package/dist/plugins/checkpoint-store-sql.js +74 -3
  184. package/dist/plugins/device-store-sql.d.ts +5 -2
  185. package/dist/plugins/device-store-sql.js +4 -1
  186. package/dist/plugins/execution-placement-sql.d.ts +11 -1
  187. package/dist/plugins/execution-placement-sql.js +12 -1
  188. package/dist/plugins/file-run-store.d.ts +7 -2
  189. package/dist/plugins/file-run-store.js +12 -2
  190. package/dist/plugins/fork-routing-session-store.d.ts +10 -32
  191. package/dist/plugins/fork-routing-session-store.js +2 -61
  192. package/dist/plugins/k8s-exec-protocol.d.ts +4 -1
  193. package/dist/plugins/k8s-exec-protocol.js +6 -1
  194. package/dist/plugins/local-checkpoint-store.d.ts +10 -1
  195. package/dist/plugins/local-checkpoint-store.js +22 -0
  196. package/dist/plugins/local-session-store.d.ts +260 -39
  197. package/dist/plugins/local-session-store.js +582 -57
  198. package/dist/plugins/local-session-window.d.ts +17 -3
  199. package/dist/plugins/local-session-window.js +7 -13
  200. package/dist/plugins/local-task-attachment-store.d.ts +12 -2
  201. package/dist/plugins/local-task-attachment-store.js +67 -43
  202. package/dist/plugins/memory-key-guards.d.ts +3 -3
  203. package/dist/plugins/memory-run-store.d.ts +7 -2
  204. package/dist/plugins/memory-run-store.js +12 -2
  205. package/dist/plugins/one-time-migrations.d.ts +68 -2
  206. package/dist/plugins/one-time-migrations.js +120 -4
  207. package/dist/plugins/pg-pool.js +3 -2
  208. package/dist/plugins/pg-session-storage.d.ts +2 -0
  209. package/dist/plugins/pg-session-storage.js +3 -2
  210. package/dist/plugins/remote-env-e2b.d.ts +47 -7
  211. package/dist/plugins/remote-env-e2b.js +242 -46
  212. package/dist/plugins/remote-env-k8s.d.ts +51 -6
  213. package/dist/plugins/remote-env-k8s.js +234 -44
  214. package/dist/plugins/remote-env-local-docker.d.ts +40 -14
  215. package/dist/plugins/remote-env-local-docker.js +127 -33
  216. package/dist/plugins/run-store-sql.d.ts +11 -3
  217. package/dist/plugins/run-store-sql.js +13 -4
  218. package/dist/plugins/sandbox-read-floor.d.ts +273 -0
  219. package/dist/plugins/sandbox-read-floor.js +608 -0
  220. package/dist/plugins/session-ownership.d.ts +2 -1
  221. package/dist/plugins/session-placement.d.ts +17 -4
  222. package/dist/plugins/session-placement.js +2 -1
  223. package/dist/plugins/session-store.d.ts +18 -20
  224. package/dist/plugins/session-store.js +4 -12
  225. package/dist/plugins/store-backend.d.ts +41 -7
  226. package/dist/plugins/store-backend.js +22 -4
  227. package/dist/plugins/store-contracts.d.ts +35 -3
  228. package/dist/plugins/store-contracts.js +3 -0
  229. package/dist/plugins/task-attachment-store.d.ts +112 -14
  230. package/dist/plugins/task-attachment-store.js +221 -28
  231. package/dist/plugins/tidb-pool.js +2 -1
  232. package/dist/plugins/tidb-session-store.d.ts +4 -1
  233. package/dist/plugins/tidb-session-store.js +3 -2
  234. package/dist/plugins/workspace-fill.d.ts +60 -0
  235. package/dist/plugins/workspace-fill.js +106 -0
  236. package/dist/project-bundle.d.ts +38 -0
  237. package/dist/project-bundle.js +609 -0
  238. package/dist/run-cancel-context.d.ts +34 -0
  239. package/dist/run-cancel-context.js +7 -0
  240. package/dist/run-local.js +2 -8
  241. package/dist/runs.d.ts +39 -12
  242. package/dist/runs.js +69 -55
  243. package/dist/sandbox-egress-policy.d.ts +4 -1
  244. package/dist/sandbox-egress-policy.js +3 -1
  245. package/dist/sandbox-git-plane.d.ts +31 -12
  246. package/dist/sandbox-git-plane.js +24 -4
  247. package/dist/security.d.ts +11 -2
  248. package/dist/security.js +8 -0
  249. package/dist/server-secret-env.d.ts +2 -1
  250. package/dist/server-secret-env.js +2 -4
  251. package/dist/session-error-wire.d.ts +46 -4
  252. package/dist/session-error-wire.js +23 -0
  253. package/dist/session-incarnation.d.ts +9 -3
  254. package/dist/session-sync-kernel.d.ts +42 -1
  255. package/dist/session-sync-kernel.js +17 -0
  256. package/dist/session-sync.js +16 -4
  257. package/dist/sql-engine-coordinates.d.ts +49 -0
  258. package/dist/sql-engine-coordinates.js +27 -0
  259. package/dist/standing-answer-grant.d.ts +31 -2
  260. package/dist/standing-answer-grant.js +14 -2
  261. package/dist/store-posture.d.ts +1 -1
  262. package/dist/task-a2a.d.ts +1 -1
  263. package/dist/task-mcp.d.ts +1 -1
  264. package/dist/task-settings.d.ts +62 -27
  265. package/dist/task-settings.js +105 -29
  266. package/dist/terminal.d.ts +97 -20
  267. package/dist/terminal.js +107 -18
  268. package/dist/tool-approval.d.ts +4 -3
  269. package/dist/tool-approval.js +12 -14
  270. package/dist/trace/core-keyset-guard.d.ts +196 -2
  271. package/dist/trace/engine-notice-wire.d.ts +8 -2
  272. package/dist/trace/engine-notice-wire.js +4 -2
  273. package/dist/trace/exit-seat.d.ts +9 -1
  274. package/dist/trace/exit-seat.js +1 -0
  275. package/dist/trace/ledger-sink.d.ts +8 -4
  276. package/dist/trace/ledger-sink.js +2 -2
  277. package/dist/trace/model-segment.d.ts +2 -2
  278. package/dist/trace/project.d.ts +18 -1
  279. package/dist/trace/project.js +16 -0
  280. package/dist/trace/redact.js +323 -90
  281. package/dist/trace/self-minted-wire.d.ts +419 -4
  282. package/dist/trace/self-minted-wire.js +145 -0
  283. package/dist/trace/wire-projection-faces.d.ts +1 -1
  284. package/dist/trace/wire-projection-faces.js +1 -1
  285. package/dist/verifier-pause-card.d.ts +8 -0
  286. package/dist/verifier-pause-card.js +19 -0
  287. package/dist/web-admin-client/apply-effective.d.ts +5 -7
  288. package/dist/web-admin-client/apply-effective.js +22 -2
  289. package/dist/web-admin-client/candidate-gate.d.ts +1 -1
  290. package/dist/web-admin-client/effective-keys.js +2 -0
  291. package/dist/web-admin-client/read-warnings.d.ts +2 -2
  292. package/dist/web-admin-client/types.d.ts +4 -0
  293. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -2
  294. package/package.json +2 -2
  295. package/wire-changes/server@7.141.0.json +367 -0
  296. package/wire-changes/server@7.142.0.json +639 -0
@@ -1,4 +1,6 @@
1
- import { type PersistedTaskResult, type RunRecord } from "../plugins/store-contracts.js";
1
+ import type { CollapseUnder, ExitResult, SeatKeyPaths, TextLeafPaths } from "../trace/core-keyset-guard.js";
2
+ import { type PersistedResultSideKeys, type PersistedTaskResult, type RunRecord } from "../plugins/store-contracts.js";
3
+ import { type PauseSeat, type StoredResultReadSeat } from "../terminal.js";
2
4
  /** 一次终局写口交给观测面的原料(store 侧装配,**未脱敏** —— 脱敏在本模块内做,见 {@link notifyRunTerminal})。 */
3
5
  export interface RunTerminalRecord {
4
6
  /** 这条 run 的账本 id = `GET /v1/runs/:id` 的 id(本仓 run 行主键名为 taskId,同一个值)。 */
@@ -164,35 +166,87 @@ export declare function redactModelText(raw: string): string;
164
166
  /** 回声座上的值留不留:形内 ⇒ `true`(原样留);`undefined` / 空串 ⇒ `false`(缺席本身,不计数);其余越界 ⇒ `false` + 计数。
165
167
  * 调用方按 `false` 删键 / 不铸键 —— 本函数是全部回声座(结果面 / 账本孪生 / 子代通告 / side-query 200 体)的**唯一**判决口。 */
166
168
  export declare function admitProviderEcho(value: unknown, seat: string): value is string;
167
- /** {@link redactTerminalResult} 会碰的全部顶层键 = 现行形里**不是** `"verbatim"` 的行(`"redacted"` ∪ [ref] 的
168
- * `"provider-echo"`)∪ 旧形平面键;`memoRedactTerminalResult` 的记忆键由它派生(两处同源,见 `RESULT_KEY_TREATMENT` 顶注)。
169
- * 🔴 [ref] 起改名(原 `REDACTABLE_RESULT_LEAVES`):回声键不脱敏但**会被改**(越界 ⇒ 删键),漏进记忆键集 = 读面记忆腿对存量行
170
- * O(1) 原样直返,读面纵深对那几片恒不生效([ref] 立案时 `editedFiles` 那一格的同一个病)。 */
169
+ /**
170
+ * 🔴 **[ref]:一条结果上的文本叶一张座表** —— 结果汇点({@link redactTerminalResult})判「哪片叶要脱、怎么脱」的**唯一**一处。
171
+ *
172
+ * 键 = 一条结果上**每一片自由文本叶**的路径(装得下任意文字的串 / 模板串 / 品牌串 / `unknown`;点分;数组元素记 `[]`;索引签名记 `*`),值 = 闭集处置词。结果形 = 本仓结算点交给封口的三种出口结果
173
+ * (普通腿 `TaskResult` / verify 腿 `VerificationResult` / cascade 腿 `CascadeRunResult`,与停驻座门 ⑩f 同一组)∪ server 侧记键(`PersistedResultSideKeys`)。
174
+ * 键集**由类型派生**(`trace/core-keyset-guard.ts` ⑩g 的 `TextLeafPaths`),表的型就是派生键集上的映射 ⇒ core 在任何一种出口结果的任何一层加一片
175
+ * 自由文本叶(或把数字座 / 闭集词座放宽成串、加一个 `unknown` 座)⇒ 少一行 **TS2741**;表里留了 core 没有的残条目 ⇒ **TS2353**。数字 / 布尔 /
176
+ * 闭集字面量联合装不下文字,不进表(闭集词逐字过境是它的型担保的,不是一行表上的判断)。
177
+ *
178
+ * 存在理由(两次「按层记键」的病,第二次是本表的来历):
179
+ * · [ref] U2:读面记忆手抄过自己的叶集 ⇒ 收成「`TaskResult` 顶层键 × 处置」一张表(`RESULT_KEY_TREATMENT`,本表取代,零别名);
180
+ * · [ref]:那张表按 `keyof TaskResult` 记,组合腿结果的**超形**(verify 的 `verification`、cascade 的五键)不在键集里 ⇒
181
+ * `verification.findings[]` / `evidence`(验证器模型写的自由文本)、`attempts[].gateError` / `diagnostics`(门的异常文案 / 门附的理由)原样落 run 行 /
182
+ * 账本 done 行 / 同步 200 体,读面整只回放;而且表只到顶层,叶在哪一层由六只手写臂各自去够(`terminal.message` / `reason`、`remoteEnvFailures[]`、
183
+ * `editedFiles[].path`、`result` / `salvagedOutput`、`rewindNotes[]`),回声键另有一张实现表外加一段加载期对账。
184
+ * 现在:一张表 + 一只走表函数({@link applyResultTextLeaves}),写入口(店 / 账本)与读出口(同步体 / 读面)同调。
185
+ *
186
+ * **处置词(闭集,穷尽 `switch` 消费 —— 加词不加臂 = 编译红)**:
187
+ * · `"model-text"` —— 模型自由文本 / 模型可控字节 ⇒ {@link redactModelText}([ref]:与 CoT 同一只 `redactSecrets`、同一张替换串表;不设体量上限,抛则占位);
188
+ * · `"error-text"` —— 有界的披露散文(异常文案 / 引擎披露行)⇒ {@link redactErrorMessage};
189
+ * · `"provider-echo"` —— 服务商回声、引擎逐字转交的不透明 id ⇒ 只做形状校验({@link admitProviderEcho}:形内原样、越界删键 + 计数),不过脱敏器;
190
+ * · `"provider-join-key"` —— 出身 provider 的跨面 join 键(工具调用 id)⇒ 本面逐字(形状在 core brain 入口一次施加,见 {@link admitProviderEcho} 顶注);
191
+ * · `"verbatim"` —— 本栈内部铸造的 id / 部署配置 / 引擎观测面 ⇒ 不碰。**唯一的模型可控逐字座**是 `structuredOutput`(见该行注)。
192
+ * · `"outward-code"` —— 机器码座(因由的 `terminal.code`、cascade 每一级的 `attempts[].errorCode`:同一类码)⇒ 本汇点不碰 —— 折码的属主是出口封口
193
+ * (`terminal.ts` 的写封 / 读封,{@link sealResultForExit}):出了本服务码形的码在汇点之前已折成 `internal.store_error` 并留运维线索,汇点再折一次就是第二个属主。
194
+ * · 归属词 —— 该路径下是一棵**另有派生表**的子树,本表只登记属主,不在两张表里各判一次:`"stats-tree"`(stats 五表)/ `"terminal-detail"`(detail 三臂表)/
195
+ * `"api-failure"`({@link API_FAILURE_TREATMENT};结果面与账本子代通告面两张脸共用)/ `"stranded-answer"`({@link STRANDED_ANSWER_TREATMENT},逐行)。
196
+ * 属主表的型是 ⑩g 的 `OwnerTable`:每个成员只许盖得住它之下全部自由文本叶的词 ⇒ 子树里多一片叶而属主那一行盖不住(数字袋 `stats.nested` 里加一个串)
197
+ * 同样 tsc 红 —— 折叠只换了「在哪张表上红」,不留盲区。
198
+ * 停驻座的凭据与门(`PAUSE_SEATS` 的六条路径)**不在本表**:凭据归出口封口摘、门归 {@link redactCheckpointGate};键集从座表派生后减掉,不手抄。
199
+ *
200
+ * [ref] / [ref](7.75.1)那条规则在这里成文:**结果上的模型自由文本一律过脱敏器**,没有「别的 sink 自判」这条退路;留 `"verbatim"` 的是本栈铸的
201
+ * id / 目录 id / 部署配置(`structuredOutput` 一座除外,见行内注),逐叶理由见行内注。
202
+ */
203
+ export type TextLeafTreatment = "model-text" | "error-text" | "provider-echo" | "provider-join-key" | "verbatim" | "outward-code" | "stats-tree" | "terminal-detail" | "api-failure" | "stranded-answer";
204
+ /**
205
+ * 子树另有属主的路径前缀 —— 派生出的叶路径落在它之下就折成它本身(⑩g 的 `CollapseUnder`:按**路径**折,不按类型停 —— 结构类型的「停在某型」
206
+ * 会把恰好同形的别处子树一起吞掉)。前四只各对应一只归属词;`attempts.[].model` 是 core 的 `ModelRef`(`string | Model`):本服务的梯子只给目录 id 串
207
+ * (`http/run-meta.ts` 的 `cascadeConfig`,后台腿与同步腿同一只),对象臂不可达 ⇒ 整座按串处置,不展开 `Model` 的二十余格(对象臂真到达那天,它的凭据座
208
+ * —— `headers` —— 是出口封口的事,与 `PAUSE_SEATS` 同类,不是文本表的事)。
209
+ * ⚠️ 五只前缀里**只有这一只没有属主表接着判**(前四只的属主表是 `OwnerTable`,子树里多一片叶盖不住即红):`Model` 加一个串成员不会红 ——
210
+ * 它与「对象臂不可达」是同一个前提,前提翻了(梯子交对象)就得给它一张属主表或展开成行。
211
+ */
212
+ type TextLeafOwnedPrefix = "stats" | "terminal.detail" | "apiFailure" | "strandedHumanAnswers.[]" | "attempts.[].model";
213
+ /** 停驻座的凭据 / 门路径(从 `PAUSE_SEATS` 派生):先折叠(门是一棵子树),再从键集里减掉。 */
214
+ type PauseSeatPath = SeatKeyPaths<PauseSeat, "token" | "gate">;
215
+ /** 本表的键集(派生)。 */
216
+ export type ResultTextLeafPath = Exclude<CollapseUnder<TextLeafPaths<ExitResult | PersistedResultSideKeys>, TextLeafOwnedPrefix | PauseSeatPath>, PauseSeatPath>;
217
+ export declare const RESULT_TEXT_LEAVES: {
218
+ readonly [P in ResultTextLeafPath]: TextLeafTreatment;
219
+ };
220
+ /** {@link redactTerminalResult} 会碰的全部顶层键 = 文本叶表上**会动字节**的行的根键 ∪ 旧形平面键 ∪ 停驻座的根键 ∪ `editedFiles`(条目上界);
221
+ * `memoRedactTerminalResult` 的记忆键由它派生(两处同源,不手抄)。漏进记忆键集 = 读面记忆腿对存量行那几片 O(1) 原样直返,读面纵深恒不生效
222
+ * ([ref] 立案时 `editedFiles` 那一格、[ref] 立案时 `attempts` 那一格的同一个病 —— 后者修前不在任何键表里)。
223
+ * 回声行不脱敏但**会被改**(越界 ⇒ 删键),所以同样进集([ref] 起名 `TREATED_…`,原 `REDACTABLE_…`)。 */
171
224
  export declare const TREATED_RESULT_LEAVES: readonly string[];
172
- export declare function redactTerminalResult<T extends {
173
- terminal?: unknown;
174
- /** 旧形(≤7.63.0)的三个顶层座;形上取 `unknown` —— 读盘面对盘上字节不作假设。 */
175
- errorMessage?: unknown;
176
- blockedReason?: unknown;
177
- checkpointGate?: unknown;
178
- remoteEnvFailures?: readonly {
179
- message?: string | undefined;
180
- }[] | undefined;
181
- /** [ref]:模型自由文本两叶 + 引擎披露散文一族。形上同样取 `unknown`(读面纪律,见下)。 */
182
- result?: unknown;
183
- salvagedOutput?: unknown;
184
- rewindNotes?: unknown;
185
- /** 🔴 形上**故意**是 `unknown`:本函数也是**读面**(旧持久 blob / 非 core Runner 的形不可信),
186
- * 声明成 `{path,edits}[]` 会逼每一个喂坏形的调用点铸一次宽松断言 —— 而「坏形从哪来」正是本座要
187
- * 处理的事(同一份不信任在 `remoteEnvFailures` 的实现里也已成文)。运行期逐项判形,不抛。 */
188
- editedFiles?: unknown;
189
- /** [ref]:形上同样 `unknown` —— 本函数是读盘面,`stats` 的树形逐层现判(见 {@link redactStats})。 */
190
- stats?: unknown;
191
- /** [ref]:provider 回声三键(形上 `unknown`,读盘面纪律同上;处置见 {@link PROVIDER_ECHO_SHAPERS})。 */
192
- apiFailure?: unknown;
193
- strandedHumanAnswers?: unknown;
194
- responseModel?: unknown;
195
- } | null | undefined>(result: T): T;
225
+ /**
226
+ * 同口:终态 `result` 整块也持久化(`GET /v1/runs/:id` 直出),写入前把里面的**自由文本座**脱敏,其余键
227
+ * 逐字不动;`undefined`/`null` 透传。
228
+ *
229
+ * 🔴 [ref](core 7.6.0 [ref] D-8):自由文本座**搬家了** —— 失败文案与阻塞理由从顶层平面键
230
+ * (`errorMessage` / `blockedReason`)搬进因由 `terminal` 的两条臂(`failed.message` / `blocked.reason`)。
231
+ * 本函数**两种形都认**,而这不是「兼容读臂」(codex 对抗复审 r1 [high],亲读验真后**改判**;首版删掉了旧键
232
+ * 臂,那是错的):本函数是**读盘面**,而 `task_run.result` / `task_event(done).result` 里躺着 7.63.0 及以前
233
+ * 写下的**真字节**,它们本来就是平面形。写口只剩因由一条(没有任何东西会再写出旧形),所以这里不存在
234
+ * 「两个写者」;而不认旧形的代价是**可复现的凭据回放**:上线前落盘的原文经 `GET /v1/runs/:id/events` 重新
235
+ * 明文外发(读面这一层纵深正是为那批行存在的)。⇒ 规则仍只有一条:**读盘认盘上真有的形,写盘只写一种形**。
236
+ *
237
+ * 读面也走本函数,所以形上一律取宽:旧持久 blob 与非 core 的 Runner 实现给的形不可信,运行期逐层判形、不抛(走表函数与各属主同款不信任)。
238
+ */
239
+ /**
240
+ * **结果整块的唯一汇点** —— 三孪生 store 的 `setTerminal` / park 两口(经 {@link sealRunRowResult})、`redactLedgerEventData` 的 `done.result`、
241
+ * `POST /v1/tasks` 200 体(`http/routes/tasks.ts` 的 `mintSubmitExitResult`)、读面(`GET /v1/runs/:id` / `/events`,经 {@link memoRedactTerminalResult})
242
+ * 全调它,于是新铸与**存量回放**同时被覆盖(core 铸点修不回溯已写行)。四段,各有一个属主:
243
+ * ① `editedFiles` 条目上界(容器界,不是文本处置;先截后走表,不为越界条目付扫描);
244
+ * ② **文本叶表** {@link RESULT_TEXT_LEAVES} 一张走完({@link applyResultTextLeaves})—— 自由文本 / 回声 / 两棵另有属主的子树都在这一步;
245
+ * ③ 停驻座的门({@link PAUSE_SEATS} × {@link redactCheckpointGate});
246
+ * ④ 旧形(≤7.63.0)的三个顶层平面键 —— 盘上冻结形,不在任何活类型上(见 {@link LEGACY_RESULT_LEAVES})。
247
+ * 形上取宽:本函数也是**读盘面**(旧持久 blob / 非 core Runner 的形不可信),每一段逐层判形、不抛;字节没变 ⇒ **同一引用**。
248
+ */
249
+ export declare function redactTerminalResult<T extends object | null | undefined>(result: T): T;
196
250
  /**
197
251
  * 🔴 **[ref] —— run 行 `result` 列的唯一入口**:先过出口封口({@link sealResultForExit}:摘恢复凭据 + 折域外码),
198
252
  * 再过 {@link redactTerminalResult}。三家 run 店(SQL 两方言 / file / memory)的**三个**写口 —— `setTerminal` 与
@@ -205,8 +259,15 @@ export declare function redactTerminalResult<T extends {
205
259
  * 所以调用点已封过口的腿零行为变化。
206
260
  *
207
261
  * `null` 原样(= 这条腿没有结果可落:引擎没给终局就收流 / 断连竞态 park / 重开 re-park)。
262
+ *
263
+ * 本函数是**写入口**(结果第一次落盘 ⇒ 折码运维线索 `at=exit`);读面读存量行用 {@link sealStoredRunRowResult}(读座必填)。
208
264
  */
209
265
  export declare function sealRunRowResult(result: PersistedTaskResult | null): PersistedTaskResult | null;
266
+ /**
267
+ * {@link sealRunRowResult} 的**读入口**(`GET /v1/runs/:id` 的非终态臂读停驻行):同一套封口 + 同一只汇点,只差折码运维线索的观看点 ——
268
+ * 读座必填({@link StoredResultReadSeat}),再观看走 fail-open 纪律(见 `terminal.ts` 的 `sealStoredResult`)。
269
+ */
270
+ export declare function sealStoredRunRowResult(result: PersistedTaskResult | null, seat: StoredResultReadSeat): PersistedTaskResult | null;
210
271
  /** [ref](第五轮合并重扫 wf_f00c00bc 两根 [high]):同一个 `TaskResult` 除 run 行外还被逐字追加进 run_events 的 `done` 行
211
272
  * (bg/verify/cascade/stream/resume 五腿),`failed` 行带原文 `errorMessage`,`GET /v1/runs/:id/events` 原样回放。
212
273
  * 三孪生 `appendEvent` 入口 + 事件读面(旧行纵深)同调本函数:只认 `done.result`(整块走 `redactTerminalResult`)与
@@ -251,7 +312,7 @@ export declare function redactLeaderResultWithFlag(result: unknown): {
251
312
  };
252
313
  export declare function memoRedactedRead<T>(seat: string, raw: T, redact: (v: T) => T): T;
253
314
  /** run 终态 result 的读面记忆只按**本函数会改字节的那几叶**({@link TREATED_RESULT_LEAVES}:脱敏叶 ∪ [ref] 回声叶 ∪ 旧形平面键,属主是
254
- * `RESULT_KEY_TREATMENT`)做键与留体——
315
+ * 文本叶表 {@link RESULT_TEXT_LEAVES})做键与留体——
255
316
  * 第十六轮重扫:按整块 result 摘要每次轮询要 stringify 一份可能数 MB 的 result,且大 result 的脏行永远存不进去。叶全缺席
256
317
  * ⇒ O(1) 直返(`redactTerminalResult` 本就同引用)。
257
318
  * 🔴 [ref](core 7.6.0 D-8):新形把前两片搬进了 `terminal`(同属一个键,按它整只做叶更省);旧形的两片
@@ -262,7 +323,7 @@ export declare function memoRedactedRead<T>(seat: string, raw: T, redact: (v: T)
262
323
  * `memoRedactTerminalResult` 会对它 O(1) 直返明文,读面纵深对这一叶恒不生效(这正是 [ref] 立案时
263
324
  * `editedFiles` 那一格的病)。读数:8MB result 的一次摘要 ~10ms 量级,远小于一次全扫;干净行仍只摘要
264
325
  * 一次即进 clean 集,脏行超过 {@link READ_MEMO_DIRTY_MAX_ENTRY_BYTES} 时退化为每次重扫(既有形)。 */
265
- export declare function memoRedactTerminalResult<T extends Parameters<typeof redactTerminalResult>[0]>(seat: string, result: T): T;
326
+ export declare function memoRedactTerminalResult<T extends Parameters<typeof redactTerminalResult>[0]>(seat: StoredResultReadSeat, raw: T): T;
266
327
  /**
267
328
  * 🔴 **账本行的读面口 —— 全部耐久读腿共用这一只**([ref],7.105.0)。
268
329
  *
@@ -290,4 +351,5 @@ export declare function redactLedgerEventForRead(type: string, data: unknown): u
290
351
  export declare function diffScanShadowCountForTest(): number;
291
352
  export declare function resetDiffScanShadowCountForTest(): void;
292
353
  export declare function resetReadRedactionMemoForTest(): void;
354
+ export {};
293
355
  //# sourceMappingURL=run-terminal.d.ts.map
@@ -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, sealStoredResult } 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";
@@ -128,43 +128,138 @@ function shapeEchoMembers(node, table, seat) {
128
128
  }
129
129
  return out ?? node;
130
130
  }
131
- function shapeEchoRows(rows, table, seat) {
132
- if (!Array.isArray(rows))
133
- return rows;
134
- const next = rows.map((row) => shapeEchoMembers(row, table, seat));
135
- return next.every((x, i) => x === rows[i]) ? rows : next;
136
- }
137
131
  const MAX_EDITED_FILES = 1000;
138
- const RESULT_KEY_TREATMENT = {
139
- terminal: "redacted",
140
- remoteEnvFailures: "redacted",
141
- editedFiles: "redacted",
142
- responseModel: "provider-echo",
143
- apiFailure: "provider-echo",
144
- strandedHumanAnswers: "provider-echo",
132
+ export const RESULT_TEXT_LEAVES = {
145
133
  taskId: "verbatim",
146
134
  runId: "verbatim",
147
135
  sessionId: "verbatim",
148
136
  model: "verbatim",
149
- compaction: "verbatim",
150
- effectiveReasoning: "verbatim",
151
- result: "redacted",
152
- salvagedOutput: "redacted",
153
- retryAfterMs: "verbatim",
154
- degraded: "verbatim",
137
+ "terminal.code": "outward-code",
138
+ "terminal.message": "error-text",
139
+ "terminal.reason": "error-text",
140
+ "terminal.detail": "terminal-detail",
141
+ "terminal.checkpointId": "verbatim",
142
+ "terminal.requestedByCallId": "provider-join-key",
143
+ "terminal.nestedPause.checkpointId": "verbatim",
144
+ "terminal.nestedPause.requestedByCallId": "provider-join-key",
145
+ result: "model-text",
146
+ salvagedOutput: "model-text",
147
+ "remoteEnvFailures.[].message": "error-text",
148
+ "rewindNotes.[].message": "error-text",
149
+ "editedFiles.[].path": "model-text",
150
+ responseModel: "provider-echo",
151
+ apiFailure: "api-failure",
152
+ "strandedHumanAnswers.[]": "stranded-answer",
153
+ "degraded.from": "verbatim",
154
+ "degraded.to": "verbatim",
155
+ "degraded.chain.[]": "verbatim",
156
+ "effectiveReasoning.endpoint": "verbatim",
157
+ "resultEntryIds.[]": "verbatim",
158
+ "pendingApproval.askIds.[]": "verbatim",
159
+ "effectiveReadDenyPatterns.[].pattern": "verbatim",
160
+ "effectiveMemoryScopes.writeScope": "verbatim",
161
+ "effectiveMemoryScopes.scopes.[].scope": "verbatim",
162
+ "effectiveMemoryScopes.projectKey.scope": "verbatim",
163
+ "effectiveMemoryScopes.materializedResidue.[]": "verbatim",
155
164
  structuredOutput: "verbatim",
156
- resultEntryIds: "verbatim",
157
- rewindNotes: "redacted",
158
- haltedOnUserRejection: "verbatim",
159
- haltedByUser: "verbatim",
160
- pendingApproval: "verbatim",
161
- approvalWaitedMs: "verbatim",
162
- effectiveReadFace: "verbatim",
163
- effectiveWriteFace: "verbatim",
164
- effectiveReadDenyPatterns: "verbatim",
165
- effectiveMemoryScopes: "verbatim",
166
- stats: "redacted",
165
+ stats: "stats-tree",
166
+ "verification.findings.[]": "model-text",
167
+ "verification.evidence": "model-text",
168
+ "verification.verifierPause.sessionId": "verbatim",
169
+ "attempts.[].model": "verbatim",
170
+ "attempts.[].errorCode": "outward-code",
171
+ "attempts.[].gateError": "error-text",
172
+ "attempts.[].diagnostics": "model-text",
173
+ "cancelContext.lastEventKind": "verbatim",
174
+ "cancelContext.lastBrainStatus.phase": "verbatim",
175
+ "cancelContext.lastBrainStatus.errClass": "verbatim",
167
176
  };
177
+ const DROP_LEAF = Symbol("drop-leaf");
178
+ function textLeafAct(treatment) {
179
+ switch (treatment) {
180
+ case "verbatim":
181
+ case "provider-join-key":
182
+ case "outward-code":
183
+ return undefined;
184
+ case "model-text":
185
+ return (v) => (typeof v === "string" ? redactModelText(v) : v);
186
+ case "error-text":
187
+ return (v) => (typeof v === "string" ? redactErrorMessage(v) : v);
188
+ case "provider-echo":
189
+ return (v, _holder, seat) => (admitProviderEcho(v, seat) ? v : DROP_LEAF);
190
+ case "stats-tree":
191
+ return (v) => redactStats(v);
192
+ case "terminal-detail":
193
+ return (v, holder) => shapeTerminalDetail(v, holder);
194
+ case "api-failure":
195
+ return (v) => shapeEchoMembers(v, API_FAILURE_TREATMENT, "apiFailure");
196
+ case "stranded-answer":
197
+ return (v) => shapeEchoMembers(v, STRANDED_ANSWER_TREATMENT, "strandedHumanAnswers[]");
198
+ default: {
199
+ const unhandled = treatment;
200
+ throw new Error(`unhandled text-leaf treatment: ${String(unhandled)}`);
201
+ }
202
+ }
203
+ }
204
+ const ACTIVE_TEXT_LEAVES = Object.entries(RESULT_TEXT_LEAVES).flatMap(([seat, treatment]) => {
205
+ const act = textLeafAct(treatment);
206
+ return act === undefined ? [] : [{ seat, segments: seat.split("."), act }];
207
+ });
208
+ function mapTextLeaf(node, segments, depth, holder, act, seat) {
209
+ if (depth === segments.length)
210
+ return act(node, holder, seat);
211
+ if (node === null || typeof node !== "object")
212
+ return node;
213
+ const segment = segments[depth];
214
+ if (segment === "[]") {
215
+ if (!Array.isArray(node))
216
+ return node;
217
+ let changed = false;
218
+ const next = [];
219
+ for (const el of node) {
220
+ const n = el === undefined ? el : mapTextLeaf(el, segments, depth + 1, node, act, seat);
221
+ if (n === DROP_LEAF) {
222
+ changed = true;
223
+ continue;
224
+ }
225
+ if (!Object.is(n, el))
226
+ changed = true;
227
+ next.push(n);
228
+ }
229
+ return changed ? next : node;
230
+ }
231
+ if (Array.isArray(node))
232
+ return node;
233
+ const obj = node;
234
+ let out;
235
+ for (const key of segment === "*" ? Object.keys(obj) : Object.hasOwn(obj, segment) ? [segment] : []) {
236
+ const child = obj[key];
237
+ if (child === undefined)
238
+ continue;
239
+ const n = mapTextLeaf(child, segments, depth + 1, obj, act, seat);
240
+ if (n === DROP_LEAF)
241
+ delete (out ??= { ...obj })[key];
242
+ else if (!Object.is(n, child))
243
+ (out ??= { ...obj })[key] = n;
244
+ }
245
+ return out ?? node;
246
+ }
247
+ function applyResultTextLeaves(result) {
248
+ let out = result;
249
+ for (const row of ACTIVE_TEXT_LEAVES)
250
+ out = mapTextLeaf(out, row.segments, 0, undefined, row.act, row.seat);
251
+ return out;
252
+ }
253
+ function shapeTerminalDetail(detail, terminal) {
254
+ const kind = terminal !== null && typeof terminal === "object" ? terminal.kind : undefined;
255
+ if (kind === "failed")
256
+ return shapeArmedDetail(detail, TERMINAL_FAILURE_DETAIL_TREATMENT);
257
+ if (kind === "completed")
258
+ return shapeArmedDetail(detail, TERMINAL_COMPLETED_DETAIL_TREATMENT);
259
+ if (kind === "blocked")
260
+ return shapeTerminalBlockedDetail(detail);
261
+ return shapeArmedDetail(detail, {});
262
+ }
168
263
  const API_FAILURE_TREATMENT = {
169
264
  status: "verbatim",
170
265
  requestId: "provider-echo",
@@ -209,12 +304,15 @@ function redactStringLeaves(node, depth = 0) {
209
304
  }
210
305
  const OFF_ARM_MEMBER_TREATMENT = "free-text-tree";
211
306
  const redactDetailMember = (v) => redactStringLeaves(v, 1);
212
- function shapeTerminalFailureDetail(detail) {
307
+ const TERMINAL_COMPLETED_DETAIL_TREATMENT = {
308
+ finish_reason_unknown: { kind: "verbatim", finishReasonUnknown: "provider-echo" },
309
+ };
310
+ function shapeArmedDetail(detail, arms) {
213
311
  if (detail === null || typeof detail !== "object" || Array.isArray(detail))
214
312
  return detail;
215
313
  const d = detail;
216
314
  const kind = d.kind;
217
- const arm = typeof kind === "string" && Object.hasOwn(TERMINAL_FAILURE_DETAIL_TREATMENT, kind) ? TERMINAL_FAILURE_DETAIL_TREATMENT[kind] : {};
315
+ const arm = typeof kind === "string" && Object.hasOwn(arms, kind) ? arms[kind] : {};
218
316
  let out;
219
317
  for (const key of Object.keys(d)) {
220
318
  const v = d[key];
@@ -237,7 +335,7 @@ function shapeTerminalFailureDetail(detail) {
237
335
  }
238
336
  default: {
239
337
  const unhandled = treatment;
240
- throw new Error(`unhandled failure-detail treatment: ${String(unhandled)}`);
338
+ throw new Error(`unhandled detail-member treatment: ${String(unhandled)}`);
241
339
  }
242
340
  }
243
341
  }
@@ -282,156 +380,61 @@ function shapeTerminalBlockedDetail(detail) {
282
380
  }
283
381
  return out ?? detail;
284
382
  }
285
- const PROVIDER_ECHO_SHAPERS = {
286
- responseModel: (v) => (admitProviderEcho(v, "responseModel") ? v : undefined),
287
- apiFailure: (v) => shapeEchoMembers(v, API_FAILURE_TREATMENT, "apiFailure"),
288
- strandedHumanAnswers: (v) => shapeEchoRows(v, STRANDED_ANSWER_TREATMENT, "strandedHumanAnswers[]"),
289
- };
290
- {
291
- const judged = Object.entries(RESULT_KEY_TREATMENT).filter(([, t]) => t === "provider-echo").map(([k]) => k).sort();
292
- const wired = Object.keys(PROVIDER_ECHO_SHAPERS).sort();
293
- if (judged.join(",") !== wired.join(","))
294
- throw new Error(`run-terminal: provider-echo classification [${judged.join(",")}] ≠ shaper table [${wired.join(",")}]`);
295
- }
296
383
  const LEGACY_RESULT_LEAVES = ["errorMessage", "blockedReason", "checkpointGate"];
297
384
  export const TREATED_RESULT_LEAVES = [
298
- ...Object.entries(RESULT_KEY_TREATMENT).filter(([, t]) => t !== "verbatim").map(([k]) => k),
299
- ...LEGACY_RESULT_LEAVES,
385
+ ...new Set([
386
+ ...ACTIVE_TEXT_LEAVES.map((row) => row.segments[0]),
387
+ ...LEGACY_RESULT_LEAVES,
388
+ ...PAUSE_SEATS.map((seat) => seat.path[0]),
389
+ "editedFiles",
390
+ ]),
300
391
  ];
301
392
  export function redactTerminalResult(result) {
302
393
  if (result === undefined || result === null)
303
394
  return result;
395
+ return redactLegacyPlaneLeaves(redactPauseSeatGates(applyResultTextLeaves(capEditedFiles(result))));
396
+ }
397
+ function capEditedFiles(result) {
398
+ const files = result.editedFiles;
399
+ if (!Array.isArray(files) || files.length <= MAX_EDITED_FILES)
400
+ return result;
401
+ return { ...result, editedFiles: files.slice(0, MAX_EDITED_FILES) };
402
+ }
403
+ function redactPauseSeatGates(result) {
404
+ return mapPauseSeats(result, (seat, keys) => {
405
+ if (!Object.hasOwn(seat, keys.gate))
406
+ return seat;
407
+ const g = seat[keys.gate];
408
+ const ng = redactCheckpointGate(g);
409
+ return ng === g ? seat : { ...seat, [keys.gate]: ng };
410
+ });
411
+ }
412
+ function redactLegacyPlaneLeaves(result) {
304
413
  const r = result;
305
- let changed = false;
306
- const out = { ...r };
414
+ let out;
307
415
  if (typeof r.errorMessage === "string") {
308
- out.errorMessage = redactErrorMessage(r.errorMessage);
309
- changed = true;
416
+ const next = redactErrorMessage(r.errorMessage);
417
+ if (next !== r.errorMessage)
418
+ (out ??= { ...result }).errorMessage = next;
310
419
  }
311
420
  if (typeof r.blockedReason === "string") {
312
- out.blockedReason = redactErrorMessage(r.blockedReason);
313
- changed = true;
421
+ const next = redactErrorMessage(r.blockedReason);
422
+ if (next !== r.blockedReason)
423
+ (out ??= { ...result }).blockedReason = next;
314
424
  }
315
425
  if (r.checkpointGate !== undefined) {
316
- const legacyGate = redactCheckpointGate(r.checkpointGate);
317
- if (legacyGate !== r.checkpointGate) {
318
- out.checkpointGate = legacyGate;
319
- changed = true;
320
- }
321
- }
322
- if (r.terminal !== null && typeof r.terminal === "object") {
323
- const t = r.terminal;
324
- let nt;
325
- if (t.kind === "failed" && typeof t.message === "string")
326
- nt = { ...t, message: redactErrorMessage(t.message) };
327
- else if (t.kind === "blocked" && typeof t.reason === "string")
328
- nt = { ...t, reason: redactErrorMessage(t.reason) };
329
- if (t.kind === "blocked") {
330
- const cur = nt ?? t;
331
- const detail = cur.detail;
332
- const shaped = shapeTerminalBlockedDetail(detail);
333
- if (shaped !== detail)
334
- nt = { ...cur, detail: shaped };
335
- }
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
- 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 } };
354
- const cur = nt ?? base;
355
- const detail = cur.detail;
356
- const shaped = shapeTerminalFailureDetail(detail);
357
- if (shaped !== detail)
358
- nt = { ...cur, detail: shaped };
359
- }
360
- if (nt !== undefined) {
361
- out.terminal = nt;
362
- changed = true;
363
- }
364
- }
365
- if (r.remoteEnvFailures !== undefined) {
366
- out.remoteEnvFailures = Array.isArray(r.remoteEnvFailures)
367
- ? r.remoteEnvFailures.map((f) => (f && typeof f === "object" && typeof f.message === "string" ? { ...f, message: redactErrorMessage(f.message) } : f))
368
- : r.remoteEnvFailures;
369
- changed = true;
370
- }
371
- if (r.editedFiles !== undefined) {
372
- out.editedFiles = Array.isArray(r.editedFiles)
373
- ? r.editedFiles
374
- .slice(0, MAX_EDITED_FILES)
375
- .map((f) => {
376
- if (f === null || typeof f !== "object")
377
- return f;
378
- const path = f.path;
379
- return typeof path === "string" ? { ...f, path: redactSecrets(path) } : f;
380
- })
381
- : r.editedFiles;
382
- changed = true;
383
- }
384
- if (typeof r.result === "string") {
385
- const next = redactModelText(r.result);
386
- if (next !== r.result) {
387
- out.result = next;
388
- changed = true;
389
- }
426
+ const next = redactCheckpointGate(r.checkpointGate);
427
+ if (next !== r.checkpointGate)
428
+ (out ??= { ...result }).checkpointGate = next;
390
429
  }
391
- if (typeof r.salvagedOutput === "string") {
392
- const next = redactModelText(r.salvagedOutput);
393
- if (next !== r.salvagedOutput) {
394
- out.salvagedOutput = next;
395
- changed = true;
396
- }
397
- }
398
- if (r.rewindNotes !== undefined) {
399
- out.rewindNotes = Array.isArray(r.rewindNotes)
400
- ? r.rewindNotes.map((n) => {
401
- if (n === null || typeof n !== "object")
402
- return n;
403
- const message = n.message;
404
- return typeof message === "string" ? { ...n, message: redactErrorMessage(message) } : n;
405
- })
406
- : r.rewindNotes;
407
- changed = true;
408
- }
409
- if (r.stats !== undefined) {
410
- const next = redactStats(r.stats);
411
- if (next !== r.stats) {
412
- out.stats = next;
413
- changed = true;
414
- }
415
- }
416
- const rr = result;
417
- for (const [key, shape] of Object.entries(PROVIDER_ECHO_SHAPERS)) {
418
- const v = rr[key];
419
- if (v === undefined || shape === undefined)
420
- continue;
421
- const next = shape(v);
422
- if (next === v)
423
- continue;
424
- if (next === undefined)
425
- delete out[key];
426
- else
427
- out[key] = next;
428
- changed = true;
429
- }
430
- return changed ? out : result;
430
+ return out === undefined ? result : out;
431
431
  }
432
432
  export function sealRunRowResult(result) {
433
433
  return result === null ? null : redactTerminalResult(sealResultForExit(result));
434
434
  }
435
+ export function sealStoredRunRowResult(result, seat) {
436
+ return result === null ? null : redactTerminalResult(sealStoredResult(result, seat));
437
+ }
435
438
  export function redactLedgerEventData(type, data) {
436
439
  if (data === null || typeof data !== "object" || Array.isArray(data))
437
440
  return data;
@@ -439,7 +442,7 @@ export function redactLedgerEventData(type, data) {
439
442
  const result = data.result;
440
443
  if (result === null || typeof result !== "object")
441
444
  return data;
442
- return { ...data, result: redactTerminalResult(result) };
445
+ return { ...data, result: sealRunRowResult(result) };
443
446
  }
444
447
  if (type === "failed") {
445
448
  const msg = data.errorMessage;
@@ -896,9 +899,10 @@ export function memoRedactedRead(seat, raw, redact) {
896
899
  }
897
900
  return out;
898
901
  }
899
- export function memoRedactTerminalResult(seat, result) {
900
- if (result === undefined || result === null)
901
- return result;
902
+ export function memoRedactTerminalResult(seat, raw) {
903
+ if (raw === undefined || raw === null)
904
+ return raw;
905
+ const result = sealStoredResult(raw, seat);
902
906
  const r = result;
903
907
  if (TREATED_RESULT_LEAVES.every((k) => r[k] === undefined))
904
908
  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}。 */