@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.
- package/MIGRATION.md +657 -0
- package/USAGE.md +102 -30
- package/dist/adoption/plan.js +22 -0
- package/dist/approval-ask-audit-store.d.ts +61 -43
- package/dist/approval-ask-audit-store.js +69 -44
- package/dist/approval-ask-machine.d.ts +15 -7
- package/dist/approval-ask-machine.js +10 -4
- package/dist/approval-card.d.ts +126 -27
- package/dist/approval-card.js +103 -23
- package/dist/approval-crash-convergence.d.ts +17 -7
- package/dist/approval-crash-convergence.js +94 -22
- package/dist/approval-deny-reasons.d.ts +34 -30
- package/dist/approval-deny-reasons.js +21 -6
- package/dist/approval-policy-settlement.d.ts +1 -1
- package/dist/approval-queue-kind.d.ts +27 -0
- package/dist/approval-queue-kind.js +6 -0
- package/dist/approval-reconciler.d.ts +41 -9
- package/dist/approval-reconciler.js +45 -42
- package/dist/audit.js +4 -2
- package/dist/auth-bridge.d.ts +9 -6
- package/dist/auth-bridge.js +9 -3
- package/dist/boot/adoption.js +2 -1
- package/dist/boot/budget-tracing.d.ts +17 -1
- package/dist/boot/budget-tracing.js +10 -6
- package/dist/boot/device-lane.d.ts +1 -1
- package/dist/boot/execution-env.d.ts +24 -4
- package/dist/boot/execution-env.js +26 -23
- package/dist/boot/execution-lane.js +2 -1
- package/dist/boot/exit-boundary.js +5 -4
- package/dist/boot/governance-seams.d.ts +26 -41
- package/dist/boot/governance-seams.js +61 -28
- package/dist/boot/late-binds.d.ts +7 -4
- package/dist/boot/late-binds.js +3 -1
- package/dist/boot/leader.js +2 -4
- package/dist/boot/memory-consolidation.d.ts +0 -8
- package/dist/boot/memory-consolidation.js +5 -4
- package/dist/boot/parked-revive-gate.js +2 -1
- package/dist/boot/permission-rules-audit.d.ts +0 -28
- package/dist/boot/permission-rules-audit.js +2 -1
- package/dist/boot/read-deny-anchor-audit.js +2 -1
- package/dist/boot/reapers.js +9 -7
- package/dist/boot/resolve-spec.d.ts +1 -1
- package/dist/boot/resolve-spec.js +19 -10
- package/dist/boot/retention-lane.js +5 -3
- package/dist/boot/runner-deps.d.ts +10 -7
- package/dist/boot/runner-deps.js +20 -29
- package/dist/boot/runtime-caps.js +3 -2
- package/dist/boot/session-faces.js +4 -3
- package/dist/boot/shutdown.d.ts +9 -0
- package/dist/boot/shutdown.js +19 -4
- package/dist/boot/stage-02-web-admin-pull.js +3 -0
- package/dist/boot/stage-03-store-backend.d.ts +4 -1
- package/dist/boot/stage-03-store-backend.js +1 -2
- package/dist/boot/stage-04-stores.d.ts +5 -2
- package/dist/boot/stage-04-stores.js +6 -7
- package/dist/boot/stage-05-execution-env.d.ts +6 -3
- package/dist/boot/stage-05-execution-env.js +8 -6
- package/dist/boot/stage-06-runners.d.ts +6 -3
- package/dist/boot/stage-06-runners.js +3 -4
- package/dist/boot/stage-07-capability-layer.d.ts +6 -3
- package/dist/boot/stage-07-capability-layer.js +7 -2
- package/dist/boot/stage-08-reapers.d.ts +6 -3
- package/dist/boot/stage-08-reapers.js +3 -2
- package/dist/boot/stage-09-leader.d.ts +6 -3
- package/dist/boot/stage-10-http-server.d.ts +6 -3
- package/dist/boot/stage-10-http-server.js +14 -5
- package/dist/boot/stores.d.ts +5 -2
- package/dist/boot/stores.js +10 -9
- package/dist/boot/web-admin.d.ts +5 -1
- package/dist/boot/web-admin.js +48 -36
- package/dist/boot/webfetch-summarize-lane.js +2 -1
- package/dist/boot/workflow-orchestration.js +3 -2
- package/dist/capabilities/builtin-tools.d.ts +2 -1
- package/dist/capabilities/builtin-tools.js +2 -4
- package/dist/capabilities/composite-members.d.ts +2 -1
- package/dist/capabilities/composite-members.js +2 -1
- package/dist/capabilities/hands-lane.d.ts +9 -39
- package/dist/capabilities/hands-lane.js +8 -13
- package/dist/capabilities/mcp-probe.d.ts +3 -2
- package/dist/capabilities/scenarios.d.ts +11 -1
- package/dist/capabilities/scenarios.js +1 -0
- package/dist/capabilities/skills.d.ts +1 -17
- package/dist/capabilities/skills.js +0 -8
- package/dist/capability-facts.d.ts +31 -7
- package/dist/capability-facts.js +27 -4
- package/dist/card-void.d.ts +6 -9
- package/dist/config-catalog.js +2 -1
- package/dist/config-dir-trust.js +58 -29
- package/dist/config-invariants.d.ts +7 -1
- package/dist/config-invariants.js +7 -0
- package/dist/config-provider.d.ts +10 -0
- package/dist/config-provider.js +15 -4
- package/dist/config-root-migration.d.ts +13 -0
- package/dist/config-root-migration.js +99 -0
- package/dist/config-types.d.ts +19 -8
- package/dist/config.d.ts +10 -3
- package/dist/config.js +18 -4
- package/dist/delegated-session-owner.d.ts +5 -3
- package/dist/delegated-session-owner.js +1 -1
- package/dist/device-ws-protocol.d.ts +1 -0
- package/dist/device-ws-protocol.js +2 -1
- package/dist/env-model-table-gate.d.ts +53 -0
- package/dist/env-model-table-gate.js +53 -0
- package/dist/execution-lane-caps.d.ts +2 -1
- package/dist/fleet/fleet-bus.d.ts +34 -55
- package/dist/fleet/fleet-bus.js +35 -100
- package/dist/fleet/fleet-reconciler.d.ts +4 -4
- package/dist/fleet/fleet-reconciler.js +1 -1
- package/dist/fleet/subagent-tail-bus.d.ts +14 -11
- package/dist/fleet/subagent-tail-bus.js +15 -28
- package/dist/hooks/hook-runner.d.ts +6 -0
- package/dist/hooks/hook-runner.js +58 -8
- package/dist/host-decision.d.ts +54 -20
- package/dist/host-decision.js +42 -14
- package/dist/http/admission.d.ts +1 -1
- package/dist/http/admission.js +7 -3
- package/dist/http/approval-sweeps.js +11 -8
- package/dist/http/caller-trust.d.ts +1 -1
- package/dist/http/dispatch.js +4 -2
- package/dist/http/durable-run-leg.js +2 -2
- package/dist/http/engine-refusal.d.ts +16 -0
- package/dist/http/engine-refusal.js +17 -0
- package/dist/http/execution-context.d.ts +2 -2
- package/dist/http/idempotency.d.ts +1 -1
- package/dist/http/memory-compliance-failure-reply.d.ts +1 -3
- package/dist/http/memory-compliance-failure-reply.js +4 -6
- package/dist/http/owner-access.d.ts +11 -0
- package/dist/http/owner-access.js +13 -0
- package/dist/http/principal-gate.d.ts +3 -1
- package/dist/http/principal-gate.js +17 -8
- package/dist/http/resume-legs.d.ts +21 -7
- package/dist/http/resume-legs.js +76 -58
- package/dist/http/resume-restatement.d.ts +39 -0
- package/dist/http/resume-restatement.js +25 -0
- package/dist/http/route-ctx.d.ts +35 -10
- package/dist/http/route-ctx.js +1 -1
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/approvals-assistant.d.ts +9 -1
- package/dist/http/routes/approvals-assistant.js +142 -31
- package/dist/http/routes/attachments.js +18 -0
- package/dist/http/routes/capabilities.js +16 -4
- package/dist/http/routes/memory-policy.d.ts +2 -2
- package/dist/http/routes/memory-policy.js +27 -7
- package/dist/http/routes/notify-wake.js +23 -25
- package/dist/http/routes/rules.js +48 -13
- package/dist/http/routes/runs.js +12 -11
- package/dist/http/routes/session-memory-sync.d.ts +91 -0
- package/dist/http/routes/session-memory-sync.js +174 -0
- package/dist/http/routes/session-sync.js +13 -20
- package/dist/http/routes/sessions-list.d.ts +2 -1
- package/dist/http/routes/sessions.d.ts +2 -2
- package/dist/http/routes/sessions.js +22 -23
- package/dist/http/routes/tasks.js +34 -54
- package/dist/http/run-read-face.d.ts +7 -0
- package/dist/http/run-read-face.js +9 -3
- package/dist/http/send.d.ts +5 -0
- package/dist/http/send.js +9 -2
- package/dist/http/server.d.ts +27 -15
- package/dist/http/server.js +4 -6
- package/dist/http/stored-body-replay.js +15 -4
- package/dist/http/submit-replay.d.ts +4 -3
- package/dist/http/submit-replay.js +2 -2
- package/dist/http/sync-submit-body.d.ts +21 -4
- package/dist/http/sync-submit-body.js +13 -0
- package/dist/http/wire-types.d.ts +17 -7
- package/dist/identity-source.d.ts +21 -2
- package/dist/identity-source.js +6 -0
- package/dist/leader/leader.js +5 -2
- package/dist/leader/wire.d.ts +7 -1
- package/dist/leader/wire.js +6 -5
- package/dist/leg-facts.d.ts +37 -0
- package/dist/leg-facts.js +15 -0
- package/dist/memory-bundle-engine.d.ts +1 -4
- package/dist/memory-bundle-engine.js +2 -2
- package/dist/memory-incident-sink.d.ts +19 -6
- package/dist/memory-incident-sink.js +8 -4
- package/dist/memory-operator-faces.d.ts +30 -66
- package/dist/memory-operator-faces.js +17 -88
- package/dist/memory-scope-stores.d.ts +38 -40
- package/dist/memory-scope-stores.js +51 -36
- package/dist/memory-scope.d.ts +0 -9
- package/dist/memory-scope.js +0 -9
- package/dist/memory-sync-client.d.ts +21 -21
- package/dist/memory-sync-client.js +62 -43
- package/dist/memory-sync-identity.d.ts +24 -0
- package/dist/memory-sync-identity.js +57 -0
- package/dist/memory-sync.d.ts +27 -5
- package/dist/memory-sync.js +29 -7
- package/dist/model-plane-face.d.ts +13 -7
- package/dist/model-plane-face.js +2 -1
- package/dist/observability/fail-open.d.ts +47 -14
- package/dist/observability/fail-open.js +37 -11
- package/dist/observability/run-terminal.d.ts +92 -34
- package/dist/observability/run-terminal.js +171 -162
- package/dist/orchestration/workflow-completion-inbox.d.ts +5 -19
- package/dist/orchestration/workflow-completion-inbox.js +0 -12
- package/dist/orchestration/workflow-notify-journal.d.ts +3 -2
- package/dist/orchestration/workflow-park-decision.d.ts +8 -3
- package/dist/orchestration/workflow-park-decision.js +5 -3
- package/dist/org-delivery-gate.d.ts +11 -0
- package/dist/org-delivery-gate.js +19 -1
- package/dist/parked-decide.d.ts +13 -9
- package/dist/parked-decide.js +7 -7
- package/dist/parked-revive-surface.js +1 -1
- package/dist/peer-inbound-face.d.ts +127 -0
- package/dist/peer-inbound-face.js +158 -0
- package/dist/permission-rule-list.d.ts +13 -9
- package/dist/permission-rule-list.js +7 -3
- package/dist/plugins/approval-ask-store-file.d.ts +14 -4
- package/dist/plugins/approval-ask-store-file.js +64 -11
- package/dist/plugins/approval-ask-store-memory.d.ts +2 -1
- package/dist/plugins/approval-ask-store-memory.js +17 -14
- package/dist/plugins/approval-ask-store-sql.d.ts +70 -23
- package/dist/plugins/approval-ask-store-sql.js +79 -30
- package/dist/plugins/checkpoint-store-sql.d.ts +4 -4
- package/dist/plugins/checkpoint-store-sql.js +9 -7
- package/dist/plugins/file-history-store-sql.d.ts +24 -18
- package/dist/plugins/file-history-store-sql.js +24 -19
- package/dist/plugins/file-run-store.d.ts +35 -1
- package/dist/plugins/file-run-store.js +108 -9
- package/dist/plugins/imported-layer-root-retirement.d.ts +82 -0
- package/dist/plugins/imported-layer-root-retirement.js +96 -0
- package/dist/plugins/local-checkpoint-store.d.ts +1 -1
- package/dist/plugins/local-checkpoint-store.js +2 -2
- package/dist/plugins/local-session-store.d.ts +42 -9
- package/dist/plugins/local-session-store.js +83 -33
- package/dist/plugins/local-task-attachment-store.d.ts +12 -2
- package/dist/plugins/local-task-attachment-store.js +67 -43
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +9 -31
- package/dist/plugins/mailbox-recipient-lifecycle.js +4 -0
- package/dist/plugins/mailbox-store-sql.d.ts +12 -8
- package/dist/plugins/mailbox-store-sql.js +76 -7
- package/dist/plugins/memory-key-guards.d.ts +3 -3
- package/dist/plugins/memory-run-store.d.ts +6 -1
- package/dist/plugins/memory-run-store.js +11 -1
- package/dist/plugins/memory-sync-store-pg.d.ts +15 -0
- package/dist/plugins/memory-sync-store-pg.js +21 -0
- package/dist/plugins/memory-sync-store-tidb.d.ts +2 -0
- package/dist/plugins/memory-sync-store-tidb.js +13 -1
- package/dist/plugins/one-time-migrations.d.ts +58 -2
- package/dist/plugins/one-time-migrations.js +161 -4
- package/dist/plugins/org-delivery-quota-store.d.ts +1 -1
- package/dist/plugins/org-delivery-quota-store.js +2 -12
- package/dist/plugins/park-commit-watch.d.ts +1 -1
- package/dist/plugins/permission-rule-store-file.d.ts +10 -1
- package/dist/plugins/permission-rule-store-file.js +15 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +31 -1
- package/dist/plugins/permission-rule-store-sql.js +35 -2
- package/dist/plugins/remote-env-device.d.ts +8 -11
- package/dist/plugins/remote-env-device.js +6 -3
- package/dist/plugins/remote-env-e2b.d.ts +23 -4
- package/dist/plugins/remote-env-e2b.js +111 -28
- package/dist/plugins/remote-env-k8s.d.ts +61 -22
- package/dist/plugins/remote-env-k8s.js +133 -33
- package/dist/plugins/remote-env-local-docker.d.ts +15 -3
- package/dist/plugins/remote-env-local-docker.js +40 -12
- package/dist/plugins/retention-store-sql.d.ts +2 -2
- package/dist/plugins/run-store-sql.d.ts +9 -1
- package/dist/plugins/run-store-sql.js +9 -1
- package/dist/plugins/sandbox-read-floor.d.ts +5 -7
- package/dist/plugins/sandbox-read-floor.js +2 -7
- package/dist/plugins/sql-errors.d.ts +10 -1
- package/dist/plugins/sql-errors.js +13 -0
- package/dist/plugins/store-backend.d.ts +33 -35
- package/dist/plugins/store-backend.js +10 -1
- package/dist/plugins/store-contracts.d.ts +50 -1
- package/dist/plugins/store-contracts.js +6 -0
- package/dist/plugins/task-attachment-store.d.ts +112 -14
- package/dist/plugins/task-attachment-store.js +207 -29
- package/dist/plugins/tool-result-store-sql.d.ts +9 -8
- package/dist/plugins/tool-result-store-sql.js +23 -2
- package/dist/plugins/wiring-section-codec.d.ts +32 -0
- package/dist/plugins/wiring-section-codec.js +55 -0
- package/dist/plugins/workspace-fill.d.ts +60 -0
- package/dist/plugins/workspace-fill.js +106 -0
- package/dist/project-bundle.d.ts +38 -0
- package/dist/project-bundle.js +609 -0
- package/dist/rule-entry-list.d.ts +3 -2
- package/dist/rule-entry-list.js +5 -1
- package/dist/rules-consent.d.ts +28 -5
- package/dist/rules-consent.js +40 -28
- package/dist/run-local.js +11 -13
- package/dist/runs.d.ts +12 -8
- package/dist/runs.js +6 -8
- package/dist/runtime-governance.d.ts +1 -1
- package/dist/sandbox-egress-policy.d.ts +4 -1
- package/dist/sandbox-egress-policy.js +3 -1
- package/dist/sandbox-git-plane.d.ts +31 -12
- package/dist/sandbox-git-plane.js +24 -4
- package/dist/security.d.ts +9 -0
- package/dist/security.js +8 -0
- package/dist/server-secret-env.d.ts +4 -0
- package/dist/session-error-wire.d.ts +36 -0
- package/dist/session-error-wire.js +13 -0
- package/dist/session-incarnation.d.ts +1 -1
- package/dist/session-notify-door.d.ts +106 -0
- package/dist/session-notify-door.js +93 -0
- package/dist/session-sync.d.ts +9 -14
- package/dist/session-sync.js +5 -5
- package/dist/session-workspace.d.ts +3 -13
- package/dist/session-workspace.js +0 -9
- package/dist/standing-answer-grant.d.ts +5 -0
- package/dist/standing-answer-grant.js +10 -0
- package/dist/stores-sql/session-policy-store-sql.d.ts +4 -2
- package/dist/stores-sql/session-policy-store-sql.js +3 -13
- package/dist/task-mcp.d.ts +1 -1
- package/dist/task-settings.d.ts +21 -10
- package/dist/task-settings.js +46 -13
- package/dist/terminal.d.ts +39 -19
- package/dist/terminal.js +65 -22
- package/dist/tool-approval.d.ts +56 -37
- package/dist/tool-approval.js +78 -71
- package/dist/trace/core-keyset-guard.d.ts +134 -14
- package/dist/trace/engine-notice-wire.d.ts +9 -3
- package/dist/trace/engine-notice-wire.js +7 -3
- package/dist/trace/exit-seat.d.ts +9 -2
- package/dist/trace/exit-seat.js +1 -0
- package/dist/trace/ledger-sink.d.ts +10 -6
- package/dist/trace/ledger-sink.js +2 -2
- package/dist/trace/model-segment.d.ts +55 -25
- package/dist/trace/model-segment.js +101 -33
- package/dist/trace/project.d.ts +25 -5
- package/dist/trace/project.js +22 -0
- package/dist/trace/redact.d.ts +61 -9
- package/dist/trace/redact.js +1490 -468
- package/dist/trace/self-minted-wire.d.ts +745 -24
- package/dist/trace/self-minted-wire.js +239 -9
- package/dist/trace/wire-projection-faces.d.ts +2 -2
- package/dist/trace/wire-projection-faces.js +2 -2
- package/dist/verifier-pause-card.d.ts +33 -5
- package/dist/verifier-pause-card.js +15 -10
- package/dist/web-admin-client/apply-effective.d.ts +12 -16
- package/dist/web-admin-client/apply-effective.js +109 -9
- package/dist/web-admin-client/effective-keys.js +2 -0
- package/dist/web-admin-client/types.d.ts +4 -0
- package/dist/workspace-space.d.ts +19 -3
- package/dist/workspace-space.js +8 -4
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -1
- package/package.json +3 -2
- package/wire-changes/server@7.142.0.json +639 -0
- 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
|
-
|
|
129
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
166
|
-
return { ok: false, error: this.
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
259
|
+
resumeVM(snapshotId, options) {
|
|
254
260
|
if (this.destroyed)
|
|
255
|
-
return { ok: false, error: new RemoteExecutionError("connect_failed", "env already destroyed") };
|
|
256
|
-
if (this.
|
|
257
|
-
return { ok: false, error: this.
|
|
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
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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.
|
|
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
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
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
|
|
322
|
-
*
|
|
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
|
|
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
|
|
634
|
-
*
|
|
635
|
-
*
|
|
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
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
*
|
|
650
|
-
*
|
|
651
|
-
*
|
|
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
|
-
*
|
|
669
|
-
*
|
|
670
|
-
*
|
|
671
|
-
*
|
|
672
|
-
|
|
673
|
-
|
|
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
|