@sema-agent/server 7.145.0 → 7.146.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 +492 -0
- package/USAGE.md +218 -47
- package/deploy/facts/CHANGES.json +25 -0
- package/deploy/facts/README.md +57 -0
- package/deploy/facts/lanes.json +54 -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/chart/templates/_helpers.tpl +19 -0
- package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +47 -7
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +4 -0
- package/deploy/sema-up/chart/templates/server.yaml +4 -0
- package/deploy/sema-up/chart/values.yaml +7 -0
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +30 -14
- 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 +3 -12
- 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/boot/deployment-mods.d.ts +11 -1
- package/dist/boot/deployment-mods.js +15 -2
- package/dist/boot/device-lane.js +2 -0
- package/dist/boot/engine-lease.d.ts +193 -21
- package/dist/boot/engine-lease.js +146 -20
- package/dist/boot/execution-env.d.ts +4 -0
- package/dist/boot/execution-env.js +12 -0
- 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 +21 -4
- package/dist/boot/governance-seams.js +1 -0
- package/dist/boot/memory-consolidation.d.ts +29 -17
- package/dist/boot/memory-consolidation.js +26 -15
- package/dist/boot/reapers.d.ts +12 -4
- package/dist/boot/reapers.js +39 -15
- package/dist/boot/resolve-spec.d.ts +2 -0
- package/dist/boot/resolve-spec.js +38 -15
- package/dist/boot/runner-deps.js +1 -1
- package/dist/boot/session-faces.js +3 -1
- package/dist/boot/shutdown.js +27 -9
- package/dist/boot/stage-01-config.js +1 -1
- package/dist/boot/stage-03-store-backend.d.ts +1 -0
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -0
- package/dist/boot/stage-05-execution-env.d.ts +3 -0
- package/dist/boot/stage-05-execution-env.js +3 -3
- package/dist/boot/stage-06-runners.d.ts +3 -0
- package/dist/boot/stage-06-runners.js +11 -10
- package/dist/boot/stage-07-capability-layer.d.ts +3 -0
- package/dist/boot/stage-07-capability-layer.js +7 -2
- package/dist/boot/stage-08-reapers.d.ts +3 -0
- package/dist/boot/stage-08-reapers.js +3 -3
- package/dist/boot/stage-09-leader.d.ts +3 -0
- package/dist/boot/stage-10-http-server.d.ts +3 -0
- package/dist/boot/stage-10-http-server.js +3 -2
- package/dist/boot/stores.d.ts +1 -0
- package/dist/boot/stores.js +35 -19
- package/dist/boot/workflow-orchestration.d.ts +1 -1
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/capabilities/composite-members.d.ts +3 -1
- package/dist/capabilities/composite-members.js +3 -1
- package/dist/capabilities/scenarios.d.ts +2 -2
- package/dist/capability-facts.d.ts +18 -1
- package/dist/capability-facts.js +25 -7
- package/dist/checkpoint-ctx-seal-m28.d.ts +1 -1
- package/dist/config-catalog.js +13 -4
- package/dist/config-provider.d.ts +2 -2
- package/dist/config-types.d.ts +43 -4
- package/dist/config.d.ts +6 -1
- package/dist/config.js +67 -11
- 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 +94 -0
- package/dist/device-ws-hub.d.ts +48 -3
- package/dist/device-ws-hub.js +48 -2
- package/dist/error-code-family.d.ts +35 -0
- package/dist/error-code-family.js +26 -0
- package/dist/fleet/drain-entry.d.ts +39 -3
- package/dist/fleet/drain-entry.js +6 -0
- package/dist/fleet/fleet-bus.d.ts +2 -1
- 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/hook-runner.d.ts +33 -16
- package/dist/hooks/hook-runner.js +166 -73
- 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/checkpoint-ctx.d.ts +59 -71
- package/dist/http/checkpoint-ctx.js +34 -40
- package/dist/http/dispatch.js +18 -2
- package/dist/http/durable-run-leg.d.ts +5 -0
- package/dist/http/durable-run-leg.js +1 -0
- package/dist/http/execution-context.d.ts +4 -0
- package/dist/http/execution-context.js +9 -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 +1 -1
- package/dist/http/memory-compliance-failure-reply.js +2 -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/principal-gate.d.ts +35 -12
- package/dist/http/principal-gate.js +16 -12
- package/dist/http/request-guards.d.ts +1 -1
- package/dist/http/request-guards.js +5 -5
- package/dist/http/resume-legs.d.ts +22 -0
- package/dist/http/resume-legs.js +26 -17
- package/dist/http/route-ctx.d.ts +11 -10
- package/dist/http/route-table.js +2 -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 +2 -1
- package/dist/http/routes/background.js +1 -0
- package/dist/http/routes/capabilities.js +4 -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 +1 -1
- package/dist/http/routes/memory-origin.js +2 -4
- package/dist/http/routes/memory-policy.js +5 -1
- package/dist/http/routes/observability.js +3 -6
- package/dist/http/routes/runs.js +7 -3
- package/dist/http/routes/session-sync.js +12 -25
- package/dist/http/routes/sessions-list.d.ts +1 -1
- package/dist/http/routes/sessions.js +4 -0
- package/dist/http/routes/tasks.js +23 -5
- 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 +15 -12
- package/dist/http/server.js +18 -3
- package/dist/http/stored-body-replay.d.ts +9 -6
- package/dist/http/stored-body-replay.js +19 -5
- package/dist/http/wire-types.d.ts +8 -3
- 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-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 +36 -0
- package/dist/memory-scope.js +32 -1
- package/dist/net-address.d.ts +53 -0
- package/dist/net-address.js +111 -0
- package/dist/observability/fail-open.d.ts +14 -10
- package/dist/observability/fail-open.js +14 -10
- package/dist/orchestration/workflow-notify-journal.js +2 -3
- package/dist/org-delivery-gate.js +1 -1
- package/dist/peer-directory.d.ts +6 -12
- package/dist/peer-directory.js +5 -1
- package/dist/plugins/caching-session-store.d.ts +3 -1
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-store-face.d.ts +426 -0
- package/dist/plugins/checkpoint-store-face.js +152 -0
- package/dist/plugins/file-run-store.d.ts +0 -6
- package/dist/plugins/file-run-store.js +1 -12
- 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 +10 -8
- package/dist/plugins/local-checkpoint-store.d.ts +2 -2
- package/dist/plugins/local-checkpoint-store.js +2 -1
- package/dist/plugins/local-session-store.d.ts +28 -5
- package/dist/plugins/local-session-store.js +32 -8
- package/dist/plugins/memory-engine-pg.d.ts +29 -6
- package/dist/plugins/memory-engine-pg.js +96 -214
- package/dist/plugins/memory-engine-sql-apply.d.ts +121 -0
- package/dist/plugins/memory-engine-sql-apply.js +358 -0
- package/dist/plugins/memory-engine-tidb.d.ts +35 -9
- package/dist/plugins/memory-engine-tidb.js +97 -227
- 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 +32 -56
- package/dist/plugins/one-time-migrations.js +25 -117
- package/dist/plugins/permission-rule-store-file.d.ts +17 -3
- package/dist/plugins/permission-rule-store-file.js +8 -1
- package/dist/plugins/pg-pool.js +1 -1
- package/dist/plugins/pg-session-storage.d.ts +17 -4
- package/dist/plugins/pg-session-storage.js +8 -4
- package/dist/plugins/run-store-sql.js +2 -2
- package/dist/plugins/schema-ensure-legs.js +2 -2
- 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/sql-json-column.d.ts +5 -1
- package/dist/plugins/store-backend.d.ts +11 -8
- package/dist/plugins/store-backend.js +8 -7
- package/dist/plugins/store-contracts.d.ts +1 -11
- package/dist/plugins/store-contracts.js +0 -9
- package/dist/plugins/store-sweep.d.ts +63 -0
- package/dist/plugins/store-sweep.js +48 -0
- package/dist/plugins/tidb-pool.js +1 -1
- package/dist/plugins/tidb-session-store.d.ts +16 -3
- package/dist/plugins/tidb-session-store.js +8 -4
- package/dist/prompt-screen.d.ts +6 -9
- package/dist/prompt-screen.js +2 -5
- package/dist/rules-consent.d.ts +20 -27
- package/dist/rules-consent.js +82 -6
- package/dist/run-cancel-context.d.ts +4 -1
- package/dist/run-cancel-context.js +2 -1
- package/dist/runs.js +1 -1
- 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 +17 -0
- package/dist/sealed-key-layout.js +4 -0
- package/dist/sealed-key.js +5 -5
- package/dist/security.d.ts +38 -6
- package/dist/security.js +9 -2
- package/dist/session-notify-door.d.ts +5 -3
- package/dist/session-resident-background.d.ts +57 -0
- package/dist/session-resident-background.js +20 -0
- 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 +1 -0
- package/dist/session-workspace.js +1 -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/stored-request-env-credentials-m38.d.ts +3 -0
- package/dist/stored-request-env-credentials-m38.js +8 -0
- package/dist/stored-request-prompt-profile-m30.d.ts +1 -1
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.d.ts +13 -427
- package/dist/{plugins → stores-sql}/checkpoint-store-sql.js +33 -194
- 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}/roster-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/roster-store-sql.js +1 -1
- package/dist/{plugins → stores-sql}/tool-result-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/tool-result-store-sql.js +6 -6
- 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-settings.d.ts +59 -4
- package/dist/task-settings.js +50 -4
- package/dist/tool-approval.d.ts +2 -2
- package/dist/trace/core-keyset-guard.d.ts +8 -7
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +2 -0
- package/dist/trace/exit-seat.d.ts +6 -0
- package/dist/trace/exit-seat.js +1 -0
- package/dist/trace/project.js +9 -0
- package/dist/trace/redact.d.ts +13 -2
- package/dist/trace/redact.js +305 -24
- package/dist/trace/self-minted-wire.d.ts +326 -8
- package/dist/trace/self-minted-wire.js +125 -7
- package/dist/trace/wire-projection-faces.d.ts +1 -1
- package/dist/trace/wire-projection-faces.js +1 -1
- package/dist/usage-analytics.d.ts +4 -0
- package/package.json +12 -4
- package/scripts/drain-check-local.mjs +8 -29
- package/scripts/drain-check.mysql.sql +3 -24
- package/scripts/drain-check.pg.sql +3 -24
- package/skills/update-config.md +1 -1
- package/wire-changes/server@7.146.0.json +3221 -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,498 @@
|
|
|
7
7
|
> ⚠️ 完整清单在仓库根 `CHANGELOG.md`——它**不随 npm tarball 出包**(本文件随包)。看完整迁移窗的
|
|
8
8
|
> 权威姿势是源码 tag diff:`git diff v<旧>..v<新>`(每版都推 `v<版本>` tag);npm 包页也镜像 CHANGELOG。
|
|
9
9
|
|
|
10
|
+
## 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 库先在其中一版起服一次)
|
|
11
|
+
|
|
12
|
+
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 加性;部署零动作)**:
|
|
13
|
+
旧形:自退的空闲计时从装配那一拍起算,一律按 `ENGINE_LINGER_MS`(缺省 60 s);`/health` 探针不算触点 —— 壳在 spawn 与第一个真请求之间被饿住超过 60 s,引擎就在从没被碰过的时候自退了。
|
|
14
|
+
新形:首个非探针请求到达之前(`/health` `/readyz` `/metrics*` 不算;打开 SSE 流算)生效窗是 `max(ENGINE_LINGER_MS, ENGINE_FIRST_ATTACH_MS)`;首个非探针请求之后回到 `ENGINE_LINGER_MS`,不再回来;
|
|
15
|
+
父进程已不在(孤儿)时照旧是 `ENGINE_ORPHAN_LINGER_MS`(孤儿优先)。在飞的 run 本身不算首个请求。自退判据(无附着 ∧ 无在飞 ∧ 静默)、采样拍与 `engineLease.lingerMs` / `tickMs` 不变。
|
|
16
|
+
`engineLease.firstAttach`:`windowMs` = 生效的候首触窗,`since` = 窗开始(epoch ms),`attachedAt` = 首个非探针请求的时刻(epoch ms;`null` = 还没有过);父一直活着且一直没人碰时 `since + windowMs` 是最早自退的下界、不是预言(父死之后孤儿窗优先,可以更早)。
|
|
17
|
+
在场 ⇔ `engineLease` 在场 ∧ `ENGINE_AUTO_EXIT` 开(owned 窗有限);缺席 = 老 worker / 没装自退腿 / 只靠父监视(owned 窗为「永不」)/ 腿已收摊。
|
|
18
|
+
起服日志 `engine_lease_armed` 多 `firstAttachMs`(旋钮值)与 `firstAttachWindowMs`(生效值);候首触窗到期的自退在 `engine_lease_auto_exit` 与 `<数据根>/exit-last.json` 里读作 `lane: "awaitingFirstAttach"`(车道键见第 26 条)。
|
|
19
|
+
`exit-last.json` 带 `format`(本版 = 3,见第 26 条):起服读到别的格式号(缺键 = 上一版写的)⇒ 一行 `warn` `exit_last_stale_format`(`fileFormat` / `buildFormat`)后删掉,不再打 `exit_last_found`(只丢那一次自退的留痕)。
|
|
20
|
+
**谁需要**:cli 壳的一次性 `-p` 车道、CI 与高载宿主 —— 壳在 spawn 与首个请求之间被饿住超过 60 s 时,引擎不再在它醒来之前退掉;壳读 `engineLease.firstAttach` 按首窗语义处理起步段。
|
|
21
|
+
**谁受伤**:spawn 之后从来没被碰过、父却一直活着(或没装父监视)的引擎多活到 180 s(再加至多一个采样拍)才自退,期间占着端口、数据根锁与库连接;不复用它、自己再起一只引擎的第二只壳最长约 3 分钟撞数据根锁。
|
|
22
|
+
父死照旧由孤儿窗收;服务器形部署(两键都没设)零变化。
|
|
23
|
+
**补偿**:`ENGINE_FIRST_ATTACH_MS=0`(或任何不大于 `ENGINE_LINGER_MS` 的值)逐字回到旧形;坏值(`1..999` 秒当毫秒、负数、小数、非数、越过 24 h)拒启并指路,解析不看 `ENGINE_AUTO_EXIT` / `SEMA_PARENT_PID`。
|
|
24
|
+
**升级前做**:无(想保持旧形的部署设 `ENGINE_FIRST_ATTACH_MS=0`)。**回滚**:回到上一版即恢复旧形;本版写的 `exit-last.json` 上一版读不成(见第 26 条「回滚」)。
|
|
25
|
+
|
|
26
|
+
2. **设备 WS 未鉴权握手的 per-remote 帽(`DEVICE_MAX_PREAUTH_PER_REMOTE`)可按真实对端计:新旋钮 `DEVICE_TRUSTED_PROXY_CIDRS`(可信代理名单,CIDR 闭集,缺省空 = 不读任何代理头);帽键统一为地址规范形(安全轴,fail-closed;新旋钮 + 日志 / 指标加性;部署零动作)**:
|
|
27
|
+
旧形:帽键 = socket 对端原文。引擎在反代 / 托管入口 / 公司 NAT 之后时,全员同一个 socket 对端,共用 8 个名额 —— 一个来源占满,其余设备的升级全 503;`off` 停层后只剩全局 64。
|
|
28
|
+
新形:帽键 = 真实对端。名单空(缺省)⇒ 就是 socket 对端(与旧形同键)。socket 对端落在名单内 ⇒ 读 `X-Forwarded-For`(重复头按到达序合并),自右向左跳过名单内的项,取第一个名单外的地址;
|
|
29
|
+
名单外的对端一律不采任何代理头;名单内但请求头行数到顶(100 行,或给 server 设的更低上限;node 对超过 `maxHeadersCount` 的请求要么静默丢掉多余的头、要么直接答 431(版本行为),答 431 时握手整只被拒、没有下面这行 warn;两形下垫在前面的 `X-Forwarded-For` 都不会成为帽键)/ 头缺席 / 某项不是地址 / 全在名单内 ⇒ 键退回 socket 对端(整只代理一键)+ 一行 warn `device_preauth_forwarded_unusable`(`reason` = `too_many_headers` / `absent` / `malformed` / `all_trusted`,不带地址)。
|
|
30
|
+
名单项: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`)、空项一律拒启。
|
|
31
|
+
不读 `Forwarded` / `X-Real-IP`,不支持 PROXY protocol。`DEVICE_MAX_PREAUTH_PER_REMOTE` 的语义、缺省 8 与 `off` 臂、全局帽 64 都不变。
|
|
32
|
+
帽键地址统一为规范形: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`)。
|
|
33
|
+
观测:每次升级计数 `device_preauth_key_total{source}`(`socket` / `xff` / `fallback`);`device_preauth_cap_hit` 行多 `keySource`;起服行 `device_lane_enabled` 多 `trustedProxyCidrs`(条数)。
|
|
34
|
+
**谁需要**:设备车道在反代 / 托管入口(k8s ingress、负载均衡)/ 公司 NAT 之后的部署 —— 一个来源不再吃光其他设备的未鉴权名额。
|
|
35
|
+
**谁受伤**:名单配宽(放进不受自己控制的跳)⇒ 那里的客户端可伪造 `X-Forwarded-For` 自报帽键、绕开 per-remote 层(全局帽照兜);不写 `X-Forwarded-For` 的四层负载均衡被列入 ⇒ 每次升级退回 socket 键 + warn。
|
|
36
|
+
**补偿**:名单缺省空 = 旧形;只放自己的反代;前缀 0 与主机位歧义拒启;warn 的 `reason` 指路;名单外部署零变化。
|
|
37
|
+
**升级前做**:无。反代后的部署想按真实来源计 ⇒ 把自己的反代地址段写进 `DEVICE_TRUSTED_PROXY_CIDRS`(编排器的 compose 需透传这根 env;控制台的 device 旋钮表随契约包车道表带上它 —— 本版提货的 settings-schema 17.1.0 在车道表 device 行登记了它)。
|
|
38
|
+
**已知限制**:这根键随契约包车道表成为 worker 规格的保留名 —— worker 规格的 `env` / `secretEnv` 逃生口不再收它,唯一写位是 `runtime.execution.coords.DEVICE_TRUSTED_PROXY_CIDRS`。控制台的契约包落后于本版时,若有人先把它写进 worker 规格的 `env`,控制台升级契约包后那一行会被拒,没有一次性迁移搬它 —— 手工把它搬到 `runtime.execution.coords`(只对声明 device 车道的 worker 有意义)。
|
|
39
|
+
**回滚**:去掉 `DEVICE_TRUSTED_PROXY_CIDRS` 即回到按 socket 对端计;回到上一版时这根 env 被忽略(上一版不认识它)。
|
|
40
|
+
|
|
41
|
+
3. **两条 SQL 记忆腿(`MEMORY_ENGINE_BACKEND=pg|mysql`)兑现 core 的落点问询协议:声明 `admitsLandings`,`applyPatches` 收 `opts.admit` / `opts.confirm`(行为变更;嵌入方 / 宿主零动作)**:
|
|
42
|
+
旧形:两腿的 `applyPatches` 只收一个参数,传进来的第二参被**静默丢掉** —— `admit`(落点由谁说了算)与 `confirm`(调用方的最后一句话)一次都不调;
|
|
43
|
+
core 记忆引擎的整合 apply 见两腿不声明 `admitsLandings`,就自己先问**冻结的**拼写、再逐条交写,而两腿撞名时自己加上的 `-n` 后缀,写闸从来没见过。
|
|
44
|
+
新形:两腿声明 `admitsLandings: true`。给了 `admit` ⇒ 后端先只读地判出整批的每个落点(add 的终拼含撞名后缀、同 scope 改名留下的旧拼、update 的目标与移走的旧拼、
|
|
45
|
+
delete 移走的拼),在写任何一个之前一次问全;**每一次问都在本次 apply 的第一笔写之前** ⇒ 拒 = 一字不写、原样上抛;最多问 4 次,名仍在动 ⇒
|
|
46
|
+
抛 `memory.landing_unstable`(此时恒一字未写;问、记下问过的、轮数上限与超限的码是引擎的问询圈,与 file 腿同一只)。问过之后落点又变了(名被别的副本抢走、行被并发改名 / 搬走)且变出了还没问过的拼写 ⇒ 还一笔没写就写前重问新拼(连同其后整批剩下的预测落点一次问全);
|
|
47
|
+
已经写过(含一条写语句发出后以 I/O 失败收场、落没落不知道)就这一条报冲突(`landing moved after admission …`)、一字不写,下次 apply 再问 —— 绝不写没问过的拼写。
|
|
48
|
+
给了 `confirm` ⇒ 每条 entry 写语句发出之前同步调;抛 ⇒ 该条及其后不写、之前已提交的留下,原样上抛(不再是一条 `io error` 冲突)。
|
|
49
|
+
中止路径上已提交的 entry 照落 history 行。
|
|
50
|
+
不传第二参 ⇒ 常规路径与旧形同,一处有意更正:同批两条 add 的占名此前按 `scope|slug` 拼接判,scope / slug 含 `|` 时会把两个不同的拼写判成同名、后一条白退一个后缀,现按两格判。
|
|
51
|
+
另只在并发竞争路径上收紧:写语句把计划的 scope / slug 也绑进条件(`MEMORY_ENGINE_BACKEND=mysql` 上逐字节比,不受 `utf8mb4_bin` 尾空格不计的影响),
|
|
52
|
+
行在判与写之间被别的副本改名 / 搬走 ⇒ 按现状重判再写(旧形 update / delete 按 `id + rev` 照写 —— rev 不含 scope / slug —— 会写到一个没判过的拼写上);
|
|
53
|
+
同 id 的行在判与写之间被别的副本插入 ⇒ 重判(旧形按 id 盲覆盖)。
|
|
54
|
+
**谁需要**:把这两条 SQL 腿交给 core 记忆引擎、自己驱动记忆整合的嵌入方 —— 写闸判的是真正落下的拼写,每次写之前核对整合计划的持有者。
|
|
55
|
+
本服务自己的整合阀门(`MEMORY_CONSOLIDATION_DRIVER`)在 SQL 记忆腿上照旧拒启(这两条腿不自带引擎控制面归属,这一条不变)。
|
|
56
|
+
**谁受伤**:SQL 记忆腿上的整合 apply —— 本批开始写之后才被别的副本抢名 / 挪行的那一条报冲突不写,留到下次 apply(引擎按报告与库里实际落下的对账);
|
|
57
|
+
给了 `admit` 的批读库次数约三倍(问前判整批、问后再判一遍、写前逐条现判)。不传第二参的调用方只在并发竞争路径与 scope / slug 含 `|` 的同批 add 上看见差别(见上一段)。
|
|
58
|
+
直接把 `admit` / `confirm` 交给 SQL 腿的调用方:过去被静默丢掉,从本版起被兑现,`admit` 的拒绝与 `confirm` 的抛错原样上抛
|
|
59
|
+
(core 引擎按契约只在后端声明了 `admitsLandings` 时才交,所以此前的调用点都不交)。
|
|
60
|
+
**补偿**:不传第二参零变化;抛错原样,已提交写的审计行不丢。
|
|
61
|
+
**已知限制**:SQL 记忆腿的 confirm 在写语句前同步调,不持事务锁;要事务内验 fence 等包里的腿(7.64.0 核心存储包)。
|
|
62
|
+
**升级前做**:无。**回滚**:回到上一版即恢复旧形(库形零变化)。
|
|
63
|
+
|
|
64
|
+
4. **TiDB 记忆腿(`MEMORY_ENGINE_BACKEND=mysql`)上 stale `baseRev` 的 update 改按契约报冲突:对手恰好把行写成与本次 update 逐字节相同的目标态时,此前报 applied,现与 PG 腿同答冲突并带 `currentRev`(行为修复;部署零动作)**:
|
|
65
|
+
旧形:update 的写语句因行在判与写之间被别的副本改过而匹配零行时,TiDB 腿现读一次,若行此刻恰是这次 update 的目标态(rev 与 scope / slug 都对)就报 applied 并记一行 history —— 这一条其实没写任何东西、调用方所基的 rev 已过期;PG 腿对同一时序报 `rev mismatch (concurrent change)`。
|
|
66
|
+
新形:按 rev 判、不按字节判(core 契约:stale `baseRev` 的 update 是报告的冲突,带 `currentRev`)。零行之后只有「什么都没改」的 update(新 rev 与判过的 rev 相同、投影不动)且现读行仍在判过的 rev + 投影上才算已落(没开 `CLIENT_FOUND_ROWS` 的连接上这种 update 匹配了也数 0);
|
|
67
|
+
其余零行不再算已落:行的 rev 变了(含对手写成逐字节相同的目标态)或行没了 ⇒ 报冲突,`currentRev` = 现读值(行没了则是判时读到的值),本条不落 history,行保持对手写的那一份;
|
|
68
|
+
行只是被挪了地方(rev 不变)⇒ 沿用既有的按现状重判。没带 `baseRev` 的 update 同读(写语句仍以判时读到的 rev 为条件,与 PG 腿一致)。判之前就 stale 的路径、PG 腿、同 scope 同 id 的 re-add 幂等覆盖都不变。
|
|
69
|
+
**谁需要**:多副本并发写同一条 entry、把 TiDB 记忆腿交给 core 记忆引擎或自己驱动 `applyPatches` 的部署(记忆同步中心半场的 pull 补丁走同一口)。
|
|
70
|
+
**谁受伤**:此前把「第二个到达者」读成 applied 的调用方 —— 这个时序上现在拿到冲突;写者要的恰是行上那一份时,按冲突里的 `currentRev` 重读对账即可,报告里 applied 少一条、conflicts 多一条,行的终态不变。
|
|
71
|
+
**补偿**:无旋钮(契约句不容两种读法);`currentRev` 是现读值(行没了才退回判时的值)。**升级前做**:无。**回滚**:回到上一版即恢复旧形(库形零变化)。
|
|
72
|
+
5. **随包文书补全与订正:停机上界契约句、`blocked` 终局的用户面是 `terminal.detail`、hooks 托管标签由调用方自报且失败方向只收紧、server-as-peer 启动日志行、场景面收窄写法、坏行降级形的键集(文字订正;零行为变更;wire 零变化;部署零动作;点名三壳渲染层)**:
|
|
73
|
+
旧形:随包文书对这几处要么没写(停机从信号到进程退出的上界与 `engineSignal.draining.actionId` 的值域、托管标签的来源与权能、场景面收窄的写法),要么写偏 ——
|
|
74
|
+
把壳指去它读不到的 operator-only 配置目录取排空窗、`blocked` 终局的 `terminal.reason` 只写成「为什么做不了」、`a2a_serve_enabled` 日志行的 `tasksUsable` 字段并不存在、
|
|
75
|
+
server-as-peer 无 run store 时「卡照发、方法回 `-32004`」自 7.116.0 起已不成立。
|
|
76
|
+
新形(全部是文字,代码未动):
|
|
77
|
+
① 停机上界(`USAGE.md` 与契约文档各一条「停机上界(契约句)」):单发 `SIGTERM` 的退出上界 = `GET /health` 的 `engineSignal.draining.deadlineAt` + ≤ 1 s(排空驱动一拍)+ ≤ 15 s 终局(按定时器算的名义上界;真正强制的上界是壳自己梯子里的 `SIGKILL`);
|
|
78
|
+
两发形(第二发与第一发相隔 g ≥ `DRAIN_SECOND_SIGNAL_MIN_GAP_MS`,缺省 250 ms)= t0 + g + ≤ 15 s;10 s 在飞宽限在 15 s 之内、不相加。`engineSignal.draining.actionId` 的值域:信号致排空 = `signal:SIGTERM` / `signal:SIGHUP`(闭集),
|
|
79
|
+
运维排空口进的 = 该请求自带的 id,硬停(未经排空)期间排空口的回执 = 固定的 `hard-stop`(引擎自铸的另两类:`self-exit:attachment`、`lease:<代际>`)。
|
|
80
|
+
`DRAIN_GRACE_MS` 的生效值段与配置目录里它的语义句不再叫壳读 operator-only 的 `GET /v1/config/catalog`,改指排空期的 `engineSignal.draining.deadlineAt`;`STORE_LOCK_WAIT_MS` 一条补一句:
|
|
81
|
+
新引擎的锁等待窗应 ≥ 前任的排空窗 + 15 s 终局 + 一拍,壳 / 桌面按自己的排空窗注入,缺省不变。
|
|
82
|
+
② `blocked` 终局:`terminal.reason` 是**模型面**句(`terminal.detail` 在场时是引擎给模型的 `<system-reminder …>` 框句);用户面 / 机读面是 `terminal.detail { kind: "prompt_blocked_by_hook", cause, hookReason? }`
|
|
83
|
+
(`cause` ∈ `block` / `crashed` / `timeout` / `cancelled`)。**点名 cli · web-admin · client-core 的渲染层**:凡把 `blocked` 终局渲给人的读点,在 `terminal.detail` 在场时渲 `detail`(按 `cause` 分流,`hookReason` 按不可信文本渲),
|
|
84
|
+
不渲 `reason`;读不到 `detail` 才渲 `reason`(此时它是 agent 自己用 `ReportBlocked` 报的话);按 `detail.kind` 分支的读点留缺省臂。
|
|
85
|
+
③ hooks 托管标签(`USAGE.md` 9.5c-quater;契约 hooks 来源节):`source` 里的 `managedPolicy` / `managedPlugin:*` 由调用方自报,服务端只校闭集、不验身份;标签只改位置(托管相在非托管改写之后的最终输入上判,终判相次序)与失败方向(只收紧:未跑成或判词不可信折 `ask`;事件墙钟独立),`allow` 不看相。
|
|
86
|
+
④ 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。
|
|
87
|
+
⑤ 场景面收窄(部署自配,没有新语法):`SKILLS_DIR` 指空目录 + `config.d/skills.json` 的技能写 `scenarios` 标签;内建 `code-review` / `scan` 在 `config.d/scenarios.json` 里同名遮蔽成 `toolset: "none"`(`enabled: false` 是跳过、不遮蔽);`LSP_HOST_ENABLED` / `SCHEDULER_ENABLED` 现成开关。
|
|
88
|
+
⑥ 订正 7.145.0 节第 8 条 ① 的一句(坏行降级形的键集;7.145.0 节原文不改):降级行的键集恰为 `sessionId` · `checkpointId` · `scope` · `createdAt` · `gateKind` · `deadline` · `rowVerdict` · `objective` · `input`(`checkpointId` 读得出才在、`deadline` 在场才有)。
|
|
89
|
+
其中 `objective` 与好行同一读法 —— 路由对每一行补的 enrichment,按这道停驻门所属 run 的行预览独立读(值是串〔含 `""`:有预览记录而剥空〕或 `null`),不读坏字节、没有 run 行预览时也不铸空串;`input` 恒为 `null`;
|
|
90
|
+
摘要派生的键(`severity` / `spentMicroUsd` / 出身位三件套等)缺席 —— 7.145.0 节那句「摘要派生的键缺席」说的是这一类,`objective` 不在其中。
|
|
91
|
+
**谁需要**:按文书排壳形关机预算的壳 / 桌面;渲 `blocked` 终局的 cli · web-admin · client-core 渲染层;把 `source: "managedPolicy"` 读成「组织策略来源证明」的部署方;读 `a2a_serve_enabled` 日志里 `tasksUsable` 的编排脚本;按键表渲坏行卡的壳(cli · client-core · web-admin)与按判据键表验收的黑盒。
|
|
92
|
+
**谁受伤**:照旧文书去读 operator-only 配置目录的壳读不到;把 7.145.0 节那句读成「坏行上 `objective` 也缺席」的收件箱客户端(多一个键无害,缺键才伤);渲 `terminal.reason` 的读点会把 `<system-reminder …>` 标记露在屏上(代码一直如此,文书此前没写);读 `tasksUsable` 的脚本从来读不到那个字段。
|
|
93
|
+
**补偿**:壳按自己注入的窗 + 契约句的上界排预算;渲染层改读 `detail`;`a2a_serve_not_served` 取代 `tasksUsable`。**升级前做**:无。**回滚**:无需(只改文字)。
|
|
94
|
+
|
|
95
|
+
6. **`local_roots_split` 起服告警只报「一声不响的分家」:显式给了 `CONFIG_LOCAL_DIR`(等于数据根 = 合一,不等 = 有意分家)即视作运维已表态,不再每次起服响;推导的配置根 ≠ 数据根照报(行为修复;日志面;部署零动作)**:
|
|
96
|
+
旧形:数据根的链是 `LOCAL_DATA_ROOT` → `CONFIG_LOCAL_DIR` → `AGENT_DATA_DIR` → `~/.ai-agent`,配置根(`config.d/` 与 `remote-exec.json` 所在)的链少第一节。起服期只要两个根解析出来不相等就打一条 warn `local_roots_split`,
|
|
97
|
+
不分配置根是显式给的还是推出来的 —— 同时显式给了 `LOCAL_DATA_ROOT` 与 `CONFIG_LOCAL_DIR` 且两值有意不同的部署,每次起服也响一次,指路句「想合一就设 `CONFIG_LOCAL_DIR`」对一个已经设了它的部署没有意义。
|
|
98
|
+
新形:`CONFIG_LOCAL_DIR` 在场(空串仍算缺席)⇒ 这条 warn 不再打,不管它和数据根相等与否 —— 合一旋钮一旦给出就是表态(等 = 合一,不等 = 有意分家)。只有配置根是推导来的(`AGENT_DATA_DIR`,或家目录缺省 `~/.ai-agent`)
|
|
99
|
+
且 ≠ 数据根时才打,字段 `dataRoot` / `configRoot` 与 warn 级别不变;`note` 文案改为点明 `CONFIG_LOCAL_DIR` 没设,并多一句出路:分家是有意的 ⇒ 把 `CONFIG_LOCAL_DIR` 显式设成那个配置目录,这一行即静默;`GET /v1/config/catalog` 里 `LOCAL_DATA_ROOT` 一行的说明句同改(只改文字)。
|
|
100
|
+
两个根的解析一个字不动:数据落在哪、`config.d` 从哪读,与上一版逐字相同;只有这一条日志的在场条件变了。
|
|
101
|
+
**谁需要**:同时显式给 `LOCAL_DATA_ROOT` 与 `CONFIG_LOCAL_DIR` 且两值不同的部署(壳 / 宿主把数据根与配置根分放),此前每次起服多一条 warn。
|
|
102
|
+
**谁受伤**:靠这一行发现「数据根 ≠ 配置根」的显式双根部署(那是他们自己给的两个值,此后起服不再看到它);`CONFIG_LOCAL_DIR` 打错字(指到另一个目录)的部署同样不再被它提醒 —— 校对两个根的值,不再靠这一行。
|
|
103
|
+
**补偿**:不给 `CONFIG_LOCAL_DIR` 就是原判据(推导的配置根 ≠ 数据根照报);无旋钮。**升级前做**:无。**回滚**:回到上一版即恢复每次响的旧形(只是日志的在场条件,无持久面)。
|
|
104
|
+
|
|
105
|
+
7. **在飞 run 并发帽:新旋钮 `RUN_MAX_CONCURRENT`(本副本全局)与 `RUN_MAX_CONCURRENT_PER_PRINCIPAL`(同一已验提交主体),缺省 `0` = 关;新提交超帽 ⇒ 429 `limit.rate_exceeded` + 体 `reason: "run_concurrency_cap"` + `Retry-After: 5`(行为加性,缺省关;wire 加性;部署零动作)**:
|
|
106
|
+
旧形:没有「此刻在飞几条 run」的帽;`RATE_LIMIT_RPM` 只限每分钟提交几条,一条 run 可以跑几十分钟,新提交会在同一台机器上叠起来。
|
|
107
|
+
新形:两根整数旋钮(负数 / 小数 / 非数 boot 拒启),`0` / 缺省 = 关(升级后什么都不变)。开了之后,新提交的四个口 —— `POST /v1/runs`、A2A `message/send`、`POST /v1/tasks`、`POST /v1/tasks/stream` ——
|
|
108
|
+
在幂等重放**之后**、建行 / 认领 / SSE 头**之前**数本副本此刻在飞的 run(后台 run、同步 / 流式腿、有 run 行的续跑腿都占一格;与排空读数同一份在飞集);到帽 ⇒ 429,`errorCode: "limit.rate_exceeded"`(沿用现有限流码),
|
|
109
|
+
体多机读 `reason: "run_concurrency_cap"` 与 `retryAfterSec: 5`,头 `Retry-After: 5` 同值。同 `Idempotency-Key` / 自带 `taskId` 的重试拿回自己的回执,不吃新 429;续跑、唤醒、审批作答不判。
|
|
110
|
+
`RUN_MAX_CONCURRENT_PER_PRINCIPAL` 数同一已验主体(与成本配额门同键);无主体请求只受全局帽。帽是本副本的(各副本各数各的),闸的是新提交:续跑回来的 run 不判,在飞数可以越过帽;同键并发重复提交赶在首发还在受理的窗里到达时,帽满可能拿到一次 429,按 `Retry-After` 重投即拿回首发的回执。
|
|
111
|
+
**谁需要**:共享一台 GPU 或一只小模型网关的家用 / 小团队部署。**谁受伤**:超帽者拿 429(新行为,缺省关);消费端把 `limit.rate_exceeded` 当「稍后再来」按 `Retry-After` 退避即可,要区分来源读 `reason`(其余产地不带)。
|
|
112
|
+
**补偿**:缺省关;`Retry-After: 5` 给退避。**升级前做**:无。**回滚**:去掉两根 env 即关;回到上一版时这两根 env 被忽略(上一版不认识它们)。
|
|
113
|
+
|
|
114
|
+
8. **硬断预告:自 7.147.0 起每个部署都要显式声明执行车道 —— 未声明拒启;车道词 `none` 取代词表外的状态名 `in-process`;`REQUIRE_EXECUTION_LANE` 退役(预告;本版零行为变化、零 wire 变化;部署零动作,但 7.147.0 的升级路径上有三件事要提前排)**:
|
|
115
|
+
旧形(7.146.0 及以前,也是本版):`REMOTE_EXEC` 不设时有两条隐式臂 —— `CONFIG_PROVIDER=local` 隐含 `host`(手带在,宿主真机);其余(`remote` 或不设)落 core 的进程内桩(手带整族不挂,任务照跑、回执 `status=completed`)。
|
|
116
|
+
后一条在 `GET /v1/capabilities` 的 `executionLane.provider` 上叫 `in-process` —— 一个不在车道词表里的状态名。想对「没点名」拒启,要自己开 `REQUIRE_EXECUTION_LANE=true`(缺省关;本仓自带的部署产物都写着它)。
|
|
117
|
+
新形(自 7.147.0 起;本版只预告,代码未动):
|
|
118
|
+
**硬断预告(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 本身零行为变化。
|
|
119
|
+
**谁需要**:所有部署方 —— 尤其是 `CONFIG_PROVIDER=local` 的单机形、手写 `.env`、没写 `REMOTE_EXEC` 的托管 worker,以及给 worker 渲染 env 的编排方;读 `executionLane.provider` / 放置读面 `lane` / 409 `boundLane` / 403 `extra.lane` 的壳与客户端(按 `in-process` 字面分支的,要在 7.147.0 同波认 `none`)。
|
|
120
|
+
**谁受伤**:7.147.0 起 ① 没声明车道的部署拒启;② env 里还写着 `REQUIRE_EXECUTION_LANE` 的(拷过旧版随包部署产物的清单、自己拼的清单、编排方渲染的 worker env)拒启;③ 库里或数据根里有 `in-process` 存量行的部署要停机迁移、不可滚动(旧副本不认 `none`、新副本不认 `in-process`,混跑两头都会拒);④ 按旧词字面读 wire 的消费端。本版(7.146.0)无人受伤。
|
|
121
|
+
**补偿**:7.146.0 起就能显式点名 —— 单机用 `REMOTE_EXEC=host`,隔离用 `e2b` / `k8s` / `local-docker`(`none` 要到 7.147.0 才是车道词,现在写会被拒);要继续「不给手」的部署,7.147.0 写 `REMOTE_EXEC=none`(逐字复现今天非 local 未设的行为)。
|
|
122
|
+
编排方停渲 `REQUIRE_EXECUTION_LANE` 的同时,必须让每个 worker 的 env 带 `REMOTE_EXEC` —— 7.146.0 上只停渲这根旋钮而不点名车道,worker 会静默落进无手的进程内桩。
|
|
123
|
+
**升级前做**:无(本版)。为 7.147.0 排期:盘点哪些部署没写 `REMOTE_EXEC`;盘点 env 里的 `REQUIRE_EXECUTION_LANE`;有 `in-process` 存量行的部署排一次停机窗。**回滚**:无需(本版只改文字)。
|
|
124
|
+
|
|
125
|
+
9. **更正 7.144.0 节第 1 条与 7.137.0 节第 15 条的出路句(及 CHANGELOG 7.137.0 段的同句):`corrupt_session` / `invalid_session` 的出路里没有「从断点之上的条目分叉」这一手 —— `POST /v1/sessions/:id/fork` 不选条目,对结构坏的会话也不是出路(文字订正;零行为变化;部署零动作)**:
|
|
126
|
+
旧形:7.144.0 节第 1 条「补偿」写「结构坏改读 `corrupt_session`(别重试;换一个新会话、从断点之上的条目分叉,或请运维修好 / 移走那份日志)」,7.137.0 节第 15 条对 `invalid_session` 的消费方动作写「出路是换新会话或从断点之上的条目分叉」,契约「客户端动作」一句同说。
|
|
127
|
+
HTTP 上没有「从断点之上的条目分叉」这一手:fork 口没有条目参数,试了拿到的要么是带着同一个断点的副本,要么是 fork 自己答的 `corrupt_session`。
|
|
128
|
+
新形(只订文字,代码未动;已发节原文不动,订正只进本节;契约的「客户端动作」一句与 fork 节〔§23.4〕同改):
|
|
129
|
+
fork 口(`POST /v1/sessions/:id/fork`)不选条目:体只有 `forkId` / `forkNonce`,分叉点由引擎判 —— 取源会话已提交的历史(整份已结日志,叶 = 源会话的叶;最后一轮是带着还没有结果的工具调用的 assistant 轮时,只拷到它的父为止)。它拷的是这份日志本身、不修复任何东西:断点落在拷贝范围里的源(悬空父 / 自指 / 成环),副本带着同一个断点、打开同样答 `corrupt_session`;叶子缺席的源,或在飞轮的分叉点以上走不通的源,fork 自己就答 `corrupt_session`。两头都不是出路(引擎对成环那一形的原句里写着「fork from an entry above the loop」,HTTP 上没有对应的口)。出路是换一个新会话,或请运维修好 / 移走那份日志。
|
|
130
|
+
**谁需要**:照旧句去找「从断点之上的条目分叉」的调用方与壳(这个口没有条目参数)。**谁受伤**:把 fork 当这两个码的出路的客户端 —— 断点落在拷贝范围里时 fork 答 200 与一个新会话 id,可那份副本同样打不开(试了才发现);叶子缺席的源 fork 自己就答 `corrupt_session`。
|
|
131
|
+
**补偿**:换一个新会话;或请运维修好 / 移走那份日志(修好之后同一服务进程仍按它持有的那份答,重启进程才恢复,契约该节)。**升级前做**:无。**回滚**:无需(只改文字)。
|
|
132
|
+
10. **起服告警 `memory_engine_dir_defaulted` 改名 `memory_engine_dir_outside_data_root` 并改按路径包含判:file 形记忆引擎的已解析根不在本机数据根(`config.localDataRoot`)之下才报,句子带两条真路径;`MEMORY_ENGINE_DIR` 缺席不再是判据(行为修复;日志面,日志事件改名(旧名退役;壳 / 编排脚本按新名读))**:
|
|
133
|
+
旧形:判据 = `LOCAL_DATA_ROOT` 在 ∧ `MEMORY_ENGINE_DIR` 缺席,句子说「记忆引擎正在共享全机默认库」。`AGENT_DATA_DIR` 已把记忆根放在数据根上(或其下)时,
|
|
134
|
+
`MEMORY_ENGINE_DIR` 缺席只是没写 —— 记忆库并没有共享谁,这一行每次起服响一次、说的是假话;反过来,显式 `MEMORY_ENGINE_DIR` 指到数据根之外(记忆库与店数据真分家)时,这一行恒哑(旧判据要它缺席才成立)。
|
|
135
|
+
新形:只比路径 —— 已解析的记忆根(`MEMORY_ENGINE_DIR` → `AGENT_DATA_DIR` → `~/.ai-agent`)不在数据根(`LOCAL_DATA_ROOT` → `CONFIG_LOCAL_DIR` → `AGENT_DATA_DIR` → `~/.ai-agent`)之下 ⇒ 打一条 warn;在其下(含相等)⇒ 零条。
|
|
136
|
+
两侧都先过符号链接展平再比(盘上还不存在的尾巴只比规范化字串),数据根缺席不判。warn 的日志事件改名(旧名退役;壳 / 编排脚本按新名读):`memory_engine_dir_defaulted` → `memory_engine_dir_outside_data_root`(新判据下旧名不真 —— 显式 `MEMORY_ENGINE_DIR` 也报),零别名、不双发,级别不变;字段 `root` 保留(记忆根)、多一个 `dataRoot`(数据根)、
|
|
137
|
+
`hint` 换成一句带这两条真路径的话:「memory engine root <记忆根> is outside the local data root <数据根>; set MEMORY_ENGINE_DIR under <数据根> to isolate it」。
|
|
138
|
+
另:展平路径时盘上出了竞态(探完到取值之间目录被挪走 / 搜索权限被收)⇒ 不拒启,另报一行 warn `memory_engine_dir_check_unavailable`(`root` · `dataRoot` · `errorKind` · `errorCode`,不带消息原文)。
|
|
139
|
+
两个根的解析与记忆库落在哪一个字不动,只有这一条日志的在场条件与句子变了。
|
|
140
|
+
**谁需要**:同时给了 `LOCAL_DATA_ROOT` 与 `AGENT_DATA_DIR`、记忆根已在数据根之下的部署(此前每次起服多一句假话);显式给了 `MEMORY_ENGINE_DIR` 的部署(此前这一行对它们恒哑,现在按真路径比)。
|
|
141
|
+
**谁受伤**:按旧事件名读起服日志的壳 / 编排脚本读不到这一行了(旧名退役,改读新名);信号本身没丢 —— 此前靠这一行发现「忘设 `MEMORY_ENGINE_DIR`」的人(`LOCAL_DATA_ROOT` 在、记忆根落默认链且在数据根之外)照报,只是句子改真。读数变化只有日志在场与否:
|
|
142
|
+
此前不报、现在报 = 显式 `MEMORY_ENGINE_DIR` 在数据根之外;没设 `LOCAL_DATA_ROOT`、只设 `CONFIG_LOCAL_DIR` 把数据根挪走而记忆根仍落默认链(`AGENT_DATA_DIR` → `~/.ai-agent`)。
|
|
143
|
+
此前报、现在不报 = `LOCAL_DATA_ROOT` 在、`MEMORY_ENGINE_DIR` 缺席,但 `AGENT_DATA_DIR` 把记忆根放在数据根上或其下。**补偿**:句子带两条真路径,看一眼即知哪一侧要挪;无旋钮;
|
|
144
|
+
想让它静默就把 `MEMORY_ENGINE_DIR` 放到数据根之下(或让数据根包住记忆根)。**升级前做**:按旧事件名 `memory_engine_dir_defaulted` 读起服日志的壳 / 编排脚本改读 `memory_engine_dir_outside_data_root`(字段 `root` · `dataRoot` · `hint`;旧名不再发)。**回滚**:回到上一版即恢复旧名、旧判据与旧句子(只是日志,无持久面)。
|
|
145
|
+
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`)**:
|
|
146
|
+
旧形:两只路由各自内联「单用户形不问名单」。诊断面:名单为空 ∧ `REQUIRE_PRINCIPAL` 未开 ⇒ 不判运维,零凭证部署只许本机读、配了 service 凭据的部署过了全局凭据门即读;
|
|
147
|
+
outcomes:`REQUIRE_PRINCIPAL` 未开 ⇒ 不判运维(名单为空时人人可读,配了具名名单也被无视);能力位 `outcomeLedger` 在单用户形上不看名册。
|
|
148
|
+
新形:两口与其余运维口同序,部署形不是输入 —— 没有运维名册(`OPERATOR_PRINCIPALS` 为空且没有 `OPERATOR_SINGLE_USER=true`)⇒ 501 `capability.operator_principals_required`;
|
|
149
|
+
名单非空而调用方不在名单上 ⇒ 403 `auth.operator_only`;单用户声明在场 ⇒ 每个调用方过运维门。诊断面过了运维门之后:远程请求后面没有验过的身份(service 凭据 / 鉴权桥登录令牌 / 直连门签名令牌)⇒ 403 `auth.loopback_only`,本机照读(一条门,不再按名单在不在分两条)。
|
|
150
|
+
能力位 `outcomeLedger` = 有运维名册 ∧ 可查询账面;outcomes 口名册缺席先于账面缺席答:过了运维门(名册在场,调用方在名单上或单用户声明在场)之后,账面不可查询的部署(outcome sink 只写 JSONL 文件、没有查询面)另答第二个 501 `capability.outcome_ledger_required`(与名册缺席的 501 `capability.operator_principals_required` 是两个码,探针与看板按体上的 `errorCode` 判、不按状态码判)。起服 warn `operator_undeclared_single_user` 的在场条件由「单用户 ∧ 无名册 ∧ 有审批底座」变成「单用户 ∧ 无名册」,句子多点名这两口;
|
|
151
|
+
两只 403 句去掉「on a multi-tenant worker」(机器码不变)。
|
|
152
|
+
**谁需要**:单用户部署上配了具名运维名单的运维(此前 outcomes 视图对名单外的调用方也开);「运维面只认显式声明」这一条律在每个运维口上都成立。
|
|
153
|
+
**谁受伤**:名单为空、没写声明的单用户部署 —— 两口从 200 变 501:读诊断面的工具(壳的体检读诊断面回体的那几行)与 outcomes 看板读不到了;
|
|
154
|
+
单用户部署 + 鉴权桥 + 零静态凭据 + 已声明 —— 诊断面对带登录令牌的远程调用方从 403 `auth.loopback_only` 变成放行(不带身份的远程请求照旧 403)。
|
|
155
|
+
**补偿**:`OPERATOR_SINGLE_USER=true`(只在 `REQUIRE_PRINCIPAL` 未开且名单为空时成立,否则拒启)或具名 `OPERATOR_PRINCIPALS`;起服 warn 点名这一行;501 拒句同句给两条出路;能力位 `outcomeLedger` 如实。
|
|
156
|
+
**升级前做**:名单为空的单用户部署,要诊断面 / outcomes 视图(或壳的体检读诊断面的那几行)⇒ 写一行 `OPERATOR_SINGLE_USER=true`;单用户部署配了具名名单的,确认读 outcomes 的调用方带名单内的主体;
|
|
157
|
+
按「单用户形诊断面不问名单」写的探针 / 看板改按 501 / 403 两码判。**回滚**:回到上一版即恢复旧门(无持久面)。
|
|
158
|
+
12. **后台子代状态 `agentState` 过 wire 的读法成文并钉死,订正 7.116.0 节里「`details` 是否经 `tool_end.structured` 到客户端……没有核过」一句(文字订正;零行为变更;wire 零变化;部署零动作)**:
|
|
159
|
+
旧句:7.116.0 节写过 `agentState` 经事件流到客户端这一路仓内没有 wire 级钉、`structured` 带不带它取决于引擎对卡面 `type` 的白名单、本服务没有核过。现在核过并钉死了(`src` 一行未动,读数就是实现):
|
|
160
|
+
· `tool_end.structured` 本服务只换卡内串叶里的凭据形、不枚举卡内的键,`agentState` 逐键原样过 —— 主流、forward 分支、子代 tail 流、账本落行与 `GET /v1/runs/:id/events` · `GET /v1/tasks/:id/turns` · trace SSE 的回放都一样;
|
|
161
|
+
· 进不进 `structured` 由引擎的卡投影器定(类型在卡集里、且整卡序列化不超过 65,536 字符;超了整卡略去):`AgentTranscript` 的步骤答话(`structured.type` 为 `agent-transcript`:`structured.agentState`、`steps[i].at` / `inFlight`)与 `ListAgents`(`structured.type` 为 `list-agents`:每个后台子代行 `rows[i].agentState`)带它;
|
|
162
|
+
· 不带它的三类是引擎的选择(缺席 = 引擎没给,不是本服务摘的):拒答(引擎取得了状态的那几类:转录已不在 / 未保留 / 读失败,首行 `State: …` 在 `output` 文本上;未知或无权限的 id 的拒答两者都没有)· `ListAgents` 里本进程没有活句柄的名册行(`state:"unknown"`)· 后台子代任务 poll 的 `details`(它的 `type` 是 `background_agent`,不进 `structured`;引擎的 `TaskOutput` 工具已退役,这份 poll 如今只有下面的 HTTP 读口);
|
|
163
|
+
· 持久子代行的读口 `GET /v1/runs/:id/subagents/:handle/output` 与 `GET /v1/runs/:id/tasks/:tid/output` 的体里 `output.agentState` 与 `content` 的 `state:` 行,对别的副本写下的行同读:已结行 `lastActivityAt` 是落定时刻,停驻行是停驻时刻,
|
|
164
|
+
别的副本还标 running 的行答 `not_local` 且 `agentState` 无 `lastActivityAt`;**停驻行(行上有审批 token)的审批卡读 `unreadable`、不带 `checkpointId` / `deadline`**(读口不交检查点座,当前实现的有意决定;行上没有 token 的读 `missing`)—— 等的那张卡看 `GET /v1/approvals` 的 `pending[]`。
|
|
165
|
+
**谁受影响**:读 `structured.agentState` / `output.agentState` 渲染子代窗格或状态行的壳与 SDK。**不改会怎样**:按「所有后台子代应答都带 `agentState`」写的渲染在拒答、名册 `unknown` 行、停驻行审批卡三处读空。
|
|
166
|
+
**怎么改**:按上面的缺席形处理(缺席读作「这一条没有状态」,不读作出错);停驻子代的审批态读队列行。**升级前做**:无。**回滚**:无需(只改文字与测试)。
|
|
167
|
+
13. **收编批量导入:源主体把本机会话导进收编目的地 `POST /v1/adoption/:id/sessions`,能力位 `adoptionImport`(按调用方 present-iff)给出 `:id` 与两只帽;两根新旋钮 `ADOPTION_IMPORT_MAX_SESSIONS` / `ADOPTION_IMPORT_MAX_SESSION_BYTES`(新面;wire 加性;部署零动作)**:
|
|
168
|
+
旧形:收编(`POST /v1/adoption`,operator)只改绑云端已有的行;用户本机的会话没有门进到收编目的地。
|
|
169
|
+
新形:源主体本人(逐字等于那条收编行的源主体;operator 不能代)以自己的身份 `POST /v1/adoption/:id/sessions`,体恰好 `{ "sessions": [ { "clientSessionId": "<本地 id>", "entries": [ … ] }, … ] }`,
|
|
170
|
+
会话导进那条收编的目的主体名下(请求体不能点名目的地)。云端会话 id 由 `(adoptionId, clientSessionId)` 确定性派生:重投 / 续传 / 并发都只落一份,已在的读成 `already_imported`。
|
|
171
|
+
200 + 逐元素结局 `imported` / `already_imported` / `rejected{code: too_large | invalid_envelope | duplicate_client_session_id}`;信封多一个键(如 `cwd`)⇒ 这个元素 `invalid_envelope`(本版不存会话元数据)。
|
|
172
|
+
导进来的会话与会话同步推送进来的一样是只读镜像(执行放置 `mirror`):读得到、列得出,要在云端接着跑先 `POST /v1/sessions/:id/fork`;直接在上面执行答 409 `conflict.session_mirror` + `forkPath`。
|
|
173
|
+
整请求拒:没有身份 401;local / 内存后端 501 `capability.adoption_store_required`;没有这条收编 404 `not_found.adoption`;不是源主体 403 `auth.adoption_source_only`;没收编完 409 `adoption.not_adopted`;
|
|
174
|
+
体形 400 `request.body_shape`;元素数超帽 400 `request.field_invalid`(`field: "sessions"`、`reason: "over_cap"`、`count`、`cap`)。
|
|
175
|
+
`GET /v1/capabilities` 对源主体本人多一位 `adoptionImport: { adoptionId, maxSessions, maxSessionBytes }`(别的调用方、没收编完、部署没有这一面 ⇒ 键缺席)。
|
|
176
|
+
两根旋钮(配置目录可读):`ADOPTION_IMPORT_MAX_SESSIONS`(每请求元素数,缺省 100,地板 1)、`ADOPTION_IMPORT_MAX_SESSION_BYTES`(每元素 JSON 字节数,缺省 6291456,地板 1048576,天花板 8388593);越界钳到边界并起服告警,小数拒启。
|
|
177
|
+
**谁需要**:从本机升迁到云端部署的用户与替他们做一键升迁的壳 / 客户端。**谁受伤**:信封带元数据(工作目录、首尾时间戳)的客户端要剥掉再送;导进来的会话是只读镜像,在云端接着跑要先 fork(新会话 id);整只请求体超过 8 MiB ⇒ 整请求 413(没有逐元素结局),单只信封本身超过 8 MiB 的会话导不进来。
|
|
178
|
+
同批的门收紧:会话同步推送第二阶段与本口共用一道条目门,存不下的条目(`id` / `parentId` 超 64 字符、`type` 不是 1–32 字符的串)现在答 422 `invalid_entries`(新句)—— 此前 SQL 店上是 5xx,local 店上照收。
|
|
179
|
+
**补偿**:按能力位的两只帽分批;结局逐元素给码;重投安全;运维可抬两只帽。**升级前做**:无(新面;不配旋钮即缺省值)。**回滚**:回到上一版即无此口与此位(已导入的会话是目的主体名下的普通会话,留在库里照常可用)。
|
|
180
|
+
14. **hooks 托管车道成为任务座上自己的一张引擎注册 `settings.hooks.managed`:引擎的 handler 预算(`HOOKS_TIMEOUT_MS`)每车道一份,非托管钩子吃光自己那份不再让托管钩子在 `Stop` / `SubagentStop` / `PreCompact` / `PostToolUse` 族上整只不跑且无声;托管车道被自己的预算叫停记 `hook_managed_unrun{budget_exhausted}`;`Stop` 上 `continue:false` 只撤本车道的推回(安全轴,失效关闭;行为修复 + wire 加性:新注册名、既有原因词多一种成因;部署零动作,按注册名字面读的读者见「升级前做」)**:
|
|
181
|
+
旧形:请求的 hooks 不分车道,铸成任务座上一张引擎注册 `settings.hooks`,两条车道(非托管 / 托管 = 组的 `source` 为 `managedPolicy` 或 `managedPlugin:<name>`)在这一只 handler 里共用引擎的一份 `HOOKS_TIMEOUT_MS` 预算;
|
|
182
|
+
本服务的车道墙钟只门新条目起跑,一条已经起跑的非托管条目能跑到自己的 `timeout`。它把这份预算吃光时,`PreToolUse` / `UserPromptSubmit` 上引擎 fail-closed 拒(方向对),
|
|
183
|
+
其余站上引擎跳过整只 handler —— 托管钩子一条也不跑、本服务不发任何帧,连非托管已经给出的上下文也一起丢。能力位 `taskSettings.managedHookGroups` 说「托管组跑不成即失效关闭」,这一支不是那样。
|
|
184
|
+
新形:一条车道 = 一张引擎注册。有非托管组 ⇒ `settings.hooks`(名字、挂法、预算读数、`once` 键与上一版逐字同);有托管组 ⇒ `settings.hooks.managed`,排在 `settings.hooks` 之前、外层挂:
|
|
185
|
+
先把事件交下去,等非托管车道(以及更下方的注册与引擎核心)答完,才在答回来的那一份上跑托管插件相与托管策略相并折叠 —— 托管车道最后判、判的是非托管改写之后的最终输入。
|
|
186
|
+
挂法只有这一种(不随站点变)⇒ 同座的非托管车道与更下方的运维 handler 恒先判,否决恒跑。
|
|
187
|
+
**收紧一条**:部署座(运维声明的 mod 包)在 `classic.PreToolUse` 上、**任务座之下**(`append` 档)挂了链成员 ⇒ 那一站上托管条目**只许收紧** —— 否决 / 问(含托管条目没跑成时失效关闭折的问)/ 上下文照收;
|
|
188
|
+
放行 ⇒ 这次调用拒(与不带标签的放行在运维 handler 之下被引擎座信任律拒同一个结局);改写(带 `ask` 的也算)给不进运维 handler(它只判过改写之前的那一份)⇒ 这次调用拒;下方要真人批的问(`requiresRealApproval`)在托管作答之后照旧要真人批。任务座之下的链站点读引擎的准入记录(观察者不算;记录不带匹配器 ⇒
|
|
189
|
+
运维 handler 带匹配器、这一次调用不中时也按「有」收紧 —— 只多收紧,不跳过否决)。部署座链成员只在任务座之上(`prepend` 档,或同档 `user` —— 同档里部署座在前)的站上不收紧:运维 handler 已先判、并在答回来的结果上再判。
|
|
190
|
+
每条车道各有一份引擎预算(两张注册读同一个 `HOOKS_TIMEOUT_MS`)、一只事件墙钟、一份 prompt 条数、一份上下文额度与一份 `once` 账。非托管把自己的预算吃光 ⇒ `PreToolUse` / `UserPromptSubmit` 上引擎照旧 fail-closed 拒
|
|
191
|
+
(拒句点名 `extension "settings.hooks"`),其余站上引擎只跳过非托管那只 handler,托管车道照跑。托管车道被自己的引擎预算叫停 ⇒ 撞上的那条托管同步条目记未跑成,发 `hook_notice` 帧
|
|
192
|
+
`kind: "hook_managed_unrun"`、`reason: "budget_exhausted"`(与墙钟到点同一个词),`detail` 点名引擎预算(`HOOKS_TIMEOUT_MS`)并说其后的托管条目都没跑;每个事件恰一帧(其后的组 / 相 / 重判那一遍不再起、不再记);
|
|
193
|
+
叫停之后才跑完的 http / prompt / agent 条目(不持子进程、不随信号停)同样按叫停记;拒站上引擎照旧 fail-closed 拒,其余站上结论是下方的答案。任务取消叫停不记帧(成因在叫停那一刻定,取消之后子进程收尾拖过预算余量也不记)。
|
|
194
|
+
没有托管组的请求只得到 `settings.hooks` 一张,与上一版逐字同。有托管组时折叠与上一版同,三处读法变了:
|
|
195
|
+
① `Stop` / `SubagentStop`:每条车道的 `continue:false` 只撤本车道的推回(本车道的拦停与上下文一并丢),别的车道的推回、运维声明的部署座链成员的推回都不撤 —— 两车道意见相左
|
|
196
|
+
(一条 `continue:false`、另一条拦停或只给上下文)⇒ 推回作数、这一轮不收场(连续推回仍受引擎上限 8 兜住);上一版任一车道的 `continue:false` 让两车道的请求钩子整体无意见。
|
|
197
|
+
② 观察站(`PostCompact` / `StopFailure`):两张注册按链序串行,托管车道先跑、非托管后跑(上一版同一只 handler 里非托管先;观察者不作答,次序不进任何结论)。
|
|
198
|
+
③ 两车道都给上下文且合计超过 10 000 字:非托管车道先在自己那张注册里截一次,托管车道把答回来的那一整段排在自己的上下文之后、在剩余份额里只截尾 —— 托管的上下文仍整段在前,
|
|
199
|
+
非托管那一段里条目的边界与「省略几条」的计数不再与托管的一起算(可能见到两行截断标记)。
|
|
200
|
+
订正 7.137.0 节第 10 条的铸点数(那一节原句不动):本服务自己铸的 handler 答案铸点(带 `action` / `block` / `additionalContext` / `overlays` 键的对象字面量,判据不变)现为共 19 处 —— hooks 车道注册 18 处、部署座品牌行 1 处 —— 仍全是普通对象字面量;托管车道接在下方答案之上作答时,用展开把下方答案的成员原样带上(拷贝,不另铸)。
|
|
201
|
+
**谁需要**:带组织策略钩子(组上标 `managedPolicy` / `managedPlugin:<name>`)的壳与嵌入方 —— 一条慢的或挂住的用户 / 项目 / 插件钩子不再能让托管的 `Stop` / `PreCompact` / `PostToolUse` 守卫整只不跑且无声;托管车道自己超时也看得见。
|
|
202
|
+
**谁受伤**:① 一个事件的最坏墙钟由 1 × `HOOKS_TIMEOUT_MS` 变成 2 ×(缺省 600 s ⇒ 1200 s);② 两车道意见相左的 `Stop` 钩子(一条 `continue:false`、另一条推回 ⇒ 这一轮不收场,上一版收场);
|
|
203
|
+
③ 按字面只认 `settings.hooks` 一个注册名的读者:有托管组时 `wiring_manifest.mods[]` 多一行 `settings.hooks.managed`,`allowRuleShadowed[].entries`、`askReasons[].registration` 与钩子失败时模型读到的拒句在托管车道作答 / 失败时点名它;
|
|
204
|
+
④ 运维声明、`append` 档(任务座之下)在 `classic.PreToolUse` 上挂链成员的部署 mod 包:带托管标签的组在那一站上只许收紧 —— 改写 ⇒ 这次调用拒(带匹配器的运维 handler 不中的调用同样拒;上一版那种调用上改写作数)、
|
|
205
|
+
放行 ⇒ 拒(带匹配器的运维 handler 不中的调用同样拒;上一版运维 handler 在链上时同样被拒)、问照问(上一版同形被拒)、否决照常;不带标签的组与上一版同;自报托管标签换不来运维 handler 之上的放行或改写;
|
|
206
|
+
只挂观察者、或链成员只在任务座之上(`prepend` / `user` 档)的部署包不受影响;
|
|
207
|
+
⑤ 两车道上下文合计超过 10 000 字时非托管那一段的截法(见上 ③);⑥ 跨车道依赖执行次序的观察站钩子(参照实现并发跑同一事件的钩子,次序本就不是契约)。
|
|
208
|
+
**补偿**:`HOOKS_TIMEOUT_MS` 照旧可调(调低即同时收紧两份预算);能力位 `taskSettings.managedHookGroups` 不变(位说的话现在逐字成立);不想要这层严格,去掉组上的 `source`(缺席 = 非托管,只有一张注册);
|
|
209
|
+
④ 那一形要托管放行 / 改写作数,运维把那只 mod 挂到 `prepend` / `user` 档(在请求钩子之上判)。
|
|
210
|
+
**升级前做**:按字面只认 `settings.hooks` 的 `wiring_manifest` / `allowRuleShadowed` / `askReasons` 读者改为同时认 `settings.hooks.managed`;上游请求超时按 2 × `HOOKS_TIMEOUT_MS` 的最坏事件墙钟复核。
|
|
211
|
+
**回滚**:回到上一版即恢复一张注册、共用一份预算、旧的 `Stop` 折叠与观察站次序(无持久面)。
|
|
212
|
+
|
|
213
|
+
15. **请求面压缩开关:`settings.autoCompactEnabled`(CC 2.1.309 settings 同名键,布尔)逐字交给引擎的自动压缩座 `compaction.autoCompact`;能力位 `taskSettings.autoCompactEnabled`(wire 加性;不带这个键的请求行为不变;部署零动作)**:
|
|
214
|
+
旧形:请求面没有压缩开关 —— 壳的 `DISABLE_AUTO_COMPACT` / `DISABLE_COMPACT` 让本地显示说「不会自动压缩」,而引擎照压;`settings.autoCompactEnabled` 在新提交面是集外键,`400 request.body_shape`。
|
|
215
|
+
新形:`settings.autoCompactEnabled`(布尔)被受理,`true` / `false` 逐字交给引擎的自动压缩座 `compaction.autoCompact`(与顶层 `compaction.clampTolerance` 同一个 `compaction` 对象、同一只映射);缺席 ⇒ 不写 `compaction.autoCompact`,缺省值的属主仍是引擎与部署席
|
|
216
|
+
(引擎读序:请求席 → 部署席 → 开;显式 `true` 压过部署席的关,缺席跟部署席走 —— 本服务自己的装配不设部署席,对它而言两者读数相同)。
|
|
217
|
+
非布尔(`"false"` / `0` / `null` / 容器)⇒ `400 request.field_invalid`;续跑重放腿对存量体里的非布尔丢弃、不拒。能力位 `taskSettings.autoCompactEnabled`(恒真):见位才发,老 server 对这个键 `400 request.body_shape`。
|
|
218
|
+
**`false` 关掉的是引擎自起的三遍**(窗阈值那一遍、服务商拒绝过长请求后的恢复压缩、任务尾摘要);手动压缩(`POST /v1/runs/:id/compact`)归引擎的另一只座 `manualCompact`,本服务不写它 ⇒ 不受影响 —— 与参照实现同读(那里 `autoCompactEnabled=false` 只关自动,`DISABLE_COMPACT` 才连手动一起关;壳对后者自己不发 `/compact`)。
|
|
219
|
+
不受这个键管的是请求投影层的另几道缩减:较早的旧工具结果换成指针(不改转录)、请求媒体裁剪。
|
|
220
|
+
关掉之后撞上窗口上限的 run:请求发出前上下文超过守卫线(窗口的 `max(窗口 − 23 000 token, floor(窗口 × 0.85))`)时,引擎不做摘要:先清旧工具结果,仍超线则只保留尾部、较早的消息从这一次请求里省掉(会话里的完整历史不动);
|
|
221
|
+
服务商仍 4xx 拒绝 ⇒ 这条 run 以 `terminal.kind:"failed"` 终局,拒绝被引擎归为「输入本身超出上下文上限」时 `terminal.detail.errorKind` 为 `"input_too_long"`(拒绝点名别的部位时是 `image_unprocessable` / `tool_schema_refused`,缺席 = 没点名已分类部位)。
|
|
222
|
+
**谁需要**:壳 —— 用户设了 `DISABLE_AUTO_COMPACT` / `autoCompactEnabled=false`,此前壳显示「不会自动压缩」而引擎照压;壳见位后把这个布尔发过来,显示与行为才对得上。
|
|
223
|
+
**谁受伤**:发 `false` 的那条 run 自己(更长的历史每回合重发、较早的指令可能落在被裁掉的那一段、可能以 failed 终局),以及共享这份 `compaction` 的委派子代;不发这个键的调用方零变化。
|
|
224
|
+
**补偿**:显式开关本身(发 `true`,或在没有部署席的装配上不发,即回到开);失败终局上的 `terminal.detail` 机读位;每任务预算上限(`maxCostUsd` / `maxTokens`)照常封顶。**升级前做**:无。**回滚**:回到上一版即恢复旧形(壳在老 server 上见不到能力位,不发这个键)。
|
|
225
|
+
|
|
226
|
+
16. **请求的 `settings.env` 不收凭据:名字是本引擎的凭据变量(配置目录 `secret` 行 ∪ 模型条目 `apiKeyEnv`)或值是秘密形 ⇒ 新提交 `400 request.env_credential_refused`;升级前停驻的任务窗内续跑时剥掉照续(一次性迁移 M38,窗 30 天)(安全轴,fail-closed;wire 新码;调用方动作;部署零动作)**:
|
|
227
|
+
旧形:`settings.env` 只判形与帽(对象、≤ 256 条、键 ≤ 256 / 值 ≤ 32768 字符),凭据形的条目照收;单用户 host / device 车道把它原样叠进模型 shell 的环境,settings hooks 的命令环境与 http `$NAME` 插值也读它。
|
|
228
|
+
新形:会交到子进程的条目里,名字是本引擎的凭据变量(`GET /v1/config/catalog` 里 `secret` 型的全部行 ∪ 生效配置每条模型条目的 `apiKeyEnv`;比名不分大小写)或值是秘密形(settings-schema 的 `containsSecretToken`)
|
|
229
|
+
⇒ `400 request.env_credential_refused`,体带 `field: "settings.env"` 与 `entries: [{ key, match }]`(`match` = `"name"` / `"value_shape"`,两者都中报 `"name"`),值从不回显;不剥、不降级;不分车道。
|
|
230
|
+
续跑:升级前受理、停驻、存体里带这类条目的任务,一次性迁移 M38 的窗(本版发布日 + 30 天)内续跑时这些条目从 shell / hooks 的环境里剥掉、任务照续(运维 warn `settings_env_credentials_dropped`,只计数,不带键名与值);
|
|
231
|
+
窗关后续跑答 409 `resume_blocked_by_policy`(`blockedBy: "request.env_credential_refused"`,同一组机读位),卡仍待决。
|
|
232
|
+
**谁需要**:把模型凭据交给 sema 本机用的用户 —— 凭据不再随一个模型读得到的设置文件进会话的 shell 与 hooks。
|
|
233
|
+
**谁受伤**:还把凭据写进 `settings.json` `env` 的老壳(400);刻意经 `settings.env` 给模型 shell 或 http 钩子一枚秘密形令牌的调用方(400;钩子那一形今天没有替代通道,已知限制);值形扫描误伤的非凭据长串(400);
|
|
234
|
+
窗关后才续跑的升级前停驻任务(409)。
|
|
235
|
+
**补偿**:拒体按 `entries` 逐条机读点名;要让模型 shell 持令牌 ⇒ 放在引擎进程环境里一个不在配置目录、也不是模型条目 `apiKeyEnv` 的名下,配 `inheritEnv:"all"`(单用户 host 车道);窗 30 天 = 停驻行终局兜底缺省。
|
|
236
|
+
**怎么改**(调用方):把凭据挪出 `settings.env`,放进引擎进程启动时的环境(壳起的本机引擎:壳的凭据文件;服务形部署:进程环境 / 编排器的 secret 注入),重发。
|
|
237
|
+
**升级前做**:部署零动作(想让带这类条目的停驻任务不在窗关后 409,窗内续完即可)。**回滚**:回到上一版即恢复旧形(零持久形变化;M38 不写库)。
|
|
238
|
+
|
|
239
|
+
17. **错误码目录加「码族」列:契约附录 A 每个码恰属五族之一(`transient` · `deterministic` · `store_judged` · `pending_decision` · `retention_expired`),消费端按列读、不再各抄一张码表;`wire-changes` 清单多一集 `errorCodeFamily`(契约列加性;应答体零变化;部署零动作)**:
|
|
240
|
+
旧形:「这个失败值不值得重试」「卡还在不在」「留存是不是已被收走」的码集住在各消费端的手写名单里(sdk 十个确定性失败码、client-core 一组留存失效码),server 只在 decide / resume 腿的体上盖 `retriable`(它说「卡仍 pending」,不说「重试会成功」)。新码不进名单就被静默重试。
|
|
241
|
+
新形:契约文档附录 A.1 / A.1b 每一行的第二格写码族;A.1g 是词表与读法;A.1h 登记 33 个表外扁平码的族。五个词 —— `transient`(原样重发等一等可能成)· `deterministic`(重发改不了判,别自动重发)·
|
|
242
|
+
`store_judged`(逐次由店判,读体键 `permanence`)· `pending_decision`(卡仍待决,读体键 `retriable`:在场说「卡还在」,不说「重发会成功」;缺席不推出卡已不在)· `retention_expired`(留存已被收走,新开)。传输层的重试判据 =
|
|
243
|
+
状态 ∈ 重试集(408 / 429 / 500 / 502 / 503 / 504)∧ ¬(族 = `deterministic` ∧ 状态不是 408 / 425 / 429:等待类状态不被族豁免)∧ 体 `permanence` ≠ `terminal`。`wire-changes/server@7.146.0.json` 起多一个集 `errorCodeFamily`:本版整列入册进 `registered`(码本来就在 wire 上),
|
|
244
|
+
之后的版本记族的增删改。**应答体一个字节没变**:没有新码、新键、新状态码。
|
|
245
|
+
**谁需要**:sdk(`NON_RETRYABLE_CODES` 可改按列派生;对着手写的十码对账,多出 `auth.service_token_required` · `state.no_sandbox_base` · `state.mcp_reconnect_unsettled` 三个 503 码,这三个重试不会好)、client-core(留存失效码集与「卡仍待决」的读法)。
|
|
246
|
+
**谁受伤**:没有人被迫改。按列读之后行为会变的至多两处:传输层的豁免集多上述三个 503 码(这几个口多半是非幂等 POST,sdk 现有的动词门本来就不自动重发它们〔推断,未逐口核〕,实际行为变化至多是边角);`resume.cap` 与 `resume.session_not_found` 不再属于「留存失效」(归 `deterministic`,渲通用的「不可续」),`retention_expired` 目前只有 `resume.evicted` 一员。
|
|
247
|
+
**补偿**:不读这一列的消费端零变化;表外码(core 原码镜像,如 `resume.tool_unavailable` · `checkpoint.config_refused`,不在目录行里)没有族,缺省读法照旧 —— 看状态与前缀,体上有 `retriable: true` 照 `pending_decision` 读。
|
|
248
|
+
**升级前做**:无。**回滚**:无需动作(文书与生成器的清单;回到上一版时目录没有这一列,按列读的消费端回落到自己的名单)。
|
|
249
|
+
|
|
250
|
+
18. **会话记忆状态报出引擎记忆写家:带层座(`?scope=`)时多一个可选键 `writeHome`(那只店的引擎答案,绝对目录,字节原样),不带层座时多两个可选键:顶层 `writeHome`(引擎在店之间择好的会话级一个家)与 `planes`(逐店明细里引擎答的 `writeHome` 原样透出);单用户 `host` 车道在场,其余车道缺席,与能力位 `projectContext` 同一只射程谓词(wire 加性;部署零动作)**:
|
|
251
|
+
旧形:会话记忆状态体是 `sessionId` · `autoConsolidationArmed` · `memorySync?` 加五个会话键;引擎把会话写进哪个目录,没有任何 wire 面报出来(能力面只有记忆引擎的后端与向量模式)。
|
|
252
|
+
新形:路径由引擎定义,本服务只透出,不拼、不规范化、不折叠、不择一。`writeHome` 是店绑定的键(会话的写家住在哪只店,就由那只店的引擎答)。带 `?scope=<层键>`:那一层住的店的引擎答案,多一个可选顶层键 `writeHome: string`(canonical 绝对目录)。
|
|
253
|
+
不带 `?scope=`:整个部署的答案 —— 多一个可选顶层键 `writeHome`,是引擎在店之间择好的会话级一个家(点名家的店里最近写入的那只的家;任一店的写家读不出、两店同一时刻点名、或没有店点名 ⇒ 缺席,引擎不铸替身;单店部署 = 那只店自己的);
|
|
254
|
+
再多一个可选顶层键 `planes: [{ plane: "project" | "personal", writeHome?: string }]`,每只店一行(店序是引擎的),`writeHome` 是那只店引擎答的值原样,这只店没有家的行只剩 `plane`;行里引擎的其余五键不上 wire。
|
|
255
|
+
在场 ⇔ 引擎答了 ∧ 部署形表行 `callerOwnsWorkerDisk` 为真(= `GET /v1/capabilities` 的 `projectContext` 为真的那些部署:单用户 `host` 车道);托管 / 沙箱 / 设备 / 无手车道两键都缺席(`planes` 整个键也缺席)。缺席不等于「老 server」:
|
|
256
|
+
引擎不答它时(会话既没有账户行、也没有已提交的贡献可命名写域,或这些源读不出,或记忆库布局还不能派生家)行里没有 `writeHome`;不带层座时引擎不择(另一只店的写家读不出 / 两店同刻)顶层也缺席;`projectContext` 为假的部署永远不会有这两键。其余键、状态码、错误码零变化。
|
|
257
|
+
**谁需要**:单用户本机部署的壳(打开会话记忆目录一类的面,不再自拼带哈希后缀的目录名)。
|
|
258
|
+
**谁受伤**:没有人被迫改 —— 按闭集键读体的消费方对多出的可选键不受影响;要知道这是 worker 这台机器上的路径,只在 `projectContext` 为真(单用户 `host` 车道)时才来;本服务不判调用方的壳与 worker 是不是同一台机器(单用户部署里调用方就是主人),
|
|
259
|
+
分居两台机器时这个路径对壳没有意义,壳要自己判;不带层座时顶层缺席不等于会话没有家 —— 读 `planes[]` 或带 `?scope=` 看各店自己的。
|
|
260
|
+
**补偿**:缺席可读 —— `projectContext` 为假 ⇒ 两键不会来;为真时顶层缺席读 `planes[].writeHome` 或带层座。
|
|
261
|
+
**升级前做**:无。**回滚**:回到上一版即不再有这两键(其余键不变)。
|
|
262
|
+
|
|
263
|
+
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:两码加性、一回执词退出;升级前做见本条)**:
|
|
264
|
+
换钉:`@sema-agent/core` 7.62.0 → 7.63.0 精确,`@sema-agent/primitives` 随之 7.63.0。下列各项按「谁看得见」排。
|
|
265
|
+
① **停驻的工具审批行(硬破坏)**:
|
|
266
|
+
旧形:停驻行与活问上的绑定摘要只摘入参;一张对 Write 的批准与同一调用 id、逐字同参的 Edit 摘要相同(本服务另把工具名放进审批身份,活门上已分问)。
|
|
267
|
+
新形:停驻行的 `boundInputHash`、活问与路由问的摘要、批准的许可一律摘 `{ tool, input }` 一条记录,停驻行用一个读方要求词自报这一读法。升级前停驻的工具审批行没有这一声明 ⇒ 本版引擎在认领前拒,
|
|
268
|
+
行字节不动、仍 pending:`POST /v1/approvals/:id/decide`(与其余续跑口)答 `409 approval_binding_mismatch`、`reason: "requirements_damaged"`、`retriable: true`,run 行重新停驻,卡不孤儿;
|
|
269
|
+
引擎句点名「摘要早于工具绑定」;收件箱与运维队列上这一行的 `rowVerdict` 同为 `damaged`。反方向同理:本版停驻的行带着上一版不认识的读法声明,混跑期落到 7.145.x 副本上的续跑答 `409 checkpoint.unsupported_version`(`reason: "version_newer"`),行同样留着。
|
|
270
|
+
活问(非停驻)的审批身份里含摘要 ⇒ 升级前已决的活问,升级后同一调用再问一次会出一张新卡(不回放旧答案;安全方向)。
|
|
271
|
+
② **规则导入回执**(`POST /v1/rules/cc-import/redeem` · `POST /v1/rules/local-import/redeem`):
|
|
272
|
+
旧形:成员里引擎拒的一律 `outcome: "indeterminate"` + `reason: "store_refused"` + `detail` = 引擎原话(那时引擎的拒只带自由文本)。
|
|
273
|
+
新形:引擎给拒臂两只机读位(拒因码与「落没落」)。`committed: "no"` ⇒ `outcome: "refused"`(没落);`committed: "unknown"` ⇒ `outcome: "indeterminate"`(写可能已落);
|
|
274
|
+
两者的 `reason` = 引擎拒因码原样(引擎闭集,17 词;例:旧导入记录里从 `/` 写起的全局规则 ⇒ `refused` + `unsupported.layer_root`,店写抖动 ⇒ `indeterminate` + `store_write`),`detail` 仍是引擎原话。`store_refused` 退出 wire。
|
|
275
|
+
滚动升级窗:7.145.x 副本落定、票行仍在(local-import 票寿内)的回执被本版副本回放时,回执里的 `store_refused` 读不出 ⇒ 响亮拒(不改写落盘回执);票行随票寿被收走即闭窗,不另做迁移。
|
|
276
|
+
反方向同理:本版落定、票行仍在的回执被 7.145.x 副本回放时,只要有一条引擎拒的成员(它的 `reason` 是引擎拒因码,7.145.x 的回执边界 schema 只认 `store_refused`)整张读不出 ⇒ 那一次回放响亮失败(服务器通用错误,不是 200 回执;不改写落盘回执、不重跑兑付);
|
|
277
|
+
全是 `persisted` / `no-op` 成员的回执两版互读无碍。同样随票寿闭窗;混跑期把 local-import 的兑付与重放都打到同一版本的副本上即可避开。
|
|
278
|
+
**本版第 23 条 ⑥ 取代上面 `indeterminate` 的读法**:规则导入这两口上,任一成员引擎答 `committed: "unknown"` ⇒ 不落定、放回认领、`503 state.rule_import_retry` 同票重走,落定的 200 回执里不再出 `indeterminate` 成员(`refused`、`reason` = 引擎拒因码、`store_refused` 退出这几处照旧)。
|
|
279
|
+
③ **记忆**:
|
|
280
|
+
— `userlocal:<P>` 族(个人平面上只留本机、不复制的层):同步层(显式 `MEMORY_SYNC_SCOPE`,或由 `MEMORY_SCOPE` 缺省派生)是这一族 ⇒ 起服拒(点名旋钮);
|
|
281
|
+
中心同步口 `POST /v2/memory/sync/:scope` 对这一族答 `400 memory_sync_invalid_scope`(既有码),在属主门之前。判据只有引擎的复制判官一只。
|
|
282
|
+
受影响的不止同步层:7.145.x 的前缀表里没有 `userlocal:`,字面以 `userlocal:` 起头的层键(`MEMORY_SCOPE`、登记簿各项目的 `defaultScopes`)按不透明层读、落项目平面;
|
|
283
|
+
本版按保留前缀读 ⇒ 带它的读列表声明 v2(同列表里保留前缀的折叠拼写随之按下一条拒),这一层落个人平面、不复制 —— 7.145.x 上写进这一层的条目留在项目平面原处,升级后这一层读不到它们;
|
|
284
|
+
不当同步层用的这种层起服不拒、不告警。谁需要:7.145.x 上手拼过这种字面层名的部署;谁受伤:这一层的可见域静默由项目面移到个人面;
|
|
285
|
+
补偿:升级前给这一层改名(改成不以保留前缀起头的键;改了名的键是另一层,要带走条目先用 `GET /v1/memory/export?scope=<旧键>` 留一份)。
|
|
286
|
+
自检:升级前在 `MEMORY_SCOPE` / `MEMORY_SYNC_SCOPE` 与登记簿各项目的 `defaultScopes` 里找字面以 `userlocal:` 起头的键,有则先改名再升级。
|
|
287
|
+
— v2 契约下,读作保留前缀(`user:` / `userlocal:` / `org:` / `proj:` / `userproj:`)的另一种拼法(大小写不同、全角冒号、前后空白)拒(`config.memory_scope_key`),不再当作不透明层;
|
|
288
|
+
`userlocal:` 的折叠拼写在不声明 v2 的部署上也不复制。
|
|
289
|
+
— 合规档 `hipaa` / `zdr` 的内建否决多一词 `memory_consolidation`:显式 `MEMORY_CONSOLIDATION_DRIVER=on` 与这两档(或 `COMPLIANCE_ADDITIONAL_DENIES` 含该词)同设 ⇒ 起服拒(拒句点名三只旋钮);
|
|
290
|
+
未设 ⇒ 整理阀门缺省关、零提示 —— 手动整理口(`POST /v1/admin/memory/consolidation/run`)因此答 `501 feature.memory_consolidation_disabled`(句子说阀门关,不点名合规档);
|
|
291
|
+
手动整理每一轮也交部署档位(引擎否决 ⇒ `409 memory.consolidation_refused`,拒因 `config.compliance_denied`),但本服务的装配下档位否决时阀门结构上开不起来,这一 409 不可达。
|
|
292
|
+
— 店集只算**写过**的个人店:被拒的个人层抹除、点名个人层的只读不再让个人店进店集(目录照旧会建 —— 引擎的开店律没变,店集不再读它);
|
|
293
|
+
一次成功的写、一次执行了却什么都没擦的个人层抹除(它在个人店记下请求锚)让店进集。订正 MIGRATION 7.144.0 节第 11 条 ⑤ 的已知限制(那一节原句不动):
|
|
294
|
+
不点名层的出处 / 清标账 / 清标不再因一只从没写过的个人店永久答 `400 request.memory_layer`;盘上已留下的空个人店零迁移、零删除,自本版起不算 —— 那一条「补偿」里删 `personal/` 目录的手动步骤不再需要。
|
|
295
|
+
— 公告队列(file 形记忆控制面里的 `announcements.json`)读不出:此前下一次写入静默换成空队列(积压的公告丢了、无声);本版每次入队与取出都响亮拒 —— 运维日志
|
|
296
|
+
`memory_engine_incident`(`code: "memory.announce_failed"`,计数 `memory_engine_incident_total`),坏字节原样留给运维,修好或删掉文件即恢复;队列坏着时控制面账本的重建也拒。
|
|
297
|
+
队列锁等过 3 s 的入队此前不持锁照写,本版拒那一次入队(同一条日志),不落无锁的写。
|
|
298
|
+
— 层键读不出的起服拒(`config.memory_scope_key`,同步层 / 记忆层键)句首由 `resolveMemoryScopeStore: …` 换成 `memoryScopeStores.planeOf: …`(平面那一问改由引擎的一只读法答;码不变;
|
|
299
|
+
订正 MIGRATION 7.140.0 节第 6 条括号里引的句首,那一节原句不动)。
|
|
300
|
+
— SQL 记忆腿(`MEMORY_ENGINE_BACKEND=pg|mysql`)的落点问询:问的整圈交引擎(轮数上限、超限拒码),行为见本节第 3 条(已按本版终形写)。
|
|
301
|
+
— 引擎包根退役五名(整理驱动的计划目录 / 运行文件两只常量、`archiveDistillerPlan`、`readConsolidationDriverRun`、`readIntentCredentials`):本服务的读者改读引擎对象上的异步座
|
|
302
|
+
(整理运行行),运维面与 wire 零变化;自己从引擎包 import 这些名的嵌入方按引擎的迁移说明改。
|
|
303
|
+
④ **停驻行的成员形**:引擎读一行停驻行只用一张成员形表 —— 门是已登记门类的记录、`pendingAction` 是已登记种类的记录(工具审批带串 `toolCallId`)、`state` 是记录、
|
|
304
|
+
`createdAt` 是有限数、`deadline` 缺席或有限数;不合 ⇒ 判官答 `damaged`(`requirements_damaged`),续跑 / 决断拒、行留 pending、字节不动,列表面照列它、`rowVerdict` 非 `ok`。
|
|
305
|
+
此前只缺 `pendingAction` 的行判官答 `ok`(行照列却决不了);门类缺席 / 不是串的卡在决断口上的 `error` 是判官对这份字节的那一句(判官答 `ok` 的罕见形说自己读不出门类;`gate_not_tool_approval`,码不变);门类是一个本引擎没登记的串时仍是既有的门类指路句(既有行为,本版未动)。
|
|
306
|
+
`DB_BACKEND=local`:收件箱 / 运维队列(含订阅流)/ 任务视图对摘要读不动的行(缺 `state` 等)照列一行 —— 身份键 `sessionId` / `scope` / `gateKind`? 取引擎读出的那一份,`createdAt` / `deadline` 照存储体上的原值带(未经引擎读出、不校形;坏行上它们可以不是数),
|
|
307
|
+
摘要派生的键缺席 —— 不再整张 `503 approvals.read_unavailable`。订正 MIGRATION 7.145.0 节第 8 条「local 的列表面候引擎」与那一条的例外句(那一节原句不动)。
|
|
308
|
+
SQL 后端的坏行照旧由本服务在存储体之外握着的列事实答(会话 / scope / 建行时刻 / 门型 / `checkpointId`),wire 形不变。
|
|
309
|
+
7.49.0 之前停驻(不带行摘要)且成员形不对的行(例:`deadline: null` 当「无截止」、`createdAt` 是 `NaN`)此前能续,本版拒(硬破坏;本服务自己不写这种行)。
|
|
310
|
+
⑤ **后台 fork 子代**(引擎的后台委派 fork 出的子会话):建行那一笔就落进委派分区(三只会话店同一条:SQL 两孪生与行同一条 INSERT,local 随存档行头)⇒ 不出现在 `GET /v1/sessions` 列表里、
|
|
311
|
+
按会话 id 的认领形取用拒、随委派树一起列与删(与带放置的委派子会话同一组义务)。行属主照旧是 fork 的属主那一读。客户端经路由的 `POST /v1/sessions/:id/fork` 不变(不带放置)。
|
|
312
|
+
⑥ **停驻赎回的完成**:本进程持有停驻的子代赎回跑完 ⇒ 完成回到停驻周期欠账的那条车道(根会话正在跑的那一轮,或下一轮开轮时投出一帧 `task_notification`(`task_type: "background_agent"`));
|
|
313
|
+
此前经会话通知门进根会话收件箱。停驻落在别的进程 / 重启之前的(跨进程)⇒ 照旧经会话通知门,另有一条运维受众的引擎通告 `delegation.resume_lane_missing`(`{ taskId, rootSessionId? }`,不上会话流)。
|
|
314
|
+
⑦ **通告**:用户面引擎通告白名单加两码 —— `memory.harvest_refused`(记忆收割整批被拒;`detail { kind, committed, reportId?, sessionId? }`)与 `memory.harvest_conflict`
|
|
315
|
+
(店没收下部分改动;`detail { count, conflicts[{ op, id, concurrent }], reportId?, sessionId? }`);引擎的通告码 `session.records_skipped` 退出(本服务自 7.144.0 起已不发)。
|
|
316
|
+
**谁需要**:所有部署(引擎随版换);用 hipaa / zdr 档的部署(记忆整理与合规档同一条否决);多副本与重启频繁的 file 部署(店集一个事实一种读法);导规则的壳(拒因码可按码处置);
|
|
317
|
+
`DB_BACKEND=local` 上读审批列表的壳(一行坏字节不再挡住整张)。
|
|
318
|
+
**谁受伤**:① 升级时还挂着待决工具审批卡的部署 —— 那些卡在本版上决不了;混跑期两版互拒对方停驻的行;
|
|
319
|
+
② 按 `reason: "store_refused"` 字面分支的回执读者;③ 把同步层写成 `userlocal:` 族或折叠拼写的部署(起服拒);v2 部署上用折叠拼写当层名的请求;同时开着整理阀门与 hipaa / zdr 档的部署(起服拒);
|
|
320
|
+
按层键拒句的句首做字符串匹配的脚本;公告队列文件坏了的 file 部署(公告在修好之前不送达);
|
|
321
|
+
④ 7.49.0 之前停驻、成员形不对的行(本版决不了);只按位置列 `ok` 行的列表读者(多出 `damaged` 行);
|
|
322
|
+
⑤ 按会话列表找后台 fork 子会话的读者(它们改在委派树里);⑥ 本进程停驻的赎回完成时根会话空闲:完成那一帧等根会话下一轮开轮才投,存在进程内存里 —— 进程重启前没开轮就丢(跨进程形不受影响,照旧进收件箱)。
|
|
323
|
+
⑥ 同一帧在进程内只认会话 id、引擎投递时不比住客:根会话被删、进程没重启、同一个 id 又被登记 ⇒ 新住客的下一轮收到删前那一位的子代完成(含结果摘要)。上一版这一形经会话通知门、投递前复核住客,本版不经 ——
|
|
324
|
+
另一位属主重登的那一半由本节第 20 条拦(本进程删的会话);两半都由引擎 7.64.0 的住客地址在进程内关掉(本节第 23 条 ①:删前化身的完成被弃、运维席说一次)。
|
|
325
|
+
**补偿**:① 待决卡升级前决完或 expire(见下);混跑期按副本版本路由续跑,或先排空再整体换版;② 回执读者按 `outcome` 判(`refused` = 没落,`indeterminate` = 去 `GET /v1/rules` 对账),`reason` 按引擎拒因码读;
|
|
326
|
+
③ 同步层改写成可复制的族;不想要整理否决就不用这两档,或不开阀门;拒句按码(`config.memory_scope_key`)读;公告队列看 `memory_engine_incident` 日志、修或删 `announcements.json`;
|
|
327
|
+
④ 列表按 `rowVerdict` 渲(非 `ok` 的行渲其 `sentence`);这样的旧行在停驻它的版本上续完,或 expire 后重跑;
|
|
328
|
+
⑤ 后台 fork 子会话按委派树读(`GET /v1/sessions/:id` 的子代 / 委派面);⑥ 根会话的下一轮会结清欠账,要即时看见就保持根会话在跑。
|
|
329
|
+
⑥ 删除之后别马上用同一个会话 id 重开(换新 id 永远安全);另一位属主在本进程用它起执行本版起由第 20 条拒。
|
|
330
|
+
**升级前做**:① 把待决的工具审批卡决完,或 expire(停驻行被 expire 后任务从头再跑);先停光 7.145.x 副本再起本版,不要混跑续跑;
|
|
331
|
+
② 回执读者把 `store_refused` 分支改成按 `outcome` + 引擎拒因码读;③ 核 `MEMORY_SYNC_SCOPE` / `MEMORY_SCOPE` 不是 `userlocal:` 族、不是保留前缀的折叠拼写,登记簿 `defaultScopes` 里没有字面以 `userlocal:` 起头的层键(有则先改名,见 ③);核 hipaa / zdr 部署没有显式 `MEMORY_CONSOLIDATION_DRIVER=on`。
|
|
332
|
+
**回滚**:回到 7.145.x ⇒ 本版停驻的工具审批行在 7.145.x 上答 `checkpoint.unsupported_version`(行留着,回到本版可续),本版落定的回执里的新拒因码 7.145.x 回放时读不出(票寿内);其余各项无持久面。
|
|
333
|
+
|
|
334
|
+
20. **🔴 本进程删过的会话 id 只再执行给删前的属主:另一位属主在本进程用同一个 id 起执行(新提交、续跑、唤醒、停驻赎回)⇒ `409 conflict.session_id_retired`(续跑家族 `409 resume_blocked_by_policy`),什么都不跑(安全轴,fail-closed;wire 新码;行为变更;部署零动作)**:
|
|
335
|
+
旧形:会话 id 由调用方自选;一只会话被删之后,任何主体带同一个 id 提交 ⇒ 当作未知 id 登记给他并开跑;在别的副本上登记的同 id 会话,也照常在这只进程上续跑 / 唤醒。而引擎(7.63.0)把送不到活 run 的完成帧
|
|
336
|
+
(后台子代跑完、本进程停驻的赎回跑完,根会话此刻没有在跑的一轮)按会话 id 暂存在进程内存里、交给这只 id 在本进程的下一只 run、不比住客,会话删除清不到它 ⇒ 删前那一位的子代完成(含结果摘要)
|
|
337
|
+
会交进新住客的下一轮(第 19 条 ⑥ 让「本进程停驻的赎回」这一形也走这条路)。
|
|
338
|
+
新形:`DELETE /v1/sessions/:id` 在删除会话本体之前,在本服务进程里记下「这只 id → 删前属主」;本服务每一条带根会话的执行起点都经同一只执行上下文解析器对根会话行做一次行读,读完就问这份记录:
|
|
339
|
+
本进程删过这只 id、而行上的住客不是删前属主 ⇒ 拒,什么都不跑;句子不回显 id 与属主,只说换 id。「是不是同一位」与会话属主门同一条等价律:字面相等(含无主与无主)、单用户形里无主的行 ≡ `default` 主体
|
|
340
|
+
(壳 ≤1.0.82 留下的存量无主会话被壳带 `default` 删掉、再用同 id 起执行 —— 照常)、非 `REQUIRE_PRINCIPAL` 部署上的存量哨兵 `anon:shell-live` ≡ 没有主体的调用方;有方向、不互推;同一只 id 在本进程删过几次,住客就要对每一位删前属主都是同一位(再删不洗掉前一位),被互不等价的属主各删过一次 ⇒ 谁都不是。
|
|
341
|
+
新提交(`POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs`)答 `409` + `errorCode:"conflict.session_id_retired"`(码族 `deterministic`)—— 这一步在授权口之后,未知 id 已在授权口登记给调用方
|
|
342
|
+
(与解析器同一步的其它拒同序:那只空会话归他,留存收走或他自己删);续跑家族(审批决断后的续跑、`POST /v1/sessions/:id/wake`、`/v1/assistant/tasks/:id/resume` · `/plan_review`、
|
|
343
|
+
工作流决断后的宿主新轮)与停驻赎回答 `409 resume_blocked_by_policy` + `blockedBy:"conflict.session_id_retired"`(认领之前,卡仍待决 —— SLA 到期拒扫那一腿例外:它把准入策略的拒读作确定性,当场过期那张卡、run 终局);A2A 入口照它既有的拒形答(JSON-RPC `-32602`、HTTP 200,
|
|
344
|
+
不带这只码,也不带换 id 的句子 —— 运维日志有原因)。删前属主本人照常。`requireExistingSession` 而 id 不在 ⇒ 仍是 `404 resume.session_not_found`(授权口先答)。
|
|
345
|
+
记录只活在删掉它的那只服务进程里(不落库、重启即消、不跨副本),有界:满了驱逐最旧一条,逐次计数 + 每进程一次 warn(fail-open 计数 tag `server.session-id-tombstone.evicted`,登 `P-DEBT`:被驱逐的 id 上这道门失守)。无旋钮。
|
|
346
|
+
**谁需要**:多租部署与调用方自选会话 id 的部署 —— 一只被删会话的 id 不再成为另一位主体收下删前那一位后台结果的入口。
|
|
347
|
+
**谁受伤**:真想复用一只已删会话 id 的另一位主体(会话 id 是 uuid,撞上别人删掉的那一只的概率可忽略):删掉它的那只进程活着时,这个 id 在那只进程上对他不可用;
|
|
348
|
+
在同一只进程上先后被两位属主删过的 id 对两位都不可用。
|
|
349
|
+
**补偿**:换一个新的会话 id(拒句明示);无开关(安全轴不设放行旋钮)。
|
|
350
|
+
**已知限制**:只记本进程删的 —— 别的副本删的、托管留存按期删的会话不在记录里,那之后另一位主体登记同 id 并在持有暂存的那只进程上起执行,这道门不拦;同一属主删后重登同 id 不归这道门判(第 19 条 ⑥)。
|
|
351
|
+
两形都由引擎 7.64.0 的住客地址在进程内关掉(第 23 条 ①:暂存按会话 id + 住客存取,删前化身的完成被弃、运维席说一次);这道门照常留着,两道独立。
|
|
352
|
+
**升级前做**:无。**回滚**:回到 7.145.x ⇒ 没有这道门(记录本来就只在进程内存里,零持久面)。
|
|
353
|
+
|
|
354
|
+
21. **嵌入方类型面:服务型 `ServiceWorkflowJournalStore`(`StoreBackend.workflowJournal()` 的返回型)的可选成员 `deleteByRun?` 删 —— workflow journal 只剩按龄清扫一条删路;`ServiceConfig` 多七个必填席(嵌入方类型面 BREAKING;零 wire、零表、零存储格式;部署零动作)**:
|
|
355
|
+
旧形:SQL 后端的 journal 店带一只按 run 删(`deleteByRun(runId)`),引擎的 journal 契约从来没有这一员,本服务生产路径零调用者(清扫走按龄的 `reapExpired`)。
|
|
356
|
+
新形:这一员连同服务型上的可选成员一起删,零别名;按龄清扫不变。同一版里检查点店与 workflow journal 店的源文件从 `src/plugins/` 换到 `src/stores-sql/`(类名、导出、SQL、表与列一字不改),
|
|
357
|
+
检查点店两只孪生共用的行形与判据另住一只模块 —— 包的导出表只有根等几只入口,这些文件的路径从包外本来就 import 不到,无需动作。
|
|
358
|
+
同一版 `ServiceConfig` 多七个必填席,`loadConfig` 各从对应旋钮一次铸出:`adoptionImportMaxSessions` / `adoptionImportMaxSessionBytes`(`ADOPTION_IMPORT_MAX_SESSIONS` / `ADOPTION_IMPORT_MAX_SESSION_BYTES`,第 13 条)、
|
|
359
|
+
`serviceTokenActsForDeployment`(`SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT`,第 24 条)、`engineFirstAttachMs`(`ENGINE_FIRST_ATTACH_MS`,第 1 条)、`engineHandoverLingerMs`(`ENGINE_HANDOVER_LINGER_MS`,第 26 条)、
|
|
360
|
+
`runMaxConcurrent` / `runMaxConcurrentPerPrincipal`(`RUN_MAX_CONCURRENT` / `RUN_MAX_CONCURRENT_PER_PRINCIPAL`,第 7 条)。
|
|
361
|
+
**谁受伤**:自建 `StoreBackend`、并对 journal 店调 `deleteByRun` 的嵌入方 —— TypeScript 编译红即通知;自拼 `ServiceConfig` 的嵌入方同样编译红 ——
|
|
362
|
+
绕过类型拼出的配置里 `serviceTokenActsForDeployment` 缺席读作「不代」(只有字面 `true` 是代;出示 service 凭据、不报主体的调用方成了无身份调用方,起服打一行 `service_token_posture { actsForDeployment: false }`)。
|
|
363
|
+
**出路**:按 run 删换成按龄清扫(`reapExpired(now, maxAgeMs)`),或在自己的库上按 `run_id` 删 `workflow_journal` 与 `workflow_journal_owner` 两表的行;`ServiceConfig` 走 `loadConfig`,或照各条的缺省把七席写满。**回滚**:回到 7.145.x 即可(没有数据迁移)。
|
|
364
|
+
|
|
365
|
+
22. **k8s 沙箱 Role 的 `persistentvolumeclaims` 四动词与 `secrets` `create` 改按特性开关授 —— 随包 chart 缺省不再渲这两条规则;设了 `WORKSPACE_CACHE=volume` / `K8S_SANDBOX_ENV` 的存量部署要在 values 里开对应开关(或手写 RBAC 补规则)(部署面;行为收紧;两个旋钮都没设的部署零动作)**:
|
|
366
|
+
旧形:随包 chart 的 `templates/sandbox-rbac.yaml` 与 cluster 静态清单 `stack/sema-stack-cluster.yaml` 对所有部署无条件授 `persistentvolumeclaims`(`get` / `create` / `delete` / `deletecollection`)与 `secrets`(`create`),引擎旋钮开没开都一样 ——
|
|
367
|
+
没开缓存卷的部署也持有 `deletecollection persistentvolumeclaims`,没转发 env 的部署也持有 `secrets create`。
|
|
368
|
+
新形:这两条规则只在对应开关开着时授 —— `WORKSPACE_CACHE=volume` ↔ chart 值 `sandbox.workspaceCacheVolume`(布尔,缺省 `false`;`--set-string …=false` 这类字符串渲染即拒)、
|
|
369
|
+
`K8S_SANDBOX_ENV` 非空 ↔ chart 值 `sandbox.sandboxEnv`(`NAME,NAME` 名单字符串,缺省空)。同一个 chart 值**同时写引擎 env**(主 worker 与 v4pro 变体)与 Role 规则,开关与引擎旋钮只有一个写者;
|
|
370
|
+
cluster 静态清单里这两条规则是注释块,给 server 设了对应 env 时取消注释。规则表只写在源码的一张表里,chart / 静态清单 / 随包 `deploy/facts/sandbox-rbac.json` 与部署前置文档(仓库 docs 目录下 DEPLOY-PREREQS)的规则表都从它生成。pod / exec / log 与出网自检的两只只读照旧恒授。
|
|
371
|
+
**谁需要**:按最小权限部署 k8s 沙箱车道的 owner(没开缓存卷 / 没设沙箱 env 的部署不再持有这两条规则),以及整份拷走 chart 沙箱 RBAC 模板的取用方(规则与开关同表驱动)。
|
|
372
|
+
**谁受伤**:用随包 chart 或静态清单、引擎旋钮是**手补在 Deployment 上**(chart 之外)的存量部署 —— 升级后 Role 里没有对应规则:
|
|
373
|
+
`K8S_SANDBOX_ENV` 点到了本进程环境里有的键而 `secrets` 缺 `create` ⇒ **起服拒**,拒句带 `[sandbox-secret-rbac]`、点名缺的动词与要加的 Role 规则原文;
|
|
374
|
+
`WORKSPACE_CACHE=volume` 而 `persistentvolumeclaims` 缺动词 ⇒ 服务起得来,但每条 run 拿不到缓存卷(run 照起、不挂卷),fail-open 计数 `server.workspace-cache.unavailable` 涨。
|
|
375
|
+
**补偿 / 怎么改**:用 chart 的 —— 在 values 里开对应开关(`sandbox.workspaceCacheVolume: true` / `sandbox.sandboxEnv: "NAME,NAME"`),chart 同时写引擎 env,之前在 Deployment 上手补的同名 env 可以去掉;
|
|
376
|
+
用静态清单的 —— 取消对应规则注释块的注释;自维护 chart / 手写 RBAC 的 —— 照随包 `deploy/facts/sandbox-rbac.json`(`when` 列 = 开关)补那一行规则。把 `templates/sandbox-rbac.yaml` 整份拷进别的 chart 的取用方,只需在自己的 values 里补这两个键(模板自带开关判官;键缺席渲染即拒)。
|
|
377
|
+
**升级前做**:两个旋钮都没设 ⇒ 零动作(升级后 Role 少了两条多余权限);设了的部署按上一条在升级前开好开关。语句与读法同部署前置文档(仓库 docs 目录下 DEPLOY-PREREQS)7.146.0 节。**回滚**:回到 7.145.x 即恢复无条件渲(零持久形变化)。
|
|
378
|
+
|
|
379
|
+
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:一帧键加性;升级前做见本条)**:
|
|
380
|
+
换钉:`@sema-agent/core` 7.63.0 → 7.64.0 精确,`@sema-agent/primitives` 随之 7.64.0。下列各项按「谁看得见」排。
|
|
381
|
+
① **住客地址(硬破坏)**:
|
|
382
|
+
旧形:引擎按会话 id 投帧与排空会话盒 —— 一只会话删了、同一个 id 又被登记(另一位属主或同一位),前任住客的后台工作此后送来的完成、停在会话盒里的信与回执,会进后任的模型。
|
|
383
|
+
新形:地址 =(会话 id,住客),住客 = 会话行上那一格化身(本服务三只会话店建行时各铸一只,删了重建换一只)。投给前任住客的帧与盒记录弃掉、ack 出盒,运维席一条
|
|
384
|
+
`delegation.delivery_discarded`(`detail { taskId, taskType, sessionId, path, addressed, current }`;不带正文、不带化身令牌;不上会话流);被弃的跨会话信给发信方一张 `refused` 回执。
|
|
385
|
+
会话盒的每条记录点名它给哪一位住客(随既有 `peer_meta` 列,零 DDL)。**升级时盒里还停着的、上一版引擎写下的记录不点名住客 ⇒ 升级后首次排空一律弃**(每条一则通告 + 给发信方 `refused` 回执)——
|
|
386
|
+
丢的是旧引擎停而未投的东西:未读的跨会话信、后台子代停驻的话。**混版**:本版写的记录带两只上一版验证器拒的键 ⇒ 滚动升级期 7.145.x 副本认领装着这种记录的盒失败
|
|
387
|
+
(运维日志 `mailbox_message_column_corrupt`),记录留在盒里,全部副本升到本版后照常排空,不丢;反方向不对称:本版副本排到 7.145.x 副本滚动期写下的记录(不点名住客)照样弃(同上通告 + 回执)
|
|
388
|
+
⇒ 全部副本同版之后再放新流量写信。
|
|
389
|
+
复活的后台代理树读不到树根住客 ⇒ 它升到树根的终态帧在树根有住客时被弃(`addressed: unknown`),子代自己会话上那一份保留;此前会进树根的下一轮。
|
|
390
|
+
同一属主删后用同一个 id 重登:删前化身的子代完成在进程内不再交进新化身(本节第 20 条「已知限制」与第 19 条 ⑥ 的那一半随之关掉;第 20 条那道执行起点门照常)。
|
|
391
|
+
② **File 记忆店账本(硬破坏)**:
|
|
392
|
+
旧形:还是「绑定之前」形(裸 id → rev 映射)的 `revs.json`,引擎读时升级。新形:只读带信封的那一形;裸映射与以它为快照的事务日志一律拒(无码 `ControlPlaneCorruptError`)。
|
|
393
|
+
本服务:`POST /v1/memory/export` / `POST /v1/memory/import` 遇它答 `500 internal.memory_control_plane_corrupt` + 引擎拒句;出处 / 整理 / 合规三口同码。7.145.x 上同一只店:出包答 409 `memory.export_incomplete`,入包与其余口照常服务、下一次无争用进入时就地升级账本。
|
|
394
|
+
受影响的是引擎 5.33.0 以来没开过的 File 记忆店。
|
|
395
|
+
③ **记忆控制面载体**:清标账的行改存正文摘要、正文另存为对象(行的下一次加锁写把旧行的正文挪出去)⇒ 7.145.x 副本读本版写过的清标账拒(`ControlPlaneCorruptError`,「row is malformed」)。
|
|
396
|
+
本服务的 `memory-origin` 口经引擎读,答的 `entryText` 与上一版逐字同。隔离席的文件名由 `<毫秒>-hold-<捕获名>` 改成 `<内容摘要前 16 位十六进制>-hold-<捕获名>`,行先写、字节后挪;
|
|
397
|
+
上一版留下的孤字节在升级后首次对账按内容摘要收养。另:引擎的副本控制面收养动词只复制并记回执、不删源(删源随引擎后续版本)。
|
|
398
|
+
④ **停驻行三处判坏**:门类与待决动作不是登记表配好的那一对(六对之外的 24 种)、`checkpointId` 是空串、资源账不是对象 ⇒ 收件箱 / 运维队列 / 任务视图上 `rowVerdict` `damaged`,
|
|
399
|
+
续跑 / 决断在认领前答 `409` + `reason: "requirements_damaged"`,行留 pending、字节不动。此前前一形有的能续:人批准了、行被消费、停着的工具没跑。本服务自己不写这种行;存量有没有,按下方普查数。
|
|
400
|
+
⑤ **规则提议**:批里没有 `kind` 的成员整只批进 `dropped`(`problem: "malformed"`,运维计数 `server.rule-offers.offer-dropped`),审批卡上少这一条提议;此前读作 `command`。
|
|
401
|
+
本服务数这种批的起服普查退役(它的 fail-open 计数 tag `server.approval-batch.kindless-row` 不再计)。
|
|
402
|
+
⑥ **兑付腿**(其中规则导入两口的落定律,取代第 19 条 ② 里 `indeterminate` 成员的读法,见下面「规则导入两只 redeem 口」一段):审批记录店在兑付里读 / 写失败,引擎答带码的拒(`store_read` / `store_write`,带 `committed`),此前抛。本服务读法一条:店故障且引擎说店没变(`committed: "no"`)⇒ 可重试的
|
|
403
|
+
`rule_store_error`,停驻迟到腿不缓存;`committed: "unknown"` 的店故障与其余拒同读 `redeem-refused`(回执缓存 —— 重试是一次新的兑付,那一次写若其实已落,重兑会把其间被撤掉的规则再落一次)。
|
|
404
|
+
批臂读在整只批上:每一员都是店没变的拒、其中有店故障,才重兑。相对 7.145.x:规则店写之前的读失败改为可重试;记 dot 的 CAS / dot 分配失败(落规则之前,引擎答 `unknown`)改为不重试。wire 零变化。
|
|
405
|
+
规则导入两只 redeem 口(`cc-import` / `local-import`):成员结局全部确定(`persisted` / `no-op` / `refused`)⇒ 落定 200;任一成员引擎答 `committed: "unknown"` ⇒ 不落定,放回认领、`503 state.rule_import_retry`,
|
|
406
|
+
同一张票重来即重走(同一条审批记录、记过的 dot;已落的读 `no-op`,其间撤掉的放行不再落,但那一员在重走的回执里仍读 `persisted`,以规则列表为准)。相对 7.145.x:那一形由 200 + 该成员 `indeterminate`(票用掉)改为 503 同票重走。
|
|
407
|
+
⑦ **一次性迁移(7.61.0 之前导入的全局 `/x` 放行起服退役)的 local 腿**:读哪些桶 = 导入记录点名的属主 ∪ 引擎列桶口叫得出的属主(本机属主那只桶、收编标记点名的身份)—— 收编改名之后
|
|
408
|
+
没有导入记录点名的那只桶此前读不到(导入的全局放行照旧在每个项目根放行),本版读到、退役;引擎判坏的桶(`permission_rules.bucket_damaged`)点名跳过、不挡起服、字节不动;
|
|
409
|
+
一次读失败(`permission_rules.bucket_unreadable`,带 `errno`)照旧起服拒。叫不出属主的桶仍不读。
|
|
410
|
+
列桶口本身拒也起服拒:规则目录被引擎判为不可用(`permission_rules.bucket_damaged`)、列目录读失败(`permission_rules.bucket_unreadable`,带 `errno`)、收编标记读不出 —— 这三形没有「跳过这一只桶」可言,整次迁移不跑完。
|
|
411
|
+
规则目录在就列,没有导入记录也列(7.145.x 上没有导入记录时这一腿零读、不会因此拒);规则目录不在 ⇒ 零读。迁移窗到 2026-11-30,窗关之后的版本连这一腿一起删。
|
|
412
|
+
⑧ **加性与随版**:`tool_end.gate.disposition.echoed`(denied 臂可选,`[{ kind, value, canonical? }]`,只站在 `deniedBy` 为 `read_boundary` / `ask_resolution` 旁;缺席照旧画整句;读边界拒命中一行拒表时带上(被拒路径在前、那一行在后),`GET /v1/runs/:id/events` 回放同形 ——
|
|
413
|
+
把整只 `disposition` 逐字比成 `{ kind, deniedBy }` 的读者会多见这一键,改成按键读)·
|
|
414
|
+
扣信回执态多 `held_by_policy`(部署策略 / 收信方设置扣下:不问人、不跑到期)· 委派腿 gate 站的用户面通告投委派树根,来源腿在 `detail.sourceSessionId` / `agentId` ·
|
|
415
|
+
失败委派的工具结果 `isError` 为真 · 引擎铸的记忆通告从系统提示挪到腿的首个请求 · 压缩两座(第 15 条)· 会话级 `writeHome`(第 18 条)。
|
|
416
|
+
⑨ **`DB_BACKEND=local` 的文件历史**:引擎的 local 文件历史店带了整会话清理动词 ⇒ `DELETE /v1/sessions/:id` 连 v1 基线(原始文件字节)与只被这只会话引用的 blob 一起删
|
|
417
|
+
(此前 `reap`:边界删光、基线留到数据根被删为止,一条 `session_file_history_baselines_retained` warn —— 本版起 local 上不再出现);店故障 ⇒ 这一腿抛、会话行留着,重试收敛。
|
|
418
|
+
会话同步导入带 `resolution: "overwrite-dst"`、目的端已有不同的文件历史 ⇒ 擦掉目的端那一份、换成推来的那一份(此前 local 上 `422 conflict`);无同意照旧 `422`。
|
|
419
|
+
这订正 CHANGELOG 7.136.0 段「local identical 重推带不同文件历史」补披露条里「`overwrite-dst` 在 local 上也是 `422`、换不掉目的端的文件历史」两句(那一段原句不动)。
|
|
420
|
+
**谁需要**:所有部署(引擎随版换);删后同 id 重建会话的部署;导规则、走 local 一次性迁移的部署;按回显画拒绝的壳;`DB_BACKEND=local` 上删会话(删除权补齐)与带 `overwrite-dst` 重推的调用方。
|
|
421
|
+
**谁受伤**:① 升级时会话盒里还停着旧引擎写下、没投出去的信与子代话的部署;滚动升级期混版副本共一只信箱;复活的后台代理树(升到树根的终态帧被弃);
|
|
422
|
+
② 引擎 5.33.0 以来没开过的 File 记忆店;③ 共用一只记忆控制面、版本不同的副本;直读 `origin-clearances.json` 的脚本;按 `<毫秒>-hold-` 前缀列隔离目录的脚本;
|
|
423
|
+
④ 库里门 × 待决动作配错的停驻行(本版决不了);⑤ 卡上靠无 kind 批成员给出的规则提议;⑥ 停驻迟到腿上「记住规则」撞记 dot 的 CAS / dot 分配故障(本版不再重试);规则店持续写故障时的规则导入(票有效期内一直 503,过期 404);⑨ 在 local 上带 `overwrite-dst` 重推、以为换不掉目的端文件历史的调用方(同意即替换;替换是先擦目的端、再导入推来的那一份 —— 擦了之后再导入失败〔如推送途中坏了的 blob〕⇒ 目的端原来的文件历史已经没了、目标留空,重传那枚 blob 再推一次即落到空目标上)。
|
|
424
|
+
**补偿**:① 运维通告逐条可查(`delegation.delivery_discarded`,发信方另有 `refused` 回执);混版窗里旧副本领不动的盒不丢,旧副本滚动期写的记录本版副本照样弃 ⇒ 全部副本同版后再放新流量写信;② 先用 7.145.x(引擎 7.63.0)开一次那只店;③ 一起升;清标账改经 `GET /v1/memory/origin/clearances` 读;脚本改认新席名;
|
|
425
|
+
④ 在停驻它的版本上决完,或 expire 后重跑;⑤ 重新提议;⑥ 同命令再触发一次取新卡;导入按 `retryAfterSec` 同票重来,票过期后重新导入(成员级幂等)。
|
|
426
|
+
**升级前做**:① 让 7.145.x 副本把会话盒排空(会话都跑完一轮、没有未读的跨会话信),再整体换版;多副本部署全部副本同版之后再放新流量写信;
|
|
427
|
+
② File 记忆店(`MEMORY_ENGINE_BACKEND=file`,缺省)先用 7.145.x 开一次;③ 共用一只记忆控制面的副本同时升;
|
|
428
|
+
④ 数一数门 × 待决动作配错的待决停驻行(只读;六对 = `human`/`irreversible_ask` ↔ `tool_approval`、`resource_limit` ↔ `resource_limit`、`needs_review` ↔ `review`、`plan_review` ↔ `plan_review`、`task_done` ↔ `task_done`,其余皆错):
|
|
429
|
+
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;`
|
|
430
|
+
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。
|
|
431
|
+
**回滚**:回到 7.145.x ⇒ 本版写的会话盒记录旧副本认领失败(记录留着,回到本版可排);本版写过的清标账旧副本读不动;File 记忆店的账本两版都读得动(带信封的那一形);其余各项无持久面。
|
|
432
|
+
|
|
433
|
+
24. **不报主体的 service 凭据可声明为无身份调用方:新旋钮 `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT`(缺省 `true` = 授权判定不变;`false` ⇒ fleet 读面 / 运维聚合口 / 写档对它收窄)· `GET /health` 的 `auth` 加一键 · 运维口 401 operator 句改写(安全轴,opt-in;wire 加性 + 一句改写;零迁移;缺省部署零动作)**:
|
|
434
|
+
旧形:出示这台部署的 service token、不带主体头的请求恒代部署本人(fleet 调用方:舰队流 / 会话列表 / 发件链接 / 名册 / trace / 用量看全舰队,删除 / fork / 同步对任何会话照开,运维聚合口 `/metrics*` 与 `GET /v1/tasks/source-summary` 照放);部署没有座位改这一读法。
|
|
435
|
+
新形:env `SERVICE_TOKEN_ACTS_FOR_DEPLOYMENT`(词表布尔,缺省 `true`,词表外拒启;只有 env 一个座,起服读一次)。不设 / `true` ⇒ 与旧形逐字同的授权判定。`false` ⇒ 这一形的调用方是无身份调用方:
|
|
436
|
+
fleet 读面与删除 / fork / 同步 `401 auth.unauthorized`(identity 句)、运维聚合口 `401`(operator 句;`METRICS_TOKEN` / `TRACE_TOKEN` 照放)、舰队流多租户 `401 auth.principal_required` / 单用户落 `default` 那一族、无主的委派子代会话单用户形 `404`(多租形由会话读面的主体门先答 `401 auth.principal_required`,两形同);
|
|
437
|
+
带主体头的请求、建 run、run 面、只读凭据判据两形同读;起服一行 `service_token_posture { actsForDeployment: false }`。没配 service token 的部署上设 `false` 不改变任何东西。
|
|
438
|
+
缺省部署也看得见的两处:`GET /health` 的 `auth` 恒多一个布尔键 `serviceTokenActsForDeployment`(= 配了 service token ∧ 本位);运维口 401 operator 句的 service token 出路多了条件
|
|
439
|
+
「where this deployment lets its service token act for the deployment itself (GET /health reports it as auth.serviceTokenActsForDeployment; …)」(码、状态、体键不变)。
|
|
440
|
+
**谁需要**:单 service token + 多主体的网关部署(网关替每个用户写主体头),关掉「漏带头 = 看全部」。
|
|
441
|
+
**谁受伤**:开 `false` 的部署的裸 service token 运维脚本 / 面板(当天成片 `401`;会话列表 / 发件链接 / 名册与他人会话的写档没有全量替换凭据);按整只 `/health.auth` 对象逐键比的探针与金样(要补键);按 operator 句字面匹配的告警。
|
|
442
|
+
**补偿**:不设即旧判定;按端点换凭据(trace / 用量 / `source-summary` / 舰队流 → 只读 `TRACE_TOKEN`;`/metrics*` → 只读 `METRICS_TOKEN`;门后列表与写档 → 带具名主体头,只见那位主体的);设回 `true` 重启即复原;`/health.auth.serviceTokenActsForDeployment` 自报。
|
|
443
|
+
**升级前做**:缺省部署零动作(按整只 `auth` 对象比的探针补键、按句子匹配 operator 401 的告警改按 `errorCode` 判)。要开 `false` 的部署:先把全部副本升到本版再设(旧引擎不认这一键,照旧按「不带主体头 = 部署本人」答);
|
|
444
|
+
全部副本设同一个值(滚动重启完成之前有副本还按旧读法答,收窄不完整);开之前把运维脚本按上面的端点换凭据;开之后核起服行与 `/health.auth.serviceTokenActsForDeployment: false`。
|
|
445
|
+
它不解决「网关不可信」:持 service token 的一方在主体头里写谁就是谁 —— 鉴权桥不改这一点(桥只给带登录令牌的请求验身份,带 service token 的请求照旧信主体头);要防这一层,别把 service token 交给不可信的一方(不可信的调用方走鉴权桥的登录令牌),或开直连门(主体只认签名的 principal 令牌,自报的主体头不再是身份)。**回滚**:删掉这一行或设回 `true` 后重启;零持久面、零 DDL、零一次性迁移。
|
|
446
|
+
|
|
447
|
+
25. **🔴 自由文本脱敏:行首键形(YAML / INI / compose 的配置行 `password: <值>` / `PASSWORD = <值>`)是声明形的第四种 —— 值成记号;值是类型名(`str` / `string` / `SecretStr` …)时不是值(行为面;安全;脱敏产物变;部署零动作)**:
|
|
448
|
+
— **声明形的定义**(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`)
|
|
449
|
+
在自由文本里是名字锚,当赋值写成 ① 名字带引号(`"password": …`)② 值带引号(`password: "…"`)③ 赋值符两侧零空白(`password=…` / `--password=…`)④ **行首键形**:
|
|
450
|
+
名字在行首(左边隔着行内空白,可夹 YAML 的 `- ` 列表项记号;JSON 串值的开头与 `\n` 转义同是行首)、名字不带引号、赋值符(`:` / `=`)**右边至少一个空白**(左边有没有空白不论),
|
|
451
|
+
且不带引号的值是**那一行余下的全部** —— 之后只许行尾,或一段 ` #` 行尾注释(`password: changeme # default` 遮 `changeme`)。值以字母数字起头时遮(`$VAR` / `${VAR}` / `<占位>` / 表达式 / `None` / `true` 不算值)。
|
|
452
|
+
④ 上值整段是类型名(`str` / `string` / `bytes` / `int` / `integer` / `float` / `number` / `bool` / `boolean` / `any` / `object` / `array` / `SecretStr`,ASCII 大小写不敏感)时不是值 ——
|
|
453
|
+
行首的类型注解(` password: str` / `password: string` / `api_key: SecretStr`)逐字留;①②③ 上类型名照旧是字面量(`password=string` 遮)。
|
|
454
|
+
— **不变**:行中的散文形赋值(`set the password: x` / `… password = x`)、值之后行上还有东西的行(`password: str = ""` / `Password: must be at least 8 characters` / ` password: pw,`)不是声明形;
|
|
455
|
+
`token` 只在赋值那一半的零空白形上是锚(行首的 `token: …` 照旧是常用词);`passwd` / `pwd` 任何形都是锚;JSON 字段与 URL 参数位的读法不变。
|
|
456
|
+
— **仍不遮**:复合名(compose 的 `POSTGRES_PASSWORD: <值>`;名字按整名认)、点分键(`spring.datasource.password = <值>`;零空白的 `spring.datasource.password=<值>` 照旧遮)、
|
|
457
|
+
值尾还剩剥掉的句读(`password: hunter2.`)、值在下一行(`password:` + 换行 + 缩进值)。要靠脱敏挡住的凭据别以这几形写出。
|
|
458
|
+
— **流式与有界行**:活流逐块帧与出口座的有界行读的是 head 读法 —— 值之后的行尾在这一段之外时,从值起点遮到段尾(判定未决),等行尾到了再交出;逐块拼接仍 = 段末帧。
|
|
459
|
+
**谁需要**:agent 读 compose / `application.yml` / `.ini` 进工具输出、转录与同步体的部署 —— 配置行里的口令 / 密钥值此前在这些出口上原样。
|
|
460
|
+
**谁受伤**:① 文书 / 回复里行首的配置示例值换成记号:占位词(`password: xxx`)、独占一行的标签行(`Password: required`);② 代码答复里对象字面末项不带逗号时的变量名(` password: pw`)、
|
|
461
|
+
行首的代码赋值(`password = user_input`)、类型名表之外的类型写法(GraphQL `password: String!`)换成记号;③ 带这一形的多行命令不再给常驻放行(每次问人);④ 脱敏计数上升
|
|
462
|
+
(`redactions_applied_total{pattern="redacted",arm="full"}`,与 `password=` 一族同一格)。
|
|
463
|
+
**补偿**:名字或值带引号照旧是声明形;要原样显示示例的文书写 `password: <your-password>` 或 `password: "${VAR}"`;类型名不遮;无开关(凭据轴只收紧)。
|
|
464
|
+
**升级前做**:无。**回滚**:回到 7.145.x ⇒ 行首键形回到明文(只有 ①②③ 三种声明形);无持久数据。
|
|
465
|
+
|
|
466
|
+
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;部署零动作)**:
|
|
467
|
+
旧形:壳退出只能停引擎(后台 shell 一起被收掉)或丢下引擎;丢下的引擎按 `ENGINE_LINGER_MS` 自退,后台 shell 不算工作;SIGHUP 空闲窗(`SIGHUP_IDLE_GRACE_MS`)另按自己的判据走硬停,不写留痕。
|
|
468
|
+
新形:附着租约四条车道,一只派生函数(从上到下第一条成立者)—— `handover`(调过交接口、之后还没有壳 attach)> `orphan`(父已不在)> `awaitingFirstAttach`(还没有过非探针请求)> `owned`。
|
|
469
|
+
`handover` 的窗 = `ENGINE_HANDOVER_LINGER_MS`,且引擎此刻一退就会被退出边界硬收的后台 shell(在跑、整张进程级注册表、不含 retain 行)在这条车道里算工作;别的车道窗与判据逐字照旧。SIGHUP 空闲窗读同一只工作谓词,`handover` 车道里它不计时(寿命只归租约腿)。
|
|
470
|
+
这只数不是 `/health.inflightBreakdown.sessionResident`(那是总数里经过提交的会话的会话驻留行;交接数还含 run 腿上的行与没经过提交的会话的行,读得出时 ≥ 驻留项);读不出 ⇒ 按 1 计、一行 `warn` `engine_handover_shell_count_unreadable`。
|
|
471
|
+
`POST /v1/engine/handover` 体恰为 `{ "reason": "background_exit" }` ⇒ 200 `{ lane: "handover", since, lingerMs, backgroundShells }`(幂等);`POST /v1/engine/attach` 体 `{}` 或空 ⇒ 200 `{ lane, handedOverForMs? }`(清交接位)。
|
|
472
|
+
不可用 ⇒ 501 `capability.engine_handover_unavailable`(租约腿没装 / `REQUIRE_PRINCIPAL=true` / 停机中);体不合形 ⇒ 400 `request.field_invalid`。`GET /v1/capabilities` 的 `engine.handover` 与两口读同一只事实。
|
|
473
|
+
`GET /health` 的 `engineLease` 多 `lane`(四词闭集,`engineLease` 在场即在场)与 `handover { since, reason, lingerMs, backgroundShells }`(只在 `handover` 车道在场);`engineLease.lingerMs` 的最短窗把交接窗算进去(缺省 30 min,默认读数不变)。
|
|
474
|
+
日志:新 `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 }`。
|
|
475
|
+
`exit-last.json` 格式 3 取代上一版的格式 1(没有 `format` 键的形):必填 `lane`,不写 `orphan`(上一版的键)—— `orphan:true` ⟺ `lane:"orphan"`,候首触窗到期(第 1 条)⟺ `lane:"awaitingFirstAttach"`(没有单独的布尔键;格式 2 从没随任何已发版本发出);格式号不符的文件 ⇒ 第 1 条的 `warn` `exit_last_stale_format` 后删掉(只丢那一次自退的留痕)。
|
|
476
|
+
**谁需要**:cli 壳的退出三选一 —— 交接后壳自己退出,后台 shell 跑完再按交接窗收;下一只壳 attach 即回到原车道。
|
|
477
|
+
**谁受伤**:交接之后引擎多活到后台 shell 跑完再加交接窗,期间占着端口、数据根锁与库连接(不复用它、自己再起一只引擎的壳撞数据根锁;一只永不退出的后台 shell 让它一直活着);按旧键名读 `exit-last.json` / `engine_lease_auto_exit` / `sighup_idle_watch_armed` 的脚本;交接之后终端关掉(SIGHUP)不再关引擎。
|
|
478
|
+
**补偿**:`ENGINE_HANDOVER_LINGER_MS` 调短(下界 60 s,上界 24 h,坏值拒启、解析无条件);壳选「Exit and stop tasks」照旧停引擎;运维随时 SIGTERM;交接态在 `/health.engineLease.handover` 与 `engine_lane_changed` 里可读;旧键名一一对应到 `lane` / `work`。
|
|
479
|
+
**升级前做**:按旧键名读 `exit-last.json` / 上述两条日志的脚本改读新键。**回滚**:回到上一版即恢复旧形;本版写的 `exit-last.json`(格式 3,没有 `orphan`)上一版读不成 —— 不报 `exit_last_found`,文件留在盘上直到下一次自退覆盖它(只少那一次留痕,不挡启动)。
|
|
480
|
+
|
|
481
|
+
27. **一次性迁移 M6–M8 退役:启动期迁移连同各自的读侧半场与记号写点删码;M7 的拒臂留为按写者版本的永久门(持久数据面;行为变更;运维日志形变更;随包排空判据少一条;嵌入方 BREAKING,类型面)**:
|
|
482
|
+
7.116.0 / 7.117.0 引入的三条一次性迁移,窗(发布日 + 30 天)于 2026-11-04 / 11-05 关,本版删了它们的码。M9–M12 的窗 2026-11-06 … 11-08 关,本版不动,随后续版本窗关即删。逐条删了什么、删后存量形由谁接住:
|
|
483
|
+
- **M6**(7.116.0,run 死亡判决机读码回填):起服给只有句子、码列为空的 `failed` 行补 `run.stalled` / `run.orphaned`,连同 SQL 读面把这种行读成码的半场与 local 腿的写回。
|
|
484
|
+
删后这种行(只有 ≤ 7.115.x 的写者铸得出)`GET /v1/runs/:id` 的 `errorCode` 缺席、只剩 `error` 句子,不再被判成持有者死亡(那条 run 上丢掉的 steer 不再告知)。没有响亮臂。
|
|
485
|
+
- **M7**(7.117.0,停驻行 allow 读法记号的拒臂):删的是记号 `permissionsAllowReading` 的写点、「按记号判」的读法与随包排空判据 `permissions-allow-list`(两份 SQL 的那一段与 `drain-check-local.mjs` 的那一条)。
|
|
486
|
+
拒臂本身留为**按写者版本的永久门**:续跑重放之前,体里带非空 `settings.permissions.allow` 而续跑上下文的写者版本证不出 ≥ 7.117.0(缺席 / 读不出 / 更早 —— 7.123.x 及更早的写者都不记写者版本)⇒
|
|
487
|
+
409 `checkpoint.unsupported_version`(一句拒句;有写者版本时带 `writerVersion` / `readerVersion`),行字节不动、卡仍 pending;出路 = 作为新任务重提,仍停驻的先取消(`POST /v1/runs/:id/cancel`)。
|
|
488
|
+
这一门不随窗走:日历窗关不证明旧行不在(留存拉长、备份恢复、调长了 `APPROVAL_TERMINAL_BACKSTOP_MS`)。它只认写者版本一个证据 ⇒ 7.117.0–7.123.x 写下、带非空 allow 的行(有当年的记号、没有写者版本;7.145.x 按记号照续)本版同样拒。
|
|
489
|
+
- **M8**(7.117.0,停驻行披露位换名):SQL 起服把 `risk_descriptor` 里的旧键 `shadowedRule` 改写成 `allowRuleShadowed`。删后没经过它的停驻行留旧键:运维待批队列上只缺结构化披露,旧键的文本照样脱敏显示。没有响亮臂。
|
|
490
|
+
- **运维日志**:起服行 `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`(有才在)。按这些字段做告警或看板的规则要改。
|
|
491
|
+
- **随包排空判据**:两份 SQL 与 `drain-check-local.mjs` 去掉 `permissions-allow-list`(local 脚本的判据表少一条)。要在 7.115.0 / 7.117.0 / 7.118.0 那几条版本边界上数,用 7.118.0–7.145.x 任一版包里的同名判据。
|
|
492
|
+
- **嵌入方(类型面)BREAKING**:`StoreBackend.runOneTimeMigrations()` 的返回型 `OneTimeMigrationReport`(经包根导出的 `StoreBackend` 可达)去掉三个读数键(`holderDeathCodeRowsBackfilled` / `allowRuleShadowRowsMigrated` / `allowRuleShadowRowsUnreadable`);读它们的代码、把值标成 `OneTimeMigrationReport` 再写这些键的对象字面量 tsc 红;
|
|
493
|
+
自实现该方法、未标注类型就直接返回含这些键的字面量的代码 tsc 不报(多出的键没有人读),也请一并删掉。
|
|
494
|
+
- **谁需要**:所有部署 —— 删码让起服少走几步、排空判据少一条;续跑判据的 allow 读法问改按写者版本判、不再读记号(本版删 M6 / M7 / M8)。
|
|
495
|
+
- **谁受伤**:① **跳版升级**:从 ≤ 7.116.x 直接跳到本版、中间没在 7.117.0–7.145.x 任一版起过服的 SQL 库 —— 写库的两条(M6 / M8)没跑过,存量形照上面各条落地;
|
|
496
|
+
② **滚动升级窗**:7.117.0–7.145.x 的副本只写当前形(码列、新键),窗里不长新的旧形行;混跑更早的副本时它们写下的旧形行同样照上面各条落地;
|
|
497
|
+
③ **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 **直跳**本版的部署不在此列 —— 那批卡停驻得多新就活多久,与日期无关;
|
|
498
|
+
④ **反向(回滚 / 混跑里的 7.145.x 副本)**:本版写下的续跑上下文不再带记号 ⇒ 7.145.x 及以前的副本读到**任何**体里带非空 allow 的本版停驻行(壳从 CC settings 透传的 `settings.permissions.allow` 常带它;leader 子代行体里没有 `settings`,不在其内)时,
|
|
499
|
+
照它自己的问答 409 `checkpoint.unsupported_version`(带 `writerVersion` 7.146.0 / `readerVersion`;响亮,卡仍 pending)—— 回滚面比「plan_review 写回的行」大得多,回滚预案按「带 allow 的本版停驻卡全数」估。
|
|
500
|
+
- **补偿 / 做法**:跳版升级的库,**先在 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 升级、没有 ③ 那批卡的无须动作。
|
|
501
|
+
|
|
10
502
|
## 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
503
|
|
|
12
504
|
1. **🔴 `DB_BACKEND=local`:仍带属主戳的存档上,会话同步导入的第一阶段(`POST /v1/sessions/:id/sync/import`)按 id 分类出 fork / stale 且没带同意时,直接答 409 `conflict.session_archive_stamped` + 带出路句,不再先答通用的 `conflict`(wire 加性:这一口多答一个已在册的码;行为修复;部署零动作)**:
|