@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
|
@@ -16,7 +16,7 @@ export function callerOf(req, w) {
|
|
|
16
16
|
const subject = gatedSubject(req, w.config);
|
|
17
17
|
return {
|
|
18
18
|
subject,
|
|
19
|
-
operator: explicitOperatorOk(subject === undefined ? undefined : personOf(subject), w.config),
|
|
19
|
+
operator: explicitOperatorOk(subject === undefined ? undefined : personOf(subject), w.config, "operate"),
|
|
20
20
|
fleet: actsForDeployment(req, w.config, () => subject),
|
|
21
21
|
traceRead: traceTokenPresented(req, w.config),
|
|
22
22
|
principalRequired: DEPLOYMENT_SHAPE_PREDICATES.principalRequired.holds(w.config),
|
|
@@ -24,7 +24,7 @@ export function callerOf(req, w) {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
export function callerOfDecision(base, decider, roster) {
|
|
27
|
-
return { ...base, subject: deciderSubjectOf(base.subject, decider), operator: explicitOperatorOk(decider, roster), fleet: undefined, traceRead: false };
|
|
27
|
+
return { ...base, subject: deciderSubjectOf(base.subject, decider), operator: explicitOperatorOk(decider, roster, "operate"), fleet: undefined, traceRead: false };
|
|
28
28
|
}
|
|
29
29
|
export function deciderSubjectOf(requestSubject, decider) {
|
|
30
30
|
return decider === undefined ? undefined : subjectOf(decider, requestSubject === undefined ? undefined : partsOf(requestSubject).scenario);
|
|
@@ -47,9 +47,8 @@ export const ROUTE_FACES = {
|
|
|
47
47
|
"run-task-stop": "run.supervise",
|
|
48
48
|
"elicitation-respond": null,
|
|
49
49
|
"question-respond": null,
|
|
50
|
-
"tool-approval-respond": null,
|
|
51
|
-
"tool-approval-read": null,
|
|
52
50
|
"task-ask-decision": null,
|
|
51
|
+
"task-ask-read": null,
|
|
53
52
|
"run-permission-mode": "run.supervise",
|
|
54
53
|
"run-memory-capture-optout": "run.drive",
|
|
55
54
|
"session-init": null,
|
|
@@ -410,9 +409,24 @@ export async function readVisibleSession(entry, store, sessionId) {
|
|
|
410
409
|
const verdict = await judgeSessionById(entry, store, sessionId);
|
|
411
410
|
return verdict === undefined || verdict === "door" || verdict === "not_visible" ? undefined : verdict;
|
|
412
411
|
}
|
|
413
|
-
export async function
|
|
412
|
+
export async function sessionOccupantUnchanged(entry, store, sessionId, admitted) {
|
|
414
413
|
const head = await readOwnerCell(entry, sessionId, () => store.headOf(sessionId));
|
|
415
|
-
return sessionRowPresent(head) && head
|
|
414
|
+
return sessionRowPresent(head) && sameOccupant(admitted, head);
|
|
415
|
+
}
|
|
416
|
+
export async function recheckSyncGate(store, sessionId, admitted, port) {
|
|
417
|
+
const live = await store.headOf(sessionId);
|
|
418
|
+
switch (port) {
|
|
419
|
+
case "pull":
|
|
420
|
+
return rowRead(live) && sameOccupant(admitted, live);
|
|
421
|
+
case "push": {
|
|
422
|
+
const held = rowRead(live) ? live : await deletionHeadReadOf(store)(sessionId);
|
|
423
|
+
return rowRead(held) && sameOccupant(admitted, held);
|
|
424
|
+
}
|
|
425
|
+
default: {
|
|
426
|
+
const unknownPort = port;
|
|
427
|
+
throw new Error(`recheckSyncGate: no port ${JSON.stringify(unknownPort)}`);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
416
430
|
}
|
|
417
431
|
export async function judgeSession(entry, store, sessionId, reading) {
|
|
418
432
|
if (!sessionRowPresent(reading))
|
|
@@ -448,6 +462,15 @@ export function sessionFactsReadOf(store) {
|
|
|
448
462
|
return rowRead(head) ? { get leafId() { return head.leafId; } } : undefined;
|
|
449
463
|
};
|
|
450
464
|
}
|
|
465
|
+
export function sessionOccupantReadOf(store) {
|
|
466
|
+
const headOf = store?.headOf;
|
|
467
|
+
if (typeof headOf !== "function")
|
|
468
|
+
return undefined;
|
|
469
|
+
return async (sessionId) => {
|
|
470
|
+
const head = await headOf.call(store, sessionId);
|
|
471
|
+
return rowRead(head) ? sessionFaceOfHead(sessionId, head) : undefined;
|
|
472
|
+
};
|
|
473
|
+
}
|
|
451
474
|
export async function readSessionAgent(store, sessionId) {
|
|
452
475
|
const placementOf = store?.placementOf;
|
|
453
476
|
if (placementOf === undefined)
|
|
@@ -477,13 +500,17 @@ export async function readVisibleLatestRun(entry, store, sessionId) {
|
|
|
477
500
|
const latest = await store.latestRunForSession(sessionId);
|
|
478
501
|
return rowRead(latest) && seesRun(entry, latest.owner) ? latest : undefined;
|
|
479
502
|
}
|
|
480
|
-
export function
|
|
503
|
+
export function listOwnerOf(filter, named) {
|
|
481
504
|
return filter.gateOwner ?? named;
|
|
482
505
|
}
|
|
483
506
|
export function listVisibleRuns(store, filter, named, query) {
|
|
484
|
-
const owner =
|
|
507
|
+
const owner = listOwnerOf(filter, named);
|
|
485
508
|
return store.listRuns({ ...query, ...(owner ? { owner } : {}) });
|
|
486
509
|
}
|
|
510
|
+
export function listVisibleSessions(lister, filter, named, query) {
|
|
511
|
+
const owner = listOwnerOf(filter, named);
|
|
512
|
+
return lister({ ...query, ...(owner !== undefined ? { owner } : {}), ...(filter.includeUnowned ? { includeUnowned: true } : {}) });
|
|
513
|
+
}
|
|
487
514
|
export function listRunsOfScope(store, scope, limit) {
|
|
488
515
|
return store.listRuns({ owner: ownerOfCheckpointScope(scope), limit });
|
|
489
516
|
}
|
|
@@ -534,14 +561,17 @@ export const WORKFLOW_SESSION_ASSERTION = {
|
|
|
534
561
|
"workflow-stream": { phase: "accept", label: "workflow.stream" },
|
|
535
562
|
"workflow-agent-steer": { phase: "accept", label: "workflow.agent-steer" },
|
|
536
563
|
};
|
|
564
|
+
export function workflowScopeOf(subject) {
|
|
565
|
+
return engineScopeOf(subject);
|
|
566
|
+
}
|
|
537
567
|
export function listVisibleWorkflows(entry, store, opts) {
|
|
538
|
-
return store.listByScope(
|
|
568
|
+
return store.listByScope(workflowScopeOf(entry.caller.subject), opts);
|
|
539
569
|
}
|
|
540
570
|
export async function judgeWorkflowRun(entry, store, runId) {
|
|
541
571
|
const row = await store.get(runId);
|
|
542
572
|
if (!rowRead(row))
|
|
543
573
|
return "missing";
|
|
544
|
-
const engineCaller = { ...entry.caller, subject: recoveredSubject(
|
|
574
|
+
const engineCaller = { ...entry.caller, subject: recoveredSubject(workflowScopeOf(entry.caller.subject)) };
|
|
545
575
|
const verdict = verdictOnQuals(entry, qualsOf(engineCaller, ownerCellOf(row.scope)));
|
|
546
576
|
if (verdict === "door" || verdict === "not_visible")
|
|
547
577
|
return verdict;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import type { ServiceConfig } from "../config-types.js";
|
|
3
|
+
import { type NonPersonTier, type OperatorPower, type OperatorRoster } from "../operator-roster.js";
|
|
3
4
|
import { type Person, type Subject } from "../owner-brands.js";
|
|
4
|
-
import type
|
|
5
|
+
import { type Caller } from "../owner-faces.js";
|
|
5
6
|
import { type IdentitySource, type RunIdentity } from "../identity-source.js";
|
|
6
7
|
import type { Logger } from "../observability/logger.js";
|
|
7
8
|
/** Coerce a possibly-repeated request header to a single string (or undefined). */
|
|
@@ -126,23 +127,50 @@ export declare function actsForDeployment(req: IncomingMessage, config: ServiceC
|
|
|
126
127
|
*/
|
|
127
128
|
export declare function serviceTokenDeclaredActsForDeployment(config: Pick<ServiceConfig, "serviceTokenActsForDeployment">): boolean;
|
|
128
129
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*/
|
|
132
|
-
export type OperatorRoster = Pick<ServiceConfig, "operatorPrincipals" | "operatorSingleUser">;
|
|
133
|
-
/**
|
|
134
|
-
* 🔴 **「谁是 operator」的唯一读法**([ref],[ref] ① 裁 A;IMAGE-API-DESIGN.md §P2.4a MUST-FIX 的那一只门)。
|
|
130
|
+
* 🔴 **「这位验过的人在这台部署上持不持这只运维权力」的唯一读法**([ref],[ref] ① 裁 A;IMAGE-API-DESIGN.md §P2.4a MUST-FIX 的那一只门)。
|
|
131
|
+
* 档表与人 → 档的读法住在叶子 `operator-roster.ts`(`ROSTER_TIERS` / `rosterTierOf`);本函数 = 「人落在某档 ∧ 那一档持 `power`」。
|
|
135
132
|
* · 名单为空 ⇒ **没人是**(没有任何形把「空名单」读成「人人是」—— 那条读法 `isOperator` 已删);
|
|
136
|
-
* · 名单非空 ⇒
|
|
137
|
-
* · 单用户形显式声明 `OPERATOR_SINGLE_USER=true` ⇒
|
|
138
|
-
* 凭据门 —— 没配凭据的部署上,能连上端口的都是)
|
|
133
|
+
* · 名单非空 ⇒ 验过的人在名单里才是;全运维档(`OPERATOR_PRINCIPALS`)持每一只权力,排空档(`OPERATOR_DRAIN_PRINCIPALS`)只持 `drain`;
|
|
134
|
+
* · 单用户形显式声明 `OPERATOR_SINGLE_USER=true` ⇒ 这台部署的**每个调用方**落全运维档(单用户形只有一位用户,能到这台部署的就是他;边界是部署自己的
|
|
135
|
+
* 凭据门 —— 没配凭据的部署上,能连上端口的都是)。声明只在单用户形、且各档名单都空时成立(起服不变量)。
|
|
136
|
+
* `power` 必填、零缺省:运维面的门与放宽位传 `"operate"`,排空口传它声明行的 `power`(`routes/admin-drain.ts`)。
|
|
139
137
|
* `person` 必须是验过的人(`gatedPerson` / `personOf(主体)`),绝不是自述头,也不是带场景的主体(名册登记的是人)。全部运维面(审批队列、steer / interrupt / wake 的属主门旁路、记忆运维口、bake 门……)读这一只 —— 只答授权;
|
|
140
138
|
* 送话口的文本框架(`trusted`)从不读它(调用方的话恒 `trusted: false`,见 `routes/runs.ts` steer 口的注);
|
|
141
139
|
* 🔴 SINGLE mint point (E1):不要再造兄弟。
|
|
142
140
|
*/
|
|
143
|
-
export declare function explicitOperatorOk(person: Person | undefined, roster: OperatorRoster): boolean;
|
|
144
|
-
/**
|
|
145
|
-
export declare function operatorRosterPresent(roster: OperatorRoster): boolean;
|
|
141
|
+
export declare function explicitOperatorOk(person: Person | undefined, roster: OperatorRoster, power: OperatorPower): boolean;
|
|
142
|
+
/** 「这台部署上**有没有**人能持这只权力」的唯一读法(持它的某档名单非空 ∨ 单用户声明在场)—— 能力事实 `operatorLane` 读这一只(整理阀门的可达性告警随本条退役)。单用户形上,装了运维面的进程里它恒真(`operator-declaration-required`:服务进程起服第 1 段、`createHttpServer` 对不声明的单用户形拒),多租形上持它的各档名单都空 ⇒ 假。 */
|
|
143
|
+
export declare function operatorRosterPresent(roster: OperatorRoster, power: OperatorPower): boolean;
|
|
144
|
+
/**
|
|
145
|
+
* 🔴 **圈禁的唯一判官**(三个读点,同一只判:请求的人 —— {@link requestConfinedTier},分派层整次请求判一次;决定证明推出的决定者 —— 直连门决定口验过证明之后,
|
|
146
|
+
* `routes/approvals-assistant.ts` 的 `admitDirectDoorDecider`;设备行的属主 —— {@link deviceOwnerConfinedTier},设备 hello 准入,`device-ws-hub.ts`)。`person` 落在**非人档** ∧ 这一条路由没声明那一档持的权力(`power` = 路由声明行的 `power` 列,缺席 = 没声明)
|
|
147
|
+
* ⇒ 答那一档(调用方 403 `auth.principal_confined`,{@link sendPrincipalConfined});人档 / 不在名册 / 路由声明了它持的权力 ⇒ `undefined`(照常往下判)。
|
|
148
|
+
* 不是第二套鉴权:身份读法、名册来源都不新;它答的是「这只验过的身份在本请求上能不能用」——与 [ref] `auth.scope_mismatch` 同一位置的第二个原因。
|
|
149
|
+
*/
|
|
150
|
+
export declare function confinedTierOf(person: Person | undefined, roster: OperatorRoster, power: OperatorPower | undefined): NonPersonTier | undefined;
|
|
151
|
+
/**
|
|
152
|
+
* 请求读点:这次请求的人在本路由上被不被圈禁。**只在名册里有非人档的名字时读人**(`rosterHasNonPersonNames`;没声明的部署零新读、逐字节同今天)。
|
|
153
|
+
* 读的是这次请求里**任一只验得过的人**(`verifiedPerson`:三来源按身份边界的序),**不**因同一请求另带了一枚验不过的 Bearer 而读成「没有人」——
|
|
154
|
+
* 那条律(`gatedSubject`)只收窄身份、从不授权;圈禁是收窄的另一面,请求里只要出示了一只被圈禁的身份就判它(读路凭据谓词照样会认那只身份,
|
|
155
|
+
* 例如直连门 principal 令牌 + 坏 Bearer 的 `/health`,所以这里不能比它少认)。**不判场景头**(不把「REQUIRE 401 先于场景头 400」的既有序提前改掉)。
|
|
156
|
+
* 读人只在人名坏形时抛(`assertPrincipalShape` 的 400):非人档的名字由起服 / 装配不变量 `operator-roster-well-formed` 保证都是合形的主体名,坏形的串
|
|
157
|
+
* 永远对不上任何一个 ⇒ 本请求没有可圈禁的身份 ⇒ 不判(下游每一次读人都抛同一只、同一处答 400)。这不是放宽臂:名单里的人永远读得出来。
|
|
158
|
+
*/
|
|
159
|
+
export declare function requestConfinedTier(req: IncomingMessage, config: ServiceConfig, power: OperatorPower | undefined): NonPersonTier | undefined;
|
|
160
|
+
/**
|
|
161
|
+
* 设备读点:设备行的属主此刻被不被圈禁。设备车道不经 HTTP(`GET /v1/device/ws` 凭设备密钥对握手,不带任何一枚人的凭据),所以请求读点看不到它;设备行按**属主**绑定,
|
|
162
|
+
* 登记那一刻的属主是验过的人 —— `http/execution-context.ts` 的 `deviceOwnerDomainOf` 是复合身份 `{ tenant, subject }` 的唯一铸点,`subject` 格逐字节取自 `gatedPerson` ——
|
|
163
|
+
* 于是行里存的就是一只持久的属主串,按恢复管线(`recoveredSubject` → `personOf`;与组织信封的发件人同一条)读回那位人,再交同一只判官。设备车道上没有任何路由声明过权力
|
|
164
|
+
* (`power` 缺席):落在非人档的属主在这条车道上整个不算数 —— 它登记的设备不许连上、不许为它执行指令(HTTP 面同一位置已 403)。
|
|
165
|
+
* 读的是名册**现态**(`roster` 每次现读,不拍快照、不把「登记时在哪一档」记在设备行里)。名册只来自 env、起服冻结 ⇒ 进程内连着的设备不会被挪档;挪档后的重启,新进程的每一次 hello 按新名册判。
|
|
166
|
+
*/
|
|
167
|
+
export declare function deviceOwnerConfinedTier(owner: {
|
|
168
|
+
readonly subject: string;
|
|
169
|
+
}, roster: OperatorRoster): NonPersonTier | undefined;
|
|
170
|
+
/** 圈禁拒句(一档一句,模块级常量;冻结门按常量解引用逐字钉)。不回显主体名;点名名单所在的 env 与这一档能用的那一条路由。 */
|
|
171
|
+
export declare const PRINCIPAL_CONFINED_DRAIN = "forbidden \u2014 this caller is a drain-only service principal on this deployment (it is named in OPERATOR_DRAIN_PRINCIPALS), and that identity counts only on POST /v1/admin/drain: every other endpoint refuses it; use an identity that is not on that list for anything else";
|
|
172
|
+
/** `403 auth.principal_confined` 的唯一铸点(一档一句,穷举 switch:加一只非人档不接句子 = 编译红)。 */
|
|
173
|
+
export declare function sendPrincipalConfined(res: ServerResponse, tier: NonPersonTier): void;
|
|
146
174
|
/**
|
|
147
175
|
* 起服一行:部署声明 `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT=false` ⇒ `service_token_posture { actsForDeployment: false }`(info);缺省不打。
|
|
148
176
|
* 声明形让运维面板开位当天成片 401,而「位关了」与「token 错了」在 wire 上同体(反探测律),这一行是起服时唯一一处说清这台部署选了哪一读法的地方。
|
|
@@ -154,14 +182,14 @@ export declare function buildServiceTokenPostureNotice(config: Pick<ServiceConfi
|
|
|
154
182
|
actsForDeployment: false;
|
|
155
183
|
};
|
|
156
184
|
} | undefined;
|
|
157
|
-
/** operator
|
|
158
|
-
* 身份都打不通 = 这台部署上不可用 ⇒ 501,不是鉴权拒(403 只留给「名单非空而你不在名单上」)
|
|
159
|
-
export declare function sendOperatorPrincipalsRequired(res: ServerResponse): void;
|
|
185
|
+
/** operator 面族在「持这只权力的名单都空」这一形上的**唯一**拒发口:事实 `operatorLane(d, power)`(`capability-facts.ts`)为假 ⇒ 这一面对任何
|
|
186
|
+
* 身份都打不通 = 这台部署上不可用 ⇒ 501,不是鉴权拒(403 只留给「名单非空而你不在名单上」)。能力位读的是同一只事实。一只权力一句(穷举 switch)。 */
|
|
187
|
+
export declare function sendOperatorPrincipalsRequired(res: ServerResponse, power: OperatorPower): void;
|
|
160
188
|
/**
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
189
|
+
* 「这台部署上没有人持这只权力」时**唯一**的出路句 —— 与 {@link operatorRosterPresent} 同一组旋钮(档表里持 `power` 的各档名单 + 单用户声明),所以句子不比事实少说一条出路:
|
|
190
|
+
* 持它的每一档名单(按档表的规范序列出;`operate` 只有 `OPERATOR_PRINCIPALS`,`drain` 另有 `OPERATOR_DRAIN_PRINCIPALS`),或单用户形的显式声明 `OPERATOR_SINGLE_USER=true`
|
|
191
|
+
* (只在 `REQUIRE_PRINCIPAL` 未开且各档名单都空时成立,否则起服拒 —— 句子把它限定在单用户部署上)。拒发口 {@link sendOperatorPrincipalsRequired}、能力事实闭集 `operator_principals_empty` 的义、
|
|
192
|
+
* 记忆整理阀门的起服告警都说这一句,别处不再各写一份。
|
|
165
193
|
*/
|
|
166
|
-
export declare function buildOperatorRosterWayOut(): string;
|
|
194
|
+
export declare function buildOperatorRosterWayOut(power: OperatorPower): string;
|
|
167
195
|
//# sourceMappingURL=principal-gate.d.ts.map
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { timingSafeEqual } from "node:crypto";
|
|
2
2
|
import { DEPLOYMENT_SHAPE_PREDICATES } from "../deployment-shape.js";
|
|
3
|
-
import { PRINCIPAL_TOKEN_HEADER, verifiedPerson, verifiedSubject, scenarioHeaderOf, scenarioWithoutPrincipalError, ssoVerifiedPrincipal, ssoVerifiedPrincipalInc, ssoVerifiedScope } from "../security.js";
|
|
3
|
+
import { HttpError, PRINCIPAL_TOKEN_HEADER, verifiedPerson, verifiedSubject, scenarioHeaderOf, scenarioWithoutPrincipalError, ssoVerifiedPrincipal, ssoVerifiedPrincipalInc, ssoVerifiedScope } from "../security.js";
|
|
4
|
+
import { ROSTER_TIERS, ROSTER_TIER_ORDER, rosterHasNonPersonNames, rosterNamesOf, rosterTierOf, tierHolds, tierIsPerson } from "../operator-roster.js";
|
|
4
5
|
import { personOf } from "../owner-brands.js";
|
|
6
|
+
import { recoveredSubject } from "../owner-faces.js";
|
|
5
7
|
import { IDENTITY_SOURCES, runIdentityClaimOverflow } from "../identity-source.js";
|
|
6
8
|
import { sendError } from "./send.js";
|
|
7
9
|
import { canonicalAddress } from "../net-address.js";
|
|
@@ -159,23 +161,71 @@ export function actsForDeployment(req, config, subject) {
|
|
|
159
161
|
export function serviceTokenDeclaredActsForDeployment(config) {
|
|
160
162
|
return config.serviceTokenActsForDeployment === true;
|
|
161
163
|
}
|
|
162
|
-
export function explicitOperatorOk(person, roster) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
return roster.operatorPrincipals.length > 0 && person !== undefined && roster.operatorPrincipals.includes(person);
|
|
164
|
+
export function explicitOperatorOk(person, roster, power) {
|
|
165
|
+
const tier = rosterTierOf(person, roster);
|
|
166
|
+
return tier !== undefined && tierHolds(tier, power);
|
|
166
167
|
}
|
|
167
|
-
export function operatorRosterPresent(roster) {
|
|
168
|
-
return roster.operatorSingleUser === true || roster.
|
|
168
|
+
export function operatorRosterPresent(roster, power) {
|
|
169
|
+
return roster.operatorSingleUser === true || ROSTER_TIER_ORDER.some((tier) => tierHolds(tier, power) && rosterNamesOf(tier, roster).length > 0);
|
|
170
|
+
}
|
|
171
|
+
export function confinedTierOf(person, roster, power) {
|
|
172
|
+
const tier = rosterTierOf(person, roster);
|
|
173
|
+
if (tier === undefined || tierIsPerson(tier))
|
|
174
|
+
return undefined;
|
|
175
|
+
if (power !== undefined && tierHolds(tier, power))
|
|
176
|
+
return undefined;
|
|
177
|
+
return tier;
|
|
178
|
+
}
|
|
179
|
+
export function requestConfinedTier(req, config, power) {
|
|
180
|
+
if (!rosterHasNonPersonNames(config))
|
|
181
|
+
return undefined;
|
|
182
|
+
let person;
|
|
183
|
+
try {
|
|
184
|
+
person = verifiedPerson(req, config);
|
|
185
|
+
}
|
|
186
|
+
catch (e) {
|
|
187
|
+
if (e instanceof HttpError)
|
|
188
|
+
return undefined;
|
|
189
|
+
throw e;
|
|
190
|
+
}
|
|
191
|
+
return confinedTierOf(person, config, power);
|
|
192
|
+
}
|
|
193
|
+
export function deviceOwnerConfinedTier(owner, roster) {
|
|
194
|
+
return confinedTierOf(personOf(recoveredSubject(owner.subject)), roster, undefined);
|
|
195
|
+
}
|
|
196
|
+
export const PRINCIPAL_CONFINED_DRAIN = "forbidden — this caller is a drain-only service principal on this deployment (it is named in OPERATOR_DRAIN_PRINCIPALS), and that identity counts only on POST /v1/admin/drain: every other endpoint refuses it; use an identity that is not on that list for anything else";
|
|
197
|
+
export function sendPrincipalConfined(res, tier) {
|
|
198
|
+
switch (tier) {
|
|
199
|
+
case "drain":
|
|
200
|
+
sendError(res, 403, "auth.principal_confined", PRINCIPAL_CONFINED_DRAIN);
|
|
201
|
+
return;
|
|
202
|
+
default: {
|
|
203
|
+
const unknownTier = tier;
|
|
204
|
+
throw new Error(`sendPrincipalConfined: unknown confined tier ${String(unknownTier)}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
169
207
|
}
|
|
170
208
|
export function buildServiceTokenPostureNotice(config) {
|
|
171
209
|
if (serviceTokenDeclaredActsForDeployment(config))
|
|
172
210
|
return undefined;
|
|
173
211
|
return { event: "service_token_posture", fields: { actsForDeployment: false } };
|
|
174
212
|
}
|
|
175
|
-
export function sendOperatorPrincipalsRequired(res) {
|
|
176
|
-
|
|
213
|
+
export function sendOperatorPrincipalsRequired(res, power) {
|
|
214
|
+
switch (power) {
|
|
215
|
+
case "operate":
|
|
216
|
+
sendError(res, 501, "capability.operator_principals_required", `this endpoint is operator-only and this deployment has no operator roster (OPERATOR_PRINCIPALS is empty and OPERATOR_SINGLE_USER is not declared), so no caller can be an operator; ${buildOperatorRosterWayOut(power)}`);
|
|
217
|
+
return;
|
|
218
|
+
case "drain":
|
|
219
|
+
sendError(res, 501, "capability.operator_principals_required", `this endpoint is open to this deployment's operators and its drain-only service principals, and it names neither (OPERATOR_PRINCIPALS and OPERATOR_DRAIN_PRINCIPALS are empty and OPERATOR_SINGLE_USER is not declared), so no caller can call it; ${buildOperatorRosterWayOut(power)}`);
|
|
220
|
+
return;
|
|
221
|
+
default: {
|
|
222
|
+
const unknownPower = power;
|
|
223
|
+
throw new Error(`sendOperatorPrincipalsRequired: unknown power ${String(unknownPower)}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
177
226
|
}
|
|
178
|
-
export function buildOperatorRosterWayOut() {
|
|
179
|
-
|
|
227
|
+
export function buildOperatorRosterWayOut(power) {
|
|
228
|
+
const rosters = ROSTER_TIER_ORDER.filter((tier) => tierHolds(tier, power)).map((tier) => `${ROSTER_TIERS[tier].env} with the named ${ROSTER_TIERS[tier].holders}`);
|
|
229
|
+
return `configure ${rosters.join(" or ")}, or — on a single-user deployment (REQUIRE_PRINCIPAL off) — declare OPERATOR_SINGLE_USER=true`;
|
|
180
230
|
}
|
|
181
231
|
//# sourceMappingURL=principal-gate.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **通道事实**(纯叶,只依赖 `node:http` 的型):一条请求从本服务的哪一只监听口进来。
|
|
3
|
+
*
|
|
4
|
+
* ## 律(一条)
|
|
5
|
+
* 闭集 {@link REQUEST_CHANNELS} = `tcp`(TCP 监听口)· `control-socket`(本机控制 socket,`control-socket.ts`)。
|
|
6
|
+
* 唯一写者 = 控制 socket 那只 `http.Server` 的请求监听器({@link markControlSocketRequest},`http/server.ts` 里恰一处调用);唯一读法 = {@link requestChannelOf}。
|
|
7
|
+
* **缺标 ⇒ `tcp`**(fail-closed):没被那只监听器标过的请求一律按 TCP 读。不按 `req.socket.remoteAddress` 缺席反推 —— TCP 连接断开之后它同样缺席,反推形是 fail-open。
|
|
8
|
+
*
|
|
9
|
+
* ## 通道换来什么(不换来什么)
|
|
10
|
+
* 控制 socket 证明的是「对端是引擎的 OS 用户(或 root)」—— 能穿过私有目录的只有他们。宿主车道上模型跑的命令也是这个用户,所以**通道不是凭据**:
|
|
11
|
+
* 它不进读路谓词(`dispatch.ts` 的 `readCredentialOk`)、不进全局凭据门、不进身份来源闭集(`identity-source.ts` 的 `IDENTITY_SOURCES`);
|
|
12
|
+
* 它只换来 `/health` 的读者档 `engine-user`(引擎自描述的全键,`health-reader.ts`)、诊断面远程来源门的「本机」一读、限流的地址回落键。
|
|
13
|
+
* 读它的每一处都**穷举**本闭集(`switch` + `never`),没有一处写「等于某一词」的比较 —— 加一种通道不接 ⇒ 编译红,而不是默认得到某一档。
|
|
14
|
+
*/
|
|
15
|
+
import type { IncomingMessage } from "node:http";
|
|
16
|
+
/** 请求通道的闭集(顺序无语义)。 */
|
|
17
|
+
export declare const REQUEST_CHANNELS: readonly ["tcp", "control-socket"];
|
|
18
|
+
export type RequestChannel = (typeof REQUEST_CHANNELS)[number];
|
|
19
|
+
/** **唯一写者**:控制 socket 那只 `http.Server` 的请求监听器在把请求交给共享监听器之前调一次。别处调用 = 把 TCP 请求读成本机用户(源码门钉调用点恰一处)。 */
|
|
20
|
+
export declare function markControlSocketRequest(req: IncomingMessage): void;
|
|
21
|
+
/** 这条请求从哪一只监听口进来 —— 唯一读法;缺标 ⇒ `tcp`。 */
|
|
22
|
+
export declare function requestChannelOf(req: IncomingMessage): RequestChannel;
|
|
23
|
+
//# sourceMappingURL=request-channel.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const REQUEST_CHANNELS = ["tcp", "control-socket"];
|
|
2
|
+
const controlSocketRequests = new WeakSet();
|
|
3
|
+
export function markControlSocketRequest(req) {
|
|
4
|
+
controlSocketRequests.add(req);
|
|
5
|
+
}
|
|
6
|
+
export function requestChannelOf(req) {
|
|
7
|
+
return controlSocketRequests.has(req) ? "control-socket" : "tcp";
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=request-channel.js.map
|
|
@@ -9,6 +9,7 @@ import { escapedStatementBytes, packetWallStatementBytes, rowWallPayloadBytes }
|
|
|
9
9
|
import { MAX_JSON_BODY_BYTES } from "../json-body-limit.js";
|
|
10
10
|
import { deliverVia } from "../submission-exit.js";
|
|
11
11
|
import { canonicalAddress } from "../net-address.js";
|
|
12
|
+
import { requestChannelOf } from "./request-channel.js";
|
|
12
13
|
export function refuseSubmitBody(walls, body) {
|
|
13
14
|
const rowWall = walls.maxRowBytes;
|
|
14
15
|
const packetWall = walls.maxPacketBytes;
|
|
@@ -171,8 +172,7 @@ export function createRequestGuards(ctx) {
|
|
|
171
172
|
function rateLimited(req, res) {
|
|
172
173
|
if (!deps.rateLimiter)
|
|
173
174
|
return false;
|
|
174
|
-
const
|
|
175
|
-
const key = (deps.config.directDoorActive ? undefined : principalFrom(req, deps.config)) ?? (peer === undefined ? "anon" : (canonicalAddress(peer) ?? peer));
|
|
175
|
+
const key = (deps.config.directDoorActive ? undefined : principalFrom(req, deps.config)) ?? rateLimitAddressKeyOf(req);
|
|
176
176
|
const d = deps.rateLimiter.check(key);
|
|
177
177
|
if (d.allowed)
|
|
178
178
|
return false;
|
|
@@ -220,4 +220,19 @@ export function createRequestGuards(ctx) {
|
|
|
220
220
|
}
|
|
221
221
|
return { quotaExceeded, ownerCostQuotaDenied, ownerFleetLeaseDenied, ownerLeaseDenied, ownerQuotaDenied, leaseDenied, usageWindowDenialFor, usageWindowDenied, rateLimited, safeDecode, readJson, readRawBody };
|
|
222
222
|
}
|
|
223
|
+
function rateLimitAddressKeyOf(req) {
|
|
224
|
+
const channel = requestChannelOf(req);
|
|
225
|
+
switch (channel) {
|
|
226
|
+
case "tcp": {
|
|
227
|
+
const peer = req.socket.remoteAddress;
|
|
228
|
+
return peer === undefined ? "anon" : (canonicalAddress(peer) ?? peer);
|
|
229
|
+
}
|
|
230
|
+
case "control-socket":
|
|
231
|
+
return "control-socket";
|
|
232
|
+
default: {
|
|
233
|
+
const unknownChannel = channel;
|
|
234
|
+
throw new Error(`rate limit: request channel ${String(unknownChannel)} has no address key`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
223
238
|
//# sourceMappingURL=request-guards.js.map
|
|
@@ -2,6 +2,8 @@ import { openCheckpointCtx } from "./checkpoint-ctx.js";
|
|
|
2
2
|
import { storeFaultClassOf } from "../plugins/store-fault.js";
|
|
3
3
|
import { refusalBody } from "./refusal-body.js";
|
|
4
4
|
import { frozenProjectContextOf } from "../project-context.js";
|
|
5
|
+
import { frozenMemorySeedOf } from "../project-registry.js";
|
|
6
|
+
import { permissionModeWriteOf } from "../permission-mode-admission.js";
|
|
5
7
|
export async function readResumeCtx(load, opening) {
|
|
6
8
|
const read = await readStoredCtx(load);
|
|
7
9
|
if (read.kind !== "ok")
|
|
@@ -9,19 +11,56 @@ export async function readResumeCtx(load, opening) {
|
|
|
9
11
|
const opened = openCheckpointCtx(read.ctx, opening.opener, opening.sessionId);
|
|
10
12
|
if (opened.kind !== "ok")
|
|
11
13
|
return { kind: "unsealable", field: opened.field, reason: opened.reason };
|
|
14
|
+
const where = (key) => ({ kind: "corrupt", where: `checkpoint ctx for session ${JSON.stringify(opening.sessionId)}: ${key}` });
|
|
15
|
+
const { memorySeed: _storedSeed, projectContext: _storedContext, permissionModeWrite: _storedWrite, ...rest } = opened.ctx;
|
|
16
|
+
const seed = frozenMemorySeedOf(opened.ctx.memorySeed);
|
|
12
17
|
const frozen = frozenProjectContextOf(opened.ctx.projectContext);
|
|
18
|
+
const written = permissionModeWriteOf(opened.ctx.permissionModeWrite);
|
|
19
|
+
let seedPart;
|
|
20
|
+
switch (seed.kind) {
|
|
21
|
+
case "absent":
|
|
22
|
+
seedPart = {};
|
|
23
|
+
break;
|
|
24
|
+
case "none":
|
|
25
|
+
seedPart = { memorySeed: null };
|
|
26
|
+
break;
|
|
27
|
+
case "malformed":
|
|
28
|
+
return where("memorySeed");
|
|
29
|
+
case "ok":
|
|
30
|
+
seedPart = { memorySeed: seed.seed };
|
|
31
|
+
break;
|
|
32
|
+
default: {
|
|
33
|
+
const unhandled = seed;
|
|
34
|
+
throw new Error(`resume-ctx-read: unplaced frozen memory seed reading ${JSON.stringify(unhandled)}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
let contextPart;
|
|
13
38
|
switch (frozen.kind) {
|
|
14
39
|
case "absent":
|
|
15
|
-
|
|
40
|
+
contextPart = {};
|
|
41
|
+
break;
|
|
16
42
|
case "malformed":
|
|
17
|
-
return
|
|
43
|
+
return where("projectContext");
|
|
18
44
|
case "ok":
|
|
19
|
-
|
|
45
|
+
contextPart = { projectContext: frozen.context };
|
|
46
|
+
break;
|
|
20
47
|
default: {
|
|
21
48
|
const unhandled = frozen;
|
|
22
49
|
throw new Error(`resume-ctx-read: unplaced frozen project context reading ${JSON.stringify(unhandled)}`);
|
|
23
50
|
}
|
|
24
51
|
}
|
|
52
|
+
switch (written.kind) {
|
|
53
|
+
case "absent":
|
|
54
|
+
return { kind: "ok", ctx: { ...rest, ...seedPart, ...contextPart } };
|
|
55
|
+
case "malformed":
|
|
56
|
+
return where("permissionModeWrite");
|
|
57
|
+
case "ok":
|
|
58
|
+
return { kind: "ok", ctx: { ...rest, ...seedPart, ...contextPart, permissionModeWrite: written.write } };
|
|
59
|
+
default: {
|
|
60
|
+
const unhandled = written;
|
|
61
|
+
throw new Error(`resume-ctx-read: unplaced permission-mode write reading ${JSON.stringify(unhandled)}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
25
64
|
}
|
|
26
65
|
async function readStoredCtx(load) {
|
|
27
66
|
let stored;
|
|
@@ -21,7 +21,7 @@ import type { HostDecision } from "../host-decision.js";
|
|
|
21
21
|
import { type GateSighting } from "../approval-gate-currency.js";
|
|
22
22
|
import { type CancelRunReader } from "../run-cancel-card.js";
|
|
23
23
|
import { type PlanApprovePermissionModeAfter } from "../task-settings.js";
|
|
24
|
-
import type { RouteCtxBase, DriveResumeArgs, PreparedPlanReview, RememberSessionRequest, ResumeCheckpointOutcome, ResumeLegOutcome, WorkflowDecisionDelivery } from "./route-ctx.js";
|
|
24
|
+
import type { RouteCtxBase, DriveResumeArgs, PersistRuleRequest, PreparedPlanReview, RememberSessionRequest, ResumeCheckpointOutcome, ResumeLegOutcome, WorkflowDecisionDelivery } from "./route-ctx.js";
|
|
25
25
|
import type { RunRegistry, RouteHelpers, RouteLegs } from "./route-ctx.js";
|
|
26
26
|
import type { createRequestGuards } from "./request-guards.js";
|
|
27
27
|
import type { FlatServiceDeps } from "./server.js";
|
|
@@ -121,7 +121,7 @@ export declare function createResumeLegs(ctx: {
|
|
|
121
121
|
runnerFor: FlatServiceDeps["runnerFor"];
|
|
122
122
|
} & RunRegistry & RouteHelpers & Pick<RouteLegs, "prepareSpec" | "finalizeTaskResult"> & Pick<ReturnType<typeof createRequestGuards>, "ownerCostQuotaDenied" | "ownerFleetLeaseDenied" | "usageWindowDenialFor">): {
|
|
123
123
|
routeCtxBase: RouteCtxBase;
|
|
124
|
-
resumeCheckpoint: (sessionId: string, decision: "approve" | "deny", reason: string | undefined, hostDecision: HostDecision, req: IncomingMessage | undefined, answer: QuestionAnswer | undefined, binding: DecideBinding, remember?: RememberSessionRequest, acceptEarly?: boolean, decider?: KeyCaller, restatement?: ResumeRestatement) => Promise<ResumeCheckpointOutcome>;
|
|
124
|
+
resumeCheckpoint: (sessionId: string, decision: "approve" | "deny", reason: string | undefined, hostDecision: HostDecision, req: IncomingMessage | undefined, answer: QuestionAnswer | undefined, binding: DecideBinding, remember?: RememberSessionRequest, acceptEarly?: boolean, decider?: KeyCaller, restatement?: ResumeRestatement, persistRule?: PersistRuleRequest) => Promise<ResumeCheckpointOutcome>;
|
|
125
125
|
driveResumeIntoRunLog: (args: DriveResumeArgs) => Promise<ResumeLegOutcome>;
|
|
126
126
|
driveResumeLeg: (args: DriveResumeArgs, onAccepted?: (receipt: {
|
|
127
127
|
status: number;
|
|
@@ -129,7 +129,7 @@ export declare function createResumeLegs(ctx: {
|
|
|
129
129
|
}) => void) => Promise<ResumeLegOutcome>;
|
|
130
130
|
decisionRowAdmits: (cs: CheckpointStoreFull, token: CheckpointToken, who: KeyCaller | undefined, bodyScope: string | undefined) => Promise<boolean>;
|
|
131
131
|
resumePreempted: (sessionId: string, req: IncomingMessage | undefined, acceptEarly?: boolean, decider?: KeyCaller, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
|
|
132
|
-
startFreshHostTurn: (sessionId: string, objective: string, subject: string | undefined, req: IncomingMessage, workflowDecision: WorkflowDecisionDelivery, runId: string, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
|
|
132
|
+
startFreshHostTurn: (sessionId: string, objective: string, subject: string | undefined, req: IncomingMessage | undefined, workflowDecision: WorkflowDecisionDelivery, runId: string, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
|
|
133
133
|
resumeWake: (sessionId: string, message: PendingSteerInput | undefined, caller: Subject | undefined, req: IncomingMessage | undefined, acceptEarly?: boolean, workflowDecision?: WorkflowDecisionDelivery, ownerLeaseAdmittedFor?: string, restatement?: ResumeRestatement) => Promise<ResumeLegOutcome>;
|
|
134
134
|
preparePlanReview: (sessionId: string, log?: {
|
|
135
135
|
taskId?: string;
|
|
@@ -146,6 +146,7 @@ export declare function createResumeLegs(ctx: {
|
|
|
146
146
|
}>;
|
|
147
147
|
drivePlanReview: (prepared: PreparedPlanReview, decision: "approve" | "edit" | "reject", editedPlan: string | undefined, reason: string | undefined, hostDecision: HostDecision, req: IncomingMessage | undefined, acceptEarly?: boolean, permissionModeAfter?: PlanApprovePermissionModeAfter) => Promise<ResumeLegOutcome>;
|
|
148
148
|
sessionNotifyDoor: import("../session-notify-door.js").SessionNotifyDoor;
|
|
149
|
+
handOverRunEndedDecisions: (runId: string) => Promise<void>;
|
|
149
150
|
};
|
|
150
151
|
export {};
|
|
151
152
|
//# sourceMappingURL=resume-legs.d.ts.map
|