@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
|
@@ -3,9 +3,9 @@ import { skillCardFacts } from "../../approval-card.js";
|
|
|
3
3
|
import { hostDecisionFacts, readDecider, retiredDecisionKeyFacts, DECIDED_BY_NOT_IN_PROOF } from "../../host-decision.js";
|
|
4
4
|
import { sameExecutionRecord } from "@sema-agent/core";
|
|
5
5
|
import { findParkedAgentForCheckpoint } from "../../parked-decide.js";
|
|
6
|
-
import { DECIDED_REPLAY_SCAN_CAP, pendingTriageOrder } from "../../plugins/checkpoint-store-face.js";
|
|
6
|
+
import { DECIDED_REPLAY_SCAN_CAP, displayRuleOffers, pendingTriageOrder } from "../../plugins/checkpoint-store-face.js";
|
|
7
7
|
import { approvalPayloadFingerprint } from "../../plugins/approval-payload-fingerprint.js";
|
|
8
|
-
import { carriesDeploymentListQuestion, standingAnswerDurablyRecordable } from "../../tool-approval.js";
|
|
8
|
+
import { cardRuleOffersOfAskRow, carriesDeploymentListQuestion, readPersistRuleSlot, standingAnswerDurablyRecordable } from "../../tool-approval.js";
|
|
9
9
|
import { APPROVAL_GATE_KINDS } from "../../approval-content-kind.js";
|
|
10
10
|
import { isParkedRunStatus } from "../../plugins/store-contracts.js";
|
|
11
11
|
import { principalFrom, scopeCellOf, CHECKPOINT_PUBLIC_SCOPE, PRINCIPAL_TOKEN_HEADER, APPROVAL_MAC_HEADER, APPROVAL_MAC_KID_HEADER } from "../../security.js";
|
|
@@ -13,7 +13,7 @@ import { keyAdmits } from "../../owner-faces.js";
|
|
|
13
13
|
import { personOf } from "../../owner-brands.js";
|
|
14
14
|
import { editedPlanBinding, verifyDirectDoorProof } from "../../principal-jwt.js";
|
|
15
15
|
import { isWellFormedUnicode } from "../../principal-shape.js";
|
|
16
|
-
import { MAX_APPROVAL_REASON_CHARS, projectQuestionAnswer, questionAnswerFromProjection } from "../../approval-hmac.js";
|
|
16
|
+
import { MAX_APPROVAL_REASON_CHARS, persistRuleFromProjection, projectPersistRule, projectQuestionAnswer, questionAnswerFromProjection } from "../../approval-hmac.js";
|
|
17
17
|
import { PLAN_APPROVE_PERMISSION_MODES_AFTER, isPlanApprovePermissionModeAfter, planReviewDecisionExitsPlan, storedBodyPermissionMode } from "../../task-settings.js";
|
|
18
18
|
import { MAX_APPROVAL_NONCE_CHARS } from "../../plugins/approval-nonce-store.js";
|
|
19
19
|
import { redactedPreview, redactSecrets } from "../../trace/redact.js";
|
|
@@ -22,12 +22,13 @@ import { buildRunName } from "../../fleet/fleet-bus.js";
|
|
|
22
22
|
import { sleep } from "../sse-log.js";
|
|
23
23
|
import { bindSseLifecycle } from "../sse-lifecycle.js";
|
|
24
24
|
import { sendJson, sendError, sseHeaders, logRequestError, SSE_MAX_STREAM_MS, SSE_HEARTBEAT_IDLE_MS } from "../send.js";
|
|
25
|
-
import {
|
|
25
|
+
import { createLogger } from "../../observability/logger.js";
|
|
26
|
+
import { gatedSubject, explicitOperatorOk, confinedTierOf, sendPrincipalConfined, sendPrincipalRefusal } from "../principal-gate.js";
|
|
26
27
|
import { admitRunById, admitSessionById, callerEntry, callerOf, callerOfDecision, deciderSubjectOf, enter, latestRunIdOf, listRunsOfScope, protocolEntry, readSessionAgent, readVisibleRun, refuse, runFactsOf, withCaller } from "../owner-access.js";
|
|
27
28
|
import { governanceOriginOf } from "../../runtime-governance.js";
|
|
28
29
|
import { deploymentListAsks } from "../../approval.js";
|
|
29
30
|
import { grantBindingOf } from "../../standing-answer-grant.js";
|
|
30
|
-
import { sendResumeOutcome } from "../route-ctx.js";
|
|
31
|
+
import { readRememberSlot, ruleReceiptOf, sendResumeOutcome } from "../route-ctx.js";
|
|
31
32
|
import { assertNever } from "../route-ctx.js";
|
|
32
33
|
import * as facts from "../../capability-facts.js";
|
|
33
34
|
import { storeFaultClassOf } from "../../plugins/store-fault.js";
|
|
@@ -38,13 +39,14 @@ import { fieldConflictFacts } from "../../field-conflict.js";
|
|
|
38
39
|
import { buildSettlementEvidence } from "../../gate-settlement.js";
|
|
39
40
|
import { seatText } from "../../trace/exit-seat.js";
|
|
40
41
|
import { approvalQueueKindOfDoorId } from "../../approval-queue-kind.js";
|
|
41
|
-
import { defaultPeerInboundFace, parsePeerInboundId
|
|
42
|
+
import { defaultPeerInboundFace, parsePeerInboundId } from "../../peer-inbound-face.js";
|
|
43
|
+
import { engineScopeOfOwner } from "../../engine-identity.js";
|
|
42
44
|
import { RESUME_RESTATABLE_KEYS, readResumeRestatement } from "../resume-restatement.js";
|
|
43
45
|
const DECIDE_BODY_DECLARED_KEYS = [
|
|
44
|
-
"answer", "boundCallId", "boundInputHash", "checkpointToken", "decidedBy", "decidedVia", "decision", "feedback", "reason", "remember", "updatedInput",
|
|
46
|
+
"answer", "boundCallId", "boundInputHash", "checkpointToken", "decidedBy", "decidedVia", "decision", "feedback", "persistRule", "reason", "remember", "updatedInput",
|
|
45
47
|
...RESUME_RESTATABLE_KEYS,
|
|
46
48
|
];
|
|
47
|
-
const DECIDE_PROOF_COVERED_KEYS = ["answer", "boundCallId", "boundInputHash", "decision", "reason"];
|
|
49
|
+
const DECIDE_PROOF_COVERED_KEYS = ["answer", "boundCallId", "boundInputHash", "decision", "persistRule", "reason"];
|
|
48
50
|
const DECIDE_NOT_IN_PROOF_KEYS = ["checkpointToken", "decidedBy", "decidedVia", "feedback", "remember", "updatedInput", ...RESUME_RESTATABLE_KEYS];
|
|
49
51
|
function readDecisionDoorRestatement(res, body, directDoorActive) {
|
|
50
52
|
if (directDoorActive && RESUME_RESTATABLE_KEYS.some((key) => body[key] !== undefined)) {
|
|
@@ -67,6 +69,7 @@ const PROOF_SLOT_OF = {
|
|
|
67
69
|
decision: "decision",
|
|
68
70
|
editedPlan: "boundInputHash",
|
|
69
71
|
permissionModeAfter: "permissionModeAfter",
|
|
72
|
+
persistRule: "persistRule",
|
|
70
73
|
reason: "reason",
|
|
71
74
|
};
|
|
72
75
|
function buildApprovalEnvelope(sessionId, covered, reading) {
|
|
@@ -311,7 +314,7 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
|
|
|
311
314
|
}
|
|
312
315
|
const cs = park.checkpointStore;
|
|
313
316
|
const principal = gatedSubject(req, deps.config);
|
|
314
|
-
const operator = explicitOperatorOk(principal === undefined ? undefined : personOf(principal), deps.config);
|
|
317
|
+
const operator = explicitOperatorOk(principal === undefined ? undefined : personOf(principal), deps.config, "operate");
|
|
315
318
|
const ownScope = principal ?? CHECKPOINT_PUBLIC_SCOPE;
|
|
316
319
|
if (match.decl.id === "approvals-stream") {
|
|
317
320
|
const ownerParam = operator ? (new URLSearchParams(match.search).get("owner") ?? undefined) : undefined;
|
|
@@ -332,7 +335,7 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
|
|
|
332
335
|
sendApprovalsReadFailure(req, res, deps.logger, err);
|
|
333
336
|
return;
|
|
334
337
|
}
|
|
335
|
-
const pending = [...(await projectDurableQueue(durableRows, deps.config, deps.sessionStorage)), ...peerInboundRowsFor(defaultPeerInboundFace, principal, ownerParam)()];
|
|
338
|
+
const pending = [...(await projectDurableQueue(durableRows, deps.config, deps.sessionStorage, deps.toolApproval)), ...peerInboundRowsFor(defaultPeerInboundFace, principal, ownerParam)()];
|
|
336
339
|
const livePending = deps.toolApproval ? await deps.toolApproval.listLivePending(scope) : undefined;
|
|
337
340
|
sendJson(res, 200, {
|
|
338
341
|
pending,
|
|
@@ -676,19 +679,16 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
|
|
|
676
679
|
return;
|
|
677
680
|
}
|
|
678
681
|
const storeNowMs = await store.nowMs();
|
|
679
|
-
const
|
|
680
|
-
const proof = verifyDirectDoorProof({ jwt: hdr(PRINCIPAL_TOKEN_HEADER), mac: hdr(APPROVAL_MAC_HEADER), kid: hdr(APPROVAL_MAC_KID_HEADER) }, buildApprovalEnvelope(run.sessionId, PLAN_REVIEW_PROOF_COVERED_KEYS, {
|
|
682
|
+
const proof = admitDirectDoorDecider(req, res, buildApprovalEnvelope(run.sessionId, PLAN_REVIEW_PROOF_COVERED_KEYS, {
|
|
681
683
|
boundCallId: planNonce ?? null,
|
|
682
684
|
checkpointId: sighting?.value,
|
|
683
685
|
decision,
|
|
684
686
|
editedPlan: decision === "edit" ? editedPlanBinding(body.editedPlan) : null,
|
|
685
687
|
permissionModeAfter: isPlanApprovePermissionModeAfter(body.permissionModeAfter) ? body.permissionModeAfter : undefined,
|
|
686
688
|
reason: typeof body.reason === "string" ? body.reason : null,
|
|
687
|
-
}), deps.config, { actionBinding: false, nowSec: Math.floor(storeNowMs / 1000) });
|
|
688
|
-
if (
|
|
689
|
-
sendError(res, proof.status, proof.errorCode, proof.error);
|
|
689
|
+
}), deps.config, match.decl.power, { actionBinding: false, nowSec: Math.floor(storeNowMs / 1000) });
|
|
690
|
+
if (proof === undefined)
|
|
690
691
|
return;
|
|
691
|
-
}
|
|
692
692
|
deciderPrincipal = proof.principal;
|
|
693
693
|
singleUse = proof.singleUse === undefined ? undefined : { proof: proof.singleUse, store };
|
|
694
694
|
}
|
|
@@ -739,7 +739,7 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
|
|
|
739
739
|
const doorKind = approvalQueueKindOfDoorId(sessionId);
|
|
740
740
|
switch (doorKind) {
|
|
741
741
|
case "peer_inbound":
|
|
742
|
-
await decidePeerInbound(req, res, sessionId, { readJson, config: deps.config, logger: deps.logger, principal, face: defaultPeerInboundFace });
|
|
742
|
+
await decidePeerInbound(req, res, sessionId, { readJson, config: deps.config, logger: deps.logger, principal, face: defaultPeerInboundFace, power: match.decl.power });
|
|
743
743
|
return;
|
|
744
744
|
case "checkpoint":
|
|
745
745
|
break;
|
|
@@ -771,15 +771,12 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
|
|
|
771
771
|
return;
|
|
772
772
|
}
|
|
773
773
|
let remember = false;
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
sendError(res, 400, "request.field_conflict", "remember requires decision 'approve'", fieldConflictFacts("remember_decision", ["remember", "decision"]));
|
|
781
|
-
return;
|
|
782
|
-
}
|
|
774
|
+
const rememberSlot = readRememberSlot(body.remember, decision);
|
|
775
|
+
if (rememberSlot.kind === "refused") {
|
|
776
|
+
sendError(res, 400, rememberSlot.refusal.errorCode, rememberSlot.refusal.message, rememberSlot.refusal.facts);
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
if (rememberSlot.kind === "session") {
|
|
783
780
|
if (deps.config.directDoorActive) {
|
|
784
781
|
sendError(res, 400, "remember_not_in_proof", "remember is not supported on a direct-door worker (not covered by the decision proof)");
|
|
785
782
|
return;
|
|
@@ -790,6 +787,12 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
|
|
|
790
787
|
}
|
|
791
788
|
remember = true;
|
|
792
789
|
}
|
|
790
|
+
const ruleSlot = readPersistRuleSlot(body.persistRule, decision === "approve" ? "allow" : "deny");
|
|
791
|
+
if (!ruleSlot.ok) {
|
|
792
|
+
sendError(res, 400, "request.body_shape", ruleSlot.error);
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
const ruleProjection = ruleSlot.slot !== undefined ? projectPersistRule(ruleSlot.slot) : undefined;
|
|
793
796
|
let answer;
|
|
794
797
|
let answerProjection;
|
|
795
798
|
if (body.answer !== undefined) {
|
|
@@ -863,24 +866,19 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
|
|
|
863
866
|
};
|
|
864
867
|
let deciderPrincipal = principal === undefined ? undefined : personOf(principal);
|
|
865
868
|
if (deps.config.directDoorActive) {
|
|
866
|
-
const
|
|
867
|
-
const h = req.headers[n];
|
|
868
|
-
return Array.isArray(h) ? h[0] : h;
|
|
869
|
-
};
|
|
870
|
-
const proof = verifyDirectDoorProof({ jwt: hdr(PRINCIPAL_TOKEN_HEADER), mac: hdr(APPROVAL_MAC_HEADER), kid: hdr(APPROVAL_MAC_KID_HEADER) }, buildApprovalEnvelope(sessionId, DECIDE_PROOF_COVERED_KEYS, {
|
|
869
|
+
const proof = admitDirectDoorDecider(req, res, buildApprovalEnvelope(sessionId, DECIDE_PROOF_COVERED_KEYS, {
|
|
871
870
|
answer: answerProjection,
|
|
872
871
|
boundCallId: binding.boundCallId,
|
|
873
872
|
boundInputHash: binding.boundInputHash,
|
|
874
873
|
decision,
|
|
874
|
+
persistRule: ruleProjection,
|
|
875
875
|
reason: typeof body.reason === "string" ? body.reason : null,
|
|
876
|
-
}), deps.config);
|
|
877
|
-
if (
|
|
878
|
-
sendError(res, proof.status, proof.errorCode, proof.error);
|
|
876
|
+
}), deps.config, match.decl.power);
|
|
877
|
+
if (proof === undefined)
|
|
879
878
|
return;
|
|
880
|
-
}
|
|
881
879
|
deciderPrincipal = proof.principal;
|
|
882
880
|
}
|
|
883
|
-
const deciderCaller = { subject: deciderSubjectOf(principal, deciderPrincipal), operator: explicitOperatorOk(deciderPrincipal, deps.config) };
|
|
881
|
+
const deciderCaller = { subject: deciderSubjectOf(principal, deciderPrincipal), operator: explicitOperatorOk(deciderPrincipal, deps.config, "operate") };
|
|
884
882
|
if (!deciderCaller.operator) {
|
|
885
883
|
const cpScope = await cs
|
|
886
884
|
.peekPendingScope(sessionId, { gateKinds: APPROVAL_GATE_KINDS })
|
|
@@ -890,7 +888,8 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
|
|
|
890
888
|
return;
|
|
891
889
|
}
|
|
892
890
|
}
|
|
893
|
-
const
|
|
891
|
+
const persistRule = ruleProjection !== undefined ? { slot: persistRuleFromProjection(ruleProjection), inputWasEdited: binding.updatedInput !== undefined } : undefined;
|
|
892
|
+
const out = await resumeCheckpoint(sessionId, decision, body.reason ?? undefined, hostDecisionFacts(decider, deciderPrincipal), req, answer, binding, remember ? { grantedBy: deciderPrincipal ?? null, laneCannotRecord: "refuse" } : undefined, true, deciderCaller, restated.restatement, persistRule);
|
|
894
893
|
const replay = await decideIdempotentReplay(cs, {
|
|
895
894
|
sessionId,
|
|
896
895
|
out,
|
|
@@ -909,12 +908,31 @@ export async function handleApprovalsAssistant(req, res, match, ctx) {
|
|
|
909
908
|
sendResumeOutcome(res, replay, deps.logger);
|
|
910
909
|
return;
|
|
911
910
|
}
|
|
912
|
-
|
|
911
|
+
const rule = out.status >= 200 && out.status < 300 ? ruleReceiptOf(out, persistRule) : undefined;
|
|
912
|
+
const extra = { ...(remember ? { rememberApplied: out.rememberApplied === true } : {}), ...(rule ?? {}) };
|
|
913
|
+
sendResumeOutcome(res, out, deps.logger, Object.keys(extra).length > 0 ? extra : undefined);
|
|
913
914
|
return;
|
|
914
915
|
}
|
|
915
916
|
}
|
|
916
917
|
return assertNever(match.decl.id);
|
|
917
918
|
}
|
|
919
|
+
function admitDirectDoorDecider(req, res, envelope, config, power, opts) {
|
|
920
|
+
const hdr = (n) => {
|
|
921
|
+
const h = req.headers[n];
|
|
922
|
+
return Array.isArray(h) ? h[0] : h;
|
|
923
|
+
};
|
|
924
|
+
const proof = verifyDirectDoorProof({ jwt: hdr(PRINCIPAL_TOKEN_HEADER), mac: hdr(APPROVAL_MAC_HEADER), kid: hdr(APPROVAL_MAC_KID_HEADER) }, envelope, config, opts);
|
|
925
|
+
if (!proof.ok) {
|
|
926
|
+
sendError(res, proof.status, proof.errorCode, proof.error);
|
|
927
|
+
return undefined;
|
|
928
|
+
}
|
|
929
|
+
const confined = confinedTierOf(proof.principal, config, power);
|
|
930
|
+
if (confined !== undefined) {
|
|
931
|
+
sendPrincipalConfined(res, confined);
|
|
932
|
+
return undefined;
|
|
933
|
+
}
|
|
934
|
+
return proof;
|
|
935
|
+
}
|
|
918
936
|
async function decidePeerInbound(req, res, id, env) {
|
|
919
937
|
const body = (await env.readJson(req));
|
|
920
938
|
const decision = body?.decision === "approve" ? "approve" : body?.decision === "deny" ? "deny" : undefined;
|
|
@@ -937,19 +955,13 @@ async function decidePeerInbound(req, res, id, env) {
|
|
|
937
955
|
}
|
|
938
956
|
let decider = env.principal;
|
|
939
957
|
if (env.config.directDoorActive) {
|
|
940
|
-
const
|
|
941
|
-
|
|
942
|
-
return Array.isArray(h) ? h[0] : h;
|
|
943
|
-
};
|
|
944
|
-
const proof = verifyDirectDoorProof({ jwt: hdr(PRINCIPAL_TOKEN_HEADER), mac: hdr(APPROVAL_MAC_HEADER), kid: hdr(APPROVAL_MAC_KID_HEADER) }, buildApprovalEnvelope(id, DECIDE_PROOF_COVERED_KEYS, { answer: undefined, boundCallId: undefined, boundInputHash: undefined, decision, reason: null }), env.config);
|
|
945
|
-
if (!proof.ok) {
|
|
946
|
-
sendError(res, proof.status, proof.errorCode, proof.error);
|
|
958
|
+
const proof = admitDirectDoorDecider(req, res, buildApprovalEnvelope(id, DECIDE_PROOF_COVERED_KEYS, { answer: undefined, boundCallId: undefined, boundInputHash: undefined, decision, persistRule: undefined, reason: null }), env.config, env.power);
|
|
959
|
+
if (proof === undefined)
|
|
947
960
|
return;
|
|
948
|
-
}
|
|
949
961
|
decider = proof.principal;
|
|
950
962
|
}
|
|
951
963
|
const coord = parsePeerInboundId(id);
|
|
952
|
-
const outcome = coord === undefined ? { kind: "not_found" } : await env.face.decide(
|
|
964
|
+
const outcome = coord === undefined ? { kind: "not_found" } : await env.face.decide(engineScopeOfOwner(decider), coord, decision);
|
|
953
965
|
switch (outcome.kind) {
|
|
954
966
|
case "not_found":
|
|
955
967
|
sendError(res, 404, "not_found.approval", "approval not found");
|
|
@@ -1016,7 +1028,7 @@ function redactPendingDisclosures(row) {
|
|
|
1016
1028
|
function peerInboundRowsFor(face, principal, operatorOwnerParam) {
|
|
1017
1029
|
if (operatorOwnerParam !== undefined && operatorOwnerParam !== principal)
|
|
1018
1030
|
return () => [];
|
|
1019
|
-
const scope =
|
|
1031
|
+
const scope = engineScopeOfOwner(principal);
|
|
1020
1032
|
return () => face.list(scope);
|
|
1021
1033
|
}
|
|
1022
1034
|
function projectPendingForWire(row, deployment, agent) {
|
|
@@ -1034,9 +1046,45 @@ function projectPendingForWire(row, deployment, agent) {
|
|
|
1034
1046
|
});
|
|
1035
1047
|
return { kind: "checkpoint", ...redacted, ...(governanceForced ? { governanceForced } : {}), ...(rememberRefused ? { rememberRefused: true } : {}), ...(agent !== undefined ? { agent } : {}) };
|
|
1036
1048
|
}
|
|
1037
|
-
async function projectDurableQueue(rows, deployment, sessions) {
|
|
1049
|
+
async function projectDurableQueue(rows, deployment, sessions, cards) {
|
|
1038
1050
|
const agents = await sessionAgentsOf(rows.map((r) => r.sessionId), sessions);
|
|
1039
|
-
|
|
1051
|
+
const carded = await Promise.all(rows.map((r) => withCardRecord(r, cards)));
|
|
1052
|
+
return carded.map((r) => projectPendingForWire(r, deployment, agents.get(r.sessionId)));
|
|
1053
|
+
}
|
|
1054
|
+
const queueLogger = createLogger();
|
|
1055
|
+
async function withCardRecord(row, cards) {
|
|
1056
|
+
if (cards === undefined || row.toolCallId === null || row.boundInputHash === undefined)
|
|
1057
|
+
return row;
|
|
1058
|
+
const asked = await cards.readParkedAskOfGate(row.sessionId, { boundCallId: row.toolCallId, boundInputHash: row.boundInputHash });
|
|
1059
|
+
const withOffers = (ruleOffers) => {
|
|
1060
|
+
const next = { ...row };
|
|
1061
|
+
if (ruleOffers === undefined)
|
|
1062
|
+
delete next.ruleOffers;
|
|
1063
|
+
else
|
|
1064
|
+
next.ruleOffers = ruleOffers;
|
|
1065
|
+
return next;
|
|
1066
|
+
};
|
|
1067
|
+
const withAskIdentity = (next, ask) => {
|
|
1068
|
+
if (next.taskId !== null && next.taskId !== ask.taskId) {
|
|
1069
|
+
queueLogger.warn("approval queue row: the parked leg's task differs from the ask's task — the row keeps its checkpoint identity", { sessionId: row.sessionId, askId: ask.askId });
|
|
1070
|
+
return next;
|
|
1071
|
+
}
|
|
1072
|
+
return { ...next, taskId: ask.taskId, askId: ask.askId };
|
|
1073
|
+
};
|
|
1074
|
+
switch (asked.kind) {
|
|
1075
|
+
case "none":
|
|
1076
|
+
return row;
|
|
1077
|
+
case "unreadable":
|
|
1078
|
+
return withOffers(undefined);
|
|
1079
|
+
case "row": {
|
|
1080
|
+
const offers = cardRuleOffersOfAskRow(asked.row);
|
|
1081
|
+
return withAskIdentity(withOffers(offers === undefined ? undefined : displayRuleOffers(offers, { countRedactions: false })), asked.row);
|
|
1082
|
+
}
|
|
1083
|
+
default: {
|
|
1084
|
+
const unhandled = asked;
|
|
1085
|
+
throw new Error(`queue projection: unhandled parked-ask reading ${JSON.stringify(unhandled)}`);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1040
1088
|
}
|
|
1041
1089
|
async function sessionAgentsOf(sessionIds, sessions) {
|
|
1042
1090
|
const out = new Map();
|
|
@@ -1121,7 +1169,7 @@ export async function streamApprovals(req, res, cs, live, peerInbound, sessions,
|
|
|
1121
1169
|
while (!closed) {
|
|
1122
1170
|
let snapshot;
|
|
1123
1171
|
try {
|
|
1124
|
-
const pending = [...(await projectDurableQueue(await cs.listPending(scope), governance, sessions)), ...(peerInbound?.() ?? [])];
|
|
1172
|
+
const pending = [...(await projectDurableQueue(await cs.listPending(scope), governance, sessions, live)), ...(peerInbound?.() ?? [])];
|
|
1125
1173
|
snapshot = { pending, livePending: live ? await live.listLivePending(scope) : [] };
|
|
1126
1174
|
}
|
|
1127
1175
|
catch (err) {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* ── 读口:逐字投 core `list()` 行 ─────────────────────────────────────────────────────────────────
|
|
11
11
|
* 读的是**进程内**注册表(`defaultTaskRegistry.list`),访问元组 = 会话自己的 `{ owner: sid, sessionId: sid, scope }`
|
|
12
|
-
* (scope =
|
|
12
|
+
* (scope = 会话的引擎租户分区 `sessionTenantScope`,经唯一换算 `engineScopeOfOwner`,与 core 注册铸值同源)⇒ 可见集完全由 core 的 `canAccess` 判(fail-closed:
|
|
13
13
|
* 缺轴即拒;本会话的会话驻留行、task id 即会话 id 的 run 行、本会话发起的 workflow、根会话是本会话的后台 agent)。
|
|
14
14
|
* 键逐个处置(下面的 {@link ROW_KEY_DISPOSITION},core 给行加键 ⇒ 编译红):`task_id` 改名 `id`;`retained` **真才带**
|
|
15
15
|
* (core:缺席 ⇒ 这一行在 `includeRetained:false` 的硬面上会停);`description` 是模型写的描述、缺席时是启动时的命令文本 ——
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
*
|
|
41
41
|
* 🔴 **停止口在无凭据写门内**(`credentialGated: ["POST"]`;车OL F1 = 7.102.0 合并复审 gpt-6 腿 [high]):门的两个合取项它都中
|
|
42
42
|
* —— ① 授权的唯一输入是 principal 头(属主判 `admitSessionRow` 与 operator 臂 `explicitOperatorOk` 读的都是 `gatedSubject`,
|
|
43
|
-
*
|
|
44
|
-
* 进程,`includeRetained:true` 连显式 retain 的活服务一起停)。于是无 service 凭证且未开 `ALLOW_UNAUTHED_WRITES`
|
|
43
|
+
* 没带过门凭据的请求上它收调用方自报的头);② 不可撤销、爆炸半径跨租户(知道会话 id + 自报它的属主 ⇒ 停掉那个会话的后台
|
|
44
|
+
* 进程,`includeRetained:true` 连显式 retain 的活服务一起停)。于是无 service 凭证且未开 `ALLOW_UNAUTHED_WRITES` 的部署上,不带过门凭据的请求打它与
|
|
45
45
|
* 其余改写门同码同句 503 `auth.service_token_required`(在路由之前,`dispatch.ts` 那一道),同一只会话级收敛函数的另一个调用点
|
|
46
46
|
* `DELETE /v1/sessions/:id` 早在同一形下被 `isDestructiveSessionWrite` 拒。读口 `GET …/background` 不进:它有属主门兜底、只读、
|
|
47
47
|
* 只列本会话,与 `GET /v1/rules` 同判。已知同族缺口(不在本口单独打补丁):能力位 `exitFaces` 不含「凭据就绪」这一项,见契约
|
|
@@ -38,6 +38,10 @@ export declare const CAPABILITIES_ROUTES: readonly [{
|
|
|
38
38
|
readonly id: "capability-mcp";
|
|
39
39
|
readonly path: "/v1/capabilities/mcp";
|
|
40
40
|
readonly methods: readonly ["GET"];
|
|
41
|
+
}, {
|
|
42
|
+
readonly id: "capability-scenario-effective";
|
|
43
|
+
readonly path: "/v1/capabilities/scenario";
|
|
44
|
+
readonly methods: readonly ["GET"];
|
|
41
45
|
}, {
|
|
42
46
|
readonly id: "capability-mcp-probe";
|
|
43
47
|
readonly path: "/v1/capabilities/mcp/probe";
|
|
@@ -19,7 +19,7 @@ import { sendJson, sendError } from "../send.js";
|
|
|
19
19
|
import { codeFieldOf } from "../../terminal.js";
|
|
20
20
|
import { engineRefusalAnswerOf } from "../engine-refusal.js";
|
|
21
21
|
import { assertNever } from "../route-ctx.js";
|
|
22
|
-
import { fileHistoryCaptureOf } from "../../file-history-capture.js";
|
|
22
|
+
import { fileHistoryCaptureOf, fileHistoryWired } from "../../file-history-capture.js";
|
|
23
23
|
import { projectMemoryEngineCapability } from "../../memory-posture.js";
|
|
24
24
|
import { projectWriteProtectionCapability } from "../../write-protection.js";
|
|
25
25
|
import { projectStoreCapability, unwiredStorePosture } from "../../store-posture.js";
|
|
@@ -27,6 +27,7 @@ import { projectWebSearchCapability } from "../../plugins/web-search.js";
|
|
|
27
27
|
import { projectExecutionLaneCapability } from "../../capabilities/execution-lane.js";
|
|
28
28
|
import { SETTINGS_CONTRACT_CAPABILITY } from "../../capabilities/settings-contract.js";
|
|
29
29
|
import { judgeSandboxGitPlane, sandboxGitPlanePremisesOf } from "../../sandbox-git-plane.js";
|
|
30
|
+
import { SESSION_KINDS } from "../../session-kind.js";
|
|
30
31
|
import { MCP_ASSERTION_HEADER_SENT, MCP_REQUEST_TRANSPORT_KINDS } from "../../mcp-assertion-header.js";
|
|
31
32
|
import { gateCompositeMembers } from "../../capabilities/composite-members.js";
|
|
32
33
|
import { projectApprovalsStreamLiveCapability } from "../../capabilities/approvals-push.js";
|
|
@@ -35,7 +36,8 @@ import { centerEntitlementSourceWired } from "../../runtime-caps-resolver.js";
|
|
|
35
36
|
import * as facts from "../../capability-facts.js";
|
|
36
37
|
import { judgeAutoModeArming } from "../../auto-mode-face.js";
|
|
37
38
|
import { coercePermissionModeStrict, PERMISSION_MODE_WORDS, taskHooksHonored } from "../../task-settings.js";
|
|
38
|
-
import { gatedPerson, sendPrincipalRefusal } from "../principal-gate.js";
|
|
39
|
+
import { gatedPerson, gatedSubject, sendPrincipalRefusal } from "../principal-gate.js";
|
|
40
|
+
import { scenarioRequestedBySubject } from "../../request-form.js";
|
|
39
41
|
import { readAdoptionImportCapability } from "../../adoption/import.js";
|
|
40
42
|
import { headReadPresent } from "../../session-incarnation.js";
|
|
41
43
|
import { callerTrust } from "../caller-trust.js";
|
|
@@ -56,6 +58,12 @@ function retentionAdvertisement(config) {
|
|
|
56
58
|
export function createCapabilitiesLocal() {
|
|
57
59
|
return { mcpProbe: createMcpProbeLocal() };
|
|
58
60
|
}
|
|
61
|
+
const QUERY_SCENARIO_REPEATED = Symbol("scenario query given more than once");
|
|
62
|
+
const SCENARIO_QUERY_REPEATED_REFUSAL = "scenario must be given at most once (omit it to read this deployment's default scenario)";
|
|
63
|
+
function scenarioQueryOf(search) {
|
|
64
|
+
const given = new URLSearchParams(search).getAll("scenario");
|
|
65
|
+
return given.length > 1 ? QUERY_SCENARIO_REPEATED : given[0];
|
|
66
|
+
}
|
|
59
67
|
export async function handleCapabilities(req, res, match, ctx) {
|
|
60
68
|
const { deps } = ctx;
|
|
61
69
|
switch (match.decl.id) {
|
|
@@ -84,6 +92,7 @@ export async function handleCapabilities(req, res, match, ctx) {
|
|
|
84
92
|
deps.logger?.warn("auto_mode_face_resolver_fault", { fault: autoModeFault });
|
|
85
93
|
const rulesLaneForCaller = facts.ruleLaneForCaller(deps, gatedPerson(req, deps.config)).available;
|
|
86
94
|
const streamApprovalFact = facts.streamApproval(deps);
|
|
95
|
+
const historyWired = fileHistoryWired(deps.backend);
|
|
87
96
|
sendJson(res, 200, gateCompositeMembers({
|
|
88
97
|
...deps.capabilities,
|
|
89
98
|
...facts.engineCapabilityBits(),
|
|
@@ -138,6 +147,7 @@ export async function handleCapabilities(req, res, match, ctx) {
|
|
|
138
147
|
permissionRulesRevoke: facts.ruleLane(deps).available,
|
|
139
148
|
respondFreeFormRules: true,
|
|
140
149
|
respondBatchRuleOffers: true,
|
|
150
|
+
approvalDecideRuleSlot: true,
|
|
141
151
|
oneShot: true,
|
|
142
152
|
policy: true,
|
|
143
153
|
usage: Boolean(deps.costQuota),
|
|
@@ -211,19 +221,21 @@ export async function handleCapabilities(req, res, match, ctx) {
|
|
|
211
221
|
retention: retentionAdvertisement(deps.config),
|
|
212
222
|
peerLane: Boolean(deps.peerDirectory),
|
|
213
223
|
scenarioSubject: true,
|
|
224
|
+
effectiveScenario: true,
|
|
214
225
|
sessionList: facts.sessionList(deps).available,
|
|
215
226
|
sessionSearch: facts.sessionList(deps).available,
|
|
227
|
+
sessionKinds: facts.sessionKinds(deps).available ? [...SESSION_KINDS] : [],
|
|
216
228
|
sessionFork: facts.sessionFork(deps).available,
|
|
217
229
|
sessionDelete: facts.sessionDelete(deps).available,
|
|
218
|
-
resumeAt:
|
|
230
|
+
resumeAt: deps.backend !== undefined && headReadPresent(deps.sessionStorage),
|
|
219
231
|
promptSuggestions: true,
|
|
220
232
|
sessionPolicy: facts.sessionPolicy(deps).available,
|
|
221
233
|
sessionRulesNamespaceForms: sessionRulesNamespaceFormsHonored(),
|
|
222
|
-
restoreFiles:
|
|
223
|
-
rewindFilesTo:
|
|
234
|
+
restoreFiles: historyWired,
|
|
235
|
+
rewindFilesTo: historyWired && headReadPresent(deps.sessionStorage),
|
|
224
236
|
sessionRewindFiles: facts.sessionRewindFiles(deps).available,
|
|
225
237
|
sessionRewindFilesPreview: facts.sessionRewindFilesPreview(deps).available,
|
|
226
|
-
fileHistoryCapture: fileHistoryCaptureOf(
|
|
238
|
+
fileHistoryCapture: fileHistoryCaptureOf(historyWired, deps.config.fileHistoryCapture),
|
|
227
239
|
scheduler: facts.hostScheduler(deps.config).available,
|
|
228
240
|
sessionSync: facts.sessionSync(deps).available,
|
|
229
241
|
sessionSyncFileHistory: facts.sessionSyncFileHistory(deps).available,
|
|
@@ -260,15 +272,30 @@ export async function handleCapabilities(req, res, match, ctx) {
|
|
|
260
272
|
sendPrincipalRefusal(res, req, deps.config);
|
|
261
273
|
return;
|
|
262
274
|
}
|
|
263
|
-
const
|
|
264
|
-
if (
|
|
265
|
-
sendError(res, 400, "request.field_invalid",
|
|
275
|
+
const named = scenarioQueryOf(match.search);
|
|
276
|
+
if (named === QUERY_SCENARIO_REPEATED) {
|
|
277
|
+
sendError(res, 400, "request.field_invalid", SCENARIO_QUERY_REPEATED_REFUSAL);
|
|
266
278
|
return;
|
|
267
279
|
}
|
|
268
|
-
const scenarioName = await deps.scenarioGate(principal,
|
|
280
|
+
const { scenario: scenarioName } = await deps.scenarioGate(principal, scenarioRequestedBySubject(gatedSubject(req, deps.config), named));
|
|
269
281
|
await serveMcpProbeFace(res, ctx, principal, { declaredBy: "deployment", specs: mcpForScenario(deps.config.mcpServers, scenarioName) ?? [] });
|
|
270
282
|
return;
|
|
271
283
|
}
|
|
284
|
+
case "capability-scenario-effective": {
|
|
285
|
+
const principal = gatedPerson(req, deps.config);
|
|
286
|
+
if (deps.config.requirePrincipal && !principal) {
|
|
287
|
+
sendPrincipalRefusal(res, req, deps.config);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const named = scenarioQueryOf(match.search);
|
|
291
|
+
if (named === QUERY_SCENARIO_REPEATED) {
|
|
292
|
+
sendError(res, 400, "request.field_invalid", SCENARIO_QUERY_REPEATED_REFUSAL);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
const choice = await deps.scenarioGate(principal, scenarioRequestedBySubject(gatedSubject(req, deps.config), named));
|
|
296
|
+
sendJson(res, 200, { scenario: choice.scenario, source: choice.source });
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
272
299
|
case "capability-mcp-probe": {
|
|
273
300
|
const principal = gatedPerson(req, deps.config);
|
|
274
301
|
if (deps.config.requirePrincipal && !principal) {
|
|
@@ -398,6 +425,7 @@ export const CAPABILITIES_ROUTES = [
|
|
|
398
425
|
{ id: "capabilities", path: "/v1/capabilities", methods: ["GET"] },
|
|
399
426
|
{ id: "capability-scenario", pattern: /^\/v1\/capabilities\/scenarios\/(?<name>.*)$/, label: "/v1/capabilities/scenarios/:name", methods: ["GET"] },
|
|
400
427
|
{ id: "capability-mcp", path: "/v1/capabilities/mcp", methods: ["GET"] },
|
|
428
|
+
{ id: "capability-scenario-effective", path: "/v1/capabilities/scenario", methods: ["GET"] },
|
|
401
429
|
{ id: "capability-mcp-probe", path: "/v1/capabilities/mcp/probe", methods: ["POST"] },
|
|
402
430
|
];
|
|
403
431
|
//# sourceMappingURL=capabilities.js.map
|
|
@@ -23,13 +23,13 @@ export async function handleConfigCatalog(req, res, match, ctx) {
|
|
|
23
23
|
sendError(res, 501, "feature.config_catalog_disabled", "the config catalog is switched off on this deployment (CONFIG_CATALOG_ENABLED=false)");
|
|
24
24
|
return;
|
|
25
25
|
case "operator_principals_empty":
|
|
26
|
-
sendOperatorPrincipalsRequired(res);
|
|
26
|
+
sendOperatorPrincipalsRequired(res, "operate");
|
|
27
27
|
return;
|
|
28
28
|
default:
|
|
29
29
|
return assertNever(fact.why);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
if (!explicitOperatorOk(principal, deps.config)) {
|
|
32
|
+
if (!explicitOperatorOk(principal, deps.config, "operate")) {
|
|
33
33
|
sendError(res, 403, "auth.operator_only", OPERATOR_ONLY_MESSAGE);
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
@@ -144,7 +144,7 @@ export async function handleDevices(req, res, match, ctx) {
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
const { store, hub, enrollment, runStore } = lane;
|
|
147
|
-
const operator = explicitOperatorOk(principal, deps.config);
|
|
147
|
+
const operator = explicitOperatorOk(principal, deps.config, "operate");
|
|
148
148
|
const domain = deviceOwnerDomainOf(req, deps.config);
|
|
149
149
|
if (match.decl.id === "devices-list") {
|
|
150
150
|
if (!operator && domain === undefined) {
|
|
@@ -42,7 +42,6 @@ export interface ServerWiringGates {
|
|
|
42
42
|
* 不再是装配现场的事实,而是别处算完可能已漂的复述)。 */
|
|
43
43
|
export interface ServerWiringGateInput {
|
|
44
44
|
toolApprovalEnabled: boolean;
|
|
45
|
-
streamApprovalEnabled: boolean;
|
|
46
45
|
/** 谓词自己的入参类型(结构形,不 import store 依赖树)—— 取型而非重述,两处不可能漂。 */
|
|
47
46
|
backend: StreamApprovalGateInput["backend"];
|
|
48
47
|
/** 谓词自己的入参类型(只收店的形,工厂方法过不了 tsc)—— 取型而非重述,与 `backend` 同理;在场性即事实,本面不读实例的内容。 */
|
|
@@ -116,8 +115,9 @@ export declare function assertStaticWiringConsistent(facts: StaticWiringFacts, l
|
|
|
116
115
|
* 字符串,端口误暴露到公网就是侦察面(装配拓扑 / 治理姿态 / 写保护名表)。配了 service 凭据的部署上,到得了这里的请求都过了全局凭据门、
|
|
117
116
|
* 必然带着验过的身份,本判不咬;不要求静态凭据在场(鉴权桥的登录令牌就是身份)。
|
|
118
117
|
*
|
|
119
|
-
*
|
|
120
|
-
* `remoteAddress`
|
|
118
|
+
* 「本机」按请求通道穷举(`request-channel.ts`;加一种通道不接 ⇒ 编译红):经本机控制 socket 来的请求 = 本机(能连上它的只有引擎的 OS 用户 —— 与 `/health` 把它认作
|
|
119
|
+
* 本机用户同读,同一只请求不被一面认作本机、另一面认作远程);经 TCP 来的请求判源 = TCP 对端地址(`req.socket.remoteAddress`),**非任何头**(XFF 类头在无反代形上是自造面;
|
|
120
|
+
* 有反代的部署必然配凭据)。`remoteAddress` 缺席(socket 已断等边缘)⇒ 判拒(fail-closed)。
|
|
121
121
|
*/
|
|
122
122
|
export declare function remoteWithoutVerifiedIdentity(req: IncomingMessage, config: Parameters<typeof verifiedIdentitySource>[1]): boolean;
|
|
123
123
|
export declare function handleDiagnostics(req: IncomingMessage, res: ServerResponse, match: RouteMatch<DiagnosticsRouteId>, ctx: RouteCtx): Promise<void>;
|
|
@@ -5,6 +5,7 @@ import { readOutboundWiring } from "../../outbound-dispatcher.js";
|
|
|
5
5
|
import { resolveStreamApprovalGate } from "../../tool-approval.js";
|
|
6
6
|
import { sendJson, sendError } from "../send.js";
|
|
7
7
|
import { gatedPerson, explicitOperatorOk, isLoopbackAddress, sendOperatorPrincipalsRequired, verifiedIdentitySource } from "../principal-gate.js";
|
|
8
|
+
import { requestChannelOf } from "../request-channel.js";
|
|
8
9
|
import * as facts from "../../capability-facts.js";
|
|
9
10
|
import { assertNever } from "../route-ctx.js";
|
|
10
11
|
import { STORE_NOT_DURABLE_CODE, StoreNotDurableError, describeStoreRoot, projectStoreDurabilityWiring, unwiredStorePosture } from "../../store-posture.js";
|
|
@@ -12,7 +13,6 @@ import { describeLocalStoreDeclaration } from "../../local-store-declaration.js"
|
|
|
12
13
|
export function buildServerWiringGates(input) {
|
|
13
14
|
const gate = resolveStreamApprovalGate({
|
|
14
15
|
toolApprovalEnabled: input.toolApprovalEnabled,
|
|
15
|
-
streamApprovalEnabled: input.streamApprovalEnabled,
|
|
16
16
|
backend: input.backend,
|
|
17
17
|
checkpointStore: input.checkpointStore,
|
|
18
18
|
});
|
|
@@ -126,17 +126,30 @@ export function assertStaticWiringConsistent(facts, logger) {
|
|
|
126
126
|
return audit;
|
|
127
127
|
}
|
|
128
128
|
export function remoteWithoutVerifiedIdentity(req, config) {
|
|
129
|
-
return !
|
|
129
|
+
return !requestFromThisHost(req) && verifiedIdentitySource(req, config) === undefined;
|
|
130
|
+
}
|
|
131
|
+
function requestFromThisHost(req) {
|
|
132
|
+
const channel = requestChannelOf(req);
|
|
133
|
+
switch (channel) {
|
|
134
|
+
case "tcp":
|
|
135
|
+
return isLoopbackAddress(req.socket.remoteAddress);
|
|
136
|
+
case "control-socket":
|
|
137
|
+
return true;
|
|
138
|
+
default: {
|
|
139
|
+
const unknownChannel = channel;
|
|
140
|
+
throw new Error(`diagnostics: request channel ${String(unknownChannel)} has no locality reading`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
130
143
|
}
|
|
131
144
|
export async function handleDiagnostics(req, res, match, ctx) {
|
|
132
145
|
const { deps } = ctx;
|
|
133
146
|
switch (match.decl.id) {
|
|
134
147
|
case "diagnostics-wiring": {
|
|
135
|
-
if (!facts.operatorLane(deps).available) {
|
|
136
|
-
sendOperatorPrincipalsRequired(res);
|
|
148
|
+
if (!facts.operatorLane(deps, "operate").available) {
|
|
149
|
+
sendOperatorPrincipalsRequired(res, "operate");
|
|
137
150
|
return;
|
|
138
151
|
}
|
|
139
|
-
if (!explicitOperatorOk(gatedPerson(req, deps.config), deps.config)) {
|
|
152
|
+
if (!explicitOperatorOk(gatedPerson(req, deps.config), deps.config, "operate")) {
|
|
140
153
|
sendError(res, 403, "auth.operator_only", "wiring diagnostics are operator-only");
|
|
141
154
|
return;
|
|
142
155
|
}
|
|
@@ -156,8 +169,7 @@ export async function handleDiagnostics(req, res, match, ctx) {
|
|
|
156
169
|
configApply: deps.configApplyState?.() ?? null,
|
|
157
170
|
mcpRevocations: deps.mcpRevocationState?.() ?? null,
|
|
158
171
|
serverGates: buildServerWiringGates({
|
|
159
|
-
toolApprovalEnabled: deps.
|
|
160
|
-
streamApprovalEnabled: deps.config.streamApproval?.enabled === true,
|
|
172
|
+
toolApprovalEnabled: deps.config.toolApprovalEnabled === true,
|
|
161
173
|
backend: deps.backend,
|
|
162
174
|
checkpointStore: deps.checkpointStore,
|
|
163
175
|
durableApproval: deps.config.durableApproval === true,
|