@sema-agent/server 7.145.0 → 7.147.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 +876 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +374 -99
- package/deploy/facts/CHANGES.json +25 -0
- package/deploy/facts/README.md +57 -0
- package/deploy/facts/lanes.json +61 -0
- package/deploy/facts/lanes.schema.json +57 -0
- package/deploy/facts/sandbox-rbac.json +113 -0
- package/deploy/facts/sandbox-rbac.schema.json +74 -0
- package/deploy/facts/sealed-key.json +9 -0
- package/deploy/facts/sealed-key.schema.json +52 -0
- package/deploy/sema-up/README.md +2 -2
- package/deploy/sema-up/chart/templates/_helpers.tpl +41 -0
- package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +47 -7
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +9 -4
- package/deploy/sema-up/chart/templates/server.yaml +9 -4
- package/deploy/sema-up/chart/values.yaml +8 -1
- package/deploy/sema-up/cluster-up.sh +2 -1
- package/deploy/sema-up/lib/flagshape.sh +4 -0
- package/deploy/sema-up/lib/lanes.json +2 -5
- package/deploy/sema-up/sema-up.sh +12 -9
- package/deploy/sema-up/stack/compose.yaml +5 -4
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +34 -17
- package/dist/adoption/import-limits.d.ts +6 -0
- package/dist/adoption/import-limits.js +7 -0
- package/dist/adoption/import.d.ts +62 -0
- package/dist/adoption/import.js +107 -0
- package/dist/adoption/wire.d.ts +52 -0
- package/dist/adoption/wire.js +9 -0
- package/dist/approval-ask-machine.d.ts +2 -2
- package/dist/approval-card.d.ts +7 -16
- package/dist/approval-card.js +0 -4
- package/dist/approval-gate-currency.d.ts +1 -1
- package/dist/approval-gate-currency.js +1 -1
- package/dist/approval-reconciler.d.ts +1 -1
- package/dist/approval.d.ts +3 -3
- package/dist/audit.js +2 -2
- package/dist/bench/s1/live-deps.js +3 -1
- package/dist/boot/crash-last.js +2 -1
- package/dist/boot/deployment-mods.d.ts +11 -1
- package/dist/boot/deployment-mods.js +15 -2
- package/dist/boot/device-lane.js +7 -5
- package/dist/boot/engine-lease.d.ts +195 -22
- package/dist/boot/engine-lease.js +146 -20
- package/dist/boot/execution-env.d.ts +5 -0
- package/dist/boot/execution-env.js +57 -33
- package/dist/boot/execution-lane.d.ts +37 -9
- package/dist/boot/execution-lane.js +74 -20
- package/dist/boot/exit-boundary.d.ts +50 -0
- package/dist/boot/exit-boundary.js +32 -0
- package/dist/boot/exit-last.d.ts +20 -4
- package/dist/boot/exit-last.js +23 -5
- package/dist/boot/governance-seams.d.ts +2 -2
- package/dist/boot/governance-seams.js +1 -0
- package/dist/boot/leader.js +1 -1
- package/dist/boot/memory-boundary.d.ts +11 -11
- package/dist/boot/memory-boundary.js +3 -3
- package/dist/boot/memory-consolidation.d.ts +42 -41
- package/dist/boot/memory-consolidation.js +26 -28
- package/dist/boot/org-memory.js +3 -2
- package/dist/boot/parked-revive-gate.d.ts +1 -1
- package/dist/boot/parked-revive-gate.js +1 -1
- package/dist/boot/reapers.d.ts +12 -4
- package/dist/boot/reapers.js +40 -16
- package/dist/boot/resolve-spec.d.ts +2 -0
- package/dist/boot/resolve-spec.js +126 -123
- package/dist/boot/retention-lane.d.ts +4 -42
- package/dist/boot/runner-deps.js +1 -1
- package/dist/boot/session-faces.d.ts +1 -0
- package/dist/boot/session-faces.js +11 -3
- package/dist/boot/shutdown.js +27 -9
- package/dist/boot/stage-01-config.d.ts +1 -1
- package/dist/boot/stage-01-config.js +7 -3
- package/dist/boot/stage-02-web-admin-pull.d.ts +1 -1
- package/dist/boot/stage-02-web-admin-pull.js +10 -8
- package/dist/boot/stage-03-store-backend.d.ts +2 -1
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +2 -1
- package/dist/boot/stage-05-execution-env.d.ts +4 -1
- package/dist/boot/stage-05-execution-env.js +6 -6
- package/dist/boot/stage-06-runners.d.ts +5 -2
- package/dist/boot/stage-06-runners.js +12 -13
- package/dist/boot/stage-07-capability-layer.d.ts +5 -2
- package/dist/boot/stage-07-capability-layer.js +7 -7
- package/dist/boot/stage-08-reapers.d.ts +5 -2
- package/dist/boot/stage-08-reapers.js +3 -3
- package/dist/boot/stage-09-leader.d.ts +6 -2
- package/dist/boot/stage-10-http-server.d.ts +6 -2
- package/dist/boot/stage-10-http-server.js +5 -3
- package/dist/boot/stores.d.ts +10 -0
- package/dist/boot/stores.js +53 -26
- package/dist/boot/web-admin.js +3 -3
- package/dist/boot/workflow-orchestration.d.ts +1 -1
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/capabilities/center-plugins.d.ts +2 -0
- package/dist/capabilities/center-plugins.js +6 -2
- package/dist/capabilities/composite-members.d.ts +4 -1
- package/dist/capabilities/composite-members.js +4 -1
- package/dist/capabilities/execution-lane.d.ts +7 -7
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +1 -1
- package/dist/capabilities/scenarios.d.ts +34 -20
- package/dist/capabilities/scenarios.js +13 -9
- package/dist/capabilities/settings-contract.d.ts +29 -0
- package/dist/capabilities/settings-contract.js +14 -0
- package/dist/capabilities/skills.d.ts +5 -5
- package/dist/capability-facts.d.ts +56 -1
- package/dist/capability-facts.js +59 -8
- package/dist/center-credential-renewer.js +3 -2
- package/dist/checkpoint-ctx-seal-m28.d.ts +1 -1
- package/dist/config-catalog.js +19 -9
- package/dist/config-invariants.d.ts +18 -3
- package/dist/config-invariants.js +36 -19
- package/dist/config-lkg.d.ts +1 -1
- package/dist/config-lkg.js +5 -6
- package/dist/config-provider.d.ts +2 -2
- package/dist/config-provider.js +2 -0
- package/dist/config-types.d.ts +228 -185
- package/dist/config.d.ts +74 -6
- package/dist/config.js +146 -64
- package/dist/degenerate-instrument.js +1 -1
- package/dist/deleted-session-ids.d.ts +19 -0
- package/dist/deleted-session-ids.js +26 -0
- package/dist/deploy-facts.d.ts +155 -0
- package/dist/deploy-facts.js +95 -0
- package/dist/deployment-shape.d.ts +21 -12
- package/dist/deployment-shape.js +24 -6
- package/dist/device-ws-hub.d.ts +48 -3
- package/dist/device-ws-hub.js +48 -2
- package/dist/env-facts.d.ts +7 -5
- package/dist/env-facts.js +10 -6
- package/dist/error-code-family.d.ts +35 -0
- package/dist/error-code-family.js +26 -0
- package/dist/execution-config-root.d.ts +5 -5
- package/dist/execution-config-root.js +5 -5
- package/dist/execution-env-purpose.d.ts +14 -0
- package/dist/execution-env-purpose.js +29 -0
- package/dist/execution-lane-caps.d.ts +49 -86
- package/dist/execution-lane-caps.js +52 -62
- package/dist/execution-placement.d.ts +18 -2
- package/dist/execution-placement.js +19 -0
- package/dist/file-history-disclosure.d.ts +2 -2
- package/dist/fleet/drain-entry.d.ts +46 -3
- package/dist/fleet/drain-entry.js +6 -0
- package/dist/fleet/fleet-bus.d.ts +2 -1
- package/dist/fleet/serving-lease.js +3 -4
- package/dist/history-anchor.d.ts +22 -0
- package/dist/history-anchor.js +14 -0
- package/dist/hooks/branch-transcript.d.ts +1 -1
- package/dist/hooks/branch-transcript.js +1 -0
- package/dist/hooks/classic-stations.d.ts +25 -8
- package/dist/hooks/classic-stations.js +29 -3
- package/dist/hooks/command-spawn.d.ts +1 -4
- package/dist/hooks/command-spawn.js +0 -11
- package/dist/hooks/hook-runner.d.ts +85 -24
- package/dist/hooks/hook-runner.js +326 -109
- package/dist/hooks/hook-source.d.ts +14 -2
- package/dist/hooks/hook-source.js +8 -0
- package/dist/http/active-run-conflict.d.ts +1 -1
- package/dist/http/active-run-conflict.js +1 -1
- package/dist/http/admission.js +11 -1
- package/dist/http/approval-sweeps.d.ts +2 -5
- package/dist/http/approval-sweeps.js +3 -2
- package/dist/http/checkpoint-ctx.d.ts +76 -71
- package/dist/http/checkpoint-ctx.js +40 -40
- package/dist/http/claim-latency.d.ts +10 -0
- package/dist/http/claim-latency.js +12 -0
- package/dist/http/dispatch.js +19 -3
- package/dist/http/durable-run-leg.d.ts +5 -0
- package/dist/http/durable-run-leg.js +3 -1
- package/dist/http/execution-context.d.ts +7 -1
- package/dist/http/execution-context.js +13 -0
- package/dist/http/health-self-report.d.ts +6 -2
- package/dist/http/health-self-report.js +3 -2
- package/dist/http/memory-compliance-failure-reply.d.ts +2 -2
- package/dist/http/memory-compliance-failure-reply.js +5 -15
- package/dist/http/memory-control-plane-corrupt-reply.d.ts +25 -0
- package/dist/http/memory-control-plane-corrupt-reply.js +19 -0
- package/dist/http/memory-store-refusal-reply.d.ts +3 -3
- package/dist/http/memory-store-refusal-reply.js +3 -0
- package/dist/http/owner-access.d.ts +11 -0
- package/dist/http/owner-access.js +7 -4
- package/dist/http/principal-gate.d.ts +28 -16
- package/dist/http/principal-gate.js +10 -19
- package/dist/http/request-guards.d.ts +2 -2
- package/dist/http/request-guards.js +5 -5
- package/dist/http/resume-legs.d.ts +29 -10
- package/dist/http/resume-legs.js +94 -56
- package/dist/http/rewind-files-reply.d.ts +34 -0
- package/dist/http/rewind-files-reply.js +36 -0
- package/dist/http/route-ctx.d.ts +43 -26
- package/dist/http/route-table.js +4 -0
- package/dist/http/routes/adoption.d.ts +11 -0
- package/dist/http/routes/adoption.js +80 -6
- package/dist/http/routes/agents-roster.js +1 -0
- package/dist/http/routes/approvals-assistant.js +7 -26
- package/dist/http/routes/background.js +1 -0
- package/dist/http/routes/capabilities.js +12 -3
- package/dist/http/routes/devices.js +1 -1
- package/dist/http/routes/diagnostics.d.ts +9 -14
- package/dist/http/routes/diagnostics.js +10 -20
- package/dist/http/routes/engine.d.ts +31 -0
- package/dist/http/routes/engine.js +81 -0
- package/dist/http/routes/memory-bundle.js +3 -0
- package/dist/http/routes/memory-consolidation.js +3 -5
- package/dist/http/routes/memory-origin.d.ts +2 -2
- package/dist/http/routes/memory-origin.js +2 -4
- package/dist/http/routes/memory-policy.js +5 -1
- package/dist/http/routes/notify-wake.js +2 -1
- package/dist/http/routes/observability.js +3 -6
- package/dist/http/routes/projects.d.ts +70 -0
- package/dist/http/routes/projects.js +86 -0
- package/dist/http/routes/rules.js +30 -2
- package/dist/http/routes/runs.js +15 -11
- package/dist/http/routes/session-sync.js +39 -35
- package/dist/http/routes/sessions-list.d.ts +1 -1
- package/dist/http/routes/sessions.d.ts +7 -1
- package/dist/http/routes/sessions.js +108 -2
- package/dist/http/routes/tasks.js +32 -8
- package/dist/http/routes/trace-usage.js +1 -1
- package/dist/http/run-concurrency-cap.d.ts +86 -0
- package/dist/http/run-concurrency-cap.js +54 -0
- package/dist/http/server.d.ts +31 -14
- package/dist/http/server.js +29 -3
- package/dist/http/stored-body-replay.d.ts +12 -7
- package/dist/http/stored-body-replay.js +28 -5
- package/dist/http/wire-types.d.ts +27 -13
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/instruction-source-notice.d.ts +1 -1
- package/dist/json-body-limit.d.ts +8 -0
- package/dist/json-body-limit.js +2 -0
- package/dist/leader/diffout.d.ts +1 -1
- package/dist/local-data-root.d.ts +2 -2
- package/dist/memory-embedder-reembed.d.ts +38 -0
- package/dist/memory-embedder-reembed.js +20 -0
- package/dist/memory-incident-sink.d.ts +0 -28
- package/dist/memory-incident-sink.js +5 -0
- package/dist/memory-operator-faces.d.ts +9 -4
- package/dist/memory-scope-stores.d.ts +9 -7
- package/dist/memory-scope-stores.js +3 -14
- package/dist/memory-scope.d.ts +38 -2
- package/dist/memory-scope.js +33 -2
- package/dist/memory-store-refusal.d.ts +17 -4
- package/dist/memory-store-refusal.js +1 -1
- package/dist/memory-sync-client.d.ts +2 -0
- package/dist/memory-sync-client.js +13 -11
- package/dist/memory-sync.js +1 -1
- package/dist/model-compat.d.ts +35 -21
- package/dist/model-compat.js +49 -21
- package/dist/model-entry-refusal.d.ts +11 -1
- package/dist/model-entry-refusal.js +7 -0
- package/dist/namespaced-rule-name.d.ts +18 -1
- package/dist/namespaced-rule-name.js +12 -0
- package/dist/net-address.d.ts +53 -0
- package/dist/net-address.js +111 -0
- package/dist/observability/fail-open.d.ts +29 -17
- package/dist/observability/fail-open.js +29 -17
- package/dist/observability/metrics.d.ts +2 -0
- package/dist/observability/metrics.js +2 -0
- package/dist/observability/secret-env-scrub.d.ts +30 -4
- package/dist/observability/secret-env-scrub.js +15 -3
- package/dist/orchestration/workflow-agent-session-index.d.ts +7 -12
- package/dist/orchestration/workflow-agent-session-index.js +1 -6
- package/dist/orchestration/workflow-completion-inbox.d.ts +26 -6
- package/dist/orchestration/workflow-completion-inbox.js +63 -45
- package/dist/orchestration/workflow-notify-journal.js +2 -3
- package/dist/org-delivery-gate.js +1 -1
- package/dist/org-memory-admission.d.ts +5 -2
- package/dist/org-memory-admission.js +25 -10
- package/dist/parked-decide.d.ts +33 -26
- package/dist/parked-decide.js +36 -44
- package/dist/peer-directory.d.ts +6 -12
- package/dist/peer-directory.js +5 -1
- package/dist/plugins/approval-ask-store-file.d.ts +10 -2
- package/dist/plugins/approval-ask-store-file.js +37 -4
- package/dist/plugins/approval-ask-store-memory.d.ts +5 -3
- package/dist/plugins/approval-ask-store-memory.js +11 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +3 -0
- package/dist/plugins/approval-ask-store-sql.js +3 -1
- package/dist/plugins/blob-backend.d.ts +38 -195
- package/dist/plugins/blob-backend.js +33 -229
- package/dist/plugins/caching-session-store.d.ts +12 -5
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-index-columns.d.ts +1 -1
- package/dist/plugins/checkpoint-index-columns.js +3 -2
- package/dist/plugins/checkpoint-store-face.d.ts +426 -0
- package/dist/plugins/checkpoint-store-face.js +152 -0
- package/dist/plugins/device-store-sql.d.ts +2 -2
- package/dist/plugins/device-store-sql.js +5 -10
- package/dist/plugins/execution-lane-rename-m40.d.ts +20 -0
- package/dist/plugins/execution-lane-rename-m40.js +10 -0
- package/dist/plugins/execution-placement-sql.d.ts +63 -88
- package/dist/plugins/execution-placement-sql.js +94 -54
- package/dist/plugins/file-run-store.d.ts +26 -18
- package/dist/plugins/file-run-store.js +64 -75
- package/dist/plugins/fork-routing-session-store.d.ts +6 -2
- package/dist/plugins/fork-routing-session-store.js +2 -2
- package/dist/plugins/imported-layer-root-retirement.d.ts +22 -11
- package/dist/plugins/imported-layer-root-retirement.js +4 -8
- package/dist/plugins/inbox-payload-column.d.ts +14 -0
- package/dist/plugins/inbox-payload-column.js +13 -0
- package/dist/plugins/local-checkpoint-store.d.ts +7 -2
- package/dist/plugins/local-checkpoint-store.js +13 -8
- package/dist/plugins/local-data-dir-modes-m39.d.ts +48 -0
- package/dist/plugins/local-data-dir-modes-m39.js +182 -0
- package/dist/plugins/local-engine-high-water.d.ts +11 -0
- package/dist/plugins/local-engine-high-water.js +59 -0
- package/dist/plugins/local-session-store.d.ts +119 -30
- package/dist/plugins/local-session-store.js +156 -53
- package/dist/plugins/local-task-attachment-store.d.ts +2 -0
- package/dist/plugins/local-task-attachment-store.js +10 -11
- package/dist/plugins/memory-embedder-fingerprint.d.ts +33 -10
- package/dist/plugins/memory-embedder-fingerprint.js +52 -12
- package/dist/plugins/memory-embedder.d.ts +1 -1
- package/dist/plugins/memory-embedder.js +2 -2
- package/dist/plugins/memory-engine-pg.d.ts +30 -6
- package/dist/plugins/memory-engine-pg.js +96 -214
- package/dist/plugins/memory-engine-sql-apply.d.ts +130 -0
- package/dist/plugins/memory-engine-sql-apply.js +358 -0
- package/dist/plugins/memory-engine-tidb.d.ts +38 -9
- package/dist/plugins/memory-engine-tidb.js +99 -230
- package/dist/plugins/memory-key-guards.d.ts +1 -1
- package/dist/plugins/memory-origin-law.d.ts +3 -3
- package/dist/plugins/one-time-migrations.d.ts +169 -83
- package/dist/plugins/one-time-migrations.js +295 -235
- package/dist/plugins/owner-only-file-mode.d.ts +29 -0
- package/dist/plugins/owner-only-file-mode.js +141 -0
- package/dist/plugins/permission-rule-store-file.d.ts +17 -3
- package/dist/plugins/permission-rule-store-file.js +20 -1
- package/dist/plugins/pg-pool.d.ts +2 -1
- package/dist/plugins/pg-pool.js +12 -5
- package/dist/plugins/release-version.d.ts +20 -0
- package/dist/plugins/release-version.js +28 -0
- package/dist/plugins/remote-env-adb.d.ts +20 -4
- package/dist/plugins/remote-env-adb.js +39 -11
- package/dist/plugins/remote-env-e2b.d.ts +12 -3
- package/dist/plugins/remote-env-e2b.js +6 -4
- package/dist/plugins/remote-env-host.d.ts +9 -1
- package/dist/plugins/remote-env-host.js +6 -5
- package/dist/plugins/remote-env-k8s.d.ts +5 -2
- package/dist/plugins/remote-env-k8s.js +15 -4
- package/dist/plugins/remote-env-local-docker.d.ts +4 -1
- package/dist/plugins/remote-env-local-docker.js +3 -3
- package/dist/plugins/remote-env-ssh.d.ts +8 -2
- package/dist/plugins/remote-env-ssh.js +26 -24
- package/dist/plugins/remote-shell.d.ts +59 -30
- package/dist/plugins/remote-shell.js +175 -62
- package/dist/plugins/retention-declaration.d.ts +37 -0
- package/dist/plugins/retention-declaration.js +9 -0
- package/dist/plugins/retention-deployment.d.ts +126 -0
- package/dist/plugins/retention-deployment.js +88 -0
- package/dist/plugins/retention-lane-store-sql.d.ts +74 -4
- package/dist/plugins/retention-lane-store-sql.js +103 -1
- package/dist/plugins/retention-sql.d.ts +29 -0
- package/dist/plugins/retention-sql.js +8 -0
- package/dist/plugins/run-store-sql.js +2 -2
- package/dist/plugins/schema-consistency.d.ts +0 -6
- package/dist/plugins/schema-consistency.js +1 -2
- package/dist/plugins/schema-ensure-legs.d.ts +1 -1
- package/dist/plugins/schema-ensure-legs.js +13 -3
- package/dist/plugins/session-ext-table.d.ts +74 -0
- package/dist/plugins/session-ext-table.js +121 -0
- package/dist/plugins/session-fork.d.ts +31 -9
- package/dist/plugins/session-fork.js +3 -2
- package/dist/plugins/session-placement.d.ts +4 -2
- package/dist/plugins/session-row-sql.d.ts +8 -7
- package/dist/plugins/session-row-sql.js +15 -7
- package/dist/plugins/session-store-sql.d.ts +131 -0
- package/dist/plugins/session-store-sql.js +298 -0
- package/dist/plugins/session-workspace-cell.d.ts +2 -2
- package/dist/plugins/session-workspace-cell.js +2 -2
- package/dist/plugins/shared-memory-store-sql.d.ts +10 -0
- package/dist/plugins/shared-memory-store-sql.js +13 -13
- package/dist/plugins/snapshot-bucket-presence.js +1 -1
- package/dist/plugins/sql-driver.d.ts +23 -7
- package/dist/plugins/sql-driver.js +41 -8
- package/dist/plugins/sql-errors.d.ts +5 -2
- package/dist/plugins/sql-errors.js +4 -0
- package/dist/plugins/sql-json-column.d.ts +5 -1
- package/dist/plugins/store-backend.d.ts +46 -16
- package/dist/plugins/store-backend.js +192 -69
- package/dist/plugins/store-contracts.d.ts +10 -13
- package/dist/plugins/store-contracts.js +1 -9
- package/dist/plugins/store-sweep.d.ts +63 -0
- package/dist/plugins/store-sweep.js +48 -0
- package/dist/plugins/task-attachment-store.d.ts +6 -8
- package/dist/plugins/task-attachment-store.js +15 -10
- package/dist/plugins/task-list-store-sql.d.ts +1 -1
- package/dist/plugins/text-column-capacity.d.ts +21 -0
- package/dist/plugins/text-column-capacity.js +5 -0
- package/dist/plugins/tidb-pool.d.ts +3 -2
- package/dist/plugins/tidb-pool.js +20 -32
- package/dist/plugins/user-input-ledger-sql.d.ts +1 -1
- package/dist/prompt-screen.d.ts +6 -9
- package/dist/prompt-screen.js +2 -5
- package/dist/read-face-posture.d.ts +6 -6
- package/dist/read-face-posture.js +2 -2
- package/dist/request-value-closure.d.ts +5 -5
- package/dist/request-value-closure.js +1 -1
- package/dist/rules-consent.d.ts +48 -27
- package/dist/rules-consent.js +147 -23
- package/dist/run-cancel-context.d.ts +4 -1
- package/dist/run-cancel-context.js +2 -1
- package/dist/run-local.js +17 -13
- package/dist/runs.d.ts +48 -30
- package/dist/runs.js +27 -17
- package/dist/runtime-caps-resolver.d.ts +15 -8
- package/dist/runtime-caps-resolver.js +14 -10
- package/dist/sandbox-egress-policy.js +6 -11
- package/dist/sandbox-rbac-rules.d.ts +88 -0
- package/dist/sandbox-rbac-rules.js +80 -0
- package/dist/sealed-key-layout.d.ts +16 -0
- package/dist/sealed-key-layout.js +3 -0
- package/dist/sealed-key.js +8 -6
- package/dist/security.d.ts +43 -9
- package/dist/security.js +9 -2
- package/dist/sema-config-dir.js +2 -2
- package/dist/server-secret-env.d.ts +2 -0
- package/dist/service-version.d.ts +2 -1
- package/dist/service-version.js +2 -2
- package/dist/session-error-wire.d.ts +1 -1
- package/dist/session-incarnation.d.ts +8 -5
- package/dist/session-notify-door.d.ts +5 -3
- package/dist/session-resident-background.d.ts +110 -0
- package/dist/session-resident-background.js +88 -0
- package/dist/session-row.d.ts +1 -1
- package/dist/session-sync-kernel.d.ts +53 -14
- package/dist/session-sync-kernel.js +70 -1
- package/dist/session-sync.d.ts +5 -3
- package/dist/session-workspace.d.ts +12 -2
- package/dist/session-workspace.js +6 -0
- package/dist/sighup-idle.d.ts +9 -7
- package/dist/sighup-idle.js +4 -5
- package/dist/spec-fields.d.ts +16 -0
- package/dist/spec-fields.js +7 -0
- package/dist/store-posture.d.ts +2 -1
- package/dist/stored-request-env-credentials-m38.d.ts +3 -0
- package/dist/stored-request-env-credentials-m38.js +8 -0
- package/dist/stored-request-hooks-m20.d.ts +3 -2
- package/dist/stored-request-hooks-m20.js +19 -14
- package/dist/stored-request-prompt-profile-m30.d.ts +1 -1
- package/dist/stores-sql/blob-index-sql.d.ts +148 -0
- package/dist/stores-sql/blob-index-sql.js +154 -0
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.d.ts +14 -428
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.js +43 -220
- package/dist/{plugins → stores-sql}/file-history-store-sql.d.ts +23 -11
- package/dist/{plugins → stores-sql}/file-history-store-sql.js +23 -18
- package/dist/{plugins → stores-sql}/mailbox-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/mailbox-store-sql.js +4 -4
- package/dist/{plugins → stores-sql}/pg-session-storage.d.ts +27 -67
- package/dist/{plugins → stores-sql}/pg-session-storage.js +82 -207
- package/dist/{plugins → stores-sql}/retention-store-sql.d.ts +123 -217
- package/dist/{plugins → stores-sql}/retention-store-sql.js +66 -190
- package/dist/{plugins → stores-sql}/roster-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/roster-store-sql.js +1 -1
- package/dist/{plugins → stores-sql}/session-event-payload.d.ts +1 -1
- package/dist/{plugins → stores-sql}/session-event-payload.js +1 -1
- package/dist/stores-sql/session-policy-store-sql.d.ts +1 -1
- package/dist/stores-sql/session-write-hooks.d.ts +59 -0
- package/dist/stores-sql/session-write-hooks.js +2 -0
- package/dist/{plugins → stores-sql}/tidb-session-storage.d.ts +10 -11
- package/dist/{plugins → stores-sql}/tidb-session-storage.js +10 -21
- package/dist/{plugins → stores-sql}/tidb-session-store.d.ts +35 -112
- package/dist/{plugins → stores-sql}/tidb-session-store.js +73 -169
- package/dist/{plugins → stores-sql}/tool-result-store-sql.d.ts +3 -3
- package/dist/{plugins → stores-sql}/tool-result-store-sql.js +6 -6
- package/dist/stores-sql/windowed-session-storage.d.ts +56 -0
- package/dist/stores-sql/windowed-session-storage.js +61 -0
- package/dist/{plugins → stores-sql}/workflow-journal-store-sql.d.ts +7 -12
- package/dist/{plugins → stores-sql}/workflow-journal-store-sql.js +3 -8
- package/dist/task-a2a.d.ts +7 -1
- package/dist/task-a2a.js +15 -14
- package/dist/task-cwd.d.ts +11 -3
- package/dist/task-cwd.js +17 -1
- package/dist/task-mcp.d.ts +10 -2
- package/dist/task-mcp.js +13 -16
- package/dist/task-settings.d.ts +68 -8
- package/dist/task-settings.js +63 -6
- package/dist/tool-approval.d.ts +23 -10
- package/dist/tool-approval.js +10 -6
- package/dist/trace/core-keyset-guard.d.ts +17 -10
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +4 -0
- package/dist/trace/exit-seat.d.ts +29 -1
- package/dist/trace/exit-seat.js +4 -0
- package/dist/trace/project.d.ts +33 -16
- package/dist/trace/project.js +21 -9
- package/dist/trace/redact.d.ts +13 -2
- package/dist/trace/redact.js +347 -78
- package/dist/trace/self-minted-wire.d.ts +587 -16
- package/dist/trace/self-minted-wire.js +215 -9
- package/dist/trace/sema-provenance.d.ts +45 -41
- package/dist/trace/sema-provenance.js +81 -10
- package/dist/trace/task-notification-facets.d.ts +70 -2
- package/dist/trace/task-notification-facets.js +71 -1
- package/dist/trace/wire-projection-faces.d.ts +39 -3
- package/dist/trace/wire-projection-faces.js +27 -2
- package/dist/unread-request-members.d.ts +66 -0
- package/dist/unread-request-members.js +41 -0
- package/dist/usage-analytics.d.ts +4 -0
- package/dist/user-input-ledger.d.ts +2 -2
- package/dist/web-admin-client/apply-effective.js +22 -26
- package/dist/web-admin-client/candidate-gate.d.ts +35 -3
- package/dist/web-admin-client/candidate-gate.js +53 -5
- package/dist/web-admin-client/center-request.d.ts +4 -1
- package/dist/web-admin-client/center-request.js +2 -1
- package/dist/web-admin-client/effective-keys.js +0 -1
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/http-client.d.ts +1 -0
- package/dist/web-admin-client/http-client.js +17 -9
- package/dist/web-admin-client/restart-signal.js +5 -2
- package/dist/web-admin-client/skills-mcp.d.ts +20 -6
- package/dist/web-admin-client/skills-mcp.js +26 -21
- package/dist/web-admin-client/types.d.ts +34 -49
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +2 -2
- package/package.json +22 -13
- package/scripts/drain-check-local.mjs +8 -55
- package/scripts/drain-check.mysql.sql +3 -40
- package/scripts/drain-check.pg.sql +3 -40
- package/skills/update-config.md +1 -1
- package/wire-changes/server@7.146.0.json +3221 -0
- package/wire-changes/server@7.147.0.json +813 -0
- package/dist/approval-batch-census.d.ts +0 -27
- package/dist/approval-batch-census.js +0 -27
package/dist/http/dispatch.js
CHANGED
|
@@ -11,6 +11,7 @@ import { ENGINE_SIGNAL_KEY, buildEngineSignal, fleetMembershipKeys, healthConfig
|
|
|
11
11
|
import { buildHealthSelfReport } from "./health-self-report.js";
|
|
12
12
|
import { deploymentModPackages as deploymentModPackagesFact } from "../capability-facts.js";
|
|
13
13
|
import { actsForDeployment, admitRunIdentity, authorized, systemFor, gatedPrincipal, sendPrincipalRefusal, sendUnauthorized, traceTokenPresented, verifiedIdentitySource, hasServiceAuth, devOpenDeployment } from "./principal-gate.js";
|
|
14
|
+
import { inflightTotal } from "../fleet/drain-entry.js";
|
|
14
15
|
const PROCESS_STARTED_AT_MS = Date.now() - Math.round(process.uptime() * 1000);
|
|
15
16
|
export function readCredentialOk(req, config) {
|
|
16
17
|
if (!hasServiceAuth(config))
|
|
@@ -130,17 +131,32 @@ export function createDispatch(ctx) {
|
|
|
130
131
|
const engineSignal = buildEngineSignal(signal);
|
|
131
132
|
const declaredMods = deploymentModPackagesFact(deps);
|
|
132
133
|
const configHash = createHash("sha256")
|
|
133
|
-
.update(JSON.stringify({ model: deps.config.model.id, sessionBackend: deps.config.sessionBackend, dbBackend: deps.config.dbBackend, dataRoot: deps.config.localDataRoot, configProvider: deps.config.configProvider, remoteExec: deps.config.remoteExec
|
|
134
|
+
.update(JSON.stringify({ model: deps.config.model.id, sessionBackend: deps.config.sessionBackend, dbBackend: deps.config.dbBackend, dataRoot: deps.config.localDataRoot, configProvider: deps.config.configProvider, remoteExec: deps.config.remoteExec.provider, port: deps.config.port }))
|
|
134
135
|
.digest("hex")
|
|
135
136
|
.slice(0, 16);
|
|
136
137
|
sendJson(res, 200, {
|
|
137
138
|
status: "ok",
|
|
138
139
|
...(typeof deps.capabilities?.version === "string" ? { version: deps.capabilities.version } : {}),
|
|
139
140
|
...healthDrainingKeys(signal),
|
|
140
|
-
...(
|
|
141
|
+
...(() => {
|
|
142
|
+
const breakdown = deps.drainState?.inflightBreakdown?.();
|
|
143
|
+
return breakdown ? { inflight: inflightTotal(breakdown), inflightBreakdown: breakdown } : {};
|
|
144
|
+
})(),
|
|
141
145
|
...(() => {
|
|
142
146
|
const lease = deps.drainState?.engineLease?.();
|
|
143
|
-
|
|
147
|
+
if (!lease)
|
|
148
|
+
return {};
|
|
149
|
+
const fa = lease.firstAttach;
|
|
150
|
+
const ho = lease.handover;
|
|
151
|
+
return {
|
|
152
|
+
engineLease: {
|
|
153
|
+
lingerMs: lease.lingerMs,
|
|
154
|
+
tickMs: lease.tickMs,
|
|
155
|
+
lane: lease.lane,
|
|
156
|
+
...(fa ? { firstAttach: { windowMs: fa.windowMs, since: fa.since, attachedAt: fa.attachedAt } } : {}),
|
|
157
|
+
...(ho ? { handover: { since: ho.since, reason: ho.reason, lingerMs: ho.lingerMs, backgroundShells: ho.backgroundShells } } : {}),
|
|
158
|
+
},
|
|
159
|
+
};
|
|
144
160
|
})(),
|
|
145
161
|
...(deps.storePosture?.degradedReason !== undefined ? { durable: false, storeDegraded: true } : {}),
|
|
146
162
|
...healthReadinessKeys(signal.verdict),
|
|
@@ -2,6 +2,7 @@ import type { RunStore } from "../plugins/store-backend.js";
|
|
|
2
2
|
import type { RunIdemBinding, RunRecord } from "../plugins/store-contracts.js";
|
|
3
3
|
import type { PreparedTaskSubmission, RouteCtxBase, WorkflowDecisionDelivery } from "./route-ctx.js";
|
|
4
4
|
import type { RunIdentity } from "../identity-source.js";
|
|
5
|
+
import type { RunSlot } from "./run-concurrency-cap.js";
|
|
5
6
|
export interface DurableRunLegArgs {
|
|
6
7
|
/** `prepareSpec` 的产物,或内部车道按同一条 `resolveSpec` 装配出来的等价形。 */
|
|
7
8
|
prepared: PreparedTaskSubmission;
|
|
@@ -27,6 +28,10 @@ export interface DurableRunLegArgs {
|
|
|
27
28
|
/** `/decide` 第三条车道的 fresh 投递腿交来的那一件决定投递(带着的决定 + 起跑之前落行的那一笔;语义与 TRUSTED 纪律的属主 =
|
|
28
29
|
* `route-ctx.ts` 的 {@link WorkflowDecisionDelivery} 顶注)。缺席 ⇒ 只摊本会话已受理的决定行。 */
|
|
29
30
|
workflowDecision?: WorkflowDecisionDelivery;
|
|
31
|
+
/** 提交门占着的**并发帽席位**(`http/run-concurrency-cap.ts`):本腿在 `runInBackground` 把这条 run 登记进 `inflightRuns` 的那一拍(它在返回前同步登记)就地放掉 ——
|
|
32
|
+
* 与 `POST /v1/tasks` 两口同形,在飞集里的这一条不再叠一枚席位。落点拒 / 续跑输入拒 / 409 / 抛 等没走到登记的出口不放,由提交门的 `finally` 兜底(`release` 幂等)。
|
|
33
|
+
* 缺席 = 没有帽可放(`/decide` 第三条车道〔延续,不判帽〕、帽关着的部署)。 */
|
|
34
|
+
runSlot?: RunSlot;
|
|
30
35
|
}
|
|
31
36
|
/**
|
|
32
37
|
* 本腿的结局:一份收据,或「这次提交的一把幂等钥匙已经指向一条行」(店的原子赢或观察的**观察**臂 —— 本腿不碰
|
|
@@ -8,6 +8,7 @@ import { declaredApprovalFrameFamilies, resolveStreamApprovalGate } from "../too
|
|
|
8
8
|
import { buildActiveRunConflict } from "./active-run-conflict.js";
|
|
9
9
|
import { commitExecutionContext } from "./execution-context.js";
|
|
10
10
|
import { rootSessionAbsentAnswer } from "./execution-context.js";
|
|
11
|
+
import { timeClaim } from "./claim-latency.js";
|
|
11
12
|
import { commitSessionInheritEnv } from "./session-inherit-env.js";
|
|
12
13
|
import { clearTurnActivity, readTurnActivityMs } from "../turn-activity.js";
|
|
13
14
|
import { recordResourceWindow } from "../resource-window.js";
|
|
@@ -21,7 +22,7 @@ export async function mintAndDriveDurableRun(ctx, runStore, args) {
|
|
|
21
22
|
const sessionId = args.prepared.spec.sessionId;
|
|
22
23
|
const taskId = args.clientTaskId ?? uuidv7();
|
|
23
24
|
const trustedInternals = await heldWorkflowParkDecisions(deps, sessionId, args.workflowDecision?.carried);
|
|
24
|
-
const created = await runStore.createRun(taskId, sessionId, args.prepared.auth?.principal ?? null, deps.instanceId ?? "default", { ...runMeta(args.prepared, args.source), identity: args.identity, idem: args.idem ?? null });
|
|
25
|
+
const created = await timeClaim(deps.metrics, "run_claim", runStore.createRun(taskId, sessionId, args.prepared.auth?.principal ?? null, deps.instanceId ?? "default", { ...runMeta(args.prepared, args.source), identity: args.identity, idem: args.idem ?? null }));
|
|
25
26
|
if (created.ok)
|
|
26
27
|
clearTurnActivity(taskId);
|
|
27
28
|
if (created.ok)
|
|
@@ -99,6 +100,7 @@ export async function mintAndDriveDurableRun(ctx, runStore, args) {
|
|
|
99
100
|
executionLane: args.prepared.execution.lane,
|
|
100
101
|
}
|
|
101
102
|
: undefined, deps.checkpointStore, args.prepared.engineNotices, trustedInternals, deps.userInputLedger, args.prepared.acceptance, createSessionWorkspaceRecorder(sessionWorkspaceStoreOf(deps.sessionStorage), args.prepared.legFacts?.sessionWitness), args.prepared.legFacts?.skills));
|
|
103
|
+
args.runSlot?.release();
|
|
102
104
|
return { status: 202, body: { taskId, sessionId, status: "running", ...(args.prepared.warnings !== undefined ? { warnings: args.prepared.warnings } : {}) } };
|
|
103
105
|
}
|
|
104
106
|
//# sourceMappingURL=durable-run-leg.js.map
|
|
@@ -12,12 +12,15 @@
|
|
|
12
12
|
* 在场而与行头不是同一位住客(化身 ∧ 属主,写口同一只判官 `sameOccupant`)⇒ 同 404(他人在门与解析之间删掉并同 id 重登记,或同一化身的属主变了 ——
|
|
13
13
|
* local M10 认领 / identical 重戳 / SQL 导入提交点改属主 —— 判到新住客的车道就是错的);local 格是 `forking`
|
|
14
14
|
* ⇒ 409 `conflict.fork_in_progress`;读故障抛(不吞成 absent)。解析器不建行、不铸根。
|
|
15
|
+
* 随后(同一步,就在那一读之后):这只根会话 id 在本进程被删过、而那一读的住客不是删前的属主 ⇒ 409 `conflict.session_id_retired`
|
|
16
|
+
* (表与规则 `deleted-session-ids.ts`,这里是它唯一的读点;店不带执行席 ⇒ fresh 判门判过的那一读,continuation 判不出 ⇒ 表里有就拒)。
|
|
15
17
|
* ② 定车道:`mirror` ⇒ 409 `conflict.session_mirror`(体带 `forkPath`);`writer(L)` 而 L 不在本部署的车道表 ⇒ 409 `execution_lane.not_served{boundLane}`;absent ⇒ 表首。
|
|
16
18
|
* ③ 授权:主体的执行车道裁定(`gateExecutionLane`,判据与码同 `runtime-caps-resolver.ts`);服务形不判。
|
|
17
19
|
* ④ 只 fresh:设备准入链(体 `deviceId` 只在 device 车道收;准入链三步 + 首绑目标三读,全读;判的是步 ① 那一读)。
|
|
18
20
|
*
|
|
19
21
|
* 入口三形(判别联合,{@link ExecutionEntry}):`fresh`(提交腿:根 = authorizer 交出的 `auth.sessionId`,`judged` = authorizer 判过的头)·
|
|
20
|
-
* `continuation`(续跑家族与停驻赎回:根 = checkpoint / 停驻行的根;不带 `judged` —— 步 ①
|
|
22
|
+
* `continuation`(续跑家族与停驻赎回:根 = checkpoint / 停驻行的根;不带 `judged` —— 步 ① 那一读就是这条执行对根的唯一一读,认领之后由写口按它判;
|
|
23
|
+
* run 外回退口 `POST /v1/sessions/:id/rewind-files` 同形:根 = 路径上的会话,它不认领、不提交放置,只取步 ①–③ 的拒)·
|
|
21
24
|
* `service`(服务 run:没有会话根)。
|
|
22
25
|
* `fresh` / `continuation` 两形型上恒带 `root: string`,`service` 形没有 `root` 键 —— 「按一只缺席的根去读行」在型上不可表达。
|
|
23
26
|
*
|
|
@@ -108,6 +111,8 @@ export declare function resolveExecutionContext(deps: ExecutionContextDeps, entr
|
|
|
108
111
|
readonly root: string;
|
|
109
112
|
}>): Promise<RootedExecutionContext>;
|
|
110
113
|
export declare function resolveExecutionContext(deps: ExecutionContextDeps, entry: ExecutionEntry): Promise<ExecutionContext>;
|
|
114
|
+
/** 步 ① 之后那一判的拒句(409 `conflict.session_id_retired`;不回显 id / 属主)。续跑家族把它包进 `resume_blocked_by_policy` 的句子里答。 */
|
|
115
|
+
export declare const SESSION_ID_RETIRED_MESSAGE = "this session id was deleted on this server while a different owner held it, so this server will not run it for you \u2014 start the session under a new id";
|
|
111
116
|
/** 拒体里「继续在本处执行」的下一步路径(fork 口)—— 镜像拒体的 `forkPath` 唯一铸法(执行面与会话行写口 `PATCH /v1/sessions/:id` 同读)。 */
|
|
112
117
|
export declare function forkPathOf(root: string): string;
|
|
113
118
|
/** 解析器的拒是不是「会话不在」(停驻赎回腿把它答成自己既有的 `decide.not_parked`;判据只在这里认那只答复的码)。 */
|
|
@@ -198,6 +203,7 @@ export interface ExecutionCommitDeps {
|
|
|
198
203
|
} | undefined;
|
|
199
204
|
readonly metrics?: {
|
|
200
205
|
inc(name: string, labels?: Record<string, string>): void;
|
|
206
|
+
observe?(name: string, value: number, labels?: Record<string, string>): void;
|
|
201
207
|
} | undefined;
|
|
202
208
|
}
|
|
203
209
|
/**
|
|
@@ -6,7 +6,9 @@ import { sameOccupant } from "../execution-placement.js";
|
|
|
6
6
|
import { deployedExecutionLanes } from "../execution-lane-caps.js";
|
|
7
7
|
import { gateExecutionLane } from "../runtime-caps-resolver.js";
|
|
8
8
|
import { releaseClaimedRun } from "./claimed-run.js";
|
|
9
|
+
import { sessionIdRetiredFor } from "../deleted-session-ids.js";
|
|
9
10
|
import { refusalBody } from "./refusal-body.js";
|
|
11
|
+
import { timeClaim } from "./claim-latency.js";
|
|
10
12
|
export async function resolveExecutionContext(deps, entry) {
|
|
11
13
|
const lanes = deployedExecutionLanes(deps.config);
|
|
12
14
|
switch (entry.kind) {
|
|
@@ -16,6 +18,8 @@ export async function resolveExecutionContext(deps, entry) {
|
|
|
16
18
|
case "continuation": {
|
|
17
19
|
const seat = deps.sessionStorage?.executionPlacement;
|
|
18
20
|
const reading = seat === undefined ? undefined : await readRow(seat, entry.root, entry.kind === "fresh" ? entry.judged : undefined);
|
|
21
|
+
if (sessionIdRetiredFor(entry.root, servedOwnerOf(entry, reading), deps.config))
|
|
22
|
+
throw createCodedHttpError(409, "conflict.session_id_retired", SESSION_ID_RETIRED_MESSAGE);
|
|
19
23
|
const { lane, placement } = laneOf(entry.root, reading?.cell ?? { role: "absent" }, lanes);
|
|
20
24
|
gateExecutionLane(await deps.executionRuling?.(entry.principal), lane, deps.logger);
|
|
21
25
|
const ctx = { kind: entry.kind, root: entry.root, occupant: reading?.occupant, placement, lane };
|
|
@@ -30,6 +34,12 @@ export async function resolveExecutionContext(deps, entry) {
|
|
|
30
34
|
}
|
|
31
35
|
}
|
|
32
36
|
}
|
|
37
|
+
export const SESSION_ID_RETIRED_MESSAGE = "this session id was deleted on this server while a different owner held it, so this server will not run it for you — start the session under a new id";
|
|
38
|
+
function servedOwnerOf(entry, reading) {
|
|
39
|
+
if (reading !== undefined)
|
|
40
|
+
return reading.occupant.owner;
|
|
41
|
+
return entry.kind === "fresh" ? entry.judged?.owner : undefined;
|
|
42
|
+
}
|
|
33
43
|
async function readRow(seat, root, judged) {
|
|
34
44
|
const reading = await seat.read(root);
|
|
35
45
|
if (reading === undefined || (judged !== undefined && !sameOccupant(judged, reading.occupant)))
|
|
@@ -194,6 +204,9 @@ export async function commitExecutionContext(deps, claim, ctx) {
|
|
|
194
204
|
if (ctx.occupant === undefined || seat === undefined)
|
|
195
205
|
return null;
|
|
196
206
|
const occupant = ctx.occupant;
|
|
207
|
+
return timeClaim(deps.metrics, "placement_commit", commitPlacement(deps, claim, ctx, seat, occupant));
|
|
208
|
+
}
|
|
209
|
+
async function commitPlacement(deps, claim, ctx, seat, occupant) {
|
|
197
210
|
const release = (why) => releaseClaim(deps, claim, why);
|
|
198
211
|
const deadlineMs = placementWriteDeadlineMs(deps.config?.runStaleSec);
|
|
199
212
|
const withDeadline = async (work) => {
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
* `service_token` 臂读的正是它),所以 `required` 与 `kinds` 是同一次求值的两个投影,不是两个来源;
|
|
13
13
|
* · `auth.identityAttach` = kinds 里有没有**带调用方身份**的一类({@link carriesCallerIdentity},穷举):`service_token` 认的是系统
|
|
14
14
|
* (`systemFor` 回系统名或 null),不是人;
|
|
15
|
+
* · `auth.serviceTokenActsForDeployment` = 出示 service 凭据、不报主体的调用方在这台部署上代不代部署本人 —— `required`(同一次 kinds 求值的 `service_token` 词)
|
|
16
|
+
* ∧ 门读那一格声明的同一只读法 `serviceTokenDeclaredActsForDeployment`(`actsForDeployment` 的合取项,`principal-gate.ts`)。没配 service 凭据 ⇒ `false`(那一臂够不着);
|
|
17
|
+
* 缺省部署 ⇒ 与 `required` 同值。运维聚合口的 401 operator 句指的就是这一位;
|
|
15
18
|
* · `operator` = 能力事实 `operatorLane`(operator 面族的 501 门读的同一只;名单本身不上 wire);
|
|
16
19
|
* · `center.issuer` = 鉴权桥 issuer 的唯一取值 `authBridgeIssuerOf`(装配 `boot/stage-09-leader.ts` 与 caps `centerWiring.issuer` 同读);
|
|
17
20
|
* · `center.webBaseUrl` = 运维旋钮 `SEMA_WEB_ADMIN_WEB_URL`(`config.webAdmin.webBaseUrl`,接了中心才挂;起服时已判成固定基址);
|
|
@@ -49,6 +52,7 @@ export interface HealthSelfReport {
|
|
|
49
52
|
readonly required: boolean;
|
|
50
53
|
readonly kinds: readonly IdentitySource[];
|
|
51
54
|
readonly identityAttach: IdentityAttach;
|
|
55
|
+
readonly serviceTokenActsForDeployment: boolean;
|
|
52
56
|
};
|
|
53
57
|
readonly operator: OperatorPresence;
|
|
54
58
|
readonly center: {
|
|
@@ -58,8 +62,8 @@ export interface HealthSelfReport {
|
|
|
58
62
|
};
|
|
59
63
|
}
|
|
60
64
|
/**
|
|
61
|
-
* 三键的**唯一铸点**(`build*`:纯数据)。只读装配本身:`auth`
|
|
62
|
-
*
|
|
65
|
+
* 三键的**唯一铸点**(`build*`:纯数据)。只读装配本身:`auth` 四位都从一次 `wiredIdentitySources` 求值投出(`required` = 其中有 `service_token`;
|
|
66
|
+
* `serviceTokenActsForDeployment` = `required` ∧ 门读的那一格声明),不收调用方递进来的第二份布尔 —— 一个事实一次求值。
|
|
63
67
|
*/
|
|
64
68
|
export declare function buildHealthSelfReport(deps: Pick<FlatServiceDeps, "config" | "webAdminJwtVerifier" | "sessionStorage" | "runStore">): HealthSelfReport;
|
|
65
69
|
//# sourceMappingURL=health-self-report.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { wiredIdentitySources } from "./principal-gate.js";
|
|
1
|
+
import { serviceTokenDeclaredActsForDeployment, wiredIdentitySources } from "./principal-gate.js";
|
|
2
2
|
import { operatorLane, sessionList } from "../capability-facts.js";
|
|
3
3
|
import { authBridgeIssuerOf } from "../auth-bridge.js";
|
|
4
4
|
import { centerLaneConfigured } from "../web-admin-client/center-request.js";
|
|
@@ -26,8 +26,9 @@ export function buildHealthSelfReport(deps) {
|
|
|
26
26
|
const issuer = authBridgeIssuerOf(config)?.issuer;
|
|
27
27
|
const webBaseUrl = config.webAdmin?.webBaseUrl;
|
|
28
28
|
const sessionsVisible = centerLaneConfigured(config) && config.fleetAdvertiseAddress !== undefined && bridgeWired && sessionList(deps).available ? (config.requirePrincipal ? true : "unknown") : false;
|
|
29
|
+
const required = kinds.includes("service_token");
|
|
29
30
|
return {
|
|
30
|
-
auth: { required
|
|
31
|
+
auth: { required, kinds, identityAttach: kinds.some(carriesCallerIdentity) ? "available" : "unavailable", serviceTokenActsForDeployment: required && serviceTokenDeclaredActsForDeployment(config) },
|
|
31
32
|
operator: operatorLane(deps).available ? "present" : "absent",
|
|
32
33
|
center: {
|
|
33
34
|
...(issuer !== undefined ? { issuer: buildDisplaySafeUrl(issuer) } : {}),
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
*
|
|
11
11
|
* ## 规则(三层,与 operator 面既有层序逐字同序)
|
|
12
12
|
* ① core 的**本口专属**码(闭集穷举 `switch`,见 {@link sentCoreCode})—— 码与状态两面同;文案按受众(下一节,一条规则);
|
|
13
|
-
* ②
|
|
13
|
+
* ② **店形拒**一族(按族表读;成员举例 `memory.target_outside_store` / `memory.scope_home_not_directory` / 引擎 7.65.0 起 `memory.control_plane_links_unsupported`)—— 跨面 store 状态码,409、码原样
|
|
14
14
|
* (判据 `memory-store-refusal.ts` 一只;运维行 `memory_store_form_refused { code, path?, form? }` 两受众同一只铸点,路径只在那里);
|
|
15
|
-
* ③ `ControlPlaneCorruptError` —— typed 500 `internal.memory_control_plane_corrupt`(fail-closed
|
|
15
|
+
* ③ `ControlPlaneCorruptError` —— typed 500 `internal.memory_control_plane_corrupt`(fail-closed 信号,一码两义;映射本体在 `memory-control-plane-corrupt-reply.ts` 那一只,导出导入 / 外源 / 整理 / 合规各口同调);
|
|
16
16
|
* 其余 ⇒ `false`(未分类,调用方发它自己那句 500 且**不回显**内部文本)。
|
|
17
17
|
*
|
|
18
18
|
* ## 文案按受众分(码与状态不分)—— **一条规则,三层同施,不按码挑**(F9,7.108.0 合并复审 opus 腿 O-9)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ControlPlaneCorruptError } from "@sema-agent/core";
|
|
2
1
|
import { logStoreFormRefusal, storeFormRefusalOf } from "../memory-store-refusal.js";
|
|
2
|
+
import { sentControlPlaneCorrupt } from "./memory-control-plane-corrupt-reply.js";
|
|
3
3
|
import { sentMemoryStoreRefusal } from "./memory-store-refusal-reply.js";
|
|
4
4
|
import { sendError } from "./send.js";
|
|
5
5
|
import { assertNever } from "./route-ctx.js";
|
|
@@ -63,6 +63,9 @@ export function sentMemoryComplianceFailure(res, err, audience, logger) {
|
|
|
63
63
|
case "memory.scope_home_not_directory":
|
|
64
64
|
sendError(res, 409, "memory.scope_home_not_directory", "session memory erasure refused — a scope directory in this deployment's memory store is not a real directory (it was replaced by a link or a file), so this erasure did not complete; ask the operator to put the real directory back, then resend with the same requestId");
|
|
65
65
|
return true;
|
|
66
|
+
case "memory.control_plane_links_unsupported":
|
|
67
|
+
sendError(res, 409, "memory.control_plane_links_unsupported", "session memory erasure refused — this deployment's memory control plane is on a file system that cannot make hard links, so its memory store does not open and this erasure changed nothing; ask the operator to move the control plane to a volume that supports hard links, then resend with the same requestId");
|
|
68
|
+
return true;
|
|
66
69
|
default:
|
|
67
70
|
return assertNever(storeForm.code);
|
|
68
71
|
}
|
|
@@ -70,19 +73,6 @@ export function sentMemoryComplianceFailure(res, err, audience, logger) {
|
|
|
70
73
|
return assertNever(audience);
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
|
-
|
|
74
|
-
switch (audience.kind) {
|
|
75
|
-
case "operator":
|
|
76
|
-
sendError(res, 500, "internal.memory_control_plane_corrupt", err.message);
|
|
77
|
-
return true;
|
|
78
|
-
case "session_owner":
|
|
79
|
-
audience.withheld(err.message);
|
|
80
|
-
sendError(res, 500, "internal.memory_control_plane_corrupt", "session memory erasure could not be completed — this deployment's memory control plane could not be read cleanly (depending on where it stopped, either nothing was changed or the deletions were already committed and a replay finishes them); ask the operator to repair it, then resend with the same requestId");
|
|
81
|
-
return true;
|
|
82
|
-
default:
|
|
83
|
-
return assertNever(audience);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return false;
|
|
76
|
+
return sentControlPlaneCorrupt(res, err, audience);
|
|
87
77
|
}
|
|
88
78
|
//# sourceMappingURL=memory-compliance-failure-reply.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core 的 `ControlPlaneCorruptError` ⇒ typed 500 `internal.memory_control_plane_corrupt` 的 **HTTP 映射** —— 唯一一处码字面量、唯一一处 `instanceof` 判别。
|
|
3
|
+
*
|
|
4
|
+
* ## 为什么是一只
|
|
5
|
+
* 这是 core 的 fail-closed 信号:记忆引擎的控制面(账本 / 事务日志 / 清标账 / 治理账)说不清,它宁可不答,也不在一个说不清的账上拼一个答案。
|
|
6
|
+
* 凡是会碰控制面的 operator 记忆口,对它的答法必须是同一句话:消费端按 `errorCode` 分支,运维有具体动作(修 / 重建账本后重试)。
|
|
7
|
+
* 此前这条映射写在四个地方(导出 / 导入口、外源标记口、整理口、合规口),码字面量与判别各一份 = 第五个口加错码或漏一支的口子。
|
|
8
|
+
* 同族的店形拒早已是一只(`sentMemoryStoreRefusal`,在 `memory-store-refusal-reply.ts`);本文件是第二只。挂在每一个**已分类收尾**上:
|
|
9
|
+
* `routes/memory-bundle.ts`(导出 / 导入)· `routes/memory-origin.ts`(外源列表 / 清标 / 清标账列表 —— 清标账列表是纯控制面读,店形拒不挂在它上面,它的损坏信号走这一只)·
|
|
10
|
+
* `routes/memory-consolidation.ts`(整理)· `memory-compliance-failure-reply.ts`(出处 / 抹除,两受众)。
|
|
11
|
+
*
|
|
12
|
+
* ## 文案按受众分(码与状态不分;与 `memory-compliance-failure-reply.ts` 同一条规则)
|
|
13
|
+
* · operator ⇒ 引擎原句上 wire(点名**哪一张**控制面账本坏了,运维下一步动作取决于它;原句带宿主路径,过了 operator 门的受众拿它不是泄露);
|
|
14
|
+
* · 会话所有者(自助抹除口,只有这一个口有这个受众)⇒ 一句固定指路,引擎原句整句交 `withheld` 落运维行 —— 不逐句判断哪句安全。
|
|
15
|
+
* 固定句**一码两义都真**:操作前账本读不出 ⇒ 什么都没发生;落定后残留枚举失败 ⇒ 抹除已提交、重放收敛(core 原话)。两句都不许诺零删除,
|
|
16
|
+
* 都指路「运维修好后用同一个 requestId 重发」。本层**不**嗅 core 文案去分辨哪一义(拿上游自由文本当判别式是第二真源)。
|
|
17
|
+
*
|
|
18
|
+
* 两处 `sendError` 的码都写**字面量**:错误码目录门(`test/error-code-catalog-live.test.ts`)与文案冻结门(`test/api-error-text-freeze.test.ts`,
|
|
19
|
+
* 固定句是它冻的那一句)扫的是源码字面量,变量态的码 / 句对它们隐形。
|
|
20
|
+
*/
|
|
21
|
+
import type { ServerResponse } from "node:http";
|
|
22
|
+
import type { MemoryComplianceAudience } from "./memory-compliance-failure-reply.js";
|
|
23
|
+
/** `err` 是 core 的控制面损坏 ⇒ 500 `internal.memory_control_plane_corrupt`(文案按受众),返回 true(已应答);否则 false,一个字节都不写。 */
|
|
24
|
+
export declare function sentControlPlaneCorrupt(res: ServerResponse, err: unknown, audience: MemoryComplianceAudience): boolean;
|
|
25
|
+
//# sourceMappingURL=memory-control-plane-corrupt-reply.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ControlPlaneCorruptError } from "@sema-agent/core";
|
|
2
|
+
import { assertNever } from "./route-ctx.js";
|
|
3
|
+
import { sendError } from "./send.js";
|
|
4
|
+
export function sentControlPlaneCorrupt(res, err, audience) {
|
|
5
|
+
if (!(err instanceof ControlPlaneCorruptError))
|
|
6
|
+
return false;
|
|
7
|
+
switch (audience.kind) {
|
|
8
|
+
case "operator":
|
|
9
|
+
sendError(res, 500, "internal.memory_control_plane_corrupt", err.message);
|
|
10
|
+
return true;
|
|
11
|
+
case "session_owner":
|
|
12
|
+
audience.withheld(err.message);
|
|
13
|
+
sendError(res, 500, "internal.memory_control_plane_corrupt", "session memory erasure could not be completed — this deployment's memory control plane could not be read cleanly (depending on where it stopped, either nothing was changed or the deletions were already committed and a replay finishes them); ask the operator to repair it, then resend with the same requestId");
|
|
14
|
+
return true;
|
|
15
|
+
default:
|
|
16
|
+
return assertNever(audience);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=memory-control-plane-corrupt-reply.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* **operator 面 HTTP 映射** + 两受众共用的**运维行** ——
|
|
2
|
+
* **店形拒**一族(`memory.target_outside_store` / `memory.scope_home_not_directory` / `memory.control_plane_links_unsupported`,族表与判据在 `src/memory-store-refusal.ts`)的
|
|
3
|
+
* **operator 面 HTTP 映射** + 两受众共用的**运维行** —— operator 面唯一一处码字面量(会话所有者面的逐码臂在 `http/memory-compliance-failure-reply.ts`;引擎加码 ⇒ 两处各补一臂)。挂在每一个触 store 树的 operator 记忆口的已分类收尾上:
|
|
4
4
|
* `routes/memory-compliance.ts`(出处 / 抹除;经 `http/memory-compliance-failure-reply.ts` 的 operator 受众臂)· `routes/memory-origin.ts`(外源列表 / 清标;**不含**只读控制面的清标账列表 ——
|
|
5
5
|
* core 的 wire 表逐字:只碰控制面的面不判,给它挂一条永远收不到的码路径正是附录 A 活触发门要防的形)·
|
|
6
6
|
* `routes/memory-bundle.ts`(导出 / 导入)。会话所有者的自助抹除口**不走这里的 wire 句**(经 `http/memory-compliance-failure-reply.ts` 的会话所有者受众臂:同码、固定文案),
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* `POST /v1/admin/memory/consolidation/run` 也不走这里:那口把 core 的**任何**有码拒一律收成 409 `memory.consolidation_refused`
|
|
9
9
|
* (码进文案,附录 A 该行),这一族已在那条臂上,不再给它第二个码。
|
|
10
10
|
*
|
|
11
|
-
* ## 为什么 409(
|
|
11
|
+
* ## 为什么 409(一族同一条)
|
|
12
12
|
* core 的读法:operator 要处置的盘形(去掉 store 里那只通到外面的目录链 / 把 scope home 放回真目录),不是可重试的 IO 故障,也不是对调用方的裁决。与
|
|
13
13
|
* `memory.erasure_census_incomplete` 同一类(**当前 store 状态**下这次做不了;状态修好后重发即改判)⇒ 409,不 500(服务器没坏)、
|
|
14
14
|
* 不 4xx 请求族(请求没写错)。抹除面:链先于请求在场 ⇒ core 在提交点之前拒,零删除、零 journal(真 core 格钉在
|
|
@@ -12,6 +12,9 @@ export function sentMemoryStoreRefusal(res, err, logger) {
|
|
|
12
12
|
case "memory.scope_home_not_directory":
|
|
13
13
|
sendError(res, 409, "memory.scope_home_not_directory", refusal.message);
|
|
14
14
|
return true;
|
|
15
|
+
case "memory.control_plane_links_unsupported":
|
|
16
|
+
sendError(res, 409, "memory.control_plane_links_unsupported", refusal.message);
|
|
17
|
+
return true;
|
|
15
18
|
default: {
|
|
16
19
|
const unhandled = refusal.code;
|
|
17
20
|
throw new Error(`unhandled store-form refusal word: ${String(unhandled)}`);
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import type { ServiceConfig } from "../config-types.js";
|
|
17
17
|
import type { Logger } from "../observability/logger.js";
|
|
18
18
|
import type { RunRecord } from "../plugins/store-contracts.js";
|
|
19
|
+
import type { SessionHead } from "@sema-agent/core";
|
|
19
20
|
import { type OwnerAwareSessionStore, type Principal, type SessionCaller, type SessionOwnerCell } from "../security.js";
|
|
20
21
|
import { type IdentityWiring, type OperatorRoster } from "./principal-gate.js";
|
|
21
22
|
/** 调用点挂哪条臂(闭集):`owner` = 只有属主判官;`owner_or_operator` = 属主判官 ∨ 显式运维(`explicitOperatorOk`,唯一读法)。 */
|
|
@@ -46,6 +47,16 @@ export declare function readOwnedRun(config: OwnerAccessConfig, runStore: {
|
|
|
46
47
|
export declare function readOwnedSession(w: IdentityWiring & {
|
|
47
48
|
readonly config: OwnerAccessConfig;
|
|
48
49
|
}, store: Pick<OwnerAwareSessionStore, "placementOf"> & Required<Pick<OwnerAwareSessionStore, "headOf">>, caller: SessionCaller, sessionId: string, arm: OwnerArm): Promise<SessionOwnerCell | undefined>;
|
|
50
|
+
/**
|
|
51
|
+
* 同一只读口,连头一起交回:门过了的调用点还要读这只会话的**内容**(坏档判据 `leafOfAdmittedHead` 读头的叶子;门之前不许读)或头上的属主原值时用它 ——
|
|
52
|
+
* 一次头读、一只判官,与 {@link readOwnedSession} 是同一读(那一只就是本函数取 `cell`)。`undefined` 的读法同上。
|
|
53
|
+
*/
|
|
54
|
+
export declare function readOwnedSessionHead(w: IdentityWiring & {
|
|
55
|
+
readonly config: OwnerAccessConfig;
|
|
56
|
+
}, store: Pick<OwnerAwareSessionStore, "placementOf"> & Required<Pick<OwnerAwareSessionStore, "headOf">>, caller: SessionCaller, sessionId: string, arm: OwnerArm): Promise<{
|
|
57
|
+
readonly cell: SessionOwnerCell;
|
|
58
|
+
readonly head: SessionHead;
|
|
59
|
+
} | undefined>;
|
|
49
60
|
/**
|
|
50
61
|
* 🔴 **会话读面的属主读的第三个结局**:有主 / 无此行 / **属主读不出**(店交出具名拒 {@link SessionOwnerUnreadableError} —— 会话的行事实没有落下,补铸它要读的存档又用不了;
|
|
51
62
|
* 谁也判不了「这是不是你的会话」)。第三个读作第二个:**与「没有这一行」同一个值**(`undefined`),调用点落的就是它们对「不存在 / 非属主」的那一臂 ——
|
|
@@ -32,11 +32,14 @@ export async function readOwnedRun(config, runStore, principal, taskId, arm) {
|
|
|
32
32
|
return row !== undefined && runRowReadable(config, principal, row.owner, arm) ? row : undefined;
|
|
33
33
|
}
|
|
34
34
|
export async function readOwnedSession(w, store, caller, sessionId, arm) {
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
return (await readOwnedSessionHead(w, store, caller, sessionId, arm))?.cell;
|
|
36
|
+
}
|
|
37
|
+
export async function readOwnedSessionHead(w, store, caller, sessionId, arm) {
|
|
38
|
+
const head = await store.headOf(sessionId);
|
|
39
|
+
if (head === undefined || head.owner === undefined)
|
|
37
40
|
return undefined;
|
|
38
|
-
const cell = await sessionOwnerCellOf(store, sessionId, owner);
|
|
39
|
-
return operatorArmHolds(w.config, caller.principal, arm) || sessionOwnerReadable(caller, cell, w) ? cell : undefined;
|
|
41
|
+
const cell = await sessionOwnerCellOf(store, sessionId, head.owner);
|
|
42
|
+
return operatorArmHolds(w.config, caller.principal, arm) || sessionOwnerReadable(caller, cell, w) ? { cell, head } : undefined;
|
|
40
43
|
}
|
|
41
44
|
export async function foldOwnerUnreadable(logger, face, sessionId, read) {
|
|
42
45
|
try {
|
|
@@ -72,8 +72,10 @@ export declare function sendPrincipalRefusal(res: ServerResponse, req: IncomingM
|
|
|
72
72
|
* 每面一句模块级常量(冻结门按常量解引用逐字钉)。三句都**不含任何值**(令牌 / 头名 / 路径实参一概不回显),且**不区分**
|
|
73
73
|
* 「没带」与「带错」—— 同一道门上两者逐字同体,区分就是探测面。
|
|
74
74
|
* · `credential` —— 全局凭据门(`dispatch.ts`):部署配了 service token,请求没带或带的不认(registry 登录令牌验不过同属此面);
|
|
75
|
-
* · `operator` —— 只给运维凭据开的口(`/metrics*` 与 `GET /v1/tasks/source-summary`):不带主体头的 service token 开得了
|
|
76
|
-
* {@link actsForDeployment}
|
|
75
|
+
* · `operator` —— 只给运维凭据开的口(`/metrics*` 与 `GET /v1/tasks/source-summary`):不带主体头的 service token 开得了 —— 在部署让它代自己说话时
|
|
76
|
+
* ({@link actsForDeployment};带主体头的是那位主体;声明 `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT=false` 的部署上它不代任何人),指标口另认只读的 `METRICS_TOKEN`、
|
|
77
|
+
* `source-summary` 另认只读的 `TRACE_TOKEN`(都在全局门之前判)。句子只有一句、两形都真:service token 那条出路带条件「在这台部署让它代自己说话时」,
|
|
78
|
+
* 并指 `/health` 的自报位 `auth.serviceTokenActsForDeployment` 去读这台部署的答案 —— 铸点不读配置、签名不变(一面一只常量);
|
|
77
79
|
* · `identity` —— 过了凭据门(或这台部署没配 service token)、但这一口要一个**验过的调用方身份**:属主寻址的读 / 写面、规则面、
|
|
78
80
|
* 记忆面。在配了 service token 的部署上,「带 service token 却没身份」只会落在只认身份的口(规则 / 记忆 / 会话策略)上 ——
|
|
79
81
|
* 这时再叫调用方「去带 service token」是假出路,所以这一面的句子只讲身份。
|
|
@@ -81,7 +83,7 @@ export declare function sendPrincipalRefusal(res: ServerResponse, req: IncomingM
|
|
|
81
83
|
*/
|
|
82
84
|
export type UnauthorizedFace = "credential" | "operator" | "identity";
|
|
83
85
|
export declare const UNAUTHORIZED_CREDENTIAL = "unauthorized \u2014 the request carries no credential this deployment accepts: send the deployment's service token as a Bearer token in the Authorization header (its operator set it as SERVICE_AUTH_TOKEN or SERVICE_AUTH_TOKENS; a sema-up deployment keeps SERVICE_AUTH_TOKEN in ~/.sema-up/<project>/.env on the machine that ran sema-up)";
|
|
84
|
-
export declare const UNAUTHORIZED_OPERATOR = "unauthorized \u2014 this endpoint is for the deployment's operators and the request carries no operator credential: send the deployment's service token as a Bearer token in the Authorization header without a principal header (a service-token request that names a principal acts for that principal, not for the deployment), or a read-only token this endpoint accepts (METRICS_TOKEN for the metrics endpoints, TRACE_TOKEN for the task source summary)";
|
|
86
|
+
export declare const UNAUTHORIZED_OPERATOR = "unauthorized \u2014 this endpoint is for the deployment's operators and the request carries no operator credential: send the deployment's service token as a Bearer token in the Authorization header without a principal header where this deployment lets its service token act for the deployment itself (GET /health reports it as auth.serviceTokenActsForDeployment; a service-token request that names a principal acts for that principal, not for the deployment), or a read-only token this endpoint accepts (METRICS_TOKEN for the metrics endpoints, TRACE_TOKEN for the task source summary)";
|
|
85
87
|
export declare const UNAUTHORIZED_IDENTITY = "unauthorized \u2014 this endpoint acts for a named caller and the request carries no caller identity this deployment verifies: identify the caller the way this deployment does (a registry sign-in token as the Bearer token, a signed principal token on a direct-door deployment, or the principal header set by a trusted front end)";
|
|
86
88
|
export declare function sendUnauthorized(res: ServerResponse, face: UnauthorizedFace): void;
|
|
87
89
|
/**
|
|
@@ -128,15 +130,24 @@ export declare function wiredIdentitySources(w: IdentityWiring): readonly Identi
|
|
|
128
130
|
*/
|
|
129
131
|
export declare function devOpenDeployment(w: IdentityWiring): boolean;
|
|
130
132
|
/**
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
133
|
+
* 🔴 **律(一句,一个参数)**:出示这台部署的 service 凭据且不报主体的调用方代部署本人说话(fleet),**除非部署声明 `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT=false`**
|
|
134
|
+
* —— 此时它是无身份调用方,按各面既有的「过了凭据门、没有主体」那一臂答。带主体头的 service 凭据请求是前端(BFF)代那位主体发的 —— 它读那位主体,
|
|
135
|
+
* 不读全舰队(两形同读);部署姿态(单用户 / 多租)不改这一句(单用户形上的主体头同样是「这次请求为谁」)。
|
|
136
|
+
* 本函数是这条律的**唯一实施点**:声明位({@link ServiceConfig.serviceTokenActsForDeployment},env 一处)是这里的一个合取项,两个读者一次继承 ——
|
|
137
|
+
* fleet 调用方的凭据臂({@link sessionCallerOf})与 `/metrics` 族的 service 臂(`dispatch.ts`);不加拒码、不加闸点。自报位 `/health.auth.serviceTokenActsForDeployment`
|
|
138
|
+
* 投的是同一只读法({@link serviceTokenDeclaredActsForDeployment})与同一只武装谓词(`http/health-self-report.ts`)。先判声明与凭据、后取主体:`principal` 只在两者都成立时才求值(调用点那一次 {@link gatedPrincipal}),
|
|
139
|
+
* 没带凭据的请求不因主体头的形而改答。
|
|
135
140
|
*/
|
|
136
141
|
export declare function actsForDeployment(req: IncomingMessage, config: ServiceConfig, principal: () => Principal | undefined): boolean;
|
|
142
|
+
/**
|
|
143
|
+
* 声明位 `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT` 的**唯一读法**:门({@link actsForDeployment})、自报位(`http/health-self-report.ts`)、起服行
|
|
144
|
+
* ({@link buildServiceTokenPostureNotice})三处都经它,不各写一份真值判断。只有字面 `true` 是「代部署本人」:`loadConfig` 恒写这一格(缺省 `true`),
|
|
145
|
+
* 绕过类型手搓的配置缺这一格 ⇒ 读作不代(fail-closed:安全轴上的缺席不静默放宽),三处同读 —— 不会出现「门收窄、自报位说缺席、起服行沉默」。
|
|
146
|
+
*/
|
|
147
|
+
export declare function serviceTokenDeclaredActsForDeployment(config: Pick<ServiceConfig, "serviceTokenActsForDeployment">): boolean;
|
|
137
148
|
/**
|
|
138
149
|
* 🔴 **「这个调用方是不是 fleet 调用方(看得到所有租户)」的唯一铸点**({@link SessionCaller}):验过的主体 + 是不是 fleet —— {@link devOpenDeployment} 上的任何
|
|
139
|
-
* 调用方,或 {@link actsForDeployment}(出示 service
|
|
150
|
+
* 调用方,或 {@link actsForDeployment}(出示 service 凭据、不报主体,除非部署声明 `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT=false`)。带主体头的是那位主体,不是 fleet;只读 trace token 不是 service 凭据;operator 不在这里
|
|
140
151
|
* (运维口各自读 {@link explicitOperatorOk})。读者:会话行属主门(无主 placed 行的放行臂)与 fleet 面的 {@link fleetViewOf} —— 同一问一只读法。
|
|
141
152
|
*/
|
|
142
153
|
export declare function sessionCallerOf(req: IncomingMessage, w: IdentityWiring): SessionCaller;
|
|
@@ -175,21 +186,22 @@ export type OperatorRoster = Pick<ServiceConfig, "operatorPrincipals" | "operato
|
|
|
175
186
|
* · 名单非空 ⇒ 验过的主体在名单里才是;
|
|
176
187
|
* · 单用户形显式声明 `OPERATOR_SINGLE_USER=true` ⇒ 这台部署的**每个调用方**都是(单用户形只有一位用户,能到这台部署的就是他;边界是部署自己的
|
|
177
188
|
* 凭据门 —— 没配凭据的部署上,能连上端口的都是)。声明只在单用户形成立(起服不变量)。
|
|
178
|
-
* `principal` 必须是验过的身份(`gatedPrincipal`),绝不是自述头。全部运维面(审批队列、steer
|
|
189
|
+
* `principal` 必须是验过的身份(`gatedPrincipal`),绝不是自述头。全部运维面(审批队列、steer / interrupt / wake 的属主门旁路、记忆运维口、bake 门……)读这一只 —— 只答授权;
|
|
190
|
+
* 送话口的文本框架(`trusted`)从不读它(调用方的话恒 `trusted: false`,见 `routes/runs.ts` steer 口的注);
|
|
179
191
|
* 🔴 SINGLE mint point (E1):不要再造兄弟。
|
|
180
192
|
*/
|
|
181
193
|
export declare function explicitOperatorOk(principal: string | undefined, roster: OperatorRoster): boolean;
|
|
182
|
-
/** 「这台部署**有没有**运维」的唯一读法(名单非空 ∨ 单用户声明在场)—— 能力事实 `operatorLane
|
|
194
|
+
/** 「这台部署**有没有**运维」的唯一读法(名单非空 ∨ 单用户声明在场)—— 能力事实 `operatorLane` 读这一只(整理阀门的可达性告警随本条退役)。单用户形上,装了运维面的进程里它恒真(`operator-declaration-required`:服务进程起服第 1 段、`createHttpServer` 对不声明的单用户形拒),多租形上空名单 ⇒ 假。 */
|
|
183
195
|
export declare function operatorRosterPresent(roster: OperatorRoster): boolean;
|
|
184
196
|
/**
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
197
|
+
* 起服一行:部署声明 `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT=false` ⇒ `service_token_posture { actsForDeployment: false }`(info);缺省不打。
|
|
198
|
+
* 声明形让运维面板开位当天成片 401,而「位关了」与「token 错了」在 wire 上同体(反探测律),这一行是起服时唯一一处说清这台部署选了哪一读法的地方。
|
|
199
|
+
* 不加逐请求事件(请求日志有 route / status,无凭据来源)。判据与字段单源在这里,装配处(`boot/stage-07-capability-layer.ts`)只调一次、原样打。
|
|
188
200
|
*/
|
|
189
|
-
export declare function
|
|
190
|
-
event: "
|
|
201
|
+
export declare function buildServiceTokenPostureNotice(config: Pick<ServiceConfig, "serviceTokenActsForDeployment">): {
|
|
202
|
+
event: "service_token_posture";
|
|
191
203
|
fields: {
|
|
192
|
-
|
|
204
|
+
actsForDeployment: false;
|
|
193
205
|
};
|
|
194
206
|
} | undefined;
|
|
195
207
|
/** operator 面族在「名单为空」这一形上的**唯一**拒发口:事实 `operatorLane`(`capability-facts.ts`)为假 ⇒ 这一面对任何
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { timingSafeEqual } from "node:crypto";
|
|
2
2
|
import { DEPLOYMENT_SHAPE_PREDICATES } from "../deployment-shape.js";
|
|
3
|
-
import { PRINCIPAL_TOKEN_HEADER, verifiedPrincipal, ssoVerifiedPrincipal, ssoVerifiedPrincipalInc, ssoVerifiedScope, ownerlessRowOpen, mintPrincipal } from "../security.js";
|
|
3
|
+
import { PRINCIPAL_TOKEN_HEADER, sameSessionOwner, verifiedPrincipal, ssoVerifiedPrincipal, ssoVerifiedPrincipalInc, ssoVerifiedScope, ownerlessRowOpen, mintPrincipal } from "../security.js";
|
|
4
4
|
import { IDENTITY_SOURCES, runIdentityClaimOverflow } from "../identity-source.js";
|
|
5
5
|
import { sendError } from "./send.js";
|
|
6
6
|
export function headerStr(v) {
|
|
@@ -120,7 +120,7 @@ export function sendPrincipalRefusal(res, req, config) {
|
|
|
120
120
|
sendError(res, 401, "auth.principal_required", `missing principal header '${config.principalHeader}'`);
|
|
121
121
|
}
|
|
122
122
|
export const UNAUTHORIZED_CREDENTIAL = "unauthorized — the request carries no credential this deployment accepts: send the deployment's service token as a Bearer token in the Authorization header (its operator set it as SERVICE_AUTH_TOKEN or SERVICE_AUTH_TOKENS; a sema-up deployment keeps SERVICE_AUTH_TOKEN in ~/.sema-up/<project>/.env on the machine that ran sema-up)";
|
|
123
|
-
export const UNAUTHORIZED_OPERATOR = "unauthorized — this endpoint is for the deployment's operators and the request carries no operator credential: send the deployment's service token as a Bearer token in the Authorization header without a principal header (a service-token request that names a principal acts for that principal, not for the deployment), or a read-only token this endpoint accepts (METRICS_TOKEN for the metrics endpoints, TRACE_TOKEN for the task source summary)";
|
|
123
|
+
export const UNAUTHORIZED_OPERATOR = "unauthorized — this endpoint is for the deployment's operators and the request carries no operator credential: send the deployment's service token as a Bearer token in the Authorization header without a principal header where this deployment lets its service token act for the deployment itself (GET /health reports it as auth.serviceTokenActsForDeployment; a service-token request that names a principal acts for that principal, not for the deployment), or a read-only token this endpoint accepts (METRICS_TOKEN for the metrics endpoints, TRACE_TOKEN for the task source summary)";
|
|
124
124
|
export const UNAUTHORIZED_IDENTITY = "unauthorized — this endpoint acts for a named caller and the request carries no caller identity this deployment verifies: identify the caller the way this deployment does (a registry sign-in token as the Bearer token, a signed principal token on a direct-door deployment, or the principal header set by a trusted front end)";
|
|
125
125
|
export function sendUnauthorized(res, face) {
|
|
126
126
|
switch (face) {
|
|
@@ -139,15 +139,10 @@ export function sendUnauthorized(res, face) {
|
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
-
function sameIdentity(principal, owner) {
|
|
143
|
-
return principal === owner;
|
|
144
|
-
}
|
|
145
142
|
export function runOwnerReadable(principal, owner, config) {
|
|
146
143
|
if (owner === null)
|
|
147
144
|
return true;
|
|
148
|
-
|
|
149
|
-
return true;
|
|
150
|
-
return !DEPLOYMENT_SHAPE_PREDICATES.principalRequired.holds(config) && owner === "anon:shell-live" && principal === undefined;
|
|
145
|
+
return sameSessionOwner(config, owner, principal ?? null);
|
|
151
146
|
}
|
|
152
147
|
export function hasServiceAuth(config) {
|
|
153
148
|
return Boolean(config.authToken) || Object.keys(config.authTokens ?? {}).length > 0;
|
|
@@ -173,7 +168,10 @@ export function devOpenDeployment(w) {
|
|
|
173
168
|
return wiredIdentitySources(w).length === 0 && !w.config.traceToken && !DEPLOYMENT_SHAPE_PREDICATES.principalRequired.holds(w.config);
|
|
174
169
|
}
|
|
175
170
|
export function actsForDeployment(req, config, principal) {
|
|
176
|
-
return systemFor(req, config) !== undefined && principal() === undefined;
|
|
171
|
+
return serviceTokenDeclaredActsForDeployment(config) && systemFor(req, config) !== undefined && principal() === undefined;
|
|
172
|
+
}
|
|
173
|
+
export function serviceTokenDeclaredActsForDeployment(config) {
|
|
174
|
+
return config.serviceTokenActsForDeployment === true;
|
|
177
175
|
}
|
|
178
176
|
export function sessionCallerOf(req, w) {
|
|
179
177
|
const principal = gatedPrincipal(req, w.config);
|
|
@@ -211,17 +209,10 @@ export function explicitOperatorOk(principal, roster) {
|
|
|
211
209
|
export function operatorRosterPresent(roster) {
|
|
212
210
|
return roster.operatorSingleUser === true || roster.operatorPrincipals.length > 0;
|
|
213
211
|
}
|
|
214
|
-
export function
|
|
215
|
-
if (
|
|
212
|
+
export function buildServiceTokenPostureNotice(config) {
|
|
213
|
+
if (serviceTokenDeclaredActsForDeployment(config))
|
|
216
214
|
return undefined;
|
|
217
|
-
return {
|
|
218
|
-
event: "operator_undeclared_single_user",
|
|
219
|
-
fields: {
|
|
220
|
-
detail: "this single-user deployment declares no operator: OPERATOR_PRINCIPALS is empty and OPERATOR_SINGLE_USER is not set, so no caller is an operator — " +
|
|
221
|
-
"GET /v1/approvals, its stream, /v1/assistant/inbox and /v1/assistant/tasks show each caller only its own pending approvals (a caller that sends no principal sees only the anonymous ones - the cards and tasks that were submitted without a principal - never a named principal's) and ignore ?owner=. " +
|
|
222
|
-
"To act as this deployment's operator, add one line: OPERATOR_SINGLE_USER=true",
|
|
223
|
-
},
|
|
224
|
-
};
|
|
215
|
+
return { event: "service_token_posture", fields: { actsForDeployment: false } };
|
|
225
216
|
}
|
|
226
217
|
export function sendOperatorPrincipalsRequired(res) {
|
|
227
218
|
sendError(res, 501, "capability.operator_principals_required", `this endpoint is operator-only and this deployment has no operator roster (OPERATOR_PRINCIPALS is empty and OPERATOR_SINGLE_USER is not declared), so no caller can be an operator; ${buildOperatorRosterWayOut()}`);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 请求守门族([ref] 切片:`http/server.ts` 4837–5195
|
|
2
|
+
* 请求守门族([ref] 切片:`http/server.ts` 4837–5195 逐字搬家,正文一字未改;JSON 体上限的数住叶子 `json-body-limit.ts`)。
|
|
3
3
|
* 配额 / 租约 / 用量窗 / 限流 / owner-scope / 体读取 —— 每只守门的判据与它自己的头注原位随行。
|
|
4
4
|
* ctx 字段 1 只(`deps`):本族对外围的耦合就这一格,它也是这一族的可测性读数。
|
|
5
5
|
*/
|
|
@@ -23,7 +23,7 @@ import { type SqlWallSource, type SqlWallsReading } from "../plugins/sql-driver.
|
|
|
23
23
|
*
|
|
24
24
|
* 🔴 **包墙腿是同一只规则的提前一跑,不是第二套规则**([ref] 主会话裁定):包墙是物理连接的事实(会话值,连接建立时从全局拷一份、此后不变),
|
|
25
25
|
* 终判在将要执行写入的那条连接上 —— 那是库自己(续跑输入那一笔被拒 ⇒ 店的带码拒 ⇒ 同一个 413;会话日志那一笔走它既有的失败面);SQL 快照 blob 则由
|
|
26
|
-
* `blob-
|
|
26
|
+
* 店的 blob 索引(`stores-sql/blob-index-sql.ts`)经 `connectJudged` 在写入连接上判。受理时手里没有那条连接,判官 `sqlWallsOf` 读的 `facts` 是池里**最近一次初始化**的那条连接的读数
|
|
27
27
|
* (`SqlDriver.facts`:池见过的最新读数,只在有连接初始化时才更新),同一个折算 `packetWallStatementBytes`:拒 ⇒ 413 在任何副作用之前;收 ⇒ 写入那条连接上的判决仍是终判。
|
|
28
28
|
* 这个读数是**缓存**,DBA 调了全局值之后、下一条连接初始化之前,它与库此刻的值两个方向都可能不一致:调大 ⇒ 受理口仍按旧的小值拒(新墙本装得下的体也 413,
|
|
29
29
|
* 直到有连接按新值初始化 —— 快照 blob 的旧连接自换就会带来一条);调小 ⇒ 受理口按旧的大值放行,写入那条连接上的库再拒(续跑输入那一笔 = 同一个 413)。
|
|
@@ -9,14 +9,14 @@ import { runRowReadable } from "./owner-access.js";
|
|
|
9
9
|
import { DEPLOYMENT_SHAPE_PREDICATES } from "../deployment-shape.js";
|
|
10
10
|
import { quotaWindowResetsAt } from "../observability/cost-quota.js";
|
|
11
11
|
import { escapedStatementBytes, packetWallStatementBytes, rowWallPayloadBytes } from "../plugins/sql-driver.js";
|
|
12
|
-
|
|
12
|
+
import { MAX_JSON_BODY_BYTES } from "../json-body-limit.js";
|
|
13
13
|
export function refuseSubmitBody(walls, body) {
|
|
14
14
|
const rowWall = walls.maxRowBytes;
|
|
15
15
|
const packetWall = walls.maxPacketBytes;
|
|
16
16
|
const row = rowWall === null ? null : { wallBytes: rowWall, limitBytes: rowWallPayloadBytes(rowWall, "json") };
|
|
17
17
|
const packet = packetWall === null ? null : { wallBytes: packetWall, limitBytes: packetWallStatementBytes(packetWall) };
|
|
18
|
-
const liveRow = row !== null && row.limitBytes <
|
|
19
|
-
const livePacket = packet !== null && packet.limitBytes < 2 *
|
|
18
|
+
const liveRow = row !== null && row.limitBytes < MAX_JSON_BODY_BYTES ? row : null;
|
|
19
|
+
const livePacket = packet !== null && packet.limitBytes < 2 * MAX_JSON_BODY_BYTES ? packet : null;
|
|
20
20
|
if (liveRow === null && livePacket === null)
|
|
21
21
|
return null;
|
|
22
22
|
const json = JSON.stringify(body);
|
|
@@ -228,8 +228,8 @@ export function createRequestGuards(ctx) {
|
|
|
228
228
|
let size = 0;
|
|
229
229
|
for await (const c of req) {
|
|
230
230
|
size += c.length;
|
|
231
|
-
if (size >
|
|
232
|
-
throw bodyTooLargeError("request body too large",
|
|
231
|
+
if (size > MAX_JSON_BODY_BYTES)
|
|
232
|
+
throw bodyTooLargeError("request body too large", MAX_JSON_BODY_BYTES);
|
|
233
233
|
chunks.push(c);
|
|
234
234
|
}
|
|
235
235
|
if (chunks.length === 0)
|