@sema-agent/server 7.142.0 → 7.144.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 +608 -0
- package/USAGE.md +63 -36
- package/dist/adoption/plan.js +22 -0
- package/dist/approval-ask-audit-store.d.ts +7 -5
- package/dist/approval-ask-audit-store.js +12 -6
- package/dist/approval-ask-machine.d.ts +15 -7
- package/dist/approval-ask-machine.js +10 -4
- package/dist/approval-card.d.ts +155 -39
- package/dist/approval-card.js +111 -31
- package/dist/approval-queue-kind.d.ts +27 -0
- package/dist/approval-queue-kind.js +6 -0
- package/dist/approval-reconciler.d.ts +8 -8
- package/dist/approval-reconciler.js +3 -3
- package/dist/audit.js +4 -2
- package/dist/boot/budget-tracing.d.ts +1 -1
- package/dist/boot/execution-env.js +1 -1
- package/dist/boot/governance-seams.d.ts +26 -41
- package/dist/boot/governance-seams.js +61 -28
- package/dist/boot/late-binds.d.ts +7 -4
- package/dist/boot/late-binds.js +3 -1
- package/dist/boot/leader.js +2 -4
- package/dist/boot/memory-consolidation.d.ts +0 -8
- package/dist/boot/memory-consolidation.js +3 -3
- package/dist/boot/reapers.js +5 -4
- package/dist/boot/resolve-spec.d.ts +1 -1
- package/dist/boot/resolve-spec.js +8 -8
- package/dist/boot/runner-deps.d.ts +14 -6
- package/dist/boot/runner-deps.js +6 -17
- package/dist/boot/shutdown.d.ts +9 -0
- package/dist/boot/shutdown.js +18 -2
- package/dist/boot/stage-01-config.js +2 -0
- package/dist/boot/stage-02-web-admin-pull.js +3 -0
- package/dist/boot/stage-03-store-backend.d.ts +4 -1
- package/dist/boot/stage-03-store-backend.js +1 -2
- package/dist/boot/stage-04-stores.d.ts +5 -2
- package/dist/boot/stage-04-stores.js +3 -5
- package/dist/boot/stage-05-execution-env.d.ts +5 -2
- package/dist/boot/stage-06-runners.d.ts +5 -2
- package/dist/boot/stage-06-runners.js +1 -3
- package/dist/boot/stage-07-capability-layer.d.ts +5 -2
- package/dist/boot/stage-07-capability-layer.js +6 -2
- package/dist/boot/stage-08-reapers.d.ts +5 -2
- package/dist/boot/stage-09-leader.d.ts +5 -2
- package/dist/boot/stage-10-http-server.d.ts +5 -2
- package/dist/boot/stage-10-http-server.js +4 -1
- package/dist/boot/stores.d.ts +5 -2
- package/dist/boot/stores.js +7 -7
- package/dist/boot/web-admin.d.ts +5 -1
- package/dist/boot/web-admin.js +31 -19
- package/dist/capabilities/hands-lane.d.ts +9 -39
- package/dist/capabilities/hands-lane.js +8 -13
- package/dist/capabilities/mcp-probe.d.ts +3 -2
- package/dist/capabilities/scenarios.d.ts +23 -17
- package/dist/capabilities/scenarios.js +2 -2
- package/dist/capabilities/skills.d.ts +1 -17
- package/dist/capabilities/skills.js +0 -8
- package/dist/capability-facts.d.ts +8 -8
- package/dist/capability-facts.js +4 -4
- package/dist/card-void.d.ts +6 -9
- package/dist/config-catalog.js +1 -1
- package/dist/config-d-migration.d.ts +2 -0
- package/dist/config-dir-trust.js +58 -29
- package/dist/config-invariants.d.ts +7 -1
- package/dist/config-invariants.js +7 -0
- package/dist/config-provider.d.ts +10 -0
- package/dist/config-provider.js +15 -4
- package/dist/config-root-migration.d.ts +13 -0
- package/dist/config-root-migration.js +99 -0
- package/dist/config-types.d.ts +5 -5
- package/dist/config.d.ts +4 -3
- package/dist/config.js +1 -1
- package/dist/delegated-session-owner.d.ts +35 -151
- package/dist/delegated-session-owner.js +1 -83
- package/dist/device-ws-protocol.d.ts +1 -0
- package/dist/device-ws-protocol.js +2 -1
- package/dist/entry-mode-clamp-notice.d.ts +1 -1
- package/dist/env-model-table-gate.d.ts +53 -0
- package/dist/env-model-table-gate.js +53 -0
- package/dist/execution-placement.d.ts +7 -4
- package/dist/fleet/fleet-bus.d.ts +28 -52
- package/dist/fleet/fleet-bus.js +35 -100
- package/dist/fleet/fleet-reconciler.d.ts +4 -4
- package/dist/fleet/fleet-reconciler.js +1 -1
- package/dist/fleet/subagent-tail-bus.d.ts +14 -11
- package/dist/fleet/subagent-tail-bus.js +15 -28
- package/dist/hooks/classic-stations.d.ts +3 -1
- package/dist/hooks/classic-stations.js +2 -0
- package/dist/hooks/hook-runner.js +28 -7
- package/dist/host-decision.d.ts +54 -20
- package/dist/host-decision.js +42 -14
- package/dist/http/admission.d.ts +1 -1
- package/dist/http/admission.js +7 -3
- package/dist/http/approval-sweeps.js +11 -8
- package/dist/http/caller-trust.d.ts +1 -1
- package/dist/http/durable-run-leg.js +2 -2
- package/dist/http/engine-refusal.d.ts +16 -0
- package/dist/http/engine-refusal.js +17 -0
- package/dist/http/memory-compliance-failure-reply.d.ts +1 -3
- package/dist/http/memory-compliance-failure-reply.js +4 -6
- package/dist/http/owner-access.d.ts +11 -0
- package/dist/http/owner-access.js +13 -0
- package/dist/http/principal-gate.d.ts +1 -1
- package/dist/http/refusal-body.d.ts +7 -3
- package/dist/http/refusal-body.js +1 -0
- package/dist/http/resume-legs.d.ts +21 -7
- package/dist/http/resume-legs.js +82 -53
- package/dist/http/resume-restatement.d.ts +39 -0
- package/dist/http/resume-restatement.js +25 -0
- package/dist/http/route-ctx.d.ts +35 -10
- package/dist/http/route-ctx.js +1 -1
- package/dist/http/routes/approvals-assistant.d.ts +9 -1
- package/dist/http/routes/approvals-assistant.js +143 -31
- package/dist/http/routes/capabilities.js +11 -2
- package/dist/http/routes/memory-policy.d.ts +2 -2
- package/dist/http/routes/memory-policy.js +1 -1
- package/dist/http/routes/notify-wake.js +23 -25
- package/dist/http/routes/rules.js +48 -13
- package/dist/http/routes/runs.js +9 -8
- package/dist/http/routes/session-memory-sync.d.ts +34 -6
- package/dist/http/routes/session-memory-sync.js +27 -10
- package/dist/http/routes/session-sync.js +13 -20
- package/dist/http/routes/sessions.d.ts +2 -2
- package/dist/http/routes/sessions.js +22 -23
- package/dist/http/routes/tasks.js +27 -49
- package/dist/http/server.d.ts +13 -7
- package/dist/http/server.js +2 -2
- package/dist/http/stored-body-replay.js +15 -4
- package/dist/http/wire-types.d.ts +17 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lane-home-probe.d.ts +15 -0
- package/dist/lane-home-probe.js +4 -0
- package/dist/leader/leader.js +5 -2
- package/dist/leader/wire.d.ts +7 -1
- package/dist/leader/wire.js +6 -5
- package/dist/leg-facts.d.ts +37 -0
- package/dist/leg-facts.js +15 -0
- package/dist/memory-bundle-engine.d.ts +1 -4
- package/dist/memory-bundle-engine.js +2 -2
- package/dist/memory-operator-faces.d.ts +30 -66
- package/dist/memory-operator-faces.js +17 -88
- package/dist/memory-scope-stores.d.ts +38 -40
- package/dist/memory-scope-stores.js +51 -36
- package/dist/memory-scope.d.ts +0 -9
- package/dist/memory-scope.js +0 -9
- package/dist/memory-sync-client.js +14 -3
- package/dist/memory-sync.d.ts +20 -4
- package/dist/memory-sync.js +23 -4
- package/dist/model-plane-face.d.ts +13 -7
- package/dist/model-plane-face.js +2 -1
- package/dist/observability/corrupt-read-seat.d.ts +5 -9
- package/dist/observability/corrupt-read-seat.js +1 -2
- package/dist/observability/fail-open.d.ts +30 -10
- package/dist/observability/fail-open.js +27 -10
- package/dist/observability/run-terminal.d.ts +1 -1
- package/dist/observability/run-terminal.js +6 -2
- package/dist/orchestration/workflow-completion-inbox.d.ts +5 -19
- package/dist/orchestration/workflow-completion-inbox.js +0 -12
- package/dist/orchestration/workflow-notify-journal.d.ts +3 -2
- package/dist/orchestration/workflow-park-decision.d.ts +8 -3
- package/dist/orchestration/workflow-park-decision.js +5 -3
- package/dist/org-delivery-gate.d.ts +11 -0
- package/dist/org-delivery-gate.js +19 -1
- package/dist/parked-decide.d.ts +13 -9
- package/dist/parked-decide.js +7 -7
- package/dist/parked-revive-surface.d.ts +6 -7
- package/dist/parked-revive-surface.js +1 -1
- package/dist/peer-inbound-face.d.ts +122 -0
- package/dist/peer-inbound-face.js +123 -0
- package/dist/permission-rule-list.d.ts +13 -9
- package/dist/permission-rule-list.js +7 -3
- package/dist/plugins/approval-ask-store-file.js +18 -6
- package/dist/plugins/approval-ask-store-memory.js +8 -6
- package/dist/plugins/approval-ask-store-sql.d.ts +28 -13
- package/dist/plugins/approval-ask-store-sql.js +30 -11
- package/dist/plugins/caching-session-store.d.ts +0 -3
- package/dist/plugins/caching-session-store.js +0 -3
- package/dist/plugins/checkpoint-store-sql.d.ts +45 -38
- package/dist/plugins/checkpoint-store-sql.js +108 -45
- package/dist/plugins/file-history-store-sql.d.ts +24 -18
- package/dist/plugins/file-history-store-sql.js +24 -19
- package/dist/plugins/file-run-store.d.ts +29 -0
- package/dist/plugins/file-run-store.js +97 -8
- package/dist/plugins/fork-routing-session-store.d.ts +8 -1
- package/dist/plugins/fork-routing-session-store.js +6 -0
- package/dist/plugins/imported-layer-root-retirement.d.ts +82 -0
- package/dist/plugins/imported-layer-root-retirement.js +96 -0
- package/dist/plugins/local-checkpoint-store.d.ts +6 -8
- package/dist/plugins/local-checkpoint-store.js +5 -4
- package/dist/plugins/local-session-store.d.ts +69 -30
- package/dist/plugins/local-session-store.js +133 -57
- package/dist/plugins/local-session-window.d.ts +4 -2
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +9 -31
- package/dist/plugins/mailbox-recipient-lifecycle.js +4 -0
- package/dist/plugins/mailbox-store-sql.d.ts +12 -8
- package/dist/plugins/mailbox-store-sql.js +76 -7
- package/dist/plugins/memory-sync-store-pg.d.ts +15 -0
- package/dist/plugins/memory-sync-store-pg.js +21 -0
- package/dist/plugins/memory-sync-store-tidb.d.ts +2 -0
- package/dist/plugins/memory-sync-store-tidb.js +13 -1
- package/dist/plugins/one-time-migrations.d.ts +44 -14
- package/dist/plugins/one-time-migrations.js +118 -15
- package/dist/plugins/org-delivery-quota-store.d.ts +1 -1
- package/dist/plugins/org-delivery-quota-store.js +2 -12
- package/dist/plugins/park-commit-watch.d.ts +1 -1
- package/dist/plugins/permission-rule-store-file.d.ts +10 -1
- package/dist/plugins/permission-rule-store-file.js +15 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +31 -1
- package/dist/plugins/permission-rule-store-sql.js +35 -2
- package/dist/plugins/pg-session-storage.d.ts +1 -9
- package/dist/plugins/pg-session-storage.js +2 -19
- package/dist/plugins/remote-env-device.d.ts +8 -11
- package/dist/plugins/remote-env-device.js +6 -3
- package/dist/plugins/remote-env-host.d.ts +8 -4
- package/dist/plugins/remote-env-host.js +7 -9
- package/dist/plugins/remote-env-k8s.d.ts +37 -24
- package/dist/plugins/remote-env-k8s.js +50 -17
- package/dist/plugins/remote-shell.js +12 -2
- package/dist/plugins/retention-store-sql.d.ts +2 -2
- package/dist/plugins/sandbox-read-floor.d.ts +5 -7
- package/dist/plugins/sandbox-read-floor.js +2 -7
- package/dist/plugins/schema-consistency.d.ts +5 -1
- package/dist/plugins/session-fork.d.ts +1 -1
- package/dist/plugins/session-ownership.d.ts +9 -0
- package/dist/plugins/session-ownership.js +6 -0
- package/dist/plugins/session-store.d.ts +13 -16
- package/dist/plugins/session-store.js +9 -10
- package/dist/plugins/sql-errors.d.ts +10 -1
- package/dist/plugins/sql-errors.js +13 -0
- package/dist/plugins/sql-json-column.d.ts +24 -2
- package/dist/plugins/sql-json-column.js +38 -3
- package/dist/plugins/store-backend.d.ts +23 -28
- package/dist/plugins/store-backend.js +12 -3
- package/dist/plugins/store-contracts.d.ts +29 -5
- package/dist/plugins/store-contracts.js +4 -1
- package/dist/plugins/task-attachment-store.d.ts +2 -2
- package/dist/plugins/task-attachment-store.js +37 -52
- package/dist/plugins/tidb-session-store.d.ts +2 -14
- package/dist/plugins/tidb-session-store.js +2 -20
- package/dist/plugins/tool-result-store-sql.d.ts +9 -8
- package/dist/plugins/tool-result-store-sql.js +23 -2
- package/dist/plugins/wiring-section-codec.d.ts +32 -0
- package/dist/plugins/wiring-section-codec.js +55 -0
- package/dist/plugins/workspace-fill.d.ts +1 -1
- package/dist/rule-entry-list.d.ts +3 -2
- package/dist/rule-entry-list.js +5 -1
- package/dist/rules-consent.d.ts +28 -5
- package/dist/rules-consent.js +40 -28
- package/dist/run-local.js +11 -6
- package/dist/runs.d.ts +12 -8
- package/dist/runs.js +10 -7
- package/dist/runtime-governance.d.ts +1 -1
- package/dist/security.d.ts +0 -4
- package/dist/server-secret-env.d.ts +4 -0
- package/dist/session-error-wire.d.ts +34 -23
- package/dist/session-error-wire.js +8 -3
- package/dist/session-incarnation.d.ts +3 -3
- package/dist/session-notify-door.d.ts +106 -0
- package/dist/session-notify-door.js +97 -0
- package/dist/session-sync.d.ts +9 -14
- package/dist/session-sync.js +5 -5
- package/dist/session-workspace.d.ts +3 -13
- package/dist/session-workspace.js +0 -9
- package/dist/standing-answer-grant.d.ts +5 -0
- package/dist/standing-answer-grant.js +10 -0
- package/dist/stores-sql/session-policy-store-sql.d.ts +4 -2
- package/dist/stores-sql/session-policy-store-sql.js +3 -13
- package/dist/task-mcp.d.ts +1 -1
- package/dist/task-settings.d.ts +11 -8
- package/dist/task-settings.js +31 -11
- package/dist/tool-approval.d.ts +55 -35
- package/dist/tool-approval.js +112 -74
- package/dist/trace/core-keyset-guard.d.ts +12 -9
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +4 -2
- package/dist/trace/exit-seat.d.ts +7 -1
- package/dist/trace/exit-seat.js +1 -0
- package/dist/trace/ledger-sink.d.ts +2 -2
- package/dist/trace/ledger-sink.js +12 -4
- package/dist/trace/model-segment.d.ts +74 -25
- package/dist/trace/model-segment.js +141 -32
- package/dist/trace/project.d.ts +15 -6
- package/dist/trace/project.js +12 -4
- package/dist/trace/redact.d.ts +72 -9
- package/dist/trace/redact.js +1509 -471
- package/dist/trace/self-minted-wire.d.ts +598 -47
- package/dist/trace/self-minted-wire.js +190 -20
- package/dist/trace/wire-projection-faces.d.ts +1 -1
- package/dist/trace/wire-projection-faces.js +1 -1
- package/dist/verifier-pause-card.d.ts +33 -5
- package/dist/verifier-pause-card.js +15 -10
- package/dist/web-admin-client/apply-effective.d.ts +12 -16
- package/dist/web-admin-client/apply-effective.js +90 -10
- package/dist/workspace-space.d.ts +19 -3
- package/dist/workspace-space.js +8 -4
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -1
- package/package.json +3 -2
- package/wire-changes/server@7.143.0.json +1167 -0
- package/wire-changes/server@7.144.0.json +291 -0
- package/dist/session-records-skipped-notice.d.ts +0 -21
- package/dist/session-records-skipped-notice.js +0 -27
package/MIGRATION.md
CHANGED
|
@@ -7,6 +7,614 @@
|
|
|
7
7
|
> ⚠️ 完整清单在仓库根 `CHANGELOG.md`——它**不随 npm tarball 出包**(本文件随包)。看完整迁移窗的
|
|
8
8
|
> 权威姿势是源码 tag diff:`git diff v<旧>..v<新>`(每版都推 `v<版本>` tag);npm 包页也镜像 CHANGELOG。
|
|
9
9
|
|
|
10
|
+
## 7.144.0 —— 🔴 会话日志回放丢了记录:用户面通告只剩引擎的 `session.lineage_rerooted`(`session.records_skipped` 退役)、丢了分支上祖先的会话从断点续上、走不成一棵树的已存日志答 `corrupt_session`(打开面 `invalid_session` 退役)(wire BREAKING:一个通告码与一个错误码退出;行为修复;部署零动作) · 跨会话来信有序关停:info 行字段改为 `{ queues, cards }`、回执没落进发信方的箱每条一行 warn(运维面;日志形变更) · 引擎在没有自己席的地方说的话落结构化 `engine_notice` 日志行,不再是裸 `console.warn` 句(运维面;日志形变更) · 🔴 `DB_BACKEND=local`:数据根里的会话元数据边档本构建读不出(更新的引擎写下 / 损坏 / 读不了)⇒ `ensureSchema()` 拒启 `config.schema_mismatch`,开始服务之前判(行为修复;fail-closed;持久面;零 DDL) · SQL 后端:更新引擎停驻的行续跑 / 决断答 409 `checkpoint.unsupported_version`(不再答 `conflict.checkpoint_unreadable`)、运维队列行与助手收件箱行带 `rowVerdict`(wire 拒码改答 + 加性;部署零动作) · 持久问店车道上同一只审批问被另一腿再问时,「这一问要人」取行上那张卡与这一腿请求的并集(安全;行为收紧;wire 零形变;部署零动作) · 🔴 引擎 7.62.0:部署的 mod 包按内核契约 8 重建(部署面;BREAKING) · 远端五车道的私有暂存目录多一道 ACL 核:继承来的 ACL 条目去不掉 / 读不出 / 目标机系统不在闭集里 ⇒ 不暂存,退回就地写目标(行为收紧,fail-closed;安全;部署零动作) · 🔴 活流文字段的脱敏单位收成段(与账本 `text` 行同一个):引擎的 `text_end` 是文字块的交付点、不收段,锚与值分在同一段两块时 `text_delta` / `text_end` 照样遮;更正 7.143.0 节第 11 条「文字段的单位是引擎的文字块」一句(wire 值语义;安全;部署零动作) · 🔴 `DB_BACKEND=local`:仍带属主戳的存档的拒有了自己的码 `conflict.session_archive_stamped`,fork 与改日志的各形推送(含载荷分叉的 fast_forward)同码同句(wire BREAKING:这两扇写口上带戳存档的拒由 `conflict` 改新码;行为修复;部署零动作) · 更正 7.143.0 节五处说法:退役工具名写进 deny / ask 规则时按名单的来源各答各码(请求体 422 `request.unprocessable` · 部署名单拒启 · `config.legacy_tool_name` 只来自存量会话规则)、`decidedVia` 在直连门部署上哪几口不收、续跑门 `/resume` 的真路由、user 层要根的 allow 免不了配置根下写保护表上的写、被拒的个人层抹除与点名个人层的只读也会在盘上留下一只从没写过的个人店(文书;零行为变化) · host 车道:执行环境的家目录主张证不了 ⇒ 环境在开跑前就不铸,run 失败终局码 `env.home_unconfirmed`(同步提交腿 409),命令带不带路径同一首拒;worktree 的 git 基环境不再带家目录主张;更正 7.140.0 节第 12 条 ③(wire 新码;行为修复;部署零动作)
|
|
11
|
+
|
|
12
|
+
1. **🔴 `DB_BACKEND=local`:会话日志回放丢了读不出的记录 —— 用户面只剩一只帧 `session.lineage_rerooted`(引擎铸),本服务自铸的 `session.records_skipped` 退役;丢了分支上祖先的会话从断点续上;走不成一棵树的已存日志答 `corrupt_session`,打开面不再出现 `invalid_session`(wire BREAKING;行为修复;部署零动作)**:
|
|
13
|
+
旧形(7.143.0,core 7.61.0):打开一只回放跳过了记录的会话时,只有本服务自铸的一帧 `session.records_skipped`(`{ dropped, entriesKept, sessionId }`,每次打开一帧、会话缓存命中的轮次不说);引擎不发 `session.lineage_rerooted`(那一帧从 core 7.62.0 才有)。
|
|
14
|
+
被跳过的记录若是分支上的祖先,这一轮失败(`invalid_session`:同步口 500、流式终帧 failed、后台 run 行 failed),会话再也跑不动;读口与提交口对走不成一棵树的已存日志答 500 `invalid_session`。
|
|
15
|
+
新形:只剩 `session.lineage_rerooted`(`detail: { break, recordsDropped, recordsTotal, leaf, entriesOnPath, sessionId, runId }`,`break: true` 另带 `{ missingParentId, rootedAt, entriesCut }`),每条腿一帧(会话缓存命中的轮次照样说)。
|
|
16
|
+
丢了祖先的会话从断点续上(`break: true`),这一轮跑完(同步口 200)。回放没丢记录的断开(悬空父 / 自指 / 成环 / 叶子缺席)答 `corrupt_session`(与存档读不出同码、同一个客户端动作);
|
|
17
|
+
`invalid_session` 只剩会话同步导入面(答 `422 invalid_entries`,不变)。
|
|
18
|
+
已知差异:进程已持有这只会话的活存储时盘上才坏的行,这一轮读的是内存里那份完整历史 ⇒ 不发帧(此前每次打开一帧),下一次起服后的第一轮才发;
|
|
19
|
+
丢了祖先的会话 run 续上了,而会话视图(`GET /v1/sessions/:id` / `…/memory-status`)对同一只断开照答 500 `corrupt_session`。
|
|
20
|
+
运维面不变:回放跳过的每条记录照样计 `fail_open_total{tag="server.session-repo.corrupt-record-skipped"}`、逐条进探针文件(`SEMA_FAILOPEN_PROBE`)。执行放置回填(一次性迁移)点名读不出存档的 `fault` 闭集收成 `corrupt_session` / `storage`。
|
|
21
|
+
**谁需要**:文件后端上存档坏了的会话的用户(会话还能跑;一件事一只帧)。**谁受伤**:按 `session.records_skipped` 渲染、或按打开面 `invalid_session` 分支的消费方。
|
|
22
|
+
**补偿**:同一事实改读 `session.lineage_rerooted`(`recordsDropped` = 旧 `dropped`;`entriesOnPath` 是 run 上下文里保留的条目数,不等于旧 `entriesKept` 的全部幸存条目);结构坏改读 `corrupt_session`
|
|
23
|
+
(别重试;换一个新会话、从断点之上的条目分叉,或请运维修好 / 移走那份日志)。
|
|
24
|
+
**升级前做**:无。**回滚**:回到上一版 ⇒ 回到只有 `session.records_skipped` 那一帧(上一版的引擎不发 `session.lineage_rerooted`)、丢了祖先的会话重新失败(`invalid_session`);落盘数据不受影响(本版不写任何新形)。
|
|
25
|
+
|
|
26
|
+
2. **跨会话来信的有序关停改为结清进程里的每只 held 队列,并等结清回执落进发信方的箱(运维面;日志形变更;部署零动作)**:
|
|
27
|
+
旧形:info `peer_inbound_settled_at_shutdown` 的字段是 `{ queues, scopeUnresolved }`(`queues` = 结清了的、scope 求得出的队列数;`queues > 0` 或 `scopeUnresolved > 0` 才发);关停按会话行的属主求每只队列的 scope,求不出的计进 `scopeUnresolved`、那只队列不结清;结清回执投出即返。
|
|
28
|
+
新形:字段改为 `{ queues, cards }`(`queues` = 注册表里的每只队列、含空的;`cards` = 关停那一刻快照里的卡数;只在 `cards > 0` 时发;`scopeUnresolved` 退役:关停读引擎的队列枚举,不再求 scope);回执没落进发信方的箱 ⇒ 每只有回执没落箱的队列一行 warn `peer_inbound_shutdown_receipt_unlanded`(带引擎那句话,点名该队列所有没落箱的 seq,同一只队列两条都没落是一行里列两个 seq;卡照样已结清)。
|
|
29
|
+
兜底计数 `server.peer-inbound.notice-coordinates-unreadable` 退役,新计数 `server.peer-inbound.queue-box-unknown`(按构造不可达的一形:队列的箱既不是会话自己的箱、也不是收件箱)。
|
|
30
|
+
**谁需要**:滚动发布与重启时关停的运维 —— 关停真的等结清回执落进发信方的箱,落不进的按队列一行 warn 点名 seq。
|
|
31
|
+
**谁受伤**:按 `scopeUnresolved` 或旧计数告警的运维。**补偿**:回执没落箱改读 `peer_inbound_shutdown_receipt_unlanded`。**升级前做**:无。**回滚**:回到上一版即恢复旧字段。
|
|
32
|
+
|
|
33
|
+
3. **引擎在没有自己通告席的地方说的话(品牌模型构造 / 一次请求的路由读 / 对端拨号 / 直建蒸馏座)改落结构化 `engine_notice` 日志行,不再是裸 `console.warn` 句(运维面;日志形变更;部署零动作)**:
|
|
34
|
+
典型一形:`MODEL_API_KEY` 不足 8 字符时,起服日志里只剩本服务那一行结构化 `own_credential_value_not_withheld`,引擎那一行裸句消失。HTTP 服务与本机单次运行两个入口在日志接上之后装这只进程缺省席;装席之前的几步(读配置)引擎若说话仍是裸句。
|
|
35
|
+
**谁需要**:把 stderr 当 JSON 行流收的日志管道(引擎裸句不再混进来)。
|
|
36
|
+
**谁受伤**:按引擎裸句子串告警的运维。**补偿**:同一事实改读 `engine_notice` 行的 `code`。**升级前做**:无。**回滚**:回到上一版即恢复裸句。
|
|
37
|
+
|
|
38
|
+
4. **🔴 `DB_BACKEND=local`:数据根里的严格边档(今天一只:`session-incarnations.json`)本构建读不出 ⇒ 起服拒 `config.schema_mismatch`,在 `ensureSchema()` 里、开始服务之前判(行为修复;fail-closed;零 DDL;部署零动作)**:
|
|
39
|
+
— **此前**:没有这只码。严格读在第一次用到那只边档时抛一句无码的拒因(`… is unreadable (malformed) — refusing to read or write session owners and incarnations …`),落点随路径漂:
|
|
40
|
+
起服一次性迁移读到这只边档的(7.141.0 起迁移窗内每次起服都读;7.139.0 / 7.140.0 在数据根里有 run 的会话时读)以它拒启;起服路径没读到它的(例:只调 `ensureSchema()` 的嵌入方)起得来,每个碰到会话元数据的请求答 500 `internal.error`。
|
|
41
|
+
起服之后另一只写者写进来的、本构建读不出的字节,会被本进程下一次写静默盖掉。
|
|
42
|
+
— **本版**:`ensureSchema()`(先于 M33 快照消化与任何请求)把这只边档从盘上读一遍(同一进程里先前已载入的也重读),读不出 ⇒ 拒启,码与 SQL 后端列册对账同一个 `config.schema_mismatch`,拒句同形:
|
|
43
|
+
点名文件、种别与不认得的键名,方向句「the data root is NEWER than this build」,出路三条 —— 部署写下它的那一版;回滚 = 恢复升级前的数据根备份(字节损坏同此出路);读不出字节(例:`EACCES`)⇒ 修好读权限 / 盘 / 挂载再起,文件不用动。
|
|
44
|
+
检查只读,文件原地不动。没设 `DB_BACKEND`(缺省推导的 local)同样拒启,不退回内存。
|
|
45
|
+
起服之后这只边档第一次被碰时才读不出(嵌入方跳过了 `ensureSchema()`;或起服后另一只写者把它写成本构建读不出的形 —— 每次写之前先读盘上现有字节)⇒ 同一只拒(同码);
|
|
46
|
+
读不出的是形 ⇒ 这只边档在本进程里此后每一读每一写都拒(重启才重判),碰它的请求失败(经全局兜底的路由答 500 `internal.error`、运维日志一行 error 级 `request_error` 带本码);盘上字节一个不盖。
|
|
47
|
+
读不出字节(I/O)只让那一次读写失败,不粘。
|
|
48
|
+
嵌入方:包根多导出一只类 `LocalDataRootSchemaMismatchError`(`code` = `config.schema_mismatch`;`findings` 逐文件 `{ path, label, problem, unknownFields }`)与它的类型 `LocalSidecarMismatch`,与 SQL 后端的 `RetiredSchemaPresentError` 同码。
|
|
49
|
+
**谁需要**:`DB_BACKEND=local` 的部署与壳起的本机引擎 —— 降级附着(新引擎写过的根交给旧一些的引擎)拒在开始服务之前、带机读码,拒句即出路。
|
|
50
|
+
**谁受伤**:只调 `ensureSchema()` 的嵌入方遇到读不出的会话元数据边档,此前起得来(只有碰它的请求失败),现在拒启;按旧拒因句子写的告警失配。
|
|
51
|
+
**补偿**:拒句点名文件、种别与出路;判只读,文件原地不动;告警改按码 `config.schema_mismatch`。≤ 7.143.0 的引擎附着更新引擎写过的根时照旧按各自的旧路径失败(已发版本改不了),规则不变:**不许降级附着;回滚 = 恢复升级前的数据根备份**。
|
|
52
|
+
订正 7.143.0 节第 43 条:「服务进程本身起得来」只对起服时不读这只边档的引擎与路径成立(7.141.0 起起服一次性迁移在窗内每次起服都读它;7.139.0 / 7.140.0 在数据根里有 run 的会话时起服回填读它;读不出即以无码的拒因拒启);规则与出路不变。
|
|
53
|
+
**升级前做**:无。**回滚**:回到上一版即回到上一版的落点;本条不改任何持久数据。
|
|
54
|
+
|
|
55
|
+
5. **`DB_BACKEND=mysql|pg`:更新引擎停驻的审批行,续跑 / 决断答 409 `checkpoint.unsupported_version`,不再答 409 `conflict.checkpoint_unreadable`;运维队列行带 `rowVerdict`(wire:一处拒码改答 + 加性键;行为修复;部署零动作)**:
|
|
56
|
+
旧形:滚动升级 / 回滚中,一行由更新的引擎停驻(格式版本超出本副本的上限),本副本 SQL 店的 `get()` 在解码之前按格式版本列先行拒:续跑 / 决断答 409 `conflict.checkpoint_unreadable`,体里 `error` 是店内句子
|
|
57
|
+
「checkpoint format version N is newer than this build supports (max M) — upgrade the service to resume it」;运维队列(`GET /v1/approvals` / `/stream`)上这张卡与可批的卡同形。
|
|
58
|
+
新形:行照常读出,续跑第一级由引擎的判官拒 —— 409 `checkpoint.unsupported_version`、体顶层 `reason: "version_newer"`(引擎 `detail.reason` 原值过境;行留 pending、字节不动;`retriable` 与两版本键照该码的既有读法,与 LOCAL 后端同一答)。
|
|
59
|
+
运维队列行带 `rowVerdict`(引擎判官对这一行的判决;`{ "kind": "lacking", "code": "checkpoint.unsupported_version", "reason": "version_newer", "sentence": … }` 这一形就是上面那一行),与助手收件箱行同名位同一答(收件箱行本版起也带这一位,两只后端同读);
|
|
60
|
+
缺席(存储体解不出 / 两次读之间行离开待决或字节变了)不是 `ok`。`conflict.checkpoint_unreadable` 不再由格式版本产生,剩下的是读这一行时抛出的故障(存储体解不出、库读故障等)。流内审批找停驻门时,判官答 `lacking` 的行本副本不绑(留给能续它的副本)。
|
|
61
|
+
运维面:SQL 后端起服后第一次列出审批队列时把待决行的存储体各读一次(之后按存储体摘要记忆,字节不变不再读);存储体解不出的行照列、不带 `rowVerdict`,计 `fail_open_total{tag="server.approvals.park-row-blob-unreadable"}`。
|
|
62
|
+
**谁需要**:运维(队列上看得出哪张卡本引擎续不了);混版车队(那张卡留给能续它的副本)。**谁受伤**:SQL 后端上按 `conflict.checkpoint_unreadable` 的句子判「版本太新」的消费方。
|
|
63
|
+
**补偿**:改读 `checkpoint.unsupported_version` 体顶层的 `reason`,或在列表上先读 `rowVerdict`。**升级前做**:无。**回滚**:回到上一版即恢复旧拒形;落盘数据不受影响(本版不写任何新形)。
|
|
64
|
+
|
|
65
|
+
6. **持久问店车道:同一只审批问被另一腿再问(换副本重入 / 混版窗)时,「这一问要人」取行上那张卡与这一腿请求的并集(安全;行为收紧;wire 零形变;部署零动作)**:
|
|
66
|
+
旧形:重入腿的呈卡帧采信行上那张卡,判据只读这一腿的请求 —— 行上要人而这一腿请求没带时,`allow_session` 记下会话放行、`decidedBy:"policy"` 的放行被收下、旧族 `tool_approval` 帧与
|
|
67
|
+
`livePending[]` 行不带 `requiresRealApproval` / `rememberRefused`;行上不要人而这一腿请求带时,呈卡帧的 `card.risk.requiresRealApproval` 说 `false`。
|
|
68
|
+
新形:两者任一说要人即按要人 —— `allow_session` 只放行这一次(`rememberApplied:false`)、策略的放行答 400(卡还在)、两族帧与列表行同说要人、提示位亮;
|
|
69
|
+
同一副本上同一只问的重复登记同值(应答口按最早那条答);行不回写(重放帧与耐久问回决口照读行)。
|
|
70
|
+
**谁需要**:多副本 / 滚动升级部署上答审批卡的人与按卡作答的策略客户端。**谁受伤**:依赖重入腿上要人卡被「本会话放行」记住的调用方。**补偿**:不需要(人照常逐次放行这一次)。
|
|
71
|
+
**升级前做**:无。**回滚**:回到上一版即恢复旧读法(本版不写任何新形,落盘数据不受影响)。
|
|
72
|
+
|
|
73
|
+
7. **🔴 引擎 7.62.0:部署的 mod 包按内核契约 8 重建(部署面;BREAKING)**:
|
|
74
|
+
— **此前**:mod 内核契约号是 7。
|
|
75
|
+
— **本版**:引擎只加载声明 `"contract": 8` 的 mod 包(读包者按相等判):按契约 7 写的包在起服被拒 `config.mods_invalid`(`MODS_PACKAGES` 的那一席,拒句点名两个契约号)。
|
|
76
|
+
8 = 扩展内核闭集收成参照实现的 145 名:`session.start` / `turn.start` / `session.measure` / `prompt.submit` 等事件开站(`session.start` / `session.end` 的底升 `classic.SessionStart` / `classic.SessionEnd`)、
|
|
77
|
+
`$.session.turns` / `usage` / `version` 有底、`session.messages` 收 `{ agentId }`。扩展在 `prompt.submit` 上改写过的输入,模型看到改写后的文本,它的 `human_input` 帧带 `rewrittenBy`(改写它的扩展注册名,按改写序;缺席 = 原样送达)。
|
|
78
|
+
请求 `settings.hooks` 里的 `SessionStart` / `SessionEnd` 照收、不在服务端挂(壳属主事件,与 `PermissionDenied` / `SubagentStart` / `SubagentStop` 同一读法)。
|
|
79
|
+
**谁需要**:写扩展改写 / 审阅输入、观察腿生命周期的部署。**谁受伤**:装了按契约 7 写的 mod 包的部署(起服拒);没声明 `MODS_PACKAGES` 的部署零动作。
|
|
80
|
+
**补偿**:mod 包把 `hooks.json` 的 `"contract"` 改成 8 并按新契约重建(新站点与 `$` 方法见引擎文档)。**升级前做**:装了 mod 包的部署先备好契约 8 的包。**回滚**:回到上一版须同时换回契约 7 的包。
|
|
81
|
+
|
|
82
|
+
8. **远端五车道的私有暂存目录多一道 ACL 核:读到继承来的 ACL 条目就去掉,去不掉 / 读不出 / 目标机系统不在闭集里 ⇒ 不暂存,退回就地写目标(行为收紧,fail-closed;安全;部署零动作)**:
|
|
83
|
+
旧形:私有暂存目录收紧后只读回模式位与属主。目标机是 macOS、且工作区目录带可继承的原生 ACL 允许条目(`directory_inherit`)时,新目录一建出来就带着条目,读回 `700` 也挡不住 ——
|
|
84
|
+
暂存件(替换 0600 的目标时,新内容)对条目所点的身份可见;FreeBSD / illumos ZFS 的 NFSv4 ACL(`aclmode=passthrough`)同类。7.139.0 节第 23 条 ⑧ 末尾把它写成已知缺口,就私有目录自身而言自本版起不再成立(已发节原文不改)。
|
|
85
|
+
新形:读回模式与属主之后,再在**目标机**上按 `uname -s` 读目录的 ACL 条目,闭集四臂 —— Linux(POSIX ACL 由模式位读回的掩码覆盖,不另读)· Darwin(`ls -led` 读、`chmod -N` 去)· FreeBSD(`ls -ld` 的 `+` 读、`setfacl -b` 去)·
|
|
86
|
+
SunOS / illumos(同读、`chmod A-` 去)。读到条目就去、去完再读,读不到才算私有;读不出、去不掉、去完仍读到、`uname` 读不出或名字在闭集之外 ⇒ 这一次写不暂存,退回就地写目标
|
|
87
|
+
(与第 23 条 ⑧ 同一条退路:非原子;ssh / local-docker / k8s 写进原 inode、权限位不变,e2b 的 `files.write` 与 adb 的 `adb push` 整份写目标、inode / 权限位由对端定),遥测计 `server.remote-write.stage-seal-fallback`。
|
|
88
|
+
整文件替换提交时跟一跳符号链接到别的目录重新暂存的那只私有目录走同一只判。wire 零变化。
|
|
89
|
+
覆盖面:只管五条远端车道的私有暂存目录;host 车道的暂存是引擎的、device 车道的是设备侧执行器的,本版不动;Linux 上经 NFS 挂载、由服务端自己执行的 NFSv4 ACL 在客户端读不出条目,Linux 臂按掩码读法算过;
|
|
90
|
+
FreeBSD / illumos 两臂按系统文档写、未上真机,工具输出与预期不符(退出状态不成、往 stderr 报了一句、头一行不是权限串、多出一行)时同样退回就地写;读 ACL 的工具若自己静默吞掉读取错误(macOS 的 `ls -le` 没有第二条读路),读到的是「没有条目」,本版看不出;
|
|
91
|
+
替换之后目标不带原件自己的 ACL 条目(整文件替换换 inode)本版不改。
|
|
92
|
+
**谁需要**:ssh 车道上目标机是 macOS / FreeBSD / illumos、且工作区目录带可继承 ACL 条目的部署(其余四条车道的目标是 Linux 容器或 Android 设备,走 Linux 臂)。
|
|
93
|
+
**谁受伤**:ssh 目标机系统不在 Linux / macOS / FreeBSD / illumos 之内的部署(OpenBSD / NetBSD / AIX / Cygwin 一类):这类目标上每一次写都改走就地写(与 7.138.x 同形,非原子),`stage-seal-fallback` 计数非零。
|
|
94
|
+
**补偿**:就地写与 7.138.x 逐字同形、写照常成功;计数点名目录;要原子替换就把工作区放到被支持的系统上。macOS / FreeBSD / illumos 目标上继承来的条目去得掉的照常暂存,无需动作。
|
|
95
|
+
**升级前做**:无。**回滚**:回到上一版即恢复旧形(私有目录上继承来的条目不再被去);暂存名是瞬时的,零数据面动作。
|
|
96
|
+
|
|
97
|
+
9. **🔴 活流文字段的脱敏单位收成段(与账本 `text` 行同一个):引擎的 `text_end` 是文字块的交付点、不收段 —— 锚与值分在同一段的两个文字块里时,`text_delta` 与 `text_end` 照样遮(wire 值语义;安全;帧数 / 帧序 / 身份零变化;部署零动作)**:
|
|
98
|
+
旧形(7.143.0):`POST /v1/tasks/stream`(顶层与转发子代腿)与子代 tail 面上,文字段的流式口在引擎每个 `text_end` 上收掉重开,`text_end.content` 是引擎那一块孤立地过脱敏器;
|
|
99
|
+
账本 `text` 行(`GET /v1/runs/:id/events` / turns)按段把同一段的几块拼起来判 —— 锚在块 1(`password=`)、值在块 2 时,活流与 `text_end` 带值明文、账本遮;
|
|
100
|
+
账本行只拼逐块帧字节,只有 `text_end`(没有逐块帧字节)的块不在行里。
|
|
101
|
+
7.143.0 节第 11 条「文字段的单位是引擎的文字块 … 此前 `text_end` 上就是这样」一句自本版起不再成立(已发节原文不改)。
|
|
102
|
+
新形:文字段与推理段同一条状态边界 —— 段(段界谓词 + 腿终局 / 子代终态),= 账本 `text` 行的单位。引擎的 `text_end` 是这一块的交付点:块里还在窗里的字节按整段读法、文本到此为止交出
|
|
103
|
+
(紧贴 `text_end` 之前那一帧不带 `eventId` 的 `text_delta`),`text_end.content` = 引擎这一块的正文接在本段前文之后判、只交这一块那一截。一块的原文 = 它的逐块帧字节,
|
|
104
|
+
只有 `text_end`(没有逐块帧字节)的块 = 它的正文;段文本 = 各块原文依次拼接,活流的段与账本 `text` 行同读(只有 `text_end` 的块活流上由它的 `text_end` 交付、不另出逐块帧,账本行里照样有它)。
|
|
105
|
+
有逐块帧的块:逐块帧拼接 = 该块 `text_end.content`(只有 `text_end` 的块没有逐块帧,它的正文只在自己的 `text_end.content` 里;引擎修剪过退化循环尾的块照旧以修剪后的为准);各块依次拼接 = 账本 `text` 行(下面两个方向除外)。交付时按到此为止的判定与整段判定不同的两个方向一个处置:凭据形恰横跨块界(读得出的半形出 `«redacted…»` 记号;读不出的半截 —— 如 `sk-ant-api0` 这样的短前缀 —— 原样出门,
|
|
106
|
+
至多是块界之前的字节;后一块上横跨的那一条整枚换记号),或交付时认作凭据、后文让它不再是(如 `password=config.` | `password2;`:活流那一截是记号、账本原样)——
|
|
107
|
+
活流按到此为止,账本整段判,该段收段时计一次 `server.live-text.hold-diverged`。帧数、帧序、`eventId`、`text_end` 在场性与 7.143.0 相同。
|
|
108
|
+
**谁需要**:读活流的 API 消费方与壳(多文字块的段:引用切块、穿插思考的回答 —— 活流与 `GET /v1/runs/:id/events` 对同一段文字同一个答案)。
|
|
109
|
+
**谁受伤**:按 `text_end` / `text_delta` 字节做逐字 diff 的消费方 —— 锚值分块的那一形从明文变记号;凭据形恰横跨块界时,后一块的 `text_end` 与逐块帧以一枚整的记号起头(前一块已带一枚);块界上认作凭据、后文让它不再是的那一截活流是记号、账本原样;按账本 `text` 行逐字 diff 的消费方 —— 只有 `text_end` 的块的正文从本版起在行里;
|
|
110
|
+
多文字块长段的 CPU:每个 `text_end` 整段扫两次(交付余下字节一次、`text_end.content` 接本段前文判一次),上界 O(块数 × 段长)(7.143.0 每块只扫这一块)。
|
|
111
|
+
**补偿**:按段读的同一份文本在 `GET /v1/runs/:id/events` 的 `text` 行;按块整段替换的读法照旧幂等(有逐块帧的块:逐块帧拼接 = 该块 `text_end.content`)。
|
|
112
|
+
**升级前做**:无。**回滚**:回到上一版即恢复旧形(文字段按块判、账本行只拼逐块帧字节);本版写下的行原样留着;零数据面动作。
|
|
113
|
+
|
|
114
|
+
10. **🔴 `DB_BACKEND=local`:仍带属主戳的存档的拒有了自己的码 `conflict.session_archive_stamped`,fork 与改日志的各形推送同码同句;载荷分叉的 `fast_forward` 与提交时才翻成 fork / stale 的无同意推送也答它(wire BREAKING:这两扇写口上带戳存档的拒由 `conflict` 改新码,按 `errorCode == "conflict"` 分支的消费方先改读;行为修复;部署零动作)**:
|
|
115
|
+
旧形(7.141.0 节第 10 条):仍带戳的存档(一次性迁移留着的,或跳过带迁移的版本升上来的数据根)上,`POST /v1/sessions/:id/fork` 与改日志的推送(会话同步导入的提交)答 `409 conflict` + 带出路句的固定句
|
|
116
|
+
(「… delete the session and push it again」)。两处不齐:
|
|
117
|
+
① **码**:`conflict` 同时是暂存提交时属主格已变那一拒的码(固定句「… start the sync again」,出路相反:从第一阶段重来)—— 同状态、同码、两条相反的出路,按码分支的机读方分不开,只能读句子;
|
|
118
|
+
② **句**:改日志的推送在提交时先过「谁赢」的判,带戳判排在它们后面 ⇒ 三形被截住,答通用的 `409 conflict`、句子 `sync conflict`、体带 `relation`:`fast_forward` 而共享条目的载荷与目的端的不同
|
|
119
|
+
(目的端把某条补写过、id 不变,推送拿着旧版本再追加);第一阶段到提交之间分类翻成 fork、翻成 stale,又没带同意(`resolution: "overwrite-dst"`)。这三形的通用句指的出路是「带同意重来」,而带同意重来在带戳存档上照样被拒 —— 死路;
|
|
120
|
+
干净追加的 `fast_forward`、同 id 异载荷、带同意的 fork 答的是带出路句的那一条,这三形不带。
|
|
121
|
+
新形:① 带戳存档的拒有自己的 wire 码 `conflict.session_archive_stamped`(状态 409,固定句的字节不变,附录 A.1 新行);fork 路由与会话同步导入的提交两扇写口读同一张映射,同码同句;
|
|
122
|
+
属主变更那一拒仍是 `conflict`。② 带戳判是提交里第一道存档判 —— 只要这一提交要换日志(「id 与内容都相同」那一支之外的一切),先问这份存档的日志换不换得了;
|
|
123
|
+
带戳存档上各形(干净追加 / 载荷分叉的 `fast_forward` / 同 id 异载荷 / fork / stale,带同意与否)一律答同一码同一句,体只有 `error` / `errorCode` 两键(不带 `relation`),什么都没写(行不动、存档原样带戳)。
|
|
124
|
+
「id 与内容都相同」的重推照旧不碰存档、照常落定;匿名存档上的应答不变(提交现在先读一次存档头:头读不出的存储故障先于同步冲突上抛,不再答 409)。
|
|
125
|
+
提交里的次序也随之定下:带戳判排在本处写者拒(`conflict.session_writer`)与引擎的日志校验之前 —— 前者在 HTTP 上只有第一阶段之后别处认领了本处写者的竞态窗里才到得了(第一阶段已拒写者),
|
|
126
|
+
后者流式上传时已判过(只有直接调店方法的嵌入方碰得到);带戳存档与这两样同时成立时,先读到新码。
|
|
127
|
+
范围(如实):第一阶段(`POST /v1/sessions/:id/sync/import`)按 id 分类出 fork / stale 且没带同意时,仍先答通用的 `409 conflict`(`sync conflict` + `relation`)—— 那一口只按 id 分类、不经提交里的带戳判,答的是同步协议的冲突答复;
|
|
128
|
+
带同意重来之后,第二阶段答新码。所以带戳存档上 fork / stale 形的推送,要到带同意的第二轮才读到出路句。
|
|
129
|
+
**谁需要**:壳 / SDK 等按机读码分支的消费方(带戳存档:删掉会话再推;属主变更:从第一阶段重来)—— 两件事现在是两个码;local 部署上对迁移留着的带戳存档(起服 warn `local_archive_kept_stamped` 点名)推送的客户端,载荷分叉的推送一次就读到「删掉会话后重推」,不会先去试带同意重来。
|
|
130
|
+
**谁受伤**:① 按 `errorCode == "conflict"` 处置带戳存档的 fork / 改日志推送拒的消费方(7.141.0–7.143.0 的读法)—— 这两扇写口上它们不再读到 `conflict`,按状态 `409` 或按 `conflict.session_archive_stamped` 分支;
|
|
131
|
+
② 按 `sync conflict` 句子或体里 `relation` 键判「要解决冲突」的客户端:载荷分叉的 `fast_forward` 与无同意的 fork / stale 在带戳存档上不再读到它们(这三形在带戳存档上本来就解决不了)。
|
|
132
|
+
**补偿**:改读新码 `conflict.session_archive_stamped`(读体的 `error` 即出路:删掉会话 `DELETE /v1/sessions/:id` 后重推);按状态 `409` 分支的不受影响。**升级前做**:无。**回滚**:回到上一版即恢复旧码与旧判序(本版不写任何新形,落盘数据不受影响)。
|
|
133
|
+
|
|
134
|
+
11. **更正(7.143.0 节第 19 条、第 26 条、第 10 条、第 31 条与第 36 条五处说法,文书;零行为变化)**:
|
|
135
|
+
① **第 19 条**写「策略的 deny / ask 名单点名 `TaskOutput`(或 `TeamCreate` / `TeamDelete`)⇒ 跑前拒 `config.legacy_tool_name`」,这只对一种来源成立。退役工具名写进 deny / ask 规则时,在哪里拒、答什么,按名单的来源分:
|
|
136
|
+
— 请求体 `settings.permissions.deny` / `ask`:三条提交口(`POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs`)受理时拒,零模型调用;`422`、码 `request.unprocessable`、句首 `request settings cannot be applied as written:`,体带 `field`(`settings.permissions.deny` / `settings.permissions.ask`)与 `detail.problems[]`,退役名那一条 `reason: "retired"`。
|
|
137
|
+
— 部署名单 `APPROVAL_REQUIRE` / `APPROVAL_DENY` / `APPROVAL_NEVER_AUTO` / `APPROVAL_GRANT`:起服拒启,拒句点名条目(没有 wire 码);中心下发的 `governance.approvalRequire` 整组被拒、保前值。
|
|
138
|
+
— `config.legacy_tool_name`(同步腿 `400`;异步与流式腿落在终态 run 行的码上)只来自存量:升级前的写口收下、盘上留着的会话规则 `toolDeny`(例:7.142.x 上经 `PUT /v1/sessions/:id/policy` 写进去的 `TaskOutput`),升级后在那只会话上提交即得这一码,拒句是引擎的;出路 = operator 用 `PUT /v1/sessions/:id/policy` 改写那条会话的规则。
|
|
139
|
+
请求体 `settings.permissions.allow` 点名这三个名字照旧只得一行提示。
|
|
140
|
+
② **第 26 条**没有标门。**直连门部署**(`DIRECT_APPROVAL_DOOR` 连同它要求的 HMAC 钥与签名身份锚都在)上,`POST /v1/approvals/:sessionId/decide`、`POST /v1/assistant/tasks/:id/plan_review` 与 `POST /v1/tasks/:taskId/asks/:askId/decision` 三口不收 `decidedBy`(在场即 `400 decided_by_not_in_proof`,不论值),
|
|
141
|
+
所以 `decidedBy: "policy"` + `decidedVia` 在这三口上是 400;只带 `decidedVia`(旁边是缺席的人)在任何部署的任何一口上都是 400(live `/respond` 码 `request.body_shape`,其余三口 `request.field_invalid`)。
|
|
142
|
+
live `POST /v1/tool-approvals/:id/respond` 不带决策证明,直连门部署上照样按第 26 条受理。不是直连门的部署,四口按第 26 条原句受理。
|
|
143
|
+
③ **第 10 条**的 `/resume` 是 `POST /v1/assistant/tasks/:id/resume`(没有 `POST /v1/runs/:id/resume` 这条路由)。四道续跑门各续各的门:`POST /v1/approvals/:sessionId/decide` 续工具审批卡;`POST /v1/assistant/tasks/:id/plan_review` 续 `plan_review` 门;
|
|
144
|
+
`/resume` 续资源限停驻(门 `resource_limit`:调度抢占,或预算 / 轮数 / 墙钟分片),停在审批卡上的任务打它得 `409 gate_not_resumable`;`POST /v1/sessions/:id/wake` 续 `task_done` 停驻,有未决门时得 `409 wake.gate_pending`。
|
|
145
|
+
④ **第 31 条**写「`userSettings` 里要根的 allow 规则免问的是配置根下的路径」(CHANGELOG 同节「现在」句:「它免问配置根下 `secret` 的写」),对配置根下的**写**不成立:
|
|
146
|
+
— 写:目标在引擎缺省写保护表上的写(配置根就在表的 `.sema` 行上,见下)照问,任何 allow 规则 —— 带层条目、纯串、`//` 绝对形 —— 都清不掉;卡上 `mandate: "write_protection"`,问句说它由确认这一次清掉、不由常驻 allow 规则。
|
|
147
|
+
规则答不了这一类问;模式级放行与 auto 模式分类器对它照引擎自己的读法,不在本条。
|
|
148
|
+
— 配置根在每条车道上都在 `.sema` 行上:声明了 `SEMA_CONFIG_DIR` 时它就是交给引擎的配置目录,`.sema` 行在它及其以下全命中;缺省 `~/.sema` 与路径里带 `.sema` 段的任何目录(含沙箱车道缺省的 `<home>/.sema`)在任何车道上都命中;
|
|
149
|
+
转进沙箱的 `SEMA_CONFIG_DIR` 是本服务同名 env 的原值(名单只收名),与交给引擎的配置目录是同一只。
|
|
150
|
+
— 两处不归这一行:引擎数据根(记忆引擎的根;壳布局 `~/.sema/engine-data`)坐在配置根下时,根里的写按根内的相对路径判、豁免于 `.sema` 行(表上别的行照判);
|
|
151
|
+
部署整表替换写保护表(`WRITE_PROTECTED_TABLE_REPLACE`)去掉 `.sema` 行时,这一行随之不在。
|
|
152
|
+
— 读不在写保护表上(这张表只管写),第 31 条对读的说法不受本条影响。
|
|
153
|
+
构造:本机车道,请求体 `settings.permissions.allow` 带 `{ "rule": "Edit(/secret/**)", "layer": "userSettings" }`,写配置根下 `secret/n.txt` ⇒ 停在一张审批卡上(`mandate: "write_protection"`),不是免问落盘。
|
|
154
|
+
⑤ **第 36 条 ③**写「本部署的店集 = 盘上的(个人挂载上有店就算)」,少说了「盘上的店」是怎么来的:记忆引擎的 file 店**一打开就建目录、写根锚**,部署对象又把「目录在 / 本对象开过」算进店集 —— 所以一次**被拒**的个人层抹除(`400 config.memory_erasure_scope`,什么都没擦)、或任何一次点名个人层的只读(`GET …/memory-status?scope=user:<x>`、出处 / 清标账带层座)都会留下一只从没写过的个人店,
|
|
155
|
+
此后不点名层的出处 / 清标账 / 清标请求永久答 `400 request.memory_layer`(重启照旧);7.142.0 同序列不翻(那时店集由配置点名的层推出,不读盘)。这是缺陷(被拒请求不该改变部署之后的应答),根在引擎的店集读法,本服务只能消症状、不修根,本版**不改**:
|
|
156
|
+
**补偿**:在请求里点名层(GET 口 `?scope=<层键>`、POST 口体 `"scope"`)照常可用;要退回「不点名层」的读法时,确认个人店目录 `<记忆根>/personal/.engine` 下**只有** `root-anchor.json` 一个文件(= 从没写过)再删掉整只 `personal/` 目录 —— 有别的文件就不是空店,别删。构造与现状读数见本版发车帖。
|
|
157
|
+
7.143.0 节原文不改(已发节字节不动)。无三问(更正条)。
|
|
158
|
+
|
|
159
|
+
12. **host 车道:执行环境的家目录主张证不了 ⇒ 环境在开跑前就不铸,run `failed` 终局带码 `env.home_unconfirmed`(同步提交腿 409),命令带不带路径都是同一首拒;worktree 的 git 基环境不再带家目录主张;更正 7.140.0 节第 12 条 ③(wire 新码;行为修复;部署零动作)**:
|
|
160
|
+
旧形(7.140.0–7.143.0):host 车道(含 `run-local`)上家目录主张(`REMOTE_EXEC_HOME_DIR`,缺席时服务进程的家目录)与子进程拿到的 `HOME`(继承面 + 会话 `settings.env`)对不上 / 读不出 / 不是绝对路径时,环境照铸、门不开:
|
|
161
|
+
run 照常开跑、模型照常被调;模型发出的命令不带路径(`echo hi` / `ls`)⇒ 工具结果是环境的拒句(`shell_unavailable`,点名声明值与量到的 `HOME`);带路径(`cat notes.txt` / `cat ~/notes.txt`)⇒ 先撞引擎的读边界
|
|
162
|
+
(`read_unestablished`,「could not establish what is read」),句子不点名家目录 —— 同一根因两种首拒,后一种把人引去读边界。run 多以 `completed` 收场(模型读到拒句后自己作答)。
|
|
163
|
+
新形:host 环境在构造时就判(读数是本服务组合给子进程的那份 env,铸环境时就到手),证不了 ⇒ 环境不铸 —— 工厂抛带码的拒,引擎在准备期原样承运:run `failed`,
|
|
164
|
+
`terminal.code` = `env.home_unconfirmed`,`terminal.message` = 判官的拒句(点名主张、量到的 `HOME` 与改法;与旧形无路径命令那一句同文)。一条命令没跑、模型一次没调、一个 token 没烧,命令带不带路径无从分别。
|
|
165
|
+
同步提交腿 `POST /v1/tasks` 按零工作拒答 **409** `errorCode: "env.home_unconfirmed"`(不计费、不占提交幂等键);流式腿终帧 `done.result.terminal`、后台 run 行同码。码是本服务自铸的执行环境拒码(`env.*` 族)今天唯一的一员,契约附录 A 有行。
|
|
166
|
+
worktree 隔离的子代:引擎先铸树,子环境构造即拒,树随即被引擎收掉,子代以同码失败。worktree 的 git 基环境(起服铸、只跑 `git worktree add/remove/prune`、从不交给引擎)不再带家目录主张:不对证、不拒,孤儿 worktree 清扫照跑。
|
|
167
|
+
远端五车道(k8s / local-docker / ssh / adb / e2b)不变:家目录读数要环境开起来才有,照旧在开环境那一拍拒、拒句落在工具结果里;引擎的读边界要先读环境才判得了的命令(递归读形 `grep -r … ~/…` 一类;adb 上连带路径的普通读)在那里先被读边界拦下(要人批 / 只读面拒),句子不点名家目录 —— 这些车道上同一根因两种首拒仍在。
|
|
168
|
+
**订正 7.140.0 节第 12 条 ③**(已发节原文不改):「那只环境拒起(命令面 `shell_unavailable`、文件面 `target_unavailable`、连接 `connect_failed`)」本版起读作「环境不铸,run 失败终局 `env.home_unconfirmed`(同步腿 409)」;
|
|
169
|
+
「起服时铸的 worktree 基环境同样被证,对不上时孤儿 worktree 清扫不跑」本版起不成立(基环境不带主张,清扫照跑)。三条出路不变:删掉声明(或设成 `HOME` 的值),或去掉会话里的 `HOME`。
|
|
170
|
+
7.141.0 节第 32 条 ③ 所述的两种首拒(`shell_unavailable` / `read_unestablished`),在 host 车道上本版起收成上面那一只;那一条说到的 adb 与其余远端车道仍是那一形(上段)。
|
|
171
|
+
**谁需要**:host 车道的部署与 `run-local` 用户 —— 家目录配错时第一句就点名根因(声明值 vs 量到的 `HOME`),不再被带路径命令的读边界拒引去别处;零 token 早失败。
|
|
172
|
+
**谁受伤**:按 run `completed` + 工具结果里的拒句(或 `shell_unavailable` 字样)认这一形的脚本与告警;同步腿上按 HTTP 200 读这一形的调用方(现为 409)。
|
|
173
|
+
**补偿**:按码 `env.home_unconfirmed` 分支(同步腿 `errorCode` / 终局 `terminal.code`);句子与旧形无路径命令那一句同文。
|
|
174
|
+
**升级前做**:无(主张与 `HOME` 一致的部署零差别)。**回滚**:回到上一版即恢复旧形;本条不写任何持久数据。
|
|
175
|
+
|
|
176
|
+
## 7.143.0 —— `wiring_manifest` 帧的容器段在 run 店 File 孪生按会话块账本去重(持久面;体量;回滚地板 = 本版) · env 两槽 × 目录:本地根首份管模型面目录的首次写入决定文档(K0)、`planeRefusalCode` 只答最新候选、leader 路由模型经服务表解、env cheap 槽悬空一次性 warn(配置面;行为收紧) · 🔴 部署治理的装配相容性门改在部署 MCP 服务器 / A2A 对端物化之后判:`mcp` / `a2a` 锁、合规否决 `mcp_servers` / `a2a_peers` 撞上部署自带的服务器 / 对端 ⇒ 起服拒(行为收紧,fail-closed;部署面) · 运维审批队列行带族名 `kind`、被扣的跨会话来信作 `peer_inbound` 行进审批席(wire 加性;🔴 消费方先按 `kind` 分支) · k8s 车道:停驻时沙箱从未起过的停驻,续跑改作一次新连接(空间开 ⇒ 恢复 `latest`);打包过的停驻快照对象不在 ⇒ 一行 `workspace_latest_dangling`(`lane: "park"`)+ 空目录;更正 7.142.0 节第 9 条尾的已知限制(行为修复;运维面日志加性) · 订正 7.141.0 节第 1 条的「谁受伤」:结构化 warn 只覆盖本服务写的那一行,网关密钥被拒收时引擎另说一行裸 `console.warn`(引擎已知限制),logger 接上后的那一行受 `LOG_LEVEL` 约束(文字订正;零行为变更) · 🔴 SQL 后端 `task_attachment` 加一列生成列 `seed_session_id` + 唯一索引 `uq_att_seed`:一只会话一只种子改由唯一键判,已有种子会话上的并发提交恒答 409(行为修复;DDL 升级前先加列;wire 零变化) · 续跑请求可重述对端表:四道续跑门收提交体同键的 `mcpServers` / `a2aPeers`,缺席 = 冻结读法(wire 加性;行为面;壳宜每次续跑送当前表) · 🔴 活流模型文本过同一只脱敏器:`text_delta` / `reasoning_delta` 逐块帧只放已判定的字节,拼接 = 段末帧正文 = `done.result`,段末余下的字节一帧补齐(wire 值语义;安全) · 会话读面(视图 · 记忆状态 · 记忆抹除 · 头探针 · 事件流 · 执行放置)对「文件后端上行事实没有落下、存档又读不出」的会话,从 500 `corrupt_session` 改答 404 `not_found.session`(与对非属主、对不存在的会话同一只;原故障进运维日志 `session_owner_unreadable`;行为面;应答格状态变化) · 中心 MCP 声明撞同一工具命名空间前缀:同步提交腿从 `200` + `failed` 体改 `409 config.mcp_server_name_collision`,`GET /v1/capabilities/mcp` 从无码 `500` 改同码同状态同句(wire 码与状态变;按 HTTP 状态分支的提交方看一眼) · 🔴 持久 ask 店车道上 askId 的身份含这一问展示给人的动作(工具名 + 入参摘要):同一 run 同一腿里复用调用 id、换了入参或换了工具的那一问出自己的卡(安全轴;行为收紧;不透明 `askId` 值变;零 DDL) · 🔴 `POST /v1/approvals/:sessionId/decide` 的 `boundCallId` 与 `boundInputHash` 两位必带,缺哪位 400 `decide_requires_binding` 点名哪位;不再拿当前停驻行补;`remember_requires_binding` 退役(BREAKING 行为面;安全轴;决断方回显队列行上的那一对) · 订正 7.142.0 节第 18 / 19 条的两处读数说法:坏块 / 撤块时能力位读 `no_caller_credential`(`no_origins` 是平面的第九条前提);强锚名紧贴前一枚凭据尾巴那一形在 7.142.0 上于 `GET /v1/runs/:id/events` 回放的 `tool_end` 行与活流逐块帧明文(文字订正;零行为变更;这一形本版起已修,见第 41 条) · 会话记忆同步触发口的 409 `conflict.session_memory_unobserved` 体恒带 `reason`:最近一条已结 run 的记录里没有记忆观测 ⇒ 点名它的记录里有什么、句子给出路;🔴 它配了记忆而没挂上(`memoryless`)⇒ 由 200 空报告改 409 `memory_not_mounted`;读集仍只读最近一条已结 run(wire 加性;行为面;三句拒句换形 / 新句;零 DDL;部署零动作) · 🔴 引擎 7.61.0:升级前结清在途审批、排空旧 worker,mod 包按契约 7 重建(部署面;BREAKING) · 🔴 审批卡的委派子代出处键 `sourceTaskId` 改名 `sourceSessionId`(wire BREAKING;零别名) · 通告码 `context.image_removed` 改名 `context.media_removed`、TaskOutput 退役(wire 码改名;策略名单) · 设备车道放置围栏 + 协议修订 4 `symlink_loop`(行为面;wire 加性) · SQL 后端新表 `mailbox_consumed`(起服自建) · `DB_BACKEND=local` 工具结果按 TTL 回收(行为变化) · blob 上传哈希不符一律 400、嵌入方两只店换新组形(wire 值变化;类型面 BREAKING) · 记忆同步:别的 scheme 里的 URL userinfo 也判凭据(行为收紧) · 设置导入:用户层 `/` 形路径规则留在文件里(行为收窄)、导入预览的用户层不收 `root`(wire BREAKING) · 🔴 SQL 后端 `approval_ask` 加一列 `decided_via`、决定体加性键 `decidedVia`、能力位 `approvalDecidedVia`(wire 加性;DDL 升级前先加列) · `verify:true` 任务的上限封住实现腿与各轮修复的合计,花光 ⇒ 不再修复(行为收窄;wire 加性) · 订正 7.139.0 节第 24 条 ③:没配包装的 worktree 子代仍由本服务拒(文字订正;零行为变更) · 嵌入方包 `resolveSpec` 的包装须返回同一只对象(嵌入方行为面 BREAKING) · 验证器自己停驻的那张卡改由引擎的作废动词结算、会话钉随之放掉,编排(leader)路径同样作废(行为面;修复;部署零动作;订正 7.141.0 节第 31 条的两条已知限制) · `settings.permissions.allow` 的条目也可带出处层,user 层的 `/` 形 allow 读在执行环境的配置根(wire 条目型放宽 + 能力位;端见位才发;收掉 7.141.0 节第 15 条「已知限制」的 allow 那一半) · 后台子代一个 id:面板 / 完成通知 / 孙代嵌套 / 审批归属都读注册表行 id;升级与回滚前各让停驻的后台子代结清(行为面;部署面) · Runner 之外复活的后台子代(停驻赎回 / 操作员续跑)的完成走委派树根会话的会话通知门(行为修复;wire 零新键) · 🔴 记忆同步:中心每个层分区一只化身、同步口改到 `/v2/memory/sync/:scope`、本机游标原样携带化身(引擎三处硬破坏;中心库新表起服自建;部署:两端同版 + 停驻层删游标) · 🔴 抹除与会话记忆状态答整个部署(`409 memory.erasure_store_unjudged` 与会话自助抹除体的 `scope` 退役;嵌入方类型面 BREAKING) · 🔴 规则店:引擎 7.61.0 之前从用户层设置导入的、从 `/` 写起的全局放行起服即退役(按 add;deny / ask 不动;一次性迁移 M36,每次起服幂等;持久数据面;行为收紧;部署零动作) · 本地导入载体的 deny / ask 在 prepare 当场落店、预览成员带 `outcome`,放行仍在 redeem 落;收紧写不进 ⇒ 整批 503、放行扣下(行为面;wire 加性) · 自由文本脱敏的取证读法按出处读:一枚凭据不拿自己上一轮的读数当证据、私钥收尾栅栏落在不完整读数里两读取并、SSH2 块之后紧跟的孤立收尾之前读作无头体、取证级数界 32 到顶整段遮(行为面;安全;脱敏产物可能变;运维面多一个 fail-open 标签) · 🔴 审批卡的断连重放帧与活铸帧同事实:问行卡信封加一座 `liveFacts`,断连重放的 `approval_request` 带活铸帧顶层的同一组卡外事实;本版之前铸的行重放帧带 `liveFactsUnknown: true`(安全轴;wire 加性;存形加性,零 DDL;🔴 多副本先停光旧副本再让本版接流量) · 🔴 自由文本脱敏的名字面:复合凭据名(`api_key=` 一族)在自由文本的声明形里是名字锚、名字的左界止于前一枚已认出凭据的终点(紧贴形首遍即遮、各出口同读)、不带引号的值里面的赋值照问(行为面;安全;脱敏产物变;带这些赋值的命令不再给常驻放行;部署零动作) · 运行时依赖 `@modelcontextprotocol/server` 2.4.0(npm 安装多一只包;部署零动作)
|
|
177
|
+
|
|
178
|
+
1. **`DB_BACKEND=local`:run 账本里每条 run 的装配清单(`wiring_manifest` 行)按会话去重存 —— 容器段存进每会话一只块账本 `<数据根>/run-blobs/<会话>.jsonl`,行里只留引用(持久数据面:存形加性,存量不迁移;wire 与读面零变化;回滚地板 = 本版;部署零动作)**:
|
|
179
|
+
旧形:`runs/<taskId>/events.jsonl` 里每条 run 的 `wiring_manifest` 行带一整份清单(名册、MCP、技能……;实测每行约 37–44 KB,同会话每条 run 一份,占 run 账本约八成)。
|
|
180
|
+
新形:这一行里值为对象 / 数组的段换成 `{ "$blob": "sha256:<64 hex>" }`,段体按会话在 `run-blobs/<会话>.jsonl`(一行一只 `{ digest, body }`;文件名 = 会话 id 的可读前缀 + `-` + 会话 id 的 sha256)里只存一份 —— 没变的段跨 run 共用一块,变了的段多一块;
|
|
181
|
+
标量段与 `eventId` 照旧在行里。`GET /v1/runs/:id/events`、run 事件流、会话 MCP 面板与其余经 run 店的读口读到的仍是整帧,逐字段与以前相等(同一段的嵌套键序取首次存下的那一份)。
|
|
182
|
+
升级前写下的整帧行不改写、照常读;从本版起新写的行是引用形 —— 账本只向前缩,旧会话随删会话回收。删会话先删这只块账本、再删各 run 目录;
|
|
183
|
+
块账本删不掉(权限 / 挂载)⇒ 这次删会话整次答错误、一样都不删,修好之后重试即可。
|
|
184
|
+
块账本缺行 / 坏行(断电丢尾、手工改动)⇒ 引用它的那一帧读不出:读口不交出这一帧(其余帧照交;不交出缺段的清单),计数 `fail_open_total{tag="server.run-store.corrupt-record-skipped"}` 每帧每进程一次;
|
|
185
|
+
块账本整份读不出(权限 / 挂载)与 `events.jsonl` 读不出同一条路:`RUN_STORE_STRICT_HYDRATE=on` 拒启并点名路径,否则起服原样抛。
|
|
186
|
+
直读 `events.jsonl` 的离线工具(取证脚本、按行统计)从本版起读到引用形:要整帧就经 `GET /v1/runs/:id/events` 读,或按 `run-blobs/<会话>.jsonl` 的 `{ digest, body }` 自行换回。
|
|
187
|
+
**谁需要**:长会话的 local 车道(run 账本的盘面、起服堆与读盘随 run 数线性长,其中约八成是重复的清单)。**谁受伤**:直读 `events.jsonl` 的离线工具(见上);回滚到上一版(见下)。
|
|
188
|
+
**补偿**:直读账本的离线工具改经 `GET /v1/runs/:id/events` 读整帧,或按 `run-blobs/<会话>.jsonl` 的 `{ digest, body }` 自行换回;回滚只伤回放面,再升回本版即复原。**升级前做**:无。**回滚地板 = 本版**:本版写过的数据根回到上一版,旧二进制读得出账本但不认引用 —— 回放面(`GET /v1/runs/:id/events`、事件流重连)上本版写下的 run 的清单段显示成 `{ "$blob": … }`,
|
|
189
|
+
会话 MCP 面板对这些 run 读成缺席;活 run 不受影响(旧二进制整帧写)。再升回本版即复原(块账本还在)。旧二进制删会话不删 `run-blobs/` 里的块账本 —— 留下的只占空间。
|
|
190
|
+
|
|
191
|
+
2. **🔴 本地配置源:一份管模型面的 `config.d/models.json`,在设了 `MODEL_ID` 时只有配置根的 `config.env-models.json` 读作 `replaced` 才顶替 env 模型表;升级的本地根由起服时的一次性迁移铸这份确认(行为收紧;升级之后才写下目录的根要写一份确认;中心配置源零变化)**:
|
|
192
|
+
— **谁受影响**:`CONFIG_PROVIDER=local`(含 `run-local` / `sema` CLI)、设了 `MODEL_ID`(env 模型表已声明;严格名册布防 `CONFIG_REQUIRE_ROSTER=true` 时 env 表是占位,不算)、`config.d/models.json` 有启用条目的配置根。中心配置源不守卫:中心发布的目录照旧整表顶替 env 表。
|
|
193
|
+
— **配置根**就是放 `config.d/` 的那个目录(`CONFIG_LOCAL_DIR` → `AGENT_DATA_DIR` → `~/.ai-agent`)。决定文件 `<配置根>/config.env-models.json`,两种写法 `{"envModels":"replaced"}`(目录顶替 env 表)/ `{"envModels":"kept"}`(env 表保留);
|
|
194
|
+
缺席读作 `kept`;读不懂(坏 JSON / 坏形 / 读不出)从不读成确认(每份内容每进程一行 warn `config_env_models_unreadable`)。
|
|
195
|
+
— **升级时自动做的**:本版第一次起服(读本地配置之前、目录信任判官之后)在每个本地配置根上跑一次契约包的迁移:独占创建运行记录 `<配置根>/config.migration.SS-M11.json`;决定缺席且 `config.d/models.json` 此刻管模型面 ⇒
|
|
196
|
+
铸 `{"envModels":"replaced"}` —— 升级前「目录顶替 env 表」的读法原样保住:info `config_dir_migrated` 记一条收据,env 模型已声明时再一行 warn `config_env_models_replaced_by_migration` 点名从此被顶替的 env 模型。
|
|
197
|
+
根不在 ⇒ 以 `0700` 建出(只放运行记录,不建 `config.d`)。运行记录在场之后迁移不再跑,决定缺席就是 `kept`。
|
|
198
|
+
— **升级后要动手的几形**:① 升级时还没有管模型面的目录、之后才写下第一份的根(含新装):这份目录的模型面被拒 ——
|
|
199
|
+
`/health.modelRefusals.plane` = `config.catalog_replaces_env_models`,`GET /v1/models.modelPlane` = `{ "servedTable": "env", "catalog": "refused", "planeRefusalCode": "config.catalog_replaces_env_models" }`,warn `web_admin_model_plane_refused` 点名路径与出路;
|
|
200
|
+
env 模型继续服务,同一份目录的其余配置照落。要让目录顶替 env 表:写 `config.env-models.json` = `{"envModels":"replaced"}`(下一个刷新拍或 `POST /v1/admin/config/refresh` 生效,不用重启),或撤掉 `MODEL_ID` / `MODEL_CHEAP_ID`。
|
|
201
|
+
② 升级时 `models.json` 读不出(权限 / I/O)或确认写不成:warn `config_env_models_mint_failed` 带手工恢复句,之后同 ① 处置。③ 只读配置根:运行记录建不成 ⇒ 不铸,每次起服重跑、每进程一行 warn `config_dir_migration_failed`;手写的决定照常生效。
|
|
202
|
+
④ 运行记录读不懂 ⇒ warn `config_env_models_marker_unreadable`,按已跑处置。
|
|
203
|
+
— **撤销**:要回到 env 模型,删掉决定文件或写 `{"envModels":"kept"}`,再**重启**:运行中的进程在下一个刷新拍对目录判组拒(`planeRefusalCode` 在场),但组拒不降档 —— 在服的那一代目录照旧服务,env 模型在下一次起服才回来。删掉运行记录再起服 ⇒ 迁移重跑,决定缺席即重铸。
|
|
204
|
+
— **目录信任**:根上这两份文档与 `config.d` 下的文档同一套判据(属主只能是本服务的用户 / root / `CONFIG_LOCAL_OWNER_UID`,不得组 / 他人可写,常规文件,≤ 16 MiB),不过 ⇒ 拒启 `[config.dir_untrusted]`;`config.d` 缺席时也判到根。手写决定文件后核一下模式位(`chmod go-w`)。
|
|
205
|
+
— **跳版**:迁移随契约包下一个大版本删除;在那之后才第一次升到本系列的根没有迁移替它铸确认,管模型面的目录被拒,按 ① 处置。
|
|
206
|
+
— **回滚**:回到上一版 ⇒ 决定文件与运行记录不被读(目录照旧整表顶替 env 表);两份文件留在盘上,再升回本版照读。
|
|
207
|
+
**谁需要**:同一个本地配置根上既声明 env 模型、又放目录的部署(目录顶不顶替 env 模型由盘上一份文件说)。**谁受伤**:如上 ① – ③。**出路**:如上。
|
|
208
|
+
|
|
209
|
+
3. **`GET /v1/models.modelPlane` 加性键 `planeRefusalCode`;`catalog: "refused"` 的模型面那一半改读最新到达的候选(wire 加性;wire 值语义收窄;部署零动作)**:
|
|
210
|
+
`planeRefusalCode` 在场 ⇔ 最新到达的目录候选被模型面组拒,值 = 那一拒的码(契约包 `MODEL_PLANE_REFUSAL_CODES` 之一);`catalog: "refused"` 而本键缺席 ⇔ 最新到达的候选被候选判官整拒(看同一应答的 `candidateRejected`)。
|
|
211
|
+
此前 `catalog` 的模型面那一半读 `/health.modelRefusals.plane`:更新的候选到了而没走到模型面那一判(被候选判官整拒,或过了判官、却在换装时被拒)时,旧候选的组拒仍让 `catalog` 答 `refused`;
|
|
212
|
+
本版起这一形改按在服的表答(`adopted` / `absent`),那一份换装失败只在 `/health` 的世代账(target ≠ applied)里看得见(与「装配期被引擎整份拒收」同一形,本版仍没有座)。`/health.modelRefusals.plane` 的读法不变(最近一份被判过的模型面的组拒判决,不随更新的到达撤)。
|
|
213
|
+
同一只路由判官的码可能同时出现在 `planeRefusalCode` 与 `refusalCode`:前者指最新到达的候选目录,后者指此刻在服的那张表。
|
|
214
|
+
**谁需要**:读 `modelPlane` 判「刚写 / 刚发布的目录为什么没落」的壳与控制台。**谁受伤**:把 `catalog: "refused"` 读成「上一份被拒的目录还挂着」的消费方。
|
|
215
|
+
**出路**:用 `planeRefusalCode` 与 `candidateRejected` 分两种拒;要问「最新候选落没落」读世代账。**升级前做**:无;**回滚**:键消失,`catalog` 回到旧读法。
|
|
216
|
+
|
|
217
|
+
4. **leader 路由腿:没有 `MODEL_ROUTER_ID` 时在服务表里解 `classifier` 角色(classifier → summarize → default),不再钉 `MODEL_CHEAP_ID` 的名;目录采纳后悬空的 env 角色绑定每名一行 warn(行为面;运维面日志加性;部署零动作或目录里一行绑定)**:
|
|
218
|
+
纯 env 部署:路由腿仍跑在 `MODEL_CHEAP_ID` 的模型上(env cheap 槽绑 `summarize`),没有 cheap 槽仍跑主模型 —— 零变化。采纳了目录的 leader 部署:路由腿跑目录自己的 `classifier` 绑定,没有就 `summarize`,都没有就目录缺省(此前钉的 env cheap 名不在目录表里)。
|
|
219
|
+
要路由跑便宜模型:在目录 `roles` 里把 `classifier`(或 `summarize`)绑到一条便宜条目、激活 `flash` 档,或设 `MODEL_ROUTER_ID=<目录条目名>`(按名在服务表里解,与此前同)。
|
|
220
|
+
leader 的每一只 Runner(修复 / 路由 / worker 腿)从本版起带档位表,角色在档位展开的视图里解,与主 runner 同答:激活了档位的部署上,worker 腿里按档位缺省解的角色(委派子代 / 压缩)从此解到档位绑定的条目(此前落到缺省模型)。
|
|
221
|
+
同版:目录的模型面落地时,env 角色底里目录没覆写的角色(`MODEL_CHEAP_ID` 绑的 `subagent` / `summarize`)绑的名不在这份目录(档位展开后)里 ⇒ 每个名每进程一行 warn `config_env_role_binding_dangling { model, env, roles, engineNotice: "model.role_defaulted" }`;
|
|
222
|
+
选模不变(引擎读作未设、沿角色链回落,每个任务一条 `model.role_defaulted`)。出路同上:在目录里绑这些角色,或让目录里有一条叫这个名的条目。**回滚**:路由腿回到 `MODEL_ROUTER_ID || MODEL_CHEAP_ID`,warn 行消失。
|
|
223
|
+
**谁需要**:采纳了目录的 leader 部署 —— 路由腿跑在这份目录里真有的条目上(此前钉的 env cheap 名不在目录表里);运维在目录落地那一刻读到哪一条 env 角色绑定悬空,而不是只在每个任务的 `model.role_defaulted` 里零散读到。
|
|
224
|
+
**谁受伤**:采纳了目录、目录里既没绑 `classifier` 也没绑 `summarize`、又没激活 `flash` 档、却指望路由腿跑 `MODEL_CHEAP_ID` 那只便宜模型的 leader 部署 —— 路由腿改跑目录缺省模型;激活了档位的 leader 部署 —— worker 腿里按档位缺省解的角色改解到档位绑定的条目。
|
|
225
|
+
**补偿**:在目录 `roles` 里绑 `classifier`(或 `summarize`),或设 `MODEL_ROUTER_ID=<目录条目名>`;warn 行点名悬空的名与它绑的角色。
|
|
226
|
+
|
|
227
|
+
5. **🔴 部署治理的装配相容性门改在部署 MCP 服务器 / A2A 对端物化之后判:`LOCKED_CONFIG_KEYS` 的 `mcp` / `a2a` 锁、合规否决 `mcp_servers` / `a2a_peers`,撞上部署自带的服务器 / 对端(`config.d/mcp.json` 或中心下发)⇒ 起服拒(行为收紧,fail-closed;部署面;落在这四形里的部署要动手)**:
|
|
228
|
+
— **此前**:USAGE「部署治理三声明」写明的两形启动期拒 —— `LOCKED_CONFIG_KEYS=mcp` + 部署自己配了 MCP 服务器、合规档位禁 `mcp_servers` + 部署自己配了 MCP 服务器 —— 在 HTTP 服务上从未发生:
|
|
229
|
+
判据在部署 MCP 基线读进来之前就跑完了,于是这两形照常起服,而每条任务在引擎门口被拒 —— 锁形答 `400 config.locked_key`(不带 `mcpServers` 的任务也一样),否决形落 `200` 失败体(`config.compliance_denied`),部署自带的服务器零拨号。
|
|
230
|
+
同族的 `LOCKED_CONFIG_KEYS=a2a` / 否决 `a2a_peers` + 中心下发的 A2A 对端同样只在任务腿上撞拒(判据此前不看这两项)。`run-local` / `sema` 的 MCP 两形早已在启动时拒(零变化)。
|
|
231
|
+
— **本版**:四形都在起服时拒(进程退出码 1;句子点名那把锁 / 那条否决与两条出路),与 `toolPolicy` 锁、单用户形禁 `web_fetch` 同一只判据、同一个出口。判据的时点挪到部署基线物化之后:`toolPolicy` 锁与单用户禁 `web_fetch` 两形照旧拒启,
|
|
232
|
+
只是拒的那一刻在起服序列里稍晚(仍早于场景装配、reaper 与 HTTP 监听)。`enabled: false` 的条目、引用的 env 名在本服务上缺席而被跳过的条目不算「配了」。
|
|
233
|
+
— **升级前做**:落在四形里的部署二选一 —— 去掉锁 / 否决(`LOCKED_CONFIG_KEYS` 里删 `mcp` / `a2a`,`COMPLIANCE_ADDITIONAL_DENIES` 里删 `mcp_servers` / `a2a_peers`),或去掉部署自带的服务器 / 对端(`config.d/mcp.json` 的条目、中心 `mcp` / `a2a` 域的条目)。
|
|
234
|
+
中心侧之后再加服务器 / 对端仍是 restart-to-apply:落进这四形的那一次变更让滚动重启的新副本起服拒(旧副本照跑),出路同上。
|
|
235
|
+
**谁需要**:配了锁或合规档位的部署 —— 配错的组合在起服时点名,而不是起得来、任务全失败。**谁受伤**:落在四形里、服务器 / 对端只挂在某几个场景上、其余场景的任务今天照常服务的部署 —— 升级后整台起不来。
|
|
236
|
+
**出路**:同「升级前做」;要锁住请求自带的 MCP / A2A 而保留部署自带的,本服务没有这一形(引擎的锁守的是同一个字段)。**回滚**:HTTP 服务回到上一版 ⇒ 四形照旧起服、任务腿照旧撞拒(`run-local` / `sema` 上 MCP 两形在上一版就拒启,回滚不改)。
|
|
237
|
+
|
|
238
|
+
6. **🔴 运维审批队列的行带族名 `kind`(闭集 `checkpoint` | `peer_inbound`);被扣下、等收信方审的跨会话来信作 `peer_inbound` 行进 `GET /v1/approvals` 的 `pending[]` 与 `/v1/approvals/stream`,经同一决断口 `POST /v1/approvals/:id/decide` 批 / 拒(wire 加性;🔴 按「每一行都是停驻门」写死的消费方要先按 `kind` 分支;部署零动作)**:
|
|
239
|
+
`pending[]` 的每一行与流上的 `pending` / `resolved` 帧从本版起带 `kind`:停驻门的行 `kind: "checkpoint"`,其余键与上一版逐字同;新族 `peer_inbound` = 收信会话的权限档对等判扣下的跨会话来信
|
|
240
|
+
(发信方的权限档与收信方对不上,成因 `mode-mismatch` / `no-mode-asserted` / `invalid-mode-attestation`),行键 `id` / `recipientSessionId` / `lane` / `cause` / `content` / `sentAt` / `heldAt` / `fromSession?` / `fromName?` / `fromScope?`,**没有** `sessionId` / `toolCallId` / `riskDescriptor` / `deadline`。
|
|
241
|
+
决断口 `:id` = 行的 `id`(`peer_inbound:` 前缀,不透明),体只收 `{ decision: "approve" | "deny" }`(其余键 400 点名拒),答 `200 { kind, id, outcome }` / `404 not_found.approval` / `503 state.peer_decision_unrecorded`(新码,可重试)。
|
|
242
|
+
`resolved` 帧按族:`checkpoint` 族带 `sessionId` + `toolCallId`(同上一版,另加 `kind`),`peer_inbound` 族带 `id`。`synced.count` 数 `pending` 车道全部行(两族同计)。
|
|
243
|
+
部署策略扣下的信(`CROSS_SESSION_INBOUND=hold`)**不进**审批席(组织策略不由收信方逐封越过);只有收信方本人列得出、决得了(operator 不多看)。行是**本副本**进程内投影(跨副本看不到,同 `livePending`);有序关停把仍被扣的信以 `expired` 结清并回执发信方。
|
|
244
|
+
**谁需要**:用跨会话通信、收发两方权限档会不一致的部署 —— 此前被扣的信只能等到期,收信方没有任何面能放行或拒绝。
|
|
245
|
+
**谁受伤**:按 `pending[]` 每一行都是停驻门写死的消费方(读 `row.sessionId` 去 `/decide`、读 `riskDescriptor`、按 `(sessionId, toolCallId)` 消 `resolved`)—— 一行 `peer_inbound` 到来时读到缺席。
|
|
246
|
+
**出路**:先按 `kind` 分支;不认识的 `kind` 跳过该行、不要拿它去 `/decide`(契约 §0.11)。**升级前做**:无;**回滚**:`kind` 键与 `peer_inbound` 行消失,被扣的信回到只能等到期。
|
|
247
|
+
|
|
248
|
+
7. **k8s 车道:停驻时沙箱从未起过(什么都没打包)的停驻,续跑改作一次新连接 —— 空间开着就等上一条提交、按 `latest` 恢复;打包过的停驻快照对象不在 ⇒ 一行 `workspace_latest_dangling`(`lane: "park"`)+ 空目录;更正 7.142.0 节第 9 条尾的「已知限制」(行为修复;运维面日志加性;部署零动作)**:
|
|
249
|
+
此前:run 在首次碰到沙箱之前就停驻(pod 还没起)⇒ 停驻快照 id 下没有对象;续跑走停驻车道、取包得 404,读作「空快照」⇒ 新 pod 上的空目录,不读空间的 `latest`。
|
|
250
|
+
空间开着(`WORKSPACE_PERSIST=space`,缺省)时这条腿的 run 末提交随后覆写 `latest` ⇒ 此前各条 run 的改动从下一条 run 起不在了,且不报警。
|
|
251
|
+
同一个 404 也是「打包过的停驻快照被桶的生命周期规则 / 手工删掉」的读数 —— 两件事一样静默。
|
|
252
|
+
现在:停驻快照 id 自己说清打包没打包 —— `kata-<记号>-…` = 打包过(此前铸下的 id 都是这一族);`nopack-<记号>-…` = 停驻时没有 pod、什么都没打包,桶里从不放对象。
|
|
253
|
+
— `nopack-…` 的续跑 = 一次新连接(与 run 首次碰沙箱同一条走法),这种 id 下不发任何取包请求:空间开 ⇒ 等上一条提交落定、读 `latest`,在 ⇒ 恢复(不播种),不在 ⇒ 空目录(播种);
|
|
254
|
+
空间关 ⇒ 空目录(播种,同此前);没有这只会话 ⇒ 空目录 + 一行 `workspace_space_unavailable`(此前续跑不出这行);读住客 / 提交围栏 / `latest` 失败 ⇒ 续跑 `connect_failed`(与连接同句,引擎按续跑重试)。
|
|
255
|
+
— `kata-…` 的续跑照旧取包;对象不在 ⇒ 一行 `workspace_latest_dangling`(`lane: "park"` / `key` / `sessionId` / `effect`),与空间 `latest` 悬空同一行名、同一条规则(响亮、可继续),这条腿从空目录开始(播种);
|
|
256
|
+
空间开着时它的 run 末提交成为新的 `latest`。空间那一臂的同一行多一个字段 `lane: "space"`(其余字段不变)。
|
|
257
|
+
**升级窗**:升级之前铸下的停驻 id 都是 `kata-…` 形(那时还不区分):升级时仍停驻着、而停驻前 pod 还没起的 run,续跑读到的是「打包过、对象不在」⇒ 一行 `workspace_latest_dangling`(`lane: "park"`)+ 空目录 ——
|
|
258
|
+
工作区与此前同,多一行;空间开着时它的 run 末提交仍覆写 `latest`(只这一窗;升级之后的停驻不再如此)。
|
|
259
|
+
**谁需要**:k8s 车道上空间开着、用耐久审批(停驻 → 续跑)的会话 —— 在首次碰沙箱之前就停驻的 run(首个工具就要审批、计划审阅)续跑后看得到此前各条 run 的文件,run 末提交不再把它们冲掉;想看见停驻快照被清走的运维。
|
|
260
|
+
**谁受伤**:按 `workspace_latest_dangling` 告警的运维:停驻快照的悬空也报这一行;升级窗里停驻着的那几条 run 续跑时各报一行(见上)。
|
|
261
|
+
**出路**:告警按 `lane` 分两类;升级窗那几行按 `key` 里的会话 id 对账即可。**回滚**:回到上一版 ⇒ `nopack-…` 的停驻在旧二进制上续跑取包得 404 ⇒ 旧形(空目录、不报警);`kata-…` 不受影响。
|
|
262
|
+
**更正(7.142.0 节第 9 条尾,文书)**:那一条的「已知限制」—— 空间开着时停驻在先、续跑不恢复 `latest`、run 末提交覆写此前改动且不报警 —— 自本版起不再成立(本条即其修法);7.142.0 节原文不改(已发节字节不动)。
|
|
263
|
+
|
|
264
|
+
8. **更正(7.141.0 节第 1 条「谁受伤」,文书;零行为变化)**:该条说起服自有凭据值被引擎拒收「此前是一行裸 stderr 文本,现在是日志器的一行 `warn` `own_credential_value_not_withheld { name, reason }`」—— 说的是**本服务自己**写的那一行,这一半不改。没写全的是另两件事(亲读:真主进程起服,7.141.0 标签与本版读数同形):
|
|
265
|
+
① **网关密钥**(`MODEL_API_KEY` / `ANTHROPIC_API_KEY`,起服交给模型适配器的那一个)被引擎判「不是凭据值」(占位词 / 不足 8 字符 / 一个字符重复)时,进程输出里除这一行结构化 `warn`,**还有一行引擎写的裸文本**:
|
|
266
|
+
`a credential the engine was handed is … — it is used as given, but a variable holding the same string is not withheld from a spawned child (said once per value; the value is not repeated)`。
|
|
267
|
+
引擎在适配器构造口收下网关密钥的那一刻对同一个值「每进程每值说一次」,而这个收值口没有通告席(适配器的配置没有通告位),引擎落它自己的 `console.warn` —— 引擎文档把这一形列为已知限制(无席的收值口共四个:适配器构造 / 请求路由读 / 对端拨号 / 直建蒸馏座)。
|
|
268
|
+
本服务不是这一行的写者、也无席可接,不在引擎外面吞 `console`;引擎不收的自有凭据变量(例如 `SERVICE_AUTH_TOKEN`,本版真主进程读数)被拒时只有结构化那一行。两行说的是同一个值同一件事,都不带值;本服务这一行点名变量,引擎那一行只说哪一类。
|
|
269
|
+
② 结构化行走日志器:起服第一步(日志器未建)的那一行当拍写 stderr,不受 `LOG_LEVEL` 约束;日志器接上之后(模型目录换代并进的条目的值被拒)受 `LOG_LEVEL` 约束 —— `error` 级读不到,而此前的裸 `console.warn` 无条件出。
|
|
270
|
+
**谁需要**:读这件事告警的运维。**谁受伤**:① 以为 7.141.0 之后这件事在 stderr 里只剩 JSON 行的日志管线 / 告警规则(把「不是 JSON 的行」当异常、或按行解析 stderr 的)—— 网关密钥是占位词时仍会读到引擎那一行(7.141.0 与本版同形,不是新回归);② `LOG_LEVEL=error` 的部署:换代并进条目的值被拒那一行读不到。
|
|
271
|
+
**补偿**:给网关密钥一个真值(至少 8 字符、不是占位词)—— 引擎与本服务的两行一起消失;按事件名 `own_credential_value_not_withheld` 与字段 `name` 筛本服务的行;机读事实读 `GET /v1/capabilities` 的 `inherit_env.own_credential_values_withheld`(一个值没按值扣 ⇒ false,不随日志级走);`LOG_LEVEL` 至少 `warn`。
|
|
272
|
+
引擎一侧那一行等引擎给收值口一席、或让声明口拒收的值记作已说,本服务再接;在此之前它是引擎的,本版不改。7.141.0 节原文不改(已发节字节不动)。
|
|
273
|
+
|
|
274
|
+
9. **🔴 SQL 后端:`task_attachment` 加一列生成列 `seed_session_id` 与唯一索引 `uq_att_seed` ——「一只会话一只种子」改由表上的唯一键判;已有种子的会话上的并发提交恒答 `409 attachment.bundle_seed_fixed`,不再撞死锁 / 锁等待成店错(行为修复;DDL:升级前先加列,先升库再升副本;wire 零变化;订正 7.142.0 节第 10 条的「已知限制」)**:
|
|
275
|
+
— **此前**:SQL 两方言判「这只会话有没有种子」用的是一只事务里的锚读:按 id 序加锁读全部未绑的项目包与本会话的项目包,再加锁读这只包自己的行。两只并发事务的取锁序可以反向,引擎挑一只输家回滚,
|
|
276
|
+
店最多重来 4 次,被反复挑中的那只把店错抛给调用方(PG `40P01`);任何一只未绑的项目包(不论哪个会话、哪个属主)被别的事务长时间锁住时,项目包绑定在锁等待上限处答店错(MySQL 协议 `1205`、PG `55P03`)。
|
|
277
|
+
— **本版**:每一行的绑定都是同一条带谓词的 `UPDATE`;「一只会话一只种子」是表上的唯一键 —— 生成列 `seed_session_id` = 项目包行的 `session_id`(其余行 NULL;库从 `mime` 与 `session_id` 推导,本服务不写它),
|
|
278
|
+
唯一索引 `uq_att_seed` 在它上面,第二只项目包的绑定被库以唯一键冲突拒,答 `409 attachment.bundle_seed_fixed`。一次绑定只碰要绑的行与这只会话在唯一键上的那一个值:已有种子的会话上的提交不等别的会话 / 别的属主的行即答 409(只在这只会话自己的种子行正被别的事务写着时排在那只写者之后);
|
|
279
|
+
无种子会话的两次并发首绑恰一只绑上(与 7.142.0 的契约同)。local 后端零变化。
|
|
280
|
+
— **升级前做(`DB_BACKEND=mysql|pg`)**:先在库上加列 —— 没加就起服 ⇒ 列册对账拒启 `config.schema_mismatch`,拒句逐字打印同一句:
|
|
281
|
+
MySQL 协议(TiDB / MySQL)`ALTER TABLE task_attachment ADD COLUMN seed_session_id VARCHAR(190) GENERATED ALWAYS AS (CASE WHEN mime = 'application/vnd.sema.project-bundle' THEN session_id END) VIRTUAL;`;PostgreSQL `ALTER TABLE task_attachment ADD COLUMN seed_session_id VARCHAR(190) COLLATE "C" GENERATED ALWAYS AS (CASE WHEN mime = 'application/vnd.sema.project-bundle' THEN session_id END) STORED;`
|
|
282
|
+
唯一索引 `uq_att_seed` 由本版起服时自己补建(MySQL 协议在线 `ADD UNIQUE INDEX`;PG `CREATE UNIQUE INDEX CONCURRENTLY`)。存量行不迁移:列由库从已有两列算出;7.142.0 的店已保证一只会话至多一只项目包,存量行不撞这只唯一键。
|
|
283
|
+
先升库、再升副本:加了列的库上,重启的旧副本被列册对账判成「库比代码新」而拒启;还在跑的旧副本照常服务(它的写同样受唯一键约束 —— 与新副本并发绑第二只项目包的那一窄形,旧副本答店错而不是 409)。
|
|
284
|
+
**谁需要**:SQL 后端上用项目包的会话 —— 并发提交(壳重试、多端同时续)不再偶发店错。**谁受伤**:SQL 后端的部署者:升级前多一句 DDL(PG 的 `STORED` 生成列加列时重写整表;MySQL 协议的 `VIRTUAL` 不重写)。
|
|
285
|
+
**出路**:同「升级前做」。**回滚**:先停光本版的全部副本(唯一键是本版判「一只会话一只种子」的唯一判官:删索引时还在服务的本版副本会让同一会话并发绑上两只项目包),再删索引、删列(否则旧版起服拒启:库比代码新),再起 7.142.x —— MySQL 协议 `ALTER TABLE task_attachment DROP INDEX uq_att_seed;` 再 `ALTER TABLE task_attachment DROP COLUMN seed_session_id;`;
|
|
286
|
+
PG `DROP INDEX IF EXISTS uq_att_seed;` 再 `ALTER TABLE task_attachment DROP COLUMN seed_session_id;`。删列不动任何一行的绑定。
|
|
287
|
+
|
|
288
|
+
10. **续跑请求可重述对端表:`/decide` · `plan_review` · `/resume` · `/wake` 的请求体收提交体同键的 `mcpServers` / `a2aPeers`(wire 加性;行为面;部署零动作)**:
|
|
289
|
+
— **本版**:键在场(不是 `null`)⇒ 这张表取代停驻任务存下的提交体里的同名表(本次续跑读它,续跑受理后随续跑输入写回,之后不送的续跑重放的也是它);值形与 `POST /v1/tasks` 同一只判官(坏形同码同句 400)。
|
|
290
|
+
键缺席或 `null` ⇒ 冻结读法:重放提交时存下的表(与上一版逐字同)。两键各自独立;空数组是一张空表,不是缺席。
|
|
291
|
+
— **任务停在一只 MCP 调用上、目标台不在送去的表里**:由引擎判,本服务不判 —— 引擎 7.61.0 起三码各答各形,以 core 为准:那只工具不在了 ⇒ `resume.tool_unavailable`(引擎重开检查点:卡仍 pending、可再决);同名而已不是批准时那一只 ⇒ `resume.tool_contract_mismatch`(同样重开);还是那一只而它的面或声明变了 ⇒ `resume.target_moved`(这次调用不执行、批准用掉,须重新发起),本服务逐字过境。出路:把那一台加回表再决,或取消这条 run。
|
|
292
|
+
— **`/resume` 现在读体**:无体照旧;体不是 JSON ⇒ `400 request.invalid_json`(上一版不读体)。**直连门部署**:`/decide` / `plan_review` 送这两键 ⇒ `400 restatement_not_in_proof`(不论值),不送即可。
|
|
293
|
+
— **不读重述的路**:SLA 到期拒扫、live 卡答复口的停驻赎回(没有调用方送来的表)。`/decide` 命中停驻后台子代的卡 ⇒ `400 decide.parked_restatement_unsupported`
|
|
294
|
+
(子代复活的是它停驻时的那一份,表无处可盖;卡仍 pending)—— 去掉这两键再决。workflow 出身的卡:投递那一跑还活着时同一决定换一张表重投 ⇒ `409 conflict.session_active_run`(不再答首投回执)。
|
|
295
|
+
**谁需要**:任务停着期间移除过自己 MCP 服务器 / A2A 对端的用户(例如 `sema mcp remove` 之后续跑,不让它被重连)和替他们续跑的壳。
|
|
296
|
+
**谁受伤**:不送当前表的壳 —— 续跑仍按提交时的表重连(含已删的台),本服务不替它判、不预拒(本条如实披露);每次都送表的壳在停驻后台子代的卡上得 400,要去掉两键再决(见上)。
|
|
297
|
+
**补偿**:壳在**每次**续跑送它此刻的整张表(MCP 与 A2A 各一张);写回失败时(运维面 warn + `resume_ctx_not_persisted_total`)这一跑照用送来的表,之后一次不送的续跑回到上一张 —— 每次都送就没有这一形。
|
|
298
|
+
**升级前做**:无。**回滚**:回到上一版 ⇒ `/decide` / `plan_review` 送这两键得 `400`,`/resume` / `/wake` 忽略它们;已经写回的表留在续跑输入里,照常重放。
|
|
299
|
+
|
|
300
|
+
11. **🔴 活流模型文本过同一只脱敏器:`text_delta` / `reasoning_delta` 逐块帧只放脱敏器已判定的字节,一段的拼接 = 段末帧正文;段末余下的字节在段末帧之前一帧补齐(wire 值语义;安全;部署零动作)**:
|
|
301
|
+
— **本版**:`POST /v1/tasks/stream`(顶层与转发子代腿)与 `GET /v1/runs/:id/subagents/:handle/stream` 上,模型文本的逐块帧经与 `done` / 账本 / `text_end` / `reasoning_end` **同一只**自由文本脱敏器放行:
|
|
302
|
+
服务端按流身份把每段喂进脱敏器的流式口,只放它已判定的字节 —— 末尾那一截(脱敏器的未决尾:本版至多 202 个读法单元,外加一个重扫步长)等更多字节到了再判。含凭据形的段,活流拼接出来的字节与该段的 `text_end.content` / `reasoning_end.content` 相同(凭据是记号,不再是明文);
|
|
303
|
+
文字段的单位是引擎的文字块(与 `text_end` 同),账本 `text` 行按 turn 拼接后再判 —— 一条凭据的锚与值分落在同一 turn 的两个文字块里时,账本行遮、`text_end` 与活流不遮(此前 `text_end` 上就是这样);
|
|
304
|
+
不含凭据形的段逐字节不变,只是分帧变了。
|
|
305
|
+
— **帧怎么变**:core 的每一块仍恰出一帧、同一枚 `eventId`、原序,但 `delta` 可以是 `""`(这一块的字节还在窗里);段末还有没放出的字节 ⇒ 紧贴段末帧之前多一帧 `text_delta` / `reasoning_delta`,
|
|
306
|
+
**不带 `eventId`**(因而不发 `id:` 行),身份三键(`parentToolCallId` / `sourceTaskId` / `bgAgentId`)随行。转发子代腿与 tail 面的逐块帧此后也带上 core 给的 `sourceTaskId` / `bgAgentId`(加性)。
|
|
307
|
+
— **延迟**:一个字节在它之后又到了未决尾上界(本版 202 个读法单元,由脱敏器的臂表读出:各臂判定距离的最大值)之后的下一次重扫时出门(重扫步长 = max(64, 段长 / 32) 个码元);
|
|
308
|
+
落在还没判定完的凭据形(PEM 栅栏、没收尾的 JSON 串值 / URL userinfo、带引号的值)里的那一截等判定或段末。不到上界的短段在段末一次出。
|
|
309
|
+
— **tail 面半路订阅**:订阅者在一段中途开始听,从此刻起收逐块帧,判定仍按整段上下文;它收到的 `reasoning_end` 是整段(此前只覆盖它开始听之后的那一截)。
|
|
310
|
+
**谁需要**:读活流的 API 消费方与渲染端 —— 此前一条凭据在 `done` 上是记号、在活流上是明文。
|
|
311
|
+
**谁受伤**:① 拿活流逐块原文做 diff / 校验和、或拿它当「模型原文」存档的消费方(含凭据形的段字节变了);② 假设每个 `text_delta` 都带 `eventId`、或每帧 `delta` 非空的消费方;③ 对首字延迟敏感的渲染端。
|
|
312
|
+
**补偿**:① 要的是一段的定稿 ⇒ 读 `text_end` / `reasoning_end` / `done`(与活流拼接同一份字节),或经 `GET /v1/runs/:id/events` 回放;② 空 `delta` 照常拼接,余下那一帧按身份三键归并,续流游标沿用上一枚 `id:`;
|
|
313
|
+
③ 延迟上界是脱敏器的未决尾上界(本版 202 单元)加段长的 1/32,散文在头 202 单元之后按步长连续流出。
|
|
314
|
+
**升级前做**:无。**回滚**:回到上一版 ⇒ `text_delta` 逐块原样、`reasoning_delta` 逐块各自脱敏(跨块的凭据形在活流上露出);落盘数据不受影响。
|
|
315
|
+
|
|
316
|
+
12. **会话读面对「属主读不出」的会话答 404,不再是 500 `corrupt_session`(行为面:一个应答格的状态变了;运维面日志加性;零新码;部署零动作)**:
|
|
317
|
+
— **哪一形**:文件后端(`DB_BACKEND=local`)上,会话的行事实(属主 / 化身)只住在会话元数据边档的那一格;7.104.0 之前写下、此后从没被读过的会话没有这一格,要从存档补铸它,存档又读不出(会话头坏 / 截在会话头里 / 日志结构走不通)
|
|
318
|
+
⇒ 这只会话没有可读的属主。SQL 后端的会话行就是 `session_meta` 那一行,没有这一形。
|
|
319
|
+
— **本版**:`GET /v1/sessions/:id` · `GET …/memory-status` · `POST …/memory/erase` · `GET …/head` · `GET …/events` · `GET …/execution-placement` 对这一形答 404 `not_found.session`,体与「没有这只会话」逐字同,带着身份的谁来读都一样(此前 500 + 原故障的码 `corrupt_session` / `invalid_session`,
|
|
320
|
+
读者拿得到「这个 id 在盘上、且坏了」)。原故障(码与句)进运维日志一行 warn `session_owner_unreadable`,字段 `{ face, sessionId, errorCode, err }`(`errorCode` = 此前这一读答的码)。
|
|
321
|
+
— **没动**:边档有格而存档读不出的会话(属主可判)—— 非属主 404、属主照旧 500(原故障的码;执行放置口读的是行格、不读存档内容,属主 200);I/O 级读故障(说不出在不在)与别的读故障照旧 500;改名 · 分叉 · 删除 · 规则 · 后台任务 · 通知 · MCP 重连 ·
|
|
322
|
+
会话同步各口 · 提交三口对这一形仍答原故障的 500;没有身份边界的部署上同一形同样 404。
|
|
323
|
+
**谁需要**:带身份边界的文件后端部署的 API 消费方与运维 —— 读面对别人的会话、对属主读不出的会话、对不存在的会话是同一句话。
|
|
324
|
+
**谁受伤**:① 把读面的 500 当「服务错」告警、或拿读面的 `corrupt_session` 判「这只会话存档坏了」的运维 / 监控 / 壳(这一形现在与「没有这只会话」不可区分);② 本来就依赖「读面 500 ⇒ 去查盘」的手工流程。
|
|
325
|
+
**补偿**:按运维日志行 `session_owner_unreadable` 告警与定位(它带会话 id 与原码);这一形本来就不在会话列表里;要修就把它的存档文件(数据根 `sessions/` 目录下)从留存副本恢复 —— 恢复后第一次读会补铸行事实,读面随之恢复。
|
|
326
|
+
**升级前做**:无。**回滚**:回到上一版 ⇒ 读面对这一形重新答 500 + 原故障的码(`corrupt_session` / `invalid_session`);落盘数据不受影响。
|
|
327
|
+
|
|
328
|
+
13. **中心 MCP 声明撞同一工具命名空间前缀:同步提交腿从 `200` + `failed` 体改 `409 config.mcp_server_name_collision`;`GET /v1/capabilities/mcp` 从无码 `500 internal.error` 改同码、同状态、同句(wire 码与状态变;部署零动作)**:
|
|
329
|
+
— **本版**:部署声明的 MCP 服务器里,两台的名字归一后(引擎铸工具名只留 `[a-zA-Z0-9_-]`,其余换成 `_`)同挂一个工具命名空间前缀 —— `my.srv` / `my_srv` 同挂 `mcp__my_srv__` —— 引擎在任何传输被触碰之前把整份声明集拒掉(码 `config.mcp_server_name_collision`,句子点名两个原拼写、指路改名)。
|
|
330
|
+
同一份声明集上,两个面现在读**同一张**「引擎拒码 → 状态」表:`POST /v1/tasks`(同步腿)答 `409`,体 `{ error, errorCode }`;`GET /v1/capabilities/mcp` 答 `409`,同体、同码、同句(句子里若有凭据形的拼写,两面都盖住、不外露,只是记号写法不同)。
|
|
331
|
+
此前:同步腿 `200` + `terminal.failed`(码与整句在终局体里);读面 `500 internal.error` 无码。
|
|
332
|
+
— **不变**:异步 `POST /v1/runs` 与流式腿 HTTP 2xx,同码落终态 run 行;`POST /v1/capabilities/mcp/probe` 自带申报那一口,同一份坏申报仍是 `400 request.field_invalid`(因由不回显);逐字同名的中心声明被配置包的 `mcp` 域在候选判官那一拍整份拒(`config_candidate_rejected`;整份候选不采纳,读面继续答在服的那一份中心声明,没有更早的在服配置就是 `servers: []`),不经引擎。
|
|
333
|
+
**谁需要**:中心(或 `config.d/mcp.json`)里配了 MCP 声明、其中有归一后同前缀的部署:运维与壳的 `mcp list` 在读面上读到原因,而不是无码 `500`;按 HTTP 状态分支的提交方不再把挂不起来的声明集读成一次成功的 `200`。声明集的另一个来源 —— 单用户部署上请求自带的 `mcpServers` —— 里归一后同前缀的两条,同步腿同样答这个码这个状态(一个码一个状态,不分来源)。
|
|
334
|
+
**谁受伤**:① 在这类部署上(或自带了撞前缀的 `mcpServers`)调同步 `POST /v1/tasks`、按 `200` 走成功路径再读 `terminal` 的调用方:现在拿到 `409` 与 `{ error, errorCode }`,没有 `terminal`(该部署每一次提交本来就失败,只是状态换了);② 把读面 `500` 当「服务坏了」做重试或告警的探活:现在 `409`,重试不改判。
|
|
335
|
+
**补偿**:一律按 `errorCode` 分支(两个面同码);出路在运维手里 —— 改中心声明里的名字,让归一后各不相同(拒句点名两个原拼写)。配置坏的部署读面另落一条 warn `mcp_status_face_declaration_refused { code, error }`。
|
|
336
|
+
**升级前做**:无(声明集里没有归一后同前缀的两台的部署零变化)。**回滚**:回到上一版 ⇒ 同步腿 `200` + `failed` 体、读面无码 `500`;落盘数据不受影响。
|
|
337
|
+
|
|
338
|
+
14. **🔴 持久 ask 店车道:askId 的身份含这一问展示给人的动作(工具名 + 入参摘要)—— 同一 run 同一腿里,模型在后一次回复中复用了前一次的调用 id、换了入参或换了工具,那一问是新问、出自己的卡(安全轴;行为收紧;不透明 `askId` 值变;零 DDL;部署零动作)**:
|
|
339
|
+
— **本版**:流内审批协议上场的部署(持久 ask 店在场)上,ask 身份 = (会话, run, 调用 id, 腿, 委派父调用 id, 类集, **工具名, 入参摘要**);入参摘要是引擎在派发这一问时铸的、与停驻卡上 `boundInputHash` 同一只值。
|
|
340
|
+
引擎的入参摘要只覆盖入参、不覆盖工具名,所以工具名单独进身份。
|
|
341
|
+
此前身份不含这两样:引擎只在一次回复之内拒重复的调用 id,跨回复复用同一 id、换了入参(或换了工具、入参逐字同)的第二问与第一问同身份 ⇒ 幂等命中第一问已决的行,
|
|
342
|
+
第一问的「是」被回放给第二问 —— 那次调用不出卡、不经人就执行。同一调用同工具同入参的重试照旧幂等(同一身份、回各自的答)。
|
|
343
|
+
— **wire 值变更**:不透明 `askId`(`approval_request` 呈卡帧、`POST /v1/tasks/:taskId/asks/:askId/decision` 的路径段)的**每一只值**都与上一版不同 ——
|
|
344
|
+
身份元组多了两元,没有入参摘要的问那一元是空串,同样改值(形不变:64 位十六进制串)。消费方只把它当不透明 id 用 ⇒ 零动作。
|
|
345
|
+
— **升级窗**:升级前写下的问行按上一版的派生存着,本服务不重算、不迁移。升级时还挂着的一张卡照旧按它行上的 `askId` 可答;同一调用在升级之后再被问一次时得一只新 id、出一张新卡(人多答一次)。
|
|
346
|
+
没有入参摘要的问(绕过引擎派发点的嵌入方自铸的问)只按工具名分问,不按入参分;对账器的 `unmatchableNoHash` 计数照旧报这类行。
|
|
347
|
+
**谁需要**:流内审批协议上场的部署 —— 一次批准只放行人看到的那一个动作(那一个工具、那一份入参)。
|
|
348
|
+
**谁受伤**:无(收紧:换了入参或换了工具的那一问回到人面前)。升级窗里同一调用再问一次的那张卡多出一次。
|
|
349
|
+
**补偿**:n/a(答那张卡)。**升级前做**:无。**回滚**:回到上一版 ⇒ 身份回到不含动作的形,本版写下的问行按它们存下的 `askId` 照旧可答。
|
|
350
|
+
|
|
351
|
+
15. **🔴 `POST /v1/approvals/:sessionId/decide`:`boundCallId` 与 `boundInputHash` 两位必带(决断方回显它在 `GET /v1/approvals` 那一行上看到的那一对),缺哪位 ⇒ `400 decide_requires_binding`,体带 `missingKeys` 点名缺的那几位;本服务不再拿当前停驻行补;`remember_requires_binding` 退役(BREAKING 行为面;安全轴;wire:错误码集少一码、拒体加性键 `missingKeys`)**:
|
|
352
|
+
— **本版**:决定落在决断方点名的那一个动作上。两位都是非空串才受理;缺席或空串 ⇒ 400(`null` 等非字符串值照旧先在值形门答 `400 request.field_invalid`)。判在门型守卫之后
|
|
353
|
+
(错门型照旧先拿 `409 gate_not_tool_approval` + 指路),续跑一步都不驱动、卡仍 pending。同一判对这道门的每一个决定者成立:本口、活卡回决停驻成的那张卡(停驻时绑定的那一对)、SLA 到期拒扫(它读下的那张卡的那一对)。
|
|
354
|
+
— **此前**:只要求 `checkpointToken` 或 `boundCallId` 之一,缺的 `boundInputHash` 由**此刻**停在门上的那一行补。同一调用 id、换了入参的新停驻顶替了决断方看到的那一张时,对旧动作的批准落在新动作上 ——
|
|
355
|
+
只回显 `boundCallId` 的合规形正中这一形。
|
|
356
|
+
— **跟着收的三处**:① `remember: "session"` 不再另有一道门:不带那一对 ⇒ 与一切决定同答 `400 decide_requires_binding`(此前 `400 remember_requires_binding`,本码退役);
|
|
357
|
+
② 幂等回放(首决已结清后同一份体重发)要求 `boundInputHash` 与行逐字相等 —— 不带 hash 的重发不回放、答 404(此前跳过这一判、回放成功);一份按本版首决成功过的体必然带着它;
|
|
358
|
+
③ 体形拒句把那一对写成必带键。
|
|
359
|
+
— **决不了的卡**:队列行上没有 `boundInputHash` 的工具审批卡 —— 只有引擎铸入参摘要之前停驻的老行(绑定纪元之前的行)—— 本口决不了,SLA 拒扫也决不了;
|
|
360
|
+
用 `POST /v1/runs/:id/cancel` 收场,或候它的终局时刻收割。
|
|
361
|
+
**谁需要**:每一个决断方 —— 一次批准只落在人看到的那一个动作上。
|
|
362
|
+
**谁受伤**:只回显 `boundCallId`(或只回显 `checkpointToken`)的决断方 —— 升级后决定得 400;拿 `remember_requires_binding` 分支的消费方(码不再出现)。
|
|
363
|
+
**补偿**:从队列行原样回显那一对:`GET /v1/approvals` 的 `pending[]` 行与 `/v1/approvals/stream` 的 `pending` 帧都带 `boundCallId` / `boundInputHash`;按 `missingKeys` 补齐再决。
|
|
364
|
+
**升级前做**:决断方(SDK / 壳 / BFF)先升到回显两位的版本,再升本服务。**回滚**:回到上一版 ⇒ 缺 `boundInputHash` 的决定重新被当前停驻行补(本条修的那一形回来);带全那一对的决定两版同答。
|
|
365
|
+
|
|
366
|
+
16. **更正(7.142.0 节第 18 条与第 19 条的两处读数说法,文书;零行为变化)**:
|
|
367
|
+
① **第 18 条**「谁受伤」写「坏块的部署(平面读 `no_origins`)」,回滚句写「平面读 `no_origins` 那一侧不变」;7.142.0 节 CHANGELOG 同说,`web_admin_sandbox_git_refused` 行的 `effect` 句也说「the sandbox git plane reads no_origins」。这些说的是平面的**第九条前提**(`sandboxGit.origins` 非空)不成立。
|
|
368
|
+
`GET /v1/capabilities` 的 `credentialPlane.sandboxGit.reason` 取判序里**第一个**不成立的前提(九词闭集与判序见契约附录 B):第三条前提(取值口的 worker 凭据)恒不成立,所以坏块、撤块、没有块的部署线上读到的都是 `no_caller_credential`(或更前的词),`no_origins` 要前八条都成立才会成为读数。第 18 条 ② 那一句(读数停在 `no_caller_credential`)本来就这样写,以它为准。
|
|
369
|
+
② **第 19 条**对第二形(强锚名紧贴在前一枚凭据的尾巴上)写「run 行与账本回放上被遮(读面多过一遍脱敏)」。在 7.142.0 上该形首遍不遮、第二遍才遮,读数看这个出口过几遍:`GET /v1/runs/:id` 的 run 行(写口一遍、读口一遍;经同步 / 流式提交落库的结果写前还多过出口那一遍)与 `GET /v1/runs/:id/events` 回放里的 `text` / `reasoning` / `done` 行(账本汇点写口一遍、回放读面一遍,至少两遍)被遮;
|
|
370
|
+
**回放里的 `tool_end` 行**(工具自己的输出,例如 Bash 回显)只过工具输出投影那一遍、回放读面不再过 —— 这一形在那里**明文**。流式 `done` 帧、同步体、运维日志行不变(一遍,明文);活流逐块帧 `text_delta` / `reasoning_delta` 与 `text_end` / `reasoning_end`(7.143.0 起与 `done` 同一只脱敏器、同一遍)同样明文。
|
|
371
|
+
第一形(复合凭据名)在每个出口都是明文,第 19 条原句不变。**本版起两形都遮**(第 41 条):复合凭据名在自由文本的声明形里是名字锚;名字的左界止于前一枚已认出的凭据的终点,第二形首遍即遮、各出口同读,上面这段出口遍数读数只是 7.142.0 的读数。
|
|
372
|
+
**谁需要**:按「凭据不会以明文出现在日志 / 转录里」配告警、做审计的部署,以及把 `GET /v1/runs/:id/events` 当作已脱敏副本交给下游的消费方;读 `credentialPlane.sandboxGit.reason` 并按 `no_origins` 分支的运维 / 嵌入方。
|
|
373
|
+
**谁受伤**:无新增(零行为变更);照第 19 条原句认定「账本回放不带这一形」的部署 —— 7.142.0 写下的回放里的 `tool_end` 行会带。
|
|
374
|
+
**补偿**:升级前已落库的 `tool_end` 行回放读面不再过脱敏(第 41 条「存量行」)⇒ 已有的回放可按这两形自查;`reason` 按判序第一个不成立的前提读。7.142.0 节原文不改(已发节字节不动)。**升级前做**:无。**回滚**:无关。
|
|
375
|
+
|
|
376
|
+
17. **🔴 引擎 7.61.0:升级前结清在途审批、排空旧 worker;部署的 mod 包按契约 7 重建(部署面;BREAKING)**:
|
|
377
|
+
— **此前**:引擎 7.60.0 的检查点把发起会话记在 `sourceTaskId` 下;mod 内核契约号是 6。
|
|
378
|
+
— **本版**:引擎只认新键 `sourceSessionId`(零别名)—— 升级前停驻、升级后才决断的卡,读回答 `requirements_damaged`,不能再决断;SQL 检查点店读到旧键的行同样判不可读,不静默读成空。
|
|
379
|
+
引擎只加载声明 `"contract": 7` 的 mod 包:按契约 6 写的包在起服被拒 `config.mods_invalid`,拒句点名两个契约号。
|
|
380
|
+
**谁需要**:所有升级到本版的部署。**谁受伤**:升级时还停着审批卡的部署(那几张卡作废,要重新提交任务);同一只库上混跑旧 worker 的滚动窗;装了 mod 包的部署。
|
|
381
|
+
**补偿**:升级前在旧版上把在途审批批完 / 拒完(`GET /v1/approvals` 为空),排空并停光旧 worker 再起本版;mod 包把 `hooks.json` 的 `"contract"` 改成 7 并按新契约重建(新站点与 `$` 调用见引擎文档)。回滚到 7.142.x:同样先结清本版的在途审批再起旧版。
|
|
382
|
+
|
|
383
|
+
18. **🔴 审批卡的委派子代出处键 `sourceTaskId` 改名 `sourceSessionId`(wire BREAKING;零别名;值不变)**:
|
|
384
|
+
— **此前**:活的 `tool_approval` / `approval_request` 帧、`GET /v1/approvals` 的 `livePending` 与停驻行、卡片 JSON 上,委派子代的卡带 `sourceTaskId`(值是子代的会话 id)。
|
|
385
|
+
— **本版**:同一格叫 `sourceSessionId`,同值;`sourceTaskId` 不再出现。唤醒腿写进检查点的这一格改填会话 id(此前误填了 run 的 task id)。
|
|
386
|
+
本版之前铸的卡信封(SQL `approval_ask.card_json` / local 问账里同一份信封)上那一格还叫 `sourceTaskId`:读口改名读回(一次性迁移 M37,只有读侧,窗口见登记表;
|
|
387
|
+
每改一次计一次 fail-open `server.approval-card.retired-card-key-read`)—— 断连重放、回决口、幂等重入照读,wire 上只出 `sourceSessionId`(不是别名)。
|
|
388
|
+
**谁需要**:引擎同一个会话身份只有一个名字。**谁受伤**:按 `sourceTaskId` 在场判「这是委派子代的卡」、或拿它关联子代行的壳 / SDK / 控制台。**补偿**:改读 `sourceSessionId`;`fromSubagent` 判别位与 `originTaskId` 不变。
|
|
389
|
+
|
|
390
|
+
19. **通告码 `context.image_removed` 改名 `context.media_removed`;TaskOutput 工具退役(wire 码改名;任务柄读腿文字;策略名单)**:
|
|
391
|
+
— **本版**:媒体离开模型请求的通告只铸 `context.media_removed`(`detail.reason` 说原因、`documents` 计文档),旧码不再出现;模型名册里没有 `TaskOutput`(后台命令的输出读输出文件,后台 agent / 工作流的结果在完成通告里);
|
|
392
|
+
HTTP 任务柄读腿的正文围栏标签由 `TaskOutput <id>` 改为 `task <id>`;策略的 deny / ask 名单点名 `TaskOutput`(或 `TeamCreate` / `TeamDelete`)⇒ 跑前拒 `config.legacy_tool_name`,allow 名单只得一行提示。
|
|
393
|
+
**谁需要**:读媒体移出通告的消费方 —— 图片与文档离开模型请求是同一只码(`detail.reason` 说原因、`documents` 计文档);在 deny / ask 名单里写了已退役工具名的部署 —— 跑前被点名,而不是一条名册里已经没有的工具名在名单里匹配不到任何调用。
|
|
394
|
+
**谁受伤**:按旧通告码写分支的消费方;按旧围栏标签匹配任务柄正文的 UI;策略名单里写了 `TaskOutput` 的部署。**补偿**:改读新码;按新标签匹配;从 deny / ask 名单里删掉这三个名字。
|
|
395
|
+
|
|
396
|
+
20. **设备车道:放置围栏 + 设备执行器协议修订 4(行为面;wire 加性;部署零动作)**:
|
|
397
|
+
— **本版**:被放在某台设备上的续跑 / 委派 / 唤醒腿,根会话此刻绑的不是那台设备(中途换绑过)⇒ `device.identity_mismatch`,在连接之前拒,不改道到新设备;引擎对报告与围栏不符的新腿答 `config.placement_not_honored`。
|
|
398
|
+
协议修订号 3 → 4:文件操作的结局码闭集加 `symlink_loop`,执行器声明修订 4 才发;`deviceExecutor.protocolVersion` 报 4。
|
|
399
|
+
**谁需要**:用设备车道、任务停着期间可能给根会话换绑设备的部署 —— 续跑 / 委派 / 唤醒腿在连接之前被拒,不跑到一台没有那份工作区的设备上;执行器在文件操作上撞到符号链接环时有一个专门的结局码可报。
|
|
400
|
+
**谁受伤**:在任务停着时给根会话换绑设备、又想在新设备上续跑的用户(新设备上没有那份工作区)。**补偿**:结束或取消在途任务,在新设备上重新开始;执行器升到修订 4 再发新词。
|
|
401
|
+
|
|
402
|
+
21. **SQL 后端:新表 `mailbox_consumed`(信箱已收窗;本服务起服自建;部署零动作)**:
|
|
403
|
+
— **本版**:`ack` 删掉的带身份记录各留一行(每盒留最新的引擎窗那么多行,同段修剪),追加时与持有行一起交引擎判重 —— 已收过的记录重投答它原来的 `seq`,不再当新信。表由起服的建表语句自建(`CREATE TABLE IF NOT EXISTS`),存量信箱行不迁移。
|
|
404
|
+
**谁需要**:SQL 后端上会重投带身份记录的发信方(重试、断线重连)—— 已收过的那一条答它原来的 `seq`,收信方不把它当一封新信再收一次。
|
|
405
|
+
**谁受伤**:SQL 部署多一张表(每盒的行数以引擎窗为界、同段修剪);回滚到 7.142.x 的那段时间里,重投已收过的记录照旧当新信收(旧版不读这张表)。
|
|
406
|
+
**补偿**:部署零动作(表起服自建);升级之前已被 `ack` 删掉的记录没有窗行(存量不迁移),升级后重投它们仍当新信 —— 窗从升级那一刻起积累。
|
|
407
|
+
**回滚**到 7.142.x:旧版不读这张表,表留着即可(再升回本版时接着用)。
|
|
408
|
+
|
|
409
|
+
22. **`DB_BACKEND=local`:落盘的工具结果按 `TOOL_RESULT_TTL_SEC` 老化回收(行为变化;运维面日志 tag 改名)**:
|
|
410
|
+
— **此前**:本机后端的工具结果目录没有任何清理路径,只增不减;SQL 后端按 TTL 回收。
|
|
411
|
+
— **本版**:本机与 SQL 同一只回收腿,按 `TOOL_RESULT_TTL_SEC`(缺省 86400 秒)收走更老的工具结果;回收失败的节流日志 tag 由 `tool_result_reap_older_than` 改为 `tool_result_reap`。
|
|
412
|
+
**谁需要**:长期运行的本机部署 —— 工具结果目录此前只增不减,盘面无界。
|
|
413
|
+
**谁受伤**:本机部署里依赖比 TTL 更老的工具结果引用的会话(引用读不回)。**补偿**:把 `TOOL_RESULT_TTL_SEC` 调大;告警规则按新 tag 匹配。
|
|
414
|
+
|
|
415
|
+
23. **会话同步 blob 上传:内容与哈希不符一律 400;嵌入方的文件历史店 / 工具结果店换新组形(wire 值变化;嵌入方类型面 BREAKING)**:
|
|
416
|
+
— **本版**:`PUT /v1/sessions/:id/sync/blobs/:hash` 内容地址对不上 ⇒ 400 `request.hash_mismatch`(此前一形答 502 `unsupported_format`)。
|
|
417
|
+
嵌入方自建的文件历史店:`syncBlobFaces` / `putBlob` / `getBlob` / `hasBlobs` 退役,改交引擎的 `blobExchange` 组(`put` / `get` / `has`,整组或没有;内容地址在 `put` 判);自建工具结果店:`reapOlderThan` 退役,改 `reap(now, { maxAgeMs })`。
|
|
418
|
+
**谁需要**:会话同步客户端 —— 内容与哈希不符读到一个确定的 400(同一份字节重传不会好),而不是一个看似可重试的 502;嵌入方 —— 两只店的 blob 面收成引擎的一组,内容地址只在 `put` 一处判。
|
|
419
|
+
**谁受伤**:把 502 当可重试的同步客户端;自建这两只店的嵌入方(编译即红)。**补偿**:哈希不符按 400 处理(重传正确内容);按新组形实现。
|
|
420
|
+
|
|
421
|
+
24. **记忆同步:套在别的 scheme 下的 URL userinfo 也判作凭据(行为收紧;部署面)**:
|
|
422
|
+
— **本版**:`MEMORY_SYNC_URL` / `MEMORY_SYNC_SERVE_IDENTITY` / 同步层名里出现 `proj:https://user@host/…` 这一形 ⇒ 起服拒;同步口请求的 `peer` / `target` 带这一形 ⇒ 400(不回显值)。
|
|
423
|
+
**谁需要**:不让凭据落进会被日志记下、存进本机游标、经能力位 `memorySyncServe.identity` 逐字公开的那些值的部署 —— 此前 `proj:https://user@host/…` 这种外面再套一层 scheme 的写法漏判。
|
|
424
|
+
**谁受伤**:把凭据写进这些值的部署(此前放行)。**补偿**:凭据从这些值里拿掉,走凭据配置。
|
|
425
|
+
|
|
426
|
+
25. **设置导入:用户层里以 `/` 起的路径规则留在设置文件里(行为收窄);🔴 导入预览请求体的 `userSettings` 层不再收 `root`(wire BREAKING;零别名)**:
|
|
427
|
+
— **本版**:导入预览把这类规则列进 `preview.skipped`(原因前缀 `unsupported.layer_root:`),不再存成每个项目根都读的全局规则;先前准备好的导入记录在兑现时拒这类候选。
|
|
428
|
+
`POST /v1/rules/cc-import/prepare` 的每一层按 `layer` 分形:`{ layer: "userSettings", path, content }`(**没有** `root`)| `{ layer: "projectSettings" | "localSettings", path, root, content }`。
|
|
429
|
+
用户层带 `root` ⇒ 400 `request.body_shape`,拒句 `body must be {layers:[{layer:"userSettings",path,content} | {layer:"projectSettings"|"localSettings",path,root,content}]}`(此前每一层都必带 `root`,用户层那一格从不被读)。
|
|
430
|
+
**谁需要**:从 CC 导入用户层设置的用户 —— 用户层的 `/x` 规则此前存成每个项目根都读的全局规则(第 37 条起服退役的就是这批存量);导入客户端 —— 用户层不再要一个从不被读的 `root`。
|
|
431
|
+
**谁受伤**:靠导入把用户层 `/x` 规则带进来的用户;在用户层上照旧带 `root` 的导入客户端 —— 每次带用户层的预览都 400,不只是带 `/x` 规则的那几次。
|
|
432
|
+
**补偿**:在项目层写同一条规则(项目层的 `/` 形读在那个项目的根);导入客户端在 `userSettings` 层上去掉 `root`(项目层 / 本地层照旧带)。
|
|
433
|
+
|
|
434
|
+
26. **🔴 SQL 后端:`approval_ask` 加一列 `decided_via`;决定体加性键 `decidedVia`;能力位 `approvalDecidedVia`(wire 加性;DDL:升级前先加列,先升库再升副本;零一次性迁移)**:
|
|
435
|
+
— **本版**:四条决定口(`POST /v1/tool-approvals/:id/respond`、`POST /v1/tasks/:taskId/asks/:askId/decision`、`POST /v1/approvals/:sessionId/decide`、`plan_review`)受理 `decidedVia`(取引擎的座位闭集,只许在 `decidedBy: "policy"` 旁),
|
|
436
|
+
`hostDecision.decidedVia` 原样交引擎;问账行与决定同一条 UPDATE 落列 `decided_via`。行上 NULL(含加列前的旧行)读作缺席 = 部署自己的策略;请求体上的 `decidedVia: null` 不是缺席,答 400。
|
|
437
|
+
— **DDL**(升级前先在库上执行;没加就起服 ⇒ 拒启 `config.schema_mismatch`,拒句逐字打印同一句):
|
|
438
|
+
MySQL 协议 `ALTER TABLE approval_ask ADD COLUMN decided_via VARCHAR(32) NULL;`;PostgreSQL `ALTER TABLE approval_ask ADD COLUMN decided_via VARCHAR(32) COLLATE "C";`
|
|
439
|
+
存量行不改写(加列即 NULL)。加了列的库上,重启的 7.142.x 副本拒启(库比代码新)。
|
|
440
|
+
**谁需要**:按 PermissionRequest 钩子代答卡片的壳与宿主(模型读到「一只 PermissionRequest 钩子拒了这次调用」,不是部署策略句)。**谁受伤**:已有问账表的 SQL 部署(`DB_BACKEND=mysql|pg`):升级前多一句 DDL。
|
|
441
|
+
**补偿**:能力位 `approvalDecidedVia`(恒 `true`)见位才发;**回滚**到 7.142.x:先停光本版全部副本,再 `ALTER TABLE approval_ask DROP COLUMN decided_via;`,再起旧版。
|
|
442
|
+
|
|
443
|
+
27. **`verify:true` 任务的上限封住整个任务的实现侧:每轮修复只拿余额,一条轴花光 ⇒ 不再修复(行为收窄;wire 加性 `verification.allowanceExhausted`;部署零动作)**:
|
|
444
|
+
— **本版**:任务的 `limits`(请求的 `maxCostUsd` / `maxTokens` / `limits.maxTurns`,或 `MAX_TASK_COST_USD` / `MAX_TASK_TOKENS` 落成的值;开着 `RESOURCE_SUSPEND` 时是跨片总额 `RESOURCE_SUSPEND_TOTAL_TOKENS` / `_TOTAL_BUDGET_USD`,每一片仍按 `limits` 的窗走)
|
|
445
|
+
管实现腿与各轮修复的合计:每轮修复拿的是上限减去前面各腿自报的花费。修复腿越过余额 ⇒ 照常 `limits.max_cost_exceeded` / `max_tokens_exceeded` / `max_turns_exceeded`;某条轴已花光 ⇒ 不派修复,判词停在那次 FAIL,
|
|
446
|
+
结果带 `verification.allowanceExhausted: { axis: "cost" | "tokens" | "turns", remaining?: 0 }`。前面有一腿没报价(模型无价目,结果里没有 `costMicroUsd`)而任务带美元上限 ⇒ 美元轴余额算不出,读作没有余额(`axis: "cost"`,不带 `remaining`)。
|
|
447
|
+
此前每轮修复是新开的一次运行、整份重拿上限,跨片总额也逐腿重给 —— 本文件 7.140.0 节第 10 条「补偿」里「verify 任务没有跨腿的总额」一句自本版起不再成立(已发节字节不动)。
|
|
448
|
+
**谁需要**:给 verify 任务设了花费上限、要它真封住整个任务的部署。**谁受伤**:按「每轮修复各有一份上限」配额的调用方(修复轮数可能变少,结果多一键);配了 `MAX_TASK_COST_USD` 却跑无价目模型的部署 —— verify 任务第一次 FAIL 之后不再修复(起服那行 `cost_ceiling_without_pricing` 说的就是这台)。
|
|
449
|
+
**补偿**:按整个任务配上限(各轮可能花的加起来);给模型配价目(`MODEL_COST_*` / 名册行的 `cost`);轮数仍由 `verifyRounds` 管。**回滚**:回到 7.142.x 即回到逐腿整份(无数据面)。
|
|
450
|
+
|
|
451
|
+
28. **更正(7.139.0 节第 24 条 ③,文书;零行为变化)**:本机宿主车道上没配 worktree 包装、要 `isolation: "worktree"` 的 workflow 子代,拒它的仍是本服务的 host 工厂(码 `isolation.unavailable`,句子点名 `WORKTREE_ISOLATION_ENABLED` / `WORKTREE_REPO_ROOT`),
|
|
452
|
+
不随引擎 7.61.0 改由引擎拒:worktree 的核验在引擎契约里是执行环境工厂一方的义务(必须铸 worktree 或抛),引擎没有回执可核。部署零动作;7.139.0 节原文不改(已发节字节不动)。
|
|
453
|
+
|
|
454
|
+
29. **嵌入方:包一层 `ServiceDeps.resolveSpec` 的包装必须返回装配器交回的同一只对象(嵌入方行为面 BREAKING;部署零动作)**:
|
|
455
|
+
— **此前**:本服务的部署事实(执行车道、run 技能名册、受理见证)以 symbol 键挂在装配器交回的 spec 上,`{ ...spec, model }` 这类拷贝把它们一起带过去。
|
|
456
|
+
— **本版**:事实登记在以装配器交回的那一只对象为键的载体里,不在 spec 上;拷贝读不到 ⇒ 选路答 500(`HandsLaneUnstampedError`,日志留原句),技能名册与会话工作区见证缺席。
|
|
457
|
+
**谁需要**:每一条 run 与续跑 —— 引擎的 `TaskSpec` 一读门按 `Reflect.ownKeys` 判自有成员,不是它声明的键(含 symbol 键)一律拒(新 run `config.spec_unknown_key`、续跑 `checkpoint.config_refused`),挂在 spec 上的部署事实会让任务跑不起来。
|
|
458
|
+
**谁受伤**:在 `createResolveSpec` 外面再包一层、返回拷贝的嵌入方。**补偿**:在交回的对象上改并返回它(`return Object.assign(spec, { model: … })`);只用本服务装配器的部署零动作。
|
|
459
|
+
|
|
460
|
+
30. **验证器自己停驻的那张卡改由引擎的作废动词结算,会话钉随之放掉;编排(leader)路径同样作废(行为面;修复;部署零动作;订正 7.141.0 节第 31 条的两条已知限制)**:
|
|
461
|
+
7.141.0 第 31 条写的两条已知限制 ——「作废只结清卡,引擎为它钉住的验证器会话不在这里释放,留在副本内存里直到进程重启」「编排(leader)路径上的验证器卡本版不作废」—— 本版两条都收:
|
|
462
|
+
后台 run、同步提交、续跑 verify 臂与 leader 的 worker 结算一律交跑过那次验证门的 Runner 的作废动词(引擎读卡上记的组合腿,只收验证器腿铸的卡;卡 `expired`、验证器会话放钉),本服务不再读卡、比会话、店级作废。
|
|
463
|
+
**谁需要**:长寿副本、看待决面的人与壳。**谁受伤**:按 `server.verifier-pause.card-void-failed` 探针行的旧原因词(`reason=store_error|card_mismatch|no_checkpoint_store`)筛的告警 —— 探针行改带引擎的码(`code=<码 | thrown>`)。
|
|
464
|
+
**补偿**:告警改按 `code=` 筛(`thrown` = checkpoint 店在出错;`checkpoint.void_unpin_failed` = 卡已作废、会话钉没放掉)。7.141.0 节原文不改(已发节字节不动)。
|
|
465
|
+
|
|
466
|
+
31. **`settings.permissions.allow` 的条目也可带出处层 `{ rule, layer }`;user 层的 `/` 形 allow 读在执行环境的配置根(wire 条目型放宽 + 能力位 `settings.permissions.layeredAllow`;端见位才发;部署零动作,沙箱车道配置根读不出的部署见补偿)**:
|
|
467
|
+
7.141.0 节第 15 条为 deny / ask 立的读法 —— 一条路径规则的 `/` 读在它那一层的根上 —— 本版扩到 allow 桶(收掉那一条「已知限制」里 allow 桶只收纯串的那一半):`userSettings` 里要根的 allow 规则免问的是配置根下的路径、不再是任务根下的;
|
|
468
|
+
别的层与纯串照旧读在任务根。条目一条一员按位置交给引擎(命中报的位置 = settings 表的下标)。
|
|
469
|
+
**谁需要**:user 层写了 `/` 形 allow 的端用户。**谁受伤**:① 依赖「user 层 `/x` 放每个项目的 `x`」的人 —— 端升级发带层条目后任务根下 `x` 的写照问;② 沙箱车道配置根读不出的部署(home 未声明且没转 `SEMA_CONFIG_DIR`):这样的 allow 422 `home_unresolvable`;
|
|
470
|
+
③ 回滚 / 滚动发布中的旧副本读到带层 allow 的体 ⇒ 新提交 400、续跑 409。
|
|
471
|
+
**补偿**:① 规则挪进项目层,或写相对形 `x/**` / `//` 绝对形;② 沙箱 env 名单加 `SEMA_CONFIG_DIR`,或声明 `REMOTE_EXEC_HOME_DIR`;转进去的值写绝对路径(相对值由引擎在开跑时拒这条 run);③ 端读能力位 `settings.permissions.layeredAllow`、见位才发。7.141.0 节原文不改(已发节字节不动)。
|
|
472
|
+
|
|
473
|
+
32. **后台子代一个 id(引擎换代):面板、完成通知、孙代嵌套、审批归属都读注册表行 id `a…`;升级前停驻的后台子代先结清,回滚前同样(行为面;部署面:升级 / 回滚前各一步;wire 键零变化)**:
|
|
474
|
+
引擎这一版起后台子代的 tick、结果、完成通知、孙代的父链接与问上的 `agentId` 都是它的注册表行 id;本服务按这一个 id 读,不把它的会话 id 当别名读(升级前的 id 不被读成新 id 的别名)。
|
|
475
|
+
**谁需要**:看面板的端(一只后台子代一行)。**谁受伤**:① 升级时还停驻着的后台子代 —— 它升级前登记的那些行(它自己的后台任务、它派出的子代,属主是它当时的会话 id)在它以行 id 复活之后够不着;
|
|
476
|
+
② 回滚:本版停驻的后台子代的卡记着行 id(要求词 `row_task_id`),上一版读不懂这个词,续跑拒 `version_newer`。
|
|
477
|
+
**补偿**:升级前与回滚前各让停驻的后台子代结清(答掉它的审批、或停掉它);没结清的卡升回本版即可续跑。**升级前做**:让停驻的后台子代结清(答掉它的审批、或停掉它)。**回滚前做**:同样让本版停驻的后台子代结清;没结清的卡在回滚后的副本上续跑不了,升回本版即可续跑。
|
|
478
|
+
运维日志 `task_notification_observed` 删 `hadFleetRow` 键(后台子代的行不经那条腿)。
|
|
479
|
+
|
|
480
|
+
33. **Runner 之外复活的后台子代,完成通告走委派树根会话的会话通知门(行为修复;wire 零新键;部署零动作)**:
|
|
481
|
+
— **此前**:引擎 7.61.0 下,停驻的后台子代经 `POST /v1/approvals/:sessionId/decide` 批准恒答 409 `decide.revive_rejected`(引擎 `revive.no_background`:Runner 之外的续跑解不出完成 sink 就不起),子代永不再跑;
|
|
482
|
+
7.61.0 之前续跑起得来、完成谁都收不到。操作员续跑(`POST /v1/runs/:id/subagents/:target/resume`)起的续跑同样起得来、完成不交给任何人。
|
|
483
|
+
— **本版**:这两种续跑跑完,完成交给委派树根会话的会话通知门(与 `POST /v1/sessions/:id/notify` 同一只门):根会话在本副本有活流 ⇒ 注入那条 run(`<task-notification type="external">`,最早边界);
|
|
484
|
+
空闲 ⇒ 进它的收件箱,下次开流排空成一帧 `task_notification`。帧 = notify 门的 external 形:`task_type: "external"`、`task_id` = 子代句柄、`status`、`summary`、`result?`、`seq`(停驻周期号),不带 `completionId`。
|
|
485
|
+
投递那一刻根会话不在、或住客已换(删了、同 id 被重新登记、属主变了)⇒ 不交,一行 warn `background_completion_undelivered`。更深的行(孙代)报给委派树的根。
|
|
486
|
+
门在投递动作之前紧邻地复核住客(属主与化身两样),`POST /v1/sessions/:id/notify` 同此:属主门读过之后、投递之前这只会话被删、同 id 换了住客或换了属主 ⇒ 答 404 `not_found.session`(此前照投给下一位住客);
|
|
487
|
+
收件箱条目的属主照旧取属主门那一读(无主会话盖请求主体)。会话店不铸住客令牌(嵌入方自建的店;头读没有 `incarnation`)⇒ 复核只比属主:属主没变 ⇒ 照投(与此前同形),变了 ⇒ 404;
|
|
488
|
+
本服务自带的店每次建行都铸令牌。
|
|
489
|
+
**谁需要**:停驻后台子代、再由人决断的部署;用操作员续跑动词的壳。**谁受伤**:把复活的完成帧当噪声的消费方(根会话多一帧 `task_notification`);按 `task_type: "background_agent"` 或 `completionId` 关联子代完成的消费方
|
|
490
|
+
(这一形上两键都不在);根会话空闲时排空的是展示帧,下一次 run 的模型上下文里没有它。**补偿**:帧形是 notify 门既有的 external 形,按 `task_id`(子代句柄)关联;同一子代两次复活的完成 `seq` 不同。
|
|
491
|
+
|
|
492
|
+
34. **会话记忆同步触发口 `POST /v1/sessions/:id/memory/sync`:409 `conflict.session_memory_unobserved` 体恒带 `reason`(闭集五词),句子由 `reason` 定;最近一条已结 run 的记录里没有记忆观测的那一形有了自己的一句出路;🔴 它配了记忆而没挂上(`memoryless`)的那一形由 200 空报告改 409(wire 加性;行为面;三句拒句换形 / 新句;零 DDL;部署零动作)**:
|
|
493
|
+
— **本版**:读集照旧只读会话**最近一条已结 run** 的记忆观测,不往更早的 run 找。读集取不到时 409 体多一个键 `reason`,判序 = 读的先后:
|
|
494
|
+
`no_settled_run`(会话还没有已结 run)· `run_result_missing`(最近一条已结 run 的记录里没有结果:实例丢了被收割、停驻过期被收割 —— 收割写空结果,停驻时那份观测随之不在 —— 、在引擎答出之前抛)·
|
|
495
|
+
`run_result_unobserved`(记录里有结果、结果里没有记忆观测:引擎在准备阶段拒了 / 失败了它,引擎答出之前被取消,或更早版本的引擎写下的结果)·
|
|
496
|
+
`memory_not_mounted`(观测在,说那一条配了记忆而没挂上:引擎 `memoryless`,`mount-failed` / `no-backend`)· `no_leaf`(观测在、说得出读集,会话还没有叶子)。
|
|
497
|
+
停因本身读那条 run 的终局(`GET /v1/runs/:id` 的 `status` / `errorCode`;没挂上的因由读它的 `result.effectiveMemoryScopes.reason`)。有在飞 run 时照旧另带 `activeTaskId`。
|
|
498
|
+
— **行为变化(🔴)**:最近一条已结 run 的观测是 `memoryless` 时,上一版把读集读作 `[]`、答 200 空报告(`scopes: []`、`layers: []`);本版答 409 `memory_not_mounted` —— 挂载失败时那一腿本该读哪几层不可知,`[]` 只留给本会话没配记忆(`none`)。
|
|
499
|
+
— **句子**:`no_settled_run` 不变;两只空观测因由同一句(「the latest settled run in this session has no memory observation on record, and an earlier run is never read in its place — run another task in this session (if that run was refused, fix what refused it first), then sync」);
|
|
500
|
+
`memory_not_mounted` 一句(「memory was configured for the latest settled run in this session but did not mount, so which memory this session reads is unknown, and an earlier run is never read in its place — run another task in this session (if its memory fails to mount again, fix that first), then sync」,新臂);
|
|
501
|
+
`no_leaf` 一句(「this session has no transcript yet, so there is no revision to sync from — run a task in it (or let the run in flight finish), then sync」)。此前三臂同一句「this session has no settled run with a memory observation yet …」。
|
|
502
|
+
— **不变**:码、状态 409、门序、零请求零写;观测是 `mounted` / `none` 的 run 读集与 200 报告逐字同上一版;持久数据零变化(空观测由读口从行上已有事实算出,不落盘)。
|
|
503
|
+
**谁需要**:壳与控制台 —— 按 `reason` 告诉用户同步为什么不可用、怎么解开(会话里早先成功过的 run 不再让人以为同步坏了;记忆没挂上的会话不再被当成「同步完了」推上云)。
|
|
504
|
+
**谁受伤**:按 409 体逐字节比对、或按句子匹配这一码的消费方:体多一个键,空观测两臂与 `no_leaf` 臂换了句子;最近一条 run 记忆没挂上的会话 —— 上一版 200 空报告、本版 409,同步按钮灰到再跑一条挂上记忆的任务为止。
|
|
505
|
+
**补偿**:按 `errorCode` + `reason` 分支,不比句子;`reason` 是闭集,读不懂的词按「读集取不到」处置(在会话里跑一条任务、等在飞的 run 结束,再触发);`memory_not_mounted` 反复出现 ⇒ 读那条 run 的 `result.effectiveMemoryScopes.reason`,查记忆引擎的挂载故障。
|
|
506
|
+
**升级前做**:无。**回滚**:回到上一版 ⇒ 409 体不再带 `reason`,三臂回到同一句,`memoryless` 回到 200 空报告;落盘数据不受影响。
|
|
507
|
+
|
|
508
|
+
35. **🔴 记忆同步:中心每个层分区一只化身,写之前判请求的主张;同步口改到 `POST /v2/memory/sync/:scope`(`/v1/…` 答 404);本机游标原样携带化身(引擎 7.61.0 三处硬破坏;持久数据面:中心库新表 `agent_memory_engine_sync_partition`,起服自建、零 ALTER;部署:两端同版 + 停驻层删游标)**:
|
|
509
|
+
此前:游标只绑层、对端地址与本机店。中心库被清空重建或从更早的备份恢复,同一地址读作同一个对端 —— 下一轮按旧基线对账,中心没有的基线条目答成「中心已删」、旧副本答成「中心改过」,本机照落,这一轮还报 `ok`。
|
|
510
|
+
现在:① 中心每个层分区一只化身(分区第一次被同步读到时出生、存在中心库),结果体 `cursor.incarnation` 恒在场;请求的 `peerIncarnation` 在任何读写之前比 —— 不是本分区的、或带非空基线却没有主张 ⇒ 200 `{ refused: "baseline_incarnation", incarnation }`,零读零写;
|
|
511
|
+
一轮写完之后化身已变 ⇒ 500(不答算在旧状态上的结果)。② 同步口路径 `/v2/memory/sync/:scope`;`/v1/memory/sync/…` 无人认领 ⇒ 404。③ 本机执行器把落盘游标的 `peerIncarnation` 原样交引擎;中心在化身轴上的拒 = 停驻(同另三轴,一条出路:删游标;运维行 `axis: "incarnation"`)。
|
|
512
|
+
**谁需要**:DB 记忆平面的中心与连它的本机同步腿 —— 中心库重建之后设备上的条目不再被一轮「成功」的同步删掉或回滚。
|
|
513
|
+
**谁受伤**:① 升级期:新旧两端互答 404(新客户端只打 `/v2`、旧中心只认 `/v1`;新中心对旧客户端同样 404),两侧都什么都没写,**同步暂停,两端同版后恢复**;
|
|
514
|
+
② 两端同版后的第一轮:每一层带基线的游标(升级前写下的,没有化身)被中心拒 `absent`,本机那一层停驻(`GET /v1/sessions/:id/memory-status` 的 `memorySync.parked[]`、运维行 `memory_sync_layer_parked { axis: "incarnation", found: "absent" }`),停驻层每一轮仍发一次请求、被中心在写之前拒掉;
|
|
515
|
+
③ 中心从备份恢复:恢复回来的化身就是备份时那一只,读作同一份状态 —— 备份之后设备上的新条目照旧会被删掉或回滚(引擎的已知限制)。
|
|
516
|
+
**补偿**:① 两端都升到本版,先后不限(升级期只是不同步,不丢数据);② 删掉停驻层的游标文件(运维行 `cursorPath` 逐字;`<记忆引擎根>/sync-cursors/<scope 的 sha256 前 32 位>.json`),下一轮从空基线重收敛:
|
|
517
|
+
两边都改过的条目按冲突报,上一轮之后一侧删掉的条目会从另一侧回来;③ 中心从备份恢复之后、起服之前删掉 `agent_memory_engine_sync_partition` 的全部行(轮换化身):每个客户端下一轮被拒 `other`、按 ② 处置(DEPLOY-PREREQS)。
|
|
518
|
+
**升级前做**:无(新表起服时 `CREATE TABLE IF NOT EXISTS` 自建;库账号已有建表权限)。**回滚**:旧中心不认 `/v2` ⇒ 同步再停;本版写下的游标带 `peerIncarnation`,旧二进制按名挑员时丢掉它 —— 回到旧版即回到旧语义;新表留着无读者。
|
|
519
|
+
**嵌入方**(自建 `ServiceDeps`):`memorySync` 的答型改为 `MemorySyncAnswer`(结果或拒答);自建 `MemorySyncStore` 多一口 `partitionIncarnation(scope)`(TypeScript 编译红即通知)。
|
|
520
|
+
|
|
521
|
+
36. **🔴 抹除与会话记忆状态答整个部署:两只抹除口走引擎的一只部署对象,会话记忆状态不带层座 ⇒ 引擎在每只店上折成的那一份,本部署有哪些店读盘上的(行为面;409 `memory.erasure_store_unjudged` 退役、会话自助抹除体的 `scope` 退役;嵌入方类型面 BREAKING;部署零动作)**:
|
|
522
|
+
此前(7.140.0 起):目录钉住的 file 部署上,落到个人挂载那只店的抹除一律 `409 memory.erasure_store_unjudged`、什么都没擦;会话记忆状态由本服务折;本部署的店集由配置点名的层推。
|
|
523
|
+
现在:① 抹除(`POST /v1/memory/erase` 与 `POST /v1/sessions/:id/memory/erase`)交引擎的部署对象 —— 一个 `requestId` 在整个部署里只名一次请求:执行之前读遍每只店的锚,同一个 id 头一回换了选择子或执行在另一只店 ⇒ `409 memory.erasure_selector_mismatch`,
|
|
524
|
+
换了授权集 ⇒ `400 config.memory_erasure_scope`,什么都没删;个人层的抹除照常执行;`select.ids` / `select.sessionId` 不带 `expectedScopes` ⇒ 每只店各擦各的那一份、收执合成一份;授权集的层分住两只店 ⇒ `400 config.memory_erasure_scope`。
|
|
525
|
+
② 会话记忆状态不带层座 ⇒ 引擎的部署对象折好的一份;带层座 ⇒ 那只店上的引擎答案。③ 本部署的店集 = 盘上的(个人挂载上有店就算,配置不再点名个人层也算)。
|
|
526
|
+
**谁需要**:目录钉住的 file 部署上要擦个人层记忆的 operator 与会话所有者(擦得掉、重放收敛);换过 `MEMORY_SCOPE` 的部署(个人挂载上留下的那一份照样被状态数到、被按会话抹除擦掉)。
|
|
527
|
+
**谁受伤**:① 按 `409 memory.erasure_store_unjudged` 分支的客户端 —— 码退役,这些请求现在照常执行;② 会话自助抹除体带 `scope` ⇒ `400 request.body_shape`(7.140.0 起的层座,本版退役:抹除交整个部署,没有「落哪只店」可点);
|
|
528
|
+
③ 个人挂载上有店的部署,不带层座的出处 / 清标 / 清标账请求 ⇒ `400 request.memory_layer`(此前配置不点名个人层时答在部署的店上);④ 抹除那一条只走 incident 座的码(`memory.erasure_index_residue`)的运维行名由 `memory_compliance_incident` 变为 `memory_engine_incident`;
|
|
529
|
+
⑤ 嵌入方(自建 `ServiceDeps` / 直调记忆作用域店):`SessionMemoryStatusFace` 改为 `readingAt(at?) → { key, status(sessionId) }`、`MemoryComplianceFaces.erase(input)` 去掉层座参、`createMemoryScopeStores` 去掉 `namedLayers`(多一个可选 `captureRecords`)、
|
|
530
|
+
`foldPlaneStatuses` / `memoryStoresOfDeployment` / `memoryLayersNamedBy` / `MemoryErasureStoreUnjudged` 删除、`backendOwnsControlPlane` 改从 `memory-scope-stores.ts` 导入(TypeScript 编译红即通知;零别名)。
|
|
531
|
+
**补偿**:① ② 去掉对退役码 / 键的分支;③ 在请求里点名层(GET 口 `?scope=<层键>`,POST 口体 `"scope"`);④ 告警按码匹配(两种行名都带 `code`);⑤ 照新形改。记忆引擎根下多一个目录 `.memory-erasure-judge`(抹除判官锁;根本就要可写)。
|
|
532
|
+
**升级前做**:无。**回滚**:回到上一版即回到上一版的答法(本版个人店上执行过的抹除,其锚留在那只店里:上一版对那只店的抹除照答 409,不会重复执行)。
|
|
533
|
+
|
|
534
|
+
37. **🔴 规则店:引擎 7.61.0 之前从用户层设置导入、从 `/` 写起的全局放行,起服即退役(一次性迁移 M36;持久数据面;行为收紧;部署零动作)**:
|
|
535
|
+
旧形:引擎 7.61.0 之前的设置导入(`/v1/rules/cc-import/*`、`/v1/rules/local-import/*`)把用户层(用户配置目录下那份 settings)里 `Edit(/notes/**)` 这样从 `/` 写起的路径规则存成**全局**行。
|
|
536
|
+
全局行在每个任务的**项目根**读 `/x`,用户层却在它自己的配置目录读 —— 一条本意是「配置目录下的 notes」的放行,在每个项目里放行 `notes/` 的编辑、不问。
|
|
537
|
+
引擎 7.61.0 起导入不再这样存(本版第 25 条);已存的行引擎不迁、也不在读侧丢,判据交给店的属主跑。
|
|
538
|
+
新形:每次起服的一次性迁移读规则桶(SQL:规则表里的每一只;local:导入记录点名过的属主的那几只),按引擎那一句判据退役:态是 `allow` ∧ add 的出处是设置导入(`imported-cc`)∧ 行的 scope 是全局 ∧ 规则在项目根读 `/x`。
|
|
539
|
+
**按 add 退役、不按行**:同一条规则另有人亲手同意过的那一份(`user` 出处),规则照旧生效,只少了导入那一份;deny / ask 不动(它们在项目根只收紧);`//abs`、`~/`、相对路径、非路径规则与项目 scope 的行不动。
|
|
540
|
+
第二次起服零写。SQL 两库与 local(File)同一只函数、同一处写法:墓碑经这只桶自己的写面落(与撤销口同一形),删除点由本副本铸。
|
|
541
|
+
读数:起服报告两键 `importedLayerRootAllowsRetired`(逐行:桶键 / 工具名 / 退役的 add 数 / 规则是否还生效;不带规则正文)与 `importedLayerRootBucketsSkipped`(闭集四词 `bucket_unreadable` / `vanished` / `not_writable` / `contended`;`vanished` = 写它的那一步里这只桶被另一副本删掉了,无可退役、不拒启);
|
|
542
|
+
warn `imported_layer_root_allow_retired` / `imported_layer_root_bucket_skipped`,一行一桶 / 一行一规则。
|
|
543
|
+
**谁需要**:用过设置导入的部署 —— 那几条放行从此不在每个项目里替人答应。
|
|
544
|
+
**谁受伤**:① 依赖那条错位放行的人:升级后在项目里编辑 / 读那几个目录会被问(本意本来就不是它);② 回滚到引擎 7.61.0 之前的版本后再导入:旧导入门会把同形的行再铸出来;
|
|
545
|
+
③ local 车道审批记录日志损坏、或某只规则桶文件 / 规则目录的收编标记读不出(含一次 I/O 失败)的数据根:迁移读不全 ⇒ 起服拒(此前起服照常、只在规则面上拒)—— 不跳过(跳过就是让那几行照旧放行而不说);
|
|
546
|
+
④ SQL 后端:窗内每次起服读一遍规则表里的每一只桶,桶多的库起服变慢;起服那一刻库读失败 ⇒ 起服拒(SQL 店的判官判为损坏的桶不在此列 —— 指纹 / 文法戳 / 行形不合,或某只 JSON 列的体读不出:点名跳过 `bucket_unreadable`、一个字节不动、接着读下一只桶,它本来就什么都不放行;一只与导入无关的坏桶不挡起服);
|
|
547
|
+
⑤ local 车道:引擎的本地数据根收编把一只桶改名到没有任何导入记录点名的身份之后,这只桶迁移叫不出、不退役(已知缺口)。
|
|
548
|
+
**补偿**:① 真要在每个项目里放行的,以项目 scope 或 `//abs` 绝对路径重新同意一次;本意是用户配置目录的,写 `~/…`;② 再升回本版,起服把再铸的那几只 add 再退役一次(每次起服都跑);③ 按拒句点名的文件与行修好再起;④ 读失败照常重启(迁移幂等);⑤ 那只桶里导入的全局 `/x` 放行经撤销面撤掉(`DELETE /v1/rules`)。
|
|
549
|
+
**回滚**:墓碑是上一版撤销口写的同一形,上一版照常读;回滚不动库,被退役的那几条不回来(要回来就重新同意)。迁移码在不再支持回滚到引擎 7.61.0 之前的版本时删(窗口见登记表)。
|
|
550
|
+
|
|
551
|
+
38. **本地导入载体(`POST /v1/rules/local-import/{prepare,redeem}`)的 deny / ask 在 prepare 当场落店 —— 收紧不等同意(行为面;wire 加性;部署零动作)**:
|
|
552
|
+
旧形:三态都合成进导入层、经导入记录与票在 redeem 落;引擎 7.61.0 起导入门把用户层里从 `/` 写起的路径规则留在设置文件里,全局 `/x` 的 deny / ask 因此成员级 `not_importable`(云端不拒)。
|
|
553
|
+
新形:收下的 deny / ask 按提交序经直写接缝当场落(与 `POST /v1/rules` 同一只;出处 `user`),预览成员 `{key, admitted:true, outcome:"persisted"|"no-op"}`;allow 照旧经记录与票在 redeem 落,
|
|
554
|
+
本版铸的票的回执只有 allow;只有 deny / ask 的一批没有票。整工具的 deny / ask 同样当场落。一条 deny / ask 写不进店 ⇒ `503 state.rule_write_failed`(带 `committed`),这一批的 allow 全部扣下、没有票;同一批重发幂等。
|
|
555
|
+
**谁需要**:用载体迁移本机规则的人 —— 本机生效的收紧在云端同样生效。**谁受伤**:按回执数收紧的客户端;把 prepare 当无副作用预览的客户端;按出处 `imported-cc` 筛收紧的治理面。
|
|
556
|
+
**补偿**:收紧的结局读预览成员的 `outcome`;撤销走 `DELETE /v1/rules`;出处词与直写口同义(放行仍是 `imported-cc`)。滚动窗里旧版本铸的票照旧在 redeem 落它记录里的 deny / ask。
|
|
557
|
+
|
|
558
|
+
39. **自由文本脱敏的取证读法按出处读(行为面;安全;脱敏产物可能变;运维面多一个 fail-open 标签 `server.redact.forensic-level-cap`;部署零动作)**:
|
|
559
|
+
— **本版**:一枚凭据不再拿自己上一轮的读数当证据,嵌套或相邻的另一枚凭据照算;一段由字符类自然停下的值盖住私钥栅栏或 URL 的 `@` 时两种读法都算、取覆盖多的那一份;
|
|
560
|
+
SSH2 私钥块收好之后的孤立收尾栅栏之前读作丢了起头的体(体从体长上界内最早的那一枚已收口块的终点起,体与孤立收尾那一行照遮;此前一枚记号盖到孤立收尾之后,现在各块与体各一枚);
|
|
561
|
+
私钥收尾本身落在一段值里的块只在一读里收好 ⇒ 不藏、也不越过它体里的起始栅栏(那一枚照读截断律,收尾之后的体形串遮掉);证据链深过 32 环的输入从那一处遮到末尾,并记一次 `server.redact.forensic-level-cap`。
|
|
562
|
+
**谁需要**:日志 / 转录 / 结果里出现「赋值形凭据紧贴私钥栅栏或 URL」、URL 密码里带 `@`、或嵌套 / 相邻私钥块的部署 —— 此前这些形下私钥体或 URL 凭据的一段原样出门。
|
|
563
|
+
**谁受伤**:按字节比对脱敏产物的消费方(这些形遮得更多;两枚起始栅栏共用一枚收尾、其后不远另有收尾时,遮到后一枚收尾;私钥收尾被一段值盖住、其后只剩别的块自己的收尾时,遮到最后一枚;
|
|
564
|
+
只看窗内的读法里私钥块的收尾只有两读的(例如落在没写完的 JSON 秘密字段里)⇒ 遮到窗尾;SSH2 块与其后的孤立收尾之间从一枚记号变成几枚,覆盖不变;
|
|
565
|
+
SSH2 / PEM 起始栅栏成千上万枚、共用其后同一枚收尾的输入整段遮,级数随枚数涨、32 级封顶,耗时为上一版的数倍到百倍)。
|
|
566
|
+
**补偿**:无开关(凭据轴只收紧);done 帧与事件回放同一份产物可作比对基准;到顶的输入看 `server.redact.forensic-level-cap` 计数(每次脱敏至多一次)。
|
|
567
|
+
**升级前做**:无。**回滚**:回到上一版 ⇒ 读法回到旧形,上述形下的那一段重新原样出门;无持久数据。
|
|
568
|
+
|
|
569
|
+
40. **🔴 审批卡的断连重放帧与活铸帧同事实:问行卡信封(SQL `approval_ask.card_json` / File 问账的同一份信封)加一座 `liveFacts`,断连重放的 `approval_request` 帧带活铸帧顶层的同一组卡外事实;本版之前铸的行重放帧带 `liveFactsUnknown: true`(安全轴;wire 加性;持久数据面:存形加性,零 DDL;🔴 多副本先停光旧副本再让本版接流量)**:
|
|
570
|
+
— **本版**:铸卡时活铸帧顶层的十一位卡外事实(`mandated` / `mandate` / `origin` / `boundGrantDigest` / `boundGrants` / `classifierNoRuling` / `boundGrantAbsence` / `approvalCard` / `readRootCandidate` / `probeReason` / `requestedBy`)
|
|
571
|
+
与卡同一条写落进卡信封的 `liveFacts` 座(在场才拷;一位都不在场时是空座;这组事实里有 NUL / 孤代理 ⇒ 不落座,行读作「不知道」—— PostgreSQL 问店存不下逐字的那一份)。
|
|
572
|
+
断流续读、开流 preamble、起服接管行与按问读口内嵌的帧只读这一座 ⇒ 行上记着的每一位与活铸帧逐字同值;起服接管行顶层的 `mandated` / `mandate` / `origin` 读内嵌帧,
|
|
573
|
+
行上没有座 ⇒ 行顶层同带 `liveFactsUnknown: true`。同一只问被另一腿再问(重启续跑、另一只副本)时,重入那一腿的活铸帧与列表行采信行上这一座;
|
|
574
|
+
「本会话放行」的判据只收窄(强制位取两边之并、授予绑定两边一致才认)(行上没有座 ⇒ 这一腿的读数照旧)。
|
|
575
|
+
行上没有这一座(本版之前铸的行)或它读不出 ⇒ 重放帧带 `liveFactsUnknown: true`、十一位一位不带;这时的缺席不是断言,按强制 / 未知渲。活铸帧恒不带它。
|
|
576
|
+
— **不回填**:存量行不改写、不迁移;待决的问被答掉或到期即离开重放集,存量随 ask 期限收敛。零 DDL(卡信封是不透明列)。
|
|
577
|
+
— **滚动升级窗**:上一版的卡信封读者是 `.strict()` 的,读不动带这一座的行。上一版副本碰到本版写下的行:断连重放跳过那只卡(一次 warn)、幂等重入走 park、回决口按「要人」读(拒策略放行)、
|
|
578
|
+
持久规则兑付答素材缺席(规则不落)。都是收紧方向,不会错放;本版副本读上一版写下的行 ⇒ 存量行形(`liveFactsUnknown`)。
|
|
579
|
+
**谁需要**:断线重连的壳与控制台 —— 重连之后的卡与断开前同一张;只经 preamble 到达的后台子代的问第一次带全开卡事实。
|
|
580
|
+
**谁受伤**:滚动升级窗里由上一版副本服务的问(上一句的四形);把重放帧上的缺席读成「不是 X」的消费方,在存量行上读到 `liveFactsUnknown`。
|
|
581
|
+
**补偿**:读 `liveFactsUnknown` 分支(在场 ⇒ 按强制 / 未知渲);上一版 server 既不带事实也不带标记,按服务版本分支。
|
|
582
|
+
**升级前做**:先停光上一版副本再让本版接流量(k8s 多副本用 `Recreate`,或先把旧副本摘出负载均衡)。只排空待决的问不够 —— 本版副本新写的问,还在服务的旧副本照样读不动。
|
|
583
|
+
不这样做也可以:窗里旧副本上的四形都是收紧方向、不会错放,代价是那些卡在旧副本上重连看不到、走 park。
|
|
584
|
+
**回滚**:回到上一版 ⇒ 本版写下的、仍待决的问在旧副本上落滚动升级窗那四形(走 park / 人答);local 车道起服收敛读不出这些行的卡信封,成因词落 `crashed_before_park`(一次兜底计数);
|
|
585
|
+
旧副本新铸的行回到无座形,再升回本版即读作存量行。
|
|
586
|
+
|
|
587
|
+
41. **🔴 自由文本脱敏的名字面:复合凭据名在自由文本的声明形里是名字锚;名字的左界止于前一枚已认出的凭据的终点;不带引号的值里面的赋值照问(行为面;安全;脱敏产物变;带这些赋值的命令不再给常驻放行;部署零动作)**:
|
|
588
|
+
— **本版**:① `api_key` / `apikey` / `api-key` / `access_token` / `refresh_token` / `id_token` / `private_key` / `x-amz-signature` / `x-amz-security-token` / `x-amz-credential` 与 `password` / `secret` / `client_secret` 同档:
|
|
589
|
+
在自由文本 `名=值` / `名: 值` 的声明形(名字带引号、值带引号,或赋值符两侧零空白)上,值是以字母数字起头的字面量时遮(`$VAR` / `%s` / `<占位>` / 表达式 / `None` 不算值)。
|
|
590
|
+
② 名字的左界止于前一枚已认出的凭据(或可读的结构块)的终点:强锚名紧贴在前一枚凭据的尾巴上(`-----END PRIVATE KEY-----password=…`;PGP 收尾栅栏、PuTTY 的 `Private-MAC:` 行、AWS 键 id 同形,中间无分隔)时首遍即遮、再过一遍读数不变 ⇒
|
|
591
|
+
流式 `done` 帧、同步体、运维日志行、活流逐块帧、`GET /v1/runs/:id` 的 run 行与 `GET /v1/runs/:id/events` 回放里的 `text` / `reasoning` / `done` / `tool_end` 行同读(此前单遍口明文、多遍口被遮,见第 16 条)。
|
|
592
|
+
③ 每个赋值符恰问一次,值怎么读不取决于它在不在另一只值里:不带引号的值里面的赋值照问 —— `api_key=abc,password="my secret value"` 里两个值都遮,强锚的不带引号值里夹着的 `…?Sig=password="n "<尾段>` 尾段也遮(此前外层不带引号的值把里面的赋值藏住,里面那一只不认)。
|
|
593
|
+
常驻放行的命令素材闸读同一只脱敏器:命令里带 ① 这类赋值(`curl … -d api_key=<字面量>`)⇒ 判为带凭据,不给常驻放行。
|
|
594
|
+
— **不变**:JSON 字段与 URL 参数位的读法(表里每个名字照旧都是锚);`token` / `key` / `auth` / `sig` / `signature` / `sas` 在自由文本里仍只是常用词(只在结构位置上是锚);
|
|
595
|
+
赋值符两侧带空白的不带引号形(`api_key = abc`)不是声明形;名字按整名认(`DB_PASSWORD` / `foo-api_key` 是另一个名字)。
|
|
596
|
+
— **存量行**:回放读面对 run 行与 `text` / `reasoning` / `done` 行再过一遍脱敏 ⇒ 升级前落下的这些行按本版读法遮;`tool_end` 行回放读面不再过(只剥媒体字节)⇒ 升级前写下的这几形照旧明文,升级后新写的行照遮。
|
|
597
|
+
— **仍不遮**:名字整个落在前一枚已认出凭据的值里(以字母数字收尾的令牌后面紧贴强锚名,`ghp_…password=<值>`)时令牌照遮、`<值>` 明文,各出口同读;中间有分隔照遮。
|
|
598
|
+
**谁需要**:prompt / 工具输出 / 日志 / 结果里出现这些赋值形的部署 —— 此前 `api_key=<字面量>` 一族在自由文本里原样出门,紧贴形在单遍口上原样出门。
|
|
599
|
+
**谁受伤**:① 关键字参数透传(`f(api_key=api_key)`)的变量名换成记号;② 带这些赋值的命令不再给常驻放行(每次问人);③ 脱敏计数上升;④ 不带引号的值里面的赋值现在也遮(上一版跳过),外层值与里面那一只相交时两枚记号相邻、里面那一只的名字随外层记号盖住;⑤ 源码与配置片段里的对象字面量(`apiKey: "…"` / `access_token: "…"`;名字大小写不敏感,值带引号即声明形)的值换成记号,测试夹具与示例代码里的假值同样;⑥ 赋值符密集的长输入脱敏变慢,仍与长度同阶(每几个字符一个赋值符的 40 万字符输入约为上一版的 2–8 倍,约 0.1 s;散文与长值不变);⑦ 这些名字后面、本来由值自身形状认出的值(`api_key=ghp_…` / `access_token=AKIA…` / `API_KEY=sk-…`)记号从 `«redacted:<种类>»` 变成强锚值的 `«redacted»`(与 `password=` 同读),`redactions_applied_total` 的 `pattern` 随之由种类名移到 `redacted`;
|
|
600
|
+
按字节比对脱敏产物的消费方在这几形上读到差。
|
|
601
|
+
**补偿**:赋值符两侧带空白(`api_key = x`)不是声明形、不作锚(既有判据);新遮的值记在 `redactions_applied_total{pattern="redacted",arm="full"}`(与 `password=` 一族同一格),按 `arm` 维与弱证据臂分开读;
|
|
602
|
+
无开关(凭据轴只收紧);done 帧与事件回放同一份产物可作比对基准。
|
|
603
|
+
**升级前做**:无。**回滚**:回到上一版 ⇒ 上述几形回到上一版读法(复合凭据名在自由文本里只靠值自身形状、紧贴形在单遍口上明文、不带引号的值里面的赋值不问);无持久数据。
|
|
604
|
+
|
|
605
|
+
42. **运行时依赖 `@modelcontextprotocol/server` 2.4.0(npm 消费方安装时一并装上;部署零动作;镜像里的回声 MCP 可作探针)**:
|
|
606
|
+
— **此前**:镜像里的回声 MCP 脚本(`/app/scripts/mcp-echo.mjs`)借引擎带进安装树的 MCP SDK v1 跑;本包 `dependencies` 里没有 MCP 服务端包。
|
|
607
|
+
— **本版**:引擎 7.61.0 不再把 SDK v1 带进安装树,回声脚本改依赖本包自己声明的 `@modelcontextprotocol/server` 2.4.0(`package.json` 的 `dependencies`);
|
|
608
|
+
镜像照旧把脚本拷到 `/app/scripts/mcp-echo.mjs`。`npm install @sema-agent/server` 一并装上这只包;服务进程本身不加载它(只有回声类脚本用:镜像回声 + `scripts/drill/mcp-principal-echo.mjs`)。
|
|
609
|
+
**谁需要**:用镜像里的回声 MCP(stdio,`bun /app/scripts/mcp-echo.mjs`;工具 `echo` / `env_check`)探 MCP 接线与 `envRefs` 注入的部署。
|
|
610
|
+
**谁受伤**:只装 npm 包的消费方多装一只依赖 —— 这只包 7 023 377 字节、117 个文件(其中源图 4 305 531 字节);它的两只依赖 `@modelcontextprotocol/core` 2.4.0 与 `zod`(^4.2.0)
|
|
611
|
+
已随引擎 / 契约包在安装树里(去重),净增只有这一只包。npm 包不带回声脚本(`files` 不含 `scripts/mcp-echo.mjs`),这只依赖在 npm 安装里没有读者。
|
|
612
|
+
**补偿**:无(本版不拆成可选依赖)。**升级前做**:无。**回滚**:回到上一版 ⇒ 依赖表回到上一版(上一版的回声脚本读引擎带进来的 SDK v1);无持久数据。
|
|
613
|
+
|
|
614
|
+
43. **更正(7.141.0 节「谁受伤 ①」,文书;零行为变化)**:`DB_BACKEND=local` 上,回滚到上一版后上一版读本版写过的 `session-incarnations.json` 不是「严格拒启」—— 严格读在第一次用到那只边档时才拒(`ensureLoaded`),
|
|
615
|
+
所以读不出的那一形(≤ 7.140.0 的副本附着 ≥ 7.141.0 写下的数据根 —— 7.141.0 起每格多 `createdAt` / `forkedFrom` 两键;本版边档形零改,7.141.0 / 7.142.0 读得了本版写的根)用户面是每个碰到它的请求答 500 `internal.error`(引擎日志:边档 malformed),服务进程本身起得来。规则不变:**不许降级附着;回滚 = 恢复升级前的数据根备份**。
|
|
616
|
+
「数据根比代码新 ⇒ 起服拒 + 机器码」(与 SQL 后端 `config.schema_mismatch` 同一条律)另票、不在本版。无三问(更正条)。
|
|
617
|
+
|
|
10
618
|
## 7.142.0 —— `onError` 汇点的日志行一律带引擎错自带的机器码 `code`(码须合码形,否则省略;记忆事故行与起服面三只引擎座的无码占位改为键缺席;`mcp_server_unavailable` / `a2a_peer_unavailable` / `task_degraded` / `prompt_composition_warning` / `prompt_cache_break` / `runner_error` 多结构化字段;运维面;日志形加性) · 一次性兜底 warn 由 stderr 裸文本行改为一行 JSON 日志(`msg` 逐字 `[sema] fail-open: <tag>`,字段 `{ tag, count }`;运维面;日志形变更) · 订正 7.139.0 节第 16 条:停驻赎回在认领之前判卡的主体的车道裁定,不被许可本部署车道的主体对停驻卡的 approve / deny 答 409 `resume_blocked_by_policy`(文字订正;零行为变更) · 折码的运维线索:读面上的再读改走 fail-open 的计数与一次 warn、长得像码的秘密报 `<not-a-code>`(订正 7.141.0 节第 30 条读面那一半;运维面;日志形变更;安全) · 起服面运维行里的异常句改经出口座:凭据形遮掉、控制字符剥掉、界 200 码元(运维面;日志形变更;安全) · 会话列表不再漏掉存档读不出的会话:行带加性键 `unreadable: { errorCode }`(行为面;wire 加性) · 🔴 记忆同步中心必须声明同步身份 `MEMORY_SYNC_SERVE_IDENTITY`(没声明 ⇒ 同步口 501);中心侧同步口拒不是同步身份的 `peer`(400)与不是本中心的 `peer`(409)(BREAKING 部署面;升级序先客户端后中心;wire 加性) · 会话记忆同步触发口 `POST /v1/sessions/:id/memory/sync`(wire 加性);同步一轮从不整轮失败、客户端侧轮级日志行 `memory_sync_failed` 退役(运维面;中心同步口答 500 的那一臂照旧发同名行);同步层名带凭据形拒启(行为收紧);`ServiceDeps.memorySyncLeg` 多要两成员(嵌入方类型面 BREAKING) · 隔离车道的附件改由恢复点放进工作区(行为修复) · 项目包:`application/vnd.sema.project-bundle` 上传、绑进隔离车道的会话作为工作区的种子(wire 加性:一个受理的 mime 值 + 四个新拒码;嵌入方 `ServiceDeps.taskAttachmentStore` 类型面 BREAKING) · 附件一经绑定不再改绑(行为收窄;`409 attachment.bound_elsewhere`) · local 车道有序关停截断的审批卡:`crashConverged[].cause` 与决断口同一个词,前世 `PARKING` 孤儿起服即 `VOID`(行为面;wire 值变化;零新键、零新词;审计收敛行写不进起服拒,行为收紧) · 嵌入方(自建 `StoreBackend`):`StoreBackend.checkpointReadView()` 多交一口 `findCheckpointCandidatesForAsk()`(BREAKING,类型面;零别名) · 结果上组合腿的自由文本过脱敏(`verification.findings[]` / `evidence`、`attempts[].diagnostics` / `gateError`;completed 因由的 `finishReasonUnknown` 过回声形状闸;行为面;安全;wire 值可能变) · `GET /v1/runs/:id/events` 的停驻尾帧一律是状态帧:挂起前的 `model_usage` 行写在 `suspended` / `needs_review` 之前,`verify:true` 的停驻与不带 `verify` 的停驻同序(行为面;wire 事件序;订正 7.141.0 节第 32 条 ①) · 同键重放的同步体改成首答的信封 + `replay: true`(BREAKING 对按重放形解析的消费方;wire 形;订正 7.141.0 节第 32 条 ②) · http hook 名单在拨出点执行:`settings.allowedHttpHookUrls` 不放行 ⇒ http hook 不发出、`settings.httpHookAllowedEnvVars` 与条目 `allowedEnvVars` 取交(安全;行为面;wire 加性) · 🔴 问账行成因拆成两列:SQL 后端 `approval_ask.denied_reason` 改名 `ending_cause`、加列 `park_trigger`,local 问账日志整本重写一次(本服务起服时自己改;升级前备份、先停光旧副本;回滚 = 恢复备份或手工三句;嵌入方类型面 BREAKING;wire 零变化) · 沙箱 git 平面接上有效配置块 `sandboxGit`(中心投影、热生效;坏块读作没有 origin + 一行 warn `web_admin_sandbox_git_refused`;本版平面读数不变;运维面) · run 行记下令牌化身号(零 DDL;部署零动作) · `ServiceDeps.sandboxGitPlane` 由值改为读函数(嵌入方类型面 BREAKING) · 自由文本脱敏的两处已知漏形写明:复合凭据名(`api_key=` 一族)的值、紧贴前一枚凭据尾巴的强锚值(安全披露;零行为变更) · 用户面通告多一键 `eventId`、live 帧带 `id:` 行;有账本口的腿断流后通告与文件卡的死直写不再记丢帧,文件卡账本孪生写失败改记计数(wire 加性;运维面计数口径变化)
|
|
11
619
|
|
|
12
620
|
1. **`onError` 汇点的日志行一律带引擎错自带的机器码 `code`(运维面;日志形加性,记忆事故行与起服面三只引擎座的无码占位除外;部署零动作)**:
|