@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
package/dist/security.js
CHANGED
|
@@ -3,8 +3,10 @@ import { DEPLOYMENT_SHAPE_PREDICATES } from "./deployment-shape.js";
|
|
|
3
3
|
import { FACES, OWNERLESS_ORDINARY_CELL, ownerCellOf, ownerlessCellWithoutRead, qualsOf, recoveredSubject, visibleOn } from "./owner-faces.js";
|
|
4
4
|
import { mintDurableOwnerKey, mintPerson, partsOf, personOf, scenarioNamed, subjectOf } from "./owner-brands.js";
|
|
5
5
|
import { deletionHeadReadOf } from "./session-incarnation.js";
|
|
6
|
+
import { isSessionKind, sessionKindFaceOf } from "./session-kind.js";
|
|
6
7
|
import { memoryScopeFor } from "./memory-scope.js";
|
|
7
8
|
import { verifyPrincipalJwt } from "./principal-jwt.js";
|
|
9
|
+
import { engineScopeOfOwner } from "./engine-identity.js";
|
|
8
10
|
import { fieldConflictFacts } from "./field-conflict.js";
|
|
9
11
|
import { refusalReservedKeyMessage, refusalReservedKeyOf } from "./http/refusal-body.js";
|
|
10
12
|
import { PRINCIPAL_MAX_BYTES, principalShapeProblem } from "./principal-shape.js";
|
|
@@ -33,6 +35,14 @@ export const ATTACH_ABSENT_MESSAGE = "requireExistingSession: session does not e
|
|
|
33
35
|
function attachAbsentError() {
|
|
34
36
|
return createCodedHttpError(404, "resume.session_not_found", ATTACH_ABSENT_MESSAGE);
|
|
35
37
|
}
|
|
38
|
+
export const SESSION_KIND_MISMATCH_MESSAGE = "this session already exists with a different session kind — a session's kind is written once, when the session is created, and never changes; send the same sessionKind the session was created with, omit sessionKind to run the session as it is, or start a new session";
|
|
39
|
+
function sessionKindMismatch(rowKind) {
|
|
40
|
+
return createCodedHttpError(409, "conflict.session_kind_mismatch", SESSION_KIND_MISMATCH_MESSAGE, rowKind === undefined ? undefined : { sessionKind: rowKind });
|
|
41
|
+
}
|
|
42
|
+
export const SESSION_KIND_UNRECORDABLE_MESSAGE = "sessionKind requires a session store that records a session's kind and ages such sessions out (DB_BACKEND=mysql|pg|local) — this deployment cannot, so the session would be created as a top-level conversation; capabilities.sessionKinds lists the kinds a deployment accepts";
|
|
43
|
+
function sessionKindUnrecordable() {
|
|
44
|
+
return createCodedHttpError(400, "request.precondition_unmet", SESSION_KIND_UNRECORDABLE_MESSAGE);
|
|
45
|
+
}
|
|
36
46
|
export async function sessionOwnerCellOf(store, sessionId, owner) {
|
|
37
47
|
if (owner !== null)
|
|
38
48
|
return ownerCellOf(owner);
|
|
@@ -122,13 +132,25 @@ export function createAuthorizer(config, sessionStore, logger) {
|
|
|
122
132
|
};
|
|
123
133
|
const birthFace = birthFaceOf(sessionStore);
|
|
124
134
|
const withdrawFace = withdrawFaceOf(sessionStore);
|
|
125
|
-
const
|
|
126
|
-
|
|
135
|
+
const kindFace = sessionKindFaceOf(sessionStore);
|
|
136
|
+
const registerNew = async (id, owner, kind, register, onBirth) => {
|
|
137
|
+
if (kind !== undefined && birthFace === undefined)
|
|
138
|
+
throw sessionKindUnrecordable();
|
|
139
|
+
if (birthFace === undefined || (withdrawFace === undefined && kind === undefined))
|
|
127
140
|
return register(id, owner);
|
|
128
|
-
const receipt = await birthFace.registerWithReceipt(id, owner);
|
|
129
|
-
if (receipt.minted !== undefined)
|
|
141
|
+
const receipt = await birthFace.registerWithReceipt(id, owner, kind);
|
|
142
|
+
if (receipt.minted !== undefined && withdrawFace !== undefined)
|
|
130
143
|
onBirth?.(receipt.minted, withdrawFace);
|
|
131
144
|
};
|
|
145
|
+
const judgeKind = async (id, wanted, judged, subject) => {
|
|
146
|
+
if (kindFace === undefined)
|
|
147
|
+
throw sessionKindUnrecordable();
|
|
148
|
+
const reading = await kindFace.sessionKindOf(id);
|
|
149
|
+
if (reading === undefined || judged === undefined || reading.incarnation !== judged.incarnation)
|
|
150
|
+
throw attachRefused("not_visible", subject);
|
|
151
|
+
if (reading.kind !== wanted)
|
|
152
|
+
throw sessionKindMismatch(reading.kind);
|
|
153
|
+
};
|
|
132
154
|
return async ({ req, body, onBirth }) => {
|
|
133
155
|
const subject = verifiedSubject(req, config);
|
|
134
156
|
if (config.requirePrincipal && !subject) {
|
|
@@ -142,6 +164,7 @@ export function createAuthorizer(config, sessionStore, logger) {
|
|
|
142
164
|
projectId = body.projectId.toLowerCase();
|
|
143
165
|
}
|
|
144
166
|
const requireExisting = body.requireExistingSession === true;
|
|
167
|
+
const kind = isSessionKind(body.sessionKind) ? body.sessionKind : undefined;
|
|
145
168
|
const headOf = deletionHeadReadOf(sessionStore);
|
|
146
169
|
let head;
|
|
147
170
|
const readOwner = headOf === undefined ? undefined : async (id) => {
|
|
@@ -159,7 +182,7 @@ export function createAuthorizer(config, sessionStore, logger) {
|
|
|
159
182
|
throw attachRefused("missing", subject);
|
|
160
183
|
}
|
|
161
184
|
if (register) {
|
|
162
|
-
await registerNew(requested, subject ?? null, register, onBirth);
|
|
185
|
+
await registerNew(requested, subject ?? null, kind, register, onBirth);
|
|
163
186
|
owner = await readOwner(requested);
|
|
164
187
|
}
|
|
165
188
|
else if (config.requirePrincipal) {
|
|
@@ -170,11 +193,18 @@ export function createAuthorizer(config, sessionStore, logger) {
|
|
|
170
193
|
const claimCaller = claimCallerOf(subject, config);
|
|
171
194
|
if (!visibleOn("session.attach", qualsOf(claimCaller, await sessionCellFor("session.attach", claimCaller, sessionStore, requested, owner))))
|
|
172
195
|
throw attachRefused("not_visible", subject);
|
|
196
|
+
if (kind !== undefined)
|
|
197
|
+
await judgeKind(requested, kind, head, subject);
|
|
198
|
+
}
|
|
199
|
+
else if (kind !== undefined) {
|
|
200
|
+
throw register ? attachRefused("missing", subject) : sessionKindUnrecordable();
|
|
173
201
|
}
|
|
174
202
|
}
|
|
175
203
|
else if (config.requirePrincipal) {
|
|
176
204
|
throw new HttpError(403, "session reuse needs an owner-aware session store on a multi-tenant deployment: this worker's session store cannot attest who owns a session, so a sessionId cannot be authorized — including one this worker itself minted a moment ago (without a register seam it was never recorded as yours). Configure a durable session backend (SESSION_BACKEND), or omit sessionId on every turn to start fresh.");
|
|
177
205
|
}
|
|
206
|
+
if (!readOwner && kind !== undefined)
|
|
207
|
+
throw sessionKindUnrecordable();
|
|
178
208
|
sessionId = requested;
|
|
179
209
|
}
|
|
180
210
|
else {
|
|
@@ -183,9 +213,13 @@ export function createAuthorizer(config, sessionStore, logger) {
|
|
|
183
213
|
}
|
|
184
214
|
sessionId = uuidv7();
|
|
185
215
|
if (register)
|
|
186
|
-
await registerNew(sessionId, subject ?? null, register, onBirth);
|
|
216
|
+
await registerNew(sessionId, subject ?? null, kind, register, onBirth);
|
|
217
|
+
else if (kind !== undefined)
|
|
218
|
+
throw sessionKindUnrecordable();
|
|
187
219
|
if (readOwner)
|
|
188
220
|
await readOwner(sessionId);
|
|
221
|
+
if (kind !== undefined)
|
|
222
|
+
await judgeKind(sessionId, kind, head, subject);
|
|
189
223
|
}
|
|
190
224
|
return { subject, sessionId, memoryScope: memoryScopeFor(config, subject === undefined ? undefined : personOf(subject), projectId), resolvedProjectId: projectId, ...(head === undefined ? {} : { head }) };
|
|
191
225
|
};
|
|
@@ -223,7 +257,7 @@ export function subjectWidthExceeded(subject) {
|
|
|
223
257
|
export const CHECKPOINT_PUBLIC_SCOPE = "_";
|
|
224
258
|
export const BACKGROUND_REGISTRY_ANON_SCOPE = "default";
|
|
225
259
|
export function backgroundScopesForCheckpointScope(scope) {
|
|
226
|
-
return scope === CHECKPOINT_PUBLIC_SCOPE ? [CHECKPOINT_PUBLIC_SCOPE, BACKGROUND_REGISTRY_ANON_SCOPE] : [scope];
|
|
260
|
+
return scope === CHECKPOINT_PUBLIC_SCOPE ? [CHECKPOINT_PUBLIC_SCOPE, BACKGROUND_REGISTRY_ANON_SCOPE] : [engineScopeOfOwner(scope)];
|
|
227
261
|
}
|
|
228
262
|
export const encodeCheckpointScope = (subject) => subject ?? CHECKPOINT_PUBLIC_SCOPE;
|
|
229
263
|
export const decodeCheckpointScope = (scope) => (scope === CHECKPOINT_PUBLIC_SCOPE ? undefined : mintDurableOwnerKey(scope));
|
|
@@ -30,7 +30,8 @@ export declare function provisionSemaConfigDir(config: {
|
|
|
30
30
|
* (与记忆根那一判共用同一只规范形,那一判的失败方向是多报,这一判的是漏报;如实披露)。
|
|
31
31
|
* 句子只描述位置关系,后果限定在引擎**缺省**写保护表上:用 `WRITE_PROTECTED_TABLE_REPLACE` 去掉那一行的部署不受影响(这一行不读那张表),可忽略它。
|
|
32
32
|
*
|
|
33
|
-
* 规范形读不出(
|
|
33
|
+
* 规范形读不出(两边路径上有一段没有搜索权限 / 链接成环,或盘上竞态:探完到取值之间目录被挪走 / 搜索权限被收)⇒ 不给位置结论(看不见的一段不当成「还不存在」),
|
|
34
|
+
* 披露面也不得把起服打死:响亮报另一行 `sema_config_root_workspace_check_unavailable`(类名 + 机器码),起服照常。
|
|
34
35
|
* 位置:HTTP 服务在装配第 2 段执行车道合成之后(读的是合成后的车道与工作区底),`run-local` 在工作区定下之后 —— 车道在这两处才定形,所以不与 {@link provisionSemaConfigDir} 同一拍。
|
|
35
36
|
*/
|
|
36
37
|
export declare function announceConfigRootEnclosingWorkspace(config: {
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
* `ADB_VENDOR_KEYS` / `AWS_SECRET_ACCESS_KEY` 一类,实测)。三个继承词只在引擎一处判:
|
|
19
19
|
* · `"all"` = 整份环境 **减** 本进程声明的自有凭据名;`"scrub"`(缺省)= 形状剥 ∪ 该名单;`[names]` = 严格白名单,点到名单中的名 ⇒ 引擎响亮拒
|
|
20
20
|
* (`inheritEnvPolicyProblem`:构造时与 spawn 时两格都拒,拒句带名;本仓不自判 withheld、不留第二读法)。
|
|
21
|
-
* · 名单 =
|
|
21
|
+
* · 名单 = 本包凭据类变量名({@link CREDENTIAL_ENV_NAMES}:配置目录(`config-catalog.ts`)全部 `type:"secret"` 名 ∪ bake-runner 进程自己的凭据名 `BAKE_RUNNER_CREDENTIAL_ENV`
|
|
22
|
+
* —— 目录只装服务进程读的 env,runner 的 bearer 不是目录行)∪ 名单型旋钮名(`env-name-allowlist-knobs.ts`,其原文可能夹着被错展开的令牌)∪ **生效配置
|
|
22
23
|
* 模型条目的 `apiKeyEnv`**(key-resolver 取凭据的那张表 `config.modelApiKeyEnv` 的值 —— 本进程消费的凭据变量名,条目由中心热应用新增 / 改名),
|
|
23
24
|
* **机器派生**、不手抄、不按「归谁消费」切({@link serverWithheldEnvNames} 一处)。声明两个时机、同一只 {@link declareServerWithheldEnv}:起服第一步(三个进程入口:
|
|
24
25
|
* `boot/stage-01-config.ts` / `run-local.ts` / `bake-runner/main.ts`,在任何执行环境构造与 spawn 之前 —— 声明先于构造才有构造时拒;此时没有生效配置 = 空表),
|
|
@@ -29,9 +30,10 @@
|
|
|
29
30
|
* `loadConfig()` 的**声明前提**({@link ownCredentialDeclarationRefusal}:起服表的名没全扣 ⇒ `loadConfig` 抛,拒句点名 {@link declareServerWithheldEnv} —— 「先声明」不再只是入口里的位置契约,
|
|
30
31
|
* 不经入口直接调 `loadConfig` 的进程〔包根嵌入方 / bench / 探针脚本〕得先声明,声明对它们才不是空的)与能力词 `inherit_env.own_credentials_withheld` 在本进程的事实
|
|
31
32
|
* {@link ownCredentialsWithheld}(当前生效配置应声明的名全被扣;活配置经 {@link bindOwnCredentialsConfig} 在 `loadConfig()` 之后绑一次;未绑 / 没扣 ⇒ false)。
|
|
32
|
-
* · **值臂**(core 7.52.0 [ref]):声明是一张表 `{ names, values }`。`values` =
|
|
33
|
-
* 此刻装着的**每一枚**本服务凭据 —— 颗粒按本服务读这只变量的那一只解析器定(
|
|
34
|
-
* `APPROVAL_HMAC_KEYS`
|
|
33
|
+
* · **值臂**(core 7.52.0 [ref]):声明是一张表 `{ names, values }`。`values` = 本包凭据类变量(本包凭据类变量名 ∪ 模型条目 `apiKeyEnv`,{@link serverCredentialValueSources})
|
|
34
|
+
* 此刻装着的**每一枚**本服务凭据 —— 颗粒按本服务读这只变量的那一只解析器定(行的 `credentialForm`:装着凭据值的颗粒整值总在内,`SERVICE_AUTH_TOKENS` 另加每一枚令牌、
|
|
35
|
+
* `APPROVAL_HMAC_KEYS` 另加每一把钥;名单型旋钮的颗粒 `name-list` 是零枚 —— 原文是变量名单,不是凭据;一只变量有几个读者就取几个读法的并集 —— 模型条目的 `apiKeyEnv` 指着它 ⇒
|
|
36
|
+
* key-resolver 把它整值读成一枚,哪怕它是一行名单型旋钮;{@link credentialsHeldBy})—— 引擎按整串比,所以一枚令牌换了个变量名放着与原变量同扣,部分重叠 / 前后缀不同的值不扣。
|
|
35
37
|
* 逐枚交给引擎的同一只判;引擎判「不是凭据值」的那一枚不扣、名照扣、不拒启、点名那个变量一次。能力词 `inherit_env.own_credential_values_withheld` 的事实 = {@link ownCredentialValuesWithheld}(位真 ⇔ 值臂每一枚都真扣)。
|
|
36
38
|
* 「这个变量是不是本服务的凭据」(名是,或值是)只有一只读法 {@link ownCredentialVariable}(判官 = 引擎此刻的声明):名单型旋钮的解析器与声明增长时的重判都问它。
|
|
37
39
|
* · 调用方显式传入的 env(`cfg.env` / 单次命令的 `env` / 沙箱的点名放回)不是继承,照旧原样叠在组合结果之上 —— 那是适配器自己的凭据通道。
|
|
@@ -54,19 +56,19 @@
|
|
|
54
56
|
import { type InheritEnvPolicy, type SecretEnvFinding } from "@sema-agent/core";
|
|
55
57
|
import type { ServiceConfig } from "./config-types.js";
|
|
56
58
|
import { type SecretEnvScrubSite } from "./observability/secret-env-scrub.js";
|
|
57
|
-
/**
|
|
58
|
-
export declare const
|
|
59
|
+
/** 本包凭据类变量名({@link CREDENTIAL_FORM_OF} 的键;排序只为读数稳定)。 */
|
|
60
|
+
export declare const CREDENTIAL_ENV_NAMES: ReadonlySet<string>;
|
|
59
61
|
/** 生效配置模型条目 name → `apiKeyEnv`(变量**名**,值从本进程 env 取)—— `ServiceConfig.modelApiKeyEnv` 的形,key-resolver 读凭据的那张表。 */
|
|
60
62
|
export type ModelApiKeyEnvTable = Readonly<Record<string, string>>;
|
|
61
63
|
/**
|
|
62
|
-
* 本进程的自有凭据名(
|
|
64
|
+
* 本进程的自有凭据名(机器派生,三臂一处:本包凭据类变量名 ∪ 名单型旋钮名 ∪ `modelApiKeyEnv` 表的值;排序只为读数稳定)。纯函数:给哪张表就答哪张表的应声明
|
|
63
65
|
* 集合 —— 声明时给候选表、能力位给活表,同一只派生。名字按原文交引擎(目录臂同形),不在本仓折叠大小写。
|
|
64
66
|
*/
|
|
65
67
|
export declare function serverWithheldEnvNames(modelApiKeyEnv?: ModelApiKeyEnvTable): readonly string[];
|
|
66
68
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
69
|
+
* 本进程的**凭据类变量**名:本包凭据类变量名 ∪ 模型条目 `apiKeyEnv` 的值 —— 名单与值臂两臂同一张表派生,只少不在那张表里的名单型旋钮名(今天 = bake-runner 进程的
|
|
70
|
+
* `BAKE_ENV_ALLOW`)。两个读者问同一张:值臂按每只的颗粒读出它此刻装着的凭据值({@link credentialsHeldBy};名单型旋钮的颗粒 `name-list` ⇒ 零枚,名照扣),
|
|
71
|
+
* 请求 `settings.env` 的凭据判据按名拒(`task-settings.ts` `settingsEnvCredentialIssue`)。纯函数,排序只为读数稳定。
|
|
70
72
|
*/
|
|
71
73
|
export declare function serverCredentialValueSources(modelApiKeyEnv?: ModelApiKeyEnvTable): readonly string[];
|
|
72
74
|
/**
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { declareWithheldEnv, hostChildEnv, inheritEnvPolicyProblem, inheritedHostEnv } from "@sema-agent/core";
|
|
2
|
-
import { CONFIG_CATALOG } from "./config-catalog.js";
|
|
2
|
+
import { BAKE_RUNNER_CREDENTIAL_ENV, CONFIG_CATALOG } from "./config-catalog.js";
|
|
3
3
|
import { parseApprovalHmacKeys, parseServiceAuthTokens } from "./auth-keys.js";
|
|
4
4
|
import { ENV_NAME_ALLOWLIST_KNOB_NAMES } from "./env-name-allowlist-knobs.js";
|
|
5
5
|
import { recordOwnCredentialValueNotWithheld, recordSecretEnvScrub } from "./observability/secret-env-scrub.js";
|
|
6
|
-
|
|
6
|
+
const CREDENTIAL_FORM_OF = new Map([
|
|
7
|
+
...CONFIG_CATALOG.flatMap((spec) => (spec.credentialForm === undefined ? [] : [[spec.name, spec.credentialForm]])),
|
|
8
|
+
...Object.entries(BAKE_RUNNER_CREDENTIAL_ENV),
|
|
9
|
+
]);
|
|
10
|
+
export const CREDENTIAL_ENV_NAMES = new Set([...CREDENTIAL_FORM_OF.keys()].sort());
|
|
7
11
|
const NO_MODEL_ENTRIES = Object.freeze({});
|
|
8
12
|
export function serverWithheldEnvNames(modelApiKeyEnv = NO_MODEL_ENTRIES) {
|
|
9
|
-
return [...new Set([...
|
|
13
|
+
return [...new Set([...CREDENTIAL_ENV_NAMES, ...ENV_NAME_ALLOWLIST_KNOB_NAMES, ...Object.values(modelApiKeyEnv)])].sort();
|
|
10
14
|
}
|
|
11
15
|
export function serverCredentialValueSources(modelApiKeyEnv = NO_MODEL_ENTRIES) {
|
|
12
|
-
return [...new Set([...
|
|
16
|
+
return [...new Set([...CREDENTIAL_ENV_NAMES, ...Object.values(modelApiKeyEnv)])].sort();
|
|
13
17
|
}
|
|
14
|
-
const CREDENTIAL_FORM_OF = new Map(CONFIG_CATALOG.flatMap((spec) => (spec.credentialForm === undefined ? [] : [[spec.name, spec.credentialForm]])));
|
|
15
18
|
const DROPPED_KEYS_TOLD_BY_LOAD_CONFIG = () => { };
|
|
16
19
|
function credentialsIn(form, raw) {
|
|
17
20
|
switch (form) {
|
|
@@ -21,6 +24,8 @@ function credentialsIn(form, raw) {
|
|
|
21
24
|
return [raw, ...Object.keys(parseServiceAuthTokens(raw))];
|
|
22
25
|
case "key-set":
|
|
23
26
|
return [raw, ...parseApprovalHmacKeys(raw, DROPPED_KEYS_TOLD_BY_LOAD_CONFIG).map((k) => k.key)];
|
|
27
|
+
case "name-list":
|
|
28
|
+
return [];
|
|
24
29
|
default: {
|
|
25
30
|
const unreachable = form;
|
|
26
31
|
throw new Error(`unhandled secret credential form: ${String(unreachable)}`);
|
|
@@ -32,15 +37,17 @@ let beforeLast;
|
|
|
32
37
|
const valueRefusalAnnounced = new Set();
|
|
33
38
|
let liveConfig;
|
|
34
39
|
const envValueOf = (name) => process.env[name];
|
|
35
|
-
function credentialsHeldBy(source) {
|
|
40
|
+
function credentialsHeldBy(source, keyEnvs) {
|
|
36
41
|
const raw = envValueOf(source);
|
|
37
42
|
if (raw === undefined || raw === "")
|
|
38
43
|
return [];
|
|
39
|
-
|
|
44
|
+
const row = CREDENTIAL_FORM_OF.get(source);
|
|
45
|
+
const read = [...(row === undefined ? [] : credentialsIn(row, raw)), ...(keyEnvs.has(source) ? credentialsIn("whole", raw) : [])];
|
|
46
|
+
return [...new Set(read)].filter((v) => v !== "");
|
|
40
47
|
}
|
|
41
|
-
function heldValues(held) {
|
|
48
|
+
function heldValues(held, keyEnvs) {
|
|
42
49
|
return [...held].flatMap(([source, at]) => {
|
|
43
|
-
const all = credentialsHeldBy(source);
|
|
50
|
+
const all = credentialsHeldBy(source, keyEnvs);
|
|
44
51
|
return [...at].flatMap((i) => {
|
|
45
52
|
const value = all[i];
|
|
46
53
|
return value === undefined ? [] : [value];
|
|
@@ -49,16 +56,17 @@ function heldValues(held) {
|
|
|
49
56
|
}
|
|
50
57
|
export function declareServerWithheldEnv(modelApiKeyEnv = NO_MODEL_ENTRIES) {
|
|
51
58
|
const names = [...new Set([...(declared?.names ?? []), ...serverWithheldEnvNames(modelApiKeyEnv)])].sort();
|
|
59
|
+
const keyEnvs = new Set([...(declared?.keyEnvs ?? []), ...Object.values(modelApiKeyEnv)]);
|
|
52
60
|
const held = new Map(declared?.held ?? []);
|
|
53
|
-
declareWithheldEnv({ names, values: heldValues(held) });
|
|
61
|
+
declareWithheldEnv({ names, values: heldValues(held, keyEnvs) });
|
|
54
62
|
for (const source of serverCredentialValueSources(modelApiKeyEnv)) {
|
|
55
63
|
const at = new Set(held.get(source) ?? []);
|
|
56
64
|
let refusal;
|
|
57
|
-
credentialsHeldBy(source).forEach((_, i) => {
|
|
65
|
+
credentialsHeldBy(source, keyEnvs).forEach((_, i) => {
|
|
58
66
|
if (at.has(i))
|
|
59
67
|
return;
|
|
60
68
|
try {
|
|
61
|
-
declareWithheldEnv({ names, values: heldValues(new Map(held).set(source, new Set([...at, i]))) });
|
|
69
|
+
declareWithheldEnv({ names, values: heldValues(new Map(held).set(source, new Set([...at, i])), keyEnvs) });
|
|
62
70
|
at.add(i);
|
|
63
71
|
held.set(source, new Set(at));
|
|
64
72
|
}
|
|
@@ -72,11 +80,11 @@ export function declareServerWithheldEnv(modelApiKeyEnv = NO_MODEL_ENTRIES) {
|
|
|
72
80
|
}
|
|
73
81
|
}
|
|
74
82
|
beforeLast = declared;
|
|
75
|
-
declared = { names: new Set(names), held };
|
|
83
|
+
declared = { names: new Set(names), held, keyEnvs };
|
|
76
84
|
return names;
|
|
77
85
|
}
|
|
78
86
|
export function withdrawServerWithheldEnv() {
|
|
79
|
-
declareWithheldEnv({ names: [...(beforeLast?.names ?? [])], values: heldValues(beforeLast?.held ?? new Map()) });
|
|
87
|
+
declareWithheldEnv({ names: [...(beforeLast?.names ?? [])], values: heldValues(beforeLast?.held ?? new Map(), beforeLast?.keyEnvs ?? new Set()) });
|
|
80
88
|
declared = beforeLast;
|
|
81
89
|
}
|
|
82
90
|
export function bindOwnCredentialsConfig(config) {
|
|
@@ -102,7 +110,8 @@ export function ownCredentialValuesWithheld() {
|
|
|
102
110
|
if (declared === undefined || liveConfig === undefined)
|
|
103
111
|
return false;
|
|
104
112
|
const held = declared.held;
|
|
105
|
-
|
|
113
|
+
const keyEnvs = new Set([...declared.keyEnvs, ...Object.values(liveConfig.modelApiKeyEnv)]);
|
|
114
|
+
return serverCredentialValueSources(liveConfig.modelApiKeyEnv).every((source) => (held.get(source)?.size ?? 0) === credentialsHeldBy(source, keyEnvs).length);
|
|
106
115
|
}
|
|
107
116
|
export function ownCredentialVariable(name) {
|
|
108
117
|
if (inheritEnvPolicyProblem([name]) !== undefined)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **会话绑定** —— 一次提交写在会话上的三格进程内事实(工作目录 · shell 环境 · 继承策略;host / device 工厂在 run 起跑那一拍按会话键现读)的唯一律。
|
|
3
|
+
*
|
|
4
|
+
* ## 律
|
|
5
|
+
* 会话绑定是**被受理的 run** 的事实,不是请求的事实:
|
|
6
|
+
* · **判在写之前** —— 装配器(`boot/resolve-spec.ts`)只判、只算这条腿要写的那一份({@link SessionBindings},随部署事实 `LegFacts.sessionBindings` 走);
|
|
7
|
+
* 工作目录那一格 = 这条腿**跑在**的那一枚(请求带的 ?? 项目继承来的 ?? 会话上已登记的),装配器自己的读者(hooks 的工作目录、真任务根、写门基准、组合腿的根)
|
|
8
|
+
* 与起跑时的工厂读的是同一枚 —— 提交点把它原样写进会话,装配读与起跑读之间别的提交的写改不了这条腿的落点;
|
|
9
|
+
* · **一个写点** —— run 认领之后、起跑之前的唯一提交点 {@link commitLegBindings}(四个认领点:流式提交 / 同步提交 / durable 建行腿 / 续跑驱动腿;
|
|
10
|
+
* 类级机器门 `test/inherit-env-request-key.test.ts`)。装配器之后、认领之前的一切拒(装配期的拒、路由层的建行 409 / placement / 续跑输入 / 起跑前复核)零写;
|
|
11
|
+
* · **写在判之后的,同一只撤回** —— 写了之后才收场 `refused` 的提交(引擎零工作的拒、受理之前取消)由提交出口(`submission-exit.ts`)按本次的回执撤回;
|
|
12
|
+
* 受理 / record 的落定。登记簿记的是「已落定的底 + 还没落定的各笔(按提交序)」,三张表恒是它的物化:撤回只抽掉这一笔、重新物化 —— 别的提交的写原样、原序,
|
|
13
|
+
* 两笔都被撤就回到底(不会把一笔被拒的写当成另一笔的「写之前」还原回来);围栏清过 / 会话删过 ⇒ 回执一笔不动。
|
|
14
|
+
* 行判撤的提交另由出口按住客清掉全部条目(与 `DELETE` 同一组,既有)。没有出口座的腿(续跑驱动腿 · 后台建行腿:认领即 record)写即落定。
|
|
15
|
+
*
|
|
16
|
+
* 一条被拒的提交因此不留任何它写下的会话绑定 —— 请求自带的 `cwd`、项目继承来的第一条 `folder`、`settings.env`、`inheritEnv` 同一条律,
|
|
17
|
+
* 与会话行(提交出口)、请求形的拒(`request-form.ts`,在铸点之前答)同一个「拒后零残留」。
|
|
18
|
+
*
|
|
19
|
+
* ## 三格的缺席语义(各自原样)
|
|
20
|
+
* · `cwd`:缺席 = 这条腿没有工作目录(请求没带、没继承、会话上也没登记)⇒ 不动;
|
|
21
|
+
* · `shellEnv`:缺席 = 不动(粘住上一条受理的 —— 壳每条请求重发,粘住无害;装配器不读这一格);
|
|
22
|
+
* · `inheritEnv`:缺席 = 清(缺省清洗 —— 粘住 = 替一个没说话的请求放宽凭据面;理由在 `boot/execution-env.ts` 的登记簿注)。
|
|
23
|
+
* 装配器没铸事实(嵌入方自带的装配器)⇒ 按「什么都没要」写:`inheritEnv` 清、其余不动(安全轴 fail-closed 的那一侧)。
|
|
24
|
+
*
|
|
25
|
+
* ## 残余(如实)
|
|
26
|
+
* · 登记簿仍按**会话**键控、工厂在起跑那一刻现读(core 的执行环境工厂上下文只带 sessionId / taskId,没有 per-run 座):有 run 店的部署上认领串行化同会话的 run,
|
|
27
|
+
* 「写 → 读」落在同一条认领窗里;没有 run 店的部署上同会话并发受理的两条 run 仍是「最后写者赢」。
|
|
28
|
+
* · 续跑腿没有提交出口:它在 markResuming 赢之后写**那条停驻任务自己**盘上的值(不是别的请求的);core 的 pre-CAS 守卫在那之后才拒的续跑照样留着它,
|
|
29
|
+
* 下一条受理的 run 照写覆盖。
|
|
30
|
+
* · 登记簿是每副本进程内的(围栏与清除只在处理该请求的副本上发生),见 `createSessionScopedRegistries` 头注。
|
|
31
|
+
*/
|
|
32
|
+
import type { TaskInheritEnv } from "./request-value-closure.js";
|
|
33
|
+
/** 一条腿要写在会话上的绑定(装配器判出的那一份;提交点原样写)。缺席语义见本文件头注。 */
|
|
34
|
+
export interface SessionBindings {
|
|
35
|
+
/** 这条腿跑在的工作目录(请求带的 ?? 项目继承来的 ?? 会话上已登记的;前两者只在车道能力 `callerCwd` 成立且是宿主绝对路径时算数)。缺席 = 不动。 */
|
|
36
|
+
readonly cwd?: string;
|
|
37
|
+
/** 请求的 `settings.env`(只在 `callerCwd` 成立时在场)。缺席 = 不动。 */
|
|
38
|
+
readonly shellEnv?: Readonly<Record<string, string>>;
|
|
39
|
+
/** 请求的 `inheritEnv`(装配器判过值形 / 车道 / 射程)。缺席 = 清。 */
|
|
40
|
+
readonly inheritEnv?: TaskInheritEnv;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 三格的**唯一铸法**:在场(≠ `undefined`)的格才出键,缺席的格不出键。本函数只答「缺席 = 没有这个键」,不替任何一格选缺省 —— 每一格缺席读作什么见上面头注,由各读者按那一条读。
|
|
44
|
+
* 三个调用点同用:装配器算这条腿的绑定(`boot/resolve-spec.ts`)、登记簿读一份当下的三格、登记簿把一笔写叠在一份读数之上(`boot/execution-env.ts`)。
|
|
45
|
+
* 此前各写一遍三条件展开,`inheritEnv` 这个键在三处各被拼一次;现在这个键的属性字面量在 src 只此一处(类级门 `test/secret-env-scrub-host-legs.test.ts` 的 [ref] 格数的就是它)。
|
|
46
|
+
* `shellEnv` 的型随调用点(装配器交只读的、登记簿的表里是可变的)。
|
|
47
|
+
*/
|
|
48
|
+
export declare function bindingsOf<E extends Readonly<Record<string, string>>>(cwd: string | undefined, shellEnv: E | undefined, inheritEnv: TaskInheritEnv | undefined): {
|
|
49
|
+
readonly cwd?: string;
|
|
50
|
+
readonly shellEnv?: E;
|
|
51
|
+
readonly inheritEnv?: TaskInheritEnv;
|
|
52
|
+
};
|
|
53
|
+
/** 一笔提交的回执(撤回 / 落定只认这一笔)。 */
|
|
54
|
+
export interface SessionBindingReceipt {
|
|
55
|
+
readonly sessionId: string;
|
|
56
|
+
/** 这一笔的回执号。 */
|
|
57
|
+
readonly token: symbol;
|
|
58
|
+
}
|
|
59
|
+
/** 登记簿的写座(`boot/execution-env.ts` `createSessionScopedRegistries` 铸;HTTP 面经 `ServiceDeps.sessionBindings` 拿到)。 */
|
|
60
|
+
export interface SessionBindingSeat {
|
|
61
|
+
/** 写一笔(唯一调用者 = {@link commitLegBindings}),交回回执。 */
|
|
62
|
+
commitSessionBindings(sessionId: string, bindings: SessionBindings): SessionBindingReceipt;
|
|
63
|
+
/** 撤回一笔:这一笔还没落定 ⇒ 抽掉它、三格重新物化(别的提交的写原样)、答 `true`;否则(已落定 / 已撤 / 清过)一笔不动、答 `false`。 */
|
|
64
|
+
withdrawSessionBindings(receipt: SessionBindingReceipt): boolean;
|
|
65
|
+
/** 落定一笔(这次提交被受理 / 交给了它自己的耐久 run):此后不可撤。已撤 / 清过 ⇒ 答 `false`。 */
|
|
66
|
+
settleSessionBindings(receipt: SessionBindingReceipt): boolean;
|
|
67
|
+
}
|
|
68
|
+
/** 提交点读的那一面:写座(缺席 = 夹具 / 嵌入方没接登记簿 ⇒ no-op)。 */
|
|
69
|
+
export interface LegBindingsCommitCtx {
|
|
70
|
+
readonly sessionBindings?: SessionBindingSeat | undefined;
|
|
71
|
+
}
|
|
72
|
+
/** 提交出口收回执的那一面(`submission-exit.ts` 的 `SubmissionSeat.noteBindings`):收场 `refused` ⇒ 撤回,`accepted` / `record` ⇒ 落定。 */
|
|
73
|
+
export interface BindingReceiptSink {
|
|
74
|
+
noteBindings(receipt: SessionBindingReceipt, face: Pick<SessionBindingSeat, "withdrawSessionBindings" | "settleSessionBindings">): void;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* **唯一提交点**:在 run 认领(与执行放置、续跑输入、起跑前复核)之后、起跑之前调一次 —— 把这条腿的绑定写进它的根会话,回执交给这次提交的出口座
|
|
78
|
+
* (同步 / 流式两条提交腿:收场定撤还是落定);`exit` 缺席(续跑驱动腿没有座;后台建行腿认领即 record,之后不再有拒)⇒ 写即落定。
|
|
79
|
+
* `bindings` 缺席(装配器没铸事实)⇒ 按「什么都没要」写。
|
|
80
|
+
*/
|
|
81
|
+
export declare function commitLegBindings(ctx: LegBindingsCommitCtx, exit: BindingReceiptSink | undefined, sessionId: string, bindings: SessionBindings | undefined): void;
|
|
82
|
+
//# sourceMappingURL=session-bindings.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function bindingsOf(cwd, shellEnv, inheritEnv) {
|
|
2
|
+
return {
|
|
3
|
+
...(cwd !== undefined ? { cwd } : {}),
|
|
4
|
+
...(shellEnv !== undefined ? { shellEnv } : {}),
|
|
5
|
+
...(inheritEnv !== undefined ? { inheritEnv } : {}),
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export function commitLegBindings(ctx, exit, sessionId, bindings) {
|
|
9
|
+
const seat = ctx.sessionBindings;
|
|
10
|
+
if (seat === undefined)
|
|
11
|
+
return;
|
|
12
|
+
const receipt = seat.commitSessionBindings(sessionId, bindings ?? {});
|
|
13
|
+
if (exit !== undefined)
|
|
14
|
+
exit.noteBindings(receipt, seat);
|
|
15
|
+
else
|
|
16
|
+
seat.settleSessionBindings(receipt);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=session-bindings.js.map
|
|
@@ -89,8 +89,8 @@ export type RetireSessionChildrenOutcome = {
|
|
|
89
89
|
};
|
|
90
90
|
/**
|
|
91
91
|
* 一只会话的**引擎租户分区** —— **唯一一处取**:以它为根的后台子代、它的后台 shell、它的会话信箱盒,都登记在这一分区(删除门、换绑 / 导入两门、结清口、
|
|
92
|
-
* 删除协调器的信箱腿与 shell 收割腿、删后收尾的丢箱同读;属主串本身不是 scope)
|
|
93
|
-
* (`engine-identity.ts` 的 `
|
|
92
|
+
* 删除协调器的信箱腿与 shell 收割腿、删后收尾的丢箱同读;属主串本身不是 scope)。引擎按任务规格的身份格登记,所以这里读的是**引擎身份那一格**
|
|
93
|
+
* (`engine-identity.ts` 的 `engineScopeOfOwner`,唯一换算):没带场景的会话 = 属主(逐字节同改前);带场景的会话(属主 `_scn:<场景>:<人>`)=
|
|
94
94
|
* 引擎登记时用的那一个值(今天是人)—— 按属主串去枚举 / 退役 / 收割会打到一个空分区。无主 ⇒ `"default"`。
|
|
95
95
|
*/
|
|
96
96
|
export declare function sessionTenantScope(owner: string | null): string;
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { recoveredSubject } from "./owner-faces.js";
|
|
3
|
-
import { taskSpecIdentityOf } from "./engine-identity.js";
|
|
1
|
+
import { engineScopeOfOwner } from "./engine-identity.js";
|
|
4
2
|
import { expireCardUnderStoredScope } from "./card-settle-stored-scope.js";
|
|
5
3
|
export const RETIRE_MAX_ROUNDS = 6;
|
|
6
4
|
const RETIRE_BACKOFF_MS = [0, 25, 50, 100, 200, 400];
|
|
7
5
|
export function sessionTenantScope(owner) {
|
|
8
|
-
|
|
9
|
-
return "default";
|
|
10
|
-
return taskSpecIdentityOf(partsOf(recoveredSubject(owner))).principal ?? "default";
|
|
6
|
+
return engineScopeOfOwner(owner);
|
|
11
7
|
}
|
|
12
8
|
async function liveChildren(deps, rootSessionId, scope) {
|
|
13
9
|
const out = new Map();
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* 持有者已死的在删行,重发的 DELETE 同样是接管。
|
|
21
21
|
* 持久面:SQL = 旁表 `session_ext.deleting_token`(列属主 `plugins/session-ext-table.ts`);local = 会话元数据边档那一格的 `deleting`。
|
|
22
22
|
*/
|
|
23
|
+
import type { SessionKind } from "./session-kind.js";
|
|
23
24
|
/** 围栏的回执:这一次删除的令牌 + 被删的那一位住客的化身(空间回收的键;存量行没有化身 ⇒ `undefined`)。 */
|
|
24
25
|
export interface SessionDeletionTicket {
|
|
25
26
|
readonly token: string;
|
|
@@ -36,10 +37,24 @@ export interface PendingSessionDeletion {
|
|
|
36
37
|
* (某腿失败 / 被接管)—— 死的;`elsewhere` = 不是本进程铸的(上一个进程 / 别的副本)。
|
|
37
38
|
*/
|
|
38
39
|
export type DeletionHolder = "running" | "ended" | "elsewhere";
|
|
39
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* 老化的条件(会话种类的律在 `session-kind.ts`;唯一调用者 = 维护拍的老化腿 `boot/session-age-out.ts`):候选读只挑人,**判官是围栏根行锁里的这一判** ——
|
|
42
|
+
* 对一只**活**行,锁住根行之后、写令牌之前再判:住客仍是候选读到的那一位(`incarnation`:候选读之后同 id 被删并重登记的新住客不被碰)∧ 种类仍是 `kind`
|
|
43
|
+
* ∧ 最后活动仍早于 `idleBefore`(候选读之后一次 run / 追加 / 收场把它推前 ⇒ 不删)∧ 当下没有活引用(在跑的 run 的认领 —— 围栏本来就判 —— / 待决的检查点 /
|
|
44
|
+
* 在跑或停驻的后台子代以它为会话 · 父 · 根 / 它发起的在跑 workflow;SQL 两孪生与托管留存同读一只谓词)∧ 所在域不在保全中(SQL:托管留存的保全行锁)。
|
|
45
|
+
* 任一不成立 ⇒ 回滚、`undefined`,一个字节不写。在删行(一次失败的删除撂下的)照常按持有者判接管 —— 它已经在删,不回到活。
|
|
46
|
+
* 条件与收尾者的 `expect` 同位:一只围栏、一个可选条件,不是第二条删除路;`DELETE /v1/sessions/:id` 不带它。
|
|
47
|
+
*/
|
|
48
|
+
export interface SessionAgeOutExpectation {
|
|
49
|
+
readonly incarnation: string | undefined;
|
|
50
|
+
readonly kind: SessionKind;
|
|
51
|
+
readonly idleBefore: Date;
|
|
52
|
+
}
|
|
53
|
+
/** 围栏的选项:`holder` = 令牌持有者在哪(协调器的在飞表);`expect` = 只接管这一只令牌(收尾者;活行 / 别的令牌 ⇒ `undefined`);`ageOut` = 老化的锁内条件({@link SessionAgeOutExpectation})。 */
|
|
40
54
|
export interface SessionDeletionFenceOptions {
|
|
41
55
|
readonly holder: (token: string) => DeletionHolder;
|
|
42
56
|
readonly expect?: string;
|
|
57
|
+
readonly ageOut?: SessionAgeOutExpectation;
|
|
43
58
|
}
|
|
44
59
|
/** 围栏的答复:回执(本次立了 / 接管了)· `inProgress`(一次仍可能活着的删除持有这一行 —— 不接管)· `undefined`(行不在 / 属主不是这一位 / 收尾者的令牌对不上)。 */
|
|
45
60
|
export type SessionDeletionFenceAnswer = SessionDeletionTicket | {
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
* (请求 core 把种类放进错误,而不是在这里解析句子)。
|
|
43
43
|
* · `invalid_entry` / `invalid_fork_target` —— 留白:本仓今天没有一条 wire 口把它们作为自己的
|
|
44
44
|
* 应答(它们在 core 的追加 / 分叉面上抛,落进各站点既有的处置或通用 500)。给它们起名是另一件事、另一张票。
|
|
45
|
-
* · `conflict` —— `import` 面 **409 `conflict`**(固定句 {@link
|
|
46
|
-
*
|
|
45
|
+
* · `conflict` —— `import` 面 **409 `conflict`**(固定句 {@link STAGED_IMPORT_OCCUPANT_CHANGED_SENTENCE});`open` 面留白。按码映射时 import 面上这个词只有一个来源:
|
|
46
|
+
* 暂存提交的住客 CAS(`session-sync-kernel.ts` 的 `StagedCommitOccupantChangedError`,三家店在提交事务里比「此刻的行 = 这次导入的门判过的那一位住客」(属主 ∧ 化身),
|
|
47
47
|
* 不等 ⇒ 回滚)—— 码位与同族的提交期同步冲突(`SyncConflictError` ⇒ 409 `conflict`「sync conflict」)同一个,出路也相同:从第一阶段重来(重新过门)。
|
|
48
48
|
* 本服务自铸的同码具名拒 {@link StampedSessionArchiveError}(local 店:存档仍带更早版本写下的属主戳)不按码映射 —— 出路不同(重来照样撞),它有**自己的 wire 码**:
|
|
49
49
|
* 由 {@link sessionErrorWireOf} 按**型**先认:两面同答 409 `conflict.session_archive_stamped` + 固定句 {@link STAMPED_SESSION_ARCHIVE_SENTENCE}(与上一句的属主变更拒同状态、不同码:
|
|
@@ -90,7 +90,7 @@ export declare const PLACED_SESSION_SENTENCE = "this session holds a delegated a
|
|
|
90
90
|
* import 面 `conflict` 的固定句:暂存提交时会话的属主格已不是开暂存时门判过的那一格(另一副本在导入流式进行期间删建 / 认领 / 新建了它),提交事务回滚。
|
|
91
91
|
* 不发店的原句(它点名会话 id);固定句只说发生了什么与出路(冻结在 `test/api-error-text-freeze.test.ts` 的常量锚格)。
|
|
92
92
|
*/
|
|
93
|
-
export declare const
|
|
93
|
+
export declare const STAGED_IMPORT_OCCUPANT_CHANGED_SENTENCE = "session changed hands while the import streamed (deleted, re-created or re-owned); nothing was imported \u2014 start the sync again";
|
|
94
94
|
/**
|
|
95
95
|
* local 店的具名拒(唯一铸点 `plugins/local-session-store.ts` 的 `assertArchiveAnonymous`):这只会话的引擎存档仍带更早版本写下的属主戳(一次性迁移 M33 改写不了它,或数据根跳过了带这次迁移的版本)
|
|
96
96
|
* ⇒ 不在它上面造新存档(fork),也不原地换它的日志(改日志的推送,含第一阶段对 fork / stale 的早拒);零写。`SessionError.code` 是 core 闭集的 `conflict`;句子(给运维日志,点名会话 id)归本错,
|
|
@@ -2,7 +2,7 @@ import { SessionError } from "@sema-agent/core";
|
|
|
2
2
|
export const STAGED_IMPORT_INVALID_SENTENCE = "staged session log failed validation";
|
|
3
3
|
export const PLACED_SESSION_SENTENCE = "this session holds a delegated agent's transcript, so session sync cannot overwrite it; sync into a different session id";
|
|
4
4
|
const PLACEMENT_KIND = "subagent";
|
|
5
|
-
export const
|
|
5
|
+
export const STAGED_IMPORT_OCCUPANT_CHANGED_SENTENCE = "session changed hands while the import streamed (deleted, re-created or re-owned); nothing was imported — start the sync again";
|
|
6
6
|
export class StampedSessionArchiveError extends SessionError {
|
|
7
7
|
sessionId;
|
|
8
8
|
constructor(sessionId) {
|
|
@@ -23,7 +23,7 @@ export const STAMPED_SESSION_ARCHIVE_SENTENCE = "this session's stored archive s
|
|
|
23
23
|
const CORRUPT_SESSION = { status: 500, errorCode: "corrupt_session" };
|
|
24
24
|
const INVALID_ENTRIES = { status: 422, errorCode: "invalid_entries", sentence: STAGED_IMPORT_INVALID_SENTENCE };
|
|
25
25
|
const SESSION_PLACED = { status: 409, errorCode: "conflict.session_placed", sentence: PLACED_SESSION_SENTENCE, facts: { placement_kind: PLACEMENT_KIND } };
|
|
26
|
-
const
|
|
26
|
+
const STAGED_IMPORT_OCCUPANT_CHANGED = { status: 409, errorCode: "conflict", sentence: STAGED_IMPORT_OCCUPANT_CHANGED_SENTENCE };
|
|
27
27
|
const STAMPED_SESSION_ARCHIVE = { status: 409, errorCode: "conflict.session_archive_stamped", sentence: STAMPED_SESSION_ARCHIVE_SENTENCE };
|
|
28
28
|
export function sessionErrorWireOf(e, face) {
|
|
29
29
|
return e instanceof StampedSessionArchiveError ? STAMPED_SESSION_ARCHIVE : sessionErrorHttp(e.code, face);
|
|
@@ -44,7 +44,7 @@ export function sessionErrorHttp(code, face) {
|
|
|
44
44
|
case "placement_refused":
|
|
45
45
|
return face === "import" ? SESSION_PLACED : undefined;
|
|
46
46
|
case "conflict":
|
|
47
|
-
return face === "import" ?
|
|
47
|
+
return face === "import" ? STAGED_IMPORT_OCCUPANT_CHANGED : undefined;
|
|
48
48
|
case "not_found":
|
|
49
49
|
case "invalid_entry":
|
|
50
50
|
case "invalid_fork_target":
|
|
@@ -73,6 +73,8 @@ export declare function incarnationLogPrefix(incarnation: string): string;
|
|
|
73
73
|
* 把其中每一只化身形的串截成 {@link incarnationLogPrefix}(前 8 位 + `…`)。规则只有一条:完整令牌不进日志正文;前 8 位留着对账。
|
|
74
74
|
*/
|
|
75
75
|
export declare function redactIncarnations(text: string): string;
|
|
76
|
+
/** {@link SessionIncarnationMissingError} 的码(读到空化身的那一拒;k8s 车道按它把住客读拒分成立定的一形)。 */
|
|
77
|
+
export declare const SESSION_INCARNATION_MISSING = "session.incarnation_missing";
|
|
76
78
|
/**
|
|
77
79
|
* 会话行在、化身却是空的 —— 响亮拒(头注「读到空化身」一条)。具名类型:调用方按类型认它,不按文案。
|
|
78
80
|
* 文案不带任何令牌(本来就是空的),只点名会话 id 与出路。
|
|
@@ -100,6 +102,14 @@ export declare function incarnationFromCell(sessionId: string, cell: unknown, em
|
|
|
100
102
|
/** 一行原始列 → {@link SessionFace}(属主 + 一只令牌)的唯一口:化身那一格经 {@link incarnationFromCell} 的 `refuse` 读法(空 ⇒ 响亮拒)。
|
|
101
103
|
* 按 id 的读者经 {@link sessionFaceOfHead};批量来源读(一次性迁移 M23 窗内的回填扫描)与 staged 换装的回读直接从行列经它。 */
|
|
102
104
|
export declare function sessionFaceFromRow(sessionId: string, owner: string | null, incarnation: unknown): SessionFace;
|
|
105
|
+
/**
|
|
106
|
+
* 门承认的那一位住客在门后读的半途不再占着这只 id(删了、或删后同 id 被重建 —— 包括同一属主)。会话同步的拉取流在每页交出之前复判住客,不是那一位 ⇒ 抛它,
|
|
107
|
+
* 流在那里结束、不写尾行(客户端读作截断,重拉)—— 从不交出别一代住客的条目。不上 wire(流头已发,状态码改不了),只落一行运维 info。
|
|
108
|
+
*/
|
|
109
|
+
export declare class SessionOccupantChangedError extends Error {
|
|
110
|
+
readonly sessionId: string;
|
|
111
|
+
constructor(sessionId: string);
|
|
112
|
+
}
|
|
103
113
|
/**
|
|
104
114
|
* 头的叶子那一格读不出 —— 会话**内容**读不出时的那只故障(local 店:会话存档读不出,例如存档首行的会话头坏了;行上的属主与住客照样读得出)。
|
|
105
115
|
* {@link headFromRow} 收它:头照答属主与住客,叶子那一格带着这只故障,读 `leafId` 的那一位收到它本身(同一只错误对象,码与句子原样 ——
|
|
@@ -12,9 +12,10 @@ const INCARNATION_TOKEN_SHAPE = /[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9
|
|
|
12
12
|
export function redactIncarnations(text) {
|
|
13
13
|
return text.replace(INCARNATION_TOKEN_SHAPE, (token) => `${incarnationLogPrefix(token)}…`);
|
|
14
14
|
}
|
|
15
|
+
export const SESSION_INCARNATION_MISSING = "session.incarnation_missing";
|
|
15
16
|
export class SessionIncarnationMissingError extends Error {
|
|
16
17
|
sessionId;
|
|
17
|
-
code =
|
|
18
|
+
code = SESSION_INCARNATION_MISSING;
|
|
18
19
|
constructor(sessionId) {
|
|
19
20
|
super(`session ${sessionId} has no incarnation token: every session row is minted one when it is created. An empty value means a write path ` +
|
|
20
21
|
`that did not mint one, a hand-edited row, or a database upgraded from before 7.104.0 straight to a version after 7.135.x (a boot of any ` +
|
|
@@ -41,6 +42,14 @@ export function incarnationFromCell(sessionId, cell, empty = "refuse") {
|
|
|
41
42
|
export function sessionFaceFromRow(sessionId, owner, incarnation) {
|
|
42
43
|
return { owner, incarnation: incarnationFromCell(sessionId, incarnation) };
|
|
43
44
|
}
|
|
45
|
+
export class SessionOccupantChangedError extends Error {
|
|
46
|
+
sessionId;
|
|
47
|
+
constructor(sessionId) {
|
|
48
|
+
super(`session ${sessionId}: the occupant the gate admitted no longer holds this id — the stream ends here`);
|
|
49
|
+
this.sessionId = sessionId;
|
|
50
|
+
this.name = "SessionOccupantChangedError";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
44
53
|
export class UnreadableLeaf {
|
|
45
54
|
fault;
|
|
46
55
|
constructor(fault) {
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **会话种类 `sessionKind`** —— 一只会话是不是用户的顶层对话,是它出生那一笔写下的一个事实(规则只写在这里一次;三只会话店、授权口、列表口、能力面与老化腿同读)。
|
|
3
|
+
*
|
|
4
|
+
* ## 律
|
|
5
|
+
* · 闭集 {@link SESSION_KINDS};**缺席 = 顶层对话**(存量行、老壳建的行、fork / 同步导入 / run-local / 定时与 A2A 起的会话恒缺席 —— 缺席不存缺省词,顶层只有一种拼法)。
|
|
6
|
+
* · **只有建这只会话的那一次提交写它**(提交体 `sessionKind`,授权口登记新行的那一笔:SQL = 建行事务里的建行钩、local = 建行那一笔格写),此后终身不改 ——
|
|
7
|
+
* 没有改写它的写口;整段换装就地改写同一行(种类随行),删后同 id 重登记是新住客(无种类)。
|
|
8
|
+
* · 它只决定两件事:**会话枚举的缺省视图列不列它**(列表与 peer 目录读同一只 lister 的同一只视图 {@link sessionKindListed};缺省视图 = 无种类,
|
|
9
|
+
* `?sessionKind=<词>` = 只列那一种)与**它按哪只视界老化**(有种类 ⇒ 最后活动之后 `BG_AGENT_RETENTION_MS`、无活引用时由维护拍删)。
|
|
10
|
+
* · 按 id 的每一口读写、属主判、执行放置、同步 / fork / 删除对它与对任何会话是同一句话:种类不是资格、不是面、不是访问谓词。
|
|
11
|
+
*
|
|
12
|
+
* ## 与委派分区不是一件事
|
|
13
|
+
* core 的委派分区(`session_meta.placement_*`,placed 行)是引擎写的、不是列表面的行、不能当执行根;种类是客户端经提交写的、是列表面的行(缺省视图不列)、可以当执行根。
|
|
14
|
+
* 两个事实答两个问题,一个推不出另一个;「列不列」这一问的读者只有一只(lister 的视图谓词)。
|
|
15
|
+
*/
|
|
16
|
+
/** 会话种类的闭集(**顺序 = 拒句里的列举顺序**;加一个词 = 判它在缺省视图里列不列、按哪只视界老化,并逐处过编译)。 */
|
|
17
|
+
export declare const SESSION_KINDS: readonly ["sidechain"];
|
|
18
|
+
/** 一只会话的种类(缺席 = 顶层对话)。 */
|
|
19
|
+
export type SessionKind = (typeof SESSION_KINDS)[number];
|
|
20
|
+
/** 值是不是闭集里的一个词(判的是 wire 值 / 行上那一格的形;表外 ⇒ 不是)。 */
|
|
21
|
+
export declare function isSessionKind(v: unknown): v is SessionKind;
|
|
22
|
+
/**
|
|
23
|
+
* 🔴 **视图谓词的唯一判法**(local 店的 lister 与老化候选面同调;SQL 两孪生的同一句是 `plugins/session-store-sql.ts` 的 `sessionKindSql`):
|
|
24
|
+
* 一行进一只视图 ⇔ 行上的种类**等于**视图的种类(两边缺席相等 —— 缺省视图只列无种类的行)。
|
|
25
|
+
*/
|
|
26
|
+
export declare function sessionKindListed(rowKind: SessionKind | undefined, view: SessionKind | undefined): boolean;
|
|
27
|
+
/** 按 id 读种类的答案:读到它时行上的住客(化身那一格,按 `absent` 读)与种类(缺席 = 顶层)。`undefined`(整只)= 没有这只会话。 */
|
|
28
|
+
export interface SessionKindReading {
|
|
29
|
+
readonly incarnation: string | undefined;
|
|
30
|
+
readonly kind: SessionKind | undefined;
|
|
31
|
+
}
|
|
32
|
+
/** 会话店的按 id 种类读(三只持久店都交;包装层原样转发)。 */
|
|
33
|
+
export interface SessionKindFace {
|
|
34
|
+
sessionKindOf(sessionId: string): Promise<SessionKindReading | undefined>;
|
|
35
|
+
}
|
|
36
|
+
/** 店上的种类读(没有 ⇒ `undefined`:这台部署记不了种类 —— 能力位 `sessionKinds` 为空、带键提交 400)。 */
|
|
37
|
+
export declare function sessionKindFaceOf(store: unknown): SessionKindFace | undefined;
|
|
38
|
+
/** 行上那一格 → 种类(SQL 列 / local 格的唯一解码):闭集里的词 ⇒ 它;NULL / 缺 ⇒ 缺席;别的值 ⇒ 响亮抛(手改库 / 将来的词落到旧构建上 —— 不猜成顶层)。 */
|
|
39
|
+
export declare function sessionKindFromCell(sessionId: string, cell: unknown): SessionKind | undefined;
|
|
40
|
+
/** 老化候选面的一行(候选读只挑人,判官是删除围栏根行锁里的那一判 —— `session-deletion.ts` 的 `SessionAgeOutExpectation`)。 */
|
|
41
|
+
export interface IdleSession {
|
|
42
|
+
readonly sessionId: string;
|
|
43
|
+
/** 行上的属主(删除协调器按它走)。 */
|
|
44
|
+
readonly owner: string | null;
|
|
45
|
+
/** 读到它时行上的住客(围栏比它:候选读之后同 id 被删并重登记的新住客不被碰)。 */
|
|
46
|
+
readonly incarnation: string | undefined;
|
|
47
|
+
/** 最后活动(ISO;SQL `updated_at`,local 新近标记 —— 与列表行的 `lastActivityAt` 同一读法)。 */
|
|
48
|
+
readonly lastActivityAt: string;
|
|
49
|
+
}
|
|
50
|
+
/** 老化候选面的续页键(`(lastActivityAt, sessionId)` 升序:最老先出)。 */
|
|
51
|
+
export interface IdleSessionCursor {
|
|
52
|
+
readonly lastActivityAt: string;
|
|
53
|
+
readonly sessionId: string;
|
|
54
|
+
}
|
|
55
|
+
/** 老化候选面的序:最老先出(`(lastActivityAt, sessionId)` 升序 —— SQL 两孪生的 `ORDER BY` 与 local 店的排序同读这一判)。 */
|
|
56
|
+
export declare function idleSessionAfter(row: IdleSessionCursor, cursor: IdleSessionCursor | undefined): boolean;
|
|
57
|
+
//# sourceMappingURL=session-kind.d.ts.map
|