@sema-agent/server 7.141.0 → 7.143.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 (341) hide show
  1. package/MIGRATION.md +657 -0
  2. package/USAGE.md +102 -30
  3. package/dist/adoption/plan.js +22 -0
  4. package/dist/approval-ask-audit-store.d.ts +61 -43
  5. package/dist/approval-ask-audit-store.js +69 -44
  6. package/dist/approval-ask-machine.d.ts +15 -7
  7. package/dist/approval-ask-machine.js +10 -4
  8. package/dist/approval-card.d.ts +126 -27
  9. package/dist/approval-card.js +103 -23
  10. package/dist/approval-crash-convergence.d.ts +17 -7
  11. package/dist/approval-crash-convergence.js +94 -22
  12. package/dist/approval-deny-reasons.d.ts +34 -30
  13. package/dist/approval-deny-reasons.js +21 -6
  14. package/dist/approval-policy-settlement.d.ts +1 -1
  15. package/dist/approval-queue-kind.d.ts +27 -0
  16. package/dist/approval-queue-kind.js +6 -0
  17. package/dist/approval-reconciler.d.ts +41 -9
  18. package/dist/approval-reconciler.js +45 -42
  19. package/dist/audit.js +4 -2
  20. package/dist/auth-bridge.d.ts +9 -6
  21. package/dist/auth-bridge.js +9 -3
  22. package/dist/boot/adoption.js +2 -1
  23. package/dist/boot/budget-tracing.d.ts +17 -1
  24. package/dist/boot/budget-tracing.js +10 -6
  25. package/dist/boot/device-lane.d.ts +1 -1
  26. package/dist/boot/execution-env.d.ts +24 -4
  27. package/dist/boot/execution-env.js +26 -23
  28. package/dist/boot/execution-lane.js +2 -1
  29. package/dist/boot/exit-boundary.js +5 -4
  30. package/dist/boot/governance-seams.d.ts +26 -41
  31. package/dist/boot/governance-seams.js +61 -28
  32. package/dist/boot/late-binds.d.ts +7 -4
  33. package/dist/boot/late-binds.js +3 -1
  34. package/dist/boot/leader.js +2 -4
  35. package/dist/boot/memory-consolidation.d.ts +0 -8
  36. package/dist/boot/memory-consolidation.js +5 -4
  37. package/dist/boot/parked-revive-gate.js +2 -1
  38. package/dist/boot/permission-rules-audit.d.ts +0 -28
  39. package/dist/boot/permission-rules-audit.js +2 -1
  40. package/dist/boot/read-deny-anchor-audit.js +2 -1
  41. package/dist/boot/reapers.js +9 -7
  42. package/dist/boot/resolve-spec.d.ts +1 -1
  43. package/dist/boot/resolve-spec.js +19 -10
  44. package/dist/boot/retention-lane.js +5 -3
  45. package/dist/boot/runner-deps.d.ts +10 -7
  46. package/dist/boot/runner-deps.js +20 -29
  47. package/dist/boot/runtime-caps.js +3 -2
  48. package/dist/boot/session-faces.js +4 -3
  49. package/dist/boot/shutdown.d.ts +9 -0
  50. package/dist/boot/shutdown.js +19 -4
  51. package/dist/boot/stage-02-web-admin-pull.js +3 -0
  52. package/dist/boot/stage-03-store-backend.d.ts +4 -1
  53. package/dist/boot/stage-03-store-backend.js +1 -2
  54. package/dist/boot/stage-04-stores.d.ts +5 -2
  55. package/dist/boot/stage-04-stores.js +6 -7
  56. package/dist/boot/stage-05-execution-env.d.ts +6 -3
  57. package/dist/boot/stage-05-execution-env.js +8 -6
  58. package/dist/boot/stage-06-runners.d.ts +6 -3
  59. package/dist/boot/stage-06-runners.js +3 -4
  60. package/dist/boot/stage-07-capability-layer.d.ts +6 -3
  61. package/dist/boot/stage-07-capability-layer.js +7 -2
  62. package/dist/boot/stage-08-reapers.d.ts +6 -3
  63. package/dist/boot/stage-08-reapers.js +3 -2
  64. package/dist/boot/stage-09-leader.d.ts +6 -3
  65. package/dist/boot/stage-10-http-server.d.ts +6 -3
  66. package/dist/boot/stage-10-http-server.js +14 -5
  67. package/dist/boot/stores.d.ts +5 -2
  68. package/dist/boot/stores.js +10 -9
  69. package/dist/boot/web-admin.d.ts +5 -1
  70. package/dist/boot/web-admin.js +48 -36
  71. package/dist/boot/webfetch-summarize-lane.js +2 -1
  72. package/dist/boot/workflow-orchestration.js +3 -2
  73. package/dist/capabilities/builtin-tools.d.ts +2 -1
  74. package/dist/capabilities/builtin-tools.js +2 -4
  75. package/dist/capabilities/composite-members.d.ts +2 -1
  76. package/dist/capabilities/composite-members.js +2 -1
  77. package/dist/capabilities/hands-lane.d.ts +9 -39
  78. package/dist/capabilities/hands-lane.js +8 -13
  79. package/dist/capabilities/mcp-probe.d.ts +3 -2
  80. package/dist/capabilities/scenarios.d.ts +11 -1
  81. package/dist/capabilities/scenarios.js +1 -0
  82. package/dist/capabilities/skills.d.ts +1 -17
  83. package/dist/capabilities/skills.js +0 -8
  84. package/dist/capability-facts.d.ts +31 -7
  85. package/dist/capability-facts.js +27 -4
  86. package/dist/card-void.d.ts +6 -9
  87. package/dist/config-catalog.js +2 -1
  88. package/dist/config-dir-trust.js +58 -29
  89. package/dist/config-invariants.d.ts +7 -1
  90. package/dist/config-invariants.js +7 -0
  91. package/dist/config-provider.d.ts +10 -0
  92. package/dist/config-provider.js +15 -4
  93. package/dist/config-root-migration.d.ts +13 -0
  94. package/dist/config-root-migration.js +99 -0
  95. package/dist/config-types.d.ts +19 -8
  96. package/dist/config.d.ts +10 -3
  97. package/dist/config.js +18 -4
  98. package/dist/delegated-session-owner.d.ts +5 -3
  99. package/dist/delegated-session-owner.js +1 -1
  100. package/dist/device-ws-protocol.d.ts +1 -0
  101. package/dist/device-ws-protocol.js +2 -1
  102. package/dist/env-model-table-gate.d.ts +53 -0
  103. package/dist/env-model-table-gate.js +53 -0
  104. package/dist/execution-lane-caps.d.ts +2 -1
  105. package/dist/fleet/fleet-bus.d.ts +34 -55
  106. package/dist/fleet/fleet-bus.js +35 -100
  107. package/dist/fleet/fleet-reconciler.d.ts +4 -4
  108. package/dist/fleet/fleet-reconciler.js +1 -1
  109. package/dist/fleet/subagent-tail-bus.d.ts +14 -11
  110. package/dist/fleet/subagent-tail-bus.js +15 -28
  111. package/dist/hooks/hook-runner.d.ts +6 -0
  112. package/dist/hooks/hook-runner.js +58 -8
  113. package/dist/host-decision.d.ts +54 -20
  114. package/dist/host-decision.js +42 -14
  115. package/dist/http/admission.d.ts +1 -1
  116. package/dist/http/admission.js +7 -3
  117. package/dist/http/approval-sweeps.js +11 -8
  118. package/dist/http/caller-trust.d.ts +1 -1
  119. package/dist/http/dispatch.js +4 -2
  120. package/dist/http/durable-run-leg.js +2 -2
  121. package/dist/http/engine-refusal.d.ts +16 -0
  122. package/dist/http/engine-refusal.js +17 -0
  123. package/dist/http/execution-context.d.ts +2 -2
  124. package/dist/http/idempotency.d.ts +1 -1
  125. package/dist/http/memory-compliance-failure-reply.d.ts +1 -3
  126. package/dist/http/memory-compliance-failure-reply.js +4 -6
  127. package/dist/http/owner-access.d.ts +11 -0
  128. package/dist/http/owner-access.js +13 -0
  129. package/dist/http/principal-gate.d.ts +3 -1
  130. package/dist/http/principal-gate.js +17 -8
  131. package/dist/http/resume-legs.d.ts +21 -7
  132. package/dist/http/resume-legs.js +76 -58
  133. package/dist/http/resume-restatement.d.ts +39 -0
  134. package/dist/http/resume-restatement.js +25 -0
  135. package/dist/http/route-ctx.d.ts +35 -10
  136. package/dist/http/route-ctx.js +1 -1
  137. package/dist/http/route-table.js +2 -0
  138. package/dist/http/routes/approvals-assistant.d.ts +9 -1
  139. package/dist/http/routes/approvals-assistant.js +142 -31
  140. package/dist/http/routes/attachments.js +18 -0
  141. package/dist/http/routes/capabilities.js +16 -4
  142. package/dist/http/routes/memory-policy.d.ts +2 -2
  143. package/dist/http/routes/memory-policy.js +27 -7
  144. package/dist/http/routes/notify-wake.js +23 -25
  145. package/dist/http/routes/rules.js +48 -13
  146. package/dist/http/routes/runs.js +12 -11
  147. package/dist/http/routes/session-memory-sync.d.ts +91 -0
  148. package/dist/http/routes/session-memory-sync.js +174 -0
  149. package/dist/http/routes/session-sync.js +13 -20
  150. package/dist/http/routes/sessions-list.d.ts +2 -1
  151. package/dist/http/routes/sessions.d.ts +2 -2
  152. package/dist/http/routes/sessions.js +22 -23
  153. package/dist/http/routes/tasks.js +34 -54
  154. package/dist/http/run-read-face.d.ts +7 -0
  155. package/dist/http/run-read-face.js +9 -3
  156. package/dist/http/send.d.ts +5 -0
  157. package/dist/http/send.js +9 -2
  158. package/dist/http/server.d.ts +27 -15
  159. package/dist/http/server.js +4 -6
  160. package/dist/http/stored-body-replay.js +15 -4
  161. package/dist/http/submit-replay.d.ts +4 -3
  162. package/dist/http/submit-replay.js +2 -2
  163. package/dist/http/sync-submit-body.d.ts +21 -4
  164. package/dist/http/sync-submit-body.js +13 -0
  165. package/dist/http/wire-types.d.ts +17 -7
  166. package/dist/identity-source.d.ts +21 -2
  167. package/dist/identity-source.js +6 -0
  168. package/dist/leader/leader.js +5 -2
  169. package/dist/leader/wire.d.ts +7 -1
  170. package/dist/leader/wire.js +6 -5
  171. package/dist/leg-facts.d.ts +37 -0
  172. package/dist/leg-facts.js +15 -0
  173. package/dist/memory-bundle-engine.d.ts +1 -4
  174. package/dist/memory-bundle-engine.js +2 -2
  175. package/dist/memory-incident-sink.d.ts +19 -6
  176. package/dist/memory-incident-sink.js +8 -4
  177. package/dist/memory-operator-faces.d.ts +30 -66
  178. package/dist/memory-operator-faces.js +17 -88
  179. package/dist/memory-scope-stores.d.ts +38 -40
  180. package/dist/memory-scope-stores.js +51 -36
  181. package/dist/memory-scope.d.ts +0 -9
  182. package/dist/memory-scope.js +0 -9
  183. package/dist/memory-sync-client.d.ts +21 -21
  184. package/dist/memory-sync-client.js +62 -43
  185. package/dist/memory-sync-identity.d.ts +24 -0
  186. package/dist/memory-sync-identity.js +57 -0
  187. package/dist/memory-sync.d.ts +27 -5
  188. package/dist/memory-sync.js +29 -7
  189. package/dist/model-plane-face.d.ts +13 -7
  190. package/dist/model-plane-face.js +2 -1
  191. package/dist/observability/fail-open.d.ts +47 -14
  192. package/dist/observability/fail-open.js +37 -11
  193. package/dist/observability/run-terminal.d.ts +92 -34
  194. package/dist/observability/run-terminal.js +171 -162
  195. package/dist/orchestration/workflow-completion-inbox.d.ts +5 -19
  196. package/dist/orchestration/workflow-completion-inbox.js +0 -12
  197. package/dist/orchestration/workflow-notify-journal.d.ts +3 -2
  198. package/dist/orchestration/workflow-park-decision.d.ts +8 -3
  199. package/dist/orchestration/workflow-park-decision.js +5 -3
  200. package/dist/org-delivery-gate.d.ts +11 -0
  201. package/dist/org-delivery-gate.js +19 -1
  202. package/dist/parked-decide.d.ts +13 -9
  203. package/dist/parked-decide.js +7 -7
  204. package/dist/parked-revive-surface.js +1 -1
  205. package/dist/peer-inbound-face.d.ts +127 -0
  206. package/dist/peer-inbound-face.js +158 -0
  207. package/dist/permission-rule-list.d.ts +13 -9
  208. package/dist/permission-rule-list.js +7 -3
  209. package/dist/plugins/approval-ask-store-file.d.ts +14 -4
  210. package/dist/plugins/approval-ask-store-file.js +64 -11
  211. package/dist/plugins/approval-ask-store-memory.d.ts +2 -1
  212. package/dist/plugins/approval-ask-store-memory.js +17 -14
  213. package/dist/plugins/approval-ask-store-sql.d.ts +70 -23
  214. package/dist/plugins/approval-ask-store-sql.js +79 -30
  215. package/dist/plugins/checkpoint-store-sql.d.ts +4 -4
  216. package/dist/plugins/checkpoint-store-sql.js +9 -7
  217. package/dist/plugins/file-history-store-sql.d.ts +24 -18
  218. package/dist/plugins/file-history-store-sql.js +24 -19
  219. package/dist/plugins/file-run-store.d.ts +35 -1
  220. package/dist/plugins/file-run-store.js +108 -9
  221. package/dist/plugins/imported-layer-root-retirement.d.ts +82 -0
  222. package/dist/plugins/imported-layer-root-retirement.js +96 -0
  223. package/dist/plugins/local-checkpoint-store.d.ts +1 -1
  224. package/dist/plugins/local-checkpoint-store.js +2 -2
  225. package/dist/plugins/local-session-store.d.ts +42 -9
  226. package/dist/plugins/local-session-store.js +83 -33
  227. package/dist/plugins/local-task-attachment-store.d.ts +12 -2
  228. package/dist/plugins/local-task-attachment-store.js +67 -43
  229. package/dist/plugins/mailbox-recipient-lifecycle.d.ts +9 -31
  230. package/dist/plugins/mailbox-recipient-lifecycle.js +4 -0
  231. package/dist/plugins/mailbox-store-sql.d.ts +12 -8
  232. package/dist/plugins/mailbox-store-sql.js +76 -7
  233. package/dist/plugins/memory-key-guards.d.ts +3 -3
  234. package/dist/plugins/memory-run-store.d.ts +6 -1
  235. package/dist/plugins/memory-run-store.js +11 -1
  236. package/dist/plugins/memory-sync-store-pg.d.ts +15 -0
  237. package/dist/plugins/memory-sync-store-pg.js +21 -0
  238. package/dist/plugins/memory-sync-store-tidb.d.ts +2 -0
  239. package/dist/plugins/memory-sync-store-tidb.js +13 -1
  240. package/dist/plugins/one-time-migrations.d.ts +58 -2
  241. package/dist/plugins/one-time-migrations.js +161 -4
  242. package/dist/plugins/org-delivery-quota-store.d.ts +1 -1
  243. package/dist/plugins/org-delivery-quota-store.js +2 -12
  244. package/dist/plugins/park-commit-watch.d.ts +1 -1
  245. package/dist/plugins/permission-rule-store-file.d.ts +10 -1
  246. package/dist/plugins/permission-rule-store-file.js +15 -2
  247. package/dist/plugins/permission-rule-store-sql.d.ts +31 -1
  248. package/dist/plugins/permission-rule-store-sql.js +35 -2
  249. package/dist/plugins/remote-env-device.d.ts +8 -11
  250. package/dist/plugins/remote-env-device.js +6 -3
  251. package/dist/plugins/remote-env-e2b.d.ts +23 -4
  252. package/dist/plugins/remote-env-e2b.js +111 -28
  253. package/dist/plugins/remote-env-k8s.d.ts +61 -22
  254. package/dist/plugins/remote-env-k8s.js +133 -33
  255. package/dist/plugins/remote-env-local-docker.d.ts +15 -3
  256. package/dist/plugins/remote-env-local-docker.js +40 -12
  257. package/dist/plugins/retention-store-sql.d.ts +2 -2
  258. package/dist/plugins/run-store-sql.d.ts +9 -1
  259. package/dist/plugins/run-store-sql.js +9 -1
  260. package/dist/plugins/sandbox-read-floor.d.ts +5 -7
  261. package/dist/plugins/sandbox-read-floor.js +2 -7
  262. package/dist/plugins/sql-errors.d.ts +10 -1
  263. package/dist/plugins/sql-errors.js +13 -0
  264. package/dist/plugins/store-backend.d.ts +33 -35
  265. package/dist/plugins/store-backend.js +10 -1
  266. package/dist/plugins/store-contracts.d.ts +50 -1
  267. package/dist/plugins/store-contracts.js +6 -0
  268. package/dist/plugins/task-attachment-store.d.ts +112 -14
  269. package/dist/plugins/task-attachment-store.js +207 -29
  270. package/dist/plugins/tool-result-store-sql.d.ts +9 -8
  271. package/dist/plugins/tool-result-store-sql.js +23 -2
  272. package/dist/plugins/wiring-section-codec.d.ts +32 -0
  273. package/dist/plugins/wiring-section-codec.js +55 -0
  274. package/dist/plugins/workspace-fill.d.ts +60 -0
  275. package/dist/plugins/workspace-fill.js +106 -0
  276. package/dist/project-bundle.d.ts +38 -0
  277. package/dist/project-bundle.js +609 -0
  278. package/dist/rule-entry-list.d.ts +3 -2
  279. package/dist/rule-entry-list.js +5 -1
  280. package/dist/rules-consent.d.ts +28 -5
  281. package/dist/rules-consent.js +40 -28
  282. package/dist/run-local.js +11 -13
  283. package/dist/runs.d.ts +12 -8
  284. package/dist/runs.js +6 -8
  285. package/dist/runtime-governance.d.ts +1 -1
  286. package/dist/sandbox-egress-policy.d.ts +4 -1
  287. package/dist/sandbox-egress-policy.js +3 -1
  288. package/dist/sandbox-git-plane.d.ts +31 -12
  289. package/dist/sandbox-git-plane.js +24 -4
  290. package/dist/security.d.ts +9 -0
  291. package/dist/security.js +8 -0
  292. package/dist/server-secret-env.d.ts +4 -0
  293. package/dist/session-error-wire.d.ts +36 -0
  294. package/dist/session-error-wire.js +13 -0
  295. package/dist/session-incarnation.d.ts +1 -1
  296. package/dist/session-notify-door.d.ts +106 -0
  297. package/dist/session-notify-door.js +93 -0
  298. package/dist/session-sync.d.ts +9 -14
  299. package/dist/session-sync.js +5 -5
  300. package/dist/session-workspace.d.ts +3 -13
  301. package/dist/session-workspace.js +0 -9
  302. package/dist/standing-answer-grant.d.ts +5 -0
  303. package/dist/standing-answer-grant.js +10 -0
  304. package/dist/stores-sql/session-policy-store-sql.d.ts +4 -2
  305. package/dist/stores-sql/session-policy-store-sql.js +3 -13
  306. package/dist/task-mcp.d.ts +1 -1
  307. package/dist/task-settings.d.ts +21 -10
  308. package/dist/task-settings.js +46 -13
  309. package/dist/terminal.d.ts +39 -19
  310. package/dist/terminal.js +65 -22
  311. package/dist/tool-approval.d.ts +56 -37
  312. package/dist/tool-approval.js +78 -71
  313. package/dist/trace/core-keyset-guard.d.ts +134 -14
  314. package/dist/trace/engine-notice-wire.d.ts +9 -3
  315. package/dist/trace/engine-notice-wire.js +7 -3
  316. package/dist/trace/exit-seat.d.ts +9 -2
  317. package/dist/trace/exit-seat.js +1 -0
  318. package/dist/trace/ledger-sink.d.ts +10 -6
  319. package/dist/trace/ledger-sink.js +2 -2
  320. package/dist/trace/model-segment.d.ts +55 -25
  321. package/dist/trace/model-segment.js +101 -33
  322. package/dist/trace/project.d.ts +25 -5
  323. package/dist/trace/project.js +22 -0
  324. package/dist/trace/redact.d.ts +61 -9
  325. package/dist/trace/redact.js +1490 -468
  326. package/dist/trace/self-minted-wire.d.ts +745 -24
  327. package/dist/trace/self-minted-wire.js +239 -9
  328. package/dist/trace/wire-projection-faces.d.ts +2 -2
  329. package/dist/trace/wire-projection-faces.js +2 -2
  330. package/dist/verifier-pause-card.d.ts +33 -5
  331. package/dist/verifier-pause-card.js +15 -10
  332. package/dist/web-admin-client/apply-effective.d.ts +12 -16
  333. package/dist/web-admin-client/apply-effective.js +109 -9
  334. package/dist/web-admin-client/effective-keys.js +2 -0
  335. package/dist/web-admin-client/types.d.ts +4 -0
  336. package/dist/workspace-space.d.ts +19 -3
  337. package/dist/workspace-space.js +8 -4
  338. package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -1
  339. package/package.json +3 -2
  340. package/wire-changes/server@7.142.0.json +639 -0
  341. package/wire-changes/server@7.143.0.json +1167 -0
@@ -24,6 +24,7 @@ import { FileError, ExecutionError, RemoteExecutionError, type ExecutionEnv, typ
24
24
  import { type SandboxReadFloorKnob } from "../execution-lane-caps.js";
25
25
  import { type SandboxReadFloor } from "./sandbox-read-floor.js";
26
26
  import { type LaneHomeConfig } from "../lane-home-probe.js";
27
+ import type { WorkspaceFill, WorkspaceFillOf } from "./workspace-fill.js";
27
28
  /** Options accepted by `ExecutionEnv.exec` (core does not re-export the type; derive it from the seam). */
28
29
  type ExecOpts = Parameters<ExecutionEnv["exec"]>[1];
29
30
  /** Minimal optional observability hooks (kept structural so the adapter stays standalone-testable). */
@@ -75,6 +76,8 @@ export interface RemoteContainerEnvConfig extends RemoteEnvObservers, LaneHomeCo
75
76
  dataTimeoutMs?: number;
76
77
  /** `SANDBOX_READ_FLOOR`(keep | off;缺席 ⇒ keep):本沙箱守不守读拒表的字节地板 = 读地板模块服务本车道 ∧ 本键不是 off(`sandbox-read-floor.ts`)。 */
77
78
  sandboxReadFloor?: SandboxReadFloorKnob;
79
+ /** 恢复点的填充座(`workspace-fill.ts`;工厂按 run 装配):沙箱新建 / 恢复之后、交给本环境之前,经本适配器已连上的通道往工作区里放内容。缺席 ⇒ 不放。 */
80
+ workspaceFill?: WorkspaceFill;
78
81
  }
79
82
  /** Minimal slice of the E2B `Sandbox` static API the adapter uses — injectable so tests pass a fake. */
80
83
  export interface SandboxApi {
@@ -124,9 +127,12 @@ export declare class RemoteContainerExecutionEnv implements RemoteExecutionEnv,
124
127
  private destroyed;
125
128
  /** 家目录的座(主张在场 ⇒ 每只沙箱对证 · 否则建沙箱那一拍实测 · 实测缺席 ⇒ 缺席 + 一行 warn)。 */
126
129
  private readonly homeSeat;
127
- /** 家目录:沙箱答了而与主张不一致(或答的不是绝对路径)⇒ 这只环境的拒,记一次、此后每次连接 / 恢复原样回它(同一模板同一个答案:不再建沙箱、不再问)。 */
128
- private homeRefusal?;
129
- /** In-flight connect/resume, memoized so concurrent lazy first-use OR resume provisions exactly one VM (no double-bill). */
130
+ /** 这只环境的拒 —— 记一次、此后每次连接 / 恢复原样回它(同一模板同一个答案:不再建沙箱、不再问)。两个写者:家目录(沙箱答了而与主张不一致,或答的不是绝对路径)
131
+ * 与恢复点的填充(换一台沙箱也是同一个答的拒:种子不是项目包、摘要不符、镜像没有 `tar`、镜像预置撞名 —— `FillOutcome.standing`)。 */
132
+ private connectRefusal?;
133
+ /** In-flight connect/resume, memoized so concurrent lazy first-use OR resume provisions exactly one VM (no double-bill). `target` = the snapshot a resume
134
+ * restores (`undefined` = a fresh sandbox): {@link resumeVM} shares only a resume of the SAME snapshot — a connect for anything else is not the
135
+ * workspace it is asked to restore (it waits that one out, then releases the sandbox it left). */
130
136
  private connecting?;
131
137
  /** Count of exec/execStream calls in flight — `suspendVM` refuses while > 0 (council #4: never snapshot a running command). */
132
138
  private activeCommands;
@@ -150,6 +156,8 @@ export declare class RemoteContainerExecutionEnv implements RemoteExecutionEnv,
150
156
  /** 地板模块的三件原语。引导命令经 {@link startIn}(起动形 `bootstrap`:只在附着中合法);放置 = root 建目录 → `files.write`(root)写暂存件 →
151
157
  * root `chmod 0755 && mv -f`;中继 = 以模块给的身份起一只长连后台命令(stdin 开着:`sendStdin` 写答,stdout 回调读问)。 */
152
158
  private floorTransport;
159
+ /** 收据句柄。还没连上(懒环境:续跑腿的引擎在 `resumeVM` **之前**先取它比车道)⇒ 未连接形 `{ sandboxId: "(unconnected)", provider, mountPath }`(与 k8s 车道同形),
160
+ * 不抛 —— 抛了,续跑腿在恢复之前就失败。 */
153
161
  workspaceHandle(): WorkspaceHandle;
154
162
  /**
155
163
  * Public host for a port inside the sandbox (E2B reverse proxy → `<port>-<id>.e2b.app`). The LSP sidecar
@@ -197,6 +205,11 @@ export declare class RemoteContainerExecutionEnv implements RemoteExecutionEnv,
197
205
  ok: false;
198
206
  error: RemoteExecutionError;
199
207
  }>;
208
+ /** The one walk of a resume ({@link resumeVM} memoizes it). */
209
+ private resumeWalk;
210
+ /** Kill the fresh sandbox this env holds (minted before a restore point that restores another): no second billable VM, no answer from the wrong workspace.
211
+ * The connect memo is the calling resume's own ({@link resumeVM}) — left as it is. */
212
+ private releaseMinted;
200
213
  private doResumeVM;
201
214
  /** Cross-replica re-attach to a still-running VM = v2 ([ref] council #15: v1.5 always snapshots→resumeVM). */
202
215
  reconnect(_sessionToken: SessionToken): Promise<{
@@ -227,6 +240,10 @@ export declare class RemoteContainerExecutionEnv implements RemoteExecutionEnv,
227
240
  * 上界 = 控制面 RPC 的墙钟(`rpcTimeoutMs`:问一个环境变量,不是跑用户命令)。
228
241
  */
229
242
  private homeVerdict;
243
+ /** 恢复点的填充:有座 ⇒ 经这只沙箱的通道({@link fillChannel})放(`origin` = 新建的沙箱 / 恢复出来的沙箱);没有 ⇒ 什么都不放。 */
244
+ private fillAt;
245
+ /** 恢复点手里的通道:固定命令经唯一起动接缝(起动形 `adapter`,与引擎命令同一执行用户)、写 = `files.write`(与文件面同一个缺省用户);两件都受数据墙钟。 */
246
+ private fillChannel;
230
247
  /** BL-31 — (re)start the periodic sandbox-lifetime extension. `setTimeout(timeoutMs)` resets the auto-kill window
231
248
  * from now; we re-arm at ~80% of the (clamped, ≤1h) window so a long-held sandbox never expires mid-run. A no-op
232
249
  * when paused/destroyed; `unref`'d so it never keeps the process alive; cleared on destroy. */
@@ -380,6 +397,8 @@ export declare class RemoteContainerExecutionEnv implements RemoteExecutionEnv,
380
397
  * so a task that never touches the hand (e.g. a leader that only plans) pays zero VM cost. The Runner owns the
381
398
  * lifetime and calls `destroy()` on task end (via `hasDestroy`); a never-used env's destroy is a no-op.
382
399
  */
383
- export declare function e2bExecutionEnvFactory(config: RemoteContainerEnvConfig, deps?: RemoteContainerEnvDeps): ExecutionEnvFactory;
400
+ export declare function e2bExecutionEnvFactory(config: Omit<RemoteContainerEnvConfig, "workspaceFill"> & {
401
+ readonly workspaceFillOf?: WorkspaceFillOf;
402
+ }, deps?: RemoteContainerEnvDeps): ExecutionEnvFactory;
384
403
  export {};
385
404
  //# sourceMappingURL=remote-env-e2b.d.ts.map
@@ -35,7 +35,7 @@ export class RemoteContainerExecutionEnv {
35
35
  handle;
36
36
  destroyed = false;
37
37
  homeSeat;
38
- homeRefusal;
38
+ connectRefusal;
39
39
  connecting;
40
40
  activeCommands = 0;
41
41
  paused = false;
@@ -138,10 +138,7 @@ export class RemoteContainerExecutionEnv {
138
138
  };
139
139
  }
140
140
  workspaceHandle() {
141
- if (!this.handle) {
142
- throw new RemoteExecutionError("connect_failed", "workspaceHandle() called before connect()");
143
- }
144
- return this.handle;
141
+ return this.handle ?? { sandboxId: "(unconnected)", provider: PROVIDER, mountPath: this.cwd };
145
142
  }
146
143
  async getHost(port) {
147
144
  const conn = await this.ensureConnected();
@@ -162,17 +159,18 @@ export class RemoteContainerExecutionEnv {
162
159
  }
163
160
  if (this.destroyed)
164
161
  return { ok: false, error: new RemoteExecutionError("connect_failed", "execution env already destroyed") };
165
- if (this.homeRefusal)
166
- return { ok: false, error: this.homeRefusal };
162
+ if (this.connectRefusal)
163
+ return { ok: false, error: this.connectRefusal };
167
164
  if (this.paused)
168
165
  return { ok: false, error: new RemoteExecutionError("connect_failed", "execution env is suspended (paused) — resumeVM(snapshotId) before use") };
169
166
  if (this.sbx)
170
167
  return ok(this.workspaceHandle());
171
168
  if (this.connecting)
172
- return this.connecting;
173
- this.connecting = this.doConnect(config);
174
- const r = await this.connecting;
175
- if (!r.ok)
169
+ return this.connecting.promise;
170
+ const mine = { target: undefined, promise: this.doConnect(config) };
171
+ this.connecting = mine;
172
+ const r = await mine.promise;
173
+ if (!r.ok && this.connecting === mine)
176
174
  this.connecting = undefined;
177
175
  return r;
178
176
  }
@@ -201,6 +199,14 @@ export class RemoteContainerExecutionEnv {
201
199
  await sbx.kill().catch(() => { });
202
200
  return { ok: false, error: new RemoteExecutionError("connect_failed", "execution env destroyed during connect") };
203
201
  }
202
+ const filled = await this.fillAt(sbx, this.cfg.mountPath, "minted");
203
+ if (!filled.ok || this.destroyed) {
204
+ await sbx.kill().catch(() => { });
205
+ this.cfg.metrics?.inc("remote_env_connect_total", { provider: PROVIDER, result: "error" });
206
+ if (!filled.ok && filled.standing)
207
+ this.connectRefusal = filled.error;
208
+ return { ok: false, error: filled.ok ? new RemoteExecutionError("connect_failed", "execution env destroyed during connect") : filled.error };
209
+ }
204
210
  this.sbx = sbx;
205
211
  this.paused = false;
206
212
  this.startKeepAlive();
@@ -250,20 +256,50 @@ export class RemoteContainerExecutionEnv {
250
256
  return { ok: false, error: this.remoteError(e, options?.abortSignal?.aborted ? "aborted" : "unknown") };
251
257
  }
252
258
  }
253
- async resumeVM(snapshotId, options) {
259
+ resumeVM(snapshotId, options) {
254
260
  if (this.destroyed)
255
- return { ok: false, error: new RemoteExecutionError("connect_failed", "env already destroyed") };
256
- if (this.homeRefusal)
257
- return { ok: false, error: this.homeRefusal };
261
+ return Promise.resolve({ ok: false, error: new RemoteExecutionError("connect_failed", "env already destroyed") });
262
+ if (this.connectRefusal)
263
+ return Promise.resolve({ ok: false, error: this.connectRefusal });
258
264
  if (this.sbx && !this.paused && this.sbx.sandboxId === snapshotId)
259
- return ok(this.workspaceHandle());
260
- if (this.connecting)
261
- return this.connecting;
262
- this.connecting = this.doResumeVM(snapshotId, options);
263
- const r = await this.connecting;
264
- if (!r.ok)
265
- this.connecting = undefined;
266
- return r;
265
+ return Promise.resolve(ok(this.workspaceHandle()));
266
+ const inFlight = this.connecting;
267
+ if (inFlight?.target === snapshotId)
268
+ return inFlight.promise;
269
+ const mine = { target: snapshotId, promise: this.resumeWalk(inFlight, snapshotId, options) };
270
+ this.connecting = mine;
271
+ const forget = () => {
272
+ if (this.connecting === mine)
273
+ this.connecting = undefined;
274
+ };
275
+ mine.promise.then((r) => {
276
+ if (!r.ok)
277
+ forget();
278
+ }, forget);
279
+ return mine.promise;
280
+ }
281
+ async resumeWalk(inFlight, snapshotId, options) {
282
+ if (inFlight !== undefined) {
283
+ await inFlight.promise;
284
+ if (this.destroyed)
285
+ return { ok: false, error: new RemoteExecutionError("connect_failed", "env already destroyed") };
286
+ if (this.sbx && !this.paused && this.sbx.sandboxId === snapshotId)
287
+ return ok(this.workspaceHandle());
288
+ }
289
+ if (this.sbx && !this.paused)
290
+ await this.releaseMinted(snapshotId);
291
+ return this.doResumeVM(snapshotId, options);
292
+ }
293
+ async releaseMinted(resumed) {
294
+ const sbx = this.sbx;
295
+ if (sbx === undefined)
296
+ return;
297
+ this.sbx = undefined;
298
+ this.handle = undefined;
299
+ this.stopKeepAlive();
300
+ await this.disposeBackgroundShells();
301
+ await this.rpc("sandbox.kill", () => sbx.kill()).catch((e) => this.cfg.logger?.warn("remote_env_minted_release_failed", { sandboxId: sbx.sandboxId, error: errMsg(e) }));
302
+ this.cfg.logger?.info?.("remote_env_minted_released", { sandboxId: sbx.sandboxId, resumed });
267
303
  }
268
304
  async doResumeVM(snapshotId, options) {
269
305
  try {
@@ -288,6 +324,18 @@ export class RemoteContainerExecutionEnv {
288
324
  this.cfg.metrics?.inc("remote_env_resume_total", { provider: PROVIDER, result: "error" });
289
325
  return { ok: false, error: home };
290
326
  }
327
+ const filled = await this.fillAt(sbx, restoredRoot, "restored");
328
+ if (this.destroyed) {
329
+ await sbx.kill().catch(() => { });
330
+ return { ok: false, error: new RemoteExecutionError("connect_failed", "execution env destroyed during resume") };
331
+ }
332
+ if (!filled.ok) {
333
+ await this.rpc("sandbox.pause", (signal) => sbx.pause({ signal }), undefined, this.cfg.dataTimeoutMs).catch((e) => this.cfg.logger?.warn?.("remote_env_fill_refused_repause_failed", { sandboxId: sbx.sandboxId, error: errMsg(e) }));
334
+ this.cfg.metrics?.inc("remote_env_resume_total", { provider: PROVIDER, result: "error" });
335
+ if (filled.standing)
336
+ this.connectRefusal = filled.error;
337
+ return { ok: false, error: filled.error };
338
+ }
291
339
  this.sbx = sbx;
292
340
  this.paused = false;
293
341
  this.startKeepAlive();
@@ -340,9 +388,39 @@ export class RemoteContainerExecutionEnv {
340
388
  return undefined;
341
389
  const error = new RemoteExecutionError("connect_failed", verdict.refusal);
342
390
  if (verdict.answered)
343
- this.homeRefusal = error;
391
+ this.connectRefusal = error;
344
392
  return error;
345
393
  }
394
+ fillAt(sbx, root, origin) {
395
+ return this.cfg.workspaceFill === undefined ? Promise.resolve({ ok: true }) : this.cfg.workspaceFill.fill(this.fillChannel(sbx), root, origin);
396
+ }
397
+ fillChannel(sbx) {
398
+ return {
399
+ run: async (command) => {
400
+ const s = this.startIn(ADAPTER_START, command, undefined);
401
+ if (!s.ok)
402
+ return { ok: false, error: s.error.message };
403
+ try {
404
+ const r = await this.rpc("workspace.fill", (signal) => this.runIn(sbx, s.value, { signal, timeoutMs: this.cfg.dataTimeoutMs }), undefined, this.cfg.dataTimeoutMs);
405
+ return { ok: true, exitCode: r.exitCode, stdout: r.stdout, stderr: r.stderr };
406
+ }
407
+ catch (e) {
408
+ if (e instanceof CommandExitError)
409
+ return { ok: true, exitCode: e.exitCode, stdout: e.stdout, stderr: e.stderr };
410
+ return { ok: false, error: errMsg(e) };
411
+ }
412
+ },
413
+ write: async (abs, bytes) => {
414
+ try {
415
+ await this.rpc("files.write", (signal) => sbx.files.write(abs, toArrayBuffer(bytes), { signal }), undefined, this.cfg.dataTimeoutMs);
416
+ return { ok: true };
417
+ }
418
+ catch (e) {
419
+ return { ok: false, error: errMsg(e) };
420
+ }
421
+ },
422
+ };
423
+ }
346
424
  startKeepAlive() {
347
425
  this.stopKeepAlive();
348
426
  const everyMs = Math.max(30_000, Math.floor(this.cfg.timeoutMs * 0.8));
@@ -1130,10 +1208,15 @@ export class RemoteContainerExecutionEnv {
1130
1208
  }
1131
1209
  }
1132
1210
  export function e2bExecutionEnvFactory(config, deps) {
1133
- return (ctx) => new RemoteContainerExecutionEnv({
1134
- ...config,
1135
- metadata: { ...config.metadata, semaManaged: "1", sessionId: ctx.sessionId, ...(ctx.taskId ? { taskId: ctx.taskId } : {}) },
1136
- }, deps);
1211
+ const { workspaceFillOf, ...base } = config;
1212
+ return (ctx) => {
1213
+ const workspaceFill = workspaceFillOf?.(ctx);
1214
+ return new RemoteContainerExecutionEnv({
1215
+ ...base,
1216
+ metadata: { ...base.metadata, semaManaged: "1", sessionId: ctx.sessionId, ...(ctx.taskId ? { taskId: ctx.taskId } : {}) },
1217
+ ...(workspaceFill !== undefined ? { workspaceFill } : {}),
1218
+ }, deps);
1219
+ };
1137
1220
  }
1138
1221
  function errMsg(e) {
1139
1222
  return e instanceof Error ? e.message : String(e);
@@ -123,6 +123,9 @@ export interface K8sEnvConfig extends LaneHomeConfig {
123
123
  /** Run-end outcome seat — called once per `destroy()` that attempted a space snapshot (the factory's caller binds it
124
124
  * to the run, so the run's terminal frame can carry `workspaceSnapshot: "failed"`). */
125
125
  onWorkspaceSnapshot?: (outcome: "saved" | "failed") => void;
126
+ /** 恢复点的填充座(`workspace-fill.ts`;工厂按 run 装配):pod 的工作区铸出 / 恢复之后、`connect` / `resumeVM` 交还之前,经 {@link RemoteK8sExecutionEnv} 自己的
127
+ * exec 通道(不经公开面 —— 连接进行中公开面会等同一只连接记忆)往工作区里放内容。缺席 ⇒ 不放。 */
128
+ workspaceFill?: WorkspaceFill;
126
129
  /**
127
130
  * 🔴 ADDITIVE pod-spec patch (a SERVICE-side adapter seam, NOT a core seam: the K8s pod shape is
128
131
  * provider-specific, so it stays in the adapter per [ref]). A deployment supplies extra volumes / volumeMounts
@@ -171,6 +174,7 @@ import { type SandboxSecretSeatKind, type SandboxSecretVerb } from "./k8s-exec-p
171
174
  export { type PodSpecPatch, applyPodSpecPatch } from "./k8s-exec-protocol.js";
172
175
  import { type SandboxPodApi, type SandboxPodListing } from "./k8s-pod-reaper.js";
173
176
  import { type SandboxLeaseEntryInput } from "../sandbox-git-lease.js";
177
+ import type { WorkspaceFill } from "./workspace-fill.js";
174
178
  type ConnectResult = {
175
179
  ok: true;
176
180
  value: WorkspaceHandle;
@@ -318,9 +322,12 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
318
322
  private readonly inFlight;
319
323
  /** Resolvers of {@link whenIdle}: woken when the last command in flight ends. */
320
324
  private idleWaiters;
321
- /** This env's one connect in flight (see {@link connect}): the explicit connect, the lazy connect and `reconnect` that arrive while it runs
322
- * share it — one pod creation, one restore (the E2B race lesson). Cleared the moment it settles, whatever the outcome. */
325
+ /** This env's one lifecycle walk in flight — a connect ({@link connect}) or a resume ({@link resumeVM}): the explicit connect, the lazy connect of
326
+ * the first operation and `reconnect` that arrive while it runs share its answer — one pod creation, one restore, one fill (the E2B race lesson).
327
+ * Cleared the moment it settles, whatever the outcome (by the walk that set it, never by an earlier one). */
323
328
  private connectInFlight?;
329
+ /** The resume among them, with the snapshot it restores: a second `resumeVM` of the same snapshot shares it (one restore, one pod). */
330
+ private resumeInFlight?;
324
331
  /** The env's refusal — a fact of this env until `destroy`, written once ({@link holdRefusal}) and answered as it stands to every later connect (and to
325
332
  * every later pod creation: {@link provision}): the same refusal, zero pods, zero store requests, no second line. Two causes write it:
326
333
  * the space restore (`latest` names an archive that is there and did not come back — {@link restoreSnapshot}) and the pod's admission (the cluster created
@@ -355,6 +362,7 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
355
362
  private cacheUnavailableSaid;
356
363
  private readonly logger?;
357
364
  private readonly onWorkspaceSnapshot?;
365
+ private readonly workspaceFill?;
358
366
  private readonly cacheMisses?;
359
367
  constructor(config: K8sEnvConfig, deps?: K8sEnvDeps);
360
368
  /** The lease seat of the pod this env holds now — `undefined` without a broker seat or without a pod (the server's lease writes follow it: a resumed env holds a new pod and a new seat). */
@@ -378,6 +386,7 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
378
386
  * loud `workspace_latest_dangling`, the pointer deleted, an empty workspace); absent (404 — the key, with the bucket there) ⇒ a fresh pod; a read that
379
387
  * FAILS ⇒ a loud `connect_failed` — a 404 `NoSuchBucket` included ({@link refuseMissingBucket}) — never a silent fresh workspace (a run that believes it resumed while it did not is
380
388
  * the worst form). Once the pod holds the workspace, this env arms its fence seat (its destroy will commit).
389
+ * The same walk ({@link establish}) is the restore point of a parked run's resumed leg whose park packed nothing ({@link resumeVM}).
381
390
  * Persistence off / no store ⇒ a fresh pod, exactly as before. Persistence on but no such session (the occupant absent) ⇒ a
382
391
  * fresh pod and one `workspace_space_unavailable` line (no restore by any other key). The occupant read FAULTED ⇒ the same
383
392
  * loud `connect_failed` as a failed `latest` read, no pod ({@link provision} refuses it — every entry that would create one).
@@ -389,8 +398,23 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
389
398
  * as it stands to every later connect on every lane — the previous commit is not waited on again, `latest` is not read again, no pod is created.
390
399
  */
391
400
  connect(config?: RemoteConnectConfig): Promise<ConnectResult>;
392
- /** The one walk of a connect ({@link connect} runs it once at a time). */
401
+ /** The one walk of a connect ({@link connect} runs it once at a time) — also the resumed leg's walk when its park packed nothing ({@link restorePointOf},
402
+ * under the resume's own hold of the same gate). */
393
403
  private establish;
404
+ /**
405
+ * The restore point's fill (`workspace-fill.ts`): a pod whose workspace this env just minted or restored is handed over only once the fill seat placed
406
+ * its content — through {@link fillChannel} (this adapter's own exec, never the public face: inside a connect the public face waits on that very connect).
407
+ * A fill that does not complete releases the pod (no tool and no run-end snapshot may see a half-filled workspace); a refusal that would answer the same
408
+ * again (`standing`) is held for the env ({@link holdRefusal}). No seat ⇒ the pod as it came. `origin` tells the seat whether the workspace was minted
409
+ * (a new pod with nothing restored: the space off / unavailable / without `latest`, or a dangling restore point — `latest` or a park snapshot whose archive is gone)
410
+ * or restored (the space's `latest`, or a park snapshot whose archive came back). A park that packed nothing resumes through a new connect, so it reads as that connect does.
411
+ */
412
+ private settle;
413
+ /** The restore point's channel: a fixed command through the one start seam (start form `adapter`, the engine's commands' identity) and a write in
414
+ * {@link writeChunked}'s form — both straight on {@link runExec} with the data bound (never {@link ensureConnected}). */
415
+ private fillChannel;
416
+ /** Release the pod this env holds (its workspace is not handed over): the pod deleted, its seats cleared. No pod ⇒ nothing. */
417
+ private releasePod;
394
418
  /** This env holds a workspace its `destroy()` will commit ⇒ arm its seat on the space's commit fence (from here the
395
419
  * run's terminal write fences the space; `workspace-space-commit.ts`). Each write of this run's row sets its deadline to
396
420
  * now + the upload's own wall-clock bound (`dataTimeoutMs`). No-op unless the space lane is open. */
@@ -426,9 +450,11 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
426
450
  * never its text. Not a knob: there is no honest way to run a space we could not read — a retry of the run reads it again.
427
451
  */
428
452
  private refuseUnreadableOccupant;
429
- /** Every space-lane operator line: the space is named by its incarnation's log prefix only, and free text (a curl
430
- * stderr, a fetch error) passes {@link redactIncarnations} — the full token never reaches a log body. */
453
+ /** Every space-lane operator line: the space is named by its incarnation's log prefix only ({@link snapshotLine} does the rest). */
431
454
  private spaceLine;
455
+ /** Every snapshot operator line, both lanes — the ONE redaction seat: each string field (a key, a curl stderr, a fetch error, an effect) passes
456
+ * {@link redactIncarnations}, so a full incarnation-shaped token never reaches a log body, whatever text carried it there. */
457
+ private snapshotLine;
432
458
  /** A fresh pod (create → Running → workspace root), bounded retry — THE seat every pod of this env is created through
433
459
  * ({@link connect} and, via {@link restoreSnapshot}, {@link resumeVM}). A lane keyed by an occupant read that faulted ⇒ refused
434
460
  * here, before any request ({@link refuseUnreadableOccupant}): never retried (the reading is this env's, fixed at construction). */
@@ -630,9 +656,14 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
630
656
  */
631
657
  private uploadSnapshot;
632
658
  /**
633
- * Resume a workspace snapshot onto a FRESH pod (resume = executionEnvFactory rebuild + resumeVM):
634
- * provision a pod, then download + untar the snapshot into the workspace ({@link restoreSnapshot}, lane `park`). A
635
- * missing object (empty/plan-only snapshot) resumes as a clean workspace.
659
+ * Resume a parked run's workspace onto a FRESH pod (resume = executionEnvFactory rebuild + resumeVM). Where the leg's workspace comes from is
660
+ * read off the park's snapshot id — it says what the park packed ({@link snapshotIdHolds}), never guessed from what the store answers:
661
+ * - an archive ⇒ provision a pod, then download + untar it into the workspace ({@link restoreSnapshot}, lane `park`): it came back ⇒ `restored`
662
+ * (never seeded); it is not there ⇒ a dangling restore point, the same rule on both lanes ({@link dropDangling}: one line, an empty workspace);
663
+ * - nothing (the env held no pod when it parked — the run parked before anything touched its hand) ⇒ there is no workspace of the park to
664
+ * restore, so the leg's restore point is the one a new connect has ({@link establish}): space open ⇒ the previous commit waited out and
665
+ * `latest` restored (none ⇒ a fresh workspace), space off ⇒ a fresh workspace — never a fresh workspace beside a `latest` that the leg's
666
+ * run-end commit would then overwrite. No archive is asked for under such an id.
636
667
  *
637
668
  * [ref]①(priorHandle 根保真)——k8s 走**诚实臂**而非绑定臂:pod 的 workspace volume 挂在**当前**
638
669
  * 配置根(cfg.mountPath),往 priorHandle.mountPath 绑=往容器 rootfs untar 大工作区,ephemeral-storage
@@ -641,14 +672,16 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
641
672
  * 变更窗的分歧由 core 侧 fail-closed reopen 兜底,审批不烧错根。
642
673
  */
643
674
  resumeVM(snapshotId: SnapshotId, options?: VmLifecycleOptions): Promise<ConnectResult>;
644
- /**
645
- * The ONE tar download (both lanes): provision a FRESH pod, download + untar the lane's archive into the workspace.
646
- * A missing archive (404) starts from the clean workspace on both lanes — what differs is what it means:
647
- * - park: a plan-only suspend has no object — nothing to say;
648
- * - space: `latest` dangles (its pointer is only written after a successful upload, so the archive was removed later —
649
- * by the bucket's lifecycle rule or a hand): the data is gone by an operator rule ⇒ loud and continuable —
650
- * {@link dropDanglingLatest} (one `workspace_latest_dangling` line, the pointer deleted); the run's own run-end
651
- * snapshot then becomes the new `latest`.
675
+ /** The one walk of a resume ({@link resumeVM} runs it under the connect gate). */
676
+ private resumeWalk;
677
+ /** The resumed leg's restore point, chosen by what the park's id names ({@link resumeVM}) — a closed set, one arm each. */
678
+ private restorePointOf;
679
+ /**
680
+ * The ONE tar download (both lanes): provision a FRESH pod, download + untar the lane's archive into the workspace. Only an id that names an
681
+ * archive reaches it ({@link snapshotIdHolds}: a park that packed nothing resumes through {@link establish}; `latest` names only an object
682
+ * that was written). So a missing archive (404) is one fact on both lanes — the restore point names data that is gone (removed later, by the
683
+ * bucket's lifecycle rule or a hand) ⇒ loud and continuable, ONE rule: {@link dropDangling} (one `workspace_latest_dangling` line), and the
684
+ * run continues on the clean workspace, origin `minted` (no restorable tree ⇒ the restore point seeds it, exactly as on a fresh connect).
652
685
  * An attempt that does not complete releases the pod it provisioned: no tool and no run-end snapshot may ever see a torn
653
686
  * workspace. A transient class ({@link restoreFailureIsTransient}) is tried again on a fresh pod after the `retry.backoffMs`
654
687
  * pause, up to the lane's {@link RESTORE_MAX_ATTEMPTS}; a non-transient one ends the restore at once. The lane then says what
@@ -665,12 +698,18 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
665
698
  /** The pause before a restore's next attempt (`retry.backoffMs`, the adapter's one retry pause). `false` ⇒ aborted (now or during it). */
666
699
  private restorePause;
667
700
  /**
668
- * `latest` names an archive that is not there ([ref]): one `workspace_latest_dangling{space, key, deleted}` line and the
669
- * pointer is deleted (the next run must not trip on it again); the run continues on the empty workspace. A pointer
670
- * delete that fails rides on the same line (`deleted: false` + the error) — the next run then says it once more.
671
- * This env is the space's only writer here (the commit fence admits one per space), so the delete is a plain one.
672
- */
673
- private dropDanglingLatest;
701
+ * A restore point names an archive that is not there — the data is gone by an operator rule (a bucket lifecycle rule, a hand): loud and
702
+ * continuable, ONE rule on both lanes — one `workspace_latest_dangling{lane, key, …}` line, and the run continues on the empty workspace
703
+ * {@link restoreSnapshot} hands over. `key` = the object the id names, spelled by {@link snapshotBase} (the one spelling of both partitions).
704
+ * What each lane adds is only what it holds:
705
+ * - space: its `latest` pointer is deleted (the next run must not trip on it again); the line carries `space` and `deleted` — a delete that
706
+ * fails rides on the same line (`deleted: false` + the error) and the next run says it once more. This env is the space's only writer here
707
+ * (the commit fence admits one per space), so the delete is a plain one. The run's own run-end snapshot then becomes the new `latest`;
708
+ * - park: there is no pointer to drop (the id lives in the engine's checkpoint); the line carries the session id. With the space open, the
709
+ * resumed leg's run-end snapshot then becomes the space's new `latest`.
710
+ * Both lines pass the one redaction seat ({@link snapshotLine}).
711
+ */
712
+ private dropDangling;
674
713
  /**
675
714
  * Honest post-resume consistency ([ref] §5 council #8): the workspace FILES are restored byte-for-byte
676
715
  * from the snapshot, so read-before-edit hashing already lines up — there's nothing to re-fetch. In-VM