@sema-agent/server 7.149.0 → 7.151.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 +307 -9
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +92 -40
- package/deploy/sema-up/README.md +7 -1
- 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 +1 -0
- package/deploy/sema-up/kube-up.sh +1 -1
- package/deploy/sema-up/lib/flagshape.sh +1 -1
- package/deploy/sema-up/lib/helm-values-cluster.py +2 -0
- package/deploy/sema-up/lib/helm-values-kube.py +2 -0
- package/dist/adoption/import.js +3 -3
- package/dist/approval-ask-machine.d.ts +1 -1
- package/dist/approval-card.d.ts +3 -3
- package/dist/approval-gate-currency.d.ts +2 -2
- package/dist/audit.d.ts +1 -1
- package/dist/audit.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 +2 -2
- package/dist/bake-runner/main.d.ts +4 -2
- package/dist/bind-host.d.ts +2 -3
- package/dist/bind-host.js +2 -4
- package/dist/boot/budget-tracing.js +1 -1
- package/dist/boot/deferred-sandbox-path-env.d.ts +5 -3
- package/dist/boot/deferred-sandbox-path-env.js +1 -2
- package/dist/boot/engine-lease.d.ts +5 -0
- package/dist/boot/engine-lease.js +1 -0
- package/dist/boot/execution-env.d.ts +8 -14
- package/dist/boot/execution-env.js +54 -17
- 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/memory-consolidation.d.ts +3 -2
- package/dist/boot/memory-consolidation.js +6 -6
- package/dist/boot/parked-revive-gate.d.ts +5 -5
- package/dist/boot/parked-revive-gate.js +2 -3
- package/dist/boot/reapers.d.ts +5 -0
- package/dist/boot/reapers.js +12 -1
- package/dist/boot/resolve-spec.d.ts +7 -8
- package/dist/boot/resolve-spec.js +80 -35
- package/dist/boot/retention-lane.d.ts +1 -1
- package/dist/boot/runner-deps.d.ts +9 -2
- package/dist/boot/runner-deps.js +3 -3
- 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 +28 -24
- package/dist/boot/stage-01-config.js +2 -0
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-05-execution-env.d.ts +5 -3
- package/dist/boot/stage-05-execution-env.js +2 -2
- package/dist/boot/stage-06-runners.d.ts +7 -4
- package/dist/boot/stage-06-runners.js +16 -8
- package/dist/boot/stage-07-capability-layer.d.ts +7 -4
- package/dist/boot/stage-07-capability-layer.js +3 -2
- package/dist/boot/stage-08-reapers.d.ts +7 -4
- package/dist/boot/stage-08-reapers.js +4 -2
- package/dist/boot/stage-09-leader.d.ts +11 -5
- package/dist/boot/stage-09-leader.js +12 -3
- package/dist/boot/stage-10-http-server.d.ts +44 -6
- package/dist/boot/stage-10-http-server.js +12 -10
- package/dist/boot/web-admin.d.ts +1 -1
- package/dist/boot/web-admin.js +3 -1
- 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/capability-facts.d.ts +84 -66
- package/dist/capability-facts.js +58 -41
- 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 +15 -12
- package/dist/config-invariants.d.ts +2 -1
- package/dist/config-invariants.js +4 -4
- package/dist/config-types.d.ts +22 -15
- package/dist/config.d.ts +51 -2
- package/dist/config.js +35 -24
- package/dist/deployment-governance.d.ts +7 -28
- package/dist/deployment-governance.js +1 -14
- 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 +1 -0
- package/dist/device-ws-hub.js +66 -29
- package/dist/device-ws-protocol.d.ts +79 -12
- package/dist/device-ws-protocol.js +64 -26
- package/dist/engine-identity.d.ts +23 -5
- package/dist/engine-identity.js +13 -0
- package/dist/entry-mode-clamp-notice.d.ts +2 -1
- package/dist/execution-env-refusal.d.ts +23 -0
- package/dist/execution-env-refusal.js +5 -0
- package/dist/execution-lane-caps.d.ts +3 -1
- package/dist/field-conflict.d.ts +3 -3
- 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 +14 -1
- package/dist/fleet/engine-signal.js +5 -1
- package/dist/fleet/fleet-reconciler.d.ts +1 -1
- package/dist/fleet/serving-lease.d.ts +18 -3
- package/dist/fleet/serving-lease.js +81 -35
- package/dist/fleet-client.d.ts +13 -11
- package/dist/fleet-client.js +53 -33
- package/dist/history-anchor.js +1 -1
- package/dist/hitl-delivery.d.ts +1 -3
- package/dist/hitl-delivery.js +1 -1
- package/dist/hooks/hook-runner.js +2 -2
- package/dist/host-lsp-manager.d.ts +2 -2
- package/dist/http/active-run-conflict.d.ts +3 -7
- package/dist/http/active-run-conflict.js +2 -2
- package/dist/http/admission.js +19 -4
- package/dist/http/approval-sweeps.js +7 -6
- package/dist/http/caller-trust.d.ts +2 -2
- package/dist/http/caller-trust.js +3 -3
- package/dist/http/checkpoint-ctx.d.ts +20 -63
- package/dist/http/checkpoint-ctx.js +2 -24
- package/dist/http/claim-heartbeat.d.ts +4 -4
- package/dist/http/claim-heartbeat.js +3 -3
- package/dist/http/dispatch.d.ts +2 -1
- package/dist/http/dispatch.js +36 -29
- package/dist/http/durable-run-leg.js +17 -17
- package/dist/http/health-self-report.d.ts +9 -1
- package/dist/http/health-self-report.js +2 -0
- package/dist/http/owner-access.d.ts +264 -20
- package/dist/http/owner-access.js +215 -5
- package/dist/http/readiness.d.ts +4 -2
- package/dist/http/resume-ctx-read.js +38 -1
- package/dist/http/resume-legs.d.ts +2 -1
- package/dist/http/resume-legs.js +273 -89
- package/dist/http/route-ctx.d.ts +41 -19
- package/dist/http/route-table.d.ts +1 -1
- package/dist/http/routes/a2a-serve.js +15 -14
- package/dist/http/routes/admin-memory-optout.d.ts +1 -1
- package/dist/http/routes/agents-roster.js +2 -3
- package/dist/http/routes/approvals-assistant.d.ts +3 -2
- package/dist/http/routes/approvals-assistant.js +12 -12
- package/dist/http/routes/background.d.ts +3 -3
- package/dist/http/routes/capabilities.js +10 -6
- package/dist/http/routes/config-catalog.d.ts +1 -1
- package/dist/http/routes/fleet.js +10 -8
- package/dist/http/routes/mcp-reconnect.js +2 -2
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/notify-wake.js +2 -3
- package/dist/http/routes/projects.d.ts +4 -2
- package/dist/http/routes/projects.js +7 -6
- package/dist/http/routes/retention-ops.d.ts +1 -1
- package/dist/http/routes/run-permission-mode.d.ts +1 -1
- package/dist/http/routes/run-permission-mode.js +2 -2
- package/dist/http/routes/runs.d.ts +1 -1
- package/dist/http/routes/runs.js +125 -66
- package/dist/http/routes/session-memory-sync.js +4 -5
- package/dist/http/routes/session-sync.d.ts +4 -3
- package/dist/http/routes/session-sync.js +174 -83
- package/dist/http/routes/sessions-list.js +13 -7
- package/dist/http/routes/sessions.d.ts +1 -1
- package/dist/http/routes/sessions.js +26 -48
- package/dist/http/routes/tasks.js +38 -23
- package/dist/http/routes/trace-usage.js +14 -14
- package/dist/http/routes/workflows.d.ts +1 -0
- package/dist/http/routes/workflows.js +20 -38
- package/dist/http/server.d.ts +28 -30
- package/dist/http/server.js +7 -3
- package/dist/http/stored-body-replay.d.ts +3 -24
- package/dist/http/stored-body-replay.js +2 -12
- package/dist/http/submit-ctx.d.ts +1 -2
- package/dist/http/submit-ctx.js +8 -6
- package/dist/http/submit-replay.d.ts +15 -2
- package/dist/http/submit-replay.js +10 -4
- package/dist/http/wire-types.d.ts +19 -6
- package/dist/identity-source.d.ts +20 -3
- package/dist/identity-source.js +14 -0
- package/dist/index.d.ts +4 -0
- package/dist/lane-home-probe.d.ts +3 -7
- package/dist/lane-home-probe.js +0 -1
- package/dist/leader/endpoint.js +9 -8
- package/dist/leader/leader.d.ts +2 -1
- package/dist/leg-facts.d.ts +19 -5
- package/dist/leg-facts.js +3 -1
- package/dist/mcp-authorization-face.d.ts +18 -14
- package/dist/mcp-authorization-face.js +3 -2
- package/dist/memory-scope.d.ts +5 -4
- package/dist/memory-scope.js +4 -4
- package/dist/memory-store-refusal.d.ts +1 -1
- package/dist/memory-sync-client.d.ts +30 -2
- package/dist/memory-sync-client.js +16 -9
- package/dist/observability/corrupt-read-seat.d.ts +1 -1
- package/dist/observability/err-text.d.ts +7 -0
- package/dist/observability/err-text.js +5 -0
- package/dist/observability/fail-open.d.ts +12 -8
- package/dist/observability/fail-open.js +12 -8
- package/dist/observability/logger.d.ts +7 -0
- package/dist/observability/logger.js +3 -1
- package/dist/observability/metrics.js +1 -0
- package/dist/observability/run-terminal.d.ts +1 -1
- 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/owner-faces.d.ts +28 -4
- package/dist/owner-faces.js +2 -0
- package/dist/parked-decide.d.ts +104 -53
- 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/peer-seat.d.ts +1 -1
- package/dist/peer-seat.js +52 -59
- package/dist/permission-mode-admission.d.ts +41 -5
- package/dist/permission-mode-admission.js +29 -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 +10 -2
- package/dist/plugins/approval-ask-store-file.js +8 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +6 -1
- package/dist/plugins/approval-ask-store-memory.js +28 -9
- package/dist/plugins/approval-ask-store-sql.d.ts +43 -2
- package/dist/plugins/approval-ask-store-sql.js +34 -5
- package/dist/plugins/approval-exemption-store.js +3 -0
- package/dist/plugins/approval-nonce-store.js +2 -0
- 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/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/exec-path-law.d.ts +34 -0
- package/dist/plugins/exec-path-law.js +13 -0
- package/dist/plugins/execution-placement-sql.js +6 -6
- package/dist/plugins/file-run-store.js +1 -1
- 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 +4 -1
- package/dist/plugins/local-checkpoint-store.js +3 -0
- 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-run-store.js +1 -1
- 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 +80 -61
- package/dist/plugins/one-time-migrations.js +241 -104
- 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 +28 -1
- 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 +8 -3
- package/dist/plugins/remote-env-adb.d.ts +19 -15
- package/dist/plugins/remote-env-adb.js +44 -17
- 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 +114 -14
- package/dist/plugins/remote-env-e2b.d.ts +18 -7
- package/dist/plugins/remote-env-e2b.js +53 -40
- package/dist/plugins/remote-env-file-error.js +6 -2
- package/dist/plugins/remote-env-host.d.ts +18 -1
- package/dist/plugins/remote-env-host.js +48 -47
- package/dist/plugins/remote-env-k8s.d.ts +41 -39
- package/dist/plugins/remote-env-k8s.js +56 -32
- package/dist/plugins/remote-env-local-docker.d.ts +13 -8
- package/dist/plugins/remote-env-local-docker.js +37 -43
- package/dist/plugins/remote-env-ssh.d.ts +18 -12
- package/dist/plugins/remote-env-ssh.js +64 -62
- package/dist/plugins/remote-shell.d.ts +101 -2
- package/dist/plugins/remote-shell.js +221 -3
- package/dist/plugins/replica-registration.d.ts +35 -0
- package/dist/plugins/replica-registration.js +48 -0
- 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.d.ts +1 -1
- 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 +22 -3
- package/dist/plugins/run-store-sql.js +33 -9
- package/dist/plugins/scenario-prefix-switch-m42.d.ts +6 -12
- package/dist/plugins/scenario-prefix-switch-m42.js +7 -5
- package/dist/plugins/schema-consistency.d.ts +9 -5
- package/dist/plugins/schema-consistency.js +48 -18
- package/dist/plugins/schema-drift-sentence.js +1 -1
- package/dist/plugins/send-file-ledger.js +3 -0
- package/dist/plugins/serving-requirement.d.ts +68 -0
- package/dist/plugins/serving-requirement.js +60 -0
- package/dist/plugins/session-birth.d.ts +6 -2
- 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/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/stop-then-start-sentence.d.ts +48 -3
- package/dist/plugins/stop-then-start-sentence.js +48 -0
- 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 +40 -13
- package/dist/plugins/store-backend.js +169 -27
- package/dist/plugins/store-boundary.d.ts +57 -0
- package/dist/plugins/store-boundary.js +139 -0
- package/dist/plugins/store-contracts.d.ts +29 -2
- package/dist/plugins/store-contracts.js +3 -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.js +9 -0
- 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 +6 -1
- 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-fill.d.ts +4 -7
- package/dist/plugins/workspace-fill.js +2 -1
- package/dist/plugins/write-behind-counter.js +5 -0
- package/dist/process-instance.d.ts +3 -0
- package/dist/process-instance.js +7 -0
- package/dist/project-context.d.ts +64 -0
- package/dist/project-context.js +66 -0
- package/dist/project-registry.d.ts +46 -0
- package/dist/project-registry.js +44 -0
- package/dist/question.d.ts +9 -21
- package/dist/question.js +28 -19
- 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/run-acceptance.d.ts +3 -2
- package/dist/run-acceptance.js +4 -6
- package/dist/run-cancel-card.d.ts +1 -1
- package/dist/run-cancel-card.js +2 -1
- package/dist/run-local.js +1 -0
- package/dist/runs.d.ts +37 -8
- package/dist/runs.js +53 -12
- package/dist/runtime-governance.d.ts +5 -4
- package/dist/security.d.ts +31 -33
- package/dist/security.js +41 -7
- package/dist/server-secret-env.d.ts +12 -10
- package/dist/server-secret-env.js +24 -15
- package/dist/session-agent.d.ts +1 -10
- package/dist/session-agent.js +0 -6
- 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 +28 -4
- package/dist/session-incarnation.js +14 -2
- package/dist/session-kind.d.ts +57 -0
- package/dist/session-kind.js +22 -0
- package/dist/session-notify-door.d.ts +4 -4
- package/dist/session-notify-door.js +5 -6
- package/dist/session-row.d.ts +21 -1
- package/dist/session-row.js +7 -1
- package/dist/session-rules-seat.d.ts +4 -3
- package/dist/session-rules-seat.js +3 -11
- package/dist/session-sync-kernel.d.ts +24 -14
- package/dist/session-sync-kernel.js +3 -6
- package/dist/session-sync.d.ts +4 -98
- package/dist/session-sync.js +4 -74
- 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/checkpoint-store-sql.d.ts +21 -2
- package/dist/stores-sql/checkpoint-store-sql.js +106 -18
- package/dist/stores-sql/file-history-store-sql.d.ts +52 -2
- package/dist/stores-sql/file-history-store-sql.js +108 -70
- 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 +2 -10
- package/dist/stores-sql/retention-store-sql.js +2 -10
- 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 +6 -5
- package/dist/task-settings.d.ts +19 -5
- package/dist/task-settings.js +13 -7
- package/dist/terminal.d.ts +33 -2
- package/dist/terminal.js +139 -9
- package/dist/tool-approval.d.ts +147 -12
- package/dist/tool-approval.js +206 -109
- package/dist/trace/engine-notice-wire.d.ts +14 -0
- package/dist/trace/engine-notice-wire.js +18 -1
- package/dist/trace/project.d.ts +4 -3
- package/dist/trace/project.js +3 -2
- package/dist/trace/projection-table.d.ts +33 -2
- package/dist/trace/self-minted-wire.d.ts +422 -26
- package/dist/trace/self-minted-wire.js +149 -23
- package/dist/trace/tool-card.d.ts +3 -0
- package/dist/trace/tool-card.js +24 -0
- package/dist/trace/tool-output-media.d.ts +2 -1
- package/dist/unattended-permission-mode.d.ts +1 -1
- package/dist/web-admin-client/apply-effective.d.ts +1 -1
- package/dist/web-admin-client/effective-keys.d.ts +1 -1
- package/dist/web-admin-client/skills-mcp.d.ts +1 -1
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +120 -41
- package/package.json +3 -3
- package/wire-changes/server@7.150.0.json +335 -0
- package/wire-changes/server@7.151.0.json +762 -0
- package/dist/http/session-inherit-env.d.ts +0 -36
- package/dist/http/session-inherit-env.js +0 -6
|
@@ -5,6 +5,8 @@ import { dialectProtocolJsonEncoder } from "./sql-driver.js";
|
|
|
5
5
|
import { SCHEMA_STATEMENTS, acquireEnsureSchemaLock, releaseEnsureSchemaLock } from "./tidb-pool.js";
|
|
6
6
|
import { PG_SCHEMA_STATEMENTS, acquirePgEnsureSchemaLock, releasePgEnsureSchemaLock } from "./pg-pool.js";
|
|
7
7
|
import { createObjectColumnReader, decodeJsonColumn, decodeNullableJsonColumn, isJsonColumnBodyProblem, jsonColumnText, jsonColumnTextExpr, readOpaqueJsonValueColumn, } from "./sql-json-column.js";
|
|
8
|
+
import { rewrittenBackgroundRecordM53, rewrittenToolEndDataM53 } from "./store-fault-sentence-m53.js";
|
|
9
|
+
import { pgSafeJsonStringify } from "./pg-safe-json.js";
|
|
8
10
|
import { incarnationFromCell, sessionFaceFromRow } from "../session-incarnation.js";
|
|
9
11
|
import { StoreBootRefusalError } from "./store-contracts.js";
|
|
10
12
|
import { decodeRunResultCellM44 } from "./run-store-sql.js";
|
|
@@ -30,7 +32,10 @@ import { isUnusableArchive } from "../execution-placement.js";
|
|
|
30
32
|
import { IDENTITY_COLUMN_NAME, SCENARIO_PREFIX_LIKE, SCENARIO_PREFIX_MARKER_ID, ScenarioPrefixSwitchRefusedError } from "./scenario-prefix-switch-m42.js";
|
|
31
33
|
import { MIGRATION_MARKER_TABLE, SKILL_EXEMPTION_CUTOFF_ID, markIfAbsentSql, migrationMarkerDdl } from "./one-time-migration-marker.js";
|
|
32
34
|
import { describeUpgradeDriftTail, expectedTableShapes } from "./schema-consistency.js";
|
|
33
|
-
import { stopThenStartAction } from "./stop-then-start-sentence.js";
|
|
35
|
+
import { olderReplicaEvidenceSentence, stopThenStartAction } from "./stop-then-start-sentence.js";
|
|
36
|
+
import { buildThisReplicaRegistration, registerReplica } from "./replica-registration.js";
|
|
37
|
+
import { assertReplicaTablesPresent, assertServingRequirementsMet, recordServingRequirement } from "./serving-requirement.js";
|
|
38
|
+
import { assertStopThenStartDeclarations, guardOwedStopThenStart, readOlderReplicaEvidence } from "./stop-then-start.js";
|
|
34
39
|
const RETIRED_SESSION_RULE_BUCKETS = ["commandAllow", "commandDeny"];
|
|
35
40
|
export function buildMigrationReceipts() {
|
|
36
41
|
return {
|
|
@@ -65,6 +70,7 @@ export function buildMigrationReceipts() {
|
|
|
65
70
|
scenarioPrefixSourcesScanned: 0,
|
|
66
71
|
withdrawMarkWritten: 0,
|
|
67
72
|
sessionDeletingSwitchMarked: 0,
|
|
73
|
+
storeFaultSentencesRewritten: 0,
|
|
68
74
|
runErrorCodeColumnRewritten: 0,
|
|
69
75
|
runObjectivePreviewRewritten: 0,
|
|
70
76
|
shellSentinelOwnersCleared: 0,
|
|
@@ -127,6 +133,7 @@ function changedAnything(r) {
|
|
|
127
133
|
r.sessionMetaColumnsDropped > 0 ||
|
|
128
134
|
r.withdrawMarkWritten > 0 ||
|
|
129
135
|
r.sessionDeletingSwitchMarked > 0 ||
|
|
136
|
+
r.storeFaultSentencesRewritten > 0 ||
|
|
130
137
|
r.runErrorCodeColumnRewritten > 0 ||
|
|
131
138
|
r.runObjectivePreviewRewritten > 0 ||
|
|
132
139
|
r.shellSentinelOwnersCleared > 0 ||
|
|
@@ -197,20 +204,6 @@ const OLD_GRAMMAR_SESSION_RULES_COLUMN = "rule_entries_old_grammar";
|
|
|
197
204
|
const RETIRED_ASK_CAUSE_COLUMN = "denied_reason";
|
|
198
205
|
const ASK_EXECUTION_LANE_COLUMN = "execution_lane";
|
|
199
206
|
export const ONE_TIME_MIGRATIONS = [
|
|
200
|
-
{
|
|
201
|
-
id: "M12",
|
|
202
|
-
introducedIn: "7.122.0",
|
|
203
|
-
releasedOn: "2026-10-09",
|
|
204
|
-
removableAfter: "2026-11-08",
|
|
205
|
-
removal: "删模式词读法记号的判据与拒臂:`http/stored-body-replay.ts` 的 `permissionModeReadingUnstated`;`http/checkpoint-ctx.ts` 的 `permissionModeReadingStated` / `permissionModeReadingRefusal` / `PERMISSION_MODE_READINGS`、" +
|
|
206
|
-
"`StoredBodyReplayRefusal` 的 `permission_mode_reading` 臂及其日志字段与答复臂、`buildCheckpointCtx` 与 `withPermissionModeRewritten` 两处记号写点" +
|
|
207
|
-
"(后者删后 `resume-legs.ts` `drivePlanReview` 里对它的那一处调用回到只换体的 `{ ...ctx, body }`)、`CheckpointCtx.permissionModeReading`、" +
|
|
208
|
-
"`http/stored-body-replay.ts` 里 `StoredReplayDeployment` 的 `autonomy` 位与 `storedBodyReplayRefusal` 读 `deployment.autonomy` 的那一句(这一位只服务这一问;四个问点传 `deps.config` 整份,home 位还服务 `permissions` 一问,不动);" +
|
|
209
|
-
"`test/stored-request-prompt-profile-m30.test.ts` 的 SHARED 表里 `StoredBodyReplayRefusal` 那一行(rows 含 M12;M30 的登记行组已先删时该表已不在,这一句无事可做):rows 去掉 M12、整行并入同文件的 SITES(值 = 该行的 files 数组)",
|
|
210
|
-
afterRemoval: "没有响亮臂:删码之后仍停驻、在 7.121.x 及以前写下的行(把 `APPROVAL_TERMINAL_BACKSTOP_MS` 调长的部署,或跳过了带本条的版本直接升的库)在设了 " +
|
|
211
|
-
"`AUTONOMY=plan` 的部署上按体里的原词重放(运维的 plan 不再被按段重钳)—— 升级前把这些停驻的 run 决掉 / 取消,或升级窗内设 `AUTONOMY=read-only`",
|
|
212
|
-
reportKeys: [],
|
|
213
|
-
},
|
|
214
207
|
{
|
|
215
208
|
id: "M13",
|
|
216
209
|
introducedIn: "7.123.0",
|
|
@@ -223,6 +216,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
223
216
|
"(`test/config-lkg.test.ts`、`test/config-hot/batch1-version-ordinal.test.ts` 改写成 3;`test/models-dropped-entries-s1295.test.ts` 的旧 LKG 迁移格改钉 2 读回不可用)",
|
|
224
217
|
afterRemoval: "既有响亮臂 `config_lkg_unusable`(`loadLkg` 对 2 答「unknown formatVersion 2」):2 读回 ⇒ 不可用,中心可达照拉(整拉,读腿铸出完整载体,新 LKG 按 3 覆盖)、" +
|
|
225
218
|
"断着则 env 兜底,下一份干净候选重写 —— 与回滚到 7.122.0 读 3 同一种处置",
|
|
219
|
+
stopThenStart: null,
|
|
226
220
|
reportKeys: [],
|
|
227
221
|
},
|
|
228
222
|
{
|
|
@@ -236,6 +230,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
236
230
|
"`test/ss11-stored-migrations.test.ts` 的 M15 组(4 原样读回那一格留)",
|
|
237
231
|
afterRemoval: "既有响亮臂 `config_lkg_unusable`(`loadLkg` 对 3 答「unknown formatVersion 3」):旧载荷的 LKG 读回 ⇒ 不可用,中心可达照拉(整拉,新 LKG 按 4 覆盖)、" +
|
|
238
232
|
"断着则 env 兜底 —— 与回滚到 7.123.0 读 4 同一种处置",
|
|
233
|
+
stopThenStart: null,
|
|
239
234
|
reportKeys: [],
|
|
240
235
|
},
|
|
241
236
|
{
|
|
@@ -247,6 +242,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
247
242
|
"`test/ss11-stored-migrations.test.ts` 的 M16 组;部署文档里「起服自动迁 config.d」那一句(运维仍可手跑契约命令行,直到契约删族)",
|
|
248
243
|
afterRemoval: "契约读腿的墓碑(永久):config.d 里还带旧形的域文档 —— `runtime.json` 带事实 ⇒ `RetiredDomainError` 整份读不出;`atModelAllowlist` / `models.default` ⇒ " +
|
|
249
244
|
"models 域降级、rosters 整份读不出 —— 拒句点名迁移 id;出路是运维手跑契约命令行(契约删族之后只剩手改)",
|
|
245
|
+
stopThenStart: null,
|
|
250
246
|
reportKeys: [],
|
|
251
247
|
},
|
|
252
248
|
{
|
|
@@ -265,6 +261,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
265
261
|
"`config.schema_mismatch`(缺 `rule_entries`、多那一列)—— " +
|
|
266
262
|
"出路是先在一只带本条的版本上起服一次;② 行里仍带退役命令桶:SQL 店读回照旧答 `corrupt`(引擎的形读法点名那只桶,与本条在场时同一个结局),只是起服日志不再逐行点名 —— " +
|
|
267
263
|
"运维在库里把那一行改写成引擎文法或删掉它(删会话即删规则);③ 跳过本条直接升的库同样没有改名那一拍的条目判读 —— 由 ① 的拒启接住(出路同 ①)",
|
|
264
|
+
stopThenStart: null,
|
|
268
265
|
reportKeys: ["sessionRuleColumn", "sessionRuleRowsWithRetiredBuckets", "sessionRuleRowsWithOldGrammarEntries", "sessionRuleRowsWithUnreadableDeny"],
|
|
269
266
|
shapeChanges: [{ kind: "rename", table: SESSION_POLICY_TABLE, from: [RETIRED_SESSION_RULES_COLUMN, OLD_GRAMMAR_SESSION_RULES_COLUMN], to: SESSION_RULES_COLUMN.name }],
|
|
270
267
|
},
|
|
@@ -283,6 +280,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
283
280
|
"幂等重入走 park、回决口按要人;仍带它们的待决停驻行(把 `APPROVAL_TERMINAL_BACKSTOP_MS` 调长的部署、local 车道引擎 File 店里窗关仍未决的 —— 停驻行从来不由本服务改写," +
|
|
284
281
|
"窗内靠读侧改写读,窗关后读侧改写删)由本服务的读面按坏行处置:运维队列行缺那一位 + `server.approval-card.closed-word-out-of-set` 计数、耐久 `/decide` 的 remember 按强制(只放行这一次)。" +
|
|
285
282
|
"引擎续跑不受影响:续跑入口读行摘要、不按今日闭集重判停驻行上的这两座,行字节引擎怎么写的还是怎么在",
|
|
283
|
+
stopThenStart: null,
|
|
286
284
|
reportKeys: ["retiredCardWordAskRowsRewritten", "retiredCardWordRowsUnreadable"],
|
|
287
285
|
},
|
|
288
286
|
{
|
|
@@ -310,6 +308,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
310
308
|
"批准后撞 `resume.tool_unavailable`(拒绝照常可出)—— 出路是拒绝那张卡,用改好的 `toolAxes` 重新提交。会撞上它的是活过窗的升级前停驻行:发布后才升级的部署、" +
|
|
311
309
|
"调长了 `APPROVAL_TERMINAL_BACKSTOP_MS` 的部署、滚动升级里旧副本在窗内新写的行(头注 M19 段)。A2A 一面同:存量体里 `a2aPeers[].toolAxes` 判不过的对端续跑整条不挂," +
|
|
312
310
|
"运维 warn `a2a_injection_dropped` 点名,停驻在它 skill 上的审批批准后撞 `resume.tool_unavailable` —— 出路同上:拒绝那张卡,改好声明重新提交",
|
|
311
|
+
stopThenStart: null,
|
|
313
312
|
reportKeys: [],
|
|
314
313
|
},
|
|
315
314
|
{
|
|
@@ -327,6 +326,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
327
326
|
afterRemoval: "没有新的臂,接住它的是今天的读法(删码零行为变化:窗关那一刻起重读臂已经不生效):升级前存下的请求体里带这两形的 `settings.hooks`,在会采纳 hooks 的车道上续跑被拒 —— " +
|
|
328
327
|
"「请求成员读不出」判据(`src/unread-request-members.ts`)答 409 `resume_blocked_by_policy`(`blockedBy: request.field_invalid`,`field: settings.hooks`),卡仍待决、行不动(7.147.0 起;此前是整份不采纳照跑)—— " +
|
|
329
328
|
"出路是取消这类停驻任务、删掉那个未知字段 / `__proto__` 键后重新提交。会撞上它的是活过窗的升级前停驻行:发布后才升级的部署、调长了 `APPROVAL_TERMINAL_BACKSTOP_MS` 的部署、滚动升级里旧副本在窗内新写的行(头注 M20 段)",
|
|
329
|
+
stopThenStart: null,
|
|
330
330
|
reportKeys: [],
|
|
331
331
|
},
|
|
332
332
|
{
|
|
@@ -342,6 +342,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
342
342
|
"队列行不带卡词(壳显示通用审批卡),到期走 SLA 拒扫腿(模型读到「拒」),决断口仍按工具名认问答(`approve` 必须带 `answer`,否则 400);出路 = 升级前答完或拒掉;" +
|
|
343
343
|
"② `gate_kind` 为 NULL 的停驻行:既有响亮臂 —— 运维待批队列(`listPending`)不列它、计 `server.approvals.queue-row-gate-kind-missing`(决断口按门型绑定取行,本来就不认它);" +
|
|
344
344
|
"出路是运维把那一行置 expired 或删掉会话(终局收割照旧在 `terminal_at_ms` 收它)",
|
|
345
|
+
stopThenStart: null,
|
|
345
346
|
reportKeys: ["parkedQuestionCardsWritten", "parkedQuestionRowsLeftAsWritten", "parkedRowGateKindsBackfilled", "parkedRowsUnresumableExpired"],
|
|
346
347
|
},
|
|
347
348
|
{
|
|
@@ -354,6 +355,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
354
355
|
"文件头注 formatVersion 5 一段里「4 的载荷 …」那两句;`test/center-artifact-v3-lane.test.ts` 的两格 4 读回(5 原样读回那一格留)",
|
|
355
356
|
afterRemoval: "既有响亮臂 `config_lkg_unusable`(`loadLkg` 对 4 答「unknown formatVersion 4」):4 读回 ⇒ 不可用,中心可达照拉(整拉,新 LKG 按 5 覆盖)、断着则 env 兜底 —— " +
|
|
356
357
|
"与回滚到 7.131.x 读 5 同一种处置",
|
|
358
|
+
stopThenStart: null,
|
|
357
359
|
reportKeys: [],
|
|
358
360
|
},
|
|
359
361
|
{
|
|
@@ -372,6 +374,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
372
374
|
"其余调用方答 404(与别人的行同体)—— 出路是升级时先过一次带本条的版本,或运维按 `placement_root_session_id`(缺则 `placement_parent_session_id`)那一行的属主手工回填、" +
|
|
373
375
|
"推不出的写一个任何主体都不匹配的值;停驻挂点只比对宿主行属主与引擎交来的属主(复活腿交那一行自己的属主),不写无主行;" +
|
|
374
376
|
"建行那一笔记 `placement.owner` 不随本条删(那是常设的写法 —— core 盒义务 7,不是迁移)",
|
|
377
|
+
stopThenStart: null,
|
|
375
378
|
reportKeys: ["placedSessionOwnersInherited", "placedSessionOwnersOrphaned", "placedSessionOwnersRemaining"],
|
|
376
379
|
},
|
|
377
380
|
{
|
|
@@ -386,6 +389,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
386
389
|
"`test/one-time-migrations.test.ts` 的 M24 组与 `test/one-time-migrations-db-integration.test.ts` 的 M24 格。**不随本条删**:属主表、行主键里的令牌与店的写面 / 读面墙(那是常设的数据形)",
|
|
387
390
|
afterRemoval: "起服对账一族的列集探针接住(`schema-consistency.ts` 的 `assertSchemaMatchesCode`,常设):跳过了带本条的版本直接升的库,`workflow_journal` 上仍带 scope 列、没有 incarnation 列 = 库与代码列集不符 ⇒ " +
|
|
388
391
|
"响亮拒启(`config.schema_mismatch`),拒句点名两列;出路是先在带本条的版本(7.133.x)起服一次让它走完,再升",
|
|
392
|
+
stopThenStart: null,
|
|
389
393
|
reportKeys: ["workflowJournalScopeColumn", "workflowJournalOwnersBackfilled", "workflowJournalForeignScopeRowsRemoved"],
|
|
390
394
|
shapeChanges: [{ kind: "rebuild", table: WORKFLOW_JOURNAL_TABLE, whilePresent: RETIRED_JOURNAL_SCOPE_COLUMN, supplies: [WORKFLOW_JOURNAL_SUPPLIED_COLUMN] }],
|
|
391
395
|
},
|
|
@@ -399,6 +403,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
399
403
|
"`test/memory-project-layer-fold.test.ts` 的 ① 格与 `test/memory-project-layer-fold-db-integration.test.ts` 整份、" +
|
|
400
404
|
"`test/project-identity.test.ts` 的 `repo:` 金样格(公式金样改钉 `p` 档摘要)",
|
|
401
405
|
afterRemoval: "没有新的臂(如实):窗内一次都没跑过任务的项目,它的 `repo:` 层留在库里、不再被任何读列表包含(不读、不删;起服拒只管运维点名这一族);出路 = 升级时先过一次带本条的版本并在每个项目跑一次任务",
|
|
406
|
+
stopThenStart: null,
|
|
402
407
|
reportKeys: [],
|
|
403
408
|
},
|
|
404
409
|
{
|
|
@@ -411,6 +416,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
411
416
|
"**不随本条删**:键的铸点 `breakerKeyOf` / `routeDigestOf`(常设的键形)与新表 `breaker_state`",
|
|
412
417
|
afterRemoval: "没有新的臂(如实):跳过了带本条的版本直接升的库,退役表 `circuit_breaker` 留在库里、没有读者也没有写者(断路器只读写 `breaker_state`)—— " +
|
|
413
418
|
"出路 = 升级时先过一次带本条的版本(它起服删掉退役表);不先过也无害 —— 退役表没有读者也没有写者,留在库里只占空间(建议性状态,无数据价值)",
|
|
419
|
+
stopThenStart: null,
|
|
414
420
|
reportKeys: ["retiredBreakerTablesDropped"],
|
|
415
421
|
},
|
|
416
422
|
{
|
|
@@ -423,6 +429,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
423
429
|
"`MAILBOX_KEYED_TABLES` / `mailboxKeyDeleteSql`(`drop` 的常设语句)",
|
|
424
430
|
afterRemoval: "没有新的臂(如实):跳过了带本条的版本直接升的库,判官拒的键的行留在库里,任何入口对它都按「箱不在」答(不读、不投、不清)—— 出路 = 升级时先过一次带本条的版本," +
|
|
425
431
|
"或照 `docs/DEPLOY-PREREQS.md` 7.133.0 SQL 节的查法按键手工删",
|
|
432
|
+
stopThenStart: null,
|
|
426
433
|
reportKeys: ["mailboxRejectedKeyRowsRemoved"],
|
|
427
434
|
},
|
|
428
435
|
{
|
|
@@ -440,6 +447,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
440
447
|
"**不随本条删**:凭据位密封的常设规则(封口 / 开口 / 闭集 / 读口第四态 / 409 码 / 装配期拒启)",
|
|
441
448
|
afterRemoval: "读口对凭据位上明文的常设拒臂接住:跳过了带本条的版本直接升的库,带明文凭据的停驻行续跑答 409 `conflict.checkpoint_ctx_unsealable`(`reason:\"plaintext\"`)," +
|
|
442
449
|
"行字节不动 —— 出路 = 作为新任务重提(仍停驻的先取消),或升级时先过一次带本条的版本",
|
|
450
|
+
stopThenStart: null,
|
|
443
451
|
reportKeys: [],
|
|
444
452
|
},
|
|
445
453
|
{
|
|
@@ -452,6 +460,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
452
460
|
"`test/checkpoint-index-columns-db-integration.test.ts` 的 M29 格。**不随本条删**:`approval_card` 列、写口的派生、到期 facet 的生成谓词(常设)",
|
|
453
461
|
afterRemoval: "没有新的臂(如实):跳过了带本条的版本直接升的库,升级前停驻、升级后仍挂着的行卡列是 NULL —— 生成谓词读门型的 facet(审批门 ⇒ SLA 拒扫腿),问答行到期被拒扫" +
|
|
454
462
|
"(引擎对问答拒收 `sla_timeout`,拒扫腿每拍一条失败,由 `terminal_at_ms` 兜底收割);运维队列行不带卡词。出路 = 升级前答完 / 拒掉停驻的问答,或升级时先过一次带本条的版本",
|
|
463
|
+
stopThenStart: null,
|
|
455
464
|
reportKeys: ["parkedApprovalCardsBackfilled", "parkedApprovalCardRowsUnreadable", "parkedApprovalCardRowsTooLong"],
|
|
456
465
|
},
|
|
457
466
|
{
|
|
@@ -480,6 +489,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
480
489
|
"**不随本条删**:续跑判据的第四问(退役请求键闭集 `RETIRED_REQUEST_KEYS` / `retiredRequestKeyOf` / `retiredRequestKeyRefusal`,常设)",
|
|
481
490
|
afterRemoval: "续跑判据第四问的常设拒臂接住:跳过了带本条的版本直接升的库(或窗内从没起过本版的部署),体里仍带 `promptProfile` 的停驻行续跑在五个问点上答 409 `checkpoint.unsupported_version`" +
|
|
482
491
|
"(判据 `retired_request_key`,`http/stored-body-replay.ts`)、行字节不动 —— 出路 = 作为新任务重提(`promptLean` 代替 `promptProfile`;仍停驻的先取消),或升级时先过一次带本条的版本并在窗内起服",
|
|
492
|
+
stopThenStart: null,
|
|
483
493
|
reportKeys: [],
|
|
484
494
|
},
|
|
485
495
|
{
|
|
@@ -493,6 +503,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
493
503
|
"`test/memory-sync-client.test.ts` 里标题以 `🔴 M31:` 或 `M31 ` 起头的格、对 `relocateSyncCursorsM31` 的引入与常量 `LEGACY_PEER_DIR`,常量 `CURSOR_FILE` 的行注改成「没有读者」(用它的格随删后无人用它 ⇒ 常量一起删)",
|
|
494
504
|
afterRemoval: "没有新的臂(如实):跳过了带本条的版本直接升的数据根,升级前的游标还在 `sync-cursors/central/` 与 `sync-cursor-central.json`,没有读者 ⇒ 那几层以空基线首轮同步" +
|
|
495
505
|
"(两边都改过的条目按冲突上报,上一轮之后在一侧删掉的条目从另一侧回来)。出路 = 升级时先过一次带本条的版本并在窗内跑一轮同步,或升级前在旧版上跑完一轮同步、再删掉这些文件",
|
|
506
|
+
stopThenStart: null,
|
|
496
507
|
reportKeys: [],
|
|
497
508
|
},
|
|
498
509
|
{
|
|
@@ -514,6 +525,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
514
525
|
"**不随本条删**:执行放置八列、会话店的执行席、设备店的首绑 / 换绑两只写(常设的数据形)",
|
|
515
526
|
afterRemoval: "起服对账一族的跳版库拒启臂接住:删码同版把 `device_session` / `device_session_retired` 两张表加进退役 schema 判据(`schema-consistency.ts` 的跳版库探针,先于建表)⇒ " +
|
|
516
527
|
"跳过了带本条的版本直接升的库响亮拒启,出路 = 先在带本条的版本起服一次让切换走完,再升;缺执行放置列的库由列集对账缺列拒启(`config.schema_mismatch`,拒句给 ALTER),同一出路",
|
|
528
|
+
stopThenStart: null,
|
|
517
529
|
reportKeys: ["executionPlacementColumnsAdded", "deviceBindingsMoved", "deviceBindingsOrphaned", "deviceBindingTablesDropped", "executionPlacementsBackfilled", "askExecutionLanesBackfilled", "executionPlacementSessionsUnreadable"],
|
|
518
530
|
shapeChanges: [{ kind: "add", table: APPROVAL_ASK_TABLE, column: ASK_EXECUTION_LANE_COLUMN, whilePresent: { table: "session_meta", anyOf: SESSION_EXT_MOVED_COLUMNS.map((c) => c.name) } }],
|
|
519
531
|
},
|
|
@@ -535,6 +547,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
535
547
|
"`session-error-wire.ts` 的 `StampedSessionArchiveError` / `STAMPED_SESSION_ARCHIVE_SENTENCE` / `sessionErrorWireOf` 与本店带戳判的唯一读口 `assertArchiveAnonymous`(fork 的源、改日志推送的落点、会话同步导入第一阶段的早拒三处问它)、行上缺建档时刻的 F 类读法(`server.local-session-row.created-at-absent`)",
|
|
536
548
|
afterRemoval: "三只常设臂接住:① 数据根下的快照目录非空 ⇒ 拒启(`config.local_archive_snapshot_present`,点名文件与两条出路);② 跳过了带本条的版本直接升的数据根(或本条留着的存档),带属主戳的存档被 fork、改日志的推送与会话同步导入第一阶段对 fork / stale 的早拒同一只具名拒(409 `conflict.session_archive_stamped` + 固定句,零写 / 行格净零写)," +
|
|
537
549
|
"读 / 续跑 / 拉取照常 —— 出路 = 删掉会话后重推,或升级时先过一次带本条的版本并在窗内起服;③ 行上没有建档时刻的格(同一类数据根)⇒ 列表 / 会话视图 / 交出的元数据读纪元(F 类 tag 计数)",
|
|
550
|
+
stopThenStart: null,
|
|
538
551
|
reportKeys: ["localArchiveRowFactsBackfilled", "localArchivesAnonymized", "localArchivesKeptStamped", "localArchivesUnreadable", "localArchiveSnapshotsRecovered"],
|
|
539
552
|
},
|
|
540
553
|
{
|
|
@@ -551,6 +564,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
551
564
|
afterRemoval: "两只常设臂接住:① SQL —— 删码同版把 `approval_ask.denied_reason` 加进退役 schema 判据(`schema-consistency.ts` 的跳版库探针,先于建表)⇒ 跳过了带本条的版本直接升的库响亮拒启," +
|
|
552
565
|
"出路 = 先在带本条的版本起服一次让迁移走完,再升(列册对账见幽灵列 / 缺列同样拒启,但它的拒句给的是加列,不是这一出路 —— 所以退役判据要在删码同版加上);" +
|
|
553
566
|
"② local —— 信封号 1 的日志记录走 File 问账店「认不出的信封号」拒启(`unknown envelope version`,点名文件与出路:用写下它的那一版起服一次,或移开文件)",
|
|
567
|
+
stopThenStart: null,
|
|
554
568
|
reportKeys: ["askCauseColumnsChanged", "askParkTriggersMoved", "askJournalRecordsUpgraded"],
|
|
555
569
|
shapeChanges: [
|
|
556
570
|
{ kind: "rename", table: APPROVAL_ASK_TABLE, from: [RETIRED_ASK_CAUSE_COLUMN], to: APPROVAL_ASK_ENDING_CAUSE_COLUMN.name },
|
|
@@ -567,6 +581,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
567
581
|
"**不随本条删**:模型面闸 `env-model-table-gate.ts`、`LocalConfigProvider` 读决定(etag 覆盖)、目录信任判官的根级文档名单(常设)",
|
|
568
582
|
afterRemoval: "常设的模型面闸接住:跳过了带本条的版本直接升的本地根(或运行记录在场而决定缺席的根),决定缺席读作 kept ⇒ env 模型表已声明时管模型面的本地目录被组拒 " +
|
|
569
583
|
"`config.catalog_replaces_env_models`,拒句点名被顶替的 env 模型与两条出路(在配置根写 `config.env-models.json` = `{\"envModels\":\"replaced\"}`,或撤掉 MODEL_ID / MODEL_CHEAP_ID)",
|
|
584
|
+
stopThenStart: null,
|
|
570
585
|
reportKeys: [],
|
|
571
586
|
},
|
|
572
587
|
{
|
|
@@ -584,6 +599,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
584
599
|
"**不随本条删**:`SqlDurableRulePartitionProvider` 收「方言 + 执行口」的那一形(`BucketSql`;常设,池照旧满足它)",
|
|
585
600
|
afterRemoval: "没有响亮臂(如实):删码之后,跳过了带本条的版本直接升的库(或回滚到引擎 7.61.0 之前、在其上又导入过的库),存量的这种全局 `/x` allow 照旧在每个项目根放行,本服务不再点名 —— " +
|
|
586
601
|
"出路 = 升级时先过一次带本条的版本并起服;或运维列出桶里出处为导入(`adds[].origin` = `imported-cc`)、scope 为全局、从 `/` 写起的 allow(`GET /v1/rules`)并撤掉(`DELETE /v1/rules`,撤的是这条规则的全部批准)",
|
|
602
|
+
stopThenStart: null,
|
|
587
603
|
reportKeys: ["importedLayerRootAllowsRetired", "importedLayerRootBucketsSkipped", "importedLayerRootBucketsUnnamed"],
|
|
588
604
|
},
|
|
589
605
|
{
|
|
@@ -596,6 +612,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
596
612
|
"`test/approval-card-source-key-m37.test.ts` 整只文件、本文件头注 M37 段",
|
|
597
613
|
afterRemoval: "既有坏行臂接住(响亮,不再改名):仍带旧键的存卡(跳过了带本条的版本直接升的库、窗关之后还在写的 7.142.x 副本)整卡读不出 —— 断连重放跳过 + 一次 warn、" +
|
|
598
614
|
"幂等重入走 park、回决口按要人",
|
|
615
|
+
stopThenStart: null,
|
|
599
616
|
reportKeys: [],
|
|
600
617
|
},
|
|
601
618
|
{
|
|
@@ -610,6 +627,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
610
627
|
"`test/settings-env-credential.test.ts` 里窗开的三格(剥键照续 / 剥空登记空表 / 预判窗开不拦)与「窗关当天仍开」那格、`withM38Window` 助手(窗关的几格改成不注入窗直接断言拒)、M38 登记行那一格;本文件头注 M38 段",
|
|
611
628
|
afterRemoval: "没有新的臂,接住它的是窗关之后的读法(删码零行为变化:窗关那一刻起剥键臂已经不生效):存体 `settings.env` 里仍带凭据条目的停驻行,续跑前的预判拒(409 `resume_blocked_by_policy`,`blockedBy: request.env_credential_refused`,机读位点名键与命中类),卡仍 pending —— " +
|
|
612
629
|
"出路是取消那条 run,把凭据挪进引擎进程环境后重新提交。会撞上它的是活过窗的升级前停驻行:发布后才升级的部署、调长了 `APPROVAL_TERMINAL_BACKSTOP_MS` 的部署、滚动升级里旧副本在窗内新写的行、窗内续跑过又停驻到窗外的任务(头注 M38 段)",
|
|
630
|
+
stopThenStart: null,
|
|
613
631
|
reportKeys: [],
|
|
614
632
|
},
|
|
615
633
|
{
|
|
@@ -623,6 +641,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
623
641
|
"**不随本条删**:数据根建目录只经 `ensureDir` 这条律本身(常设)、`plugins/owner-only-file-mode.ts`(本服务文件的 `0600` 唯一值与原子写的两个出口:异步出口常设,同步出口按它自己的退役条件 —— core 的原子写改成独占新建 tmp —— 走,不随本条)及它们的钉 —— `test/data-dir-law-census.test.ts`(`src/**` 零裸 mkdir、零手写 0o700、文件模式只认一个名字、tmp 只在一只写口里铸)与 `test/data-dir-modes.test.ts`(每只 local 店首建目录 0700、旧 tmp 不被复用)",
|
|
624
642
|
afterRemoval: "没有响亮臂(如实,也无需):删码之后,跳过了带本条的版本直接升的数据根,升级前铸成的 0755 目录原样留着(新建的目录一律 0700,不受影响;里面的文件多半仍是 0600),本服务不再点名 —— " +
|
|
625
643
|
"出路 = 运维一次 `chmod 700` 数据根下 `runs`(及其子目录)· `space-commits` · `checkpoint-ctx` · `.tmp` · `attachments` · `scratchpad`(及其子目录)· `plugin-cache`(及其子目录)· `<记忆引擎根>/sync-cursors`,或升级时先过一次带本条的版本并起服",
|
|
644
|
+
stopThenStart: null,
|
|
626
645
|
reportKeys: [],
|
|
627
646
|
},
|
|
628
647
|
{
|
|
@@ -630,15 +649,20 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
630
649
|
introducedIn: "7.147.0",
|
|
631
650
|
releasedOn: "2026-11-07",
|
|
632
651
|
removableAfter: "2026-12-07",
|
|
633
|
-
removal: "删 `src/plugins/execution-lane-rename-m40.ts` 整只文件;本文件的 M40 步(`renameRetiredExecutionLaneWordsM40` / `
|
|
634
|
-
"`EXECUTION_LANE_RENAME_REFUSED_CODE
|
|
635
|
-
"`store-backend.ts` 的 `LocalBackend.ensureSchema` 第一步与 `executionLaneWordsRenamed`
|
|
652
|
+
removal: "删 `src/plugins/execution-lane-rename-m40.ts` 整只文件;本文件的 M40 步(`renameRetiredExecutionLaneWordsM40` / `refuseExecutionLaneRenameM40`〔本行 `stopThenStart.refuse`;证据读法 `readOlderReplicaEvidence`、判活窗输入与守卫段归 `stop-then-start.ts`,常设,不随本行删〕/ `ExecutionLaneRenameRefusedError` / " +
|
|
653
|
+
"`EXECUTION_LANE_RENAME_REFUSED_CODE`,`migrateStepsOn` 第一步那一行)、报告 / 收据 / 日志 / `NO_SQL_MIGRATIONS` 的 `executionLaneWordsRenamed`、头注 M40 段;" +
|
|
654
|
+
"`store-backend.ts` 的 `LocalBackend.ensureSchema` 第一步与 `executionLaneWordsRenamed` 字段;" +
|
|
636
655
|
"`local-session-store.ts` 的内核 `renameRetiredExecutionLaneWordsInCellsM40` 与数据根准入的具名读者 `readSessionMetaSidecarInWindow`(在内存里套的那一步;准入的解码点改用 `readSessionMetaSidecar`);" +
|
|
637
656
|
"`LocalSessionStore.renameRetiredExecutionLaneWordM40`、`FileApprovalAskStore.renameRetiredExecutionLaneWordM40` 与内核的 `renameExecutionLaneWord`;" +
|
|
638
657
|
"`approval-ask-store-sql.ts` / `execution-placement-sql.ts` 拒句里的 `retiredExecutionLaneHintM40(…)` 补句;`test/execution-lane-rename-m40.test.ts` 整只文件与 `test/execution-placement-switch-db-integration.test.ts` 的 M40 组",
|
|
639
658
|
afterRemoval: "既有读口的拒臂接住(响亮,不再改名):仍带旧词的行 —— 跳过了带本条的版本直接升的库、窗关之后还在写的更早版本副本 —— SQL 问行读口拒、会话执行格读口拒(`ExecutionPlacementRowError`)," +
|
|
640
659
|
"local 会话元数据边档整只严格拒启(`config.schema_mismatch`),local 问账日志由 M32 回填的词表外拒臂拒启(M32 删码之后:那只问行原样装回)。出路 = 升级时先过一次带本条的版本并起服",
|
|
641
|
-
stopThenStart:
|
|
660
|
+
stopThenStart: {
|
|
661
|
+
reason: "renames the retired execution-lane word \"in-process\" to \"none\" on stored approval asks and sessions; a replica of an earlier version would keep writing the old word after the rename",
|
|
662
|
+
owedOn: owesExecutionLaneRenameM40,
|
|
663
|
+
refuse: refuseExecutionLaneRenameM40,
|
|
664
|
+
fence: { kind: "accepted", residual: "an earlier replica keeps writing the old word after the rename; this version's readers refuse such a row loudly, and the next boot inside the window renames it again" },
|
|
665
|
+
},
|
|
642
666
|
reportKeys: ["executionLaneWordsRenamed"],
|
|
643
667
|
},
|
|
644
668
|
{
|
|
@@ -646,13 +670,18 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
646
670
|
introducedIn: "7.147.0",
|
|
647
671
|
releasedOn: "2026-11-07",
|
|
648
672
|
removableAfter: "2026-12-07",
|
|
649
|
-
removal: "删本文件的 M41 步(`moveSessionCellsToSideTable` / `
|
|
650
|
-
"`SessionExtMoveRefusalReason` / `sameCell` / `SESSION_EXT_MOVE_PAGE`,`migrateStepsOn`
|
|
673
|
+
removal: "删本文件的 M41 步(`moveSessionCellsToSideTable` / `refuseSessionExtMoveM41`〔本行 `stopThenStart.refuse`〕/ `deploymentColumnsOnMeta` / `SessionExtMoveRefusedError` / `SESSION_EXT_MOVE_REFUSED_CODE` / " +
|
|
674
|
+
"`SessionExtMoveRefusalReason` / `sameCell` / `SESSION_EXT_MOVE_PAGE`,`migrateStepsOn` 里那一行)、报告 / 收据 / 日志 / `NO_SQL_MIGRATIONS` 的 `sessionExtRowsMoved` / `sessionMetaColumnsDropped`、头注 M41 段;" +
|
|
651
675
|
"M32 读形里的 `cellsOnSideTable` 判(它读本条的 `deploymentColumnsOnMeta`):M32 还在时改成恒旁表形 —— 删 M32 写 `session_meta` 八列的那些臂(② ④ ④b ⑥ 与 ③ 的 `migrateDeviceBindingsStatement` 臂)," +
|
|
652
|
-
"留 ③ 的旁表臂(`migrateDeviceBindingsOntoSideTableStatements`:围栏拒句的「采旧」在任何库上仍要能落到执行格);M32 先于本条删码时这些随 M32 一并删;`
|
|
676
|
+
"留 ③ 的旁表臂(`migrateDeviceBindingsOntoSideTableStatements`:围栏拒句的「采旧」在任何库上仍要能落到执行格);M32 先于本条删码时这些随 M32 一并删;`test/session-ext-move-db-integration.test.ts` 整只文件。能力名单 `REPLICA_CAPABILITIES` 里的 `M41` 不删(只增)",
|
|
653
677
|
afterRemoval: "跳过了带本条的版本直接升上来的库:`session_meta` 上仍带部署格列 ⇒ 起服列册对账拒启(`config.schema_mismatch`,那几列是本树之外的多余列,拒句不给 ALTER —— 出路是带本条的版本);" +
|
|
654
678
|
"部署格从旁表读,旧列上的值不被任何读者读。出路 = 升级时先过一次带本条的版本并起服",
|
|
655
|
-
stopThenStart:
|
|
679
|
+
stopThenStart: {
|
|
680
|
+
reason: "moves the session deployment cells from session_meta to session_ext and then retires the old columns; a cell an earlier replica writes between the copy and the retirement is lost, and every cell write it makes afterwards fails",
|
|
681
|
+
owedOn: owesSessionExtMoveM41,
|
|
682
|
+
refuse: refuseSessionExtMoveM41,
|
|
683
|
+
fence: { kind: "accepted", residual: "a cell an earlier replica writes between the copy and the column drop is lost; after the drop every cell write it makes fails" },
|
|
684
|
+
},
|
|
656
685
|
reportKeys: ["sessionExtRowsMoved", "sessionMetaColumnsDropped"],
|
|
657
686
|
shapeChanges: [{ kind: "drop", table: "session_meta", columns: SESSION_EXT_MOVED_COLUMNS.map((c) => c.name) }],
|
|
658
687
|
},
|
|
@@ -661,12 +690,17 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
661
690
|
introducedIn: "7.148.0",
|
|
662
691
|
releasedOn: "2026-11-08",
|
|
663
692
|
removableAfter: "2026-12-08",
|
|
664
|
-
removal: "删 `src/plugins/scenario-prefix-switch-m42.ts` 整只文件;本文件的 M42 步(`switchScenarioPrefixM42` / `scannedIdentityColumnsM42
|
|
665
|
-
"`
|
|
693
|
+
removal: "删 `src/plugins/scenario-prefix-switch-m42.ts` 整只文件;本文件的 M42 步(`switchScenarioPrefixM42` / `scannedIdentityColumnsM42` / `refuseScenarioPrefixSwitchM42`〔本行 `stopThenStart.refuse`〕,`migrateStepsOn` 第一步那一行)、报告 / 收据 / 日志的 `scenarioPrefixSourcesScanned`、头注 M42 段;" +
|
|
694
|
+
"`store-backend.ts` 的 `LocalBackend.runOneTimeMigrations` 里 M42 那一腿(`switchLocalScenarioPrefixM42`)与四只 File 店的 `scenarioPrefixOwnerRowsM42`(run / 会话 / 问 / 附件);`test/scenario-prefix-switch-m42.test.ts` 与 `test/scenario-prefix-switch-db-integration.test.ts` 两只文件。" +
|
|
666
695
|
"标记表 `one-time-migration-marker.ts` 不随删(常设:中央建表语句建它,`Skill` 豁免截点那一行的家);库里留下的 `M42` 标记行 / 数据根里的标记文件无人再读,不删",
|
|
667
696
|
afterRemoval: "没有响亮臂(如实):跳过了带本条的版本直接升的库,存量里以 `_scn:` 开头的身份被恢复管线读作某个人的场景(拆不出合文法的场景与人的 ⇒ `owner.malformed_subject` 响亮)。" +
|
|
668
697
|
"出路 = 升级时先过一次带本条的版本并起服(它扫一次、命中即拒启点名)",
|
|
669
|
-
stopThenStart:
|
|
698
|
+
stopThenStart: {
|
|
699
|
+
reason: "scans stored identities for the reserved scenario prefix and records a marker; an earlier replica does not reserve the prefix and would keep accepting such identities after the scan",
|
|
700
|
+
owedOn: owesScenarioPrefixSwitchM42,
|
|
701
|
+
refuse: refuseScenarioPrefixSwitchM42,
|
|
702
|
+
fence: { kind: "accepted", residual: "an earlier replica keeps accepting identities that start with the reserved scenario prefix after the scan; this version reads such an identity as someone else's scenario" },
|
|
703
|
+
},
|
|
670
704
|
reportKeys: ["scenarioPrefixSourcesScanned"],
|
|
671
705
|
},
|
|
672
706
|
{
|
|
@@ -679,6 +713,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
679
713
|
"local 会话元数据格「没有 `clientWrites` 位 ⇒ upgrade_pending」那一臂;库里留下的标记行无人再读,不删(与 M42 同一张标记表)",
|
|
680
714
|
afterRemoval: "窗 30 天之后更早版本的副本早已不在;标记行不再被任何读者读(留着无害)。跳过了带本条的版本直接升上来的库:撤回出口从第一次起服就启用 —— " +
|
|
681
715
|
"跨两版以上的混跑本就不被支持(7.147.0 起的停-迁-起)。出路 = 升级时先过一次带本条的版本并起服",
|
|
716
|
+
stopThenStart: null,
|
|
682
717
|
reportKeys: ["withdrawMarkWritten"],
|
|
683
718
|
},
|
|
684
719
|
{
|
|
@@ -692,6 +727,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
692
727
|
afterRemoval: "没有响亮臂(如实):跳过了带本条的版本直接升上来的库,旧行按列答 —— 停驻两口在列建立之前写下的 `needs_review` 行 `errorCode` 缺席(`review.pending` 仍在 `result` 里)、" +
|
|
693
728
|
"列里是没折过的原码的旧行答原码;`result.terminal.code` 仍在 `result` 里。调长了停驻终局兜底(`APPROVAL_TERMINAL_BACKSTOP_MS` > 30 天)的部署,窗关时还可能有更早版本写下的停驻没结清,读法同上。" +
|
|
694
729
|
"出路 = 升级时先过一次带本条的版本并起服",
|
|
730
|
+
stopThenStart: null,
|
|
695
731
|
reportKeys: ["runErrorCodeColumnRewritten"],
|
|
696
732
|
},
|
|
697
733
|
{
|
|
@@ -704,6 +740,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
704
740
|
"`test/run-preview-m45.test.ts` 与 `test/helpers/run-preview-m45-rows.ts` 整个文件、`test/session-preview-single-source-db-integration.test.ts` 的 M45 组",
|
|
705
741
|
afterRemoval: "没有响亮臂(如实):跳过了带本条的版本直接升上来的库,7.124.0 之前写下的、以注入块起头的预览照旧按列答 —— 会话列表 / `GET /v1/tasks` / 助手任务行名 / 收件箱上显示那段块文本。" +
|
|
706
742
|
"出路 = 升级时先过一次带本条的版本并起服",
|
|
743
|
+
stopThenStart: null,
|
|
707
744
|
reportKeys: ["runObjectivePreviewRewritten"],
|
|
708
745
|
},
|
|
709
746
|
{
|
|
@@ -723,6 +760,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
723
760
|
"SQL 在 `ensureSchema()` 建表之前(`LegacySkillExemptionsPresentError`,与退役 schema 探针同一处),local 在数据根准入(读数种别 `skipped-required-migration`)。" +
|
|
724
761
|
"出路 = 先用一个仍带本条、不低于 7.148.0(local 还要不低于拒句里已记的引擎高水位)的版本对这只库完整起一次,再升;SQL 另可手工 `DELETE FROM approval_exemption WHERE tool_name = 'Skill'`。" +
|
|
725
762
|
"T0 由常设的一步落(SQL:`ensureSchema()` 建表之后的种子行;local:准入的锁内一步):判过、缺席才落 —— 删码之后全新的库照样有 T0,不会被自己写下的合法行拒",
|
|
763
|
+
stopThenStart: null,
|
|
726
764
|
reportKeys: ["legacySkillExemptionsDropped"],
|
|
727
765
|
},
|
|
728
766
|
{
|
|
@@ -739,6 +777,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
739
777
|
afterRemoval: "跳版拒启臂接住(常设,数据根准入的一格:只读、本进程第一笔写之前、引擎高水位抬之前):(打开之前的引擎高水位早于 7.148.0 或缺席 ∨ 数据根里的收令牌欠账标记还在 —— 带本条的版本打开过、没收完)" +
|
|
740
778
|
"∧ 根里有存档在而会话元数据格缺的会话 ⇒ 拒启 `config.schema_mismatch`(读数种别 `skipped-required-migration`,点名会话数与版本),零写、不抬高水位 —— " +
|
|
741
779
|
"出路 = 先用一个仍带本条、不低于 7.148.0 且不低于已记高水位的版本(服务或 run-local)完整起一次,再升",
|
|
780
|
+
stopThenStart: null,
|
|
742
781
|
reportKeys: ["localArchiveTokensAdopted", "localArchiveTokensMinted"],
|
|
743
782
|
},
|
|
744
783
|
{
|
|
@@ -753,6 +792,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
753
792
|
afterRemoval: "没有响亮臂(如实):没有身份边界的部署跳过了带本条的版本直接升上来,哨兵属主的存量行仍记着那个字面量,属主面表已不认它 —— 不带主体的本地单用户读不到、续不上那些会话与 run(404)," +
|
|
754
793
|
"带同一个头的请求仍读得到(属主相同)。出路 = 升级时先过一次带本条的版本并起服(或运维手工 `UPDATE <表> SET owner = NULL WHERE owner = 'anon:shell-live'`,三张表见删法)。" +
|
|
755
794
|
"有身份边界的部署本条本来就零改写,删码前后同答(哨兵是一位普通的具名属主)",
|
|
795
|
+
stopThenStart: null,
|
|
756
796
|
reportKeys: ["shellSentinelOwnersCleared", "shellSentinelOwnerRowsRetained"],
|
|
757
797
|
},
|
|
758
798
|
{
|
|
@@ -766,6 +806,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
766
806
|
afterRemoval: "没有响亮臂(如实):跳过了带本条的版本直接升上来的库,升级前停下、升级后仍挂着的卡归属为空 —— 按 run 找卡的读口找不到它:取消那条 run 不作废它、" +
|
|
767
807
|
"两条停驻收割把那条 run 当成「卡已不在」收掉(`approval.expired`)、决断答 409 `conflict.resume_context_unavailable`,卡由终局兜底收割收走。出路 = 升级前答完 / 拒掉停驻的卡," +
|
|
768
808
|
"或升级时先过一次带本条的版本并起服(或运维手工 `UPDATE checkpoint SET host_session_id = session_id WHERE host_session_id IS NULL`)",
|
|
809
|
+
stopThenStart: null,
|
|
769
810
|
reportKeys: ["checkpointHostSessionsBackfilled"],
|
|
770
811
|
},
|
|
771
812
|
{
|
|
@@ -778,6 +819,7 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
778
819
|
"`approval-ask-store-memory.ts` 的 `deleteByTaskM50`;`test/approval-ask-session-cascade.test.ts` 的 M50 组(窗内 / 窗关当天 / 窗关次日 / 坏记录四格与 `withM50Window` 助手);本文件头注 M50 段",
|
|
779
820
|
afterRemoval: "既有的词表外动词拒启(`approval-ask-store-file.ts` 重放的动词闭集判,拒句点名账本路径,出路 = 用写下它的那一版起服一次或把文件挪开)—— 与窗关之后本条自己的拒启同一个结局,删码零行为变化。" +
|
|
780
821
|
"会撞上它的是窗内一次都没在带本条的版本上起过服的 local 数据根(跳过本版直接升的),账本里又恰好留着一条嵌入方写下的这只词",
|
|
822
|
+
stopThenStart: null,
|
|
781
823
|
reportKeys: [],
|
|
782
824
|
},
|
|
783
825
|
{
|
|
@@ -785,13 +827,30 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
785
827
|
introducedIn: "7.148.0",
|
|
786
828
|
releasedOn: "2026-11-08",
|
|
787
829
|
removableAfter: "2026-12-08",
|
|
788
|
-
removal: "删本文件的 M51 步(`switchSessionDeletingM51` / `SessionDeletingSwitchRefusedError` / `SESSION_DELETING_SWITCH_REFUSED_CODE` / `SESSION_DELETING_MARK_ID`,`migrateStepsOn` 里那一行)、" +
|
|
830
|
+
removal: "删本文件的 M51 步(`switchSessionDeletingM51` / `refuseSessionDeletingSwitchM51`〔本行 `stopThenStart.refuse`〕/ `SessionDeletingSwitchRefusedError` / `SESSION_DELETING_SWITCH_REFUSED_CODE` / `SESSION_DELETING_MARK_ID`,`migrateStepsOn` 里那一行)、" +
|
|
789
831
|
"报告 / 收据 / `changedAnything` / `readingFields` / `NO_SQL_MIGRATIONS` 的 `sessionDeletingSwitchMarked`、头注 M51 段;`test/session-deleting-state-db-integration.test.ts` 的 M51 组;" +
|
|
790
832
|
"库里留下的 `M51` 标记行无人再读,不删。**不随本条删**:在删态本身(列、围栏、规则 L 的在删半、终刀判令牌 —— 常设)、标记表 `one-time-migration-marker.ts`(常设)",
|
|
791
833
|
afterRemoval: "没有响亮臂(也无需):窗 30 天之后更早版本的副本早已不在;跳过了带本条的版本直接升上来的库 —— 跨两版以上的混跑本就不被支持(7.147.0 起的停-迁-起)。出路 = 升级时先过一次带本条的版本并起服",
|
|
792
|
-
stopThenStart:
|
|
834
|
+
stopThenStart: {
|
|
835
|
+
reason: "switches session deletion to a deleting state that every replica must read; an earlier replica does not read it and would accept a submission on a session this version is deleting",
|
|
836
|
+
owedOn: owesSessionDeletingSwitchM51,
|
|
837
|
+
refuse: refuseSessionDeletingSwitchM51,
|
|
838
|
+
fence: { kind: "accepted", residual: "an earlier replica does not read the deleting state and may accept a submission on a session this version is deleting" },
|
|
839
|
+
},
|
|
793
840
|
reportKeys: ["sessionDeletingSwitchMarked"],
|
|
794
841
|
},
|
|
842
|
+
{
|
|
843
|
+
id: "M53",
|
|
844
|
+
introducedIn: "7.151.0",
|
|
845
|
+
releasedOn: "2026-11-10",
|
|
846
|
+
removableAfter: "2026-12-10",
|
|
847
|
+
removal: "删本文件的 M53 步(`rewriteStoreFaultSentencesM53` / `rewriteBackgroundAgentRowsM53` / `rewriteToolEndEventsM53` / `M53_PAGE` / `M53_BACKGROUND_AGENT_TABLE`,`migrateStepsOn` 里那两行)、整只 `store-fault-sentence-m53.ts`、" +
|
|
848
|
+
"报告 / 收据 / `changedAnything` / `readingFields` / `NO_SQL_MIGRATIONS` 的 `storeFaultSentencesRewritten`、头注 M53 段;`test/store-fault-sentence-m53.test.ts` 与 `test/store-fault-sentence-m53-db-integration.test.ts`(`scripts/db-integration-files.json` 里它那一行同删)。" +
|
|
849
|
+
"**不随本条删**:店边界本身(`terminal.ts` 的 `storeBoundaryFault`、`store-boundary.ts` 的封口 —— 常设)",
|
|
850
|
+
afterRemoval: "没有响亮臂(如实):跳过了带本条的版本直接升的库上,换句之前落盘的后台子代行与 run 事件卡格仍带库驱动的原句(回读 / 回放照原样渲染);出路只有运维:按留存清理,或手删那些行",
|
|
851
|
+
stopThenStart: null,
|
|
852
|
+
reportKeys: ["storeFaultSentencesRewritten"],
|
|
853
|
+
},
|
|
795
854
|
];
|
|
796
855
|
export function migrationWindowOpen(window, today) {
|
|
797
856
|
return window.removableAfter === null || today <= window.removableAfter;
|
|
@@ -808,7 +867,7 @@ export function migrationCarried(id) {
|
|
|
808
867
|
return ONE_TIME_MIGRATIONS.some((w) => w.id === id);
|
|
809
868
|
}
|
|
810
869
|
export function stopThenStartMigrations(registry = ONE_TIME_MIGRATIONS) {
|
|
811
|
-
return registry.flatMap((row) =>
|
|
870
|
+
return registry.flatMap((row) => row.stopThenStart === null ? [] : [{ id: row.id, introducedIn: row.introducedIn, ...(row.shapeChanges !== undefined ? { shapeChanges: row.shapeChanges } : {}), ...row.stopThenStart }]);
|
|
812
871
|
}
|
|
813
872
|
export const NO_SQL_MIGRATIONS = {
|
|
814
873
|
sessionRuleColumn: "file-store",
|
|
@@ -840,6 +899,7 @@ export const NO_SQL_MIGRATIONS = {
|
|
|
840
899
|
sessionMetaColumnsDropped: 0,
|
|
841
900
|
withdrawMarkWritten: 0,
|
|
842
901
|
sessionDeletingSwitchMarked: 0,
|
|
902
|
+
storeFaultSentencesRewritten: 0,
|
|
843
903
|
askCauseColumnsChanged: 0,
|
|
844
904
|
askParkTriggersMoved: 0,
|
|
845
905
|
};
|
|
@@ -898,16 +958,30 @@ async function columnExists(db, dialect, table, column) {
|
|
|
898
958
|
export function createSqlImportedLayerRootSource(exec) {
|
|
899
959
|
return { candidateOwners: async () => ({ owners: await listRuleBucketOwners(exec), unnamedBuckets: 0 }), durable: new SqlDurableRulePartitionProvider(exec), isWholeBucketRefusal: isSqlBucketRefusal, isVanishedBucket: isSqlBucketVanished };
|
|
900
960
|
}
|
|
901
|
-
export async function runSqlOneTimeMigrations(dialect, pool, input) {
|
|
902
|
-
|
|
961
|
+
export async function runSqlOneTimeMigrations(dialect, pool, input, me = buildThisReplicaRegistration()) {
|
|
962
|
+
const stopThenStart = stopThenStartMigrations();
|
|
963
|
+
assertStopThenStartDeclarations(stopThenStart);
|
|
964
|
+
const head = async (db) => {
|
|
965
|
+
await assertReplicaTablesPresent(db, dialect, me);
|
|
966
|
+
await registerReplica(db, dialect, me, Date.now());
|
|
967
|
+
await assertServingRequirementsMet(db, me);
|
|
968
|
+
};
|
|
969
|
+
const locked = async (db) => {
|
|
970
|
+
await assertServingRequirementsMet(db, me);
|
|
971
|
+
await guardOwedStopThenStart(db, dialect, input, stopThenStart);
|
|
972
|
+
return migrateOn(db, dialect, input);
|
|
973
|
+
};
|
|
974
|
+
return dialect === "mysql" ? withMysqlLock(pool, head, locked) : withPgLock(pool, head, locked);
|
|
903
975
|
}
|
|
904
|
-
async function withMysqlLock(pool, run) {
|
|
976
|
+
async function withMysqlLock(pool, head, run) {
|
|
905
977
|
const conn = await pool.getConnection();
|
|
906
978
|
let locked = false;
|
|
907
979
|
try {
|
|
980
|
+
const db = mysqlDb(conn);
|
|
981
|
+
await head(db);
|
|
908
982
|
await acquireEnsureSchemaLock(conn, "oneTimeMigrations");
|
|
909
983
|
locked = true;
|
|
910
|
-
return await run(
|
|
984
|
+
return await run(db);
|
|
911
985
|
}
|
|
912
986
|
finally {
|
|
913
987
|
if (locked)
|
|
@@ -915,13 +989,15 @@ async function withMysqlLock(pool, run) {
|
|
|
915
989
|
conn.release();
|
|
916
990
|
}
|
|
917
991
|
}
|
|
918
|
-
async function withPgLock(pool, run) {
|
|
992
|
+
async function withPgLock(pool, head, run) {
|
|
919
993
|
const client = await pool.connect();
|
|
920
994
|
let locked = false;
|
|
921
995
|
try {
|
|
996
|
+
const db = pgDb(client);
|
|
997
|
+
await head(db);
|
|
922
998
|
await acquirePgEnsureSchemaLock(client, "oneTimeMigrations");
|
|
923
999
|
locked = true;
|
|
924
|
-
return await run(
|
|
1000
|
+
return await run(db);
|
|
925
1001
|
}
|
|
926
1002
|
finally {
|
|
927
1003
|
if (locked)
|
|
@@ -940,10 +1016,9 @@ async function migrateOn(db, dialect, input) {
|
|
|
940
1016
|
return completedReport(receipts);
|
|
941
1017
|
}
|
|
942
1018
|
async function migrateStepsOn(db, dialect, receipts, input) {
|
|
943
|
-
await switchScenarioPrefixM42(db, dialect, receipts
|
|
944
|
-
await renameRetiredExecutionLaneWordsM40(db, dialect, receipts
|
|
945
|
-
await
|
|
946
|
-
await switchSessionDeletingM51(db, dialect, receipts, input);
|
|
1019
|
+
await switchScenarioPrefixM42(db, dialect, receipts);
|
|
1020
|
+
await renameRetiredExecutionLaneWordsM40(db, dialect, receipts);
|
|
1021
|
+
await switchSessionDeletingM51(db, dialect, receipts);
|
|
947
1022
|
await rewriteRunErrorCodeColumnM44(db, dialect, receipts);
|
|
948
1023
|
await rewriteRunObjectivePreviewM45(db, dialect, receipts);
|
|
949
1024
|
await clearShellSentinelOwnersM48(db, dialect, receipts, input);
|
|
@@ -966,6 +1041,7 @@ async function migrateStepsOn(db, dialect, receipts, input) {
|
|
|
966
1041
|
await moveSessionCellsToSideTable(db, dialect, receipts);
|
|
967
1042
|
await markWithdrawEnabledM43(db, dialect, receipts, input);
|
|
968
1043
|
await dropLegacySkillExemptionsM46(db, dialect, receipts);
|
|
1044
|
+
await rewriteStoreFaultSentencesM53(db, dialect, receipts);
|
|
969
1045
|
}
|
|
970
1046
|
const M44_PAGE = 500;
|
|
971
1047
|
async function rewriteRunErrorCodeColumnM44(db, dialect, receipts) {
|
|
@@ -1009,6 +1085,71 @@ async function rewriteOneRunErrorCodeM44(db, dialect, row) {
|
|
|
1009
1085
|
? "UPDATE task_run SET error_code = ? WHERE task_id = ? AND status = ? AND updated_at = ? AND error_code <=> ?"
|
|
1010
1086
|
: "UPDATE task_run SET error_code = $1 WHERE task_id = $2 AND status = $3 AND updated_at = $4 AND error_code IS NOT DISTINCT FROM $5", [target, taskId, String(row["status"]), row["updated_at"], storedCode]);
|
|
1011
1087
|
}
|
|
1088
|
+
const M53_PAGE = 500;
|
|
1089
|
+
const M53_BACKGROUND_AGENT_TABLE = "background_agent";
|
|
1090
|
+
async function rewriteStoreFaultSentencesM53(db, dialect, receipts) {
|
|
1091
|
+
if (await tableExists(db, dialect, M53_BACKGROUND_AGENT_TABLE))
|
|
1092
|
+
await rewriteBackgroundAgentRowsM53(db, dialect, receipts);
|
|
1093
|
+
if (await tableExists(db, dialect, "task_event"))
|
|
1094
|
+
await rewriteToolEndEventsM53(db, dialect, receipts);
|
|
1095
|
+
}
|
|
1096
|
+
async function rewriteBackgroundAgentRowsM53(db, dialect, receipts) {
|
|
1097
|
+
let after;
|
|
1098
|
+
for (;;) {
|
|
1099
|
+
const cursor = after === undefined ? "" : dialect === "mysql" ? " AND (scope_key, handle) > (?, ?)" : " AND (scope_key, handle) > ($1, $2)";
|
|
1100
|
+
const page = await db.rows(`SELECT scope_key, handle, rev, ${jsonColumnText(dialect, "record_json")} FROM ${M53_BACKGROUND_AGENT_TABLE} WHERE ${jsonColumnTextExpr(dialect, "record_json")} LIKE '%"errorCode"%'${cursor} ORDER BY scope_key, handle LIMIT ${M53_PAGE}`, after === undefined ? [] : [after.scope, after.handle]);
|
|
1101
|
+
for (const row of page) {
|
|
1102
|
+
let record;
|
|
1103
|
+
try {
|
|
1104
|
+
record = decodeJsonColumn(row["record_json"], readJsonObjectColumn, `${M53_BACKGROUND_AGENT_TABLE}.record_json for handle ${String(row["handle"])}`);
|
|
1105
|
+
}
|
|
1106
|
+
catch (err) {
|
|
1107
|
+
if (isJsonColumnBodyProblem(err))
|
|
1108
|
+
continue;
|
|
1109
|
+
throw err;
|
|
1110
|
+
}
|
|
1111
|
+
const rewritten = rewrittenBackgroundRecordM53(record);
|
|
1112
|
+
if (rewritten === undefined)
|
|
1113
|
+
continue;
|
|
1114
|
+
const rev = Number(row["rev"]);
|
|
1115
|
+
const next = { ...rewritten, rev: rev + 1 };
|
|
1116
|
+
receipts.storeFaultSentencesRewritten += await db.exec(dialect === "mysql"
|
|
1117
|
+
? `UPDATE ${M53_BACKGROUND_AGENT_TABLE} SET record_json = ?, rev = ? WHERE scope_key = ? AND handle = ? AND rev = ?`
|
|
1118
|
+
: `UPDATE ${M53_BACKGROUND_AGENT_TABLE} SET record_json = $1, rev = $2 WHERE scope_key = $3 AND handle = $4 AND rev = $5`, [dialect === "mysql" ? JSON.stringify(next) : pgSafeJsonStringify(next), rev + 1, row["scope_key"], row["handle"], row["rev"]]);
|
|
1119
|
+
}
|
|
1120
|
+
if (page.length < M53_PAGE)
|
|
1121
|
+
return;
|
|
1122
|
+
const last = page[page.length - 1];
|
|
1123
|
+
after = { scope: last["scope_key"], handle: last["handle"] };
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
async function rewriteToolEndEventsM53(db, dialect, receipts) {
|
|
1127
|
+
const carded = dialect === "mysql" ? "JSON_EXTRACT(data, '$.structured.errorCode') IS NOT NULL" : "data->'structured'->>'errorCode' IS NOT NULL";
|
|
1128
|
+
let after;
|
|
1129
|
+
for (;;) {
|
|
1130
|
+
const cursor = after === undefined ? "" : dialect === "mysql" ? " AND (task_id, seq) > (?, ?)" : " AND (task_id, seq) > ($1, $2)";
|
|
1131
|
+
const page = await db.rows(`SELECT task_id, seq, ${jsonColumnText(dialect, "data")} FROM task_event WHERE type = 'tool_end' AND ${carded}${cursor} ORDER BY task_id, seq LIMIT ${M53_PAGE}`, after === undefined ? [] : [after.taskId, after.seq]);
|
|
1132
|
+
for (const row of page) {
|
|
1133
|
+
let data;
|
|
1134
|
+
try {
|
|
1135
|
+
data = decodeJsonColumn(row["data"], readJsonObjectColumn, `task_event.data for task ${String(row["task_id"])} seq ${String(row["seq"])}`);
|
|
1136
|
+
}
|
|
1137
|
+
catch (err) {
|
|
1138
|
+
if (isJsonColumnBodyProblem(err))
|
|
1139
|
+
continue;
|
|
1140
|
+
throw err;
|
|
1141
|
+
}
|
|
1142
|
+
const next = rewrittenToolEndDataM53(data);
|
|
1143
|
+
if (next === undefined)
|
|
1144
|
+
continue;
|
|
1145
|
+
receipts.storeFaultSentencesRewritten += await db.exec(dialect === "mysql" ? "UPDATE task_event SET data = ? WHERE task_id = ? AND seq = ?" : "UPDATE task_event SET data = $1::jsonb WHERE task_id = $2 AND seq = $3", [dialect === "mysql" ? JSON.stringify(next) : pgSafeJsonStringify(next), String(row["task_id"]), row["seq"]]);
|
|
1146
|
+
}
|
|
1147
|
+
if (page.length < M53_PAGE)
|
|
1148
|
+
return;
|
|
1149
|
+
const last = page[page.length - 1];
|
|
1150
|
+
after = { taskId: String(last["task_id"]), seq: last["seq"] };
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1012
1153
|
const M45_PAGE = 500;
|
|
1013
1154
|
async function rewriteRunObjectivePreviewM45(db, dialect, receipts) {
|
|
1014
1155
|
if (!(await tableExists(db, dialect, "task_run")))
|
|
@@ -1096,33 +1237,50 @@ async function markWithdrawEnabledM43(db, dialect, receipts, input) {
|
|
|
1096
1237
|
const marked = await db.rows(dialect === "mysql" ? `SELECT 1 AS present FROM ${MIGRATION_MARKER_TABLE} WHERE migration_id = ?` : `SELECT 1 AS present FROM ${MIGRATION_MARKER_TABLE} WHERE migration_id = $1`, [WITHDRAW_MARK_ID]);
|
|
1097
1238
|
if (marked.length > 0)
|
|
1098
1239
|
return;
|
|
1099
|
-
if ((await
|
|
1240
|
+
if ((await readOlderReplicaEvidence(db, dialect, input, "M43")) !== undefined)
|
|
1100
1241
|
return;
|
|
1101
1242
|
receipts.withdrawMarkWritten += await db.exec(markIfAbsentSql(dialect), [WITHDRAW_MARK_ID, Date.now()]);
|
|
1102
1243
|
}
|
|
1244
|
+
async function migrationMarked(read, dialect, id) {
|
|
1245
|
+
if (!(await tableExists({ rows: read }, dialect, MIGRATION_MARKER_TABLE)))
|
|
1246
|
+
return false;
|
|
1247
|
+
return (await read(`SELECT 1 AS present FROM ${MIGRATION_MARKER_TABLE} WHERE migration_id = '${id}'`)).length > 0;
|
|
1248
|
+
}
|
|
1249
|
+
async function owesExecutionLaneRenameM40(read, dialect) {
|
|
1250
|
+
return (await executionLaneWordRowsM40(read, dialect)).pendingRows > 0;
|
|
1251
|
+
}
|
|
1252
|
+
async function owesSessionExtMoveM41(read, dialect) {
|
|
1253
|
+
return (await deploymentColumnsOnMeta({ rows: read }, dialect)).length > 0;
|
|
1254
|
+
}
|
|
1255
|
+
async function owesScenarioPrefixSwitchM42(read, dialect) {
|
|
1256
|
+
return !(await migrationMarked(read, dialect, SCENARIO_PREFIX_MARKER_ID));
|
|
1257
|
+
}
|
|
1258
|
+
async function owesSessionDeletingSwitchM51(read, dialect) {
|
|
1259
|
+
return !(await migrationMarked(read, dialect, SESSION_DELETING_MARK_ID));
|
|
1260
|
+
}
|
|
1103
1261
|
export const SESSION_DELETING_MARK_ID = "M51";
|
|
1104
1262
|
export const SESSION_DELETING_SWITCH_REFUSED_CODE = "config.session_deleting_switch_refused";
|
|
1105
1263
|
export class SessionDeletingSwitchRefusedError extends StoreBootRefusalError {
|
|
1106
1264
|
code = SESSION_DELETING_SWITCH_REFUSED_CODE;
|
|
1107
|
-
reason = "
|
|
1108
|
-
constructor(
|
|
1109
|
-
super(`${SESSION_DELETING_SWITCH_REFUSED_CODE} (reason:
|
|
1110
|
-
`(a submission on a session being deleted is refused), but ${
|
|
1265
|
+
reason = "older_replica";
|
|
1266
|
+
constructor(evidence, tail = "") {
|
|
1267
|
+
super(`${SESSION_DELETING_SWITCH_REFUSED_CODE} (reason: older_replica): this version deletes a session through a deleting state that every replica must read ` +
|
|
1268
|
+
`(a submission on a session being deleted is refused), but ${olderReplicaEvidenceSentence(evidence)} — ` +
|
|
1111
1269
|
"a replica of an earlier version may still be serving; it does not read that state and would accept a submission on a session this version is deleting. Nothing was changed and no marker was written. " +
|
|
1112
|
-
stopThenStartAction(
|
|
1270
|
+
stopThenStartAction(evidence.after) +
|
|
1113
1271
|
tail);
|
|
1114
1272
|
this.name = "SessionDeletingSwitchRefusedError";
|
|
1115
1273
|
}
|
|
1116
1274
|
}
|
|
1117
|
-
async function
|
|
1275
|
+
async function refuseSessionDeletingSwitchM51(evidence, read, dialect) {
|
|
1276
|
+
return new SessionDeletingSwitchRefusedError(evidence, await describeUpgradeDriftTail(read, dialect));
|
|
1277
|
+
}
|
|
1278
|
+
async function switchSessionDeletingM51(db, dialect, receipts) {
|
|
1118
1279
|
if (!(await tableExists(db, dialect, MIGRATION_MARKER_TABLE)))
|
|
1119
1280
|
await execUntil(db, migrationMarkerDdl(dialect), () => tableExists(db, dialect, MIGRATION_MARKER_TABLE));
|
|
1120
|
-
|
|
1121
|
-
if (marked.length > 0)
|
|
1281
|
+
if (!(await owesSessionDeletingSwitchM51((sql) => db.rows(sql), dialect)))
|
|
1122
1282
|
return;
|
|
1123
|
-
|
|
1124
|
-
if (heartbeat !== undefined)
|
|
1125
|
-
throw new SessionDeletingSwitchRefusedError(heartbeat, await describeUpgradeDriftTail((sql) => db.rows(sql), dialect));
|
|
1283
|
+
await recordServingRequirement(db, dialect, "M51", Date.now());
|
|
1126
1284
|
receipts.sessionDeletingSwitchMarked += await db.exec(markIfAbsentSql(dialect), [SESSION_DELETING_MARK_ID, Date.now()]);
|
|
1127
1285
|
}
|
|
1128
1286
|
export async function scannedIdentityColumnsM42(db, dialect) {
|
|
@@ -1139,11 +1297,11 @@ export async function scannedIdentityColumnsM42(db, dialect) {
|
|
|
1139
1297
|
}
|
|
1140
1298
|
return out.sort((a, b) => `${a.table}.${a.column}`.localeCompare(`${b.table}.${b.column}`));
|
|
1141
1299
|
}
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
if (
|
|
1300
|
+
async function refuseScenarioPrefixSwitchM42(evidence, read, dialect) {
|
|
1301
|
+
return new ScenarioPrefixSwitchRefusedError("older_replica", [], evidence, await describeUpgradeDriftTail(read, dialect));
|
|
1302
|
+
}
|
|
1303
|
+
export async function switchScenarioPrefixM42(db, dialect, receipts) {
|
|
1304
|
+
if (!(await owesScenarioPrefixSwitchM42((sql) => db.rows(sql), dialect)))
|
|
1147
1305
|
return;
|
|
1148
1306
|
const columns = await scannedIdentityColumnsM42(db, dialect);
|
|
1149
1307
|
const hits = [];
|
|
@@ -1156,9 +1314,9 @@ export async function switchScenarioPrefixM42(db, dialect, receipts, input) {
|
|
|
1156
1314
|
receipts.scenarioPrefixSourcesScanned += columns.length;
|
|
1157
1315
|
if (hits.length > 0)
|
|
1158
1316
|
throw new ScenarioPrefixSwitchRefusedError("stored_prefix", hits, undefined, await describeUpgradeDriftTail((sql) => db.rows(sql), dialect));
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1317
|
+
if (!(await tableExists(db, dialect, MIGRATION_MARKER_TABLE)))
|
|
1318
|
+
await execUntil(db, migrationMarkerDdl(dialect), () => tableExists(db, dialect, MIGRATION_MARKER_TABLE));
|
|
1319
|
+
await recordServingRequirement(db, dialect, "M42", Date.now());
|
|
1162
1320
|
await db.exec(markIfAbsentSql(dialect), [SCENARIO_PREFIX_MARKER_ID, Date.now()]);
|
|
1163
1321
|
}
|
|
1164
1322
|
export const EXECUTION_LANE_RENAME_REFUSED_CODE = "config.execution_lane_rename_refused";
|
|
@@ -1191,52 +1349,34 @@ export class ExecutionLaneRenameWriteRefusedError extends StoreBootRefusalError
|
|
|
1191
1349
|
}
|
|
1192
1350
|
}
|
|
1193
1351
|
const EXECUTION_LANE_TABLES = [APPROVAL_ASK_TABLE, "session_meta", SESSION_EXT_TABLE];
|
|
1194
|
-
|
|
1352
|
+
async function executionLaneWordRowsM40(read, dialect) {
|
|
1195
1353
|
const tables = [];
|
|
1196
1354
|
for (const table of EXECUTION_LANE_TABLES)
|
|
1197
|
-
if (await columnExists(
|
|
1355
|
+
if (await columnExists({ rows: read }, dialect, table, "execution_lane"))
|
|
1198
1356
|
tables.push(table);
|
|
1199
1357
|
let pendingRows = 0;
|
|
1200
1358
|
for (const table of tables) {
|
|
1201
|
-
const [row] = await
|
|
1359
|
+
const [row] = await read(`SELECT COUNT(*) AS n FROM ${table} WHERE execution_lane = '${RETIRED_EXECUTION_LANE_WORD_M40}'`);
|
|
1202
1360
|
pendingRows += Number(row?.["n"] ?? 0);
|
|
1203
1361
|
}
|
|
1362
|
+
return { tables, pendingRows };
|
|
1363
|
+
}
|
|
1364
|
+
export async function renameRetiredExecutionLaneWordsM40(db, dialect, receipts) {
|
|
1365
|
+
const { tables, pendingRows } = await executionLaneWordRowsM40((sql) => db.rows(sql), dialect);
|
|
1204
1366
|
if (pendingRows === 0)
|
|
1205
1367
|
return;
|
|
1206
|
-
await
|
|
1368
|
+
await recordServingRequirement(db, dialect, "M40", Date.now());
|
|
1207
1369
|
for (const table of tables) {
|
|
1208
1370
|
receipts.executionLaneWordsRenamed += await db.exec(dialect === "mysql" ? `UPDATE ${table} SET execution_lane = ? WHERE execution_lane = ?` : `UPDATE ${table} SET execution_lane = $1 WHERE execution_lane = $2`, [RENAMED_EXECUTION_LANE_M40, RETIRED_EXECUTION_LANE_WORD_M40]);
|
|
1209
1371
|
}
|
|
1210
1372
|
}
|
|
1211
|
-
async function
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
return undefined;
|
|
1219
|
-
const newestCell = row?.["newest"];
|
|
1220
|
-
const newest = newestCell instanceof Date ? newestCell : new Date(String(newestCell));
|
|
1221
|
-
const now = Date.now();
|
|
1222
|
-
const restartAtMs = (Number.isNaN(newest.getTime()) ? now : newest.getTime()) + input.liveRunWindowMs;
|
|
1223
|
-
return {
|
|
1224
|
-
liveRuns,
|
|
1225
|
-
windowSec: Math.round(input.liveRunWindowMs / 1000),
|
|
1226
|
-
restartAfter: new Date(restartAtMs).toISOString(),
|
|
1227
|
-
after: `${new Date(restartAtMs).toISOString()} (${Math.max(0, Math.ceil((restartAtMs - now) / 1000))}s from now)`,
|
|
1228
|
-
};
|
|
1229
|
-
}
|
|
1230
|
-
async function refuseWhileRunsHeartbeat(db, dialect, pendingRows, input) {
|
|
1231
|
-
const heartbeat = await readLiveRunHeartbeat(db, dialect, input);
|
|
1232
|
-
if (heartbeat === undefined)
|
|
1233
|
-
return;
|
|
1234
|
-
const { liveRuns, windowSec, restartAfter, after } = heartbeat;
|
|
1235
|
-
throw new ExecutionLaneRenameRefusedError(pendingRows, liveRuns, restartAfter, `${pendingRows} stored rows (approval asks / sessions) carry the execution lane word "${RETIRED_EXECUTION_LANE_WORD_M40}", the name an earlier version gave the lane with no execution environment, ` +
|
|
1236
|
-
`which this version calls "${RENAMED_EXECUTION_LANE_M40}" and does not read; this boot renames them (one-time migration M40), but ${liveRuns} running runs on this database heartbeat within the last ${windowSec}s ` +
|
|
1237
|
-
`(REAP_RUN_STALE_SEC) — a replica of an earlier version is still serving, and it would keep writing the old word after the rename. No stored row was changed. ` +
|
|
1238
|
-
stopThenStartAction(after) +
|
|
1239
|
-
(await describeUpgradeDriftTail((sql) => db.rows(sql), dialect)));
|
|
1373
|
+
async function refuseExecutionLaneRenameM40(evidence, read, dialect) {
|
|
1374
|
+
const { pendingRows } = await executionLaneWordRowsM40(read, dialect);
|
|
1375
|
+
return new ExecutionLaneRenameRefusedError(pendingRows, evidence.liveRuns, evidence.restartAfter, `${pendingRows} stored rows (approval asks / sessions) carry the execution lane word "${RETIRED_EXECUTION_LANE_WORD_M40}", the name an earlier version gave the lane with no execution environment, ` +
|
|
1376
|
+
`which this version calls "${RENAMED_EXECUTION_LANE_M40}" and does not read; this boot renames them (one-time migration M40), but ${olderReplicaEvidenceSentence(evidence)} ` +
|
|
1377
|
+
`— a replica of an earlier version may still be serving, and it would keep writing the old word after the rename. No stored row was changed. ` +
|
|
1378
|
+
stopThenStartAction(evidence.after) +
|
|
1379
|
+
(await describeUpgradeDriftTail(read, dialect)));
|
|
1240
1380
|
}
|
|
1241
1381
|
export const SESSION_EXT_MOVE_REFUSED_CODE = "config.session_ext_move_refused";
|
|
1242
1382
|
export class SessionExtMoveRefusedError extends StoreBootRefusalError {
|
|
@@ -1262,23 +1402,19 @@ const sameCell = (dialect, column) => {
|
|
|
1262
1402
|
return dialect === "mysql" ? `sm.${column.name} <=> ${side}` : `sm.${column.name} IS NOT DISTINCT FROM ${side}`;
|
|
1263
1403
|
};
|
|
1264
1404
|
const SESSION_EXT_MOVE_PAGE = 500;
|
|
1265
|
-
|
|
1266
|
-
const columns = await deploymentColumnsOnMeta(
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
throw new SessionExtMoveRefusedError("live_runs", `${columns.length} session cells (${columns.map((c) => c.name).join(", ")}) still live on session_meta; this version keeps them on the side table ${SESSION_EXT_TABLE} and moves them on this boot ` +
|
|
1273
|
-
`(one-time migration M41: copy, verify, then drop the columns), but ${heartbeat.liveRuns} running runs on this database heartbeat within the last ${heartbeat.windowSec}s (REAP_RUN_STALE_SEC) — ` +
|
|
1274
|
-
"a replica of an earlier version is still serving; a cell it writes between the copy and the drop would be lost, and every cell write it makes after the drop fails. Nothing was changed. " +
|
|
1275
|
-
stopThenStartAction(heartbeat.after) +
|
|
1276
|
-
(await describeUpgradeDriftTail((sql) => db.rows(sql), dialect)));
|
|
1405
|
+
async function refuseSessionExtMoveM41(evidence, read, dialect) {
|
|
1406
|
+
const columns = await deploymentColumnsOnMeta({ rows: read }, dialect);
|
|
1407
|
+
return new SessionExtMoveRefusedError("older_replica", `${columns.length} session cells (${columns.map((c) => c.name).join(", ")}) still live on session_meta; this version keeps them on the side table ${SESSION_EXT_TABLE} and moves them on this boot ` +
|
|
1408
|
+
`(one-time migration M41: copy, verify, then drop the columns), but ${olderReplicaEvidenceSentence(evidence)} — ` +
|
|
1409
|
+
"a replica of an earlier version may still be serving; a cell it writes between the copy and the drop would be lost, and every cell write it makes after the drop fails. Nothing was changed. " +
|
|
1410
|
+
stopThenStartAction(evidence.after) +
|
|
1411
|
+
(await describeUpgradeDriftTail(read, dialect)));
|
|
1277
1412
|
}
|
|
1278
1413
|
export async function moveSessionCellsToSideTable(db, dialect, receipts) {
|
|
1279
1414
|
const columns = await deploymentColumnsOnMeta(db, dialect);
|
|
1280
1415
|
if (columns.length === 0)
|
|
1281
1416
|
return;
|
|
1417
|
+
await recordServingRequirement(db, dialect, "M41", Date.now());
|
|
1282
1418
|
const names = columns.map((c) => c.name);
|
|
1283
1419
|
const p = dialect === "mysql" ? () => "?" : (n) => `$${n}`;
|
|
1284
1420
|
const upsert = `INSERT INTO ${SESSION_EXT_TABLE} (session_id, ${names.join(", ")}) SELECT session_id, ${names.join(", ")} FROM session_meta ` +
|
|
@@ -2149,6 +2285,7 @@ function readingFields(r) {
|
|
|
2149
2285
|
scenarioPrefixSourcesScanned: r.scenarioPrefixSourcesScanned,
|
|
2150
2286
|
withdrawMarkWritten: r.withdrawMarkWritten,
|
|
2151
2287
|
sessionDeletingSwitchMarked: r.sessionDeletingSwitchMarked,
|
|
2288
|
+
storeFaultSentencesRewritten: r.storeFaultSentencesRewritten,
|
|
2152
2289
|
runErrorCodeColumnRewritten: r.runErrorCodeColumnRewritten,
|
|
2153
2290
|
runObjectivePreviewRewritten: r.runObjectivePreviewRewritten,
|
|
2154
2291
|
shellSentinelOwnersCleared: r.shellSentinelOwnersCleared,
|