@sema-agent/server 7.150.0 → 7.152.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 +451 -0
- package/README.md +15 -3
- package/README.zh-CN.md +10 -2
- package/USAGE.md +144 -87
- package/deploy/sema-up/README.md +11 -4
- package/deploy/sema-up/chart/Chart.yaml +1 -1
- package/deploy/sema-up/chart/templates/NOTES.txt +5 -0
- package/deploy/sema-up/chart/templates/_helpers.tpl +15 -16
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -3
- package/deploy/sema-up/chart/templates/server.yaml +5 -3
- package/deploy/sema-up/chart/values-full-single.yaml +3 -1
- package/deploy/sema-up/chart/values.yaml +8 -1
- package/deploy/sema-up/cluster-up.sh +7 -6
- package/deploy/sema-up/kube-up.sh +6 -6
- package/deploy/sema-up/lib/flagshape.sh +36 -8
- package/deploy/sema-up/lib/helm-values-cluster.py +2 -0
- package/deploy/sema-up/lib/helm-values-kube.py +2 -0
- package/deploy/sema-up/machines.example.yaml +3 -1
- package/deploy/sema-up/sema-up.sh +22 -16
- package/dist/adoption/import.js +3 -3
- package/dist/approval-ask-audit-store.d.ts +1 -1
- package/dist/approval-ask-machine.d.ts +4 -10
- package/dist/approval-ask-retention.d.ts +1 -1
- package/dist/approval-card.d.ts +12 -14
- package/dist/approval-gate-currency.d.ts +9 -9
- package/dist/approval-gate-currency.js +3 -4
- package/dist/approval-hmac.d.ts +17 -1
- package/dist/approval-hmac.js +7 -1
- package/dist/approval-queue-kind.d.ts +1 -1
- package/dist/approval.d.ts +2 -2
- package/dist/approval.js +2 -2
- package/dist/auth-bridge.d.ts +20 -0
- package/dist/auth-bridge.js +9 -0
- package/dist/background-session-reap.d.ts +1 -1
- package/dist/bake-runner/main.d.ts +4 -2
- package/dist/bind-host.d.ts +3 -6
- package/dist/bind-host.js +4 -7
- package/dist/boot/budget-tracing.js +1 -1
- package/dist/boot/coordinators.d.ts +1 -1
- package/dist/boot/coordinators.js +9 -10
- package/dist/boot/device-lane.js +2 -0
- package/dist/boot/engine-lease.d.ts +5 -0
- package/dist/boot/engine-lease.js +1 -0
- package/dist/boot/execution-env.d.ts +9 -14
- package/dist/boot/execution-env.js +85 -22
- package/dist/boot/execution-lane.js +32 -5
- package/dist/boot/late-binds.d.ts +8 -4
- package/dist/boot/late-binds.js +7 -1
- package/dist/boot/leader.d.ts +31 -30
- package/dist/boot/leader.js +38 -28
- package/dist/boot/leg-path-adjudication.d.ts +40 -0
- package/dist/boot/leg-path-adjudication.js +18 -0
- package/dist/boot/memory-consolidation.d.ts +3 -2
- package/dist/boot/memory-consolidation.js +6 -6
- package/dist/boot/parked-revive-gate.js +3 -15
- package/dist/boot/reapers.d.ts +6 -1
- package/dist/boot/reapers.js +13 -2
- package/dist/boot/resolve-spec.d.ts +3 -3
- package/dist/boot/resolve-spec.js +43 -48
- package/dist/boot/runner-deps.d.ts +46 -35
- package/dist/boot/runner-deps.js +94 -91
- package/dist/boot/session-age-out.d.ts +36 -0
- package/dist/boot/session-age-out.js +101 -0
- package/dist/boot/session-faces.d.ts +5 -14
- package/dist/boot/session-faces.js +9 -5
- package/dist/boot/shutdown.d.ts +6 -0
- package/dist/boot/shutdown.js +10 -4
- package/dist/boot/stage-01-config.js +2 -0
- package/dist/boot/stage-02-web-admin-pull.js +4 -5
- package/dist/boot/stage-05-execution-env.d.ts +5 -3
- package/dist/boot/stage-05-execution-env.js +3 -2
- package/dist/boot/stage-06-runners.d.ts +9 -4
- package/dist/boot/stage-06-runners.js +24 -9
- package/dist/boot/stage-07-capability-layer.d.ts +8 -4
- package/dist/boot/stage-07-capability-layer.js +3 -2
- package/dist/boot/stage-08-reapers.d.ts +8 -4
- package/dist/boot/stage-08-reapers.js +4 -2
- package/dist/boot/stage-09-leader.d.ts +12 -5
- package/dist/boot/stage-09-leader.js +14 -5
- package/dist/boot/stage-10-http-server.d.ts +19 -5
- package/dist/boot/stage-10-http-server.js +14 -21
- package/dist/boot/stores.js +7 -4
- package/dist/boot/web-admin.js +5 -8
- package/dist/boot/workflow-orchestration.d.ts +7 -2
- package/dist/boot/workflow-orchestration.js +24 -7
- package/dist/bounded-rotation.d.ts +29 -0
- package/dist/bounded-rotation.js +24 -0
- package/dist/capabilities/approvals-push.d.ts +3 -3
- package/dist/capabilities/scenarios.d.ts +28 -13
- package/dist/capabilities/scenarios.js +2 -2
- package/dist/capability-facts.d.ts +43 -32
- package/dist/capability-facts.js +45 -51
- package/dist/card-rule-offers.d.ts +32 -0
- package/dist/card-rule-offers.js +130 -0
- package/dist/center-credential.d.ts +25 -6
- package/dist/center-credential.js +25 -5
- package/dist/config-catalog.d.ts +26 -7
- package/dist/config-catalog.js +26 -22
- package/dist/config-dir-trust.js +4 -2
- package/dist/config-invariants.d.ts +20 -8
- package/dist/config-invariants.js +55 -12
- package/dist/config-lkg.d.ts +5 -19
- package/dist/config-lkg.js +8 -62
- package/dist/config-provider.d.ts +1 -1
- package/dist/config-root-migration.d.ts +2 -2
- package/dist/config-types.d.ts +38 -42
- package/dist/config.d.ts +58 -7
- package/dist/config.js +90 -40
- package/dist/control-socket.d.ts +51 -0
- package/dist/control-socket.js +115 -0
- package/dist/deployment-governance.d.ts +2 -1
- package/dist/deployment-shape.d.ts +9 -1
- package/dist/deployment-shape.js +2 -1
- package/dist/device-protocol.d.ts +5 -4
- package/dist/device-protocol.js +1 -1
- package/dist/device-ws-hub.d.ts +7 -0
- package/dist/device-ws-hub.js +10 -3
- package/dist/device-ws-protocol.d.ts +63 -10
- package/dist/device-ws-protocol.js +56 -25
- package/dist/elicitation.js +2 -2
- package/dist/engine-identity.d.ts +19 -7
- package/dist/engine-identity.js +10 -2
- package/dist/entry-mode-clamp-notice.d.ts +2 -1
- package/dist/entry-problems.d.ts +40 -3
- package/dist/entry-problems.js +3 -1
- package/dist/execution-env-refusal.d.ts +29 -0
- package/dist/execution-env-refusal.js +8 -0
- package/dist/execution-lane-caps.d.ts +3 -1
- package/dist/field-conflict.d.ts +1 -1
- package/dist/file-history-capture.d.ts +11 -4
- package/dist/file-history-capture.js +9 -6
- package/dist/file-history-disclosure.d.ts +7 -5
- package/dist/file-history-disclosure.js +7 -5
- package/dist/fleet/drain-entry.d.ts +4 -0
- package/dist/fleet/engine-signal.d.ts +12 -29
- package/dist/fleet/engine-signal.js +1 -7
- package/dist/fleet-client.js +2 -5
- package/dist/gate-settlement.d.ts +1 -8
- package/dist/gate-settlement.js +0 -4
- package/dist/history-anchor.js +1 -1
- package/dist/hitl-delivery.d.ts +2 -3
- package/dist/hitl-delivery.js +0 -2
- package/dist/hooks/hook-llm.js +4 -2
- package/dist/hooks/hook-runner.d.ts +3 -2
- package/dist/hooks/hook-runner.js +18 -3
- package/dist/host-decision.d.ts +11 -11
- package/dist/host-lsp-manager.d.ts +2 -2
- package/dist/http/active-run-conflict.d.ts +35 -2
- package/dist/http/active-run-conflict.js +48 -19
- package/dist/http/admission.js +17 -2
- package/dist/http/approval-sweeps.d.ts +1 -1
- package/dist/http/approval-sweeps.js +10 -7
- package/dist/http/checkpoint-ctx.d.ts +4 -0
- package/dist/http/checkpoint-ctx.js +2 -0
- package/dist/http/dispatch.d.ts +8 -3
- package/dist/http/dispatch.js +59 -32
- package/dist/http/durable-run-leg.js +16 -17
- package/dist/http/health-reader.d.ts +16 -9
- package/dist/http/health-reader.js +2 -1
- package/dist/http/health-self-report.d.ts +9 -1
- package/dist/http/health-self-report.js +3 -1
- package/dist/http/owner-access.d.ts +33 -14
- package/dist/http/owner-access.js +40 -10
- package/dist/http/principal-gate.d.ts +49 -21
- package/dist/http/principal-gate.js +61 -11
- package/dist/http/request-channel.d.ts +23 -0
- package/dist/http/request-channel.js +9 -0
- package/dist/http/request-guards.js +17 -2
- package/dist/http/resume-ctx-read.js +42 -3
- package/dist/http/resume-legs.d.ts +4 -3
- package/dist/http/resume-legs.js +367 -117
- package/dist/http/route-ctx.d.ts +91 -15
- package/dist/http/route-ctx.js +17 -0
- package/dist/http/route-table.d.ts +5 -1
- package/dist/http/route-table.js +4 -0
- package/dist/http/routes/admin-config-refresh.js +3 -3
- package/dist/http/routes/admin-drain.d.ts +3 -0
- package/dist/http/routes/admin-drain.js +7 -7
- package/dist/http/routes/admin-memory-optout.d.ts +1 -1
- package/dist/http/routes/admin-memory-optout.js +3 -3
- package/dist/http/routes/adoption.js +3 -5
- package/dist/http/routes/agents-roster.js +2 -3
- package/dist/http/routes/approvals-assistant.d.ts +2 -1
- package/dist/http/routes/approvals-assistant.js +99 -51
- package/dist/http/routes/background.d.ts +3 -3
- package/dist/http/routes/capabilities.d.ts +4 -0
- package/dist/http/routes/capabilities.js +38 -10
- package/dist/http/routes/config-catalog.js +2 -2
- package/dist/http/routes/devices.js +1 -1
- package/dist/http/routes/diagnostics.d.ts +3 -3
- package/dist/http/routes/diagnostics.js +19 -7
- package/dist/http/routes/fleet.js +10 -8
- package/dist/http/routes/images.js +10 -10
- package/dist/http/routes/memory-bundle.js +3 -3
- package/dist/http/routes/memory-compliance.js +3 -3
- package/dist/http/routes/memory-consolidation.js +2 -2
- package/dist/http/routes/memory-origin.js +3 -3
- package/dist/http/routes/memory-policy.js +2 -2
- package/dist/http/routes/observability.js +3 -3
- package/dist/http/routes/projects.d.ts +3 -2
- package/dist/http/routes/projects.js +4 -5
- package/dist/http/routes/retention-ops.js +3 -3
- package/dist/http/routes/rules.js +5 -5
- package/dist/http/routes/run-permission-mode.d.ts +2 -1
- package/dist/http/routes/run-permission-mode.js +2 -2
- package/dist/http/routes/runs.d.ts +4 -9
- package/dist/http/routes/runs.js +171 -65
- package/dist/http/routes/session-sync.d.ts +22 -9
- package/dist/http/routes/session-sync.js +204 -107
- package/dist/http/routes/sessions-list.js +13 -7
- package/dist/http/routes/sessions.js +30 -15
- package/dist/http/routes/tasks.js +46 -41
- package/dist/http/routes/trace-usage.js +2 -2
- package/dist/http/routes/workflows.js +1 -1
- package/dist/http/server.d.ts +30 -30
- package/dist/http/server.js +16 -4
- package/dist/http/submit-ctx.d.ts +1 -1
- package/dist/http/submit-ctx.js +7 -4
- package/dist/http/wire-types.d.ts +14 -4
- package/dist/human-facing-args.d.ts +33 -0
- package/dist/human-facing-args.js +33 -0
- package/dist/identity-source.d.ts +20 -3
- package/dist/identity-source.js +14 -0
- package/dist/index.d.ts +5 -1
- package/dist/k8s-api-credentials.d.ts +29 -0
- package/dist/k8s-api-credentials.js +25 -0
- package/dist/lane-home-probe.d.ts +3 -7
- package/dist/lane-home-probe.js +2 -2
- package/dist/leader/diffup.d.ts +19 -0
- package/dist/leader/diffup.js +7 -0
- package/dist/leader/leader.d.ts +116 -11
- package/dist/leader/leader.js +69 -5
- package/dist/leader/repair-wire.js +2 -2
- package/dist/leader/run-entry.d.ts +2 -1
- package/dist/leader/run-entry.js +1 -1
- package/dist/leader/wire.d.ts +42 -132
- package/dist/leader/wire.js +81 -67
- package/dist/leg-facts.d.ts +13 -5
- package/dist/leg-facts.js +2 -1
- package/dist/memory-scope.d.ts +23 -11
- package/dist/memory-scope.js +18 -6
- package/dist/memory-sync-client.d.ts +30 -2
- package/dist/memory-sync-client.js +16 -9
- package/dist/model-entry-headers.d.ts +9 -10
- package/dist/model-entry-headers.js +0 -4
- package/dist/model-entry-refusal.d.ts +7 -4
- package/dist/model-entry-refusal.js +11 -5
- package/dist/model-plane-face.d.ts +1 -1
- package/dist/model-plane-face.js +3 -1
- package/dist/model-route-endpoint.d.ts +13 -7
- package/dist/model-route-endpoint.js +14 -11
- package/dist/model-select.d.ts +22 -0
- package/dist/model-select.js +9 -0
- package/dist/model-unreachable-notice.d.ts +11 -0
- package/dist/model-unreachable-notice.js +4 -4
- package/dist/object-store-buckets.d.ts +640 -6
- package/dist/object-store-buckets.js +166 -0
- package/dist/observability/err-text.d.ts +7 -0
- package/dist/observability/err-text.js +5 -0
- package/dist/observability/fail-open.d.ts +25 -17
- package/dist/observability/fail-open.js +25 -17
- package/dist/observability/logger.js +3 -1
- package/dist/observability/metrics.js +1 -0
- package/dist/operator-roster.d.ts +68 -0
- package/dist/operator-roster.js +32 -0
- package/dist/orchestration/workflow-notify-journal.d.ts +18 -1
- package/dist/orchestration/workflow-notify-journal.js +12 -1
- package/dist/orchestration/workflow-park-decision.d.ts +70 -18
- package/dist/orchestration/workflow-park-decision.js +49 -10
- package/dist/orchestration/workflow-park-holder.d.ts +65 -0
- package/dist/orchestration/workflow-park-holder.js +98 -0
- package/dist/orchestration/workflow-record-fence.d.ts +36 -0
- package/dist/orchestration/workflow-record-fence.js +42 -0
- package/dist/outbound-dispatcher.d.ts +71 -8
- package/dist/outbound-dispatcher.js +48 -7
- package/dist/owner-faces.d.ts +2 -2
- package/dist/parked-decide.d.ts +106 -55
- package/dist/parked-decide.js +153 -117
- package/dist/peer-directory.d.ts +2 -2
- package/dist/peer-inbound-face.d.ts +2 -6
- package/dist/peer-inbound-face.js +0 -3
- package/dist/permission-mode-admission.d.ts +74 -5
- package/dist/permission-mode-admission.js +56 -3
- package/dist/plugins/adoption-log-sql.d.ts +3 -1
- package/dist/plugins/adoption-log-sql.js +7 -1
- package/dist/plugins/approval-ask-store-file.d.ts +14 -2
- package/dist/plugins/approval-ask-store-file.js +11 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +10 -1
- package/dist/plugins/approval-ask-store-memory.js +35 -10
- package/dist/plugins/approval-ask-store-sql.d.ts +69 -4
- package/dist/plugins/approval-ask-store-sql.js +45 -5
- package/dist/plugins/approval-exemption-store.js +3 -0
- package/dist/plugins/approval-nonce-store.js +2 -0
- package/dist/plugins/blob-backend.d.ts +83 -7
- package/dist/plugins/blob-backend.js +57 -6
- package/dist/plugins/breaker-state-sql.js +2 -0
- package/dist/plugins/caching-session-store.d.ts +9 -15
- package/dist/plugins/caching-session-store.js +6 -0
- package/dist/plugins/checkpoint-index-columns.d.ts +20 -16
- package/dist/plugins/checkpoint-index-columns.js +3 -6
- package/dist/plugins/checkpoint-store-face.d.ts +119 -61
- package/dist/plugins/checkpoint-store-face.js +134 -55
- package/dist/plugins/device-store-sql.js +6 -0
- package/dist/plugins/error-origin.d.ts +18 -0
- package/dist/plugins/error-origin.js +10 -0
- package/dist/plugins/execution-placement-sql.js +6 -6
- package/dist/plugins/image-bake-store-sql.js +6 -0
- package/dist/plugins/image-index-sql.js +4 -0
- package/dist/plugins/landed-attendants.d.ts +212 -0
- package/dist/plugins/landed-attendants.js +161 -0
- package/dist/plugins/leader-run-store-sql.js +4 -0
- package/dist/plugins/local-checkpoint-store.d.ts +13 -3
- package/dist/plugins/local-checkpoint-store.js +38 -49
- package/dist/plugins/local-session-live-reference.d.ts +40 -0
- package/dist/plugins/local-session-live-reference.js +39 -0
- package/dist/plugins/local-session-store.d.ts +71 -33
- package/dist/plugins/local-session-store.js +129 -27
- package/dist/plugins/memory-engine-pg.js +4 -0
- package/dist/plugins/memory-engine-sql-apply.js +5 -2
- package/dist/plugins/memory-engine-tidb.js +4 -0
- package/dist/plugins/memory-optout-grant-store-sql.js +4 -0
- package/dist/plugins/memory-sync-store-pg.js +5 -0
- package/dist/plugins/memory-sync-store-tidb.js +5 -0
- package/dist/plugins/one-time-migrations.d.ts +104 -80
- package/dist/plugins/one-time-migrations.js +226 -132
- package/dist/plugins/org-delivery-quota-store.js +4 -1
- package/dist/plugins/outcome-ledger-sql.js +2 -0
- package/dist/plugins/permission-rule-store-sql.js +11 -4
- package/dist/plugins/pg-cost-quota.js +4 -0
- package/dist/plugins/pg-pool.js +35 -10
- package/dist/plugins/pg-rate-limiter.js +2 -0
- package/dist/plugins/posix-shell-fs.d.ts +6 -1
- package/dist/plugins/posix-shell-fs.js +4 -1
- package/dist/plugins/remote-env-adb.d.ts +19 -15
- package/dist/plugins/remote-env-adb.js +41 -15
- package/dist/plugins/remote-env-connect-seat.d.ts +105 -0
- package/dist/plugins/remote-env-connect-seat.js +72 -0
- package/dist/plugins/remote-env-device.d.ts +22 -5
- package/dist/plugins/remote-env-device.js +106 -8
- package/dist/plugins/remote-env-e2b.d.ts +15 -6
- package/dist/plugins/remote-env-e2b.js +42 -32
- package/dist/plugins/remote-env-file-error.js +6 -2
- package/dist/plugins/remote-env-host.d.ts +46 -10
- package/dist/plugins/remote-env-host.js +124 -52
- package/dist/plugins/remote-env-k8s.d.ts +109 -41
- package/dist/plugins/remote-env-k8s.js +160 -54
- package/dist/plugins/remote-env-local-docker.d.ts +13 -8
- package/dist/plugins/remote-env-local-docker.js +34 -41
- package/dist/plugins/remote-env-ssh.d.ts +18 -12
- package/dist/plugins/remote-env-ssh.js +60 -59
- package/dist/plugins/remote-shell.d.ts +98 -1
- package/dist/plugins/remote-shell.js +218 -0
- package/dist/plugins/replica-registration.d.ts +1 -1
- package/dist/plugins/replica-registration.js +1 -1
- package/dist/plugins/resume-anchor-store-sql.d.ts +11 -2
- package/dist/plugins/resume-anchor-store-sql.js +12 -5
- package/dist/plugins/retention-lane-store-sql.js +4 -0
- package/dist/plugins/retention-sql.d.ts +20 -2
- package/dist/plugins/retention-sql.js +11 -0
- package/dist/plugins/run-store-sql.d.ts +21 -2
- package/dist/plugins/run-store-sql.js +31 -7
- package/dist/plugins/s3-presign.d.ts +23 -0
- package/dist/plugins/s3-presign.js +37 -3
- package/dist/plugins/scenario-prefix-switch-m42.d.ts +1 -1
- package/dist/plugins/scenario-prefix-switch-m42.js +2 -2
- package/dist/plugins/scheduler-support.d.ts +2 -2
- package/dist/plugins/scheduler-support.js +0 -3
- package/dist/plugins/schema-consistency.d.ts +4 -2
- package/dist/plugins/schema-consistency.js +19 -2
- package/dist/plugins/schema-indexes.js +2 -0
- package/dist/plugins/send-file-ledger.d.ts +2 -2
- package/dist/plugins/send-file-ledger.js +5 -2
- package/dist/plugins/send-user-file.d.ts +3 -4
- package/dist/plugins/send-user-file.js +56 -52
- package/dist/plugins/serving-requirement.d.ts +26 -7
- package/dist/plugins/serving-requirement.js +11 -4
- package/dist/plugins/session-birth.d.ts +6 -2
- package/dist/plugins/session-blob-claim-token.d.ts +15 -0
- package/dist/plugins/session-blob-claim-token.js +20 -0
- package/dist/plugins/session-blob-namespace.d.ts +46 -0
- package/dist/plugins/session-blob-namespace.js +116 -0
- package/dist/plugins/session-capture-record-store-sql.js +2 -0
- package/dist/plugins/session-ext-table.d.ts +14 -1
- package/dist/plugins/session-ext-table.js +5 -1
- package/dist/plugins/session-row-sql.d.ts +49 -2
- package/dist/plugins/session-row-sql.js +56 -13
- package/dist/plugins/session-store-sql.d.ts +34 -18
- package/dist/plugins/session-store-sql.js +98 -17
- package/dist/plugins/shared-memory-store-sql.d.ts +1 -0
- package/dist/plugins/shared-memory-store-sql.js +6 -2
- package/dist/plugins/snapshot-bucket-presence.d.ts +25 -2
- package/dist/plugins/snapshot-bucket-presence.js +8 -2
- package/dist/plugins/sql-driver.d.ts +2 -1
- package/dist/plugins/sql-driver.js +18 -3
- package/dist/plugins/sql-errors.d.ts +11 -6
- package/dist/plugins/sql-errors.js +5 -6
- package/dist/plugins/sql-json-column.d.ts +1 -1
- package/dist/plugins/stop-then-start-sentence.d.ts +10 -4
- package/dist/plugins/stop-then-start-sentence.js +14 -10
- package/dist/plugins/stop-then-start.d.ts +109 -0
- package/dist/plugins/stop-then-start.js +104 -0
- package/dist/plugins/store-backend.d.ts +84 -15
- package/dist/plugins/store-backend.js +236 -72
- package/dist/plugins/store-boundary.d.ts +57 -0
- package/dist/plugins/store-boundary.js +139 -0
- package/dist/plugins/store-contracts.d.ts +17 -0
- package/dist/plugins/store-fault-sentence-m53.d.ts +7 -0
- package/dist/plugins/store-fault-sentence-m53.js +25 -0
- package/dist/plugins/store-fault.d.ts +26 -7
- package/dist/plugins/store-fault.js +18 -2
- package/dist/plugins/task-attachment-store.d.ts +2 -1
- package/dist/plugins/task-attachment-store.js +14 -1
- package/dist/plugins/task-list-store-sql.d.ts +2 -2
- package/dist/plugins/task-list-store-sql.js +10 -8
- package/dist/plugins/tidb-cost-quota.js +4 -0
- package/dist/plugins/tidb-pool.js +21 -25
- package/dist/plugins/tidb-rate-limiter.js +4 -0
- package/dist/plugins/user-input-ledger-sql.js +4 -0
- package/dist/plugins/workflow-run-store-sql.d.ts +28 -10
- package/dist/plugins/workflow-run-store-sql.js +64 -4
- package/dist/plugins/workspace-custody.d.ts +4 -3
- package/dist/plugins/workspace-fill.d.ts +4 -7
- package/dist/plugins/workspace-fill.js +2 -1
- package/dist/plugins/write-behind-counter.js +5 -0
- package/dist/project-context.d.ts +0 -2
- package/dist/project-context.js +4 -8
- package/dist/project-registry.d.ts +46 -0
- package/dist/project-registry.js +44 -0
- package/dist/question.d.ts +2 -1
- package/dist/question.js +5 -13
- package/dist/request-form.d.ts +6 -1
- package/dist/request-form.js +4 -1
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +4 -0
- package/dist/request-value-closure.js +10 -0
- package/dist/rule-issue-reading.d.ts +1 -1
- package/dist/rules-consent.d.ts +1 -1
- package/dist/run-acceptance.d.ts +3 -2
- package/dist/run-acceptance.js +4 -6
- package/dist/run-local.js +9 -9
- package/dist/runs.d.ts +54 -16
- package/dist/runs.js +67 -13
- package/dist/runtime-governance.d.ts +5 -4
- package/dist/security.d.ts +30 -32
- package/dist/security.js +41 -7
- package/dist/sema-config-dir.d.ts +2 -1
- package/dist/server-secret-env.d.ts +12 -10
- package/dist/server-secret-env.js +24 -15
- package/dist/session-bindings.d.ts +82 -0
- package/dist/session-bindings.js +18 -0
- package/dist/session-children-retire.d.ts +2 -2
- package/dist/session-children-retire.js +2 -6
- package/dist/session-deletion.d.ts +16 -1
- package/dist/session-error-wire.d.ts +3 -3
- package/dist/session-error-wire.js +3 -3
- package/dist/session-incarnation.d.ts +10 -0
- package/dist/session-incarnation.js +10 -1
- package/dist/session-kind.d.ts +57 -0
- package/dist/session-kind.js +22 -0
- package/dist/session-row.d.ts +21 -1
- package/dist/session-row.js +7 -1
- package/dist/session-sync-kernel.d.ts +24 -14
- package/dist/session-sync-kernel.js +3 -6
- package/dist/session-sync.d.ts +25 -103
- package/dist/session-sync.js +14 -76
- package/dist/session-titler.d.ts +10 -3
- package/dist/session-titler.js +19 -6
- package/dist/ssh-host-key.d.ts +5 -0
- package/dist/ssh-host-key.js +3 -0
- package/dist/stores-sql/blob-index-sql.d.ts +30 -9
- package/dist/stores-sql/blob-index-sql.js +40 -21
- package/dist/stores-sql/checkpoint-store-sql.d.ts +54 -27
- package/dist/stores-sql/checkpoint-store-sql.js +70 -146
- package/dist/stores-sql/file-history-store-sql.d.ts +113 -15
- package/dist/stores-sql/file-history-store-sql.js +205 -95
- package/dist/stores-sql/pg-session-storage.d.ts +34 -7
- package/dist/stores-sql/pg-session-storage.js +37 -13
- package/dist/stores-sql/retention-store-sql.d.ts +1 -9
- package/dist/stores-sql/retention-store-sql.js +5 -19
- package/dist/stores-sql/session-policy-store-sql.d.ts +30 -7
- package/dist/stores-sql/session-policy-store-sql.js +61 -44
- package/dist/stores-sql/session-write-hooks.d.ts +11 -0
- package/dist/stores-sql/tidb-session-store.d.ts +58 -7
- package/dist/stores-sql/tidb-session-store.js +37 -13
- package/dist/submission-exit.d.ts +3 -2
- package/dist/submission-exit.js +9 -1
- package/dist/task-cwd.d.ts +2 -2
- package/dist/task-settings.d.ts +7 -5
- package/dist/task-settings.js +3 -3
- package/dist/terminal.d.ts +33 -2
- package/dist/terminal.js +139 -9
- package/dist/tool-approval.d.ts +465 -507
- package/dist/tool-approval.js +606 -1222
- package/dist/trace/core-keyset-guard.d.ts +1 -1
- package/dist/trace/ledger-events.d.ts +3 -3
- package/dist/trace/project.d.ts +2 -3
- package/dist/trace/redact.js +3 -2
- package/dist/trace/self-minted-wire.d.ts +571 -178
- package/dist/trace/self-minted-wire.js +189 -56
- package/dist/web-admin-client/apply-effective.js +2 -2
- package/dist/web-admin-client/read-warnings.d.ts +2 -2
- package/dist/web-admin-client/read-warnings.js +1 -1
- package/dist/web-admin-client/types.d.ts +1 -1
- package/dist/workspace-space.d.ts +10 -4
- package/dist/workspace-space.js +4 -1
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +79 -28
- package/package.json +7 -3
- package/scripts/embed-minimal.mjs +3 -3
- package/wire-changes/server@7.151.0.json +762 -0
- package/wire-changes/server@7.152.0.json +900 -0
- package/dist/config-d-migration.d.ts +0 -37
- package/dist/config-d-migration.js +0 -60
- package/dist/http/session-inherit-env.d.ts +0 -36
- package/dist/http/session-inherit-env.js +0 -6
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { writeLogText } from "../observability/logger.js";
|
|
2
2
|
import { spawn } from "node:child_process";
|
|
3
3
|
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
4
|
+
import path, {} from "node:path";
|
|
5
5
|
import { anchoredPath, anchorUnder, joinedPath } from "./exec-path-law.js";
|
|
6
6
|
import fs from "node:fs/promises";
|
|
7
7
|
import { randomBytes } from "node:crypto";
|
|
8
|
-
import { openSync, closeSync, readSync, statSync, truncateSync, unlinkSync, mkdirSync, rmdirSync, mkdtempSync, existsSync,
|
|
8
|
+
import { openSync, closeSync, readSync, statSync, truncateSync, unlinkSync, mkdirSync, rmdirSync, mkdtempSync, existsSync, accessSync, renameSync, constants as FS_CONST } from "node:fs";
|
|
9
9
|
import { StringDecoder } from "node:string_decoder";
|
|
10
10
|
import { armPipeDestroyGrace, numEnvOr } from "./remote-shell.js";
|
|
11
11
|
import { buildLivenessCut, commandBoundsOf } from "../exec-bounds.js";
|
|
@@ -13,7 +13,7 @@ import { buildCapturedOutput, createCutError } from "../exec-cut.js";
|
|
|
13
13
|
import { hostBackgroundShellEnabled, hostExecSpoolEnabled } from "../config.js";
|
|
14
14
|
import { IS_WIN32, resolveHostShell, hostShell, pinHostShell, spawnGroupOptions, killTreeHard, killTreeSoft, hardKillGroupNow, collapseWin32EnvKeys, adoptHostForegroundChild } from "./host-platform.js";
|
|
15
15
|
import { BackgroundShellManager, seedMemStream, feedMemStream, drainMemStream } from "./background-shell-support.js";
|
|
16
|
-
import { FileError, NodeExecutionEnv, inheritEnvPolicyProblem, ExecutionError, RemoteExecutionError, RollingTailBuffer, walkSymlinkChain, markTruncated, SchedulerError, BackgroundShellError, physicalPathOf
|
|
16
|
+
import { FileError, NodeExecutionEnv, inheritEnvPolicyProblem, ExecutionError, RemoteExecutionError, RollingTailBuffer, walkSymlinkChain, markTruncated, SchedulerError, BackgroundShellError, physicalPathOf, } from "@sema-agent/core";
|
|
17
17
|
import { capabilitiesFor } from "../execution-lane-caps.js";
|
|
18
18
|
import { DEPLOYMENT_SHAPE_PREDICATES } from "../deployment-shape.js";
|
|
19
19
|
import { LaneHomeSeat, laneHomeRefusal } from "../lane-home-probe.js";
|
|
@@ -21,7 +21,10 @@ import { composeHostSubprocessEnv, hostSubprocessEnv, withheldFromHostSubprocess
|
|
|
21
21
|
import { nameTooLongCode } from "./remote-env-file-error.js";
|
|
22
22
|
import { trackEphemeralHostWorkspace, untrackEphemeralHostWorkspace } from "./host-workspace-registry.js";
|
|
23
23
|
import { createWorkspaceCustody } from "./workspace-custody.js";
|
|
24
|
+
import { canonicalPathOf, pathIsWithin, presentOnDisk } from "../memory-scope.js";
|
|
25
|
+
import { errorCodeOf } from "../observability/err-text.js";
|
|
24
26
|
import { OWNER_ONLY_FILE_MODE } from "./owner-only-file-mode.js";
|
|
27
|
+
import { createConnectSeat, withdrawOnAbort } from "./remote-env-connect-seat.js";
|
|
25
28
|
const PROVIDER = "host";
|
|
26
29
|
const DEFAULT_COMMAND_TIMEOUT_MS = 30 * 60_000;
|
|
27
30
|
const inflightFsDrainWaitMs = () => numEnvOr("HOST_FS_DRAIN_WAIT_MS", 10_000, 1);
|
|
@@ -39,6 +42,7 @@ const unsupported = (op) => ({
|
|
|
39
42
|
});
|
|
40
43
|
const BORROWED = Object.freeze({ kind: "borrowed" });
|
|
41
44
|
const RELEASED = Object.freeze({ kind: "released" });
|
|
45
|
+
const NO_ROOTS = Object.freeze([]);
|
|
42
46
|
const UNSUPPORTED_SCHEDULER_CAPS = {
|
|
43
47
|
supported: false,
|
|
44
48
|
maxScheduledPerScope: 0,
|
|
@@ -130,20 +134,26 @@ export class RemoteHostExecutionEnv {
|
|
|
130
134
|
return this.spoolRootDir;
|
|
131
135
|
}
|
|
132
136
|
tenure;
|
|
137
|
+
hasLeft = false;
|
|
133
138
|
preparing;
|
|
139
|
+
seat = createConnectSeat({
|
|
140
|
+
live: () => (this.prepared && !this.destroyed ? this.handle : undefined),
|
|
141
|
+
inFlight: () => (this.prepared ? undefined : this.preparing?.then(() => this.preparedAnswer(), (e) => this.prepareFailed(e))),
|
|
142
|
+
establish: (config) => withdrawOnAbort(this.ensurePrepared().then(() => this.preparedAnswer(), (e) => this.prepareFailed(e)), config?.abortSignal),
|
|
143
|
+
});
|
|
134
144
|
handle;
|
|
135
145
|
constructor(config = {}) {
|
|
136
146
|
if (config.workspaceDir) {
|
|
137
|
-
this.workspaceDir =
|
|
147
|
+
this.workspaceDir = hostSeatPath(config.workspaceDir);
|
|
138
148
|
const shared = config.custody?.sharedRoot;
|
|
139
|
-
this.tenure = shared !== undefined ? { kind: "held",
|
|
149
|
+
this.tenure = shared !== undefined ? { kind: "held", roots: [hostSeatPath(shared)] } : BORROWED;
|
|
140
150
|
}
|
|
141
151
|
else {
|
|
142
|
-
const base = config.workspaceBase ?? os.tmpdir();
|
|
152
|
+
const base = hostSeatPath(config.workspaceBase ?? os.tmpdir());
|
|
143
153
|
const id = config.id ?? randomBytes(6).toString("hex");
|
|
144
154
|
const suffix = randomBytes(4).toString("hex");
|
|
145
|
-
this.workspaceDir = path
|
|
146
|
-
this.tenure = { kind: "held",
|
|
155
|
+
this.workspaceDir = anchorUnder(path, base, `sema-host-${sanitizeId(id)}-${suffix}`);
|
|
156
|
+
this.tenure = { kind: "held", roots: [this.workspaceDir] };
|
|
147
157
|
}
|
|
148
158
|
const inheritEnvProblem = inheritEnvPolicyProblem(config.inheritEnv);
|
|
149
159
|
if (inheritEnvProblem !== undefined)
|
|
@@ -171,11 +181,18 @@ export class RemoteHostExecutionEnv {
|
|
|
171
181
|
return this.teardownSettled;
|
|
172
182
|
}
|
|
173
183
|
leftover = undefined;
|
|
184
|
+
get left() {
|
|
185
|
+
return this.hasLeft;
|
|
186
|
+
}
|
|
174
187
|
get settled() {
|
|
175
|
-
return this.teardownSettled && this.
|
|
188
|
+
return this.teardownSettled && this.hasLeft;
|
|
189
|
+
}
|
|
190
|
+
get heldRoots() {
|
|
191
|
+
return this.tenure.kind === "held" ? this.tenure.roots : NO_ROOTS;
|
|
176
192
|
}
|
|
177
|
-
|
|
178
|
-
|
|
193
|
+
assumeRoot(root) {
|
|
194
|
+
this.tenure = { kind: "held", roots: this.tenure.kind === "held" ? [...this.tenure.roots, root] : [root] };
|
|
195
|
+
trackUnlessAbsent(root);
|
|
179
196
|
}
|
|
180
197
|
workspaceHandle() {
|
|
181
198
|
return this.handle;
|
|
@@ -185,18 +202,14 @@ export class RemoteHostExecutionEnv {
|
|
|
185
202
|
return unsupported("connect(snapshotId)");
|
|
186
203
|
if (this.destroyed)
|
|
187
204
|
return { ok: false, error: new RemoteExecutionError("connect_failed", "execution env already destroyed") };
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
await this.ensurePrepared();
|
|
192
|
-
}
|
|
193
|
-
catch (e) {
|
|
194
|
-
return { ok: false, error: new RemoteExecutionError("connect_failed", `failed to create host workspace ${this.workspaceDir}: ${errMsg(e)}`, asError(e)) };
|
|
195
|
-
}
|
|
196
|
-
if (config?.secrets?.length) {
|
|
197
|
-
}
|
|
205
|
+
return this.seat.connect(config);
|
|
206
|
+
}
|
|
207
|
+
preparedAnswer() {
|
|
198
208
|
return ok(this.handle);
|
|
199
209
|
}
|
|
210
|
+
prepareFailed(e) {
|
|
211
|
+
return { ok: false, error: new RemoteExecutionError("connect_failed", `failed to create host workspace ${this.workspaceDir}: ${errMsg(e)}`, asError(e)) };
|
|
212
|
+
}
|
|
200
213
|
async suspendVM(_options) {
|
|
201
214
|
return unsupported("suspendVM");
|
|
202
215
|
}
|
|
@@ -240,17 +253,37 @@ export class RemoteHostExecutionEnv {
|
|
|
240
253
|
catch { }
|
|
241
254
|
this.spoolRootDir = undefined;
|
|
242
255
|
}
|
|
256
|
+
this.hasLeft = true;
|
|
243
257
|
const tenure = this.tenure;
|
|
244
258
|
if (tenure.kind !== "held")
|
|
245
259
|
return;
|
|
246
260
|
this.tenure = RELEASED;
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
261
|
+
const tombs = [];
|
|
262
|
+
for (const root of tenure.roots) {
|
|
263
|
+
if (this.cfg.custody?.passOn(this, root) === true)
|
|
264
|
+
continue;
|
|
265
|
+
const tomb = removalTombOf(root);
|
|
266
|
+
try {
|
|
267
|
+
renameSync(root, tomb);
|
|
268
|
+
}
|
|
269
|
+
catch (e) {
|
|
270
|
+
if (e?.code === "ENOENT")
|
|
271
|
+
untrackEphemeralHostWorkspace(root);
|
|
272
|
+
else
|
|
273
|
+
trackUnlessAbsent(root);
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
trackEphemeralHostWorkspace(tomb);
|
|
277
|
+
untrackEphemeralHostWorkspace(root);
|
|
278
|
+
tombs.push(tomb);
|
|
252
279
|
}
|
|
253
|
-
|
|
280
|
+
for (const tomb of tombs) {
|
|
281
|
+
try {
|
|
282
|
+
await fs.rm(tomb, { recursive: true, force: true });
|
|
283
|
+
untrackEphemeralHostWorkspace(tomb);
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
}
|
|
254
287
|
}
|
|
255
288
|
}
|
|
256
289
|
async cleanup() {
|
|
@@ -1294,8 +1327,8 @@ export class RemoteHostExecutionEnv {
|
|
|
1294
1327
|
.mkdir(this.workspaceDir, { recursive: true })
|
|
1295
1328
|
.then(() => {
|
|
1296
1329
|
this.prepared = true;
|
|
1297
|
-
|
|
1298
|
-
|
|
1330
|
+
for (const root of this.heldRoots)
|
|
1331
|
+
trackUnlessAbsent(root);
|
|
1299
1332
|
})
|
|
1300
1333
|
.catch((e) => {
|
|
1301
1334
|
this.preparing = undefined;
|
|
@@ -1327,7 +1360,7 @@ export class RemoteHostExecutionEnv {
|
|
|
1327
1360
|
return false;
|
|
1328
1361
|
const real = (x) => {
|
|
1329
1362
|
try {
|
|
1330
|
-
return
|
|
1363
|
+
return physicalPathOf(x);
|
|
1331
1364
|
}
|
|
1332
1365
|
catch {
|
|
1333
1366
|
return undefined;
|
|
@@ -1408,6 +1441,13 @@ export class RemoteHostExecutionEnv {
|
|
|
1408
1441
|
return new FileError("unknown", msg, p);
|
|
1409
1442
|
}
|
|
1410
1443
|
}
|
|
1444
|
+
export function hostSeatPath(p, pathApi = path) {
|
|
1445
|
+
if (pathApi.sep === "\\" && /^[A-Za-z]:(?![\\/])/.test(p)) {
|
|
1446
|
+
const driveCwd = pathApi.resolve(p.slice(0, 2));
|
|
1447
|
+
return p.length === 2 ? driveCwd : anchorUnder(pathApi, driveCwd, p.slice(2));
|
|
1448
|
+
}
|
|
1449
|
+
return anchoredPath(pathApi, process.cwd(), p);
|
|
1450
|
+
}
|
|
1411
1451
|
function sanitizeId(id) {
|
|
1412
1452
|
return id.replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 64) || "task";
|
|
1413
1453
|
}
|
|
@@ -1427,39 +1467,71 @@ function asError(e) {
|
|
|
1427
1467
|
function signalNumber(signal) {
|
|
1428
1468
|
return os.constants.signals[signal];
|
|
1429
1469
|
}
|
|
1470
|
+
function heldRootContaining(custody, dir) {
|
|
1471
|
+
const found = [];
|
|
1472
|
+
custody.holder((m) => {
|
|
1473
|
+
const root = m.heldRoots.find((r) => pathIsWithin(r, dir, canonicalPathOf));
|
|
1474
|
+
if (root !== undefined)
|
|
1475
|
+
found.push(root);
|
|
1476
|
+
return root !== undefined;
|
|
1477
|
+
});
|
|
1478
|
+
return found[0];
|
|
1479
|
+
}
|
|
1480
|
+
function passOnRoot(custody, self, root) {
|
|
1481
|
+
if (custody.holder((m) => m !== self && m.heldRoots.includes(root)) !== undefined)
|
|
1482
|
+
return true;
|
|
1483
|
+
const unreadable = [];
|
|
1484
|
+
const occupant = custody.holder((m) => {
|
|
1485
|
+
if (m === self || m.left)
|
|
1486
|
+
return false;
|
|
1487
|
+
try {
|
|
1488
|
+
return pathIsWithin(root, m.cwd, canonicalPathOf);
|
|
1489
|
+
}
|
|
1490
|
+
catch (error) {
|
|
1491
|
+
unreadable.push({ dir: m.cwd, error });
|
|
1492
|
+
return false;
|
|
1493
|
+
}
|
|
1494
|
+
});
|
|
1495
|
+
if (occupant !== undefined) {
|
|
1496
|
+
occupant.assumeRoot(root);
|
|
1497
|
+
return true;
|
|
1498
|
+
}
|
|
1499
|
+
const first = unreadable[0];
|
|
1500
|
+
if (first === undefined)
|
|
1501
|
+
return false;
|
|
1502
|
+
trackUnlessAbsent(root);
|
|
1503
|
+
writeLogText("stderr", `RemoteHostExecutionEnv: kept ${root} instead of removing it — could not read whether the working directory ${first.dir} lies inside it ` +
|
|
1504
|
+
`(${errorCodeOf(first.error) ?? "unreadable"}); nobody takes it over, and the exit-time sweep removes it`);
|
|
1505
|
+
return true;
|
|
1506
|
+
}
|
|
1507
|
+
function trackUnlessAbsent(root) {
|
|
1508
|
+
let absent;
|
|
1509
|
+
try {
|
|
1510
|
+
absent = !presentOnDisk(root);
|
|
1511
|
+
}
|
|
1512
|
+
catch {
|
|
1513
|
+
absent = false;
|
|
1514
|
+
}
|
|
1515
|
+
if (!absent)
|
|
1516
|
+
trackEphemeralHostWorkspace(root);
|
|
1517
|
+
}
|
|
1518
|
+
function removalTombOf(root) {
|
|
1519
|
+
return anchorUnder(path, path.dirname(root), `.${path.basename(root)}.removing-${randomBytes(4).toString("hex")}`);
|
|
1520
|
+
}
|
|
1430
1521
|
export function hostExecutionEnvFactory(config = {}, legOf = () => ({})) {
|
|
1431
1522
|
const custody = createWorkspaceCustody();
|
|
1432
|
-
const
|
|
1523
|
+
const passOn = (self, root) => passOnRoot(custody, self, root);
|
|
1433
1524
|
return (ctx) => {
|
|
1434
1525
|
const { minted, ...leg } = legOf(ctx);
|
|
1435
1526
|
const identity = ctx.taskId ?? ctx.sessionId;
|
|
1436
1527
|
return custody.envOf(identity, () => {
|
|
1437
1528
|
const dir = leg.workspaceDir ?? config.workspaceDir;
|
|
1438
|
-
const sharedRoot = dir === undefined ? undefined : custody
|
|
1439
|
-
const env = new RemoteHostExecutionEnv({ ...config, ...leg, id: config.id ?? identity, custody: {
|
|
1529
|
+
const sharedRoot = dir === undefined ? undefined : heldRootContaining(custody, hostSeatPath(dir));
|
|
1530
|
+
const env = new RemoteHostExecutionEnv({ ...config, ...leg, id: config.id ?? identity, custody: { passOn, ...(sharedRoot !== undefined ? { sharedRoot } : {}) } });
|
|
1440
1531
|
minted?.(env);
|
|
1441
1532
|
return env;
|
|
1442
1533
|
});
|
|
1443
1534
|
};
|
|
1444
1535
|
}
|
|
1445
|
-
function dirWithin(dir, root) {
|
|
1446
|
-
const inside = (d, r) => {
|
|
1447
|
-
const rel = path.relative(r, d);
|
|
1448
|
-
return rel === "" || (rel.split(path.sep)[0] !== ".." && !path.isAbsolute(rel));
|
|
1449
|
-
};
|
|
1450
|
-
return inside(path.resolve(dir), path.resolve(root)) || inside(physicalPathOf(dir), physicalPathOf(root));
|
|
1451
|
-
}
|
|
1452
|
-
function physicalPathOf(p) {
|
|
1453
|
-
let head = path.resolve(p);
|
|
1454
|
-
const tail = [];
|
|
1455
|
-
while (!existsSync(head)) {
|
|
1456
|
-
const up = path.dirname(head);
|
|
1457
|
-
if (up === head)
|
|
1458
|
-
return path.resolve(p);
|
|
1459
|
-
tail.unshift(path.basename(head));
|
|
1460
|
-
head = up;
|
|
1461
|
-
}
|
|
1462
|
-
return path.join(realpathSync(head), ...tail);
|
|
1463
|
-
}
|
|
1464
1536
|
export { localDockerExecutionEnvFactory, RemoteLocalDockerExecutionEnv } from "./remote-env-local-docker.js";
|
|
1465
1537
|
//# sourceMappingURL=remote-env-host.js.map
|
|
@@ -2,13 +2,46 @@ import { type SpaceReclaimer, type WorkspaceSpacePolicy, type CacheReclaimReason
|
|
|
2
2
|
import { type SpaceCommitFence } from "../workspace-space-commit.js";
|
|
3
3
|
import { type CacheMissMemory, type WorkspaceCacheCapability } from "../workspace-cache.js";
|
|
4
4
|
import { type SandboxEgressGap, type SandboxIpv6 } from "../sandbox-egress-policy.js";
|
|
5
|
-
import {
|
|
5
|
+
import { type K8sApiCredentialFact } from "../k8s-api-credentials.js";
|
|
6
|
+
import { FileError, ExecutionError, RemoteExecutionError, type ExecutionEnv, type ExecResult, type RemoteExecutionEnv, type WorkspaceHandle, type FileInfo, type Result, type SymlinkChain, type BoundFileObject, type OutputChunk, type ExecStreamOptions, type RemoteConnectConfig, type SnapshotId, type SessionToken, type VmLifecycleOptions, type ExecutionEnvFactory, type BackgroundShellCapability, type BackgroundShellId, type BackgroundShellError, type BackgroundSpawnOptions, type BackgroundPoll, type ExecutionEnvCapabilities } from "@sema-agent/core";
|
|
6
7
|
import { type SandboxReadFloorKnob } from "../execution-lane-caps.js";
|
|
7
8
|
import { type SandboxReadFloor } from "./sandbox-read-floor.js";
|
|
8
9
|
import type { PodSpecPatch } from "./k8s-exec-protocol.js";
|
|
9
10
|
import { type LaneHomeConfig } from "../lane-home-probe.js";
|
|
11
|
+
import { type ConnectResult } from "./remote-env-connect-seat.js";
|
|
10
12
|
type ExecOpts = Parameters<ExecutionEnv["exec"]>[1];
|
|
11
13
|
export { buildBgRunnerScript, buildBgLauncherScript, buildBgPollScript, buildBgKillScript, buildBgDisposeScript, buildDetachCapableExec, buildKillAllScript, parseBgPollOutput, type ParsedBgPoll, } from "./k8s-bg-scripts.js";
|
|
14
|
+
/**
|
|
15
|
+
* This process's in-cluster identity: the platform's `KUBERNETES_SERVICE_*` and the mounted service-account files. `readMounted` throws when the file is unreadable.
|
|
16
|
+
* (In this file a bare `read(` names a control-plane GET — the RBAC table's source reader classifies every one — so the mount reader carries its own name.)
|
|
17
|
+
*/
|
|
18
|
+
export interface InClusterIdentity {
|
|
19
|
+
readonly host: string | undefined;
|
|
20
|
+
readonly port: string | undefined;
|
|
21
|
+
readMounted(file: "token" | "ca.crt"): string;
|
|
22
|
+
}
|
|
23
|
+
/** What the control plane can be reached with — or the ONE missing fact (with the adapter code its request-time refusal carries). */
|
|
24
|
+
export type K8sApiAccess = {
|
|
25
|
+
readonly ok: true;
|
|
26
|
+
readonly apiUrl: string;
|
|
27
|
+
readonly token: string;
|
|
28
|
+
readonly ca: string | undefined;
|
|
29
|
+
} | {
|
|
30
|
+
readonly ok: false;
|
|
31
|
+
readonly fact: K8sApiCredentialFact;
|
|
32
|
+
readonly code: "connect_failed" | "auth_failed";
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* The ONE judge of "does this lane have cluster API credentials": explicit config (`K8S_API_URL` / `K8S_TOKEN` / `K8S_CA_CERT_B64`, `K8S_INSECURE_TLS`) first, the
|
|
36
|
+
* in-cluster service account second, per piece. The request-time reader ({@link RemoteK8sExecutionEnv}'s `creds()`), the boot gate and the per-run credential
|
|
37
|
+
* reading all read THIS function — what the boot refuses on is exactly what every request would have thrown on. (No kubeconfig: this lane never reads one.)
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveK8sApiAccess(cfg: {
|
|
40
|
+
readonly apiUrl?: string | undefined;
|
|
41
|
+
readonly token?: string | undefined;
|
|
42
|
+
readonly caCert?: string | undefined;
|
|
43
|
+
readonly insecureTls?: boolean | undefined;
|
|
44
|
+
}, inCluster?: InClusterIdentity): K8sApiAccess;
|
|
12
45
|
export interface K8sEnvConfig extends LaneHomeConfig {
|
|
13
46
|
/** API server URL. Default: in-cluster (`https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT`). */
|
|
14
47
|
apiUrl?: string;
|
|
@@ -175,13 +208,6 @@ export { type PodSpecPatch, applyPodSpecPatch } from "./k8s-exec-protocol.js";
|
|
|
175
208
|
import { type SandboxPodApi, type SandboxPodListing } from "./k8s-pod-reaper.js";
|
|
176
209
|
import { type SandboxLeaseEntryInput } from "../sandbox-git-lease.js";
|
|
177
210
|
import type { WorkspaceFill } from "./workspace-fill.js";
|
|
178
|
-
type ConnectResult = {
|
|
179
|
-
ok: true;
|
|
180
|
-
value: WorkspaceHandle;
|
|
181
|
-
} | {
|
|
182
|
-
ok: false;
|
|
183
|
-
error: RemoteExecutionError;
|
|
184
|
-
};
|
|
185
211
|
/** Minimal exec-socket surface (what we use of `ws`) so tests can inject a fake. */
|
|
186
212
|
export interface ExecSocket {
|
|
187
213
|
on(event: "open" | "message" | "close" | "error", listener: (...args: unknown[]) => void): void;
|
|
@@ -200,6 +226,21 @@ export interface K8sRequestOptions {
|
|
|
200
226
|
signal?: AbortSignal;
|
|
201
227
|
contentType?: string;
|
|
202
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* The control plane's reading of this lane's credentials, a closed set: `missing` (the judge's fact — nothing to send), `rejected` (the cluster answered HTTP 401),
|
|
231
|
+
* `accepted` (a 2xx answer: the credentials work), `unproven` (any other answer, or none — see {@link RemoteK8sExecutionEnv.apiCredentialReading}).
|
|
232
|
+
*/
|
|
233
|
+
export type ApiCredentialReading = {
|
|
234
|
+
readonly state: "missing";
|
|
235
|
+
readonly fact: K8sApiCredentialFact;
|
|
236
|
+
} | {
|
|
237
|
+
readonly state: "rejected";
|
|
238
|
+
} | {
|
|
239
|
+
readonly state: "accepted";
|
|
240
|
+
} | {
|
|
241
|
+
readonly state: "unproven";
|
|
242
|
+
readonly detail: string;
|
|
243
|
+
};
|
|
203
244
|
export interface K8sEnvDeps {
|
|
204
245
|
request?: (method: string, apiPath: string, body?: unknown, opts?: K8sRequestOptions) => Promise<{
|
|
205
246
|
status: number;
|
|
@@ -209,6 +250,8 @@ export interface K8sEnvDeps {
|
|
|
209
250
|
connectOnce?: (signal?: AbortSignal) => Promise<ConnectResult>;
|
|
210
251
|
/** Worker-side object-store requests (the space pointer, listing, deletes). Default: global `fetch`; either way the request goes out through the egress exit (an endpoint that answers with a redirect is refused, never followed). */
|
|
211
252
|
fetch?: typeof fetch;
|
|
253
|
+
/** This process's in-cluster identity (default: the process env's `KUBERNETES_SERVICE_*` and the mounted service-account files); a test replaces it. */
|
|
254
|
+
inCluster?: () => InClusterIdentity;
|
|
212
255
|
/** 这只环境手里的读地板模块(缺席 ⇒ `createSandboxReadFloor` 按旋钮选;钉注入守地板的模块)。能力块的 `keepsReadFloor` 读它的状态。 */
|
|
213
256
|
readFloor?: SandboxReadFloor;
|
|
214
257
|
}
|
|
@@ -325,11 +368,15 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
|
|
|
325
368
|
private connectInFlight?;
|
|
326
369
|
/** The resume among them, with the snapshot it restores: a second `resumeVM` of the same snapshot shares it (one restore, one pod). */
|
|
327
370
|
private resumeInFlight?;
|
|
328
|
-
/**
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
|
|
371
|
+
/**
|
|
372
|
+
* This env's connect seat (`remote-env-connect-seat.ts`): the one order of `connect` — a refusal the env holds ⇒ answered as it stands · a walk in flight
|
|
373
|
+
* ({@link connectInFlight}) ⇒ its answer · a pod already holding the workspace ⇒ its handle · otherwise one walk ({@link establish}). The seat holds the env's
|
|
374
|
+
* refusal — a standing one, spelled by the seat's refusal table (a missing snapshot bucket, an archive that is there and did not come back, the cluster
|
|
375
|
+
* refusing the pod at admission, the member-credential broker that cannot be set up, a fill refused the same on any pod, a home the pod answered against
|
|
376
|
+
* the claim, a session row with no occupant token): a fact of this env until `destroy`, answered to every later connect and every later pod creation
|
|
377
|
+
* ({@link provision}) — zero pods, zero store requests, no second line. A refusal that heals by itself (a quota, a store that did not answer) is not held.
|
|
378
|
+
*/
|
|
379
|
+
private readonly seat;
|
|
333
380
|
/** core `ExecutionEnv.homeDir`([ref]):pod 里执行用户的 home —— 声明在场 ⇒ 声明(开环境那一拍与 `$HOME` 对证过),否则 pod 就绪那一拍实测的 `$HOME`,见 {@link LaneHomeSeat}。读时才取(没声明时 pod 起来之前缺席)。 */
|
|
334
381
|
get homeDir(): string | undefined;
|
|
335
382
|
/** 家目录的座(声明在场 ⇒ 开环境那一拍对证 · 否则 pod 就绪那一拍实测 · 实测缺席 ⇒ 缺席 + 一行 warn)。与其余读得出家目录的车道同一只判官、同一句拒。 */
|
|
@@ -371,8 +418,18 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
|
|
|
371
418
|
get lifetimeMs(): number;
|
|
372
419
|
private resolve;
|
|
373
420
|
workspaceHandle(): WorkspaceHandle;
|
|
374
|
-
/** Resolved lazily so an in-cluster pod picks up its service account without explicit config. */
|
|
421
|
+
/** Resolved lazily so an in-cluster pod picks up its service account without explicit config ({@link resolveK8sApiAccess} is the one judge). */
|
|
375
422
|
private creds;
|
|
423
|
+
/** The missing credential fact of this env's control-plane access, or `undefined` (nothing missing) — {@link resolveK8sApiAccess}, the one judge. */
|
|
424
|
+
missingApiCredential(): K8sApiCredentialFact | undefined;
|
|
425
|
+
/**
|
|
426
|
+
* The control plane's reading of this lane's credentials, asked once per run before its env is minted ({@link readSandboxApiCredentials}): the judge's missing fact
|
|
427
|
+
* ({@link missingApiCredential}), else one SelfSubjectAccessReview (answered for every authenticated caller) — an HTTP 401 is the cluster rejecting the credentials,
|
|
428
|
+
* a 2xx the cluster accepting them. ONLY a positive proof of rejection refuses: any other answer (403, 5xx, a request that threw or timed out) is `unproven` — another
|
|
429
|
+
* fact (a Role, an outage) that the lane's own connect answers loudly and retries within its own bounds; refusing the run on it would turn every API blip into a failed run.
|
|
430
|
+
* The caller counts an `unproven` reading (a registered fail-open arm). Never throws.
|
|
431
|
+
*/
|
|
432
|
+
apiCredentialReading(): Promise<ApiCredentialReading>;
|
|
376
433
|
/** Control-plane REST call (pod create/get/delete), bounded by rpcTimeoutMs. Injectable for tests. */
|
|
377
434
|
private request;
|
|
378
435
|
private openExec;
|
|
@@ -381,18 +438,20 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
|
|
|
381
438
|
* ({@link awaitSpaceCommit}: the run store's commit row), then read `<prefix>/<incarnation>/space/latest`: present ⇒
|
|
382
439
|
* restore it through {@link restoreSnapshot} (the one tar download, shared with `resumeVM`; an archive that is gone ⇒
|
|
383
440
|
* loud `workspace_latest_dangling`, the pointer deleted, an empty workspace); absent (404 — the key, with the bucket there) ⇒ a fresh pod; a read that
|
|
384
|
-
* FAILS ⇒ a loud
|
|
441
|
+
* FAILS ⇒ a loud refusal — `connect_failed` (that attempt's: the next connect reads again), or, for a 404 `NoSuchBucket`, the env's standing
|
|
442
|
+
* `env.snapshot_bucket_missing` ({@link refuseMissingBucket}) — never a silent fresh workspace (a run that believes it resumed while it did not is
|
|
385
443
|
* the worst form). Once the pod holds the workspace, this env arms its fence seat (its destroy will commit).
|
|
386
444
|
* The same walk ({@link establish}) is the restore point of a parked run's resumed leg whose park packed nothing ({@link resumeVM}).
|
|
387
445
|
* Persistence off / no store ⇒ a fresh pod, exactly as before. Persistence on but no such session (the occupant absent) ⇒ a
|
|
388
|
-
* fresh pod and one `workspace_space_unavailable` line (no restore by any other key). The occupant read FAULTED ⇒
|
|
389
|
-
*
|
|
390
|
-
*
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
446
|
+
* fresh pod and one `workspace_space_unavailable` line (no restore by any other key). The occupant read FAULTED ⇒ a refusal worded as a
|
|
447
|
+
* failed `latest` read, no pod ({@link provision} refuses it — every entry that would create one; {@link refuseUnreadableOccupant} spells its two facts).
|
|
448
|
+
* `connect` is idempotent — the one order of the env's {@link seat}: a refusal this env holds (a restore that did not come back, a pod the cluster refused at
|
|
449
|
+
* admission, a missing bucket …) is answered as it stands to every later connect on every lane — the previous commit is not waited on again, `latest` is not
|
|
450
|
+
* read again, no pod is created; a walk in flight (the explicit connect, the lazy one of the first operation, `reconnect`, a resume) ⇒ THAT walk's answer (one pod
|
|
451
|
+
* creation, one restore, one refusal line), a caller's abort withdrawing only its own wait; a pod already holding the workspace ⇒ its handle, nothing created
|
|
452
|
+
* (the engine's restore seat is commonly not the first connection: a delegated child touched the env during its placement check); otherwise one walk. A
|
|
453
|
+
* failure that is not held (a pod that could not be created, a space read that failed) ⇒ the next connect walks afresh. The abort signal of the connect that
|
|
454
|
+
* started the walk is the one in force for the walk.
|
|
396
455
|
*/
|
|
397
456
|
connect(config?: RemoteConnectConfig): Promise<ConnectResult>;
|
|
398
457
|
/** 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,7 +461,7 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
|
|
|
402
461
|
* 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
|
|
403
462
|
* 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).
|
|
404
463
|
* 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
|
|
405
|
-
* again (`standing`) is held for the env ({@link
|
|
464
|
+
* again (`standing`) is held for the env (its {@link seat}). No seat ⇒ the pod as it came. `origin` tells the seat whether the workspace was minted
|
|
406
465
|
* (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)
|
|
407
466
|
* 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.
|
|
408
467
|
*/
|
|
@@ -430,21 +489,22 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
|
|
|
430
489
|
/** The space lane is on but this run's session has no occupant (no such session — {@link SpaceOccupant}) — said once per env
|
|
431
490
|
* (at connect, or at a destroy with a pod). `reason` = the reading's word. */
|
|
432
491
|
private sayUnavailable;
|
|
433
|
-
/** Hold `error` as this env's refusal ({@link connectRefusal}) and answer it — the ONE writer of the slot (the restore and the pod's admission both write through it). */
|
|
434
|
-
private holdRefusal;
|
|
435
492
|
/**
|
|
436
493
|
* The cluster created this env's pod and it ended `Failed` (or `Succeeded`) before it ever ran — the kubelet refused it at admission
|
|
437
494
|
* (`SysctlForbidden` when `K8S_SANDBOX_IPV6=disabled` meets a kubelet that does not allow the two sysctls, a node-affinity miss, no capacity on the
|
|
438
|
-
* node …): the env's refusal ({@link
|
|
495
|
+
* node …): the env's refusal (held by its {@link seat}: `env.sandbox_refused`, standing) with the kubelet's reason in the sentence — so the operation that meets
|
|
439
496
|
* it, and every later one, says what the cluster said, instead of a new pod per operation. One `sandbox_pod_refused{pod, phase, reason, detail}` line per env
|
|
440
497
|
* (`detail` = the kubelet's own text, cut). A retry of the run builds a fresh env, which asks the cluster afresh.
|
|
441
498
|
*/
|
|
442
499
|
private refusePod;
|
|
443
500
|
/**
|
|
444
|
-
* A lane that is on is keyed by an occupant read that FAULTED (`unreadable`) ⇒ this env creates no pod: the refusal,
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
*
|
|
501
|
+
* A lane that is on is keyed by an occupant read that FAULTED (`unreadable`) ⇒ this env creates no pod: the refusal, worded as the space-read failures are
|
|
502
|
+
* (a failed `latest` / commit-row read says the same head), naming the knob of every lane that refuses; one `workspace_space_unreadable_occupant{sessionId, code}`
|
|
503
|
+
* line per env. `code` = the store error's code, never its text. Not a knob: there is no honest way to run a space we could not read. Two facts, by the code:
|
|
504
|
+
* - `session.incarnation_missing` — the session row is there and carries no occupant token: a data defect that answers the same to every read ⇒ standing
|
|
505
|
+
* (`env.occupant_missing`, held by the {@link seat}); the way out is the row (give it its token, or delete the session) or the knob;
|
|
506
|
+
* - any other code (the read timed out, the store failed, an answer the projection could not read) ⇒ it heals by itself: a retry of the run reads it again
|
|
507
|
+
* (`connect_failed`). The reading is this env's, fixed at construction, so this env answers it to every operation all the same.
|
|
448
508
|
*/
|
|
449
509
|
private refuseUnreadableOccupant;
|
|
450
510
|
/** Every space-lane operator line: the space is named by its incarnation's log prefix only ({@link snapshotLine} does the rest). */
|
|
@@ -457,12 +517,11 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
|
|
|
457
517
|
* here, before any request ({@link refuseUnreadableOccupant}): never retried (the reading is this env's, fixed at construction). */
|
|
458
518
|
private provision;
|
|
459
519
|
/**
|
|
460
|
-
* Lazy-connect on first use —
|
|
461
|
-
* the
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
*
|
|
465
|
-
* next op's connect answers that same refusal at once.
|
|
520
|
+
* Lazy-connect on first use — an operation may meet the env before anything connected it (a delegated child's placement check, a factory layer writing into
|
|
521
|
+
* the env before handing it over), so the adapter connects itself; the engine's explicit connect at the leg's restore seat then finds it connected (the
|
|
522
|
+
* {@link seat}'s idempotent order). `destroyed` is terminal. Concurrent first ops share ONE pod create — through {@link connect}'s one walk in flight, the same
|
|
523
|
+
* seat the explicit connect shares. How long a failure stands is the seat's: a failure of that attempt (a pod that could not be created, a space read that
|
|
524
|
+
* failed) ⇒ the next op connects afresh; the env's held refusal ⇒ the next op's connect answers that same refusal at once.
|
|
466
525
|
*/
|
|
467
526
|
private ensureConnected;
|
|
468
527
|
/**
|
|
@@ -554,7 +613,7 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
|
|
|
554
613
|
* snapshotKey()+s3Presign() pair so the two call sites can't diverge.
|
|
555
614
|
*/
|
|
556
615
|
private presignSnapshot;
|
|
557
|
-
/** The key prefix of every snapshot object this env signs — the ONE reading of `keyPrefix` (unset ⇒ the default); its form is judged in {@link presignSnapshot}. */
|
|
616
|
+
/** The key prefix of every snapshot object this env signs — `workspaceSnapshotPrefixOf`, the ONE reading of `keyPrefix` (unset ⇒ the default; the boot bucket check lists under the same reading); its form is judged in {@link presignSnapshot}. */
|
|
558
617
|
private snapshotKeyPrefix;
|
|
559
618
|
/** A lane's partition prefix inside the bucket — the ONE place it is spelled (`presignSnapshot` signs under it; the reclaim reads the listing against it).
|
|
560
619
|
* The partition segment is validated by `presignSnapshot` before a URL is signed. */
|
|
@@ -591,8 +650,8 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
|
|
|
591
650
|
* The store answered `404 NoSuchBucket` — to the space's `latest` read (`read: "pointer"`) or to a restore's archive GET (`read: "archive"`, either lane:
|
|
592
651
|
* the pod relays the store's answer, {@link restoreSnapshot}): the workspace snapshot bucket does not exist, so this workspace can be neither restored nor
|
|
593
652
|
* saved — a run started on it would work on an empty /workspace and lose everything it wrote. One fact, one consequence on both lanes and both reads: the
|
|
594
|
-
* env's refusal ({@link
|
|
595
|
-
* the archive read in the same words — and one `workspace_snapshot_bucket_missing{bucket, code, effect}` line per env, carrying `space` on the space lane and
|
|
653
|
+
* env's refusal (`env.snapshot_bucket_missing`, standing, held by the {@link seat}) naming the bucket and the knob that picks it — the pointer read worded as the
|
|
654
|
+
* space-read failures are ({@link spaceReadFailed}), the archive read in the same words — and one `workspace_snapshot_bucket_missing{bucket, code, effect}` line per env, carrying `space` on the space lane and
|
|
596
655
|
* `sessionId` on the park lane (the refusal stands until destroy: later connects and operations answer it without another read or line; a retry of the run
|
|
597
656
|
* builds a fresh env, which asks the store afresh — a bucket created in between is found). The boot probe (`snapshot-bucket-presence.ts`) refuses a boot
|
|
598
657
|
* where the bucket is already missing; this is the same judgement ({@link isNoSuchBucketAnswer}) for a bucket that went missing afterwards or that the probe
|
|
@@ -706,7 +765,7 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
|
|
|
706
765
|
* - space: the archive `latest` names is THERE and did not come back ({@link RestoreFailureClass}): the run is refused all the
|
|
707
766
|
* same — never an empty workspace (the user's changes are still in the bucket) — with exactly one `workspace_restore_failed`
|
|
708
767
|
* line (its `attempts`; an attempt that failed before one that succeeded is no line) and a refusal naming the two ways out,
|
|
709
|
-
* held for the env
|
|
768
|
+
* held for the env by its {@link seat} (`env.sandbox_refused`, standing).
|
|
710
769
|
* A pod that could not be created is that attempt's failure, not the archive's: returned as it is — no line, nothing held, the
|
|
711
770
|
* next connect tries again. An abort during the pause ends the restore `aborted` (not the archive's either).
|
|
712
771
|
*/
|
|
@@ -877,6 +936,8 @@ export declare class RemoteK8sExecutionEnv implements RemoteExecutionEnv, Backgr
|
|
|
877
936
|
* 循环(上限 64、只锚不折、遇环即止),脚本与读法的单一属主在 `remote-shell.ts`,四条 shell 腿共用同一份。
|
|
878
937
|
* 缺席读法用不上(本腿在场);`ok:false` 由 core 读作「这一次没有跳」,永不是拒绝。 */
|
|
879
938
|
canonicalChain(p: string, abortSignal?: AbortSignal): Promise<Result<SymlinkChain, FileError>>;
|
|
939
|
+
/** 绑定读(逐答重绑,Linux 读法;脚本与读法的单一属主在 `remote-shell.ts`,四条 shell 腿共用同一份)。 */
|
|
940
|
+
openBound(p: string, abortSignal?: AbortSignal): Promise<Result<BoundFileObject, FileError>>;
|
|
880
941
|
canonicalPath(p: string, abortSignal?: AbortSignal): Promise<Result<string, FileError>>;
|
|
881
942
|
exists(p: string, abortSignal?: AbortSignal): Promise<Result<boolean, FileError>>;
|
|
882
943
|
createDir(p: string, options?: {
|
|
@@ -925,6 +986,13 @@ export declare function createSpaceReclaimer(config: K8sEnvConfig, deps?: K8sEnv
|
|
|
925
986
|
* nodes that join after boot are read at the next boot. Never throws (a read failure is an `unreadable` gap).
|
|
926
987
|
*/
|
|
927
988
|
export declare function checkSandboxEgressPolicy(config: K8sEnvConfig, deps?: K8sEnvDeps): Promise<SandboxEgressGap[]>;
|
|
989
|
+
/**
|
|
990
|
+
* The missing cluster-API credential fact of this k8s config's control-plane access ({@link RemoteK8sExecutionEnv.missingApiCredential}), or `undefined`. The boot
|
|
991
|
+
* gate's judgment: the one judge ({@link resolveK8sApiAccess}) over the config and the process's in-cluster identity. Never throws.
|
|
992
|
+
*/
|
|
993
|
+
export declare function sandboxApiCredentialFact(config: K8sEnvConfig, deps?: K8sEnvDeps): K8sApiCredentialFact | undefined;
|
|
994
|
+
/** The control plane's reading of this lane's credentials ({@link RemoteK8sExecutionEnv.apiCredentialReading}; a control-plane env, no pod). Never throws. */
|
|
995
|
+
export declare function readSandboxApiCredentials(config: K8sEnvConfig, deps?: K8sEnvDeps): Promise<ApiCredentialReading>;
|
|
928
996
|
/** The boot reading of one sandbox Secret seat for this k8s config ({@link RemoteK8sExecutionEnv.secretSeatReading}; a control-plane env, no pod). Never throws. */
|
|
929
997
|
export declare function readSandboxSecretSeat(config: K8sEnvConfig, seat: SandboxSecretSeatKind, deps?: K8sEnvDeps): Promise<SandboxSecretSeat>;
|
|
930
998
|
/**
|