@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
package/MIGRATION.md
CHANGED
|
@@ -8,6 +8,457 @@
|
|
|
8
8
|
> 本文件只记会影响存量部署行为的变更:某一版没有节,即那一版没有记入这里的升级动作;完整的变更流水账(修复、文字订正、内部重构)是内部记录,不随 npm 包出。
|
|
9
9
|
> 文中的「契约 §N」「契约附录 X」指服务端 wire 契约的节号(内部记录,不随包),只作查证坐标。
|
|
10
10
|
|
|
11
|
+
## 7.152.0 —— 1–33 条见下
|
|
12
|
+
|
|
13
|
+
**升级清单(本节唯一的一张;下面各条只讲为什么,不再各自重述升级步骤)** —— 一次读清本版对一只存量部署要做的全部动作。每版同形:① 手工 DDL(逐表逐句,两方言各一份)② 起服自建与一次性迁移 ③ 停-迁-起 ④ 顺序;后续每版的段头照此写,新增一句 `ALTER`、一条一次性迁移、一条停-迁-起时,先改这里,再写条目。
|
|
14
|
+
已发各节(7.151.0 及以前)逐字只读,不在原处补汇总 —— 跨过它们的部署读下面「跨过 7.151.0」一块。
|
|
15
|
+
|
|
16
|
+
- **从 7.151.x 升级到本版**:
|
|
17
|
+
- 手工 DDL(SQL 后端 `DB_BACKEND=mysql|pg`;一张表一句,**先升库、再升副本**;旧副本只在它重启时按「库比构建新」拒启,多出的这一列是它的幽灵列)。语句逐字是起服列册对账拒句打印的那一句(由本构建的建表语句生成),存量行不回填(第 2 条「运维队列决断口收 `persistRule`」:停驻行的规则 scope 快照):
|
|
18
|
+
- MySQL 协议:
|
|
19
|
+
`ALTER TABLE checkpoint ADD COLUMN card_scope_root VARCHAR(4096) NULL;`
|
|
20
|
+
- PostgreSQL:
|
|
21
|
+
`ALTER TABLE checkpoint ADD COLUMN card_scope_root VARCHAR(4096) COLLATE "C";`
|
|
22
|
+
其余各条零 DDL。`DB_BACKEND=local` 零 DDL。
|
|
23
|
+
- 起服自建(运维零手工):新表 `file_history_blob_grant` 与它的两只二级索引 `idx_file_history_blob_grant_granted` / `idx_file_history_blob_grant_blob`(起服 `CREATE TABLE IF NOT EXISTS` 自建;空表起步,存量零回填;第 3 条)。另一张新表 `blob_namespace_claim`(一库一行的认领记号,开店时缺席才铸;第 25 条);配了对象存储的部署起服时在会话快照桶写下 `<SESSION_SNAPSHOT_PREFIX>blob-namespace-claim`(第 25 条)。
|
|
24
|
+
- 一次性迁移:**M54**(SQL 两方言;起服自跑,运维零手工 DDL;第 1 条「停驻问的题干与选项整份上待决行」与第 19 条「运维待批队列行的全部动作事实与续跑执行读同一次整行解码」):删 `checkpoint` 的五只展示拷贝列 `tool_name` / `tool_input` / `risk_descriptor` / `rule_suggestions` / `has_bidi_controls`(待决行的入参与其余动作事实改为读时从整行解码投影,升级前停驻的行不重算、不迁值);读数 `checkpointDisplayColumnsDropped`(本次删掉的列数,0–5);它是停-迁-起,见下一行;`DB_BACKEND=local` 恒 0。第 3 条的新表起服自建、不回填,不占一次性迁移。
|
|
25
|
+
- 到期移除的一次性迁移:M13 / M15 / M16(第 18 条;盘上 LKG 信封 2 / 3 不再读回、本地 `config.d` 起服不再自动迁)—— 从 7.124.0 及以后升级的部署零动作;从 ≤ 7.123.x 直升须先经 7.124.0–7.151.x 任一版起服一次,或升级前备份 `config.d` 后手跑 `npx @sema-agent/settings-schema@25 migrate <config.d 目录>`(本版带的契约包 26.0.0 的 `migrate` 不再改写这几形,第 32 条)。
|
|
26
|
+
- 停-迁-起:新增 **M54**(第 1 条 / 第 19 条;SQL 两方言):起服时五列任一还在 ⇒ 先记起服要求、再一句 `ALTER TABLE checkpoint DROP COLUMN …` 删在的那几列(起服自跑,运维零手工 DDL;读数 `checkpointDisplayColumnsDropped`)—— 删列之后更早版本的副本每一次停驻与每一次队列读都失败,**升级前停光全部旧版本副本、等满判活窗**(判活窗内有不知道 M54 的副本在跑 run ⇒ 拒启 `config.checkpoint_display_columns_drop_refused`,一字节不写)。已有几条(**M40** · **M41** · **M42** · **M51**)的守卫同 7.151.0。
|
|
27
|
+
- 升级前自查(不改库;每条一行,出路在各条里):共用一只会话快照桶的各只库各有自己的 `SESSION_SNAPSHOT_PREFIX`(第 25 条;同前缀的第二只库起服拒启)、按最小权限发对象存储策略的给 `<前缀>blob-namespace-claim` 授 `s3:GetObject` / `s3:PutObject`(第 25 条;没授照起、附件与文件历史不再回收)· `SEND_USER_FILE_URL_TTL` 是十进制整数秒(不带单位)、它与 `SESSION_SNAPSHOT_TTL_SEC` ≤ 604800、开了 leader 与对象存储的 `LEADER_TIMEOUT_MS` ≤ 604200000(第 26 条;超了或非整数起服拒)· 设了 `AUTONOMY=plan` 的部署让已批过计划、此刻停着的 run 续完,或接受它们下一次续跑回到 plan、再批一次计划(第 4 条)· 部署 env 里删掉 `STREAM_APPROVAL_ENABLED`(留着即拒启,第 32 条);审批席开着的部署核 `DURABLE_APPROVAL` 与 store backend,缺一 ⇒ 没有审批卡(第 5 条)· 每一份存着的 `models` 文档里 `headers` 不是对象的条目改成对象或删掉该键、读 fleet 心跳 / `/health` 平铺引擎态键的编排改读 `engineSignal`(第 32 条)· local 后端的数据根没有放在共享文件夹 / 别的用户可写的上级目录里(第 8 条)· `REMOTE_EXEC=k8s` 的部署核集群 API 凭据(显式 `K8S_API_URL` / `K8S_TOKEN` / `K8S_CA_CERT_B64`,或 in-cluster 服务账号)在进程里读得到(第 9 条,缺 ⇒ 拒启)· 用 `sema-up` / `kube-up.sh` / `cluster-up.sh` / 机器清单起**新**部署的脚本与自动化,命令行、`-f` 配置、`machines.yaml` 或环境变量里写下了 `--users` / `USERS` / `users:`(第 12 条;已装部署的 `~/.sema-up/<project>/.env` 里有 `REQUIRE_PRINCIPAL` 一行,重跑零动作)· 开了 `LEADER_ENABLED` 的部署读第 20 条「升级前做」(强制耐久门 / 关 fork 的主体、`AUTONOMY` 档与守卫集、设了审批名单而没接停驻店的部署;零 DDL,滚动升级窗里旧副本照旧形跑 leader 任务) · 开了 `LEADER_ENABLED` 或配了 `type: "agent"` 钩子、且目录给模型配了自己钥匙(`apiKeyEnv` / `sealedApiKey`)的部署:核这些钥匙在服务进程里拿得到(拿不到 ⇒ 这两条车道此后响亮失败,不再落网关钥;第 27 条)。
|
|
28
|
+
- 顺序:① 备份 ② 上面那一句 `ALTER`(SQL 后端,先升库)③ 换版本 —— 带第 1 条(M54)的版本在 SQL 后端上**不可滚动**:停光全部旧版本副本、等满判活窗(`REAP_RUN_STALE_SEC`,缺省 120 s,必须大于 30 s 的心跳周期,否则起服拒),再起本版(先起一只,M54 在它起服时删列;拒句里的「可再起的时刻」= 最新心跳 + 判活窗),再起其余。`DB_BACKEND=local` 无 M54。
|
|
29
|
+
- **回滚**:SQL 后端回到 7.150.x / 7.151.x 的两道拒句与要跑的语句见第 1 条(先补五列、再删要求行;回到 ≤ 7.149.x 只有补列一道;回滚后本版期间停驻的行在旧版队列上缺哪几格见第 19 条);第 2 条多出的那一列的回滚见该条;`DB_BACKEND=local` 照数据根高水位不变量(`engine-high-water.json` 记着打开过这只根的最高版本 ⇒ 更旧的构建拒开这只根;常设不变量,不是本版带来的)。
|
|
30
|
+
- **跨过 7.151.0(从 ≤ 7.150.x 直升本版)另加 7.151.0 节段头升级清单的全部动作**(那一张已含「跨过 7.150.0」一块)。
|
|
31
|
+
- **文字面(第 13–17 条、第 28–29 条)**:对已发各节的勘误、补记、订正与成文,零行为变化、零部署动作 —— 读它们改的是你对已发各节的读法,不是部署动作。带读法后果的两条:第 16 条 ②(多副本上带 `mcpServers` / `a2aPeers` 决 workflow 停驻卡:7.150.x 在不持有那条 run 的副本上答 `200`,7.151.0 起各副本一律答 `400` —— 这是 7.151.0 已发的行为,本条只订正已发节里「照旧」那一句);第 28 条(SQL 后端从 7.143.0 回到 7.142.x:旧副本先被起服列册对账拒启,顺序读 7.143.0 节第 9 条与第 26 条的回滚句,再读第 32 条 ②)。
|
|
32
|
+
|
|
33
|
+
1. **停驻问的题干与选项整份上待决行:给人看的调用入参只有一份读法 —— 脱敏、按 UTF-8 字节量、一个常量 32768;问 / 计划卡整份、从不折叠,其余卡与无卡超常量折叠;问载荷帽删除;待决行 `input` 两孪生都读时投影,SQL 派生列 `checkpoint.tool_input` 退役(行为变更;wire 零新键、零新码、零新帧型,值与阈值变;一次性迁移 M54 删列 —— 与第 19 条的四列同一条迁移,停-迁-起;部署动作 = 升级前停光旧副本)**:
|
|
34
|
+
旧形(≤ 7.151.x):三只帽、两种量法 —— 待决行 `input`(`GET /v1/approvals` / `/stream`)不分卡、超 8192 个 UTF-16 单元换成 `{ truncated: true, bytes }`(`bytes` 是单元数);活卡 `args` 超 16384 UTF-8 字节 ⇒ `argsOmitted`;`question` 帧的问超 16384 个单元 ⇒ 无帧、该问按 unavailable 结算(durable 腿上改道停驻)。脱敏后 `{questions}` 超 8192 个单元的停驻问,审批人在待决行上看不到题干与选项。SQL 后端在停驻那一笔把折叠后的入参另落一列 `checkpoint.tool_input`(停驻快照里另有整份)。
|
|
35
|
+
新形:一只函数、一个常量、一种量法(脱敏后 JSON 的 UTF-8 字节数 ≤ 32768)。问(`approvalCard: "question"`)与计划(`"plan"`)卡的入参整份给出、从不折叠 —— 待决行 `input` 恒是整只 `{ questions }`,`question` 帧恒带整份的问;其余卡与无卡的行超常量折叠:活卡 `argsOmitted`,待决行 `{ truncated: true, bytes }`,`bytes` = 脱敏后 JSON 的 UTF-8 字节数(标记形不变,两键同名同型)。序列化不出 ⇒ 活卡 `argsOmitted`、待决行 `null`、问答 unavailable(同前)。待决行 `input` 在两孪生上都是**读时投影**:入参取停驻快照的 `pendingAction.args`(续跑执行的同一份字节),SQL 不再存第二份 —— 升级前停驻的行起服即按本版读法显示,不重算、不迁值。
|
|
36
|
+
**变了的**:① 有问题席、连着流的腿上超 16384 个字符的问由「不投卡、当场停驻、带外补答」改为「投卡,窗走完没人答 ⇒ 不停驻、投递失败臂」(与小问同律);后台腿上同一只问由「当场停驻」改为「先投卡、等满窗、再停驻」。② 动作卡阈值 8192 个单元(待决行)/ 16384 字节(活卡)→ 32768 字节:相对上一版零收窄(上一版待决行整份的入参最坏 24576 字节)。③ 标记 `bytes` 的单位由单元改为字节:展示这个数的消费方读数变(变对)。④ 待决队列与 `/stream` 对大问行变大;库里一行只存一份入参(停驻快照),问行的行墙与别的行同一堵。⑤ **`checkpoint.tool_input` 列退役,升级 = 一次迁移删列(M54;与第 19 条的四列同一条)**,不能两版滚动(见下)。⑥ 待决动作读不出的 SQL 行(手改 / 坏体)`input` 为 `null`(此前读列),行照列、读不出照旧计数(行形见第 19 条);这样的行续跑也读不出它。
|
|
37
|
+
**谁需要**:带外审批人(web-admin 待决队列、用 `GET /v1/approvals` 带答 decide 的运维;多租缺省形 —— 问题席按姿态关、每一问当场停驻 —— 里待决行是唯一看得到题的面)与冷恢复的壳。**谁受伤**:有问题席的连着的流上发大问的 run(变了的 ①);按「问行带 `truncated` ⇒ 卡呈不出、留待带外 decide」或按标记 `bytes` 当单元数读的消费方;按旧阈值断言的消费方;多副本 SQL 部署(升级要先停光旧副本);直接按列读 `checkpoint.tool_input` 的外部脚本 / 报表(列没了;入参在 `checkpoint` 列的 `pendingAction.args`,那是未脱敏的执行记录)。**出路**:读 `input` 的消费方对问 / 计划卡的行直接读整份(不再回落流上的 `tool_start.args`);标记 `bytes` 按 UTF-8 字节读;不加旋钮。
|
|
38
|
+
**一次性迁移 M54**(SQL 两方言;起服自跑,停-迁-起;一条迁移删 `checkpoint` 的五只展示拷贝列 —— 本条的 `tool_input` 与第 19 条的 `tool_name` / `risk_descriptor` / `rule_suggestions` / `has_bidi_controls`):五列任一在 ⇒ 先往 `serving_requirement` 记 `(M54, in_force)`,再一句 `ALTER TABLE checkpoint DROP COLUMN …` 删在的那几列(按后置条件收敛:并发起服的另一只先删了 = 目标达成;删到一半的库下一次起服只删剩下的);五列都不在 ⇒ 零动作;读数 `checkpointDisplayColumnsDropped`(本次删掉的列数,0–5)。没有搬运:五列的值都是写入时从停驻快照反范式下来的拷贝,删列不丢信息。删列之后更早版本的副本每一次停驻(它的 INSERT 点名这些列)与每一次运维队列读(它的 SELECT 点名这些列)都会失败 ⇒ **不能两版滚动**:起服时判活窗内有不知道 M54 的副本在跑 run ⇒ 拒启 `config.checkpoint_display_columns_drop_refused`(拒因 `older_replica`;一字节不写;拒句点名持有者、给全停之后最早何时再起,句尾接库此刻还差的列与升级清单)。守卫只看心跳:没有在跑 run 的空闲旧副本它看不见。`DB_BACKEND=local` 零动作(LOCAL 孪生从来没有这些列)。
|
|
39
|
+
**升级前做**:停光全部旧版本副本、等满判活窗(`REAP_RUN_STALE_SEC`),再起本版。**回滚**(本版起过服、M54 已删列并记下要求的库):回到 7.150.x / 7.151.x ⇒ 起服先被列册对账拒 `config.schema_mismatch`(缺这五列,拒句逐列给 `ALTER TABLE … ADD COLUMN`,升级清单另点名这只库要求、它没有的能力 M54)→ 照跑补列之后被起服准入拒 `config.serving_requirement_unmet`(点名 M54 与删那一行要求的语句)→ 删行之后旧版本起得来;回到 ≤ 7.149.x(没有起服准入)⇒ 只有列册对账那一道,补列即起得来(要求行留着、无人读);回滚后本版期间停驻的待决行在旧版队列上 `input` / `toolName` / `riskDescriptor` 为 `null`、`ruleOffers` / `hasBidiControls` 缺席(旧版本读那几列,补回的列是空的),决断与续跑读停驻快照、不受影响;回滚后新停驻的行回到旧读法。`DB_BACKEND=local`:本条零改库;回滚照数据根高水位不变量(段头「回滚」一行)。
|
|
40
|
+
|
|
41
|
+
2. **运维队列决断口 `POST /v1/approvals/:sessionId/decide` 收 `persistRule`;停驻卡的「不再询问」在续跑腿结清点兑,对着卡铸时的那一份记录(行为修复;wire 加性;持久面:`checkpoint` 表加一列 `card_scope_root`,SQL 部署升级前手工 DDL 一句)**:
|
|
42
|
+
旧形:运维队列行(`GET /v1/approvals` 的 `pending[i]`、`/v1/approvals/stream` 的 `pending` 帧)带引擎铸的 `ruleOffers`,决这一行的 `/decide` 却把 `persistRule` 当未知键 400(`request.body_shape` + `unknownKeys`);能兑停驻卡上候选的只有活卡回决口的停驻臂,它在协调器的赎回句柄里另兑一次,回放时还会再兑一次。同一张停驻卡的重放帧与队列行投的是两份候选(两只读者,丢弃规则不同)。
|
|
43
|
+
新形:`/decide` 收 `persistRule`,体形、拒句、回执五键(`rulePersisted` / `ruleRefusal` / `persistedRule` / `persistedRules` / `persistedRuleAnchors`)与活卡回决口同一套。从运维队列决卡的客户端:行上 `ruleOffers` 里的单条候选原样抄进 `persistRule.rule`(帧上的原字或队列行上的展示形都认,恰好一只命中才兑);合取批把它在行上数组里的下标放进 `persistRule.batchOfferIndex`。停驻卡的规则只在续跑腿的结清点兑一次(与「本会话放行」同一处、同一读),活卡回决口的停驻臂交同一只请求;**幂等回放不兑规则**:`/decide` 的回放回执不带规则位,活卡回决口的回放(同一把 id 的重试、并发后到者)带了 `persistRule` 答 `rulePersisted:false` + `rule_lane_unavailable` —— 首次有没有落,看首次回执或 `GET /v1/rules`。scope 只取铸卡快照:有问行的卡读问行快照,没有问行的直停驻卡读停驻行上新加的快照列(停驻那一刻由跑这条 run 的副本写下)。队列行投的候选 = 兑付读的那一份记录(有问行的卡投问行上的候选),选择键就是面上数组的下标。直连门(`directDoorActive`)部署:要送 `persistRule`,签名器得把它签进信封扩展位 `persistRule`(投影 `["batch", 下标]` 或 `["text", 规则文本, edited]`);没签进去的请求验签失败;不送它的签名器零改动。能力位 `approvalDecideRuleSlot`(恒真)。
|
|
44
|
+
看不见的边(如实):没有 caller cwd 的部署(远程沙箱 / 未登记的 host / 多租 host 车道)两种卡都答 `scope-unresolved`;升级前停驻、升级后才决的直停驻卡没有快照,答 `scope-unresolved`(与真不可兑同形);相对目录的合取批(`cd ./x && …`)两条腿都还兑不动。
|
|
45
|
+
谁需要:从运维队列决卡、要「不再询问」落进 server 规则店(按属主、跨壳跨机生效)的壳与 SDK 调用方。谁受伤:按「队列行候选只读」编码的消费方(不会红,语义变了 —— 本机写档照常能用);要在直连门上送这一键的签名器(加扩展位编码);依赖「活卡回决口回放时再兑一次规则」的客户端(回放不再兑,首次回执如实答 `rule_store_error` 时,在下一张同命令的卡上再勾一次);上游漂移或伪造的候选不再出现在队列行上。
|
|
46
|
+
**升级前做**(SQL 部署,起服列册对账缺列即拒启并打印同一句):MySQL 协议 `ALTER TABLE checkpoint ADD COLUMN card_scope_root VARCHAR(4096) NULL;` · PostgreSQL `ALTER TABLE checkpoint ADD COLUMN card_scope_root VARCHAR(4096) COLLATE "C";`(local 部署零动作)。**回滚**(本版 → 上一版):`/decide` 带这一键重新答 400;已经落下的规则留在规则店里(`DELETE /v1/rules` 可撤);新列对上一版是多余列(起服列册对账拒启并点名,出路是本版,或运维 `ALTER TABLE checkpoint DROP COLUMN card_scope_root`)。
|
|
47
|
+
|
|
48
|
+
3. **会话同步的文件历史 blob 按落点可见:别的主体 / 别的会话传过的 blob 不再让你的推送过预检、不再能从你的会话读出;订正 7.149.0 节第 34 条「另裁」一句为已收(安全收紧;行为变更;wire 零新键、零新码;持久面:新表 `file_history_blob_grant` 起服自建;嵌入方类型面 BREAKING 一处;部署零动作)**:
|
|
49
|
+
旧形(≤ 7.150.x):`POST /v1/sessions/:id/sync/import` 第一阶段的 blob 在场预检与提交时的重放取值口读的是全局内容地址索引 `file_history_blob`(只有 `blob_hash` 一列作键)—— 别的主体传过的 blob 对你也算在场(「有没有人存过这份内容」的预言机);不上传、只在信封里写别人那一枚的 hash,提交后经自己会话的 `GET …/sync/history/blobs/:hash` 读到别人传上去的字节。
|
|
50
|
+
新形:一枚 blob 对一次推送 / 拉取的**落点**(落点属主格 + 会话 id,与导入租约同一格:id 被占着 ⇒ 住客的属主格;空闲 ⇒ 这位调用方自己)可见 ⇔ 这只 id 此刻有住客且它的历史图引用它,或这个落点自己经 `PUT …/sync/blobs/:hash` 上传过它(字节核过地址、写成之后才记下),且字节仍在。预检、重放取值口、拉取口三口读同一只可见性;对不可见的 hash 预检答 `422 missing_blob`、拉取答 `404 not_found.blob`,与「谁都没传过」逐字节同。字节仍全局去重一份,可见性记在新表 `file_history_blob_grant`(一行 = 一个落点上传过一枚 blob);会话删除(含留存清扫、覆盖写擦除)同删这只会话的行,收割腿在 blob 孤儿回收的宽限窗(1 h)之后清掉没导入的上传,还被记着的上传不当孤儿回收。顺带收两件同类:字节索引的刷新改为单调(迟到的旧写不再把行的时刻写回更早);在场读按批(每句 ≤ 500 枚),一次很大的引用集不再撞驱动的参数个数上限。
|
|
51
|
+
**存量**:不回填 —— 已有的图行就是持久来历,升级后各会话对自己图里的 blob 照旧可见(重推 / identical / 覆盖写都不必补 `PUT`)。升级时在飞、还没导入的上传没有记录,下一次第一阶段答 `422 missing_blob`,照契约补 `PUT` 再推即可。升级之前已经被利用、写进了图的跨主体引用与「两个租户恰有同一份文件」不可区分,维持原样(撤掉会毁合法历史);要核查的运维用只读查询列出被 ≥ 2 个不同属主格的会话图引用的 blob(两方言同文):`SELECT v.blob_hash, COUNT(DISTINCT COALESCE(m.owner, '')) AS owner_cells FROM file_history_version v JOIN session_meta m ON m.session_id = v.scope WHERE v.blob_hash IS NOT NULL GROUP BY v.blob_hash HAVING COUNT(DISTINCT COALESCE(m.owner, '')) > 1` —— 公共文件与被利用的引用都在其中,查询不判是哪一种。
|
|
52
|
+
**订正 7.149.0 节第 34 条**(已发节不改字节):该条末句「在它另裁收口之前,多主体部署上互不信任的主体之间,文件历史内容并不互相保密(知道 hash 即可取)」—— 本版已收(按落点可见,上文)。仍未收的边界(另一类,如实):会话 id 被删、被别的主体同 id 重建之后,提交之后的重放 / 擦除与拉取口门读之后的读不绑住客世代 —— 含删后迟到的重放留在空闲 id 上的图:这只 id 空闲时它不算来历,被新住客占用之后读作新住客的图。
|
|
53
|
+
**谁需要**:有身份边界的多主体部署(`REQUIRE_PRINCIPAL` / service 凭据 + 主体 / 鉴权桥)—— 会话同步的文件历史在互不信任的主体之间保密,预检不再是跨租户的存在性预言机;dev-open 形没有边界,不受益也不受伤。
|
|
54
|
+
**谁受伤**:① 靠「别的会话 / 别的主体已经传过」而跳过 `PUT` 的客户端 —— 现在 `422 missing_blob`,要在**本会话 id、同一调用方身份**下补 `PUT`(按契约在第一阶段之前逐枚 `PUT` 引用的客户端不受影响;拉取再推送、对没拉到字节的 hash 跳过 `PUT` 的路径会更常见 422);② `PUT` 与导入用了不同身份(例:用「凭据 + 主体」上传、用纯 service 凭据导入到空闲 id)⇒ 落点不同 ⇒ 422;③ 上传与导入相隔超过 1 h(此前同一枚若已被别处的图引用,隔多久都过预检);④ 滚动升级窗内旧副本仍按全局答、它收的 `PUT` 不记来历 ⇒ 新副本上多一轮重传(全部副本升完即收敛);⑤ 嵌入方:自带文件历史店、只有 blob 交换组而没有按落点来历面(`blobLanding`)的店,本版起 blob 两口答 `501 capability.snapshot_store_required`、能力位 `sessionSyncFileHistory` 为假(fail-closed:不退回全局读)。
|
|
55
|
+
**补偿 / 出路**:`422 missing_blob` 的动作不变 —— 在本会话 id、同一身份下补 `PUT` 再推;安全轴不给放宽旋钮;嵌入方店照 SQL 两孪生加 `blobLanding`(`putAt` / `visibleAt`)。**升级前做**:无(段头升级清单:新表起服自建)。**回滚**(本版 → 7.150.x):新表被旧构建忽略(多出的表不算不符),预检与取值口回到全局读;再升无动作。
|
|
56
|
+
|
|
57
|
+
4. **续跑口按写据认地板的出口:`AUTONOMY=plan` 的部署上,停驻 run 体顶层的 `default` / `acceptEdits` 只有 `plan_review` 批准写下的那一格续跑原样;提交 / 在飞切档写下的同字词,与 7.152.0 之前写下的停驻行(含已批过计划的),下一次续跑照钳成 `plan`(安全轴,失效关闭;行为收紧;wire 零新键、零新码;续跑上下文多一个服务端键,零 DDL;部署零动作,升级前自查一行)**:
|
|
58
|
+
旧形(7.151.0):续跑口按词值认出口 —— 体顶层原字是 `default` / `acceptEdits` ⇒ 原样,不论是批准写回的、提交时带的还是在飞切档写下的。
|
|
59
|
+
新形:写体顶层模式词那一格的每个写者(提交、在飞切档、续跑口的钳、`plan_review` 批准 / 编辑)在同一笔写里记下谁写的、写下的是哪个词;续跑口地板在场时只对「`plan_review` 写下、且仍是它写下的那个词」原样,其余照现地板钳。没有这条记录的行(7.152.0 之前写下的)一律照钳。更早版本的副本把词改成另一个词而不改这条记录 ⇒ 对不上 ⇒ 照钳;⚠️ 已知限制:旧副本把词切走又切回记录上的同一个词(批准写下 `acceptEdits` 之后,在旧副本上 `acceptEdits → default → acceptEdits` 切档),记录仍对得上 ⇒ 原样(与 7.151.0 同读,不比上一版宽)。记录读不出 ⇒ 续跑答既有的坏体答复(500 `corrupt`)—— 不论有没有地板(读口先判形)。无地板时记录不参与判定,其余行为逐字不变。
|
|
60
|
+
谁需要:设了(或事后改成)`AUTONOMY=plan` 的运营者。**谁受伤**:改严之前以 `default` / `acceptEdits` 提交或切档、此刻停驻的 run(续跑被钳进 plan);**`AUTONOMY=plan` 部署上升级时已经批过计划、又停在别的门上的 run** —— 下一次续跑回到 plan,模型要再交一次计划、人再批一次才出 plan(不丢数据、不放宽);滚动升级窗内在旧副本上批准的计划同此。
|
|
61
|
+
补偿:不新增旋钮。MIGRATION 7.151.0 节第 13 条的「顶层同字词读不出是谁写的,照原样续跑;要它们也收紧 ⇒ `AUTONOMY=read-only`」本版退役(同字词已照钳)。
|
|
62
|
+
**升级前自查**(一行):设了 `AUTONOMY=plan` 的部署,升级前让已批过计划、此刻停着的 run 续完(决完 / 跑完),或接受它们下一次续跑回到 plan、再批一次计划;滚动升级窗内在旧副本上批准的计划同此。
|
|
63
|
+
**回滚**(本版 → 7.151.0):7.151.0 不读这条记录、照词值读(批过的 `acceptEdits` 原样、钳过的 `plan` 原样),零动作;回滚之后再升回本版,旧副本把词改成别的词的行对不上记录 ⇒ 照钳(切走又切回同一个词的除外,见上)。
|
|
64
|
+
|
|
65
|
+
5. **🔴 审批只有一个帧族 `approval_request`;旧族 `tool_approval` / `tool_approval_complete` 与总开关 `STREAM_APPROVAL_ENABLED` 退役(BREAKING;行为变更;部署动作:删掉这一键)**:
|
|
66
|
+
旧形:呈卡协议上场的腿发呈卡族,不上场的腿(无 store backend / 无 park 设施 / `STREAM_APPROVAL_ENABLED=false`)发旧族活卡;没有确认落盘身份的问在旧族腿上照样呈活卡;能力位 `approvalFrameFamilies` 取 `["approval_request"]` / `["tool_approval"]` / `[]`。
|
|
67
|
+
新形:只有呈卡族。一条腿呈卡 ⇔ 这台 worker 呈卡(审批席 ∧ store backend ∧ park 设施)∧ 没关窗 ∧ 这条 run 声明了 `approval_request`;worker 级三项(审批席 ∧ store backend ∧ park 设施)任一不成立 ⇒ 起服不装审批席:没有卡、没有活登记;受门调用的终局归引擎(开关关而有 park 设施 ⇒ 照常 durable park;开关开而无 store backend / 无 park 设施 ⇒ 引擎的无审批席臂当场拒);`/v1/capabilities` 的 `toolApproval` / `streamApproval` / `approvalsStreamLive` 三位为 `false`,有问行的卡的决断口与按问读口答 `501 feature.approval_ask_disabled`;worker 呈卡而这条腿关窗或没声明 ⇒ 这条腿没有活审批通道,每只问当场交 `UNATTENDED_APPROVAL_POLICY`。每张卡先落一行 ask 账再呈;没有确认落盘身份的问不呈卡、不登记(`arm: no_row_no_presenter`)。能力位 `approvalFrameFamilies` 取 `["approval_request"]` / `[]`。
|
|
68
|
+
看得见的边(如实):① 审批席开着而没有 park 设施的部署(多租户缺省 `DURABLE_APPROVAL` 关;env-only worker 没有 store backend)此前呈旧族活卡、人能批,本版起不装审批席:没有卡,受门调用由引擎的无审批席臂拒(`UNATTENDED_APPROVAL_POLICY` 在这里不起作用,运维日志不再有 `approver_unavailable`,起服 warn `approval_cards_unavailable`),能力位 `toolApproval` 从 `true` 变 `false`,审批卡的两扇口从 `404` 变 `501` —— 出路 = 在 store backend 上设 `DURABLE_APPROVAL=true`;把 `toolApproval` 读作「装了审批代码」的端改读 `approvalFrameFamilies`(`["approval_request"]` ⇔ 这台 worker 呈卡);② 请求声明里带 `"tool_approval"` ⇒ `400 request.field_invalid`(`bad_entry`);升级前已停驻、存体声明里带它的 run 续跑时整只声明按不合法读 ⇒ 那条腿不呈卡(park 政策下照常停驻,经 `POST /v1/approvals/:sessionId/decide` 可决)—— 出路 = 升级前决掉这些停驻,或续跑后由新提交重来;③ 账本里更早版本写下的旧族帧行回放时原样交出,本版不再写;④ 关过总开关、带 store backend 与 park 设施的部署删掉那一键之后走有账形:没有任何活流的 park 政策问先在行上挂到 `UNREACHED_ASK_TTL_MS` 窗满再停(此前当场停驻)。
|
|
69
|
+
**升级前做**:① 部署 env 里删掉 `STREAM_APPROVAL_ENABLED`(任何值都拒启 —— 本版提货的 settings-schema 26.0.0 带这一行墓碑,见第 32 条;它的「关」已经没有可回退的族);② 审批席开着的部署核 `DURABLE_APPROVAL` 与 store backend(没有 ⇒ 本版起没有审批卡);③ 壳 / SDK 只渲呈卡族、请求声明只写 `approval_request`(或照能力位声明)。**回滚**(本版 → 7.151.x):旧族与总开关回来;本版没有持久面改动。
|
|
70
|
+
|
|
71
|
+
6. **🔴 有问行的审批卡只有一对同根的口:决 `POST /v1/tasks/:taskId/asks/:askId/decision`、读 `GET /v1/tasks/:taskId/asks/:askId`;活卡应答口 `POST /v1/tool-approvals/:id/respond` 与按问读口 `GET /v1/tool-approvals/:id` 已删;决断口收 `remember:"session"` / `persistRule` / `readRootGrant`;运维队列行带 `askId`(BREAKING;部署零动作,消费方动作)**:
|
|
72
|
+
旧形(7.151.x 及以前):活卡两扇人决口 —— 应答口按 `approvalId` 收 `allow` / `allow_session` / `deny`(三个 live 手势只有它说得出),决断口按 `(taskId, askId)` 收 `approve` / `deny`(三键答 `400 request.body_shape`);读口 `GET /v1/tool-approvals/:id`,已决态说 `allow` / `deny`;队列行上没有问的身份。
|
|
73
|
+
新形:一张卡一只身份、同根两扇口;旧两路径答路由表的通用 `404 not_found.route`(决议不落、卡仍待决)。对照(逐行):
|
|
74
|
+
| 旧 | 新 |
|
|
75
|
+
|---|---|
|
|
76
|
+
| `POST /v1/tool-approvals/<approvalId>/respond` | `POST /v1/tasks/<taskId>/asks/<askId>/decision`(`askId` / `taskId` 取呈卡帧上的那两格;`livePending[]` 行上在内嵌帧 `frame.askId` / `frame.taskId`,行顶层没有这两键,`askId` 与行顶层 `approvalId` 同值) |
|
|
77
|
+
| `{"decision":"allow"}` | `{"decision":"approve"}` |
|
|
78
|
+
| `{"decision":"allow_session"}` | `{"decision":"approve","remember":"session"}` |
|
|
79
|
+
| `{"decision":"deny"}` / `note` / `updatedInput` / `persistRule` / `readRootGrant` | 原样 |
|
|
80
|
+
| 已决卡再应答 `200 idempotent:true` | 带同一 `idempotencyKey` ⇒ `200` 回放首决;不带 / 换键 ⇒ `409 conflict.ask_decided` 回显首决 |
|
|
81
|
+
| 别的副本上的属主作答 `404 tool_approval.not_pending` | `200`(决断口写行,不按副本分) |
|
|
82
|
+
| 已撤的卡 `404 tool_approval.not_pending` + `cause` | `410 gone.ask` + `cause` |
|
|
83
|
+
| 店读不出行 `404` | `500 internal.error`(可重试) |
|
|
84
|
+
| 转 park 中的行 `202 parking_in_progress` | `425 parking.ask_retry` + `Retry-After` 头(这一次决议没有被受理,等头里的秒数后重发) |
|
|
85
|
+
| `GET /v1/tool-approvals/<approvalId>` | `GET /v1/tasks/<taskId>/asks/<askId>`(体形不变;已决态 `decision` 说 `approve` / `deny`) |
|
|
86
|
+
| 呈卡协议不上场 `501 feature.tool_approval_disabled` | 两扇口 `501 feature.approval_ask_disabled` |
|
|
87
|
+
回执:带 `remember` ⇒ `rememberApplied`(落没落);带 `persistRule` 的首决 ⇒ 规则位五键;回放不带两者。队列上有问行的停驻卡带 `askId`,决它的路径 = `/v1/tasks/<taskId>/asks/<askId>/decision`。
|
|
88
|
+
看不见的边(如实):决定打在不持有那条引擎腿的副本上时,`remember` 答 `rememberApplied:false`(进程内放行只记得在持有它的副本上),`readRootGrant` 交不到(回执的 `consumerState` 已说本副本没有消费者);规则位任一副本都兑得了。同一根上读口与决断口在店读不出行时答得不同:读口 `404 not_found.ask`(看不见),决断口 `500 internal.error`。
|
|
89
|
+
运维与两个 live 词:决断口的门对运维开放 ⇒ 运维可以在别人的**活卡**上带 `remember: "session"` / `persistRule`(7.151.x 上活卡的这两个词只有应答口说得出、应答口只认卡的属主;运维能带 `remember` 的只有卡停驻之后的 `POST /v1/approvals/:sessionId/decide`);本副本的会话放行按卡的属主落键,常驻规则的记录读卡的属主,部署名单上的工具在会话放行店里记作决的那位主体为 `grantedBy`。 读根授权 `readRootGrant`(能力位 `approvalReadRootGrant` 可用、`decision: "approve"` 且没带 `remember` 时收)同此:此前只有应答口收、只认卡的属主,现在运维也能在别人的活卡上带。
|
|
90
|
+
**升级前做**:壳 / SDK / 转发路由按上表换路径与词(锁步 SDK 同版)。**回滚**(本版 → 7.151.x):两条旧路径回来,三键回到 400,队列行少 `askId`;本版没有持久面改动,已落的规则可 `DELETE /v1/rules` 撤。
|
|
91
|
+
|
|
92
|
+
7. **排空专用的服务主体:新键 `OPERATOR_DRAIN_PRINCIPALS`(名册的排空档)—— 名单里的验过主体只能调 `POST /v1/admin/drain`,在其余每条路由上整次请求 403 `auth.principal_confined`(安全轴,最小权力;行为加性:只在写了新键的部署上变;wire 加性:一只配置键、一个 403 码;设备 hello 的 `auth_failed` 多一个原因(不加词、不升协议修订号);两条新拒启;零 DDL)**:
|
|
93
|
+
旧形:能调排空口的只有运维名单 `OPERATOR_PRINCIPALS` 里的主体(或单用户声明 `OPERATOR_SINGLE_USER=true` 下的每个调用方);给一位服务主体排空的权力,就要把它写进运维名单 —— 它随之持有每一只运维面(审批队列、记忆治理、配置刷新、收编……),并且仍是一位普通身份(可以提交任务、建会话)。
|
|
94
|
+
新形:运维名册分两档,读法只有一只:`OPERATOR_PRINCIPALS` = 全运维档(持每一只运维权力,排空在内;语义不变);`OPERATOR_DRAIN_PRINCIPALS` = 排空档(只持排空一权,不是人)。排空档里的主体:调 `POST /v1/admin/drain` 与运维同一道门(身份四元比对、幂等回执不变);**在其余每条路由上**整次请求 403 `auth.principal_confined` —— 先于门前读路、全局凭据门、写门与就绪 503、路由与 405 / 404,三种身份来源(登记中心登录令牌 / 直连门签名 principal 令牌 / 受信前端的主体头)同判;直连门决定口上**决定证明推出的决定者**在排空档里同答本码(零状态变化);`GET /health` 不拒,这只身份不算读路凭据(配了 service 凭据的部署上只拿匿名档的四键)。排空口的 501 只在两档名单都空且没有单用户声明时答,拒句多一条出路;名册外调用方的 403 `auth.operator_only` 码不变,句子改为点名两档名单。`/health.operator` 仍只答全运维档在不在(只有排空档的部署答 `absent`)。设备车道同判:排空档主体名下登记过的设备在 `GET /v1/device/ws` 的 hello 被拒 `helloReject: auth_failed`(见下「设备车道」)。排空档不算运维声明:单用户部署只写它 ⇒ 照旧按「必须声明谁是运维」拒启。
|
|
95
|
+
**新拒启两条**:名册不良构 ⇒ 拒启(不变量 `operator-roster-well-formed`:同一个名字同在 `OPERATOR_PRINCIPALS` 与 `OPERATOR_DRAIN_PRINCIPALS`,或 `OPERATOR_DRAIN_PRINCIPALS` 列了不是主体名的条目 —— 空白 / 不可见字符 / 保留标识 / 超长;拒句点名 env 与条数、不回显名字;嵌入方装配路由时同判,另拒「名单不是名字列表」);`OPERATOR_SINGLE_USER=true` 与 `OPERATOR_DRAIN_PRINCIPALS` 同写 ⇒ 拒启(不变量 `operator-single-user` 的又一形)。只有主动写新键的部署撞得到。
|
|
96
|
+
谁需要:中心对受管引擎直调排空(签一枚短时登录令牌给它的服务主体,只为调排空口);多租运维把「排空」交给自动化而不交出其余运维面。**谁受伤**:① 没写新键的部署 —— 零;② 把一个名字从 `OPERATOR_PRINCIPALS` 挪进新键的部署 —— 这个名字失去其余全部运维面与一切普通身份面(本意);它挪档前以人身份建下的行留在库里,经 HTTP 再也够不着;它名下已登记的设备重启后连不上(`auth_failed`,拒的原因进运维日志 `device_hello_owner_confined`:设备 id + 档名,不回显主体名)—— 这是期望;③ 同时写了单用户声明与新键的部署 ⇒ 拒启。
|
|
97
|
+
补偿:新键缺席 = 今天;想让它回到全运维,把名字挪回 `OPERATOR_PRINCIPALS`;只想让它名下的设备继续连,把名字从排空名册移除或换一个不在排空名册里的主体(重启后设备自己连上,执行器不必重新入籍)。
|
|
98
|
+
**看不见的边(如实)**:① 圈禁是**引擎侧**的事实 —— 一台信同一签发方、却**没把这个名字写进** `OPERATOR_DRAIN_PRINCIPALS` 的引擎(手接的个人引擎、漏渲染的受管引擎、把名字从名单删掉之后)把同一枚令牌读成一位普通身份(可提交任务);「截获者最多只能调排空口」只在声明了它的引擎上成立。缓解:签发方不把这个主体名发给任何真人;按目标引擎签 `aud` 并给引擎配 `AUTH_BRIDGE_AUDIENCE`(配了它的引擎之间截获的令牌只在签给的那一台上有用);撤掉这位服务主体时**先停签令牌、等已签的过期,再从名单删名字**。② 中心若用同一枚令牌读 `/health`,圈禁之后只读到匿名档四键(`status` / `auth` / `operator` / `center`)—— 要 `instanceId` 等全键,改读心跳或带 service 凭据。③ 排空口本身的语义不变:不查服务租约围栏,期限已过也照收(进入即到期 ⇒ 立即走向硬停)。④ 没有身份边界的部署(dev-open)上主体头谁都能自报 —— 自报成排空档的名字只会把自己圈禁,与 `OPERATOR_PRINCIPALS` 今天同形。 ⑤ 设备车道(不再是看不见的边,按现态判):设备凭设备密钥对握手、不经 HTTP,按设备行的**属主**绑定 —— 一个名字被挪进排空档之后,它名下已登记的设备在每一次 hello 被拒:`helloReject: auth_failed`(既有拒因词的又一个原因;拒因闭集与协议修订号不变;位置在验签与吊销之后、单活连判与夺租之前 —— 被拒的 hello 不顶替旧连接、不动租约;没有私钥的人问不出这一条),判的是同一只圈禁判官读设备行属主,名册读现态、不把登记时的档位记在行里。名册只来自 env、起服冻结,所以生效点是**重启之后**:滚动换版的窗里,尚未换版的副本上已连着的设备照连到那一副本换版为止。执行器对 `auth_failed` 指数退避、不删钥匙;名字回到 `OPERATOR_PRINCIPALS` 或被移出排空档的那次重启后设备自己连上。排空档主体登记新设备(签发令牌与注册两口)本就在 HTTP 圈禁射程内,403 `auth.principal_confined`。挪档前注销这些设备仍然建议(吊销是终态,库里不留永远被拒的行),不再是唯一防线;它挪档前建下的会话与停驻行仍由内部续跑腿按普通属主续(无运维位),落在这些设备上的执行因设备不在线被拒(设备车道既有词 `device.offline`)。
|
|
99
|
+
**回滚**(本版 → 7.151.x):旧版不认这只键(未知键不拒、不读)⇒ 名单里的主体回到一位普通身份(不再能排空,也不再被圈禁)。回滚前先把要保留排空权的名字挪回 `OPERATOR_PRINCIPALS`,或停用那位服务主体。
|
|
100
|
+
|
|
101
|
+
8. **同机附着方改走本机控制 socket 读身份:local 后端的数据根下多一只 `control/engine.sock`,经它到达的 `/health` 读者拿全键;`listening` 启动行多两键 `controlSocket` / `controlSocketUnavailable`(行为加性;wire 加性;零新码;部署零动作,消费方动作)**:
|
|
102
|
+
本版起,`DB_BACKEND=local`(本进程持数据根锁)的引擎在 TCP 监听之后多开一只本机监听口 `<数据根的物理路径>/control/engine.sock`(unix socket;`control/` 0700、属主 = 引擎的 OS 用户)。
|
|
103
|
+
配了服务凭据的引擎上,经它到达、没出示凭据的 `/health` 读者拿全键(`pid` / `startedAt` / `instanceId` / `version` / `dataRoot` …;`port` 缺席);TCP 上的读法逐字不变(匿名读者只拿 `status` / `auth` / `operator` / `center`,对端是回环也一样)。
|
|
104
|
+
这只口**不是凭据**:配了服务凭据的引擎上,经它不带凭据的写、审批、只读三族照旧 `401`(与 TCP 同码)。开不了(Windows / 非 local 后端 / 路径超过平台上限 / `control/` 不私有 / 路径上有别的文件 / 绑失败)不拒启,`listening` 行带 `controlSocketUnavailable` 原因词;开了带 `controlSocket` 绝对路径,两键恰一只。
|
|
105
|
+
**消费方动作**(壳 / 桌面宿主):连之前核 `<数据根>/control` 是目录不是符号链接、属主是你、没有组 / 他人位,`engine.sock` 是 socket、属主是你;经 socket 读 `GET /health`,照样与你记下的锚点比 `pid` + `startedAt` + `instanceId`;带凭据的调用发在同一只 socket 上,不拿 socket 的判决去放行 TCP 上的凭据出示。
|
|
106
|
+
`listening` 行带 `controlSocketUnavailable` 时走原来的 TCP 归属证明(独占 `127.0.0.1` 的 `boundAddress` + `port` + `instanceId`),证不出就不出示凭据。读法全文在 USAGE「同机附着方怎么读身份」。
|
|
107
|
+
**部署侧**:不要代理或转发这只 socket(经它进来的读者按引擎的 OS 用户看待);数据根及其上级目录不可被别的 OS 用户写、不被 ACL 放宽;反代拨引擎精确绑定的那只地址。
|
|
108
|
+
**谁需要**:同机附着的壳与桌面宿主(日志被清之后照样读到身份)、带凭据的同机读者(凭据不发在共享绑址的 TCP 口上)。**谁受伤**:没有;拿不到 socket 的主机照旧走 `listening` 行;按 `listening` 行整行逐字节匹配的脚本多一键。
|
|
109
|
+
**补偿**:缺席响亮(原因词);零旋钮。回滚:回到 7.151.x 即无这只口(数据根下留着的 `control/` 目录无害,可删)。
|
|
110
|
+
|
|
111
|
+
9. **k8s 车道声明而集群 API 凭据缺 ⇒ 起服拒(一句拒 + 两条出路);起服之后凭据失效 ⇒ run `failed` 带 `env.sandbox_refused`(安全轴 fail-closed;行为变更;wire 零新键、零新码;部署零动作,除非凭据本来就缺)**:
|
|
112
|
+
旧形:`REMOTE_EXEC=k8s` 而没有控制面凭据 ⇒ 服务照常起,起服日志只有出网自检的一行 `sandbox_egress_policy_gap{kind: unreadable}`,之后每条 Bash 答 `shell_unavailable`、run `completed`;令牌在起服之后吊销 / 过期是同一形(pod 创建被 401 拒)。
|
|
113
|
+
新形:① 判官 `resolveK8sApiAccess`(显式 `K8S_API_URL` / `K8S_TOKEN` / `K8S_CA_CERT_B64`〔或实验室 `K8S_INSECURE_TLS=true`〕优先、in-cluster 服务账号补缺,逐件判)说缺 ⇒ **起服拒**,标题 `[config.k8s_api_credentials_missing]`,句点名「REMOTE_EXEC=k8s 需要集群 API 凭据」、缺的是地址 / 令牌 / CA 哪一件;② 每条 run 铸环境之前再读一次(判官,加一次 SelfSubjectAccessReview):缺或被集群答 HTTP 401 ⇒ run `failed`、码 `env.sandbox_refused`、模型零调用、零 pod(同步腿 409);只有正面证据才拒 —— 探问没答、403、5xx 都不拦,车道自己的连接照常答(每次计入 fail-open 登记 `server.sandbox-credentials.probe-unanswered`)。空 / 只含空白的一件按缺。
|
|
114
|
+
**谁需要**:`REMOTE_EXEC=k8s` 的部署。**谁受伤**:本来就没有可用凭据、靠「服务起着只是沙箱命令都失败」运转的误配部署 —— 升级后起不来(期望);按 run `completed` + 工具结果 `shell_unavailable` 认「集群不通」的告警,在令牌失效那一形上改读 run 终局码(同步腿 `errorCode` / 终局 `terminal.code` = `env.sandbox_refused`,409)。**补偿 / 出路**:拒句两条 —— ① 给凭据:`K8S_API_URL` + `K8S_TOKEN` + `K8S_CA_CERT_B64`(实验室 `K8S_INSECURE_TLS=true`),或把服务放进挂着服务账号的 pod;② 改车道:`REMOTE_EXEC=none` 或别的车道。不加旋钮。
|
|
115
|
+
**升级前做**:`REMOTE_EXEC=k8s` 的部署确认上面三件(或服务账号)在进程里读得到;起服拒句会逐字点名缺的那一件。**回滚**(本版 → 7.151.x):无数据面改动,回滚即回到「照常起服」的旧形。
|
|
116
|
+
|
|
117
|
+
10. **host 车道临时工作区的删除改在删前那一拍判「此刻谁的工作目录在里面」,判不出就不删;路径「在不在盘」判不出时不再当成「还不存在」(行为修复;wire 零变化;部署零动作)**:
|
|
118
|
+
射程:`REMOTE_EXEC=host` 的部署,不带 `cwd` 的任务铸的临时工作区(`<HOST_WORKSPACE_BASE>/sema-host-<id>-<rand>`);以及起服时记忆根 / 配置根 / 存储取证三处路径判、host 车道铸委派子代 / 带 `cwd` 任务的执行环境那一判。
|
|
119
|
+
旧形:委派子代的工作目录落没落在父的临时根里,只在铸子代环境那一拍判一次;那一拍途经的符号链接悬空或之后才建,子代就被当成调用方自有目录,父收场时删掉根(连同子代写下的文件)。路径上没有搜索权限 / 成环的段被当成「还不存在」。判完到删完之间才进来的执行环境写下的文件随根一并被删。
|
|
120
|
+
新形:最后一只持有者放手时按文件系统当下的答案再判一次;工作目录在根里、还没离场的执行环境接过删除,最后离场的删;判不出 ⇒ 不删(stderr 一行 `kept <根> instead of removing it`),留给进程退出;删时先在同目录改名成一只隐藏墓名(`.sema-host-…removing-…`)再删,判完之后才进来的执行环境写在原路径上新建的目录里。判不出的段不再当成不存在:起服那三处判改报各自的「查不了」行(`memory_engine_dir_check_unavailable` / `sema_config_root_workspace_check_unavailable` / 取证 `path_unresolvable`),host 车道铸带工作目录的腿时,与同一服务里被持有的临时根按表序比(比到包含它的那一只为止;没有被持有的临时根就不比)的途中判不出 ⇒ 这条腿不铸、run 失败。
|
|
121
|
+
**谁需要**:host 车道上委派子代、子代工作目录经符号链接落进父的临时根的部署。**谁受伤**:临时根可能比旧版晚删(等最后一只在里面的执行环境离场;停驻中被取消 / 过期而没被销毁、或判不出时留到进程退出);调用方自有目录经链接落进别人临时根的执行环境接过那只根的删除,它在根里的残余后台输出镜像从此被拒;按 `ls -a <HOST_WORKSPACE_BASE>` 数目录的脚本会短暂看见隐藏墓名;按「记忆根在数据根之外」那一行做告警的运维,在路径有权限受限 / 成环段时改收到「查不了」那一行;带工作目录的新任务在比的途中撞上判不出的一段(它自己的工作目录,或排在前面的某只被持有的临时根 —— 上级目录被收走搜索权限、或被换成成环链接)时铸不出执行环境、run 失败,直到那一段恢复可读或那只根的持有者收场。
|
|
122
|
+
**升级前做**:无。**回滚**:回到上一版即回到「只在铸时判、判不出当不存在」;无存储形变化。
|
|
123
|
+
|
|
124
|
+
11. **对象存储:引擎对 S3 / MinIO 做的全部请求有了一张随包机读表 `@sema-agent/server/object-store-buckets`;k8s 工作区快照桶的起服探针改列适配器写入的那只前缀(加性;探针前缀一处订正;wire 零变更;部署零动作)**:
|
|
125
|
+
表(`OBJECT_STORE_ACTIONS`)一行一个请求:桶旋钮 × key 形 × S3 动作 × 执行方(server 进程 / 只持预签名 URL 的执行沙箱 / 拿链接的用户端)× URL 有效期;`OBJECT_STORE_ACTION_PERMISSIONS` 给每个动作要的 S3 权限,`objectKeyGlob` 把 key 形按部署的前缀值写成策略资源。按桶的最小权限清单就从这张表生成(`OBJECT_STORE_ACTION_PERMISSIONS` × `objectKeyGlob`;部署前置清单「对象存储桶」一节是同一张表的渲染,内部记录)—— 想不再给引擎 MinIO root 钥、改发每引擎服务账号的部署,策略照这张表给;`MINIO_BUCKET`(leader diff-out)的两行在表里,缺省与工作区快照桶同名。
|
|
126
|
+
起服探桶:`WORKSPACE_SNAPSHOT_PREFIX` 未设时工作区快照桶的探针由列 `blobs/` 改列 `kata/`,设了时由列 `<前缀>` 改列 `<前缀>/` —— 与适配器签 key 同一读。全权凭据下答复不变;按前缀授 `s3:ListBucket` 的凭据下,修前探针 403、读成「证明不了」、走兜底口照常起服,修后与适配器同答。会话快照桶的探针仍列 `SESSION_SNAPSHOT_PREFIX`(缺省 `blobs/`)。
|
|
127
|
+
URL 有效期:`WORKSPACE_SNAPSHOT_TTL_SEC=0` 读作未设 —— k8s 快照的对象 URL 由「签成即刻过期」(那条车道本来存不了、取不回快照)改为缺省 600 s,列举 URL 照旧 600 s;其余配置下每个请求的有效期逐值不变。
|
|
128
|
+
谁需要:按最小权限发对象存储凭据的多租户 / 中心部署。谁受伤:无(请求的 URL、桶、key、有效期在任何可用配置下逐字节不变)。补偿:不需要。**升级前做**:无。**回滚**:回到上一版即回到旧的探针前缀;表与子路径随之不在。
|
|
129
|
+
**圈得住多少**(如实):按引擎发的策略只隔开 key 以每引擎前缀开头的行(`objectStoreRowEngineSlot(row)` 答那只槽);SendUserFile 三轨与 leader 补丁共 15 行按引擎圈不住 —— 共桶的引擎共用这些对象,要隔开只能各用各的桶。共用会话快照桶的引擎必须各设各的 `SESSION_SNAPSHOT_PREFIX`(第 25 条:同桶同前缀的第二只库起服即拒)。
|
|
130
|
+
|
|
131
|
+
12. **部署脚本与模板不再替部署选「几个人用」:`sema-up` 的 `--users` 必填(`kube-up.sh` / `cluster-up.sh` 单独跑时是环境变量 `USERS`),缺 ⇒ 拒并给 `--users=single` / `--users=multi` 两条出路;租户词翻译成闭集;机器清单模板不再带活的 `users:` 行(部署面 BREAKING;安全轴收紧;零服务端代码、零 wire;存量部署重跑零动作,起新部署的脚本升级前补一个词)**:
|
|
132
|
+
旧形(≤ 7.151.x):`sema-up --users` 缺省 `single`,`kube-up.sh` / `cluster-up.sh` 的 `USERS` 缺省 `single`,`machines.example.yaml` 里 `users: single` 是写好的活行,租户词翻译把任何认不出的词(含空串)都当单人 —— 没表过态的部署被写上 `OPERATOR_SINGLE_USER=true`(每个调用方都是运维)与 `REQUIRE_PRINCIPAL=false`。服务端拒句里「不止一个人调用 ⇒ 设 `REQUIRE_PRINCIPAL=true`」那一道人判,对用脚本的人永远不出现(MIGRATION 7.147.0 节第 3 条「谁受伤」③ 的形;随包 helm 图表那一层已在 7.151.0 收):用模板起团队集群又忘设人数的部署,起来之后人人是运维。
|
|
133
|
+
新形:「几个人用」是部署自己的声明,脚本不替它选(缺省 `multi` 同样不取:那是替单人部署开身份隔离)。取值来源只有:显式旗(`--users` / `-f` 配置里的 `USERS` / `machines.yaml` 写了的 `users:` / 单独跑时的环境变量 `USERS`)· 这台部署上一次落在 `.env` 的事实 `REQUIRE_PRINCIPAL`(`false` ⇒ single、`true` ⇒ multi;不带旗重跑沿用)· 向导里人答的那一句;都没有 ⇒ 非零退出,拒句点名「几个人用是这台部署自己的声明」,下一步两条出路:`--users=single`(只给一个人用:每个调用方都是它的运维,身份隔离关)· `--users=multi`(被不止一个人调用:身份隔离开,运维由具名名单 `OPERATOR_PRINCIPALS` 另给)。判在写 `.env`、起容器、动集群、发起 `ssh` 之前(不写 `.env`、零 `ssh` / `kubectl` / `helm`;`sema-up` 的空状态目录 `~/.sema-up/<project>` 先于这一判建出,里面没有 `.env`);拒句只在 `lib/flagshape.sh` 一处生成,三只脚本同调。向导里这一问没有缺省(`--interactive=json` 的 `users` 问句 `default` 由 `"single"` 变空串;有上一次的事实时 `default` 是事实词),空答即拒并列两词。显式旗与事实不一致仍拒并点名两处(原有规则不变)。`data-center` 档不装 agent,没有声明可言:不问、不拒。租户词 → `REQUIRE_PRINCIPAL` / `OPERATOR_SINGLE_USER` 的两只翻译只认 `single` / `multi`,别的词(含空串)⇒ 非零、零输出。`machines.example.yaml` 的 `users:` 成了注释行(复制模板不等于表了态)。同一个词渲出的 `.env` / values / 清单逐字同上一版。
|
|
134
|
+
谁需要:用模板 / 脚本起团队集群又忘设人数的部署。谁受伤:靠缺省 `single` 起单人部署的自动化 —— CI 里的 `sema-up -f site.env --yes`、`sema cloud deploy --yes`(壳在没有 `--users` 时透传不带它)、手写的 `kube-up.sh` / `cluster-up.sh` 调用、从旧 `machines.example.yaml` 复制来的清单:升级后**首装**被拒,补一个词即回到原状;已装部署零影响(`.env` 里的事实沿用)。补偿:拒句即出路(两条,各带一句释义);重跑沿用 `.env` 事实;本条升级前自查一行。
|
|
135
|
+
**升级前做**(只对起新部署的脚本):在命令行 / `-f` 配置 / 机器清单 / CI 环境里写下 `--users=single`(或 `USERS=single` / `users: single`)或 `--users=multi`;已装部署不必动 —— 重跑 `sema-up`(不带旗)沿用 `.env` 里的 `REQUIRE_PRINCIPAL`。换一台部署的人数仍走原有规则:先确认身份隔离的影响,再清 `.env` 里那一行。
|
|
136
|
+
**回滚**(本版 → 7.151.x):脚本回到缺省 `single`(旧版照旧静默按单人装);`.env` 键值同形、无数据面改动,回滚后不必做任何迁移。
|
|
137
|
+
|
|
138
|
+
13. **勘误:`GET /v1/approvals` 的停驻行自 7.143.0 起并不带 `sourceSessionId`;停驻行的出处键随引擎持久归属位的版本补(文字订正;零行为变更;wire 零变化;零 DDL;部署零动作)**:
|
|
139
|
+
— **勘误**:7.143.0 节第 18 条(「审批卡的委派子代出处键 `sourceTaskId` 改名 `sourceSessionId`」)的「此前 / 本版」把 `GET /v1/approvals` 的**停驻行**列进了带这一键的载体 —— 那一半从没成立过:运维队列的停驻行在 7.142.x、7.143.0 到 7.151.0 一直不带它,
|
|
140
|
+
改名只对活的 `tool_approval` / `approval_request` 帧、卡片 JSON 与 `livePending` 行内嵌的帧成立(`livePending` 行顶层带 `fromSubagent` 与同值的 `originTaskId`;该顶层键本版也改名 `sourceSessionId`,见第 21 条)。已发节字节不动,勘误写在这里。
|
|
141
|
+
— **现状**:同步 / workflow 委派子代的卡停驻之后,`pending[]` 行与 `/v1/approvals/stream` 的 `pending` 帧上没有 `fromSubagent` / `sourceSessionId` / `agentId`(同一张卡的活卡帧有);能读出归属的只有 placed 后台委派子代(行上的 `agent`、`taskId` = 句柄)。
|
|
142
|
+
**这三键是否上行随引擎版本**:引擎只在停驻行上持久「这是委派腿」与发起会话,不持久活卡帧上 `fromSubagent` 的判据与脚本声明的腿 task id,三键各有一形与活卡帧不等,本服务不替引擎造判别位;引擎把归属位与腿 task id 记进检查点之后,三键同拍上行(加性)。
|
|
143
|
+
**谁需要**:按第 18 条文字在停驻行上找 `sourceSessionId` 的消费方(收件箱 / 运维界面)。**谁受伤**:无(行为零变化)。**补偿**:不需要;子代归属读 `agent` / `taskId`,读不出就是读不出(缺席 = 这台 server 没有说,不是「不是子代」)。**升级前做**:无。**回滚**:无关(无存储形变化)。
|
|
144
|
+
|
|
145
|
+
14. **补记 7.148.0 节漏记的一条行为变化:非流式 `POST /v1/tasks` 跑完之后,这条提示词也落回退锚 —— `GET /v1/sessions/:id` 里那条用户消息行带 `taskId`(= 那次 200 体里的 `taskId`),拿它 `resumeAt` 回得去(文字补记;行为变化本身自 7.148.0 起在;wire 零新键、零新码;部署零动作;已发的 7.148.0 节不改字节,本条即补记)**:
|
|
146
|
+
漏记的是什么:7.148.0 节没有这一条。读者因此不知道,从 ≤ 7.147.x 升上来的部署上,同一条提示词走哪条腿提交,读面上有没有 `messages[].taskId`、`resumeAt` 回不回得去,已经变了。
|
|
147
|
+
旧形(≤ 7.147.x):用户消息的回退锚只在流式腿 `POST /v1/tasks/stream`、后台腿 `POST /v1/runs` 与续跑腿写;非流式 `POST /v1/tasks` 从不写 —— 同步提交的 200 体里的 `taskId` 拿去 `resumeAt` 得 `404 resume_at.unknown_event`,会话读面里那条消息行不带 `taskId`。
|
|
148
|
+
新形(7.148.0 起):同步腿不带 `verify` / `cascade` 的提交,把引擎事件喂给与后台腿、续跑腿同一只锚写入器,键 = 那次提交的 durable run id(= 200 体里的 `taskId`),属主 = 提交的已验主体;200 应答发出之前会等这一笔锚写,但**只等有界的一段**(单行店操作期限 2 秒):期限内落定 ⇒ 客户端拿到 200 时锚已在;写失败 ⇒ 200 照发、这一条没有手柄;超期 ⇒ 200 照发、那次写不取消、仍在飞,迟到落定的锚照样可用。后两形都记登记过的 fail-open 计数 `server.resume-anchor.capture-failed`(指标 `fail_open_total{tag="server.resume-anchor.capture-failed"}`)。升级之后的同步提交才有锚,升级前已跑完的不回填;没有 run 店(没有可当手柄的 run id)或没有锚落点席位的部署没有手柄,照旧无锚。**带 `verify` / `cascade` 的同步提交仍没有锚**:这两形走整包 await 的组合腿,不接锚写入器。
|
|
149
|
+
**谁需要**:用非流式 `POST /v1/tasks` 提交、之后要「回到这条提问」的调用方(一发一收形的 SDK / 脚本)。**谁受伤**:每次同步提交多一次有界的锚店单行写(与后台腿同价;锚店挂住时每次锚写至多让 200 晚一个单行店操作期限)。**补偿**:不加旋钮;读 `fail_open_total{tag="server.resume-anchor.capture-failed"}` 判锚写有没有在失败。
|
|
150
|
+
**升级前做**:无。**回滚**:回到 ≤ 7.147.x ⇒ 同步提交不再落锚(消息行不带 `taskId`、`resumeAt` 得 404);无存储形变化(同一张锚店、后台腿本来就写的同一种行)。
|
|
151
|
+
|
|
152
|
+
15. **订正 7.149.0 节第 36 条的「client-core 的对位版本」:`@sema-agent/client-core` ≥ 0.111.0(文字订正;零行为变化;wire 零变化;部署零动作;已发的 7.149.0 节不改字节,本条即订正)**:
|
|
153
|
+
订正对象:第 36 条「升级前做」里写「先确认接入的壳已能按数组形读本位(cli ≥ 1.0.164;client-core 的对位版本)」,client-core 一侧没有给版本号。能力位 `sessionReadRedaction` 由布尔改叶名表(7.148.0 节第 49 条)之后,**client-core 0.111.0 是第一个自带叶名表读口 `sessionReadRedactionOf` 的版本**(它认布尔 `true`、认非空串数组、位缺席 / 空表 / 坏形读作「未确认」);此前的版本(0.98.0 起)包内没有读这一位的读器。经 client-core 读这一位的壳,先升到 ≥ 0.111.0 再升本服务;cli 的下限 1.0.164 不变。
|
|
154
|
+
**谁需要** / **谁受伤** / **出路**:同第 36 条(壳先升、再升本服务)。**升级前做**:确认接入的壳的 client-core ≥ 0.111.0。**回滚**:无存储形变化。
|
|
155
|
+
|
|
156
|
+
16. **勘误 7.151.0 节四处与实现不符的句子:① 第 12 条「此前 `POST /v1/tasks` 答 `200`」② 第 3 条「带 `mcpServers` / `a2aPeers` 决 ⇒ 照旧 `400`」③ 第 16 条列的「请求带的 `cwd`」座 ④ 第 19 / 22 条「到行上的 `deadline`(建行 + 30 天)……收走」(文字订正;零行为变化;wire 零变化;部署零动作;已发的 7.151.0 节不改字节,本条即订正)**:
|
|
157
|
+
① **第 12 条(`cascade` × `rewindFilesTo`)的旧形不是 `200`**:上一版同体的 `POST /v1/tasks`,提交体带的锚是这只会话里真有的那条提问 ⇒ 梯级在引擎现铸的会话里找不到那条文件边界,引擎在准备期拒(零工作的拒,`rewind_snapshot.unresolvable`),同步腿答 `422 rewind_snapshot.unresolvable`,run 行仍写一行(落 `failed`);带的锚不是这只会话里任何一条提问的手柄 ⇒ `404 rewind_files_to.unknown_event`(锚的解析在装配里,各提交口同读);两种都不是 `200`。`POST /v1/runs` 带真锚时旧形答 `202`(异步受理,引擎的拒落在 run 自己的终局里)。**本版起同体一律先在受理口答 `400 request.field_conflict`**,含假锚(此前 `404`)与真锚(`POST /v1/tasks` 此前 `422`)。所以第 12 条正文与「谁受伤」里的「此前 `200` / `202`」读作:`POST /v1/tasks` 此前是 `422`(真锚)/ `404`(假锚),`POST /v1/runs` 此前是 `202`(真锚)/ `404`(假锚);本版统一为 `400`。同一块里黑盒判据 K2 的「上一版:`200`」同改。
|
|
158
|
+
② **第 3 条「带 `mcpServers` / `a2aPeers` 决、记录读作 `running` ⇒ 照旧 `400`」只对一种副本成立**:上一版(7.150.x)这句 `400` 由持有那条 run 的进程里的引擎答(引擎对重述键答「停驻原样保留」);不持有它的副本上,本进程的引擎答「这条 run 不在这里」(`not_active`),决断走续跑车道 —— 答 `200`、起宿主一跑(`taskId` = 宿主新一跑)。本版起答 `400` 的是记录栅栏:记录读作 `running`、仍持有这张卡、请求带重述键 ⇒ **任一副本**都答 `400 decide.parked_restatement_unsupported`,卡留 pending。所以:单副本、以及恰好打在持有副本上的决断,「照旧 `400`」成立(只是不再先探引擎);多副本上打在不持有副本的决断,由 `200` + 宿主一跑**变成** `400`(行为收紧:方向与第 3 条正文的「新形」一致,但不是「照旧」)。出路不变:不带 `mcpServers` / `a2aPeers` 重决。
|
|
159
|
+
③ **第 16 条列的「单用户 host 部署上请求带的 `cwd`」这一座,带 `..` 的形在 HTTP 上够不到**:请求体 `cwd` 在受理口按「主机绝对路径」形判(非空、绝对、无 `..` 段、无 NUL、有长度上限),带 `..` 段的 `cwd` 两版都在门口被拒 `400 request.field_invalid`;拒句只写「cwd must be a non-empty absolute host path」,没有点名 `..`(同一谓词在 `additionalDirectories` 的拒句里写明「no '..' segments」),读起来像「不是绝对路径」。所以对请求 `cwd` 而言,第 16 条「`..` 由文件系统解」没有可观察的变化;`.` 段不被这道形判拦(只拦 `..`),`.` 的读法变化照旧适用。第 16 条射程里不经这道受理门的两座 —— 起服时的 `HOST_WORKSPACE_BASE`、委派给子代的工作目录 —— 才是 `..` 还够得着的座。「升级前做」里「调用方送的 `cwd` 里有没有 `..` / `.` 段」读作:`HOST_WORKSPACE_BASE` 里有没有 `..` / `.`,调用方送的 `cwd` 里有没有 `.`(带 `..` 的 `cwd` 本来就进不了门)。
|
|
160
|
+
④ **第 19 / 22 条里「到行上的 `deadline`(建行 + 30 天)……收走」「到期收走」只对行上带 `deadline` 的行成立**:带 `deadline` 的行 —— 7.150.x 上同步子代问停驻出的那类行(引擎在腿没有耐久授权声明时缺省铸 `deadline` = 建行 + 30 天,第 19 条「存量行」说的就是它们)—— 到期由检查点店的过期收割收走,句子成立。被中心强制耐久门的主体的同步子代卡(第 22 条的已知缺陷)是另一形:同步子代不继承父腿的耐久授权声明,强制门替那条腿合成的声明只带作用域、没有 TTL,引擎铸的行 `deadline` 是 `null`(不论 `APPROVAL_TIMEOUT_SEC` 设成多少),没有 `deadline` 可到;这样的行只靠**终局兜底**收走:`terminal_at_ms` = 建行时刻 + `APPROVAL_TERMINAL_BACKSTOP_MS`(缺省 30 天;下限 60 秒,非有限值落缺省),由检查点店的收割拍逐行判(SQL 后端与 `DB_BACKEND=local` 同一条公式)。(带耐久授权声明的根腿与后台子代腿才会带上 `APPROVAL_TIMEOUT_SEC` 配的 TTL ⇒ 行带 `deadline`。)所以 `deadline` 为 `null` 的卡,存活期 = 终局兜底窗(缺省同为 30 天,但这时它是唯一的收走条件,调长 `APPROVAL_TERMINAL_BACKSTOP_MS` 就调长它们),不是「到期」;对它 decide 仍答 `409 conflict.resume_context_unavailable`、行不消(第 22 条)。
|
|
161
|
+
**谁需要**:按第 12 / 3 / 16 / 19 / 22 条做升级判断与黑盒验收的人(红臂读数以本条为准)。**谁受伤**:无 —— 订正的是四句与实现不符的文字,零行为变化。**补偿 / 出路**:无需动作;② 里多副本上带重述键决 workflow 停驻卡的调用方,在 7.151.0 起收到的 `400` 即「不带 `mcpServers` / `a2aPeers` 重决」的指路。**升级前做**:无。**回滚**:无存储形变化。
|
|
162
|
+
|
|
163
|
+
17. **随包文书补全三处(成文;零行为变化;wire 零变化;部署零动作)—— 各句落在 USAGE 对应节**:
|
|
164
|
+
① **file 记忆控制面账本的形只在开档判一次,运行中被外部写坏本服务不检测**(USAGE「记忆店根搬了家 ⇒ 拒启」条后):起服装配与 `run-local` 装配各在构造 file 记忆后端之前经引擎的只读口问一次账本的形;读不了的形 ⇒ 一行 warn `memory_ledger_malformed`、不拒启;之后不复查、没有定时探测。出路:修好或还原控制面账本后重启(重启即再开档)。
|
|
165
|
+
② **同一把 `Idempotency-Key` 在首发还在跑时重投,回执有两形(按落在哪个进程)**(USAGE 第 1 节「同一把 `Idempotency-Key` 重投」块):落在首发所在的同一进程 ⇒ 等首发落定、拿同一份结局 + `replay: true`(新合流的上界 = 在飞表条目的 15 分钟;已在等的请求没有第二只超时);落在另一副本、服务重启之后、或条目已过 15 分钟 ⇒ 读行,行上还没有结果 ⇒ 立刻 `200` 的轮询回执 `{ taskId, sessionId, status, replay: true }`。
|
|
166
|
+
③ **硬杀(`SIGKILL` / 内存杀手)之后,`REMOTE_EXEC=host` 车道上本服务起的前台命令进程组不被回收**(USAGE 已知限制条):退出边界只在 `exit` 事件会触发的退出上收;被信号默认终止的进程没有机会跑;进程重起后也不接管前代的组。出路与读法见 USAGE 该条。
|
|
167
|
+
这三条是此前随包文书里没有的成文,**不是行为变化**:表里的行为 7.151.0 及更早的版本就是这样。**谁需要**:排障的运维(记忆面 500 / 读到旧数据时判账本形是开档时就不对还是之后才坏;幂等重投短超时的调用方;被 OOM / 硬杀之后机器上留着孤儿命令的 host 部署)。**谁受伤**:无。**升级前做**:无。**回滚**:无。
|
|
168
|
+
|
|
169
|
+
18. **一次性迁移 M13 / M15 / M16 到期移除:盘上 LKG 信封 formatVersion 2 与 3 不再读回(`loadLkg` 答 `unknown formatVersion 2` / `unknown formatVersion 3`);本地 `config.d` 起服不再被迁移改写(迁移前写法的文档由读腿 / 车道合成响亮拒、一个字节不动);持久数据面;行为变更;运维日志 `config_lkg_migrated` 少一个 `receipts` 键、`config.d` 迁移的三行日志没了;wire 零新键、零新码;嵌入方包根导出无变化;部署零动作,除非从 ≤ 7.123.x 直升本版**:
|
|
170
|
+
三条一次性迁移的窗(M13:7.123.0 引入,发布日 2026-10-10 + 30 天,2026-11-09 关;M15 / M16:7.124.0 引入,发布日 2026-10-11 + 30 天,2026-11-10 关)都已关,本版删了它们的码。
|
|
171
|
+
M13(信封 2 → 3):`loadLkg` 读回 2 时的内存迁移(`migrateV2Lkg`:旧载体键 `models.droppedIdentities` 搬成 `models.droppedCatalogEntries`、去掉 etag)与它的两只帮手。M15(信封 3 → 4,载荷换代):读回时过契约包一次性迁移 `migrateEffectiveSnapshot` 的那一段(`migrateLkgPayload`)与读回收据,以及对契约包 `one-time-migrations` 子路径的 import。M16(本地 `config.d`):起服时把读腿会读的那几份文档交给契约的目录迁移改写的那一步 —— 接线文件 `config-d-migration.ts` 整只删、HTTP 服务第 2 段与 `run-local` 的两处调用没了。
|
|
172
|
+
旧形:7.123.x 及以前写下的 LKG(信封 `formatVersion` 2 或 3)读回时在内存里迁成当期形、启动日志 `config_lkg_migrated`(`fromFormat: 2` / `3`,M15 带 `receipts`)、按当期信封写回原位;迁不动的载荷(收据 `refused`)不读回。本地配置源的起服在第一次读 `config.d` 之前改写迁移前写法的文档(`models.atModelAllowlist` / `models.default` → `atMention` / `roles.default`;退役域 `runtime.json` 搬进 `governance.json` / `limits.json` 后删;`remote-exec.json` 的 `apiUrl` 剥掉 `#`;同设两种钥匙的模型条目落成单钥),日志 `config_dir_migrated` / `config_dir_migration_refused` / `config_dir_migration_failed`(这三行里 config.d 迁移的那一份)。
|
|
173
|
+
新形:LKG 的 2 / 3 旧文件**不读回** —— 起服一行 `config_lkg_unusable`(拒因 `unknown formatVersion 2` / `unknown formatVersion 3`),env 兜底;中心可达照拉(没有 etag 可做条件请求,整拉,读腿铸出完整的被丢条目载体,新 LKG 按当期版本覆盖),断着则 env 兜底,下一份干净候选重写;不采纳载荷(版本判在读完文件之后、载荷判形之前)、不迁、不改写文件;没有新的拒。`config_lkg_migrated` 还在(M22 的 4 → 5 一种),不再带 `receipts`。**`config.d` 起服不再被改写**,迁移前写法的文档一个字节不动:`runtime.json` 带事实 ⇒ 读腿对退役域答 `RetiredDomainError`(整份读不出);`models.atModelAllowlist` / `models.default` ⇒ models 域降级、rosters 整份读不出;`remote-exec.json` 的 `apiUrl` 带 `#`(SS-M7)⇒ 车道合成读它时拒启(`run-local` 退 2);同设两种钥匙的模型条目(SS-M5)⇒ 读腿能抢救就逐条丢弃那一条,没有幸存条目时 models 域降级、整份候选被拒回落 env;拒句 / 告警止于今天的位 / 规则本身(本版提货的契约包 26.0.0 删了这几步,不再点名迁移 id,第 32 条 ⑥)—— 出路 = 把事实手写到今天的位,或升级前用上一个契约 major 手跑 `npx @sema-agent/settings-schema@25 migrate <config.d 目录>`(整域判得过才写、原子写;26.0.0 的 `migrate` 不再改写这几形)。`config_dir_migrated` / `config_dir_migration_failed` 两个事件名还在(配置根上的 SS-M11 迁移用,行里带顶层 `migration`)。
|
|
174
|
+
直升下限(逐条):M13 —— 从 ≤ 7.122.x(起始版 7.123.0 之前)直升本版的部署,**须先经过含 M13 的版本**(7.123.0–7.151.x 任一版)起服一次;M15 —— 从 ≤ 7.123.x(起始版 7.124.0 之前)直升,**须先经过含 M15 的版本**(7.124.0–7.151.x 任一版)起服一次;M16 —— 从 ≤ 7.123.x(起始版 7.124.0 之前)直升,**须先经过含 M16 的版本**(7.124.0–7.151.x 任一版)起服一次让那几版把 `config.d` 改成新形,或升级前备份 `config.d` 后手跑上面的命令行。不先经的话:两条 LKG 只丢这份缓存(不丢数据),`config.d` 一条在起服时被读腿 / 车道合成拒、字节不动。从 7.124.0 及以后升级的部署零动作。
|
|
175
|
+
谁需要:无。**谁受伤**:从 ≤ 7.123.x 直升的部署 —— 起服时中心不可达的多一行 `config_lkg_unusable`(这一次从 env 起);**本地配置源(`CONFIG_PROVIDER=local` / `run-local`)而 `config.d` 还是迁移前写法的部署起服被拒或降级**;按 `config_lkg_migrated` 的 `fromFormat: 2` / `3` 或 `receipts` 键、按 `config_dir_migrated`(config.d 那一份)/ `config_dir_migration_refused` / `config_dir_migration_failed`(config.d 那一份)做告警的运维。
|
|
176
|
+
补偿:先经 7.124.0–7.151.x 任一版起服;或升级前备份 `config.d` 后手跑上面那一条 `@25` 的契约命令行;或删掉旧 LKG 文件(缓存、不是数据);中心可达时下一份干净候选写出当期信封。回滚:无新增影响(本版写盘的信封版本与 7.151.x 相同,只是不再读 2 / 3;本版不改写 `config.d`,回滚后的旧版照旧在自己的起服里迁)。
|
|
177
|
+
|
|
178
|
+
19. **运维待批队列行的全部动作事实与续跑执行读同一次整行解码(两后端同一只投影);`checkpoint` 的四只展示拷贝列 `tool_name` / `risk_descriptor` / `rule_suggestions` / `has_bidi_controls` 退役,并进 M54(行为变更;wire 零新键、零新码、零新帧型;一次性迁移同第 1 条那一条,零额外运维动作)**:
|
|
179
|
+
旧形(≤ 7.151.x):SQL 后端的待决队列(`GET /v1/approvals` / `/stream`)读同一张卡用两只 parser、两份存储 —— 工具名 / 绑定两键 / 卡 / 风险描述 / 规则候选 / bidi 位读写入时反范式下来的列,入参与停驻行事实读库引擎内提取的 `pendingAction` 子树,`checkpointId` 与记下的登记行读成员;续跑执行读的是整只文档的一次 `JSON.parse`。带外改过一格列,或 MariaDB 文本承载上原文带重复顶层键(引擎内提取取先到者、`JSON.parse` 取后到者)⇒ 队列显示的不是将执行的那一份。`rowVerdict` 在 SQL 上可缺席。
|
|
180
|
+
新形:**队列行 = 行址 + 动作事实**。行址(会话 / scope / 门型 / 建行时刻 / 截止 / 所属 run 的认领)取决断口找行的那一处(SQL = 列,local = 引擎摘要);动作事实(工具名、调用 id、绑定两键、入参、卡、风险描述、规则候选、bidi 位、停驻行事实、`checkpointId`、记下的登记行、技能卡位、`rowVerdict`)只出自续跑执行读的那一次整行解码,两后端同一只投影;解不出 ⇒ 动作事实 `null` / 缺席、`rowVerdict` 非 `ok`。SQL 主读只出行址与库内对整只文档算的摘要,动作事实按 (文档字节, 引擎构建) 记忆、未命中按令牌批读整行。两次读之间(主读与整行批读之间)行已离开待决 ⇒ **这一拍不列**;两次读之间行的字节变了 ⇒ 这一拍就带批读那一版(= 此刻续跑会执行的那一版)的全部动作事实 ⇒ `rowVerdict` 两后端**恒在**。
|
|
181
|
+
**变了的**:① 本服务写口写下的行每一键的值不变。② 带外改过列或文档的行:队列显示的就是将执行的那一份。③ SQL 上读不成检查点 / 引擎摘要读不动的行与 local 逐键同形:只剩行址与 `rowVerdict`(非 `ok`),`toolName` / `toolCallId` / `input` / `riskDescriptor` 为 `null`,`boundCallId` / `boundInputHash` / `approvalCard` / `ruleOffers` / `hasBidiControls` / 停驻行事实 / 技能卡位 / `checkpointId` 缺席(此前带列与成员上的那几格);收件箱 / 调度视图上这种行的 `checkpointId` 同样缺席。④ 两次读之间离开待决的行本拍不列(此前列出、不带 `rowVerdict`);字节变了的行本拍带批读那一版(此前不带 `rowVerdict`)。⑤ **读放大(如实)**:SQL 副本多持一块投影记忆,上界 **64 MiB**(按投影 JSON 的 UTF-8 字节累计,另 8192 条,先到者挤;常量,不是旋钮;单只放不进上界的投影不记)—— 待决集的投影总量超出时被挤出的行每拍按未命中整行重读(答案不变,只多读库);起服后第一拍把全部待决行整行读一遍(此前也是);命中时主读每行只出行址与 64 字节摘要(此前每拍每条连接把每行的子树文本整份再拉一遍)。⑥ 计数口径:规则候选的脱敏计数与描述读不成 / 候选丢弃的计数在 SQL 上「每份文档字节每进程一次」,local 仍每次列表一次。⑦ 文档门上的风险描述在场却读不成对象 ⇒ `riskDescriptor` 为 `null`、计 `server.approvals.risk-descriptor-cell-unreadable`(两后端同一座);文档里的规则候选读不成列表 ⇒ 键缺席、计 `server.rule-offers.offer-dropped`;`server.approvals.rule-suggestions-cell-unreadable` 随列退役(按 tag 告警的运维把它从规则里删掉)。⑧ 起服列探针不再查 `has_bidi_controls`。
|
|
182
|
+
**谁需要**:带外审批人与按 `GET /v1/approvals` 带答 decide 的运维(看到的就是将执行的那一份);MariaDB 部署与手修过停驻行的运维。**谁受伤**:SQL 副本多持 ≤ 64 MiB 记忆;SQL 上读不动的行在队列上少了列来的工具名等格;回滚要补五列(第 1 条),回滚后本版期间停驻的行在旧版队列上工具名 / 入参 / 描述为 `null`、候选 / bidi 位缺席;按列读这四列的外部脚本 / 报表失去列(值都在 `checkpoint` 列的文档里:工具名与入参在 `pendingAction`,描述在 `gate.riskDescriptor`,候选在 `pendingAction.ruleOffers`,bidi 位在 `pendingAction.hasBidiControls` —— 那是未脱敏的执行记录);两次读之间离开待决的行本拍不列。**出路**:不加旋钮 —— 记忆挤出只换代价不换答案;读不动的行带 `rowVerdict` 说明为什么,修或删那一行;删四列与删 `tool_input` 同一次停光(第 1 条的升级前做与回滚照读)。
|
|
183
|
+
|
|
184
|
+
20. **leader 车道的执行器与其余车道同读部署:按主体的运行期准入、部署治理折叠(`AUTONOMY` / `commandPolicy` / `MANUAL_MODE_SHELL_GATE` / 守卫集)落在 leader 的 worker 首跑与各修复腿上;每一条腿按它的耐久事实取审批基线与停驻设施,部署审批名单管到修复腿与不带停驻设施的 worker(安全轴收紧;行为变更;静态车道的停驻与资源分片与 7.151.x 相同;wire 零新键、零新码;受理拒句改一句;部署零动作,开了 leader 的部署见「升级前做」)**:
|
|
185
|
+
旧形(7.151.x 及以前,`LEADER_ENABLED=true`):leader 的执行器不问按主体的运行期准入 —— 被中心关了 fork、开了强制耐久门的主体,在 worker 腿上「不限」;worker 首跑与修复腿不过部署治理折叠(停驻后的续跑腿才过);模块门修复与单代理修复环不带提交者身份、不带审批基线(三张审批名单管不到这两条修复腿);worker 只在「有停驻店且有任一审批名单」时带停驻设施,不带停驻设施的 worker 也不带任何审批策略(没接停驻店的部署上三张名单管不到 worker);worker 首写续跑上下文失败被吞、停驻设施照挂,停出来的卡决不了。MIGRATION 7.151.0 节第 22 条句尾「leader 车道(`POST /v1/leader`)的执行器本版不在此列」说的就是这一形。
|
|
186
|
+
新形:leader 的每一只执行器与其余车道展开同一层部署键,每一条腿出生时盖提交者身份、过部署治理折叠(与 HTTP 提交 / 续跑腿同一只),并按这条腿的耐久事实盖审批基线与停驻设施:**耐久 ⇔ 出生点递了停驻设施 ∧ 续跑上下文真落进了停驻店**。工厂车道的 worker 首跑:部署接了停驻店即递(名单只决定哪些工具问,不决定能不能停);静态车道(无 MinIO)的 worker:照 7.151.x 的条件递(停驻店 ∧ 任一审批名单在场),停驻设施、资源分片停驻与审批问停驻逐格与 7.151.x 相同;集成修复 / 模块门修复 / 单代理修复环(续接是本 run 内存里的那一轮)恒不耐久。耐久的腿带停驻设施与 durable 审批基线;不耐久的腿带名单门基线、零停驻设施 —— 三张名单照判,无人值守层答不了的问当场拒;续跑上下文写失败的 worker 取不耐久这一形。相对 7.151.x 的净变化:三条修复腿与不带停驻设施的 worker 开始受审批名单管;工厂车道 × 停驻店 × 名单全空的部署上 worker 也带停驻设施;续跑上下文写失败的 worker 不再停出决不了的卡。被强制耐久门的主体:耐久的 worker 第一次写即停驻,leader 任务以 `suspended` 收场,卡在 `/v1/approvals`(工厂车道的卡决得了、决完的续跑不回集成;静态车道的卡见下面已知缺陷);不耐久的腿上不停驻(引擎的无设施读法,见本条末句)。`AUTONOMY=plan` 的受理拒句改句(出路只指 `AUTONOMY=ask`,并写明代价)。**已知缺陷(7.151.x 同形,本版不改)**:静态 e2b 车道 × 停驻店 × 设了审批名单时,worker 的审批问停驻成卡,卡决完的续跑在一只新执行环境上恢复、拿不到 worker 的工作树;引擎提供「宿主声明本腿审批停驻不可续」的声明位后收(同一车道的资源分片停驻不受影响)。要审批停驻可续 ⇒ 配齐 MinIO 三件套走工厂车道。
|
|
187
|
+
**谁需要** / **谁受伤** / **补偿**:同 CHANGELOG 本节同名一条(零新旋钮)。**升级前做**:开了 `LEADER_ENABLED` 的部署盘点 ① 中心上开了强制耐久门 / 关了 fork 的主体 —— 他们的 leader 任务此后在耐久的 worker 上(工厂车道 × 停驻店;静态车道 × 停驻店 × 设了审批名单)第一次写就停驻收场,在不耐久的 worker 上普通写由无人值守层按类放行、答不了的问拒;要多 worker 编排改走 `POST /v1/runs`,或在中心给这个主体放开;② `AUTONOMY` 设成 `read-only` 或 `ask`、`MANUAL_MODE_SHELL_GATE=always` 的部署 —— leader 任务此后在 `read-only` 下产不出改动、在后两者下每条 shell 要人(耐久的 worker 停驻,不耐久的腿拒);③ 有停驻店而三张审批名单全空的部署(工厂车道)—— worker 模型的 AskUserQuestion 此后停驻成卡;③′ 设了审批名单的部署 —— 名单此后也管三条修复腿,没接停驻店时也管 worker(`APPROVAL_REQUIRE` / `APPROVAL_NEVER_AUTO` 命中的调用没人可问 ⇒ 拒);④ 设了守卫集或 `commandPolicy` 的部署 —— 它们此后也管 leader 首跑。强制耐久门的读法归引擎:耐久的 worker 腿上每一问直接停驻;不耐久的腿(没递停驻设施的 worker、续跑上下文没落的 worker、各修复腿)不带停驻设施,按引擎的无设施读法 —— 一条 `config.durable_gate_unavailable` 通告,无人值守层按类答掉的普通写是策略结算的放行(满足强制门),答不了的问拒。**回滚**:回到 7.151.x ⇒ 上面「旧形」。
|
|
188
|
+
|
|
189
|
+
21. **审批列表行顶层的委派子代出处键 `originTaskId` 改名 `sourceSessionId`(wire BREAKING;零别名;值不变;部署零动作)**:
|
|
190
|
+
旧形(7.151.x 及以前):`GET /v1/approvals` 的 `livePending[]` 行、`/v1/approvals/stream` 的 `live_pending` 帧、`GET /v1/tool-approvals/:id`(7.152.0 起已删)的 `pending` 体,对委派子代发起的卡,顶层带 `fromSubagent: true` 与 `originTaskId`(键名说 task,值是子代的会话 id);同一行内嵌的呈卡帧的卡里,同一个值叫 `sourceSessionId`。
|
|
191
|
+
新形:顶层键叫 `sourceSessionId`,值不变,与内嵌帧的卡上的同名键同名同值;`originTaskId` 不再出现(无别名)。`fromSubagent` 判别位不变,新键在场 ⇔ `fromSubagent` 在场;宿主自身发起的卡两键皆缺席。
|
|
192
|
+
本条取代此前「保留不改」的两句:MIGRATION 7.143.0 节第 18 条的「`fromSubagent` 判别位与 `originTaskId` 不变」与本节第 13 条里「`livePending` 行顶层带 `fromSubagent` 与同值的 `originTaskId`」—— 它们描述 7.151.x 及更早的形(已发节字节不动,取代写在这里)。
|
|
193
|
+
看得见的边(如实):读 `originTaskId` 的消费方升级后读到缺席 —— 若把它的在场当作「这是委派子代的卡」,会把子代卡当成宿主自身的卡;判子代读 `fromSubagent`(不变),关联子代行读 `sourceSessionId`。撤卡帧的 `taskId` 是出处 run 的 id,是另一个东西,不改。
|
|
194
|
+
**谁需要**:按子代会话 id 把待决卡关联到子代行的壳与 SDK(同一个值现在只有一个名字)。**谁受伤**:读 `livePending[].originTaskId`(或 `live_pending` 帧、`pending` 体顶层同名键)的壳 / SDK / 控制台。**补偿**:改读 `sourceSessionId`,值不变。
|
|
195
|
+
**升级前做**:无(部署零动作;消费方的读点改名随 SDK 与各壳的版本)。**回滚**(本版 → 7.151.x):旧键回来;本版没有持久面改动。
|
|
196
|
+
|
|
197
|
+
22. **会话头探针 `GET /v1/sessions/:id/head` 带占用两键,ETag 改为 200 体字节的摘要(行为加性;wire 加性;零新码;零 DDL;部署零动作)**:
|
|
198
|
+
体加 `activeTaskId: string | null`(这只会话单活认领此刻的持有者;认领已放 ⇒ `null`)与 `activeTaskStatus?`(`running` / `suspended` / `needs_review`),与 409 `conflict.session_active_run` 体同一只投影(契约 §29);`DB_BACKEND=memory` 上两键都不在(那种部署不记认领)。
|
|
199
|
+
ETag 不再是 `"<leafId>"`,而是 200 体字节的 sha256 base64url:升级后每只会话的第一次探针拿 200,之后照常 304。删除口与 run 外回退口的 409 体多 `activeTaskStatus`;提交面 409 体在「认领于冲突与观察之间放掉」那一形上 `activeTaskId` 是 `null`(此前空串)。探针每次读 run 店(认领;有持有者时再读那条 run 行),读不吞错:接了持久 run 店的部署上 run 店读不出 ⇒ 探针答 `500 internal.error`(7.151.x 探针只读会话店,碰不到 run 店的故障)。
|
|
200
|
+
**谁需要**:重启后的壳 / 桌面与别的设备作过决断之后的端(答「谁占着这只会话」)。**谁受伤**:从 `leafId` 自己拼 `If-None-Match` 的探针(不再命中 304,内容照旧对);判 `activeTaskId === ""` 的消费方(改判 `null`)。**升级前做**:无。**出路**:回传收到的 ETag。**回滚**:无持久面;回到 7.151.x 探针体少两键、ETag 回到叶 id。
|
|
201
|
+
|
|
202
|
+
23. **流式提交的提示词回退锚改在提示提交那一刻落下;「没有锚的提问」那句 404 只陈述事实(行为修复;wire 零新键、零新码;一句 404 文案改短;零 DDL;部署零动作)**:
|
|
203
|
+
旧形(7.151.x 及以前):`POST /v1/tasks/stream` 的提示词回退锚只在终帧之前与断连收尾时写;进程被强杀(SIGKILL / 崩溃 / OOM)⇒ 锚缺,重启后按这条 run 的 `taskId` 发 `resumeAt` / `rewindFilesTo` / run 外口 `to` ⇒ 404,`error` 的括号里点名「带附件的提问在附件帧被中断或帧数不符时不落锚」。
|
|
204
|
+
新形:四条腿同一只写法、同一个时机 —— 第一条用户提交到手即落锚(第一次模型输出关窗时需要校正再落一次);那句 404 为 `… — no rewind anchor is recorded under that handle: it names a prompt of this session that recorded none; …`,不点名成因。
|
|
205
|
+
**存量**:旧版本下被强杀的流式 run 没有锚,本版不补(读到新句);升级之后的流式 run 不再因强杀缺锚。
|
|
206
|
+
**谁需要** / **谁受伤** / **补偿**:同 CHANGELOG 本节同名一条(零新旋钮)。**升级前做**:按这句 404 `error` 文案里 `attachment` 字样分支的脚本改读 `errorCode`。**回滚**(本版 → 7.151.x):无数据面改动;回滚后流式腿回到「终帧之前 / 断连收尾写锚」,本版写下的锚照常可读。
|
|
207
|
+
|
|
208
|
+
24. **生效场景读面 `GET /v1/capabilities/scenario` 与场景门的答形 `{ scenario, source }`(wire 加性;行为修复:三张按场景答的读面读场景头;嵌入方型面破坏;零新码;零 DDL;部署零动作)**:
|
|
209
|
+
新读面答「这次请求会生效哪只场景、它从哪一层来」:200 体 `{ scenario, source }`,`source` ∈ `request` / `ruling` / `deployment`(闭集,穷举读);可选 `?scenario=<名>` 与场景头 `x-agent-scenario` 都是点名(与提交腿同一只读法)。拒与同一请求形的提交拒体逐字同(400 `scenario_unknown` / `scenario_not_allowed` / `scenario_conflict`,503 `state.scenario_assignment_unknown` / `state.scenario_assignment_unavailable`)。能力位 `effectiveScenario`(恒真;键缺席 = 老 server,没有这张面)。
|
|
210
|
+
带场景头读 `GET /v1/capabilities/mcp` / `GET /v1/sessions/:id/mcp` / `GET /v1/sessions/:id/a2a`:答的是头里那只场景;状态面上头与 `?scenario=` 不同 ⇒ 400 `scenario_conflict`。
|
|
211
|
+
包根 `ScenarioGate` 的答从串改为 `ScenarioChoice`(`{ scenario, source }`;包根另导出 `ScenarioChoice` / `ScenarioSource`)。
|
|
212
|
+
**谁需要**:不点名场景、要按名取场景卡的交互客户端。**谁受伤**:手写 `ScenarioGate` 的嵌入方(编译红);带场景头读那三张面、依赖「头被忽略」的读者。**升级前做**:无。**出路**:手写门返回 `{ scenario, source }`(或改用包根 `createScenarioGate`,它铸的门就是生产那一只);要指派链的答就不带场景头读。**回滚**:无持久面;回到 7.151.x 没有这张面与这一位,三张读面不读场景头。
|
|
213
|
+
|
|
214
|
+
25. **🔴 一只会话快照桶 × 一个 `SESSION_SNAPSHOT_PREFIX` 只属一只库:起服开店时证明,别的库认领过 ⇒ 拒启;证不出 ⇒ 照起、不删(数据丢失修复;部署面:共桶同前缀的第二只库起不来;缺认领物件权限的部署照起、回收停到权限补齐;起服自建一张表;wire 零变化)**:
|
|
215
|
+
旧形(≤ 7.151.x):文件历史与附件的对象键是内容地址,删哪一枚只按本库的引用判 —— 两台各有自己库的引擎共用一只会话快照桶且前缀相同(含都不设)时,一台的附件孤儿清扫把另一台在引的上传当孤儿删掉,同一份内容两边都传过时一台放手就带走另一台的字节;两台照常起服,丢字节在读回时才露面。
|
|
216
|
+
新形:每只库一只认领记号(表 `blob_namespace_claim`,一库一行,起服自建、缺席才铸);桶里 `<前缀>blob-namespace-claim` 写着命名空间属于哪只库 —— 本库 ⇒ 开店;没有 ⇒ 写下本库的(`If-None-Match: *`,等一秒读回);别的库 ⇒ 拒启;读写不动(连不上 / 403 / 5xx)⇒ 照常起服(一次尝试、不重试;兜底口 `server.session-blob-namespace.claim-unproven` 计一次、一次性 warn)。会话 blob 三域的每一次删除先重读认领物件、写着本库才删 —— 证不出起服之后每一次删除都拒,存储答复后的第一次删除当场认领再删。文件历史与退役纪元两只按索引行找字节的清扫在动任何一行之前先读认领(每拍一次):证不出 ⇒ 这一拍一行不删、一字节不删,认领恢复后的清扫从同一批行重来。这一步每拍都做、哪怕没有东西要删:对象存储短暂不可用期间,没有东西要删的清扫也会在这一步拒并记失败告警(此前这样的清扫不碰对象存储、照常成功);认领物件缺席时(例如运维删掉它之后)这一步会写下本库的记号(create-only,写后等一秒读回),不只是读。**已知限制**:同一次清扫里认领读两次(动任何一行之前一次、删字节之前一次),第一次过、第二次失败(对象存储瞬时错误)⇒ 那一批索引行已删、字节留在桶里,之后的清扫找不回(文件历史与退役纪元的字节只经索引行可达);认领一直读不出时整次清扫在动任何一行之前就拒、不留这个后果,窗只剩两次读之间的瞬时失败 —— 窄,不是零。`SESSION_SNAPSHOT_PREFIX` 以 `attachments/` 或 `file-history/` 结尾 ⇒ 装载拒。
|
|
217
|
+
**升级前做**:核每只会话快照桶被哪几只库用着 —— 两只以上的库共用一只桶且 `SESSION_SNAPSHOT_PREFIX` 相同(含都不设)⇒ 除了留在原前缀的那一只,其余每只库:① 设自己的前缀(段名不要与 `file-history/` / `attachments/` / `blobs/` / `sendfile/` 同名);② 要保住它已引用的字节,先把旧前缀下的 `file-history/` 与 `attachments/` 拷到新前缀(`mc cp --recursive <alias>/<桶>/<旧前缀>attachments/ <alias>/<桶>/<新前缀>attachments/`,file-history 同);③ 再起。只有一只库用这只桶的部署零动作(首次起服写下认领物件)。按最小权限发对象存储策略的部署给 `<前缀>blob-namespace-claim` 加 `s3:GetObject` / `s3:PutObject` —— 没加的部署升级后**照起**,但附件与文件历史从此不再被回收(桶只涨不减),直到策略补齐(可见于 `server.session-blob-namespace.claim-unproven` 的计数与一次性 warn、清扫的拒删行;补齐之后的第一次删除即认领,不必重启)。
|
|
218
|
+
**出路**(拒句点名):认领物件点名的那只库已经不用这只桶(它已退役,或部署换用了另一只库)⇒ 删掉 `<桶>/<前缀>blob-namespace-claim` 再起;否则给这台引擎设自己的前缀。**回滚**:回到 7.151.x 零动作(旧版不读认领物件与新表,两者留着无害)。
|
|
219
|
+
|
|
220
|
+
26. **预签名 URL 的有效期上限只有一处:604800 s(SigV4 的 7 天),签名座对每一只签名行超了就拒;读它的旋钮装载时超了即拒(行为收紧;部署面:超限配置起服拒;wire 零变化)**:
|
|
221
|
+
旧形(≤ 7.151.x):`SEND_USER_FILE_URL_TTL` > 604800 照装、每次签发抛;`SESSION_SNAPSHOT_TTL_SEC` > 604800 签出存储拒的 URL;`LEADER_TIMEOUT_MS` > 604200000(开了 leader + 对象存储)签出的补丁链接 worker 跑完才失败。
|
|
222
|
+
新形:三者与 `WORKSPACE_SNAPSHOT_TTL_SEC`(此前超了按 3600 截)配置装载即拒(拒句点名旋钮与上限 / 最大值);签名座对任何一行超上限的请求拒签、不截。
|
|
223
|
+
`SEND_USER_FILE_URL_TTL` 不是十进制整数的写法(`1h`、`3600.5`、`-5`;`1e-999` 一类也读作 0):旧形读作 0 = 永久公链(想要会过期的链接、写了单位的部署悄悄发出永久公链);新形装载拒,拒句点名旋钮与两种合法形(0 或不设 = 永久公链;1–604800 的十进制整数秒 = 会过期的私有链接);`1e3` / `0x10` / `03600` / `+60` 这类旧形照数读的写法同拒。
|
|
224
|
+
`SESSION_SNAPSHOT_TTL_SEC` 与 `WORKSPACE_SNAPSHOT_TTL_SEC` 同读这一条写法判:旧形 `3600.5` / `1e3` / `0x10` / `03600` / `+60` 照 `Number()` 的读数装下(小数原样签进 `X-Amz-Expires`),`SESSION_SNAPSHOT_TTL_SEC` 的 `1h` / `-5` 告警后走缺省、`WORKSPACE_SNAPSHOT_TTL_SEC` 的 `-5` 由签名座读作缺省;新形这些写法都装载拒,拒句点名旋钮与合法形。存量写成这些形的部署升级时拒启;出路 = 写成十进制整数秒。`0` 的读法两根各自照旧(`SESSION_SNAPSHOT_TTL_SEC=0` 告警后走缺省,`WORKSPACE_SNAPSHOT_TTL_SEC=0` 读作缺省)。`SESSION_SNAPSHOT_TTL_SEC` 写成纯空白(只有空格):此前起服一行告警、走缺省,现在读作未设、没有这行告警、走缺省(值的读数不变,只少一行告警)。
|
|
225
|
+
**升级前做**:核这四根旋钮 —— `SEND_USER_FILE_URL_TTL` 是十进制整数秒 ≤ 604800(或 0 = 永久链;不带单位、小数点、指数)· `SESSION_SNAPSHOT_TTL_SEC` 是十进制整数秒 ≤ 604800 · `WORKSPACE_SNAPSHOT_TTL_SEC` 是十进制整数秒 ≤ 604800 · 开了 leader 且配了 `MINIO_*` 的部署 `LEADER_TIMEOUT_MS` ≤ 604200000。都在范围内的部署零动作。**回滚**:零动作。
|
|
226
|
+
|
|
227
|
+
27. **leader 车道(`POST /v1/leader`)与 agent 钩子的模型请求用目录条目自己的钥匙(`apiKeyEnv` / `sealedApiKey`),不再用部署网关钥;声明了钥匙却拿不到 ⇒ 响亮失败(行为修复;安全轴收紧;wire 零新键、零新码;零 DDL;部署零动作,自查见「升级前做」)**:
|
|
228
|
+
旧形(7.151.x 及以前):leader 的执行器(planner 路由、两条车道的 worker、集成修复,以及跑在 worker 执行器上的模块门修复与单代理修复环)与 `type: "agent"` 钩子的执行器发出的模型请求都只带部署网关钥(`MODEL_API_KEY`)—— 目录给模型配的 `apiKeyEnv` / `sealedApiKey` 在这两条车道上不生效:模型走网关的根 ⇒ 网关钥照发、账记在部署网关上;模型在别家的根上 ⇒ 引擎的配对裁决器拒(`route.credential_mismatch`),leader 的腿起不来;声明的变量缺席 / 托管密钥解不开 ⇒ 照样拿网关钥发出去。
|
|
229
|
+
新形:这两条车道与任务面同读 —— 打一只配了自己钥匙的模型时带它自己的钥匙;没配的模型照旧网关钥(逐字同旧形);声明了却拿不到 ⇒ 那次调用整体失败、拒句点名变量或托管成因、一个请求都不发(leader 的 worker 腿 failed;集成修复轮没跑完 ⇒ 合并保留原失败,拒句带成因;planner 路由不发请求、收成单路,另记 `plan_route_run_incomplete` 一行点名成因;模块门修复腿失败后照既有读法回到判官,另记 `module_repair_incomplete` 一行点名成因;agent 钩子那一条 fail,非阻断记账)。钥与执行器的目录同代:跑在一只执行器上的每条腿带那只执行器出生时那一代的钥匙(模块门修复 / 单代理修复环沿用 worker 的);中心把模型连端点带钥匙一起换掉之后,之后出生的执行器用新的一代;新钥匙不发往旧端点。
|
|
230
|
+
**谁需要** / **谁受伤** / **补偿**:同 CHANGELOG 本节同名一条(零新旋钮)。**升级前做**:开了 `LEADER_ENABLED` 或配了 `type: "agent"` 钩子、且目录给模型配了自己钥匙的部署 —— ① 核那些钥匙在服务进程里拿得到(`apiKeyEnv` 点名的变量有值、`sealedApiKey` 解得开);② 知会账务:这两条车道的用量此后记到各模型自己的账户;③ 不想让某只模型在这两条车道上按自己的账号认证 ⇒ 删掉条目的 `apiKeyEnv` / `sealedApiKey`(任务面同受影响 —— 一只模型只有一种凭据读法)。**回滚**(本版 → 7.151.x):无持久面改动;回滚后这两条车道回到只带网关钥。
|
|
231
|
+
|
|
232
|
+
28. **勘误 7.143.0 节第 32 条 ②(回滚句):它写的是 `DB_BACKEND=local` 的一形;SQL 后端(`DB_BACKEND=mysql|pg`)回到 7.142.x,旧副本先在起服时被列册对账拒启,删掉本版多出的两列之后才轮到续跑那一步;`422 parked_resume.startup_failed` 的回体键与 `rollback` 的取值域在此成文(文字订正;零行为变更;wire 零变化;部署零动作;已发的 7.143.0 节不改字节,本条即订正)**:
|
|
233
|
+
— **勘误**:7.143.0 节第 32 条 ② 写「回滚:本版停驻的后台子代的卡记着行 id(要求词 `row_task_id`),上一版读不懂这个词,续跑拒 `version_newer`」。这句讲的是回滚之后**续跑那一步**的结局,而且只对 `DB_BACKEND=local` 成立 —— 那一形的旧副本起得来,才轮得到续跑。SQL 后端要先过起服这一关,而该节没有把它接到第 32 条上(删列语句分在第 9 条与第 26 条各自的回滚句里)。
|
|
234
|
+
— **SQL 后端回滚到 7.142.x,两步**:
|
|
235
|
+
① **起服先被拒**。7.143.0 起这只库在已有的表里多了两列:`task_attachment.seed_session_id`(带唯一索引 `uq_att_seed`,第 9 条)与 `approval_ask.decided_via`(第 26 条)。7.142.x 的起服列册对账(`assertSchemaMatchesCode`,建表之后、服务之前)把库里有、而它的建表语句没有声明的列读作多出来的列,**拒启**,码 `config.schema_mismatch`。拒句以 `config.schema_mismatch: the PostgreSQL database does not match this build's schema — refusing to start.` 开头(MySQL 协议写 `the MySQL-protocol database`),随后逐表一段 `table task_attachment: UNKNOWN column(s) seed_session_id — the database is NEWER than this build (a rolling window where an old replica reached an upgraded database).`(`approval_ask` / `decided_via` 同形),每段下一行 `No ALTER is suggested for this direction: deploy the build that owns those columns (upgrade the database FIRST, then the replicas).`,末尾是闭集三条出路。旧版给的出路是「部署持有这些列的构建」,不给 `ALTER`。
|
|
236
|
+
② **删列之后才轮到第 32 条 ②**。回到 7.142.x 的路径是第 9 条与第 26 条回滚句写的那一条:先停光本版的全部副本,再删索引 `uq_att_seed` 与 `seed_session_id`、`decided_via` 两列(语句逐字在那两条里),再起 7.142.x;起得来之后,本版停驻的后台子代的卡才按第 32 条 ② 的读法被续跑拒。
|
|
237
|
+
— **`422 parked_resume.startup_failed` 的体**(后台停驻子代的赎回腿;铸点 `src/parked-decide.ts`,7.142.x、7.143.0 与本版同形):回到 7.142.x 之后对这类卡 approve,引擎在认领之前拒(`version_newer`),这条腿把它交成 `422 parked_resume.startup_failed`,不是同步续跑腿上那只 `409 checkpoint.unsupported_version`。体的键:`error`(引擎回执的原句;回执没给句子时是 `the parked resume failed during startup`)· `errorCode`(恒为本码)· `taskId`(后台子代的句柄,`a` 打头的 id)· `rollback`(恒在,取值见下)· `cause`(引擎回执带了闭集成因词 `environment` · `session_gone` · `transcript_corrupt` · `tool_unavailable` · `configuration` · `decision_rejected` 才在,没带或集外词一律缺席)· `blockedBy` / `field` / `reason`(各自在引擎回执 `detail` 的 `code` / `field` / `reason` 是非空串时才在,缺席不造键;这一形上的 `reason` 读作 `version_newer`)。体上没有 `detail`、`retriable` 键。`blockedBy` / `field` / `reason` 自 7.134.0 起在;7.134.0 之前这条腿的体除 `taskId` / `rollback` 之外的判别位只有 `cause`,7.132.0 节第 1 / 2 条「体只带 `cause`」说的就是那个范围。
|
|
238
|
+
— **`rollback` 的取值域**(四个词,引擎回滚口对**这一次 decide 自己的那一次补滚**的处置,原样上 wire;同一个键、同一张词表也在 `409 decide.revive_rejected` · `500 decide.revive_failed` · `409 decide.agent_definition_unavailable` 三只拒体上):
|
|
239
|
+
· `rolled_back` —— 这次补滚把认领放掉了:行是 `parked`、认领已清;读回确认了卡仍 pending(同一张卡可再决)。放掉认领之后读回那一步店读写抛了的形也答这个词 —— 那时卡此刻是否仍 pending 没有再确认;
|
|
240
|
+
· `lost` —— 这次补滚没有以「卡仍 pending」或「行结清为 `failed`」收场,两种形:补滚时行上已不是这一次 decide 的认领(这次补滚没写任何东西;起跑即败时引擎在驱动里先自己回滚了认领是本腿 422 上的常态:行已回 `parked`、卡仍 pending、可再决;也可能引擎已消费它、或别的写者拿走了它);或这次补滚放掉了认领、读回却发现卡已不再 pending,行又没能结清成 `failed`。本服务分不出是哪一种 —— 读 `GET /v1/approvals` 与那一行的状态看这张卡的去向。回到 7.142.x 后的这一形通常读 `lost` 而行仍 pending;
|
|
241
|
+
· `failed` —— 卡已不再 pending(被作废或已被消费),这次补滚把行结清为终局 `failed`(子代 `failed`,什么都没复活);
|
|
242
|
+
· `retry` —— 补滚读写店失败,没有确认写成任何东西:认领可能还在行上(陈旧认领清扫会放掉它),也可能已被引擎在驱动里结清;读待决列表看那张卡的去向。
|
|
243
|
+
**谁需要**:做滚动回滚的运维(SQL 后端部署)。**谁受伤**:① 按第 32 条 ② 的字面以为「回滚之后旧版起得来、只是卡续不了」的运维 —— SQL 后端的旧版在删掉那两列之前起不来;② 按 `409 checkpoint.unsupported_version` 找这一拒的脚本 —— 后台停驻子代的卡在 7.142.x 上答 `422 parked_resume.startup_failed`(同步续跑腿仍是 `409`)。**补偿 / 出路**:本条;删列的语句逐字在第 9 条与第 26 条的回滚句里。**升级前做**:无。**回滚**:无关(无存储形变化)。
|
|
244
|
+
|
|
245
|
+
29. **勘误 7.141.0 节第 3 条末句:「`/wake` 的会话 park(取消后仍留着)」不适用于 wake 在入口屏 / 预检上被取消、腿以 `checkpoint.resume_aborted` 抛出收场的那一形 —— 7.141.0 至 7.147.0 该形亲手 expire 了那张会话 park,7.148.0 起不再(文字订正;零行为变更;wire 零变化;部署零动作;已发的 7.141.0 节不改字节,本条即订正)**:
|
|
246
|
+
— **勘误**:7.141.0 节第 3 条末句「`/wake` 的会话 park(取消后仍留着)与非取消的重开形里引擎原句原样」(CHANGELOG 7.141.0 节同条同说)只对 wake 的**结果臂**成立:腿交回了结果、之后才被取消 —— wake 的合成行不持有那张 park,结果臂上的取消结算对合成行提前返回,park 留在店里,终局 `message` 是引擎原句。**不成立**的是另一形:wake 在入口屏 / 预检上被取消,腿以 `checkpoint.resume_aborted` 抛出收场(`src/http/resume-legs.ts` 的取消臂)。7.141.0 至 7.147.0 在这一臂上对 wake 同样调取消结算(`settleCardForCancel`):wake 续的是会话的 `task_done` park,它是一张 pending 的卡 ⇒ 被本服务 expire,run 行与账本终局行的 `message` 是该条那句「Cancelled — the approved action never started, and the cancel settled this approval: it cannot be resumed (start a new run to continue)」(码仍是 `cancelled`;句里的「批过的动作」「this approval」对 wake 并不存在 —— wake 的 park 没有待批动作),再 wake 答 `404 not_found.parked_checkpoint`。7.148.0 起这一臂对 wake 的合成行不再 expire(取消结算对合成行恒答 `false`):park 留 pending,终局用引擎原句,再 wake 续它 —— 7.148.0 节第 7 条把这一变化写成了「旧形 / 新形」,本条把两条接上:第 3 条末句说的 park 去向,对这一形在 7.141.0 至 7.147.0 是相反的。7.141.0 之前这一臂是否同形,本条不判。
|
|
247
|
+
**谁需要**:按第 3 条末句判断「取消一次 wake 之后这条会话还能再 wake」的调用方。**谁受伤**:7.141.0 至 7.147.0 上取消了入口屏 / 预检阶段的 wake、再 wake 读到 `404` 的调用方(文字与行为不符)。**补偿 / 出路**:新提交一条任务(新 run 与 park 并存),或等审批窗到期收割(同 7.148.0 节第 7 条);7.148.0 起无需动作。**升级前做**:无。**回滚**:无关(无存储形变化;回到 7.141.0 至 7.147.0 即回到 expire 的形)。
|
|
248
|
+
|
|
249
|
+
30. **没有把 web-admin 当配置源的进程上,缺省模型检查的拒启句(`MODEL_ID is required when no catalog default resolves [config.default_model_missing] …`)句尾只说 `MODEL_ID` 与 `config.d/models.json` 两条出路;web-admin 是配置源时整句逐字不变;句首锚两形都不动(行为变更;拒启句文字;wire 零变化;部署零动作)**:
|
|
250
|
+
旧形(≤ 7.151.x):这句拒启句对谁都在句尾说「…enable at least one model this host can serve in the catalog (config.d/models.json, or the web-admin) — either one is enough (a web-admin that answers after the boot budget counts as absent at boot: raise CONFIG_BOOT_FETCH_BUDGET_MS to wait for it).」—— 包括没有 web-admin 当配置源的进程(本机 `sema` 一次性入口、`CONFIG_PROVIDER=local`、纯 env),后半句对它们不是出路。
|
|
251
|
+
新形:句尾按「web-admin 是不是这个进程的配置源」分两形。是 ⇒ 整句逐字不变(上面那一句,含 web-admin 与 `CONFIG_BOOT_FETCH_BUDGET_MS`);不是 ⇒ 句尾只剩「…in the catalog (config.d/models.json) — either one is enough.」,不出现 web-admin 与 `CONFIG_BOOT_FETCH_BUDGET_MS`。句首 `MODEL_ID is required when no catalog default resolves [config.default_model_missing] — this model table has no default model` 到「. Set MODEL_ID=」之前的整段两形逐字同(被拒候选的「回落原因」段、「every enabled catalog entry is unavailable …」段也两形同);目录腿(候选自己没有缺省)的句子不变。7.147.0 节第 27 条写的「没有被拒候选时整句逐字不变」读作:web-admin 是配置源的进程上逐字不变(7.147.0 节原句不改字节,本条即订正读法;契约里的同一句已按这里改)。
|
|
252
|
+
同一条律多盖两句:路由端点判官的 env 腿两句拒因(`… resolve to no endpoint [config.model_route_endpoint_missing] …` 与 `… ask for the anthropic lane …`)的第三条出路原也对谁都写「(3) leave MODEL_ID unset and let the default entry of a catalog (config.d/models.json, or the web-admin) serve」。现在同一件事实(`configSourceKind(config) === "remote"`)、同一个腿类型(`ModelRefusalLeg`)分两形:web-admin 是配置源 ⇒ 整句逐字不变;不是 ⇒ 括号只剩 `(config.d/models.json)`,不再提 web-admin。事实由调用点递进来,判官函数自己不读 env、不读配置;句子里「`CONFIG_REQUIRE_ROSTER=true` on a remote registry」那一句不动(名册布防是中心接入的事实,与目录从哪来是两件事);目录腿的句子本来不提 web-admin。**嵌入方(破坏性,编译红)**:包根导出的 `judgeServedModelRoute(config, opts)` 的 `opts` 多一个必填键 `webAdminIsConfigSource`(没有配置源的自建装配传 `false`;有中心且 `CONFIG_PROVIDER` 缺席或为 `remote` 的装配传 `configSourceKind(config) === "remote"` 的值);判官在源码里的抛出形 `assertServedModelRoute` 对应的是没有目录要应用的直接装配,它不跑配置源,恒按「不是」。
|
|
253
|
+
判据只有一个事实 —— web-admin 是不是这个进程的配置源(配置源判官 `configSourceKind` 答 `remote`):不写 `CONFIG_PROVIDER` 且配了中心 ⇒ 是;`CONFIG_PROVIDER=remote` ⇒ 是;`CONFIG_PROVIDER=local`(含 `sema` / `run-local` 一次性入口,它只装本地配置源)⇒ 否,哪怕配了中心(中心照样管 fleet 面,模型目录只读本地 `config.d`);纯 env ⇒ 否。判官函数自己不读 env、不读配置,这一格由调用点递进来(少递编译红)。
|
|
254
|
+
**已知限制(如实)**:纯 env 进程(不写 `CONFIG_PROVIDER`、没配中心)没有配置源,读不到 `config.d`;它拿到的短句里第二条出路 `config.d/models.json` 要先设 `CONFIG_PROVIDER=local` 才成立,本条没有改这一点(旧形里这一半同样在句子里)。
|
|
255
|
+
**谁需要**:本机个人形(`sema` 一次性入口、`CONFIG_PROVIDER=local`)起引擎没配模型的人 —— 句尾不再指向与他们无关的 web-admin 与启动预算旋钮。**谁受伤**:按整句逐字匹配这句拒启句的脚本(没有 web-admin 配置源的进程上句子变短;按句首 `MODEL_ID is required when no catalog default resolves [config.default_model_missing]` 匹配的不受影响)。**补偿 / 出路**:按码 `config.default_model_missing` 或句首匹配(壳与运维脚本本来认的就是句首)。**升级前做**:无。**回滚**:回到 7.151.x ⇒ 句子回到对谁都说 web-admin 的那一句。
|
|
256
|
+
|
|
257
|
+
31. **续跑家族的请求在飞时被取消,200 体多 `bindingEnforced: true` 与这次取消的终局句 `errorMessage`(wire 加性;零新码;零 DDL;部署零动作)**:
|
|
258
|
+
旧形(7.151.x 及以前):`POST /v1/sessions/:id/wake`、`POST /v1/approvals/:sessionId/decide`、`POST /v1/assistant/tasks/:id/resume`、`/plan_review` 的请求在受理之前被取消(`POST /v1/runs/:id/cancel`)⇒ 200 `{ taskId?, sessionId, status: "failed", errorCode: "cancelled" }`,没有句子,也没有 `bindingEnforced`。
|
|
259
|
+
新形:同一只体多两键 —— `bindingEnforced: true`(与这几扇门的受理体 / 结果体同一位)与 `errorMessage`(这次取消的终局句,与同一 run 的 `GET /v1/runs/:id` 的 `error` / `result.terminal.message` 逐字同;没有 run 行的那一形同样带,`taskId` 缺席)。`retriable` 照旧不在取消体上。体的码与句读这条 run 行上落下的那一份终局:取消落下之后、本腿驱行终局之前行已被别的写者先收成终局(收割 / 判死 `run.stalled`;终局写先到者得)的那一形,体上是行上那一份的码与句(此前恒答 `cancelled`,而 `GET /v1/runs/:id` 答先到的那一份)。
|
|
260
|
+
**如实**:sdk 的契约(wake 200 schema)把取消形写成带 `bindingEnforced: true` 并列为必填,而本服务的取消体自这一位上 wire(5.4.0)至 7.151.x 从没带过它 —— 严格按那份 schema 校验的客户端此前会拒收这只真响应,本版起不再。
|
|
261
|
+
**谁需要** / **谁受伤** / **补偿**:同 CHANGELOG 本节同名一条(零新旋钮)。**升级前做**:无;按键集逐字断言取消体的脚本补两键。**回滚**(本版 → 7.151.x):无持久面;回滚后取消体回到少这两键的形。
|
|
262
|
+
|
|
263
|
+
32. **🔴 提货 `@sema-agent/settings-schema` 26.0.0(引擎 7.66.1 不变):fleet 心跳与 `/health` 的 8.0 平铺引擎态方言停发;`settings.hooks.PermissionDenied` 在服务端跑;目录条目头袋不是对象的条目被丢、唯一 / 被引用时候选整份拒;`STREAM_APPROVAL_ENABLED` 留着即拒启(wire BREAKING;行为变更;零 DDL;部署动作:删掉退役键、头袋改形)**:
|
|
264
|
+
旧形(≤ 7.151.x,settings-schema 25.1.0):① 心跳体顶层带 `ready` / `draining`(恒在)、`restart` / `generation` / `leaseState` / `leaseUntil`(在场律同 `engineSignal` 的同名键);`/health` 排空中带 `draining: true` 与 `drainingSince`。② `settings.hooks.PermissionDenied` 契约判给壳,服务端只记一行 debug、从不跑。③ `models[].headers` 是解析透明键:数组 / 串等非对象头袋照进读腿,由本仓判那一条目不可用(`config.model_entry_invalid` 点名 `headers`),其余模型照用。④ 本版其余提交已不读 `STREAM_APPROVAL_ENABLED`,留着它悄悄不起作用。⑤ 本机调度店里仍按会话链键存的 durable 记录(核心 5.5.0 之前写下)每次读被契约重铸到 durable 键(读时改写、下一个写者落盘)。⑥ 存量旧形(`models.atModelAllowlist` / `models.default`、带事实的 `runtime.json`、URL 带 `#`、同设两种钥匙的模型条目)的拒句与告警句尾带一段一次性迁移指路(迁移 id + `npx @sema-agent/settings-schema migrate <config.d directory>`),被拒文档(墓碑)另带迁移 id。
|
|
265
|
+
新形:① **读引擎态的消费方只读 `engineSignal`**(契约 `EngineSignal`;`readEngineSignal(body)`)—— 心跳体顶层零引擎态键;`/health` 不带 `draining` / `drainingSince`(排空起点 = `engineSignal.draining.since`);`/health` 顶层的 `ready` / `reasons` / `restart` / `restartRequired` / 成员三键 / 世代账是本服务自己的诊断键,照发。② 引擎在门上拒一次调用(策略拒、问被裁成拒、权限模式拒、合规拒、钩子筛查失败的失效关闭)⇒ 跑一次 `PermissionDenied` 条目(观察者,matcher 对 `tool_name`,答 `retry` 无处兑现、记 `hook_result_unsupported`);fresh 提交里这个事件上选中工具别名却选不中正名的 matcher ⇒ `400 request.field_invalid`(与另三个工具事件同句)。③ **`models[].headers` 不是纯 JSON 对象的条目被丢**:有未被引用的兄弟 ⇒ 只丢它(逐条丢弃行 `config_entry_dropped` 点名 `models.<下标>` 与 `headers`,候选照收);它是唯一一条、或被 `roles` / `atMention` / `tierGroups` 引用 ⇒ `models` 整域退缺省 ⇒ **候选整份拒**(`config_candidate_rejected`,`errors[].error` = `models.<下标>.headers: headers must be a plain JSON object`;`GET /v1/models` 的 `candidateRejected.domains` 含 `models`;在服务的留在上一份整套落地的配置,起服时回落链同前)。**运维怎么看见**:上面两行运维日志 + `GET /v1/models.candidateRejected`;拒句点名的是下标与键,不点名条目名(契约这一形的告警不带身份)—— 照下标找那一条。④ env 里留着 `STREAM_APPROVAL_ENABLED`(任何值)⇒ 拒启,拒句带 `config.env_key_retired`、点名这一键、不回显值;**出路 = 删掉它**(没有替代键)。⑤ 那种 durable 记录逐字读出、留在会话键上、无告警:别的会话按 durable 键列不出、取消不了它(出路见「升级前做」⑤)。⑥ **存量旧形的拒句与告警止于今天的位 / 规则本身**(契约到期删码):不再点名迁移 id、不再给 `migrate` 命令行,被拒文档(墓碑)不再带迁移 id —— 逐条丢弃行 `config_entry_dropped`、整域行 `config_domain_invalid`、拒行 `config_candidate_rejected` 的 `errors[].error`、`config.d/remote-exec.json` 的拒启句同读;句子仍点名键与今天的位、不回显值。本版带的契约包的 `migrate` 也不再改写这几形(第 18 条)。
|
|
266
|
+
**升级前做**:① 删掉 `STREAM_APPROVAL_ENABLED`;② 对每一份存着的 `models` 文档(本机 `config.d/models.json`;中心的草稿 / 已发快照 / 回滚史)跑契约包 26.0.0 CHANGELOG「三问 · 补偿」下那一条自查命令(零输出 = 与你无关),把列出的条目的 `headers` 改成对象、或删掉该键;③ 读心跳顶层或 `/health.draining` / `drainingSince` 的编排 / 脚本改读 `engineSignal`;④ 不想在服务端跑的 `PermissionDenied` 条目从请求的 `settings.hooks` 里拿掉,写了别名 matcher 的改写正名;⑤ 用本机调度店的部署对店文件跑契约包 26.0.0 CHANGELOG「到期删码 · 补偿」下那一条自查命令,把列出的 durable 记录的 `scope` 改成它打印的 durable 键(此后读口不再替你重铸);⑥ 存量里还有旧形(见 ⑥)而想自动改写的,升级前用上一个契约 major 跑一次 `npx @sema-agent/settings-schema@25 migrate <config.d 目录>`(先备份),否则按拒句把事实手写到今天的位。**回滚**(本版 → 7.151.x):平铺键回来、`PermissionDenied` 回到不跑、头袋回到本仓判条目;零持久面改动。
|
|
267
|
+
|
|
268
|
+
33. **`server.model_unreachable` 通告的建议句按失败类分:直连拒连、直连解析不了这两形换了句,超时 / 无路由 / 走了代理的形逐字不变(行为变更;`detail.remedy` 的值与正文末句;wire 键与键形不变;零新码;部署零动作)**:
|
|
269
|
+
旧形(≤ 7.151.x):对所有建连失败,正文末句都是 `Check the VPN / proxy; if the proxy changed since the server started, restart it (proxy settings are read once at startup).`,`detail.remedy` 都是 `check VPN / proxy; restart if the proxy changed since boot`。
|
|
270
|
+
新形:建议句取自失败类上的一张闭表,正文末句与 `detail.remedy` 是同一行的两句。这一跳走了代理(`detail.proxyInUse` 在场)⇒ 通用句(即旧形那一句,逐字);否则按 `detail.code` 的类 ——
|
|
271
|
+
· `ECONNREFUSED`(拒连)⇒ 正文末句 `Check that a service is listening at that address and that the model gateway address is configured correctly.`,`remedy` = `check that a service is listening at the model endpoint address; check the model gateway address configuration`(不提 VPN);
|
|
272
|
+
· `ENOTFOUND` / `EAI_AGAIN`(解析不了)⇒ 正文末句 `Check that the model gateway address is written correctly in the configuration and that DNS (and the VPN, if one is in use) can resolve it.`,`remedy` = `check the model gateway address configuration; check DNS / VPN`;
|
|
273
|
+
· `UND_ERR_CONNECT_TIMEOUT` / `EHOSTUNREACH` / `ENETUNREACH`(建连超时 / 无路由 / 网络不可达)⇒ 通用句,逐字不变。
|
|
274
|
+
通告码、`detail` 其余键(`code` / `targetHost` / `proxyInUse?` / `sessionId` / `taskId?`)、「每腿每目标一次」的去重都不变;建议句(正文末句与 `remedy`)里没有任何配置值、代理地址、凭据(模型端点的 `host:port` 仍只在正文前半句与 `detail.targetHost`,与 7.151.x 同)。
|
|
275
|
+
**谁需要**:在本机起模型服务、或把模型网关地址写错了的用户 —— 没用 VPN、没走代理的人不再被指去查 VPN。**谁受伤**:按整句匹配 `detail.remedy`(或正文末句)的消费方 —— 直连拒连、直连解析不了这两形上句子变了;超时 / 无路由 / 走代理的形逐字不变。**补偿 / 出路**:按通告码 `server.model_unreachable` 与 `detail.code` / `detail.proxyInUse` 判,不匹配建议句(引擎码册里本码的 `message` 本就只作 fallback 展示)。**升级前做**:无。**回滚**:无关(无存储形变化;回到 7.151.x 即回到对所有失败类说通用句的形)。
|
|
276
|
+
|
|
277
|
+
## 7.151.0 —— 1–22 条见下
|
|
278
|
+
|
|
279
|
+
**升级清单(本节唯一的一张;下面各条只讲为什么,不再各自重述升级步骤)** —— 一次读清本版对一只存量部署要做的全部动作。每版同形:① 手工 DDL(逐表逐句,两方言各一份)② 起服自建与一次性迁移 ③ 停-迁-起 ④ 顺序;后续每版的段头照此写,新增一句 `ALTER`、一条一次性迁移、一条停-迁-起时,先改这里,再写条目。
|
|
280
|
+
已发各节(7.150.0 及以前)逐字只读,不在原处补汇总 —— 跨过它们的部署读下面「跨过 7.150.0」一块。
|
|
281
|
+
|
|
282
|
+
- **从 7.150.x 升级到本版**:
|
|
283
|
+
- 手工 DDL(SQL 后端 `DB_BACKEND=mysql|pg`;一张表一句,**先升库、再升副本**;旧副本只在它重启时按「库比构建新」拒启,多出的这一列是它的幽灵列)。语句逐字是起服列册对账拒句打印的那一句(由本构建的建表语句生成),存量行不回填(第 1 条「客户端放置的子代会话」):
|
|
284
|
+
- MySQL 协议:
|
|
285
|
+
`ALTER TABLE session_ext ADD COLUMN session_kind VARCHAR(32) NULL;`
|
|
286
|
+
- PostgreSQL:
|
|
287
|
+
`ALTER TABLE session_ext ADD COLUMN session_kind VARCHAR(32) COLLATE "C";`
|
|
288
|
+
其余各条零 DDL:停驻问的决定记在问表既有的列上(第 2 条),workflow 停驻卡的决定行同列同形(第 3 条),续跑上下文多的一格随既有的上下文列存(第 4 条)。`DB_BACKEND=local` 零 DDL。
|
|
289
|
+
- 起服自建(运维零手工):索引 `idx_session_ext_kind`(新版起服自建:MySQL 协议在线 `ADD INDEX`,PG `CREATE INDEX CONCURRENTLY`,两遍表扫、不挡写,`session_ext` 行数大的库起服变慢;第 1 条)。无新表。
|
|
290
|
+
- 一次性迁移:**M53**(SQL 两方言;起服自跑,运维零手工;第 5 条「SQL 店的失败对外只说」):换句之前落盘的后台子代行(`background_agent.record_json` 的 `error`,及 `summary` 里逐字含它的那一段)与 run 事件里 `tool_end` 子代卡的 `errorMessage` 换成对外句(改写的后台子代行按本表写律 `rev` 抬 1);读数 `storeFaultSentencesRewritten`(起服日志 `one_time_migrations_applied`);窗 = 本版发布日 + 30 天,窗内每次起服再扫(滚动升级窗里旧副本新写的旧句下一次起服接住);`DB_BACKEND=local` 恒 0。另:停-迁-起证据读法不再登记为一次性迁移 M52,改为常设、没有删除日期(第 7 条)。
|
|
291
|
+
- 停-迁-起:**无新增**,本版条目没有一条要求停光旧副本。已有几条(**M40** · **M41** · **M42** · **M51**)本版起:守卫一律在迁移段第一笔写之前一起判;放行的那一条在它自己的第一笔改动之前往 `serving_requirement` 记一行 `in_force`(只在还欠它的库上;起过 7.148.x 的库零写);停光旧副本这一步不变,仍是运维的第一道(第 7 条)。
|
|
292
|
+
- 引擎换钉:`@sema-agent/core` 7.66.0 → 7.66.1(精确钉,`@sema-agent/primitives` 随之;随包到货,零 DDL、零新旋钮、运维零动作):行为面只一处 —— 没有耐久授权声明的腿(同步委派子代)没人答的问不再停驻,读引擎的拒(第 19 条;被中心强制耐久门的主体除外,见第 22 条);本服务自己的根腿与带转交声明的后台子代照旧停驻。
|
|
293
|
+
- 升级前自查(不改库;每条一行,出路在各条里):`BAKE_ENV_ALLOW` 不点 `BAKE_RUNNER_TOKEN`、不点与它同值的变量(第 11 条,点到 ⇒ bake-runner 拒启)· 直接 `helm` 的部署在 values 里写下 `server.operatorSingleUser` 或 `server.requirePrincipal`,先 `helm template` 同一份 values(第 20 条;经 `sema-up` 装的部署零动作)· 同一只引擎上 `SEMA_WEB_ADMIN_ASSERTION_TOKEN` 与 `_FILE` 只留一个(第 9 条,两键都有值 ⇒ 拒启)· fleet 成员上按旧日志数一数 `scope` 与本 worker `FLEET_SCOPE` 不等的登录令牌调用方(第 8 条,升级后它们 403)· 只接鉴权桥、没配 service 凭据的部署核告警脚本对 503 `auth.service_token_required` 的读法(第 10 条)· 用 `config.d/remote-exec.json` 选车道的机器 `env | grep -E '^(DOCKER|HOST)_'`(第 15 条,同车道 env 旋钮从此生效)· `AUTONOMY=plan` 的部署数一数此刻停驻的 run(第 13 条:续跑时体上的权限模式词照现地板钳进 plan;要按原词走完 ⇒ 升级前决完)· 按 `connect_failed` 告警桶缺、准入拒、恢复不回、家目录 / 主机密钥不符的规则改认 `env.*` 码,按 `auth_failed` 告警配额 403 的改认 `connect_failed`;读本版 wire 清单求交的消费方注意自铸登记 `refusalSentenceForm` 退出了一个句型键 `connect_failed(run 失败终局)#snapshot_bucket_missing`(本版清单 breaking 的唯一来源;同一句改由 `env.snapshot_bucket_missing#snapshot_bucket_missing` 入册,句型与码以外的机读位不变)(第 17 条)· 日志采集留住店边界那一行 `at=store`(第 5 条:库驱动的原话从子代卡 / 通告 / 回读 / 文件历史失败句挪到 worker 日志)· `HOST_WORKSPACE_BASE` 与调用方送的 `cwd` 里有没有 `..` / `.` 段(第 16 条,有就改写成规整绝对路径)· 接中心的部署盘点中心上关了 fork(`allowFork:false`)或开了强制耐久门(`forceDurableGate:true`)的主体(第 22 条:它们的委派子代此后同受这两位;强制门主体的同步子代没人答的问停驻成决不了的卡)。
|
|
294
|
+
- 顺序:① 备份 ② 上面那一句 `ALTER`(SQL 后端,先升库)③ 换版本(可滚动 —— 滚动窗里不要重启旧副本,它按「库比构建新」拒启;新旧副本混跑窗内的差别见第 1 条「滚动升级窗」与第 3 条「混跑窗」,全部副本升完即消失)。
|
|
295
|
+
- **跨过 7.150.0(从 ≤ 7.149.x 直升本版)另加 7.150.0 节段头升级清单的全部动作**(那一张已含「跨过 7.149.0」一块)。
|
|
296
|
+
|
|
297
|
+
1. **客户端放置的子代会话:提交体 `sessionKind: "sidechain"`(能力位 `sessionKinds`)—— 这种会话不进 `GET /v1/sessions` 的缺省视图与 `ListAgents`、最后活动之后过 `BG_AGENT_RETENTION_MS` 由维护拍删除;SQL 部署升级前手工 DDL 一句(持久数据面;行为加性;wire 加性;没有一次性迁移)**:
|
|
298
|
+
客户端可以把一次提交建的会话声明为子代对话:提交体 `sessionKind: "sidechain"`(只在建这只会话的那一笔提交里写下,此后终身不改)。这种会话不进 `GET /v1/sessions` 的缺省列表(`?sessionKind=sidechain` 单列它们)、不进 `ListAgents`、不能作 `SendMessage` 的跨会话收件人;最后活动之后过 `BG_AGENT_RETENTION_MS`、且没有在跑的 run / 待决的审批 / 在跑的子代或 workflow 挂着它时,由维护拍删除;按 id 的读写与普通会话相同。不带键的提交、存量会话与老壳零变化(存量行即顶层对话,无回填)。
|
|
299
|
+
**升级前做(SQL 部署;先升库再升副本)**:起新版之前执行这一句(起服列册对账对缺列的库拒启,拒句里逐字打印同一句):
|
|
300
|
+
- MySQL 协议(TiDB / MySQL):`ALTER TABLE session_ext ADD COLUMN session_kind VARCHAR(32) NULL`
|
|
301
|
+
- PostgreSQL:`ALTER TABLE session_ext ADD COLUMN session_kind VARCHAR(32) COLLATE "C"`
|
|
302
|
+
索引 `idx_session_ext_kind` 由新版起服自建(MySQL 协议在线 `ADD INDEX`;PG `CREATE INDEX CONCURRENTLY`,两遍表扫、不挡写,`session_ext` 行数大的库起服变慢)。local 部署零动作。没有一次性迁移、没有停-迁-起:旧副本不会写出违反新律的行(它补旁表行时种类为 NULL = 顶层)。
|
|
303
|
+
**滚动升级窗**:旧副本答的列表里仍带属主自己的 sidechain(只对属主 / 运维可见,不跨租户);旧副本不老化(新副本老化,删除围栏防双删);旧副本对带键提交答 400 `request.body_shape`(`unknownKeys:["sessionKind"]`)—— 客户端先读能力位 `sessionKinds`。
|
|
304
|
+
**谁受伤**:按列表全集断言的消费方;只被读、不再续话的 sidechain 过视界即删(读不是活动)。**补偿**:`?sessionKind=sidechain`;`BG_AGENT_RETENTION_MS` 调长(后台子代行的保留期一起变长)。
|
|
305
|
+
**回滚**(本版 → 7.150.x):旧构建的列册对账对多出的列拒启 ⇒ 先 `DROP INDEX idx_session_ext_kind`(MySQL 协议:`ALTER TABLE session_ext DROP INDEX idx_session_ext_kind`;PG:`DROP INDEX idx_session_ext_kind`)再 `ALTER TABLE session_ext DROP COLUMN session_kind`;已建的 sidechain 会话从此是普通会话(进列表、不再按 `BG_AGENT_RETENTION_MS` 老化)。local:会话元数据格多了一位,旧构建的严格边档整只拒(与客户端写计数同一回滚拒形)—— 回滚之前先用本版删掉 sidechain 会话。
|
|
306
|
+
|
|
307
|
+
2. **耐久决断口 `POST /v1/tasks/:taskId/asks/:askId/decision` 受理已转停驻的问;停驻卡的决定记在它的问行上(行为变更;wire:一面状态翻转 + 加性;持久数据面:问表既有列在 `PARKED` 行上也落值、local 后端问账账本多一个动词;部署零动作)**:
|
|
308
|
+
旧形:问一转停驻,决断口答 `410 gone.ask_parked` + 三件坐标,指路耐久审批门 `POST /v1/approvals/:sessionId/decide`;live 应答口 `POST /v1/tool-approvals/:id/respond` 的停驻臂受理之后不在问行上留记录(副本内一小时的进程内回执)。
|
|
309
|
+
新形:非直连门部署上,决断口对门仍开着的停驻形交与 live 应答口停驻臂同一只赎回 —— 受理 `200`(`accepted:"parked_redeemed"`),门上已站着一次决定 ⇒ 同 `idempotencyKey` `200` 回放首决、否则 `409 conflict.ask_decided`;停驻赎回的拒(`429` 成本配额 + `Retry-After` / `503` / `409 approval_stale` …)原样。两扇门受理之后都把决定(决议向 · 署名 · 理由 · 回决幂等键 · 出处)写到这只问仍 `PARKED` 的行上(态不变;问表既有的 `decision` / `decision_actor` / `decision_note` / `idempotency_key` / `settled_by` / `decided_via` / `decided_at_ms` 列)。直连门部署(决定要签名信封)上门仍开着的停驻形照旧 `410 gone.ask_parked`(门上已站着决定的那一形同样改答 `409 conflict.ask_decided`)。显式运维(`OPERATOR_PRINCIPALS`)代决别人的停驻卡与活卡同放(此前停驻形不放)。
|
|
310
|
+
**谁需要**:经决断口回决审批卡的壳 / SDK —— 停驻之后不必再读 410 换口、换身份,重发按同一把幂等键在两形上同答,跨副本成立。
|
|
311
|
+
**谁受伤**:按 `410 gone.ask_parked` 判「窗已关、去别处答」的壳(非直连门部署上同一请求现在直接被受理,或得到首决回显的 `409`);对 `PARKED` 问行的 `decision` 列做「为空 = 没人决过」判断的旁读者(本服务自己的读面不这么读:已决读法只认 `DECIDED` 行与停驻门本身)。
|
|
312
|
+
**出路**:壳把 `200 accepted:"parked_redeemed"` 读作「已受理、续跑开始」,把 `409 conflict.ask_decided` 读作「已有首决」(与活问同一套处置);旁读者对 `PARKED` 行读停驻门的状态(按问读口 `GET /v1/tool-approvals/:id` 的 `state`),不读 `decision` 列。live 应答口与呈卡帧的 `approvalId` 下一版退役 —— 现在就改用决断口。
|
|
313
|
+
**升级前做**:无。**回滚**(本版 → 7.150.x):SQL 后端(`mysql` / `pg`)照读 —— `PARKED` 行上多出来的列值上一版不读;`DB_BACKEND=local` 上问账账本(`<数据根>/approval-asks/asks.jsonl`)里一旦有本版写下的停驻落行记录(新动词 `recordParkedDecision`),上一版**启动即拒启**并点名(「a newer server wrote it」)—— 回滚步骤:① 停接新任务,等审批收敛(`GET /v1/approvals` 的 `pending` / `livePending` 都空);② 让本版继续跑到账本到阈压实(压实后只剩行快照,上一版读得动),或停机把 `asks.jsonl` 移开(已收敛的部署上只丢已决历史);③ 再启上一版。
|
|
314
|
+
|
|
315
|
+
3. **workflow 子代停驻卡:持有它的 run 仍在跑时,每一次决断先落成一条耐久决定行(落在那条 run 的记录行锁里,同一张卡先受理的决定立住,另一个决定答 `decide.claim_lost`);不持有它的副本不再起宿主一跑,由持有副本在一个维护周期(`REAP_INTERVAL_SEC`)内交给那条 run,run 先收场则经 run 的完成送达交给宿主会话的下一跑(行为变更;单副本上三处角落的答复变;wire 零新键、零新码;无 DDL、无迁移步;部署零动作)**:
|
|
316
|
+
旧形(7.148.0–7.150.x):`/decide` 只在跑那条 run 的进程里把决定交给它;别的副本上的决断走续跑车道 —— 答 200(`taskId` = 宿主新一跑)、起宿主一跑,那一跑的 `Workflow({resumeFromRunId})` 被引擎以「记录仍在跑」拒,`parked: true` 挂到 run 在持有副本上自己收场;同一张卡的两个不同决定落在两只副本上时,可能一个答过 200、引擎用了另一个。
|
|
317
|
+
新形:持有这张卡的 run 的记录读作 `running`(任一副本读)⇒ 决断先在那条 run 的记录行锁里落行(记录仍持有这张卡才落;先受理的决定立住、之后不被取代),答 200 `{ taskId: <workflow run id>, status: "resuming", decision }`,不起宿主一跑;跑那条 run 的进程当场(决断恰落在它)或下一个维护拍把行交给引擎;run 先收场 ⇒ 完成送达(至少一次,失败在维护拍上重投)把行交给宿主会话的下一跑 —— 这一跑由服务端起:以卡属主为主体,宿主停在 `task_done` 卡上时那张卡须同属主,付费方两门(费用额度 / 服务租约)照判、拒即不起(一行 `workflow_park_handoff_refused`,行留着、卡可再决)。记录已不读作 `running` ⇒ 续跑车道,与上一版同。
|
|
318
|
+
单副本上也变的三处角落:引擎此刻读不出这张卡 —— 503 `decide.store_unreachable` → 200;run 此刻不在这张卡上等(正在收场)—— 409 `decide.gate_moved` → 200;run 正在挂起 —— 200 体由续跑车道那一形(`taskId` = 宿主新一跑)变成活臂那一形(`taskId` = workflow run id)。带 `mcpServers` / `a2aPeers` 决、记录读作 `running` ⇒ 照旧 400 `decide.parked_restatement_unsupported`,但不再先探引擎(上一版卡恰离开 pending 时答 409)。其余成功形与拒码不变。
|
|
319
|
+
**谁需要**:SQL 后端 ≥ 2 副本、负载均衡不按子会话粘的部署 —— 决定在一个维护周期内生效,不再挂到 run 自己收场,也不白烧一次模型调用;单副本上恰在 run 收场那一窗里的决断。**谁受伤**:① 跨副本决定生效延迟 ≤ 一个维护周期(每拍至多 64 条,超出的轮到下一拍);② run 带着已受理的决定收场时,宿主会话上多一条服务端起的 run,计费给卡属主;③ 按那两处 503 / 409 角落做重试、或按 200 体 `taskId` 去轮 `GET /v1/runs/:id` 的端(活臂那一形的 `taskId` 不在 run 店里,读 `GET /v1/workflows/:taskId`);④ 持有进程死掉、或 run 收场了而终态记录没写进去(记录仍读作 `running`)⇒ 行等孤儿窗(`WORKFLOW_ORPHAN_GRACE_MS`,缺省 24 h)翻 `failed` 后才交出,其间 `parked: true` 挂着;`WORKFLOW_RUN_STORE=memory` 没有完成日志 —— 要重投的转交(宿主会话正忙等)不重投,一行 `workflow_park_handoff_not_redelivered`,完成照常推进会话,决定由宿主会话的下一跑带,或再决一次。
|
|
320
|
+
**补偿 / 出路**:要更短的跨副本生效延迟就调低 `REAP_INTERVAL_SEC`(同一拍的其余维护各腿一起变快、库读一起变多);收场转交那一跑就是这条已受理决定的去处(上一版要人再决一次),没有关掉它的旋钮;费用额度超顶 / 服务租约耗尽、属主不一致、宿主续跑输入已被回收 ⇒ 不起、一行 `workflow_park_handoff_refused` + 计数 `workflow_park_handoff_total{result}`,行留着、卡可再决;会话正忙、服务租约中心不可达、库瞬态 ⇒ 下一个维护拍重投。没有新旋钮。
|
|
321
|
+
**升级**:本条在段头升级清单之外零动作 —— 本条零手工 DDL(决定行的列不变:记录栅栏落的行 `delivered_task_id` 写 workflow run id,同宽同列)、一次性迁移无、停-迁-起无,可滚动,任何换版顺序都不比上一版差。**混跑窗**(新旧副本并存):跨副本决断仍按上一版的行为 —— 新副本落行、答 200,持有那条 run 的若是旧副本 ⇒ 没有拉取、没有收场转交,决定挂到 run 收场后宿主下一跑或再决;旧副本对读作 `running` 的记录照旧整行取代决定行,可能盖掉新副本按「先受理者立」落下的那一个。全部副本升完后新行为生效。**回滚**(本版 → 7.150.x):记录栅栏落的行旧版照读(同列同形);旧版的回执幂等判对 workflow run id 读不到在跑的一跑 ⇒ 照起一跑,与上一版同。
|
|
322
|
+
|
|
323
|
+
4. **登记簿默认读层(项目登记的 `defaultScopes` 作一条 run 记忆面的额外读层)只取提交者看得见的登记;判出的种子(哪只项目 + 判出它的那一位观者)随 run 冻结,续跑以冻结的观者重判 —— **升级前已停驻、带 `projectId` 的 run 续跑不带默认读层(运维 warn 一行 `resume_memory_seed_unjudged`);要默认读层,重提交**(安全轴,fail-closed;行为收紧;续跑上下文多一格服务端写的兄弟键;wire 零变化;部署零动作)**:
|
|
324
|
+
射程:接了配置中心(有项目登记簿)且记忆面点亮的部署;多租 / 多登记者部署上提交别人登记的项目 id 的调用方;升级时仍停驻、升级后续跑的 run。
|
|
325
|
+
旧形:默认读层按提交体的 `projectId` 直接查登记簿,不判这只登记对提交者可不可见(读面 `GET /v1/projects/:id` 答 404 的项目,它声明的 scope 词照样进这位调用方的读层;`org:` 键进记忆准入、目录不给时拒句点名它);停驻后续跑按存体的 `projectId` 现查一次。
|
|
326
|
+
新形:新提交腿判一次 —— 默认读层只取对提交者可见的那只提交项目(与读面同一只判:fleet 调用方看全部,带验过主体的调用方只看 `registeredBy` 是自己的),看不见与未登记同答(没有默认读层、不拒、拒句不点名);判出的种子随 run 写进续跑上下文(兄弟键 `memorySeed`:项目 id + 那一位观者;提交带了 `projectId` 而判不出 ⇒ `null`「判过,无」),续跑以冻结的观者经同一只判读此刻的登记(改了词 ⇒ 新词;删了、换了主人、不再对他可见 ⇒ 没有默认读层);本版之前写下的停驻行没有这一格 ⇒ 续跑不取默认读层(不回填:那时没有判过可见性),存体带 `projectId` 的每一条续跑腿记运维 warn 一行 `resume_memory_seed_unjudged`(`sessionId` + `projectId`,不带 scope 词;判过的、不带项目的续跑不记);这一格形不对 ⇒ 续跑答 500 `corrupt`(`where` 点名 `memorySeed`)。不经 HTTP 直调装配器的嵌入方没有观者 ⇒ 没有默认读层。
|
|
327
|
+
**谁需要**:多租 / 多登记者部署(一位调用方不该经默认读层读到别人登记的项目声明了什么)。
|
|
328
|
+
**谁受伤**:提交别人登记的项目 id 的调用方(默认读层没了,`org:` 键不再进准入);升级时仍停驻的 run(续跑少了默认读层,不拒、不报错);直调装配器的嵌入方;团队成员用管理员登记的项目(与读面同答,放宽可见性是另一件设计)。
|
|
329
|
+
**升级前自查**(一行):要默认读层跨过升级仍生效的停驻 run ⇒ 升级前决掉,或升级后作为新任务重提(升级后按 `resume_memory_seed_unjudged` 一行找出是哪几条)。**出路**:由登记人本人或 fleet 调用方(不报主体的 service 凭据,部署没声明 `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT=false` 时)提交。**回滚**:回到上一版即回到旧形(上一版不读这一格、原样带着,续跑按存体的 `projectId` 现查);零配置、零库形变化。
|
|
330
|
+
|
|
331
|
+
5. **SQL 店的失败对外只说「原码 + 稳定句」,而且在店边界就换句:子代结算卡、后台子代通告、子代回读、父模型读到的子代失败文本、文件历史与记忆补丁的失败句不再带库驱动的原话(行为变更;安全;运维面:库的原话挪到 `at=store` 日志行;只带数字错误号的驱动错终局码变;一次性迁移 M53)**:
|
|
332
|
+
射程:`DB_BACKEND=mysql|pg` 的部署;本地文件后端(`DB_BACKEND=local`)的店不拨 SQL、不在射程内(它们的 fs 错照旧)。
|
|
333
|
+
旧形:run 终局自 7.148.0 起是「<类别句> [original code: <码>]」,但子代结算卡 `errorMessage`、后台子代 `<task-notification>` 摘要、`GET /v1/runs/:id/subagents/:handle/output` 的 `content` / `output`、父模型读到的子代报告行、文件历史逐文件失败句、记忆补丁冲突 `reason`(经记忆同步回给对端)逐字带库驱动的原句(库账号 / 内网地址 / 表名 / 约束名);只带数字错误号、没有符号码的驱动错(TiDB 自有号)终局 `terminal.code` 缺席、`message` 是库的原句;检查点行太大的 `store.row_too_large` 与提交腿的 413 句括号带库的原句。
|
|
334
|
+
新形:这些面与 run 终局同一句(驱动没给码时只有类别句);只带数字错误号的那一形原码取那个数字的十进制串,`terminal.code` 是 `internal.store_error`;413 句不再带库的原句(墙由 `wallSource` / 错误的 `wall` 说)。会话店的 `storage` 失败码、撞键 / 死锁 / 行太大的判决与引擎的语义码不变。库的原话在 worker 日志的店边界那一行:`[terminal] outward_failure_code_folded … at=store site=<店>.<方法> class=<类别> message=<JSON 串>`(经出口座脱敏、有界),计数 `store_boundary_fault_total{site,class}`;`at=exit` 那一行的 `message=` 已是对外句。
|
|
335
|
+
存量:一次性迁移 M53 改写有结构标记的两格(见本节升级清单);父转录、卡外的 `output` 报告行、workflow 节点句等自由文本**不改写**(改写用户转录是数据完整性风险)—— 本版之前落盘的这些面仍可能带库的原话,出路 = 按留存清理,或运维手删那些行。
|
|
336
|
+
**谁需要**:多租户部署里读子代卡、通告、回读与父模型内容的人与集成方。
|
|
337
|
+
**谁受伤**:按这些面上的库原话排障的运维;按失败句文本分支的消费方;文件历史 rewind / restore 在工作区读写失败(权限拒、文件不在)时的逐文件失败句也换成类别句;按码形分支、没见过纯数字原码的消费方。
|
|
338
|
+
**出路**:判别一律读码;要库的原话读 `at=store` 那一行(按 `original=` 与时间对 `at=exit` / `request_error` 行);工作区失败的路径在同一条目的 `path` 上。
|
|
339
|
+
**升级前做**:无。**回滚**:回到上一版即回到旧形(本版 M53 改写过的格保持对外句,旧版照读,不拒)。
|
|
340
|
+
|
|
341
|
+
6. **会话附随物绑住客:推送落定之后的文件历史 / 会话规则 / 回退锚 / 行两位、运行腿的回退锚、自动标题、规则写口,只写在判过的那一位住客(属主 + 化身)上;拉取 / 推送口门后复判住客;暂存提交按住客 CAS;规则店 / 文件历史店 / 回退锚店只经后端读、一只后端各一只实例(安全轴;行为收紧;嵌入方类型面硬破坏三处;wire 零新键、零新码,新增可达的既有答复四处;零 DDL;部署零动作)**:
|
|
342
|
+
规则:附随物只经落定段写 —— 段首锁会话根行与旁表行,用行格写原语的同一只判官比住客(行在 ∧ 非在删 ∧ 非委派分区 ∧ 属主与化身整对同),同一事务写;不是那一位 ⇒ 零字节写。读侧:门读到住客 ⇒ 门后每个非故障出口发出之前复判;门判空闲 id ⇒ 门后不读这只 id。
|
|
343
|
+
**嵌入方(自建 `StoreBackend`)**:`StoreBackend.landedAttendants()` 改为必选成员(类型面硬破坏,编译红即通告;包根导出 `LandedAttendantSeat` 及其参数 / 结局型)。它交回落定席位:在锁住会话根行、判过落定住客的段里写一次推送的文件历史、会话规则、回退锚与 `PUT …/policy` 的规则(随包 SQL 两方言与 local 后端都已带)。JavaScript 后端缺这一员 ⇒ 第一次推送 / 规则写在写下任何字节之前抛(500)。同一处的会话店签名随之变(同为编译红):`exportEntriesStream(id, { afterSeq?, batchSize?, recheck })` 的 `recheck` 必带(每页交出之前调一次,抛 ⇒ 流结束);`setTitleIfNull(id, title, landed)` 多一个落定住客(行不是那一位 ⇒ `false`、零写);暂存提交的选项 `expectedOwner` 换成 `expectedOccupant`(属主 + 化身;门判「无此会话」⇒ 缺席)。`ResumeAnchorStore` 读面不再带 `put`,锚只经席位写。**附随店只有一条读法**:`ServiceDeps` 删 `sessionPolicyStore` / `fileHistoryStore` / `resumeAnchorStore` 三键(编译红即通告)—— 服务面(规则口、能力位、同步族、rewind 口)读 `ServiceDeps.backend` 的 `sessionPolicy()` / `fileHistory()` / `resumeAnchor()`;后端对这三只与 `landedAttendants()` 各恒交同一只实例,席位写的就是读口交出的那一只(自建后端同守:写经一只、读经另一只 ⇒ `PUT …/policy` 答 200 而 `GET` 与引擎读不到这条收紧)。`StoreBackend.sessionPolicy()` 不再收 logger:SQL 规则店的封键 warn 经 `createStoreBackend(config, onWarn, …)` 的 `onWarn`(缺席 ⇒ 日志出口接缝的缺省 logger)。出路:删掉这三键(它们原就是后端的投影,带 `backend` 即可);要换店,换后端交的那一只。
|
|
344
|
+
**客户端**:推送在条目已提交之后可能答 `409 conflict`(`sync conflict`,不带 `relation`)—— 其间会话被删、或同 id 被重建(含同一属主);与其它同步冲突同一出路:从第一段重来。拉取可能答 `404`(与「门后被删」同体)、或 `entries` 流无尾行结束(读作截断),原因同上;重拉。暂存提交只落在第一段判过的那一位住客(属主 + 化身)上,不再只问属主 ⇒ 同一属主在条目流式上传期间删建同 id,提交答 `409 conflict`。在删会话上的 `PATCH`(标题 / 置顶)答 `404`;规则写口 `PUT /v1/sessions/:id/policy` 门后会话被删 / 重建答 `404`。
|
|
345
|
+
**谁受伤**:在删建竞态里推拉的客户端新碰到上面几只既有答复;自建后端的嵌入方编译红。自建 `ServiceDeps` 的嵌入方:上面三键编译红;没带 `backend` 的 `ServiceDeps` ⇒ 能力位 `sessionPolicy` / `restoreFiles` / `resumeAt` / `rewindFilesTo` 读作假、`GET` / `PUT /v1/sessions/:id/policy` 两口答 501 `capability.session_store_required`、会话同步族答 501(此前注入了店就照常):附随店只经后端读写;随包装配里这几只店本就只在有后端时才铸、HTTP 面拿到的是同一只后端,所以随包的部署形够不到这一形 —— 出路是交 `ServiceDeps.backend`。**出路**:见上(全是既有出路);运维按 warn `session_sync_landed_occupant_gone` 与计数 `session_sync_landed_occupant_gone_total` 分诊。
|
|
346
|
+
**存量数据**:本版之前已经落下的迟到写(推来的历史发布进了重建的会话、空闲 id 上留下的行)与常规行分不开,原样保留。
|
|
347
|
+
**混版窗**:还在上一版的副本照上一版的行为写;旧副本全部下线之后本条的保证才成立。
|
|
348
|
+
**已知限制**:fork 子会话第一次跑时从源会话承接文件历史,不问源会话此刻还是不是 fork 时的那一位(这一半归引擎,本版不闭)。
|
|
349
|
+
**升级前做**:无。**回滚**:回到上一版即回到旧形;无存储形变化。
|
|
350
|
+
|
|
351
|
+
7. **停-迁-起迁移:守卫一律先于一切写、放行时记一条起服要求;证据读法常设(行为变更;持久面:`serving_requirement` 开始有写者、存词闭集只剩 `in_force`;wire 零新键、零新码;部署零动作)**:
|
|
352
|
+
旧形:几只停-迁-起守卫各在自己那条迁移的步里判证据 —— 排在后面的守卫拒启时,前面的迁移可能已经改了库(例:M40 已把退役车道词改名,M51 的守卫才拒,拒句仍说「Nothing was changed」)。`serving_requirement` 只有读者(起服准入),本服务不写;存词两词 `pending` / `in_force`(`pending` 从没有写者)。停-迁-起证据读法(判活窗内心跳过、持有者没登记为知道该条迁移的 `running` run)登记为一次性迁移 M52,窗 2026-12-09 关,关后删除 —— 删的是守卫唯一的证据。
|
|
353
|
+
新形:每条停-迁-起迁移在登记表里声明围栏类 —— `structural`(第一步改表,让更早副本点名旧对象的写当场失败)/ `per-write`(更早至少一版发出的写句自己读要求)/ `accepted`(成文的残余);本版的四条(M40 · M41 · M42 · M51)都是 `accepted`。起服时,迁移锁内、准入复核之后、第一步迁移之前,本构建所有还欠的停-迁-起迁移按登记序(M40 → M41 → M42 → M51)逐条判证据,任一有 ⇒ 拒启(码与句是那一条自己的),迁移段一字节不写;都没有 ⇒ 各条在自己的第一笔改动之前记 `(<迁移名>, in_force)`。之后缺这项能力的构建(本服务 7.150.0 起)起服拒 `config.serving_requirement_unmet`(`capability_missing`);起服拒句的升级清单在 `ALTER` 一步之前多一步,点名这只库要求而本构建没有的能力,并写明照清单补语句不会让缺能力的构建变安全(给蓄意回滚的删行语句)。证据读法不再是一次性迁移、没有删除日期:早于副本登记的副本持有的在跑 run 在任何日期之后都仍算证据。存词 `pending` 退役:读到它按 `in_force` 拒、拒句点名原词;`in_force` 那半句改成「a build that has it was admitted on this database and may have changed data for it」。M42 的 `older_replica` 拒句改成不再断言「没有存量身份带保留前缀」(守卫在扫描之前判):「this version reserves the prefix … and checks stored identities for it once before recording a marker, but … Nothing was scanned or changed and no marker was written.」
|
|
354
|
+
看不见的边(不变,如实):没有在跑 run 的空闲旧副本看不见;停顿 / 与库断开的旧副本迟到的写,任何观察都关不上;准入挡起服者,不挡已在服务的副本,也不挡过了准入、放锁之后才开服的那一只;早于 7.150.0 的构建不读这张表。
|
|
355
|
+
谁需要:多副本滚动升级的 SQL 部署的运维 —— 守卫拒启一定是零写的拒;一条停-迁-起迁移放行之后,缺这项能力的构建(回滚、滚动里晚到的上一版)起服即拒;此后引入的停-迁-起迁移仍看得见忙着的旧副本。谁受伤:滚动升级中仍有旧副本在跑的部署 —— 新形下同一只库可能先看到另一条的拒(按登记序第一条欠且有证据的那一条;例:同时欠 M40 与 M42 时先见 `config.execution_lane_rename_refused`);同时有以保留前缀 `_scn:` 起头的存量身份与在跑旧副本的库,先看到的拒因从 `stored_prefix` 变成 `older_replica`(全停之后再起,下一次起服才点名命中);跳版直升、还欠 M40 / M41 / M42 / M51 的库在本版第一次起服多落一行要求(7.150.0 起的构建都带这四项能力,照常起);蓄意回滚到缺某项能力的构建要先按拒句删那一行;按拒句全文匹配的脚本。补偿:拒启响亮、拒句点名能力与删行语句;停光旧副本再起(不变);按码分支,不按句子分支。
|
|
356
|
+
**升级前做**:无(段头升级清单)。**回滚**(本版 → 7.150.x):7.150.0 认得这四项能力,准入照过,记下的要求行无害地留着;更早的版本不读这张表。
|
|
357
|
+
|
|
358
|
+
8. **fleet 成员只收本空间签发的登录令牌:令牌验过签而 `scope` 不是本 worker 所绑的 `FLEET_SCOPE`(缺席 = 缺省 scope)⇒ 整次请求 403 `auth.scope_mismatch`;非 fleet 成员不比对(安全轴,fail-closed;行为变更;wire 新码;零旋钮)**:
|
|
359
|
+
旧形:登记中心的登录令牌只要验过签就挂上身份,不论它是哪个空间签发的;`FLEET_SCOPE` 只被排空口读。
|
|
360
|
+
新形:本 worker 是 fleet 成员(设了 `FLEET_GENERATION`)时,登录令牌的 `scope` 必须等于 `FLEET_SCOPE`(没写 `FLEET_SCOPE` ⇒ 缺省 scope),否则整次请求 403 `auth.scope_mismatch`(先于其余各门;`GET /health` 不拒,这枚令牌按没出示凭据分档;拒句不带本 worker 的 scope),运维日志一行 warn `auth_bridge_scope_refused` 带令牌的 scope、本 worker 的 scope 与主体;起服行 `auth_bridge_enabled` 多一格 `scopeAdmission` 说比不比。没设 `FLEET_GENERATION` 的引擎(手接、壳起的个人引擎)不比对,读法不变。同一枚 Bearer 恰好也是本部署的 service 凭据 ⇒ 按 service 凭据读,不答 403。
|
|
361
|
+
谁需要:按用户停用 / 移出空间停他名下工作的停止面 —— 本 worker 上每一条登录身份从此都属于它所绑的空间;多空间部署的租户边界。**谁受伤**:给 fleet 成员发别的空间登录令牌的部署(用户在 A 空间登录、手配了 B 空间 worker 的地址;一台 worker 有意服务多个空间);手写 `FLEET_GENERATION` 却没写 `FLEET_SCOPE` 的非缺省空间 worker(本空间的令牌也 403;编排器渲的受管引擎恒带两键,碰不上)。
|
|
362
|
+
补偿:令牌按本 worker 的空间签(登录到那个空间,或把请求发给令牌所在空间的 worker);手写成员 env 的补写 `FLEET_SCOPE`;不要比对的引擎去掉 `FLEET_GENERATION`。没有旋钮。
|
|
363
|
+
**升级前自查**(一行):在 fleet 成员上对旧版本的运维日志数一数 `auth_bridge_principal_accepted` 里 `scope` 不等于该 worker `FLEET_SCOPE`(没写即缺省 scope)的行 —— 非零 ⇒ 那些调用方升级后 403,先按上一条补偿处置;升级后看 `auth_bridge_scope_refused` 是否归零。
|
|
364
|
+
|
|
365
|
+
9. **web-admin 断言令牌的两键与主凭证同一只判官:`SEMA_WEB_ADMIN_ASSERTION_TOKEN` 与 `SEMA_WEB_ADMIN_ASSERTION_TOKEN_FILE` 都设 ⇒ 拒启;值键进本服务自有凭据的扣留名单,宿主子进程环境里不再有它(安全轴;行为变更:一条新拒启;wire 加性:`GET /health` 的 `center.assertionToken`、配置目录两行;部署零动作,除非两键都设)**:
|
|
366
|
+
旧形:本服务不读这一对键 —— 两键都设照常起服;值键不在配置目录里,`all` 继承的宿主子进程(容器 / 设备 CLI)拿得到它的值。
|
|
367
|
+
新形:接了中心(`SEMA_WEB_ADMIN_URL`)时按主凭证同一条二选一读这一对键(两键都设 ⇒ 拒启,拒句点名两键、不回显值);只读声明,不读文件内容、不向中心出示;`GET /health` 的 `center.assertionToken` 答 `declared` / `absent`,起服日志一行 `center_assertion_token`;值键是本服务自有凭据,子进程环境里扣掉。
|
|
368
|
+
谁需要:编排器与运维核受管引擎拿没拿到断言令牌;web-admin 生命周期事件的消费半(以它鉴权)。**谁受伤**:两键都设的部署(升级即拒启);在 `all` 继承的宿主子进程里读这只变量的脚本。
|
|
369
|
+
补偿:两键只留一个(编排器注入值键;手接引擎用文件键);子进程要的凭据经部署自己的按名放回通道给。
|
|
370
|
+
**升级前自查**(一行):`env | grep -cE '^SEMA_WEB_ADMIN_ASSERTION_TOKEN(_FILE)?=.'` 等于 2(两键都有非空值)的引擎,升级前删掉其中一个。
|
|
371
|
+
|
|
372
|
+
10. **写门问请求:只接了鉴权桥、没配 service 凭据的部署上,出示已验登录令牌的计费提交 / 改写门 / 破坏性会话写受理;没带过门凭据的请求照旧 503 `auth.service_token_required`,拒句改述(行为变更;安全轴不松;零新码、零旋钮)**:
|
|
373
|
+
旧形:fail-closed 写门只看部署配没配 `SERVICE_AUTH_TOKEN(S)` —— 没配就对每一个请求 503,哪怕请求带着鉴权桥验过的登录令牌;拒句「this worker requires a service auth token (set SERVICE_AUTH_TOKEN) before accepting …」。
|
|
374
|
+
新形:写门看这次请求 —— 带着 service 凭据或鉴权桥验过的登记中心登录令牌就过(直连门审批 principal 令牌不算),否则 503(`ALLOW_UNAUTHED_WRITES=true` 照旧放行;配了 service 凭据的部署上这样的请求照旧先吃全局凭据门的 401);拒句「this worker requires a service auth token (set SERVICE_AUTH_TOKEN) or a verified registry sign-in token before accepting …」。只接了鉴权桥的部署上,这类受理的 run 行 `source` 是 `sso`。全局凭据门不变(仍只由 service 凭据武装);没接任何过门来源的部署(零凭据 / 只开 `REQUIRE_PRINCIPAL` / 只配 trace 凭据 / 只开直连门)行为不变。
|
|
375
|
+
谁需要:用登记中心登录令牌认人、不配 service token 的部署。**谁受伤**:把这一码读成「worker 没配 service token」的告警脚本(只接鉴权桥的部署上它不再对已验调用方出现);按字面匹配旧拒句的消费方。
|
|
376
|
+
补偿:按码分支(码与状态不变);部署收哪几类凭据读 `GET /health` 的 `auth.kinds`(含 `sso` ⇒ 已验登录令牌过写门)。
|
|
377
|
+
**升级前自查**(一行):部署 env 里 `SERVICE_AUTH_TOKEN` / `SERVICE_AUTH_TOKENS` 都没值、而 `AUTH_BRIDGE_ISSUER` 或 `SEMA_WEB_ADMIN_URL` 有值 ⇒ 本条对它生效:先核告警 / 健康脚本有没有把 503 `auth.service_token_required` 当「没配 service token」用,改成按 `GET /health` 的 `auth.kinds` 判。
|
|
378
|
+
|
|
379
|
+
11. **🔴 bake-runner 的 bearer `BAKE_RUNNER_TOKEN` 是本包的自有凭据:`BAKE_ENV_ALLOW` 点到它或装着同一个值的另一个变量 ⇒ bake-runner 拒启;名单型旋钮的原文不再被当凭据值比(短名单的假警消失)(安全轴,fail-closed;行为收紧 + 告警订正;wire 零变化;部署零动作,除非 `BAKE_ENV_ALLOW` 点着 runner 令牌)**:
|
|
380
|
+
射程:bake-runner 进程(`BAKE_ENV_ALLOW`、它起的每一只子进程组);服务进程与 `run-local` 里装着 `BAKE_RUNNER_TOKEN` 的部署(与 bake-runner 同机、共用一份 env 文件);配了名单型旋钮(`LSP_ENV_ALLOW` / `HOOK_ENV_ALLOW` / 三只沙箱名单)的部署。
|
|
381
|
+
旧形:自有凭据声明只从配置目录派生,`BAKE_RUNNER_TOKEN` 不是目录行 ⇒ 缺省只靠形状剥不交给配方脚本,`BAKE_ENV_ALLOW=BAKE_RUNNER_TOKEN` 照解析、照放回给 `build.sh` 与主机命令,同值换名的副本照交;名单型旋钮的原文被当一枚凭据交引擎比值 ⇒ 不足 8 字符的名单(如 `LSP_ENV_ALLOW=GOPATH`)起服一行 `own_credential_value_not_withheld`、值能力位 `inherit_env.own_credential_values_withheld` 答 false。
|
|
382
|
+
新形:`BAKE_RUNNER_TOKEN` 与配置目录的 secret 行在同一份自有凭据声明里(三个进程同一份),按名与按值扣 ⇒ `BAKE_ENV_ALLOW` 点到它,或点到值等于它的另一个变量 ⇒ 拒启,`bake_runner_fatal` 一行 `env BAKE_ENV_ALLOW: entry #k of n is this deployment's own credential — …`(与点名别的自有凭据同一个开头,不回显值);任何子进程组都拿不到它与它的副本(副本那一半只对引擎收作凭据的值成立:短令牌 / 占位词只按名扣,见本段末句)。服务进程里装着它时同样不进模型驱动 shell(`inheritEnv:"all"`),五只服务侧名单点到它拒启,请求 `settings.env` 带这个键 ⇒ `400 request.env_credential_refused`(升级前停驻、存体里带这一键的任务续跑时由既有的一次性迁移窗剥掉照续,窗关之后同拒)。名单型旋钮原文只按名扣(旋钮变量照旧不进任何子进程),不再交引擎比值 ⇒ 短名单不再告警、值能力位如实;另一个名下装着同一串名单原文的变量不再被扣;名单型旋钮变量若被某条模型条目的 `apiKeyEnv` 指着(被当成密钥读),它的值照旧按凭据扣。runner 令牌不足 8 字符或是占位词 ⇒ bake-runner 起服多一行 `own_credential_value_not_withheld { name: "BAKE_RUNNER_TOKEN" }`(名照扣、不拒启)。
|
|
383
|
+
**谁需要**:跑 bake-runner 且配了 `BAKE_ENV_ALLOW` 的部署(runner 令牌不再能被放回配方脚本);配了短值名单型旋钮、被假警与 false 位困扰的部署。
|
|
384
|
+
**谁受伤**:`BAKE_ENV_ALLOW` 里写了 `BAKE_RUNNER_TOKEN`,或写了一个值与 runner 令牌相同的变量的部署(拒启);服务进程环境里也放着 runner 令牌、并让模型 shell / 名单 / `settings.env` 用到它的部署;按 `own_credential_value_not_withheld { name: "<名单型旋钮>" }` 计数的告警(这一形不再出现)。
|
|
385
|
+
**升级前自查**(一行):`BAKE_ENV_ALLOW` 不点 `BAKE_RUNNER_TOKEN`、不点与它同值的变量。**出路**:配方脚本要一枚凭据 ⇒ 给它铸一把自己的(名与值都不同于 runner 令牌)再点那个名;配方本来不读 runner 令牌,删掉那一段即可。**回滚**:回到上一版即回到旧形;零配置、零存储形变化。
|
|
386
|
+
|
|
387
|
+
12. **`cascade: true` 与 `rewindFilesTo` 同体的新提交在受理口答 `400 request.field_conflict`(`reason: "cascade_verify"`,`fields: ["rewindFilesTo","cascade"]`),此前受理(`POST /v1/tasks` 答 `200`、`POST /v1/runs` 答 `202`)而文件回退无处落地(行为收紧;wire 加性一面:状态 2xx → 400;部署零动作)**:
|
|
388
|
+
射程:`POST /v1/tasks`、`POST /v1/runs` 上,体里同时带 `cascade: true` 与非空串 `rewindFilesTo` 的**新提交**。`POST /v1/tasks/stream` 上带 `cascade` 的提交本来就答 400(同码);`verify: true` 与 `rewindFilesTo` 同体照旧受理(验证门的实现腿跑在提交的那只会话上);空串 `rewindFilesTo` 不是回退请求,不算同体。续跑腿一字不变(续跑重建本来就把 `rewindFilesTo` 整族剥掉)。
|
|
389
|
+
旧形:同体提交被受理,梯子起跑 —— 梯级每一级在引擎现铸的会话里跑、不带提交的那只会话,这只会话的历史不在梯级手里,文件回退无处落地;引擎视版本要么拒掉梯级,要么丢掉这一键、梯子照常跑完(后一种下场里调用方以为文件回到了旧边界,实际没有,也没有信号)。
|
|
390
|
+
新形:受理时 `400`,体根上 `{ reason: "cascade_verify", fields: ["rewindFilesTo", "cascade"] }`,句子 `rewindFilesTo is not supported with cascade (every rung starts a fresh session, so there is no history to restore files from)`;拒在任何副作用之前:不铸会话、不建 run 行、梯子一级都不起。未配梯子的部署上,同体提交(三口都算,含 `POST /v1/tasks/stream`)此前答 `400 request.precondition_unmet`,现在先答本拒(与 `resumeAt` × `cascade` 同序:请求形的冲突先于部署事实)。配了梯子的部署上,`POST /v1/tasks/stream` 上同体提交的 `400` 体根上 `fields` 由 `["cascade"]` 变 `["rewindFilesTo","cascade"]`,码与状态不变。
|
|
391
|
+
**谁需要**:用 `cascade` 提交、同时想让文件回到某条旧提问边界的调用方 —— 现在当场知道这一发做不到。**谁受伤**:同体提交者(此前 `200` / `202`,现在 `400`)。**出路**:去掉其一 —— 不要梯子就去掉 `cascade`,不要回退就去掉 `rewindFilesTo`;要先把文件回到旧边界再起梯子的,能力位 `sessionRewindFiles` 为真的部署上先走 run 外口 `POST /v1/sessions/:id/rewind-files`,再提交梯子。
|
|
392
|
+
**升级前做**:无(零配置、零存储形变化)。**回滚**:回到上一版即回到旧形(同体提交重新被受理);无存储形变化。
|
|
393
|
+
|
|
394
|
+
13. **续跑重放过现入口地板:`AUTONOMY=plan` 的部署上,停驻 run 被续跑之前体上的权限模式词照此刻的地板钳 —— 提交之后才改成 plan 的部署,与 7.121.x 及以前写下的停驻行,`bypassPermissions` / `auto` / `dontAsk` / 无词在下一次续跑钳成 `plan`;`plan_review` 批准写下的 `default` / `acceptEdits` 原样(安全轴,失效关闭;行为变更;wire 零新键、零新码;部署零动作)**:
|
|
395
|
+
旧形(7.122.0 起):`AUTONOMY=plan` 只在受理时盖进提交体,热改 / 重启时改档只影响之后提交的任务;停驻 run 的续跑(`/decide` · `/resume` · `/wake` · `plan_review`)照体里写下的词跑。7.150.0 上,7.121.x 及以前写下、体里是请求原词的停驻行同样按原词续跑。
|
|
396
|
+
新形:续跑之前体上的词过与受理同一只入口一步、读此刻的 `AUTONOMY`;被钳 = 钳到 `plan` 放行(不拒),钳过的词随续跑写回、之后照它读;那一腿的生效词看 `wiring_manifest.permissionMode`(钳制通告 `permission.entry_mode_clamped` 只在受理门发)。被钳进 plan 的 run 下一拍在 plan 里:写撞 plan 门,模型交计划后经 `plan_review` 批准出 plan(`permissionModeAfter` 照收)。体顶层写着地板的出口词(`default` / `acceptEdits`,批准写回只写顶层)⇒ 原样 —— 批过的计划不会被拉回 plan;只在 bundle `settings.permissions.defaultMode` 里的同字词照钳。
|
|
397
|
+
谁需要:设了(或事后改成)`AUTONOMY=plan`、有存量停驻 run 的运营者。**谁受伤**:改严之前以 `bypassPermissions` / `auto` / `dontAsk` 或不带词提交、此刻停驻的 run —— 续跑不再按原词放行,改在 plan 里继续;依赖「热改只影响之后提交的任务」的 HTTP 车道运维流程。leader 车道不变:那条车道的入口在 leader run 出生时读一次地板,停驻的 leader worker 续跑照写下的体重放(与 7.150.0 同读)。
|
|
398
|
+
补偿:不新增旋钮。要某条 run 按原词走完 ⇒ 改严之前把它决完 / 取消,或暂时改回原档位;leader 车道在飞的 run(含停驻的 worker)照出生时的词走完;要它们也停 ⇒ 取消那条 leader run。顶层的 `default` / `acceptEdits` 与批准写回同字、读不出是谁写的,照原样续跑;要它们也收紧 ⇒ `AUTONOMY=read-only`(按段只读)。回滚(本版 → 7.150.0):被钳过的行体词是 `plan`,7.150.0 照它读(仍在 plan 里,经 `plan_review` 出口),零动作。
|
|
399
|
+
|
|
400
|
+
14. **被拒的提交不再把它的工作目录、shell 环境、继承策略留在会话上(行为修复;wire 零变化;嵌入方 `ServiceDeps` 一键换名;部署零动作)**:
|
|
401
|
+
旧形:请求带的 `cwd`(或从项目登记簿继承来的第一条 `folder`)与 `settings.env` 在装配的第二步就登记到会话上;之后才被拒的提交(未知 / 不可用的历史锚、设置编译 422、会话被占 409、建行 409、执行放置拒、引擎在受理输入之前的拒 …)把它们留下,同一会话下一条不带 `cwd` 的提交在被拒那一条的目录里、带着它的 shell 变量跑。7.150.0 节「项目上下文继承」一条把继承来的 folder 这一半列为已知限制,本版起不再成立。
|
|
402
|
+
新形:三格(工作目录 · shell 环境 · `inheritEnv`)只在 run 认领之后、起跑之前写一次,工作目录写的是这条腿跑在的那一枚(请求带的 ?? 继承来的 ?? 会话上已登记的 —— 与它装配期的 hooks / 写门基准同一枚);写了之后引擎没有受理这次输入就收场的提交,在终局应答之前撤回这一笔(只抽掉这一笔,别的提交的写原样)。拒的码、句、状态、机读位逐字不变。
|
|
403
|
+
**谁受伤**:按「被拒的那一条也登记了 cwd」写过逻辑的客户端(每条提交照常带 `cwd` 即不受影响);自建 `ServiceDeps` 并传 `bindSessionInheritEnv` 的嵌入方 —— 该键退役(零别名),换成 `sessionBindings`(写一笔、按回执撤回或落定一笔的写座;缺席 = 没有登记簿,与旧键缺席同义)。
|
|
404
|
+
**升级前做**:无。**回滚**:回到 7.150.x 即回到旧形;登记簿是每副本进程内的,不涉及存储形。
|
|
405
|
+
|
|
406
|
+
15. **`config.d/remote-exec.json` 选定 host / local-docker 车道时,env 里同一车道的参数不再被无声丢弃:块 = env 读数 ∪ 文件格,同名格文件赢,文件与 env 在同一格上给了不同的值 ⇒ 一行 warn `remote_exec_file_overrides` 点名那一格的 env 键(行为变更:此前无声不生效的旋钮开始生效;wire 零新键、零新码;部署零动作,除非文件选车道的机器上设着本车道的 env 旋钮)**:
|
|
407
|
+
旧形(≤ 7.150.x):文件在场即终结车道选择,而文件腿只用文件里的格铸块 —— local-docker 只取 `image` / `mountPath`(或 `workdir`)/ `memory` / `cpus` / `network`,host 只取 `workdir` / `commandTimeoutMs`。env 里同一车道的其余参数(`DOCKER_MAX_CONTAINERS` · `DOCKER_PIDS_LIMIT` · `DOCKER_DROP_CAPS` · `DOCKER_COMMAND_TIMEOUT_MS` · `DOCKER_SANDBOX_ENV` · `DOCKER_PATH` · `DOCKER_HOST`、`HOST_COMMAND_TIMEOUT_MS`)不进块、不报:设了容器帽或 pids 限额,日志里一个字都没有,运行期无效。
|
|
408
|
+
新形:文件只定「哪条车道」。最终车道是 host / local-docker 时,块 = 该车道的 env 读数 ∪ 文件格,同名格文件赢(`image` ↔ `DOCKER_IMAGE`、`mountPath`|`workdir` ↔ `DOCKER_MOUNT_PATH`、`memory` ↔ `DOCKER_MEMORY`、`cpus` ↔ `DOCKER_CPUS`、`network` ↔ `DOCKER_NETWORK`;host:`workdir` ↔ `HOST_WORKSPACE_BASE`、`commandTimeoutMs` ↔ `HOST_COMMAND_TIMEOUT_MS`)。文件与 env 在同一格上给了**不同**的值 ⇒ 文件赢,运维日志一行 warn `remote_exec_file_overrides { provider, root, keys, note }` 点名被盖的 env 键(只点键名、不印值);同值复述、env 没设的格 ⇒ 零行。env 读数与 env 声明路径是同一只读者:同一条车道上坏值的处理与 `REMOTE_EXEC=local-docker` 逐句相同(容器帽小数 / 名单形错 ⇒ 拒启;`DOCKER_PIDS_LIMIT` 一类软旋钮的坏值 ⇒ warn 后回默认)。本步不为没被选中的车道读 env(文件选 `none` 或隔离车道时不求值 `DOCKER_*` / `HOST_*`;`REMOTE_EXEC` 声明的车道照旧在加载配置时求值,早于文件,那里的拒启不变)。`remote_exec_from_file` 与 `remote_exec_lane_preempted_by_file` 两行不变。
|
|
409
|
+
谁需要:用 `config.d/remote-exec.json` 选车道、又靠 env 调车道参数的 turnkey / 单用户部署。**谁受伤**:① 设了本车道 env 旋钮而一直被文件盖掉的部署 —— 升级后它们生效:容器帽满了新容器被拒(工具调用拿到 `limit.rate_exceeded` · `sandbox_capacity`),pids 限额与丢全部 capability 收紧沙箱,单命令超时生效,`DOCKER_HOST` 指向的守护进程被用;② 这些旋钮里有坏值而此前因不求值起得来的部署 —— 现在硬拒的坏值拒启、软旋钮 warn;③ 被文件换了车道之后环境里还残留旧车道之外的 `DOCKER_*` / `HOST_*` 的部署 —— 同样按最终车道读。
|
|
410
|
+
补偿 / 出路:升级前在文件选车道的机器上 `env | grep -E '^(DOCKER|HOST)_'` 自查;不要某只旋钮生效 ⇒ 从 env 去掉那个键;要 env 的值生效 ⇒ 删文件里同名的可选格(`image` 是文件里的必填格,只能改值)或让两处同值(同值不报);覆盖行点名的就是文件盖掉的 env 键。回滚(本版 → ≤ 7.150.x):旋钮重新被文件腿无声丢弃,回滚前先确认没有靠这些 env 旋钮兜底的安全限额。
|
|
411
|
+
|
|
412
|
+
16. **host 车道的工作区座只锚不折、托管判按内核答:`HOST_WORKSPACE_BASE`、请求的 `cwd`、委派给子代的工作目录里写的 `..` / `.` 不再先按字面折叠,由文件系统解(行为变更;wire 零变化;部署零动作,除非工作区座里写了 `..` / `.` 段)**:
|
|
413
|
+
射程:`REMOTE_EXEC=host` 的部署。工作区座 = 起服时的 `HOST_WORKSPACE_BASE`、单用户 host 部署上请求带的 `cwd`、委派子代沿用的父工作目录。
|
|
414
|
+
旧形:构造工作区时这三只座先按字面折叠(`<D>/bridge/../next` 读成 `<D>/next`,不管 `bridge` 是不是指到别处的链接);委派子代的目录落没落在父铸的临时根里,先按字面比、再按「先折后 realpath」比 —— 经链接 + `..` 拼进根里的子代目录可能被判成调用方自有目录(父收场时那只根被删),拼到根外的又可能被判成共持。
|
|
415
|
+
新形:座按写的原样(相对的锚在服务进程工作目录上),`..` 在走过链接之后由文件系统解 —— 与执行环境方法读路径同一种读法;托管判只按内核的 realpath。座是规整绝对路径(没有 `..` / `.` 段、没有重复或尾随分隔符)的部署,读到的工作区一字不变;win32 的盘相对座(`C:work`)照旧锚在那只盘的工作目录下。
|
|
416
|
+
**谁需要**:host 车道上委派后台子代、子代停驻在审批上等人批准后续跑的部署。**谁受伤**:工作区座写了 `..` / `.` 段、中间经过符号链接、依赖字面折叠落在字面那一只目录的部署 —— 现在落在链接那一边;座写了尾随分隔符 / 重复分隔符 / `.` 段的,交回的工作目录按原样带着这些字符;本机语言服务器找项目根那一步仍按字面折,这类座上可能选到字面孪生那一边的项目。
|
|
417
|
+
**升级前做**:自查 `HOST_WORKSPACE_BASE` 与调用方送的 `cwd` 里有没有 `..` / `.` 段;有就改写成要的那只目录的规整绝对路径(`realpath <座>` 的答案)。**回滚**:回到 7.150.x 即回到字面折叠;无存储形变化。
|
|
418
|
+
|
|
419
|
+
17. **远端执行车道:执行环境记住的拒改拼引擎可重试表之外的码(`env.*` 族加四码),会自愈的三形改拼可重试码;`connect` 幂等(行为变更;wire:错误码目录加四码、续跑腿恢复失败记录的 `code` / `retryable` 换;零新键;无 DDL、无迁移步;部署零动作,按码告警的运维改告警)**:
|
|
420
|
+
旧形(≤ 7.150.x):一只执行环境此后每次连接都答同一句的拒(k8s 快照桶不在、快照归档在桶里却取不回、集群在准入时拒了 pod、成员凭据中继建不起来、会话行不带住客令牌;k8s / e2b / local-docker 工作区填充的立定拒;k8s / e2b / local-docker / adb 环境答了自己的 `$HOME` 而与主张不符;ssh 主机密钥过不了钉的判)码都是 `connect_failed`;k8s 建 pod 撞配额(403 `exceeded quota`)与 adb 设备在重启 / 刷机途中的态是 `auth_failed`。已连的 k8s / adb / device 环境上再显式 `connect` ⇒ 第二只 pod / 再握手一遍 / 再准入一遍。
|
|
421
|
+
新形:立定的拒依次是 `env.snapshot_bucket_missing` / `env.sandbox_refused`(归档取不回、准入拒、中继建不起、填充立定拒)/ `env.occupant_missing` / `env.home_unconfirmed`(与 host 车道同一码)/ `env.host_key_rejected`,拒句逐字不变(只一处例外:会话行不带住客令牌那一形的拒句改点名它自己的出路 —— 给行补令牌或删会话);配额 403 与 adb 的 `bootloader` / `recovery` / `sideload` / `rescue` / `connecting` / `authorizing` 是 `connect_failed`(车道在自己的重试界内再试);device 生命周期面的 `device.claim_conflict` 是 `connect_failed`。已连的环境上再 `connect` 答当下的把手、什么都不建。从快照恢复的续跑腿遇上立定的拒:引擎不再重试这次恢复,失败记录 `remoteEnvFailures[].code` 是 `env.*` 码、`retryable: false`、`attempts: 1`;终局码仍是 `resume.env_failed`。ssh 主机密钥被拒:每只环境握手一次(此前每次操作重试满 `retry.maxAttempts` 轮)。
|
|
422
|
+
**谁需要**:接引擎准备期建立座的部署(引擎按可重试表判「立定」:不改拼,桶缺的 run 照起、每个工具都撞同一拒,配额 403 的 run 永远拒开,每个委派子代多一只 pod);读 `remoteEnvFailures[].retryable` 决定要不要再续跑的端。**谁受伤**:按 `connect_failed` 告警桶缺 / 准入拒 / 恢复不回 / 家目录不符 / 主机密钥不符的运维;按 `auth_failed` 告警配额 403 的运维;把 `remoteEnvFailures[].code` 当引擎词表闭集读的端。
|
|
423
|
+
**补偿 / 出路**:告警改按新码(或按拒句 —— 除上面那一处例外句子逐字不变,按 `snapshot_bucket_missing` / `SysctlForbidden` / `fingerprint mismatch` 之类的字面 grep 照旧命中);`env.*` 一族全部 deterministic、同步提交腿 409,出路在拒句里。没有新旋钮。
|
|
424
|
+
**升级**:段头升级清单就是全部动作,可滚动。**回滚**(本版 → 7.150.x):码回到旧拼法,零存储形变化。
|
|
425
|
+
|
|
426
|
+
18. **沙箱 / adb / 设备车道上的 path 附件附上内容;设备执行器可以实现一条新指令 `openBound`(行为变更,放宽;设备协议修订号 5 → 6,受理下沿仍 5;部署零动作)**:
|
|
427
|
+
射程:`REMOTE_EXEC` 为 e2b / k8s / local-docker / adb / device 的部署上(ssh 本版不变,见下),提交体 `userAttachments` 的 `{ path }` 条目。
|
|
428
|
+
旧形:这些车道上 path 条目照收,结局恒 `not_attached`(帧注 "cannot bind a read")。
|
|
429
|
+
新形:e2b / k8s / local-docker / adb 四条远端车道每一次读都重新打开并向目标的内核核对仍是判过的那只对象,对上了才附上内容;Linux 以外的远端目标、没挂 `/proc` 或缺 `timeout` / `readlink` / `stat` / `head` / `base64` 的目标照旧 `not_attached`。设备车道:执行器声明修订号 ≥ 6(`hello.protocolVersion`)**且**在 `hello.supports` 声明 `openBound` 才附上 —— 声明修订号 5 的执行器照旧受理,只是收不到这条指令、这一面缺席(四个 `op`、结局形与拒法见协议文档 §3.7;错误码只用你声明的修订号已有的词);**不要**用 `fileInfo` + `readBinaryFile` 仿真它 —— 不实现 ⇒ 该设备上 path 附件照旧不附。
|
|
430
|
+
**谁需要**:云上沙箱、adb 与设备部署上带 path 附件的会话。**谁受伤**:这些车道上 path 附件的内容进第一次请求 —— 带一批大文件的提交可能被整席拒「超出一次请求」(与 `host` 同律);每条附件多 2–3 次往返;读到一半变了大小的文件被拒;目录里有名字带换行的条目 ⇒ 这只目录列不出(整答拒)。
|
|
431
|
+
**ssh 车道本版不装绑定读(不变)**:ssh 部署上 path 附件照旧 `not_attached`。原因:ssh 目标可以是给不出那一次核对的 macOS / BSD 机器,这一面在场就答 `not_supported`,而 core 7.66.0 的计划文件读口把它当成读不了 —— 装上它,那类部署的计划模式会读不出计划文件。修在 core 一侧,随 core 7.68.0 到货后 server 下一版装回;本版部署零动作。
|
|
432
|
+
**出路**:少附、附小一点,或让模型自己用 Read 读;非 Linux 目标与 ssh 车道照旧。**升级前做**:无(零配置、零存储形变化)。**回滚**:回到上一版即回到旧形(path 条目恒 `not_attached`);无存储形变化;实现了修订号 6 的设备执行器对上一版按它 challenge 里的修订号声明 5,照旧受理。
|
|
433
|
+
|
|
434
|
+
19. **后台 run 里同步委派子代的问不再停驻(随引擎 7.66.1);7.150.x 期间已停驻下的子代问题卡决不了,可忽略、到期收走(行为修复;持久数据面:存量行不迁移、不改写;wire 零新键、零新码;部署零动作)**:
|
|
435
|
+
旧形(7.150.x,执行车道挂着 shell 或带出网工具的部署):`POST /v1/runs` 里父模型派 `Agent{run_in_background:false}`、子代问 AskUserQuestion、窗走完没人答 ⇒ 子代停驻,父收「status: suspended」,`GET /v1/approvals` 多一行子代的问题卡,对它 decide 带答或拒都答 409 `conflict.resume_context_unavailable`、行留着。
|
|
436
|
+
新形:同一构造子代读引擎的拒(`isError` + `notExecuted`)、接着跑,零新行;父 run 拿到子代真跑完的报告。父腿自己的问、连着的流上的同步子代、不可逆 / 出网调用的停驻都不变。
|
|
437
|
+
**存量行**:7.150.x 上停驻下的这类行 —— `toolName: "AskUserQuestion"`、`gateKind: "irreversible_ask"`、`taskId: null`、`sessionId` 是子代会话(不是任何一条 run 的会话)—— 没有续跑座,升级后仍决不了(带答 / 拒都 409、行不消);子代那一步早已随父 run 收场结束,被问的动作从未执行。它们可安全忽略:到行上的 `deadline`(建行 + 30 天,无人值守缺省)由检查点店的过期收割收走(既有收割器;`APPROVAL_TERMINAL_BACKSTOP_MS` 兜底同窗);不必手工删。
|
|
438
|
+
**谁需要** / **谁受伤** / **补偿**:同 CHANGELOG 本版同名一条(零新旋钮)。**升级前做**:无。**回滚**:回到 7.150.x ⇒ 挂 shell / 出网工具部署上的同步子代问重新停驻成决不了的卡(新停驻;已有的行两版同读)。
|
|
439
|
+
|
|
440
|
+
20. **随包 helm 图表不再替部署派生 `OPERATOR_SINGLE_USER`:单用户声明是显式 values 键 `server.operatorSingleUser`(布尔),它与 `server.requirePrincipal` 都没设 ⇒ 渲染即拒;`server.requirePrincipal` 缺省由 `"false"` 改为不设,图表只读它设没设、不再判词(部署面 BREAKING;安全轴收紧;图表 0.4.0 → 0.5.0;零服务端代码、零 wire;直接 `helm` 的部署升级前补一行 values,经 `sema-up` 装的部署零动作)**:
|
|
441
|
+
旧形(7.147.0–7.150.x):图表从 `server.requirePrincipal` 派生 `OPERATOR_SINGLE_USER`(未开 ⇒ `"true"`,开 ⇒ `"false"`),而 `requirePrincipal` 缺省 `"false"` ⇒ 什么都不写的 values 渲出「每个调用方都是运维」;`requirePrincipal` 只认 `"true"` / `"false"` 两词。服务端拒句里「不止一个人调用 ⇒ 设 `REQUIRE_PRINCIPAL=true`」那一道人判,对用图表的人永远不出现(MIGRATION 7.147.0 节第 3 条「谁受伤」③ 的形,图表绕过了拒句):忘设 `requirePrincipal` 的团队集群 `helm upgrade` 之后每个调用方成运维 —— 运维 / 记忆治理 / diagnostics / outcomes / 跨属主审批队列由 7.146.x 的人人 501 变人人可用。
|
|
442
|
+
新形:「谁是运维」是部署写的声明,图表不替它写 ——
|
|
443
|
+
· values 多一把显式键 `server.operatorSingleUser`(布尔 `true` / `false`;不设 ⇒ 不渲 `OPERATOR_SINGLE_USER`;设了 ⇒ 逐字渲给主 worker 与 v4pro 变体);字符串(含 `"false"`:模板里字符串恒为真)渲染即拒并点名那个值;
|
|
444
|
+
· `server.operatorSingleUser` 与 `server.requirePrincipal` 都没设 ⇒ `helm template` / `install` / `upgrade` 渲染即拒,拒句取服务端拒句的两条出路:一个人用 ⇒ `server.operatorSingleUser=true`;被不止一个人调用 ⇒ `server.requirePrincipal=true`;不静默二选一;
|
|
445
|
+
· `server.requirePrincipal` 缺省不再是 `"false"`:值原样渲给 `REQUIRE_PRINCIPAL`(没设仍渲服务端缺省 `"false"`),图表不再判它的词 —— `yes` / `1` / `on` 不再被图表拒,原样交服务端读;`operatorSingleUser=true` 与 `requirePrincipal=true` 同写才互斥,仍由服务端起服拒(不变量 `operator-single-user`),图表不抄那一判;`operatorSingleUser=false` 逐字渲(服务端读 `false` 与缺席同判),给自己 env 补了具名运维名单 `OPERATOR_PRINCIPALS` 的部署用它表态「我不声明单人」;
|
|
446
|
+
· `sema-up` 的 kube 两条 helm 路径(`kube-up` 与 `STACK_ENGINE=helm` 的 `cluster-up`)按 `--users` 把 `operatorSingleUser` 写进它生成的 values(single ⇒ `true`、multi ⇒ `false`):经 `sema-up` 装的部署渲出的 `OPERATOR_SINGLE_USER` 与上一版逐字相同,重跑 `sema-up` 即落新图表;compose 路径与 cluster 静态清单路径不变。
|
|
447
|
+
谁需要:被不止一个人调用的团队集群 —— 忘设租户词不再静默变成人人运维;一切直接 `helm` 的部署 —— 声明归部署。谁受伤:① 直接 `helm upgrade` 且没设 `server.requirePrincipal` 的单人部署:升级即渲染拒,补一行 `server.operatorSingleUser=true`(或命令行 `--set`);② values 里已有显式 `server.requirePrincipal: "false"`(手写的,或沿用上一次 release 值而带进来的)而没有新键的部署:渲染通过,但不再渲 `OPERATOR_SINGLE_USER`,单人 worker 起服拒(服务端拒句即出路),滚动更新停在第一只新 pod;钥匙卷是 `ReadWriteOnce` 时 Deployment 用 `Recreate` 策略,旧 pod 先停 ⇒ 补上这一键之前没有副本 —— 升级前先 `helm template` 同一份 values;③ 把 `server.requirePrincipal` 写成 `yes` / `1` / `on` 的部署:上一版渲染拒,本版放行并交服务端读成多租;④ 对着渲出清单做 diff 的工具:直接 `helm` 的多租部署的 `OPERATOR_SINGLE_USER` 由 `"false"` 变成缺席(服务端读 `false` 与缺席同判);经 `sema-up` 装的不变。补偿:渲染时的拒句就是出路,一行 values;经 `sema-up` 装的部署零动作。升级前做:直接 `helm` 的部署在 values 里加一行(单人 `server.operatorSingleUser: true`,多人 `server.requirePrincipal: true`),先 `helm template` 同一份 values 读结果(随包的 `values-full-single.yaml` 只是覆盖文件,示例命令行已带 `--set server.operatorSingleUser=true`,声明仍由你写)。回滚:回到上一版图表 ⇒ 仍从 `requirePrincipal` 派生,补的 `server.operatorSingleUser` 键上一版不读(无害);无持久数据。
|
|
448
|
+
|
|
449
|
+
21. **勘误(7.147.0 起的行为,该节漏写一条):会话驻留的后台子代理单步静默超过停滞窗 `BG_AGENT_STALL_MS` 就被引擎收成 `killed`(归因 `system`)、run 中止 —— ≤ 7.146.x 从不收(行为变更:杀掉在跑的工作;旋钮 `BG_AGENT_STALL_MS` 只许拉大;wire 零新键、零新码;部署零动作,除非部署里有单步静默得比窗长的后台子代理;已发的 7.147.0 节不改字节)**:
|
|
450
|
+
旧形(≤ 7.146.x):任务表里一直是 `running` 的后台子代理没有人收 —— 它只在干完、被停止、或随引擎受控退时结束;一次再长的 MCP 调用、一次再长的前台嵌套委派,只要引擎活着就一直等。
|
|
451
|
+
新形(自 7.147.0 起):每一次读在飞数(判停的每一拍、`GET /health`、崩溃遗言)之前,引擎先把**最后一次工具活动**距今超过窗的会话驻留后台子代理收成 `killed`、归因 `system`,它的 run 中止,运维日志一行 `background_agent_stall_reaped { reaped, stallMs }`;停驻的、随腿的、终态的行不收;多租户形(`REQUIRE_PRINCIPAL=true`)没有会话驻留的后台子代理,收割恒 0 行。
|
|
452
|
+
窗的算法:缺省 = 下限 = `max(600 s, max(STREAM_ASK_WINDOW_MS, UNREACHED_ASK_TTL_MS, QUESTION_TTL_MS, MCP_ELICITATION_TTL_MS) + 单命令上限)`,单命令上限 = 引擎解析出的 Bash 单命令上限(缺省 600 s;`BASH_MAX_TIMEOUT_MS` 抬高它,`BASH_DEFAULT_TIMEOUT_MS` 抬到它之上时它跟着抬)。窗取**四个等人窗里最长的那个**加单命令上限 —— 只调小其中一个,窗只缩到次长的那个:单用户形缺省 24 h 10 min(活审批卡窗 24 h);把 `STREAM_ASK_WINDOW_MS` 调到 60 s,窗缩到 1 h 10 min 就停了(没人在场时铸的审批卡窗 `UNREACHED_ASK_TTL_MS` 缺省 1 h 成了最长的);四个窗都在 60 s 以内才缩到 11 min(`UNREACHED_ASK_TTL_MS` 下限 60 s,`QUESTION_TTL_MS` / `MCP_ELICITATION_TTL_MS` 下限 1 s,`STREAM_ASK_WINDOW_MS` 可到 0),这也是缺省单命令上限下窗的最小值(`UNREACHED_ASK_TTL_MS` 低于 60 s 拒启)。`BG_AGENT_STALL_MS` 只许拉大:写得比这个下限小(含 `0`)⇒ 钳到下限并起服 warn 点名,没有「关」这一档;`GET /v1/config/catalog` 的 `BG_AGENT_STALL_MS` 行回显此刻的生效值。
|
|
453
|
+
「静默」的算法:只按子代**直属**的工具开始 / 结束算,每一次一拍,引擎按墙钟量。在审批卡 / 问答卡上等人、一轮很长的模型输出、一条很长的工具调用,在窗内都只是静默;等人的窗盖在派生里,所以一次等人本身不会越窗 —— 越窗的是单步里别的东西。
|
|
454
|
+
**谁需要**:共用一只本机引擎的部署(壳退后引擎要为还在干活的后台子代理留着,又不能被一只僵尸子代理永远留着)。**谁受伤**:单步静默得比窗长的合法子代理 —— 一次长 MCP 调用(引擎对它的时限缺省约 27.8 h,调用中的进度通知不算一拍)、一次前台嵌套委派(子委派里的工具活动与等人都不给这一行打拍,整段对这一行是一次静默)、一轮极长的模型输出;墙钟前跳或整机睡眠超过窗,醒来第一次读就把睡前之后再没打拍的子代理收掉。缺省读数(单用户形 24 h 10 min)下只有极端的长调用够得着窗;把四个等人窗调小的部署,窗缩到分钟级,十来分钟的 MCP 调用或嵌套委派就被收:run 中止、行落 `killed`,那一步不会续跑。
|
|
455
|
+
**补偿 / 出路**:把 `BG_AGENT_STALL_MS` 拉大到比部署里最长的一步更长(只许拉大;不必动四个等人窗);要让僵尸收得更快才调小那四个等人窗(没开审批 / 问答的部署,它们本来不起作用)。被收的子代理的 run 已中止、不会自动重试:引擎只拒绝续用用户停止的行,`killed` / `system` 的行不在其内 —— 有耐久行的命名子代理(或会话保留着的)可由模型 `SendMessage` 续用,其余重新起一只。每次收了几只读运维日志 `background_agent_stall_reaped` 的 `reaped` 字段;`GET /health` 的 `inflightBreakdown.backgroundAgents` 是收完之后还在跑的数,不是收掉的数。**升级前做**:盘点部署里有没有静默得比窗长的后台 MCP 调用或嵌套委派,有就先拉大旋钮。**回滚**:回到 ≤ 7.146.x 即回到不收。
|
|
456
|
+
|
|
457
|
+
22. **委派子代腿受中心按主体的收紧位约束:子腿与根腿问同一只按主体的运行期准入(安全轴收紧;行为变更;wire 零新键、零新码;部署零动作,接中心的部署见「升级前做」;第 19 条「新形」对被强制耐久门的主体不成立)**:
|
|
458
|
+
旧形(7.150.x 及以前,接中心且非 dry-run 的部署):中心按主体下发的运行期准入只在根腿生效;Agent 工具派的同步 / 后台子代、fork、复活的后台子代与观察者跑在另一只执行器上,那只执行器不问准入 —— 同一个主体在子腿上「不限」:fork 照起、强制耐久门不强制、观察者恒关;父腿跑着时中心收回的 bypass / auto 到不了此后派的子代;中心取数硬失败的 fail-closed 降级项(拒自编排 / fork / auto / bypass)到不了子腿。
|
|
459
|
+
新形:子腿与根腿问同一只准入,按同一个主体(子腿的主体从父腿继承)答 —— 中心对这个主体关掉的位在子腿上同样关;中心硬故障的降级窗里子腿同样拒;中心授予的观察者(或单用户部署 `EXPERIMENTAL_OBSERVER_AGENTS=true`)在子腿上也开。hook 子代理不变(服务自己的 run,不带主体)。没接中心或 dry-run 的部署上子腿只多本地合成层那几位(单用户 `EXPERIMENTAL_OBSERVER_AGENTS=true` ⇒ 子腿观察者开;`PERMISSIONS_DISABLE_AUTO_MODE=true` ⇒ 子腿 auto 拒;SQL 后端的记忆 opt-out 授权表每条子腿多读一次),都没开 ⇒ 零变化。leader 车道(`POST /v1/leader`)的执行器本版不在此列。
|
|
460
|
+
**谁需要** / **谁受伤** / **补偿**:同 CHANGELOG 本版同名一条(零新旋钮)。**升级前做**:盘点中心上对哪些主体关了 fork(`allowFork:false`)或开了强制耐久门(`forceDurableGate:true`):这些主体的子代此后同样被拒 fork、问按强制耐久门判(后台子代的问不先试连着的审批人、直接停驻,可 decide);⚠️ 被强制门的主体在持久审批部署上,**同步**子代没人答的问会停驻成一张决不了的卡(decide 409 `conflict.resume_context_unavailable`,到期收走)—— 这类主体让父腿自己问,或改派后台子代;要子代照旧,在中心给这个主体放开。**回滚**:回到 7.150.x ⇒ 子腿重新不问准入(上面「旧形」)。
|
|
461
|
+
|
|
11
462
|
## 7.150.0 —— 1–12 条见下
|
|
12
463
|
|
|
13
464
|
**升级清单(本节唯一的一张;下面各条只讲为什么,不再各自重述升级步骤)** —— 一次读清本版对一只存量部署要做的全部动作。每版同形:① 手工 DDL(逐表逐句,两方言各一份)② 起服自建与一次性迁移 ③ 停-迁-起 ④ 顺序;后续每版的段头照此写,新增一句 `ALTER`、一条一次性迁移、一条停-迁-起时,先改这里,再写条目。
|