@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
|
@@ -2,7 +2,7 @@ import { mysqlDriver, pgDriver, dialectJsonEncoder } from "./sql-driver.js";
|
|
|
2
2
|
import { isDupKeyError, isCheckViolationError } from "./sql-errors.js";
|
|
3
3
|
import { DEVICE_AUDIT_EVENTS, assertAcquireShape, assertDeviceIdShape, assertDeviceOwnerShape, assertEnrollTokenHashShape, assertIssueTokenShape, assertNewDeviceShape, assertPlaceDeviceShape, assertRebindShape, assertRevokeShape, assertWholeSeconds, parseDeviceAuditEvent, parseDevicePlatformOs, parseDeviceStatus, } from "../device-store.js";
|
|
4
4
|
import { WRITABLE, boundDeviceOf, settledDeviceBindOutcome, settledDeviceRebindOutcome } from "../execution-placement.js";
|
|
5
|
-
import { bindDeviceStatement, countDeviceBindingsOn, lockRootAndReadClaim, placeWriterStatement, readPlacementOn, rebindDeviceStatement, rowsOnSqlExec } from "./execution-placement-sql.js";
|
|
5
|
+
import { bindDeviceStatement, countDeviceBindingsOn, lockRootAndReadClaim, placeWriterStatement, readPlacementOn, rebindDeviceStatement, rowsOnSqlExec, writeCellOn } from "./execution-placement-sql.js";
|
|
6
6
|
import { ensureIndexes } from "./ensure-index.js";
|
|
7
7
|
import { decodeJsonColumn, foldJsonColumn, jsonColumnText, readJsonObjectColumn } from "./sql-json-column.js";
|
|
8
8
|
export const DEVICES_TABLE = "device";
|
|
@@ -520,11 +520,9 @@ export class SqlDeviceStore {
|
|
|
520
520
|
const now = new Date();
|
|
521
521
|
const device = { id: input.deviceId, owner: input.owner };
|
|
522
522
|
const stmt = reading.cell.role === "absent"
|
|
523
|
-
? placeWriterStatement(this.db.dialect, input.root,
|
|
524
|
-
: bindDeviceStatement(this.db.dialect, input.root,
|
|
525
|
-
|
|
526
|
-
if (res.affected !== 1)
|
|
527
|
-
throw new Error(`device-store: first bind of session ${input.root} affected ${res.affected} rows under a held row lock — engine anomaly, refusing to guess`);
|
|
523
|
+
? placeWriterStatement(this.db.dialect, input.root, { lane: "device", device }, now)
|
|
524
|
+
: bindDeviceStatement(this.db.dialect, input.root, device, now);
|
|
525
|
+
await writeCellOn(conn, this.db.dialect, input.root, stmt);
|
|
528
526
|
await conn.commit();
|
|
529
527
|
const placed = { id: input.deviceId, owner: { tenant: input.owner.tenant, subject: input.owner.subject }, rev: 0, placedAt: now.toISOString() };
|
|
530
528
|
return { outcome: "bound", device: placed };
|
|
@@ -564,10 +562,7 @@ export class SqlDeviceStore {
|
|
|
564
562
|
}
|
|
565
563
|
const from = boundDeviceOf(reading.cell).id;
|
|
566
564
|
const now = new Date();
|
|
567
|
-
|
|
568
|
-
const cas = await conn.query(stmt.text, [...stmt.values]);
|
|
569
|
-
if (cas.affected !== 1)
|
|
570
|
-
throw new Error(`device-store: rebind CAS affected ${cas.affected} rows under a held row lock — engine anomaly, refusing to guess`);
|
|
565
|
+
await writeCellOn(conn, this.db.dialect, input.root, rebindDeviceStatement(this.db.dialect, input.root, input.owner, input.expectedRev, input.targetDeviceId, now));
|
|
571
566
|
const rev = input.expectedRev + 1;
|
|
572
567
|
await this.insertAuditOn(conn, { event: "session_rebound", deviceId: input.targetDeviceId, owner: input.owner, detail: { from, to: input.targetDeviceId, rev } });
|
|
573
568
|
await conn.commit();
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🔴 一次性迁移 **M40**(窗口见 `plugins/one-time-migrations.ts` 登记表 M40 行;头注 M40 段):没有执行环境的那条车道的存词由退役名改成 `none`。
|
|
3
|
+
*
|
|
4
|
+
* 本文件是那一对词与「读到退役词时补哪一句」的**唯一属主**:SQL 腿(`one-time-migrations.ts` 的 M40 步,两方言两张表)、local 两腿(会话元数据边档 ——
|
|
5
|
+
* `LocalSessionStore.renameRetiredExecutionLaneWordM40`,排在严格边档对账之前;问账日志 —— `FileApprovalAskStore.renameRetiredExecutionLaneWordM40`,
|
|
6
|
+
* 排在 M32 回填之前)与两只 SQL 读口的拒句(`approval-ask-store-sql.ts` / `execution-placement-sql.ts`)都读这里。窗关删码 = 删这只文件与上面那几处调用。
|
|
7
|
+
*
|
|
8
|
+
* 本文件只 import 类型(零运行期依赖)⇒ 被一次性迁移段与它 import 的店文件同时读,不成环。
|
|
9
|
+
*/
|
|
10
|
+
import type { ExecutionLane } from "../execution-lane-caps.js";
|
|
11
|
+
/** 退役的存词(本版之前的部署在没有声明车道时铸下的那一个)。本版的车道闭集里没有它,任何读口读到都响亮拒。 */
|
|
12
|
+
export declare const RETIRED_EXECUTION_LANE_WORD_M40 = "in-process";
|
|
13
|
+
/** 它的新名:声明「这一部署没有执行环境」的那条车道。 */
|
|
14
|
+
export declare const RENAMED_EXECUTION_LANE_M40: ExecutionLane;
|
|
15
|
+
/**
|
|
16
|
+
* 读口拒句的补句:读到的词就是退役词 ⇒ 说清它是什么、为什么还在(迁移之后又被写下 = 有一只更早版本的副本还在服务)与出路;别的词 ⇒ 空串(拒句不变)。
|
|
17
|
+
* 起服的迁移改完之后,只有混跑的旧副本还会写下它(版本围栏见登记表 M40 行与 MIGRATION 本版节)。
|
|
18
|
+
*/
|
|
19
|
+
export declare function retiredExecutionLaneHintM40(word: string): string;
|
|
20
|
+
//# sourceMappingURL=execution-lane-rename-m40.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const RETIRED_EXECUTION_LANE_WORD_M40 = "in-process";
|
|
2
|
+
export const RENAMED_EXECUTION_LANE_M40 = "none";
|
|
3
|
+
export function retiredExecutionLaneHintM40(word) {
|
|
4
|
+
if (word !== RETIRED_EXECUTION_LANE_WORD_M40)
|
|
5
|
+
return "";
|
|
6
|
+
return (` — "${RETIRED_EXECUTION_LANE_WORD_M40}" is the name an earlier version gave the lane with no execution environment, which this version calls "${RENAMED_EXECUTION_LANE_M40}"; ` +
|
|
7
|
+
"the one-time migration M40 at boot renames every stored copy, so this row was written afterwards by a replica of an earlier version that is still serving. " +
|
|
8
|
+
"Stop every replica of the earlier version, then restart this version once (its boot renames what they wrote)");
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=execution-lane-rename-m40.js.map
|
|
@@ -1,92 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* **执行放置的 SQL 唯一模块** ——
|
|
3
|
-
*
|
|
2
|
+
* **执行放置的 SQL 唯一模块** —— 执行放置七列 + `fork_key` 一列的列定义、行 → 格解码、每一种转换的语句,与「写事务内先锁根行再读认领」那一读。
|
|
3
|
+
* 规则在 `src/execution-placement.ts` 头注;本模块只说 SQL。
|
|
4
4
|
*
|
|
5
|
-
* ##
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* 存量库的加列只由一次性迁移做,`ensureSchema` 不 ALTER(SCHEMA POLICY)。
|
|
9
|
-
* · **语句唯一属主**:会话店(执行席、导入写口)与设备店(首绑 / 换绑 / 绑定数)、一次性迁移(搬绑定 / 回填)的事务都借这里的语句,别处零手写。
|
|
10
|
-
* 语句是方言无关的 `{ text, values }`(调用方用自己的连接跑:SqlDriver 的 `SqlTxConn`、node-pg 的客户端、mysql2 的连接都行)。
|
|
5
|
+
* ## 格住在部署旁表
|
|
6
|
+
* 八列住 `session_ext`(会话的部署格旁表,建表 / 外键 / 补行的唯一属主 = `session-ext-table.ts`;一会话一行,`ON DELETE CASCADE` 随 `session_meta` 行走),
|
|
7
|
+
* 不在引擎座表 `session_meta` 上(一张表一个 DDL 属主)。旁表行不在 = 八列全缺省(absent / 非键控 fork);写者在锁住根行之后按需补行。
|
|
11
8
|
*
|
|
12
|
-
* ##
|
|
13
|
-
* `
|
|
14
|
-
* (
|
|
15
|
-
*
|
|
9
|
+
* ## 属主
|
|
10
|
+
* · 列定义住旁表属主(`session-ext-table.ts` 的 `EXECUTION_PLACEMENT_COLUMNS`;一次性迁移 M32 / M41 读同一份)。
|
|
11
|
+
* · **语句唯一属主**:执行席、会话店的事务内钩(导入落 mirror)、设备店(首绑 / 换绑 / 绑定数)与一次性迁移的事务都借这里的语句,别处零手写。
|
|
12
|
+
* 语句是方言无关的 `{ text, values }`(调用方用自己的连接跑)。
|
|
16
13
|
*
|
|
17
|
-
* ##
|
|
18
|
-
*
|
|
19
|
-
* `session_meta`
|
|
20
|
-
*
|
|
14
|
+
* ## 写序律(一条,所有部署格的写者同一条)
|
|
15
|
+
* 改住客 / 放置的每个写者(place · 首绑 / 换绑 · identical 补 mirror · 导入写口 · 删除终刀 · 留存删除)在写事务内、用该事务自己的连接:
|
|
16
|
+
* ① `FOR UPDATE` 锁根 `session_meta` 行(读住客:属主 + 化身 + 委派判别位)→ ② 需要时新语句锁定读认领 `task_active(root)`({@link lockRootAndReadClaim})
|
|
17
|
+
* → ③ 补旁表行、再锁定读这一格({@link readCellOn};先补后锁:锁定读永远落在一行在的记录上,InnoDB 间隙锁不会让两只补行互等)→ 判官(住客对不对、格是什么)
|
|
18
|
+
* → ④ 一句按格谓词定址的 UPDATE。
|
|
19
|
+
* 住客由 ① 的锁钉住(删除 / 重登记 / 改属主都要先拿这把锁),所以写语句只按格谓词定址、不再带住客谓词;持锁判过「可写」之后 UPDATE 必中一行,0 行即引擎异常。
|
|
20
|
+
* 全局锁序:设备行 → 根 meta → `task_*` → 旁表行(`run-store-sql.ts` 的 `createRun` 同序先锁根行)。认领持有者自己的初始放置写(place / 首绑)是唯一不读认领的写。
|
|
21
21
|
*/
|
|
22
22
|
import type { SqlDialect, SqlDriver, SqlExec } from "./sql-driver.js";
|
|
23
23
|
import type { DeviceOwner } from "../device-store.js";
|
|
24
24
|
import { type ExecutionLane } from "../execution-lane-caps.js";
|
|
25
|
-
import { type SessionFace } from "../session-incarnation.js";
|
|
26
25
|
import { type ExecutionPlacementCell, type ExecutionPlacementReading, type ExecutionPlacementSeat } from "../execution-placement.js";
|
|
27
26
|
/** 一条语句:文本 + 按序的参数(`?` / `$n` 已按方言铸好)。 */
|
|
28
27
|
export interface PlacementStatement {
|
|
29
28
|
readonly text: string;
|
|
30
29
|
readonly values: readonly unknown[];
|
|
31
30
|
}
|
|
32
|
-
/**
|
|
33
|
-
|
|
34
|
-
* 属主两列与设备店同宽 190、fork 键 255(服务端拼的不透明串)。PG 文本列 `COLLATE "C"`(与同表同形)。全部可空:NULL = absent / 非键控 fork。
|
|
35
|
-
*/
|
|
36
|
-
export declare const SESSION_META_PLACEMENT_COLUMNS: readonly [{
|
|
37
|
-
readonly name: "execution_role";
|
|
38
|
-
readonly mysql: "execution_role VARCHAR(16) NULL";
|
|
39
|
-
readonly pg: "execution_role VARCHAR(16) COLLATE \"C\"";
|
|
40
|
-
}, {
|
|
41
|
-
readonly name: "execution_lane";
|
|
42
|
-
readonly mysql: "execution_lane VARCHAR(32) NULL";
|
|
43
|
-
readonly pg: "execution_lane VARCHAR(32) COLLATE \"C\"";
|
|
44
|
-
}, {
|
|
45
|
-
readonly name: "execution_device_id";
|
|
46
|
-
readonly mysql: "execution_device_id VARCHAR(64) NULL";
|
|
47
|
-
readonly pg: "execution_device_id VARCHAR(64) COLLATE \"C\"";
|
|
48
|
-
}, {
|
|
49
|
-
readonly name: "execution_device_owner_tenant";
|
|
50
|
-
readonly mysql: "execution_device_owner_tenant VARCHAR(190) NULL";
|
|
51
|
-
readonly pg: "execution_device_owner_tenant VARCHAR(190) COLLATE \"C\"";
|
|
52
|
-
}, {
|
|
53
|
-
readonly name: "execution_device_owner_subject";
|
|
54
|
-
readonly mysql: "execution_device_owner_subject VARCHAR(190) NULL";
|
|
55
|
-
readonly pg: "execution_device_owner_subject VARCHAR(190) COLLATE \"C\"";
|
|
56
|
-
}, {
|
|
57
|
-
readonly name: "execution_placed_at";
|
|
58
|
-
readonly mysql: "execution_placed_at DATETIME(3) NULL";
|
|
59
|
-
readonly pg: "execution_placed_at TIMESTAMPTZ(3)";
|
|
60
|
-
}, {
|
|
61
|
-
readonly name: "execution_rev";
|
|
62
|
-
readonly mysql: "execution_rev BIGINT NULL";
|
|
63
|
-
readonly pg: "execution_rev BIGINT";
|
|
64
|
-
}, {
|
|
65
|
-
readonly name: "fork_key";
|
|
66
|
-
readonly mysql: "fork_key VARCHAR(255) NULL";
|
|
67
|
-
readonly pg: "fork_key VARCHAR(255) COLLATE \"C\"";
|
|
68
|
-
}];
|
|
69
|
-
/** 中央 DDL 内插的那一段(列与列之间逗号分隔,不带首尾逗号)。 */
|
|
70
|
-
export declare function sessionMetaPlacementColumnsDdl(dialect: SqlDialect): string;
|
|
71
|
-
/** 导入提交点同句落 mirror 的 SET 片段与守卫谓词(会话店的提交点 UPDATE 内插这两段:`SET …, ${MIRROR_ON_COMMIT_SET} WHERE session_id = ? AND ${MIRROR_ON_COMMIT_GUARD}`)。 */
|
|
72
|
-
export declare const MIRROR_ON_COMMIT_SET = "execution_role = 'mirror'";
|
|
73
|
-
export declare const MIRROR_ON_COMMIT_GUARD = "(execution_role IS NULL OR execution_role <> 'writer')";
|
|
74
|
-
/** 导入新建 / 换装重插的那一行在执行与 fork 两格上的值:`fork_key` = 沿用的键(或 NULL)、`execution_role` = mirror(列名与值同出一处)。 */
|
|
75
|
-
export declare function importedRowCells(forkKey: string | null): {
|
|
76
|
-
readonly columns: string;
|
|
77
|
-
readonly values: readonly unknown[];
|
|
78
|
-
};
|
|
79
|
-
/** 读一行放置要的列(住客两列 + 委派判别位 + 执行七列;行 → 读数的唯一解码 {@link placementReadingFromRow} 吃的就是这一组)。导入写口的事务内锁读内插它。 */
|
|
80
|
-
export declare const SESSION_META_PLACEMENT_READ_COLUMNS = "owner, incarnation, placement_kind, execution_role, execution_lane, execution_device_id, execution_device_owner_tenant, execution_device_owner_subject, execution_placed_at, execution_rev";
|
|
81
|
-
/** 按根读一行(`lock` ⇒ `FOR UPDATE`:写事务内的当前读;非事务读不加锁)。 */
|
|
82
|
-
export declare function readPlacementRowStatement(dialect: SqlDialect, root: string, opts: {
|
|
83
|
-
readonly lock: boolean;
|
|
84
|
-
}): PlacementStatement;
|
|
31
|
+
/** 按根的一次池读(非事务;不加锁):根行 LEFT JOIN 旁表行。写事务内的当前读是 {@link readPlacementOn}(两句锁定读)。 */
|
|
32
|
+
export declare function readPlacementRowStatement(dialect: SqlDialect, root: string): PlacementStatement;
|
|
85
33
|
/**
|
|
86
34
|
* place:absent → writer(L[, D]),`execution_rev = 0`。非 device 车道由会话店的执行席用(`device` 缺);device 车道的首绑由设备店在锁住设备行的
|
|
87
|
-
* 同一事务里用(`device` 在场)
|
|
35
|
+
* 同一事务里用(`device` 在场)。时刻用调用方的钟。只在写序律 ① 锁住根行、判官答「可写」之后、{@link ensureSessionExtRowStatement} 补过行之后跑。
|
|
88
36
|
*/
|
|
89
|
-
export declare function placeWriterStatement(dialect: SqlDialect, root: string,
|
|
37
|
+
export declare function placeWriterStatement(dialect: SqlDialect, root: string, cell: {
|
|
90
38
|
readonly lane: ExecutionLane;
|
|
91
39
|
readonly device?: {
|
|
92
40
|
readonly id: string;
|
|
@@ -94,14 +42,14 @@ export declare function placeWriterStatement(dialect: SqlDialect, root: string,
|
|
|
94
42
|
};
|
|
95
43
|
}, now: Date): PlacementStatement;
|
|
96
44
|
/** bind:writer(device, ∅) → writer(device, D)(fresh 首绑撞上迁移回填的格),`execution_rev = 0`。 */
|
|
97
|
-
export declare function bindDeviceStatement(dialect: SqlDialect, root: string,
|
|
45
|
+
export declare function bindDeviceStatement(dialect: SqlDialect, root: string, device: {
|
|
98
46
|
readonly id: string;
|
|
99
47
|
readonly owner: DeviceOwner;
|
|
100
48
|
}, now: Date): PlacementStatement;
|
|
101
|
-
/** rebind:writer(device, D) → writer(device, D')
|
|
102
|
-
export declare function rebindDeviceStatement(dialect: SqlDialect, root: string,
|
|
49
|
+
/** rebind:writer(device, D) → writer(device, D'),按格 ∧ 两属主列 ∧ rev 定址,`execution_rev + 1`(恒变列)。属主两列不动(换绑只在同一属主的设备之间)。 */
|
|
50
|
+
export declare function rebindDeviceStatement(dialect: SqlDialect, root: string, owner: DeviceOwner, expectedRev: number, targetDeviceId: string, now: Date): PlacementStatement;
|
|
103
51
|
/**
|
|
104
|
-
*
|
|
52
|
+
* 带设备列的根会话格(旁表上 `execution_device_id` 非空、根行不是委派分区行):绑定数的读只用它**缩小**读的行 —— 一条绑定必有设备列,反之不然;
|
|
105
53
|
* 是不是一条绑定只由行的唯一解码 {@link placementCellFromRow} + `boundDeviceOf` 判(SQL 不另判一遍)。两方言同一句。
|
|
106
54
|
*/
|
|
107
55
|
export declare function deviceCellRowsStatement(): PlacementStatement;
|
|
@@ -110,16 +58,23 @@ export declare function deviceCellRowsStatement(): PlacementStatement;
|
|
|
110
58
|
* (设备在而属主 / rev / 时刻缺、设备落在别的车道)原样抛 {@link ExecutionPlacementRowError},不当一条绑定数进去,也不当没有。
|
|
111
59
|
*/
|
|
112
60
|
export declare function countDeviceBindingsOn(conn: PlacementRowsOn): Promise<number>;
|
|
113
|
-
/** identical 臂补 mirror:absent / mirror → mirror,WHERE
|
|
114
|
-
export declare function markMirrorStatement(dialect: SqlDialect, root: string
|
|
115
|
-
/** 回填(一次性迁移):无执行格、非委派分区、有 run 行的会话行 ⇒ writer(表唯一项)。幂等(第二次跑零行)。 */
|
|
61
|
+
/** identical 臂补 mirror(导入写口同一句):absent / mirror → mirror,WHERE 不是 writer。写序律同 {@link placeWriterStatement}。 */
|
|
62
|
+
export declare function markMirrorStatement(dialect: SqlDialect, root: string): PlacementStatement;
|
|
63
|
+
/** 回填(一次性迁移 M32,窗内;写的是 7.139–7.146 形 —— 八列在 `session_meta` 上,M41 随后连同其余部署格搬进旁表):无执行格、非委派分区、有 run 行的会话行 ⇒ writer(表唯一项)。幂等(第二次跑零行)。 */
|
|
116
64
|
export declare function backfillWriterStatement(dialect: SqlDialect, lane: ExecutionLane, now: Date): PlacementStatement;
|
|
117
65
|
/**
|
|
118
|
-
* 搬绑定(一次性迁移):按 `sourceTable`(退役改名后的绑定表,列 = `root_session_id, device_id, owner_tenant, owner_subject, bound_at, rev`)整行覆盖
|
|
66
|
+
* 搬绑定(一次性迁移 M32,窗内;写 7.139–7.146 形的 `session_meta` 八列,同 {@link backfillWriterStatement}):按 `sourceTable`(退役改名后的绑定表,列 = `root_session_id, device_id, owner_tenant, owner_subject, bound_at, rev`)整行覆盖
|
|
119
67
|
* 根会话行的 device 位(`rev` 原值、`bound_at → execution_placed_at`)。只碰非委派分区行。MySQL 协议那张表的列是 VARBINARY ⇒ 转成字符串再比 / 再写。
|
|
120
68
|
* `sourceTable` 是调用方的常量表名(不是用户输入)。
|
|
121
69
|
*/
|
|
122
70
|
export declare function migrateDeviceBindingsStatement(dialect: SqlDialect, sourceTable: string): PlacementStatement;
|
|
71
|
+
/**
|
|
72
|
+
* 搬绑定的**旁表形**(一次性迁移 M32 ③,窗内;库已是旁表形 —— M41 之后、或本版起的新库,执行格住 `session_ext`):与 {@link migrateDeviceBindingsStatement}
|
|
73
|
+
* 同一组覆盖(`rev` 原值、`bound_at → execution_placed_at`、只碰非委派分区行),按写序律先补旁表行(旁表属主的补行语句 {@link ensureSessionExtRowsStatement},不碰任何格)、
|
|
74
|
+
* 再一句 UPDATE 只写执行格(受影响行数 = 搬了几行,与 7.139–7.146 形同一读法)。
|
|
75
|
+
* 两句按序跑;`sourceTable` 是调用方的常量表名。
|
|
76
|
+
*/
|
|
77
|
+
export declare function migrateDeviceBindingsOntoSideTableStatements(dialect: SqlDialect, sourceTable: string): readonly [ensure: PlacementStatement, move: PlacementStatement];
|
|
123
78
|
/** 搬绑定的孤儿计数(绑定行指向的根会话行不在,或是委派分区行 ⇒ 丢弃):迁移收据里点名的那个数。 */
|
|
124
79
|
export declare function countOrphanBindingsStatement(dialect: SqlDialect, sourceTable: string): PlacementStatement;
|
|
125
80
|
/** 一行放置读不通(角色 / 车道不在闭集,或列的组合不是四态之一)—— 响亮拒,不读作 absent(那等于把一行坏数据当成「还没放」放行给首交)。 */
|
|
@@ -144,18 +99,38 @@ export interface RootClaimReading {
|
|
|
144
99
|
readonly activeTaskId: string | null;
|
|
145
100
|
}
|
|
146
101
|
/**
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
|
|
102
|
+
* 写序律 ②:根行已被本事务锁住之后,以新语句 `SELECT task_id FROM task_active WHERE session_id = ? FOR UPDATE` 锁定读认领(PG 读已提交下取新快照、
|
|
103
|
+
* TiDB 悲观事务是当前读)。只在写事务内、锁根行之后调(会话店的事务内钩在店锁住根行之后调它;其余写者经 {@link lockRootAndReadClaim} 一步做完 ① ②)。
|
|
104
|
+
*/
|
|
105
|
+
export declare function readClaimOn(conn: PlacementRowsOn, dialect: SqlDialect, root: string): Promise<string | null>;
|
|
106
|
+
/**
|
|
107
|
+
* 写序律 ① ②(头注):**同一连接**上先锁根行,再锁定读认领。只在写事务内调;池级 `getActiveTaskId` 不是它(另一只连接,不在锁序里)。根行不在 ⇒ 不读认领。
|
|
150
108
|
*/
|
|
151
109
|
export declare function lockRootAndReadClaim(conn: PlacementRowsOn, dialect: SqlDialect, root: string): Promise<RootClaimReading>;
|
|
152
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* 写序律 ③:锁住的旁表这一格。只在根行已被本事务锁住之后调。**先补行、再锁定读**(补行 = 缺省一行,读法与行不在同一):锁定读永远落在一行在的记录上 ——
|
|
112
|
+
* InnoDB 可重复读下,锁定读一只不在的键拿的是间隙锁(彼此兼容),两只事务随后各自补行时插入意向锁互等 ⇒ 死锁。之后的格写({@link writeCellOn})只剩一句 UPDATE。
|
|
113
|
+
*/
|
|
114
|
+
export declare function readCellOn(conn: PlacementRowsOn, dialect: SqlDialect, root: string): Promise<Exclude<ExecutionPlacementCell, {
|
|
115
|
+
role: "forking";
|
|
116
|
+
}>>;
|
|
117
|
+
/** 写事务内按根的当前读(写序律 ① + ③,两句锁定读)→ 读数。行不在 / 委派分区行 ⇒ `undefined`。 */
|
|
153
118
|
export declare function readPlacementOn(conn: PlacementRowsOn, dialect: SqlDialect, root: string): Promise<ExecutionPlacementReading | undefined>;
|
|
119
|
+
/** 格写只用到的那一面:一句语句、交回受影响行数(驱动的事务连接 `SqlExec` 与会话店交给部署钩的 `SessionTxStatements` 都满足它)。 */
|
|
120
|
+
export interface PlacementCellWriter {
|
|
121
|
+
query(sql: string, params?: unknown[]): Promise<{
|
|
122
|
+
readonly affected: number;
|
|
123
|
+
}>;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* 写序律 ④:一句格写(持锁判过「可写」之后;旁表行已在 —— 锁它的那一读 {@link readCellOn} 补的)。格写必中一行,0 行即引擎异常 ⇒ 响亮抛,不折成业务答案。
|
|
127
|
+
*/
|
|
128
|
+
export declare function writeCellOn(exec: PlacementCellWriter, dialect: SqlDialect, root: string, statement: PlacementStatement): Promise<void>;
|
|
154
129
|
/**
|
|
155
|
-
* SQL 会话店的执行席(两孪生同一只实现:语句与判官都在这里与 `execution-placement.ts`,方言只在语句文本里)。`db` =
|
|
156
|
-
* · `read` ——
|
|
157
|
-
* · `place` ——
|
|
158
|
-
* · `markMirror` —— 一只事务:锁根行读认领 →
|
|
130
|
+
* SQL 会话店的执行席(两孪生同一只实现:语句与判官都在这里与 `execution-placement.ts`,方言只在语句文本里)。`db` = 店的池包成的 SqlDriver。
|
|
131
|
+
* · `read` —— 一次池读(根行 LEFT JOIN 旁表行);
|
|
132
|
+
* · `place` —— 一只事务:锁根行读格(写序律 ① ③,不读认领:认领持有者自己的初始放置写;③ 先补行再锁定读)→ 判官 → 格写;
|
|
133
|
+
* · `markMirror` —— 一只事务:锁根行读认领(① ②)→ 补行 + 锁定读这一格(③)→ 判官 → 有认领 ⇒ `active` → 格写。
|
|
159
134
|
*/
|
|
160
135
|
export declare function createSqlExecutionPlacementSeat(db: Pick<SqlDriver, "dialect" | "query" | "connect">): ExecutionPlacementSeat;
|
|
161
136
|
//# sourceMappingURL=execution-placement-sql.d.ts.map
|
|
@@ -1,29 +1,15 @@
|
|
|
1
1
|
import { isExecutionLane } from "../execution-lane-caps.js";
|
|
2
|
+
import { retiredExecutionLaneHintM40 } from "./execution-lane-rename-m40.js";
|
|
2
3
|
import { sessionFaceFromRow } from "../session-incarnation.js";
|
|
3
4
|
import { toIso } from "./sql-row-helpers.js";
|
|
5
|
+
import { SESSION_EXT_TABLE, ensureSessionExtRowStatement, ensureSessionExtRowsStatement } from "./session-ext-table.js";
|
|
4
6
|
import { WRITABLE, assertPlaceableLane, boundDeviceOf, settledMirrorOutcome, settledPlaceOutcome, } from "../execution-placement.js";
|
|
5
|
-
export const SESSION_META_PLACEMENT_COLUMNS = [
|
|
6
|
-
{ name: "execution_role", mysql: "execution_role VARCHAR(16) NULL", pg: `execution_role VARCHAR(16) COLLATE "C"` },
|
|
7
|
-
{ name: "execution_lane", mysql: "execution_lane VARCHAR(32) NULL", pg: `execution_lane VARCHAR(32) COLLATE "C"` },
|
|
8
|
-
{ name: "execution_device_id", mysql: "execution_device_id VARCHAR(64) NULL", pg: `execution_device_id VARCHAR(64) COLLATE "C"` },
|
|
9
|
-
{ name: "execution_device_owner_tenant", mysql: "execution_device_owner_tenant VARCHAR(190) NULL", pg: `execution_device_owner_tenant VARCHAR(190) COLLATE "C"` },
|
|
10
|
-
{ name: "execution_device_owner_subject", mysql: "execution_device_owner_subject VARCHAR(190) NULL", pg: `execution_device_owner_subject VARCHAR(190) COLLATE "C"` },
|
|
11
|
-
{ name: "execution_placed_at", mysql: "execution_placed_at DATETIME(3) NULL", pg: "execution_placed_at TIMESTAMPTZ(3)" },
|
|
12
|
-
{ name: "execution_rev", mysql: "execution_rev BIGINT NULL", pg: "execution_rev BIGINT" },
|
|
13
|
-
{ name: "fork_key", mysql: "fork_key VARCHAR(255) NULL", pg: `fork_key VARCHAR(255) COLLATE "C"` },
|
|
14
|
-
];
|
|
15
|
-
export function sessionMetaPlacementColumnsDdl(dialect) {
|
|
16
|
-
return SESSION_META_PLACEMENT_COLUMNS.map((c) => c[dialect]).join(",\n ");
|
|
17
|
-
}
|
|
18
7
|
const WRITER = "writer";
|
|
19
8
|
const MIRROR = "mirror";
|
|
20
9
|
const NOT_WRITER = "(execution_role IS NULL OR execution_role <> 'writer')";
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return { columns: "fork_key, execution_role", values: [forkKey, MIRROR] };
|
|
25
|
-
}
|
|
26
|
-
export const SESSION_META_PLACEMENT_READ_COLUMNS = "owner, incarnation, placement_kind, execution_role, execution_lane, execution_device_id, execution_device_owner_tenant, execution_device_owner_subject, execution_placed_at, execution_rev";
|
|
10
|
+
const EXECUTION_CELL_COLUMNS = "execution_role, execution_lane, execution_device_id, execution_device_owner_tenant, execution_device_owner_subject, execution_placed_at, execution_rev";
|
|
11
|
+
const OCCUPANT_COLUMNS = "owner, incarnation, placement_kind";
|
|
12
|
+
const READING_COLUMNS = `sm.owner, sm.incarnation, sm.placement_kind, ${EXECUTION_CELL_COLUMNS.split(", ").map((c) => `se.${c}`).join(", ")}`;
|
|
27
13
|
function binder(dialect) {
|
|
28
14
|
const values = [];
|
|
29
15
|
return {
|
|
@@ -34,38 +20,37 @@ function binder(dialect) {
|
|
|
34
20
|
},
|
|
35
21
|
};
|
|
36
22
|
}
|
|
37
|
-
function
|
|
38
|
-
const nullSafeEq = dialect === "pg" ? "IS NOT DISTINCT FROM" : "<=>";
|
|
39
|
-
return `session_id = ${p(root)} AND incarnation = ${p(occupant.incarnation)} AND owner ${nullSafeEq} ${p(occupant.owner)} AND placement_kind IS NULL`;
|
|
40
|
-
}
|
|
41
|
-
export function readPlacementRowStatement(dialect, root, opts) {
|
|
23
|
+
export function readPlacementRowStatement(dialect, root) {
|
|
42
24
|
const b = binder(dialect);
|
|
43
|
-
return { text: `SELECT ${
|
|
25
|
+
return { text: `SELECT ${READING_COLUMNS} FROM session_meta sm LEFT JOIN ${SESSION_EXT_TABLE} se ON se.session_id = sm.session_id WHERE sm.session_id = ${b.p(root)}`, values: b.values };
|
|
44
26
|
}
|
|
45
|
-
export function placeWriterStatement(dialect, root,
|
|
27
|
+
export function placeWriterStatement(dialect, root, cell, now) {
|
|
46
28
|
const b = binder(dialect);
|
|
47
29
|
const set = `execution_role = '${WRITER}', execution_lane = ${b.p(cell.lane)}, execution_device_id = ${b.p(cell.device?.id ?? null)}, ` +
|
|
48
30
|
`execution_device_owner_tenant = ${b.p(cell.device?.owner.tenant ?? null)}, execution_device_owner_subject = ${b.p(cell.device?.owner.subject ?? null)}, ` +
|
|
49
31
|
`execution_placed_at = ${b.p(now)}, execution_rev = 0`;
|
|
50
|
-
return { text: `UPDATE
|
|
32
|
+
return { text: `UPDATE ${SESSION_EXT_TABLE} SET ${set} WHERE session_id = ${b.p(root)} AND execution_role IS NULL`, values: b.values };
|
|
51
33
|
}
|
|
52
|
-
export function bindDeviceStatement(dialect, root,
|
|
34
|
+
export function bindDeviceStatement(dialect, root, device, now) {
|
|
53
35
|
const b = binder(dialect);
|
|
54
36
|
const set = `execution_device_id = ${b.p(device.id)}, execution_device_owner_tenant = ${b.p(device.owner.tenant)}, execution_device_owner_subject = ${b.p(device.owner.subject)}, execution_placed_at = ${b.p(now)}, execution_rev = 0`;
|
|
55
37
|
return {
|
|
56
|
-
text: `UPDATE
|
|
38
|
+
text: `UPDATE ${SESSION_EXT_TABLE} SET ${set} WHERE session_id = ${b.p(root)} AND execution_role = '${WRITER}' AND execution_lane = 'device' AND execution_device_id IS NULL`,
|
|
57
39
|
values: b.values,
|
|
58
40
|
};
|
|
59
41
|
}
|
|
60
|
-
export function rebindDeviceStatement(dialect, root,
|
|
42
|
+
export function rebindDeviceStatement(dialect, root, owner, expectedRev, targetDeviceId, now) {
|
|
61
43
|
const b = binder(dialect);
|
|
62
44
|
const set = `execution_device_id = ${b.p(targetDeviceId)}, execution_placed_at = ${b.p(now)}, execution_rev = execution_rev + 1`;
|
|
63
|
-
const where =
|
|
45
|
+
const where = `session_id = ${b.p(root)} AND execution_role = '${WRITER}' AND execution_lane = 'device' ` +
|
|
64
46
|
`AND execution_device_owner_tenant = ${b.p(owner.tenant)} AND execution_device_owner_subject = ${b.p(owner.subject)} AND execution_rev = ${b.p(expectedRev)}`;
|
|
65
|
-
return { text: `UPDATE
|
|
47
|
+
return { text: `UPDATE ${SESSION_EXT_TABLE} SET ${set} WHERE ${where}`, values: b.values };
|
|
66
48
|
}
|
|
67
49
|
export function deviceCellRowsStatement() {
|
|
68
|
-
return {
|
|
50
|
+
return {
|
|
51
|
+
text: `SELECT se.session_id, ${EXECUTION_CELL_COLUMNS.split(", ").map((c) => `se.${c}`).join(", ")} FROM ${SESSION_EXT_TABLE} se JOIN session_meta sm ON sm.session_id = se.session_id WHERE se.execution_device_id IS NOT NULL AND sm.placement_kind IS NULL`,
|
|
52
|
+
values: [],
|
|
53
|
+
};
|
|
69
54
|
}
|
|
70
55
|
export async function countDeviceBindingsOn(conn) {
|
|
71
56
|
const s = deviceCellRowsStatement();
|
|
@@ -75,9 +60,9 @@ export async function countDeviceBindingsOn(conn) {
|
|
|
75
60
|
bindings += 1;
|
|
76
61
|
return bindings;
|
|
77
62
|
}
|
|
78
|
-
export function markMirrorStatement(dialect, root
|
|
63
|
+
export function markMirrorStatement(dialect, root) {
|
|
79
64
|
const b = binder(dialect);
|
|
80
|
-
return { text: `UPDATE
|
|
65
|
+
return { text: `UPDATE ${SESSION_EXT_TABLE} SET execution_role = '${MIRROR}' WHERE session_id = ${b.p(root)} AND ${NOT_WRITER}`, values: b.values };
|
|
81
66
|
}
|
|
82
67
|
export function backfillWriterStatement(dialect, lane, now) {
|
|
83
68
|
const b = binder(dialect);
|
|
@@ -105,6 +90,31 @@ export function migrateDeviceBindingsStatement(dialect, sourceTable) {
|
|
|
105
90
|
values: [],
|
|
106
91
|
};
|
|
107
92
|
}
|
|
93
|
+
export function migrateDeviceBindingsOntoSideTableStatements(dialect, sourceTable) {
|
|
94
|
+
if (dialect === "pg") {
|
|
95
|
+
return [
|
|
96
|
+
ensureSessionExtRowsStatement(dialect, `SELECT sm.session_id FROM ${sourceTable} ds JOIN session_meta sm ON sm.session_id = ds.root_session_id WHERE sm.placement_kind IS NULL`),
|
|
97
|
+
{
|
|
98
|
+
text: `UPDATE ${SESSION_EXT_TABLE} SET execution_role = '${WRITER}', execution_lane = 'device', execution_device_id = ds.device_id, ` +
|
|
99
|
+
"execution_device_owner_tenant = ds.owner_tenant, execution_device_owner_subject = ds.owner_subject, execution_placed_at = ds.bound_at, execution_rev = ds.rev " +
|
|
100
|
+
`FROM ${sourceTable} ds, session_meta sm WHERE ds.root_session_id = ${SESSION_EXT_TABLE}.session_id AND sm.session_id = ${SESSION_EXT_TABLE}.session_id AND sm.placement_kind IS NULL`,
|
|
101
|
+
values: [],
|
|
102
|
+
},
|
|
103
|
+
];
|
|
104
|
+
}
|
|
105
|
+
const str = (col) => `CONVERT(ds.${col} USING utf8mb4)`;
|
|
106
|
+
const rootKey = `${str("root_session_id")} COLLATE utf8mb4_bin`;
|
|
107
|
+
return [
|
|
108
|
+
ensureSessionExtRowsStatement(dialect, `SELECT sm.session_id FROM ${sourceTable} ds JOIN session_meta sm ON ${rootKey} = sm.session_id WHERE sm.placement_kind IS NULL`),
|
|
109
|
+
{
|
|
110
|
+
text: `UPDATE ${SESSION_EXT_TABLE} se JOIN session_meta sm ON sm.session_id = se.session_id JOIN ${sourceTable} ds ON ${rootKey} = se.session_id ` +
|
|
111
|
+
`SET se.execution_role = '${WRITER}', se.execution_lane = 'device', se.execution_device_id = ${str("device_id")}, ` +
|
|
112
|
+
`se.execution_device_owner_tenant = ${str("owner_tenant")}, se.execution_device_owner_subject = ${str("owner_subject")}, se.execution_placed_at = ds.bound_at, se.execution_rev = ds.rev ` +
|
|
113
|
+
"WHERE sm.placement_kind IS NULL",
|
|
114
|
+
values: [],
|
|
115
|
+
},
|
|
116
|
+
];
|
|
117
|
+
}
|
|
108
118
|
export function countOrphanBindingsStatement(dialect, sourceTable) {
|
|
109
119
|
const rootKey = dialect === "pg" ? "ds.root_session_id" : "CONVERT(ds.root_session_id USING utf8mb4) COLLATE utf8mb4_bin";
|
|
110
120
|
return {
|
|
@@ -135,7 +145,7 @@ export function placementCellFromRow(root, row) {
|
|
|
135
145
|
throw new ExecutionPlacementRowError(root, `role ${JSON.stringify(text(role))} is not writer / mirror / NULL`);
|
|
136
146
|
const lane = isNull(row.execution_lane) ? "" : text(row.execution_lane);
|
|
137
147
|
if (!isExecutionLane(lane))
|
|
138
|
-
throw new ExecutionPlacementRowError(root, `writer lane ${JSON.stringify(lane)} is not an execution lane`);
|
|
148
|
+
throw new ExecutionPlacementRowError(root, `writer lane ${JSON.stringify(lane)} is not an execution lane${retiredExecutionLaneHintM40(lane)}`);
|
|
139
149
|
if (isNull(row.execution_device_id)) {
|
|
140
150
|
if (deviceCols.some((v) => !isNull(v)))
|
|
141
151
|
throw new ExecutionPlacementRowError(root, "device owner without a device");
|
|
@@ -164,37 +174,69 @@ export function placementReadingFromRow(root, row) {
|
|
|
164
174
|
export function rowsOnSqlExec(exec) {
|
|
165
175
|
return async (sql, values) => (await exec.query(sql, [...values])).rows;
|
|
166
176
|
}
|
|
167
|
-
|
|
177
|
+
async function lockRootOn(conn, dialect, root) {
|
|
178
|
+
const ph = dialect === "pg" ? "$1" : "?";
|
|
179
|
+
return (await conn(`SELECT ${OCCUPANT_COLUMNS} FROM session_meta WHERE session_id = ${ph} FOR UPDATE`, [root]))[0];
|
|
180
|
+
}
|
|
181
|
+
export async function readClaimOn(conn, dialect, root) {
|
|
168
182
|
const ph = dialect === "pg" ? "$1" : "?";
|
|
169
|
-
const row = await conn(`SELECT session_id FROM session_meta WHERE session_id = ${ph} FOR UPDATE`, [root]);
|
|
170
|
-
if (row.length === 0)
|
|
171
|
-
return { rowPresent: false, activeTaskId: null };
|
|
172
183
|
const claim = await conn(`SELECT task_id FROM task_active WHERE session_id = ${ph} FOR UPDATE`, [root]);
|
|
173
|
-
return
|
|
184
|
+
return claim[0] === undefined ? null : text(claim[0].task_id);
|
|
185
|
+
}
|
|
186
|
+
export async function lockRootAndReadClaim(conn, dialect, root) {
|
|
187
|
+
if ((await lockRootOn(conn, dialect, root)) === undefined)
|
|
188
|
+
return { rowPresent: false, activeTaskId: null };
|
|
189
|
+
return { rowPresent: true, activeTaskId: await readClaimOn(conn, dialect, root) };
|
|
190
|
+
}
|
|
191
|
+
export async function readCellOn(conn, dialect, root) {
|
|
192
|
+
const ph = dialect === "pg" ? "$1" : "?";
|
|
193
|
+
const ensure = ensureSessionExtRowStatement(dialect, root);
|
|
194
|
+
await conn(ensure.text, ensure.values);
|
|
195
|
+
const row = (await conn(`SELECT ${EXECUTION_CELL_COLUMNS} FROM ${SESSION_EXT_TABLE} WHERE session_id = ${ph} FOR UPDATE`, [root]))[0];
|
|
196
|
+
return placementCellFromRow(root, row ?? {});
|
|
174
197
|
}
|
|
175
198
|
export async function readPlacementOn(conn, dialect, root) {
|
|
176
|
-
const
|
|
177
|
-
|
|
199
|
+
const occupant = await lockRootOn(conn, dialect, root);
|
|
200
|
+
if (occupant === undefined || !isNull(occupant.placement_kind))
|
|
201
|
+
return undefined;
|
|
202
|
+
return { occupant: sessionFaceFromRow(root, isNull(occupant.owner) ? null : text(occupant.owner), occupant.incarnation), cell: await readCellOn(conn, dialect, root) };
|
|
203
|
+
}
|
|
204
|
+
export async function writeCellOn(exec, dialect, root, statement) {
|
|
205
|
+
const res = await exec.query(statement.text, [...statement.values]);
|
|
206
|
+
if (res.affected !== 1)
|
|
207
|
+
throw placementInvariant(root, `a cell write (${statement.text.slice(0, 48)}…)`);
|
|
178
208
|
}
|
|
179
209
|
function placementInvariant(root, what) {
|
|
180
|
-
return new Error(`execution placement of session ${root}: ${what} matched no row
|
|
210
|
+
return new Error(`execution placement of session ${root}: ${what} matched no row under a held root-row lock after the judge found the cell writable — engine/driver anomaly, refusing to guess`);
|
|
181
211
|
}
|
|
182
212
|
export function createSqlExecutionPlacementSeat(db) {
|
|
183
213
|
const read = async (root) => {
|
|
184
|
-
const s = readPlacementRowStatement(db.dialect, root
|
|
214
|
+
const s = readPlacementRowStatement(db.dialect, root);
|
|
185
215
|
return placementReadingFromRow(root, (await db.query(s.text, [...s.values])).rows[0]);
|
|
186
216
|
};
|
|
187
217
|
return {
|
|
188
218
|
read,
|
|
189
219
|
async place(root, occupant, cell) {
|
|
190
220
|
assertPlaceableLane(root, cell);
|
|
191
|
-
const
|
|
192
|
-
|
|
221
|
+
const conn = await db.connect();
|
|
222
|
+
try {
|
|
223
|
+
await conn.begin();
|
|
224
|
+
const settled = settledPlaceOutcome(root, await readPlacementOn(rowsOnSqlExec(conn), db.dialect, root), occupant, cell);
|
|
225
|
+
if (settled !== WRITABLE) {
|
|
226
|
+
await conn.rollback();
|
|
227
|
+
return settled;
|
|
228
|
+
}
|
|
229
|
+
await writeCellOn(conn, db.dialect, root, placeWriterStatement(db.dialect, root, { lane: cell.lane }, new Date()));
|
|
230
|
+
await conn.commit();
|
|
193
231
|
return { outcome: "placed" };
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
232
|
+
}
|
|
233
|
+
catch (err) {
|
|
234
|
+
await conn.rollback().catch(() => undefined);
|
|
235
|
+
throw err;
|
|
236
|
+
}
|
|
237
|
+
finally {
|
|
238
|
+
conn.release();
|
|
239
|
+
}
|
|
198
240
|
},
|
|
199
241
|
async markMirror(root, occupant) {
|
|
200
242
|
const conn = await db.connect();
|
|
@@ -215,9 +257,7 @@ export function createSqlExecutionPlacementSeat(db) {
|
|
|
215
257
|
await conn.rollback();
|
|
216
258
|
return { outcome: "active", activeTaskId: claim.activeTaskId };
|
|
217
259
|
}
|
|
218
|
-
|
|
219
|
-
if ((await conn.query(s.text, [...s.values])).affected !== 1)
|
|
220
|
-
throw placementInvariant(root, "markMirror under a held row lock");
|
|
260
|
+
await writeCellOn(conn, db.dialect, root, markMirrorStatement(db.dialect, root));
|
|
221
261
|
await conn.commit();
|
|
222
262
|
return { outcome: "mirrored" };
|
|
223
263
|
}
|
|
@@ -8,8 +8,8 @@ import { type SpaceCommitClaim, type SpaceCommitReading, type SpaceCommitState }
|
|
|
8
8
|
* `RUN_STORE_STRICT_HYDRATE=on` 下 hydrate 列不出 `runs/` 时的**拒启**类型([ref] 件B;codex 对抗复审
|
|
9
9
|
* R1-[high] 验真后从裸 `Error` 升成具名类型)。
|
|
10
10
|
*
|
|
11
|
-
* 🔴
|
|
12
|
-
* (`DB_BACKEND` 未设)
|
|
11
|
+
* 🔴 **为什么必须是一个类型而不是一句文案**(修前形;降级臂改按数据根状态判之后,`runs/` 在场的根已不会降级,类型仍是拒句的属主):`openStoreBackendWithFallback` 对**默认推导**的 local
|
|
12
|
+
* (`DB_BACKEND` 未设)曾有一条按错误种类判的降级臂 —— mkdir / 只读盘那类「这台机器存不了盘」的失败降级到内存继续起。
|
|
13
13
|
* 本拒启从 `new LocalBackend(...)` 里冒出来,长得和它们一模一样,不给它一个可判别的身份就会被同一个
|
|
14
14
|
* catch 吞掉:operator 明确要的 **fail-closed 反而变成 fail-open**,而且丢的正是持久 run 账本(这根旋钮
|
|
15
15
|
* 存在的全部理由)。判据锚在**类型**上,不在文案上 —— 文案会改,类型不会(同文件族先例:`AdoptionError`
|
|
@@ -22,6 +22,13 @@ import { type SpaceCommitClaim, type SpaceCommitReading, type SpaceCommitState }
|
|
|
22
22
|
export declare class RunStoreStrictHydrateError extends StoreBootRefusalError {
|
|
23
23
|
readonly name = "RunStoreStrictHydrateError";
|
|
24
24
|
}
|
|
25
|
+
/** run 店在数据根下自己铸的目录(构造器与一次性迁移 M39 的名册同读这一只:名册的路径 = 店真实铸的路径)。 */
|
|
26
|
+
export declare function fileRunStoreDirsFor(root: string): {
|
|
27
|
+
readonly runs: string;
|
|
28
|
+
readonly active: string;
|
|
29
|
+
readonly tmp: string;
|
|
30
|
+
readonly spaceCommits: string;
|
|
31
|
+
};
|
|
25
32
|
export declare class FileRunStore implements InProcessClaimFence {
|
|
26
33
|
private readonly runsDir;
|
|
27
34
|
private readonly activeDir;
|
|
@@ -96,7 +103,7 @@ export declare class FileRunStore implements InProcessClaimFence {
|
|
|
96
103
|
*
|
|
97
104
|
* `readJsonlRecords` 对 ENOENT 答 `[]`、对其余读错(EACCES / EIO / EISDIR / ENOTDIR)**抛普通 Error**
|
|
98
105
|
* (亲验 core `dist/stores/file/fs-atomic.js`)。那个普通 Error 从构造器冒出去之后,在**默认
|
|
99
|
-
* 推导**的 local
|
|
106
|
+
* 推导**的 local 后端上修前会被 `openStoreBackendWithFallback` 的降级臂吞成 memory —— 也就是说 strict 开着
|
|
100
107
|
* 也照样带着残缺账本(或直接换成内存)起动,两处 readdir 门白守。
|
|
101
108
|
*
|
|
102
109
|
* ⇒ strict 档:非 ENOENT 的读盘失败一律转成 {@link RunStoreStrictHydrateError}(带路径 + 原文),由
|
|
@@ -118,13 +125,21 @@ export declare class FileRunStore implements InProcessClaimFence {
|
|
|
118
125
|
*/
|
|
119
126
|
private refuseIfUnreadable;
|
|
120
127
|
private hydrate;
|
|
121
|
-
/** run.json 的整文件原子替换 —— {@link persist}
|
|
128
|
+
/** run.json 的整文件原子替换 —— {@link persist} 的落盘那一半,不碰索引(只有 `persist` 调它)。 */
|
|
122
129
|
private writeRunFile;
|
|
123
|
-
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
130
|
+
/**
|
|
131
|
+
* 索引里的行**只有这一条写律**,每个写口(建行 / 状态迁移 / 心跳 / 取消位 / 幂等绑定 / 接管 / 预览补写)都走它:
|
|
132
|
+
* **对副本判改 → 落盘成功 → 把改动合进索引里的同一只行对象**(索引里没有这一行才 `set` —— 建行)。
|
|
133
|
+
* 写口的形状恒为「在入口守卫读到的行上判,`{ ...r, 改动 }` 铸一份副本,交给本口」;`RunRow` 字段全 `readonly`,原地改一只行编不过。
|
|
134
|
+
*
|
|
135
|
+
* 三条后果都从这一条律拿到,不另设规则:
|
|
136
|
+
* · 落盘抛 ⇒ 索引里的行一字未动 —— 内存与盘同值,入口守卫读到的还是旧状态,重试照常补回。原地先改再落盘的写法,抛的那一拍把内存和盘劈成两半,
|
|
137
|
+
* 而改过的 `status` 还会让「首个终局写者赢」一类守卫把重试挡回 —— 盘上永远落不下那一笔(终局结果丢失,重启后被当孤儿记成 failed);
|
|
138
|
+
* · 落成之后索引里还是**同一只**行对象 —— 跨 await 持着行的收割腿(`reapSuspended` / `failSuspendedWithExpiredCheckpoint` / `reclaimOrphanedAtBoot`)
|
|
139
|
+
* await 之后的复核读的就是手上这只对象,换成副本它们就看不见期间的认领 / 取消 / 接管(再写一遍,把已被别腿落定的行盖掉);
|
|
140
|
+
* · 落盘与合回之间没有让出点(本口同步、体内无 await)⇒ 别的写者与收割腿读到的要么是落成前的行、要么是落成后的行,没有「盘已新、索引未合」的中间态。
|
|
141
|
+
* 在落盘与合回之间插 await 或别的事,就回到了收割写者会撞中间态的形(`test/file-run-store-persist-law.test.ts` 的结构钉守这一格)。
|
|
142
|
+
*/
|
|
128
143
|
private persist;
|
|
129
144
|
private eventLogFor;
|
|
130
145
|
/** Create a run iff the session has no active run (the task_active unique-key claim) AND no submission key of this
|
|
@@ -143,10 +158,9 @@ export declare class FileRunStore implements InProcessClaimFence {
|
|
|
143
158
|
* different claim locks) cannot both pass the check: the loser observes the winner's row. */
|
|
144
159
|
private commitNewRun;
|
|
145
160
|
/** run 行预览的写一次补写(SQL 孪生同义:列仍是 null 才写,建行写过 / 已补过的不动;行不在 ⇒ 无事)。
|
|
146
|
-
*
|
|
147
|
-
* 落成之后再把预览合回索引里的**同一只**行对象(不换对象:跨 await 持着行的收割腿复核读的是手上这只对象)。
|
|
161
|
+
* 走 {@link persist} 的写律:落盘抛 ⇒ 内存里的行一字未动(预览仍是 null)、盘上也原样,下一次补写照常再试 ——
|
|
148
162
|
* 原地先改再落盘,抛的那一拍就把内存和盘劈成两半(内存带预览、盘上 null),且「列已有值」的早退让这一分叉再也补不回来。
|
|
149
|
-
*
|
|
163
|
+
* 预览补写不碰 `updatedAt`(一次预览补写不是一次活性刷新)。 */
|
|
150
164
|
fillObjectivePreview(taskId: string, preview: string): Promise<void>;
|
|
151
165
|
requestCancel(taskId: string, owner: string | null): Promise<boolean>;
|
|
152
166
|
isCancelRequested(taskId: string, owner: string | null): Promise<boolean>;
|
|
@@ -372,12 +386,6 @@ export declare class FileRunStore implements InProcessClaimFence {
|
|
|
372
386
|
private releaseClaim;
|
|
373
387
|
/** Drop a run entirely (registry + event log + open fd + on-disk dir) — used by deleteBySession. */
|
|
374
388
|
private dropRun;
|
|
375
|
-
/**
|
|
376
|
-
* 一次性迁移 **M6 的 local 腿**(窗、删法与删后谁接住:窗口见 `plugins/one-time-migrations.ts` 登记表):把 ≤7.115.x 写下的死亡判决行
|
|
377
|
-
* (`failed` ∧ 码列空 ∧ 句子是那两句,判据 = `readLegacyHolderDeathCode`)补上机读码,盘上(`run.json` 整份原子替换,同 `persist`)与内存同改。
|
|
378
|
-
* 起服时调(`LocalBackend.runOneTimeMigrations`,任何读者之前);数据根独占 ⇒ 本车道没有滚动升级窗,不需要读侧半场。幂等:第二跑零命中零写盘。
|
|
379
|
-
*/
|
|
380
|
-
migrateLegacyHolderDeathCodes(): number;
|
|
381
389
|
/**
|
|
382
390
|
* 一次性迁移 **M32 的 local 腿**(执行放置回填;窗、删法与删后谁接住:窗口见 `plugins/one-time-migrations.ts` 登记表):有 run 行的会话 id(去重)。
|
|
383
391
|
* 起服时调(`LocalBackend.runOneTimeMigrations`,任何读者之前);读内存索引(构造时已从盘上 hydrate),零写。
|