@sema-agent/server 7.150.0 → 7.152.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATION.md +451 -0
- package/README.md +15 -3
- package/README.zh-CN.md +10 -2
- package/USAGE.md +144 -87
- package/deploy/sema-up/README.md +11 -4
- package/deploy/sema-up/chart/Chart.yaml +1 -1
- package/deploy/sema-up/chart/templates/NOTES.txt +5 -0
- package/deploy/sema-up/chart/templates/_helpers.tpl +15 -16
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -3
- package/deploy/sema-up/chart/templates/server.yaml +5 -3
- package/deploy/sema-up/chart/values-full-single.yaml +3 -1
- package/deploy/sema-up/chart/values.yaml +8 -1
- package/deploy/sema-up/cluster-up.sh +7 -6
- package/deploy/sema-up/kube-up.sh +6 -6
- package/deploy/sema-up/lib/flagshape.sh +36 -8
- package/deploy/sema-up/lib/helm-values-cluster.py +2 -0
- package/deploy/sema-up/lib/helm-values-kube.py +2 -0
- package/deploy/sema-up/machines.example.yaml +3 -1
- package/deploy/sema-up/sema-up.sh +22 -16
- package/dist/adoption/import.js +3 -3
- package/dist/approval-ask-audit-store.d.ts +1 -1
- package/dist/approval-ask-machine.d.ts +4 -10
- package/dist/approval-ask-retention.d.ts +1 -1
- package/dist/approval-card.d.ts +12 -14
- package/dist/approval-gate-currency.d.ts +9 -9
- package/dist/approval-gate-currency.js +3 -4
- package/dist/approval-hmac.d.ts +17 -1
- package/dist/approval-hmac.js +7 -1
- package/dist/approval-queue-kind.d.ts +1 -1
- package/dist/approval.d.ts +2 -2
- package/dist/approval.js +2 -2
- package/dist/auth-bridge.d.ts +20 -0
- package/dist/auth-bridge.js +9 -0
- package/dist/background-session-reap.d.ts +1 -1
- package/dist/bake-runner/main.d.ts +4 -2
- package/dist/bind-host.d.ts +3 -6
- package/dist/bind-host.js +4 -7
- package/dist/boot/budget-tracing.js +1 -1
- package/dist/boot/coordinators.d.ts +1 -1
- package/dist/boot/coordinators.js +9 -10
- package/dist/boot/device-lane.js +2 -0
- package/dist/boot/engine-lease.d.ts +5 -0
- package/dist/boot/engine-lease.js +1 -0
- package/dist/boot/execution-env.d.ts +9 -14
- package/dist/boot/execution-env.js +85 -22
- package/dist/boot/execution-lane.js +32 -5
- package/dist/boot/late-binds.d.ts +8 -4
- package/dist/boot/late-binds.js +7 -1
- package/dist/boot/leader.d.ts +31 -30
- package/dist/boot/leader.js +38 -28
- package/dist/boot/leg-path-adjudication.d.ts +40 -0
- package/dist/boot/leg-path-adjudication.js +18 -0
- package/dist/boot/memory-consolidation.d.ts +3 -2
- package/dist/boot/memory-consolidation.js +6 -6
- package/dist/boot/parked-revive-gate.js +3 -15
- package/dist/boot/reapers.d.ts +6 -1
- package/dist/boot/reapers.js +13 -2
- package/dist/boot/resolve-spec.d.ts +3 -3
- package/dist/boot/resolve-spec.js +43 -48
- package/dist/boot/runner-deps.d.ts +46 -35
- package/dist/boot/runner-deps.js +94 -91
- package/dist/boot/session-age-out.d.ts +36 -0
- package/dist/boot/session-age-out.js +101 -0
- package/dist/boot/session-faces.d.ts +5 -14
- package/dist/boot/session-faces.js +9 -5
- package/dist/boot/shutdown.d.ts +6 -0
- package/dist/boot/shutdown.js +10 -4
- package/dist/boot/stage-01-config.js +2 -0
- package/dist/boot/stage-02-web-admin-pull.js +4 -5
- package/dist/boot/stage-05-execution-env.d.ts +5 -3
- package/dist/boot/stage-05-execution-env.js +3 -2
- package/dist/boot/stage-06-runners.d.ts +9 -4
- package/dist/boot/stage-06-runners.js +24 -9
- package/dist/boot/stage-07-capability-layer.d.ts +8 -4
- package/dist/boot/stage-07-capability-layer.js +3 -2
- package/dist/boot/stage-08-reapers.d.ts +8 -4
- package/dist/boot/stage-08-reapers.js +4 -2
- package/dist/boot/stage-09-leader.d.ts +12 -5
- package/dist/boot/stage-09-leader.js +14 -5
- package/dist/boot/stage-10-http-server.d.ts +19 -5
- package/dist/boot/stage-10-http-server.js +14 -21
- package/dist/boot/stores.js +7 -4
- package/dist/boot/web-admin.js +5 -8
- package/dist/boot/workflow-orchestration.d.ts +7 -2
- package/dist/boot/workflow-orchestration.js +24 -7
- package/dist/bounded-rotation.d.ts +29 -0
- package/dist/bounded-rotation.js +24 -0
- package/dist/capabilities/approvals-push.d.ts +3 -3
- package/dist/capabilities/scenarios.d.ts +28 -13
- package/dist/capabilities/scenarios.js +2 -2
- package/dist/capability-facts.d.ts +43 -32
- package/dist/capability-facts.js +45 -51
- package/dist/card-rule-offers.d.ts +32 -0
- package/dist/card-rule-offers.js +130 -0
- package/dist/center-credential.d.ts +25 -6
- package/dist/center-credential.js +25 -5
- package/dist/config-catalog.d.ts +26 -7
- package/dist/config-catalog.js +26 -22
- package/dist/config-dir-trust.js +4 -2
- package/dist/config-invariants.d.ts +20 -8
- package/dist/config-invariants.js +55 -12
- package/dist/config-lkg.d.ts +5 -19
- package/dist/config-lkg.js +8 -62
- package/dist/config-provider.d.ts +1 -1
- package/dist/config-root-migration.d.ts +2 -2
- package/dist/config-types.d.ts +38 -42
- package/dist/config.d.ts +58 -7
- package/dist/config.js +90 -40
- package/dist/control-socket.d.ts +51 -0
- package/dist/control-socket.js +115 -0
- package/dist/deployment-governance.d.ts +2 -1
- package/dist/deployment-shape.d.ts +9 -1
- package/dist/deployment-shape.js +2 -1
- package/dist/device-protocol.d.ts +5 -4
- package/dist/device-protocol.js +1 -1
- package/dist/device-ws-hub.d.ts +7 -0
- package/dist/device-ws-hub.js +10 -3
- package/dist/device-ws-protocol.d.ts +63 -10
- package/dist/device-ws-protocol.js +56 -25
- package/dist/elicitation.js +2 -2
- package/dist/engine-identity.d.ts +19 -7
- package/dist/engine-identity.js +10 -2
- package/dist/entry-mode-clamp-notice.d.ts +2 -1
- package/dist/entry-problems.d.ts +40 -3
- package/dist/entry-problems.js +3 -1
- package/dist/execution-env-refusal.d.ts +29 -0
- package/dist/execution-env-refusal.js +8 -0
- package/dist/execution-lane-caps.d.ts +3 -1
- package/dist/field-conflict.d.ts +1 -1
- package/dist/file-history-capture.d.ts +11 -4
- package/dist/file-history-capture.js +9 -6
- package/dist/file-history-disclosure.d.ts +7 -5
- package/dist/file-history-disclosure.js +7 -5
- package/dist/fleet/drain-entry.d.ts +4 -0
- package/dist/fleet/engine-signal.d.ts +12 -29
- package/dist/fleet/engine-signal.js +1 -7
- package/dist/fleet-client.js +2 -5
- package/dist/gate-settlement.d.ts +1 -8
- package/dist/gate-settlement.js +0 -4
- package/dist/history-anchor.js +1 -1
- package/dist/hitl-delivery.d.ts +2 -3
- package/dist/hitl-delivery.js +0 -2
- package/dist/hooks/hook-llm.js +4 -2
- package/dist/hooks/hook-runner.d.ts +3 -2
- package/dist/hooks/hook-runner.js +18 -3
- package/dist/host-decision.d.ts +11 -11
- package/dist/host-lsp-manager.d.ts +2 -2
- package/dist/http/active-run-conflict.d.ts +35 -2
- package/dist/http/active-run-conflict.js +48 -19
- package/dist/http/admission.js +17 -2
- package/dist/http/approval-sweeps.d.ts +1 -1
- package/dist/http/approval-sweeps.js +10 -7
- package/dist/http/checkpoint-ctx.d.ts +4 -0
- package/dist/http/checkpoint-ctx.js +2 -0
- package/dist/http/dispatch.d.ts +8 -3
- package/dist/http/dispatch.js +59 -32
- package/dist/http/durable-run-leg.js +16 -17
- package/dist/http/health-reader.d.ts +16 -9
- package/dist/http/health-reader.js +2 -1
- package/dist/http/health-self-report.d.ts +9 -1
- package/dist/http/health-self-report.js +3 -1
- package/dist/http/owner-access.d.ts +33 -14
- package/dist/http/owner-access.js +40 -10
- package/dist/http/principal-gate.d.ts +49 -21
- package/dist/http/principal-gate.js +61 -11
- package/dist/http/request-channel.d.ts +23 -0
- package/dist/http/request-channel.js +9 -0
- package/dist/http/request-guards.js +17 -2
- package/dist/http/resume-ctx-read.js +42 -3
- package/dist/http/resume-legs.d.ts +4 -3
- package/dist/http/resume-legs.js +367 -117
- package/dist/http/route-ctx.d.ts +91 -15
- package/dist/http/route-ctx.js +17 -0
- package/dist/http/route-table.d.ts +5 -1
- package/dist/http/route-table.js +4 -0
- package/dist/http/routes/admin-config-refresh.js +3 -3
- package/dist/http/routes/admin-drain.d.ts +3 -0
- package/dist/http/routes/admin-drain.js +7 -7
- package/dist/http/routes/admin-memory-optout.d.ts +1 -1
- package/dist/http/routes/admin-memory-optout.js +3 -3
- package/dist/http/routes/adoption.js +3 -5
- package/dist/http/routes/agents-roster.js +2 -3
- package/dist/http/routes/approvals-assistant.d.ts +2 -1
- package/dist/http/routes/approvals-assistant.js +99 -51
- package/dist/http/routes/background.d.ts +3 -3
- package/dist/http/routes/capabilities.d.ts +4 -0
- package/dist/http/routes/capabilities.js +38 -10
- package/dist/http/routes/config-catalog.js +2 -2
- package/dist/http/routes/devices.js +1 -1
- package/dist/http/routes/diagnostics.d.ts +3 -3
- package/dist/http/routes/diagnostics.js +19 -7
- package/dist/http/routes/fleet.js +10 -8
- package/dist/http/routes/images.js +10 -10
- package/dist/http/routes/memory-bundle.js +3 -3
- package/dist/http/routes/memory-compliance.js +3 -3
- package/dist/http/routes/memory-consolidation.js +2 -2
- package/dist/http/routes/memory-origin.js +3 -3
- package/dist/http/routes/memory-policy.js +2 -2
- package/dist/http/routes/observability.js +3 -3
- package/dist/http/routes/projects.d.ts +3 -2
- package/dist/http/routes/projects.js +4 -5
- package/dist/http/routes/retention-ops.js +3 -3
- package/dist/http/routes/rules.js +5 -5
- package/dist/http/routes/run-permission-mode.d.ts +2 -1
- package/dist/http/routes/run-permission-mode.js +2 -2
- package/dist/http/routes/runs.d.ts +4 -9
- package/dist/http/routes/runs.js +171 -65
- package/dist/http/routes/session-sync.d.ts +22 -9
- package/dist/http/routes/session-sync.js +204 -107
- package/dist/http/routes/sessions-list.js +13 -7
- package/dist/http/routes/sessions.js +30 -15
- package/dist/http/routes/tasks.js +46 -41
- package/dist/http/routes/trace-usage.js +2 -2
- package/dist/http/routes/workflows.js +1 -1
- package/dist/http/server.d.ts +30 -30
- package/dist/http/server.js +16 -4
- package/dist/http/submit-ctx.d.ts +1 -1
- package/dist/http/submit-ctx.js +7 -4
- package/dist/http/wire-types.d.ts +14 -4
- package/dist/human-facing-args.d.ts +33 -0
- package/dist/human-facing-args.js +33 -0
- package/dist/identity-source.d.ts +20 -3
- package/dist/identity-source.js +14 -0
- package/dist/index.d.ts +5 -1
- package/dist/k8s-api-credentials.d.ts +29 -0
- package/dist/k8s-api-credentials.js +25 -0
- package/dist/lane-home-probe.d.ts +3 -7
- package/dist/lane-home-probe.js +2 -2
- package/dist/leader/diffup.d.ts +19 -0
- package/dist/leader/diffup.js +7 -0
- package/dist/leader/leader.d.ts +116 -11
- package/dist/leader/leader.js +69 -5
- package/dist/leader/repair-wire.js +2 -2
- package/dist/leader/run-entry.d.ts +2 -1
- package/dist/leader/run-entry.js +1 -1
- package/dist/leader/wire.d.ts +42 -132
- package/dist/leader/wire.js +81 -67
- package/dist/leg-facts.d.ts +13 -5
- package/dist/leg-facts.js +2 -1
- package/dist/memory-scope.d.ts +23 -11
- package/dist/memory-scope.js +18 -6
- package/dist/memory-sync-client.d.ts +30 -2
- package/dist/memory-sync-client.js +16 -9
- package/dist/model-entry-headers.d.ts +9 -10
- package/dist/model-entry-headers.js +0 -4
- package/dist/model-entry-refusal.d.ts +7 -4
- package/dist/model-entry-refusal.js +11 -5
- package/dist/model-plane-face.d.ts +1 -1
- package/dist/model-plane-face.js +3 -1
- package/dist/model-route-endpoint.d.ts +13 -7
- package/dist/model-route-endpoint.js +14 -11
- package/dist/model-select.d.ts +22 -0
- package/dist/model-select.js +9 -0
- package/dist/model-unreachable-notice.d.ts +11 -0
- package/dist/model-unreachable-notice.js +4 -4
- package/dist/object-store-buckets.d.ts +640 -6
- package/dist/object-store-buckets.js +166 -0
- package/dist/observability/err-text.d.ts +7 -0
- package/dist/observability/err-text.js +5 -0
- package/dist/observability/fail-open.d.ts +25 -17
- package/dist/observability/fail-open.js +25 -17
- package/dist/observability/logger.js +3 -1
- package/dist/observability/metrics.js +1 -0
- package/dist/operator-roster.d.ts +68 -0
- package/dist/operator-roster.js +32 -0
- package/dist/orchestration/workflow-notify-journal.d.ts +18 -1
- package/dist/orchestration/workflow-notify-journal.js +12 -1
- package/dist/orchestration/workflow-park-decision.d.ts +70 -18
- package/dist/orchestration/workflow-park-decision.js +49 -10
- package/dist/orchestration/workflow-park-holder.d.ts +65 -0
- package/dist/orchestration/workflow-park-holder.js +98 -0
- package/dist/orchestration/workflow-record-fence.d.ts +36 -0
- package/dist/orchestration/workflow-record-fence.js +42 -0
- package/dist/outbound-dispatcher.d.ts +71 -8
- package/dist/outbound-dispatcher.js +48 -7
- package/dist/owner-faces.d.ts +2 -2
- package/dist/parked-decide.d.ts +106 -55
- package/dist/parked-decide.js +153 -117
- package/dist/peer-directory.d.ts +2 -2
- package/dist/peer-inbound-face.d.ts +2 -6
- package/dist/peer-inbound-face.js +0 -3
- package/dist/permission-mode-admission.d.ts +74 -5
- package/dist/permission-mode-admission.js +56 -3
- package/dist/plugins/adoption-log-sql.d.ts +3 -1
- package/dist/plugins/adoption-log-sql.js +7 -1
- package/dist/plugins/approval-ask-store-file.d.ts +14 -2
- package/dist/plugins/approval-ask-store-file.js +11 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +10 -1
- package/dist/plugins/approval-ask-store-memory.js +35 -10
- package/dist/plugins/approval-ask-store-sql.d.ts +69 -4
- package/dist/plugins/approval-ask-store-sql.js +45 -5
- package/dist/plugins/approval-exemption-store.js +3 -0
- package/dist/plugins/approval-nonce-store.js +2 -0
- package/dist/plugins/blob-backend.d.ts +83 -7
- package/dist/plugins/blob-backend.js +57 -6
- package/dist/plugins/breaker-state-sql.js +2 -0
- package/dist/plugins/caching-session-store.d.ts +9 -15
- package/dist/plugins/caching-session-store.js +6 -0
- package/dist/plugins/checkpoint-index-columns.d.ts +20 -16
- package/dist/plugins/checkpoint-index-columns.js +3 -6
- package/dist/plugins/checkpoint-store-face.d.ts +119 -61
- package/dist/plugins/checkpoint-store-face.js +134 -55
- package/dist/plugins/device-store-sql.js +6 -0
- package/dist/plugins/error-origin.d.ts +18 -0
- package/dist/plugins/error-origin.js +10 -0
- package/dist/plugins/execution-placement-sql.js +6 -6
- package/dist/plugins/image-bake-store-sql.js +6 -0
- package/dist/plugins/image-index-sql.js +4 -0
- package/dist/plugins/landed-attendants.d.ts +212 -0
- package/dist/plugins/landed-attendants.js +161 -0
- package/dist/plugins/leader-run-store-sql.js +4 -0
- package/dist/plugins/local-checkpoint-store.d.ts +13 -3
- package/dist/plugins/local-checkpoint-store.js +38 -49
- package/dist/plugins/local-session-live-reference.d.ts +40 -0
- package/dist/plugins/local-session-live-reference.js +39 -0
- package/dist/plugins/local-session-store.d.ts +71 -33
- package/dist/plugins/local-session-store.js +129 -27
- package/dist/plugins/memory-engine-pg.js +4 -0
- package/dist/plugins/memory-engine-sql-apply.js +5 -2
- package/dist/plugins/memory-engine-tidb.js +4 -0
- package/dist/plugins/memory-optout-grant-store-sql.js +4 -0
- package/dist/plugins/memory-sync-store-pg.js +5 -0
- package/dist/plugins/memory-sync-store-tidb.js +5 -0
- package/dist/plugins/one-time-migrations.d.ts +104 -80
- package/dist/plugins/one-time-migrations.js +226 -132
- package/dist/plugins/org-delivery-quota-store.js +4 -1
- package/dist/plugins/outcome-ledger-sql.js +2 -0
- package/dist/plugins/permission-rule-store-sql.js +11 -4
- package/dist/plugins/pg-cost-quota.js +4 -0
- package/dist/plugins/pg-pool.js +35 -10
- package/dist/plugins/pg-rate-limiter.js +2 -0
- package/dist/plugins/posix-shell-fs.d.ts +6 -1
- package/dist/plugins/posix-shell-fs.js +4 -1
- package/dist/plugins/remote-env-adb.d.ts +19 -15
- package/dist/plugins/remote-env-adb.js +41 -15
- package/dist/plugins/remote-env-connect-seat.d.ts +105 -0
- package/dist/plugins/remote-env-connect-seat.js +72 -0
- package/dist/plugins/remote-env-device.d.ts +22 -5
- package/dist/plugins/remote-env-device.js +106 -8
- package/dist/plugins/remote-env-e2b.d.ts +15 -6
- package/dist/plugins/remote-env-e2b.js +42 -32
- package/dist/plugins/remote-env-file-error.js +6 -2
- package/dist/plugins/remote-env-host.d.ts +46 -10
- package/dist/plugins/remote-env-host.js +124 -52
- package/dist/plugins/remote-env-k8s.d.ts +109 -41
- package/dist/plugins/remote-env-k8s.js +160 -54
- package/dist/plugins/remote-env-local-docker.d.ts +13 -8
- package/dist/plugins/remote-env-local-docker.js +34 -41
- package/dist/plugins/remote-env-ssh.d.ts +18 -12
- package/dist/plugins/remote-env-ssh.js +60 -59
- package/dist/plugins/remote-shell.d.ts +98 -1
- package/dist/plugins/remote-shell.js +218 -0
- package/dist/plugins/replica-registration.d.ts +1 -1
- package/dist/plugins/replica-registration.js +1 -1
- package/dist/plugins/resume-anchor-store-sql.d.ts +11 -2
- package/dist/plugins/resume-anchor-store-sql.js +12 -5
- package/dist/plugins/retention-lane-store-sql.js +4 -0
- package/dist/plugins/retention-sql.d.ts +20 -2
- package/dist/plugins/retention-sql.js +11 -0
- package/dist/plugins/run-store-sql.d.ts +21 -2
- package/dist/plugins/run-store-sql.js +31 -7
- package/dist/plugins/s3-presign.d.ts +23 -0
- package/dist/plugins/s3-presign.js +37 -3
- package/dist/plugins/scenario-prefix-switch-m42.d.ts +1 -1
- package/dist/plugins/scenario-prefix-switch-m42.js +2 -2
- package/dist/plugins/scheduler-support.d.ts +2 -2
- package/dist/plugins/scheduler-support.js +0 -3
- package/dist/plugins/schema-consistency.d.ts +4 -2
- package/dist/plugins/schema-consistency.js +19 -2
- package/dist/plugins/schema-indexes.js +2 -0
- package/dist/plugins/send-file-ledger.d.ts +2 -2
- package/dist/plugins/send-file-ledger.js +5 -2
- package/dist/plugins/send-user-file.d.ts +3 -4
- package/dist/plugins/send-user-file.js +56 -52
- package/dist/plugins/serving-requirement.d.ts +26 -7
- package/dist/plugins/serving-requirement.js +11 -4
- package/dist/plugins/session-birth.d.ts +6 -2
- package/dist/plugins/session-blob-claim-token.d.ts +15 -0
- package/dist/plugins/session-blob-claim-token.js +20 -0
- package/dist/plugins/session-blob-namespace.d.ts +46 -0
- package/dist/plugins/session-blob-namespace.js +116 -0
- package/dist/plugins/session-capture-record-store-sql.js +2 -0
- package/dist/plugins/session-ext-table.d.ts +14 -1
- package/dist/plugins/session-ext-table.js +5 -1
- package/dist/plugins/session-row-sql.d.ts +49 -2
- package/dist/plugins/session-row-sql.js +56 -13
- package/dist/plugins/session-store-sql.d.ts +34 -18
- package/dist/plugins/session-store-sql.js +98 -17
- package/dist/plugins/shared-memory-store-sql.d.ts +1 -0
- package/dist/plugins/shared-memory-store-sql.js +6 -2
- package/dist/plugins/snapshot-bucket-presence.d.ts +25 -2
- package/dist/plugins/snapshot-bucket-presence.js +8 -2
- package/dist/plugins/sql-driver.d.ts +2 -1
- package/dist/plugins/sql-driver.js +18 -3
- package/dist/plugins/sql-errors.d.ts +11 -6
- package/dist/plugins/sql-errors.js +5 -6
- package/dist/plugins/sql-json-column.d.ts +1 -1
- package/dist/plugins/stop-then-start-sentence.d.ts +10 -4
- package/dist/plugins/stop-then-start-sentence.js +14 -10
- package/dist/plugins/stop-then-start.d.ts +109 -0
- package/dist/plugins/stop-then-start.js +104 -0
- package/dist/plugins/store-backend.d.ts +84 -15
- package/dist/plugins/store-backend.js +236 -72
- package/dist/plugins/store-boundary.d.ts +57 -0
- package/dist/plugins/store-boundary.js +139 -0
- package/dist/plugins/store-contracts.d.ts +17 -0
- package/dist/plugins/store-fault-sentence-m53.d.ts +7 -0
- package/dist/plugins/store-fault-sentence-m53.js +25 -0
- package/dist/plugins/store-fault.d.ts +26 -7
- package/dist/plugins/store-fault.js +18 -2
- package/dist/plugins/task-attachment-store.d.ts +2 -1
- package/dist/plugins/task-attachment-store.js +14 -1
- package/dist/plugins/task-list-store-sql.d.ts +2 -2
- package/dist/plugins/task-list-store-sql.js +10 -8
- package/dist/plugins/tidb-cost-quota.js +4 -0
- package/dist/plugins/tidb-pool.js +21 -25
- package/dist/plugins/tidb-rate-limiter.js +4 -0
- package/dist/plugins/user-input-ledger-sql.js +4 -0
- package/dist/plugins/workflow-run-store-sql.d.ts +28 -10
- package/dist/plugins/workflow-run-store-sql.js +64 -4
- package/dist/plugins/workspace-custody.d.ts +4 -3
- package/dist/plugins/workspace-fill.d.ts +4 -7
- package/dist/plugins/workspace-fill.js +2 -1
- package/dist/plugins/write-behind-counter.js +5 -0
- package/dist/project-context.d.ts +0 -2
- package/dist/project-context.js +4 -8
- package/dist/project-registry.d.ts +46 -0
- package/dist/project-registry.js +44 -0
- package/dist/question.d.ts +2 -1
- package/dist/question.js +5 -13
- package/dist/request-form.d.ts +6 -1
- package/dist/request-form.js +4 -1
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +4 -0
- package/dist/request-value-closure.js +10 -0
- package/dist/rule-issue-reading.d.ts +1 -1
- package/dist/rules-consent.d.ts +1 -1
- package/dist/run-acceptance.d.ts +3 -2
- package/dist/run-acceptance.js +4 -6
- package/dist/run-local.js +9 -9
- package/dist/runs.d.ts +54 -16
- package/dist/runs.js +67 -13
- package/dist/runtime-governance.d.ts +5 -4
- package/dist/security.d.ts +30 -32
- package/dist/security.js +41 -7
- package/dist/sema-config-dir.d.ts +2 -1
- package/dist/server-secret-env.d.ts +12 -10
- package/dist/server-secret-env.js +24 -15
- package/dist/session-bindings.d.ts +82 -0
- package/dist/session-bindings.js +18 -0
- package/dist/session-children-retire.d.ts +2 -2
- package/dist/session-children-retire.js +2 -6
- package/dist/session-deletion.d.ts +16 -1
- package/dist/session-error-wire.d.ts +3 -3
- package/dist/session-error-wire.js +3 -3
- package/dist/session-incarnation.d.ts +10 -0
- package/dist/session-incarnation.js +10 -1
- package/dist/session-kind.d.ts +57 -0
- package/dist/session-kind.js +22 -0
- package/dist/session-row.d.ts +21 -1
- package/dist/session-row.js +7 -1
- package/dist/session-sync-kernel.d.ts +24 -14
- package/dist/session-sync-kernel.js +3 -6
- package/dist/session-sync.d.ts +25 -103
- package/dist/session-sync.js +14 -76
- package/dist/session-titler.d.ts +10 -3
- package/dist/session-titler.js +19 -6
- package/dist/ssh-host-key.d.ts +5 -0
- package/dist/ssh-host-key.js +3 -0
- package/dist/stores-sql/blob-index-sql.d.ts +30 -9
- package/dist/stores-sql/blob-index-sql.js +40 -21
- package/dist/stores-sql/checkpoint-store-sql.d.ts +54 -27
- package/dist/stores-sql/checkpoint-store-sql.js +70 -146
- package/dist/stores-sql/file-history-store-sql.d.ts +113 -15
- package/dist/stores-sql/file-history-store-sql.js +205 -95
- package/dist/stores-sql/pg-session-storage.d.ts +34 -7
- package/dist/stores-sql/pg-session-storage.js +37 -13
- package/dist/stores-sql/retention-store-sql.d.ts +1 -9
- package/dist/stores-sql/retention-store-sql.js +5 -19
- package/dist/stores-sql/session-policy-store-sql.d.ts +30 -7
- package/dist/stores-sql/session-policy-store-sql.js +61 -44
- package/dist/stores-sql/session-write-hooks.d.ts +11 -0
- package/dist/stores-sql/tidb-session-store.d.ts +58 -7
- package/dist/stores-sql/tidb-session-store.js +37 -13
- package/dist/submission-exit.d.ts +3 -2
- package/dist/submission-exit.js +9 -1
- package/dist/task-cwd.d.ts +2 -2
- package/dist/task-settings.d.ts +7 -5
- package/dist/task-settings.js +3 -3
- package/dist/terminal.d.ts +33 -2
- package/dist/terminal.js +139 -9
- package/dist/tool-approval.d.ts +465 -507
- package/dist/tool-approval.js +606 -1222
- package/dist/trace/core-keyset-guard.d.ts +1 -1
- package/dist/trace/ledger-events.d.ts +3 -3
- package/dist/trace/project.d.ts +2 -3
- package/dist/trace/redact.js +3 -2
- package/dist/trace/self-minted-wire.d.ts +571 -178
- package/dist/trace/self-minted-wire.js +189 -56
- package/dist/web-admin-client/apply-effective.js +2 -2
- package/dist/web-admin-client/read-warnings.d.ts +2 -2
- package/dist/web-admin-client/read-warnings.js +1 -1
- package/dist/web-admin-client/types.d.ts +1 -1
- package/dist/workspace-space.d.ts +10 -4
- package/dist/workspace-space.js +4 -1
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +79 -28
- package/package.json +7 -3
- package/scripts/embed-minimal.mjs +3 -3
- package/wire-changes/server@7.151.0.json +762 -0
- package/wire-changes/server@7.152.0.json +900 -0
- package/dist/config-d-migration.d.ts +0 -37
- package/dist/config-d-migration.js +0 -60
- package/dist/http/session-inherit-env.d.ts +0 -36
- package/dist/http/session-inherit-env.js +0 -6
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { buildDisplaySafeUrl } from "../trace/redact.js";
|
|
2
|
-
import { MinioBlobBackend } from "./blob-backend.js";
|
|
2
|
+
import { MinioBlobBackend, sessionBlobKeyPrefixOf } from "./blob-backend.js";
|
|
3
|
+
import { workspaceSnapshotPrefixOf } from "../workspace-space.js";
|
|
3
4
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
4
5
|
import { SESSION_SNAPSHOT_BUCKET_DEFAULT, WORKSPACE_SNAPSHOT_BUCKET_DEFAULT } from "../object-store-buckets.js";
|
|
5
6
|
import { isStoreOpenWindowExpired, openWithinWait } from "./store-open-wait.js";
|
|
@@ -10,6 +11,8 @@ export const SNAPSHOT_BUCKET_ROLES = {
|
|
|
10
11
|
defaultName: SESSION_SNAPSHOT_BUCKET_DEFAULT,
|
|
11
12
|
consequence: "every snapshot-offload write and SendUserFile private-track request would answer 404 NoSuchBucket (and the orphan sweep would log one every minute, forever)",
|
|
12
13
|
createHint: "; this version's sema-up scripts create it — re-run them on an existing sema-up deployment",
|
|
14
|
+
probeOp: "boot-probe/session:LIST",
|
|
15
|
+
probePrefix: (store) => sessionBlobKeyPrefixOf(store, "legacy-blobs"),
|
|
13
16
|
},
|
|
14
17
|
workspace: {
|
|
15
18
|
noun: "workspace snapshot bucket",
|
|
@@ -17,6 +20,8 @@ export const SNAPSHOT_BUCKET_ROLES = {
|
|
|
17
20
|
defaultName: WORKSPACE_SNAPSHOT_BUCKET_DEFAULT,
|
|
18
21
|
consequence: "no workspace snapshot could be saved or restored (every run would start from an empty /workspace and every run-end save would fail on a bare 404), and no line would say the bucket is missing",
|
|
19
22
|
createHint: "",
|
|
23
|
+
probeOp: "boot-probe/workspace:LIST",
|
|
24
|
+
probePrefix: (store) => `${workspaceSnapshotPrefixOf(store)}/`,
|
|
20
25
|
},
|
|
21
26
|
};
|
|
22
27
|
export const SNAPSHOT_BUCKET_PROBE_TIMEOUT_MS = 10_000;
|
|
@@ -34,7 +39,8 @@ export function buildSnapshotBucketRefusal(bucket, endpoint, waitedMs, role = "s
|
|
|
34
39
|
}
|
|
35
40
|
export const SNAPSHOT_BUCKET_PROBE_PENDING = "probe still pending when the window ended";
|
|
36
41
|
export async function ensureSnapshotBucket(store, waitMs, logger, clock, role = "session") {
|
|
37
|
-
const
|
|
42
|
+
const roleRow = SNAPSHOT_BUCKET_ROLES[role];
|
|
43
|
+
const probe = new MinioBlobBackend({ endpoint: store.endpoint, bucket: store.bucket, accessKey: store.accessKey, secretKey: store.secretKey, ...(store.region ? { region: store.region } : {}), keyPrefix: roleRow.probePrefix(store), ops: { list: roleRow.probeOp } });
|
|
38
44
|
let verdict;
|
|
39
45
|
try {
|
|
40
46
|
verdict = await openWithinWait(async () => {
|
|
@@ -423,7 +423,8 @@ export declare function connectJudged<R>(db: SqlDriver, judge: (facts: SqlEngine
|
|
|
423
423
|
* (`getConnection` → 守卫租约上执行 → 归还,被守卫销毁的不归还)。语句契约不变:参数原样到连接,结果是 mysql2 的 `[rows, fields]` 元组,`{ sql, timeout }` 对象形
|
|
424
424
|
* 一并支持(原样交给连接);池的其余成员(`end` / `execute` / `on` …)原样转给底池,返回底池自身的方法(`on` 之类)返回本包装体 —— 链式调用不会逃出守卫。
|
|
425
425
|
* 生产池(`createTidbPool`)恒是它;mysql2 自己的 `pool.query` 对只读类错误(1290 / 1792 / 1836)的销毁收在同一张表里({@link isConnectionUnusableError}),不丢。
|
|
426
|
-
* 不覆盖 `pool.execute`(预备语句:今天只有任务附件店一处,语句是小定长行,碰不到语句墙)
|
|
426
|
+
* 不覆盖 `pool.execute`(预备语句:今天只有任务附件店一处,语句是小定长行,碰不到语句墙)—— 它与其余原样转给底池的成员一样,只给拒绝打驱动出身记号。
|
|
427
|
+
* **驱动出身记号**(`error-origin.ts` 的 `driver` 一词)是这只池座的第二件事:借连接、守卫租约上的语句与事务动词、原样转给底池的承诺,它们的拒绝都打记号(只记,不改对象、不记日志、不改控制流)。
|
|
427
428
|
*/
|
|
428
429
|
export declare function createCloseAwarePool(pool: MySqlPool): MySqlPool;
|
|
429
430
|
/** MySQL-protocol driver (TiDB / MySQL / MariaDB — `dialect` is the SQL TEXT axis, `facts.engine` the
|
|
@@ -3,6 +3,8 @@ import { recordFailOpen } from "../observability/fail-open.js";
|
|
|
3
3
|
import { errorKindOf } from "../observability/err-text.js";
|
|
4
4
|
import { writeLogText } from "../observability/logger.js";
|
|
5
5
|
import { isConnectionUnusableError } from "./sql-errors.js";
|
|
6
|
+
import { markErrorOrigin } from "./error-origin.js";
|
|
7
|
+
import { storeBoundaryFault } from "../terminal.js";
|
|
6
8
|
export class SqlStatementDeadlineExceeded extends Error {
|
|
7
9
|
deadlineMs;
|
|
8
10
|
constructor(deadlineMs) {
|
|
@@ -245,7 +247,8 @@ async function initMySqlSession(c) {
|
|
|
245
247
|
await c.query("SET SESSION tidb_txn_mode = 'pessimistic'");
|
|
246
248
|
}
|
|
247
249
|
catch (err) {
|
|
248
|
-
|
|
250
|
+
storeBoundaryFault(err, "sql-driver.initMySqlSession");
|
|
251
|
+
throw refuseSession(`this TiDB session is in "${txnMode}" transaction mode and SET SESSION tidb_txn_mode='pessimistic' was rejected`);
|
|
249
252
|
}
|
|
250
253
|
txnMode = await mysqlVar(c, "SELECT @@tidb_txn_mode AS v");
|
|
251
254
|
if (txnMode !== "pessimistic") {
|
|
@@ -342,6 +345,7 @@ function leaseOf(raw) {
|
|
|
342
345
|
return await run();
|
|
343
346
|
}
|
|
344
347
|
catch (err) {
|
|
348
|
+
markErrorOrigin(err, "driver");
|
|
345
349
|
if (isConnectionUnusableError(err)) {
|
|
346
350
|
destroy();
|
|
347
351
|
BROKEN_LEASES.set(lease, { error: err });
|
|
@@ -375,7 +379,9 @@ function leaseOf(raw) {
|
|
|
375
379
|
return lease;
|
|
376
380
|
}
|
|
377
381
|
export function createCloseAwarePool(pool) {
|
|
378
|
-
const lend = async () => leaseOf(await pool.getConnection())
|
|
382
|
+
const lend = async () => leaseOf(await pool.getConnection().catch((err) => {
|
|
383
|
+
throw markErrorOrigin(err, "driver");
|
|
384
|
+
}));
|
|
379
385
|
const query = async (...args) => {
|
|
380
386
|
const c = await lend();
|
|
381
387
|
try {
|
|
@@ -396,12 +402,21 @@ export function createCloseAwarePool(pool) {
|
|
|
396
402
|
return member;
|
|
397
403
|
return (...args) => {
|
|
398
404
|
const result = member.apply(target, args);
|
|
399
|
-
|
|
405
|
+
if (result === target)
|
|
406
|
+
return wrapper;
|
|
407
|
+
return isThenable(result)
|
|
408
|
+
? result.then(undefined, (err) => {
|
|
409
|
+
throw markErrorOrigin(err, "driver");
|
|
410
|
+
})
|
|
411
|
+
: result;
|
|
400
412
|
};
|
|
401
413
|
},
|
|
402
414
|
});
|
|
403
415
|
return wrapper;
|
|
404
416
|
}
|
|
417
|
+
function isThenable(v) {
|
|
418
|
+
return v !== null && (typeof v === "object" || typeof v === "function") && typeof v.then === "function";
|
|
419
|
+
}
|
|
405
420
|
export function mysqlDriver(pool) {
|
|
406
421
|
const session = poolSession(pool);
|
|
407
422
|
return {
|
|
@@ -109,7 +109,13 @@ export declare function isDeadlockError(dialect: SqlDialect, err: unknown): bool
|
|
|
109
109
|
/** 引擎仲裁之后整段重来的**唯一**上界(全仓每一条「撞死锁就重来」的腿共用这一个数)。8 = 锁形并发套的并发度:缺行首写的 N 路竞争每轮至多多走一轮([ref] 读数 1 成 7 死锁)。 */
|
|
110
110
|
export declare const DEADLOCK_RETRY_LIMIT = 8;
|
|
111
111
|
/**
|
|
112
|
-
*
|
|
112
|
+
* 语句源在一只**别人开的**事务里输了仲裁(例:文件历史的 scope 哨兵在锁读那一刻物理消失)—— 它不许自己回滚重开那只事务(段首的锁与判会随之丢掉),
|
|
113
|
+
* 只抛这一只;{@link retryOnDeadlock} 把它与死锁同读,从事务主人的段首整段重来(落定段、店自己的图事务同一条)。
|
|
114
|
+
*/
|
|
115
|
+
export declare class SqlArbitrationLostError extends Error {
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 「引擎判了死锁 ⇒ 整段重来」的**唯一**写法:有界({@link DEADLOCK_RETRY_LIMIT}),判据 {@link isDeadlockError} ∪ {@link SqlArbitrationLostError};用尽 / 其它错误原样抛。
|
|
113
119
|
* `attempt` 必须整段重做语义等价(读-判-写全在里面的一只事务,或一条幂等语句)。`alsoArbitrated`:店自己认的另一种仲裁产物(例:缺行首写撞主键 ——
|
|
114
120
|
* 并发的另一只首写赢了,重读即走更新腿),与死锁同族、同一个上界。锁等待超时不在任何一族里(延迟信号,见 {@link isDeadlockError} 的注):它照抛。
|
|
115
121
|
*/
|
|
@@ -241,17 +247,16 @@ export declare function isDeploymentFaultError(err: unknown): boolean;
|
|
|
241
247
|
*/
|
|
242
248
|
export declare function databaseAnswerCodesOf(dialect: SqlDialect, err: unknown): string | undefined;
|
|
243
249
|
/**
|
|
244
|
-
* 检查点店的两笔写(续跑输入 `putCtx` / 停驻行 `put`)被引擎以「一行装不下」拒 ⇒ **这一只**带码错误(码 `store.row_too_large`)
|
|
245
|
-
* (
|
|
246
|
-
*
|
|
247
|
-
* `
|
|
250
|
+
* 检查点店的两笔写(续跑输入 `putCtx` / 停驻行 `put`)被引擎以「一行装不下」拒 ⇒ **这一只**带码错误(码 `store.row_too_large`),不以驱动错上抛。
|
|
251
|
+
* `row` = 哪一张表的哪一格、为谁写(进句子);`wall` = 拒它的那堵墙({@link rowTooLargeWallOf} 的读数;提交腿按它选 413 的出路)。
|
|
252
|
+
* 句子是本仓的固定句,**不带**库的原句(店的出口只带原码 + 稳定句);库的那句(TiDB 的句子带上限与这一行的实际字节数)挂在 `cause` 上 ——
|
|
253
|
+
* 它出店时由店边界(`terminal.ts` 的 `storeBoundaryFault`:带词法内码的 typed 错原样过,`cause` 链上的驱动错就地换成边界形)记进 `at=store` 那一行、换成边界形。
|
|
248
254
|
* 提交腿把它答成 413 `request.payload_too_large`(`http/submit-ctx.ts`);停驻那一拍它经引擎的错误座落进运维日志。
|
|
249
255
|
*/
|
|
250
256
|
export declare class StoreRowTooLargeError extends Error {
|
|
251
257
|
readonly row: string;
|
|
252
258
|
readonly wall: RowTooLargeWall;
|
|
253
259
|
readonly code: "store.row_too_large";
|
|
254
|
-
readonly dbMessage: string;
|
|
255
260
|
constructor(row: string, cause: unknown, wall: RowTooLargeWall);
|
|
256
261
|
}
|
|
257
262
|
/** 店写口的翻译:{@link rowTooLargeWallOf} 认得出 ⇒ {@link StoreRowTooLargeError}(带那堵墙);其余原样交回(调用方 `throw` 它)。 */
|
|
@@ -55,13 +55,15 @@ export function isDeadlockError(dialect, err) {
|
|
|
55
55
|
return keyOf(err, "errno") === MYSQL_ER_LOCK_DEADLOCK_ERRNO || keyOf(err, "code") === MYSQL_ER_LOCK_DEADLOCK_CODE;
|
|
56
56
|
}
|
|
57
57
|
export const DEADLOCK_RETRY_LIMIT = 8;
|
|
58
|
+
export class SqlArbitrationLostError extends Error {
|
|
59
|
+
}
|
|
58
60
|
export async function retryOnDeadlock(dialect, attempt, alsoArbitrated) {
|
|
59
61
|
for (let tries = 0;; tries++) {
|
|
60
62
|
try {
|
|
61
63
|
return await attempt();
|
|
62
64
|
}
|
|
63
65
|
catch (err) {
|
|
64
|
-
if (tries < DEADLOCK_RETRY_LIMIT && (isDeadlockError(dialect, err) || alsoArbitrated?.(err) === true))
|
|
66
|
+
if (tries < DEADLOCK_RETRY_LIMIT && (isDeadlockError(dialect, err) || err instanceof SqlArbitrationLostError || alsoArbitrated?.(err) === true))
|
|
65
67
|
continue;
|
|
66
68
|
throw err;
|
|
67
69
|
}
|
|
@@ -214,16 +216,13 @@ export class StoreRowTooLargeError extends Error {
|
|
|
214
216
|
row;
|
|
215
217
|
wall;
|
|
216
218
|
code = "store.row_too_large";
|
|
217
|
-
dbMessage;
|
|
218
219
|
constructor(row, cause, wall) {
|
|
219
|
-
|
|
220
|
-
super(`${row} was refused by the database: the row is larger than the database stores in one row (${dbMessage}). ` +
|
|
220
|
+
super(`${row} was refused by the database: the row is larger than the database stores in one row. ` +
|
|
221
221
|
"Shrink what the request carries inline (images / userAttachments), or raise the database's single-row limit " +
|
|
222
|
-
"(TiDB: performance.txn-entry-size-limit, or the tidb_txn_entry_size_limit variable on TiDB 7.6+; MySQL / MariaDB: max_allowed_packet)");
|
|
222
|
+
"(TiDB: performance.txn-entry-size-limit, or the tidb_txn_entry_size_limit variable on TiDB 7.6+; MySQL / MariaDB: max_allowed_packet)", { cause });
|
|
223
223
|
this.row = row;
|
|
224
224
|
this.wall = wall;
|
|
225
225
|
this.name = "StoreRowTooLargeError";
|
|
226
|
-
this.dbMessage = dbMessage;
|
|
227
226
|
}
|
|
228
227
|
}
|
|
229
228
|
export function rowTooLargeOrSelf(dialect, err, row) {
|
|
@@ -347,7 +347,7 @@ export declare const readNonNullJsonValueColumn: JsonColumnReader<unknown>;
|
|
|
347
347
|
* **一只 JSON 数组**的承载形读者(内容判据归各列自己的既有属主,这里只判承载形)。
|
|
348
348
|
*
|
|
349
349
|
* 🔴 为什么在属主里而不是各店各写一遍([ref] 车③a 把车② 的店内私有形上收):今天有三个消费方
|
|
350
|
-
* (checkpoint 的 `
|
|
350
|
+
* (checkpoint 的 `pending_steer_queue`、image-index 的 `bands`、memory-engine 的 `embedding`),判据逐字
|
|
351
351
|
* 相同,而「这一格是不是一只数组」恰好是坏体四形的落点 —— 三份拷贝迟早有一份忘了判 `null` 字面。
|
|
352
352
|
*/
|
|
353
353
|
export declare const readJsonArrayColumn: JsonColumnReader<unknown[]>;
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
* 「停-迁-起」那一段的**唯一属主**。
|
|
3
3
|
*
|
|
4
4
|
* 一次性迁移里有几条(登记表 `stopThenStart` 一格点名的)改的是更早版本的副本还会继续写的形:改完之后它再写一笔,这一笔读不出 / 丢掉。它们没有运行期开关,
|
|
5
|
-
*
|
|
5
|
+
* 起服时由守卫段判 —— 库上有「不知道这条迁移的副本还在服务」的证据 ⇒ 拒启、一字节不写。证据只有一种读法(`stop-then-start.ts` 的 `readOlderReplicaEvidence`):
|
|
6
6
|
* 判活窗内(`REAP_RUN_STALE_SEC`,收割器判 run 持有者还活着的同一个窗)心跳过的 `running` run,持有者没有登记为知道这条迁移(`replica-registration.ts`)。
|
|
7
7
|
* 四只守卫(M40 · M41 · M42 · M51)的拒句和起服列册对账的升级清单**说同一件事**:先停光更早版本的副本、等满判活窗、再起本版。
|
|
8
8
|
* 这件事的句子只在这里写一遍:证据一段({@link olderReplicaEvidenceSentence})与动作一段({@link stopThenStartAction});各守卫只讲「为什么这一条要停」。
|
|
9
|
-
* 起服准入(`serving-requirement.ts`:库上记着本构建没有的能力 ⇒ 拒启)的拒句同属这一族,也在这里({@link servingRequirementUnmetSentence})
|
|
9
|
+
* 起服准入(`serving-requirement.ts`:库上记着本构建没有的能力 ⇒ 拒启)的拒句同属这一族,也在这里({@link servingRequirementUnmetSentence});
|
|
10
|
+
* 起服拒句升级清单里「这只库要求本构建没有的能力」一步的句子同在这里({@link unmetRequirementChecklistStep})。
|
|
10
11
|
*
|
|
11
|
-
* 叶子模块:零 import(
|
|
12
|
+
* 叶子模块:零 import(守卫段、各条的拒句、M42 的拒句文件、起服准入与列册对账都静态 import 它,不成环)。
|
|
12
13
|
*/
|
|
13
14
|
/** 证据里一只登记过、却没有这条迁移能力的持有者(归因用:点名它是谁)。 */
|
|
14
15
|
export interface OlderReplicaHolder {
|
|
@@ -47,9 +48,14 @@ export declare function stopThenStartAction(after?: string): string;
|
|
|
47
48
|
/** 起服准入里一行本构建没有的要求(`state` = 判读的态,词表外的词读作 `in_force`;`word` = 库里存的原词)。 */
|
|
48
49
|
export interface UnmetServingRequirement {
|
|
49
50
|
readonly migration: string;
|
|
50
|
-
readonly state: "
|
|
51
|
+
readonly state: "in_force";
|
|
51
52
|
readonly word: string;
|
|
52
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* 起服拒句**升级清单**里的那一步(排在 `ALTER` 一步之前;多行,第一行是步骤首句):这只库要求本构建没有的能力 —— 照清单补完语句也不会让本构建能在这里服务。
|
|
56
|
+
* `unmet` 空 ⇒ 调用方不出这一步。`unreadable` 在 ⇒ 读要求表抛了:照出这一步并如实说没读到(多停一次,不漏停)。
|
|
57
|
+
*/
|
|
58
|
+
export declare function unmetRequirementChecklistStep(unmet: readonly UnmetServingRequirement[], unreadable?: string): string[];
|
|
53
59
|
/** 起服准入的拒句(`reason` 闭集两词;码由调用方交,本模块零 import)。 */
|
|
54
60
|
export declare function servingRequirementUnmetSentence(code: string, reason: "capability_missing" | "table_absent", unmet: readonly UnmetServingRequirement[], absentTables: readonly string[], releaseLine: string): string;
|
|
55
61
|
//# sourceMappingURL=stop-then-start-sentence.d.ts.map
|
|
@@ -15,11 +15,9 @@ export function stopThenStartAction(after) {
|
|
|
15
15
|
}
|
|
16
16
|
function requirementClause(r) {
|
|
17
17
|
switch (r.state) {
|
|
18
|
-
case "pending":
|
|
19
|
-
return `${r.migration} (pending: a newer build recorded it and has not changed any data for it yet)`;
|
|
20
18
|
case "in_force":
|
|
21
19
|
return r.word === "in_force"
|
|
22
|
-
? `${r.migration} (in force:
|
|
20
|
+
? `${r.migration} (in force: a build that has it was admitted on this database and may have changed data for it)`
|
|
23
21
|
: `${r.migration} (state "${r.word}", which this build does not know — read as in force)`;
|
|
24
22
|
default: {
|
|
25
23
|
const unhandled = r.state;
|
|
@@ -27,17 +25,23 @@ function requirementClause(r) {
|
|
|
27
25
|
}
|
|
28
26
|
}
|
|
29
27
|
}
|
|
28
|
+
const rollbackDelete = (migration) => `DELETE FROM serving_requirement WHERE migration_id = '${migration}';`;
|
|
29
|
+
export function unmetRequirementChecklistStep(unmet, unreadable) {
|
|
30
|
+
if (unreadable !== undefined) {
|
|
31
|
+
return [`Whether this database requires a capability this build lacks could not be read (${unreadable}); read serving_requirement before going on — a row this build does not have means it must not serve here.`];
|
|
32
|
+
}
|
|
33
|
+
return [
|
|
34
|
+
`This database requires every serving replica to have ${unmet.map(requirementClause).join(", ")}; this build does not, and must not serve on it — the statements below do not make it safe.`,
|
|
35
|
+
`Start a build that has ${unmet.map((r) => r.migration).join(", ")} instead. Only to roll back on purpose, after handling the data of that migration: ${unmet.map((r) => rollbackDelete(r.migration)).join(" ")}`,
|
|
36
|
+
];
|
|
37
|
+
}
|
|
30
38
|
export function servingRequirementUnmetSentence(code, reason, unmet, absentTables, releaseLine) {
|
|
31
39
|
switch (reason) {
|
|
32
|
-
case "capability_missing":
|
|
33
|
-
const inForce = unmet.filter((r) => r.state === "in_force").map((r) => r.migration);
|
|
40
|
+
case "capability_missing":
|
|
34
41
|
return (`${code} (reason: capability_missing): this database requires every serving replica to have ${unmet.map(requirementClause).join(", ")}; this build (release ${releaseLine}) does not. ` +
|
|
35
42
|
"No one-time migration ran and no stored data was changed (the section head only registered this replica and removed registrations of other replicas older than 90 days). " +
|
|
36
|
-
`Start a build that has ${unmet.map((r) => r.migration).join(", ")}
|
|
37
|
-
(
|
|
38
|
-
? ""
|
|
39
|
-
: ` Only to roll back on purpose, after handling the data of that migration: ${inForce.map((m) => `DELETE FROM serving_requirement WHERE migration_id = '${m}';`).join(" ")}`));
|
|
40
|
-
}
|
|
43
|
+
`Start a build that has ${unmet.map((r) => r.migration).join(", ")}. ` +
|
|
44
|
+
`Only to roll back on purpose, after handling the data of that migration: ${unmet.map((r) => rollbackDelete(r.migration)).join(" ")}`);
|
|
41
45
|
case "table_absent":
|
|
42
46
|
return (`${code} (reason: table_absent): this database has no ${absentTables.join(" / ")} table — the serving requirements recorded there cannot be read, ` +
|
|
43
47
|
'and an unreadable requirement is not "no requirement", so this build refuses to start. Nothing was written. ' +
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **停-迁-起**(SQL 两方言;常设,不带窗)—— 一次性迁移登记表里每一条停-迁-起行的声明型、它唯一的判官、守卫段与证据读法。
|
|
3
|
+
*
|
|
4
|
+
* ## 它回答哪一问(只这一问)
|
|
5
|
+
* 「一只**已在服务**、不认迁移 M 的副本,在 M 之后写下的那一笔不兼容写,由谁挡?」—— 答案是一格闭集 {@link StopThenStartFence}(围栏类):
|
|
6
|
+
* · `structural` —— 库挡:M 的第一笔改动是 DDL(就地改名 / 删退役列 / 按建表语句重建),更早副本点名旧对象的每一句不兼容写当场失败(先围后搬);
|
|
7
|
+
* · `per-write` —— 写句挡:从 `fencedSince` 起的构建,点名的那几句写在同一句 / 同一事务里读起服要求行;`fencedSince` 严格早于 M 的引入版
|
|
8
|
+
* (逐写围栏只对带这段代码的构建生效,所以必须早至少一版装入);
|
|
9
|
+
* · `accepted` —— 没有人挡:`residual` 一句写明残余(MIGRATION 原样引),停光旧副本是唯一的补偿。
|
|
10
|
+
* 类取「从第一笔不兼容写起就成立」的那一种:晚于任何一笔搬运的 DDL 围栏不使本条成 `structural`;`per-write` 与 `structural` 同时成立 ⇒ 取 `structural`。
|
|
11
|
+
* **围栏类没有起服期的分臂**:三类在起服时同一只序 —— 守卫段读证据(有 ⇒ 拒)、各条在自己的第一笔不兼容写之前记一行起服要求(`serving-requirement.ts`)。
|
|
12
|
+
* 类只决定放行判据({@link judgeStopThenStart})、残余的披露与作者该选哪一形。
|
|
13
|
+
*
|
|
14
|
+
* ## 一份声明、一只判官
|
|
15
|
+
* 登记表(`one-time-migrations.ts` 的 `ONE_TIME_MIGRATIONS`)每一行**显式**写 `stopThenStart: StopThenStartRow | null`(缺键 = tsc 红,形门再红一次);
|
|
16
|
+
* `null` 只说「本条不声明停-迁-起」(不拒启、不进升级清单的停-迁-起一步),**不是**混跑安全的证明。判官只答「这份声明合不合本类的放行判据」;
|
|
17
|
+
* 读者两处:形门(全表,非空 ⇒ 红)与起服({@link assertStopThenStartDeclarations}:SQL 一次性迁移段**取连接之前**判本构建的每一条停-迁-起行,非空 ⇒ 抛构建缺陷,一句库语句都没发)。
|
|
18
|
+
*
|
|
19
|
+
* ## 守卫段在一切写之前
|
|
20
|
+
* {@link guardOwedStopThenStart} 在 SQL 一次性迁移段的锁内、准入复核之后、第一步迁移之前跑(`runSqlOneTimeMigrations`):按登记序逐条问「这只库还欠不欠」,
|
|
21
|
+
* 欠的读证据,任一有证据 ⇒ 抛那一条自己的拒(码与句是那一条的)—— 迁移段一字节没写,各拒句里的「Nothing was changed」由构造成立。迁移步里不再读证据。
|
|
22
|
+
*
|
|
23
|
+
* ## 证据读法(常设)
|
|
24
|
+
* {@link readOlderReplicaEvidence}:判活窗内心跳过的 `running` run(谓词 = run 店的 `runningHeartbeatPredicate` 的 `live` 一侧,与死亡判决同一只构造、同一个窗),
|
|
25
|
+
* 按持有者分组,减去登记为知道 M 的持有者(`replica-registration.ts`)。早于副本登记的副本不登记,只经它们持有的 run 心跳可见;没登记的持有者照算(保守)——
|
|
26
|
+
* 回滚到早于副本登记的构建、跳过公开序列的嵌入方、登记行过了留存视界的长寿进程会一直可能存在,所以这一读法不是过渡、没有删除日期。
|
|
27
|
+
* 它是观察谓词,不是存活证明:空闲的(零 `running` run)副本看不见;刚停的副本留下的 run 在窗内仍算(拒句给「全停之后何时再起」)。
|
|
28
|
+
* 「库上的副本够不够新」(服务下限)就是这一读法读空,不另立读口、不加版本常量。
|
|
29
|
+
*
|
|
30
|
+
* local 车道:数据根独占(起服锁只许一个进程)⇒ 没有混跑窗,守卫段与证据读法只在 SQL 腿。
|
|
31
|
+
*/
|
|
32
|
+
import type { StoreBootRefusalError } from "./store-contracts.js";
|
|
33
|
+
import type { SchemaProbeRead } from "./schema-live-columns.js";
|
|
34
|
+
import type { SqlDialect } from "./sql-driver.js";
|
|
35
|
+
import type { PendingShapeChange } from "./schema-consistency.js";
|
|
36
|
+
import type { OlderReplicaEvidence } from "./stop-then-start-sentence.js";
|
|
37
|
+
import { type ReplicaCapability } from "./replica-registration.js";
|
|
38
|
+
/** 已在服务、不认本条的副本在本条之后那一笔不兼容写由谁挡(闭集;停-迁-起行必填)。 */
|
|
39
|
+
export type StopThenStartFence =
|
|
40
|
+
/** 库挡:`fencedBy` 是本行 `shapeChanges` 里的一项(`rename` / `drop` / `rebuild`,不许 `add`),且是本条的第一笔改动。 */
|
|
41
|
+
{
|
|
42
|
+
readonly kind: "structural";
|
|
43
|
+
readonly fencedBy: PendingShapeChange;
|
|
44
|
+
}
|
|
45
|
+
/** 写句挡:从 `fencedSince`(x.y.z,严格早于本行 `introducedIn`)起的构建,`statements` 点名的那几句写读起服要求行,`(本条, in_force)` 在 ⇒ 不写、响亮。 */
|
|
46
|
+
| {
|
|
47
|
+
readonly kind: "per-write";
|
|
48
|
+
readonly fencedSince: string;
|
|
49
|
+
readonly statements: string;
|
|
50
|
+
}
|
|
51
|
+
/** 没人挡:`residual` 一句写明残余(MIGRATION 原样引);停光旧副本是唯一的补偿。 */
|
|
52
|
+
| {
|
|
53
|
+
readonly kind: "accepted";
|
|
54
|
+
readonly residual: string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* 一条停-迁-起迁移的登记格(登记表里只写引用,判据与拒句的码在本条的迁移步旁边):
|
|
58
|
+
* · `reason` —— 一句英文:更早版本的副本在迁移之后还会写什么、写了会怎样(= 为什么不能两版滚动;升级清单原样列给运维);
|
|
59
|
+
* · `owedOn` —— **这只库还欠不欠本条**的唯一读法(只读、无参语句):守卫段先问它(不欠 ⇒ 不读证据),升级清单的停-迁-起一步只列它答「欠」的行;
|
|
60
|
+
* · `refuse` —— 有证据时本条的拒(本条自己的码与句;`read` = 锁连接上的无参读口,拒句尾的库况 / 本条的计数从它读);守卫段调它,迁移步里不再读证据;
|
|
61
|
+
* · `fence` —— 围栏类({@link StopThenStartFence})。
|
|
62
|
+
*/
|
|
63
|
+
export interface StopThenStartRow {
|
|
64
|
+
readonly reason: string;
|
|
65
|
+
readonly owedOn: (read: SchemaProbeRead, dialect: SqlDialect) => Promise<boolean>;
|
|
66
|
+
readonly refuse: (evidence: OlderReplicaEvidence, read: SchemaProbeRead, dialect: SqlDialect) => Promise<StoreBootRefusalError>;
|
|
67
|
+
readonly fence: StopThenStartFence;
|
|
68
|
+
}
|
|
69
|
+
/** 一条停-迁-起行连同判官要读的两格(登记表行的 `id` / `introducedIn` / `shapeChanges`;一次性迁移文件的 `stopThenStartMigrations()` 交出这一形)。 */
|
|
70
|
+
export interface StopThenStartEntry extends StopThenStartRow {
|
|
71
|
+
readonly id: string;
|
|
72
|
+
readonly introducedIn: string;
|
|
73
|
+
readonly shapeChanges?: readonly PendingShapeChange[];
|
|
74
|
+
}
|
|
75
|
+
/** 停-迁-起证据读法的判活窗输入:= 本部署的 `REAP_RUN_STALE_SEC`(收割器判「这条 run 的持有者还活着」用的同一个窗)。 */
|
|
76
|
+
export interface LiveRunWindowInput {
|
|
77
|
+
readonly liveRunWindowMs: number;
|
|
78
|
+
}
|
|
79
|
+
/** 证据读法要的读口(一次性迁移段的锁连接;只读)。 */
|
|
80
|
+
export interface EvidenceDb {
|
|
81
|
+
rows(sql: string, params?: readonly unknown[]): Promise<Record<string, unknown>[]>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* **唯一判官**:这份停-迁-起声明自相矛盾的清单(空 = 放行)。三类各自的放行判据(穷尽 `switch`,加第四类不处理 = tsc 红),外加三类共同的两条
|
|
85
|
+
* (名在能力名单里 —— 守卫读证据 ⇔ 名在名单里;缘由句不空)。纯函数。
|
|
86
|
+
*/
|
|
87
|
+
export declare function judgeStopThenStart(entry: StopThenStartEntry): readonly string[];
|
|
88
|
+
/**
|
|
89
|
+
* **停-迁-起证据的唯一读法**(守卫段与 M43 的启用判同读;拒句与读数的句子属主 = `stop-then-start-sentence.ts`):判活窗内心跳过的 `running` run
|
|
90
|
+
* (run 店的 {@link runningHeartbeatPredicate} `live` 一侧 —— 收割器判活的同一只构造、同一个窗),按持有者(`task_run.instance_id`,建行铸、认领接管)分组,
|
|
91
|
+
* **减去登记为知道 `migrationId` 的持有者**(`knowsCapability`,与起服准入同一只判据)—— 剩下的 run 就是证据:持有者没有登记行(早于副本登记的副本、`NULL` 身份、
|
|
92
|
+
* 自传身份的嵌入方)或登记了而能力名单里没有这条迁移,照算(保守)。登记一半只作归因(点名持有者),**不判活**。
|
|
93
|
+
* 本进程此刻还在迁移段里、一条 run 都没起过 ⇒ 证据里只有别的进程。`task_run` 不在 ⇒ `undefined`。
|
|
94
|
+
* `migrationId` 在型上就要在能力名单里(`ReplicaCapability`):一条迁移读证据 ⇔ 它的名在名单里。
|
|
95
|
+
*/
|
|
96
|
+
export declare function readOlderReplicaEvidence(db: EvidenceDb, dialect: SqlDialect, input: LiveRunWindowInput, migrationId: ReplicaCapability): Promise<OlderReplicaEvidence | undefined>;
|
|
97
|
+
/**
|
|
98
|
+
* 起服时的判官读者:本构建的每一条停-迁-起声明过 {@link judgeStopThenStart},任一条自相矛盾 ⇒ 抛(构建缺陷)。纯函数;唯一调用点 = SQL 一次性迁移段的入口
|
|
99
|
+
* (`runSqlOneTimeMigrations`),**在取连接之前** —— 抛出时这一次起服对库一句语句都没发(段头的登记、准入、取锁都还没开始)。
|
|
100
|
+
*/
|
|
101
|
+
export declare function assertStopThenStartDeclarations(entries: readonly StopThenStartEntry[]): void;
|
|
102
|
+
/**
|
|
103
|
+
* **守卫段**(一次性迁移段的锁内、准入复核之后、第一步迁移之前;锁连接上;`entries` 已由调用方在取连接之前过了 {@link assertStopThenStartDeclarations}):
|
|
104
|
+
* 按登记序逐条 —— 不欠 ⇒ 跳过(不读证据);欠 ⇒ 读证据,有 ⇒ 抛那一条自己的拒({@link StopThenStartRow.refuse})。拒 ⇒ 迁移段一字节没写。
|
|
105
|
+
* 放行之后,各条在它**自己的**第一笔不兼容写之前记一行起服要求(`serving-requirement.ts` 的 `recordServingRequirement`;三类同记)—— 不在这里记:
|
|
106
|
+
* 本条若在本次起服里不欠,就没有那一笔写,也就不记。
|
|
107
|
+
*/
|
|
108
|
+
export declare function guardOwedStopThenStart(db: EvidenceDb, dialect: SqlDialect, input: LiveRunWindowInput, entries: readonly StopThenStartEntry[]): Promise<void>;
|
|
109
|
+
//# sourceMappingURL=stop-then-start.d.ts.map
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { REPLICA_CAPABILITIES, knowsCapability, readReplicaRegistrations } from "./replica-registration.js";
|
|
2
|
+
import { compareReleaseTriples, releaseTriple } from "./release-version.js";
|
|
3
|
+
import { runningHeartbeatPredicate } from "./run-store-sql.js";
|
|
4
|
+
const isCapability = (id) => REPLICA_CAPABILITIES.includes(id);
|
|
5
|
+
const sameChange = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
6
|
+
export function judgeStopThenStart(entry) {
|
|
7
|
+
const faults = [];
|
|
8
|
+
if (!isCapability(entry.id))
|
|
9
|
+
faults.push(`${entry.id} is not in REPLICA_CAPABILITIES (a stop-then-start migration reads evidence only under a capability name)`);
|
|
10
|
+
if (entry.reason.trim() === "")
|
|
11
|
+
faults.push(`${entry.id}: reason is empty`);
|
|
12
|
+
const fence = entry.fence;
|
|
13
|
+
switch (fence.kind) {
|
|
14
|
+
case "structural":
|
|
15
|
+
if (!(entry.shapeChanges ?? []).some((c) => sameChange(c, fence.fencedBy)))
|
|
16
|
+
faults.push(`${entry.id}: structural fencedBy is not one of the row's shapeChanges`);
|
|
17
|
+
if (fence.fencedBy.kind === "add")
|
|
18
|
+
faults.push(`${entry.id}: structural fencedBy is an "add" (adding a column fences no earlier writer)`);
|
|
19
|
+
break;
|
|
20
|
+
case "per-write": {
|
|
21
|
+
const since = releaseTriple(fence.fencedSince);
|
|
22
|
+
const introduced = releaseTriple(entry.introducedIn);
|
|
23
|
+
if (since === undefined)
|
|
24
|
+
faults.push(`${entry.id}: per-write fencedSince "${fence.fencedSince}" is not x.y.z`);
|
|
25
|
+
if (introduced === undefined)
|
|
26
|
+
faults.push(`${entry.id}: introducedIn "${entry.introducedIn}" is not x.y.z`);
|
|
27
|
+
if (since !== undefined && introduced !== undefined && compareReleaseTriples(since, introduced) >= 0) {
|
|
28
|
+
faults.push(`${entry.id}: per-write fencedSince ${fence.fencedSince} is not earlier than introducedIn ${entry.introducedIn} (the fencing writes must ship at least one release before the migration)`);
|
|
29
|
+
}
|
|
30
|
+
if (fence.statements.trim() === "")
|
|
31
|
+
faults.push(`${entry.id}: per-write statements is empty`);
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
case "accepted":
|
|
35
|
+
if (fence.residual.trim() === "")
|
|
36
|
+
faults.push(`${entry.id}: accepted residual is empty`);
|
|
37
|
+
break;
|
|
38
|
+
default: {
|
|
39
|
+
const unhandled = fence;
|
|
40
|
+
faults.push(`${entry.id}: unknown fence kind ${String(unhandled.kind)}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return faults;
|
|
44
|
+
}
|
|
45
|
+
export async function readOlderReplicaEvidence(db, dialect, input, migrationId) {
|
|
46
|
+
const scope = dialect === "mysql" ? "DATABASE()" : "current_schema()";
|
|
47
|
+
if ((await db.rows(`SELECT 1 AS present FROM information_schema.tables WHERE table_schema = ${scope} AND table_name = 'task_run'`)).length === 0)
|
|
48
|
+
return undefined;
|
|
49
|
+
const live = runningHeartbeatPredicate(dialect, "live", { nowMs: Date.now(), windowMs: input.liveRunWindowMs }, 1);
|
|
50
|
+
const groups = (await db.rows(`SELECT instance_id, COUNT(*) AS n, MAX(updated_at) AS newest FROM task_run WHERE ${live.sql} GROUP BY instance_id`, [live.param]))
|
|
51
|
+
.map((r) => ({ holder: typeof r["instance_id"] === "string" ? r["instance_id"] : undefined, runs: Number(r["n"] ?? 0), newest: r["newest"] }))
|
|
52
|
+
.filter((g) => g.runs > 0);
|
|
53
|
+
if (groups.length === 0)
|
|
54
|
+
return undefined;
|
|
55
|
+
const registered = await readReplicaRegistrations({ query: async (sql, params) => ({ rows: await db.rows(sql, params), affected: 0 }) }, dialect, groups.flatMap((g) => (g.holder === undefined ? [] : [g.holder])));
|
|
56
|
+
let unregisteredRuns = 0;
|
|
57
|
+
let newestMs = Number.NaN;
|
|
58
|
+
const registeredWithout = [];
|
|
59
|
+
for (const g of groups) {
|
|
60
|
+
const r = g.holder === undefined ? undefined : registered.get(g.holder);
|
|
61
|
+
if (r !== undefined && knowsCapability(r.capabilities, migrationId))
|
|
62
|
+
continue;
|
|
63
|
+
if (r === undefined)
|
|
64
|
+
unregisteredRuns += g.runs;
|
|
65
|
+
else
|
|
66
|
+
registeredWithout.push({ instanceId: r.instanceId, releaseLine: r.releaseLine, hostName: r.hostName, pid: r.pid, runs: g.runs });
|
|
67
|
+
const cell = g.newest instanceof Date ? g.newest : new Date(String(g.newest));
|
|
68
|
+
if (!Number.isNaN(cell.getTime()) && !(cell.getTime() <= newestMs))
|
|
69
|
+
newestMs = cell.getTime();
|
|
70
|
+
}
|
|
71
|
+
const liveRuns = unregisteredRuns + registeredWithout.reduce((n, h) => n + h.runs, 0);
|
|
72
|
+
if (liveRuns === 0)
|
|
73
|
+
return undefined;
|
|
74
|
+
const now = Date.now();
|
|
75
|
+
const restartAtMs = (Number.isNaN(newestMs) ? now : newestMs) + input.liveRunWindowMs;
|
|
76
|
+
return {
|
|
77
|
+
migration: migrationId,
|
|
78
|
+
liveRuns,
|
|
79
|
+
windowSec: Math.round(input.liveRunWindowMs / 1000),
|
|
80
|
+
restartAfter: new Date(restartAtMs).toISOString(),
|
|
81
|
+
after: `${new Date(restartAtMs).toISOString()} (${Math.max(0, Math.ceil((restartAtMs - now) / 1000))}s from now)`,
|
|
82
|
+
unregisteredRuns,
|
|
83
|
+
registeredWithout: registeredWithout.sort((a, b) => a.instanceId.localeCompare(b.instanceId)),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export function assertStopThenStartDeclarations(entries) {
|
|
87
|
+
const faults = entries.flatMap((e) => judgeStopThenStart(e));
|
|
88
|
+
if (faults.length > 0) {
|
|
89
|
+
throw new Error(`stop-then-start: this build declares a stop-then-start migration that contradicts its fence class (a build defect; refused before any statement reached the database): ${faults.join("; ")}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export async function guardOwedStopThenStart(db, dialect, input, entries) {
|
|
93
|
+
const read = (sql) => db.rows(sql);
|
|
94
|
+
for (const entry of entries) {
|
|
95
|
+
if (!(await entry.owedOn(read, dialect)))
|
|
96
|
+
continue;
|
|
97
|
+
if (!isCapability(entry.id))
|
|
98
|
+
throw new Error(`stop-then-start: ${entry.id} is not in REPLICA_CAPABILITIES`);
|
|
99
|
+
const evidence = await readOlderReplicaEvidence(db, dialect, input, entry.id);
|
|
100
|
+
if (evidence !== undefined)
|
|
101
|
+
throw await entry.refuse(evidence, read, dialect);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=stop-then-start.js.map
|