@sema-agent/server 7.139.0 → 7.141.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 +471 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +94 -26
- package/dist/adoption/runner.js +1 -1
- package/dist/adoption/sql.js +1 -1
- package/dist/approval-batch-census.d.ts +27 -0
- package/dist/approval-batch-census.js +27 -0
- package/dist/approval-card.d.ts +37 -22
- package/dist/approval-card.js +6 -3
- package/dist/approval.d.ts +15 -0
- package/dist/approval.js +10 -0
- package/dist/audit.d.ts +4 -2
- package/dist/audit.js +2 -2
- package/dist/bench/s1/live-deps.js +3 -2
- package/dist/bench/s1/row.d.ts +5 -2
- package/dist/bench/s1/row.js +2 -22
- package/dist/boot/adoption.js +1 -1
- package/dist/boot/device-lane.d.ts +11 -0
- package/dist/boot/device-lane.js +16 -0
- package/dist/boot/engine-lease.d.ts +24 -3
- package/dist/boot/engine-lease.js +9 -2
- package/dist/boot/execution-env.js +18 -12
- package/dist/boot/execution-lane.d.ts +8 -0
- package/dist/boot/execution-lane.js +6 -1
- package/dist/boot/memory-boundary.d.ts +16 -53
- package/dist/boot/memory-boundary.js +10 -20
- package/dist/boot/memory-consolidation.d.ts +16 -12
- package/dist/boot/memory-consolidation.js +24 -13
- package/dist/boot/reapers.d.ts +2 -2
- package/dist/boot/resolve-spec.d.ts +3 -5
- package/dist/boot/resolve-spec.js +9 -8
- package/dist/boot/runner-deps.d.ts +3 -3
- package/dist/boot/runner-deps.js +1 -0
- package/dist/boot/session-faces.d.ts +1 -1
- package/dist/boot/session-faces.js +4 -3
- package/dist/boot/shutdown.js +5 -0
- package/dist/boot/stage-03-store-backend.d.ts +2 -6
- package/dist/boot/stage-03-store-backend.js +2 -3
- package/dist/boot/stage-04-stores.d.ts +2 -6
- package/dist/boot/stage-04-stores.js +5 -5
- package/dist/boot/stage-05-execution-env.d.ts +2 -6
- package/dist/boot/stage-05-execution-env.js +3 -1
- package/dist/boot/stage-06-runners.d.ts +2 -8
- package/dist/boot/stage-06-runners.js +3 -3
- package/dist/boot/stage-07-capability-layer.d.ts +2 -7
- package/dist/boot/stage-07-capability-layer.js +8 -10
- package/dist/boot/stage-08-reapers.d.ts +2 -7
- package/dist/boot/stage-09-leader.d.ts +2 -7
- package/dist/boot/stage-10-http-server.d.ts +2 -7
- package/dist/boot/stage-10-http-server.js +6 -4
- package/dist/boot/stores.d.ts +3 -6
- package/dist/boot/stores.js +37 -44
- package/dist/boot/task-list-lane.d.ts +1 -1
- package/dist/boot/task-list-lane.js +1 -1
- package/dist/boot/web-admin.js +36 -9
- package/dist/capabilities/execution-lane.d.ts +2 -2
- package/dist/capabilities/scenarios.d.ts +1 -1
- package/dist/capability-facts.d.ts +9 -0
- package/dist/capability-facts.js +9 -0
- package/dist/card-void.d.ts +38 -0
- package/dist/card-void.js +23 -0
- package/dist/config-catalog.js +12 -8
- package/dist/config-provider.d.ts +18 -17
- package/dist/config-provider.js +28 -36
- package/dist/config-types.d.ts +36 -9
- package/dist/config.js +56 -46
- package/dist/delegated-session-owner.d.ts +23 -20
- package/dist/delegated-session-owner.js +2 -2
- package/dist/deployment-shape.d.ts +9 -8
- package/dist/deployment-shape.js +4 -4
- package/dist/device-store.d.ts +7 -0
- package/dist/device-store.js +3 -0
- package/dist/execution-config-root.d.ts +22 -0
- package/dist/execution-config-root.js +35 -0
- package/dist/execution-lane-caps.d.ts +145 -107
- package/dist/execution-lane-caps.js +144 -83
- package/dist/execution-placement.d.ts +3 -0
- package/dist/execution-placement.js +7 -0
- package/dist/fleet/drain-entry.d.ts +3 -0
- package/dist/hosted-posture.d.ts +8 -0
- package/dist/hosted-posture.js +4 -0
- package/dist/http/admission.js +3 -3
- package/dist/http/caller-trust.d.ts +3 -2
- package/dist/http/caller-trust.js +2 -1
- package/dist/http/dispatch.js +4 -0
- package/dist/http/live-frame.d.ts +24 -0
- package/dist/http/live-frame.js +16 -0
- package/dist/http/memory-compliance-failure-reply.d.ts +3 -1
- package/dist/http/memory-compliance-failure-reply.js +5 -0
- package/dist/http/memory-layer-reply.d.ts +30 -0
- package/dist/http/memory-layer-reply.js +24 -0
- package/dist/http/resume-legs.js +49 -35
- package/dist/http/retired-service-deps.d.ts +1 -1
- package/dist/http/retired-service-deps.js +1 -1
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/adoption.js +1 -1
- package/dist/http/routes/approvals-assistant.js +1 -0
- package/dist/http/routes/capabilities.js +5 -4
- package/dist/http/routes/diagnostics.d.ts +0 -19
- package/dist/http/routes/diagnostics.js +16 -2
- package/dist/http/routes/memory-bundle.d.ts +2 -2
- package/dist/http/routes/memory-bundle.js +4 -1
- package/dist/http/routes/memory-compliance.js +9 -2
- package/dist/http/routes/memory-consolidation.js +12 -1
- package/dist/http/routes/memory-origin.js +14 -2
- package/dist/http/routes/memory-policy.js +7 -2
- package/dist/http/routes/run-permission-mode.d.ts +75 -0
- package/dist/http/routes/run-permission-mode.js +170 -0
- package/dist/http/routes/session-sync.d.ts +3 -6
- package/dist/http/routes/session-sync.js +7 -2
- package/dist/http/routes/sessions.js +33 -15
- package/dist/http/routes/tasks.js +67 -68
- package/dist/http/run-read-face.js +3 -3
- package/dist/http/send.d.ts +1 -1
- package/dist/http/send.js +2 -2
- package/dist/http/server.d.ts +14 -27
- package/dist/http/server.js +2 -2
- package/dist/http/sse-log.d.ts +3 -8
- package/dist/http/stored-body-replay.d.ts +3 -3
- package/dist/http/stored-body-replay.js +3 -1
- package/dist/identity-source.d.ts +1 -1
- package/dist/identity-source.js +1 -1
- package/dist/instruction-source-notice.d.ts +7 -0
- package/dist/instruction-source-notice.js +6 -6
- package/dist/lane-home-probe.d.ts +68 -42
- package/dist/lane-home-probe.js +53 -30
- package/dist/leader/wire.js +5 -4
- package/dist/mcp-assertion-header.d.ts +4 -0
- package/dist/mcp-assertion-header.js +5 -0
- package/dist/memory-bundle-engine.d.ts +16 -9
- package/dist/memory-bundle-engine.js +29 -6
- package/dist/memory-operator-faces.d.ts +85 -30
- package/dist/memory-operator-faces.js +136 -30
- package/dist/memory-posture.d.ts +1 -1
- package/dist/memory-project-layer.d.ts +3 -21
- package/dist/memory-project-layer.js +11 -8
- package/dist/memory-scope-stores.d.ts +73 -0
- package/dist/memory-scope-stores.js +86 -0
- package/dist/memory-scope.d.ts +33 -9
- package/dist/memory-scope.js +17 -5
- package/dist/memory-sync-client.d.ts +34 -9
- package/dist/memory-sync-client.js +108 -28
- package/dist/observability/fail-open.d.ts +30 -2
- package/dist/observability/fail-open.js +30 -2
- package/dist/observability/metrics.js +0 -1
- package/dist/observability/run-terminal.d.ts +6 -2
- package/dist/observability/run-terminal.js +25 -26
- package/dist/observability/secret-env-scrub.d.ts +20 -1
- package/dist/observability/secret-env-scrub.js +14 -0
- package/dist/orchestration/workflow-completion-inbox.d.ts +5 -2
- package/dist/orchestration/workflow-completion-inbox.js +13 -5
- package/dist/orchestration/workflow-notify-journal.d.ts +5 -3
- package/dist/orchestration/workflow-notify-journal.js +2 -1
- package/dist/permission-mode-admission.d.ts +68 -0
- package/dist/permission-mode-admission.js +23 -0
- package/dist/permission-rule-list.d.ts +55 -6
- package/dist/permission-rule-list.js +52 -5
- package/dist/plugins/adoption-log-sql.js +4 -4
- package/dist/plugins/approval-ask-store-sql.js +14 -14
- package/dist/plugins/approval-nonce-store.js +4 -4
- package/dist/plugins/blob-backend.d.ts +4 -4
- package/dist/plugins/blob-backend.js +7 -7
- package/dist/plugins/breaker-state-sql.js +2 -2
- package/dist/plugins/caching-session-store.d.ts +6 -0
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-index-columns.js +2 -2
- package/dist/plugins/checkpoint-store-sql.d.ts +65 -17
- package/dist/plugins/checkpoint-store-sql.js +90 -19
- package/dist/plugins/device-store-sql.d.ts +5 -2
- package/dist/plugins/device-store-sql.js +23 -20
- package/dist/plugins/ensure-index.d.ts +1 -2
- package/dist/plugins/execution-placement-sql.d.ts +19 -9
- package/dist/plugins/execution-placement-sql.js +20 -9
- package/dist/plugins/file-history-store-sql.d.ts +2 -2
- package/dist/plugins/file-history-store-sql.js +4 -4
- package/dist/plugins/file-run-store.d.ts +2 -2
- package/dist/plugins/file-run-store.js +1 -1
- package/dist/plugins/fork-routing-session-store.d.ts +10 -32
- package/dist/plugins/fork-routing-session-store.js +2 -61
- package/dist/plugins/image-bake-store-sql.js +9 -9
- package/dist/plugins/image-index-sql.js +11 -11
- package/dist/plugins/k8s-exec-protocol.d.ts +4 -1
- package/dist/plugins/k8s-exec-protocol.js +6 -1
- package/dist/plugins/leader-run-store-sql.js +4 -4
- package/dist/plugins/local-checkpoint-store.d.ts +10 -1
- package/dist/plugins/local-checkpoint-store.js +22 -0
- package/dist/plugins/local-session-store.d.ts +227 -35
- package/dist/plugins/local-session-store.js +518 -37
- package/dist/plugins/local-session-window.d.ts +17 -3
- package/dist/plugins/local-session-window.js +7 -13
- package/dist/plugins/mailbox-store-sql.d.ts +2 -1
- package/dist/plugins/mailbox-store-sql.js +4 -4
- package/dist/plugins/memory-engine-tidb.js +5 -5
- package/dist/plugins/memory-optout-grant-store-sql.js +1 -1
- package/dist/plugins/memory-run-store.d.ts +2 -2
- package/dist/plugins/memory-run-store.js +1 -1
- package/dist/plugins/memory-sync-store-tidb.js +3 -3
- package/dist/plugins/one-time-migrations.d.ts +52 -11
- package/dist/plugins/one-time-migrations.js +101 -39
- package/dist/plugins/org-delivery-quota-store.js +2 -2
- package/dist/plugins/outcome-ledger-sql.js +2 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +4 -4
- package/dist/plugins/permission-rule-store-sql.js +16 -16
- package/dist/plugins/pg-pool.js +3 -2
- package/dist/plugins/pg-session-storage.d.ts +2 -0
- package/dist/plugins/pg-session-storage.js +3 -2
- package/dist/plugins/remote-env-adb.d.ts +7 -24
- package/dist/plugins/remote-env-adb.js +22 -5
- package/dist/plugins/remote-env-device.d.ts +2 -28
- package/dist/plugins/remote-env-device.js +2 -1
- package/dist/plugins/remote-env-e2b.d.ts +40 -27
- package/dist/plugins/remote-env-e2b.js +180 -20
- package/dist/plugins/remote-env-file-error.d.ts +1 -1
- package/dist/plugins/remote-env-file-error.js +8 -2
- package/dist/plugins/remote-env-host.d.ts +19 -35
- package/dist/plugins/remote-env-host.js +26 -3
- package/dist/plugins/remote-env-k8s.d.ts +22 -14
- package/dist/plugins/remote-env-k8s.js +150 -26
- package/dist/plugins/remote-env-local-docker.d.ts +27 -24
- package/dist/plugins/remote-env-local-docker.js +91 -24
- package/dist/plugins/remote-env-ssh.d.ts +4 -24
- package/dist/plugins/remote-env-ssh.js +4 -3
- package/dist/plugins/resume-anchor-store-sql.js +2 -2
- package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
- package/dist/plugins/retention-lane-store-sql.js +2 -2
- package/dist/plugins/retention-store-sql.d.ts +1 -1
- package/dist/plugins/retention-store-sql.js +6 -6
- package/dist/plugins/run-store-sql.d.ts +3 -3
- package/dist/plugins/run-store-sql.js +19 -18
- package/dist/plugins/sandbox-read-floor.d.ts +273 -0
- package/dist/plugins/sandbox-read-floor.js +608 -0
- package/dist/plugins/schema-consistency.d.ts +6 -6
- package/dist/plugins/schema-consistency.js +1 -1
- package/dist/plugins/schema-ensure-legs.d.ts +2 -3
- package/dist/plugins/schema-ensure-legs.js +2 -2
- package/dist/plugins/schema-live-columns.d.ts +1 -1
- package/dist/plugins/session-capture-record-store-sql.js +1 -1
- package/dist/plugins/session-ownership.d.ts +2 -1
- package/dist/plugins/session-placement.d.ts +17 -4
- package/dist/plugins/session-placement.js +2 -1
- package/dist/plugins/session-rules-column.d.ts +1 -1
- package/dist/plugins/session-rules-column.js +1 -1
- package/dist/plugins/session-store.d.ts +18 -20
- package/dist/plugins/session-store.js +4 -12
- package/dist/plugins/session-workspace-cell.d.ts +1 -1
- package/dist/plugins/session-workspace-cell.js +1 -1
- package/dist/plugins/shared-memory-store-sql.js +2 -2
- package/dist/plugins/sql-driver.d.ts +10 -5
- package/dist/plugins/sql-driver.js +6 -6
- package/dist/plugins/sql-errors.js +1 -1
- package/dist/plugins/store-backend.d.ts +35 -6
- package/dist/plugins/store-backend.js +27 -10
- package/dist/plugins/store-contracts.d.ts +9 -2
- package/dist/plugins/task-list-store-sql.js +11 -11
- package/dist/plugins/tidb-pool.js +7 -6
- package/dist/plugins/tidb-session-storage.js +4 -4
- package/dist/plugins/tidb-session-store.d.ts +4 -1
- package/dist/plugins/tidb-session-store.js +16 -15
- package/dist/plugins/tool-result-store-sql.d.ts +2 -2
- package/dist/plugins/tool-result-store-sql.js +3 -3
- package/dist/plugins/user-input-ledger-sql.js +2 -2
- package/dist/plugins/workflow-journal-store-sql.js +5 -5
- package/dist/plugins/workflow-run-store-sql.js +19 -19
- package/dist/plugins/write-behind-counter.d.ts +2 -3
- package/dist/plugins/write-behind-counter.js +5 -5
- package/dist/resource-suspend.d.ts +14 -12
- package/dist/resource-suspend.js +1 -1
- package/dist/resource-window.d.ts +4 -3
- package/dist/run-cancel-context.d.ts +34 -0
- package/dist/run-cancel-context.js +7 -0
- package/dist/run-local.js +14 -19
- package/dist/runs.d.ts +47 -16
- package/dist/runs.js +112 -113
- package/dist/security.d.ts +2 -2
- package/dist/server-secret-env.d.ts +2 -1
- package/dist/server-secret-env.js +2 -4
- package/dist/session-error-wire.d.ts +22 -4
- package/dist/session-error-wire.js +16 -0
- package/dist/session-incarnation.d.ts +10 -4
- package/dist/session-incarnation.js +1 -1
- package/dist/session-policy-wire.d.ts +1 -1
- package/dist/session-sync-kernel.d.ts +42 -1
- package/dist/session-sync-kernel.js +17 -0
- package/dist/session-sync.js +16 -4
- package/dist/sql-engine-coordinates.d.ts +49 -0
- package/dist/sql-engine-coordinates.js +27 -0
- package/dist/sql-engine-posture.d.ts +1 -1
- package/dist/sql-engine-posture.js +1 -1
- package/dist/standing-answer-grant.d.ts +31 -2
- package/dist/standing-answer-grant.js +14 -2
- package/dist/store-posture.d.ts +1 -1
- package/dist/{plugins → stores-sql}/background-agent-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/background-agent-store-sql.js +8 -8
- package/dist/{plugins → stores-sql}/session-policy-store-sql.d.ts +7 -5
- package/dist/{plugins → stores-sql}/session-policy-store-sql.js +12 -12
- package/dist/{plugins → stores-sql}/usage-window-store-sql.d.ts +1 -1
- package/dist/{plugins → stores-sql}/usage-window-store-sql.js +3 -3
- package/dist/task-a2a.d.ts +1 -1
- package/dist/task-a2a.js +5 -6
- package/dist/task-mcp.d.ts +21 -8
- package/dist/task-mcp.js +17 -9
- package/dist/task-settings.d.ts +52 -25
- package/dist/task-settings.js +91 -28
- package/dist/terminal.d.ts +103 -19
- package/dist/terminal.js +72 -20
- package/dist/trace/core-keyset-guard.d.ts +79 -2
- package/dist/trace/exit-seat.d.ts +7 -0
- package/dist/trace/exit-seat.js +1 -0
- package/dist/trace/model-segment.d.ts +2 -2
- package/dist/trace/redact.d.ts +3 -1
- package/dist/trace/redact.js +395 -110
- package/dist/trace/self-minted-wire.d.ts +226 -2
- package/dist/trace/self-minted-wire.js +79 -0
- package/dist/verifier-pause-card.d.ts +8 -0
- package/dist/verifier-pause-card.js +19 -0
- package/dist/web-admin-client/apply-effective.d.ts +5 -7
- package/dist/web-admin-client/apply-effective.js +2 -2
- package/dist/web-admin-client/candidate-gate.d.ts +11 -7
- package/dist/web-admin-client/candidate-gate.js +1 -1
- package/dist/web-admin-client/http-client.d.ts +5 -4
- package/dist/web-admin-client/http-client.js +2 -2
- package/dist/web-admin-client/read-warnings.d.ts +7 -17
- package/dist/web-admin-client/read-warnings.js +5 -9
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -2
- package/package.json +2 -2
- package/wire-changes/server@7.140.0.json +184 -0
- package/wire-changes/server@7.141.0.json +367 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { homedir } from "node:os";
|
|
2
|
-
import {
|
|
3
|
-
import { isBlankCoordinate } from "@sema-agent/settings-schema";
|
|
4
|
-
import { DECLARE_HOME_REMEDY, buildHomeAbsentNote } from "./lane-home-probe.js";
|
|
2
|
+
import { StubExecutionEnv } from "@sema-agent/core";
|
|
3
|
+
import { EXECUTION_LANE_WORDS as DECLARABLE_LANE_WORDS, EXECUTION_LANES, isBlankCoordinate, retiredLaneWordRefusal } from "@sema-agent/settings-schema/execution-lanes";
|
|
4
|
+
import { DECLARE_HOME_REMEDY, LANE_HOME_UNDECLARED_EVENT, LANE_HOME_UNMEASURED_EVENT, buildHomeAbsentNote, buildHomeUnmeasuredNote } from "./lane-home-probe.js";
|
|
5
5
|
const NO = "unsupported";
|
|
6
6
|
const YES = "supported";
|
|
7
7
|
const SU = "single-user-only";
|
|
@@ -14,15 +14,8 @@ export function executionLaneCaps(lane) {
|
|
|
14
14
|
scheduler: NO,
|
|
15
15
|
lsp: NO,
|
|
16
16
|
sandboxSendUserFile: NO,
|
|
17
|
-
isolation: NO,
|
|
18
|
-
suspendable: NO,
|
|
19
17
|
remoteScratchpad: NO,
|
|
20
|
-
sandboxPathAdjudication: NO,
|
|
21
18
|
worktreeIsolation: NO,
|
|
22
|
-
memoryPersistenceCapable: NO,
|
|
23
|
-
hostFilePlane: YES,
|
|
24
|
-
coreRemoteExecutionEnv: NO,
|
|
25
|
-
canonicalPathAuthority: NO,
|
|
26
19
|
tenantSeparation: YES,
|
|
27
20
|
};
|
|
28
21
|
case "host":
|
|
@@ -32,15 +25,8 @@ export function executionLaneCaps(lane) {
|
|
|
32
25
|
scheduler: SU,
|
|
33
26
|
lsp: SU,
|
|
34
27
|
sandboxSendUserFile: NO,
|
|
35
|
-
isolation: NO,
|
|
36
|
-
suspendable: NO,
|
|
37
28
|
remoteScratchpad: NO,
|
|
38
|
-
sandboxPathAdjudication: NO,
|
|
39
29
|
worktreeIsolation: YES,
|
|
40
|
-
memoryPersistenceCapable: YES,
|
|
41
|
-
hostFilePlane: YES,
|
|
42
|
-
coreRemoteExecutionEnv: YES,
|
|
43
|
-
canonicalPathAuthority: YES,
|
|
44
30
|
tenantSeparation: executionLaneRow(lane).tenantSeparation,
|
|
45
31
|
};
|
|
46
32
|
case "e2b":
|
|
@@ -50,15 +36,8 @@ export function executionLaneCaps(lane) {
|
|
|
50
36
|
scheduler: NO,
|
|
51
37
|
lsp: NO,
|
|
52
38
|
sandboxSendUserFile: YES,
|
|
53
|
-
isolation: YES,
|
|
54
|
-
suspendable: YES,
|
|
55
39
|
remoteScratchpad: YES,
|
|
56
|
-
sandboxPathAdjudication: YES,
|
|
57
40
|
worktreeIsolation: NO,
|
|
58
|
-
memoryPersistenceCapable: NO,
|
|
59
|
-
hostFilePlane: NO,
|
|
60
|
-
coreRemoteExecutionEnv: YES,
|
|
61
|
-
canonicalPathAuthority: YES,
|
|
62
41
|
tenantSeparation: executionLaneRow(lane).tenantSeparation,
|
|
63
42
|
};
|
|
64
43
|
case "k8s":
|
|
@@ -68,15 +47,8 @@ export function executionLaneCaps(lane) {
|
|
|
68
47
|
scheduler: NO,
|
|
69
48
|
lsp: NO,
|
|
70
49
|
sandboxSendUserFile: YES,
|
|
71
|
-
isolation: YES,
|
|
72
|
-
suspendable: YES,
|
|
73
50
|
remoteScratchpad: YES,
|
|
74
|
-
sandboxPathAdjudication: YES,
|
|
75
51
|
worktreeIsolation: NO,
|
|
76
|
-
memoryPersistenceCapable: NO,
|
|
77
|
-
hostFilePlane: NO,
|
|
78
|
-
coreRemoteExecutionEnv: YES,
|
|
79
|
-
canonicalPathAuthority: YES,
|
|
80
52
|
tenantSeparation: executionLaneRow(lane).tenantSeparation,
|
|
81
53
|
};
|
|
82
54
|
case "ssh":
|
|
@@ -86,15 +58,8 @@ export function executionLaneCaps(lane) {
|
|
|
86
58
|
scheduler: NO,
|
|
87
59
|
lsp: NO,
|
|
88
60
|
sandboxSendUserFile: SU,
|
|
89
|
-
isolation: NO,
|
|
90
|
-
suspendable: NO,
|
|
91
61
|
remoteScratchpad: YES,
|
|
92
|
-
sandboxPathAdjudication: YES,
|
|
93
62
|
worktreeIsolation: NO,
|
|
94
|
-
memoryPersistenceCapable: NO,
|
|
95
|
-
hostFilePlane: NO,
|
|
96
|
-
coreRemoteExecutionEnv: YES,
|
|
97
|
-
canonicalPathAuthority: YES,
|
|
98
63
|
tenantSeparation: executionLaneRow(lane).tenantSeparation,
|
|
99
64
|
};
|
|
100
65
|
case "adb":
|
|
@@ -104,15 +69,8 @@ export function executionLaneCaps(lane) {
|
|
|
104
69
|
scheduler: NO,
|
|
105
70
|
lsp: NO,
|
|
106
71
|
sandboxSendUserFile: NO,
|
|
107
|
-
isolation: NO,
|
|
108
|
-
suspendable: NO,
|
|
109
72
|
remoteScratchpad: NO,
|
|
110
|
-
sandboxPathAdjudication: YES,
|
|
111
73
|
worktreeIsolation: NO,
|
|
112
|
-
memoryPersistenceCapable: NO,
|
|
113
|
-
hostFilePlane: NO,
|
|
114
|
-
coreRemoteExecutionEnv: YES,
|
|
115
|
-
canonicalPathAuthority: YES,
|
|
116
74
|
tenantSeparation: executionLaneRow(lane).tenantSeparation,
|
|
117
75
|
};
|
|
118
76
|
case "local-docker":
|
|
@@ -122,15 +80,8 @@ export function executionLaneCaps(lane) {
|
|
|
122
80
|
scheduler: NO,
|
|
123
81
|
lsp: NO,
|
|
124
82
|
sandboxSendUserFile: NO,
|
|
125
|
-
isolation: YES,
|
|
126
|
-
suspendable: NO,
|
|
127
83
|
remoteScratchpad: YES,
|
|
128
|
-
sandboxPathAdjudication: YES,
|
|
129
84
|
worktreeIsolation: NO,
|
|
130
|
-
memoryPersistenceCapable: NO,
|
|
131
|
-
hostFilePlane: NO,
|
|
132
|
-
coreRemoteExecutionEnv: YES,
|
|
133
|
-
canonicalPathAuthority: YES,
|
|
134
85
|
tenantSeparation: executionLaneRow(lane).tenantSeparation,
|
|
135
86
|
};
|
|
136
87
|
case "device":
|
|
@@ -140,19 +91,98 @@ export function executionLaneCaps(lane) {
|
|
|
140
91
|
scheduler: NO,
|
|
141
92
|
lsp: NO,
|
|
142
93
|
sandboxSendUserFile: NO,
|
|
143
|
-
isolation: NO,
|
|
144
|
-
suspendable: NO,
|
|
145
94
|
remoteScratchpad: YES,
|
|
146
|
-
sandboxPathAdjudication: YES,
|
|
147
95
|
worktreeIsolation: NO,
|
|
148
|
-
memoryPersistenceCapable: NO,
|
|
149
|
-
hostFilePlane: NO,
|
|
150
|
-
coreRemoteExecutionEnv: YES,
|
|
151
|
-
canonicalPathAuthority: YES,
|
|
152
96
|
tenantSeparation: executionLaneRow(lane).tenantSeparation,
|
|
153
97
|
};
|
|
154
98
|
}
|
|
155
99
|
}
|
|
100
|
+
export const SANDBOX_READ_FLOOR_ENV = "SANDBOX_READ_FLOOR";
|
|
101
|
+
export const SANDBOX_READ_FLOOR_WORDS = ["keep", "off"];
|
|
102
|
+
export const SANDBOX_READ_FLOOR_DEFAULT = "keep";
|
|
103
|
+
export function readFloorStateOf(knob, served) {
|
|
104
|
+
switch (knob) {
|
|
105
|
+
case "off":
|
|
106
|
+
return "off";
|
|
107
|
+
case "keep":
|
|
108
|
+
return served ? "kept" : "unserved";
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export function sandboxReadFloorState(lane, knob) {
|
|
112
|
+
const k = knob ?? SANDBOX_READ_FLOOR_DEFAULT;
|
|
113
|
+
switch (lane) {
|
|
114
|
+
case "e2b":
|
|
115
|
+
return readFloorStateOf(k, false);
|
|
116
|
+
case "k8s":
|
|
117
|
+
return readFloorStateOf(k, false);
|
|
118
|
+
case "local-docker":
|
|
119
|
+
return readFloorStateOf(k, false);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const IN_PROCESS_BLOCK = new StubExecutionEnv().capabilities;
|
|
123
|
+
const HOST_BLOCK = Object.freeze({ isolation: false, suspendable: false, sharesProcessTable: true, canonicalPathAuthoritative: true, hostLocalPaths: true, externalContentTarget: false, io: true, keepsReadFloor: false });
|
|
124
|
+
const E2B_SHAPE = Object.freeze({ isolation: true, suspendable: true, sharesProcessTable: false, canonicalPathAuthoritative: true, hostLocalPaths: false, externalContentTarget: false, io: true });
|
|
125
|
+
const K8S_SHAPE = Object.freeze({ isolation: true, suspendable: false, sharesProcessTable: false, canonicalPathAuthoritative: true, hostLocalPaths: false, externalContentTarget: false, io: true });
|
|
126
|
+
const K8S_SNAPSHOT_SHAPE = Object.freeze({ ...K8S_SHAPE, suspendable: true });
|
|
127
|
+
const LOCAL_DOCKER_SHAPE = Object.freeze({ isolation: true, suspendable: false, sharesProcessTable: false, canonicalPathAuthoritative: true, hostLocalPaths: false, externalContentTarget: false, io: true });
|
|
128
|
+
function sandboxBlock(shape, state) {
|
|
129
|
+
return Object.freeze({ ...shape, keepsReadFloor: state === "kept" });
|
|
130
|
+
}
|
|
131
|
+
function sandboxShape(lane, snapshotStore) {
|
|
132
|
+
switch (lane) {
|
|
133
|
+
case "e2b":
|
|
134
|
+
return E2B_SHAPE;
|
|
135
|
+
case "k8s":
|
|
136
|
+
return snapshotStore ? K8S_SNAPSHOT_SHAPE : K8S_SHAPE;
|
|
137
|
+
case "local-docker":
|
|
138
|
+
return LOCAL_DOCKER_SHAPE;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const SSH_BLOCK = Object.freeze({ isolation: false, suspendable: false, sharesProcessTable: false, canonicalPathAuthoritative: true, hostLocalPaths: false, externalContentTarget: false, io: true, keepsReadFloor: false });
|
|
142
|
+
const ADB_BLOCK = Object.freeze({ isolation: false, suspendable: false, sharesProcessTable: false, canonicalPathAuthoritative: true, hostLocalPaths: false, externalContentTarget: false, io: true, keepsReadFloor: false });
|
|
143
|
+
const DEVICE_BLOCK = Object.freeze({ isolation: false, suspendable: false, sharesProcessTable: false, canonicalPathAuthoritative: true, hostLocalPaths: false, externalContentTarget: true, io: true, keepsReadFloor: false });
|
|
144
|
+
const NO_SUB_KNOBS = Object.freeze({ snapshotStore: false, sandboxReadFloor: undefined });
|
|
145
|
+
function laneBlock(lane, sub) {
|
|
146
|
+
switch (lane) {
|
|
147
|
+
case "in-process":
|
|
148
|
+
return IN_PROCESS_BLOCK;
|
|
149
|
+
case "host":
|
|
150
|
+
return HOST_BLOCK;
|
|
151
|
+
case "e2b":
|
|
152
|
+
case "k8s":
|
|
153
|
+
case "local-docker":
|
|
154
|
+
return sandboxBlock(sandboxShape(lane, sub.snapshotStore), sandboxReadFloorState(lane, sub.sandboxReadFloor));
|
|
155
|
+
case "ssh":
|
|
156
|
+
return SSH_BLOCK;
|
|
157
|
+
case "adb":
|
|
158
|
+
return ADB_BLOCK;
|
|
159
|
+
case "device":
|
|
160
|
+
return DEVICE_BLOCK;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
export function capabilitiesFor(deployment) {
|
|
164
|
+
const lane = executionLaneOf(deployment.remoteExec?.provider);
|
|
165
|
+
if (lane === undefined)
|
|
166
|
+
return undefined;
|
|
167
|
+
return laneBlock(lane, { snapshotStore: lane === "k8s" && Boolean(deployment.remoteExec?.s3Snapshot), sandboxReadFloor: deployment.sandboxReadFloor });
|
|
168
|
+
}
|
|
169
|
+
export function laneSandboxReadFloorState(deployment) {
|
|
170
|
+
const lane = executionLaneOf(deployment.remoteExec?.provider);
|
|
171
|
+
if (lane === undefined)
|
|
172
|
+
return undefined;
|
|
173
|
+
switch (lane) {
|
|
174
|
+
case "e2b":
|
|
175
|
+
case "k8s":
|
|
176
|
+
case "local-docker":
|
|
177
|
+
return sandboxReadFloorState(lane, deployment.sandboxReadFloor);
|
|
178
|
+
case "in-process":
|
|
179
|
+
case "host":
|
|
180
|
+
case "ssh":
|
|
181
|
+
case "adb":
|
|
182
|
+
case "device":
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
156
186
|
export const ALL_EXECUTION_LANES = Object.freeze(["in-process", ...DECLARABLE_LANE_WORDS]);
|
|
157
187
|
const EXECUTION_LANE_SET = new Set(ALL_EXECUTION_LANES);
|
|
158
188
|
export function isExecutionLane(word) {
|
|
@@ -187,6 +217,32 @@ export function isBlankRequiredEnvValue(value) {
|
|
|
187
217
|
export function laneMissingEnv(lane, env) {
|
|
188
218
|
return laneRequiredEnv(lane).filter((name) => isBlankRequiredEnvValue(env[name]));
|
|
189
219
|
}
|
|
220
|
+
export function readDeclaredLaneTable(raw) {
|
|
221
|
+
const segments = raw.split(",");
|
|
222
|
+
const lanes = [];
|
|
223
|
+
for (const [i, segment] of segments.entries()) {
|
|
224
|
+
if (segment === "") {
|
|
225
|
+
return { refusal: `REMOTE_EXEC="${raw}" has an empty entry at position ${i + 1} — it is an ordered, comma-separated list of execution lanes (the first is the default) with no blank entries; valid lanes: ${REMOTE_EXEC_PROVIDER_WORDS.join(" | ")}.` };
|
|
226
|
+
}
|
|
227
|
+
const lane = REMOTE_EXEC_PROVIDER_WORDS.find((w) => w === segment);
|
|
228
|
+
const retired = lane === undefined ? retiredLaneWordRefusal(segment) : undefined;
|
|
229
|
+
if (retired !== undefined)
|
|
230
|
+
return { refusal: `REMOTE_EXEC="${raw}": ${retired}.` };
|
|
231
|
+
if (lane === undefined) {
|
|
232
|
+
return {
|
|
233
|
+
refusal: `REMOTE_EXEC="${raw}"${segments.length > 1 ? ` lists "${segment}", which` : ""} is not an execution lane — valid: ${REMOTE_EXEC_PROVIDER_WORDS.join(" | ")}. ` +
|
|
234
|
+
`An unrecognized value used to fall through to the host/in-process lane silently; refusing to start instead (#157).`,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
if (lanes.includes(lane))
|
|
238
|
+
return { refusal: `REMOTE_EXEC="${raw}" lists "${lane}" twice — each execution lane appears once (the first one is the default).` };
|
|
239
|
+
lanes.push(lane);
|
|
240
|
+
}
|
|
241
|
+
const [first, ...rest] = lanes;
|
|
242
|
+
if (first === undefined)
|
|
243
|
+
throw new Error(`readDeclaredLaneTable: "${raw}" split into no segments`);
|
|
244
|
+
return { lanes: [first, ...rest] };
|
|
245
|
+
}
|
|
190
246
|
export function executionLaneRequiredRefusal(deployment) {
|
|
191
247
|
if (!deployment.requireExecutionLane || executionLaneOf(deployment.remoteExec?.provider) !== "in-process")
|
|
192
248
|
return undefined;
|
|
@@ -210,8 +266,8 @@ export function deployedExecutionLanes(config) {
|
|
|
210
266
|
return [executionLaneOf(config.remoteExec?.provider)];
|
|
211
267
|
}
|
|
212
268
|
export function handsOnWorkerFilePlane(lane) {
|
|
213
|
-
const
|
|
214
|
-
return
|
|
269
|
+
const block = laneBlock(lane, NO_SUB_KNOBS);
|
|
270
|
+
return block.io && block.hostLocalPaths;
|
|
215
271
|
}
|
|
216
272
|
export function laneBindsReads(lane) {
|
|
217
273
|
switch (lane) {
|
|
@@ -233,11 +289,11 @@ export function laneMeasuresHome(lane) {
|
|
|
233
289
|
case "local-docker":
|
|
234
290
|
case "ssh":
|
|
235
291
|
case "adb":
|
|
292
|
+
case "e2b":
|
|
293
|
+
case "host":
|
|
236
294
|
return true;
|
|
237
295
|
case "device":
|
|
238
|
-
case "host":
|
|
239
296
|
case "in-process":
|
|
240
|
-
case "e2b":
|
|
241
297
|
return false;
|
|
242
298
|
}
|
|
243
299
|
}
|
|
@@ -257,23 +313,10 @@ export function laneReadFaceDefault(lane) {
|
|
|
257
313
|
}
|
|
258
314
|
export const LANE_OPEN_READ_FACE_CAUTION = "a deployment that mounts host paths or shared volumes into the sandbox (hostPath, bind mount) exposes those host files to reads on an open face — pin READ_FACE=roots or add read-deny rows (READ_DENY_PATTERNS) for them";
|
|
259
315
|
export function laneIsolated(lane) {
|
|
260
|
-
|
|
261
|
-
switch (isolation) {
|
|
262
|
-
case "supported":
|
|
263
|
-
return true;
|
|
264
|
-
case "unsupported":
|
|
265
|
-
return false;
|
|
266
|
-
}
|
|
316
|
+
return laneBlock(lane, NO_SUB_KNOBS).isolation;
|
|
267
317
|
}
|
|
268
318
|
export function laneWiresExecutionEnv(lane) {
|
|
269
|
-
|
|
270
|
-
switch (wired) {
|
|
271
|
-
case "supported":
|
|
272
|
-
return true;
|
|
273
|
-
case "unsupported":
|
|
274
|
-
case "single-user-only":
|
|
275
|
-
return false;
|
|
276
|
-
}
|
|
319
|
+
return laneBlock(lane, NO_SUB_KNOBS).io;
|
|
277
320
|
}
|
|
278
321
|
export const PLANNED_LANE_DIVERGENCES = Object.freeze([]);
|
|
279
322
|
export const E2B_SANDBOX_HOME = "/home/user";
|
|
@@ -298,14 +341,32 @@ export function executionLaneHomeDir(deployment) {
|
|
|
298
341
|
return undefined;
|
|
299
342
|
}
|
|
300
343
|
}
|
|
301
|
-
export function
|
|
302
|
-
|
|
303
|
-
|
|
344
|
+
export function buildLaneHomeClaim(deployment) {
|
|
345
|
+
const home = executionLaneHomeDir(deployment);
|
|
346
|
+
if (home === undefined)
|
|
347
|
+
return {};
|
|
348
|
+
return { homeDir: home, homeDirSource: deployment.remoteExecHomeDir !== undefined ? "declared" : "lane" };
|
|
349
|
+
}
|
|
350
|
+
export function buildLaneHomeBootNote(deployment) {
|
|
304
351
|
const lane = executionLaneOf(deployment.remoteExec?.provider);
|
|
305
|
-
if (lane === undefined ||
|
|
352
|
+
if (lane === undefined || !laneWiresExecutionEnv(lane))
|
|
306
353
|
return undefined;
|
|
307
354
|
if (laneMeasuresHome(lane))
|
|
308
355
|
return undefined;
|
|
309
|
-
|
|
356
|
+
const home = executionLaneHomeDir(deployment);
|
|
357
|
+
if (home === undefined)
|
|
358
|
+
return { event: LANE_HOME_UNDECLARED_EVENT, note: buildHomeAbsentNote(lane, "REMOTE_EXEC_HOME_DIR is unset, and this lane cannot read its execution environment's home", DECLARE_HOME_REMEDY) };
|
|
359
|
+
return { event: LANE_HOME_UNMEASURED_EVENT, note: buildHomeUnmeasuredNote(lane, home) };
|
|
360
|
+
}
|
|
361
|
+
export function buildReadDenyFloorUnkeptNote(deployment) {
|
|
362
|
+
if (!deployment.readDenyFloorRequired)
|
|
363
|
+
return undefined;
|
|
364
|
+
if (capabilitiesFor(deployment)?.keepsReadFloor === true)
|
|
365
|
+
return undefined;
|
|
366
|
+
const lane = executionLaneOf(deployment.remoteExec?.provider) ?? String(deployment.remoteExec?.provider);
|
|
367
|
+
return (`READ_DENY_FLOOR_REQUIRED=true, but the "${lane}" execution lane does not keep the read-deny byte floor (a program its commands run can open a path ` +
|
|
368
|
+
`the read-deny table refuses). Every run whose read-deny table has rows — the shipped default tiers put rows there unless READ_DENY_BUILTIN_TIERS=none — ` +
|
|
369
|
+
`is refused before any command starts (config.read_deny_floor_unkept; a synchronous submit answers 409). ` +
|
|
370
|
+
`Either run on a lane that keeps the floor, or unset READ_DENY_FLOOR_REQUIRED to run with one operator notice per run instead.`);
|
|
310
371
|
}
|
|
311
372
|
//# sourceMappingURL=execution-lane-caps.js.map
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* `execution` 位(`plugins/local-session-store.ts`)。处处 `execution` 限定,与同行 `placement_*`(委派分区)不同义;执行格只在 `placement_kind IS NULL` 的行上 ——
|
|
9
9
|
* 委派分区行读作「不在」。
|
|
10
10
|
* · **读只有一只**:会话店的执行席 {@link ExecutionPlacementSeat.read}(一次行读:住客 + 格;行不在 / 委派分区行 ⇒ `undefined`;读故障抛,不吞成 `absent`)。
|
|
11
|
+
* 跨行的聚合也只有一只:设备店的绑定数 `countDeviceBindings`(writer(device, D) 的格数 = {@link boundDeviceOf} 的聚合;只交数,不交根 id)。
|
|
11
12
|
* · **写只按住客谓词** `(root, incarnation, owner) ∧ placement_kind IS NULL`:住客换了(删后重建,哪怕同一属主;local M10 窗内的认领)= 这一格不在 ⇒ 落空;
|
|
12
13
|
* 0 行一律按住客复读分类({@link settledPlaceOutcome} / {@link settledMirrorOutcome} / {@link settledDeviceBindOutcome}),**永不对现住客重试**。
|
|
13
14
|
* · **没有的转换**:writer ↔ mirror、writer(L) → writer(L')(device 车道的换绑 writer(device, D) → writer(device, D') 除外,它有自己的语句与门)。
|
|
@@ -248,6 +249,8 @@ export declare class InMemoryExecutionPlacementSeat implements ExecutionPlacemen
|
|
|
248
249
|
read(root: string): Promise<ExecutionPlacementReading | undefined>;
|
|
249
250
|
place(root: string, occupant: SessionFace, cell: ExecutionWriterCell): Promise<PlaceOutcome>;
|
|
250
251
|
markMirror(root: string, occupant: SessionFace): Promise<MarkMirrorOutcome>;
|
|
252
|
+
/** 绑定数(SQL 孪生 `countDeviceBindingsOn` 的对位,同一只判官):{@link boundDeviceOf} 读得出设备的格数。 */
|
|
253
|
+
countDeviceBindings(): number;
|
|
251
254
|
/** device 首绑(SQL `placeDeviceStatement` / `bindDeviceStatement` 的对位):absent 或 writer(device, ∅) ⇒ writer(device, D)、rev 0。 */
|
|
252
255
|
bindDevice(root: string, occupant: SessionFace, device: {
|
|
253
256
|
readonly id: string;
|
|
@@ -175,6 +175,13 @@ export class InMemoryExecutionPlacementSeat {
|
|
|
175
175
|
this.rows.set(root, { occupant, cell: { role: "mirror" } });
|
|
176
176
|
return { outcome: "mirrored" };
|
|
177
177
|
}
|
|
178
|
+
countDeviceBindings() {
|
|
179
|
+
let bindings = 0;
|
|
180
|
+
for (const row of this.rows.values())
|
|
181
|
+
if (boundDeviceOf(row.cell) !== undefined)
|
|
182
|
+
bindings += 1;
|
|
183
|
+
return bindings;
|
|
184
|
+
}
|
|
178
185
|
bindDevice(root, occupant, device, placedAt) {
|
|
179
186
|
const settled = settledDeviceBindOutcome(root, this.rows.get(root), occupant, device.id);
|
|
180
187
|
if (settled !== WRITABLE)
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
* 纯类型 + 纯函数叶(值 import 只有 scope 读法叶与 run 行判词叶)。
|
|
31
31
|
*/
|
|
32
32
|
import type { DrainReceipt, DrainRequest, EngineDraining } from "@sema-agent/settings-schema/fleet";
|
|
33
|
+
import type { EngineLeaseFacts } from "../boot/engine-lease.js";
|
|
33
34
|
/**
|
|
34
35
|
* 引擎自铸的动作号 —— **一张表**(排空事实与回执里不来自请求体的全部拼法;请求体的 `actionId` 由调用方自取):
|
|
35
36
|
* · {@link ENGINE_DRAIN_CAUSES}:没有请求承载的排空成因(停止信号 / SIGHUP 升级 / 附着租约自退);
|
|
@@ -89,6 +90,8 @@ export interface DrainState {
|
|
|
89
90
|
lastActivityAt?: () => number;
|
|
90
91
|
attachedStreams?: () => number;
|
|
91
92
|
lastAttachEndedAt?: () => number;
|
|
93
|
+
/** [ref]:附着租约窗的读口(`/health.engineLease`)。收尾链在**装了租约腿**时才装它,读口现读租约腿的把手 —— 腿还在观察才有读数,未装配的盒子里根本没有这只口。 */
|
|
94
|
+
engineLease?: () => EngineLeaseFacts | undefined;
|
|
92
95
|
}
|
|
93
96
|
/** 排空盒子里的排空事实(三键齐才是;入口整组写,所以「缺一」只出现在手搭的夹具上)。 */
|
|
94
97
|
export declare function drainingFactOf(s: Pick<DrainState, "draining" | "since" | "actionId" | "deadlineAt">): EngineDraining | undefined;
|
package/dist/hosted-posture.d.ts
CHANGED
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
* `docs/DEPLOY-PREREQS.md` 的「托管 / 多租部署」段把它写成部署前置,并列出忘设它的后果。
|
|
66
66
|
*/
|
|
67
67
|
import { type ServiceConfigFlat } from "./config-types.js";
|
|
68
|
+
import { type PermissionMode } from "@sema-agent/core";
|
|
68
69
|
/** 托管/多租的**证据词表**(闭集;加词 ⇒ {@link hostedEvidenceNote} 的穷举 switch 编译红)。
|
|
69
70
|
* 🔴 恰一词是裁定([ref] ①),不是暂时的:加回一条推断臂 = 翻案,先要新裁定。 */
|
|
70
71
|
export declare const HOSTED_EVIDENCE_WORDS: readonly ["require-principal"];
|
|
@@ -123,6 +124,13 @@ export type TaskHostPostureScope = HostedPostureInput & Readonly<Pick<ServiceCon
|
|
|
123
124
|
* 两条腿同射程、不同处置,射程只有一处答案。
|
|
124
125
|
*/
|
|
125
126
|
export declare function taskWriteFaceRefusal(c: TaskWriteFaceInput): string | undefined;
|
|
127
|
+
/**
|
|
128
|
+
* **腿② 的词形入口** —— 一个模式词在这台部署上会不会开出它掀不开的写围栏:词的模式列开写面(引擎模式表本尊,
|
|
129
|
+
* `modePolicyOf(word).writeFace === "open"`,今天只有 `bypassPermissions`)∧ {@link taskWriteFaceRefusal} 答拒 ⇒ 拒因;否则 `undefined`。
|
|
130
|
+
* 读者两个,同是受理判官的托管一步(`permission-mode-admission.ts` 顶注「两口的调用形」):在飞 run 的切档口经判官本体;提交口与续跑重放存储体经装配期那一判
|
|
131
|
+
* (`boot/resolve-spec.ts`,问盖过章的词)。哪天 core 让第二个模式也开写面,两处当场跟上,不是再手抄一个模式词。
|
|
132
|
+
*/
|
|
133
|
+
export declare function permissionModeWriteFaceRefusal(word: PermissionMode | undefined, c: TaskWriteFaceInput): string | undefined;
|
|
126
134
|
/**
|
|
127
135
|
* **腿④** —— 这条请求要让 host shell 继承整份用户环境(`inheritEnv:"all"`),这台部署给不给?返回拒因;`undefined` = 放行。
|
|
128
136
|
* 调用方只在值为 `"all"` 时问(`"scrub"` 就是缺省,任何部署都受理)。
|
package/dist/hosted-posture.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { TASK_WRITE_FACE_ESCALATIONS } from "./config-types.js";
|
|
2
2
|
import { DEPLOYMENT_SHAPE_PREDICATES } from "./deployment-shape.js";
|
|
3
|
+
import { modePolicyOf } from "@sema-agent/core";
|
|
3
4
|
export const HOSTED_EVIDENCE_WORDS = ["require-principal"];
|
|
4
5
|
export function buildHostedPosture(c) {
|
|
5
6
|
const evidence = [];
|
|
@@ -41,6 +42,9 @@ export function taskWriteFaceRefusal(c) {
|
|
|
41
42
|
`Refused because this deployment is HOSTED/multi-tenant (${hostedBecause(facts)}), so the task layer may only TIGHTEN the write face, never open it. ` +
|
|
42
43
|
`Set TASK_WRITE_FACE_ESCALATION=allow if the DEPLOYMENT permits the task layer to open it, or omit permissionMode:"bypassPermissions".`);
|
|
43
44
|
}
|
|
45
|
+
export function permissionModeWriteFaceRefusal(word, c) {
|
|
46
|
+
return word !== undefined && modePolicyOf(word).writeFace === "open" ? taskWriteFaceRefusal(c) : undefined;
|
|
47
|
+
}
|
|
44
48
|
export function taskInheritEnvRefusal(c) {
|
|
45
49
|
if (DEPLOYMENT_SHAPE_PREDICATES.taskHostPostureDeclarations.holds(c))
|
|
46
50
|
return undefined;
|
package/dist/http/admission.js
CHANGED
|
@@ -2,11 +2,11 @@ import { APPROVAL_REACH, IMAGE_ADMISSION, isApprovalReach, isPermissionMode, isT
|
|
|
2
2
|
import { isAtMentionable, matchCatalogModel, refusedCatalogEntry, selectableCatalog } from "../model-select.js";
|
|
3
3
|
import { echoModelRef, modelUnavailableMessage } from "../model-entry-refusal.js";
|
|
4
4
|
import { HttpError, sessionIdShapeIssue } from "../security.js";
|
|
5
|
-
import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, MAX_SETTINGS_ENV_VARS, MAX_SETTINGS_ENV_KEY_CHARS, MAX_SETTINGS_ENV_VALUE_CHARS, PERMISSION_MODE_WORDS, parseTaskSettings, settingsPermissionBucketIssue, skillListingBudgetFractionOk, skillListingMaxDescOk, hooksKeyIssue,
|
|
5
|
+
import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, MAX_SETTINGS_ENV_VARS, MAX_SETTINGS_ENV_KEY_CHARS, MAX_SETTINGS_ENV_VALUE_CHARS, PERMISSION_MODE_WORDS, parseTaskSettings, settingsPermissionBucketIssue, skillListingBudgetFractionOk, skillListingMaxDescOk, hooksKeyIssue, taskHooksHonored, taskSettingsKeyIssue } from "../task-settings.js";
|
|
6
6
|
import { tightenOnlySeatIssue } from "../tighten-only-seats.js";
|
|
7
7
|
import { approvalFrameFamiliesIssue } from "../tool-approval.js";
|
|
8
8
|
import { buildEntryModeClampNotice } from "../entry-mode-clamp-notice.js";
|
|
9
|
-
import {
|
|
9
|
+
import { stampSubmissionEntryMode } from "../permission-mode-admission.js";
|
|
10
10
|
import { taskBodyKeyIssue } from "../request-key-closure.js";
|
|
11
11
|
import { FILE_HISTORY_DISABLED_NO_RESTORE, fileHistoryRestoreConflict, fileHistoryRestoreKeysInBody, inheritEnvFieldIssue, singleMemberOffFieldIssue } from "../request-value-closure.js";
|
|
12
12
|
import * as facts from "../capability-facts.js";
|
|
@@ -738,7 +738,7 @@ export function createAdmission(ctx) {
|
|
|
738
738
|
return null;
|
|
739
739
|
}
|
|
740
740
|
}
|
|
741
|
-
const { body: admitted, entry: entryMode } =
|
|
741
|
+
const { body: admitted, entry: entryMode } = stampSubmissionEntryMode(body, deps.config);
|
|
742
742
|
const lease = deps.peerDesk.lease("fresh");
|
|
743
743
|
try {
|
|
744
744
|
const auth = await deps.authorize({ req, body: admitted });
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* ## 律
|
|
5
5
|
* 契约(settings-schema `SAFETY_MERGE_SPEC.permissions` 的成员阶梯)按**层的信任档**准入每个成员:`allow` 放宽免问面(`loosen`),要 `global`;`deny` / `ask` 只收紧,
|
|
6
|
-
* 文件层最低档 `local`
|
|
7
|
-
*
|
|
6
|
+
* 文件层最低档 `local` 就收。准入不读层:提交体是合并后的结果,层只在合并端(cli 本地)存在;deny / ask 条目可以带出处层(`{ rule, layer }`),但那个层只选这条规则的
|
|
7
|
+
* `/` 读在哪个根(`permission-rule-list.ts` 的 `layerRuleRoot`),自报的层不可验、**不进本判**。所以本服务准入的「层」= **这次请求验过的凭据**:档只由部署形 + 身份来源
|
|
8
|
+
* + 登录令牌的 scope 角色推,调用方说什么(含条目上的层)都不改档。
|
|
8
9
|
*
|
|
9
10
|
* · 单用户 turnkey(`requirePrincipal !== true`,本仓 posture 判别式同一只)⇒ `global`:一台机一位超管;
|
|
10
11
|
* · 多租 · 部署的 service 凭据 ⇒ `global`:部署自己的凭据是运维档(契约给「启动方自己的行为」—— `SETTINGS_SOURCE_CONTRACT.flagSettings` —— 的档),持它的前端为自己转发的内容负责;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { domainWriteRole, isAtLeast, isRole, memberAdmission, membersOf, roleAtLeast, USER_ROLES, } from "@sema-agent/settings-schema";
|
|
2
2
|
import { entryProblem, entryProblemsFacts } from "../entry-problems.js";
|
|
3
3
|
import { ssoVerifiedRole } from "../security.js";
|
|
4
|
+
import { ruleTextOf } from "../permission-rule-list.js";
|
|
4
5
|
import { verifiedIdentitySource } from "./principal-gate.js";
|
|
5
6
|
export function callerTrust(req, config) {
|
|
6
7
|
if (config.requirePrincipal !== true)
|
|
@@ -34,7 +35,7 @@ function effectiveRuleTables(t) {
|
|
|
34
35
|
for (const member of membersOf("permissions")) {
|
|
35
36
|
const entries = t.permissions[member];
|
|
36
37
|
if (entries !== undefined)
|
|
37
|
-
out.push({ member, field: `settings.permissions.${member}`, entries, source: "settings" });
|
|
38
|
+
out.push({ member, field: `settings.permissions.${member}`, entries: entries.map(ruleTextOf), source: "settings" });
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
if (t.skills !== undefined && t.userInvokedSkills !== undefined) {
|
package/dist/http/dispatch.js
CHANGED
|
@@ -138,6 +138,10 @@ export function createDispatch(ctx) {
|
|
|
138
138
|
...(typeof deps.capabilities?.version === "string" ? { version: deps.capabilities.version } : {}),
|
|
139
139
|
...healthDrainingKeys(signal),
|
|
140
140
|
...(deps.drainState?.inflight ? { inflight: deps.drainState.inflight() } : {}),
|
|
141
|
+
...(() => {
|
|
142
|
+
const lease = deps.drainState?.engineLease?.();
|
|
143
|
+
return lease ? { engineLease: { lingerMs: lease.lingerMs, tickMs: lease.tickMs } } : {};
|
|
144
|
+
})(),
|
|
141
145
|
...(deps.storePosture?.degradedReason !== undefined ? { durable: false, storeDegraded: true } : {}),
|
|
142
146
|
...healthReadinessKeys(signal.verdict),
|
|
143
147
|
model: deps.config.model.id,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `POST /v1/tasks/stream`(活流腿:新提交、同键重放、在飞合流的跟随方)的**唯一**帧写口。
|
|
3
|
+
*
|
|
4
|
+
* 律(一条):这条流上的每一帧都是 `[id: <eventId>\n]event: <type>\ndata: <json>\n\n`,事件名 = 载荷的 `type`。
|
|
5
|
+
* 心跳是同一只写口写的 `event: heartbeat` + `data: {}`。与 durable 尾(`http/sse-log.ts`)、sdk 的 `toSseResponse` 中继同形。
|
|
6
|
+
*
|
|
7
|
+
* `id:` 行(契约 §0.6):载荷带非空 string `eventId` 才发,值逐字 = `eventId`;没有就不发,EventSource 沿用上一游标 ——
|
|
8
|
+
* 绝不合成占位 id(那会把不可锚的位置伪装成可锚)。`id:` 行是**每帧唯一**的续流游标,所以载荷的 `eventId` 必须是**本帧
|
|
9
|
+
* 自己的**身份(server 自铸帧的唯一铸点:`trace/model-segment.ts` 的 `reasoningSegmentEventId`)。三道门各管一段:
|
|
10
|
+
* {@link LiveFrame} 管「铸点说得出这两个键的型」;本函数的运行期判据管「真的是」(通体 `Record<string, unknown>` 的
|
|
11
|
+
* 构造器返回值进得来 —— `null` 读 `.length` 会把整条流摔掉、数组会被强转成一枚编出来的游标);`test/live-sse-cursor.test.ts`
|
|
12
|
+
* 的规则式全流判据管「同一条流内不重复」。
|
|
13
|
+
*/
|
|
14
|
+
import type { ServerResponse } from "node:http";
|
|
15
|
+
/** 活流帧的载荷型:`type` 是事件名(必填,型说得出口);`eventId` 在场即**本帧自己的**续流游标。其余键由各自铸点白名单。 */
|
|
16
|
+
export type LiveFrame = {
|
|
17
|
+
readonly type: string;
|
|
18
|
+
readonly eventId?: string;
|
|
19
|
+
} & Record<string, unknown>;
|
|
20
|
+
/** 写一帧。`type` 不是非空串 = 铸点违约(型门之外漏进来的通体记录),响亮抛 —— 写一行编出来的事件名是撒谎,不写事件名就回到两只形。 */
|
|
21
|
+
export declare function writeLiveFrame(res: ServerResponse, payload: LiveFrame): void;
|
|
22
|
+
/** 心跳:真帧,不是 SSE 注释(逐帧解析的 BFF 会丢注释行,下游看到的是一段零帧的窗)。没有监听心跳的 EventSource 客户端忽略它。 */
|
|
23
|
+
export declare function writeLiveHeartbeat(res: ServerResponse): void;
|
|
24
|
+
//# sourceMappingURL=live-frame.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { liveToolEndForBacklog } from "../trace/tool-output-media.js";
|
|
2
|
+
function frameBytes(event, data, anchor) {
|
|
3
|
+
const idLine = typeof anchor === "string" && anchor.length > 0 ? `id: ${anchor}\n` : "";
|
|
4
|
+
return `${idLine}event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
|
|
5
|
+
}
|
|
6
|
+
export function writeLiveFrame(res, payload) {
|
|
7
|
+
const name = payload.type;
|
|
8
|
+
if (typeof name !== "string" || name.length === 0)
|
|
9
|
+
throw new TypeError(`live SSE frame without a string type: ${JSON.stringify(name)}`);
|
|
10
|
+
const frame = name === "tool_end" ? liveToolEndForBacklog(payload, res.writableLength) : payload;
|
|
11
|
+
res.write(frameBytes(name, frame, payload.eventId));
|
|
12
|
+
}
|
|
13
|
+
export function writeLiveHeartbeat(res) {
|
|
14
|
+
res.write(frameBytes("heartbeat", {}, undefined));
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=live-frame.js.map
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
* core 的另外三只 409 与 `ControlPlaneCorruptError` 全落 500 `internal.error` —— 「同一个 requestId 拿去抹另一个会话」这种**调用方自己
|
|
9
9
|
* 能改**的错被说成服务器坏了。两份分类 = 两个判官,少的那份恒是静默的一份。现在**码与状态**只在这里判一次,两面同读。
|
|
10
10
|
*
|
|
11
|
-
* ## 规则(三层,与 operator
|
|
11
|
+
* ## 规则(三层,与 operator 面既有层序逐字同序;另有本服务自铸的一只,先判)
|
|
12
|
+
* ⓪ 本服务的抹除店护栏拒 {@link MemoryErasureStoreUnjudged} —— 409 `memory.erasure_store_unjudged`(抹除落到部署的店之外的那只店:本部署此刻判不了
|
|
13
|
+
* 同一个 `requestId` 跨店的幂等;什么都没删)。文案按受众,同下一节的规则;
|
|
12
14
|
* ① core 的**本口专属**码(闭集穷举 `switch`,见 {@link sentCoreCode})—— 码与状态两面同;文案按受众(下一节,一条规则);
|
|
13
15
|
* ② **店形拒**两码 `memory.target_outside_store`(core 7.31.1 [ref])/ `memory.scope_home_not_directory`(core 7.44.0 [ref])—— 跨面 store 状态码,409、码原样
|
|
14
16
|
* (判据 `memory-store-refusal.ts` 一只;运维行 `memory_store_form_refused { code, path?, form? }` 两受众同一只铸点,路径只在那里);
|
|
@@ -3,6 +3,7 @@ import { logStoreFormRefusal, storeFormRefusalOf } from "../memory-store-refusal
|
|
|
3
3
|
import { sentMemoryStoreRefusal } from "./memory-store-refusal-reply.js";
|
|
4
4
|
import { sendError } from "./send.js";
|
|
5
5
|
import { assertNever } from "./route-ctx.js";
|
|
6
|
+
import { MemoryErasureStoreUnjudged } from "../memory-operator-faces.js";
|
|
6
7
|
function sentCoreCode(res, coreCode, coreMessage, audience) {
|
|
7
8
|
switch (coreCode) {
|
|
8
9
|
case "config.memory_erasure_request":
|
|
@@ -42,6 +43,10 @@ function codeOf(err) {
|
|
|
42
43
|
return typeof code === "string" ? code : undefined;
|
|
43
44
|
}
|
|
44
45
|
export function sentMemoryComplianceFailure(res, err, audience, logger) {
|
|
46
|
+
if (err instanceof MemoryErasureStoreUnjudged) {
|
|
47
|
+
sendError(res, 409, "memory.erasure_store_unjudged", textFor(audience, err.message, "session memory erasure refused — this erasure reaches memory kept in this deployment's second memory store, which this build does not erase from (an erasure requestId is judged on the deployment's main store only); nothing was erased — it becomes available with the next engine update, or ask the operator"));
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
45
50
|
const coreCode = codeOf(err);
|
|
46
51
|
if (coreCode !== undefined && sentCoreCode(res, coreCode, err instanceof Error ? err.message : String(err), audience))
|
|
47
52
|
return true;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 记忆动词的**层座**与「这次请求落不到一只记忆店」的拒 —— 两件的 HTTP 半场,唯一一处。
|
|
3
|
+
*
|
|
4
|
+
* ## 规则(店的那一半在 `src/memory-scope-stores.ts`)
|
|
5
|
+
* 一次记忆请求只落一只店:请求点名的层住的那一只;不点名层的动词(条目 id / 店级账本)答在本部署点名的层与部署的店共处的那一只上,
|
|
6
|
+
* 两只店分住时不猜、拒。会话 id 的两口不点名层时不拒:记忆状态读本部署的每一只店再折成一份,按会话抹除落部署的店(`memory-operator-faces.ts`)。
|
|
7
|
+
* 不点名层的动词因此多一个可选的**层座** `scope`:GET 口在查询串(`?scope=<层键>`),POST 口在体里(`"scope": "<层键>"`);
|
|
8
|
+
* 点名的层只用来定店,动词本身的语义不变。点名层的动词(导出 / 导入 / 外源列表 / 整理 / operator 抹除的 `select.scope` 与 `expectedScopes`)
|
|
9
|
+
* 本来就点名,不加座。
|
|
10
|
+
*
|
|
11
|
+
* ## 层座的读法({@link readLayerSeat})
|
|
12
|
+
* 缺席 ⇒ 没点名;在场 ⇒ 必须是非空串,否则 400 `request.field_invalid`、面一次都不调(空串与非串不是「没点名」—— 静默当缺席会把请求答在
|
|
13
|
+
* 另一只店上)。
|
|
14
|
+
*
|
|
15
|
+
* ## 拒的映射({@link sentMemoryLayerRefusal})
|
|
16
|
+
* `MemoryLayerRefusal` ⇒ 400 `request.memory_layer`:请求可以改对(点名层 / 按店拆成几次),服务器没坏,也不是盘形问题。
|
|
17
|
+
* 文案按受众分(与 `memory-compliance-failure-reply.ts` 同一条规则):operator ⇒ 原句(点名部署配置的层、哪几层住在哪只店 —— 运维要的就是它);
|
|
18
|
+
* 会话所有者 ⇒ 固定一句(只说怎么办),原句交 `withheld` 落运维行 —— 部署配置的层键不是这个受众的材料。
|
|
19
|
+
*/
|
|
20
|
+
import type { ServerResponse } from "node:http";
|
|
21
|
+
import type { MemoryLayerSeat } from "../memory-operator-faces.js";
|
|
22
|
+
import type { MemoryComplianceAudience } from "./memory-compliance-failure-reply.js";
|
|
23
|
+
/**
|
|
24
|
+
* 层座:`present` = 键在不在(查询串 `has` / 体 `in`),`value` = 它的值。缺席 ⇒ `undefined`;非空串 ⇒ `{ layer }`;
|
|
25
|
+
* 其余 ⇒ 已答 400 `request.field_invalid`,返回 `null`(调用方 `return`)。
|
|
26
|
+
*/
|
|
27
|
+
export declare function readLayerSeat(res: ServerResponse, present: boolean, value: unknown): MemoryLayerSeat | undefined | null;
|
|
28
|
+
/** `err` 是本服务的层拒 ⇒ 400 `request.memory_layer`(文案按受众),返回 true;否则 false,一个字节都不写。 */
|
|
29
|
+
export declare function sentMemoryLayerRefusal(res: ServerResponse, err: unknown, audience: MemoryComplianceAudience): boolean;
|
|
30
|
+
//# sourceMappingURL=memory-layer-reply.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { MemoryLayerRefusal } from "../memory-scope-stores.js";
|
|
2
|
+
import { sendError } from "./send.js";
|
|
3
|
+
export function readLayerSeat(res, present, value) {
|
|
4
|
+
if (!present)
|
|
5
|
+
return undefined;
|
|
6
|
+
if (typeof value === "string" && value.length > 0)
|
|
7
|
+
return { layer: value };
|
|
8
|
+
sendError(res, 400, "request.field_invalid", "scope must be a non-empty memory layer key when present — it names the layer whose memory store this request is answered on");
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
export function sentMemoryLayerRefusal(res, err, audience) {
|
|
12
|
+
if (!(err instanceof MemoryLayerRefusal))
|
|
13
|
+
return false;
|
|
14
|
+
switch (audience.kind) {
|
|
15
|
+
case "operator":
|
|
16
|
+
sendError(res, 400, "request.memory_layer", err.message);
|
|
17
|
+
return true;
|
|
18
|
+
case "session_owner":
|
|
19
|
+
audience.withheld(err.message);
|
|
20
|
+
sendError(res, 400, "request.memory_layer", "the memory store this request reaches cannot be told — the `scope` in the request is not a memory layer this deployment can read, or this deployment's own memory layer configuration cannot be read; resend without `scope` (or with a readable layer), or ask the operator");
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=memory-layer-reply.js.map
|