@sema-agent/server 7.131.0 → 7.133.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 +575 -0
- package/README.md +12 -9
- package/README.zh-CN.md +9 -6
- package/USAGE.md +326 -98
- package/deploy/sema-up/README.md +19 -1
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -2
- package/deploy/sema-up/chart/templates/server.yaml +5 -2
- package/deploy/sema-up/stack/compose.yaml +3 -0
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
- package/dist/adoption/plan.d.ts +3 -2
- package/dist/adoption/plan.js +7 -5
- package/dist/adoption/runner.js +3 -10
- package/dist/adoption/sql.d.ts +3 -2
- package/dist/adoption/sql.js +3 -5
- package/dist/adoption/wire.d.ts +4 -1
- package/dist/adoption/wire.js +1 -0
- package/dist/approval-ask-audit-store.d.ts +31 -13
- package/dist/approval-ask-audit-store.js +272 -74
- package/dist/approval-ask-machine.d.ts +15 -0
- package/dist/approval-ask-machine.js +6 -0
- package/dist/approval-ask-retention.d.ts +136 -0
- package/dist/approval-ask-retention.js +102 -0
- package/dist/approval-card.d.ts +82 -20
- package/dist/approval-card.js +46 -16
- package/dist/approval-deny-reasons.d.ts +1 -1
- package/dist/approval.d.ts +9 -0
- package/dist/approval.js +24 -3
- package/dist/audit.d.ts +33 -19
- package/dist/audit.js +12 -16
- package/dist/auth-bridge.d.ts +4 -0
- package/dist/auth-bridge.js +10 -11
- package/dist/bake-runner/main.js +3 -2
- package/dist/boot/deferred-sandbox-path-env.js +1 -1
- package/dist/boot/deployment-mods.d.ts +31 -0
- package/dist/boot/deployment-mods.js +26 -0
- package/dist/boot/execution-env.d.ts +1 -1
- package/dist/boot/execution-env.js +27 -12
- package/dist/boot/execution-lane.js +11 -0
- package/dist/boot/leader.js +2 -0
- package/dist/boot/memory-boundary.d.ts +2 -2
- package/dist/boot/memory-boundary.js +2 -2
- package/dist/boot/memory-consolidation.d.ts +5 -4
- package/dist/boot/memory-consolidation.js +7 -6
- package/dist/boot/org-delivery.d.ts +28 -0
- package/dist/boot/org-delivery.js +20 -0
- package/dist/boot/read-deny-anchor-audit.d.ts +17 -0
- package/dist/boot/read-deny-anchor-audit.js +36 -0
- package/dist/boot/reapers.d.ts +3 -0
- package/dist/boot/reapers.js +21 -1
- package/dist/boot/resolve-spec.d.ts +4 -5
- package/dist/boot/resolve-spec.js +74 -123
- package/dist/boot/runner-deps.d.ts +19 -8
- package/dist/boot/runner-deps.js +15 -2
- package/dist/boot/session-faces.d.ts +2 -7
- package/dist/boot/session-faces.js +4 -2
- package/dist/boot/stage-02-web-admin-pull.js +4 -1
- package/dist/boot/stage-03-store-backend.d.ts +1 -1
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.d.ts +4 -4
- package/dist/boot/stage-05-execution-env.js +7 -10
- package/dist/boot/stage-06-runners.d.ts +4 -2
- package/dist/boot/stage-06-runners.js +11 -7
- package/dist/boot/stage-07-capability-layer.d.ts +4 -2
- package/dist/boot/stage-07-capability-layer.js +27 -6
- package/dist/boot/stage-08-reapers.d.ts +4 -2
- package/dist/boot/stage-08-reapers.js +2 -2
- package/dist/boot/stage-09-leader.d.ts +6 -9
- package/dist/boot/stage-10-http-server.d.ts +6 -9
- package/dist/boot/stage-10-http-server.js +7 -9
- package/dist/boot/stores.d.ts +1 -1
- package/dist/boot/stores.js +7 -8
- package/dist/boot/web-admin.d.ts +4 -3
- package/dist/boot/web-admin.js +186 -98
- package/dist/boot/workflow-orchestration.d.ts +2 -0
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/brain.js +25 -25
- package/dist/breaker-key.d.ts +6 -0
- package/dist/breaker-key.js +29 -0
- package/dist/budget.js +5 -4
- package/dist/caller-text-echo.d.ts +23 -0
- package/dist/caller-text-echo.js +21 -0
- package/dist/capabilities/brand-identity.d.ts +26 -0
- package/dist/capabilities/brand-identity.js +27 -0
- package/dist/capabilities/center-plugins.d.ts +7 -0
- package/dist/capabilities/center-plugins.js +1 -1
- package/dist/capabilities/center-prompts.d.ts +32 -59
- package/dist/capabilities/center-prompts.js +18 -32
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/composite-members.js +1 -1
- package/dist/capabilities/engine-capabilities.js +2 -1
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +30 -6
- package/dist/capabilities/hands-lane.js +11 -1
- package/dist/capabilities/mcp-probe.d.ts +48 -3
- package/dist/capabilities/mcp-probe.js +47 -135
- package/dist/capabilities/scenarios.d.ts +95 -45
- package/dist/capabilities/scenarios.js +53 -38
- package/dist/capabilities/skills.d.ts +19 -4
- package/dist/capabilities/skills.js +30 -10
- package/dist/capability-facts.d.ts +34 -4
- package/dist/capability-facts.js +28 -2
- package/dist/center-config-tier.d.ts +69 -0
- package/dist/center-config-tier.js +42 -0
- package/dist/checkpoint-identity.d.ts +16 -0
- package/dist/checkpoint-identity.js +19 -0
- package/dist/config-catalog.d.ts +17 -10
- package/dist/config-catalog.js +47 -32
- package/dist/config-d-migration.d.ts +3 -1
- package/dist/config-d-migration.js +2 -2
- package/dist/config-dir-trust.d.ts +114 -0
- package/dist/config-dir-trust.js +388 -0
- package/dist/config-invariants.d.ts +18 -5
- package/dist/config-invariants.js +35 -3
- package/dist/config-lkg.d.ts +9 -9
- package/dist/config-lkg.js +20 -4
- package/dist/config-provider.d.ts +9 -2
- package/dist/config-provider.js +18 -6
- package/dist/config-types.d.ts +75 -20
- package/dist/config-types.js +8 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.js +137 -62
- package/dist/delegated-session-owner.d.ts +185 -0
- package/dist/delegated-session-owner.js +119 -0
- package/dist/device-protocol.d.ts +5 -3
- package/dist/device-protocol.js +1 -1
- package/dist/device-ws-hub.js +21 -2
- package/dist/device-ws-protocol.d.ts +70 -6
- package/dist/device-ws-protocol.js +50 -22
- package/dist/elicitation.js +3 -2
- package/dist/entry-problems.d.ts +34 -0
- package/dist/entry-problems.js +14 -0
- package/dist/env-name-allowlist-knobs.d.ts +12 -2
- package/dist/env-name-allowlist-knobs.js +5 -4
- package/dist/exec-bounds.d.ts +15 -3
- package/dist/exec-bounds.js +4 -0
- package/dist/execution-lane-caps.d.ts +56 -10
- package/dist/execution-lane-caps.js +50 -0
- package/dist/field-conflict.d.ts +43 -0
- package/dist/field-conflict.js +20 -0
- package/dist/fleet/fleet-bus.d.ts +80 -6
- package/dist/fleet/fleet-bus.js +41 -9
- package/dist/hooks/classic-stations.d.ts +91 -0
- package/dist/hooks/classic-stations.js +27 -0
- package/dist/hooks/command-spawn.d.ts +57 -0
- package/dist/hooks/command-spawn.js +139 -0
- package/dist/hooks/hook-llm.d.ts +8 -5
- package/dist/hooks/hook-llm.js +79 -36
- package/dist/hooks/hook-runner.d.ts +349 -95
- package/dist/hooks/hook-runner.js +855 -568
- package/dist/hooks/hook-source.d.ts +44 -0
- package/dist/hooks/hook-source.js +40 -0
- package/dist/http/active-run-conflict.d.ts +5 -13
- package/dist/http/active-run-conflict.js +17 -27
- package/dist/http/admission.d.ts +8 -2
- package/dist/http/admission.js +188 -101
- package/dist/http/approval-sweeps.js +99 -21
- package/dist/http/caller-trust.d.ts +77 -0
- package/dist/http/caller-trust.js +143 -0
- package/dist/http/checkpoint-ctx.d.ts +41 -24
- package/dist/http/checkpoint-ctx.js +23 -16
- package/dist/http/claimed-run.d.ts +14 -0
- package/dist/http/claimed-run.js +15 -0
- package/dist/http/device-placement.d.ts +2 -4
- package/dist/http/device-placement.js +7 -11
- package/dist/http/dispatch.d.ts +0 -4
- package/dist/http/dispatch.js +15 -13
- package/dist/http/durable-run-leg.d.ts +6 -33
- package/dist/http/durable-run-leg.js +36 -10
- package/dist/http/health-self-report.d.ts +7 -5
- package/dist/http/health-self-report.js +4 -18
- package/dist/http/owner-access.d.ts +56 -0
- package/dist/http/owner-access.js +42 -0
- package/dist/http/principal-gate.d.ts +70 -28
- package/dist/http/principal-gate.js +61 -15
- package/dist/http/readiness.d.ts +11 -5
- package/dist/http/readiness.js +10 -3
- package/dist/http/refusal-body.d.ts +21 -0
- package/dist/http/refusal-body.js +4 -0
- package/dist/http/request-guards.d.ts +43 -23
- package/dist/http/request-guards.js +53 -17
- package/dist/http/resume-ctx-read.d.ts +2 -5
- package/dist/http/resume-ctx-read.js +7 -4
- package/dist/http/resume-legs.d.ts +28 -4
- package/dist/http/resume-legs.js +169 -91
- package/dist/http/retired-service-deps.d.ts +43 -0
- package/dist/http/retired-service-deps.js +18 -0
- package/dist/http/route-ctx.d.ts +44 -28
- package/dist/http/route-ctx.js +4 -0
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/a2a-serve.js +3 -4
- package/dist/http/routes/admin-config-refresh.js +1 -1
- package/dist/http/routes/admin-drain.js +1 -1
- package/dist/http/routes/admin-memory-optout.js +5 -1
- package/dist/http/routes/adoption.js +2 -9
- package/dist/http/routes/approvals-assistant.js +49 -48
- package/dist/http/routes/background.js +3 -2
- package/dist/http/routes/capabilities.js +21 -5
- package/dist/http/routes/config-catalog.d.ts +3 -3
- package/dist/http/routes/config-catalog.js +1 -1
- package/dist/http/routes/devices.js +3 -17
- package/dist/http/routes/diagnostics.js +6 -2
- package/dist/http/routes/images.js +6 -7
- package/dist/http/routes/leader.js +1 -8
- package/dist/http/routes/mcp-reconnect.d.ts +1 -1
- package/dist/http/routes/mcp-reconnect.js +3 -2
- package/dist/http/routes/memory-bundle.js +1 -1
- package/dist/http/routes/memory-compliance.js +1 -1
- package/dist/http/routes/memory-consolidation.js +1 -1
- package/dist/http/routes/memory-origin.js +1 -1
- package/dist/http/routes/memory-policy.d.ts +1 -1
- package/dist/http/routes/memory-policy.js +3 -2
- package/dist/http/routes/notify-wake.js +8 -21
- package/dist/http/routes/observability.js +2 -2
- package/dist/http/routes/principal-inbox.d.ts +39 -0
- package/dist/http/routes/principal-inbox.js +76 -0
- package/dist/http/routes/retention-ops.js +2 -9
- package/dist/http/routes/rules.js +5 -18
- package/dist/http/routes/runs.d.ts +5 -0
- package/dist/http/routes/runs.js +34 -107
- package/dist/http/routes/session-sync.js +15 -26
- package/dist/http/routes/sessions.js +30 -40
- package/dist/http/routes/shared-memory.js +2 -13
- package/dist/http/routes/side-query.js +8 -7
- package/dist/http/routes/tasks.js +67 -21
- package/dist/http/routes/workflows.d.ts +351 -0
- package/dist/http/routes/workflows.js +153 -119
- package/dist/http/send.d.ts +33 -10
- package/dist/http/send.js +21 -4
- package/dist/http/server.d.ts +27 -18
- package/dist/http/server.js +34 -6
- package/dist/http/stored-body-replay.js +17 -4
- package/dist/http/submit-ctx.d.ts +25 -0
- package/dist/http/submit-ctx.js +40 -0
- package/dist/http/submit-replay.d.ts +4 -3
- package/dist/http/submit-replay.js +5 -4
- package/dist/http/wire-types.d.ts +11 -8
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -2
- package/dist/lane-home-probe.d.ts +112 -0
- package/dist/lane-home-probe.js +101 -0
- package/dist/leader/endpoint.d.ts +4 -1
- package/dist/leader/endpoint.js +11 -10
- package/dist/limit-refusal.d.ts +59 -0
- package/dist/limit-refusal.js +15 -0
- package/dist/main.js +1 -1
- package/dist/mcp-assertion-header.d.ts +32 -19
- package/dist/mcp-assertion-header.js +10 -9
- package/dist/mcp-tool-faces.d.ts +5 -0
- package/dist/mcp-tool-faces.js +6 -4
- package/dist/memory-project-layer.d.ts +37 -0
- package/dist/memory-project-layer.js +46 -0
- package/dist/memory-scope.d.ts +24 -17
- package/dist/memory-scope.js +24 -8
- package/dist/memory-sync-client.d.ts +27 -13
- package/dist/memory-sync-client.js +107 -18
- package/dist/model-entry-refusal.d.ts +9 -1
- package/dist/model-entry-refusal.js +6 -1
- package/dist/model-plane-face.d.ts +51 -0
- package/dist/model-plane-face.js +24 -0
- package/dist/model-provider.d.ts +44 -12
- package/dist/model-provider.js +21 -2
- package/dist/model-route-endpoint.d.ts +9 -12
- package/dist/model-route-endpoint.js +8 -11
- package/dist/model-route-env.d.ts +22 -0
- package/dist/model-route-env.js +2 -0
- package/dist/model-route-gap.d.ts +60 -30
- package/dist/model-route-gap.js +21 -15
- package/dist/observability/corrupt-read-seat.d.ts +7 -0
- package/dist/observability/corrupt-read-seat.js +9 -0
- package/dist/observability/cost-taxonomy.d.ts +7 -7
- package/dist/observability/err-text.d.ts +6 -0
- package/dist/observability/err-text.js +18 -4
- package/dist/observability/fail-open.d.ts +76 -14
- package/dist/observability/fail-open.js +76 -14
- package/dist/observability/metrics.js +4 -1
- package/dist/observability/prompt-manifest.d.ts +33 -82
- package/dist/observability/prompt-manifest.js +122 -17
- package/dist/observability/run-terminal.js +14 -6
- package/dist/observability/secret-env-scrub.d.ts +13 -1
- package/dist/observability/secret-env-scrub.js +13 -1
- package/dist/observability/tool-trace.d.ts +16 -21
- package/dist/observability/tool-trace.js +58 -49
- package/dist/operator-ask.d.ts +10 -0
- package/dist/operator-ask.js +3 -0
- package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
- package/dist/orchestration/workflow-agent-session-index.js +9 -13
- package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
- package/dist/orchestration/workflow-completion-inbox.js +13 -0
- package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
- package/dist/orchestration/workflow-notify-journal.js +27 -34
- package/dist/orchestration/workflow-park-decision.d.ts +89 -0
- package/dist/orchestration/workflow-park-decision.js +118 -0
- package/dist/org-delivery-gate.d.ts +81 -0
- package/dist/org-delivery-gate.js +59 -0
- package/dist/panel-tool-names.d.ts +23 -0
- package/dist/panel-tool-names.js +8 -0
- package/dist/parked-decide.d.ts +39 -6
- package/dist/parked-decide.js +98 -51
- package/dist/parked-revive-surface.d.ts +9 -2
- package/dist/parked-revive-surface.js +11 -8
- package/dist/per-task-image.d.ts +7 -1
- package/dist/per-task-image.js +3 -3
- package/dist/permission-rule-list.d.ts +1 -1
- package/dist/permission-rule-list.js +2 -2
- package/dist/plain-string-record.d.ts +25 -0
- package/dist/plain-string-record.js +32 -0
- package/dist/plugins/approval-ask-store-file.d.ts +16 -1
- package/dist/plugins/approval-ask-store-file.js +21 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
- package/dist/plugins/approval-ask-store-memory.js +34 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
- package/dist/plugins/approval-ask-store-sql.js +37 -1
- package/dist/plugins/blob-backend.d.ts +83 -15
- package/dist/plugins/blob-backend.js +68 -15
- package/dist/plugins/breaker-state-sql.d.ts +2 -2
- package/dist/plugins/breaker-state-sql.js +4 -4
- package/dist/plugins/caching-session-store.d.ts +3 -0
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +28 -4
- package/dist/plugins/checkpoint-store-sql.js +59 -28
- package/dist/plugins/file-history-store-sql.d.ts +5 -2
- package/dist/plugins/file-history-store-sql.js +3 -1
- package/dist/plugins/file-run-store.d.ts +5 -13
- package/dist/plugins/file-run-store.js +9 -0
- package/dist/plugins/fork-routing-session-store.d.ts +9 -1
- package/dist/plugins/fork-routing-session-store.js +12 -1
- package/dist/plugins/host-platform.d.ts +2 -0
- package/dist/plugins/host-platform.js +2 -1
- package/dist/plugins/k8s-bg-scripts.d.ts +11 -0
- package/dist/plugins/k8s-bg-scripts.js +22 -0
- package/dist/plugins/local-checkpoint-store.d.ts +2 -0
- package/dist/plugins/local-checkpoint-store.js +11 -3
- package/dist/plugins/local-session-store.d.ts +1 -1
- package/dist/plugins/local-session-store.js +1 -1
- package/dist/plugins/local-session-window.d.ts +39 -0
- package/dist/plugins/local-session-window.js +54 -0
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
- package/dist/plugins/mailbox-store-sql.d.ts +30 -48
- package/dist/plugins/mailbox-store-sql.js +77 -52
- package/dist/plugins/memory-embedder-fingerprint.js +2 -1
- package/dist/plugins/memory-run-store.d.ts +5 -13
- package/dist/plugins/memory-run-store.js +8 -0
- package/dist/plugins/one-time-migrations.d.ts +245 -93
- package/dist/plugins/one-time-migrations.js +668 -207
- package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
- package/dist/plugins/org-delivery-quota-store.js +228 -0
- package/dist/plugins/permission-rule-store-sql.d.ts +13 -7
- package/dist/plugins/permission-rule-store-sql.js +4 -18
- package/dist/plugins/pg-pool.js +39 -7
- package/dist/plugins/pg-session-storage.d.ts +20 -8
- package/dist/plugins/pg-session-storage.js +34 -21
- package/dist/plugins/remote-env-adb.d.ts +12 -12
- package/dist/plugins/remote-env-adb.js +21 -6
- package/dist/plugins/remote-env-device.js +3 -0
- package/dist/plugins/remote-env-e2b.d.ts +1 -1
- package/dist/plugins/remote-env-e2b.js +21 -9
- package/dist/plugins/remote-env-host.d.ts +9 -9
- package/dist/plugins/remote-env-host.js +10 -32
- package/dist/plugins/remote-env-k8s.d.ts +103 -38
- package/dist/plugins/remote-env-k8s.js +288 -95
- package/dist/plugins/remote-env-local-docker.d.ts +27 -13
- package/dist/plugins/remote-env-local-docker.js +82 -11
- package/dist/plugins/remote-env-ssh.d.ts +21 -12
- package/dist/plugins/remote-env-ssh.js +117 -5
- package/dist/plugins/remote-shell.d.ts +0 -1
- package/dist/plugins/remote-shell.js +1 -2
- package/dist/plugins/retention-store-sql.js +6 -2
- package/dist/plugins/run-store-sql.d.ts +16 -14
- package/dist/plugins/run-store-sql.js +22 -2
- package/dist/plugins/schema-consistency.d.ts +54 -0
- package/dist/plugins/schema-consistency.js +52 -0
- package/dist/plugins/schema-indexes.js +2 -0
- package/dist/plugins/send-user-file.js +2 -2
- package/dist/plugins/session-epoch-anchor.d.ts +39 -0
- package/dist/plugins/session-epoch-anchor.js +22 -0
- package/dist/plugins/session-store.d.ts +18 -8
- package/dist/plugins/session-store.js +15 -4
- package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
- package/dist/plugins/shared-memory-store-sql.js +5 -16
- package/dist/plugins/sql-driver.d.ts +205 -1
- package/dist/plugins/sql-driver.js +325 -13
- package/dist/plugins/sql-errors.d.ts +64 -0
- package/dist/plugins/sql-errors.js +57 -0
- package/dist/plugins/store-backend.d.ts +36 -1
- package/dist/plugins/store-backend.js +42 -15
- package/dist/plugins/store-contracts.d.ts +42 -0
- package/dist/plugins/store-contracts.js +1 -0
- package/dist/plugins/tidb-pool.d.ts +6 -1
- package/dist/plugins/tidb-pool.js +44 -10
- package/dist/plugins/tidb-session-storage.d.ts +8 -11
- package/dist/plugins/tidb-session-storage.js +6 -16
- package/dist/plugins/tidb-session-store.d.ts +24 -4
- package/dist/plugins/tidb-session-store.js +29 -5
- package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
- package/dist/plugins/workflow-journal-store-sql.js +19 -6
- package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
- package/dist/plugins/workflow-run-store-sql.js +50 -9
- package/dist/posture-source.d.ts +18 -10
- package/dist/posture-source.js +4 -1
- package/dist/project-identity.d.ts +45 -6
- package/dist/project-identity.js +162 -8
- package/dist/project-layer-key.d.ts +28 -0
- package/dist/project-layer-key.js +29 -0
- package/dist/prompts-domain-validate.d.ts +17 -61
- package/dist/prompts-domain-validate.js +9 -119
- package/dist/question.js +3 -2
- package/dist/read-deny-entry.d.ts +25 -0
- package/dist/read-deny-entry.js +12 -0
- package/dist/read-face-posture.d.ts +37 -11
- package/dist/read-face-posture.js +32 -3
- package/dist/request-key-closure.d.ts +9 -2
- package/dist/request-key-closure.js +11 -5
- package/dist/request-value-closure.d.ts +5 -0
- package/dist/request-value-closure.js +11 -3
- package/dist/rule-entry-list.d.ts +38 -11
- package/dist/rule-entry-list.js +106 -30
- package/dist/rules-consent.js +3 -4
- package/dist/run-acceptance.d.ts +19 -3
- package/dist/run-acceptance.js +13 -1
- package/dist/run-local.js +54 -24
- package/dist/runs.d.ts +15 -8
- package/dist/runs.js +35 -1
- package/dist/runtime-caps-resolver.d.ts +16 -6
- package/dist/runtime-caps-resolver.js +18 -5
- package/dist/sandbox-pkg-source.d.ts +19 -1
- package/dist/sandbox-pkg-source.js +29 -7
- package/dist/security.d.ts +87 -9
- package/dist/security.js +52 -9
- package/dist/server-secret-env.d.ts +44 -18
- package/dist/server-secret-env.js +49 -8
- package/dist/session-error-wire.d.ts +19 -2
- package/dist/session-error-wire.js +5 -1
- package/dist/session-incarnation.d.ts +15 -5
- package/dist/session-incarnation.js +16 -9
- package/dist/session-titled-frame.d.ts +33 -0
- package/dist/session-titled-frame.js +4 -0
- package/dist/session-titler.d.ts +9 -1
- package/dist/session-titler.js +27 -6
- package/dist/spec-fields.d.ts +28 -16
- package/dist/spec-fields.js +66 -54
- package/dist/sql-engine-posture.d.ts +31 -4
- package/dist/sql-engine-posture.js +36 -1
- package/dist/stored-request-tool-axes-m19.d.ts +19 -4
- package/dist/stored-request-tool-axes-m19.js +30 -2
- package/dist/task-a2a.d.ts +9 -1
- package/dist/task-a2a.js +73 -47
- package/dist/task-cwd.d.ts +1 -1
- package/dist/task-mcp.d.ts +46 -58
- package/dist/task-mcp.js +82 -107
- package/dist/task-settings.d.ts +95 -108
- package/dist/task-settings.js +77 -98
- package/dist/text-bidi.d.ts +1 -48
- package/dist/text-bidi.js +3 -5
- package/dist/tighten-only-seats.d.ts +150 -0
- package/dist/tighten-only-seats.js +196 -0
- package/dist/tool-approval.d.ts +304 -88
- package/dist/tool-approval.js +623 -239
- package/dist/trace/core-keyset-guard.d.ts +122 -20
- package/dist/trace/engine-notice-wire.d.ts +11 -3
- package/dist/trace/engine-notice-wire.js +8 -1
- package/dist/trace/exit-seat.d.ts +28 -0
- package/dist/trace/exit-seat.js +76 -0
- package/dist/trace/ledger-events.d.ts +6 -3
- package/dist/trace/ledger-sink.js +4 -1
- package/dist/trace/model-segment.js +1 -1
- package/dist/trace/project.d.ts +98 -17
- package/dist/trace/project.js +98 -50
- package/dist/trace/projection-table.d.ts +100 -0
- package/dist/trace/projection-table.js +130 -0
- package/dist/trace/redact.d.ts +54 -0
- package/dist/trace/redact.js +778 -152
- package/dist/trace/self-minted-wire.d.ts +345 -1
- package/dist/trace/self-minted-wire.js +117 -1
- package/dist/trace/wire-projection-faces.d.ts +377 -3
- package/dist/trace/wire-projection-faces.js +164 -1
- package/dist/url-refusal.js +2 -0
- package/dist/web-admin-client/apply-effective.d.ts +12 -0
- package/dist/web-admin-client/apply-effective.js +56 -5
- package/dist/web-admin-client/candidate-gate.d.ts +6 -6
- package/dist/web-admin-client/candidate-gate.js +3 -3
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/facade.js +1 -1
- package/dist/web-admin-client/http-client.js +0 -6
- package/dist/web-admin-client/read-face.js +5 -9
- package/dist/web-admin-client/read-warnings.d.ts +13 -0
- package/dist/web-admin-client/read-warnings.js +10 -0
- package/dist/web-admin-client/skills-mcp.d.ts +3 -0
- package/dist/web-admin-client/skills-mcp.js +11 -9
- package/dist/web-admin-client/types.d.ts +2 -3
- package/dist/workspace-cache.d.ts +35 -0
- package/dist/workspace-cache.js +36 -0
- package/dist/workspace-space.d.ts +3 -2
- package/dist/workspace-space.js +2 -0
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +65 -10
- package/package.json +8 -4
- package/scripts/drain-check-local.mjs +34 -1
- package/scripts/drain-check.mysql.sql +30 -2
- package/scripts/drain-check.pg.sql +29 -2
- package/dist/capabilities/memory-notice.d.ts +0 -138
- package/dist/capabilities/memory-notice.js +0 -64
- package/dist/capabilities/prompt.d.ts +0 -17
- package/dist/capabilities/prompt.js +0 -6
- package/dist/mcp-content-origin.d.ts +0 -34
- package/dist/mcp-content-origin.js +0 -10
- package/dist/tool-axis-words.d.ts +0 -27
- package/dist/tool-axis-words.js +0 -9
- package/dist/wire-name-bound.d.ts +0 -14
- package/dist/wire-name-bound.js +0 -13
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { Pool as MysqlPool } from "mysql2/promise";
|
|
2
|
+
import type { Pool as PgPool } from "pg";
|
|
3
|
+
import { type SqlDriver } from "./sql-driver.js";
|
|
4
|
+
/** 发件人行表(单数形;`test/schema-naming-invariants.test.ts` 的闭集词表钉着)。 */
|
|
5
|
+
export declare const ORG_DELIVERY_SENDER_QUOTA_TABLE = "org_delivery_sender_quota";
|
|
6
|
+
/** 收件人行表。 */
|
|
7
|
+
export declare const ORG_DELIVERY_RECIPIENT_QUOTA_TABLE = "org_delivery_recipient_quota";
|
|
8
|
+
/** 对偶行表。 */
|
|
9
|
+
export declare const ORG_DELIVERY_PAIR_QUOTA_TABLE = "org_delivery_pair_quota";
|
|
10
|
+
/** 门用的那份额度。门持有它(唯一的数字源在 `org-delivery-gate.ts`),店只按它数。 */
|
|
11
|
+
export interface OrgDeliveryQuotaPolicy {
|
|
12
|
+
/** 固定窗宽(毫秒)。 */
|
|
13
|
+
readonly windowMs: number;
|
|
14
|
+
/** 一个发件人在一个窗里能做的投递尝试数上界(成没成都算)。 */
|
|
15
|
+
readonly attemptsPerSender: number;
|
|
16
|
+
/** 同一个发件人在一个窗里能投给同一个收件人的封数上界。 */
|
|
17
|
+
readonly perPair: number;
|
|
18
|
+
/** 一个收件人在一个窗里能收的封数上界(全部发件人合计)。 */
|
|
19
|
+
readonly perRecipient: number;
|
|
20
|
+
}
|
|
21
|
+
export interface OrgDeliveryQuotaStore {
|
|
22
|
+
/**
|
|
23
|
+
* 原子地把这位发件人的一次投递**尝试**算进店钟当前窗:未满 ⇒ +1、答 `true`;已满 ⇒ 什么都不记、答 `false`。
|
|
24
|
+
* 店读不出 / 写不进 ⇒ **抛**(调用方按失败处置,绝不当成「放行」)。
|
|
25
|
+
*/
|
|
26
|
+
admitAttempt(fromScope: string, policy: OrgDeliveryQuotaPolicy): Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* 原子地把一封 (fromScope → toScope) 的信算进**店钟当前窗**的两只计数器:两界都未满 ⇒ 两只各 +1、答 `true`;
|
|
29
|
+
* 任一界已满 ⇒ 什么都不记、答 `false`。店读不出 / 写不进 ⇒ **抛**。
|
|
30
|
+
*/
|
|
31
|
+
take(fromScope: string, toScope: string, policy: OrgDeliveryQuotaPolicy): Promise<boolean>;
|
|
32
|
+
}
|
|
33
|
+
/** 窗起点(一处算法,三条腿共用)。 */
|
|
34
|
+
export declare function quotaWindowStart(nowMs: number, windowMs: number): number;
|
|
35
|
+
/** 店里记着的那个窗(`heldStart`)的计数此刻还算不算数 —— 头注那条律的**唯一**写法:此刻的窗,或此刻的下一个窗。 */
|
|
36
|
+
export declare function heldWindowCounts(heldStart: number, at: number, windowMs: number): boolean;
|
|
37
|
+
/** 一位发件人的当前窗(`windowMs` = 开窗那一次的窗宽:窗何时结束是条目自己的事实,File 腿据它丢已过窗的条目)。 */
|
|
38
|
+
interface SenderWindow {
|
|
39
|
+
windowStart: number;
|
|
40
|
+
windowMs: number;
|
|
41
|
+
attempts: number;
|
|
42
|
+
}
|
|
43
|
+
/** 一位收件人的当前窗。 */
|
|
44
|
+
interface RecipientWindow {
|
|
45
|
+
windowStart: number;
|
|
46
|
+
windowMs: number;
|
|
47
|
+
total: number;
|
|
48
|
+
/** fromScope → 本窗已投封数。 */
|
|
49
|
+
pairs: Map<string, number>;
|
|
50
|
+
}
|
|
51
|
+
/** 两张窗表(Memory 腿的全部状态;File 腿整份落盘的就是它)。 */
|
|
52
|
+
interface QuotaWindows {
|
|
53
|
+
senders: Map<string, SenderWindow>;
|
|
54
|
+
recipients: Map<string, RecipientWindow>;
|
|
55
|
+
}
|
|
56
|
+
export declare class MemoryOrgDeliveryQuotaStore implements OrgDeliveryQuotaStore {
|
|
57
|
+
protected readonly nowMs: () => number;
|
|
58
|
+
protected state: QuotaWindows;
|
|
59
|
+
/** @param nowMs 店钟(单进程腿:店 = 这个进程,缺省本进程墙钟)。 */
|
|
60
|
+
constructor(nowMs?: () => number);
|
|
61
|
+
admitAttempt(fromScope: string, policy: OrgDeliveryQuotaPolicy): Promise<boolean>;
|
|
62
|
+
take(fromScope: string, toScope: string, policy: OrgDeliveryQuotaPolicy): Promise<boolean>;
|
|
63
|
+
/**
|
|
64
|
+
* 落新的整份状态,只留窗还没结束的条目(按条目自己的窗宽判;已结束的发件人 / 收件人整个丢掉 —— 有界:量 = 本窗活跃的主体数)。
|
|
65
|
+
* 丢掉的条目按头注那条律本来就不再算数(过去的窗),所以剪枝不改任何判决;剪枝写在**这里**而不是 File 腿里,Memory 与 File
|
|
66
|
+
* 因此对同一串记账逐笔同判(墙钟回拨的那一形也同判)。File 腿覆写 {@link persist}:先落盘、再换内存(反过来的话,一次写盘失败
|
|
67
|
+
* 会留下「内存记了、盘上没有」)。
|
|
68
|
+
*/
|
|
69
|
+
protected commit(next: QuotaWindows): void;
|
|
70
|
+
/** Memory 腿无盘可落。 */
|
|
71
|
+
protected persist(_next: QuotaWindows): void;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* local 车道的配额店:Memory 腿的同一份算法 + 每次记账后**整份原子改写**一个 JSON 快照(`atomicWriteFile`:
|
|
75
|
+
* 同盘临时文件 + rename,崩溃只会留下旧的或新的整份,不会留半份)。
|
|
76
|
+
*
|
|
77
|
+
* 为什么是整份快照而不是追加日志:快照只装「当前窗」(写入时顺手丢掉已过窗的发件人 / 收件人),量 = 本窗活跃的主体数,
|
|
78
|
+
* 每次记账改写一次的代价与它同阶;追加日志则要再带一套压实与断尾规则。记账频次本来就被本店自己界住。
|
|
79
|
+
*
|
|
80
|
+
* 🔴 读不出的快照 ⇒ **拒用**(fail-closed,响亮):每一次记账都抛,出路在拒句里(移开文件 = 本窗计数清零)。
|
|
81
|
+
* 跳过坏文件当成「没记过」= 一次位腐就把整个配额窗放开,那是放行方向的静默降级。
|
|
82
|
+
*/
|
|
83
|
+
export declare class FileOrgDeliveryQuotaStore extends MemoryOrgDeliveryQuotaStore {
|
|
84
|
+
private readonly path;
|
|
85
|
+
private readonly tmpDir;
|
|
86
|
+
/** 快照读不出时的拒句(在场 ⇒ 店拒用)。 */
|
|
87
|
+
private readonly unusable;
|
|
88
|
+
constructor(root: string, opts?: {
|
|
89
|
+
nowMs?: () => number;
|
|
90
|
+
warn?: (event: string, fields: Record<string, unknown>) => void;
|
|
91
|
+
});
|
|
92
|
+
admitAttempt(fromScope: string, policy: OrgDeliveryQuotaPolicy): Promise<boolean>;
|
|
93
|
+
take(fromScope: string, toScope: string, policy: OrgDeliveryQuotaPolicy): Promise<boolean>;
|
|
94
|
+
protected persist(next: QuotaWindows): void;
|
|
95
|
+
}
|
|
96
|
+
export declare class SqlOrgDeliveryQuotaStore implements OrgDeliveryQuotaStore {
|
|
97
|
+
private readonly db;
|
|
98
|
+
constructor(db: SqlDriver);
|
|
99
|
+
private q;
|
|
100
|
+
admitAttempt(fromScope: string, policy: OrgDeliveryQuotaPolicy): Promise<boolean>;
|
|
101
|
+
take(fromScope: string, toScope: string, policy: OrgDeliveryQuotaPolicy): Promise<boolean>;
|
|
102
|
+
/**
|
|
103
|
+
* 一个记账事务:库钟先读(池上一条值语句,不在事务里留普通 SELECT),判过 ⇒ 提交,判拒 ⇒ 回滚(零残留)。
|
|
104
|
+
* 🔴 **引擎判了死锁 ⇒ 整事务重来**(有界,`isDeadlockError` 是全仓唯一的可重试锁故障判据):被挑中的一方已整事务回滚、锁全放,
|
|
105
|
+
* 重来时读-判-写全部重做,语义等价。真 InnoDB(REPEATABLE READ)上这条路是真的:窗前进时按收件人前缀删旧对偶行要取范围 / 间隙锁,
|
|
106
|
+
* 两位相邻收件人同时翻窗、各自往两人之间的间隙里插新对偶行 ⇒ 互等(TiDB 无间隙锁、PG 读已提交不取间隙锁)。谁当牺牲者是引擎的任意选择,
|
|
107
|
+
* 抛给调用方等于把一次内部仲裁当成投递失败。锁等待超时**不**重来(延迟信号,照抛)。
|
|
108
|
+
*/
|
|
109
|
+
private inTx;
|
|
110
|
+
private inTxOnce;
|
|
111
|
+
private admitIn;
|
|
112
|
+
private takeIn;
|
|
113
|
+
}
|
|
114
|
+
/** MySQL 协议腿的构造绑定。 */
|
|
115
|
+
export declare class TiDBOrgDeliveryQuotaStore extends SqlOrgDeliveryQuotaStore {
|
|
116
|
+
constructor(pool: MysqlPool);
|
|
117
|
+
}
|
|
118
|
+
/** PostgreSQL 腿的构造绑定。 */
|
|
119
|
+
export declare class PgOrgDeliveryQuotaStore extends SqlOrgDeliveryQuotaStore {
|
|
120
|
+
constructor(pool: PgPool);
|
|
121
|
+
}
|
|
122
|
+
export {};
|
|
123
|
+
//# sourceMappingURL=org-delivery-quota-store.d.ts.map
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { atomicWriteFile, ensureDir } from "@sema-agent/core";
|
|
4
|
+
import { mysqlDriver, pgDriver, sqlDbNowMs } from "./sql-driver.js";
|
|
5
|
+
import { isDeadlockError } from "./sql-errors.js";
|
|
6
|
+
import { alignedWindow } from "../observability/cost-quota.js";
|
|
7
|
+
export const ORG_DELIVERY_SENDER_QUOTA_TABLE = "org_delivery_sender_quota";
|
|
8
|
+
export const ORG_DELIVERY_RECIPIENT_QUOTA_TABLE = "org_delivery_recipient_quota";
|
|
9
|
+
export const ORG_DELIVERY_PAIR_QUOTA_TABLE = "org_delivery_pair_quota";
|
|
10
|
+
export function quotaWindowStart(nowMs, windowMs) {
|
|
11
|
+
return alignedWindow(nowMs, windowMs).bucket * windowMs;
|
|
12
|
+
}
|
|
13
|
+
export function heldWindowCounts(heldStart, at, windowMs) {
|
|
14
|
+
return heldStart === at || heldStart === at + windowMs;
|
|
15
|
+
}
|
|
16
|
+
export class MemoryOrgDeliveryQuotaStore {
|
|
17
|
+
nowMs;
|
|
18
|
+
state = { senders: new Map(), recipients: new Map() };
|
|
19
|
+
constructor(nowMs = Date.now) {
|
|
20
|
+
this.nowMs = nowMs;
|
|
21
|
+
}
|
|
22
|
+
async admitAttempt(fromScope, policy) {
|
|
23
|
+
const at = quotaWindowStart(this.nowMs(), policy.windowMs);
|
|
24
|
+
const held = this.state.senders.get(fromScope);
|
|
25
|
+
const current = held !== undefined && heldWindowCounts(held.windowStart, at, policy.windowMs) ? held : { windowStart: at, windowMs: policy.windowMs, attempts: 0 };
|
|
26
|
+
if (current.attempts >= policy.attemptsPerSender)
|
|
27
|
+
return false;
|
|
28
|
+
const senders = new Map(this.state.senders).set(fromScope, { ...current, attempts: current.attempts + 1 });
|
|
29
|
+
this.commit({ senders, recipients: this.state.recipients });
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
async take(fromScope, toScope, policy) {
|
|
33
|
+
const at = quotaWindowStart(this.nowMs(), policy.windowMs);
|
|
34
|
+
const held = this.state.recipients.get(toScope);
|
|
35
|
+
const current = held !== undefined && heldWindowCounts(held.windowStart, at, policy.windowMs) ? held : { windowStart: at, windowMs: policy.windowMs, total: 0, pairs: new Map() };
|
|
36
|
+
const pair = current.pairs.get(fromScope) ?? 0;
|
|
37
|
+
if (current.total >= policy.perRecipient || pair >= policy.perPair)
|
|
38
|
+
return false;
|
|
39
|
+
const next = { ...current, total: current.total + 1, pairs: new Map(current.pairs).set(fromScope, pair + 1) };
|
|
40
|
+
this.commit({ senders: this.state.senders, recipients: new Map(this.state.recipients).set(toScope, next) });
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
commit(next) {
|
|
44
|
+
const now = this.nowMs();
|
|
45
|
+
const live = (m) => new Map([...m].filter(([, w]) => w.windowStart + w.windowMs > now));
|
|
46
|
+
const pruned = { senders: live(next.senders), recipients: live(next.recipients) };
|
|
47
|
+
this.persist(pruned);
|
|
48
|
+
this.state = pruned;
|
|
49
|
+
}
|
|
50
|
+
persist(_next) { }
|
|
51
|
+
}
|
|
52
|
+
const isCount = (x) => typeof x === "number" && Number.isInteger(x) && x >= 0;
|
|
53
|
+
const isWidth = (x) => isCount(x) && x > 0;
|
|
54
|
+
const isPlain = (x) => x !== null && typeof x === "object" && !Array.isArray(x) && Object.getPrototypeOf(x) === Object.prototype;
|
|
55
|
+
function readSnapshot(raw) {
|
|
56
|
+
if (!isPlain(raw) || raw.v !== 1 || !isPlain(raw.senders) || !isPlain(raw.recipients))
|
|
57
|
+
return { ok: false, problem: "expected { v: 1, senders: {…}, recipients: {…} }" };
|
|
58
|
+
const senders = new Map();
|
|
59
|
+
for (const [from, entry] of Object.entries(raw.senders)) {
|
|
60
|
+
if (!isPlain(entry) || !isCount(entry.w) || !isWidth(entry.ms) || !isCount(entry.n))
|
|
61
|
+
return { ok: false, problem: `sender ${JSON.stringify(from)} is not { w, ms, n }` };
|
|
62
|
+
senders.set(from, { windowStart: entry.w, windowMs: entry.ms, attempts: entry.n });
|
|
63
|
+
}
|
|
64
|
+
const recipients = new Map();
|
|
65
|
+
for (const [to, entry] of Object.entries(raw.recipients)) {
|
|
66
|
+
if (!isPlain(entry) || !isCount(entry.w) || !isWidth(entry.ms) || !isCount(entry.n) || !isPlain(entry.pairs))
|
|
67
|
+
return { ok: false, problem: `recipient ${JSON.stringify(to)} is not { w, ms, n, pairs }` };
|
|
68
|
+
const pairs = new Map();
|
|
69
|
+
for (const [from, n] of Object.entries(entry.pairs)) {
|
|
70
|
+
if (!isCount(n))
|
|
71
|
+
return { ok: false, problem: `pair ${JSON.stringify([to, from])} is not a count` };
|
|
72
|
+
pairs.set(from, n);
|
|
73
|
+
}
|
|
74
|
+
recipients.set(to, { windowStart: entry.w, windowMs: entry.ms, total: entry.n, pairs });
|
|
75
|
+
}
|
|
76
|
+
return { ok: true, state: { senders, recipients } };
|
|
77
|
+
}
|
|
78
|
+
export class FileOrgDeliveryQuotaStore extends MemoryOrgDeliveryQuotaStore {
|
|
79
|
+
path;
|
|
80
|
+
tmpDir;
|
|
81
|
+
unusable;
|
|
82
|
+
constructor(root, opts) {
|
|
83
|
+
super(opts?.nowMs);
|
|
84
|
+
const dir = join(root, "org-delivery-quota");
|
|
85
|
+
ensureDir(dir);
|
|
86
|
+
this.tmpDir = join(dir, ".tmp");
|
|
87
|
+
ensureDir(this.tmpDir);
|
|
88
|
+
this.path = join(dir, "windows.json");
|
|
89
|
+
if (!existsSync(this.path))
|
|
90
|
+
return;
|
|
91
|
+
let parsed;
|
|
92
|
+
try {
|
|
93
|
+
parsed = readSnapshot(JSON.parse(readFileSync(this.path, "utf8")));
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
parsed = { ok: false, problem: err instanceof Error ? err.message : String(err) };
|
|
97
|
+
}
|
|
98
|
+
if (!parsed.ok) {
|
|
99
|
+
this.unusable = `the cross-principal delivery quota file ${this.path} cannot be read (${parsed.problem}) — every delivery is refused until an operator moves it away (moving it resets the current window's counts)`;
|
|
100
|
+
(opts?.warn ?? ((event, fields) => console.warn(event, fields)))("org_delivery_quota_corrupt_read", { path: this.path, problem: parsed.problem });
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
this.state = parsed.state;
|
|
104
|
+
}
|
|
105
|
+
async admitAttempt(fromScope, policy) {
|
|
106
|
+
if (this.unusable !== undefined)
|
|
107
|
+
throw new Error(this.unusable);
|
|
108
|
+
return super.admitAttempt(fromScope, policy);
|
|
109
|
+
}
|
|
110
|
+
async take(fromScope, toScope, policy) {
|
|
111
|
+
if (this.unusable !== undefined)
|
|
112
|
+
throw new Error(this.unusable);
|
|
113
|
+
return super.take(fromScope, toScope, policy);
|
|
114
|
+
}
|
|
115
|
+
persist(next) {
|
|
116
|
+
const { senders, recipients } = next;
|
|
117
|
+
const snapshot = {
|
|
118
|
+
v: 1,
|
|
119
|
+
senders: Object.fromEntries([...senders].map(([from, w]) => [from, { w: w.windowStart, ms: w.windowMs, n: w.attempts }])),
|
|
120
|
+
recipients: Object.fromEntries([...recipients].map(([to, w]) => [to, { w: w.windowStart, ms: w.windowMs, n: w.total, pairs: Object.fromEntries(w.pairs) }])),
|
|
121
|
+
};
|
|
122
|
+
atomicWriteFile(this.tmpDir, this.path, `${JSON.stringify(snapshot)}\n`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const DEADLOCK_RETRY_LIMIT = 3;
|
|
126
|
+
export class SqlOrgDeliveryQuotaStore {
|
|
127
|
+
db;
|
|
128
|
+
constructor(db) {
|
|
129
|
+
this.db = db;
|
|
130
|
+
}
|
|
131
|
+
q(tidb, pg) {
|
|
132
|
+
return this.db.dialect === "tidb" ? tidb : pg;
|
|
133
|
+
}
|
|
134
|
+
async admitAttempt(fromScope, policy) {
|
|
135
|
+
return this.inTx(ORG_DELIVERY_SENDER_QUOTA_TABLE, policy, (conn, at) => this.admitIn(conn, fromScope, at, policy));
|
|
136
|
+
}
|
|
137
|
+
async take(fromScope, toScope, policy) {
|
|
138
|
+
return this.inTx(ORG_DELIVERY_RECIPIENT_QUOTA_TABLE, policy, (conn, at) => this.takeIn(conn, fromScope, toScope, at, policy));
|
|
139
|
+
}
|
|
140
|
+
async inTx(table, policy, body) {
|
|
141
|
+
for (let tries = 0;; tries++) {
|
|
142
|
+
try {
|
|
143
|
+
return await this.inTxOnce(table, policy, body);
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
if (tries < DEADLOCK_RETRY_LIMIT && isDeadlockError(this.db.dialect, err))
|
|
147
|
+
continue;
|
|
148
|
+
throw err;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async inTxOnce(table, policy, body) {
|
|
153
|
+
const at = quotaWindowStart(await sqlDbNowMs(this.db, table), policy.windowMs);
|
|
154
|
+
const conn = await this.db.connect();
|
|
155
|
+
try {
|
|
156
|
+
await conn.begin();
|
|
157
|
+
const granted = await body(conn, at);
|
|
158
|
+
if (granted)
|
|
159
|
+
await conn.commit();
|
|
160
|
+
else
|
|
161
|
+
await conn.rollback();
|
|
162
|
+
return granted;
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
await conn.rollback().catch((rollbackErr) => {
|
|
166
|
+
throw new AggregateError([err, rollbackErr], `${table}: the quota transaction failed and its rollback failed too`);
|
|
167
|
+
});
|
|
168
|
+
throw err;
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
conn.release();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async admitIn(conn, fromScope, at, policy) {
|
|
175
|
+
const S = ORG_DELIVERY_SENDER_QUOTA_TABLE;
|
|
176
|
+
await conn.query(this.q(`INSERT INTO ${S} (from_scope, window_start_ms, attempts) VALUES (?, ?, 0) ON DUPLICATE KEY UPDATE from_scope = from_scope`, `INSERT INTO ${S} (from_scope, window_start_ms, attempts) VALUES ($1, $2, 0) ON CONFLICT (from_scope) DO NOTHING`), [fromScope, at]);
|
|
177
|
+
const { rows } = await conn.query(this.q(`SELECT window_start_ms, attempts FROM ${S} WHERE from_scope = ? FOR UPDATE`, `SELECT window_start_ms, attempts FROM ${S} WHERE from_scope = $1 FOR UPDATE`), [fromScope]);
|
|
178
|
+
const held = rows[0];
|
|
179
|
+
if (held === undefined)
|
|
180
|
+
throw new Error(`${S}: the sender row for ${JSON.stringify(fromScope)} vanished inside its own transaction`);
|
|
181
|
+
const heldStart = Number(held.window_start_ms);
|
|
182
|
+
const counts = heldWindowCounts(heldStart, at, policy.windowMs);
|
|
183
|
+
const windowStart = counts ? heldStart : at;
|
|
184
|
+
const attempts = counts ? Number(held.attempts) : 0;
|
|
185
|
+
if (attempts >= policy.attemptsPerSender)
|
|
186
|
+
return false;
|
|
187
|
+
await conn.query(this.q(`UPDATE ${S} SET window_start_ms = ?, attempts = ? WHERE from_scope = ?`, `UPDATE ${S} SET window_start_ms = $1, attempts = $2 WHERE from_scope = $3`), [windowStart, attempts + 1, fromScope]);
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
async takeIn(conn, fromScope, toScope, at, policy) {
|
|
191
|
+
const R = ORG_DELIVERY_RECIPIENT_QUOTA_TABLE;
|
|
192
|
+
const P = ORG_DELIVERY_PAIR_QUOTA_TABLE;
|
|
193
|
+
await conn.query(this.q(`INSERT INTO ${R} (to_scope, window_start_ms, delivered) VALUES (?, ?, 0) ON DUPLICATE KEY UPDATE to_scope = to_scope`, `INSERT INTO ${R} (to_scope, window_start_ms, delivered) VALUES ($1, $2, 0) ON CONFLICT (to_scope) DO NOTHING`), [toScope, at]);
|
|
194
|
+
const { rows: rr } = await conn.query(this.q(`SELECT window_start_ms, delivered FROM ${R} WHERE to_scope = ? FOR UPDATE`, `SELECT window_start_ms, delivered FROM ${R} WHERE to_scope = $1 FOR UPDATE`), [toScope]);
|
|
195
|
+
const held = rr[0];
|
|
196
|
+
if (held === undefined)
|
|
197
|
+
throw new Error(`${R}: the recipient row for ${JSON.stringify(toScope)} vanished inside its own transaction`);
|
|
198
|
+
const heldStart = Number(held.window_start_ms);
|
|
199
|
+
const rolls = !heldWindowCounts(heldStart, at, policy.windowMs);
|
|
200
|
+
const windowStart = rolls ? at : heldStart;
|
|
201
|
+
const total = rolls ? 0 : Number(held.delivered);
|
|
202
|
+
if (rolls) {
|
|
203
|
+
await conn.query(this.q(`DELETE FROM ${P} WHERE to_scope = ? AND window_start_ms <> ?`, `DELETE FROM ${P} WHERE to_scope = $1 AND window_start_ms <> $2`), [toScope, windowStart]);
|
|
204
|
+
}
|
|
205
|
+
await conn.query(this.q(`INSERT INTO ${P} (to_scope, from_scope, window_start_ms, delivered) VALUES (?, ?, ?, 0) ON DUPLICATE KEY UPDATE to_scope = to_scope`, `INSERT INTO ${P} (to_scope, from_scope, window_start_ms, delivered) VALUES ($1, $2, $3, 0) ON CONFLICT (to_scope, from_scope) DO NOTHING`), [toScope, fromScope, windowStart]);
|
|
206
|
+
const { rows: pr } = await conn.query(this.q(`SELECT window_start_ms, delivered FROM ${P} WHERE to_scope = ? AND from_scope = ? FOR UPDATE`, `SELECT window_start_ms, delivered FROM ${P} WHERE to_scope = $1 AND from_scope = $2 FOR UPDATE`), [toScope, fromScope]);
|
|
207
|
+
const pairRow = pr[0];
|
|
208
|
+
if (pairRow === undefined)
|
|
209
|
+
throw new Error(`${P}: the pair row for ${JSON.stringify([toScope, fromScope])} vanished inside its own transaction`);
|
|
210
|
+
const pair = Number(pairRow.window_start_ms) === windowStart ? Number(pairRow.delivered) : 0;
|
|
211
|
+
if (total >= policy.perRecipient || pair >= policy.perPair)
|
|
212
|
+
return false;
|
|
213
|
+
await conn.query(this.q(`UPDATE ${R} SET window_start_ms = ?, delivered = ? WHERE to_scope = ?`, `UPDATE ${R} SET window_start_ms = $1, delivered = $2 WHERE to_scope = $3`), [windowStart, total + 1, toScope]);
|
|
214
|
+
await conn.query(this.q(`UPDATE ${P} SET window_start_ms = ?, delivered = ? WHERE to_scope = ? AND from_scope = ?`, `UPDATE ${P} SET window_start_ms = $1, delivered = $2 WHERE to_scope = $3 AND from_scope = $4`), [windowStart, pair + 1, toScope, fromScope]);
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
export class TiDBOrgDeliveryQuotaStore extends SqlOrgDeliveryQuotaStore {
|
|
219
|
+
constructor(pool) {
|
|
220
|
+
super(mysqlDriver(pool));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
export class PgOrgDeliveryQuotaStore extends SqlOrgDeliveryQuotaStore {
|
|
224
|
+
constructor(pool) {
|
|
225
|
+
super(pgDriver(pool));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=org-delivery-quota-store.js.map
|
|
@@ -437,13 +437,17 @@ export interface UnreadableRuleBucket {
|
|
|
437
437
|
readonly ownerKey: string;
|
|
438
438
|
readonly why: string;
|
|
439
439
|
}
|
|
440
|
-
/**
|
|
441
|
-
|
|
442
|
-
|
|
440
|
+
/**
|
|
441
|
+
* M11 写进的读数账 —— 三格与一次性迁移段那一只收据账(`one-time-migrations.ts` 的 `MigrationReceipts`)上的同名三格**同名同形**,迁移段把它的账直接递进来
|
|
442
|
+
* (S-1594:一次起服一只收据账,M11 不另起第二套):删掉的行在那只桶的回写**提交的那一刻**追加,之后任何一步失败,拒因随账带走它们。
|
|
443
|
+
*/
|
|
444
|
+
export interface UndurableScopePurgeReadings {
|
|
445
|
+
/** 删掉的行(一行一条读数;每只桶的回写提交之后才追加)。 */
|
|
446
|
+
readonly undurableScopeRuleRows: UndurableScopeRuleRow[];
|
|
443
447
|
/** 连续争不过在线写者(OCC 每次都输)而留到下一次起服的桶数。那些桶里的坏行这期间照旧由引擎读侧丢掉并告知。 */
|
|
444
|
-
|
|
448
|
+
undurableScopeRuleBucketsDeferred: number;
|
|
445
449
|
/** 读腿整桶拒的桶(形 / 指纹 / behavior 闭集 / 墓碑规范文本 / 单一验证器):一个字节不动,逐桶交出拒因,等人处置。 */
|
|
446
|
-
readonly
|
|
450
|
+
readonly undurableScopeRuleBucketsUnreadable: UnreadableRuleBucket[];
|
|
447
451
|
}
|
|
448
452
|
/** {@link purgeUndurableScopeRows} 要的最小查询口(一次性迁移段的 `MigrationDb` 同形;占位符按方言由本函数写)。 */
|
|
449
453
|
export interface UndurableScopePurgeDb {
|
|
@@ -458,13 +462,15 @@ export interface UndurableScopePurgeDb {
|
|
|
458
462
|
* 而撤销口删不动它(引擎的写臂对这种 scope 的墓碑同样拒)。⇒ 一次性迁移,不留「撤销口对坏 scope 另开一条读法」的长期双读。
|
|
459
463
|
*
|
|
460
464
|
* 读法与写法都是**店的那一只**:每只桶先过唯一判官 {@link decodeBucketRow}(读腿用的同一只),判官整桶拒 ⇒ 这只桶**一个字节不动**,
|
|
461
|
-
* 进 `
|
|
465
|
+
* 进 `undurableScopeRuleBucketsUnreadable`(桶键 + 不带行内容的拒因;读腿对它的整桶拒仍是它的属主,出路是人);判官放行 ⇒ 在那份合法状态上筛 scope,
|
|
462
466
|
* 经写臂的同一只 {@link writeBucket} 整桶 OCC 回写(`WHERE owner_key = ? AND rev = ?`,rev+1,落盘字节与指纹同写臂)—— 不碰别的桶。
|
|
463
467
|
* **硬删、不铸墓碑**:墓碑的作用是挡同步回灌,而引擎的 sync-join 对 scope 不合法的入站行本来就丢(`applySyncJoin`),
|
|
464
468
|
* 本店也不实现同步(见 `apply` 的 sync-join 臂)。
|
|
465
469
|
* 幂等:第二跑零命中零写(读不出的桶每一跑照报,直到有人处置)。
|
|
470
|
+
* 读数写进调用方递进来的账(`into`,{@link UndurableScopePurgeReadings}):删掉的行在那只桶的回写提交之后追加 ⇒ 本函数半途抛出时,已删的行已经在账上;
|
|
471
|
+
* 错误**原样**上抛(不加工、不自铸拒因句 —— 收据由迁移段那一只收据账随拒因带走,S-1594)。
|
|
466
472
|
*/
|
|
467
|
-
export declare function purgeUndurableScopeRows(db: UndurableScopePurgeDb, dialect: "tidb" | "pg", now?: () => number): Promise<
|
|
473
|
+
export declare function purgeUndurableScopeRows(db: UndurableScopePurgeDb, dialect: "tidb" | "pg", into: UndurableScopePurgeReadings, now?: () => number): Promise<void>;
|
|
468
474
|
/** 三个 SQL 面的一次性装配束(one driver, three faces)。`durable` = [ref] 的 durable 分区后端;
|
|
469
475
|
* 引擎接缝上的统一店由 `main.ts` 用 `createPermissionRuleStoreProvider({ durable })` 合成一次。 */
|
|
470
476
|
export interface PermissionRuleStores {
|
|
@@ -783,21 +783,7 @@ export const RULE_PENDING_APPROVAL_RETENTION_MS = 24 * 60 * 60_000;
|
|
|
783
783
|
export const RULE_REAP_BATCH = 500;
|
|
784
784
|
const UNDURABLE_PURGE_PAGE = 200;
|
|
785
785
|
const UNDURABLE_PURGE_OCC_ATTEMPTS = 5;
|
|
786
|
-
export async function purgeUndurableScopeRows(db, dialect, now = Date.now) {
|
|
787
|
-
const acc = { removed: [], bucketsDeferred: 0, bucketsUnreadable: [] };
|
|
788
|
-
try {
|
|
789
|
-
await purgeAllBuckets(db, dialect, now, acc);
|
|
790
|
-
}
|
|
791
|
-
catch (e) {
|
|
792
|
-
if (acc.removed.length === 0)
|
|
793
|
-
throw e;
|
|
794
|
-
throw new Error(`the one-time removal of persisted permission rules whose scope the engine refuses failed AFTER removing ${acc.removed.length} row(s) — record them before retrying: ` +
|
|
795
|
-
acc.removed.map((r) => `${r.kind} in bucket ${r.ownerKey} (${r.behavior} ${r.tool}, scope root ${JSON.stringify(r.scopeRoot)})`).join("; ") +
|
|
796
|
-
`. Underlying failure: ${e instanceof Error ? e.message : String(e)}`, { cause: e });
|
|
797
|
-
}
|
|
798
|
-
return acc;
|
|
799
|
-
}
|
|
800
|
-
async function purgeAllBuckets(db, dialect, now, acc) {
|
|
786
|
+
export async function purgeUndurableScopeRows(db, dialect, into, now = Date.now) {
|
|
801
787
|
const cols = `owner_key, ${bucketRowColumns(dialect)}`;
|
|
802
788
|
let after = "";
|
|
803
789
|
for (;;) {
|
|
@@ -813,11 +799,11 @@ async function purgeAllBuckets(db, dialect, now, acc) {
|
|
|
813
799
|
const outcome = await purgeOneBucket(db, dialect, ownerKey, row, now);
|
|
814
800
|
switch (outcome.kind) {
|
|
815
801
|
case "purged":
|
|
816
|
-
|
|
802
|
+
into.undurableScopeRuleRows.push(...outcome.rows);
|
|
817
803
|
settled = true;
|
|
818
804
|
break;
|
|
819
805
|
case "unreadable":
|
|
820
|
-
|
|
806
|
+
into.undurableScopeRuleBucketsUnreadable.push({ ownerKey, why: outcome.why });
|
|
821
807
|
settled = true;
|
|
822
808
|
break;
|
|
823
809
|
case "clean":
|
|
@@ -835,7 +821,7 @@ async function purgeAllBuckets(db, dialect, now, acc) {
|
|
|
835
821
|
}
|
|
836
822
|
}
|
|
837
823
|
if (!settled)
|
|
838
|
-
|
|
824
|
+
into.undurableScopeRuleBucketsDeferred += 1;
|
|
839
825
|
}
|
|
840
826
|
if (page.length < UNDURABLE_PURGE_PAGE)
|
|
841
827
|
break;
|
package/dist/plugins/pg-pool.js
CHANGED
|
@@ -19,6 +19,7 @@ import { ensurePgRetentionSchema } from "./retention-store-sql.js";
|
|
|
19
19
|
import { ensureIndexes } from "./ensure-index.js";
|
|
20
20
|
import { SESSION_RULES_COLUMN } from "./session-rules-column.js";
|
|
21
21
|
import { CENTRAL_SCHEMA_INDEXES } from "./schema-indexes.js";
|
|
22
|
+
import { PRINCIPAL_MAX_LENGTH } from "../security.js";
|
|
22
23
|
export const PG_SCHEMA_STATEMENTS = [
|
|
23
24
|
`CREATE TABLE IF NOT EXISTS task_run (
|
|
24
25
|
task_id VARCHAR(64) COLLATE "C" NOT NULL,
|
|
@@ -140,6 +141,25 @@ export const PG_SCHEMA_STATEMENTS = [
|
|
|
140
141
|
consumed_at_ms BIGINT NOT NULL,
|
|
141
142
|
expires_at_ms BIGINT NOT NULL,
|
|
142
143
|
PRIMARY KEY (session_id, nonce)
|
|
144
|
+
)`,
|
|
145
|
+
`CREATE TABLE IF NOT EXISTS org_delivery_sender_quota (
|
|
146
|
+
from_scope VARCHAR(${PRINCIPAL_MAX_LENGTH}) COLLATE "C" NOT NULL,
|
|
147
|
+
window_start_ms BIGINT NOT NULL,
|
|
148
|
+
attempts INT NOT NULL,
|
|
149
|
+
PRIMARY KEY (from_scope)
|
|
150
|
+
)`,
|
|
151
|
+
`CREATE TABLE IF NOT EXISTS org_delivery_recipient_quota (
|
|
152
|
+
to_scope VARCHAR(${PRINCIPAL_MAX_LENGTH}) COLLATE "C" NOT NULL,
|
|
153
|
+
window_start_ms BIGINT NOT NULL,
|
|
154
|
+
delivered INT NOT NULL,
|
|
155
|
+
PRIMARY KEY (to_scope)
|
|
156
|
+
)`,
|
|
157
|
+
`CREATE TABLE IF NOT EXISTS org_delivery_pair_quota (
|
|
158
|
+
to_scope VARCHAR(${PRINCIPAL_MAX_LENGTH}) COLLATE "C" NOT NULL,
|
|
159
|
+
from_scope VARCHAR(${PRINCIPAL_MAX_LENGTH}) COLLATE "C" NOT NULL,
|
|
160
|
+
window_start_ms BIGINT NOT NULL,
|
|
161
|
+
delivered INT NOT NULL,
|
|
162
|
+
PRIMARY KEY (to_scope, from_scope)
|
|
143
163
|
)`,
|
|
144
164
|
`CREATE TABLE IF NOT EXISTS user_input_acceptance (
|
|
145
165
|
accept_id VARCHAR(64) COLLATE "C" NOT NULL,
|
|
@@ -263,17 +283,19 @@ export const PG_SCHEMA_STATEMENTS = [
|
|
|
263
283
|
)`,
|
|
264
284
|
`CREATE TABLE IF NOT EXISTS workflow_journal (
|
|
265
285
|
run_id VARCHAR(191) COLLATE "C" NOT NULL,
|
|
286
|
+
incarnation VARCHAR(64) COLLATE "C" NOT NULL,
|
|
266
287
|
ordinal INT NOT NULL,
|
|
267
|
-
-- SVC-2 / CORE-9 audit BLOCKER: cross-tenant resume isolation (the WorkflowJournalStore seam takes a scope
|
|
268
|
-
-- param). NOT NULL DEFAULT '' — a row written without a scope lands in the '' bucket, which is
|
|
269
|
-
-- CROSS-SCOPE-ORPHANED but harmless: a real resume always filters \`WHERE scope = <caller>\`, so '' rows are
|
|
270
|
-
-- never handed to a tenant. Keep the DEFAULT: it is what makes a scope-less write land in that dead bucket
|
|
271
|
-
-- instead of failing or leaking into a real tenant's scope.
|
|
272
|
-
scope VARCHAR(190) COLLATE "C" NOT NULL DEFAULT '',
|
|
273
288
|
call_key VARCHAR(255) COLLATE "C" NOT NULL,
|
|
274
289
|
result TEXT COLLATE "C" NOT NULL,
|
|
275
290
|
created_at_ms BIGINT NOT NULL,
|
|
276
|
-
PRIMARY KEY (run_id, ordinal)
|
|
291
|
+
PRIMARY KEY (run_id, incarnation, ordinal)
|
|
292
|
+
)`,
|
|
293
|
+
`CREATE TABLE IF NOT EXISTS workflow_journal_owner (
|
|
294
|
+
run_id VARCHAR(191) COLLATE "C" NOT NULL,
|
|
295
|
+
scope VARCHAR(190) COLLATE "C" NOT NULL,
|
|
296
|
+
incarnation VARCHAR(64) COLLATE "C" NOT NULL,
|
|
297
|
+
appended_at_ms BIGINT NOT NULL,
|
|
298
|
+
PRIMARY KEY (run_id)
|
|
277
299
|
)`,
|
|
278
300
|
`CREATE TABLE IF NOT EXISTS workflow_resume_claim (
|
|
279
301
|
source_run_id VARCHAR(191) COLLATE "C" NOT NULL,
|
|
@@ -298,6 +320,16 @@ export const PG_SCHEMA_STATEMENTS = [
|
|
|
298
320
|
agent_key VARCHAR(191) COLLATE "C" NOT NULL,
|
|
299
321
|
scope VARCHAR(190) COLLATE "C" NOT NULL,
|
|
300
322
|
PRIMARY KEY (session_id, run_id)
|
|
323
|
+
)`,
|
|
324
|
+
`CREATE TABLE IF NOT EXISTS workflow_park_decision (
|
|
325
|
+
token VARCHAR(120) COLLATE "C" NOT NULL,
|
|
326
|
+
run_id VARCHAR(191) COLLATE "C" NOT NULL,
|
|
327
|
+
host_session_id VARCHAR(190) COLLATE "C" NOT NULL,
|
|
328
|
+
outcome TEXT COLLATE "C" NOT NULL,
|
|
329
|
+
fingerprint VARCHAR(64) COLLATE "C" NOT NULL,
|
|
330
|
+
delivered_task_id VARCHAR(191) COLLATE "C" NOT NULL,
|
|
331
|
+
accepted_at_ms BIGINT NOT NULL,
|
|
332
|
+
PRIMARY KEY (token)
|
|
301
333
|
)`,
|
|
302
334
|
`CREATE TABLE IF NOT EXISTS workflow_completion_inbox (
|
|
303
335
|
seq BIGSERIAL,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { BaseSessionStorage, type
|
|
1
|
+
import { BaseSessionStorage, type AcquiredSession, type PlacedSessionRow, type SessionMetadata, type SessionPlacementRecord, type SessionStore, type SessionTreeEntry, type SessionWriteOptions } from "@sema-agent/core";
|
|
2
2
|
import type { Pool, PoolClient } from "pg";
|
|
3
3
|
import type { SessionSummary } from "./store-contracts.js";
|
|
4
4
|
import { type SessionRowPatch } from "../session-row.js";
|
|
5
5
|
import { type PlacementAcquireOpts } from "./session-placement.js";
|
|
6
|
+
import { type OrphanOwnerLog } from "../delegated-session-owner.js";
|
|
6
7
|
import { type StagingHandle } from "../session-sync-kernel.js";
|
|
7
8
|
import { type InstructionSourceBaseline } from "../instruction-source-notice.js";
|
|
8
9
|
import { type SessionFace } from "../session-incarnation.js";
|
|
@@ -30,10 +31,9 @@ export declare class PgSessionStorage extends BaseSessionStorage {
|
|
|
30
31
|
private readonly sessionId;
|
|
31
32
|
private readonly floorSeq;
|
|
32
33
|
constructor(pool: Pool, sessionId: string, metadata: SessionMetadata, entries: SessionTreeEntry[], leafId: string | null, floorEntryId?: string | null, floorSeq?: number);
|
|
33
|
-
/** @see TiDBSessionStorage.getEpochAnchor — [ref] S3 [ref] pull seam, PG dialect twin
|
|
34
|
-
* (
|
|
35
|
-
|
|
36
|
-
getEpochAnchor(): Promise<PromptEpochDescriptor | undefined>;
|
|
34
|
+
/** @see TiDBSessionStorage.getEpochAnchor — [ref] S3 [ref] pull seam, PG dialect twin: the same reading
|
|
35
|
+
* ({@link scanEpochAnchor}, the record as stored), this backend's page query. */
|
|
36
|
+
getEpochAnchor(): Promise<unknown>;
|
|
37
37
|
/** @see TiDBSessionStorage.wake — F3 bounded `[floor..leaf]` rebuild; null if the session does not exist. */
|
|
38
38
|
static wake(pool: Pool, sessionId: string): Promise<PgSessionStorage | null>;
|
|
39
39
|
/** The bounded-window floor = last compaction's firstKeptEntryId (and its seq). @see TiDBSessionStorage.computeFloor */
|
|
@@ -66,12 +66,24 @@ export declare class PgSessionStore implements SessionStore {
|
|
|
66
66
|
};
|
|
67
67
|
/** In-flight acquisitions keyed by id, so concurrent acquire(sameId) in one process share one. */
|
|
68
68
|
private readonly pending;
|
|
69
|
-
|
|
69
|
+
/** 委派子代孤行那一行 warn 的去处(TiDB 孪生同格)。 */
|
|
70
|
+
private readonly log;
|
|
71
|
+
constructor(pool: Pool, opts?: {
|
|
72
|
+
readonly log?: OrphanOwnerLog;
|
|
73
|
+
});
|
|
70
74
|
acquire(sessionId?: string, opts?: PlacementAcquireOpts): Promise<AcquiredSession>;
|
|
71
75
|
private load;
|
|
72
|
-
/** Idempotently create a session_meta row with an owner. Existing owner is never overwritten.
|
|
76
|
+
/** Idempotently create a session_meta row with an owner (core `SessionStore.register`). Existing owner is never overwritten. */
|
|
77
|
+
register(sessionId: string, owner: string | null): Promise<void>;
|
|
78
|
+
/** acquire 的建行(唯一一处;S-1770 委派继承律,只住在 `createPlacedSessionRow`,本店交既有读写口 —— TiDB 孪生同名方法同注)。 */
|
|
79
|
+
private createOnAcquire;
|
|
80
|
+
/** S-1770 委派继承律的认领口(TiDB 孪生 {@link TiDBSessionStore.claimOwnerless} 同义;句 = `CLAIM_OWNERLESS_PLACED_SQL`,规则在 `delegated-session-owner.ts`)。 */
|
|
81
|
+
claimOwnerless(sessionId: string, incarnation: string, owner: string): Promise<boolean>;
|
|
82
|
+
/** 若干来源行的会话面(属主 + 化身)一次读回(TiDB 孪生同义;化身经与 `sessionFaceOf` 同一只解码,空 ⇒ 响亮拒)。 */
|
|
83
|
+
private sourceFaces;
|
|
84
|
+
/** The one session_meta INSERT. Existing owner is never overwritten.
|
|
73
85
|
* [ref]:`placement` 与行同一条 INSERT;`DO NOTHING` 臂 ⇒ 已存在行的元组永不被重写(first-write 不可变)。 */
|
|
74
|
-
|
|
86
|
+
private insertMeta;
|
|
75
87
|
/** [ref] 义务 6 的廉价探针(TiDB 孪生 {@link TiDBSessionStore.placementOf} 同义)。 */
|
|
76
88
|
placementOf(sessionId: string): Promise<SessionPlacementRecord | undefined>;
|
|
77
89
|
/** [ref] 义务 5 —— placed 分区枚举(年龄锚/上界/tupleIncomplete 三条读法与 TiDB 孪生逐字同义,
|