@sema-agent/server 7.145.0 → 7.147.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATION.md +876 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +374 -99
- package/deploy/facts/CHANGES.json +25 -0
- package/deploy/facts/README.md +57 -0
- package/deploy/facts/lanes.json +61 -0
- package/deploy/facts/lanes.schema.json +57 -0
- package/deploy/facts/sandbox-rbac.json +113 -0
- package/deploy/facts/sandbox-rbac.schema.json +74 -0
- package/deploy/facts/sealed-key.json +9 -0
- package/deploy/facts/sealed-key.schema.json +52 -0
- package/deploy/sema-up/README.md +2 -2
- package/deploy/sema-up/chart/templates/_helpers.tpl +41 -0
- package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +47 -7
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +9 -4
- package/deploy/sema-up/chart/templates/server.yaml +9 -4
- package/deploy/sema-up/chart/values.yaml +8 -1
- package/deploy/sema-up/cluster-up.sh +2 -1
- package/deploy/sema-up/lib/flagshape.sh +4 -0
- package/deploy/sema-up/lib/lanes.json +2 -5
- package/deploy/sema-up/sema-up.sh +12 -9
- package/deploy/sema-up/stack/compose.yaml +5 -4
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +34 -17
- package/dist/adoption/import-limits.d.ts +6 -0
- package/dist/adoption/import-limits.js +7 -0
- package/dist/adoption/import.d.ts +62 -0
- package/dist/adoption/import.js +107 -0
- package/dist/adoption/wire.d.ts +52 -0
- package/dist/adoption/wire.js +9 -0
- package/dist/approval-ask-machine.d.ts +2 -2
- package/dist/approval-card.d.ts +7 -16
- package/dist/approval-card.js +0 -4
- package/dist/approval-gate-currency.d.ts +1 -1
- package/dist/approval-gate-currency.js +1 -1
- package/dist/approval-reconciler.d.ts +1 -1
- package/dist/approval.d.ts +3 -3
- package/dist/audit.js +2 -2
- package/dist/bench/s1/live-deps.js +3 -1
- package/dist/boot/crash-last.js +2 -1
- package/dist/boot/deployment-mods.d.ts +11 -1
- package/dist/boot/deployment-mods.js +15 -2
- package/dist/boot/device-lane.js +7 -5
- package/dist/boot/engine-lease.d.ts +195 -22
- package/dist/boot/engine-lease.js +146 -20
- package/dist/boot/execution-env.d.ts +5 -0
- package/dist/boot/execution-env.js +57 -33
- package/dist/boot/execution-lane.d.ts +37 -9
- package/dist/boot/execution-lane.js +74 -20
- package/dist/boot/exit-boundary.d.ts +50 -0
- package/dist/boot/exit-boundary.js +32 -0
- package/dist/boot/exit-last.d.ts +20 -4
- package/dist/boot/exit-last.js +23 -5
- package/dist/boot/governance-seams.d.ts +2 -2
- package/dist/boot/governance-seams.js +1 -0
- package/dist/boot/leader.js +1 -1
- package/dist/boot/memory-boundary.d.ts +11 -11
- package/dist/boot/memory-boundary.js +3 -3
- package/dist/boot/memory-consolidation.d.ts +42 -41
- package/dist/boot/memory-consolidation.js +26 -28
- package/dist/boot/org-memory.js +3 -2
- package/dist/boot/parked-revive-gate.d.ts +1 -1
- package/dist/boot/parked-revive-gate.js +1 -1
- package/dist/boot/reapers.d.ts +12 -4
- package/dist/boot/reapers.js +40 -16
- package/dist/boot/resolve-spec.d.ts +2 -0
- package/dist/boot/resolve-spec.js +126 -123
- package/dist/boot/retention-lane.d.ts +4 -42
- package/dist/boot/runner-deps.js +1 -1
- package/dist/boot/session-faces.d.ts +1 -0
- package/dist/boot/session-faces.js +11 -3
- package/dist/boot/shutdown.js +27 -9
- package/dist/boot/stage-01-config.d.ts +1 -1
- package/dist/boot/stage-01-config.js +7 -3
- package/dist/boot/stage-02-web-admin-pull.d.ts +1 -1
- package/dist/boot/stage-02-web-admin-pull.js +10 -8
- package/dist/boot/stage-03-store-backend.d.ts +2 -1
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +2 -1
- package/dist/boot/stage-05-execution-env.d.ts +4 -1
- package/dist/boot/stage-05-execution-env.js +6 -6
- package/dist/boot/stage-06-runners.d.ts +5 -2
- package/dist/boot/stage-06-runners.js +12 -13
- package/dist/boot/stage-07-capability-layer.d.ts +5 -2
- package/dist/boot/stage-07-capability-layer.js +7 -7
- package/dist/boot/stage-08-reapers.d.ts +5 -2
- package/dist/boot/stage-08-reapers.js +3 -3
- package/dist/boot/stage-09-leader.d.ts +6 -2
- package/dist/boot/stage-10-http-server.d.ts +6 -2
- package/dist/boot/stage-10-http-server.js +5 -3
- package/dist/boot/stores.d.ts +10 -0
- package/dist/boot/stores.js +53 -26
- package/dist/boot/web-admin.js +3 -3
- package/dist/boot/workflow-orchestration.d.ts +1 -1
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/capabilities/center-plugins.d.ts +2 -0
- package/dist/capabilities/center-plugins.js +6 -2
- package/dist/capabilities/composite-members.d.ts +4 -1
- package/dist/capabilities/composite-members.js +4 -1
- package/dist/capabilities/execution-lane.d.ts +7 -7
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +1 -1
- package/dist/capabilities/scenarios.d.ts +34 -20
- package/dist/capabilities/scenarios.js +13 -9
- package/dist/capabilities/settings-contract.d.ts +29 -0
- package/dist/capabilities/settings-contract.js +14 -0
- package/dist/capabilities/skills.d.ts +5 -5
- package/dist/capability-facts.d.ts +56 -1
- package/dist/capability-facts.js +59 -8
- package/dist/center-credential-renewer.js +3 -2
- package/dist/checkpoint-ctx-seal-m28.d.ts +1 -1
- package/dist/config-catalog.js +19 -9
- package/dist/config-invariants.d.ts +18 -3
- package/dist/config-invariants.js +36 -19
- package/dist/config-lkg.d.ts +1 -1
- package/dist/config-lkg.js +5 -6
- package/dist/config-provider.d.ts +2 -2
- package/dist/config-provider.js +2 -0
- package/dist/config-types.d.ts +228 -185
- package/dist/config.d.ts +74 -6
- package/dist/config.js +146 -64
- package/dist/degenerate-instrument.js +1 -1
- package/dist/deleted-session-ids.d.ts +19 -0
- package/dist/deleted-session-ids.js +26 -0
- package/dist/deploy-facts.d.ts +155 -0
- package/dist/deploy-facts.js +95 -0
- package/dist/deployment-shape.d.ts +21 -12
- package/dist/deployment-shape.js +24 -6
- package/dist/device-ws-hub.d.ts +48 -3
- package/dist/device-ws-hub.js +48 -2
- package/dist/env-facts.d.ts +7 -5
- package/dist/env-facts.js +10 -6
- package/dist/error-code-family.d.ts +35 -0
- package/dist/error-code-family.js +26 -0
- package/dist/execution-config-root.d.ts +5 -5
- package/dist/execution-config-root.js +5 -5
- package/dist/execution-env-purpose.d.ts +14 -0
- package/dist/execution-env-purpose.js +29 -0
- package/dist/execution-lane-caps.d.ts +49 -86
- package/dist/execution-lane-caps.js +52 -62
- package/dist/execution-placement.d.ts +18 -2
- package/dist/execution-placement.js +19 -0
- package/dist/file-history-disclosure.d.ts +2 -2
- package/dist/fleet/drain-entry.d.ts +46 -3
- package/dist/fleet/drain-entry.js +6 -0
- package/dist/fleet/fleet-bus.d.ts +2 -1
- package/dist/fleet/serving-lease.js +3 -4
- package/dist/history-anchor.d.ts +22 -0
- package/dist/history-anchor.js +14 -0
- package/dist/hooks/branch-transcript.d.ts +1 -1
- package/dist/hooks/branch-transcript.js +1 -0
- package/dist/hooks/classic-stations.d.ts +25 -8
- package/dist/hooks/classic-stations.js +29 -3
- package/dist/hooks/command-spawn.d.ts +1 -4
- package/dist/hooks/command-spawn.js +0 -11
- package/dist/hooks/hook-runner.d.ts +85 -24
- package/dist/hooks/hook-runner.js +326 -109
- package/dist/hooks/hook-source.d.ts +14 -2
- package/dist/hooks/hook-source.js +8 -0
- package/dist/http/active-run-conflict.d.ts +1 -1
- package/dist/http/active-run-conflict.js +1 -1
- package/dist/http/admission.js +11 -1
- package/dist/http/approval-sweeps.d.ts +2 -5
- package/dist/http/approval-sweeps.js +3 -2
- package/dist/http/checkpoint-ctx.d.ts +76 -71
- package/dist/http/checkpoint-ctx.js +40 -40
- package/dist/http/claim-latency.d.ts +10 -0
- package/dist/http/claim-latency.js +12 -0
- package/dist/http/dispatch.js +19 -3
- package/dist/http/durable-run-leg.d.ts +5 -0
- package/dist/http/durable-run-leg.js +3 -1
- package/dist/http/execution-context.d.ts +7 -1
- package/dist/http/execution-context.js +13 -0
- package/dist/http/health-self-report.d.ts +6 -2
- package/dist/http/health-self-report.js +3 -2
- package/dist/http/memory-compliance-failure-reply.d.ts +2 -2
- package/dist/http/memory-compliance-failure-reply.js +5 -15
- package/dist/http/memory-control-plane-corrupt-reply.d.ts +25 -0
- package/dist/http/memory-control-plane-corrupt-reply.js +19 -0
- package/dist/http/memory-store-refusal-reply.d.ts +3 -3
- package/dist/http/memory-store-refusal-reply.js +3 -0
- package/dist/http/owner-access.d.ts +11 -0
- package/dist/http/owner-access.js +7 -4
- package/dist/http/principal-gate.d.ts +28 -16
- package/dist/http/principal-gate.js +10 -19
- package/dist/http/request-guards.d.ts +2 -2
- package/dist/http/request-guards.js +5 -5
- package/dist/http/resume-legs.d.ts +29 -10
- package/dist/http/resume-legs.js +94 -56
- package/dist/http/rewind-files-reply.d.ts +34 -0
- package/dist/http/rewind-files-reply.js +36 -0
- package/dist/http/route-ctx.d.ts +43 -26
- package/dist/http/route-table.js +4 -0
- package/dist/http/routes/adoption.d.ts +11 -0
- package/dist/http/routes/adoption.js +80 -6
- package/dist/http/routes/agents-roster.js +1 -0
- package/dist/http/routes/approvals-assistant.js +7 -26
- package/dist/http/routes/background.js +1 -0
- package/dist/http/routes/capabilities.js +12 -3
- package/dist/http/routes/devices.js +1 -1
- package/dist/http/routes/diagnostics.d.ts +9 -14
- package/dist/http/routes/diagnostics.js +10 -20
- package/dist/http/routes/engine.d.ts +31 -0
- package/dist/http/routes/engine.js +81 -0
- package/dist/http/routes/memory-bundle.js +3 -0
- package/dist/http/routes/memory-consolidation.js +3 -5
- package/dist/http/routes/memory-origin.d.ts +2 -2
- package/dist/http/routes/memory-origin.js +2 -4
- package/dist/http/routes/memory-policy.js +5 -1
- package/dist/http/routes/notify-wake.js +2 -1
- package/dist/http/routes/observability.js +3 -6
- package/dist/http/routes/projects.d.ts +70 -0
- package/dist/http/routes/projects.js +86 -0
- package/dist/http/routes/rules.js +30 -2
- package/dist/http/routes/runs.js +15 -11
- package/dist/http/routes/session-sync.js +39 -35
- package/dist/http/routes/sessions-list.d.ts +1 -1
- package/dist/http/routes/sessions.d.ts +7 -1
- package/dist/http/routes/sessions.js +108 -2
- package/dist/http/routes/tasks.js +32 -8
- package/dist/http/routes/trace-usage.js +1 -1
- package/dist/http/run-concurrency-cap.d.ts +86 -0
- package/dist/http/run-concurrency-cap.js +54 -0
- package/dist/http/server.d.ts +31 -14
- package/dist/http/server.js +29 -3
- package/dist/http/stored-body-replay.d.ts +12 -7
- package/dist/http/stored-body-replay.js +28 -5
- package/dist/http/wire-types.d.ts +27 -13
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/instruction-source-notice.d.ts +1 -1
- package/dist/json-body-limit.d.ts +8 -0
- package/dist/json-body-limit.js +2 -0
- package/dist/leader/diffout.d.ts +1 -1
- package/dist/local-data-root.d.ts +2 -2
- package/dist/memory-embedder-reembed.d.ts +38 -0
- package/dist/memory-embedder-reembed.js +20 -0
- package/dist/memory-incident-sink.d.ts +0 -28
- package/dist/memory-incident-sink.js +5 -0
- package/dist/memory-operator-faces.d.ts +9 -4
- package/dist/memory-scope-stores.d.ts +9 -7
- package/dist/memory-scope-stores.js +3 -14
- package/dist/memory-scope.d.ts +38 -2
- package/dist/memory-scope.js +33 -2
- package/dist/memory-store-refusal.d.ts +17 -4
- package/dist/memory-store-refusal.js +1 -1
- package/dist/memory-sync-client.d.ts +2 -0
- package/dist/memory-sync-client.js +13 -11
- package/dist/memory-sync.js +1 -1
- package/dist/model-compat.d.ts +35 -21
- package/dist/model-compat.js +49 -21
- package/dist/model-entry-refusal.d.ts +11 -1
- package/dist/model-entry-refusal.js +7 -0
- package/dist/namespaced-rule-name.d.ts +18 -1
- package/dist/namespaced-rule-name.js +12 -0
- package/dist/net-address.d.ts +53 -0
- package/dist/net-address.js +111 -0
- package/dist/observability/fail-open.d.ts +29 -17
- package/dist/observability/fail-open.js +29 -17
- package/dist/observability/metrics.d.ts +2 -0
- package/dist/observability/metrics.js +2 -0
- package/dist/observability/secret-env-scrub.d.ts +30 -4
- package/dist/observability/secret-env-scrub.js +15 -3
- package/dist/orchestration/workflow-agent-session-index.d.ts +7 -12
- package/dist/orchestration/workflow-agent-session-index.js +1 -6
- package/dist/orchestration/workflow-completion-inbox.d.ts +26 -6
- package/dist/orchestration/workflow-completion-inbox.js +63 -45
- package/dist/orchestration/workflow-notify-journal.js +2 -3
- package/dist/org-delivery-gate.js +1 -1
- package/dist/org-memory-admission.d.ts +5 -2
- package/dist/org-memory-admission.js +25 -10
- package/dist/parked-decide.d.ts +33 -26
- package/dist/parked-decide.js +36 -44
- package/dist/peer-directory.d.ts +6 -12
- package/dist/peer-directory.js +5 -1
- package/dist/plugins/approval-ask-store-file.d.ts +10 -2
- package/dist/plugins/approval-ask-store-file.js +37 -4
- package/dist/plugins/approval-ask-store-memory.d.ts +5 -3
- package/dist/plugins/approval-ask-store-memory.js +11 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +3 -0
- package/dist/plugins/approval-ask-store-sql.js +3 -1
- package/dist/plugins/blob-backend.d.ts +38 -195
- package/dist/plugins/blob-backend.js +33 -229
- package/dist/plugins/caching-session-store.d.ts +12 -5
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-index-columns.d.ts +1 -1
- package/dist/plugins/checkpoint-index-columns.js +3 -2
- package/dist/plugins/checkpoint-store-face.d.ts +426 -0
- package/dist/plugins/checkpoint-store-face.js +152 -0
- package/dist/plugins/device-store-sql.d.ts +2 -2
- package/dist/plugins/device-store-sql.js +5 -10
- package/dist/plugins/execution-lane-rename-m40.d.ts +20 -0
- package/dist/plugins/execution-lane-rename-m40.js +10 -0
- package/dist/plugins/execution-placement-sql.d.ts +63 -88
- package/dist/plugins/execution-placement-sql.js +94 -54
- package/dist/plugins/file-run-store.d.ts +26 -18
- package/dist/plugins/file-run-store.js +64 -75
- package/dist/plugins/fork-routing-session-store.d.ts +6 -2
- package/dist/plugins/fork-routing-session-store.js +2 -2
- package/dist/plugins/imported-layer-root-retirement.d.ts +22 -11
- package/dist/plugins/imported-layer-root-retirement.js +4 -8
- package/dist/plugins/inbox-payload-column.d.ts +14 -0
- package/dist/plugins/inbox-payload-column.js +13 -0
- package/dist/plugins/local-checkpoint-store.d.ts +7 -2
- package/dist/plugins/local-checkpoint-store.js +13 -8
- package/dist/plugins/local-data-dir-modes-m39.d.ts +48 -0
- package/dist/plugins/local-data-dir-modes-m39.js +182 -0
- package/dist/plugins/local-engine-high-water.d.ts +11 -0
- package/dist/plugins/local-engine-high-water.js +59 -0
- package/dist/plugins/local-session-store.d.ts +119 -30
- package/dist/plugins/local-session-store.js +156 -53
- package/dist/plugins/local-task-attachment-store.d.ts +2 -0
- package/dist/plugins/local-task-attachment-store.js +10 -11
- package/dist/plugins/memory-embedder-fingerprint.d.ts +33 -10
- package/dist/plugins/memory-embedder-fingerprint.js +52 -12
- package/dist/plugins/memory-embedder.d.ts +1 -1
- package/dist/plugins/memory-embedder.js +2 -2
- package/dist/plugins/memory-engine-pg.d.ts +30 -6
- package/dist/plugins/memory-engine-pg.js +96 -214
- package/dist/plugins/memory-engine-sql-apply.d.ts +130 -0
- package/dist/plugins/memory-engine-sql-apply.js +358 -0
- package/dist/plugins/memory-engine-tidb.d.ts +38 -9
- package/dist/plugins/memory-engine-tidb.js +99 -230
- package/dist/plugins/memory-key-guards.d.ts +1 -1
- package/dist/plugins/memory-origin-law.d.ts +3 -3
- package/dist/plugins/one-time-migrations.d.ts +169 -83
- package/dist/plugins/one-time-migrations.js +295 -235
- package/dist/plugins/owner-only-file-mode.d.ts +29 -0
- package/dist/plugins/owner-only-file-mode.js +141 -0
- package/dist/plugins/permission-rule-store-file.d.ts +17 -3
- package/dist/plugins/permission-rule-store-file.js +20 -1
- package/dist/plugins/pg-pool.d.ts +2 -1
- package/dist/plugins/pg-pool.js +12 -5
- package/dist/plugins/release-version.d.ts +20 -0
- package/dist/plugins/release-version.js +28 -0
- package/dist/plugins/remote-env-adb.d.ts +20 -4
- package/dist/plugins/remote-env-adb.js +39 -11
- package/dist/plugins/remote-env-e2b.d.ts +12 -3
- package/dist/plugins/remote-env-e2b.js +6 -4
- package/dist/plugins/remote-env-host.d.ts +9 -1
- package/dist/plugins/remote-env-host.js +6 -5
- package/dist/plugins/remote-env-k8s.d.ts +5 -2
- package/dist/plugins/remote-env-k8s.js +15 -4
- package/dist/plugins/remote-env-local-docker.d.ts +4 -1
- package/dist/plugins/remote-env-local-docker.js +3 -3
- package/dist/plugins/remote-env-ssh.d.ts +8 -2
- package/dist/plugins/remote-env-ssh.js +26 -24
- package/dist/plugins/remote-shell.d.ts +59 -30
- package/dist/plugins/remote-shell.js +175 -62
- package/dist/plugins/retention-declaration.d.ts +37 -0
- package/dist/plugins/retention-declaration.js +9 -0
- package/dist/plugins/retention-deployment.d.ts +126 -0
- package/dist/plugins/retention-deployment.js +88 -0
- package/dist/plugins/retention-lane-store-sql.d.ts +74 -4
- package/dist/plugins/retention-lane-store-sql.js +103 -1
- package/dist/plugins/retention-sql.d.ts +29 -0
- package/dist/plugins/retention-sql.js +8 -0
- package/dist/plugins/run-store-sql.js +2 -2
- package/dist/plugins/schema-consistency.d.ts +0 -6
- package/dist/plugins/schema-consistency.js +1 -2
- package/dist/plugins/schema-ensure-legs.d.ts +1 -1
- package/dist/plugins/schema-ensure-legs.js +13 -3
- package/dist/plugins/session-ext-table.d.ts +74 -0
- package/dist/plugins/session-ext-table.js +121 -0
- package/dist/plugins/session-fork.d.ts +31 -9
- package/dist/plugins/session-fork.js +3 -2
- package/dist/plugins/session-placement.d.ts +4 -2
- package/dist/plugins/session-row-sql.d.ts +8 -7
- package/dist/plugins/session-row-sql.js +15 -7
- package/dist/plugins/session-store-sql.d.ts +131 -0
- package/dist/plugins/session-store-sql.js +298 -0
- package/dist/plugins/session-workspace-cell.d.ts +2 -2
- package/dist/plugins/session-workspace-cell.js +2 -2
- package/dist/plugins/shared-memory-store-sql.d.ts +10 -0
- package/dist/plugins/shared-memory-store-sql.js +13 -13
- package/dist/plugins/snapshot-bucket-presence.js +1 -1
- package/dist/plugins/sql-driver.d.ts +23 -7
- package/dist/plugins/sql-driver.js +41 -8
- package/dist/plugins/sql-errors.d.ts +5 -2
- package/dist/plugins/sql-errors.js +4 -0
- package/dist/plugins/sql-json-column.d.ts +5 -1
- package/dist/plugins/store-backend.d.ts +46 -16
- package/dist/plugins/store-backend.js +192 -69
- package/dist/plugins/store-contracts.d.ts +10 -13
- package/dist/plugins/store-contracts.js +1 -9
- package/dist/plugins/store-sweep.d.ts +63 -0
- package/dist/plugins/store-sweep.js +48 -0
- package/dist/plugins/task-attachment-store.d.ts +6 -8
- package/dist/plugins/task-attachment-store.js +15 -10
- package/dist/plugins/task-list-store-sql.d.ts +1 -1
- package/dist/plugins/text-column-capacity.d.ts +21 -0
- package/dist/plugins/text-column-capacity.js +5 -0
- package/dist/plugins/tidb-pool.d.ts +3 -2
- package/dist/plugins/tidb-pool.js +20 -32
- package/dist/plugins/user-input-ledger-sql.d.ts +1 -1
- package/dist/prompt-screen.d.ts +6 -9
- package/dist/prompt-screen.js +2 -5
- package/dist/read-face-posture.d.ts +6 -6
- package/dist/read-face-posture.js +2 -2
- package/dist/request-value-closure.d.ts +5 -5
- package/dist/request-value-closure.js +1 -1
- package/dist/rules-consent.d.ts +48 -27
- package/dist/rules-consent.js +147 -23
- package/dist/run-cancel-context.d.ts +4 -1
- package/dist/run-cancel-context.js +2 -1
- package/dist/run-local.js +17 -13
- package/dist/runs.d.ts +48 -30
- package/dist/runs.js +27 -17
- package/dist/runtime-caps-resolver.d.ts +15 -8
- package/dist/runtime-caps-resolver.js +14 -10
- package/dist/sandbox-egress-policy.js +6 -11
- package/dist/sandbox-rbac-rules.d.ts +88 -0
- package/dist/sandbox-rbac-rules.js +80 -0
- package/dist/sealed-key-layout.d.ts +16 -0
- package/dist/sealed-key-layout.js +3 -0
- package/dist/sealed-key.js +8 -6
- package/dist/security.d.ts +43 -9
- package/dist/security.js +9 -2
- package/dist/sema-config-dir.js +2 -2
- package/dist/server-secret-env.d.ts +2 -0
- package/dist/service-version.d.ts +2 -1
- package/dist/service-version.js +2 -2
- package/dist/session-error-wire.d.ts +1 -1
- package/dist/session-incarnation.d.ts +8 -5
- package/dist/session-notify-door.d.ts +5 -3
- package/dist/session-resident-background.d.ts +110 -0
- package/dist/session-resident-background.js +88 -0
- package/dist/session-row.d.ts +1 -1
- package/dist/session-sync-kernel.d.ts +53 -14
- package/dist/session-sync-kernel.js +70 -1
- package/dist/session-sync.d.ts +5 -3
- package/dist/session-workspace.d.ts +12 -2
- package/dist/session-workspace.js +6 -0
- package/dist/sighup-idle.d.ts +9 -7
- package/dist/sighup-idle.js +4 -5
- package/dist/spec-fields.d.ts +16 -0
- package/dist/spec-fields.js +7 -0
- package/dist/store-posture.d.ts +2 -1
- package/dist/stored-request-env-credentials-m38.d.ts +3 -0
- package/dist/stored-request-env-credentials-m38.js +8 -0
- package/dist/stored-request-hooks-m20.d.ts +3 -2
- package/dist/stored-request-hooks-m20.js +19 -14
- package/dist/stored-request-prompt-profile-m30.d.ts +1 -1
- package/dist/stores-sql/blob-index-sql.d.ts +148 -0
- package/dist/stores-sql/blob-index-sql.js +154 -0
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.d.ts +14 -428
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.js +43 -220
- package/dist/{plugins → stores-sql}/file-history-store-sql.d.ts +23 -11
- package/dist/{plugins → stores-sql}/file-history-store-sql.js +23 -18
- package/dist/{plugins → stores-sql}/mailbox-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/mailbox-store-sql.js +4 -4
- package/dist/{plugins → stores-sql}/pg-session-storage.d.ts +27 -67
- package/dist/{plugins → stores-sql}/pg-session-storage.js +82 -207
- package/dist/{plugins → stores-sql}/retention-store-sql.d.ts +123 -217
- package/dist/{plugins → stores-sql}/retention-store-sql.js +66 -190
- package/dist/{plugins → stores-sql}/roster-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/roster-store-sql.js +1 -1
- package/dist/{plugins → stores-sql}/session-event-payload.d.ts +1 -1
- package/dist/{plugins → stores-sql}/session-event-payload.js +1 -1
- package/dist/stores-sql/session-policy-store-sql.d.ts +1 -1
- package/dist/stores-sql/session-write-hooks.d.ts +59 -0
- package/dist/stores-sql/session-write-hooks.js +2 -0
- package/dist/{plugins → stores-sql}/tidb-session-storage.d.ts +10 -11
- package/dist/{plugins → stores-sql}/tidb-session-storage.js +10 -21
- package/dist/{plugins → stores-sql}/tidb-session-store.d.ts +35 -112
- package/dist/{plugins → stores-sql}/tidb-session-store.js +73 -169
- package/dist/{plugins → stores-sql}/tool-result-store-sql.d.ts +3 -3
- package/dist/{plugins → stores-sql}/tool-result-store-sql.js +6 -6
- package/dist/stores-sql/windowed-session-storage.d.ts +56 -0
- package/dist/stores-sql/windowed-session-storage.js +61 -0
- package/dist/{plugins → stores-sql}/workflow-journal-store-sql.d.ts +7 -12
- package/dist/{plugins → stores-sql}/workflow-journal-store-sql.js +3 -8
- package/dist/task-a2a.d.ts +7 -1
- package/dist/task-a2a.js +15 -14
- package/dist/task-cwd.d.ts +11 -3
- package/dist/task-cwd.js +17 -1
- package/dist/task-mcp.d.ts +10 -2
- package/dist/task-mcp.js +13 -16
- package/dist/task-settings.d.ts +68 -8
- package/dist/task-settings.js +63 -6
- package/dist/tool-approval.d.ts +23 -10
- package/dist/tool-approval.js +10 -6
- package/dist/trace/core-keyset-guard.d.ts +17 -10
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +4 -0
- package/dist/trace/exit-seat.d.ts +29 -1
- package/dist/trace/exit-seat.js +4 -0
- package/dist/trace/project.d.ts +33 -16
- package/dist/trace/project.js +21 -9
- package/dist/trace/redact.d.ts +13 -2
- package/dist/trace/redact.js +347 -78
- package/dist/trace/self-minted-wire.d.ts +587 -16
- package/dist/trace/self-minted-wire.js +215 -9
- package/dist/trace/sema-provenance.d.ts +45 -41
- package/dist/trace/sema-provenance.js +81 -10
- package/dist/trace/task-notification-facets.d.ts +70 -2
- package/dist/trace/task-notification-facets.js +71 -1
- package/dist/trace/wire-projection-faces.d.ts +39 -3
- package/dist/trace/wire-projection-faces.js +27 -2
- package/dist/unread-request-members.d.ts +66 -0
- package/dist/unread-request-members.js +41 -0
- package/dist/usage-analytics.d.ts +4 -0
- package/dist/user-input-ledger.d.ts +2 -2
- package/dist/web-admin-client/apply-effective.js +22 -26
- package/dist/web-admin-client/candidate-gate.d.ts +35 -3
- package/dist/web-admin-client/candidate-gate.js +53 -5
- package/dist/web-admin-client/center-request.d.ts +4 -1
- package/dist/web-admin-client/center-request.js +2 -1
- package/dist/web-admin-client/effective-keys.js +0 -1
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/http-client.d.ts +1 -0
- package/dist/web-admin-client/http-client.js +17 -9
- package/dist/web-admin-client/restart-signal.js +5 -2
- package/dist/web-admin-client/skills-mcp.d.ts +20 -6
- package/dist/web-admin-client/skills-mcp.js +26 -21
- package/dist/web-admin-client/types.d.ts +34 -49
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +2 -2
- package/package.json +22 -13
- package/scripts/drain-check-local.mjs +8 -55
- package/scripts/drain-check.mysql.sql +3 -40
- package/scripts/drain-check.pg.sql +3 -40
- package/skills/update-config.md +1 -1
- package/wire-changes/server@7.146.0.json +3221 -0
- package/wire-changes/server@7.147.0.json +813 -0
- package/dist/approval-batch-census.d.ts +0 -27
- package/dist/approval-batch-census.js +0 -27
package/MIGRATION.md
CHANGED
|
@@ -7,6 +7,882 @@
|
|
|
7
7
|
> ⚠️ 完整清单在仓库根 `CHANGELOG.md`——它**不随 npm tarball 出包**(本文件随包)。看完整迁移窗的
|
|
8
8
|
> 权威姿势是源码 tag diff:`git diff v<旧>..v<新>`(每版都推 `v<版本>` tag);npm 包页也镜像 CHANGELOG。
|
|
9
9
|
|
|
10
|
+
## 7.147.0 —— 1–30 条见下
|
|
11
|
+
|
|
12
|
+
1. **硬断预告 —— 本版兑现:每个部署都要显式声明执行车道,未声明拒启;车道词 `none` 取代词表外的状态名 `in-process`;`REQUIRE_EXECUTION_LANE` 退役(设了即拒启)(行为 BREAKING;wire 值形 BREAKING;部署动作:写明 `REMOTE_EXEC`、去掉 `REQUIRE_EXECUTION_LANE`,有 `in-process` 存量行的部署停机迁移、不可滚动;全部细节与回滚见本节「执行车道恒点名」一条)**:
|
|
13
|
+
旧形(7.146.0 及以前):`REMOTE_EXEC` 不设时有两条隐式臂 —— `CONFIG_PROVIDER=local` 隐含 `host`(手带在,宿主真机);其余(`remote` 或不设)落 core 的进程内桩(手带整族不挂,任务照跑、回执 `status=completed`)。
|
|
14
|
+
后一条在 `GET /v1/capabilities` 的 `executionLane.provider` 上叫 `in-process` —— 一个不在车道词表里的状态名。想对「没点名」拒启,要自己开 `REQUIRE_EXECUTION_LANE=true`(缺省关;本仓自带的部署产物都写着它)。
|
|
15
|
+
新形(自 7.147.0 起,即本版):
|
|
16
|
+
**硬断(自 7.147.0 起)**:每个部署都要显式声明自己最终生效的执行车道 —— env `REMOTE_EXEC`(`CONFIG_PROVIDER=local` 形下 `config.d/remote-exec.json` 也算);没有声明 ⇒ 拒启,拒句以 `No execution lane is declared` 起、一行给出照旧行为的修法(`CONFIG_PROVIDER=local` 不再隐含 `host`,非 local 未设也不再静默落进「不挂手」的进程内桩)。「不给智能体的工具提供执行环境」写成车道词 `none`,取代词表外的状态名 `in-process`(wire 五处换值,零别名:`GET /v1/capabilities` 的 `executionLane.provider`、`GET /v1/sessions/:id/execution-placement` 的 `lane`、409 `execution_lane.not_served` 与 409 `execution_lane.tree_bound` 的 `boundLane`、403 `execution_lane_not_allowed` 的 `extra.lane`);`REQUIRE_EXECUTION_LANE` 已退役(设了任何非空值 ⇒ 拒启,拒句指向 `REMOTE_EXEC`),自己拼的清单或拷过随包部署产物的 env 里写着它的,升级前要去掉。库里或数据根里记着 `in-process` 的会话 / 审批行由一次性迁移 M40 在起服时改成 `none`:停全部旧副本、再起 7.147.0,不可滚动混跑;SQL 后端上判活窗(`REAP_RUN_STALE_SEC`)内还有 run 在心跳 ⇒ 起服拒 `config.execution_lane_rename_refused`,拒句给出可再起的时刻;守卫只看心跳,没有在跑的 run 的空闲旧副本它看不见 —— 停全部旧副本是运维的动作(细节与回滚见 MIGRATION 7.147.0 节「执行车道恒点名」一条)。web-admin 渲染 env 的中心 worker,须先停渲 `REQUIRE_EXECUTION_LANE`、同时让每个 worker 的 env 带 `REMOTE_EXEC`,再升到 7.147.0。照旧行为的一行修法:7.146.0 里非 local 且未设车道的 ⇒ 7.147.0 写 `REMOTE_EXEC=none`,`CONFIG_PROVIDER=local` 且未设的 ⇒ 写 `REMOTE_EXEC=host`(7.146.0 及以前不认 `none` 这个词,别提前写)。
|
|
17
|
+
**谁需要**:所有部署方 —— 尤其是 `CONFIG_PROVIDER=local` 的单机形、手写 `.env`、没写 `REMOTE_EXEC` 的托管 worker,以及给 worker 渲染 env 的编排方;读 `executionLane.provider` / 放置读面 `lane` / 409 `boundLane` / 403 `extra.lane` 的壳与客户端(按 `in-process` 字面分支的,要在 7.147.0 同波认 `none`)。
|
|
18
|
+
**谁受伤**:7.147.0 起 ① 没声明车道的部署拒启;② env 里还写着 `REQUIRE_EXECUTION_LANE` 的(拷过旧版随包部署产物的清单、自己拼的清单、编排方渲染的 worker env)拒启;③ 库里或数据根里有 `in-process` 存量行的部署要停机迁移、不可滚动(旧副本不认 `none`、新副本不认 `in-process`,混跑两头都会拒);④ 按旧词字面读 wire 的消费端。
|
|
19
|
+
**补偿**:7.146.0 上就能先显式点名 —— 单机用 `REMOTE_EXEC=host`,隔离用 `e2b` / `k8s` / `local-docker`(`none` 是本版才有的车道词,7.146.0 及以前写会被拒,别提前写);要继续「不给手」的部署,本版写 `REMOTE_EXEC=none`(逐字复现 7.146.0 非 local 未设的行为)。
|
|
20
|
+
编排方停渲 `REQUIRE_EXECUTION_LANE` 的同时,必须让每个 worker 的 env 带 `REMOTE_EXEC` —— 7.146.0 上只停渲这根旋钮而不点名车道,worker 会静默落进无手的进程内桩。
|
|
21
|
+
**升级前做**:盘点哪些部署没写 `REMOTE_EXEC`(7.146.0 上非 local 而未设的 ⇒ 写 `REMOTE_EXEC=none`,`CONFIG_PROVIDER=local` 而未设的 ⇒ 写 `REMOTE_EXEC=host`);盘点 env 里的 `REQUIRE_EXECUTION_LANE`(去掉);有 `in-process` 存量行的部署排一次停机窗(停全部旧副本、再起本版,不可滚动)。步骤见本节「执行车道恒点名」一条。**回滚**:见本节「执行车道恒点名」一条(含 M40 改写过的行的回写语句),本条不另给第二份。
|
|
22
|
+
|
|
23
|
+
2. **`task_notification` 帧的会话箱车道上 wire:三只载体 `crossSessionMessage` / `crossSessionNotice` / `inboxNotice` 与侧记 `_sema_provenance` 的三个 lane 词(`cross_session_message` / `cross_session_notice` / `inbox_notice`)及 `peerMeta`(含 typed 通告 `peerMeta.notice`)逐成员投(wire 加性;部署零动作)**:
|
|
24
|
+
旧形:接了会话席的部署上,引擎的会话箱 drain 交来的帧(一条对端会话的信 / 本会话发出那条信的投递回执与对端空闲通告 / 一行收件箱计数)在本服务 wire 上只有经典键(`task_id` / `summary` / `result` …);三只载体与它们的侧记恒缺席,消费端只能渲通用通知卡;`inboxNotice.resupplied` 恒缺席。
|
|
25
|
+
新形:三条腿(同步 live SSE / bg·resume 两条 durable 账本行 / 空闲态 park → drain 的补投帧)同形加键 ——
|
|
26
|
+
`crossSessionMessage { from, fromSession?, fromName?, fromMode?, fromScope?, body }`(`from` = 发信方规范编码地址,身份逐字;`fromName` / `body` 过脱敏);
|
|
27
|
+
`crossSessionNotice { kind: "delivery_notice" | "idle_notice", text }`(`text` 是引擎渲给模型的那一句,过脱敏);
|
|
28
|
+
`inboxNotice { pending, delivered, urgent?, resupplied? }`(非负整数;`seq` 每个 run 从 1 起);
|
|
29
|
+
`_sema_provenance.kind` 放行 core 词表四员,两种箱记录 lane 带 `peerMeta { fromSession?, fromRoot?, fromMode?, kind?, fromScope?, notice?, urgent? }`,
|
|
30
|
+
回执 / 空闲帧的卡从 `peerMeta.notice { state, refSeq?, recipient?, dropReason?, finishedAt?, detail?, target? }` 渲(`state` 开集串逐字,新词原样过境;`recipient` / `target` / `detail` / `dropReason` 过脱敏)。
|
|
31
|
+
仍不投:`peer`、`received`、`peerMeta.senderKey`、`peerMeta.gateReceiptId`、`peerMeta.occupant`、`peerMeta.fromOccupant`(凭据 / 身份令牌类:准入键、投递回执号、会话化身令牌)、`inboxNotice.box`(同帧 `task_id` = `inbox:<box>` 与 `_sema_provenance.from` 已带)。
|
|
32
|
+
在场却读不出(容器不是纯数据记录(类实例 / `Date` / `Map` 也算坏)/ 必需成员缺席 / 成员形坏 / 闭集词出词表)⇒ 那一只键整键缺席,运维计数 `server.trace.projection-input-malformed` +1;缺席不计。`_sema_provenance` 词表外 lane 词此前静默丢,现同样计一次。
|
|
33
|
+
park 补投帧上这些文本位与本服务其余 park 文本位同一个 4000 字界。
|
|
34
|
+
**谁需要**:接了会话席的多会话部署上的三端渲染 —— 对端信的转录行、投递回执 / 空闲通告的卡、收件箱计数行;按 `inboxNotice.resupplied` 标注补投的壳。
|
|
35
|
+
**谁受伤**:按「帧上未知键」报错或整帧比对的消费端与金样(要补键);对端信的帧变大(`body` 与经典 `result` 同一串,live 帧上两份);按 `taskId:status:seq` 跨 run 去重收件箱通告的消费端会吞同会话第二个 run 的第一条通告(请把 run 身份并进键)。
|
|
36
|
+
**补偿**:新键全部可缺席、缺席 = 上一版形,不读这些键的消费端逐字不变;坏形整键缺席并有运维计数;凭据类身份键不上 wire;文本位经与 `summary` / `result` 同一读法的脱敏。
|
|
37
|
+
**升级前做**:部署零动作。消费端:按载体在场分派渲染(优先序 `agentMessage` → `crossSessionMessage` → `crossSessionNotice` → `inboxNotice`),回执 / 空闲卡读 `_sema_provenance.peerMeta.notice`(不解析 `text`),`notice.state` 按开集读。**回滚**:回到上一版即恢复旧形;零持久面、零 DDL、零一次性迁移(park 已入箱的补投帧带着新键,上一版 drain 原样带出,老消费端忽略)。
|
|
38
|
+
|
|
39
|
+
3. **🔴 单用户部署必须声明「谁是运维」:`REQUIRE_PRINCIPAL` 未开、`OPERATOR_PRINCIPALS` 为空、`OPERATOR_SINGLE_USER` 不是 `true` ⇒ 装配运维面时拒(服务进程起服拒,直接调 `createHttpServer` 的嵌入方同拒;不变量 `operator-declaration-required`);起服日志 `operator_undeclared_single_user` 与 `memory_consolidation_valve_unreachable` 退役(行为 BREAKING;安全轴;没写声明的单用户部署升级前补一行)**:
|
|
40
|
+
旧形:单用户部署不写声明照常起服,起服一行 warn `operator_undeclared_single_user`;这台部署上没有运维 —— 审批队列的跨属主列表与决议对谁都不开(每个调用方只看自己的卡),`GET /v1/diagnostics/wiring`、`GET /v1/outcomes`、管理与记忆治理口对谁都答 501 `capability.operator_principals_required`。
|
|
41
|
+
新形:多一条跨域不变量 `operator-declaration-required`(服务进程在起服第 1 段判;所有装运维面者在 `createHttpServer` 装路由之前再判同一句,直接调工厂的嵌入方只过这一处):单用户形(`REQUIRE_PRINCIPAL` 不是 `true`)必须二选一 —— `OPERATOR_SINGLE_USER=true`(这台单用户部署的每个调用方都是运维)或 `OPERATOR_PRINCIPALS=<主体,…>`(只有点名的主体是运维);
|
|
42
|
+
两样都没有 ⇒ 进程在起服第 1 段退出(先于任何起服日志、店连接与中心拉取;嵌入方:`createHttpServer` 抛同一句),stderr 一行拒句点名这两条出路,并说明不止一个人调用的 worker 是多租、该设 `REQUIRE_PRINCIPAL=true`。`OPERATOR_SINGLE_USER=false` 与没写同判。多租形不归本条(空名单 = 没人是运维,合法;开了 `DURABLE_APPROVAL` 的多租形照旧由 `operator-principals-required` 管)。
|
|
43
|
+
`operator-single-user`(单用户声明与多租 / 非空名单互斥)与 `operator-principals-required` 两条的拒启集不变。三根键都只在 env、起服冻结;配置热改路径只对「把声明改成被拒形」的候选判本条(三键没动 ⇒ 不判,不装运维面的 `run-local` 的限额照落)。
|
|
44
|
+
不装路由的 `run-local` 不判本条(它不跑起服第 1 段、不调 `createHttpServer`,`loadConfig()` 本身不拒)。运维面的 501 `capability.operator_principals_required` 从此只在「多租 + 空名单」上出现。
|
|
45
|
+
两条起服日志退役:`operator_undeclared_single_user`(在场条件与本条拒启条件同一);`memory_consolidation_valve_unreachable`(显式开得起来的记忆整理阀门只在单用户 + file 记忆后端上,过了第 1 段就有运维)。`memory_consolidation_run_credential_gated` 不变。
|
|
46
|
+
本包的一键部署渲这一行:`sema-up --users=single`(缺省)写 `OPERATOR_SINGLE_USER=true`、`--users=multi` 写 `false`(compose `.env` 每次重跑按租户词重写;cluster 清单同值);chart 两只 worker 从 `server.requirePrincipal` 派生(未开 ⇒ `"true"`,开 ⇒ `"false"`);`server.requirePrincipal` 从此只认 `"true"` / `"false"`(大小写不论),别的词 `helm template` / `helm upgrade` 渲染即拒并点名那个值。具名运维名单这几份模板不渲。
|
|
47
|
+
**谁需要**:单用户部署的运维 —— 旧形下这些运维面静默对谁都 501,起服只有一行 warn,运维不知道自己丢了它们。
|
|
48
|
+
**谁受伤**:① 没写声明的单用户 / 本机部署(手写 env、自己的 compose 或编排):升级即拒启;② 读起服日志 `operator_undeclared_single_user` / `memory_consolidation_valve_unreachable` 的告警规则从此读不到这两行;
|
|
49
|
+
③ 一台忘设 `REQUIRE_PRINCIPAL` 的团队机器若照出路写 `OPERATOR_SINGLE_USER=true`,每个调用方都成运维 —— 拒句因此把这条出路限定在单用户部署,并点名「不止一个人调用 ⇒ 设 `REQUIRE_PRINCIPAL=true`」;
|
|
50
|
+
④ chart 部署把 `server.requirePrincipal` 写成 `yes` / `1` / `on` 之类的:渲染即拒(改写成 `"true"` / `"false"`);⑤ 直接调 `createHttpServer` 的嵌入方:无声明的单用户 config 装配即抛(同一句),此前装得起来、运维口对谁都 501。
|
|
51
|
+
**补偿**:拒句就是出路 —— 一行声明二选一;没有旋钮、没有宽限、没有缺省。一键部署:重跑 `sema-up`(不带旗即沿用上一次的租户词)或 `helm upgrade` 即落新模板。
|
|
52
|
+
**升级前做**:单用户部署在 env 里补一行 `OPERATOR_SINGLE_USER=true`(或 `OPERATOR_PRINCIPALS=<主体,…>`);团队机器确认 `REQUIRE_PRINCIPAL=true` 已设。**回滚**:回到上一版 ⇒ 不写声明照常起服(起服 warn 回来);补的那一行上一版照读(同一根键、同一个判法);无持久数据。
|
|
53
|
+
|
|
54
|
+
4. **🔴 `DB_BACKEND=local`:数据根记引擎版本高水位 —— 比记录旧的引擎(本版及以后)开这只根起服拒 `config.schema_mismatch`;marker 读不出同拒;嵌入方类型 `LocalSidecarMismatch` 改名 `LocalDataRootMismatch`(行为变更;持久面;无迁移;部署零动作)**:
|
|
55
|
+
旧形:7.144.0 起数据根比代码新只靠**格式**围栏判 —— 会话元数据边档 `session-incarnations.json` 本构建读不出 ⇒ 拒;只盖格形变过的那一跳,格形没变的相邻版本,旧引擎开新引擎服务过的根照常起服(版本降级无人守)。
|
|
56
|
+
新形:数据根顶层多一只 `engine-high-water.json`,恰一键 `{"highWater":"x.y.z"}` = 打开过这只根的最高引擎版本(契约见 USAGE「嵌入形契约」同名一条)。local 后端**打开数据根的那一刻**(取锁之后、本仓任何一只店建起之前)先判、后抬:
|
|
57
|
+
判 —— 高水位高于本构建 ⇒ 拒;marker 在而读不出(I/O 错 / 悬空符号链接 / 不是 JSON / 缺键 / 多键 / 版本串不是纯 `x.y.z`)⇒ 拒,**不当缺席**;本构建版本按发布线读(`x.y.z`,可带 `-预发布` / `+构建` 后缀,后缀只剥不比:`7.147.0-rc.1` 按 `7.147.0` 判与抬,marker 恒写纯三段),读不出(例 `unknown`)⇒ 拒,先于读 marker;判拒 = 本仓零字节写(店一只没建,收尾不落盘);
|
|
58
|
+
拒与格式围栏同一只具名类 `LocalDataRootSchemaMismatchError`、同码、同一张三条出路(本构建版本读不出那一形是确定的拒启族里的一句普通拒),由公开序列的 `ensureSchema()` 交出;`findings` 多一种 `problem: "newer-engine"`(同一段必带 `engineHighWater: { highWater, engine }`),拒句点名 marker、高水位与本构建版本。
|
|
59
|
+
抬 —— 判过即抬,先于店构造里的自修、起服对账、一次性迁移与任何服务写:本构建高于记录(或缺席)⇒ 原子替换成本构建(`0600`,目录项证不了落盘也算没写成),相等不写(只证它在盘上);写到一半进程死了,水位已是本构建(比它旧的引擎重开被拒,本构建重开续跑);
|
|
60
|
+
对账或迁移在抬之后被拒 ⇒ 水位留在本构建;写不进 ⇒ 不以这只根服务(起服拒;缺省推导的 local 在起服时为空的根上按既有降级臂退内存)。SQL 后端不读不写它。
|
|
61
|
+
同一只字节一读也管会话元数据等边档:路径上是一条悬空符号链接 ⇒ 读不出(严格边档拒启、装饰性边档隔离留证后按空表继续),不再当「还没有」。
|
|
62
|
+
包根导出的读数类型 `LocalSidecarMismatch` 改名 `LocalDataRootMismatch`(它现在也装 marker 的读数),零别名 —— 按名字 import 它的嵌入方 tsc 红,改名即可;它是以 `problem` 为判别位的联合:`"newer-engine"` 那一支必带 `engineHighWater`,别的种别那一支没有它(字段 `path` / `label` / `unknownFields` 不变)。
|
|
63
|
+
**无迁移**:marker 由本版第一次打开数据根时写下,升级即生效;升级前不用做任何事。缺席 = 还没有本版及以后的引擎打开过这只根。
|
|
64
|
+
**谁需要**:`DB_BACKEND=local` 的单机部署与本机壳 —— 新引擎服务过数据根之后,换回旧二进制(或旧壳冷起自己钉的旧引擎)不恢复备份就照起,旧引擎在新引擎写过的数据上跑。
|
|
65
|
+
**谁受伤**:① 在同一只数据根上交替跑不同版本引擎的开发 / 测试(源码树的 `package.json` 版本落后于代码时同理);② 为躲一个问题降级又没有升级前备份的用户;③ 起服在对账或一次性迁移段被拒之后不恢复备份就换回旧版的部署(水位在打开那一刻已抬),含按跳版拒句的「先过一次带某条迁移的版本」去做、而那一版也是本版及以后的情形 —— 先恢复升级前备份;
|
|
66
|
+
④ 按名字 import `LocalSidecarMismatch` 的嵌入方。
|
|
67
|
+
**补偿**:拒句点名 marker、高水位与出路 —— 部署不低于高水位的 server;回滚 = 恢复升级前的数据根备份(marker 随备份回到旧值);同一台机器要并行跑多个版本 ⇒ 各给一个数据根(`LOCAL_DATA_ROOT`)。不设绕过旋钮;格式围栏照旧在下面兜。
|
|
68
|
+
**保护起点(如实)**:只有旧的那一端是本版及以后才守得住;更早的引擎不读这只文件,换回它们照旧只有格式围栏。
|
|
69
|
+
**回滚**:唯一支持形 = 恢复升级前的数据根备份。不恢复备份换回上一版(7.146.x 及更早):上一版不读 marker,照旧起服(格式围栏照旧判);换回本版及以后、但低于记录的版本 ⇒ 拒。不要手删 / 手改 marker 来绕过 —— 删了就是把一只服务过的根当成没人服务过。
|
|
70
|
+
|
|
71
|
+
5. **🔴 SQL 后端:会话上本服务记的十二格搬出引擎座表 `session_meta`,住旁表 `session_ext`;一次性迁移 M41(停-迁-起,不可滚动);外键级联是起服前提(持久面一次性迁移;行为变更;wire 零变化;部署动作:停全部旧副本再起本版)**:
|
|
72
|
+
① **表形**:
|
|
73
|
+
旧形:`session_meta` 一行同时带引擎的列(身份 / 属主 / 化身 / 叶子 / 时刻 / 委派分区元组)与本服务的十二格 —— `title` · `pinned` · `instruction_source` · `workspace` · `execution_role` · `execution_lane` · `execution_device_id` · `execution_device_owner_tenant` · `execution_device_owner_subject` · `execution_placed_at` · `execution_rev` · `fork_key`。
|
|
74
|
+
新形:`session_meta` 只剩引擎的列;十二格住 `session_ext`(主键 `session_id`,外键 `fk_session_ext_session` 引 `session_meta(session_id)` `ON DELETE CASCADE`,各列定义与宽度同前)。一会话一行;行不在 = 每一格缺省(未命名、未置顶、没记过基线 / 位置、没有执行格、非键控 fork)—— 写者锁住会话行之后按需补行。删一只会话(属主删除、委派真删、留存删除)在同一条语句里带走它的旁表行,同一 id 重新登记的新住客从空行起步。
|
|
75
|
+
② **一次性迁移 M41(SQL 两方言;local 零动作)**:起服时 ① 把 `session_meta` 上仍在的这几列按会话 id 分页、每一行都搬,upsert 进 `session_ext`(旁表那一行的这几格 = 会话行上的值;上一次没跑完留下的旁表行也改回会话行上的值);② 逐行核对两边相等(有一行不等 ⇒ 起服拒 `config.session_ext_move_refused`(`copy_mismatch`),一列不删,下一次起服重搬);③ 一句 `ALTER TABLE session_meta DROP COLUMN …` 删掉在场的这几列。中断 ⇒ 下一次起服从头重跑,结果相同。窗 = 发布日 + 30 天,窗内每次起服都跑(之后零动作),窗关之后的第一个 minor 删码。起服读数 `sessionExtRowsMoved` / `sessionMetaColumnsDropped`。
|
|
76
|
+
**停-迁-起**:删列之后,旧副本对这十二格的每一笔读写都撞未知列;搬与删之间旧副本落下的写会丢 ⇒ 停掉全部旧版本副本 → 起本版(起服时迁移)→ 再起其余副本。**守卫**:还有列要搬,而判活窗(`REAP_RUN_STALE_SEC`)内还有 `running` run 在心跳 ⇒ 起服拒 `config.session_ext_move_refused`(`live_runs`),一个字节不写;拒句给出可以再起的时刻。守卫只看心跳 —— 空闲的旧副本它看不见,停全部旧副本是运维的动作。
|
|
77
|
+
③ **外键级联是起服前提**:建表之后、一次性迁移之前,起服在一只事务里插一对行、删会话行、读旁表行、回滚(库零写);旁表行还在 ⇒ 拒 `config.session_ext_cascade_absent`。PostgreSQL 恒执行外键;TiDB 要执行外键的版本且会话变量 `foreign_key_checks` 为 `ON`(DSN 或全局设置可能关掉它);MySQL 要 InnoDB。表是在外键不执行时建的(约束没记下)⇒ 删掉那只(空的)`session_ext` 再起。
|
|
78
|
+
外键两侧的字符列在 MySQL 协议方言上必须同字符集、同排序规则,而存量库的 `session_meta` 可能随建库时的库缺省(`session_meta` 建表句给表尾写上 `COLLATE utf8mb4_bin` 之前建的库;stock MySQL 8 / 9 的缺省是 `utf8mb4_0900_ai_ci`)⇒ 建 `session_ext` 之前起服读一次 `information_schema.COLUMNS` 里 `session_meta.session_id` 的字符集与排序规则,外键列逐字照写(其余列仍是表级 `utf8mb4_bin`;PostgreSQL 腿照旧 `COLLATE "C"`)。读不出被引列,或库以**确定拒**(闭集:外键两侧列不相容 3780 / 加不上外键 1215 / 被引列缺索引 1822 / 存储引擎拒建表 1005 / 表级权限拒 1142 / 缺表 1146 —— `sql-errors.ts` 的部署错配类一张表)拒了建表句 ⇒ 起服拒 `config.schema_mismatch`,拒句点名 `session_ext`、写下的字符集 / 排序规则与库的原句(不是「库打不开」,开库等待窗不重试它);闭集之外的语句级错(TiDB 8028 / 9005、锁等待 1205 …)原样上抛,等待窗重试;连接类故障(断连、服务端关停、连接被杀)照旧原样上抛,等待窗重试。
|
|
79
|
+
④ **整段换装就地改写(行为变更)**:`replaceEntries`(会话同步的整段换装)此前删掉会话行再新建(标题、置顶、换源通告基线、位置与项目随之清空,化身与 fork 键沿用);本版就地改写导入者自己的那一行(属主门 ∧ 不是委派转录;化身与旁表行不动),与暂存提交同一读法 —— 换装之后标题 / 置顶照旧由同步的行重放写,换源通告基线与位置与项目保留服务端上一次记下的值。导入的拒判次序:有 run 认领 ⇒ 409 `session_active`,本处是该会话的写者 ⇒ 409 `conflict.session_writer`,都在写任何字节之前判(两者同在时,整段换装此前先答写者,现与暂存提交同序先答认领)。
|
|
80
|
+
**谁需要**:SQL 后端的每个部署(引擎的会话行只带引擎的列,本服务的格有自己的表与删除语义)。**谁受伤**:滚动升级的部署(守卫拒,或空闲旧副本漏网后撞未知列);外键不执行的库(起服拒);直接读 `session_meta` 这十二列的运维查询 / 报表(改读 `session_ext`);依赖「整段换装清空标题 / 基线」的脚本。
|
|
81
|
+
**补偿**:拒句给出可以再起的时刻与库端设置;迁移中断可重跑;读旧列的查询改成 `SELECT … FROM session_meta sm LEFT JOIN session_ext se ON se.session_id = sm.session_id`(行不在 = 缺省)。
|
|
82
|
+
**升级前做**:① 确认库执行外键(TiDB:`SELECT @@foreign_key_checks` 答 `1`);② 停全部旧副本,再起本版;③ 把直接读这十二列的查询改读 `session_ext`。
|
|
83
|
+
**回滚**:换回 7.146.x 之前停全部本版副本,把列加回并回写(本版的 `session_ext` 就是数据源):逐列 `ALTER TABLE session_meta ADD COLUMN <7.146.x 建表句里的列定义>`,再 `UPDATE session_meta sm JOIN session_ext se ON se.session_id = sm.session_id SET sm.title = se.title, …`(PostgreSQL:`UPDATE session_meta sm SET title = se.title, … FROM session_ext se WHERE se.session_id = sm.session_id`);`session_ext` 留着不影响 7.146.x(它不读这张表)。
|
|
84
|
+
回到 7.146.x 还要撤第 16 条的 M40 改写,次序固定:① 停全部本版副本 → ② 本条的加列与回写(`execution_lane` 由此回到 `session_meta`)→ ③ 第 16 条回滚里的两条反向 `UPDATE`(第二条写的正是 ② 加回来的 `session_meta.execution_lane`;先跑它会撞未知列)→ ④ 起 7.146.x。
|
|
85
|
+
|
|
86
|
+
6. **🔴 pg 记忆向量面:embedder 指纹对不上缺省拒启、一行不清;清列重嵌只经显式确认口令 `MEMORY_EMBEDDER_REEMBED=<model>/<dimensions>`(行为反转;新旋钮;部署动作:换 embedder 时给口令)**:
|
|
87
|
+
旧形:配了 `MEMORY_EMBEDDER_*` 的 pg 记忆部署,起服时 `agent_memory_engine_meta` 记下的 `{model, dimensions}` 与配置对不上 —— `changed`(不等)/ `unattributed`(元表无行而库里有向量)/ `unreadable`(那一行读不出)——
|
|
88
|
+
⇒ 先把 `agent_memory_engine_entry.embedding` 整列清成 NULL、再写新身份,服务照常起(检索在重嵌之前退词面档)。
|
|
89
|
+
新形:这三态缺省**拒启**,一行不清、元表不写;拒句点名所处的态、记下的与配置的身份和出路:① 只有 `changed` 才有 —— 把 `MEMORY_EMBEDDER_MODEL` / `MEMORY_EMBEDDER_DIM` 改回记下的身份;
|
|
90
|
+
② 确认重嵌 —— 设 `MEMORY_EMBEDDER_REEMBED=<本次配置的 model>/<dim>`(拒句给出的是 shell 赋值形 `MEMORY_EMBEDDER_REEMBED='<model>/<dim>'`,值带 POSIX 单引号,模型名含空格 / `$` / 引号也能原样粘进 shell;引号只是 shell 的写法,env 里的值不带引号 —— 写进 YAML / `.env` 文件 / 编排器 env 列表时只写引号里那一段),停机后再起:清列一次、记下新身份,`memory_embedder_identity_changed` 照旧响亮;
|
|
91
|
+
③ 撤掉 `MEMORY_EMBEDDER_*`,以词面档起、存量向量原样留。口令形:维度在最后一个 `/` 之后(`BAAI/bge-m3/1024`);必须恰好点名本次配置的身份,形不对(`true` / `1` 这类开关形)或对不上 ⇒ 拒启;
|
|
92
|
+
embedder 三键不全时单独在场 ⇒ 与 `MEMORY_EMBEDDER_TIMEOUT_MS` / `MEMORY_EMBEDDER_API_KEY` 同一条半配拒。口令绑定身份:新身份记下之后下一次起服判「相等」,口令留着无害;再换模型,旧口令对不上新配置 ⇒ 拒启。
|
|
93
|
+
相等 / 无记录且零向量两态照旧(零写 / 只记身份)。元表的写改成条件写:多副本同时起服而配置不一致时,判与写之间另一副本抢先记下的身份不再被盖掉 ——
|
|
94
|
+
本副本回读看见它、按它重判(未确认 ⇒ 拒启)。`MEMORY_ENGINE_BACKEND=mysql|file` 无向量面,零变化。
|
|
95
|
+
**谁需要**:任何配了 `MEMORY_EMBEDDER_*` 的 pg 部署 —— 换模型 / 改维度 / 回滚残留 / 手改元表的一次手滑不再在起服时不可逆地丢掉全部向量。
|
|
96
|
+
**谁受伤**:靠「换模型、下次起服自动清列」的部署 —— 升级后换模型起服即拒;运维脚本里「删 `agent_memory_engine_meta` 那一行让下次起服保守清一次」的做法现在也拒,要带口令起一次。
|
|
97
|
+
**补偿**:拒句给出口令与三条出路;撤掉 embedder 即可先以词面档起来。
|
|
98
|
+
**升级前做**:不换 embedder 的部署零动作(记下的身份与配置相等 ⇒ 照常起)。正在换、或升级同一拍要换的:在这一次起服的 env 里加 `MEMORY_EMBEDDER_REEMBED=<新 model>/<新 dim>`,停全部副本后再起(停机纪律不变)。
|
|
99
|
+
**回滚**:换回上一版无须动作(上一版不读这一键;多出来的 env 键它不认,照旧按自动清列处置)。
|
|
100
|
+
|
|
101
|
+
7. **🔴 场景面:部署接了配置中心而中心答不出这位主体的场景裁定(不可达 / 超时 / 答复读不出 / 指派两键形不对)⇒ 该 run `503 state.scenario_assignment_unavailable`,不再落部署缺省场景、不再放行点名的场景;没接中心 / 匿名运行 / 旧中心照旧(安全轴,fail-closed;wire 新码;行为变更;部署零动作)**:
|
|
102
|
+
**旧形**:部署接了中心(设了 `SEMA_WEB_ADMIN_URL`、非干跑)、请求带 principal,而中心这一问答不出来(不可达 / 超时 / 非 2xx / 体判坏 / 回声不符)⇒ 这位主体的 run 照跑:请求不点名 ⇒ 部署缺省场景,点名 ⇒ 白名单读成空、照放;
|
|
103
|
+
中心答了而指派两键形不对 ⇒ 非串元素逐个丢、非数组折成空、非串指派折成「无指派」,只发一键时另一键补空值,照用。受限主体在这一拍可能被放进比他的指派更宽的工具面。
|
|
104
|
+
**新形**:同一构造 ⇒ `503 state.scenario_assignment_unavailable`(体 `error` / `errorCode` / `permanence: "transient"`;码族 `transient`;不带 `Retry-After`),拒在一切副作用与计费之前,零 run;点名与不点名同拒。
|
|
105
|
+
两键的读法:都缺席 = 旧中心(无治理);都在场且形对 = 裁定;其余一切(形不对、只发一键)= 读不出 ⇒ 同拒。
|
|
106
|
+
读面同一只门:`GET /v1/capabilities/mcp`、`GET /v1/sessions/:id/a2a` 整面 503;`GET /v1/sessions/:id/mcp` 答 200,`servers` 缺席,拒因在 `scenarioRefusal`(该码下无 `detail`)。
|
|
107
|
+
续跑家族(审批决断后的续跑、`POST /v1/sessions/:id/wake`、`/v1/assistant/tasks/:id/resume` · `/plan_review`)同码同状态 503 + `retriable: true`,**不折** `409 resume_blocked_by_policy`(认领之前,卡仍待决;SLA 到期的自动拒不把这张卡过期,逐拍重试,中心恢复后再决即可)。
|
|
108
|
+
`/plan_review` 的直连门证明:一次性 nonce 在这一判之前已经用掉 —— 中心恢复后重铸 nonce 重签再发。停驻的后台子代赎回不问场景门,中心答不出时照常赎回。
|
|
109
|
+
**不变**:没接中心(没设 `SEMA_WEB_ADMIN_URL`,或 `SEMA_WEB_ADMIN_DRY_RUN=true`;`run-local`)、匿名运行(无 principal,中心不被问)、中心答了但两键都不发、中心答了「无指派」—— 照旧走请求名或部署缺省场景;
|
|
110
|
+
指派悬空仍是 `503 state.scenario_assignment_unknown`;请求体点名的未知名仍先答 `400 scenario_unknown`。
|
|
111
|
+
**嵌入方**(自建 `ScenarioGateSources.principalCaps`,包根 `createScenarioGate` 的入参):读数方法的答成三态 —— 裁定 / `undefined`(缺席 = 无治理)/ `"unavailable"`(故障 ⇒ 门拒);中心答不出时要答 `"unavailable"`,仍答 `undefined` 就是放行;读数方法抛错 ⇒ 门不接,读面答 500。
|
|
112
|
+
**谁需要**:接了配置中心的多租户 / 受限主体部署(中心答不出时受限主体不越界)。
|
|
113
|
+
**谁受伤**:接了中心的部署在中心答不出期间,每一个带 principal 的新提交与续跑都被拒(此刻分不出谁受限)—— 此前照跑、只拒放大位;单用户而接了中心的部署同受;中心发出形不对的两键 ⇒ 受影响主体全拒,直到中心改好。
|
|
114
|
+
**补偿**:码族 `transient`,按码重试;取数失败只复用一个短窗(缺省 10 秒),中心恢复后至多这么久即恢复;刚取到的正常裁定在缓存窗(缺省一分钟)内不再问中心;拒句点名出路(恢复本部署到配置中心的链路)。安全轴不设放行旋钮。
|
|
115
|
+
**升级前做**:壳 / SDK / 控制台:把 `state.scenario_assignment_unavailable` 当可重试的拒渲染(用 `error` 原句;续跑口上同码,不是 `resume_blocked_by_policy`,别给「取消任务」当出路);渲会话 mcp 面板的 `scenarioRefusal` 时不假定 `detail` 在场。
|
|
116
|
+
运维:看 `runtime_caps_resolve_failed` 是否常响 —— 常响的部署升级后那些时刻会变成拒,先修本部署到中心的链路;确认中心对 `?principal=` 视图两键要么都发、要么都不发。嵌入方:按上一段改读数方法。
|
|
117
|
+
**回滚**:无持久面;换回上一版即回到旧形。
|
|
118
|
+
|
|
119
|
+
8. **宿主车道模型 shell「被扣了哪些变量名」只有引擎通告一只读法:`secret_env_scrubbed` 日志行的 `site:"server.remote-env-host.spawn-env"` 一支退役(日志面;wire 零变化;部署零动作)**:
|
|
120
|
+
旧形:默认清洗环境(`inheritEnv:"scrub"`)的宿主车道模型 shell,被扣的变量名有两处日志:引擎通告 `inherit_env.names_withheld`(服务日志里的 `engine_notice` 行,`detail.names` / `detail.ownCredentials`;每会话每名字集一次),
|
|
121
|
+
与本服务宿主腿 spawn 时写的 `secret_env_scrubbed { site: "server.remote-env-host.spawn-env", keys, … }`(每进程 × 键一次)—— 同一批名字,两种读法。
|
|
122
|
+
新形:后一行不再写;名字只读 `engine_notice` 行(日志不封条数;会话流的同码帧每个数组至多 32 项;引擎的去重记录有界,每会话至多 200 份名字集摘要,尽力而为)。通告只在**根腿**调引擎自己的 shell 工具时出:委派子代调 shell 不出 —— 根腿自己从不调 shell、只把活派给子代跑 shell 的会话,服务日志里不再有这批名字(计数器照记)。`secret_env_scrubbed_total{site="server.remote-env-host.spawn-env",kind,confidence}` 计数器照记,读数不变。
|
|
123
|
+
**不变**:其余九个 `site` 值(project-memory / center-plugins / leader 的 git 腿、语言服务器、bake-runner、local-docker 与 adb 的 CLI 腿、settings hooks 命令腿,以及 git worktree 基环境)的 `secret_env_scrubbed` 行照旧 —— 引擎没有这些腿的读者,那一行仍是它们的唯一读法;git worktree 基环境(`WORKTREE_ISOLATION_ENABLED` 的 host 车道上本服务自己跑 `git worktree add / remove / prune` 的环境,从不交给引擎)此前记在 host shell 的现场名下,本版起记在新现场 `server.remote-env-host.git-base` 名下(行的字节除 `site` 与 `note` 外不变);模型面不变(被扣的变量在模型 shell 里读「未设置」)。
|
|
124
|
+
**谁需要**:读「这台部署的模型 shell 收不到哪些变量」的运维 —— 一处可读。
|
|
125
|
+
**谁受伤**:按 `secret_env_scrubbed` 行(`site` 为 `server.remote-env-host.spawn-env`)告警 / 过滤 / 做看板的运维脚本(开了 worktree 隔离的部署:基环境的行改到 `git-base` 名下,计数器标签同改);只靠委派子代跑 shell 的会话(见新形末句);用本包 host 车道适配器、不接 `RunnerDeps.onNotice` 的嵌入方(此前有这一行日志;现在名字只经引擎通告到达,没有通告席时引擎把句子落 `console.warn`,结构化日志行没有)。
|
|
126
|
+
**补偿**:`engine_notice` 行带同样的名字(并分出自有凭据一半);计数器不变;接 `onNotice` 的嵌入方读同一条通告。
|
|
127
|
+
**升级前做**:有上述告警 / 过滤规则的,改读 `engine_notice` 行(`code` = `inherit_env.names_withheld`,字段 `detail.names`);按 `site="server.remote-env-host.spawn-env"` 数 worktree 基环境剥除次数的看板,把基环境那份改看 `site="server.remote-env-host.git-base"`;其余零动作。
|
|
128
|
+
**回滚**:无持久面;换回上一版即恢复这一行。
|
|
129
|
+
|
|
130
|
+
9. **远端车道(ssh / adb / local-docker / k8s / e2b)写文件的「不暂存、直接写目标」退路:取消的读法只看落在哪一段,订正 7.139.0 节第 23 条 ⑧ 的一句;准备 / 提交脚本去掉 `readlink -n` 与 `stat`(行为修复 + 文字订正;wire 零变化;部署零动作)**:
|
|
131
|
+
订正(7.139.0 节原文不动):第 23 条 ⑧ 写「写目标那一步因取消中断 ⇒ `unknown`……(那一步自己的通道准备也算在内,保守)」与「核不过 —— ……目标机上没有 `stat` —— 这一次写不暂存」。两处在本版都不成立:
|
|
132
|
+
① 一次传输分两段 —— 备件阶段(第一个字节发往目标机之前:adb 在本机落的临时件、ssh 开 sftp 通道含懒重连、k8s 建连、追加退路里 adb / e2b 的读旧 + 拼)与传输阶段(字节真发出的那一段)。取消落在备件阶段 ⇒ `aborted`、目标未碰、一个字节没发(修前读数:`unknown`「目标可能只写了一半」;ssh 另有 `ok:true`,取消落在拿通道的那一刻时 sftp 照样把整份写到目标);
|
|
133
|
+
只有传输阶段被取消打断才答 `unknown`;传输阶段不收取消(ssh 的 sftp)⇒ 照样写完、答成功,不变。local-docker 的 `docker exec -i` 起进程与 e2b 的 `files.write` 没有可单列的备件,取消落在其中仍答 `unknown`。
|
|
134
|
+
② 脚本只用 POSIX sh 的形:`readlink` 不带 `-n`(读到的一跳核过是同一只文件才信,核不上经链接就地写)、不用 `stat`(模式串与数字属主一律读 `ls -ldn`)。目标机上**没有 `stat` 不再是退回就地写的原因**,权限位照样带到换上去的新件上;
|
|
135
|
+
带不过去(目标的模式串读不出 / 读不懂、或目标机拒了那一次 `chmod`)而新件照样换上去 ⇒ 写照样答成功,五条车道同一行运维 warn `remote_env_file_mode_failed`(带车道名、目标路径的显示形与目标原来的模式串;升级前这一形无声,目标的模式位悄悄换成新件落下时的位);
|
|
136
|
+
`mv` 没成、落到就地拷入时不报(写进原 inode,模式本就不变);
|
|
137
|
+
收紧之后读不出模式串(`ls` 不可用 / 输出读不懂)才是 —— 与修前同一出路(直写退路 + `stage-seal-fallback` 计数)。悬空的单跳链接现在经链接就地写建出目标(修前 rename 原子建出;只在写的过程中崩溃时有可见差别)。
|
|
138
|
+
toybox(Android)上这些形按文档 / 源码**推断**可用,未上真机。
|
|
139
|
+
③ adb 的本机备件临时件带 0600(内容可能含凭据);adb push 把本机件的模式带上设备,所以设备目标的模式不再靠本机 umask,而是 push 之后显式 `chmod 0644`(adb 的每次 push 多一次设备命令往返)。设模式是**尽力而为**:字节已经落地,`chmod` 失败(设备文件系统不认改模式,如 Android 共享存储;设备掉线)⇒ 写照样答成功,运维日志一行 warn `remote_env_file_mode_failed`(带 push 目的地的显示形与设备回话首行),文件保留 push 落下的模式。
|
|
140
|
+
**取消落在这一步上,分两路**:直写退路(push 直落目标)⇒ 字节已在目标上,写答成功 + 同一行 warn;暂存路(push 进私有目录)⇒ 编排在提交之前复核取消 ⇒ `aborted`、目标一个字节没动(从未提交)、暂存件清掉 —— 与其余车道「提交前取消」同一读法。
|
|
141
|
+
文件保留 push 落下的模式时 —— 认模式的文件系统上是本机件的 0600,不认模式的文件系统上是它给的固定模式。升级前 push 成功即答成功、不设模式,模式随本机 umask(常见 0644)。
|
|
142
|
+
**谁需要**:adb 车道(Android)与精简镜像上的远端写;取消后要重试写的调用方(`aborted` 可直接重试)。**谁受伤**:依赖「备件窗口取消也答 `unknown`」的调用方读到更窄的 `unknown` 集合;写进不认改模式的设备路径(如 `/sdcard`)的部署每次写多一行 warn(写本身成功);五条车道上已有目标的权限位带不过去的那一次写多一行 warn(此前无声);`chmod` 失败而文件系统认模式的那一次,设备上的文件是 0600 而不是升级前的 0644(同一用户之外的设备进程读不到)。**补偿**:无需旋钮;传输中途的取消仍答 `unknown`,先重读目标;warn 带路径,模式不对的那只文件可在设备上补一次 `chmod`。
|
|
143
|
+
**升级前做**:无。**回滚**:无持久面;换回上一版即回到旧形。
|
|
144
|
+
|
|
145
|
+
10. **org scope 键的文法判只有引擎一只:静态目录、中心下发的目录里有引擎文法之外的 org 键 ⇒ 起服拒 / 该代目录不采用;共享记忆店的铸键点同判(行为面收紧;wire 零新键;部署动作:核键)**:
|
|
146
|
+
旧形:「这是不是一把 org scope 键」几处各判各的 —— 共享记忆店写侧收 `org:` 加至多 185 个非空白字符,`MEMORY_ORG_DIRECTORY_JSON` 装载收 `org:` 加任意非空白串,中心下发的 `orgMemory` 段只过契约包的类别门(`org:` 加非空白);引擎的记忆准入另按 v2 文法判(`org:` 加一段 `[A-Za-z0-9._-]` 或大写 `%XX` 的名,段至多 64 个编码字符)。名里有 `@` / `/` / `:` / 非 ASCII 的 org 键(例 `org:team@acme`)在目录与店里合法、到引擎的记忆准入里整请求拒(`config.memory_scope_key`),共享库读面却能用。
|
|
147
|
+
新形:三处判官都是引擎导出的 `isOrgScopeKey`,本仓不再存任何一份文法。① 静态目录:有键不过 ⇒ 起服拒,拒句点名主体与键(`MEMORY_ORG_DIRECTORY_JSON[…] has an invalid org scope key …`)。② 中心下发的远程目录:一代 `orgMemory` 里只要有一把键不过 ⇒ 这一代整代不采用(不丢单键放行其余;旧授予的时间戳不续、gen 高水位不动,中心改发好的一代即采用),该主体的目录答「坏形」:org 记忆准入判瞬时 `memory.admission_required`(503,带重试提示),共享库读面答连接不可用(可重试);服务日志一条 `org_directory_generation_refused`(`gen` / `badKeyCount` / 至多 5 把净化后的坏键),退避窗内不重复。③ 共享记忆店的铸键点(嵌入方 / 管理面调 `putScopeState` / `putStore`):键不过 ⇒ 在落任何语句之前抛 `shared-memory scope key … is not usable`;店的另三个写方法(`putDocument` / `deleteDocument` / `deleteStore`)的 `scopeKey` 是对登记行属主的围栏 —— 逐字比对(含 MySQL 尾随空格的拼法一律不当同一把键),不判键形,所以**店里已有的存量键行不受影响**:仍可写文档、可删,删后在引擎认的键下重建即可(无迁移代码)。
|
|
148
|
+
**谁需要**:要「目录 / 店 / 引擎对同一把键答同一个话」的运维 —— 此前用时才响。
|
|
149
|
+
**谁受伤**:静态目录里、中心目录里或店行里用了引擎文法之外 org 键的部署:静态目录起服拒;中心目录含这类键 ⇒ 该主体的整代目录不采用,所有读目录的面在中心改好键之前一直按「目录不可用」处理(与目录取数失败同映射):org 记忆准入瞬时拒;共享库读面对带 principal 的请求连其部署自证的库也不可读;principal 收件箱投递对收发任一方答不上来答 404 `org_delivery.not_member`(这一口不带重试提示)。此前这一代照常采用。一把陈旧的坏键出现在很多主体的表里时,这些主体同受;店的铸键点拒这类键。这类键本来就过不了引擎的记忆准入。
|
|
150
|
+
**补偿**:服务日志与拒句点名坏键(净化、有界);把名写成引擎文法的规范形 `org:…%XX`(引擎的 `formatOrgScope(<名>)` 即铸,例 `org:team@acme` → `org:team%40acme`)即恢复;存量店行无需动。
|
|
151
|
+
**升级前做**:核一遍三处的 org 键 —— 静态目录 JSON 里的 scope 键、中心(web-admin)里各主体的 org 记忆授权键、共享记忆店 `shared_memory_scope` / `shared_memory_store` 两表的 `scope_key` 列(只读 `SELECT`):全是 `org:` 加 `[A-Za-z0-9._-]`(段至多 64 字符)的 ⇒ 零动作;有别的字符的 ⇒ 先把目录与登记里的键改成 `%XX` 形,店里存量行无需动(围栏方法仍按旧键寻址可改可删);要迁到新键的,由导入方按新键重新导入后再用既有删除口逐行删旧键的行,不做任何整库 / 整表操作。中心一侧:同一代里好键坏键并存时整代不采用,改键要一次改齐。
|
|
152
|
+
**回滚**:无持久面;换回上一版即恢复旧收法。
|
|
153
|
+
|
|
154
|
+
11. **`inheritEnv` 的 `400 request.field_invalid` 机读位 `reason` 闭集四词 → 三词:`no_authorizer_session` 退出(装配器的根会话只剩一个读法 = 执行上下文交进来的根;「没有 authorizer 会话」这一拒因在 HTTP 面上不可达)**:
|
|
155
|
+
旧形:`inheritEnv:"all"` 在装配器读不到 `auth.sessionId` 时答 `400 request.field_invalid`、`reason:"no_authorizer_session"`。
|
|
156
|
+
新形:装配器只读执行上下文交进的根会话(受理漏斗与续跑腿恒交接),该拒因臂删除;`reason` 闭集 = `unknown_word` · `not_a_string` · `lane_not_host`(其余不变)。
|
|
157
|
+
**谁受伤**:按 `reason === "no_authorizer_session"` 分支的消费方(已知:sdk `openapi.yaml` / README 词表、client-core `inheritEnvWire.ts` 词表)—— 该词不再出现,分支变死码;改读 = 从词表删它。**补偿**:HTTP 面上两者本就恒等,线上零行为差;只是词表收窄。
|
|
158
|
+
|
|
159
|
+
12. **送话口的正文以用户输入到达模型,与调用方是不是运维无关:steer / interrupt 带 `text` 形 / wake 的正文与它们的停驻条目恒以用户源交给引擎;服务自己铸的 workflow 决定投递文本(宿主仍停驻时)恒以系统源投递(行为修复;授权面零变;wire 零新键;部署零动作)**:
|
|
160
|
+
旧形:三口的正文按调用方身份定框架 —— 运维(具名 `OPERATOR_PRINCIPALS`,或 `OPERATOR_SINGLE_USER=true` 下的每个调用方)的话被引擎铸成带 mark 的 `<system-reminder>`;workflow 决定投递文本跟着决定者身份走。
|
|
161
|
+
新形:调用方的话恒为用户源(live 腿 = 用户在工作中发来的新消息;停驻 / 唤醒腿续跑首轮 = 引擎的围栏数据段);服务自己铸的决定投递文本在唤醒腿上恒为系统源(与决定者身份无关)。运维身份只管越过属主门,判据不变。
|
|
162
|
+
**谁受伤**:靠「运维 steer 以系统提醒到模型」的部署(已知消费方零读点);单用户部署里回合停驻期间送达的插话,升级后以引擎的围栏数据段到达(段头「仅为数据」)。**补偿**:要以系统源注入的部署用引擎的 hook 反馈 / 部署提示座。**已知限制**:升级前已停在卡上的运维条目带着冻结的框架续跑;同一把 `Idempotency-Key` 跨升级重发同一句运维 steer ⇒ `409 steering.duplicate_input_id`(`detail.differs` 含 `"trusted"`,别换 key 重发)。
|
|
163
|
+
|
|
164
|
+
13. **应答口命中停驻行时点的「本会话放行」(`allow_session`)与 `/decide` 的 `remember:"session"` 同一只请求、同一个铸点:可记的停驻行由不记变记,`POST /v1/tool-approvals/:id/respond` 的 `parked_redeemed` 体上 `rememberApplied` 由恒 `false` 变真答;同口两条幂等回放(`idempotent:true`)不再挂 `rememberApplied`(行为修复;wire 值变化;部署零动作)**:
|
|
165
|
+
按 `rememberApplied === false` 断言「停驻支恒不记」或回放体带该键的消费方改读:`true` = 记住了,`false` = 只放行这一次,缺席(回放)= 本次没有授予判定(看首次回执或 `GET /v1/approvals/:sessionId/exemptions`)。workflow 出身 / 无会话锚的停驻行上 `allow_session` 不新增 400(与 `/decide` 的 `remember` 400 是唯一允许的两口差)。已知限制:耐久 ask 决定口 `POST /v1/tasks/:taskId/asks/:askId/decision` 的体不收 `remember`(只答未转停驻的活问;活问的「本会话放行」走 live 应答口的 `allow_session`)。
|
|
166
|
+
|
|
167
|
+
14. **`POST /v1/tasks/stream` 的账本落 `prompt_assembled` / `config_assembled` / `cross_boundary_taint` 三种既有行(此前这条腿恒缺,`POST /v1/runs` 与续跑腿一直有;wire 加性:零新键、零新事件名;部署零动作)**:
|
|
168
|
+
按事件序号逐字比对这条腿账本的消费方多见三种行(清单行先于首帧、污染行先于它被发出之后的下一帧,都先于终局行);按事件名分派的消费方零改动。非流式 `POST /v1/tasks` 结构上没有账本,不变。
|
|
169
|
+
|
|
170
|
+
15. **执行车道的声明座只有 `REMOTE_EXEC`:`REQUIRE_EXECUTION_LANE` 退役(设了任何非空值 ⇒ 起服拒,`config.env_key_retired`,拒句点名替代名 `REMOTE_EXEC`;随包部署产物不再渲它;部署面 BREAKING;7.146.0 已预告),车道词 `none` 落地(`REMOTE_EXEC=none` / `config.d/remote-exec.json` 的 `{"provider":"none"}`;`executionLane.provider` 的 `in-process` 换成 `none`(wire 值形 BREAKING,见第 16 条);部署零动作)**:
|
|
171
|
+
① **`REQUIRE_EXECUTION_LANE` 退役**:
|
|
172
|
+
旧形:`REQUIRE_EXECUTION_LANE=true` 让「没点名车道」拒启,随包部署产物(车道表 · 两份根 compose · 栈 compose · 两份 chart · 集群清单)一律写着这一键。
|
|
173
|
+
新形:它在契约包的退役 env 表里(替代名 `REMOTE_EXEC`),在场即拒启,写 `false` 也拒;空串 = 未设。随包产物不再渲该键;配置目录的退役投影 `retired[]` 列它。
|
|
174
|
+
② **车道词 `none`**:
|
|
175
|
+
旧形:`none` 不是车道词(写了拒启);「无手」只有 `REMOTE_EXEC` 未设一种写法,`executionLane.provider` 答 `in-process`。车道表(逗号串)遇第一处坏段即停、拒句列一份手抄的词表。
|
|
176
|
+
新形:声明了 `none` ⇒ 与 7.146.0 上非 local 形(`CONFIG_PROVIDER` 不是 `local`)的未设同一个运行期状态(无手、能力行同、执行环境块同;本版未设本身拒启,见第 16 条),`executionLane` 答 `{ provider: "none", toolsOnThisHost: false }`。车道表的拒因全部交回(坏词与重复同表两条都报),
|
|
177
|
+
`none` 与别的车道同表 ⇒ 拒(`must be the only entry`),只含空白的段报空段,拒句以契约规则句收尾;结论(拒启)与多车道「一进程一条」拒启不变。
|
|
178
|
+
**硬断预告的另两件本版同样兑现**:本文件「硬断预告」一条(7.146.0 期登记,见上)里的「未声明车道即拒启」与「`in-process` 改写成 `none`(含一次性迁移)」见本节「执行车道恒点名」一条 —— 预告的四件在 7.147.0 全部落地。
|
|
179
|
+
**谁需要**:每个部署(车道只有一个声明座 `REMOTE_EXEC`);要把「不给工具执行环境」写成声明的部署。**谁受伤**:自己写的 env、自己拼的清单、或从 7.146.x 及以前的随包产物拷过 env 的部署 —— 起服拒;对 `executionLane.provider` 八词穷举的客户端;按车道表旧拒句措辞匹配的脚本;
|
|
180
|
+
记着 `in-process` 的存量会话 / 审批行 —— 由一次性迁移 M40 改写成 `none`(见本节「执行车道恒点名」一条)。
|
|
181
|
+
**补偿**:自写 env 删一行(随包 compose 不带 `env_file`,旧 `.env` 里的残行不进容器);要表态「不给工具执行环境」写 `REMOTE_EXEC=none`。
|
|
182
|
+
**升级前做**:在部署的 env / 清单 / `.env` 里查 `REQUIRE_EXECUTION_LANE`,删掉;由中心(web-admin)编排器起的 worker,先把编排器换成已停渲该键的发行、再升 worker(DEPLOY-PREREQS 本版节)。
|
|
183
|
+
**回滚**:回到 7.146.x 时 `REQUIRE_EXECUTION_LANE` 缺席 = 旧缺省(不拒),无需加回;回到 7.146.x 之前先把 `REMOTE_EXEC=none` 撤掉(旧版拒启这一词)。
|
|
184
|
+
|
|
185
|
+
16. **🔴 执行车道恒点名:每个部署都要声明自己最终生效的执行车道(env `REMOTE_EXEC`;`CONFIG_PROVIDER=local` 形下 `config.d/remote-exec.json` 也算),未声明 ⇒ 拒启;状态名 `in-process` 改名车道词 `none`(wire 五处换值,零别名);存量 `in-process` 行由一次性迁移 M40 改写(停-迁-起,不可滚动);起服行 `exec_lane_selected` 只带 `{lane}`(行为 BREAKING;wire 值形 BREAKING;嵌入方类型面 BREAKING;持久面一次性迁移;部署动作:写明 `REMOTE_EXEC`,有存量行的部署停全部旧副本)**:
|
|
186
|
+
① **未声明即拒启**:
|
|
187
|
+
旧形:`REMOTE_EXEC` 未设 / 空串时,`CONFIG_PROVIDER=local` 隐含 `host`(工具直接跑在这台机器上,无 OS 沙箱),其余形静默落进不挂手的进程内桩(手带整族不挂、任务照跑、回执 `completed`)—— 同一个「没写」,两种结局靠第三个变量分。
|
|
188
|
+
新形:判点在执行车道合成步的尾部(本地配置文件覆写之后、中心拉取之前):最终车道不来自显式声明 ⇒ 拒启,拒句以 `No execution lane is declared — every deployment names its execution lane: set REMOTE_EXEC (with CONFIG_PROVIDER=local, config.d/remote-exec.json also declares it). To keep what this deployment did before 7.147.0: REMOTE_EXEC=none when CONFIG_PROVIDER is not "local" (…), REMOTE_EXEC=host when CONFIG_PROVIDER=local (…). …` 起,一行给出照旧行为的两条修法;`CONFIG_PROVIDER` 只回答「配置从哪来」,不选车道。
|
|
189
|
+
`REMOTE_EXEC=""`(空串)与未设同判。`run-local` 入口自身声明 `host` 车道(入口 = 部署者;声明的先后 = `config.d/remote-exec.json` > `REMOTE_EXEC` > 入口,在场的最高者终结选择,入口只填缺席位,不写进程 env)。`config.d/remote-exec.json` 点了隔离车道(`e2b` / `k8s` / `ssh` / `adb`:坐标此版只从 env 取)而 `REMOTE_EXEC` 没有声明同一条 ⇒ 拒启(修前:一行 `remote_exec_file_isolated_lane_unwired` 告警后照跑 env 的车道,或判点拒);出路是 `REMOTE_EXEC=<同一条>` 带齐坐标 env,或把文件改成要的车道;它只跑 `host` / `none`,部署声明了别的车道 ⇒ 起任何任务之前拒(换跑 HTTP 服务,或声明 `host` / `none`)。自建装配的嵌入方:`composeExecutionLane` 的 `ctx.drivesFromFile` 换成必填的 `ctx.entry`(HTTP 形递包根导出的 `HTTP_SERVICE_LANE_ENTRY`)。
|
|
190
|
+
② **`none` 两座皆无**:`REMOTE_EXEC=none`(或文件 `{"provider":"none"}`)⇒ 执行环境工厂与执行环境座都不给,每个 run 的 `wiring_manifest.hands = {mounted:false, reason:"no_execution_env"}`;手带之外的工具照常执行;请求体 hooks 与 stdio MCP 不归车道管(各自的开关照旧)。
|
|
191
|
+
③ **wire 五处换值(对象形不变,`in-process` → `none`)**:`GET /v1/capabilities` 的 `executionLane.provider` · `GET /v1/sessions/:id/execution-placement` 的 `lane` · 409 `execution_lane.not_served` 的 `boundLane` · 409 `execution_lane.tree_bound` 的 `boundLane` · 403 `execution_lane_not_allowed` 的 `extra.lane`。
|
|
192
|
+
车道全集仍是八个词(`host` `e2b` `k8s` `ssh` `adb` `local-docker` `device` `none`),`in-process` 不在其中;`REMOTE_EXEC=in-process` 起服拒(拒句列合法词)。嵌入方类型 `ExecutionLane` / `ALL_EXECUTION_LANES` 删旧词,零别名。
|
|
193
|
+
④ **起服行**:`exec_lane_selected` 由合成步在判点与不变量都过了之后发恰一行,字段只有 `{ lane }`(最终车道);此前多带的 `source` 退役;`remote_exec_real_system` 的「单机缺省落了 host」那一形随隐式 `host` 退役(显式 `host` / 非隔离车道照旧有这一行)。
|
|
194
|
+
⑤ **一次性迁移 M40(SQL 两方言 + local)**:`approval_ask.execution_lane` 与 `session_meta.execution_lane` 里的 `in-process` 改写成 `none`;local 数据根里会话元数据边档与审批问账日志里的同一词同改。改值不丢信息;窗 = 发布日 + 30 天,窗内每次起服都跑(之后无行可改即零动作),窗关之后的第一个 minor 删码。
|
|
195
|
+
**停-迁-起**:有 `in-process` 存量行的部署,停掉全部旧版本副本 → 起本版(起服时迁移)→ 再起其余副本;两版副本不可混跑(旧副本会在改写之后接着写旧词)。
|
|
196
|
+
**守卫**:SQL 后端上若库里有带旧词的行,而判活窗(`REAP_RUN_STALE_SEC`,收割器判「持有者还活着」用的同一个窗)内还有 `running` run 在心跳 ⇒ 起服拒 `config.execution_lane_rename_refused`,一行不改;拒句给出可以再起的时刻(最新心跳 + 判活窗,ISO 时刻与「N 秒之后」两种写法)—— 旧副本确已全停时,那些心跳是它们留下的 run,过了那个时刻收割谓词也判它们为死,再起即过。
|
|
197
|
+
**守卫看不见的一形(如实)**:守卫只看心跳,**空闲的旧副本**(没有在跑的 run)不留心跳 ⇒ 守卫放行;改写之后它若接新活,会再写下旧词,本版读到旧词的行时按「这一词已改名」响亮拒(不静默当作别的车道)。出路:停掉它,再起一次本版(窗内每次起服都跑 M40,漏网的旧词再改一遍)。所以「停全部旧副本」是运维的动作,守卫只兜住有 run 在跑的那一种。
|
|
198
|
+
local 数据根由数据根锁保证同一时刻只有一个进程,无需守卫。local 两腿读得出旧词而改写落不了盘(不可变文件 / 只读挂载 / 盘满)⇒ 起服拒 `config.execution_lane_rename_refused`,拒句点名文件与原错码,文件一个字节不动;恢复那只文件与所在目录的写权限再起,改名在下一次起服重跑。
|
|
199
|
+
**谁需要**:每个部署(车道只有一个声明座,「没写」不再有两种结局);按 `executionLane.provider` 判无手的面板与客户端(词表内的词,不再是表外状态名)。
|
|
200
|
+
**谁受伤**:没写 `REMOTE_EXEC` 的部署 —— 起服拒;按 `in-process` 字面分支的客户端(读到 `none`);有存量行又想滚动升级的部署(守卫拒,或空闲旧副本漏网后的响亮拒);依赖 `exec_lane_selected.source` 的日志规则。
|
|
201
|
+
**补偿**:拒句里就是一行修法;`none` 逐字复现 7.146.0 非 local 未设的运行期行为,`host` 逐字复现 local 未设的行为;守卫的拒句给出可以再起的时刻;M40 窗内每次起服都跑。
|
|
202
|
+
**升级前做**:① 在 env / 清单 / `.env` 里写明 `REMOTE_EXEC`:7.146.0 上非 local 而未设的 ⇒ `REMOTE_EXEC=none`,`CONFIG_PROVIDER=local` 而未设的 ⇒ `REMOTE_EXEC=host`(或在 `config.d/remote-exec.json` 里写);② 跑过未点名车道的部署(库里或数据根里可能有 `in-process` 行):停全部旧副本,再起本版;③ 客户端把 `executionLane.provider` / 放置读面 `lane` / `boundLane` / `extra.lane` 的 `in-process` 分支改读 `none`;④ 中心按 `allowedLanes` 写的车道准入策略里列 `none`(过渡期两个词都列,升级完删旧词 —— 那是策略数据,不是代码里的双读)。
|
|
203
|
+
**回滚**:回到 7.146.x 之前停全部本版副本,并把 `REMOTE_EXEC=none` 撤掉(7.146.x 不认这一词);M40 改写过的 SQL 行要回写才能被 7.146.x 读成它认得的词 —— **前提**:`session_meta.execution_lane` 在本版已被 M41 搬进 `session_ext`(第 5 条),先按第 5 条回滚把列加回 `session_meta` 并从 `session_ext` 回写,再跑下面两条(次序见第 5 条回滚):`UPDATE approval_ask SET execution_lane = 'in-process' WHERE execution_lane = 'none';` 与 `UPDATE session_meta SET execution_lane = 'in-process' WHERE execution_lane = 'none';`(在本版上声明过 `none` 之后新建的行同样会被改回,这正是 7.146.x 对「无手」的叫法);local 数据根没有反向工具 —— 升级前备份数据根,回滚 = 用备份。
|
|
204
|
+
|
|
205
|
+
17. **🔴 缺省推导的 local 只在数据根不存在 / 为空时退回内存;数据根上已有东西而开不了 ⇒ 拒启,与显式 `DB_BACKEND=local` 同形(行为变更)**
|
|
206
|
+
旧形:没写 `DB_BACKEND` 的部署开数据根失败 ⇒ 退回内存 + 一行 `store_db_unreachable_fallback_memory`(adoption 在飞与店的确定拒启除外),数据根里已有会话 / run 账本的那一形也一样;另一实例持锁时,第二只裸 boot 等满 `STORE_LOCK_WAIT_MS` 窗后退内存。
|
|
207
|
+
新形:开店之前读一次数据根:不存在 / 空目录 ⇒ 照旧退内存(`/health.storeDegraded`、gauge `store_backend_degraded` = 1、`store.degradedReason: "local_unwritable"`);有任何条目或列不出 ⇒ 开它时的任何失败原样拒启;持锁那一形等满窗后拒,拒句点名持锁 pid。
|
|
208
|
+
**升级前做**:`store_backend_degraded` 现为 1 的副本升级后可能拒启 —— 先读启动日志里 `store_db_unreachable_fallback_memory` 的 `error`,修好数据根的权限 / 挂载;本来就要内存形的写 `DB_BACKEND=memory`;要另起一个空根就把 `LOCAL_DATA_ROOT` 指到空目录。同机两只裸 boot 共用一个数据根的,给第二只单独的 `LOCAL_DATA_ROOT`。
|
|
209
|
+
**回滚**:回到上一版即回到按错误种类判的降级臂;数据零改动。
|
|
210
|
+
|
|
211
|
+
18. **引擎 7.64.0 → 7.65.0(`@sema-agent/core` 精确钉;`@sema-agent/primitives` 随 core 的同版精确依赖到 7.65.0):① 🔴 记忆控制面要在能建硬链接的卷上 —— 不能 ⇒ File 记忆后端起服拒 `memory.control_plane_links_unsupported`;② 兑付与导入的引擎拒按「可不可重试」一读,兑付后被撤的放行读 `refused` / `dot_removed`;③ 规则导入 prepare 的审批记录建不成 ⇒ `503 state.rule_write_failed`;④ 住客比较一读律;⑤ 起服日志 `session_box_mount` 取代 `mailbox_store_enabled` 上两格;⑥ 一次性迁移 local 腿报叫不出名字的桶数;⑦ 限制表上退役且没有后继的工具名 = 这一行跳过 + 说一句(会话流多一码 `config.legacy_tool_name`;请求体 / 部署名单 / 中心下发的审批名单不再拒)(行为变更 + 硬破坏一条;部署动作只在 ①)**:
|
|
212
|
+
换钉:`@sema-agent/core` 7.64.0 → 7.65.0 精确(`package.json` 只钉 core),`@sema-agent/primitives` 随 core 的精确依赖到 7.65.0。下列各项按「谁看得见」排。
|
|
213
|
+
① **记忆控制面的硬链接(硬破坏)**:
|
|
214
|
+
旧形:File 记忆店在任何文件系统上都打开;控制面所在的卷不能建硬链接时,每个控制对象写失败 —— 一次收留把可疑文件从模型可见面拿下、副本却一份都没存下(报告 `quarantine copy FAILED`)。
|
|
215
|
+
新形:引擎每次开店先在控制面顶层试建一枚硬链接(`.link-probe-<uuid>`,试完即删);不能 ⇒ 店在打开处被拒,码 `memory.control_plane_links_unsupported`(店形拒一族的第三码;拒句点名 errno、不带路径),店里的文件一个字节不动。
|
|
216
|
+
本服务:`MEMORY_ENGINE_BACKEND=file`(缺省)的 File 记忆后端构造期抛 ⇒ **起服拒**;`MEMORY_ENGINE_BACKEND=pg|mysql` 的引擎 mount 时在自己的控制面上开 File 店被拒 ⇒ 这一跑没有记忆、会话照跑
|
|
217
|
+
(`effectiveMemoryScopes` = `{ state: "memoryless", reason: "mount-failed" }`;运维行 `memory_engine_incident` 带码,fail-open 计数 `server.memory.store-form-refused-step-skipped`);运维面经引擎开店撞上它 ⇒ `409` 原码。
|
|
218
|
+
**谁需要**:每一次收留都要真存下副本的部署(上一版在这种卷上静默丢副本)。**谁受伤**:记忆控制面(记忆根 —— `MEMORY_ENGINE_DIR`,缺席时数据根 —— 下面那只 `<slug>/.engine` 目录;目录钉住的部署另有个人平面的 `personal/.engine`,运维面第一次用到个人平面时开)在不能建硬链接的卷上 —— 有的网络共享、FAT / exFAT 卷、有的容器 overlay 配置。
|
|
219
|
+
**补偿**:把控制面挪到支持硬链接的卷上;店的文件不受拒动,无需迁移。支持形:docker `-v` 绑定挂载、k8s PVC 块存储、`hostPath`、`emptyDir`(本地文件系统)都能建硬链接;NFS 不可靠(见 DEPLOY-PREREQS 的 `DB_BACKEND=local` 数据目录一节);SMB / Azure Files / FUSE 类卷不在支持形(不能建硬链接 ⇒ File 记忆后端起服拒)。本服务的工具结果、文件历史与邮箱锁本来就要硬链接,但那是数据根所在的卷;记忆根在另一只卷上时,那只卷要自己试。进程崩在试建与删除之间会留一枚 `.link-probe-*`(不当记录读,可手删)。
|
|
220
|
+
② **兑付 / 导入的引擎拒**:赎回拒臂与批成员拒臂多一位 `retriable`。卡道:`retriable` 真且是店故障 ⇒ 可重试的 `rule_store_error`(批:全员被拒且全员可重试才重兑);其余 `redeem-refused`。
|
|
221
|
+
导入两只 redeem 口:成员可重试或引擎说不知落没落 ⇒ `503 state.rule_import_retry` 同票重走;其余拒是确定结局(200 回执里 `refused`)。相对上一条(7.146.0 节第 23 条「引擎 7.63.0 → 7.64.0」⑥):
|
|
222
|
+
记 dot 的 CAS / dot 分配失败卡道改回可重试;同票重走时其间被属主撤掉的放行在回执里读 `refused` + `reason: "dot_removed"`(此前仍读 `persisted`;那一条的已知限制只对引擎 ≤ 7.64.0 成立)。
|
|
223
|
+
③ **规则导入 prepare**:引擎的审批记录店建不成这次导入的记录 ⇒ `POST /v1/rules/cc-import/prepare` / `POST /v1/rules/local-import/prepare` 答 `503 state.rule_write_failed`(带 `committed: "no"`;没有票、没有放行落店;
|
|
224
|
+
local-import 这一批收下的 deny / ask 可能已落店)—— 原样重发即重铸。此前两口落未分类 500。确认口的记录店故障:卡道可重试、导入道同票重走。
|
|
225
|
+
④ **住客比较**:两侧都没有化身令牌的住客比较由「说不准」改答「同一位」,一侧有一侧没有答「不是同一位」。本服务会话缓存的新鲜判随之命中两侧都没戳的会话头(本服务的店建行即铸化身;写面照旧拒)。
|
|
226
|
+
⑤ **起服日志**:`session_box_mount { peerLaneMountable, peerLaneRefusal?, reason? }`(邮箱店 × 会话店一只判;不拒起服);`mailbox_store_enabled` 去掉 `peerLaneMountable` / `peerLaneRefusal` 两格。
|
|
227
|
+
⑥ **一次性迁移(导入层根的全局放行退役)local 腿**:引擎一次答出桶在场的属主(导入记录点名的身份交给它)与叫不出名字的桶数;报告新键 `importedLayerRootBucketsUnnamed`(SQL 恒 0),
|
|
228
|
+
非零每次起服 warn `imported_layer_root_buckets_unnamed`(带个数)—— 那几只桶本步没读,其中这种放行照旧生效,按属主列规则(`GET /v1/rules`)处置。
|
|
229
|
+
⑦ **限制表上退役且没有后继的工具名**(引擎退役表里那一行是 `removed` / `folded into`:`TeamCreate` · `TaskOutput` · `MultiEdit` …)—— 这一行跳过 + 说一句(不审、不拒),整表不拒(只在有人说那一句的三道门,见下);改名了的旧名(有后继:`Task` ⇒ `Agent`、`KillShell` ⇒ `TaskStop`)照旧拒。
|
|
230
|
+
行原样留着(表谁都不改;嵌入方自挂同名工具时它照管那只工具)。谁读这张表,谁说:
|
|
231
|
+
请求体 `settings.permissions.deny` / `ask` 与会话存下 / 祖先交下来的规则 —— 引擎读:请求照收(此前 `422 request.unprocessable`、`reason: "retired"`;存量会话规则上此前整跑被拒),会话流通告 `config.legacy_tool_name`(受众 user);
|
|
232
|
+
部署 `APPROVAL_REQUIRE` / `APPROVAL_DENY` / `APPROVAL_NEVER_AUTO` —— 本服务读:照常起服(此前拒启),起服 warn `approval_list_legacy_tool_name`(一张表一行,点名 env 与条目);只剩这种行的表仍算审批意图(没有 checkpoint 店的部署照「名单在场要 durable 门」拒启,与写任何名字同一判 —— 删掉那一行即可);
|
|
233
|
+
中心下发 `governance.approvalRequire` —— 本服务读:整组照落(此前整组拒、保前值),组受理之后 warn `web_admin_approval_require_legacy_tool_name`。
|
|
234
|
+
放行只在有人说那一句的这三道门;没有人说话的面照拒(不拒就是静默受理),候引擎下一版在选择器表 / 技能表发退役名通告、并导出通告句源后同形放行:请求体 `settings.permissions.neverAuto`(`422`,与上一版同码同句)·
|
|
235
|
+
请求的 `excludeTools`(`400 config.tool_face_control`)/ 子代 `denyTools`(`400 config.agent.unknown_tool`)/ 技能 `disallowedTools`(`400 request.field_invalid`)。
|
|
236
|
+
**谁需要**:写着这种名字的限制表(壳从 CC 用户 settings 转投的 deny 表常带)—— 不再因一行死项整份被拒。**谁受伤**:按 422 `reason: "retired"` / 拒启 / 整组拒找这种名字的调用方与运维 —— 改读通告与两条 warn。**补偿**:按通告 / warn 点名的条目把它从表里删掉。
|
|
237
|
+
**引擎已知限度(随版发)**:多只副本共一只记忆控制面时,扣留账的对账与收留写可能交错、把行记成 `capture_lost` 而保管字节成孤(KL-3485-a,引擎下一版收);
|
|
238
|
+
采集退出记录与污染标记对同一只坏槽两读(KL-3466-b,过渡双读);引擎面百分号只解一层(KL-3487-a)—— 本服务出口脱敏器解到定点,覆盖它。
|
|
239
|
+
**谁需要 / 谁受伤 / 补偿**:见各项。**升级前做**:① 核记忆控制面所在的卷能建硬链接(在那个目录里 `ln a b` 试一次);不能就先挪;② 按 `mailbox_store_enabled.peerLaneMountable` 告警的规则改读 `session_box_mount`;
|
|
240
|
+
其余零动作。**回滚**:回到上一版 ⇒ 不能建硬链接的卷上 File 记忆店照旧打开(并照旧丢收留副本);其余各项无持久面(零 DDL、零一次性迁移)。
|
|
241
|
+
|
|
242
|
+
19. **本服务自己要的目录一律 `0700`:新建的目录创建即 `0700`,升级前由裸 `mkdir` 铸成 `0755` 的 `DB_BACKEND=local` 数据根下 `runs/<taskId>` · `space-commits` · `checkpoint-ctx` · `.tmp` · `attachments` · 会话 scratchpad · 中心 plugin 缓存 · 记忆同步游标目录起服时一次性收紧(一次性迁移 M39);本服务自己落的文件一律 `0600`、原子写的 tmp 每次独占新建(安全面;持久面;日志面加性;部署零动作,外部读者见「升级前做」)**:
|
|
243
|
+
旧形:本服务自己铸的目录有几种做法 —— 一部分店走 core 的 `ensureDir`(`0700`),run 店(`runs/<taskId>` · `space-commits`)· checkpoint 店(`checkpoint-ctx` · `.tmp`)· 附件店(`attachments`)· 会话 scratchpad · 中心 plugin 缓存 · 记忆同步游标目录 · 配置根下的 LKG 父目录与技能正文缓存直接 `mkdir -p`(进程 umask 之下的 `0755`)。
|
|
244
|
+
目录 `0755` 而里面的文件多半 `0600`:组 / 他人读不了文件,但列得出文件名(run 的 taskId、附件 id、checkpoint token 文件名);附件店的文件与会话边档(`session-titles.json` 等)是默认的 `0644`,`0755` 的 `attachments` 目录连附件字节都对别的本机用户开着。
|
|
245
|
+
新形:这些写口也走 `ensureDir`,新建的目录一律 `0700`(`src/**` 没有第二种建目录的写法、没有手写的 `0o700`,有普查钉);本服务自己落的文件(附件 · 会话边档 · 记忆同步游标 · LKG · 技能正文缓存 · 凭证续签 · 钥匙文件 · 完成收件箱 · spool · 数据根顶层的 `exit-last.json` / `crash-last.json`)只读一个模式值 `0600`;
|
|
246
|
+
原子写的 tmp 每次独占新建(pid + 随机名、`O_EXCL`;同步写口 —— 完成收件箱账本的压实、续租被拒的粘性位 —— 也一样,它们原先经引擎的原子写,那一只以截断方式打开 tmp):此前固定 / 可复用的 tmp 名(附件的 `<id>.bin.tmp` / `<id>.json.tmp`、最近活动边档的 `<path>.<pid>.<n>.tmp`)在崩溃后留下的升级前 `0644` tmp 会被下一次写截断后原样改名上位、把 `0644` 带上正式文件,现在不会。升级前已有的 `0755` 目录,`ensureDir` 对已存在的目录什么也不做 —— 所以起服时(`DB_BACKEND=local`,任何读者之前)一次性收紧:
|
|
247
|
+
对 `runs` 与它下面的每一只子目录 · `tmp` · `space-commits` · `checkpoint-ctx` · `.tmp` · `attachments` · `scratchpad`(与每个会话段)· `plugin-cache`(往下三层)· `<记忆引擎根>/sync-cursors`(缺省 = `<数据根>/sync-cursors`;引擎根在数据根之外则不在其内)从数据根(持锁的那只物理路径;起服途中它自身被换成链接 ⇒ 一行 warn 点名数据根(`.`),整步不走)逐段往下看:
|
|
248
|
+
路径上任一段是符号链接 ⇒ 这一条整条不走、进 warn(码 `SYMLINK_IN_PATH`,链接指向根内根外一样);是真目录且带组 / 他人位的 ⇒ 先以 `O_NOFOLLOW` 打开取 fd,再核这只 fd 就是根内那条路径上的目录
|
|
249
|
+
(物理路径按段在数据根之下、那条路径此刻的 inode 等于 fd 的、路上每一段此刻仍不是链接),三者皆过才对这只 fd 收紧成 `0700`(已有文件的模式一字不动;普通文件不碰;不在的不建;数据根自身与名册外的目录不碰)。
|
|
250
|
+
收紧了至少一只 ⇒ 一行起服提示 `local_data_dir_modes_tightened`(`count` + 至多五个 `examples`,相对数据根);第二次起服零命中零写、不再有这一行。win32 没有 POSIX 模式位,整段不动。
|
|
251
|
+
**收紧失败不拒启,但响亮**:目录不属于服务进程的用户(只能写、不能改模式)、路径上有符号链接、检查之后被换走(`ESTALE`)等 ⇒ 逐目录点名(路径 + 码)进 warn `local_data_dir_mode_refused`(`entries` 至多十条,带出路),窗内每次起服再报,其余目录照收,服务照起。
|
|
252
|
+
把店目录链到别的盘的部署:链接那头的真目录不被跟、不被改,由属主自己 `chmod 700`(这一行窗内每次起服都在 —— 迁移看不见链接那头是否已改)。
|
|
253
|
+
新写下的文件在这样的目录里仍是 `0600`(含附件店与会话边档);留着的缺口只有一格:升级前写下的附件字节(`0644`)在一只收不紧的 `attachments` 目录里仍可被他人读到 —— 看到这一行 warn 点名 `attachments` 的部署要当天处理。
|
|
254
|
+
**不在迁移里的(披露)**:SQL 后端的 host 车道在同一个数据根下铸的 `scratchpad` / `plugin-cache`、配置根(`SEMA_CONFIG_DIR`,缺省 `~/.sema`)下的 LKG 父目录与 `skill-cache`、`MEMORY_ENGINE_DIR` 指到数据根之外的 `sync-cursors`,升级前若是 `0755` 原样留着(新建的一律 `0700`);升级前已落盘的边档文件(`session-*.json`)与记忆同步游标不扫 —— 下一次重写即换成 `0600`;崩溃留下的旧固定名 tmp(`attachments/<id>.bin.tmp` 等)不再被复用、也不清扫;数据根顶层的 `exit-last.json` / `crash-last.json` 是原地覆盖,升级前已在的那两只模式不动(新建的是 `0600`)。
|
|
255
|
+
要收这些:`chmod 700` 它们(目录),或 `chmod -R go-rwx <配置根>`。工作树类目录(宿主执行环境替工具建的目录)、spool、壳 / 请求 / 运维点名的目录不在其内,模式不变。
|
|
256
|
+
**谁需要**:每个 `DB_BACKEND=local` 部署(自动,无配置);配置根与缓存目录的收紧只对新建生效。**谁受伤**:靠组 / 他人读权限读数据根的外部进程 —— 另一个用户身份的备份 / 监控 / 同步任务升级后列不出、读不进这些目录;数据根的目录属主不是服务进程用户的部署,收紧被拒、每次起服一行 warn。
|
|
257
|
+
**补偿**:外部读者换成服务进程的用户身份,或给数据根加 ACL(`setfacl`);被拒的目录由属主 `chmod 700 <目录>`(或 `chown` 给服务用户)后重启,那一行 warn 即消失。无放宽旋钮(只收不放)。
|
|
258
|
+
**升级前做**:`find <数据根> -maxdepth 3 -type d -perm /077` 看一眼会被收紧的目录(信息性);有别的用户身份在读数据根的部署(备份 / 监控),升级前把读者换成服务身份或配 ACL。
|
|
259
|
+
**将来变化**:这一步是一次性迁移,窗内(发布日 + 30 天,日期见 `plugins/one-time-migrations.ts` 登记表 M39 行)每次起服都跑,窗关之后的第一个 minor 删码 —— 此后从更早的版本直升的数据根,升级前铸成的 `0755` 目录原样留着(新建的一律 `0700`,不受影响),本服务不再点名;
|
|
260
|
+
出路 = 运维一次 `chmod 700` 数据根下 `runs`(及其子目录)· `space-commits` · `checkpoint-ctx` · `.tmp` · `attachments` · `scratchpad`(及其子目录)· `plugin-cache`(及其子目录)· `<记忆引擎根>/sync-cursors`,或升级时先过一次带本条的版本并起服。**回滚**:回到 7.146.x 时已收紧的目录保持 `0700`(旧版对已存在的目录不 chmod),旧版新建的目录又是 `0755`。
|
|
261
|
+
|
|
262
|
+
20. **hook 条目的 `onFailure: "block"` 自本版起执行:同步的 command / http 条目被选中却没给出裁决 ⇒ 按退出码 2 算,它守的动作被拦下;续跑重放读出存量请求里的 `onFailure`(安全轴,失效关闭;行为变更;部署零动作);同批:续跑存量体里有本版读者读不出、而本部署本会采纳的成员 ⇒ `409 resume_blocked_by_policy`(安全轴,不再去掉照跑);新提交 `settings.env` 有成员不是串 ⇒ `400 request.field_invalid`(采纳 env 的车道);坏 `args` 的 400 判决改由契约分类器出(`detail.reason` 由 `wire_key_invalid` 变为 `entry-invalid` / `guard-entry-invalid`;wire 值变,BREAKING)**:
|
|
263
|
+
旧形:7.135.0–7.146.x 新提交里 command / http 条目上的 `onFailure` ⇒ `400 request.body_shape`(读者不携带);续跑重放的存量请求里它被读者剥掉 —— 写了 `"block"` 的守卫起不来时照放行。
|
|
264
|
+
新形:读者携带它(契约包 19.0.0),本服务执行 `block`:起不来 / 超时 / 退出码非 0 非 2(http 非 2xx)/ 输出读不成判词 / `PreToolUse` 判词在闭集外,以及本服务自己的门让它没跑成(URL 名单拦下、
|
|
265
|
+
shell 形 powershell、`if` 评不出、组的 matcher 编不过、事件墙钟耗尽)⇒ 交给事件的是一次退出码 2(`PreToolUse` deny · `UserPromptSubmit` / `PreCompact` block · Post* 三站一段反馈上下文),
|
|
266
|
+
句子 `<事件> hook did not reach a verdict (<成因>); blocking because onFailure is "block"`。`async` / `asyncRewake`、`Stop`、`StopFailure` / `PostCompact` 上不生效;`continue` 与缺席同 7.146.0。
|
|
267
|
+
`onFailure` 写在 prompt / agent / mcp_tool 条目上照旧是读者不携带的键(新提交 400)。7.135.0 节第 13 条「投影前剥掉 `onFailure`」的建议对 command / http 条目不再适用。
|
|
268
|
+
**谁需要**:要守卫起不来时拦下的调用方。**谁受伤**:① 写了 `block` 的条目因本服务自己的门没跑成 —— 此前放行,现在拦下;② 升级前停驻的任务:存量请求(只可能来自 7.134.x 及更早:7.135.0 起新提交带这个键就 400)
|
|
269
|
+
里写了 `block` 的守卫续跑时开始按 block 执行;存量里写的是两词之外的值 ⇒ 读者判坏块,续跑**拒**:这条车道本会采纳请求体 hooks(单用户车道)⇒ `409 resume_blocked_by_policy`(`blockedBy: "request.field_invalid"`,`field: "settings.hooks"`;句子只点名成员键,不回显值),卡 / 任务仍待决、行不动;不采纳请求体 hooks 的车道(多租户)零变化 —— 续跑重读的一次性迁移不接这一形(坏值没有可猜的正确值)。
|
|
270
|
+
同一条律覆盖存量体里本版读者读不出、而这条车道本会采纳的每一个成员:`settings` 的其它键(如 `env` —— 有成员不是帽内的串;空记录 `{}` 不算 —— 车道采纳调用方 cwd,或采纳请求体 hooks 且请求带着 hooks 时)、`mcpServers[i]` 的传输成员(部署注入请求 MCP、条目名不被部署占住时)、`a2aPeers[i].headers` 的成员(部署注入请求 A2A 时)——
|
|
271
|
+
升级前这些成员被去掉、任务照跑(运维日志 `task_settings_deferred` / `mcp_transport_members_dropped` / `a2a_peer_headers_members_dropped`,外加 hooks 的 fail-open 计数 `server.hooks.resume-reader-refused`),这三行日志与该计数本版一并退役;新提交带同样的成员 ⇒ `400 request.field_invalid`(同一只判;新提交面唯一的新拒是 `settings.env` 里值不是串的成员 —— 受理门收下了它们,此前装配静默不交;只在采纳 env 的车道上拒:单用户 host / device,或采纳请求体 hooks 的车道上请求带着 hooks,其余车道 env 没有读者、零变)。
|
|
272
|
+
判的是**续跑将要跑的那一份体**:续跑请求带了重述键 `mcpServers` / `a2aPeers`(四道续跑门都收)⇒ 按盖过重述之后的体判,读不出的 MCP / A2A 成员可由一张合形的整表(空表也算)换掉、照常续跑;不带 ⇒ 存量体原样判。
|
|
273
|
+
拒体形(如实):复用 `409 resume_blocked_by_policy` + `blockedBy: "request.field_invalid"`(不铸新码);句子只列成员键路径(不回显值、不带会话坐标 —— 会话坐标在运维行 `resume_refused_stored_body` 上);A2A 对端不看场景同名占位(存体预判在认领之前答、不知道场景)⇒ 会输给同场景部署同名对端的那条请求对端照样算,方向是多拒一次。
|
|
274
|
+
**补偿**:拦下的那句点名成因,故障帧点名是哪一条;改条目 / 改 URL 名单,或改回 `continue`。不加窗、不加旋钮。续跑被拒的停驻任务:拒句点名哪些成员读不出;出路 = 读不出的是 MCP / A2A 成员 ⇒ 续跑请求带这一键的合形整表;其余 ⇒ 取消那只任务、按本版的形重提(一次性迁移 M20 窗内,两类此前受理的 hooks 存量形照旧由剥键重读接住,不拒)。新提交的 `settings.env` 值写成串即过。
|
|
275
|
+
**同批:坏 `args` 的 400 判决改由契约分类器出**:
|
|
276
|
+
旧形:7.133.0 起本服务在契约分类器装上的同一坐标上读原值 `args`,形错 ⇒ `400 request.field_invalid`,`detail: { reason: "wire_key_invalid", key: "args", path: [..., "args"] }`。
|
|
277
|
+
新形:契约包 19.0.0 承运 `args`(串数组、元素无 NUL;`[]` 与空串元素合法 —— 与本服务旧读法同形),坏值是分类器的坏块;本服务不再读第二遍原值:`detail.reason` 变为 `entry-invalid`(非守卫事件)/ `guard-entry-invalid`(守卫事件),
|
|
278
|
+
`key` 仍是 `"args"`,`path` 指那一条而不是那只键;句子换成块码释义。受理与执行的形不变。
|
|
279
|
+
**谁受伤**:按 `reason === "wire_key_invalid"` ∧ `key === "args"` 匹配的客户端 / 脚本。**补偿**:按 `detail.key === "args"` 读。
|
|
280
|
+
**升级前做**:原样投影宿主设置文件的调用方,确认守卫条目上 `block` 是本意;有 7.134.x 及更早停驻、hooks 里写着 `onFailure` 的任务,升级前把它们跑完或取消。**回滚**:回到 7.146.x 即回到「新提交 400、续跑剥掉」,`args` 的 400 判决回到旧坐标与旧 `reason`。
|
|
281
|
+
|
|
282
|
+
21. **日志脱敏认复合凭据名(`DB_PASSWORD` / `PGPASSWORD` / `SECRET_KEY` / `AWS_SECRET_ACCESS_KEY` …,名字末尾收在强档词上);请求面 URL 凭据判官随包认同一批名字(行为变更:遮得更多、新提交拒得更多;部署零动作)**:
|
|
283
|
+
旧形:脱敏器只认整名表上的名字,复合名后面的值原样出门;请求面 URL 只拒整名在表上的参数。
|
|
284
|
+
新形:名字判定读契约包的判官(整名在表上,或末段尾部是 `password` / `passwd` / `pwd` / `secret` / `apikey`,或末尾是 `secret_key` / `secret_access_key` / `api_key` / `access_token`;只看末尾,`password_hash` / `tokens` 不算);日志四个名字读者同读,名长不封顶。
|
|
285
|
+
请求面 URL 带这类参数(`?db_password=…`)⇒ 新提交 `400 request.field_invalid`(`reason: "url_credential_param"`);续跑重放存量体照旧不判。
|
|
286
|
+
**谁需要**:日志 / trace 里出现复合凭据名的部署。**谁受伤**:读日志的人(末尾收在强档词上的非凭据名也被遮,如 `show_password=1`;单行出门形里凭据值后紧贴的下一行首词随值遮);URL 里带复合凭据名参数的调用方。
|
|
287
|
+
**补偿**:无放宽旋钮(脱敏只收不放);非凭据的名字改名让末段不落在强档词上;URL 凭据改走同一条目的头位(MCP `transport.headers` · A2A `headers` · hook `headers` · 搜索 `apiKey`)。**升级前做**:无。**回滚**:回到 7.146.x 即回到整名判定。
|
|
288
|
+
|
|
289
|
+
22. **本地配置源开始读 `config.d/a2a.json`(行为变更);中心发的 `a2a` 域过契约读口(坏条目点名丢);内部型 `EffectiveConfig.a2a` 改契约型 `A2aConfig`、`CenterA2aPeer` 删(包导出面零变化);同批披露:对端 `allowSkills: []` 的读法将变(本版零行为变化)**:
|
|
290
|
+
旧形:`EffectiveConfig.a2a?: { peers: CenterA2aPeer[] }`(本仓自持的对端型,`enabled` / `scenarios` 可缺席);本地腿不读 `config.d/a2a.json`(读腿点名为没人读的文件);中心 `/effective.a2a` 原样透传给解析器。
|
|
291
|
+
新形:`EffectiveConfig.a2a?: A2aConfig`(`@sema-agent/settings-schema` 的型;条目 `A2aPeerSpec`,`enabled` / `scenarios` 由读口补缺省、型上必填),`CenterA2aPeer` 删去(两者都不在包根 / 子路径的导出面上);两腿读成同一个声明;
|
|
292
|
+
本地腿没写 = `{ peers: [] }`,中心没发这一域 = 缺席(契约包 20.0.0 起线上读口不替中心编造它没发的域),两者与空名册是同一个运行期状态(不拨对端)。写法见 USAGE 9.5i-bis。
|
|
293
|
+
**谁需要**:本地配置源要声明常驻 A2A 对端的部署。
|
|
294
|
+
**谁受伤**:① 越过包的 `exports` 深引 `dist/web-admin-client/*` 的代码(不受支持的面):`CenterA2aPeer` 不在了、`EffectiveConfig.a2a` 的条目要带 `enabled` / `scenarios`;② 本地配置根里早就有 `config.d/a2a.json` 的部署,升级后这些对端在首次被用到时被拨号(任务准备取卡 / 会话 A2A 面板读缓存缺失或过期;起服本身只解析配置、不取卡);③ 中心发的对端 url 带 userinfo / fragment / 像密钥的 query 值、名字越界、`headerRefs` 有坏成员 ⇒ 这一条不再拨(此前原样交给引擎)。
|
|
295
|
+
**补偿**:① 改从 `@sema-agent/settings-schema` 取 `A2aConfig` / `A2aPeerSpec`;② 不要的文件删掉;③ 按读口告警改对那一条,凭据走 `headerRefs`。
|
|
296
|
+
**披露:对端 `allowSkills: []` 的读法将变(本版零行为变化、零 wire)**:今天配置腿(`config.d/a2a.json` / 配置中心)上 `allowSkills` 写空表与不写同读 = 挂对端发布的**全部**技能(契约包 20.0.0 的字段定义,本服务照它读);请求腿 `a2aPeers[].allowSkills: []` 原样交引擎 = 零技能。
|
|
297
|
+
契约包下一个 major 起配置腿上空表 = **零技能**(与请求腿同读),本服务随那一版提货。**谁受伤**:配置腿上写了 `allowSkills: []` 本意是「全部」的部署 —— 提货那一版起这个对端一只技能都不挂。**升级前做**:要全部就删掉这个键,要不拨这个对端就写 `enabled: false`;本版无需动作。
|
|
298
|
+
**披露:对端拨号面今天没有主机底线(已知限制)**:启用的对端按 `url` / `cardUrl` 取卡、按卡里写的服务端点发送,不过任何部署主机底线(本服务今天不给引擎接它);`url` / `cardUrl` 是运维写的,可指向任意主机(含内网与回环),不带头的对端(这次发送不带任何声明的头)的服务端点由它的卡写、可指向任意主机、遇重定向照跟(带头的对端另受引擎的端点绑定:服务端点须落在声明的 `url` / `cardUrl` 所在的源上,且不跟重定向);取卡发生在每次任务准备与会话 A2A 面板缓存缺失 / 过期时,起服本身不取卡;多租户部署同样挂(多租户闸只关请求体自带的 `a2aPeers`,部署基线照挂)。**谁受伤**:在多租户 / 公共部署里写了 `config.d/a2a.json` 对端的运维 —— 不带头的对端,它的卡能让引擎去敲内网地址。**补偿**:只写可信对端、自审 `config.d/a2a.json`;出路 = 部署主机底线接线(尚未到货)。
|
|
299
|
+
**升级前做**:本地配置根 `ls config.d/a2a.json`;留下的对端逐个确认可信(见上一条披露)。**回滚**:回到 7.146.x 后 `config.d/a2a.json` 又不被读(读腿点名),中心腿回到透传。
|
|
300
|
+
|
|
301
|
+
23. **目录条目的 `thinkingLevelMap` 开始生效(坏形整条丢);anthropic 条目的 `compat` 按线路生效;`GET /v1/models` 行加 `thinkingLevelMap`(行为变更 + wire 加性;部署零动作,升级前自查目录)**:
|
|
302
|
+
旧形(7.146.x):条目带 `thinkingLevelMap`(合形也算)⇒ 契约包读腿把它当未知键剥掉并告警(`unknown-keys-dropped`),**本服务把该告警判成域失败 ⇒ 整份候选拒**(本地 `config.d` 起服回落 env,env 也没配模型即零模型 `config_local_no_models`;中心腿停在上一份好配置),声明到不了引擎;anthropic-messages 条目的 `compat` 一律整只丢 + 一条 `model_compat_dropped`。
|
|
303
|
+
新形:契约包 20.0.0 判 `thinkingLevelMap` 的形(键 `off` / `minimal` / `low` / `medium` / `high` / `xhigh` / `max`,值非空串或 `null`),合形原样交引擎(串 = 那一档发的值,`null` = 那一档不支持;当前引擎只在 openai-completions / responses 条目上读它,anthropic-messages 条目上原样带、零效果),
|
|
304
|
+
坏形(未知键 / 非对象 / 空串 / 非串非 `null`)⇒ 那一条被读腿丢(`entry-dropped`);被 `roles` / `atMention.only` / `tierGroups` 引用的条目坏了 ⇒ 契约包把整个 `models` 域读成缺省(`domain-defaulted`),本服务把它判成域失败 ⇒ 整份候选拒(本地 `config.d` 起服回落 env、中心腿停在上一份好配置)。env 腿没有这一席。
|
|
305
|
+
条目里写了本契约版本不认识的键(`thinkingLevelMap` 自己的键是闭集,那是上一句的坏形,不是这里):7.147.0 仍整份候选拒(读腿剥键告警,本服务判成域失败);自 7.148.0 随 settings-schema 22.0.0 起,允许逐条丢弃的域里持键层为数组元素的未知键 ⇒ 该条目丢弃(点名),其余域不变。
|
|
306
|
+
anthropic-messages 条目的 `compat` 读 `thinkingMode`(`budget` | `adaptive`)/ `effortLevels` / `supportsTemperature` / `contextManagement` / `interleavedThinking`;写了 openai 线路的键(`thinkingFormat` 等)照旧整只丢 + warn。
|
|
307
|
+
`GET /v1/models` 行加可选键 `thinkingLevelMap`,anthropic 行可带 `compat`;声明了的行上 `supportsThinkingOff` / `supportedEffortLevels` 随声明变。
|
|
308
|
+
**谁需要**:端点某档关不掉 / 换名的部署,adaptive / effort 族 anthropic 端点。**谁受伤**:① 目录里写过 `thinkingLevelMap` 的(此前整份候选被拒、没有装上,见旧形)—— 坏形的那一条升级后被丢,被引用时整份候选被拒(停在上一份好配置 / env);合形的见 ②;
|
|
309
|
+
② 写过合形的 / anthropic 条目写过 anthropic 键 `compat` 的 —— 升级后请求形变(该档的值换成声明的拼写、`adaptive` 不再带 `budget_tokens`、`supportsTemperature: false` 丢调用方 temperature);
|
|
310
|
+
③ 按封闭 schema 严格校验 `/v1/models` 行的消费方。**补偿**:读腿告警 / `model_compat_dropped` 点名条目;删掉那个键即回到 7.146.x 的读数。
|
|
311
|
+
**升级前做**:在 `config.d/models.json` 与配置中心目录里查 `thinkingLevelMap` 与 anthropic 条目的 `compat`;坏形改合形或删掉,不想升级后生效的删掉。**回滚**:回到 7.146.x ⇒ 带 `thinkingLevelMap` 的目录整份候选被拒(本地 `config.d` 回落 env、中心腿停在上一份好配置),回滚前先删这个键;anthropic 条目的 `compat` 回到「整只丢」。
|
|
312
|
+
|
|
313
|
+
24. **hook 条目的 `rewakeMessage` / `rewakeSummary` / `cloud`(command;`cloud` 也在 http)与 `continueOnBlock`(prompt)由新提交 400 变受理,本服务如实带、不执行;续跑重放读出存量里的这几键(行为变更;部署零动作)**:
|
|
314
|
+
旧形:7.135.0–7.146.x 新提交带这几键 ⇒ `400 request.body_shape`(`unknownKeys` 点名);续跑重放的存量请求里它们被读者剥掉。
|
|
315
|
+
新形:契约包 20.0.0 承运并判形(`rewakeMessage` / `rewakeSummary` 非空串、`continueOnBlock` 布尔、`cloud` 任意值),在各自的归属型上受理;本服务的执行器不读它们(唤醒文本不加前缀、`cloud` 写什么都照跑、`continueOnBlock` 不改阻断结局)。
|
|
316
|
+
写在别的条目类型上照旧 400。能力位 `settingsContract.hookEntryFields` 的列随之多这四键。
|
|
317
|
+
**谁需要**:原样投影宿主设置文件的调用方。**谁受伤**:① 以为写了就生效的调用方;② 升级前停驻的任务:存量请求(只可能来自 7.134.x 及更早)里三键写了坏值(空串 / 非串 / 非布尔)⇒ 读者判坏块,
|
|
318
|
+
续跑**拒**:这条车道本会采纳请求体 hooks(单用户车道)⇒ `409 resume_blocked_by_policy`(`blockedBy: "request.field_invalid"`,`field: "settings.hooks"`;句子只点名成员键,不回显值),卡 / 任务仍待决、行不动;不采纳请求体 hooks 的车道(多租户)零变化(同第 20 条)—— 续跑重读的一次性迁移不接这一形。
|
|
319
|
+
`cloud` 不同:它没有坏值,读者不读它的值;存量里 `cloud` 的值藏着守卫迹象(契约包分类器的判法:以 `PreToolUse` / `PermissionRequest` 为键的成员、匹配器形的对象,嵌多深都算)时读者整份拒,
|
|
320
|
+
续跑重读的一次性迁移在窗内把这只 `cloud` 剥掉、同一份 hooks 照采纳(运维日志 `hooks_read_as_before_upgrade` 点名被剥坐标)—— 与升级前同读。
|
|
321
|
+
**补偿**:能力位与契约附录明写不执行;不加窗、不加旋钮。
|
|
322
|
+
**升级前做**:有 7.134.x 及更早停驻、hooks 里写着这几键的任务,升级前把它们跑完或取消(否则续跑被拒,见上)。**回滚**:回到 7.146.x 即回到「新提交 400、续跑剥掉」。
|
|
323
|
+
|
|
324
|
+
25. **`DB_BACKEND=local`:会话同步干跑 `POST /v1/sessions/:id/sync/plan` 对仍带属主戳的存档,按 id 分类出 fork / stale 时直接答 `409 conflict.session_archive_stamped` + 固定句,不再答 `200` + `relation`(wire 加性:干跑多一口答该码;行为修复;部署零动作)**:
|
|
325
|
+
旧形:干跑只读两边的 id 集合并分类、不问存档带不带戳 —— 带戳存档上 fork / stale 答 `200` + `relation`,而同一份 id 集合的真推送在第一阶段就被 `409 conflict.session_archive_stamped` 早拒(7.145.0 节第 1 条):干跑说「分叉了,可带同意去推」,推送说「删掉会话再推」。
|
|
326
|
+
新形:干跑问第一阶段同一只早拒判官(按没带同意问;体里没有「同意」位),带戳 ⇒ 同码同体(体只有 `error` / `errorCode`,不带 `relation`);不开暂存、不拿租约、不写存档。`fast_forward` / `identical` / `fresh`、匿名存档与 SQL 后端上的 fork / stale、分区会话(委派子代的转录),干跑照旧 `200` + 关系体。
|
|
327
|
+
干跑这一读是「此刻读」(不持锁):提交里持锁的那一问仍是权威。带同意的同一推送第一阶段受理、提交里被同一只带戳判以同码拒,所以带戳存档上干跑答这个码对两种推法都是实话。
|
|
328
|
+
**谁需要**:先调干跑再决定推不推的壳 / SDK 在 local 部署的带戳存档上(起服 warn `local_archive_kept_stamped` 点名过的会话):当场读到出路,不再先问用户保留哪边。
|
|
329
|
+
**谁受伤**:把干跑当「永不 409 的纯读分类」的客户端(已装 SDK 24.0.0 的 spec 与注释这样写)—— 这两形它们读到 409 而不是 `200` 关系体;把非 2xx 一律当「服务不可用」重试的逻辑会白重试(确定性拒,重发同答)。
|
|
330
|
+
**补偿**:按码 `conflict.session_archive_stamped` 分支,体的 `error` 即出路(`DELETE /v1/sessions/:id` 后重推);按状态 409 分支的不受影响。
|
|
331
|
+
**SDK 锁步前的读法**:已装 SDK 的 spec 与注释仍写「plan 永不 409」(锁步版本改注与 spec);在 SDK 锁步版本之前,`pushSessionBundle` 的第一步是干跑 —— 对 local 部署上带戳的目标,它第一步就读到这个 409(SDK 映射为抛错,此前返回 conflict 结果,用户当时拿到的是「保留哪边」的问题,带同意重推后才在提交里读到同一个码)。
|
|
332
|
+
**升级前做**:无。**回滚**:回到 7.146.x 即回到「干跑只读 id 集合」。
|
|
333
|
+
|
|
334
|
+
26. **停驻补投帧的整条字节预算:收件条目的扩展键按 UTF-8 字节量,越过最窄后端的 `payload` 列宽(65,535 字节)⇒ 补投帧是最小形并带 `payloadTruncated { droppedKeys, bytes }`(行为修复 + wire 加性;部署零动作)**:
|
|
335
|
+
旧形:停驻收件条目(下一次开流 drain 出的 `task_notification` / `workflow_complete` 补投帧)的扩展键只有逐成员的界;多枚满界文本位、多字节文字或控制字符转义一放大,MySQL 协议后端上那一条入箱失败(通知丢,只剩一行服务端日志),PostgreSQL / File 照存全形。
|
|
336
|
+
新形:三种后端同一个预算(最窄后端的 `payload` 列容量;按 UTF-8 字节量)。装得下 ⇒ 帧形逐字同上一版;装不下 ⇒ 补投帧只带去重键位(`task_id` / `task_type` / `status` / `seq` / `attempt` 里带着的那几位)、归因侧记 `_sema_provenance`(带着且装得下就留)、`summary`、
|
|
337
|
+
`payloadTruncated { droppedKeys(被丢的键名,全形键序), bytes(全形扩展键的 UTF-8 字节数) }`,其余键缺席(`workflow_complete` 的去重键是 `runId`,只多 `payloadTruncated`)。
|
|
338
|
+
侧记自身也装不下 ⇒ 侧记也丢,且全形带归因成员(`_sema_provenance` / `agentMessage` / `crossSessionMessage`)时 `summary` 换成 `[payload over budget: summary withheld; see payloadTruncated]`、`droppedKeys` 末尾多一个 `summary`。live 腿(活流帧 / bg·resume 账本行)不变。
|
|
339
|
+
**谁需要**:park 的耐久投递 —— 停驻的完成在任何后端上都在下一次开流时到达。**谁受伤**:越界的停驻通知在所有后端上收最小形(侧记也越界的那一形连摘要原句也扣下);PostgreSQL / File 部署在这一尺寸段此前收全形。按帧上未知键报错的消费端要认这一键。
|
|
340
|
+
**补偿**:帧上点名丢了什么;去重键位全在;同一次完成的活腿帧照旧全形;运维计数 `server.workflow-completion-inbox.payload-over-budget`。
|
|
341
|
+
**升级前做**:部署零动作。消费端:`payloadTruncated` 在场 ⇒ 按「这一帧的扩展键被裁」渲(`summary` 照渲、点名缺了哪些)。**回滚**:回到上一版即回到「无整条预算」;已入箱的最小形条目两个家族不同:
|
|
342
|
+
`task_notification` —— 上一版 drain 把 payload 整只铺回帧上,`payloadTruncated` 与侧记照带(老消费端忽略未知键;已换成受信句的 `summary` 在列里,照出);
|
|
343
|
+
`workflow_complete` —— 上一版 drain 只读 `completionId` / `diagnostics` 两键,`payloadTruncated` 回滚即消失,帧上只剩 `runId` / `status` / `summary`,披露丢失(通知本身照到)。零 DDL、零一次性迁移。
|
|
344
|
+
|
|
345
|
+
27. **缺省模型检查的拒启句(`MODEL_ID is required when no catalog default resolves [config.default_model_missing] …`)在「本地候选整份被判官拒、回落 env、又没有 `MODEL_ID`」时,同一行多一段回落原因:被拒的文档名、拒码、原因类词与文档路径;句首的 grep 锚不变(拒启句 / 日志加性;部署零动作)**:
|
|
346
|
+
旧形:这一句只说「这张表没有缺省模型」+ 二选一的出路,不说这次为什么走的是 env 腿 —— 点名被拒文档与悬空符号链接的只有先出的 `config_candidate_rejected` warn 行。
|
|
347
|
+
新形:判官整拒了候选(`config.d` 里某份文档悬空链接 / 坏 JSON / 空 / 不是对象 / 太深 / 读不出,或某个域判形失败,或退役域文件)时,句子在 `(every enabled catalog entry …)` 那一段之后多 `(the config candidate was rejected whole … — rejected: "<文档名>" [<拒码>] <原因类词>: <文档路径> | …)`。
|
|
348
|
+
只带机读字段:原因类词是闭集常量(`dangling symbolic link` · `unreadable` · `parse error` · `empty file` · `not a JSON object` · `nested too deep` · `retired domain file` · `the domain failed its schema`),文档路径是 `<配置根>/config.d/<域>.json`(本地配置源才有)。
|
|
349
|
+
**不带**链接指向的目标路径、不带配置值、不抄契约 / 读腿的原句 —— 那些只留在 `config_candidate_rejected` 行。`config_candidate_rejected` 行的 `errors` 每条多一个键 `kind`(闭集词 `schema_invalid` · `empty` · `parse_error` · `not_object` · `too_deep` · `retired_domain` · `dangling_symlink` · `unreadable`,即上面各短语的机读形;日志加性)。没有被拒候选的拒启(纯 env、候选被收下)整句逐字不变。
|
|
350
|
+
**谁需要**:模型只配在 `config.d/models.json`、没设 `MODEL_ID` 的部署碰上候选被整拒,和只渲引擎原句的壳。**谁受伤**:对拒启句整句做精确相等匹配的脚本(只在候选被整拒这一形上变长)。
|
|
351
|
+
**补偿**:按句首锚 `MODEL_ID is required when no catalog default resolves [config.default_model_missing]` 前缀匹配,或读 `config_candidate_rejected` 行。**升级前做**:无。**回滚**:回到 7.146.x 即回到不带回落原因的句子。
|
|
352
|
+
|
|
353
|
+
28. **嵌入方类型面:`StoreBackend.retention` 改形 —— 入参 `{ taskAttachmentTable, taskListTables, logger? }` 不变,返回从 SQL 留存店类改为执行器面(破坏性三方法的 `audit` 必填);服务内的字节口 `BlobBackend` 四方法收成三只字节方法(包根不导出;零 wire、零表、零存储格式;部署零动作)**:
|
|
354
|
+
旧形:`retention?(opts): SqlRetentionStore` —— 三只破坏性方法收 `{ domain, cutoffMs, audit? }`,`audit` 类型上可选、缺席时运行期抛;`BlobBackend` = `putBlob` / `getBlob` / `hasBlobs` / `deleteBlobs`,后两只带索引语义。
|
|
355
|
+
新形:`retention?(opts): RetentionExecutor` —— `listRetentionDomains()` / `previewRetention({ domain, cutoffMs })` / `expireCheckpoints` · `deleteExpiredSessions` · `deleteOrphanToolResults`(各收 `{ domain, cutoffMs, audit }`,`audit` 必填,
|
|
356
|
+
`{ mode, policyDays, fencingToken }`)/ `retention`;`deleteExpiredSessions` 的回执照旧在有结束了的空间时多 `endedSpaces`。`BlobBackend` = `put(key, bytes)` / `get(key)` / `delete(keys)`(只搬字节;在不在、孤儿、宽限窗、内容寻址校验在索引的属主)。
|
|
357
|
+
**谁需要**:把 SQL 店目录逐字搬进引擎侧包的那一步(执行器入参与引擎的 `{ domain, cutoffMs }` 同形;部署的表经事务内钩参与)。**谁受伤**:自己实现 `StoreBackend`(带 `retention`)或直接调 `backend.retention(opts)` 的嵌入方 ——
|
|
358
|
+
返回型与入参型的名字变了,经执行器类型漏传 `audit` 是编译错;经引擎契约类型调用照旧在运行期当场拒(与修前同);改本仓源码、自带 `BlobBackend` 实现的人。
|
|
359
|
+
**补偿**:实现方让 `retention` 返回一只带上面六个成员的对象(与本仓 SQL 后端的组合同形);调用方每次破坏性调用带上本轮的 `audit`。字节口实现只剩三只方法:`hasBlobs` / `deleteBlobs` 的索引语义交给索引属主。
|
|
360
|
+
**升级前做**:无(零表、零存储格式、零 wire)。**回滚**:回到上一版即回到旧形(代码面,无数据面)。
|
|
361
|
+
|
|
362
|
+
29. **决断类续跑入口上这一行自己的拒答行上 `rowVerdict.code`:任何门同一个码 `checkpoint.invalid_outcome`;`approval_binding_mismatch` / `resume_outcome_invalid` 只给真有成因的拒;订正 7.124.0 节第 14 条「没有 `field` 的拒逐字维持 `approval_binding_mismatch`」半句(wire 码变;按码分支的客户端改读法;部署零动作)**:
|
|
363
|
+
旧形:一张停驻行被引擎的行判官判续不了(例 `reason: "requirements_damaged"`)时,运维队列 / 收件箱行上 `rowVerdict.code` 是 `checkpoint.invalid_outcome`,决断类入口却按门借码 ——
|
|
364
|
+
`POST /v1/approvals/:id/decide` 上答 `409 approval_binding_mismatch`(没有 `field`)、`/v1/assistant/tasks/:id/plan_review` 与 `/resume` / `/v1/sessions/:id/wake` 上答 `409 resume_outcome_invalid`;
|
|
365
|
+
决断口上存储体读不成检查点答 `409 conflict.checkpoint_unreadable`,存储体 `{}` 等门类读不出 / 别的门上的坏行答 `409 gate_not_tool_approval`。引擎在 `policy_ask` 门上不带判别位的拒也借 `approval_binding_mismatch`。
|
|
366
|
+
新形:有决断成因的拒照旧(引擎点名绑定席 ⇒ `approval_binding_mismatch`;点名决定体的别的格、或审阅门上不带判别位的内容拒 ⇒ `resume_outcome_invalid`);其余一律 `409 checkpoint.invalid_outcome` ——
|
|
367
|
+
这一行自己的拒(体顶层 `reason` 在场,码与行上 `rowVerdict.code` 同一只判官、同一个判决,`error` 以行上 `rowVerdict.sentence` 开头)与引擎不带判别位 / 带本服务不认得的 `field` 的拒。决断口在门型守卫之前先问这一行:行坏了就答行的拒,行好才指门;
|
|
368
|
+
存储体读不成检查点的那一形同答行的拒(店的别的失败仍 `conflict.checkpoint_unreadable`)。更新引擎停驻、门类本版不认的行在决断口答 `409 checkpoint.unsupported_version` + 两版本键(此前 `gate_not_tool_approval` 指错门)。
|
|
369
|
+
`retriable: true`(卡仍 pending、行字节不动)、`reason` / `thrownName` / `field` 原样:续跑腿上与修前同;决断口两早退臂此前不带 `reason` / `retriable`,本版带上。
|
|
370
|
+
**订正 7.124.0 节第 14 条**:那一条「决断口的 409 不再借名」子条里的「没有 `field` 的拒(含 core 的行完整性拒,例 `read_face_damaged`)逐字维持 `approval_binding_mismatch`」自本版起不成立 —— 那些拒答 `checkpoint.invalid_outcome`;
|
|
371
|
+
同一子条前半句「`approval_binding_mismatch` 只说绑定变了(重取坐标再决)」自本版起才名副其实。已发段原样留着。
|
|
372
|
+
**谁需要**:按码分支的客户端 —— 「这一行续不了」与「绑定变了 / 改那一格」按码就分得开。**谁受伤**:对 `approval_binding_mismatch` 一律重取坐标再决、对 `resume_outcome_invalid` 一律提示改那一格、按 `gate_not_tool_approval` / `conflict.checkpoint_unreadable` 处置坏卡的客户端:坏行上拿到新码。已把 `checkpoint.invalid_outcome` 与 `approval_binding_mismatch` 并成一臂的客户端码面零变化、行为照旧 —— 本版的分因要它们拆开那一臂才看得见。
|
|
373
|
+
**补偿 / 升级前做**:客户端加一臂 `checkpoint.invalid_outcome`(已与 `approval_binding_mismatch` 并成一臂的拆出来),按体顶层 `reason` 在不在分两形 —— 在场 = 这一行自己的拒:按 `reason` 与 `error`(= 行上 `rowVerdict.sentence`,出路是作为新任务重提;停它的那一版 worker 也许还能续)呈「这张卡续不了」,不再重取坐标;
|
|
374
|
+
缺席 = 引擎没点名哪一格的拒(带本服务不认得的 `field`〔原样上 wire,引擎新加的格〕,或与决定体无关的引擎内部拒):卡仍待决,出路读 `error` 句,同样不重取坐标;
|
|
375
|
+
行上 `rowVerdict` 非 `ok` 的卡本就不该呈批准。按前缀 `checkpoint.*` 兜底的客户端零改。**回滚**:回到上一版即回到按门借码;数据零改动。
|
|
376
|
+
|
|
377
|
+
30. **一次性迁移 M9 退役:park 指针索引改主键的启动期迁移连同它的读侧半场删码;随包排空判据 `workflow-park-holder` 少一条(持久数据面;行为变更;同一批存量卡的 409 码换了;运维日志形变更;嵌入方 BREAKING,类型面)**:
|
|
378
|
+
7.118.0 引入的一条一次性迁移,窗(发布日 2026-10-07 + 30 天)于 2026-11-06 关,本版删了它的码 —— 写半场与读侧半场(同一件事「引擎 7.43 及以前写下的 workflow 子代停驻记录」)同窗同删。M10–M12 的窗 2026-11-07 … 11-08 关,本版不动,随后续版本窗关即删。逐处删了什么、删后存量形由谁接住:
|
|
379
|
+
- **写半场**:SQL 起服不再把 `workflow_agent_session`(workflow park 指针索引,派生投影)的主键由 `(session_id)` 改成 `(session_id, run_id)`(暂存表复制 + 原子换名那一整套连同暂存表 `workflow_agent_session_m9` / 待删旧表 `workflow_agent_session_m9_old` 的收尾删除)。
|
|
380
|
+
删后仍是旧主键的库(从 ≤ 7.117.x 直接升到本版、中间没在 7.118.0–7.146.x 任一版起过服),指针写口(冲突目标 `(session_id, run_id)`)两方言各自落败:TiDB / MySQL 的 `REPLACE INTO` 按单列主键整行替换 —— 同一个子会话只剩后写的一枚指针,续跑链 / 分叉里后写的记录覆盖先写的,判决只看得到一条记录(分叉判不出、链尾可能被更早的记录盖掉);
|
|
381
|
+
PostgreSQL 的冲突目标没有可仲裁的唯一约束 ⇒ 指针写失败(响亮)。没有响亮的起服臂。
|
|
382
|
+
出路:运维手工照中央 DDL 重建这张表(派生投影,丢了只丢升级那一刻还停驻着的旧卡的指针),或先在一只 7.118.0–7.146.x 的版本上起服一次再升本版。`DB_BACKEND=local` 的索引是账本、没有主键,这一半对它本来就是空转。
|
|
383
|
+
- **读侧半场**:路由里「点名子会话的条目没有持有者位(引擎 7.43 及以前写下)」的专读臂删除。删后这样的存量卡路由判 `none`、落 legacy 腿,答 `409 conflict.resume_context_unavailable`(响亮;成因是子会话没有续跑上下文)—— 不再答 `409 decide.workflow_parks_unreadable`、句子里「更早的引擎版本」那一说随之没了;出路不变:续跑发起它的那条 workflow run。
|
|
384
|
+
`decide.workflow_parks_unreadable` 自此只有一种成因:某一条点名这张卡的记录的停驻列表读不出(条目形坏 / 这一份在场却不是列表),一句拒文,体键不变(`runId`、在场才带的 `readableHolderRunId`)。`DB_BACKEND=local` 同样适用(路由是同一只)。
|
|
385
|
+
- **随包排空判据**:两份 SQL 与 `drain-check-local.mjs` 去掉 `workflow-park-holder`(local 脚本的判据表少一条,末行 `WORKFLOW-PARK-HOLDER` 与命中行 `WORKFLOW-PARK-ROW` 不再出)。要在 7.118.0 那条边界上数这些卡,用 7.118.0–7.146.x 任一版包里的同名判据。
|
|
386
|
+
- **运维日志**:起服行 `one_time_migrations_applied` 与被打断时的 `one_time_migrations_interrupted` 去掉 `workflowParkIndexKey` / `workflowParkIndexRowsCarried` 两个读数字段(`removableAfter` 读数去掉 `M9` 一个键,`note` 不再叙述它)。按这些字段做告警或看板的规则要改。
|
|
387
|
+
- **嵌入方(类型面)BREAKING**:`StoreBackend.runOneTimeMigrations()` 的返回型 `OneTimeMigrationReport`(经包根导出的 `StoreBackend` 可达)去掉 `workflowParkIndexKey` / `workflowParkIndexRowsCarried`;读它们的代码、把值标成 `OneTimeMigrationReport` 再写这些键的对象字面量 tsc 红;
|
|
388
|
+
自实现该方法、未标注类型就直接返回含这些键的字面量的代码 tsc 不报(多出的键没有人读),也请一并删掉。
|
|
389
|
+
- **谁需要**:所有部署 —— 起服少走一步、排空判据少一条。
|
|
390
|
+
- **谁受伤**:① **跳版升级**:从 ≤ 7.117.x 直接跳到本版的 SQL 库 —— 仍是旧主键(TiDB / MySQL 上指针被整行替换、PostgreSQL 上指针写失败;上面写半场一条);② **升级那一刻还停驻着、由引擎 7.43 及以前写下的 workflow 子代卡**(7.118.0 起新写的记录恒带持有者位;`APPROVAL_TERMINAL_BACKSTOP_MS` 调长的部署或从 ≤ 7.117.x 直跳的部署才可能还有)——
|
|
391
|
+
决定口的 409 码由 `decide.workflow_parks_unreadable` 换成 `conflict.resume_context_unavailable`,按那一码做分支或按「更早的引擎版本」那句话匹配的客户端 / 告警要改;两者都是响亮的 409、卡仍 pending、什么都没投递;③ 按上面日志字段做告警的运维。
|
|
392
|
+
- **补偿 / 做法**:**表形**(① 那一类):跳版升级的库先在 7.118.0–7.146.x 任一版上起服一次再升本版,或升级后运维手工照中央 DDL 重建 `workflow_agent_session`(排空卡改不了主键)。**存量卡**(② 那一类):升级前把它们决掉或取消(数法见旧包判据 `workflow-park-holder`),或升级后续跑发起它的那条 workflow run 再决。**升级前做**:常规从 7.146.x 升级、没有 ② 那批卡的部署无须动作;**回滚**:回到 7.146.x 即恢复旧读法与旧判据,本版没有写任何新的存储形。
|
|
393
|
+
|
|
394
|
+
## 7.146.0 —— ① 引擎首次附着前的宽限 `ENGINE_FIRST_ATTACH_MS`(缺省 180 s):从没被非探针请求碰过的引擎要等 `max(ENGINE_LINGER_MS, 本值)` 才自退;`/health.engineLease` 多一格 `firstAttach`(行为变更 + wire 加性;部署零动作) ② 设备 WS 未鉴权握手的 per-remote 帽可按真实对端计:新旋钮 `DEVICE_TRUSTED_PROXY_CIDRS`(可信代理名单,缺省空 = 今日行为);帽键统一为地址规范形;提货 settings-schema 17.1.0(安全轴,fail-closed;新旋钮 + 日志 / 指标加性;部署零动作) ③ SQL 记忆腿(`MEMORY_ENGINE_BACKEND=pg|mysql`)兑现 core 的落点问询协议(`admitsLandings` / `opts.admit` / `opts.confirm`):在这两条腿上驱动 core 记忆整合时,写闸判的是真正落下的拼写,此前传进来的第二参被静默丢掉(行为变更;部署零动作) ④ TiDB 记忆腿(`MEMORY_ENGINE_BACKEND=mysql`)上 stale `baseRev` 的 update 改按契约报冲突:对手恰好把行写成与本次 update 逐字节相同的目标态时,此前报 applied,现与 PG 腿同答冲突并带 `currentRev`(行为修复;部署零动作) ⑤ 随包文书补全与订正:停机上界契约句、`blocked` 终局的用户面是 `terminal.detail`(点名 cli · web-admin · client-core 渲染层)、hooks 托管标签由调用方自报且失败方向只收紧、server-as-peer 启动日志行、场景面收窄写法、坏行降级形的键集(文字订正;零行为变更;部署零动作) ⑥ `local_roots_split` 起服告警只报「一声不响的分家」:显式给了 `CONFIG_LOCAL_DIR`(等于数据根 = 合一,不等 = 有意分家)即视作运维已表态,不再每次起服响;推导的配置根 ≠ 数据根照报(行为修复;日志面;部署零动作) ⑦ 在飞 run 并发帽:新旋钮 `RUN_MAX_CONCURRENT`(本副本全局)与 `RUN_MAX_CONCURRENT_PER_PRINCIPAL`(同一已验提交主体),缺省 `0` = 关;新提交超帽 ⇒ 429 `limit.rate_exceeded` + `reason: "run_concurrency_cap"` + `Retry-After: 5`(行为加性,缺省关;wire 加性;部署零动作) ⑧ 硬断预告:自 7.147.0 起每个部署都要显式声明执行车道(`REMOTE_EXEC`;`CONFIG_PROVIDER=local` 形下 `config.d/remote-exec.json` 也算),未声明拒启;车道词 `none` 取代词表外的状态名 `in-process`;`REQUIRE_EXECUTION_LANE` 退役(预告;本版零行为变化、零 wire 变化;部署零动作,但 7.147.0 的升级路径上有三件事要提前排) ⑨ 更正 7.144.0 节第 1 条与 7.137.0 节第 15 条的出路句:`corrupt_session` / `invalid_session` 的出路里没有「从断点之上的条目分叉」—— `POST /v1/sessions/:id/fork` 不选条目,对结构坏的会话也不是出路(文字订正;零行为变化;部署零动作) ⑩ 起服告警 `memory_engine_dir_defaulted` 改名 `memory_engine_dir_outside_data_root` 并改按路径包含判:file 形记忆引擎的已解析根不在本机数据根(`config.localDataRoot`)之下才报,句子带两条真路径;`MEMORY_ENGINE_DIR` 缺席不再是判据(行为修复;日志面,日志事件改名(旧名退役;壳 / 编排脚本按新名读)) ⑪ 单用户部署上 `GET /v1/diagnostics/wiring` 与 `GET /v1/outcomes` 也先问运维名册:名单为空且没写 `OPERATOR_SINGLE_USER=true` ⇒ 两口答 501;单用户部署的具名名单对 `GET /v1/outcomes` 也生效(安全轴,fail-closed;行为变更;名单为空的单用户部署要这两口写一行 `OPERATOR_SINGLE_USER=true`) ⑫ 后台子代状态 `agentState` 过 wire 的读法成文并钉死,订正 7.116.0 节「未核」一句:哪些应答带它、哪些不带(缺席是引擎的选择);持久子代行读口的状态是 core 同一只读器的产物,停驻行的审批卡读作 `unreadable`(文字订正;零行为变更;wire 零变化;部署零动作) ⑬ 收编批量导入:源主体把本机会话导进收编目的地 `POST /v1/adoption/:id/sessions`,能力位 `adoptionImport`(按调用方 present-iff)给出 `:id` 与两只帽;两根新旋钮 `ADOPTION_IMPORT_MAX_SESSIONS` / `ADOPTION_IMPORT_MAX_SESSION_BYTES`(新面;wire 加性;部署零动作) ⑭ hooks 托管车道成为任务座上自己的一张引擎注册 `settings.hooks.managed`:引擎 handler 预算(`HOOKS_TIMEOUT_MS`)每车道一份,非托管钩子吃光自己那份挤不掉托管钩子;托管车道被自己的预算叫停记 `hook_managed_unrun{budget_exhausted}`;`Stop` 上 `continue:false` 只撤本车道的推回(安全轴,失效关闭;行为修复 + wire 加性:新注册名;部署零动作,按注册名字面读的读者见本条「升级前做」) ⑮ 请求面压缩开关:`settings.autoCompactEnabled`(布尔)逐字交给引擎的自动压缩座 `compaction.autoCompact`,能力位 `taskSettings.autoCompactEnabled`;键缺席时与旧形逐字相同(wire 加性;部署零动作) ⑯ 请求的 `settings.env` 不收凭据:名字是本引擎的凭据变量或值是秘密形 ⇒ 新提交 400 `request.env_credential_refused`;升级前停驻的任务窗内续跑时剥掉照续(安全轴,fail-closed;wire 新码;调用方动作:凭据挪进引擎进程的环境;部署零动作) ⑰ 错误码目录加「码族」列:契约附录 A 每个码恰属五族之一,消费端按列读、不再各抄码表;`wire-changes` 清单多一集 `errorCodeFamily`(契约列加性;应答体零变化;部署零动作) ⑱ 会话记忆状态报出引擎记忆写家:带层座(`?scope=`)时多一个可选键 `writeHome`(那只店的引擎答案,绝对目录,字节原样),不带层座时多一个可选键 `planes`(逐店明细里引擎答的 `writeHome` 原样透出),单用户 `host` 车道在场、其余车道缺席,与能力位 `projectContext` 同一只射程谓词(wire 加性;部署零动作) ⑲ 🔴 引擎 7.62.0 → 7.63.0:升级前停驻的工具审批行在本版上续跑不了(`409 approval_binding_mismatch` + `reason: "requirements_damaged"`,升级前先排空;混跑期两版互拒对方停驻的行)· 规则导入回执的引擎拒成员按落没落分 `refused` / `indeterminate`、`reason` = 引擎拒因码(`store_refused` 退出)· 记忆收紧(`userlocal:` 族不复制、v2 下保留前缀的折叠拼写拒、hipaa / zdr 否决记忆整理、店集只算写过的个人店、公告队列文件坏了响亮拒)· 停驻行成员形不对即判坏、`DB_BACKEND=local` 的审批列表不再因一行坏字节整张 503 · 后台 fork 子代进委派分区 · 本进程停驻的赎回完成回停驻车道 · 用户面通告加两码(行为变更 + 硬破坏两条;wire:两通告码加性、一回执词退出;升级前先排空待决工具审批卡) ⑳ 🔴 本进程删过的会话 id 只再执行给删前的属主:另一位属主在本进程用同一个 id 起执行(新提交、续跑、唤醒、停驻赎回)⇒ `409 conflict.session_id_retired`(续跑家族 `409 resume_blocked_by_policy`),什么都不跑(安全轴,fail-closed;wire 新码;行为变更;部署零动作) ㉑ 嵌入方类型面:服务型 `ServiceWorkflowJournalStore` 的可选成员 `deleteByRun?` 删(journal 只剩按龄清扫一条删路);`ServiceConfig` 多七个必填席(各由 `loadConfig` 从本版新旋钮铸出);检查点店与 workflow journal 店的源文件换了目录,包外本来就 import 不到(嵌入方类型面 BREAKING 两处;零 wire、零表、零存储格式;部署零动作) ㉒ k8s 沙箱 Role 的 `persistentvolumeclaims` 四动词与 `secrets` `create` 改按特性开关授:随包 chart 缺省不再渲这两条规则,设了 `WORKSPACE_CACHE=volume` / `K8S_SANDBOX_ENV` 的存量部署要在 values 里开对应开关(或手写 RBAC 补规则)(部署面;行为收紧;两个旋钮都没设的部署零动作) ㉓ 🔴 引擎 7.63.0 → 7.64.0:会话帧与会话盒按住客投 —— 删后同 id 重建的后任不再收前任后台工作的完成、信与回执(弃一条在运维席说一次 `delegation.delivery_discarded`),升级前让旧副本排空会话盒、混版副本共一只信箱时旧副本领不动装着本版记录的盒、本版副本弃掉旧副本写下的记录 · File 记忆店的「绑定之前」账本形退役(先用上一版引擎开一次)· 共用一只记忆控制面的副本一起升级 · 停驻行三处判坏 · 规则提议里无 kind 的批成员整批丢 · 兑付腿店故障只在店没变时可重试 · 规则导入成员结局不知 ⇒ 503 同票重走 · 一次性迁移 local 腿读得更全 · 拒绝回显上帧(行为变更 + 硬破坏三条;wire:一帧键加性;升级前先排空会话盒) ㉔ 不报主体的 service 凭据可声明为无身份调用方:新旋钮 `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT`(缺省 `true` = 授权判定不变;`false` ⇒ fleet 读面 / 运维聚合口 / 写档对它收窄);`GET /health` 的 `auth` 加一键、运维口 401 operator 句改写(安全轴,opt-in;wire 加性 + 一句改写;零迁移;缺省部署零动作) ㉕ 🔴 自由文本脱敏:行首键形(YAML / INI / compose 的配置行 `password: <值>` / `PASSWORD = <值>`)是声明形的第四种 —— 值成记号;值是类型名(`str` / `string` / `SecretStr` …)时不是值(行为面;安全;脱敏产物变;部署零动作) ㉖ 引擎交接车道:壳退出的「Move to background and exit」—— 新口 `POST /v1/engine/handover` / `POST /v1/engine/attach`、能力位 `engine.handover`、新旋钮 `ENGINE_HANDOVER_LINGER_MS`(缺省 30 min);`/health.engineLease` 多 `lane` / `handover`;`exit-last.json` 用格式 3(`lane` 取代上一版的 `orphan`;第 1 条的首附着窗到期同由 `lane` 说)(新面 + wire 加性;留痕文件与日志键 BREAKING;部署零动作) ㉗ 一次性迁移 M6–M8 退役;M7 的拒臂留为按写者版本的永久门(持久数据面;行为变更;运维日志形变更;随包排空判据少一条;嵌入方 `OneTimeMigrationReport` 去三键〔BREAKING,类型面〕;没在 7.117.0–7.145.x 任一版起过服的 SQL 库先在其中一版起服一次)
|
|
395
|
+
|
|
396
|
+
1. **引擎首次附着前的宽限:装了自退腿(`ENGINE_AUTO_EXIT` 开,或 `SEMA_PARENT_PID` 在场)的引擎,在起服以来还没有过任何非探针 HTTP 请求时,按 `max(ENGINE_LINGER_MS, ENGINE_FIRST_ATTACH_MS)`(缺省 180 s)判自退;`GET /health` 的 `engineLease` 加性多一格 `firstAttach { windowMs, since, attachedAt }`(行为变更 + wire 加性;部署零动作)**:
|
|
397
|
+
旧形:自退的空闲计时从装配那一拍起算,一律按 `ENGINE_LINGER_MS`(缺省 60 s);`/health` 探针不算触点 —— 壳在 spawn 与第一个真请求之间被饿住超过 60 s,引擎就在从没被碰过的时候自退了。
|
|
398
|
+
新形:首个非探针请求到达之前(`/health` `/readyz` `/metrics*` 不算;打开 SSE 流算)生效窗是 `max(ENGINE_LINGER_MS, ENGINE_FIRST_ATTACH_MS)`;首个非探针请求之后回到 `ENGINE_LINGER_MS`,不再回来;
|
|
399
|
+
父进程已不在(孤儿)时照旧是 `ENGINE_ORPHAN_LINGER_MS`(孤儿优先)。在飞的 run 本身不算首个请求。自退判据(无附着 ∧ 无在飞 ∧ 静默)、采样拍与 `engineLease.lingerMs` / `tickMs` 不变。
|
|
400
|
+
`engineLease.firstAttach`:`windowMs` = 生效的候首触窗,`since` = 窗开始(epoch ms),`attachedAt` = 首个非探针请求的时刻(epoch ms;`null` = 还没有过);父一直活着且一直没人碰时 `since + windowMs` 是最早自退的下界、不是预言(父死之后孤儿窗优先,可以更早)。
|
|
401
|
+
在场 ⇔ `engineLease` 在场 ∧ `ENGINE_AUTO_EXIT` 开(owned 窗有限);缺席 = 老 worker / 没装自退腿 / 只靠父监视(owned 窗为「永不」)/ 腿已收摊。
|
|
402
|
+
起服日志 `engine_lease_armed` 多 `firstAttachMs`(旋钮值)与 `firstAttachWindowMs`(生效值);候首触窗到期的自退在 `engine_lease_auto_exit` 与 `<数据根>/exit-last.json` 里读作 `lane: "awaitingFirstAttach"`(车道键见第 26 条)。
|
|
403
|
+
`exit-last.json` 带 `format`(本版 = 3,见第 26 条):起服读到别的格式号(缺键 = 上一版写的)⇒ 一行 `warn` `exit_last_stale_format`(`fileFormat` / `buildFormat`)后删掉,不再打 `exit_last_found`(只丢那一次自退的留痕)。
|
|
404
|
+
**谁需要**:cli 壳的一次性 `-p` 车道、CI 与高载宿主 —— 壳在 spawn 与首个请求之间被饿住超过 60 s 时,引擎不再在它醒来之前退掉;壳读 `engineLease.firstAttach` 按首窗语义处理起步段。
|
|
405
|
+
**谁受伤**:spawn 之后从来没被碰过、父却一直活着(或没装父监视)的引擎多活到 180 s(再加至多一个采样拍)才自退,期间占着端口、数据根锁与库连接;不复用它、自己再起一只引擎的第二只壳最长约 3 分钟撞数据根锁。
|
|
406
|
+
父死照旧由孤儿窗收;服务器形部署(两键都没设)零变化。
|
|
407
|
+
**补偿**:`ENGINE_FIRST_ATTACH_MS=0`(或任何不大于 `ENGINE_LINGER_MS` 的值)逐字回到旧形;坏值(`1..999` 秒当毫秒、负数、小数、非数、越过 24 h)拒启并指路,解析不看 `ENGINE_AUTO_EXIT` / `SEMA_PARENT_PID`。
|
|
408
|
+
**升级前做**:无(想保持旧形的部署设 `ENGINE_FIRST_ATTACH_MS=0`)。**回滚**:回到上一版即恢复旧形;本版写的 `exit-last.json` 上一版读不成(见第 26 条「回滚」)。
|
|
409
|
+
|
|
410
|
+
2. **设备 WS 未鉴权握手的 per-remote 帽(`DEVICE_MAX_PREAUTH_PER_REMOTE`)可按真实对端计:新旋钮 `DEVICE_TRUSTED_PROXY_CIDRS`(可信代理名单,CIDR 闭集,缺省空 = 不读任何代理头);帽键统一为地址规范形(安全轴,fail-closed;新旋钮 + 日志 / 指标加性;部署零动作)**:
|
|
411
|
+
旧形:帽键 = socket 对端原文。引擎在反代 / 托管入口 / 公司 NAT 之后时,全员同一个 socket 对端,共用 8 个名额 —— 一个来源占满,其余设备的升级全 503;`off` 停层后只剩全局 64。
|
|
412
|
+
新形:帽键 = 真实对端。名单空(缺省)⇒ 就是 socket 对端(与旧形同键)。socket 对端落在名单内 ⇒ 读 `X-Forwarded-For`(重复头按到达序合并),自右向左跳过名单内的项,取第一个名单外的地址;
|
|
413
|
+
名单外的对端一律不采任何代理头;名单内但请求头行数到顶(100 行,或给 server 设的更低上限;node 对超过 `maxHeadersCount` 的请求要么静默丢掉多余的头、要么直接答 431(版本行为),答 431 时握手整只被拒、没有下面这行 warn;两形下垫在前面的 `X-Forwarded-For` 都不会成为帽键)/ 头缺席 / 某项不是地址 / 全在名单内 ⇒ 键退回 socket 对端(整只代理一键)+ 一行 warn `device_preauth_forwarded_unusable`(`reason` = `too_many_headers` / `absent` / `malformed` / `all_trusted`,不带地址)。
|
|
414
|
+
名单项:IP 地址或 CIDR(裸地址 = /32、/128 的单台),逗号分隔,项两侧空格忽略;不是 IP 地址或 CIDR 的项(主机名之类)、zone id、主机位非零(`10.0.0.5/8`,拒句给 `10.0.0.0/8` 与 `10.0.0.5/32` 两个出路)、前缀 0(`0.0.0.0/0` / `::/0`)、空项一律拒启。
|
|
415
|
+
不读 `Forwarded` / `X-Real-IP`,不支持 PROXY protocol。`DEVICE_MAX_PREAUTH_PER_REMOTE` 的语义、缺省 8 与 `off` 臂、全局帽 64 都不变。
|
|
416
|
+
帽键地址统一为规范形:IPv4-mapped IPv6(`::ffff:1.2.3.4`)写成点分 IPv4,IPv6 压缩小写 —— 名单空的部署唯一可见差 = `device_preauth_cap_hit` 行里 `remoteKey` 对 mapped 对端的拼法(`::ffff:1.2.3.4` → `1.2.3.4`)。
|
|
417
|
+
观测:每次升级计数 `device_preauth_key_total{source}`(`socket` / `xff` / `fallback`);`device_preauth_cap_hit` 行多 `keySource`;起服行 `device_lane_enabled` 多 `trustedProxyCidrs`(条数)。
|
|
418
|
+
**谁需要**:设备车道在反代 / 托管入口(k8s ingress、负载均衡)/ 公司 NAT 之后的部署 —— 一个来源不再吃光其他设备的未鉴权名额。
|
|
419
|
+
**谁受伤**:名单配宽(放进不受自己控制的跳)⇒ 那里的客户端可伪造 `X-Forwarded-For` 自报帽键、绕开 per-remote 层(全局帽照兜);不写 `X-Forwarded-For` 的四层负载均衡被列入 ⇒ 每次升级退回 socket 键 + warn。
|
|
420
|
+
**补偿**:名单缺省空 = 旧形;只放自己的反代;前缀 0 与主机位歧义拒启;warn 的 `reason` 指路;名单外部署零变化。
|
|
421
|
+
**升级前做**:无。反代后的部署想按真实来源计 ⇒ 把自己的反代地址段写进 `DEVICE_TRUSTED_PROXY_CIDRS`(编排器的 compose 需透传这根 env;控制台的 device 旋钮表随契约包车道表带上它 —— 本版提货的 settings-schema 17.1.0 在车道表 device 行登记了它)。
|
|
422
|
+
**已知限制**:这根键随契约包车道表成为 worker 规格的保留名 —— worker 规格的 `env` / `secretEnv` 逃生口不再收它,唯一写位是 `runtime.execution.coords.DEVICE_TRUSTED_PROXY_CIDRS`。控制台的契约包落后于本版时,若有人先把它写进 worker 规格的 `env`,控制台升级契约包后那一行会被拒,没有一次性迁移搬它 —— 手工把它搬到 `runtime.execution.coords`(只对声明 device 车道的 worker 有意义)。
|
|
423
|
+
**回滚**:去掉 `DEVICE_TRUSTED_PROXY_CIDRS` 即回到按 socket 对端计;回到上一版时这根 env 被忽略(上一版不认识它)。
|
|
424
|
+
|
|
425
|
+
3. **两条 SQL 记忆腿(`MEMORY_ENGINE_BACKEND=pg|mysql`)兑现 core 的落点问询协议:声明 `admitsLandings`,`applyPatches` 收 `opts.admit` / `opts.confirm`(行为变更;嵌入方 / 宿主零动作)**:
|
|
426
|
+
旧形:两腿的 `applyPatches` 只收一个参数,传进来的第二参被**静默丢掉** —— `admit`(落点由谁说了算)与 `confirm`(调用方的最后一句话)一次都不调;
|
|
427
|
+
core 记忆引擎的整合 apply 见两腿不声明 `admitsLandings`,就自己先问**冻结的**拼写、再逐条交写,而两腿撞名时自己加上的 `-n` 后缀,写闸从来没见过。
|
|
428
|
+
新形:两腿声明 `admitsLandings: true`。给了 `admit` ⇒ 后端先只读地判出整批的每个落点(add 的终拼含撞名后缀、同 scope 改名留下的旧拼、update 的目标与移走的旧拼、
|
|
429
|
+
delete 移走的拼),在写任何一个之前一次问全;**每一次问都在本次 apply 的第一笔写之前** ⇒ 拒 = 一字不写、原样上抛;最多问 4 次,名仍在动 ⇒
|
|
430
|
+
抛 `memory.landing_unstable`(此时恒一字未写;问、记下问过的、轮数上限与超限的码是引擎的问询圈,与 file 腿同一只)。问过之后落点又变了(名被别的副本抢走、行被并发改名 / 搬走)且变出了还没问过的拼写 ⇒ 还一笔没写就写前重问新拼(连同其后整批剩下的预测落点一次问全);
|
|
431
|
+
已经写过(含一条写语句发出后以 I/O 失败收场、落没落不知道)就这一条报冲突(`landing moved after admission …`)、一字不写,下次 apply 再问 —— 绝不写没问过的拼写。
|
|
432
|
+
给了 `confirm` ⇒ 每条 entry 写语句发出之前同步调;抛 ⇒ 该条及其后不写、之前已提交的留下,原样上抛(不再是一条 `io error` 冲突)。
|
|
433
|
+
中止路径上已提交的 entry 照落 history 行。
|
|
434
|
+
不传第二参 ⇒ 常规路径与旧形同,一处有意更正:同批两条 add 的占名此前按 `scope|slug` 拼接判,scope / slug 含 `|` 时会把两个不同的拼写判成同名、后一条白退一个后缀,现按两格判。
|
|
435
|
+
另只在并发竞争路径上收紧:写语句把计划的 scope / slug 也绑进条件(`MEMORY_ENGINE_BACKEND=mysql` 上逐字节比,不受 `utf8mb4_bin` 尾空格不计的影响),
|
|
436
|
+
行在判与写之间被别的副本改名 / 搬走 ⇒ 按现状重判再写(旧形 update / delete 按 `id + rev` 照写 —— rev 不含 scope / slug —— 会写到一个没判过的拼写上);
|
|
437
|
+
同 id 的行在判与写之间被别的副本插入 ⇒ 重判(旧形按 id 盲覆盖)。
|
|
438
|
+
**谁需要**:把这两条 SQL 腿交给 core 记忆引擎、自己驱动记忆整合的嵌入方 —— 写闸判的是真正落下的拼写,每次写之前核对整合计划的持有者。
|
|
439
|
+
本服务自己的整合阀门(`MEMORY_CONSOLIDATION_DRIVER`)在 SQL 记忆腿上照旧拒启(这两条腿不自带引擎控制面归属,这一条不变)。
|
|
440
|
+
**谁受伤**:SQL 记忆腿上的整合 apply —— 本批开始写之后才被别的副本抢名 / 挪行的那一条报冲突不写,留到下次 apply(引擎按报告与库里实际落下的对账);
|
|
441
|
+
给了 `admit` 的批读库次数约三倍(问前判整批、问后再判一遍、写前逐条现判)。不传第二参的调用方只在并发竞争路径与 scope / slug 含 `|` 的同批 add 上看见差别(见上一段)。
|
|
442
|
+
直接把 `admit` / `confirm` 交给 SQL 腿的调用方:过去被静默丢掉,从本版起被兑现,`admit` 的拒绝与 `confirm` 的抛错原样上抛
|
|
443
|
+
(core 引擎按契约只在后端声明了 `admitsLandings` 时才交,所以此前的调用点都不交)。
|
|
444
|
+
**补偿**:不传第二参零变化;抛错原样,已提交写的审计行不丢。
|
|
445
|
+
**已知限制**:SQL 记忆腿的 confirm 在写语句前同步调,不持事务锁;要事务内验 fence 等包里的腿(7.64.0 核心存储包)。
|
|
446
|
+
**升级前做**:无。**回滚**:回到上一版即恢复旧形(库形零变化)。
|
|
447
|
+
|
|
448
|
+
4. **TiDB 记忆腿(`MEMORY_ENGINE_BACKEND=mysql`)上 stale `baseRev` 的 update 改按契约报冲突:对手恰好把行写成与本次 update 逐字节相同的目标态时,此前报 applied,现与 PG 腿同答冲突并带 `currentRev`(行为修复;部署零动作)**:
|
|
449
|
+
旧形:update 的写语句因行在判与写之间被别的副本改过而匹配零行时,TiDB 腿现读一次,若行此刻恰是这次 update 的目标态(rev 与 scope / slug 都对)就报 applied 并记一行 history —— 这一条其实没写任何东西、调用方所基的 rev 已过期;PG 腿对同一时序报 `rev mismatch (concurrent change)`。
|
|
450
|
+
新形:按 rev 判、不按字节判(core 契约:stale `baseRev` 的 update 是报告的冲突,带 `currentRev`)。零行之后只有「什么都没改」的 update(新 rev 与判过的 rev 相同、投影不动)且现读行仍在判过的 rev + 投影上才算已落(没开 `CLIENT_FOUND_ROWS` 的连接上这种 update 匹配了也数 0);
|
|
451
|
+
其余零行不再算已落:行的 rev 变了(含对手写成逐字节相同的目标态)或行没了 ⇒ 报冲突,`currentRev` = 现读值(行没了则是判时读到的值),本条不落 history,行保持对手写的那一份;
|
|
452
|
+
行只是被挪了地方(rev 不变)⇒ 沿用既有的按现状重判。没带 `baseRev` 的 update 同读(写语句仍以判时读到的 rev 为条件,与 PG 腿一致)。判之前就 stale 的路径、PG 腿、同 scope 同 id 的 re-add 幂等覆盖都不变。
|
|
453
|
+
**谁需要**:多副本并发写同一条 entry、把 TiDB 记忆腿交给 core 记忆引擎或自己驱动 `applyPatches` 的部署(记忆同步中心半场的 pull 补丁走同一口)。
|
|
454
|
+
**谁受伤**:此前把「第二个到达者」读成 applied 的调用方 —— 这个时序上现在拿到冲突;写者要的恰是行上那一份时,按冲突里的 `currentRev` 重读对账即可,报告里 applied 少一条、conflicts 多一条,行的终态不变。
|
|
455
|
+
**补偿**:无旋钮(契约句不容两种读法);`currentRev` 是现读值(行没了才退回判时的值)。**升级前做**:无。**回滚**:回到上一版即恢复旧形(库形零变化)。
|
|
456
|
+
5. **随包文书补全与订正:停机上界契约句、`blocked` 终局的用户面是 `terminal.detail`、hooks 托管标签由调用方自报且失败方向只收紧、server-as-peer 启动日志行、场景面收窄写法、坏行降级形的键集(文字订正;零行为变更;wire 零变化;部署零动作;点名三壳渲染层)**:
|
|
457
|
+
旧形:随包文书对这几处要么没写(停机从信号到进程退出的上界与 `engineSignal.draining.actionId` 的值域、托管标签的来源与权能、场景面收窄的写法),要么写偏 ——
|
|
458
|
+
把壳指去它读不到的 operator-only 配置目录取排空窗、`blocked` 终局的 `terminal.reason` 只写成「为什么做不了」、`a2a_serve_enabled` 日志行的 `tasksUsable` 字段并不存在、
|
|
459
|
+
server-as-peer 无 run store 时「卡照发、方法回 `-32004`」自 7.116.0 起已不成立。
|
|
460
|
+
新形(全部是文字,代码未动):
|
|
461
|
+
① 停机上界(`USAGE.md` 与契约文档各一条「停机上界(契约句)」):单发 `SIGTERM` 的退出上界 = `GET /health` 的 `engineSignal.draining.deadlineAt` + ≤ 1 s(排空驱动一拍)+ ≤ 15 s 终局(按定时器算的名义上界;真正强制的上界是壳自己梯子里的 `SIGKILL`);
|
|
462
|
+
两发形(第二发与第一发相隔 g ≥ `DRAIN_SECOND_SIGNAL_MIN_GAP_MS`,缺省 250 ms)= t0 + g + ≤ 15 s;10 s 在飞宽限在 15 s 之内、不相加。`engineSignal.draining.actionId` 的值域:信号致排空 = `signal:SIGTERM` / `signal:SIGHUP`(闭集),
|
|
463
|
+
运维排空口进的 = 该请求自带的 id,硬停(未经排空)期间排空口的回执 = 固定的 `hard-stop`(引擎自铸的另两类:`self-exit:attachment`、`lease:<代际>`)。
|
|
464
|
+
`DRAIN_GRACE_MS` 的生效值段与配置目录里它的语义句不再叫壳读 operator-only 的 `GET /v1/config/catalog`,改指排空期的 `engineSignal.draining.deadlineAt`;`STORE_LOCK_WAIT_MS` 一条补一句:
|
|
465
|
+
新引擎的锁等待窗应 ≥ 前任的排空窗 + 15 s 终局 + 一拍,壳 / 桌面按自己的排空窗注入,缺省不变。
|
|
466
|
+
② `blocked` 终局:`terminal.reason` 是**模型面**句(`terminal.detail` 在场时是引擎给模型的 `<system-reminder …>` 框句);用户面 / 机读面是 `terminal.detail { kind: "prompt_blocked_by_hook", cause, hookReason? }`
|
|
467
|
+
(`cause` ∈ `block` / `crashed` / `timeout` / `cancelled`)。**点名 cli · web-admin · client-core 的渲染层**:凡把 `blocked` 终局渲给人的读点,在 `terminal.detail` 在场时渲 `detail`(按 `cause` 分流,`hookReason` 按不可信文本渲),
|
|
468
|
+
不渲 `reason`;读不到 `detail` 才渲 `reason`(此时它是 agent 自己用 `ReportBlocked` 报的话);按 `detail.kind` 分支的读点留缺省臂。
|
|
469
|
+
③ hooks 托管标签(`USAGE.md` 9.5c-quater;契约 hooks 来源节):`source` 里的 `managedPolicy` / `managedPlugin:*` 由调用方自报,服务端只校闭集、不验身份;标签只改位置(托管相在非托管改写之后的最终输入上判,终判相次序)与失败方向(只收紧:未跑成或判词不可信折 `ask`;事件墙钟独立),`allow` 不看相。
|
|
470
|
+
④ server-as-peer:启动日志 info `a2a_serve_enabled` 的键是 `card` / `rpc` / `advertisedUrl` / `skills` / `blockingWaitMs`(没有 `tasksUsable`);开关开而没有 durable run store 时是 warn `a2a_serve_not_served`,卡与 `POST /v1/a2a` 一起 404。
|
|
471
|
+
⑤ 场景面收窄(部署自配,没有新语法):`SKILLS_DIR` 指空目录 + `config.d/skills.json` 的技能写 `scenarios` 标签;内建 `code-review` / `scan` 在 `config.d/scenarios.json` 里同名遮蔽成 `toolset: "none"`(`enabled: false` 是跳过、不遮蔽);`LSP_HOST_ENABLED` / `SCHEDULER_ENABLED` 现成开关。
|
|
472
|
+
⑥ 订正 7.145.0 节第 8 条 ① 的一句(坏行降级形的键集;7.145.0 节原文不改):降级行的键集恰为 `sessionId` · `checkpointId` · `scope` · `createdAt` · `gateKind` · `deadline` · `rowVerdict` · `objective` · `input`(`checkpointId` 读得出才在、`deadline` 在场才有)。
|
|
473
|
+
其中 `objective` 与好行同一读法 —— 路由对每一行补的 enrichment,按这道停驻门所属 run 的行预览独立读(值是串〔含 `""`:有预览记录而剥空〕或 `null`),不读坏字节、没有 run 行预览时也不铸空串;`input` 恒为 `null`;
|
|
474
|
+
摘要派生的键(`severity` / `spentMicroUsd` / 出身位三件套等)缺席 —— 7.145.0 节那句「摘要派生的键缺席」说的是这一类,`objective` 不在其中。
|
|
475
|
+
**谁需要**:按文书排壳形关机预算的壳 / 桌面;渲 `blocked` 终局的 cli · web-admin · client-core 渲染层;把 `source: "managedPolicy"` 读成「组织策略来源证明」的部署方;读 `a2a_serve_enabled` 日志里 `tasksUsable` 的编排脚本;按键表渲坏行卡的壳(cli · client-core · web-admin)与按判据键表验收的黑盒。
|
|
476
|
+
**谁受伤**:照旧文书去读 operator-only 配置目录的壳读不到;把 7.145.0 节那句读成「坏行上 `objective` 也缺席」的收件箱客户端(多一个键无害,缺键才伤);渲 `terminal.reason` 的读点会把 `<system-reminder …>` 标记露在屏上(代码一直如此,文书此前没写);读 `tasksUsable` 的脚本从来读不到那个字段。
|
|
477
|
+
**补偿**:壳按自己注入的窗 + 契约句的上界排预算;渲染层改读 `detail`;`a2a_serve_not_served` 取代 `tasksUsable`。**升级前做**:无。**回滚**:无需(只改文字)。
|
|
478
|
+
|
|
479
|
+
6. **`local_roots_split` 起服告警只报「一声不响的分家」:显式给了 `CONFIG_LOCAL_DIR`(等于数据根 = 合一,不等 = 有意分家)即视作运维已表态,不再每次起服响;推导的配置根 ≠ 数据根照报(行为修复;日志面;部署零动作)**:
|
|
480
|
+
旧形:数据根的链是 `LOCAL_DATA_ROOT` → `CONFIG_LOCAL_DIR` → `AGENT_DATA_DIR` → `~/.ai-agent`,配置根(`config.d/` 与 `remote-exec.json` 所在)的链少第一节。起服期只要两个根解析出来不相等就打一条 warn `local_roots_split`,
|
|
481
|
+
不分配置根是显式给的还是推出来的 —— 同时显式给了 `LOCAL_DATA_ROOT` 与 `CONFIG_LOCAL_DIR` 且两值有意不同的部署,每次起服也响一次,指路句「想合一就设 `CONFIG_LOCAL_DIR`」对一个已经设了它的部署没有意义。
|
|
482
|
+
新形:`CONFIG_LOCAL_DIR` 在场(空串仍算缺席)⇒ 这条 warn 不再打,不管它和数据根相等与否 —— 合一旋钮一旦给出就是表态(等 = 合一,不等 = 有意分家)。只有配置根是推导来的(`AGENT_DATA_DIR`,或家目录缺省 `~/.ai-agent`)
|
|
483
|
+
且 ≠ 数据根时才打,字段 `dataRoot` / `configRoot` 与 warn 级别不变;`note` 文案改为点明 `CONFIG_LOCAL_DIR` 没设,并多一句出路:分家是有意的 ⇒ 把 `CONFIG_LOCAL_DIR` 显式设成那个配置目录,这一行即静默;`GET /v1/config/catalog` 里 `LOCAL_DATA_ROOT` 一行的说明句同改(只改文字)。
|
|
484
|
+
两个根的解析一个字不动:数据落在哪、`config.d` 从哪读,与上一版逐字相同;只有这一条日志的在场条件变了。
|
|
485
|
+
**谁需要**:同时显式给 `LOCAL_DATA_ROOT` 与 `CONFIG_LOCAL_DIR` 且两值不同的部署(壳 / 宿主把数据根与配置根分放),此前每次起服多一条 warn。
|
|
486
|
+
**谁受伤**:靠这一行发现「数据根 ≠ 配置根」的显式双根部署(那是他们自己给的两个值,此后起服不再看到它);`CONFIG_LOCAL_DIR` 打错字(指到另一个目录)的部署同样不再被它提醒 —— 校对两个根的值,不再靠这一行。
|
|
487
|
+
**补偿**:不给 `CONFIG_LOCAL_DIR` 就是原判据(推导的配置根 ≠ 数据根照报);无旋钮。**升级前做**:无。**回滚**:回到上一版即恢复每次响的旧形(只是日志的在场条件,无持久面)。
|
|
488
|
+
|
|
489
|
+
7. **在飞 run 并发帽:新旋钮 `RUN_MAX_CONCURRENT`(本副本全局)与 `RUN_MAX_CONCURRENT_PER_PRINCIPAL`(同一已验提交主体),缺省 `0` = 关;新提交超帽 ⇒ 429 `limit.rate_exceeded` + 体 `reason: "run_concurrency_cap"` + `Retry-After: 5`(行为加性,缺省关;wire 加性;部署零动作)**:
|
|
490
|
+
旧形:没有「此刻在飞几条 run」的帽;`RATE_LIMIT_RPM` 只限每分钟提交几条,一条 run 可以跑几十分钟,新提交会在同一台机器上叠起来。
|
|
491
|
+
新形:两根整数旋钮(负数 / 小数 / 非数 boot 拒启),`0` / 缺省 = 关(升级后什么都不变)。开了之后,新提交的四个口 —— `POST /v1/runs`、A2A `message/send`、`POST /v1/tasks`、`POST /v1/tasks/stream` ——
|
|
492
|
+
在幂等重放**之后**、建行 / 认领 / SSE 头**之前**数本副本此刻在飞的 run(后台 run、同步 / 流式腿、有 run 行的续跑腿都占一格;与排空读数同一份在飞集);到帽 ⇒ 429,`errorCode: "limit.rate_exceeded"`(沿用现有限流码),
|
|
493
|
+
体多机读 `reason: "run_concurrency_cap"` 与 `retryAfterSec: 5`,头 `Retry-After: 5` 同值。同 `Idempotency-Key` / 自带 `taskId` 的重试拿回自己的回执,不吃新 429;续跑、唤醒、审批作答不判。
|
|
494
|
+
`RUN_MAX_CONCURRENT_PER_PRINCIPAL` 数同一已验主体(与成本配额门同键);无主体请求只受全局帽。帽是本副本的(各副本各数各的),闸的是新提交:续跑回来的 run 不判,在飞数可以越过帽;同键并发重复提交赶在首发还在受理的窗里到达时,帽满可能拿到一次 429,按 `Retry-After` 重投即拿回首发的回执。
|
|
495
|
+
**谁需要**:共享一台 GPU 或一只小模型网关的家用 / 小团队部署。**谁受伤**:超帽者拿 429(新行为,缺省关);消费端把 `limit.rate_exceeded` 当「稍后再来」按 `Retry-After` 退避即可,要区分来源读 `reason`(其余产地不带)。
|
|
496
|
+
**补偿**:缺省关;`Retry-After: 5` 给退避。**升级前做**:无。**回滚**:去掉两根 env 即关;回到上一版时这两根 env 被忽略(上一版不认识它们)。
|
|
497
|
+
|
|
498
|
+
8. **硬断预告:自 7.147.0 起每个部署都要显式声明执行车道 —— 未声明拒启;车道词 `none` 取代词表外的状态名 `in-process`;`REQUIRE_EXECUTION_LANE` 退役(预告;本版零行为变化、零 wire 变化;部署零动作,但 7.147.0 的升级路径上有三件事要提前排)**:
|
|
499
|
+
旧形(7.146.0 及以前,也是本版):`REMOTE_EXEC` 不设时有两条隐式臂 —— `CONFIG_PROVIDER=local` 隐含 `host`(手带在,宿主真机);其余(`remote` 或不设)落 core 的进程内桩(手带整族不挂,任务照跑、回执 `status=completed`)。
|
|
500
|
+
后一条在 `GET /v1/capabilities` 的 `executionLane.provider` 上叫 `in-process` —— 一个不在车道词表里的状态名。想对「没点名」拒启,要自己开 `REQUIRE_EXECUTION_LANE=true`(缺省关;本仓自带的部署产物都写着它)。
|
|
501
|
+
新形(自 7.147.0 起;本版只预告,代码未动):
|
|
502
|
+
**硬断预告(7.147.0 起)**:每个部署都要显式声明自己最终生效的执行车道 —— env `REMOTE_EXEC`(`CONFIG_PROVIDER=local` 形下 `config.d/remote-exec.json` 也算);没有声明 ⇒ 拒启(`CONFIG_PROVIDER=local` 不再隐含 `host`,非 local 未设也不再静默落进「不挂手」的进程内桩)。「不给智能体的工具提供执行环境」改写成车道词 `none`,取代词表外的状态名 `in-process`(`GET /v1/capabilities` 的 `executionLane.provider`、`GET /v1/sessions/:id/execution-placement` 的 `lane`、409 的 `boundLane`、403 `execution_lane_not_allowed` 的 `extra.lane` 换值);`REQUIRE_EXECUTION_LANE` 退役(设了任何非空值 ⇒ 拒启,拒句指向 `REMOTE_EXEC`),自己拼的清单或拷过随包部署产物的 env 里写着它的,升级前要去掉。库里或数据根里已有记着 `in-process` 的会话 / 审批行的部署(跑过未点名车道的进程内桩的),须停全部旧副本、跑一次性迁移、再起 7.147.0,不可滚动混跑;web-admin 渲染 env 的中心 worker,须先停渲 `REQUIRE_EXECUTION_LANE`,再升到 7.147.0。照旧行为的一行修法:7.146.0 里非 local 且未设车道的 ⇒ 7.147.0 写 `REMOTE_EXEC=none`,`CONFIG_PROVIDER=local` 且未设的 ⇒ 写 `REMOTE_EXEC=host`(7.146.0 及以前不认 `none` 这个词,别提前写)。7.146.0 本身零行为变化。
|
|
503
|
+
**谁需要**:所有部署方 —— 尤其是 `CONFIG_PROVIDER=local` 的单机形、手写 `.env`、没写 `REMOTE_EXEC` 的托管 worker,以及给 worker 渲染 env 的编排方;读 `executionLane.provider` / 放置读面 `lane` / 409 `boundLane` / 403 `extra.lane` 的壳与客户端(按 `in-process` 字面分支的,要在 7.147.0 同波认 `none`)。
|
|
504
|
+
**谁受伤**:7.147.0 起 ① 没声明车道的部署拒启;② env 里还写着 `REQUIRE_EXECUTION_LANE` 的(拷过旧版随包部署产物的清单、自己拼的清单、编排方渲染的 worker env)拒启;③ 库里或数据根里有 `in-process` 存量行的部署要停机迁移、不可滚动(旧副本不认 `none`、新副本不认 `in-process`,混跑两头都会拒);④ 按旧词字面读 wire 的消费端。本版(7.146.0)无人受伤。
|
|
505
|
+
**补偿**:7.146.0 起就能显式点名 —— 单机用 `REMOTE_EXEC=host`,隔离用 `e2b` / `k8s` / `local-docker`(`none` 要到 7.147.0 才是车道词,现在写会被拒);要继续「不给手」的部署,7.147.0 写 `REMOTE_EXEC=none`(逐字复现今天非 local 未设的行为)。
|
|
506
|
+
编排方停渲 `REQUIRE_EXECUTION_LANE` 的同时,必须让每个 worker 的 env 带 `REMOTE_EXEC` —— 7.146.0 上只停渲这根旋钮而不点名车道,worker 会静默落进无手的进程内桩。
|
|
507
|
+
**升级前做**:无(本版)。为 7.147.0 排期:盘点哪些部署没写 `REMOTE_EXEC`;盘点 env 里的 `REQUIRE_EXECUTION_LANE`;有 `in-process` 存量行的部署排一次停机窗。**回滚**:无需(本版只改文字)。
|
|
508
|
+
|
|
509
|
+
9. **更正 7.144.0 节第 1 条与 7.137.0 节第 15 条的出路句(及 CHANGELOG 7.137.0 段的同句):`corrupt_session` / `invalid_session` 的出路里没有「从断点之上的条目分叉」这一手 —— `POST /v1/sessions/:id/fork` 不选条目,对结构坏的会话也不是出路(文字订正;零行为变化;部署零动作)**:
|
|
510
|
+
旧形:7.144.0 节第 1 条「补偿」写「结构坏改读 `corrupt_session`(别重试;换一个新会话、从断点之上的条目分叉,或请运维修好 / 移走那份日志)」,7.137.0 节第 15 条对 `invalid_session` 的消费方动作写「出路是换新会话或从断点之上的条目分叉」,契约「客户端动作」一句同说。
|
|
511
|
+
HTTP 上没有「从断点之上的条目分叉」这一手:fork 口没有条目参数,试了拿到的要么是带着同一个断点的副本,要么是 fork 自己答的 `corrupt_session`。
|
|
512
|
+
新形(只订文字,代码未动;已发节原文不动,订正只进本节;契约的「客户端动作」一句与 fork 节〔§23.4〕同改):
|
|
513
|
+
fork 口(`POST /v1/sessions/:id/fork`)不选条目:体只有 `forkId` / `forkNonce`,分叉点由引擎判 —— 取源会话已提交的历史(整份已结日志,叶 = 源会话的叶;最后一轮是带着还没有结果的工具调用的 assistant 轮时,只拷到它的父为止)。它拷的是这份日志本身、不修复任何东西:断点落在拷贝范围里的源(悬空父 / 自指 / 成环),副本带着同一个断点、打开同样答 `corrupt_session`;叶子缺席的源,或在飞轮的分叉点以上走不通的源,fork 自己就答 `corrupt_session`。两头都不是出路(引擎对成环那一形的原句里写着「fork from an entry above the loop」,HTTP 上没有对应的口)。出路是换一个新会话,或请运维修好 / 移走那份日志。
|
|
514
|
+
**谁需要**:照旧句去找「从断点之上的条目分叉」的调用方与壳(这个口没有条目参数)。**谁受伤**:把 fork 当这两个码的出路的客户端 —— 断点落在拷贝范围里时 fork 答 200 与一个新会话 id,可那份副本同样打不开(试了才发现);叶子缺席的源 fork 自己就答 `corrupt_session`。
|
|
515
|
+
**补偿**:换一个新会话;或请运维修好 / 移走那份日志(修好之后同一服务进程仍按它持有的那份答,重启进程才恢复,契约该节)。**升级前做**:无。**回滚**:无需(只改文字)。
|
|
516
|
+
10. **起服告警 `memory_engine_dir_defaulted` 改名 `memory_engine_dir_outside_data_root` 并改按路径包含判:file 形记忆引擎的已解析根不在本机数据根(`config.localDataRoot`)之下才报,句子带两条真路径;`MEMORY_ENGINE_DIR` 缺席不再是判据(行为修复;日志面,日志事件改名(旧名退役;壳 / 编排脚本按新名读))**:
|
|
517
|
+
旧形:判据 = `LOCAL_DATA_ROOT` 在 ∧ `MEMORY_ENGINE_DIR` 缺席,句子说「记忆引擎正在共享全机默认库」。`AGENT_DATA_DIR` 已把记忆根放在数据根上(或其下)时,
|
|
518
|
+
`MEMORY_ENGINE_DIR` 缺席只是没写 —— 记忆库并没有共享谁,这一行每次起服响一次、说的是假话;反过来,显式 `MEMORY_ENGINE_DIR` 指到数据根之外(记忆库与店数据真分家)时,这一行恒哑(旧判据要它缺席才成立)。
|
|
519
|
+
新形:只比路径 —— 已解析的记忆根(`MEMORY_ENGINE_DIR` → `AGENT_DATA_DIR` → `~/.ai-agent`)不在数据根(`LOCAL_DATA_ROOT` → `CONFIG_LOCAL_DIR` → `AGENT_DATA_DIR` → `~/.ai-agent`)之下 ⇒ 打一条 warn;在其下(含相等)⇒ 零条。
|
|
520
|
+
两侧都先过符号链接展平再比(盘上还不存在的尾巴只比规范化字串),数据根缺席不判。warn 的日志事件改名(旧名退役;壳 / 编排脚本按新名读):`memory_engine_dir_defaulted` → `memory_engine_dir_outside_data_root`(新判据下旧名不真 —— 显式 `MEMORY_ENGINE_DIR` 也报),零别名、不双发,级别不变;字段 `root` 保留(记忆根)、多一个 `dataRoot`(数据根)、
|
|
521
|
+
`hint` 换成一句带这两条真路径的话:「memory engine root <记忆根> is outside the local data root <数据根>; set MEMORY_ENGINE_DIR under <数据根> to isolate it」。
|
|
522
|
+
另:展平路径时盘上出了竞态(探完到取值之间目录被挪走 / 搜索权限被收)⇒ 不拒启,另报一行 warn `memory_engine_dir_check_unavailable`(`root` · `dataRoot` · `errorKind` · `errorCode`,不带消息原文)。
|
|
523
|
+
两个根的解析与记忆库落在哪一个字不动,只有这一条日志的在场条件与句子变了。
|
|
524
|
+
**谁需要**:同时给了 `LOCAL_DATA_ROOT` 与 `AGENT_DATA_DIR`、记忆根已在数据根之下的部署(此前每次起服多一句假话);显式给了 `MEMORY_ENGINE_DIR` 的部署(此前这一行对它们恒哑,现在按真路径比)。
|
|
525
|
+
**谁受伤**:按旧事件名读起服日志的壳 / 编排脚本读不到这一行了(旧名退役,改读新名);信号本身没丢 —— 此前靠这一行发现「忘设 `MEMORY_ENGINE_DIR`」的人(`LOCAL_DATA_ROOT` 在、记忆根落默认链且在数据根之外)照报,只是句子改真。读数变化只有日志在场与否:
|
|
526
|
+
此前不报、现在报 = 显式 `MEMORY_ENGINE_DIR` 在数据根之外;没设 `LOCAL_DATA_ROOT`、只设 `CONFIG_LOCAL_DIR` 把数据根挪走而记忆根仍落默认链(`AGENT_DATA_DIR` → `~/.ai-agent`)。
|
|
527
|
+
此前报、现在不报 = `LOCAL_DATA_ROOT` 在、`MEMORY_ENGINE_DIR` 缺席,但 `AGENT_DATA_DIR` 把记忆根放在数据根上或其下。**补偿**:句子带两条真路径,看一眼即知哪一侧要挪;无旋钮;
|
|
528
|
+
想让它静默就把 `MEMORY_ENGINE_DIR` 放到数据根之下(或让数据根包住记忆根)。**升级前做**:按旧事件名 `memory_engine_dir_defaulted` 读起服日志的壳 / 编排脚本改读 `memory_engine_dir_outside_data_root`(字段 `root` · `dataRoot` · `hint`;旧名不再发)。**回滚**:回到上一版即恢复旧名、旧判据与旧句子(只是日志,无持久面)。
|
|
529
|
+
11. **单用户部署上 `GET /v1/diagnostics/wiring` 与 `GET /v1/outcomes` 也先问运维名册:名单为空且没写 `OPERATOR_SINGLE_USER=true` ⇒ 两口答 501 `capability.operator_principals_required`;单用户部署配了具名 `OPERATOR_PRINCIPALS` ⇒ `GET /v1/outcomes` 只给名单内的主体(安全轴,fail-closed;行为变更;名单为空的单用户部署要这两口写一行 `OPERATOR_SINGLE_USER=true`)**:
|
|
530
|
+
旧形:两只路由各自内联「单用户形不问名单」。诊断面:名单为空 ∧ `REQUIRE_PRINCIPAL` 未开 ⇒ 不判运维,零凭证部署只许本机读、配了 service 凭据的部署过了全局凭据门即读;
|
|
531
|
+
outcomes:`REQUIRE_PRINCIPAL` 未开 ⇒ 不判运维(名单为空时人人可读,配了具名名单也被无视);能力位 `outcomeLedger` 在单用户形上不看名册。
|
|
532
|
+
新形:两口与其余运维口同序,部署形不是输入 —— 没有运维名册(`OPERATOR_PRINCIPALS` 为空且没有 `OPERATOR_SINGLE_USER=true`)⇒ 501 `capability.operator_principals_required`;
|
|
533
|
+
名单非空而调用方不在名单上 ⇒ 403 `auth.operator_only`;单用户声明在场 ⇒ 每个调用方过运维门。诊断面过了运维门之后:远程请求后面没有验过的身份(service 凭据 / 鉴权桥登录令牌 / 直连门签名令牌)⇒ 403 `auth.loopback_only`,本机照读(一条门,不再按名单在不在分两条)。
|
|
534
|
+
能力位 `outcomeLedger` = 有运维名册 ∧ 可查询账面;outcomes 口名册缺席先于账面缺席答:过了运维门(名册在场,调用方在名单上或单用户声明在场)之后,账面不可查询的部署(outcome sink 只写 JSONL 文件、没有查询面)另答第二个 501 `capability.outcome_ledger_required`(与名册缺席的 501 `capability.operator_principals_required` 是两个码,探针与看板按体上的 `errorCode` 判、不按状态码判)。起服 warn `operator_undeclared_single_user` 的在场条件由「单用户 ∧ 无名册 ∧ 有审批底座」变成「单用户 ∧ 无名册」,句子多点名这两口;
|
|
535
|
+
两只 403 句去掉「on a multi-tenant worker」(机器码不变)。
|
|
536
|
+
**谁需要**:单用户部署上配了具名运维名单的运维(此前 outcomes 视图对名单外的调用方也开);「运维面只认显式声明」这一条律在每个运维口上都成立。
|
|
537
|
+
**谁受伤**:名单为空、没写声明的单用户部署 —— 两口从 200 变 501:读诊断面的工具(壳的体检读诊断面回体的那几行)与 outcomes 看板读不到了;
|
|
538
|
+
单用户部署 + 鉴权桥 + 零静态凭据 + 已声明 —— 诊断面对带登录令牌的远程调用方从 403 `auth.loopback_only` 变成放行(不带身份的远程请求照旧 403)。
|
|
539
|
+
**补偿**:`OPERATOR_SINGLE_USER=true`(只在 `REQUIRE_PRINCIPAL` 未开且名单为空时成立,否则拒启)或具名 `OPERATOR_PRINCIPALS`;起服 warn 点名这一行;501 拒句同句给两条出路;能力位 `outcomeLedger` 如实。
|
|
540
|
+
**升级前做**:名单为空的单用户部署,要诊断面 / outcomes 视图(或壳的体检读诊断面的那几行)⇒ 写一行 `OPERATOR_SINGLE_USER=true`;单用户部署配了具名名单的,确认读 outcomes 的调用方带名单内的主体;
|
|
541
|
+
按「单用户形诊断面不问名单」写的探针 / 看板改按 501 / 403 两码判。**回滚**:回到上一版即恢复旧门(无持久面)。
|
|
542
|
+
12. **后台子代状态 `agentState` 过 wire 的读法成文并钉死,订正 7.116.0 节里「`details` 是否经 `tool_end.structured` 到客户端……没有核过」一句(文字订正;零行为变更;wire 零变化;部署零动作)**:
|
|
543
|
+
旧句:7.116.0 节写过 `agentState` 经事件流到客户端这一路仓内没有 wire 级钉、`structured` 带不带它取决于引擎对卡面 `type` 的白名单、本服务没有核过。现在核过并钉死了(`src` 一行未动,读数就是实现):
|
|
544
|
+
· `tool_end.structured` 本服务只换卡内串叶里的凭据形、不枚举卡内的键,`agentState` 逐键原样过 —— 主流、forward 分支、子代 tail 流、账本落行与 `GET /v1/runs/:id/events` · `GET /v1/tasks/:id/turns` · trace SSE 的回放都一样;
|
|
545
|
+
· 进不进 `structured` 由引擎的卡投影器定(类型在卡集里、且整卡序列化不超过 65,536 字符;超了整卡略去):`AgentTranscript` 的步骤答话(`structured.type` 为 `agent-transcript`:`structured.agentState`、`steps[i].at` / `inFlight`)与 `ListAgents`(`structured.type` 为 `list-agents`:每个后台子代行 `rows[i].agentState`)带它;
|
|
546
|
+
· 不带它的三类是引擎的选择(缺席 = 引擎没给,不是本服务摘的):拒答(引擎取得了状态的那几类:转录已不在 / 未保留 / 读失败,首行 `State: …` 在 `output` 文本上;未知或无权限的 id 的拒答两者都没有)· `ListAgents` 里本进程没有活句柄的名册行(`state:"unknown"`)· 后台子代任务 poll 的 `details`(它的 `type` 是 `background_agent`,不进 `structured`;引擎的 `TaskOutput` 工具已退役,这份 poll 如今只有下面的 HTTP 读口);
|
|
547
|
+
· 持久子代行的读口 `GET /v1/runs/:id/subagents/:handle/output` 与 `GET /v1/runs/:id/tasks/:tid/output` 的体里 `output.agentState` 与 `content` 的 `state:` 行,对别的副本写下的行同读:已结行 `lastActivityAt` 是落定时刻,停驻行是停驻时刻,
|
|
548
|
+
别的副本还标 running 的行答 `not_local` 且 `agentState` 无 `lastActivityAt`;**停驻行(行上有审批 token)的审批卡读 `unreadable`、不带 `checkpointId` / `deadline`**(读口不交检查点座,当前实现的有意决定;行上没有 token 的读 `missing`)—— 等的那张卡看 `GET /v1/approvals` 的 `pending[]`。
|
|
549
|
+
**谁受影响**:读 `structured.agentState` / `output.agentState` 渲染子代窗格或状态行的壳与 SDK。**不改会怎样**:按「所有后台子代应答都带 `agentState`」写的渲染在拒答、名册 `unknown` 行、停驻行审批卡三处读空。
|
|
550
|
+
**怎么改**:按上面的缺席形处理(缺席读作「这一条没有状态」,不读作出错);停驻子代的审批态读队列行。**升级前做**:无。**回滚**:无需(只改文字与测试)。
|
|
551
|
+
13. **收编批量导入:源主体把本机会话导进收编目的地 `POST /v1/adoption/:id/sessions`,能力位 `adoptionImport`(按调用方 present-iff)给出 `:id` 与两只帽;两根新旋钮 `ADOPTION_IMPORT_MAX_SESSIONS` / `ADOPTION_IMPORT_MAX_SESSION_BYTES`(新面;wire 加性;部署零动作)**:
|
|
552
|
+
旧形:收编(`POST /v1/adoption`,operator)只改绑云端已有的行;用户本机的会话没有门进到收编目的地。
|
|
553
|
+
新形:源主体本人(逐字等于那条收编行的源主体;operator 不能代)以自己的身份 `POST /v1/adoption/:id/sessions`,体恰好 `{ "sessions": [ { "clientSessionId": "<本地 id>", "entries": [ … ] }, … ] }`,
|
|
554
|
+
会话导进那条收编的目的主体名下(请求体不能点名目的地)。云端会话 id 由 `(adoptionId, clientSessionId)` 确定性派生:重投 / 续传 / 并发都只落一份,已在的读成 `already_imported`。
|
|
555
|
+
200 + 逐元素结局 `imported` / `already_imported` / `rejected{code: too_large | invalid_envelope | duplicate_client_session_id}`;信封多一个键(如 `cwd`)⇒ 这个元素 `invalid_envelope`(本版不存会话元数据)。
|
|
556
|
+
导进来的会话与会话同步推送进来的一样是只读镜像(执行放置 `mirror`):读得到、列得出,要在云端接着跑先 `POST /v1/sessions/:id/fork`;直接在上面执行答 409 `conflict.session_mirror` + `forkPath`。
|
|
557
|
+
整请求拒:没有身份 401;local / 内存后端 501 `capability.adoption_store_required`;没有这条收编 404 `not_found.adoption`;不是源主体 403 `auth.adoption_source_only`;没收编完 409 `adoption.not_adopted`;
|
|
558
|
+
体形 400 `request.body_shape`;元素数超帽 400 `request.field_invalid`(`field: "sessions"`、`reason: "over_cap"`、`count`、`cap`)。
|
|
559
|
+
`GET /v1/capabilities` 对源主体本人多一位 `adoptionImport: { adoptionId, maxSessions, maxSessionBytes }`(别的调用方、没收编完、部署没有这一面 ⇒ 键缺席)。
|
|
560
|
+
两根旋钮(配置目录可读):`ADOPTION_IMPORT_MAX_SESSIONS`(每请求元素数,缺省 100,地板 1)、`ADOPTION_IMPORT_MAX_SESSION_BYTES`(每元素 JSON 字节数,缺省 6291456,地板 1048576,天花板 8388593);越界钳到边界并起服告警,小数拒启。
|
|
561
|
+
**谁需要**:从本机升迁到云端部署的用户与替他们做一键升迁的壳 / 客户端。**谁受伤**:信封带元数据(工作目录、首尾时间戳)的客户端要剥掉再送;导进来的会话是只读镜像,在云端接着跑要先 fork(新会话 id);整只请求体超过 8 MiB ⇒ 整请求 413(没有逐元素结局),单只信封本身超过 8 MiB 的会话导不进来。
|
|
562
|
+
同批的门收紧:会话同步推送第二阶段与本口共用一道条目门,存不下的条目(`id` / `parentId` 超 64 字符、`type` 不是 1–32 字符的串)现在答 422 `invalid_entries`(新句)—— 此前 SQL 店上是 5xx,local 店上照收。
|
|
563
|
+
**补偿**:按能力位的两只帽分批;结局逐元素给码;重投安全;运维可抬两只帽。**升级前做**:无(新面;不配旋钮即缺省值)。**回滚**:回到上一版即无此口与此位(已导入的会话是目的主体名下的普通会话,留在库里照常可用)。
|
|
564
|
+
14. **hooks 托管车道成为任务座上自己的一张引擎注册 `settings.hooks.managed`:引擎的 handler 预算(`HOOKS_TIMEOUT_MS`)每车道一份,非托管钩子吃光自己那份不再让托管钩子在 `Stop` / `SubagentStop` / `PreCompact` / `PostToolUse` 族上整只不跑且无声;托管车道被自己的预算叫停记 `hook_managed_unrun{budget_exhausted}`;`Stop` 上 `continue:false` 只撤本车道的推回(安全轴,失效关闭;行为修复 + wire 加性:新注册名、既有原因词多一种成因;部署零动作,按注册名字面读的读者见「升级前做」)**:
|
|
565
|
+
旧形:请求的 hooks 不分车道,铸成任务座上一张引擎注册 `settings.hooks`,两条车道(非托管 / 托管 = 组的 `source` 为 `managedPolicy` 或 `managedPlugin:<name>`)在这一只 handler 里共用引擎的一份 `HOOKS_TIMEOUT_MS` 预算;
|
|
566
|
+
本服务的车道墙钟只门新条目起跑,一条已经起跑的非托管条目能跑到自己的 `timeout`。它把这份预算吃光时,`PreToolUse` / `UserPromptSubmit` 上引擎 fail-closed 拒(方向对),
|
|
567
|
+
其余站上引擎跳过整只 handler —— 托管钩子一条也不跑、本服务不发任何帧,连非托管已经给出的上下文也一起丢。能力位 `taskSettings.managedHookGroups` 说「托管组跑不成即失效关闭」,这一支不是那样。
|
|
568
|
+
新形:一条车道 = 一张引擎注册。有非托管组 ⇒ `settings.hooks`(名字、挂法、预算读数、`once` 键与上一版逐字同);有托管组 ⇒ `settings.hooks.managed`,排在 `settings.hooks` 之前、外层挂:
|
|
569
|
+
先把事件交下去,等非托管车道(以及更下方的注册与引擎核心)答完,才在答回来的那一份上跑托管插件相与托管策略相并折叠 —— 托管车道最后判、判的是非托管改写之后的最终输入。
|
|
570
|
+
挂法只有这一种(不随站点变)⇒ 同座的非托管车道与更下方的运维 handler 恒先判,否决恒跑。
|
|
571
|
+
**收紧一条**:部署座(运维声明的 mod 包)在 `classic.PreToolUse` 上、**任务座之下**(`append` 档)挂了链成员 ⇒ 那一站上托管条目**只许收紧** —— 否决 / 问(含托管条目没跑成时失效关闭折的问)/ 上下文照收;
|
|
572
|
+
放行 ⇒ 这次调用拒(与不带标签的放行在运维 handler 之下被引擎座信任律拒同一个结局);改写(带 `ask` 的也算)给不进运维 handler(它只判过改写之前的那一份)⇒ 这次调用拒;下方要真人批的问(`requiresRealApproval`)在托管作答之后照旧要真人批。任务座之下的链站点读引擎的准入记录(观察者不算;记录不带匹配器 ⇒
|
|
573
|
+
运维 handler 带匹配器、这一次调用不中时也按「有」收紧 —— 只多收紧,不跳过否决)。部署座链成员只在任务座之上(`prepend` 档,或同档 `user` —— 同档里部署座在前)的站上不收紧:运维 handler 已先判、并在答回来的结果上再判。
|
|
574
|
+
每条车道各有一份引擎预算(两张注册读同一个 `HOOKS_TIMEOUT_MS`)、一只事件墙钟、一份 prompt 条数、一份上下文额度与一份 `once` 账。非托管把自己的预算吃光 ⇒ `PreToolUse` / `UserPromptSubmit` 上引擎照旧 fail-closed 拒
|
|
575
|
+
(拒句点名 `extension "settings.hooks"`),其余站上引擎只跳过非托管那只 handler,托管车道照跑。托管车道被自己的引擎预算叫停 ⇒ 撞上的那条托管同步条目记未跑成,发 `hook_notice` 帧
|
|
576
|
+
`kind: "hook_managed_unrun"`、`reason: "budget_exhausted"`(与墙钟到点同一个词),`detail` 点名引擎预算(`HOOKS_TIMEOUT_MS`)并说其后的托管条目都没跑;每个事件恰一帧(其后的组 / 相 / 重判那一遍不再起、不再记);
|
|
577
|
+
叫停之后才跑完的 http / prompt / agent 条目(不持子进程、不随信号停)同样按叫停记;拒站上引擎照旧 fail-closed 拒,其余站上结论是下方的答案。任务取消叫停不记帧(成因在叫停那一刻定,取消之后子进程收尾拖过预算余量也不记)。
|
|
578
|
+
没有托管组的请求只得到 `settings.hooks` 一张,与上一版逐字同。有托管组时折叠与上一版同,三处读法变了:
|
|
579
|
+
① `Stop` / `SubagentStop`:每条车道的 `continue:false` 只撤本车道的推回(本车道的拦停与上下文一并丢),别的车道的推回、运维声明的部署座链成员的推回都不撤 —— 两车道意见相左
|
|
580
|
+
(一条 `continue:false`、另一条拦停或只给上下文)⇒ 推回作数、这一轮不收场(连续推回仍受引擎上限 8 兜住);上一版任一车道的 `continue:false` 让两车道的请求钩子整体无意见。
|
|
581
|
+
② 观察站(`PostCompact` / `StopFailure`):两张注册按链序串行,托管车道先跑、非托管后跑(上一版同一只 handler 里非托管先;观察者不作答,次序不进任何结论)。
|
|
582
|
+
③ 两车道都给上下文且合计超过 10 000 字:非托管车道先在自己那张注册里截一次,托管车道把答回来的那一整段排在自己的上下文之后、在剩余份额里只截尾 —— 托管的上下文仍整段在前,
|
|
583
|
+
非托管那一段里条目的边界与「省略几条」的计数不再与托管的一起算(可能见到两行截断标记)。
|
|
584
|
+
订正 7.137.0 节第 10 条的铸点数(那一节原句不动):本服务自己铸的 handler 答案铸点(带 `action` / `block` / `additionalContext` / `overlays` 键的对象字面量,判据不变)现为共 19 处 —— hooks 车道注册 18 处、部署座品牌行 1 处 —— 仍全是普通对象字面量;托管车道接在下方答案之上作答时,用展开把下方答案的成员原样带上(拷贝,不另铸)。
|
|
585
|
+
**谁需要**:带组织策略钩子(组上标 `managedPolicy` / `managedPlugin:<name>`)的壳与嵌入方 —— 一条慢的或挂住的用户 / 项目 / 插件钩子不再能让托管的 `Stop` / `PreCompact` / `PostToolUse` 守卫整只不跑且无声;托管车道自己超时也看得见。
|
|
586
|
+
**谁受伤**:① 一个事件的最坏墙钟由 1 × `HOOKS_TIMEOUT_MS` 变成 2 ×(缺省 600 s ⇒ 1200 s);② 两车道意见相左的 `Stop` 钩子(一条 `continue:false`、另一条推回 ⇒ 这一轮不收场,上一版收场);
|
|
587
|
+
③ 按字面只认 `settings.hooks` 一个注册名的读者:有托管组时 `wiring_manifest.mods[]` 多一行 `settings.hooks.managed`,`allowRuleShadowed[].entries`、`askReasons[].registration` 与钩子失败时模型读到的拒句在托管车道作答 / 失败时点名它;
|
|
588
|
+
④ 运维声明、`append` 档(任务座之下)在 `classic.PreToolUse` 上挂链成员的部署 mod 包:带托管标签的组在那一站上只许收紧 —— 改写 ⇒ 这次调用拒(带匹配器的运维 handler 不中的调用同样拒;上一版那种调用上改写作数)、
|
|
589
|
+
放行 ⇒ 拒(带匹配器的运维 handler 不中的调用同样拒;上一版运维 handler 在链上时同样被拒)、问照问(上一版同形被拒)、否决照常;不带标签的组与上一版同;自报托管标签换不来运维 handler 之上的放行或改写;
|
|
590
|
+
只挂观察者、或链成员只在任务座之上(`prepend` / `user` 档)的部署包不受影响;
|
|
591
|
+
⑤ 两车道上下文合计超过 10 000 字时非托管那一段的截法(见上 ③);⑥ 跨车道依赖执行次序的观察站钩子(参照实现并发跑同一事件的钩子,次序本就不是契约)。
|
|
592
|
+
**补偿**:`HOOKS_TIMEOUT_MS` 照旧可调(调低即同时收紧两份预算);能力位 `taskSettings.managedHookGroups` 不变(位说的话现在逐字成立);不想要这层严格,去掉组上的 `source`(缺席 = 非托管,只有一张注册);
|
|
593
|
+
④ 那一形要托管放行 / 改写作数,运维把那只 mod 挂到 `prepend` / `user` 档(在请求钩子之上判)。
|
|
594
|
+
**升级前做**:按字面只认 `settings.hooks` 的 `wiring_manifest` / `allowRuleShadowed` / `askReasons` 读者改为同时认 `settings.hooks.managed`;上游请求超时按 2 × `HOOKS_TIMEOUT_MS` 的最坏事件墙钟复核。
|
|
595
|
+
**回滚**:回到上一版即恢复一张注册、共用一份预算、旧的 `Stop` 折叠与观察站次序(无持久面)。
|
|
596
|
+
|
|
597
|
+
15. **请求面压缩开关:`settings.autoCompactEnabled`(CC 2.1.309 settings 同名键,布尔)逐字交给引擎的自动压缩座 `compaction.autoCompact`;能力位 `taskSettings.autoCompactEnabled`(wire 加性;不带这个键的请求行为不变;部署零动作)**:
|
|
598
|
+
旧形:请求面没有压缩开关 —— 壳的 `DISABLE_AUTO_COMPACT` / `DISABLE_COMPACT` 让本地显示说「不会自动压缩」,而引擎照压;`settings.autoCompactEnabled` 在新提交面是集外键,`400 request.body_shape`。
|
|
599
|
+
新形:`settings.autoCompactEnabled`(布尔)被受理,`true` / `false` 逐字交给引擎的自动压缩座 `compaction.autoCompact`(与顶层 `compaction.clampTolerance` 同一个 `compaction` 对象、同一只映射);缺席 ⇒ 不写 `compaction.autoCompact`,缺省值的属主仍是引擎与部署席
|
|
600
|
+
(引擎读序:请求席 → 部署席 → 开;显式 `true` 压过部署席的关,缺席跟部署席走 —— 本服务自己的装配不设部署席,对它而言两者读数相同)。
|
|
601
|
+
非布尔(`"false"` / `0` / `null` / 容器)⇒ `400 request.field_invalid`;续跑重放腿对存量体里的非布尔丢弃、不拒。能力位 `taskSettings.autoCompactEnabled`(恒真):见位才发,老 server 对这个键 `400 request.body_shape`。
|
|
602
|
+
**`false` 关掉的是引擎自起的三遍**(窗阈值那一遍、服务商拒绝过长请求后的恢复压缩、任务尾摘要);手动压缩(`POST /v1/runs/:id/compact`)归引擎的另一只座 `manualCompact`,本服务不写它 ⇒ 不受影响 —— 与参照实现同读(那里 `autoCompactEnabled=false` 只关自动,`DISABLE_COMPACT` 才连手动一起关;壳对后者自己不发 `/compact`)。
|
|
603
|
+
不受这个键管的是请求投影层的另几道缩减:较早的旧工具结果换成指针(不改转录)、请求媒体裁剪。
|
|
604
|
+
关掉之后撞上窗口上限的 run:请求发出前上下文超过守卫线(窗口的 `max(窗口 − 23 000 token, floor(窗口 × 0.85))`)时,引擎不做摘要:先清旧工具结果,仍超线则只保留尾部、较早的消息从这一次请求里省掉(会话里的完整历史不动);
|
|
605
|
+
服务商仍 4xx 拒绝 ⇒ 这条 run 以 `terminal.kind:"failed"` 终局,拒绝被引擎归为「输入本身超出上下文上限」时 `terminal.detail.errorKind` 为 `"input_too_long"`(拒绝点名别的部位时是 `image_unprocessable` / `tool_schema_refused`,缺席 = 没点名已分类部位)。
|
|
606
|
+
**谁需要**:壳 —— 用户设了 `DISABLE_AUTO_COMPACT` / `autoCompactEnabled=false`,此前壳显示「不会自动压缩」而引擎照压;壳见位后把这个布尔发过来,显示与行为才对得上。
|
|
607
|
+
**谁受伤**:发 `false` 的那条 run 自己(更长的历史每回合重发、较早的指令可能落在被裁掉的那一段、可能以 failed 终局),以及共享这份 `compaction` 的委派子代;不发这个键的调用方零变化。
|
|
608
|
+
**补偿**:显式开关本身(发 `true`,或在没有部署席的装配上不发,即回到开);失败终局上的 `terminal.detail` 机读位;每任务预算上限(`maxCostUsd` / `maxTokens`)照常封顶。**升级前做**:无。**回滚**:回到上一版即恢复旧形(壳在老 server 上见不到能力位,不发这个键)。
|
|
609
|
+
|
|
610
|
+
16. **请求的 `settings.env` 不收凭据:名字是本引擎的凭据变量(配置目录 `secret` 行 ∪ 模型条目 `apiKeyEnv`)或值是秘密形 ⇒ 新提交 `400 request.env_credential_refused`;升级前停驻的任务窗内续跑时剥掉照续(一次性迁移 M38,窗 30 天)(安全轴,fail-closed;wire 新码;调用方动作;部署零动作)**:
|
|
611
|
+
旧形:`settings.env` 只判形与帽(对象、≤ 256 条、键 ≤ 256 / 值 ≤ 32768 字符),凭据形的条目照收;单用户 host / device 车道把它原样叠进模型 shell 的环境,settings hooks 的命令环境与 http `$NAME` 插值也读它。
|
|
612
|
+
新形:会交到子进程的条目里,名字是本引擎的凭据变量(`GET /v1/config/catalog` 里 `secret` 型的全部行 ∪ 生效配置每条模型条目的 `apiKeyEnv`;比名不分大小写)或值是秘密形(settings-schema 的 `containsSecretToken`)
|
|
613
|
+
⇒ `400 request.env_credential_refused`,体带 `field: "settings.env"` 与 `entries: [{ key, match }]`(`match` = `"name"` / `"value_shape"`,两者都中报 `"name"`),值从不回显;不剥、不降级;不分车道。
|
|
614
|
+
续跑:升级前受理、停驻、存体里带这类条目的任务,一次性迁移 M38 的窗(本版发布日 + 30 天)内续跑时这些条目从 shell / hooks 的环境里剥掉、任务照续(运维 warn `settings_env_credentials_dropped`,只计数,不带键名与值);
|
|
615
|
+
窗关后续跑答 409 `resume_blocked_by_policy`(`blockedBy: "request.env_credential_refused"`,同一组机读位),卡仍待决。
|
|
616
|
+
**谁需要**:把模型凭据交给 sema 本机用的用户 —— 凭据不再随一个模型读得到的设置文件进会话的 shell 与 hooks。
|
|
617
|
+
**谁受伤**:还把凭据写进 `settings.json` `env` 的老壳(400);刻意经 `settings.env` 给模型 shell 或 http 钩子一枚秘密形令牌的调用方(400;钩子那一形今天没有替代通道,已知限制);值形扫描误伤的非凭据长串(400);
|
|
618
|
+
窗关后才续跑的升级前停驻任务(409)。
|
|
619
|
+
**补偿**:拒体按 `entries` 逐条机读点名;要让模型 shell 持令牌 ⇒ 放在引擎进程环境里一个不在配置目录、也不是模型条目 `apiKeyEnv` 的名下,配 `inheritEnv:"all"`(单用户 host 车道);窗 30 天 = 停驻行终局兜底缺省。
|
|
620
|
+
**怎么改**(调用方):把凭据挪出 `settings.env`,放进引擎进程启动时的环境(壳起的本机引擎:壳的凭据文件;服务形部署:进程环境 / 编排器的 secret 注入),重发。
|
|
621
|
+
**升级前做**:部署零动作(想让带这类条目的停驻任务不在窗关后 409,窗内续完即可)。**回滚**:回到上一版即恢复旧形(零持久形变化;M38 不写库)。
|
|
622
|
+
|
|
623
|
+
17. **错误码目录加「码族」列:契约附录 A 每个码恰属五族之一(`transient` · `deterministic` · `store_judged` · `pending_decision` · `retention_expired`),消费端按列读、不再各抄一张码表;`wire-changes` 清单多一集 `errorCodeFamily`(契约列加性;应答体零变化;部署零动作)**:
|
|
624
|
+
旧形:「这个失败值不值得重试」「卡还在不在」「留存是不是已被收走」的码集住在各消费端的手写名单里(sdk 十个确定性失败码、client-core 一组留存失效码),server 只在 decide / resume 腿的体上盖 `retriable`(它说「卡仍 pending」,不说「重试会成功」)。新码不进名单就被静默重试。
|
|
625
|
+
新形:契约文档附录 A.1 / A.1b 每一行的第二格写码族;A.1g 是词表与读法;A.1h 登记 33 个表外扁平码的族。五个词 —— `transient`(原样重发等一等可能成)· `deterministic`(重发改不了判,别自动重发)·
|
|
626
|
+
`store_judged`(逐次由店判,读体键 `permanence`)· `pending_decision`(卡仍待决,读体键 `retriable`:在场说「卡还在」,不说「重发会成功」;缺席不推出卡已不在)· `retention_expired`(留存已被收走,新开)。传输层的重试判据 =
|
|
627
|
+
状态 ∈ 重试集(408 / 429 / 500 / 502 / 503 / 504)∧ ¬(族 = `deterministic` ∧ 状态不是 408 / 425 / 429:等待类状态不被族豁免)∧ 体 `permanence` ≠ `terminal`。`wire-changes/server@7.146.0.json` 起多一个集 `errorCodeFamily`:本版整列入册进 `registered`(码本来就在 wire 上),
|
|
628
|
+
之后的版本记族的增删改。**应答体一个字节没变**:没有新码、新键、新状态码。
|
|
629
|
+
**谁需要**:sdk(`NON_RETRYABLE_CODES` 可改按列派生;对着手写的十码对账,多出 `auth.service_token_required` · `state.no_sandbox_base` · `state.mcp_reconnect_unsettled` 三个 503 码,这三个重试不会好)、client-core(留存失效码集与「卡仍待决」的读法)。
|
|
630
|
+
**谁受伤**:没有人被迫改。按列读之后行为会变的至多两处:传输层的豁免集多上述三个 503 码(这几个口多半是非幂等 POST,sdk 现有的动词门本来就不自动重发它们〔推断,未逐口核〕,实际行为变化至多是边角);`resume.cap` 与 `resume.session_not_found` 不再属于「留存失效」(归 `deterministic`,渲通用的「不可续」),`retention_expired` 目前只有 `resume.evicted` 一员。
|
|
631
|
+
**补偿**:不读这一列的消费端零变化;表外码(core 原码镜像,如 `resume.tool_unavailable` · `checkpoint.config_refused`,不在目录行里)没有族,缺省读法照旧 —— 看状态与前缀,体上有 `retriable: true` 照 `pending_decision` 读。
|
|
632
|
+
**升级前做**:无。**回滚**:无需动作(文书与生成器的清单;回到上一版时目录没有这一列,按列读的消费端回落到自己的名单)。
|
|
633
|
+
|
|
634
|
+
18. **会话记忆状态报出引擎记忆写家:带层座(`?scope=`)时多一个可选键 `writeHome`(那只店的引擎答案,绝对目录,字节原样),不带层座时多两个可选键:顶层 `writeHome`(引擎在店之间择好的会话级一个家)与 `planes`(逐店明细里引擎答的 `writeHome` 原样透出);单用户 `host` 车道在场,其余车道缺席,与能力位 `projectContext` 同一只射程谓词(wire 加性;部署零动作)**:
|
|
635
|
+
旧形:会话记忆状态体是 `sessionId` · `autoConsolidationArmed` · `memorySync?` 加五个会话键;引擎把会话写进哪个目录,没有任何 wire 面报出来(能力面只有记忆引擎的后端与向量模式)。
|
|
636
|
+
新形:路径由引擎定义,本服务只透出,不拼、不规范化、不折叠、不择一。`writeHome` 是店绑定的键(会话的写家住在哪只店,就由那只店的引擎答)。带 `?scope=<层键>`:那一层住的店的引擎答案,多一个可选顶层键 `writeHome: string`(canonical 绝对目录)。
|
|
637
|
+
不带 `?scope=`:整个部署的答案 —— 多一个可选顶层键 `writeHome`,是引擎在店之间择好的会话级一个家(点名家的店里最近写入的那只的家;任一店的写家读不出、两店同一时刻点名、或没有店点名 ⇒ 缺席,引擎不铸替身;单店部署 = 那只店自己的);
|
|
638
|
+
再多一个可选顶层键 `planes: [{ plane: "project" | "personal", writeHome?: string }]`,每只店一行(店序是引擎的),`writeHome` 是那只店引擎答的值原样,这只店没有家的行只剩 `plane`;行里引擎的其余五键不上 wire。
|
|
639
|
+
在场 ⇔ 引擎答了 ∧ 部署形表行 `callerOwnsWorkerDisk` 为真(= `GET /v1/capabilities` 的 `projectContext` 为真的那些部署:单用户 `host` 车道);托管 / 沙箱 / 设备 / 无手车道两键都缺席(`planes` 整个键也缺席)。缺席不等于「老 server」:
|
|
640
|
+
引擎不答它时(会话既没有账户行、也没有已提交的贡献可命名写域,或这些源读不出,或记忆库布局还不能派生家)行里没有 `writeHome`;不带层座时引擎不择(另一只店的写家读不出 / 两店同刻)顶层也缺席;`projectContext` 为假的部署永远不会有这两键。其余键、状态码、错误码零变化。
|
|
641
|
+
**谁需要**:单用户本机部署的壳(打开会话记忆目录一类的面,不再自拼带哈希后缀的目录名)。
|
|
642
|
+
**谁受伤**:没有人被迫改 —— 按闭集键读体的消费方对多出的可选键不受影响;要知道这是 worker 这台机器上的路径,只在 `projectContext` 为真(单用户 `host` 车道)时才来;本服务不判调用方的壳与 worker 是不是同一台机器(单用户部署里调用方就是主人),
|
|
643
|
+
分居两台机器时这个路径对壳没有意义,壳要自己判;不带层座时顶层缺席不等于会话没有家 —— 读 `planes[]` 或带 `?scope=` 看各店自己的。
|
|
644
|
+
**补偿**:缺席可读 —— `projectContext` 为假 ⇒ 两键不会来;为真时顶层缺席读 `planes[].writeHome` 或带层座。
|
|
645
|
+
**升级前做**:无。**回滚**:回到上一版即不再有这两键(其余键不变)。
|
|
646
|
+
|
|
647
|
+
19. **引擎 7.62.0 → 7.63.0(`@sema-agent/core` 与 `@sema-agent/primitives` 同版精确钉):① 🔴 审批绑定摘要改摘「工具 + 入参」—— 升级前停驻的工具审批行在本版上续跑不了(`409 approval_binding_mismatch` + `reason: "requirements_damaged"`,行留 pending),混跑期旧副本也接不了本版停驻的行;② 规则导入回执的引擎拒成员换形:`refused` / `indeterminate` 按引擎的「落没落」位分,`reason` = 引擎拒因码,`store_refused` 退出;③ 记忆六处收紧:`userlocal:` 族不复制(同步层起服拒、中心同步口 400)、v2 下保留前缀的折叠拼写拒、hipaa / zdr 合规档否决记忆整理、店集只算写过的个人店(订正 MIGRATION 7.144.0 节第 11 条 ⑤ 的已知限制)、公告队列文件坏了响亮拒、层键读不出的起服拒句换句首;④ 停驻行成员形不对即判坏,`DB_BACKEND=local` 的审批列表不再因一行坏字节整张 503;⑤ 后台 fork 子代进委派分区(不进会话列表);⑥ 本进程停驻的赎回完成回到停驻车道;⑦ 用户面通告加两码 `memory.harvest_refused` / `memory.harvest_conflict`(行为变更 + 硬破坏两条;wire:两码加性、一回执词退出;升级前做见本条)**:
|
|
648
|
+
换钉:`@sema-agent/core` 7.62.0 → 7.63.0 精确,`@sema-agent/primitives` 随之 7.63.0。下列各项按「谁看得见」排。
|
|
649
|
+
① **停驻的工具审批行(硬破坏)**:
|
|
650
|
+
旧形:停驻行与活问上的绑定摘要只摘入参;一张对 Write 的批准与同一调用 id、逐字同参的 Edit 摘要相同(本服务另把工具名放进审批身份,活门上已分问)。
|
|
651
|
+
新形:停驻行的 `boundInputHash`、活问与路由问的摘要、批准的许可一律摘 `{ tool, input }` 一条记录,停驻行用一个读方要求词自报这一读法。升级前停驻的工具审批行没有这一声明 ⇒ 本版引擎在认领前拒,
|
|
652
|
+
行字节不动、仍 pending:`POST /v1/approvals/:id/decide`(与其余续跑口)答 `409 approval_binding_mismatch`、`reason: "requirements_damaged"`、`retriable: true`,run 行重新停驻,卡不孤儿;
|
|
653
|
+
引擎句点名「摘要早于工具绑定」;收件箱与运维队列上这一行的 `rowVerdict` 同为 `damaged`。反方向同理:本版停驻的行带着上一版不认识的读法声明,混跑期落到 7.145.x 副本上的续跑答 `409 checkpoint.unsupported_version`(`reason: "version_newer"`),行同样留着。
|
|
654
|
+
活问(非停驻)的审批身份里含摘要 ⇒ 升级前已决的活问,升级后同一调用再问一次会出一张新卡(不回放旧答案;安全方向)。
|
|
655
|
+
② **规则导入回执**(`POST /v1/rules/cc-import/redeem` · `POST /v1/rules/local-import/redeem`):
|
|
656
|
+
旧形:成员里引擎拒的一律 `outcome: "indeterminate"` + `reason: "store_refused"` + `detail` = 引擎原话(那时引擎的拒只带自由文本)。
|
|
657
|
+
新形:引擎给拒臂两只机读位(拒因码与「落没落」)。`committed: "no"` ⇒ `outcome: "refused"`(没落);`committed: "unknown"` ⇒ `outcome: "indeterminate"`(写可能已落);
|
|
658
|
+
两者的 `reason` = 引擎拒因码原样(引擎闭集,17 词;例:旧导入记录里从 `/` 写起的全局规则 ⇒ `refused` + `unsupported.layer_root`,店写抖动 ⇒ `indeterminate` + `store_write`),`detail` 仍是引擎原话。`store_refused` 退出 wire。
|
|
659
|
+
滚动升级窗:7.145.x 副本落定、票行仍在(local-import 票寿内)的回执被本版副本回放时,回执里的 `store_refused` 读不出 ⇒ 响亮拒(不改写落盘回执);票行随票寿被收走即闭窗,不另做迁移。
|
|
660
|
+
反方向同理:本版落定、票行仍在的回执被 7.145.x 副本回放时,只要有一条引擎拒的成员(它的 `reason` 是引擎拒因码,7.145.x 的回执边界 schema 只认 `store_refused`)整张读不出 ⇒ 那一次回放响亮失败(服务器通用错误,不是 200 回执;不改写落盘回执、不重跑兑付);
|
|
661
|
+
全是 `persisted` / `no-op` 成员的回执两版互读无碍。同样随票寿闭窗;混跑期把 local-import 的兑付与重放都打到同一版本的副本上即可避开。
|
|
662
|
+
**本版第 23 条 ⑥ 取代上面 `indeterminate` 的读法**:规则导入这两口上,任一成员引擎答 `committed: "unknown"` ⇒ 不落定、放回认领、`503 state.rule_import_retry` 同票重走,落定的 200 回执里不再出 `indeterminate` 成员(`refused`、`reason` = 引擎拒因码、`store_refused` 退出这几处照旧)。
|
|
663
|
+
③ **记忆**:
|
|
664
|
+
— `userlocal:<P>` 族(个人平面上只留本机、不复制的层):同步层(显式 `MEMORY_SYNC_SCOPE`,或由 `MEMORY_SCOPE` 缺省派生)是这一族 ⇒ 起服拒(点名旋钮);
|
|
665
|
+
中心同步口 `POST /v2/memory/sync/:scope` 对这一族答 `400 memory_sync_invalid_scope`(既有码),在属主门之前。判据只有引擎的复制判官一只。
|
|
666
|
+
受影响的不止同步层:7.145.x 的前缀表里没有 `userlocal:`,字面以 `userlocal:` 起头的层键(`MEMORY_SCOPE`、登记簿各项目的 `defaultScopes`)按不透明层读、落项目平面;
|
|
667
|
+
本版按保留前缀读 ⇒ 带它的读列表声明 v2(同列表里保留前缀的折叠拼写随之按下一条拒),这一层落个人平面、不复制 —— 7.145.x 上写进这一层的条目留在项目平面原处,升级后这一层读不到它们;
|
|
668
|
+
不当同步层用的这种层起服不拒、不告警。谁需要:7.145.x 上手拼过这种字面层名的部署;谁受伤:这一层的可见域静默由项目面移到个人面;
|
|
669
|
+
补偿:升级前给这一层改名(改成不以保留前缀起头的键;改了名的键是另一层,要带走条目先用 `GET /v1/memory/export?scope=<旧键>` 留一份)。
|
|
670
|
+
自检:升级前在 `MEMORY_SCOPE` / `MEMORY_SYNC_SCOPE` 与登记簿各项目的 `defaultScopes` 里找字面以 `userlocal:` 起头的键,有则先改名再升级。
|
|
671
|
+
— v2 契约下,读作保留前缀(`user:` / `userlocal:` / `org:` / `proj:` / `userproj:`)的另一种拼法(大小写不同、全角冒号、前后空白)拒(`config.memory_scope_key`),不再当作不透明层;
|
|
672
|
+
`userlocal:` 的折叠拼写在不声明 v2 的部署上也不复制。
|
|
673
|
+
— 合规档 `hipaa` / `zdr` 的内建否决多一词 `memory_consolidation`:显式 `MEMORY_CONSOLIDATION_DRIVER=on` 与这两档(或 `COMPLIANCE_ADDITIONAL_DENIES` 含该词)同设 ⇒ 起服拒(拒句点名三只旋钮);
|
|
674
|
+
未设 ⇒ 整理阀门缺省关、零提示 —— 手动整理口(`POST /v1/admin/memory/consolidation/run`)因此答 `501 feature.memory_consolidation_disabled`(句子说阀门关,不点名合规档);
|
|
675
|
+
手动整理每一轮也交部署档位(引擎否决 ⇒ `409 memory.consolidation_refused`,拒因 `config.compliance_denied`),但本服务的装配下档位否决时阀门结构上开不起来,这一 409 不可达。
|
|
676
|
+
— 店集只算**写过**的个人店:被拒的个人层抹除、点名个人层的只读不再让个人店进店集(目录照旧会建 —— 引擎的开店律没变,店集不再读它);
|
|
677
|
+
一次成功的写、一次执行了却什么都没擦的个人层抹除(它在个人店记下请求锚)让店进集。订正 MIGRATION 7.144.0 节第 11 条 ⑤ 的已知限制(那一节原句不动):
|
|
678
|
+
不点名层的出处 / 清标账 / 清标不再因一只从没写过的个人店永久答 `400 request.memory_layer`;盘上已留下的空个人店零迁移、零删除,自本版起不算 —— 那一条「补偿」里删 `personal/` 目录的手动步骤不再需要。
|
|
679
|
+
— 公告队列(file 形记忆控制面里的 `announcements.json`)读不出:此前下一次写入静默换成空队列(积压的公告丢了、无声);本版每次入队与取出都响亮拒 —— 运维日志
|
|
680
|
+
`memory_engine_incident`(`code: "memory.announce_failed"`,计数 `memory_engine_incident_total`),坏字节原样留给运维,修好或删掉文件即恢复;队列坏着时控制面账本的重建也拒。
|
|
681
|
+
队列锁等过 3 s 的入队此前不持锁照写,本版拒那一次入队(同一条日志),不落无锁的写。
|
|
682
|
+
— 层键读不出的起服拒(`config.memory_scope_key`,同步层 / 记忆层键)句首由 `resolveMemoryScopeStore: …` 换成 `memoryScopeStores.planeOf: …`(平面那一问改由引擎的一只读法答;码不变;
|
|
683
|
+
订正 MIGRATION 7.140.0 节第 6 条括号里引的句首,那一节原句不动)。
|
|
684
|
+
— SQL 记忆腿(`MEMORY_ENGINE_BACKEND=pg|mysql`)的落点问询:问的整圈交引擎(轮数上限、超限拒码),行为见本节第 3 条(已按本版终形写)。
|
|
685
|
+
— 引擎包根退役五名(整理驱动的计划目录 / 运行文件两只常量、`archiveDistillerPlan`、`readConsolidationDriverRun`、`readIntentCredentials`):本服务的读者改读引擎对象上的异步座
|
|
686
|
+
(整理运行行),运维面与 wire 零变化;自己从引擎包 import 这些名的嵌入方按引擎的迁移说明改。
|
|
687
|
+
④ **停驻行的成员形**:引擎读一行停驻行只用一张成员形表 —— 门是已登记门类的记录、`pendingAction` 是已登记种类的记录(工具审批带串 `toolCallId`)、`state` 是记录、
|
|
688
|
+
`createdAt` 是有限数、`deadline` 缺席或有限数;不合 ⇒ 判官答 `damaged`(`requirements_damaged`),续跑 / 决断拒、行留 pending、字节不动,列表面照列它、`rowVerdict` 非 `ok`。
|
|
689
|
+
此前只缺 `pendingAction` 的行判官答 `ok`(行照列却决不了);门类缺席 / 不是串的卡在决断口上的 `error` 是判官对这份字节的那一句(判官答 `ok` 的罕见形说自己读不出门类;`gate_not_tool_approval`,码不变);门类是一个本引擎没登记的串时仍是既有的门类指路句(既有行为,本版未动)。
|
|
690
|
+
`DB_BACKEND=local`:收件箱 / 运维队列(含订阅流)/ 任务视图对摘要读不动的行(缺 `state` 等)照列一行 —— 身份键 `sessionId` / `scope` / `gateKind`? 取引擎读出的那一份,`createdAt` / `deadline` 照存储体上的原值带(未经引擎读出、不校形;坏行上它们可以不是数),
|
|
691
|
+
摘要派生的键缺席 —— 不再整张 `503 approvals.read_unavailable`。订正 MIGRATION 7.145.0 节第 8 条「local 的列表面候引擎」与那一条的例外句(那一节原句不动)。
|
|
692
|
+
SQL 后端的坏行照旧由本服务在存储体之外握着的列事实答(会话 / scope / 建行时刻 / 门型 / `checkpointId`),wire 形不变。
|
|
693
|
+
7.49.0 之前停驻(不带行摘要)且成员形不对的行(例:`deadline: null` 当「无截止」、`createdAt` 是 `NaN`)此前能续,本版拒(硬破坏;本服务自己不写这种行)。
|
|
694
|
+
⑤ **后台 fork 子代**(引擎的后台委派 fork 出的子会话):建行那一笔就落进委派分区(三只会话店同一条:SQL 两孪生与行同一条 INSERT,local 随存档行头)⇒ 不出现在 `GET /v1/sessions` 列表里、
|
|
695
|
+
按会话 id 的认领形取用拒、随委派树一起列与删(与带放置的委派子会话同一组义务)。行属主照旧是 fork 的属主那一读。客户端经路由的 `POST /v1/sessions/:id/fork` 不变(不带放置)。
|
|
696
|
+
⑥ **停驻赎回的完成**:本进程持有停驻的子代赎回跑完 ⇒ 完成回到停驻周期欠账的那条车道(根会话正在跑的那一轮,或下一轮开轮时投出一帧 `task_notification`(`task_type: "background_agent"`));
|
|
697
|
+
此前经会话通知门进根会话收件箱。停驻落在别的进程 / 重启之前的(跨进程)⇒ 照旧经会话通知门,另有一条运维受众的引擎通告 `delegation.resume_lane_missing`(`{ taskId, rootSessionId? }`,不上会话流)。
|
|
698
|
+
⑦ **通告**:用户面引擎通告白名单加两码 —— `memory.harvest_refused`(记忆收割整批被拒;`detail { kind, committed, reportId?, sessionId? }`)与 `memory.harvest_conflict`
|
|
699
|
+
(店没收下部分改动;`detail { count, conflicts[{ op, id, concurrent }], reportId?, sessionId? }`);引擎的通告码 `session.records_skipped` 退出(本服务自 7.144.0 起已不发)。
|
|
700
|
+
**谁需要**:所有部署(引擎随版换);用 hipaa / zdr 档的部署(记忆整理与合规档同一条否决);多副本与重启频繁的 file 部署(店集一个事实一种读法);导规则的壳(拒因码可按码处置);
|
|
701
|
+
`DB_BACKEND=local` 上读审批列表的壳(一行坏字节不再挡住整张)。
|
|
702
|
+
**谁受伤**:① 升级时还挂着待决工具审批卡的部署 —— 那些卡在本版上决不了;混跑期两版互拒对方停驻的行;
|
|
703
|
+
② 按 `reason: "store_refused"` 字面分支的回执读者;③ 把同步层写成 `userlocal:` 族或折叠拼写的部署(起服拒);v2 部署上用折叠拼写当层名的请求;同时开着整理阀门与 hipaa / zdr 档的部署(起服拒);
|
|
704
|
+
按层键拒句的句首做字符串匹配的脚本;公告队列文件坏了的 file 部署(公告在修好之前不送达);
|
|
705
|
+
④ 7.49.0 之前停驻、成员形不对的行(本版决不了);只按位置列 `ok` 行的列表读者(多出 `damaged` 行);
|
|
706
|
+
⑤ 按会话列表找后台 fork 子会话的读者(它们改在委派树里);⑥ 本进程停驻的赎回完成时根会话空闲:完成那一帧等根会话下一轮开轮才投,存在进程内存里 —— 进程重启前没开轮就丢(跨进程形不受影响,照旧进收件箱)。
|
|
707
|
+
⑥ 同一帧在进程内只认会话 id、引擎投递时不比住客:根会话被删、进程没重启、同一个 id 又被登记 ⇒ 新住客的下一轮收到删前那一位的子代完成(含结果摘要)。上一版这一形经会话通知门、投递前复核住客,本版不经 ——
|
|
708
|
+
另一位属主重登的那一半由本节第 20 条拦(本进程删的会话);两半都由引擎 7.64.0 的住客地址在进程内关掉(本节第 23 条 ①:删前化身的完成被弃、运维席说一次)。
|
|
709
|
+
**补偿**:① 待决卡升级前决完或 expire(见下);混跑期按副本版本路由续跑,或先排空再整体换版;② 回执读者按 `outcome` 判(`refused` = 没落,`indeterminate` = 去 `GET /v1/rules` 对账),`reason` 按引擎拒因码读;
|
|
710
|
+
③ 同步层改写成可复制的族;不想要整理否决就不用这两档,或不开阀门;拒句按码(`config.memory_scope_key`)读;公告队列看 `memory_engine_incident` 日志、修或删 `announcements.json`;
|
|
711
|
+
④ 列表按 `rowVerdict` 渲(非 `ok` 的行渲其 `sentence`);这样的旧行在停驻它的版本上续完,或 expire 后重跑;
|
|
712
|
+
⑤ 后台 fork 子会话按委派树读(`GET /v1/sessions/:id` 的子代 / 委派面);⑥ 根会话的下一轮会结清欠账,要即时看见就保持根会话在跑。
|
|
713
|
+
⑥ 删除之后别马上用同一个会话 id 重开(换新 id 永远安全);另一位属主在本进程用它起执行本版起由第 20 条拒。
|
|
714
|
+
**升级前做**:① 把待决的工具审批卡决完,或 expire(停驻行被 expire 后任务从头再跑);先停光 7.145.x 副本再起本版,不要混跑续跑;
|
|
715
|
+
② 回执读者把 `store_refused` 分支改成按 `outcome` + 引擎拒因码读;③ 核 `MEMORY_SYNC_SCOPE` / `MEMORY_SCOPE` 不是 `userlocal:` 族、不是保留前缀的折叠拼写,登记簿 `defaultScopes` 里没有字面以 `userlocal:` 起头的层键(有则先改名,见 ③);核 hipaa / zdr 部署没有显式 `MEMORY_CONSOLIDATION_DRIVER=on`。
|
|
716
|
+
**回滚**:回到 7.145.x ⇒ 本版停驻的工具审批行在 7.145.x 上答 `checkpoint.unsupported_version`(行留着,回到本版可续),本版落定的回执里的新拒因码 7.145.x 回放时读不出(票寿内);其余各项无持久面。
|
|
717
|
+
|
|
718
|
+
20. **🔴 本进程删过的会话 id 只再执行给删前的属主:另一位属主在本进程用同一个 id 起执行(新提交、续跑、唤醒、停驻赎回)⇒ `409 conflict.session_id_retired`(续跑家族 `409 resume_blocked_by_policy`),什么都不跑(安全轴,fail-closed;wire 新码;行为变更;部署零动作)**:
|
|
719
|
+
旧形:会话 id 由调用方自选;一只会话被删之后,任何主体带同一个 id 提交 ⇒ 当作未知 id 登记给他并开跑;在别的副本上登记的同 id 会话,也照常在这只进程上续跑 / 唤醒。而引擎(7.63.0)把送不到活 run 的完成帧
|
|
720
|
+
(后台子代跑完、本进程停驻的赎回跑完,根会话此刻没有在跑的一轮)按会话 id 暂存在进程内存里、交给这只 id 在本进程的下一只 run、不比住客,会话删除清不到它 ⇒ 删前那一位的子代完成(含结果摘要)
|
|
721
|
+
会交进新住客的下一轮(第 19 条 ⑥ 让「本进程停驻的赎回」这一形也走这条路)。
|
|
722
|
+
新形:`DELETE /v1/sessions/:id` 在删除会话本体之前,在本服务进程里记下「这只 id → 删前属主」;本服务每一条带根会话的执行起点都经同一只执行上下文解析器对根会话行做一次行读,读完就问这份记录:
|
|
723
|
+
本进程删过这只 id、而行上的住客不是删前属主 ⇒ 拒,什么都不跑;句子不回显 id 与属主,只说换 id。「是不是同一位」与会话属主门同一条等价律:字面相等(含无主与无主)、单用户形里无主的行 ≡ `default` 主体
|
|
724
|
+
(壳 ≤1.0.82 留下的存量无主会话被壳带 `default` 删掉、再用同 id 起执行 —— 照常)、非 `REQUIRE_PRINCIPAL` 部署上的存量哨兵 `anon:shell-live` ≡ 没有主体的调用方;有方向、不互推;同一只 id 在本进程删过几次,住客就要对每一位删前属主都是同一位(再删不洗掉前一位),被互不等价的属主各删过一次 ⇒ 谁都不是。
|
|
725
|
+
新提交(`POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs`)答 `409` + `errorCode:"conflict.session_id_retired"`(码族 `deterministic`)—— 这一步在授权口之后,未知 id 已在授权口登记给调用方
|
|
726
|
+
(与解析器同一步的其它拒同序:那只空会话归他,留存收走或他自己删);续跑家族(审批决断后的续跑、`POST /v1/sessions/:id/wake`、`/v1/assistant/tasks/:id/resume` · `/plan_review`、
|
|
727
|
+
工作流决断后的宿主新轮)与停驻赎回答 `409 resume_blocked_by_policy` + `blockedBy:"conflict.session_id_retired"`(认领之前,卡仍待决 —— SLA 到期拒扫那一腿例外:它把准入策略的拒读作确定性,当场过期那张卡、run 终局);A2A 入口照它既有的拒形答(JSON-RPC `-32602`、HTTP 200,
|
|
728
|
+
不带这只码,也不带换 id 的句子 —— 运维日志有原因)。删前属主本人照常。`requireExistingSession` 而 id 不在 ⇒ 仍是 `404 resume.session_not_found`(授权口先答)。
|
|
729
|
+
记录只活在删掉它的那只服务进程里(不落库、重启即消、不跨副本),有界:满了驱逐最旧一条,逐次计数 + 每进程一次 warn(fail-open 计数 tag `server.session-id-tombstone.evicted`,登 `P-DEBT`:被驱逐的 id 上这道门失守)。无旋钮。
|
|
730
|
+
**谁需要**:多租部署与调用方自选会话 id 的部署 —— 一只被删会话的 id 不再成为另一位主体收下删前那一位后台结果的入口。
|
|
731
|
+
**谁受伤**:真想复用一只已删会话 id 的另一位主体(会话 id 是 uuid,撞上别人删掉的那一只的概率可忽略):删掉它的那只进程活着时,这个 id 在那只进程上对他不可用;
|
|
732
|
+
在同一只进程上先后被两位属主删过的 id 对两位都不可用。
|
|
733
|
+
**补偿**:换一个新的会话 id(拒句明示);无开关(安全轴不设放行旋钮)。
|
|
734
|
+
**已知限制**:只记本进程删的 —— 别的副本删的、托管留存按期删的会话不在记录里,那之后另一位主体登记同 id 并在持有暂存的那只进程上起执行,这道门不拦;同一属主删后重登同 id 不归这道门判(第 19 条 ⑥)。
|
|
735
|
+
两形都由引擎 7.64.0 的住客地址在进程内关掉(第 23 条 ①:暂存按会话 id + 住客存取,删前化身的完成被弃、运维席说一次);这道门照常留着,两道独立。
|
|
736
|
+
**升级前做**:无。**回滚**:回到 7.145.x ⇒ 没有这道门(记录本来就只在进程内存里,零持久面)。
|
|
737
|
+
|
|
738
|
+
21. **嵌入方类型面:服务型 `ServiceWorkflowJournalStore`(`StoreBackend.workflowJournal()` 的返回型)的可选成员 `deleteByRun?` 删 —— workflow journal 只剩按龄清扫一条删路;`ServiceConfig` 多七个必填席(嵌入方类型面 BREAKING;零 wire、零表、零存储格式;部署零动作)**:
|
|
739
|
+
旧形:SQL 后端的 journal 店带一只按 run 删(`deleteByRun(runId)`),引擎的 journal 契约从来没有这一员,本服务生产路径零调用者(清扫走按龄的 `reapExpired`)。
|
|
740
|
+
新形:这一员连同服务型上的可选成员一起删,零别名;按龄清扫不变。同一版里检查点店与 workflow journal 店的源文件从 `src/plugins/` 换到 `src/stores-sql/`(类名、导出、SQL、表与列一字不改),
|
|
741
|
+
检查点店两只孪生共用的行形与判据另住一只模块 —— 包的导出表只有根等几只入口,这些文件的路径从包外本来就 import 不到,无需动作。
|
|
742
|
+
同一版 `ServiceConfig` 多七个必填席,`loadConfig` 各从对应旋钮一次铸出:`adoptionImportMaxSessions` / `adoptionImportMaxSessionBytes`(`ADOPTION_IMPORT_MAX_SESSIONS` / `ADOPTION_IMPORT_MAX_SESSION_BYTES`,第 13 条)、
|
|
743
|
+
`serviceTokenActsForDeployment`(`SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT`,第 24 条)、`engineFirstAttachMs`(`ENGINE_FIRST_ATTACH_MS`,第 1 条)、`engineHandoverLingerMs`(`ENGINE_HANDOVER_LINGER_MS`,第 26 条)、
|
|
744
|
+
`runMaxConcurrent` / `runMaxConcurrentPerPrincipal`(`RUN_MAX_CONCURRENT` / `RUN_MAX_CONCURRENT_PER_PRINCIPAL`,第 7 条)。
|
|
745
|
+
**谁受伤**:自建 `StoreBackend`、并对 journal 店调 `deleteByRun` 的嵌入方 —— TypeScript 编译红即通知;自拼 `ServiceConfig` 的嵌入方同样编译红 ——
|
|
746
|
+
绕过类型拼出的配置里 `serviceTokenActsForDeployment` 缺席读作「不代」(只有字面 `true` 是代;出示 service 凭据、不报主体的调用方成了无身份调用方,起服打一行 `service_token_posture { actsForDeployment: false }`)。
|
|
747
|
+
**出路**:按 run 删换成按龄清扫(`reapExpired(now, maxAgeMs)`),或在自己的库上按 `run_id` 删 `workflow_journal` 与 `workflow_journal_owner` 两表的行;`ServiceConfig` 走 `loadConfig`,或照各条的缺省把七席写满。**回滚**:回到 7.145.x 即可(没有数据迁移)。
|
|
748
|
+
|
|
749
|
+
22. **k8s 沙箱 Role 的 `persistentvolumeclaims` 四动词与 `secrets` `create` 改按特性开关授 —— 随包 chart 缺省不再渲这两条规则;设了 `WORKSPACE_CACHE=volume` / `K8S_SANDBOX_ENV` 的存量部署要在 values 里开对应开关(或手写 RBAC 补规则)(部署面;行为收紧;两个旋钮都没设的部署零动作)**:
|
|
750
|
+
旧形:随包 chart 的 `templates/sandbox-rbac.yaml` 与 cluster 静态清单 `stack/sema-stack-cluster.yaml` 对所有部署无条件授 `persistentvolumeclaims`(`get` / `create` / `delete` / `deletecollection`)与 `secrets`(`create`),引擎旋钮开没开都一样 ——
|
|
751
|
+
没开缓存卷的部署也持有 `deletecollection persistentvolumeclaims`,没转发 env 的部署也持有 `secrets create`。
|
|
752
|
+
新形:这两条规则只在对应开关开着时授 —— `WORKSPACE_CACHE=volume` ↔ chart 值 `sandbox.workspaceCacheVolume`(布尔,缺省 `false`;`--set-string …=false` 这类字符串渲染即拒)、
|
|
753
|
+
`K8S_SANDBOX_ENV` 非空 ↔ chart 值 `sandbox.sandboxEnv`(`NAME,NAME` 名单字符串,缺省空)。同一个 chart 值**同时写引擎 env**(主 worker 与 v4pro 变体)与 Role 规则,开关与引擎旋钮只有一个写者;
|
|
754
|
+
cluster 静态清单里这两条规则是注释块,给 server 设了对应 env 时取消注释。规则表只写在源码的一张表里,chart / 静态清单 / 随包 `deploy/facts/sandbox-rbac.json` 与部署前置文档(仓库 docs 目录下 DEPLOY-PREREQS)的规则表都从它生成。pod / exec / log 与出网自检的两只只读照旧恒授。
|
|
755
|
+
**谁需要**:按最小权限部署 k8s 沙箱车道的 owner(没开缓存卷 / 没设沙箱 env 的部署不再持有这两条规则),以及整份拷走 chart 沙箱 RBAC 模板的取用方(规则与开关同表驱动)。
|
|
756
|
+
**谁受伤**:用随包 chart 或静态清单、引擎旋钮是**手补在 Deployment 上**(chart 之外)的存量部署 —— 升级后 Role 里没有对应规则:
|
|
757
|
+
`K8S_SANDBOX_ENV` 点到了本进程环境里有的键而 `secrets` 缺 `create` ⇒ **起服拒**,拒句带 `[sandbox-secret-rbac]`、点名缺的动词与要加的 Role 规则原文;
|
|
758
|
+
`WORKSPACE_CACHE=volume` 而 `persistentvolumeclaims` 缺动词 ⇒ 服务起得来,但每条 run 拿不到缓存卷(run 照起、不挂卷),fail-open 计数 `server.workspace-cache.unavailable` 涨。
|
|
759
|
+
**补偿 / 怎么改**:用 chart 的 —— 在 values 里开对应开关(`sandbox.workspaceCacheVolume: true` / `sandbox.sandboxEnv: "NAME,NAME"`),chart 同时写引擎 env,之前在 Deployment 上手补的同名 env 可以去掉;
|
|
760
|
+
用静态清单的 —— 取消对应规则注释块的注释;自维护 chart / 手写 RBAC 的 —— 照随包 `deploy/facts/sandbox-rbac.json`(`when` 列 = 开关)补那一行规则。把 `templates/sandbox-rbac.yaml` 整份拷进别的 chart 的取用方,只需在自己的 values 里补这两个键(模板自带开关判官;键缺席渲染即拒)。
|
|
761
|
+
**升级前做**:两个旋钮都没设 ⇒ 零动作(升级后 Role 少了两条多余权限);设了的部署按上一条在升级前开好开关。语句与读法同部署前置文档(仓库 docs 目录下 DEPLOY-PREREQS)7.146.0 节。**回滚**:回到 7.145.x 即恢复无条件渲(零持久形变化)。
|
|
762
|
+
|
|
763
|
+
23. **引擎 7.63.0 → 7.64.0(`@sema-agent/core` 与 `@sema-agent/primitives` 同版精确钉):① 🔴 会话帧与会话盒按住客投 —— 升级前让旧副本排空会话盒,混版副本共一只信箱时旧副本领不动装着本版记录的盒、本版副本弃掉旧副本写下的记录;② 🔴 File 记忆店的「绑定之前」账本形退役 —— 先用上一版引擎开一次再升级;③ 共用一只记忆控制面的副本一起升级,隔离席文件名换形;④ 停驻行三处判坏(门 × 待决动作配对、`checkpointId` 空串、资源账非对象);⑤ 规则提议里无 kind 的批成员整批丢;⑥ 兑付腿的店故障只在店没变时可重试,规则导入的成员结局不知 ⇒ 不落定、同票重走;⑦ 一次性迁移(导入层根的全局放行退役)local 腿读得更全、坏桶点名跳过;⑧ 拒绝回显 `tool_end.gate.disposition.echoed` 上帧 · 扣信回执分 `held` / `held_by_policy` · 委派腿通告投树根 · 记忆通告改走首个请求;⑨ `DB_BACKEND=local`:删会话连文件历史的 v1 基线一起删,`overwrite-dst` 同步重推整段替换目的端文件历史(行为变更 + 硬破坏三条;wire:一帧键加性;升级前做见本条)**:
|
|
764
|
+
换钉:`@sema-agent/core` 7.63.0 → 7.64.0 精确,`@sema-agent/primitives` 随之 7.64.0。下列各项按「谁看得见」排。
|
|
765
|
+
① **住客地址(硬破坏)**:
|
|
766
|
+
旧形:引擎按会话 id 投帧与排空会话盒 —— 一只会话删了、同一个 id 又被登记(另一位属主或同一位),前任住客的后台工作此后送来的完成、停在会话盒里的信与回执,会进后任的模型。
|
|
767
|
+
新形:地址 =(会话 id,住客),住客 = 会话行上那一格化身(本服务三只会话店建行时各铸一只,删了重建换一只)。投给前任住客的帧与盒记录弃掉、ack 出盒,运维席一条
|
|
768
|
+
`delegation.delivery_discarded`(`detail { taskId, taskType, sessionId, path, addressed, current }`;不带正文、不带化身令牌;不上会话流);被弃的跨会话信给发信方一张 `refused` 回执。
|
|
769
|
+
会话盒的每条记录点名它给哪一位住客(随既有 `peer_meta` 列,零 DDL)。**升级时盒里还停着的、上一版引擎写下的记录不点名住客 ⇒ 升级后首次排空一律弃**(每条一则通告 + 给发信方 `refused` 回执)——
|
|
770
|
+
丢的是旧引擎停而未投的东西:未读的跨会话信、后台子代停驻的话。**混版**:本版写的记录带两只上一版验证器拒的键 ⇒ 滚动升级期 7.145.x 副本认领装着这种记录的盒失败
|
|
771
|
+
(运维日志 `mailbox_message_column_corrupt`),记录留在盒里,全部副本升到本版后照常排空,不丢;反方向不对称:本版副本排到 7.145.x 副本滚动期写下的记录(不点名住客)照样弃(同上通告 + 回执)
|
|
772
|
+
⇒ 全部副本同版之后再放新流量写信。
|
|
773
|
+
复活的后台代理树读不到树根住客 ⇒ 它升到树根的终态帧在树根有住客时被弃(`addressed: unknown`),子代自己会话上那一份保留;此前会进树根的下一轮。
|
|
774
|
+
同一属主删后用同一个 id 重登:删前化身的子代完成在进程内不再交进新化身(本节第 20 条「已知限制」与第 19 条 ⑥ 的那一半随之关掉;第 20 条那道执行起点门照常)。
|
|
775
|
+
② **File 记忆店账本(硬破坏)**:
|
|
776
|
+
旧形:还是「绑定之前」形(裸 id → rev 映射)的 `revs.json`,引擎读时升级。新形:只读带信封的那一形;裸映射与以它为快照的事务日志一律拒(无码 `ControlPlaneCorruptError`)。
|
|
777
|
+
本服务:`POST /v1/memory/export` / `POST /v1/memory/import` 遇它答 `500 internal.memory_control_plane_corrupt` + 引擎拒句;出处 / 整理 / 合规三口同码。7.145.x 上同一只店:出包答 409 `memory.export_incomplete`,入包与其余口照常服务、下一次无争用进入时就地升级账本。
|
|
778
|
+
受影响的是引擎 5.33.0 以来没开过的 File 记忆店。
|
|
779
|
+
③ **记忆控制面载体**:清标账的行改存正文摘要、正文另存为对象(行的下一次加锁写把旧行的正文挪出去)⇒ 7.145.x 副本读本版写过的清标账拒(`ControlPlaneCorruptError`,「row is malformed」)。
|
|
780
|
+
本服务的 `memory-origin` 口经引擎读,答的 `entryText` 与上一版逐字同。隔离席的文件名由 `<毫秒>-hold-<捕获名>` 改成 `<内容摘要前 16 位十六进制>-hold-<捕获名>`,行先写、字节后挪;
|
|
781
|
+
上一版留下的孤字节在升级后首次对账按内容摘要收养。另:引擎的副本控制面收养动词只复制并记回执、不删源(删源随引擎后续版本)。
|
|
782
|
+
④ **停驻行三处判坏**:门类与待决动作不是登记表配好的那一对(六对之外的 24 种)、`checkpointId` 是空串、资源账不是对象 ⇒ 收件箱 / 运维队列 / 任务视图上 `rowVerdict` `damaged`,
|
|
783
|
+
续跑 / 决断在认领前答 `409` + `reason: "requirements_damaged"`,行留 pending、字节不动。此前前一形有的能续:人批准了、行被消费、停着的工具没跑。本服务自己不写这种行;存量有没有,按下方普查数。
|
|
784
|
+
⑤ **规则提议**:批里没有 `kind` 的成员整只批进 `dropped`(`problem: "malformed"`,运维计数 `server.rule-offers.offer-dropped`),审批卡上少这一条提议;此前读作 `command`。
|
|
785
|
+
本服务数这种批的起服普查退役(它的 fail-open 计数 tag `server.approval-batch.kindless-row` 不再计)。
|
|
786
|
+
⑥ **兑付腿**(其中规则导入两口的落定律,取代第 19 条 ② 里 `indeterminate` 成员的读法,见下面「规则导入两只 redeem 口」一段):审批记录店在兑付里读 / 写失败,引擎答带码的拒(`store_read` / `store_write`,带 `committed`),此前抛。本服务读法一条:店故障且引擎说店没变(`committed: "no"`)⇒ 可重试的
|
|
787
|
+
`rule_store_error`,停驻迟到腿不缓存;`committed: "unknown"` 的店故障与其余拒同读 `redeem-refused`(回执缓存 —— 重试是一次新的兑付,那一次写若其实已落,重兑会把其间被撤掉的规则再落一次)。
|
|
788
|
+
批臂读在整只批上:每一员都是店没变的拒、其中有店故障,才重兑。相对 7.145.x:规则店写之前的读失败改为可重试;记 dot 的 CAS / dot 分配失败(落规则之前,引擎答 `unknown`)改为不重试。wire 零变化。
|
|
789
|
+
规则导入两只 redeem 口(`cc-import` / `local-import`):成员结局全部确定(`persisted` / `no-op` / `refused`)⇒ 落定 200;任一成员引擎答 `committed: "unknown"` ⇒ 不落定,放回认领、`503 state.rule_import_retry`,
|
|
790
|
+
同一张票重来即重走(同一条审批记录、记过的 dot;已落的读 `no-op`,其间撤掉的放行不再落,但那一员在重走的回执里仍读 `persisted`,以规则列表为准)。相对 7.145.x:那一形由 200 + 该成员 `indeterminate`(票用掉)改为 503 同票重走。
|
|
791
|
+
⑦ **一次性迁移(7.61.0 之前导入的全局 `/x` 放行起服退役)的 local 腿**:读哪些桶 = 导入记录点名的属主 ∪ 引擎列桶口叫得出的属主(本机属主那只桶、收编标记点名的身份)—— 收编改名之后
|
|
792
|
+
没有导入记录点名的那只桶此前读不到(导入的全局放行照旧在每个项目根放行),本版读到、退役;引擎判坏的桶(`permission_rules.bucket_damaged`)点名跳过、不挡起服、字节不动;
|
|
793
|
+
一次读失败(`permission_rules.bucket_unreadable`,带 `errno`)照旧起服拒。叫不出属主的桶仍不读。
|
|
794
|
+
列桶口本身拒也起服拒:规则目录被引擎判为不可用(`permission_rules.bucket_damaged`)、列目录读失败(`permission_rules.bucket_unreadable`,带 `errno`)、收编标记读不出 —— 这三形没有「跳过这一只桶」可言,整次迁移不跑完。
|
|
795
|
+
规则目录在就列,没有导入记录也列(7.145.x 上没有导入记录时这一腿零读、不会因此拒);规则目录不在 ⇒ 零读。迁移窗到 2026-11-30,窗关之后的版本连这一腿一起删。
|
|
796
|
+
⑧ **加性与随版**:`tool_end.gate.disposition.echoed`(denied 臂可选,`[{ kind, value, canonical? }]`,只站在 `deniedBy` 为 `read_boundary` / `ask_resolution` 旁;缺席照旧画整句;读边界拒命中一行拒表时带上(被拒路径在前、那一行在后),`GET /v1/runs/:id/events` 回放同形 ——
|
|
797
|
+
把整只 `disposition` 逐字比成 `{ kind, deniedBy }` 的读者会多见这一键,改成按键读)·
|
|
798
|
+
扣信回执态多 `held_by_policy`(部署策略 / 收信方设置扣下:不问人、不跑到期)· 委派腿 gate 站的用户面通告投委派树根,来源腿在 `detail.sourceSessionId` / `agentId` ·
|
|
799
|
+
失败委派的工具结果 `isError` 为真 · 引擎铸的记忆通告从系统提示挪到腿的首个请求 · 压缩两座(第 15 条)· 会话级 `writeHome`(第 18 条)。
|
|
800
|
+
⑨ **`DB_BACKEND=local` 的文件历史**:引擎的 local 文件历史店带了整会话清理动词 ⇒ `DELETE /v1/sessions/:id` 连 v1 基线(原始文件字节)与只被这只会话引用的 blob 一起删
|
|
801
|
+
(此前 `reap`:边界删光、基线留到数据根被删为止,一条 `session_file_history_baselines_retained` warn —— 本版起 local 上不再出现);店故障 ⇒ 这一腿抛、会话行留着,重试收敛。
|
|
802
|
+
会话同步导入带 `resolution: "overwrite-dst"`、目的端已有不同的文件历史 ⇒ 擦掉目的端那一份、换成推来的那一份(此前 local 上 `422 conflict`);无同意照旧 `422`。
|
|
803
|
+
这订正 CHANGELOG 7.136.0 段「local identical 重推带不同文件历史」补披露条里「`overwrite-dst` 在 local 上也是 `422`、换不掉目的端的文件历史」两句(那一段原句不动)。
|
|
804
|
+
**谁需要**:所有部署(引擎随版换);删后同 id 重建会话的部署;导规则、走 local 一次性迁移的部署;按回显画拒绝的壳;`DB_BACKEND=local` 上删会话(删除权补齐)与带 `overwrite-dst` 重推的调用方。
|
|
805
|
+
**谁受伤**:① 升级时会话盒里还停着旧引擎写下、没投出去的信与子代话的部署;滚动升级期混版副本共一只信箱;复活的后台代理树(升到树根的终态帧被弃);
|
|
806
|
+
② 引擎 5.33.0 以来没开过的 File 记忆店;③ 共用一只记忆控制面、版本不同的副本;直读 `origin-clearances.json` 的脚本;按 `<毫秒>-hold-` 前缀列隔离目录的脚本;
|
|
807
|
+
④ 库里门 × 待决动作配错的停驻行(本版决不了);⑤ 卡上靠无 kind 批成员给出的规则提议;⑥ 停驻迟到腿上「记住规则」撞记 dot 的 CAS / dot 分配故障(本版不再重试);规则店持续写故障时的规则导入(票有效期内一直 503,过期 404);⑨ 在 local 上带 `overwrite-dst` 重推、以为换不掉目的端文件历史的调用方(同意即替换;替换是先擦目的端、再导入推来的那一份 —— 擦了之后再导入失败〔如推送途中坏了的 blob〕⇒ 目的端原来的文件历史已经没了、目标留空,重传那枚 blob 再推一次即落到空目标上)。
|
|
808
|
+
**补偿**:① 运维通告逐条可查(`delegation.delivery_discarded`,发信方另有 `refused` 回执);混版窗里旧副本领不动的盒不丢,旧副本滚动期写的记录本版副本照样弃 ⇒ 全部副本同版后再放新流量写信;② 先用 7.145.x(引擎 7.63.0)开一次那只店;③ 一起升;清标账改经 `GET /v1/memory/origin/clearances` 读;脚本改认新席名;
|
|
809
|
+
④ 在停驻它的版本上决完,或 expire 后重跑;⑤ 重新提议;⑥ 同命令再触发一次取新卡;导入按 `retryAfterSec` 同票重来,票过期后重新导入(成员级幂等)。
|
|
810
|
+
**升级前做**:① 让 7.145.x 副本把会话盒排空(会话都跑完一轮、没有未读的跨会话信),再整体换版;多副本部署全部副本同版之后再放新流量写信;
|
|
811
|
+
② File 记忆店(`MEMORY_ENGINE_BACKEND=file`,缺省)先用 7.145.x 开一次;③ 共用一只记忆控制面的副本同时升;
|
|
812
|
+
④ 数一数门 × 待决动作配错的待决停驻行(只读;六对 = `human`/`irreversible_ask` ↔ `tool_approval`、`resource_limit` ↔ `resource_limit`、`needs_review` ↔ `review`、`plan_review` ↔ `plan_review`、`task_done` ↔ `task_done`,其余皆错):
|
|
813
|
+
MySQL 协议 `SELECT JSON_UNQUOTE(JSON_EXTRACT(checkpoint, '$.gate.kind')) AS g, JSON_UNQUOTE(JSON_EXTRACT(checkpoint, '$.pendingAction.kind')) AS p, COUNT(*) AS n FROM checkpoint WHERE status = 'pending' GROUP BY g, p;`
|
|
814
|
+
PostgreSQL `SELECT checkpoint->'gate'->>'kind' AS g, checkpoint->'pendingAction'->>'kind' AS p, COUNT(*) AS n FROM checkpoint WHERE status = 'pending' GROUP BY 1, 2;` —— 配错的行在 7.145.x 上决完或 expire。
|
|
815
|
+
**回滚**:回到 7.145.x ⇒ 本版写的会话盒记录旧副本认领失败(记录留着,回到本版可排);本版写过的清标账旧副本读不动;File 记忆店的账本两版都读得动(带信封的那一形);其余各项无持久面。
|
|
816
|
+
|
|
817
|
+
24. **不报主体的 service 凭据可声明为无身份调用方:新旋钮 `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT`(缺省 `true` = 授权判定不变;`false` ⇒ fleet 读面 / 运维聚合口 / 写档对它收窄)· `GET /health` 的 `auth` 加一键 · 运维口 401 operator 句改写(安全轴,opt-in;wire 加性 + 一句改写;零迁移;缺省部署零动作)**:
|
|
818
|
+
旧形:出示这台部署的 service token、不带主体头的请求恒代部署本人(fleet 调用方:舰队流 / 会话列表 / 发件链接 / 名册 / trace / 用量看全舰队,删除 / fork / 同步对任何会话照开,运维聚合口 `/metrics*` 与 `GET /v1/tasks/source-summary` 照放);部署没有座位改这一读法。
|
|
819
|
+
新形:env `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT`(词表布尔,缺省 `true`,词表外拒启;只有 env 一个座,起服读一次)。不设 / `true` ⇒ 与旧形逐字同的授权判定。`false` ⇒ 这一形的调用方是无身份调用方:
|
|
820
|
+
fleet 读面与删除 / fork / 同步 `401 auth.unauthorized`(identity 句)、运维聚合口 `401`(operator 句;`METRICS_TOKEN` / `TRACE_TOKEN` 照放)、舰队流多租户 `401 auth.principal_required` / 单用户落 `default` 那一族、无主的委派子代会话单用户形 `404`(多租形由会话读面的主体门先答 `401 auth.principal_required`,两形同);
|
|
821
|
+
带主体头的请求、建 run、run 面、只读凭据判据两形同读;起服一行 `service_token_posture { actsForDeployment: false }`。没配 service token 的部署上设 `false` 不改变任何东西。
|
|
822
|
+
缺省部署也看得见的两处:`GET /health` 的 `auth` 恒多一个布尔键 `serviceTokenActsForDeployment`(= 配了 service token ∧ 本位);运维口 401 operator 句的 service token 出路多了条件
|
|
823
|
+
「where this deployment lets its service token act for the deployment itself (GET /health reports it as auth.serviceTokenActsForDeployment; …)」(码、状态、体键不变)。
|
|
824
|
+
**谁需要**:单 service token + 多主体的网关部署(网关替每个用户写主体头),关掉「漏带头 = 看全部」。
|
|
825
|
+
**谁受伤**:开 `false` 的部署的裸 service token 运维脚本 / 面板(当天成片 `401`;会话列表 / 发件链接 / 名册与他人会话的写档没有全量替换凭据);按整只 `/health.auth` 对象逐键比的探针与金样(要补键);按 operator 句字面匹配的告警。
|
|
826
|
+
**补偿**:不设即旧判定;按端点换凭据(trace / 用量 / `source-summary` / 舰队流 → 只读 `TRACE_TOKEN`;`/metrics*` → 只读 `METRICS_TOKEN`;门后列表与写档 → 带具名主体头,只见那位主体的);设回 `true` 重启即复原;`/health.auth.serviceTokenActsForDeployment` 自报。
|
|
827
|
+
**升级前做**:缺省部署零动作(按整只 `auth` 对象比的探针补键、按句子匹配 operator 401 的告警改按 `errorCode` 判)。要开 `false` 的部署:先把全部副本升到本版再设(旧引擎不认这一键,照旧按「不带主体头 = 部署本人」答);
|
|
828
|
+
全部副本设同一个值(滚动重启完成之前有副本还按旧读法答,收窄不完整);开之前把运维脚本按上面的端点换凭据;开之后核起服行与 `/health.auth.serviceTokenActsForDeployment: false`。
|
|
829
|
+
它不解决「网关不可信」:持 service token 的一方在主体头里写谁就是谁 —— 鉴权桥不改这一点(桥只给带登录令牌的请求验身份,带 service token 的请求照旧信主体头);要防这一层,别把 service token 交给不可信的一方(不可信的调用方走鉴权桥的登录令牌),或开直连门(主体只认签名的 principal 令牌,自报的主体头不再是身份)。**回滚**:删掉这一行或设回 `true` 后重启;零持久面、零 DDL、零一次性迁移。
|
|
830
|
+
|
|
831
|
+
25. **🔴 自由文本脱敏:行首键形(YAML / INI / compose 的配置行 `password: <值>` / `PASSWORD = <值>`)是声明形的第四种 —— 值成记号;值是类型名(`str` / `string` / `SecretStr` …)时不是值(行为面;安全;脱敏产物变;部署零动作)**:
|
|
832
|
+
— **声明形的定义**(7.143.0 节第 41 条 ① 的「声明形」,本版起四种;已发节原文不动,定义以此为准):`password` / `secret` / `client_secret` 与复合名一族(`api_key` / `apikey` / `api-key` / `access_token` / `refresh_token` / `id_token` / `private_key` / `x-amz-signature` / `x-amz-security-token` / `x-amz-credential`)
|
|
833
|
+
在自由文本里是名字锚,当赋值写成 ① 名字带引号(`"password": …`)② 值带引号(`password: "…"`)③ 赋值符两侧零空白(`password=…` / `--password=…`)④ **行首键形**:
|
|
834
|
+
名字在行首(左边隔着行内空白,可夹 YAML 的 `- ` 列表项记号;JSON 串值的开头与 `\n` 转义同是行首)、名字不带引号、赋值符(`:` / `=`)**右边至少一个空白**(左边有没有空白不论),
|
|
835
|
+
且不带引号的值是**那一行余下的全部** —— 之后只许行尾,或一段 ` #` 行尾注释(`password: changeme # default` 遮 `changeme`)。值以字母数字起头时遮(`$VAR` / `${VAR}` / `<占位>` / 表达式 / `None` / `true` 不算值)。
|
|
836
|
+
④ 上值整段是类型名(`str` / `string` / `bytes` / `int` / `integer` / `float` / `number` / `bool` / `boolean` / `any` / `object` / `array` / `SecretStr`,ASCII 大小写不敏感)时不是值 ——
|
|
837
|
+
行首的类型注解(` password: str` / `password: string` / `api_key: SecretStr`)逐字留;①②③ 上类型名照旧是字面量(`password=string` 遮)。
|
|
838
|
+
— **不变**:行中的散文形赋值(`set the password: x` / `… password = x`)、值之后行上还有东西的行(`password: str = ""` / `Password: must be at least 8 characters` / ` password: pw,`)不是声明形;
|
|
839
|
+
`token` 只在赋值那一半的零空白形上是锚(行首的 `token: …` 照旧是常用词);`passwd` / `pwd` 任何形都是锚;JSON 字段与 URL 参数位的读法不变。
|
|
840
|
+
— **仍不遮**:复合名(compose 的 `POSTGRES_PASSWORD: <值>`;名字按整名认)、点分键(`spring.datasource.password = <值>`;零空白的 `spring.datasource.password=<值>` 照旧遮)、
|
|
841
|
+
值尾还剩剥掉的句读(`password: hunter2.`)、值在下一行(`password:` + 换行 + 缩进值)。要靠脱敏挡住的凭据别以这几形写出。
|
|
842
|
+
— **流式与有界行**:活流逐块帧与出口座的有界行读的是 head 读法 —— 值之后的行尾在这一段之外时,从值起点遮到段尾(判定未决),等行尾到了再交出;逐块拼接仍 = 段末帧。
|
|
843
|
+
**谁需要**:agent 读 compose / `application.yml` / `.ini` 进工具输出、转录与同步体的部署 —— 配置行里的口令 / 密钥值此前在这些出口上原样。
|
|
844
|
+
**谁受伤**:① 文书 / 回复里行首的配置示例值换成记号:占位词(`password: xxx`)、独占一行的标签行(`Password: required`);② 代码答复里对象字面末项不带逗号时的变量名(` password: pw`)、
|
|
845
|
+
行首的代码赋值(`password = user_input`)、类型名表之外的类型写法(GraphQL `password: String!`)换成记号;③ 带这一形的多行命令不再给常驻放行(每次问人);④ 脱敏计数上升
|
|
846
|
+
(`redactions_applied_total{pattern="redacted",arm="full"}`,与 `password=` 一族同一格)。
|
|
847
|
+
**补偿**:名字或值带引号照旧是声明形;要原样显示示例的文书写 `password: <your-password>` 或 `password: "${VAR}"`;类型名不遮;无开关(凭据轴只收紧)。
|
|
848
|
+
**升级前做**:无。**回滚**:回到 7.145.x ⇒ 行首键形回到明文(只有 ①②③ 三种声明形);无持久数据。
|
|
849
|
+
|
|
850
|
+
26. **引擎交接车道:壳退出三选一里的「Move to background and exit」—— 新口 `POST /v1/engine/handover` / `POST /v1/engine/attach`、能力位 `engine.handover`、新旋钮 `ENGINE_HANDOVER_LINGER_MS`(缺省 30 min);`/health.engineLease` 加性多 `lane` 与 `handover`;`<数据根>/exit-last.json` 用格式 3(`lane` 取代上一版的 `orphan`;第 1 条的首附着窗到期同由 `lane` 说)(新面 + wire 加性;留痕文件与日志键 BREAKING;部署零动作)**:
|
|
851
|
+
旧形:壳退出只能停引擎(后台 shell 一起被收掉)或丢下引擎;丢下的引擎按 `ENGINE_LINGER_MS` 自退,后台 shell 不算工作;SIGHUP 空闲窗(`SIGHUP_IDLE_GRACE_MS`)另按自己的判据走硬停,不写留痕。
|
|
852
|
+
新形:附着租约四条车道,一只派生函数(从上到下第一条成立者)—— `handover`(调过交接口、之后还没有壳 attach)> `orphan`(父已不在)> `awaitingFirstAttach`(还没有过非探针请求)> `owned`。
|
|
853
|
+
`handover` 的窗 = `ENGINE_HANDOVER_LINGER_MS`,且引擎此刻一退就会被退出边界硬收的后台 shell(在跑、整张进程级注册表、不含 retain 行)在这条车道里算工作;别的车道窗与判据逐字照旧。SIGHUP 空闲窗读同一只工作谓词,`handover` 车道里它不计时(寿命只归租约腿)。
|
|
854
|
+
这只数不是 `/health.inflightBreakdown.sessionResident`(那是总数里经过提交的会话的会话驻留行;交接数还含 run 腿上的行与没经过提交的会话的行,读得出时 ≥ 驻留项);读不出 ⇒ 按 1 计、一行 `warn` `engine_handover_shell_count_unreadable`。
|
|
855
|
+
`POST /v1/engine/handover` 体恰为 `{ "reason": "background_exit" }` ⇒ 200 `{ lane: "handover", since, lingerMs, backgroundShells }`(幂等);`POST /v1/engine/attach` 体 `{}` 或空 ⇒ 200 `{ lane, handedOverForMs? }`(清交接位)。
|
|
856
|
+
不可用 ⇒ 501 `capability.engine_handover_unavailable`(租约腿没装 / `REQUIRE_PRINCIPAL=true` / 停机中);体不合形 ⇒ 400 `request.field_invalid`。`GET /v1/capabilities` 的 `engine.handover` 与两口读同一只事实。
|
|
857
|
+
`GET /health` 的 `engineLease` 多 `lane`(四词闭集,`engineLease` 在场即在场)与 `handover { since, reason, lingerMs, backgroundShells }`(只在 `handover` 车道在场);`engineLease.lingerMs` 的最短窗把交接窗算进去(缺省 30 min,默认读数不变)。
|
|
858
|
+
日志:新 `engine_lane_changed { from, to, reason, since }`(`reason` ∈ `handover_requested` · `attached`)与 `engine_handover_shell_count_unreadable`;`engine_lease_armed` 多 `handoverLingerMs`;`engine_lease_auto_exit` 多 `lane`、少 `orphan`;`sighup_idle_watch_armed` 的字段改为 `{ work, idleGraceMs }`。
|
|
859
|
+
`exit-last.json` 格式 3 取代上一版的格式 1(没有 `format` 键的形):必填 `lane`,不写 `orphan`(上一版的键)—— `orphan:true` ⟺ `lane:"orphan"`,候首触窗到期(第 1 条)⟺ `lane:"awaitingFirstAttach"`(没有单独的布尔键;格式 2 从没随任何已发版本发出);格式号不符的文件 ⇒ 第 1 条的 `warn` `exit_last_stale_format` 后删掉(只丢那一次自退的留痕)。
|
|
860
|
+
**谁需要**:cli 壳的退出三选一 —— 交接后壳自己退出,后台 shell 跑完再按交接窗收;下一只壳 attach 即回到原车道。
|
|
861
|
+
**谁受伤**:交接之后引擎多活到后台 shell 跑完再加交接窗,期间占着端口、数据根锁与库连接(不复用它、自己再起一只引擎的壳撞数据根锁;一只永不退出的后台 shell 让它一直活着);按旧键名读 `exit-last.json` / `engine_lease_auto_exit` / `sighup_idle_watch_armed` 的脚本;交接之后终端关掉(SIGHUP)不再关引擎。
|
|
862
|
+
**补偿**:`ENGINE_HANDOVER_LINGER_MS` 调短(下界 60 s,上界 24 h,坏值拒启、解析无条件);壳选「Exit and stop tasks」照旧停引擎;运维随时 SIGTERM;交接态在 `/health.engineLease.handover` 与 `engine_lane_changed` 里可读;旧键名一一对应到 `lane` / `work`。
|
|
863
|
+
**升级前做**:按旧键名读 `exit-last.json` / 上述两条日志的脚本改读新键。**回滚**:回到上一版即恢复旧形;本版写的 `exit-last.json`(格式 3,没有 `orphan`)上一版读不成 —— 不报 `exit_last_found`,文件留在盘上直到下一次自退覆盖它(只少那一次留痕,不挡启动)。
|
|
864
|
+
|
|
865
|
+
27. **一次性迁移 M6–M8 退役:启动期迁移连同各自的读侧半场与记号写点删码;M7 的拒臂留为按写者版本的永久门(持久数据面;行为变更;运维日志形变更;随包排空判据少一条;嵌入方 BREAKING,类型面)**:
|
|
866
|
+
7.116.0 / 7.117.0 引入的三条一次性迁移,窗(发布日 + 30 天)于 2026-11-04 / 11-05 关,本版删了它们的码。M9–M12 的窗 2026-11-06 … 11-08 关,本版不动,随后续版本窗关即删。逐条删了什么、删后存量形由谁接住:
|
|
867
|
+
- **M6**(7.116.0,run 死亡判决机读码回填):起服给只有句子、码列为空的 `failed` 行补 `run.stalled` / `run.orphaned`,连同 SQL 读面把这种行读成码的半场与 local 腿的写回。
|
|
868
|
+
删后这种行(只有 ≤ 7.115.x 的写者铸得出)`GET /v1/runs/:id` 的 `errorCode` 缺席、只剩 `error` 句子,不再被判成持有者死亡(那条 run 上丢掉的 steer 不再告知)。没有响亮臂。
|
|
869
|
+
- **M7**(7.117.0,停驻行 allow 读法记号的拒臂):删的是记号 `permissionsAllowReading` 的写点、「按记号判」的读法与随包排空判据 `permissions-allow-list`(两份 SQL 的那一段与 `drain-check-local.mjs` 的那一条)。
|
|
870
|
+
拒臂本身留为**按写者版本的永久门**:续跑重放之前,体里带非空 `settings.permissions.allow` 而续跑上下文的写者版本证不出 ≥ 7.117.0(缺席 / 读不出 / 更早 —— 7.123.x 及更早的写者都不记写者版本)⇒
|
|
871
|
+
409 `checkpoint.unsupported_version`(一句拒句;有写者版本时带 `writerVersion` / `readerVersion`),行字节不动、卡仍 pending;出路 = 作为新任务重提,仍停驻的先取消(`POST /v1/runs/:id/cancel`)。
|
|
872
|
+
这一门不随窗走:日历窗关不证明旧行不在(留存拉长、备份恢复、调长了 `APPROVAL_TERMINAL_BACKSTOP_MS`)。它只认写者版本一个证据 ⇒ 7.117.0–7.123.x 写下、带非空 allow 的行(有当年的记号、没有写者版本;7.145.x 按记号照续)本版同样拒。
|
|
873
|
+
- **M8**(7.117.0,停驻行披露位换名):SQL 起服把 `risk_descriptor` 里的旧键 `shadowedRule` 改写成 `allowRuleShadowed`。删后没经过它的停驻行留旧键:运维待批队列上只缺结构化披露,旧键的文本照样脱敏显示。没有响亮臂。
|
|
874
|
+
- **运维日志**:起服行 `one_time_migrations_applied` 去掉三个读数字段 `holderDeathCodeRowsBackfilled` / `allowRuleShadowRowsMigrated` / `allowRuleShadowRowsUnreadable`(`removableAfter` 读数的三个键随登记行消失,`note` 不再叙述它们);存量体重放拒的三只日志行(`resume_refused_stored_body` / `steer_wake_park_refused_stored_body` / `deny_sweep_stored_body_skipped`)上 `kind: allow_list_reading` 那一形照旧出,字段 `era` 换成 `writerVersion`(有才在)。按这些字段做告警或看板的规则要改。
|
|
875
|
+
- **随包排空判据**:两份 SQL 与 `drain-check-local.mjs` 去掉 `permissions-allow-list`(local 脚本的判据表少一条)。要在 7.115.0 / 7.117.0 / 7.118.0 那几条版本边界上数,用 7.118.0–7.145.x 任一版包里的同名判据。
|
|
876
|
+
- **嵌入方(类型面)BREAKING**:`StoreBackend.runOneTimeMigrations()` 的返回型 `OneTimeMigrationReport`(经包根导出的 `StoreBackend` 可达)去掉三个读数键(`holderDeathCodeRowsBackfilled` / `allowRuleShadowRowsMigrated` / `allowRuleShadowRowsUnreadable`);读它们的代码、把值标成 `OneTimeMigrationReport` 再写这些键的对象字面量 tsc 红;
|
|
877
|
+
自实现该方法、未标注类型就直接返回含这些键的字面量的代码 tsc 不报(多出的键没有人读),也请一并删掉。
|
|
878
|
+
- **谁需要**:所有部署 —— 删码让起服少走几步、排空判据少一条;续跑判据的 allow 读法问改按写者版本判、不再读记号(本版删 M6 / M7 / M8)。
|
|
879
|
+
- **谁受伤**:① **跳版升级**:从 ≤ 7.116.x 直接跳到本版、中间没在 7.117.0–7.145.x 任一版起过服的 SQL 库 —— 写库的两条(M6 / M8)没跑过,存量形照上面各条落地;
|
|
880
|
+
② **滚动升级窗**:7.117.0–7.145.x 的副本只写当前形(码列、新键),窗里不长新的旧形行;混跑更早的副本时它们写下的旧形行同样照上面各条落地;
|
|
881
|
+
③ **7.117.0–7.123.x 停驻、体里带非空 allow 的待批卡**:本版答 409(上面 M7 一条),7.145.x 上它们照续;部署若在 7.124.0 发布(2026-10-11)前后就已升离那几版,缺省兜底窗下这批卡在 2026-11-10 之前已被收割;从 7.117.0–7.123.x **直跳**本版的部署不在此列 —— 那批卡停驻得多新就活多久,与日期无关;
|
|
882
|
+
④ **反向(回滚 / 混跑里的 7.145.x 副本)**:本版写下的续跑上下文不再带记号 ⇒ 7.145.x 及以前的副本读到**任何**体里带非空 allow 的本版停驻行(壳从 CC settings 透传的 `settings.permissions.allow` 常带它;leader 子代行体里没有 `settings`,不在其内)时,
|
|
883
|
+
照它自己的问答 409 `checkpoint.unsupported_version`(带 `writerVersion` 7.146.0 / `readerVersion`;响亮,卡仍 pending)—— 回滚面比「plan_review 写回的行」大得多,回滚预案按「带 allow 的本版停驻卡全数」估。
|
|
884
|
+
- **补偿 / 做法**:跳版升级的库,**先在 7.117.0–7.145.x 任一版上对这只库起服一次**(那几版的起服迁移把写库的两条跑完),再升本版;M6 / M8 的存量形只少一格结构化信息,不必动。命中 ③ 的卡,升级前在部署当前跑的版本上决掉或取消(经过 7.145.x 的部署在 7.145.x 上;从 7.117.0–7.123.x 直跳的部署就在那一版上)(旧包判据 `permissions-allow-list` 数不到它们 —— 它按读法记号判,而这批行带着当年的记号;数法 = 仍 pending、续跑上下文没有 `writerVersion`(7.124.0 之前写下)而提交体 `settings.permissions.allow` 是非空数组的行,宽一点的近似 = 部署换到 7.124.0 之前就已停驻、仍 pending 的卡)。回滚到 7.145.x 时,本版停驻、命中 ④ 的卡由本版副本续跑,或回滚前结清。**升级前做**:按上面的跳版做法;常规从 7.145.x 升级、没有 ③ 那批卡的无须动作。
|
|
885
|
+
|
|
10
886
|
## 7.145.0 —— ① 🔴 `DB_BACKEND=local`:带戳存档上会话同步导入的第一阶段也答 `conflict.session_archive_stamped`(wire 加性:多一口答该码;行为修复;部署零动作) ② 运维审批队列的停驻行带它那只会话的 `agent`(委派子代在委派树里的位置;与会话视图同一只读口):后台委派子代停驻的那一行能连回发起委派的会话(wire 加性;行为修复;部署零动作) ③ 订正 7.144.0 节第 12 条「远端五车道不变」一句:k8s / local-docker / ssh / adb / e2b 上家目录主张证不了时,第一句拒是哪一形按命令形、执行面与会话分(文字订正;零行为变更) ④ 🔴 `DB_BACKEND=local`:委派子代转录的建行先记属主、再建存档,进程崩在两笔之间不再留下无主的子代转录(行为修复;持久面;部署零动作) ⑤ 🔴 规则导入:cc-import 兑付时成员表里有引擎拒的成员 ⇒ 落定 200 + 回执逐成员交出,不再 503 `state.rule_import_retry` 到票过期;cc-import 口的 200 体换成与 local-import 口同一张回执 `{ members, rev }`(wire BREAKING;行为修复;部署零动作) ⑥ 🔴 `CONFIG_PROVIDER=local`:配置根里的悬空符号链接(链接在、目标不在)不再读成「缺席」—— `config.d/remote-exec.json` 或 `config.d` 目录链接悬空 ⇒ 起服拒(此前无声落宿主车道),`config.d/<域>.json` 悬空 ⇒ 整份本地候选被判官拒、回落 env(此前读成域缺省);提货 settings-schema 17.0.0;更正 7.144.0 及更早(行为收紧,fail-closed;升级前先查链接) ⑦ 🔴 装着 prompt 屏(`prompt.submit` / `classic.UserPromptSubmit`)的腿:run 行预览、会话自动标题、fleet 行名只取引擎原样交付的目标,屏判完之前不落盘,续跑输入不存目标;屏改写 / 丢弃 / 抛错 ⇒ 这些面缺席(行为修复;机密;wire 值变化:预览可缺席;嵌入方类型面 BREAKING:`ServiceDeps.deploymentMods` 必填) ⑧ 停驻行一行坏字节只坏它自己那一行:SQL 后端的收件箱照列它、带 `rowVerdict`,收件箱与任务视图不再整张 500 / 503;`DB_BACKEND=local` 上别的卡的决断不再被一张坏卡拖成 500,local 的列表面候引擎(行为修复;wire 加性;部署零动作;更正 7.144.0 节第 5 条两句) ⑨ `DB_BACKEND=local`:审批账本里任何真删了行的调用(留存清扫的两只动词与 `deleteByTask`)的那一拍,问账日志 `approval-asks/asks.jsonl` 同拍整本重写成存活行的快照 —— 被删的问的字节(含工具实参字面)当拍离开活文件;订正 7.133.0 节第 14 条 local 一句(行为修复;持久面;部署零动作)
|
|
11
887
|
|
|
12
888
|
1. **🔴 `DB_BACKEND=local`:仍带属主戳的存档上,会话同步导入的第一阶段(`POST /v1/sessions/:id/sync/import`)按 id 分类出 fork / stale 且没带同意时,直接答 409 `conflict.session_archive_stamped` + 带出路句,不再先答通用的 `conflict`(wire 加性:这一口多答一个已在册的码;行为修复;部署零动作)**:
|