@sema-agent/server 7.138.0 → 7.140.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 +457 -7
- package/README.md +7 -4
- package/README.zh-CN.md +6 -4
- package/USAGE.md +91 -41
- package/deploy/sema-up/README.md +1 -1
- package/deploy/sema-up/lib/lanes.json +3 -2
- package/dist/adoption/runner.js +1 -1
- package/dist/adoption/sql.js +1 -1
- package/dist/adoption/wire.d.ts +3 -3
- package/dist/approval-card.d.ts +26 -26
- package/dist/bench/s1/arms.d.ts +1 -1
- package/dist/bench/s1/arms.js +1 -3
- package/dist/bench/s1/live-deps.js +3 -2
- package/dist/bench/s1/row.d.ts +5 -2
- package/dist/bench/s1/row.js +2 -22
- package/dist/bench/s1/run-firm.js +2 -2
- package/dist/boot/adoption.js +1 -1
- package/dist/boot/device-lane.d.ts +8 -3
- package/dist/boot/device-lane.js +7 -2
- package/dist/boot/execution-env.d.ts +4 -2
- package/dist/boot/execution-env.js +28 -34
- package/dist/boot/execution-lane.d.ts +9 -1
- package/dist/boot/execution-lane.js +6 -1
- package/dist/boot/governance-seams.d.ts +3 -2
- package/dist/boot/governance-seams.js +9 -11
- package/dist/boot/memory-boundary.d.ts +14 -51
- package/dist/boot/memory-boundary.js +10 -20
- package/dist/boot/memory-consolidation.d.ts +15 -11
- package/dist/boot/memory-consolidation.js +25 -14
- package/dist/boot/resolve-spec.d.ts +4 -6
- package/dist/boot/resolve-spec.js +10 -13
- package/dist/boot/retention-lane.d.ts +5 -5
- package/dist/boot/retention-lane.js +0 -6
- package/dist/boot/runner-deps.d.ts +6 -4
- package/dist/boot/runner-deps.js +3 -1
- package/dist/boot/session-faces.d.ts +0 -3
- package/dist/boot/session-faces.js +15 -8
- package/dist/boot/stage-02-web-admin-pull.js +2 -2
- package/dist/boot/stage-03-store-backend.d.ts +2 -6
- package/dist/boot/stage-03-store-backend.js +2 -3
- package/dist/boot/stage-04-stores.d.ts +2 -6
- package/dist/boot/stage-04-stores.js +5 -5
- package/dist/boot/stage-05-execution-env.d.ts +2 -6
- package/dist/boot/stage-05-execution-env.js +2 -2
- package/dist/boot/stage-06-runners.d.ts +2 -6
- package/dist/boot/stage-06-runners.js +2 -3
- package/dist/boot/stage-07-capability-layer.d.ts +2 -6
- package/dist/boot/stage-08-reapers.d.ts +2 -6
- package/dist/boot/stage-09-leader.d.ts +2 -6
- package/dist/boot/stage-09-leader.js +1 -2
- package/dist/boot/stage-10-http-server.d.ts +2 -6
- package/dist/boot/stage-10-http-server.js +7 -6
- package/dist/boot/stores.d.ts +3 -6
- package/dist/boot/stores.js +27 -40
- package/dist/boot/task-list-lane.d.ts +1 -1
- package/dist/boot/task-list-lane.js +1 -1
- package/dist/boot/web-admin.js +37 -11
- package/dist/capabilities/execution-lane.d.ts +2 -2
- package/dist/capabilities/mcp-probe.js +1 -1
- package/dist/capabilities/scenarios.d.ts +1 -1
- package/dist/capability-facts.d.ts +15 -7
- package/dist/capability-facts.js +8 -3
- package/dist/config-catalog.js +9 -8
- package/dist/config-invariants.d.ts +23 -3
- package/dist/config-invariants.js +42 -0
- package/dist/config-provider.d.ts +33 -37
- package/dist/config-provider.js +51 -30
- package/dist/config-types.d.ts +21 -7
- package/dist/config.d.ts +33 -0
- package/dist/config.js +46 -16
- package/dist/delegated-session-owner.d.ts +4 -3
- package/dist/delegated-session-owner.js +1 -1
- package/dist/deployment-shape.d.ts +10 -9
- package/dist/deployment-shape.js +4 -4
- package/dist/device-enrollment.d.ts +41 -2
- package/dist/device-enrollment.js +27 -12
- package/dist/device-store.d.ts +58 -85
- package/dist/device-store.js +19 -49
- package/dist/device-ws-hub.js +2 -1
- package/dist/env-name-allowlist-knobs.d.ts +5 -4
- package/dist/exec-cut.d.ts +60 -0
- package/dist/exec-cut.js +36 -0
- package/dist/execution-lane-caps.d.ts +115 -105
- package/dist/execution-lane-caps.js +76 -82
- package/dist/execution-placement.d.ts +259 -0
- package/dist/execution-placement.js +199 -0
- package/dist/field-conflict.d.ts +3 -2
- package/dist/field-conflict.js +1 -0
- package/dist/hosted-posture.d.ts +2 -2
- package/dist/http/admission.js +8 -19
- package/dist/http/checkpoint-ctx.d.ts +21 -12
- package/dist/http/checkpoint-ctx.js +4 -2
- package/dist/http/claimed-run.d.ts +1 -1
- package/dist/http/durable-run-leg.js +9 -5
- package/dist/http/execution-context.d.ts +218 -0
- package/dist/http/execution-context.js +330 -0
- package/dist/http/memory-compliance-failure-reply.d.ts +3 -1
- package/dist/http/memory-compliance-failure-reply.js +5 -0
- package/dist/http/memory-layer-reply.d.ts +30 -0
- package/dist/http/memory-layer-reply.js +24 -0
- package/dist/http/resume-legs.js +63 -36
- package/dist/http/retired-service-deps.d.ts +1 -1
- package/dist/http/retired-service-deps.js +1 -1
- package/dist/http/route-ctx.d.ts +14 -8
- package/dist/http/routes/adoption.js +1 -1
- package/dist/http/routes/background.d.ts +29 -1
- package/dist/http/routes/background.js +29 -2
- package/dist/http/routes/devices.d.ts +13 -19
- package/dist/http/routes/devices.js +21 -26
- package/dist/http/routes/memory-bundle.js +3 -0
- package/dist/http/routes/memory-compliance.js +8 -1
- package/dist/http/routes/memory-consolidation.js +12 -1
- package/dist/http/routes/memory-origin.js +14 -2
- package/dist/http/routes/memory-policy.js +5 -0
- package/dist/http/routes/session-sync.js +110 -15
- package/dist/http/routes/sessions.d.ts +6 -0
- package/dist/http/routes/sessions.js +143 -22
- package/dist/http/routes/side-query.d.ts +12 -4
- package/dist/http/routes/side-query.js +4 -5
- package/dist/http/routes/tasks.js +41 -33
- package/dist/http/server.d.ts +40 -44
- package/dist/http/server.js +13 -2
- package/dist/http/session-inherit-env.d.ts +3 -4
- package/dist/http/session-inherit-env.js +1 -1
- package/dist/http/wire-types.d.ts +8 -12
- package/dist/identity-source.d.ts +1 -1
- package/dist/identity-source.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/lane-home-probe.d.ts +68 -42
- package/dist/lane-home-probe.js +53 -30
- package/dist/leader/wire.js +5 -4
- package/dist/memory-bundle-engine.d.ts +16 -9
- package/dist/memory-bundle-engine.js +29 -6
- package/dist/memory-operator-faces.d.ts +85 -30
- package/dist/memory-operator-faces.js +136 -30
- package/dist/memory-project-layer.d.ts +3 -21
- package/dist/memory-project-layer.js +11 -8
- package/dist/memory-scope-stores.d.ts +73 -0
- package/dist/memory-scope-stores.js +86 -0
- package/dist/memory-scope.d.ts +29 -5
- package/dist/memory-scope.js +16 -4
- package/dist/memory-sync-client.d.ts +70 -18
- package/dist/memory-sync-client.js +215 -117
- package/dist/memory-sync.d.ts +1 -1
- package/dist/memory-sync.js +3 -2
- package/dist/observability/cost-taxonomy.d.ts +2 -2
- package/dist/observability/fail-open.d.ts +12 -0
- package/dist/observability/fail-open.js +12 -0
- package/dist/observability/run-terminal.js +0 -1
- package/dist/orchestration/workflow-notify-journal.js +4 -4
- package/dist/org-memory-admission.d.ts +4 -3
- package/dist/org-memory-admission.js +6 -6
- package/dist/parked-decide.d.ts +34 -9
- package/dist/parked-decide.js +12 -19
- package/dist/parked-revive-surface.d.ts +12 -15
- package/dist/parked-revive-surface.js +3 -6
- package/dist/peer-seat.d.ts +13 -7
- package/dist/peer-seat.js +37 -3
- package/dist/plugins/adoption-log-sql.js +4 -4
- package/dist/plugins/approval-ask-store-file.d.ts +7 -0
- package/dist/plugins/approval-ask-store-file.js +11 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +6 -0
- package/dist/plugins/approval-ask-store-memory.js +12 -0
- package/dist/plugins/approval-ask-store-sql.d.ts +22 -5
- package/dist/plugins/approval-ask-store-sql.js +44 -26
- package/dist/plugins/approval-nonce-store.js +4 -4
- package/dist/plugins/blob-backend.d.ts +4 -4
- package/dist/plugins/blob-backend.js +7 -7
- package/dist/plugins/breaker-state-sql.js +2 -2
- package/dist/plugins/caching-session-store.d.ts +6 -2
- package/dist/plugins/caching-session-store.js +9 -3
- package/dist/plugins/checkpoint-index-columns.js +2 -2
- package/dist/plugins/checkpoint-store-sql.d.ts +6 -5
- package/dist/plugins/checkpoint-store-sql.js +21 -23
- package/dist/plugins/device-store-sql.d.ts +25 -51
- package/dist/plugins/device-store-sql.js +68 -122
- package/dist/plugins/ensure-index.d.ts +1 -2
- package/dist/plugins/execution-placement-sql.d.ts +151 -0
- package/dist/plugins/execution-placement-sql.js +223 -0
- package/dist/plugins/file-history-store-sql.d.ts +9 -8
- package/dist/plugins/file-history-store-sql.js +9 -9
- package/dist/plugins/file-run-store.d.ts +6 -1
- package/dist/plugins/file-run-store.js +4 -0
- package/dist/plugins/fork-routing-session-store.d.ts +6 -0
- package/dist/plugins/fork-routing-session-store.js +16 -0
- package/dist/plugins/image-bake-store-sql.js +9 -9
- package/dist/plugins/image-index-sql.js +11 -11
- package/dist/plugins/leader-run-store-sql.js +4 -4
- package/dist/plugins/local-session-store.d.ts +149 -50
- package/dist/plugins/local-session-store.js +382 -107
- package/dist/plugins/mailbox-store-sql.d.ts +2 -1
- package/dist/plugins/mailbox-store-sql.js +4 -4
- package/dist/plugins/memory-engine-tidb.js +5 -5
- package/dist/plugins/memory-key-guards.d.ts +4 -0
- package/dist/plugins/memory-key-guards.js +1 -0
- package/dist/plugins/memory-optout-grant-store-sql.js +1 -1
- package/dist/plugins/memory-run-store.d.ts +1 -1
- package/dist/plugins/memory-sync-store-tidb.js +3 -3
- package/dist/plugins/one-time-migrations.d.ts +117 -8
- package/dist/plugins/one-time-migrations.js +408 -38
- package/dist/plugins/org-delivery-quota-store.js +2 -2
- package/dist/plugins/outcome-ledger-sql.d.ts +2 -2
- package/dist/plugins/outcome-ledger-sql.js +2 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +17 -19
- package/dist/plugins/permission-rule-store-sql.js +29 -32
- package/dist/plugins/pg-pool.d.ts +7 -3
- package/dist/plugins/pg-session-storage.d.ts +31 -20
- package/dist/plugins/pg-session-storage.js +120 -52
- package/dist/plugins/remote-env-adb.d.ts +18 -19
- package/dist/plugins/remote-env-adb.js +91 -66
- package/dist/plugins/remote-env-device.d.ts +23 -31
- package/dist/plugins/remote-env-device.js +19 -17
- package/dist/plugins/remote-env-e2b.d.ts +27 -21
- package/dist/plugins/remote-env-e2b.js +91 -45
- package/dist/plugins/remote-env-file-error.d.ts +3 -1
- package/dist/plugins/remote-env-file-error.js +9 -3
- package/dist/plugins/remote-env-host.d.ts +31 -34
- package/dist/plugins/remote-env-host.js +91 -72
- package/dist/plugins/remote-env-k8s.d.ts +13 -29
- package/dist/plugins/remote-env-k8s.js +63 -55
- package/dist/plugins/remote-env-local-docker.d.ts +24 -12
- package/dist/plugins/remote-env-local-docker.js +49 -61
- package/dist/plugins/remote-env-ssh.d.ts +11 -19
- package/dist/plugins/remote-env-ssh.js +74 -57
- package/dist/plugins/remote-shell.d.ts +100 -3
- package/dist/plugins/remote-shell.js +166 -2
- package/dist/plugins/resume-anchor-store-sql.js +2 -2
- package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
- package/dist/plugins/retention-lane-store-sql.js +2 -2
- package/dist/plugins/retention-store-sql.d.ts +10 -7
- package/dist/plugins/retention-store-sql.js +13 -7
- package/dist/plugins/run-store-sql.d.ts +13 -3
- package/dist/plugins/run-store-sql.js +20 -15
- package/dist/plugins/schema-consistency.d.ts +21 -11
- package/dist/plugins/schema-consistency.js +15 -9
- package/dist/plugins/schema-drift-sentence.d.ts +27 -0
- package/dist/plugins/schema-drift-sentence.js +38 -0
- package/dist/plugins/schema-ensure-legs.d.ts +2 -3
- package/dist/plugins/schema-ensure-legs.js +2 -2
- package/dist/plugins/schema-live-columns.d.ts +1 -1
- package/dist/plugins/session-capture-record-store-sql.js +1 -1
- package/dist/plugins/session-fork.d.ts +54 -0
- package/dist/plugins/session-fork.js +38 -1
- package/dist/plugins/session-row-sql.d.ts +22 -0
- package/dist/plugins/session-row-sql.js +81 -0
- package/dist/plugins/session-rules-column.d.ts +1 -1
- package/dist/plugins/session-rules-column.js +1 -1
- package/dist/plugins/session-store.d.ts +1 -1
- package/dist/plugins/session-workspace-cell.d.ts +1 -1
- package/dist/plugins/session-workspace-cell.js +1 -1
- package/dist/plugins/shared-memory-store-sql.js +2 -2
- package/dist/plugins/sql-driver.d.ts +10 -5
- package/dist/plugins/sql-driver.js +6 -6
- package/dist/plugins/sql-errors.js +1 -1
- package/dist/plugins/store-backend.d.ts +5 -7
- package/dist/plugins/store-backend.js +23 -11
- package/dist/plugins/store-contracts.d.ts +25 -5
- package/dist/plugins/task-list-store-sql.js +11 -11
- package/dist/plugins/tidb-pool.d.ts +12 -7
- package/dist/plugins/tidb-pool.js +13 -7
- package/dist/plugins/tidb-session-storage.js +4 -4
- package/dist/plugins/tidb-session-store.d.ts +57 -26
- package/dist/plugins/tidb-session-store.js +127 -59
- package/dist/plugins/tool-result-store-sql.d.ts +5 -4
- package/dist/plugins/tool-result-store-sql.js +21 -13
- package/dist/plugins/user-input-ledger-sql.js +2 -2
- package/dist/plugins/workflow-journal-store-sql.js +5 -5
- package/dist/plugins/workflow-run-store-sql.js +19 -19
- package/dist/plugins/write-behind-counter.d.ts +2 -3
- package/dist/plugins/write-behind-counter.js +5 -5
- package/dist/project-memory.d.ts +9 -15
- package/dist/project-memory.js +5 -4
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +6 -7
- package/dist/request-value-closure.js +1 -3
- package/dist/resource-suspend.d.ts +14 -12
- package/dist/resource-suspend.js +1 -1
- package/dist/resource-window.d.ts +4 -3
- package/dist/run-local.d.ts +6 -0
- package/dist/run-local.js +34 -35
- package/dist/runs.d.ts +10 -5
- package/dist/runs.js +52 -66
- package/dist/security.d.ts +38 -12
- package/dist/security.js +8 -2
- package/dist/server-secret-env.d.ts +9 -5
- package/dist/session-children-retire.d.ts +27 -9
- package/dist/session-children-retire.js +9 -5
- package/dist/session-incarnation.d.ts +20 -10
- package/dist/session-incarnation.js +5 -3
- package/dist/session-policy-wire.d.ts +1 -1
- package/dist/session-row.d.ts +114 -5
- package/dist/session-row.js +55 -5
- package/dist/session-titler.d.ts +2 -2
- package/dist/sql-engine-posture.d.ts +1 -1
- package/dist/sql-engine-posture.js +1 -1
- package/dist/{plugins → stores-sql}/background-agent-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/background-agent-store-sql.js +8 -8
- package/dist/{plugins → stores-sql}/session-policy-store-sql.d.ts +7 -5
- package/dist/{plugins → stores-sql}/session-policy-store-sql.js +12 -12
- package/dist/{plugins → stores-sql}/usage-window-store-sql.d.ts +1 -1
- package/dist/{plugins → stores-sql}/usage-window-store-sql.js +3 -3
- package/dist/task-a2a.d.ts +1 -1
- package/dist/task-a2a.js +5 -6
- package/dist/task-cwd.d.ts +6 -1
- package/dist/task-mcp.d.ts +22 -9
- package/dist/task-mcp.js +17 -9
- package/dist/terminal.d.ts +27 -0
- package/dist/terminal.js +6 -0
- package/dist/tool-approval.d.ts +6 -0
- package/dist/tool-approval.js +8 -1
- package/dist/trace/project.d.ts +1 -0
- package/dist/trace/project.js +1 -0
- package/dist/trace/redact.d.ts +3 -1
- package/dist/trace/redact.js +80 -28
- package/dist/trace/self-minted-wire.d.ts +169 -2
- package/dist/trace/self-minted-wire.js +54 -1
- package/dist/url-refusal.d.ts +1 -1
- package/dist/web-admin-client/apply-effective.d.ts +17 -3
- package/dist/web-admin-client/apply-effective.js +20 -10
- package/dist/web-admin-client/candidate-gate.d.ts +11 -7
- package/dist/web-admin-client/candidate-gate.js +1 -1
- package/dist/web-admin-client/http-client.d.ts +5 -4
- package/dist/web-admin-client/http-client.js +2 -2
- package/dist/web-admin-client/read-warnings.d.ts +7 -17
- package/dist/web-admin-client/read-warnings.js +5 -9
- package/dist/web-admin-client/skills-mcp.js +3 -2
- package/dist/web-admin-client/types.d.ts +6 -0
- package/package.json +3 -3
- package/wire-changes/server@7.139.0.json +348 -0
- package/wire-changes/server@7.140.0.json +184 -0
- package/dist/http/device-placement.d.ts +0 -175
- package/dist/http/device-placement.js +0 -145
package/MIGRATION.md
CHANGED
|
@@ -7,6 +7,450 @@
|
|
|
7
7
|
> ⚠️ 完整清单在仓库根 `CHANGELOG.md`——它**不随 npm tarball 出包**(本文件随包)。看完整迁移窗的
|
|
8
8
|
> 权威姿势是源码 tag diff:`git diff v<旧>..v<新>`(每版都推 `v<版本>` tag);npm 包页也镜像 CHANGELOG。
|
|
9
9
|
|
|
10
|
+
## 7.140.0 —— 依赖方向门(测试门;零 wire、零行为) · `CONFIG_PROVIDER=local`:`config.d` 里读不出的文档成被拒文档,候选整拒、拒句点名文件与形(行为变更;运维面) · 脱敏:PEM 私钥 armor 体里夹着由别的凭据装着的假收尾 ⇒ 整块照遮(安全) · SQL 方言字 `"tidb"` → `"mysql"`(嵌入方类型面 BREAKING;起服日志的后端字同换) · 🔴 记忆同步:同步层是个人平面键的 file 部署,这一层改同步会话读写的那只店,旧游标升级后被拒一次(删游标,不改绑) · 记忆同步层引擎读不出 ⇒ 起服拒(行为收紧) · `verify:true` 任务停在审批 / 计划审阅门上:run 行停驻、会话保持占用(行为变更) · 新旋钮 `READ_DENY_FLOOR_REQUIRED`(缺省 false;安全) · `REMOTE_EXEC=host` 不再被代声明「记忆能持久」(行为面) · `verify:true` 任务撞资源限停驻(行为变更) · 请求自带的 MCP / A2A 声明写着引擎永远不发的头 ⇒ 新提交 400(行为收紧) · 执行环境的家目录在每只环境开起来时被对证,对不上 ⇒ 那只环境拒起(六条车道;行为收紧;安全) · 记忆诸口答在请求点名的层住的那只店上:两店部署上条目 id / 店级账本的请求带层座 `scope`、落到个人店的抹除 `409 memory.erasure_store_unjudged`(行为变更;wire 加性;嵌入方 `ServiceDeps.sessionMemoryStatus` 改形,BREAKING 类型面) · 订正 7.138.0 节第 23 条 ⑩:扣留次序是先记后判(文字订正) · 契约包 settings-schema 15.2.0 · 引擎 7.60.0
|
|
11
|
+
|
|
12
|
+
1. **依赖方向门(测试门;零 wire、零行为;部署与嵌入方零动作)**:`src/` 读引擎(`@sema-agent/core`)的方式进了一道本仓的测试门 —— 说明符闭集、禁深路径与沿文件系统走引擎安装目录、
|
|
13
|
+
禁整模块绑定、读表里不得有引擎的 SQL 方言店类、方言店文件不得继承引擎的店基类、`src/stores-sql/**` 的目录级依赖。它只检查源码,不进运行时、不改任何 wire 与存储格式。
|
|
14
|
+
唯一碰到运行路径的一处是 S1 bench 行的 `meta.coreVersion`:改读引擎根导出 `CONTRACT_KIT_ENGINE_VERSION`,值与此前相同(装机引擎的版本)。
|
|
15
|
+
**谁受伤**:无。**出路 / 回滚**:无需。
|
|
16
|
+
2. **`CONFIG_PROVIDER=local`:`config.d` 里读不出的文档不再被读成那个域的缺省,而是一条被拒文档 —— 整份本地候选被拒,拒句点名文件与形(行为变更;运维面)**:
|
|
17
|
+
`config.d/<域>.json` 在场但空 / 纯空白(编辑器非原子保存留下的半写、截断)、坏 JSON,或解析出来不是 JSON 对象(`null` / 数组 / 数 / 串 / 布尔)。上一版两类各走一条路:
|
|
18
|
+
目录域(`models` / `skills` / `mcp` / `plugins` / `scenarios` / `collab` / `prompts`)先按那个域的缺省读成一份空目录 / 空注册表、再由候选判官整拒,
|
|
19
|
+
拒判的成因记成 `domain_invalid`、另出一行 `config_domain_invalid`;门控域(`rosters` / `governance` / `execution` / `limits`)整份读抛,
|
|
20
|
+
起服记 `config_source_unreachable_using_env`、刷新拍记 `web_admin_refresh_failed`、手动刷新口答 502,没有拒判行,看不出是哪一份坏了。
|
|
21
|
+
本版不分域同判(配置契约的文件层先于域解析):读腿把配置契约对这棵目录的拒单原样交成被拒文档,候选判官整拒,`config_candidate_rejected` 的 `errors[]` 每份一条
|
|
22
|
+
`{ domain, reason, error }` —— `domain` 是那份文档的名字,`reason` 是配置契约的闭集词:`empty`(空 / 纯空白)· `invalid_json`(坏 JSON)· `not_object`(`null` / 数组 / 标量)·
|
|
23
|
+
`io`(在场却读不出:权限等);`error` 是配置契约的拒句(点名文件的真实路径与形、给出路,不回显文件内容;`io` 是文件系统的原话,有的不带路径 —— 认是哪一份读 `domain`);
|
|
24
|
+
`GET /v1/models.candidateRejected.domains` 含那个域;起服不再出 `config_source_unreachable_using_env`,刷新拍跑完(手动刷新口 200);这一形不再出 `config_domain_invalid`
|
|
25
|
+
(那一行只留给读得出、判形失败的域)。几份同时读不出 ⇒ 每份一条,一次说全;带事实的 `runtime.json`(`reason: "retired_domain"`)与读不出的文档同在 ⇒ 同一行里都列出(`runtime` 在前)。
|
|
26
|
+
退役域文件 `config.d/runtime.json` 自己读不出 ⇒ 同样是一条被拒文档(`domain: "runtime"`);配置根本身是个普通文件 ⇒ 每份文档一条 `io`(文件系统原话 `ENOTDIR`)。
|
|
27
|
+
已知边:一份读不出的文档与一份嵌套深过 200 层的文档同在 ⇒ 仍整份读抛(与上一版同),先把那份过深的文档改浅。
|
|
28
|
+
另一条已知边:读腿的失败路径是两读(严读拒了才问整目录拒单),那份文件恰在两读之间被修好 ⇒ 这一拍照原样抛严读那一读的错
|
|
29
|
+
(走读失败那条臂:起服 `config_source_unreachable_using_env`、刷新拍 `web_admin_refresh_failed`),诊断说的是已经不在的坏形;下一拍重读即自愈。
|
|
30
|
+
被拒那一拍的版本号(拒判行的 `version`、世代账的 `configTargetVersion`)是配置契约按文档内容算的版本:同样的坏内容同一个号(同一份坏树不重响),内容一改就换号、拒判行再响一次(拒句没变也换),修好回到内容版本 —— 读不出的文档按去掉首尾空白的原文算(只差首尾空白不换号),带事实的 `runtime.json` 按读出来的值算(只改缩进 / 键序不换号)。
|
|
31
|
+
`config_local_no_models` 多一个键 `reason`(判官给 `models` 的成因词),hint 按它说「读不出(哪一形)」还是「判形失败」。
|
|
32
|
+
— **谁需要**:单机 / 本地配置的部署 —— 半写的 `config.d` 文件不会被读成一份空的模型目录或 MCP 注册表,门控域的半写也不再被报成「配置源不可达」,运维直接看到是哪一份文件、坏成什么形。
|
|
33
|
+
— **谁受伤**:按 `config_source_unreachable_using_env` / `web_admin_refresh_failed` 认「门控域文件坏了」,或按 `config_domain_invalid` / `reason: "domain_invalid"` 认「某个域文件读不出」的告警规则 ——
|
|
34
|
+
改认 `config_candidate_rejected` 里 `reason` 为 `empty` / `invalid_json` / `not_object` / `io` 的那几条。配置结局不变:候选整拒、一个域都不应用,起服回落 env(本地没有 LKG),刷新拍保持在用的配置。
|
|
35
|
+
配置根本身读不出(普通文件)上一版走「源不可达」,本版是一行逐份 `io` 的拒判(结局同:env / 保现用)。
|
|
36
|
+
— **补偿**:修好那份文件(写成合法的 JSON 对象),或删掉它(删掉 = 回到那个域的缺省);下一个刷新拍落地,不用重启(restart-to-apply 的面照旧要重启)。
|
|
37
|
+
3. **脱敏:PEM 私钥 armor 体里夹着一枚由别的凭据装着的假收尾栅栏 ⇒ 整块照遮(行为面,安全;7.138.0 披露过、7.139.0 未修也漏带披露的那一形)**:
|
|
38
|
+
上一版的脱敏在 armor 体里**最早**的一枚 `-----END … PRIVATE KEY-----` 处收口 —— 那一枚若装在 JSON 秘密字段的串值里(或体里一整只 SSH2 armor 里),
|
|
39
|
+
其后的私钥体以明文留在 trace / 运维日志行里。本版跳过装在别的凭据里的收尾,盖到真收尾;有界日志行的扫描窗里真收尾在窗外 ⇒ 从起始栅栏遮到窗尾。
|
|
40
|
+
体长上界(8192)改按单元量(一枚别的凭据算一格,与 SSH2 栅栏臂同一把尺)⇒ 体里装着别的凭据、按字符量超界而按单元量不超的块也整块一枚记号。
|
|
41
|
+
其余文本输出逐字节不变;体里一枚没有任何凭据装着的收尾串仍算收尾(与「真收尾之后跟一段文字」不可区分);文本里没有真收尾时的整段读法与上一版同。
|
|
42
|
+
— **谁需要**:把含私钥 armor 的文本交给脱敏面的部署。— **谁受伤**:无。— **补偿 / 回滚**:无需;回滚到上一版即回到那一形的明文残留。
|
|
43
|
+
|
|
44
|
+
4. **SQL 方言字 `"tidb"` → `"mysql"`(嵌入方类型面 BREAKING;零 wire、零表、零存储格式;部署配置零动作)**:语法族的字只剩 `"mysql" | "pg"`,与 `DB_BACKEND` / `StoreBackend.kind` 同字;`tidb` 只剩引擎名的意思(`SqlEngine`,驱动探到的引擎事实)。
|
|
45
|
+
**谁受伤**:① 读根导出 `createTaskListLane(...)` 返回值 `backend` 的嵌入方:`"tidb"` 改成 `"mysql"`(TypeScript 编译红即通知)。② 自建 `createHttpServer` 并自己给 `sqlEngine` 的嵌入方:`dialect` 只收 `"mysql" | "pg"`,
|
|
46
|
+
`"tidb"` ⇒ 起服拒(拒句点名形 `{ dialect: "mysql" | "pg", facts }`);用本服务自己的装配、或把驱动读口原样交进来的不受影响。③ 按起服日志 `*_store_enabled` 的 `backend: "tidb"`(或 `tidb+minio`)筛的运维查询:字改为 `mysql`(`mysql+minio`)。
|
|
47
|
+
不受影响:HTTP 客户端;`DB_BACKEND` / `SESSION_BACKEND` / `MEMORY_ENGINE_BACKEND` 的取值;数据库的表、列与行。会话策略 / 治理窗 / 后台子代三只方言店的源文件同时换了目录,包的导出表里没有这几条路径,包外本来就 import 不到,无需动作。
|
|
48
|
+
**出路**:换字。没有别名,没有兼容臂。**回滚**:回到上一版即可(没有数据迁移)。
|
|
49
|
+
5. **记忆同步的同步层是个人平面的键(`user:` / `userproj:` / `org:`;同步层 = `MEMORY_SYNC_SCOPE`,缺省 = `MEMORY_SCOPE`)的 file 记忆部署:这一层改为同步会话读写的那只店;它的旧游标升级后被拒一次,删掉它(行为变更;修复)**:
|
|
50
|
+
上一版同步执行器同步部署的店(`<引擎根>/memory`),会话的全局个人层却在个人挂载上的另一只店(`<引擎根>/personal/memory`):写进这一层的新记忆不推,拉下来的会话读不到。
|
|
51
|
+
本版这一层同步个人挂载那只店(由引擎的唯一读法答,与会话同一只);项目层(`userrepo:…`)、`proj:` 键与非类型化的同步层(含 `local`)不变 —— 同步层不是个人平面的键(例:`MEMORY_SCOPE=user:<P>` 而 `MEMORY_SYNC_SCOPE=local`)⇒ 本条与你无关。
|
|
52
|
+
— **升级后看**:第一轮这一层出一行 `memory_sync_layer_failed`(`scope` = 同步层,拒句 `cursor is for store "file:…/memory"; this round's store is "file:…/personal/memory"`),这一层零请求,别的层照跑,下一轮同样拒,直到处置。
|
|
53
|
+
这一层此前没同步过(没有游标文件)⇒ 不出这一行,第一轮直接同步。
|
|
54
|
+
— **处置(只这一条)**:删掉那只游标文件(路径 = 该行的 `cursorPath`),下一轮从空基线重收敛 —— 推个人店里会话写的、拉中心这一层有的、不推删除;两边都改过的条目按冲突上报。
|
|
55
|
+
**不要**按拒句的出路 (1) 改绑:旧游标的基线是部署店里那一层的条目,个人店里没有它们,改绑后的那一轮会把它们当成「本地已删」推成删除(中心与别的设备上的这些记忆随之被删)。
|
|
56
|
+
— **谁受伤**:升级前在这类部署上跑过同步的部署(这一层停同步,直到删掉那只游标)。部署店里那一层原有的条目(上一版拉下来的)留在原处、不再有读者(会话本来就不读它们);中心有的那些在重收敛时拉进个人店。
|
|
57
|
+
— **回滚**:回到 7.139.x 病照在(同步回到部署的店);这一层的新游标绑的是个人店,7.139.x 在店轴拒它一次,处置同上(删掉它)。
|
|
58
|
+
6. **记忆同步的同步层引擎读不出 ⇒ 起服拒(行为收紧)**:同步执行器在起服装配时就向引擎问同步层住哪只店,引擎读不出的键在那里被拒,码 `config.memory_scope_key`(引擎原句,`resolveMemoryScopeStore: …`),服务不起。
|
|
59
|
+
配置边界放行、引擎拒的形今天只有一种:全空白的 `MEMORY_SYNC_SCOPE`(类型化而读不出的键 `loadConfig` 已先拒)。
|
|
60
|
+
— **谁受伤**:`MEMORY_SYNC_SCOPE` 设成全空白的部署 —— 上一版起得来,每一轮同步被引擎拒,同步从未发生;本版起不来。
|
|
61
|
+
— **补偿**:把 `MEMORY_SYNC_SCOPE` 改成要同步的那一层(或删掉它,缺省 = 类型化的 `MEMORY_SCOPE`);不开同步就把 `MEMORY_SYNC_URL` 连同 `MEMORY_SYNC_SCOPE` / `MEMORY_SYNC_TOKEN` 一并撤掉(只撤 URL、留着 scope 或 token,起服仍拒:半配置)。
|
|
62
|
+
— **回滚**:回到 7.139.x 又起得来,同步照旧每一轮被拒。
|
|
63
|
+
7. **`verify:true` 的任务停在审批 / 计划审阅门上:run 行停驻、会话保持占用,不再立刻 `failed`(行为变更;wire 形不新)**:
|
|
64
|
+
开了耐久审批(`DURABLE_APPROVAL`)且有 run 店的部署上,`verify:true` 任务的实现腿(或某一轮修复)撞上要人批的工具 / 计划审阅门时 ——
|
|
65
|
+
上一版:`POST /v1/runs` 的行立刻 `failed` + `errorCode: "unexpected.suspended"`(计划审阅门 `unexpected.needs_review`)并释放会话;`POST /v1/tasks` 答 200 终局体
|
|
66
|
+
(`terminal.kind: "failed"` + `nestedPause`);卡却仍待决,批准之后工具照样执行,行停在 `failed`、决定体不带 `taskId`。
|
|
67
|
+
本版:行停在 `suspended`(计划审阅门 `needs_review` + `errorCode: "review.pending"`),`result.terminal.kind: "paused"`(带 `gate`、不带 `token`),会话保持占用;
|
|
68
|
+
`GET /v1/runs/:id/events` 的尾帧是 `suspended` / `needs_review` 而不是 `done`;`POST /v1/tasks` 答停驻回执 `{status: "suspended" | "needs_review", taskId, sessionId}`
|
|
69
|
+
(与非 verify 任务的同步停驻同一形;同 `Idempotency-Key` 重放答同一份);决这张卡(审批门 `POST /v1/approvals/:sessionId/decide`;计划审阅门 `POST /v1/assistant/tasks/:taskId/plan_review`)续回同一条行,审批的决定体带 `taskId`,行翻成终局;
|
|
70
|
+
取消停驻中的这条 run(`POST /v1/runs/:id/cancel`)⇒ 卡离开待决列表、行 `failed` + `errorCode: "cancelled"`、会话释放。
|
|
71
|
+
另:取消一条 `verify:true` / `cascade:true` 的后台 run,引擎交回无码失败时行带 `errorCode: "cancelled"`(上一版无码)。
|
|
72
|
+
— **谁需要**:用 `verify:true` 提交、实现腿会碰到要人批的工具的任务,以及决这些卡的运维 —— 批准之后 run 行如实翻转。
|
|
73
|
+
— **谁受伤**:把「verify + 审批 ⇒ 立刻 failed」当信号的调用方 —— 修后同一提交停驻等人,停驻期间同会话再提交 / `DELETE /v1/sessions/:id` / 换绑设备 / 会话同步都答 409
|
|
74
|
+
(与普通停驻同形),先决卡或取消;同步 verify 调用方的 200 体换成停驻回执,改按停驻回执处理(轮询 `GET /v1/runs/<taskId>`)。dry-run 审阅停驻没有决断端点,停驻到取消或过期。
|
|
75
|
+
— **补偿**:`APPROVAL_TIMEOUT_SEC`(> 0 时到时收回停驻)、checkpoint 绝对过期兜底(常开)、`POST /v1/runs/:id/cancel`、部署级 `DURABLE_APPROVAL=false`(没有耐久停驻)。
|
|
76
|
+
回滚:本版不写新列、不迁数据;回退之后,本版留下的 verify 停驻行仍由续跑腿的 verify 臂驱动(那条臂在上一版就处理认领在的 verify 停驻行;回退形上未实跑)。
|
|
77
|
+
— **已知限制**:`cascade:true` 任务的某一级停在审批上时照旧 —— 行 `failed` + `unexpected.suspended`、会话释放;那张卡在 `GET /v1/approvals` 里看得见但决不掉
|
|
78
|
+
(409 `conflict.resume_context_unavailable`),到期自动收回。引擎侧修好之前请别对 cascade 任务开耐久审批。
|
|
79
|
+
8. **读拒表的字节地板可以要求了:新旋钮 `READ_DENY_FLOOR_REQUIRED`(缺省 false;安全;行为面只在设 true 时变)**:读拒表有行(出厂读拒档 credentials / agent-config 在岗即有行)
|
|
80
|
+
而这条车道的执行环境不守字节地板(起服行 `remote_exec_enabled.keepsReadFloor=false`;七条车道今天都是)时 —— 设 true ⇒ 这类 run 在准备期拒,终局码 `config.read_deny_floor_unkept`,
|
|
81
|
+
一个命令都不起、零 token,同步提交答 409;起服多一行 warn `read_deny_floor_required_unkept { provider, note }` 点名车道与键。不设 / false ⇒ 与上一版相同:run 照跑,
|
|
82
|
+
每 run 恰一条运维通告同码(`engine_notice` 结构化日志,不上用户流)。坏词(`required` 之类)⇒ 起服拒,拒句点名键与词表。
|
|
83
|
+
自拼 `ServiceConfig` 的嵌入方:新增必填席 `readDenyFloorRequired: boolean`(`READ_DENY_FLOOR_REQUIRED` 的值,缺省 false),由 `loadConfig` 一次铸出。
|
|
84
|
+
— **谁需要**:要把「读拒表里的文件字节不进对话」当硬门的部署(合规 / 托管)。
|
|
85
|
+
— **谁受伤**:设了 true 的部署上带手的 run 一律拒起(七条车道都不守地板)—— 这是旋钮本身的意思,不是副作用;不设的部署零变化。
|
|
86
|
+
— **补偿**:不设 = 照跑并每 run 一条通告;要「既跑又守」等守地板的车道。
|
|
87
|
+
9. **执行环境能力只有一个作者 `capabilitiesFor(部署配置)`;`REMOTE_EXEC=host` 不再被代声明 `memoryPersistenceCapable: true`(行为面;部署零配置改动;嵌入方零动作)**:
|
|
88
|
+
① **host 车道的记忆披露**:装配层不再替 host 车道写 `memoryPersistenceCapable: true`,`MEMORY_PERSISTENCE_CAPABLE` 原样直通、缺席即缺席;起服 info 行
|
|
89
|
+
`memory_persistence_capable_auto_declared` 删除。引擎按执行环境块(host 车道 `hostLocalPaths: true`)照教写指令、按名册推断能不能存:名册里有本机可写工具的 run 与上一版相同;
|
|
90
|
+
名册写不了的 run(如 `AUTONOMY=read-only`)从此收到「本会话没有持久记忆」的只读披露(上一版被那只代声明压掉)。host 车道的起服记忆边界审计与上一版一样零行;
|
|
91
|
+
沙箱 / 远端车道的 `memory_remote_lane_write_instruction_dropped` 照出,句子不再说「引擎把它判成 remote」。
|
|
92
|
+
② **内部模块**(都不在包根出口,嵌入方零动作;改本仓源码的人看这里):`effectiveMemoryPersistenceCapable` 删除;车道能力表删七位
|
|
93
|
+
`isolation` / `suspendable` / `canonicalPathAuthority` / `hostFilePlane` / `coreRemoteExecutionEnv` / `sandboxPathAdjudication` / `memoryPersistenceCapable`
|
|
94
|
+
(改读 `capabilitiesFor(config)` 的块:`isolation` / `suspendable` / `canonicalPathAuthoritative` / `hostLocalPaths` / `io`;写门走不走代理 = `!hostLocalPaths`);
|
|
95
|
+
`MemoryWriteBoundaryFacts.coreRemoteExecutionEnv` 删除;部署形表 `lane` 轴的事实 `k8sSnapshotStore` 换成 `block`(执行环境块)。
|
|
96
|
+
wire 零变化(`executionLane` 的 `provider` / `toolsOnThisHost` / `isolated` 八词逐格同值)。
|
|
97
|
+
— **谁需要**:改车道能力的人(改一处,适配器、部署形、起服行、wire 同翻);host 部署上名册写不了的 run 不再被说成「能存」。
|
|
98
|
+
— **谁受伤**:靠那只代声明拿到「能存」口径的 host 部署(改为如实只读披露);按 `memory_persistence_capable_auto_declared` 认 host 记忆可写的运维告警。
|
|
99
|
+
— **补偿**:host 车道确实能存而名册推断不出的形,设 `MEMORY_PERSISTENCE_CAPABLE=on`。回滚到上一版即恢复代声明(零数据面)。
|
|
100
|
+
10. **`verify:true` 任务的实现腿 / 修复轮撞资源限(预算 / turns / 墙钟)时停驻,不再 `failed`(行为变更;wire 形不新;只在 `RESOURCE_SUSPEND` 开着、有 durable checkpoint 的部署上)**:
|
|
101
|
+
上一版:`RESOURCE_SUSPEND` 开着时,普通任务撞限落一张 `resource_limit` 停驻、可续;`verify:true` 任务被 opt-in 整只排除,撞同一个限 ⇒ `POST /v1/runs` 的行 `failed` +
|
|
102
|
+
`errorCode` 为 `limits.max_walltime_exceeded` / `limits.max_turns_exceeded` / `limits.max_cost_exceeded` / `limits.max_tokens_exceeded`,已做的工作作废;`POST /v1/tasks` 答 200 终局 `failed` 体。
|
|
103
|
+
本版:行停在 `suspended`(无失败码;`result.terminal.kind: "paused"`、`gate.kind: "resource_limit"`、不带 `token`),会话保持占用,(`POST /v1/runs` 提交的 run)`GET /v1/runs/:id/events` 的尾帧是 `suspended`;
|
|
104
|
+
`POST /v1/tasks` 答停驻回执 `{status: "suspended", taskId, sessionId}`(与普通任务的同步停驻同形);`POST /v1/assistant/tasks/:taskId/resume` 续回同一条行,续完仍过验证门。
|
|
105
|
+
不变的:`cascade:true` 任务不带 opt-in,撞限仍 `failed`;验证器自己那一腿(引擎另铸它的 spec,不带 opt-in)撞限仍失败;抢占(`POST /v1/assistant/tasks/:id/preempt`)对 verify 任务的首片仍答
|
|
106
|
+
「not preempt-eligible」的 no-op(续跑片接抢占信号);没开 `RESOURCE_SUSPEND` 的部署零变化。
|
|
107
|
+
另:跨片总额三旋钮(`RESOURCE_SUSPEND_TOTAL_TOKENS` / `_TOTAL_BUDGET_USD` / `_MAX_SLICES`)与 `RESOURCE_SUSPEND_TTL_SEC` 对 verify 任务和普通任务同一份供值;`GET /v1/runs/:id` 的 `crossSliceUsage`
|
|
108
|
+
因此也出现在配了总额的 verify run 上 —— verify 是只回结果的组合腿、没有逐 turn 落账的流,running 期的 `spentTokens` / `spentMicroUsd` 是上一次停驻时落下的量(首片为 0),别当「还没花钱」读;同步 `POST /v1/tasks` 提交的 run 提交腿不写这本账(与同步提交的普通任务同形),停驻前那一片永不进账。
|
|
109
|
+
嵌入方:`resourceSuspendOptIn` 的入参 `isVerify` 删除(`src/resource-suspend.ts`,不在包根出口;改本仓源码的人看这里)。
|
|
110
|
+
— **谁需要**:开了 `RESOURCE_SUSPEND` 和 durable checkpoint、用 `verify:true` 提交的任务可能撞预算 / turns / 墙钟的部署 —— 撞限不再丢掉整条已做的工作。
|
|
111
|
+
— **谁受伤**:把「verify 任务撞限 ⇒ `failed` + `limits.*`」当信号(重试 / 告警规则读上面四个码)的调用方 —— 修后同一提交停驻等续跑;同步 verify 调用方的 200 体换成停驻回执,改按回执轮询
|
|
112
|
+
`GET /v1/runs/<taskId>`;停驻期间同会话再提交 / `DELETE /v1/sessions/:id` / 换绑设备 / 会话同步都答 409(先续跑或取消);开着 resource-suspend 时这类任务的单片花费只在边界上判
|
|
113
|
+
(引擎的流中途 $ 投影取消一臂自动关,与普通任务同),单片最多多烧一个 turn。
|
|
114
|
+
— **补偿**:`RESOURCE_SUSPEND` 关掉即整个回到「撞限 `failed`」(部署级,含非 verify 任务);`RESOURCE_SUSPEND_TTL_SEC`(缺省 30 天)收回弃置的停驻;`RESOURCE_SUSPEND_TOTAL_TOKENS` /
|
|
115
|
+
`_TOTAL_BUDGET_USD` / `_MAX_SLICES` 给**一条腿**的续跑链封顶(引擎的跨片账只跟着一次运行的续跑走:验证门的每一轮修复是引擎另起的一次运行,账从零起,总额整份重新给它 —— 实现腿一条链、每一轮修复各一条链,verify 任务没有跨腿的总额);`POST /v1/runs/:id/cancel`。刻意不加逐任务的「verify 撞限就失败」旋钮(那是第二条规则)。
|
|
116
|
+
— **回滚**:本版不写新列、不迁数据;回退之后本版留下的停驻行仍是普通的 `resource_limit` 停驻行,可用 `POST /v1/assistant/tasks/:taskId/resume` 续或取消(回退形上未实跑)。
|
|
117
|
+
11. **请求自带的 MCP / A2A 声明里写着引擎永远不发的头 ⇒ 新提交 400(行为收紧;wire 码不新)**:`mcpServers[i].transport.headers` 的件头名是 MCP 传输自己写的头
|
|
118
|
+
(`content-type` · `accept` · `mcp-session-id` · `mcp-protocol-version` · `last-event-id`,任何大小写)、同一头名两个拼写、件头名撞 `principalHeader`(`a2aPeers[i].headers` 后两形同)⇒
|
|
119
|
+
`400 request.field_invalid`,拒句点名 `mcpServers[i].transport.headers` / `a2aPeers[i].headers`、只说规范化小写的头名,不带值;`POST /v1/capabilities/mcp/probe` 同拒同句。
|
|
120
|
+
上一版:提交照收、那一台挂上,此后每一次发送 `credential_unavailable`。身份头名本身撞属主的 400 不变(同一份声明里件头也撞时,点名的是件头那一处 —— 判官先判件头)。件里名叫 `connector-assertion` 的头照收。
|
|
121
|
+
— **谁需要**:自带 MCP / A2A 头的调用方 —— 提交即知是哪一格。
|
|
122
|
+
— **谁受伤**:带这三形之一的提交整单 400(壳的 `.mcp.json` 里 http 条目写了 `Content-Type` / `Accept` 头的尤其);升级前停驻、请求体 `a2aPeers` 的对端带后两形的任务,续跑时那一条对端不挂
|
|
123
|
+
(运维 warn `a2a_injection_dropped` 点名;上一版挂上、每次发送失败)。MCP 的存量停驻体续跑照旧挂上、由引擎在发送时拒那一台。
|
|
124
|
+
— **补偿**:删掉那只头(MCP 传输自己写 `content-type` / `accept` 与会话头)、同名只留一个拼写、身份头换个名。**回滚**:回到上一版即回到「提交照收、运行期才见」(零数据面)。
|
|
125
|
+
|
|
126
|
+
12. **执行环境的家目录被证:声明(`REMOTE_EXEC_HOME_DIR`)与车道出厂答案在每只环境开起来时与环境里的 `$HOME` 对证,对不上 ⇒ 那只环境拒起(行为收紧;安全;wire 零新键、零新码)**:
|
|
127
|
+
上一版 `k8s` / `local-docker` / `ssh` 已对证;本版起 `adb` / `e2b` / `host` 同一只判官、同一组拒句。拒句点名主张、实测值与改法。升级前逐车道核一次:
|
|
128
|
+
① **`adb`** —— 声明了 `REMOTE_EXEC_HOME_DIR` 的部署:设备 shell 里 `echo $HOME` 的结果必须与它一致(去尾斜杠后逐字比);不一致 ⇒ 首连拒(`connect_failed`),设成实测值或删掉声明
|
|
129
|
+
(删掉后首连实测填座;`~/` 形规则的下单门只认声明,删声明的部署 `~/` 规则在提交时 422)。设备 shell 没有 `HOME` / 答空串 ⇒ 声明在场时拒,删掉声明即回到「座缺席 + 一行 warn」。
|
|
130
|
+
② **`e2b`** —— 不声明时主张是 `/home/user`(基础模板的用户;2026-10-29 在真沙箱上实测一致:缺省模板的用户是 `user`、`$HOME` = `/home/user`);自定义模板换了用户的部署,沙箱里 `$HOME` 不是 `/home/user` ⇒ 建沙箱时拒(`connect_failed`,沙箱随即收掉):
|
|
131
|
+
设 `REMOTE_EXEC_HOME_DIR=<沙箱里 echo $HOME 的结果>`。已挂起的会话恢复时同样对证,对不上 ⇒ 沙箱重新挂起(快照留着),改对配置后续跑。每只沙箱建起来 / 恢复时多一次 `commands.run`。
|
|
132
|
+
③ **`host`(含 `run-local`)** —— 主张(声明,缺席时 = 服务进程的家目录)必须等于子进程拿到的 `HOME`(继承面 + 会话 `settings.env`)。按旧文档把声明指向账户家而 `HOME` 指别处的部署,
|
|
133
|
+
或会话 `settings.env` 里写的 `HOME` 与主张不等的会话 ⇒ 那只环境拒起(命令面 `shell_unavailable`、文件面 `target_unavailable`、连接 `connect_failed`):删掉声明(或设成 `HOME` 的值),或去掉会话里的 `HOME`。
|
|
134
|
+
子进程 env 里没有 `HOME`(如 `inheritEnv` 名单不含它)⇒ 读数是账户的家目录(子进程 shell 对 `~` 的展开),服务进程自己的 `HOME` 指别处时对不上即拒。
|
|
135
|
+
win32 宿主:盘符形是绝对路径,`\` 与 `/`、大小写不计。起服时铸的 worktree 基环境同样被证,对不上时孤儿 worktree 清扫不跑(清扫本就尽力而为,不挡起服)。
|
|
136
|
+
④ **`device`** —— 读不了家目录,声明即座(与上一版同);声明在场时起服多一行 warn `execution_lane_home_unmeasured`(`provider` + `note`,点名声明值与「未实测」)。
|
|
137
|
+
⑤ **远端车道文件面「连不上 / 拒开」的码 `unknown` → `target_unavailable`**(k8s / local-docker / adb / e2b / ssh;动作从未开始、什么都没落下):引擎不再把它读成「任务根被删了」,
|
|
138
|
+
Bash 工具结果里是连不上的原因(含家目录的拒句)。按文件错误码 `unknown` 认「连不上」的告警 / 脚本改认 `target_unavailable`。
|
|
139
|
+
⑥ **内部模块**(都不在包根出口,嵌入方零动作;改本仓源码的人看这里):适配器的家目录配置多一位 `homeDirSource: "declared" | "lane"`(缺席 = `"declared"`),只影响拒句的改法措辞,
|
|
140
|
+
部署给适配器的两位只由 `buildLaneHomeClaim(config)` 铸;e2b / host 适配器不给 `homeDir` 时在环境开起来时实测(上一版缺席即缺席);起服句 `buildUndeclaredHomeNote` 换成 `buildLaneHomeBootNote`。
|
|
141
|
+
— **谁需要**:多用户部署、镜像换代后家目录变了而声明没跟上的部署、`e2b` 自定义模板、`host` 上会话改 `HOME` 的部署 —— `~/` 规则不再静默守错目录。
|
|
142
|
+
— **谁受伤**:主张与真实 `$HOME` 对不上而上一版照跑的部署(上面 ①–③),升级后每只环境拒起。
|
|
143
|
+
— **补偿**:拒句给出改法;回滚到上一版即恢复照单全收(零数据面)。
|
|
144
|
+
13. **记忆诸口答在请求点名的层住的那只店上;两店部署上条目 id / 店级账本的请求要带层座 `scope`;会话 id 两口不必带;个人层条目本版不经抹除口抹除(行为变更;修复;wire 加性)**:file 记忆部署上,类型化个人层(`user:` / `userproj:` / `org:`)
|
|
145
|
+
住在个人挂载上的另一只店(`<引擎根>/personal/memory`),会话写它、读它的也是那一只;上一版运维面(出处、抹除、外源标记三口、会话记忆状态、会话自助抹除)、bundle 导出 / 导入、
|
|
146
|
+
整理一律答在部署的店(`<引擎根>/memory`)上 —— 对个人层是错的答案(抹除收执说擦了、下一个会话照读得到;记忆状态答 0;导出的包是空的;导入的落在会话不读的店)。
|
|
147
|
+
本版每个动词答在请求点名的层住的那只店上:点名层的请求按点名的层(导出的 `scopes`、导入包的 `scopes`、外源列表的 `scopes`、抹除的 `select.scope` / `expectedScopes`、整理的层);
|
|
148
|
+
条目 id 与店级账本的动词(出处、清标账、清标、`select.ids` 而不带 `expectedScopes` 的抹除)多一个可选层座:GET 口查询串 `?scope=<层键>`,POST 口体 `"scope": "<层键>"`(抹除口不加键,用 `expectedScopes`)。
|
|
149
|
+
会话 id 的两口(会话记忆状态、会话自助抹除,以及 `select.sessionId` 的 operator 抹除)不点名层时不拒 —— 一只会话可以跨两只店:记忆状态读本部署的每一只店(至多两只)再合成一份
|
|
150
|
+
(计数相加、最近一次取最大、任一店有采集记录即 `captureOptedOut: true`、任一店读不出 ⇒ 那一键缺席,不补 0 / false;只有一只店时就是那只店的答案);按会话抹除落部署的店。
|
|
151
|
+
层座仍可给(会话自助抹除在体里、记忆状态在查询串),给了就只答那一层住的店。
|
|
152
|
+
**抹除只在部署的店上执行**:抹除 `requestId` 的幂等判(重放收敛、同一 id 换了选择子 ⇒ `409 memory.erasure_selector_mismatch`)记在每只店自己的证据链上,而部署还没有跨店的抹除请求身份 ——
|
|
153
|
+
所以落到个人店的抹除(点名的层住在个人挂载上;或按会话抹除而这只会话在个人店里有贡献、或个人店的账读不出)答 `409 memory.erasure_store_unjudged`,什么都没删、什么都没记。
|
|
154
|
+
这条护栏是计划删除的(不是过渡双读):引擎给出部署级的抹除请求身份那一版,本服务删掉它,个人店上的抹除随之开放。
|
|
155
|
+
— **谁受伤**:本部署点名的层(`MEMORY_SCOPE`〔单用户〕、`MEMORY_SYNC_SCOPE`、登记簿项目的种子层、`MEMORY_CONSOLIDATION_SCOPES`)里有个人平面键的 file 部署 ——
|
|
156
|
+
① 不带层座的条目 id / 店级账本请求上一版 200(答在部署的店上),本版 `400 request.memory_layer`(句子点名哪几层住哪只店);一次导出 / 外源列表点名的层跨两只店 ⇒ 400,按店拆成两次;
|
|
157
|
+
② 抹除个人层条目的请求:operator 抹除点名个人层 —— 上一版 200(落在部署的店上,对个人层是空擦),本版 `409 memory.erasure_store_unjudged`;
|
|
158
|
+
会话自助抹除(不带层座)而这只会话在个人店有贡献(或个人店的账读不出)—— 上一版 200:真擦掉这只会话在部署的店里的那一半(项目平面的层),个人店那一半原样、收执不提它;
|
|
159
|
+
本版 `409 memory.erasure_store_unjudged`、一条都不擦(两店都有贡献时,上一版擦掉的部署店那一半本版也不擦了);
|
|
160
|
+
③ 会话记忆状态上一版只数部署的店(写进个人层的那一半读成 0),本版是两只店的合计 —— 数字会变大,这是改对了。
|
|
161
|
+
引擎读不出的层键(⇒ `400 request.memory_layer`)在导出 / 同步 / 整理口上对**任何**部署(含单店)都从上一版的 200 / 500 变 400。
|
|
162
|
+
除这一条外,单店形不受影响、答法逐字同上一版 —— 单店形 = SQL 记忆后端,或 file 记忆后端而配置不点名个人平面键**且请求不点名个人平面的层**(缺省 `local` 即此形)。
|
|
163
|
+
file 部署上请求自己点名个人平面的层(例:operator 抹除 `select.scope: "user:<P>"`)不在此列,配置不点名个人平面键也一样:那一层住在个人挂载上的店 ⇒
|
|
164
|
+
抹除 `409 memory.erasure_store_unjudged`(上一版 200,答在部署的店上;拒之前个人挂载上的店已被打开,挂载目录不在时会建出),其余动词答在那只店上(上一版答在部署的店上)。
|
|
165
|
+
自建 `ServiceDeps` 并自己给 `sessionMemoryStatus` 的嵌入方:面形改为先定店 `storesAt(at?) → readonly { controlPlane, status(sessionId) }[]`(不带层座 ⇒ 本部署的每一只店;TypeScript 编译红即通知)。
|
|
166
|
+
— **处置**:运维脚本 / 控制台在这类部署上给条目 id / 店级账本的请求带上层座(要答的那一层);跨店导出拆成每店一次;引擎读不出的层键改成读得出的键。
|
|
167
|
+
会话所有者的客户端(记忆状态 / 自助抹除)不需要改请求形;两店部署上自助抹除答 409 的那一形(这只会话在个人店有贡献)要按 409 处理 —— 上一版这一形 200、擦掉部署店那一半,本版一条不擦;
|
|
168
|
+
要先擦掉部署店那一半,带层座 `scope` 点名一个住在部署的店上的层(收执只覆盖那只店,见下面已知限制 ②)。
|
|
169
|
+
个人层条目本版没有抹除口可用 —— 上一版也没有(它的收执不覆盖个人店),本版改成落到个人店的抹除在任何删除之前响亮拒。
|
|
170
|
+
嵌入方按新面形实现 `storesAt`:单店的实现返回一只元素的数组,答法与上一版同。
|
|
171
|
+
— **升级后看**:修前在部署的店上做过的操作不会被补做 —— 修前「擦掉」的个人层条目仍被会话读得到,本版同样擦不了(`409`),等引擎给出部署级抹除请求身份的那一版;
|
|
172
|
+
修前导入落进部署店的个人层条目留在原处、没有读者(推断),要它们进个人店就从原包按本版重新导入。
|
|
173
|
+
— **已知限制**(本版抹除护栏与店集的边;引擎的部署级抹除请求身份 / 部署级读口到货后收):
|
|
174
|
+
① 按会话抹除(会话自助口,或 operator 的 `select.sessionId` 不带 `expectedScopes`)已在部署的店上执行过,这只会话之后又往个人店写过 ⇒ 原样重放同一个 `requestId` 答 `409 memory.erasure_store_unjudged` ——
|
|
175
|
+
拒句的「什么都没删」说的是这一次调用,第一次的删除照旧有效;要拿到收敛的应答,在会话自助口带层座 `scope` 点名一个住在部署的店上的层(例:`local`)重放同一个 `requestId`:
|
|
176
|
+
选择子不变,引擎按第一次钉下的 id 集重答一张新收执(`at` 是这一次的;托管链完整时第一次删掉的条目列在 `erasedPreviously`)。operator 口没有层座键,这一序列上的这条路只在会话自助口。
|
|
177
|
+
② 会话自助抹除带层座、而那一层住在部署的店上 ⇒ 不过按会话的那道判:落部署的店执行、答 200,收执只覆盖部署的店(层座不进引擎、不进收执),这只会话在个人店里的那一半原样、收执不提。
|
|
178
|
+
③ 会话记忆状态的合成与按会话抹除的 409 判只看本部署此刻点名的层住的店:换过 `MEMORY_SCOPE`(或同步层、登记簿种子层、整理层)、不再点名个人平面键之后,
|
|
179
|
+
留在个人挂载那只店里的会话贡献不在其列 —— 状态里读不到那一半,按会话抹除照常 200 而那一半原样(与上一版同形)。
|
|
180
|
+
①② 随引擎的部署级抹除请求身份一并收;③ 随引擎的部署级读口改为按持久化的平面枚举。
|
|
181
|
+
— **回滚**:回到 7.139.x 各口回到部署的店上(层座键被忽略的口照旧 200 —— 答案对个人层仍是错的,个人层的抹除又变回空擦)。
|
|
182
|
+
14. **订正 7.138.0 节第 23 条 ⑩ 的「扣留次序」:引擎 7.60.0(本服务 7.139.0 起)是先记后判 —— 被读器拒的座答里认作凭据的值照样进扣留表(文字订正;零行为变更)**:
|
|
183
|
+
7.138.0 节第 23 条 ⑩ 写的是「先过读器、放行了才记 —— 被读器拒的形的值不进扣留表:那一台失败,环境里同值的变量仍交给 host shell 子进程」。
|
|
184
|
+
那一句在当时的引擎 7.59.0 上为真;7.139.0 起提货的引擎 7.60.0 恢复了先记后判,7.139.0 节没有写这一变化。现行次序:座答里认作凭据的值 ——
|
|
185
|
+
http 头按凭据词表选中的头,按所写的原值与传输会发出的值各读一份;stdio 件按 env 项的读法 —— 在读器判形**之前**就记进扣留表;空值不记;一个扣不住的值不挡别的值,整份答案随后被拒。
|
|
186
|
+
所以读器随后拒的形(件值含 CR / LF / NUL、头名不是 HTTP token、两个头名只差大小写、变量名不是标识符形)只让那一台失败,其中认作凭据的值已在表里 ——
|
|
187
|
+
服务进程环境里同值的变量**不再**交给 host shell 子进程。
|
|
188
|
+
**消费方动作**:无(只改文字,运行时没有变化)。⑩ 的补偿里「件值别与长期留在服务进程环境里的变量同值而又带读器拒的形」不再是防漏的必要条件(同值的变量已被扣下);
|
|
189
|
+
名册 `headerRefs` 指向的变量值带尾换行时那一台仍失败,去掉那个换行照旧是让它能用的办法。
|
|
190
|
+
|
|
191
|
+
## 7.139.0 —— 执行放置成为根会话行上的一格:🔴 SQL 后端 `session_meta` 加八列、`device_session` 表退役、`approval_ask` 加一列 `execution_lane`(本服务起服时自己改表;升级前备份、先停光全部旧副本再起本版;回滚只有恢复备份)· 路由 `GET /v1/devices/sessions/:id` 删除(BREAKING,wire;换读 `GET /v1/sessions/:id/execution-placement`)· 新口 `POST /v1/sessions/:id/children/retire` · fork 可带键重试 `{forkId, forkNonce}`(wire additive)· 四只新 409(`conflict.session_mirror` / `conflict.session_writer` / `conflict.fork_*` / 活子代)与拒体新顶层键 `forkPath` / `boundLane` / `children` / `retirePath`(行为面)· 会话行条件写 `expectedRowTag` ⇒ `409 conflict.session_row_changed`(wire 加性)· 🔴 记忆同步:升级后每一层停同步直到运维对该层游标做一步 · 请求键 `rewindFiles` 退役(wire BREAKING;新提交 400)· `POST /v1/rules/cc-import/prepare` 的 200 体少键 `translated`(wire BREAKING,读侧)· 后台行多可选键 `sessionId`(wire 加性)· 旁问路由 400 只给 `config.unknown_role`(行为变更)· 声明判官的拒句不再回显调用方写的名(运维面)· 部署 mod 包内核契约号 6(`contract: 5` 起服拒)· 四只新运维通告码不上用户流 · 沙箱带外 env 名单点到本服务自有凭据名 ⇒ 起服拒(`E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` / `K8S_SANDBOX_ENV`;安全,行为收紧)· k8s 车道 `K8S_NAMESPACE` 必设(部署面,行为收紧)· 模型目录 `apiKeyEnv` 点到名单型旋钮正在交出的名 ⇒ 该候选整拒(安全)· `CONFIG_PROVIDER=remote` 无中心地址 / `RETENTION_MODE=enforce` 缺天数或节律 ⇒ 起服拒(行为收紧,fail-closed)· 会话规则 / 持久规则桶文法戳 7(升级序:先升全部读者再放写)· 执行环境写入改「暂存 → 一次提交」(七条车道一条规则;行为面)· 本机宿主车道 workflow 子代 `isolation: "worktree"` 的已知变化(E10,引擎 7.61.0 收)· 嵌入方类型面 BREAKING 多处(`RunnerDeps.peerSeat` 三员对象 · `createHttpServer` 的 `authorize` 席必填 · `resolveSpec` 不再写 `sessionId` · 设备店绑定四法换两只放置写 · 停驻赎回腿的会话店必须带执行席、`root` → `rootOccupant` · `StoreBackend` 问店行与迁移报告多键)· 契约包 settings-schema 15.0.0 · 引擎 7.60.0
|
|
192
|
+
|
|
193
|
+
1. **🔴 记忆同步(`MEMORY_SYNC_URL` 设了的 file 记忆部署):升级后每一层都停同步,直到运维对那一层的游标做一步**:
|
|
194
|
+
本版起同步对端 = `MEMORY_SYNC_URL` 的规范化形(协议与主机小写、缺省端口省掉、路径去尾斜杠;起服日志 `memory_sync_enabled` 的 `peer` 就是它,该行不再带 `url`),
|
|
195
|
+
每层一只游标 `<记忆根>/sync-cursors/<scope 摘要>.json`,游标的对端 / scope / 店绑定只由引擎判。第一轮会把上一版的分区游标(`sync-cursors/central/…`)与更早的根下游标
|
|
196
|
+
(`sync-cursor-central.json`)搬到各自那一层的路径(只搬、字节不变;日志 `memory_sync_cursor_relocated`,目标路径已有游标或读不出它属于哪一层 ⇒ 原地不动、一行 `memory_sync_cursor_not_relocated`)。
|
|
197
|
+
搬过来的游标绑的对端名是 `central`,与新身份不符 ⇒ 引擎在对端轴上拒、这一层零请求,`memory_sync_layer_failed` 带引擎的拒句(两条出路)与游标路径;其余层照跑,下一轮同样拒,直到处置。
|
|
198
|
+
**处置(每一层一次,二选一)**:① 中心没换(同一只中心,只是换了身份写法)⇒ 把那只游标文件里的 `"peer"` 改成 `memory_sync_enabled` 日志里的 `peer` 值,其余字节不动,下一轮照常增量同步 —— 例外:游标里没有 `"store"` 键的(7.138.0 之前写下的 `sync-cursors/central/…` 与更早根下的 `sync-cursor-central.json` 都没有),改完 `peer` 后下一轮引擎在店轴再拒一次
|
|
199
|
+
(三轴按 scope → peer → store 的顺序判,peer 过了才轮到 store),`memory_sync_layer_failed` 的拒句点名这一轮的店身份:把它作为 `"store"` 键写进那只游标,再下一轮照常增量同步(或走处置 ②);
|
|
200
|
+
② 删掉那只游标 = 接受空基线重收敛:两边都改过的条目按冲突上报,自上一轮以来一侧删掉的条目会从另一侧回来。中心换过了只能走 ②。执行器不替运维选:读不了 / 读不成 / 被拒的游标一律原地不动。
|
|
201
|
+
**起服判 `MEMORY_SYNC_URL`**(引擎关着也判):不是层级式 http(s)、带 userinfo / query / fragment(含空的 `?` / `#`)、路径段里带令牌形、或规范化后超过中心 `peer` 列宽 ⇒ 拒启(拒句值只到 origin,不回显地址其余部分);
|
|
202
|
+
令牌只走 `MEMORY_SYNC_TOKEN`。上一版照收的这些形升级当天起服即拒 —— 升级前把地址写成基址本身。
|
|
203
|
+
两道判各有属主,本服务不另抄:地址的形归「后面要拼路径的基址」座位的判官 `pathBaseUrlRefusal`;身份里有没有凭据(路径段的令牌形、任何 userinfo)归引擎包根导出的 `carriesCredential` ——
|
|
204
|
+
引擎同步客户端判对端身份的同一只,起服对规范化后的身份调它,所以引擎在第一轮会拒的地址起服就拒,一个请求都不发。
|
|
205
|
+
|
|
206
|
+
2. **请求键 `rewindFiles` 退役(wire BREAKING;零别名)**:新提交(`POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs`)带它 ⇒ `400 request.body_shape`、`unknownKeys: ["rewindFiles"]`,不建 run;
|
|
207
|
+
续跑重放盘上旧体里的它零读者(不进引擎 —— 引擎本版对它按名拒,带它存过的任务因此照常续跑)。客户端改用 `restoreFiles` 或 `rewindFilesTo`。
|
|
208
|
+
|
|
209
|
+
3. **旁问路由(`POST /v1/side-query`)的 400 只给引擎的 `config.unknown_role`(行为变更)**:角色族四臂(角色词不在词表 / 不是模型引用 / 指到目录外 / 角色缺模型)带码 400;
|
|
210
|
+
没有引擎码的错误一律 500(上一版按英文前缀表把同形句子判 400)。调用方按 `errorCode` 判,不按句子。续跑侧:停驻卡因角色缺模型(`no_model_for_role`)被拒时与目录缺条目同判可兑 —— 配好角色表后同一张卡可续。
|
|
211
|
+
|
|
212
|
+
4. **声明判官的拒句不再回显调用方写的名(行为变更;运维面)**:请求面 `mcpServers[].toolAxes` / `toolFaces` / `sessionMetaKey` 与 A2A `toolAxes` 的 400 拒句里,调用方写的工具名 / 键 / 词换成
|
|
213
|
+
`[redacted] (N characters)`(N = 码位数)。部署腿(`config.d` / 中心下发)的 `web_admin_mcp_tool_axes_invalid` / `web_admin_mcp_tool_faces_invalid` 的 `problem` 同样只给码位数 —— server 名照点,
|
|
214
|
+
哪只工具坏了要按 server 名去配置里逐个查。码与状态码不变。
|
|
215
|
+
|
|
216
|
+
5. **部署 mod 包的内核契约号是 6**:`contract: 5` 的包起服拒 `config.mods_invalid`(拒句点名两号;不静默装、不跳过)。6 = 四个新扩展事件开站(`agent.offer` / `agent.spawn` / `turn.complete` / `session.end`)
|
|
217
|
+
+ `tool.call` 失败列 `refuse`(调用跑过之后扩展失败 ⇒ 结果扣下)。升级前把包的 `contract` 改成 6 并核处理器对新列的假设。
|
|
218
|
+
|
|
219
|
+
6. **`POST /v1/rules/cc-import/prepare` 的 200 体少一个键 `translated`(wire BREAKING,读侧)**:引擎删了这个恒空数组,本服务原样投。读它的客户端改为不读(它从来是空的)。
|
|
220
|
+
|
|
221
|
+
7. **`GET /v1/sessions/:id/background` 的行多可选键 `sessionId`(wire 加性)**:后台 agent 行在子会话绑定之后带它(跳到子会话用;那只会话照常过会话面的属主门)。键缺席 = 没有 / 还没绑定。
|
|
222
|
+
|
|
223
|
+
8. **运维面:四只新通告码受众是运维,不上用户流**:`mcp.credential_echoed`(对端把连接凭据回显进它的自述 —— 点名对端与位置,不带值)、`config.read_deny_floor_unkept`
|
|
224
|
+
(执行车道不守读拒表的字节地板 —— 本服务七只车道都声明不守,读拒表非空的每条带车道的 run 都会有一行)、`classifier.seat_rate_limited`(自动模式分类座的模型连续被限流,
|
|
225
|
+
这条 run 余下的门改由主模型判;引擎缺省连续 3 次,本服务不接这只引擎旋钮 —— 要一直问分类座就设 `AUTO_MODE_CLASSIFIER_FALLBACK=none`,那时它答不出整条拒、从不退到主模型)与 `config.image_processor_unavailable`(这条 run 没有图片处理器、一张超软目标的图原样发出;
|
|
226
|
+
本服务把 sharp 列为可选依赖,装上即到达不了)。看板 / 告警按 `audience` 过滤。
|
|
227
|
+
`/metrics` 的 `peer_registry_holders` 本版起 = 宿主租约 + 引擎持有之和(run 在飞时读数会高于名册条目数,落定后回到租约数)。
|
|
228
|
+
|
|
229
|
+
9. **嵌入方(类型面 BREAKING;部署零动作)**:`RunnerDeps.peerSeat` 是 `{ answer, hold, release }` 三员对象(函数形构造即拒 `config.invalid_argument`;本服务的 desk 已是对象;
|
|
230
|
+
desk 对它没铸过的引用 —— `env` / `vault` / `assertion` 或闭集外的种类 —— `hold` / `release` 抛,引擎报一次运维面 `peer-seat-hold`、不记持有);
|
|
231
|
+
自写执行车道的 `capabilities` 必须声明引擎八键(`hostLocalPaths` / `externalContentTarget` / `io` / `keepsReadFloor` 新必填,设备车道顶层两只散布尔已并入块);
|
|
232
|
+
`loadProjectMemory` 只答 `{ content, instructionSources? }`(无可注入 = `{ content: null }`;裸串 / `null` 引擎不读)。
|
|
233
|
+
|
|
234
|
+
10. **沙箱带外 env 名单点到本服务自有凭据名 ⇒ 起服拒(`E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` / `K8S_SANDBOX_ENV`;安全,行为收紧)**:
|
|
235
|
+
三只名单点到的变量从服务进程环境原样装进沙箱(e2b VM env / `docker exec -e` / k8s pod 自己的 Secret),沙箱里模型驱动的命令读得到。本版起它们与
|
|
236
|
+
`LSP_ENV_ALLOW` / `BAKE_ENV_ALLOW` 同一条律:点到本服务自有凭据名 —— 配置目录里全部 secret 型变量(如 `SERVICE_AUTH_TOKEN(S)` / `APPROVAL_HMAC_KEYS` /
|
|
237
|
+
`MODEL_API_KEY` / `E2B_API_KEY` / `K8S_TOKEN` / `GIT_API_TOKEN`)与名单型旋钮名本身 —— ⇒ 起服拒,拒句点名旋钮与第几段
|
|
238
|
+
(`env E2B_SANDBOX_ENV: entry #2 of 2 is this deployment's own credential — a sandbox list puts the named variable, as written, into a sandbox the model can read; …`),
|
|
239
|
+
不回显值;多租户姿态(`REQUIRE_PRINCIPAL=true`)下同样拒。
|
|
240
|
+
**谁受伤**:靠这三只名单把本服务自有凭据交进沙箱过活的部署(典型:`E2B_SANDBOX_ENV=MODEL_API_KEY` 让沙箱里的工具直调模型网关、`K8S_SANDBOX_ENV=GIT_API_TOKEN`
|
|
241
|
+
让沙箱里的 git 用本服务的 Git host 凭据)—— 升级后起服失败。
|
|
242
|
+
**升级前做(出路)**:给沙箱铸一把独立凭据 —— 名与值都不同于本服务的任何凭据(例如在网关 / Git host 上为沙箱另发一把限权、可单独吊销的 key)—— 放进服务进程环境,
|
|
243
|
+
名单改点那个名:`SANDBOX_GIT_TOKEN=<另一把令牌>`、`K8S_SANDBOX_ENV=SANDBOX_GIT_TOKEN`,沙箱里的工具改读新名。别把同一个值换个名字再点
|
|
244
|
+
(`SANDBOX_GIT_TOKEN=$GIT_API_TOKEN`):那仍是本服务的凭据进了模型可读的沙箱,只是换了名字。
|
|
245
|
+
名单只点部署方给沙箱的令牌(`GIT_TOKEN`、`NPM_TOKEN` 这类不在配置目录里的名)的部署零动作。**回滚**:回到上一版即恢复旧行为(名单照装),无数据面改动。
|
|
246
|
+
|
|
247
|
+
11. **k8s 车道:`K8S_NAMESPACE` 必须设,缺席 / 空白起服拒(部署面,行为收紧;嵌入方类型面 BREAKING)**:
|
|
248
|
+
沙箱 pod 所在的命名空间是部署事实(沙箱 Role / RoleBinding / NetworkPolicy 与回收器都认部署声明的那一个),服务不再带内置缺省。
|
|
249
|
+
`REMOTE_EXEC=k8s` 而 `K8S_NAMESPACE` 缺席、空串或只含空白 ⇒ 起服拒,拒句点名旋钮与出路:它是 k8s 车道的必需件,拒的是所有车道共用的那道必需 env 门
|
|
250
|
+
(`REMOTE_EXEC=k8s but required env K8S_NAMESPACE is unset, empty or whitespace-only — it counts as absent: …`;门的判法见第 18 条)。其它车道不读这根旋钮,缺席照常起。
|
|
251
|
+
**谁受伤**:`REMOTE_EXEC=k8s` 且没设 `K8S_NAMESPACE` 的部署 —— 升级前沙箱 pod 落在 `sandboxes`;典型是不走随包 chart 的自管集群与本地联调。
|
|
252
|
+
嵌入方:`ServiceConfig` 的 k8s 车道臂里 `namespace` 由可选改必填(类型面,编译红即消费点清单,没有别名)。
|
|
253
|
+
**升级前做(出路)**:在服务进程环境里设 `K8S_NAMESPACE=<沙箱 pod 所在的命名空间>`;原来没设的部署设成 `K8S_NAMESPACE=sandboxes`,即与升级前逐字同。
|
|
254
|
+
随包 chart(`deploy/sema-up`,取 `sandbox.namespace`)与单文件栈清单已显式设,零动作。**回滚**:回到上一版即恢复旧缺省,无数据面改动。
|
|
255
|
+
|
|
256
|
+
12. **模型目录条目的 `apiKeyEnv` 点到名单型旋钮正在交出去的名 ⇒ 该候选整拒(安全,行为收紧)**:
|
|
257
|
+
中心 / config.d 模型目录条目的 `apiKeyEnv` 在模型目录换代时并进本服务自有凭据名。本版起这一刻对活配置里的名单(`E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` /
|
|
258
|
+
`K8S_SANDBOX_ENV` / `LSP_ENV_ALLOW`)此刻交出去的名重判一次:新并进的名正被某只名单交给沙箱 / 语言服务器 ⇒ 这份候选整拒、上一代照常服务(起服时落 LKG / env;
|
|
259
|
+
刷新拍 `web_admin_refresh_failed` 每拍重判,`/health` 目标 ≠ 已应用),拒句点名旋钮、名与条目
|
|
260
|
+
(`env K8S_SANDBOX_ENV hands on GATEWAY_KEY, which this candidate makes this deployment's own credential — …`),不回显值。
|
|
261
|
+
**谁受伤**:worker 的名单点着某个变量、中心又把同一个变量写成某条模型条目的 `apiKeyEnv`(典型:`K8S_SANDBOX_ENV=GATEWAY_KEY` 让沙箱里的工具直调网关,中心又给一条模型配
|
|
262
|
+
`apiKeyEnv: GATEWAY_KEY`)—— 升级后中心那份发布在这台 worker 上整份不生效;修前同一个值既是本服务的模型凭据,又在每只沙箱里。
|
|
263
|
+
**升级前做(出路,二选一)**:给沙箱 / 语言服务器另铸一把凭据(名与值都不同),名单改点新名并重启 worker;或在中心把那条模型条目的 `apiKeyEnv` 改指另一个变量(下一拍自愈,不用重启)。
|
|
264
|
+
名单与模型条目 `apiKeyEnv` 不相交的部署零动作。**回滚**:回到上一版即恢复旧行为,无数据面改动。
|
|
265
|
+
|
|
266
|
+
13. **嵌入方(类型面 + 构造期,BREAKING):`createHttpServer` 的 `authorize` 席必填;`resolveSpec` 不再写 `sessionId`**:
|
|
267
|
+
标准起服零动作 —— 它恒装 authorizer(`run-local` 不起 HTTP 面,同样零动作)。自建 `createHttpServer(deps)` 的嵌入方:
|
|
268
|
+
① deps 加一行 `authorize: createAuthorizer(config, runner.sessions)`(包根导出;店没有属主读时退化为只派 principal 与会话 id,单用户嵌入与升级前同义);
|
|
269
|
+
这一键从 `governance` 组移到顶层必填席,写在 `governance: { authorize }` 里的改写到顶层。省掉 ⇒ 编译错;JS 嵌入方省掉 ⇒ `createHttpServer` 构造期抛,拒句点名这一行。
|
|
270
|
+
② 自建 `resolveSpec` 删掉返回值里的 `sessionId`(返回型 `ResolvedTaskSpec` 上它是 `never`);要用这条腿的根会话就读必填的 `opts.execution.root`。
|
|
271
|
+
根由 server 在装配之后盖进 spec;JS 形装配器返回另一只会话 ⇒ 提交腿 `400 request.precondition_unmet`、零 run 行(续跑腿折成 `409 resume_blocked_by_policy`,`blockedBy` 同码)。
|
|
272
|
+
要续已有会话,让请求体带它的 id(过 authorizer 的属主门)。
|
|
273
|
+
③ 注入了 `runStore` 而解析器不写 `sessionId` 的嵌入:同步 / 流式提交从此起认领 + run 行(与 durable 腿同形)。不想记 run 账就不注入 `runStore`(`/v1/runs` 501)。
|
|
274
|
+
④ SQL run 店的认领事务先锁根会话行:根会话行不在(受理之后会话被删)⇒ 四个建行点答 `404 resume.session_not_found`。自建 deps 把 SQL run 店与非 SQL 会话店配在一起的装配(生产起服不会这样配)认领永远读到零行 —— 两只店要同一个 SQL 后端。
|
|
275
|
+
|
|
276
|
+
14. **SQL 后端:执行放置切换 —— `session_meta` 加八列、`device_session` 表退役、`approval_ask` 加一列 `execution_lane`(🔴 本服务起服时自己改表;升级前备份、先停光全部旧副本再起本版;回滚只有恢复备份一条路)**:
|
|
277
|
+
「这只会话在本部署上由谁写」成了根会话行上的一格(`absent` / `writer` / `mirror`,`DB_BACKEND=local` 另有 `forking`);device 车道的设备绑定就是 `writer` 那一格里的设备。
|
|
278
|
+
本条**不用手跑 `ALTER`**:起服时先只读探一次库形,再在一次性迁移锁内依次 —— 加列(`execution_role` · `execution_lane` · `execution_device_id` · `execution_device_owner_tenant` ·
|
|
279
|
+
`execution_device_owner_subject` · `execution_placed_at` · `execution_rev` · `fork_key`,全部可空;`approval_ask.execution_lane` `NOT NULL DEFAULT ''`)→ `device_session` 的绑定整行搬进根会话行
|
|
280
|
+
(`rev` 原值)→ 有 run 行而还没有放置的会话回填成本处写者(本部署的车道)→ 问行回填车道 → 删掉旧表。中途被打断,下次起服从断点续;新副本在迁移走完之前不服务。库账号要有 DDL 权限(起服建表本就要求)。
|
|
281
|
+
**升级步**:
|
|
282
|
+
① **备份**整个库(回滚的唯一前提)。`DB_BACKEND=local`:备份整个数据根(会话元数据边档 `session-incarnations.json` 与问账日志 `approval-asks/asks.jsonl` 会被改写)。
|
|
283
|
+
② **先停光全部旧副本,再起第一个本版副本** —— 滚动升级在本版不成立:切换开始之后仍在跑的旧副本还会往 `device_session` 写首绑,那些行会让下一次起服撞围栏(见 ④)。
|
|
284
|
+
多副本 k8s 本次按 `Recreate` 做:先把副本数缩到 0、等旧 pod 退光,再升级、再放回副本数(各安装路径的缩容做法与 7.137.0 节第 4 条「升级前先缩光副本」三段相同)。
|
|
285
|
+
③ 首启时 `REMOTE_EXEC` 照旧取一个值(回填按这一条车道写)。起服日志行 `one_time_migrations_applied` 的七个读数键说这次做了什么:`executionPlacementColumnsAdded`(补了几列)·
|
|
286
|
+
`deviceBindingsMoved`(搬了几条绑定)· `deviceBindingsOrphaned`(指向已不在的会话、被丢弃的绑定数;非零另有一行 warn `device_bindings_orphaned`)· `deviceBindingTablesDropped`(删了几张绑定表)·
|
|
287
|
+
`executionPlacementsBackfilled`(回填了几只会话)· `askExecutionLanesBackfilled`(回填了几只问)· `executionPlacementSessionsUnreadable`(只 `DB_BACKEND=local`:被回填跳过的读不出的旧会话数)。
|
|
288
|
+
`DB_BACKEND=local` 数据根里「有 run、会话元数据格缺、存档读不出」的老会话被回填**跳过并告警**、起服不挡:每只一行 warn `execution_placement_session_unreadable`(`sessionId` 与 `fault`:`corrupt_session` / `invalid_session` / `storage`;
|
|
289
|
+
`storage` = 读存档文件时抛了别的故障〔I/O 级:权限不够、磁盘 I/O 错、存档大到读不进内存〕,此时多一个字段 `errno` 带系统码 `EACCES` / `EIO` / `ERR_STRING_TOO_LONG` ……),**I/O 级读故障同样跳过并点名**(fork 创建的格而存档读不出的会话同样);
|
|
290
|
+
每次起服都再报;该会话的请求照旧答存档的故障。出路 = 把它的存档文件(数据根 `sessions/` 目录下)从留存副本恢复(`storage`:修好文件权限 / 磁盘),重起后补它的放置;移走存档文件则不再告警、也不补放置(这只会话在本服务上不再存在,它的 run 行留着;fork 创建的会话例外:它的格还在,读作 fork 未落定,出路是同键重试那次 fork 或删除该会话)。
|
|
291
|
+
device 车道上升级前有 run、绑定表里却没有它的会话回填成「本处写者、device 车道、设备未知」:不带 `deviceId` 的提交答 `409 device.not_bound`,带 `deviceId` 即首绑。
|
|
292
|
+
④ **围栏**:切换已开始(`session_meta.execution_role` 列在,或中途表 `device_session_retired` 在)而 `device_session` 里又有行 ⇒ 起服拒 `config.execution_placement_switch_refused`
|
|
293
|
+
(`reason: fence`),拒在任何 DDL 之前、库零写,拒句列出这些行的根会话(至多 20 只)。先停光旧副本,再二选一,然后重起本版:
|
|
294
|
+
**采旧**(这些行在下一次起服时覆盖它们根会话行上的设备放置)—— 中途表不在时,(MySQL 协议)`RENAME TABLE device_session TO device_session_retired;`
|
|
295
|
+
(PostgreSQL)`ALTER TABLE device_session RENAME TO device_session_retired;`;中途表已在时(两方言同一串):
|
|
296
|
+
`DELETE FROM device_session_retired WHERE root_session_id IN (SELECT root_session_id FROM device_session); INSERT INTO device_session_retired (root_session_id, device_id, owner_tenant, owner_subject, bound_at, rev) SELECT root_session_id, device_id, owner_tenant, owner_subject, bound_at, rev FROM device_session; DELETE FROM device_session;`
|
|
297
|
+
**弃旧**(会话行保留现有的放置):`DELETE FROM device_session;`(只清空旧绑定表;这张空表由本版自己的迁移在下一次起服删掉,不用你动手)。
|
|
298
|
+
另一拒因 `backfill_ambiguous`(声明的车道不止一条而还有要回填的会话 / 问行)在 `REMOTE_EXEC` 只取一个值的本版不可达;拒句给的出路是「先以单一车道起一次服,让切换走完」。
|
|
299
|
+
⑤ **回滚**:唯一支持的形 = 恢复 ① 的备份(代价:切换之后的写全丢)。上一版起在已切换的库上会建回一张空 `device_session`,随后起服列册对账把执行列看成未知列而拒启
|
|
300
|
+
(`config.schema_mismatch`),不写行;再起本版,迁移删掉那张空表。`DB_BACKEND=local` 上,上一版读到带执行位的会话元数据格时整份拒那一只边档(首次触及时,不是起服时)—— 同样恢复备份。
|
|
301
|
+
⑥ **窗**:这段迁移窗内每次起服都跑(切换走完之后零动作),窗 = 本版发布日起 30 天;窗关之后的版本删掉它,并让还带 `device_session` / `device_session_retired` 的库起服拒启 ——
|
|
302
|
+
跳过本版直升的库,先在本版上起一次服。
|
|
303
|
+
`DB_BACKEND=memory`(引擎缺省的内存会话店)零动作:那种部署不记执行放置。
|
|
304
|
+
|
|
305
|
+
15. **路由:`GET /v1/devices/sessions/:id` 删除(BREAKING,wire;零转发),换读 `GET /v1/sessions/:id/execution-placement`;新口 `POST /v1/sessions/:id/children/retire`;`POST /v1/sessions/:id/fork` 收可选体 `{forkId, forkNonce}`(wire additive)**:
|
|
306
|
+
① 旧读面答全局 `404 not_found.route`。新读面 200 体 = `{role:"absent"}` | `{role:"writer", lane, device?:{deviceId, rev}}` | `{role:"mirror"}` | `{role:"forking"}`(`lane` = 执行车道词,
|
|
307
|
+
`REMOTE_EXEC` 的取值,未设 = `in-process`)。换绑的材料:旧体 `boundDevice.deviceId` / `boundDevice.rev` ⇒ 新体 `device.deviceId` / `device.rev`(`rev` 仍是换绑口 `expectedRev` 要回显的前态);
|
|
308
|
+
`boundAt` 没有了;旧体的 `rootSessionId` 就是路径里的 id。「没有绑定」此前答 `404 not_found.device`,现在是 200 —— 格不是 `writer`,或没有 `device` 键;他人会话与不在的会话同答
|
|
309
|
+
`404 not_found.session`(此前 `not_found.device`)。**可见性的门换了**:旧读面按设备域判(要有 tenant claim,且是该设备绑定的同属主,否则 403 / 404;operator 不受此限),新读面按会话判 ——
|
|
310
|
+
会话面的同一只属主谓词(有主的会话行 = 会话属主;没有身份边界的开发部署与无主的普通会话行对调用方开放,与会话面同读)∨ explicit operator。对**非 operator** 的调用方,在带身份边界的部署、有主会话上:
|
|
311
|
+
会话属主没有 tenant claim 时,旧读面答 403,现在读得到自己会话的 `device`(绑定);会话属主带的 tenant claim 与该设备绑定的属主不同时,旧读面答 404,现在读得到;
|
|
312
|
+
设备属主既不是会话属主、也不是 operator 时,旧读面读得到,现在答 `404 not_found.session`。operator 两边都读得到,无变化。非 device 部署上它也在(旧读面在那里整族 `501 capability.device_lane_required`);
|
|
313
|
+
会话店不带执行席 ⇒ `501 capability.session_store_required`。没有能力位:老 server 对新路径答 `404 not_found.route`。
|
|
314
|
+
② 结清口(无体)⇒ `200 {children: string[]}`(首轮观察到、且已全部结清的后台子代,每项与 `GET /v1/agents/roster` 行上的 id 同串)/ `409 conflict.session_children_alive`
|
|
315
|
+
(体 `remaining`,有本副本结束不了的子代,一只都没动)/ `404 not_found.session`;鉴权、限流、无凭据写门与 `POST /v1/sessions/:id/background/stop` 同。停止口本身语义不变
|
|
316
|
+
(停驻子代与它的待决卡照留);要「停一切」= 停止口 + 结清口两次调用。
|
|
317
|
+
③ fork 口:`forkId`(调用方铸的规范 uuid,= 新会话的 id)+ `forkNonce`(1–255 个字符,重试送同一个),同在同缺。首次 `200 {sessionId}`;同键重试 `200 {sessionId, replayed: true}`;
|
|
318
|
+
`forkId` 已是你的另一只会话 ⇒ `409 conflict.fork_id_taken`(终局,换一组新键);已是别人的会话 ⇒ `404 not_found.session`;缺一键 ⇒ `400 request.field_conflict`(`detail.kind: "fork_target"`);
|
|
319
|
+
`forkId` 不是规范 uuid ⇒ `400 request.id_invalid`;`forkId` 等于源 ⇒ `400 request.field_invalid`;`forkNonce` 不合形 ⇒ `400 request.field_invalid`;
|
|
320
|
+
两次撞上同一目标的别的写者 ⇒ `503 state.fork_target_unsettled`(`permanence: "transient"`,原样重试)。不带体 ⇒ 与上一版同(现铸 id);零字节体与字面 `null` 同义于不带体。
|
|
321
|
+
**体现在被解析了**(上一版这个口忽略体,任何体都照常现铸一只):畸形 JSON ⇒ `400 request.invalid_json`;超过体帽(8 MiB)⇒ `413 request.payload_too_large`;
|
|
322
|
+
JSON 数组或标量(`[]`、`"x"`、`7`)⇒ `400 request.field_invalid`。三种都拒在 fork 之前(什么都没建)。
|
|
323
|
+
对账读新读面:`GET /v1/sessions/<forkId>/execution-placement` 答 `absent` / `writer` ⇒ 已 fork;`forking` ⇒ 没拷完,同键重试补齐;404 ⇒ 没 fork。
|
|
324
|
+
|
|
325
|
+
16. **壳 / 客户端的读法:四只新 409 与拒体新顶层键 `forkPath` / `boundLane` / `children` / `retirePath`;同一份日志重推到本处执行过的会话从 200 变 409(行为面)**:
|
|
326
|
+
· `409 conflict.session_mirror`(体 `forkPath`):会话是从别处导入的只读副本 —— 要在本处继续,`POST <forkPath>`(带 `{forkId, forkNonce}` 可重试)后在新会话上执行。
|
|
327
|
+
· `409 conflict.session_writer`:推送(`POST /v1/sessions/:id/sync/import` 与 `…/sync/import/:stagingId/entries`)打到本处写者 —— 本处执行过的会话,升级时有 run 行的会话都被回填成写者。
|
|
328
|
+
**内容完全相同的重推也是 409**(此前 `200 relation:"identical"`)。改为拉取(`GET …/sync/manifest` + `…/sync/entries`),或 fork 后推自己的副本;推之前可读一次执行放置读面(`writer` ⇒ 别推)。
|
|
329
|
+
· `409 conflict.fork_in_progress`(只 `DB_BACKEND=local`):目标是一次没拷完的 fork —— 用同一组 `forkId` / `forkNonce` 重试那次 fork,或删掉这只会话。
|
|
330
|
+
· `409 execution_lane.not_served`(体 `boundLane`):会话放在本部署已不再运行的车道上(升级之后运维换了 `REMOTE_EXEC`)—— fork 出新会话,新会话首跑落在当前车道。
|
|
331
|
+
· 子代半:换绑 `409 device.rebind_active_run`、推送 `409 session_active` 的体可以是 `{children, retirePath}`(根下有活后台子代)而不是 `{activeTaskId}`(根 run 在跑)—— 按键分支;
|
|
332
|
+
`POST <retirePath>` 结清后重试。
|
|
333
|
+
· 续跑家族(`/decide` · `/answer` · `/plan_review` · `/wake` 等)上,这些拒在认领之前一律折成 `409 resume_blocked_by_policy`,`blockedBy` = 原码,原拒体的键随行。
|
|
334
|
+
· 会话在受理与执行之间被删、或删后同 id 重登记:提交腿 `404 resume.session_not_found`(零 run 行);续跑腿认领前 `409 resume_blocked_by_policy`(`blockedBy: "resume.session_not_found"`)、
|
|
335
|
+
认领后 `404 resume.session_not_found`(那条停驻的 run 以 `failed` 收尾);停驻赎回仍答 `409 decide.not_parked`。
|
|
336
|
+
· device 车道:带 `resumeAt` 的提交,设备准入的拒(`device.*`)先于解锚的拒(`resume_at.*`)—— 锚错又点错设备答 `403 device.identity_mismatch`(此前 `404 resume_at.unknown_event`);
|
|
337
|
+
提交时读根会话行出故障答 500(此前 `409 device.not_bound`;设备注册簿读故障仍是 `409 device.not_bound`)。
|
|
338
|
+
|
|
339
|
+
17. **嵌入方(类型面,BREAKING;零别名):设备店的绑定四法换成两只放置写;自建 `StoreBackend` 的问店行与迁移报告多键;会话店、authorizer、`ServiceDeps` 各多可选位**:
|
|
340
|
+
标准起服零动作。自建装配的嵌入方:
|
|
341
|
+
① 经 `ServiceDeps.deviceStore` / `StoreBackend.device()` 交出的设备店:删 `getSessionBinding` / `bindSession` / `rebindSession` / `deleteByRootSession`,实现 `placeDeviceExecution`
|
|
342
|
+
(首绑:锁设备行 → 根会话行那一格的条件写)与 `rebindDeviceExecution`(换绑:锁设备行 → 同一事务锁根会话行、读认领,有认领答 `active_run` → 按住客 + 格上属主 + `rev` 的 CAS → 审计行)。
|
|
343
|
+
绑定不再住在设备店里:执行放置的唯一载体是会话店的执行席。经 `ServiceDeps.deviceEnrollment` 交出的准入链实现 `readPlacement`,`admitSession` 判调用方交来的那一读。
|
|
344
|
+
② 自建 `StoreBackend`:`approvalAsk()` 的问店铸行时写 `executionLane`、读回带它(必填;幂等命中别人插的行不改);`runOneTimeMigrations()` 的报告多七键
|
|
345
|
+
`executionPlacementColumnsAdded` / `deviceBindingsMoved` / `deviceBindingsOrphaned` / `deviceBindingTablesDropped` / `executionPlacementsBackfilled` / `askExecutionLanesBackfilled` /
|
|
346
|
+
`executionPlacementSessionsUnreadable`(点名行数组 `{ sessionId, fault, errno? }`,`fault` 是闭集 `corrupt_session` / `invalid_session` / `storage`,`errno` 只在 `storage` 时在场;只 local 非空;不跑这段迁移的后端答 0 / 空数组)。
|
|
347
|
+
③ `OwnerAwareSessionStore` 多两只可选席:`executionPlacement`(`read` / `place` / `markMirror`)与 `forkTo(sourceId, owner, { id, key? })`。不带执行席 ⇒ 不记放置(执行放置读面 501,
|
|
348
|
+
不判 mirror / writer);不带 `forkTo` ⇒ 带键的 fork 501。包根的 `createStoreBackend()` 造出的会话店都带。
|
|
349
|
+
④ 自建 authorizer:`AuthContext` 多可选 `head`(门判过的那一读);交了它,执行起点拿它与行上的住客比,不交就不比。包根的 `createAuthorizer` 交它。
|
|
350
|
+
⑤ `ServiceDeps.executionRuling`(可选,治理组):主体的执行车道裁定,执行起点的唯一输入;缺席 = 不判。
|
|
351
|
+
⑥ 包根导出型 `ExecutionContext` 的带根两形多 `occupant` / `placement` / `lane` / `device?`,服务形多 `lane` / `placement`;自建 `resolveSpec` 收的 `opts.execution` 仍只有 `{ kind, root }`(第 13 条)。
|
|
352
|
+
⑦ 直调 `DB_BACKEND=local` 会话店(`createStoreBackend(...).session()`)的 `importEntries` 只建新会话(与两只 SQL 后端同判):id 上已有行或格缺而存档在 ⇒ `SessionError("conflict")`、
|
|
353
|
+
一个字节不写(上一版 local 店在属主本人的既有行上原地换了日志;SQL 后端一直只建新行,撞已有行答 `storage`,不变)。改写既有会话用 `replaceEntries` 或暂存提交;HTTP 会话同步只走暂存提交,零动作。
|
|
354
|
+
|
|
355
|
+
18. **契约包 settings-schema 15.0.0 提货(部署面,行为收紧;零数据面改动,回滚 = 回上一版)**:
|
|
356
|
+
① **车道必需 env 的「缺」判法统一:未设、空串、只含空白一律按缺(所有车道、所有必需键同判)**。此前起服门只判真值,`SSH_HOST=" "` / `E2B_API_KEY=" "` 这类纯空白被当成写了、起服放行、到第一次用才失败;
|
|
357
|
+
现在 `REMOTE_EXEC=<车道>` 点了名而该车道的任一必需键(`E2B_API_KEY` / `K8S_SANDBOX_IMAGE` / `K8S_NAMESPACE` / `SSH_HOST` / `SSH_USER` / `SSH_PRIVATE_KEY` / `ADB_SERIAL` / `DOCKER_IMAGE`)是这三形之一 ⇒ 起服拒,
|
|
358
|
+
拒句点名缺的键并说 `unset, empty or whitespace-only — it counts as absent`(与契约包写闸对同一件事的拒句同一句话)。前后带空白但有内容的值原样放行(不 trim)。
|
|
359
|
+
**谁受伤**:必需键写成纯空白的部署(病态输入;典型是模板渲染留下的 `" "`、或只有换行的 secret 文件内容)—— 升级后起服拒;**出路**:填真值,或不点名该车道(`unset REMOTE_EXEC`)。
|
|
360
|
+
② **compose 用户:`K8S_NAMESPACE` 随根 `docker-compose.yml` / `docker-compose.review.yml` 透传,空串透传 = 按缺**。车道表把 `K8S_NAMESPACE` 列进 k8s 车道的必需栏,两份根 compose 的必需键透传区跟着多一行 `K8S_NAMESPACE: ${K8S_NAMESPACE:-}`;
|
|
361
|
+
`REMOTE_EXEC=k8s` 的 compose 用户必须在宿主环境或 `.env` 里填它(此前 compose 只透传镜像,命名空间要在 override 里自己加;本版起标准透传)。原来没设的部署设成 `sandboxes` 即与升级前逐字同(第 11 条)。
|
|
362
|
+
其它车道的 compose 用户零动作;随包 chart 与单文件栈清单本来就显式设了,零动作。`deploy/sema-up/lanes.json` 的 k8s 行 `env` 多一键 `K8S_NAMESPACE`(值恒 `null`;读这张表的 cli / web-admin 随表重算)。
|
|
363
|
+
③ **单机形 `config.d/remote-exec.json` 的 k8s 臂 `namespace` 必填(`CONFIG_PROVIDER=local`)**:契约包读侧对缺它的文件抛,起服沿既有「文件存在而坏 ⇒ 响亮拒」(不静默退回 host),拒句点名 `namespace`。
|
|
364
|
+
**谁受伤**:文件里写了 `"provider":"k8s"` 而没写 `namespace` 的单机部署;**出路**:补 `"namespace": "<沙箱 pod 所在的命名空间>"`(此前靠内置缺省的写 `sandboxes` 即与升级前同)。
|
|
365
|
+
④ **MCP 条目的 `sessionMetaKey` / `startupTimeoutMs` 从 `config.d/mcp.json` 与中心下发一路承运到引擎(行为面)**:此前这两把键在契约包读腿被剥掉并报 `unknown-keys-dropped`(没有效果),现在原样交给引擎。
|
|
366
|
+
存量里已经写着它们的条目:合格的值自此生效(引擎在发给这台服务器的每个 `tools/call` 的 `_meta` 里放会话 id / 这台服务器的握手与首次工具列举各带这个启动界);
|
|
367
|
+
不合格的:`sessionMetaKey` 坏形 ⇒ 这一条 server 整条不挂 + 一行 `web_admin_mcp_session_meta_key_invalid` 点名(兄弟照挂);`startupTimeoutMs` 坏值 ⇒ 引擎在拨号时只拒这一台、点名 `config.mcp_startup_timeout_invalid`(兄弟照挂)。
|
|
368
|
+
**出路**:删掉这把键,或改成引擎收的值(键名格式 / 整数毫秒的判官在引擎,本服务不另判)。
|
|
369
|
+
⑤ **中心形部署:升级本服务前,中心里存量 workers 文档的 k8s 行先补 `K8S_NAMESPACE`(契约包的部署序:先补键、后升级)**。本服务不消费 workers 域,但拉取腿的契约读法会解析线上载荷里带的 workers 域(整域读不进即抛);
|
|
370
|
+
中心给 worker 的 `/effective` 视图是否带这个域取决于中心,带的话缺命名空间的 k8s 行让拉取失败、本服务回落 LKG / env。**出路**:中心侧给每个 k8s 行补 `coords.K8S_NAMESPACE`(值 = 沙箱 pod 所在的命名空间)。
|
|
371
|
+
嵌入方(类型面,加性):`CenterMcpServer` 多可选键 `startupTimeoutMs`(`unknown` 承载形);自建装配零动作。
|
|
372
|
+
随 15.1.0 判官改 import,行为不变:① 里「空串 / 只含空白」的判法改调契约包根导出的 `isBlankCoordinate`,本仓只留「未设 = 缺」一臂;拒句、放行形、可选键同前,部署者零动作。
|
|
373
|
+
|
|
374
|
+
19. **嵌入方(构造期 + 类型面,BREAKING;零别名):接了停驻赎回腿的会话店必须带执行席;自写赎回面工厂的入参 `root` → `rootOccupant`**:
|
|
375
|
+
标准起服零动作 —— 接这条腿的部署(停驻底座在场)用的会话店一律带执行席。自建 `createHttpServer(deps)` 的嵌入方:
|
|
376
|
+
① 交了 `parkedReviveSurface` 的,`sessionStorage` 必须带执行席 `executionPlacement`:用包根 `createStoreBackend()` 交出的会话店(`backend.session()`;缓存 / 分叉路由包装原样转发)。
|
|
377
|
+
缺 ⇒ `createHttpServer` 构造期抛,拒句点名这一席。不接停驻赎回腿的,不交 `parkedReviveSurface`,会话店带不带席照旧。
|
|
378
|
+
② 自写赎回面工厂(`ServiceDeps.parkedReviveSurface`)的第二参从 `{ principal, root?: { before, after } }` 改成 `{ principal, rootOccupant }`:`rootOccupant`(`{ owner, incarnation }`,恒在)
|
|
379
|
+
= 认领之后写口放行的那一位根住客。根住客换没换已由写口判过(换了 ⇒ 决定答 `409 decide.not_parked`,工厂不被调用),工厂只判属主是不是卡的 principal。读旧名 ⇒ tsc 红。
|
|
380
|
+
③ 删一只有后台子代的根会话走服务端删除路径 `DELETE /v1/sessions/:id`(它先作废 / 停掉以该会话为根的子代,做完才删会话行)。直调会话店的 `deleteSession` 只删行、不结清子代:
|
|
381
|
+
子代的待决卡仍挂着,同一个 id 再登记之后,对旧卡的决定会复活到新住客的会话上。
|
|
382
|
+
|
|
383
|
+
20. **会话行条件写(wire 加性;行为变更两处;嵌入方类型面 BREAKING,零别名)**:
|
|
384
|
+
列表行(`GET /v1/sessions` 每一行、`PATCH /v1/sessions/:id` 的 200 行)多键 `rowTag`(不透明串,只原样回传);`PATCH` 体可带 `expectedRowTag: <读到的 rowTag>` ——
|
|
385
|
+
行仍是读到的那一份才写,否则 `409 conflict.session_row_changed`、一个字节不写,体 `currentRow` = 此刻的列表行(含新 `rowTag`)。不中一律 409:`currentRow` 的可写位已等于要写的值 ⇒ 视为已同步;
|
|
386
|
+
否则按它重新决定,再带它的 `rowTag` 发,**不要原样重发**。键形不对 ⇒ `400 request.field_invalid`;只带它、没有 `title` / `pinned` ⇒ `400 request.body_shape`。
|
|
387
|
+
**行为变更**:① 只读镜像会话(从别处导入、写者在别处)上的 `PATCH` 由 200 变 `409 conflict.session_mirror`(体 `forkPath`,与执行面同码同体;带不带键都一样)—— 要在本处改名,先 fork;
|
|
388
|
+
② 不带键的 `PATCH` 在处理中这只会话的属主被改(同一会话被认领 / 同步重戳)⇒ 404、不写(上一发布版照写)。
|
|
389
|
+
**自动重放的客户端**:带上 `expectedRowTag`;滚动升级窗里落到老副本 ⇒ `400 request.body_shape`(什么都没写)—— 待同步项留着稍后再发,不要去掉键重发。交互式「此刻改名」可以不带(仍是无条件写)。
|
|
390
|
+
**嵌入方**:会话店的行写口 `patchSessionMeta(id, patch, occupant)` 删除,换成 `writeSessionRowCells(id, cells, how)`:`how = { writer: "client", row: <core 行期望>, rowTag? }` 的结局是
|
|
391
|
+
`written`(带行)/ `changed`(带此刻的行)/ `mirror` / `absent`;`{ writer: "replay", row }`(会话同步的行重放)只有 `written` / `absent`。自实现会话店按新签名实现(判序:行期望 → 写者身份 → 标签 → 写,
|
|
392
|
+
判与写同锁);列表行型 `SessionListItem` / `SessionSummary` 多可选键 `rowTag`。用包根 `createStoreBackend()` 造的三种会话店都已带。没有数据面改动、没有迁移;回滚到上一发布版即恢复无条件写。
|
|
393
|
+
|
|
394
|
+
21. **配置源与留存扫车道的两条起服拒(行为收紧,fail-closed;零数据面改动;回滚 = 回上一版)**:
|
|
395
|
+
① `CONFIG_PROVIDER=remote` 而没设 `SEMA_WEB_ADMIN_URL` ⇒ 起服拒,拒句点名两键与出路
|
|
396
|
+
(`CONFIG_PROVIDER=remote names the web-admin center as this worker's config source, but SEMA_WEB_ADMIN_URL is not set — …`)。上一发布版这一形照起:HTTP 服务不建配置源、按纯 env 跑,
|
|
397
|
+
`run-local` 读本地 `config.d`,两处都零句。**升级前自查**:写了 `CONFIG_PROVIDER=remote` 的部署(含按多租 profile 渲出来的)确认 `SEMA_WEB_ADMIN_URL` 在场 —— 要中心就补地址;
|
|
398
|
+
本就靠 env / 本地 `config.d` 跑的,改成不设 `CONFIG_PROVIDER`(纯 env)或 `CONFIG_PROVIDER=local`。`run-local`(`sema` CLI)只装本地配置源:写了 `CONFIG_PROVIDER=remote`(配没配中心地址都一样)
|
|
399
|
+
⇒ 一行拒句、退 2;共享 `.env` 里带这个词的,给 CLI 去掉它或写 `local`(没写词时 CLI 自己写 `local`)。
|
|
400
|
+
② 被要的留存扫车道必须齐:`RETENTION_MODE=enforce` 或 `RETENTION_SWEEP_INTERVAL_SEC > 0` 都是在要车道,要了就得有 `RETENTION_MAX_AGE_DAYS` 且节律 `> 0`;缺一 ⇒ 起服拒,拒句点名缺的键与出路。
|
|
401
|
+
上一发布版:enforce 而节律缺 / 为 0 照起、什么都不删、`capabilities.retention` 为 `null`(给了天数的只有一行 warn —— 7.138.0 节第 13 条「关着、配了没锁的策略」那一形,enforce 档下改为拒);
|
|
402
|
+
节律在而天数缺在装配第 6 段(一次性迁移之后)拒,本版在第 1 段拒、拒句换成本条的句子,拒的那一次起服不碰库。**升级前自查**:写了 `RETENTION_MODE=enforce` 的部署确认天数与 `> 0` 的节律都在
|
|
403
|
+
(车道跑在 SQL 后端上);本就不删的改 `RETENTION_MODE=audit-only` 或不设(节律 `> 0` 而没给天数的,同时把节律设 0)。`audit-only` 下给了天数而车道关着照起,warn `retention_policy_not_executed` 多两个字段 `mode` / `retentionSweepIntervalSec`,
|
|
404
|
+
说明句只说「节律缺或为 0」这个真因 —— 按旧说明句匹配告警的改读字段。
|
|
405
|
+
运营目录 `GET /v1/config/catalog` 的 `CONFIG_PROVIDER` / `RETENTION_MODE` / `RETENTION_SWEEP_INTERVAL_SEC` 三行 `semantics` 写出这两条拒启条件。
|
|
406
|
+
|
|
407
|
+
22. **会话规则 / 持久规则桶的文法戳 7(升级序:先升全部读者,再放写;回滚前见下)**:本版写下的会话规则行、SQL 后端 `permission_rule` 的规则桶与规则同步状态都盖文法戳 `7`
|
|
408
|
+
(零 DDL:`grammar` 列早已在)。意思动在拒绝 / 询问桶里身上带 `__` 的 MCP 名:`mcp__a__b` 同时拒 server `a` 的工具 `b` 与 server `a__b` 的每一只工具(限制只会变宽,放行不变;
|
|
409
|
+
放行表里的条目:本轮工具名单里没有这只精确名、却有另一种 server 拼法下的工具时,按引擎的句子点名、不放任何一只 —— 写成铸出的拼法 `mcp__a_b__<工具>`;名单里有这只精确名的工具则照放这一只)。戳 6 及更早的**会话规则行**保留写者的意思(精确名只拒那一只工具),
|
|
410
|
+
每层通告一次 `config.session_rules_earlier_grammar`;**持久规则桶**不留旧读法:戳 6 的桶里的整工具 `mcp__a__b` 按文法 7 读(更宽)。7.138.x 及更早的副本读不了戳 7 的行 / 桶 ——
|
|
411
|
+
整只拒,不按旧文法逐条读(会话行:那条会话每一次调用都拒;规则桶:载零条、拒每一次写,报 `permission_rules.later_grammar`;规则同步:整轮拒)。本版本就要求先停光旧副本再起(SQL 执行放置切换),
|
|
412
|
+
所以混跑窗口不出现;回滚到 7.138.x 只有恢复备份一条路(第 14 条),**不要**在库里把戳改小。
|
|
413
|
+
|
|
414
|
+
23. **执行环境的写入改成「暂存 → 一次提交」(行为面;七条车道一条规则;零配置)**:`writeFile` 是整文件替换 —— 整旧或整新,取消 ⇒ 目标未碰;
|
|
415
|
+
host 车道委托引擎的整文件替换,ssh / adb / local-docker / k8s / e2b 先在目标目录下建一只生来 0700 的私有目录 `.<名>.stage-<12 位十六进制>/`、
|
|
416
|
+
把整份传进去,再在目标机上一次 `mv -f`;`appendFile` 只暂存要加的字节、提交是一次 `cat >>`(inode 不换)。
|
|
417
|
+
**暂存自创建起不比目标更可读**:替换一只 0600 的文件时,新内容在传输期间只有写入方(与 root)读得到(私有目录别的用户进不去;
|
|
418
|
+
本机侧 adb 推送前落的临时件同样在私有目录里);host 车道的这一保证在引擎原语里:引擎 7.60.0 起目标存在时暂存件以 0600 打开。
|
|
419
|
+
准备目录、上传、提交、清理是同一个身份:**local-docker 的上传改由容器内以镜像的用户经 stdin 收字节**,不再由守护进程的 `docker cp` 以 root 落盘
|
|
420
|
+
—— 镜像用户 ≠ root 时,写文件与代理的 shell 同一套权限:镜像用户写不了的路径照实拒 `permission_denied`(7.138.x 的 `docker cp` 以 root 写得进)。
|
|
421
|
+
部署零动作;以下几处语义变了,依赖它们的先核:
|
|
422
|
+
① **硬链接被断开**:替换之后另一条硬链接留旧内容(与引擎 / 参照实现同形);
|
|
423
|
+
② **没有写权限位的文件在可写目录里会被替换**(权限位保留;修前就地写被拒 `permission_denied`)—— 防代理改文件靠写门 / 写保护规则,不靠权限位;
|
|
424
|
+
③ 替换后的文件**属于写入方**(属主不随原件);
|
|
425
|
+
④ **host 车道上名字超过约 230 字节(随服务进程号的位数浮动)的文件写不进**(引擎的暂存名超出 255 字节上限 ⇒ `unknown` / `ENAMETOOLONG`;远端五车道不受影响)—— 已知缺口,修在引擎;
|
|
426
|
+
⑤ 目标目录里可能见到一只没清掉的隐藏目录 `.<名>.stage-…/`,可以直接删:一是中断之后清理那一次往返也失败(失败的写的错误句会点名它);二是写已经成功、
|
|
427
|
+
却因文件系统为仍打开着的文件留了隐藏项(NFS 的 `.nfsXXXX`、FUSE 的 `.fuse_hidden*`、SMB 的待删)而删不掉目录 —— 写照常成功,只在服务的遥测里记一条
|
|
428
|
+
`server.remote-write.staging-dir-left`(不进错误句);
|
|
429
|
+
⑥ 远端车道的写多一次往返(提交;e2b 多两次:建私有目录 + 提交);
|
|
430
|
+
⑦ local-docker:镜像用户 ≠ root 的部署,代理以前靠 `docker cp` 的 root 身份写得进、镜像用户自己写不了的路径(例如 root 的目录里不归镜像用户写的文件)
|
|
431
|
+
现在答 `permission_denied` —— 要写那些路径,让镜像用户有权限(或镜像就以 root 跑);local-docker 新建的文件属镜像用户、权限位按容器内的 umask(以前属 root)。
|
|
432
|
+
**最常见的一处是工作区根本身**:镜像里没有这只目录时,容器启动(`docker run -w <工作区>`)以 root 建出它(root 所有、0755)——
|
|
433
|
+
镜像用户 ≠ root 的部署,写工作区里的文件从本版起答 `permission_denied`(代理的 shell 在 7.138.x 就写不进那里,只有写文件经 `docker cp` 写得进)。
|
|
434
|
+
**升级前做**:镜像里预建工作区目录并归镜像用户(例如 `RUN mkdir /workspace && chown <镜像用户> /workspace`;已有的目录启动时不改属主),或让镜像以 root 跑。
|
|
435
|
+
⑧ **私有暂存目录收不成私有时退回就地写,不再静默暂存**:准备那一步把刚建的目录收成 0700 并读回核实(模式、属主);核不过 —— `chmod` 被拒、文件系统不认权限位、
|
|
436
|
+
父目录的缺省 ACL 掩码收不下来、目标机上没有 `stat` —— 这一次写**不暂存**,退回就地写目标(与「目录不收新名字」同一条退路:非原子;取消落在写目标那一步开始之前(读旧也在这之前)⇒ `aborted`、目标未碰;写目标那一步因取消中断 ⇒ `unknown`、目标可能只写了一半(那一步自己的通道准备也算在内,保守);那一步不收取消(ssh 的 sftp)⇒ 照样写完、答成功;
|
|
437
|
+
ssh / local-docker / k8s 写进原 inode、权限位不变,e2b 的 `files.write` 与 adb 的 `adb push` 整份写目标、inode / 权限位由对端定),并在遥测里记 `server.remote-write.stage-seal-fallback`(计数非零 = 这个目录上的写都在走非原子退路,去看那个目录)。
|
|
438
|
+
**adb 两面在私有目录收不成私有时退回 7.138.x 的形**(写 = 整份 push 到目标;追加 = 读旧 + 拼 + 整份 push;非原子,中途断目标可能没了或只剩半份;`adb push` 不保 inode / 权限位,与 7.138.x 同形)
|
|
439
|
+
并计 `stage-seal-fallback`。Android 共享存储(`/sdcard` 一类:权限位由挂载派生、不认 `chmod`)上 adb 的写按 sdcardfs / MediaProvider FUSE 的权限语义**推断**每一次都走这一形(未上真机,真机读数候 test)—— 把 adb 的工作区放在 `/data/local/tmp` 一类认权限位的目录即照常暂存。
|
|
440
|
+
以前这一步的失败被吞掉、字节照样放进一只没核成私有的目录。
|
|
441
|
+
已知缺口:目标机是 macOS、且工作区父目录带继承的**原生 ACL 允许条目**时,模式位挡不住那个条目(读回 `700` 也一样);FreeBSD / illumos ZFS 的 NFSv4 ACL(`aclmode=passthrough`)同类 ——
|
|
442
|
+
这类目录上暂存件对那个条目可见,替换之后目标带的是继承来的条目、不是原件自己的 ACL(比 7.138.x 的就地直写宽:就地写不换 inode,原件的 ACL 不变);本版不另造探测臂。
|
|
443
|
+
回滚到 7.138.x:零数据面动作(暂存名是瞬时的)。
|
|
444
|
+
|
|
445
|
+
24. **本机宿主车道(`REMOTE_EXEC=host`)上 workflow 子代的 `isolation: "worktree"`(已知变化;行为面)**:本版的引擎(7.60.0)在这条车道上按宿主读,worktree 子代按物理路径比对、「它自己的目录」即收;
|
|
446
|
+
上一发布版这条车道上这一形一律拒(`isolation.unavailable`)。本版的读法:
|
|
447
|
+
① **配了包装**(`WORKTREE_ISOLATION_ENABLED=true` 且 `WORKTREE_REPO_ROOT` 指向一个 git 仓):包装铸的 worktree 被收,workflow 子代 `agent(spec, { isolation: "worktree" })` 照跑
|
|
448
|
+
(读已提交副本、调用方检出零写)—— 上一发布版这一形仍拒;
|
|
449
|
+
② **没配包装**(或仓根不存在 / 里面没有 `.git`、包装被起服关掉 —— 起服日志 `worktree_isolation_disabled_bad_repo_root`;`.git` 在而仓坏的,包装照开、铸树时 git 自己报错):本服务的 host 工厂在铸环境之前拒,码 `isolation.unavailable`,句子点名两只开关,子代零轮 ——
|
|
450
|
+
**与上一发布版同码同句形**。不拒的话引擎的新读法会收下一只本服务新铸的空临时目录:子代读不到项目里任何文件,照烧 token,结果照交回。要在这条车道上用 workflow 的 worktree 隔离,配包装;
|
|
451
|
+
③ 引擎 7.61.0 起这一形由引擎自己拒,本服务的这一臂到那一版随提货删,届时码与句子随引擎。
|
|
452
|
+
委派工具形(`Agent({ isolation: "worktree" })` / `agents[].isolation`)不受这一拒影响:worktree 由引擎自己铸,子代的根经 `parentCwd` 交给工厂,工厂收不到 `isolation` 提示。部署零动作。
|
|
453
|
+
|
|
10
454
|
## 7.138.0 —— MCP / A2A 的凭据件改由部署的对端座在发送时作答(行为面;件的形更严;嵌入方 `ServiceCoreDeps.peerDesk` 必填,BREAKING)· 🔴 SQL 后端 `session_meta` 加 `workspace` 列、`mailbox_message` 加 `record_id` 列(升级前先加列)· 请求 `projectId` 与检出记号不等 ⇒ 409 · 记忆同步:升级前写的旧游标 ⇒ 该层停同步直到运维一步(两条出路)· settings hook 子环境维持十二名边界 · 抹除授权集与收执 v2 · 已知缺口:会话级子代在父腿作用域结束后首拨 / 再问被座拒 · 引擎 7.59.0
|
|
11
455
|
|
|
12
456
|
1. **SQL 后端:`mailbox_message` 表加一列 `decision`(🔴 升级前先加列;持久数据,不能删表重建;引擎 7.57.0 的邮箱留置决定)**:
|
|
@@ -56,6 +500,9 @@
|
|
|
56
500
|
`POST /v1/sessions/:id/wake` 与 `/decide` 交给宿主的回执(workflow 子代的审批)不带。**读法**:「已提交」只读 `decisionCommitted === true`,缺席按「没提交」读;
|
|
57
501
|
它与 `errorCode:"cancelled"`、`retriable:true` 并存时照样成立,不说明卡的当前状态;`retriable:true` 只说「这一跑已重新停驻,请重读待决列表」。
|
|
58
502
|
经 `POST /v1/tool-approvals/:id/respond` 迟到兑现的停驻卡:同向重试的回放带两键,反向重试的回放(回放首次那一向)不带。
|
|
503
|
+
**同一张卡同向的并发 / 重发请求**:拿到 200 回放体(`idempotent: true`)的,是受理者之后到、而回执(或在飞的赎回)还在的那些 —— 迟到兑现的卡上回执只在受理它的那一副本上、有界(换副本 / 重启 / 被逐 / 过期之后再来的是新一次赎回,答 `409`,终局不变、不会双兑);
|
|
504
|
+
`POST /v1/approvals/:id/decide` 上,首决已落行之后到的同向重发答回放体,与首决真正重叠的输家答 `409`(`conflict.not_resumable` 或 `checkpoint.already_resolved`)。拿到回放体时:迟到兑现的卡上它带着受理体的成员(`status: "resuming"`、`taskId`、两键),
|
|
505
|
+
所以分清受理者**只看 `idempotent` 是否在场**(缺席 = 受理者),别拿 `status` / `taskId` 数「起了几跑」(回放不起续跑);`/decide` 的幂等回放体则不带 `taskId` / `status` / `checkpointId`(带 `decisionCommitted: true`),要结果面读 `GET /v1/runs/:id`。
|
|
59
506
|
**竞态收紧**:决一张后台子代的停驻卡时,若这只子代在你决断的同一刻被别处续过、又在新的卡上停驻,本版答 `409 decide.gate_moved`(此前把决定交给了那张新卡)
|
|
60
507
|
—— 重拉待决列表、对新卡再决。
|
|
61
508
|
**升级前做**:用封闭 schema 校验这些 200 体的调用方(多余键即拒)把两键加进可选键;其余零动作。**升级后看**:选中那一行的门身份读不出时,既有计数
|
|
@@ -82,7 +529,7 @@
|
|
|
82
529
|
此后也挂部署座 —— 拒绝计量计入这些腿上的拒绝(拒绝计数的看板会多出 leader 腿的那一份);`TOOL_TRACE=true` 时它们的工具调用也写追踪行、系统提示多出引擎的钩子段
|
|
83
530
|
(与主车道同配置的腿同读;此前这条车道漏挂)。
|
|
84
531
|
**要装包的部署**:① 把包放进只读物料树(镜像层 / 只读挂载),`MODS_ROOT` 指它;② 包是**受信的部署代码**,在本进程里跑、可触全部租户与进程凭据 —— 多租户部署上声明的包对全体租户生效,
|
|
85
|
-
|
|
532
|
+
准入不是沙箱,只装你审过的包;包若在 `PreToolUse` 上答 `allow`(可带 `updatedInput`),引擎仍按最终参数裁决,运维旋钮要问或要拒的(`APPROVAL_REQUIRE` / `APPROVAL_NEVER_AUTO` / `MANUAL_MODE_SHELL_GATE=always` / `governance.commandPolicy` 的问档与拒档等)与引擎强制的问句不因它改变,但**未被强制的**缺省审批问句它能清掉 —— 装包就是把这一类问句的决定权交给包作者;要某类调用无论包怎么答都问人,用这些旋钮声明;③ 包按「自包含」构建(执行代码全在 `hooks/register.mjs`,不另 import 包内文件、不读运行时资源),`register` 确定、可重复、不留进程副作用(引擎在每条腿再调它);
|
|
86
533
|
④ 改声明或换包要重启(配置刷新不重载,也没有自动重启信号);滚动升级期间新旧副本可以并存 —— 声明只在设了它的新副本上生效,停驻的任务在哪只副本续跑就按那只副本当下的部署座再准入。
|
|
87
534
|
**升级后看**:起服日志每包一行 `mods_package_loaded { name, tier, contract, digest }`(`digest` 是引擎读包者读的三件文件的字节摘要,认得出装的是哪几份字节,不是代码完整性凭据);`/health.mods.deploymentPackages` 与能力位 `modsDeploymentPackages`;每条腿 `wiring_manifest.mods[]` 有那只包一行(`seat: "deployment"`、`provenance: "operator"`;本服务自铸的注册那几行带 `provenance: "server"`)。
|
|
88
535
|
**起服拒句换形(运维面,非 wire)**:部署座准入被拒此前是 `deployment extension registration refused: <引擎句>`,现在是 `deployment mods refused: admission_refused[(<引擎码>)]: <引擎句>` ——
|
|
@@ -167,7 +614,7 @@
|
|
|
167
614
|
**Who is hurt**(对上一发布版;① ② ③ ⑤ ⑧ 是「那一台不再连上、兄弟照挂、提交照收、运行期才见」:连接期 `wiring_manifest.mcp[].errorCode` / 调用期 `tool_end.errorCode` = `credential_unavailable`,A2A 一侧只有文本;因件的形被引擎读器拒的那一台,服务端没有对应的拒行,看这些码 / 文本;`peer_seat_refused` 只在本服务的座自己拒时才有 —— 引用不在表里 / 绑定不符 / 引用种类座不答):
|
|
168
615
|
① stdio 件值含 CR / LF / NUL(多行 PEM、尾换行的 Secret);② stdio 件名不是标识符形(`ODD.NAME`、`MY-VAR`);③ MCP http 的件头名是传输自己写的头(`content-type` · `accept` · `mcp-session-id` · `mcp-protocol-version` · `last-event-id`);
|
|
169
616
|
④ MCP 或 A2A 条目的 `principalHeader` 取引擎的断言头名 `connector-assertion`(任何大小写)—— **新提交 `400 request.field_invalid`**(此前受理:上一发布版的引擎只查身份头名与静态头重名);⑤ stdio 的秘密形件(变量名被引擎认作凭据名)的值恰等于一只每个子进程都会继承的变量的值;
|
|
170
|
-
⑥ 嵌入方(下一条);⑦ MCP 条目的 `principalHeader` 取传输自己写的头名(`mcp-session-id` · `mcp-protocol-version` · `content-type` · `accept` · `last-event-id`,任何大小写)—— **入口 400**,与 ④ 同一道门、同一个码,点名 `mcpServers[i].transport.principalHeader
|
|
617
|
+
⑥ 嵌入方(下一条);⑦ MCP 条目的 `principalHeader` 取传输自己写的头名(`mcp-session-id` · `mcp-protocol-version` · `content-type` · `accept` · `last-event-id`,任何大小写)—— **入口 400**,与 ④ 同一道门、同一个码,点名 `mcpServers[i].transport.principalHeader`,拒句里的头名是引擎固定表里的规范化(小写)名,不回显调用方写的原串 / 大小写形(调用方写的恰是小写时,句里的名与所写相同)
|
|
171
618
|
(A2A 没有传输自有头名表,A2A 只中 ④);⑧ http 件值首尾带 CR / LF(Secret 文件的尾换行;此前由发送时的头规范化吞掉,现在读器拒)。④ ⑦ 的耐久 resume 重放存量体不 4xx:MCP 照挂(引擎拨号时拒那一台),A2A 那一条对端整条不进(warn `a2a_injection_dropped` 点名)。
|
|
172
619
|
另:⑨ 会话级子代(http / stdio)的已知缺口见第 25 条;⑩ **扣留次序**:引擎把座答里认作凭据的 http 头值与 stdio 秘密形件值记为自己持有的凭据值(服务进程环境里同值的变量不再交给模型可驱动的 host shell 子进程;MCP stdio 子进程只继承 MCP SDK 的少数默认变量〔`HOME` · `LOGNAME` · `PATH` · `SHELL` · `TERM` · `USER`〕与座给的件,拿不到服务进程环境的其余变量),
|
|
173
620
|
次序是先过读器、放行了才记 —— 被读器拒的形(件值含 CR / LF / NUL、头名不是 HTTP token、两个头名只差大小写、变量名不是标识符形)的值不进扣留表:那一台失败,环境里同值的变量仍交给 host shell 子进程(上一发布版先记后判,同样的形值已在表里);MCP 传输自己写的头名(③)在读器之后的协议层才拒,值此时已在表里。补偿:名册 `headerRefs` 指向的变量值去掉尾换行;件值别与长期留在服务进程环境里的变量同值而又带读器拒的形。
|
|
@@ -3654,7 +4101,7 @@ wire 面(同步提交撞 park 的 200 体、`GET /v1/runs/:id` 行形、同一
|
|
|
3654
4101
|
- **记忆抹除面的 409 `memory.layer_unwritable` 撤销(随 core 7.31.0 提货;wire 码删除 + 行为面)**:`POST /v1/memory/erase`、`POST /v1/memory/origin/entries/:entryId/clear`、`POST /v1/sessions/:id/memory/erase` 不再在引擎之前做盘上可写预检,这个码不再出现(7.100.0 那条「按 409 体 `chmod u+w <dir>` 后重试」的指路随之撤)—— core 7.31.0 的挂载**一个模式位都不改**(只读层是会话策略:往会话不写的层里写在写点被拒,绕过工具写进去的字节永不被采纳)。7.100.0 上被 409 盖住的三种答复回到 core 自己的读数(非法选择子 400 `config.memory_erasure_request`、清标空理由 422 `memory.origin_clear_invalid`、已提交抹除同 `requestId` 重放的 200 收执),锁住的是别的层时抹除可写层条目照常 200。**升级(一次性)**:存量已锁目录在**最后一个 ≤7.30.x 会话结束后**(= 7.100.0 及更早的 server 副本全部停掉之后)执行 `chmod -R u+w <memoryDir>`(file 记忆引擎的 `<数据根>/memory`)—— 混跑期旧引擎每次只读挂载都会再锁一次,7.31 不替你解。**谁受伤**:没做这一步、又去删一条住在锁住目录里的条目的部署 ⇒ `500`(日志带 core 的同一条 `chmod -R u+w` 补救句),journal 留盘、下次起服失败,照补救句做完即自愈(`docs/DEPLOY-PREREQS.md` 同名段)。**滚动窗内这一形会反复出现**:同一数据根上还有 7.100.0 及更早的副本在跑时,它每次只读挂载一层都会把那一层再锁一次 —— 窗内做过的 `chmod` 会被撤回,7.101.0 副本在那一层上删条目照样 `500` + journal 卡盘。7.101.0 起服时对记忆挂载面探一次:有锁住的层 ⇒ 一条 warn(`engine_notice`,码 `memory.layer_locked_legacy`,`detail.layers` = 层名、`detail.remedy` = 同一句 `chmod -R u+w '<memoryDir>'`),**照常起服**(不拒启:窗内每次 boot 都可能刚被旧副本锁过);看到这一行就先别在那几层上抹除 / 清标,等旧副本全停后执行那一句。按码分支 `memory.layer_unwritable` 的消费方(sdk 错误码目录)删掉那一臂。
|
|
3655
4102
|
- **settings 层里残留的 `crossSessionInbound: "accept"` ⇒ 跨会话消息 hold(core 7.31.0,行为面)—— 本服务不受影响(只 env 层接线)**:本服务三层来源里只有 env 管理层 `CROSS_SESSION_INBOUND` 接线(user / repo 两层不读),而 env 写 `accept` 自 7.100.0 起就拒启 ⇒ 下面这一形只波及**自持 settings 层的嵌入方**。7.30.x 把这个退役词读成 `next-turn` 并每腿通告一次(7.100.0 本节那句「由引擎自己读成 `next-turn`」随之过期);7.31.0 起它与任何未知词同路 —— 该层进 `invalidLayers`、fail-closed 落 `hold`(每条跨会话消息以 `invalid-setting` 因由扣住,`peer.inbound_disposition` 披露 `held`)。env `CROSS_SESSION_INBOUND=accept` 自 7.100.0 起就拒启,不受影响;`@sema-agent/settings-schema` 6.0.0 的文件层本就拒这个词,所以只有绕过 schema 写进去的 settings 文件会撞上。**迁移**(仅嵌入方):把每一层的 `accept` 改写成 `next-turn`。
|
|
3656
4103
|
- **子进程剥名收窄(core 7.31.0,运行面;7.100.0 本节「子进程按名剥凭据形变量」一条的修正)**:十个预算名(`MAX_NEW_TOKENS` `MAX_COMPLETION_TOKENS` `AIDER_MAP_TOKENS` `AIDER_MAX_CHAT_HISTORY_TOKENS` `MAX_BATCH_PREFILL_TOKENS` `MAX_WAITING_TOKENS` `MAX_TOP_N_TOKENS` `RATE_LIMIT_TOKENS` `PROMPT_TOKENS` `CONTEXT_TOKENS`)与两个开关(`DB_FOREIGN_KEYS` `JSON_SORT_KEYS`)按**精确名**豁免,重新到得了工具子 shell、git 子进程与本地语言服务器;装饰过的变体(`USERS_MAX_NEW_TOKENS`、`MAX_NEW_TOKENS_2`)仍剥。为这五名改过名的部署可以撤回那一手(留着也无害);`inheritEnv:[names]` 是嵌入方构造执行环境时的选项,不是部署级放回旋钮(7.104.0 起文档写明)。
|
|
3657
|
-
- **SQL 后端:`session_meta` 新列 `instruction_source`(存储面)**:存量 MySQL 协议 / PostgreSQL 库升级后**拒启**(`config.schema_mismatch`,拒因里逐字给出 `ALTER TABLE session_meta ADD COLUMN instruction_source VARCHAR(64) NULL;`,PG 为 `… VARCHAR(64) COLLATE "C";`)
|
|
4104
|
+
- **SQL 后端:`session_meta` 新列 `instruction_source`(存储面)**:存量 MySQL 协议 / PostgreSQL 库升级后**拒启**(`config.schema_mismatch`,拒因里逐字给出 `ALTER TABLE session_meta ADD COLUMN instruction_source VARCHAR(64) NULL;`,PG 为 `… VARCHAR(64) COLLATE "C";`),照它加列(由部署者自己执行;列集对账与拒启句永不改库);滚动序恒为「**先升库、再升副本**」(加列之后,旧副本重启会把它看成幽灵列而拒启)。`DB_BACKEND=local` 与内存形零动作。见上方「SQL 存储面 BREAKING」表。
|
|
3658
4105
|
- **沙箱名单形错拒启 + 空串值照注入(行为面)**:`E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` 写了空段、尾逗号(`A,`)、带 `-` / `.` 的键名(`MY-TOKEN`)或点名名单型旋钮(自己 / 另一只沙箱名单 / `LSP_ENV_ALLOW`)⇒ **拒启**(拒句点名键与第几段,不回显原值;修前静默吞或照转发)。点到的键值为空串(compose `X=${X:-}` 在宿主没设时的常态)⇒ **照注入空串**(修前不注入):local-docker 上 `-e X=` 盖掉镜像里的同名缺省值,e2b 上盖掉 `SANDBOX_PKG_SOURCE` 推导出的同名包源变量。**迁移**:按拒句修名单;不想盖缺省值就把那个名从名单里删掉。
|
|
3659
4106
|
- **`WEB_SEARCH_ENDPOINT` 带 userinfo ⇒ 拒启(行为面)**:`WEB_SEARCH_PROVIDER` 点名了后端、`WEB_SEARCH_ENDPOINT` 形如 `https://user:pw@host/…`(或只带 `user@`)的部署升级后拒启(`config.web_search_invalid`);每请求 `settings.webSearch.endpoint` 带这一形从 202 变 `400 request.field_invalid`(修前这一形本来就用不了:fetch 每次都抛,错误文本还带出口令)。**迁移**:brave / tavily 的凭据走 `WEB_SEARCH_API_KEY`(或 `settings.webSearch.apiKey`);带 basic-auth 的 SearXNG 在前面放一层注入鉴权的反代。
|
|
3660
4107
|
- **配置目录两行 `csv` → `secret`(wire 形变)**:`GET /v1/config/catalog` 的 `E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` 两行 `type` `csv` → `secret`、`valueClass` `plain` → `secret`、`effectiveValue` 从名字数组变 `{ present }`,`summary.secret` 计数 +2。读这两行名单内容的消费方改读起服行 `remote_exec_enabled.sandboxEnvKeys`(只键名);这两只旋钮的原文从此也不进 host shell / git 子进程 / 语言服务器(在这些子进程里读它们的脚本收不到了)。
|
|
@@ -3680,16 +4127,19 @@ wire 面(同步提交撞 park 的 200 体、`GET /v1/runs/:id` 行形、同一
|
|
|
3680
4127
|
|
|
3681
4128
|
## SQL 存储面 BREAKING(3.0.0 之后;列增批自 7.101.0 起入表)
|
|
3682
4129
|
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
4130
|
+
**常设口径**:代码是 schema 的唯一真源,启动 DDL 里没有 `ALTER TABLE` 增量 seam;列集对账与拒启句永不改库 —— boot 对旧形
|
|
4131
|
+
schema **拒启并打印要执行的 `ALTER TABLE … ADD COLUMN …`**,不会静默跑在错形表上。进程自己对已存在的表发的 DDL 只有两种:幂等加索引(只动索引、不碰列)与
|
|
4132
|
+
登记在册的一次性迁移(每条有窗、有登记行);加列 / 改列 / 改名 / 删表只有一次性迁移做。出路是闭集三条,没有销毁性的一条:
|
|
4133
|
+
部署与这个库匹配的构建;库比构建旧(缺列)⇒ 部署者自己执行拒启句打印的 `ALTER`;库比构建新(多列)⇒ 部署持有那些列的构建(先升库、再升副本)。
|
|
4134
|
+
下表前三行是预生产期(零存量用户窗口)各版当年的升级动作,保留作历史;今天的升级动作以拒启句为准。
|
|
4135
|
+
只用 file/local 存储形(未配 SQL 后端)的部署不受本节任何条目影响。
|
|
3686
4136
|
|
|
3687
4137
|
| 窗 | 变更 | 升级动作 |
|
|
3688
4138
|
|---|---|---|
|
|
3689
4139
|
| **7.6.0**(2026-08-08) | SQL 双端归一化第一刀:隔离键排序规则钉死(MySQL 腿表级 `COLLATE utf8mb4_bin`/PG 腿逐列 `COLLATE "C"`)+索引名 36 条+列名/宽度收窄 | **删库重建**(两方言) |
|
|
3690
4140
|
| **7.8.0**(2026-08-09) | SQL 命名三轴归一化第二刀:9 张表名单数化、epoch 毫秒列补 `_ms` 后缀 5 列、approval 两表 `version→rev`;wire 面零变化 | **删库重建**(两方言) |
|
|
3691
4141
|
| **7.14.0**(2026-08-12) | `tool_result` 换代(随 core 5.26.0 的 ref 格式换代):ref 四段单射形、主键 `VARCHAR(190)→518`、新增出处两列 `owner_session_id`/`owner_task_id` | 升级前两方言 **`DROP TABLE tool_result`**(不删=boot 拒启;offload 产物是可恢复窗缓存,转录内联预览不受影响) |
|
|
3692
|
-
| **7.101.0** | `session_meta` 新列 `instruction_source VARCHAR(64) NULL`(PG `COLLATE "C"`;项目指令换源通告的基线) | 两方言按拒启句里给出的 `ALTER TABLE session_meta ADD COLUMN …`
|
|
4142
|
+
| **7.101.0** | `session_meta` 新列 `instruction_source VARCHAR(64) NULL`(PG `COLLATE "C"`;项目指令换源通告的基线) | 两方言按拒启句里给出的 `ALTER TABLE session_meta ADD COLUMN …` 由部署者自己加列;**先升库、再升副本**(加列后旧副本重启见幽灵列拒启) |
|
|
3693
4143
|
|
|
3694
4144
|
> 列增批此前只记在 CHANGELOG / `docs/DEPLOY-PREREQS.md`(7.92.0 `session_policy`、7.93.4 `approval_ask.settled_by` 各加过一列),自 7.101.0 起同样入本表。7.101.0 这一列的拒启句自带可粘贴的 `ALTER`,本仓仍不替你执行。
|
|
3695
4145
|
|