@sema-agent/server 7.140.0 → 7.142.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 +505 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +142 -25
- package/dist/approval-ask-audit-store.d.ts +54 -38
- package/dist/approval-ask-audit-store.js +58 -39
- package/dist/approval-batch-census.d.ts +27 -0
- package/dist/approval-batch-census.js +27 -0
- package/dist/approval-card.d.ts +39 -24
- package/dist/approval-card.js +6 -3
- package/dist/approval-crash-convergence.d.ts +17 -7
- package/dist/approval-crash-convergence.js +94 -22
- package/dist/approval-deny-reasons.d.ts +34 -30
- package/dist/approval-deny-reasons.js +21 -6
- package/dist/approval-policy-settlement.d.ts +1 -1
- package/dist/approval-reconciler.d.ts +33 -1
- package/dist/approval-reconciler.js +43 -40
- package/dist/approval.d.ts +15 -0
- package/dist/approval.js +10 -0
- package/dist/audit.d.ts +4 -2
- package/dist/audit.js +2 -2
- package/dist/auth-bridge.d.ts +9 -6
- package/dist/auth-bridge.js +9 -3
- package/dist/boot/adoption.js +2 -1
- package/dist/boot/budget-tracing.d.ts +16 -0
- package/dist/boot/budget-tracing.js +10 -6
- package/dist/boot/device-lane.d.ts +11 -0
- package/dist/boot/device-lane.js +16 -0
- package/dist/boot/engine-lease.d.ts +24 -3
- package/dist/boot/engine-lease.js +9 -2
- package/dist/boot/execution-env.d.ts +24 -4
- package/dist/boot/execution-env.js +34 -27
- package/dist/boot/execution-lane.js +2 -1
- package/dist/boot/exit-boundary.js +5 -4
- package/dist/boot/memory-boundary.d.ts +2 -2
- package/dist/boot/memory-consolidation.d.ts +1 -1
- package/dist/boot/memory-consolidation.js +3 -2
- package/dist/boot/parked-revive-gate.js +2 -1
- package/dist/boot/permission-rules-audit.d.ts +0 -28
- package/dist/boot/permission-rules-audit.js +2 -1
- package/dist/boot/read-deny-anchor-audit.js +2 -1
- package/dist/boot/reapers.d.ts +2 -2
- package/dist/boot/reapers.js +4 -3
- package/dist/boot/resolve-spec.js +18 -6
- package/dist/boot/retention-lane.js +5 -3
- package/dist/boot/runner-deps.js +16 -13
- package/dist/boot/runtime-caps.js +3 -2
- package/dist/boot/session-faces.d.ts +1 -1
- package/dist/boot/session-faces.js +8 -6
- package/dist/boot/shutdown.js +8 -2
- package/dist/boot/stage-04-stores.js +3 -2
- package/dist/boot/stage-05-execution-env.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.js +11 -7
- package/dist/boot/stage-06-runners.d.ts +1 -3
- package/dist/boot/stage-06-runners.js +3 -2
- package/dist/boot/stage-07-capability-layer.d.ts +1 -2
- package/dist/boot/stage-07-capability-layer.js +10 -11
- package/dist/boot/stage-08-reapers.d.ts +1 -2
- package/dist/boot/stage-08-reapers.js +3 -2
- package/dist/boot/stage-09-leader.d.ts +1 -2
- package/dist/boot/stage-10-http-server.d.ts +1 -2
- package/dist/boot/stage-10-http-server.js +6 -4
- package/dist/boot/stores.js +13 -6
- package/dist/boot/web-admin.js +18 -17
- package/dist/boot/webfetch-summarize-lane.js +2 -1
- package/dist/boot/workflow-orchestration.js +3 -2
- package/dist/capabilities/builtin-tools.d.ts +2 -1
- package/dist/capabilities/builtin-tools.js +2 -4
- package/dist/capabilities/composite-members.d.ts +2 -1
- package/dist/capabilities/composite-members.js +2 -1
- package/dist/capabilities/scenarios.d.ts +1 -1
- package/dist/capability-facts.d.ts +33 -0
- package/dist/capability-facts.js +32 -0
- package/dist/card-void.d.ts +38 -0
- package/dist/card-void.js +23 -0
- package/dist/config-catalog.js +12 -8
- package/dist/config-provider.d.ts +13 -13
- package/dist/config-provider.js +19 -33
- package/dist/config-types.d.ts +39 -10
- package/dist/config.d.ts +6 -0
- package/dist/config.js +72 -49
- package/dist/delegated-session-owner.d.ts +21 -19
- package/dist/delegated-session-owner.js +1 -1
- package/dist/device-store.d.ts +7 -0
- package/dist/device-store.js +3 -0
- package/dist/execution-config-root.d.ts +22 -0
- package/dist/execution-config-root.js +35 -0
- package/dist/execution-lane-caps.d.ts +50 -2
- package/dist/execution-lane-caps.js +90 -13
- package/dist/execution-placement.d.ts +3 -0
- package/dist/execution-placement.js +7 -0
- package/dist/fleet/drain-entry.d.ts +3 -0
- package/dist/fleet/fleet-bus.d.ts +6 -3
- package/dist/hooks/hook-runner.d.ts +6 -0
- package/dist/hooks/hook-runner.js +30 -1
- package/dist/hosted-posture.d.ts +8 -0
- package/dist/hosted-posture.js +4 -0
- package/dist/http/admission.js +3 -3
- package/dist/http/caller-trust.d.ts +3 -2
- package/dist/http/caller-trust.js +2 -1
- package/dist/http/dispatch.js +8 -2
- package/dist/http/execution-context.d.ts +2 -2
- package/dist/http/idempotency.d.ts +1 -1
- package/dist/http/live-frame.d.ts +24 -0
- package/dist/http/live-frame.js +16 -0
- package/dist/http/principal-gate.d.ts +3 -1
- package/dist/http/principal-gate.js +17 -8
- package/dist/http/resume-legs.js +42 -29
- package/dist/http/route-table.js +4 -0
- package/dist/http/routes/approvals-assistant.js +1 -0
- package/dist/http/routes/attachments.js +18 -0
- package/dist/http/routes/capabilities.js +10 -6
- package/dist/http/routes/diagnostics.d.ts +0 -19
- package/dist/http/routes/diagnostics.js +16 -2
- package/dist/http/routes/memory-bundle.d.ts +2 -2
- package/dist/http/routes/memory-bundle.js +1 -1
- package/dist/http/routes/memory-compliance.js +1 -1
- package/dist/http/routes/memory-policy.js +27 -7
- package/dist/http/routes/run-permission-mode.d.ts +75 -0
- package/dist/http/routes/run-permission-mode.js +170 -0
- package/dist/http/routes/runs.js +3 -3
- package/dist/http/routes/session-memory-sync.d.ts +63 -0
- package/dist/http/routes/session-memory-sync.js +157 -0
- package/dist/http/routes/session-sync.d.ts +3 -6
- package/dist/http/routes/session-sync.js +7 -2
- package/dist/http/routes/sessions-list.d.ts +2 -1
- package/dist/http/routes/sessions.js +5 -4
- package/dist/http/routes/tasks.js +70 -71
- package/dist/http/run-read-face.d.ts +7 -0
- package/dist/http/run-read-face.js +10 -4
- package/dist/http/send.d.ts +6 -1
- package/dist/http/send.js +10 -3
- package/dist/http/server.d.ts +20 -7
- package/dist/http/server.js +2 -4
- package/dist/http/sse-log.d.ts +3 -8
- package/dist/http/stored-body-replay.d.ts +3 -3
- package/dist/http/stored-body-replay.js +3 -1
- package/dist/http/submit-replay.d.ts +4 -3
- package/dist/http/submit-replay.js +2 -2
- package/dist/http/sync-submit-body.d.ts +21 -4
- package/dist/http/sync-submit-body.js +13 -0
- package/dist/identity-source.d.ts +21 -2
- package/dist/identity-source.js +6 -0
- package/dist/instruction-source-notice.d.ts +7 -0
- package/dist/instruction-source-notice.js +6 -6
- package/dist/mcp-assertion-header.d.ts +4 -0
- package/dist/mcp-assertion-header.js +5 -0
- package/dist/memory-incident-sink.d.ts +19 -6
- package/dist/memory-incident-sink.js +8 -4
- package/dist/memory-posture.d.ts +1 -1
- package/dist/memory-scope.d.ts +4 -4
- package/dist/memory-scope.js +1 -1
- package/dist/memory-sync-client.d.ts +35 -23
- package/dist/memory-sync-client.js +122 -52
- package/dist/memory-sync-identity.d.ts +24 -0
- package/dist/memory-sync-identity.js +57 -0
- package/dist/memory-sync.d.ts +7 -1
- package/dist/memory-sync.js +6 -3
- package/dist/observability/fail-open.d.ts +57 -12
- package/dist/observability/fail-open.js +50 -9
- package/dist/observability/metrics.js +0 -1
- package/dist/observability/run-terminal.d.ts +93 -31
- package/dist/observability/run-terminal.js +175 -171
- package/dist/observability/secret-env-scrub.d.ts +20 -1
- package/dist/observability/secret-env-scrub.js +14 -0
- package/dist/orchestration/workflow-completion-inbox.d.ts +5 -2
- package/dist/orchestration/workflow-completion-inbox.js +13 -5
- package/dist/orchestration/workflow-notify-journal.d.ts +5 -3
- package/dist/orchestration/workflow-notify-journal.js +2 -1
- package/dist/permission-mode-admission.d.ts +68 -0
- package/dist/permission-mode-admission.js +23 -0
- package/dist/permission-rule-list.d.ts +55 -6
- package/dist/permission-rule-list.js +52 -5
- package/dist/plugins/approval-ask-store-file.d.ts +14 -4
- package/dist/plugins/approval-ask-store-file.js +48 -7
- package/dist/plugins/approval-ask-store-memory.d.ts +2 -1
- package/dist/plugins/approval-ask-store-memory.js +9 -8
- package/dist/plugins/approval-ask-store-sql.d.ts +42 -10
- package/dist/plugins/approval-ask-store-sql.js +49 -19
- package/dist/plugins/caching-session-store.d.ts +6 -0
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +65 -17
- package/dist/plugins/checkpoint-store-sql.js +74 -3
- package/dist/plugins/device-store-sql.d.ts +5 -2
- package/dist/plugins/device-store-sql.js +4 -1
- package/dist/plugins/execution-placement-sql.d.ts +11 -1
- package/dist/plugins/execution-placement-sql.js +12 -1
- package/dist/plugins/file-run-store.d.ts +7 -2
- package/dist/plugins/file-run-store.js +12 -2
- package/dist/plugins/fork-routing-session-store.d.ts +10 -32
- package/dist/plugins/fork-routing-session-store.js +2 -61
- package/dist/plugins/k8s-exec-protocol.d.ts +4 -1
- package/dist/plugins/k8s-exec-protocol.js +6 -1
- package/dist/plugins/local-checkpoint-store.d.ts +10 -1
- package/dist/plugins/local-checkpoint-store.js +22 -0
- package/dist/plugins/local-session-store.d.ts +260 -39
- package/dist/plugins/local-session-store.js +582 -57
- package/dist/plugins/local-session-window.d.ts +17 -3
- package/dist/plugins/local-session-window.js +7 -13
- package/dist/plugins/local-task-attachment-store.d.ts +12 -2
- package/dist/plugins/local-task-attachment-store.js +67 -43
- package/dist/plugins/memory-key-guards.d.ts +3 -3
- package/dist/plugins/memory-run-store.d.ts +7 -2
- package/dist/plugins/memory-run-store.js +12 -2
- package/dist/plugins/one-time-migrations.d.ts +68 -2
- package/dist/plugins/one-time-migrations.js +120 -4
- package/dist/plugins/pg-pool.js +3 -2
- package/dist/plugins/pg-session-storage.d.ts +2 -0
- package/dist/plugins/pg-session-storage.js +3 -2
- package/dist/plugins/remote-env-e2b.d.ts +47 -7
- package/dist/plugins/remote-env-e2b.js +242 -46
- package/dist/plugins/remote-env-k8s.d.ts +51 -6
- package/dist/plugins/remote-env-k8s.js +234 -44
- package/dist/plugins/remote-env-local-docker.d.ts +40 -14
- package/dist/plugins/remote-env-local-docker.js +127 -33
- package/dist/plugins/run-store-sql.d.ts +11 -3
- package/dist/plugins/run-store-sql.js +13 -4
- package/dist/plugins/sandbox-read-floor.d.ts +273 -0
- package/dist/plugins/sandbox-read-floor.js +608 -0
- package/dist/plugins/session-ownership.d.ts +2 -1
- package/dist/plugins/session-placement.d.ts +17 -4
- package/dist/plugins/session-placement.js +2 -1
- package/dist/plugins/session-store.d.ts +18 -20
- package/dist/plugins/session-store.js +4 -12
- package/dist/plugins/store-backend.d.ts +41 -7
- package/dist/plugins/store-backend.js +22 -4
- package/dist/plugins/store-contracts.d.ts +35 -3
- package/dist/plugins/store-contracts.js +3 -0
- package/dist/plugins/task-attachment-store.d.ts +112 -14
- package/dist/plugins/task-attachment-store.js +221 -28
- package/dist/plugins/tidb-pool.js +2 -1
- package/dist/plugins/tidb-session-store.d.ts +4 -1
- package/dist/plugins/tidb-session-store.js +3 -2
- package/dist/plugins/workspace-fill.d.ts +60 -0
- package/dist/plugins/workspace-fill.js +106 -0
- package/dist/project-bundle.d.ts +38 -0
- package/dist/project-bundle.js +609 -0
- package/dist/run-cancel-context.d.ts +34 -0
- package/dist/run-cancel-context.js +7 -0
- package/dist/run-local.js +2 -8
- package/dist/runs.d.ts +39 -12
- package/dist/runs.js +69 -55
- package/dist/sandbox-egress-policy.d.ts +4 -1
- package/dist/sandbox-egress-policy.js +3 -1
- package/dist/sandbox-git-plane.d.ts +31 -12
- package/dist/sandbox-git-plane.js +24 -4
- package/dist/security.d.ts +11 -2
- package/dist/security.js +8 -0
- package/dist/server-secret-env.d.ts +2 -1
- package/dist/server-secret-env.js +2 -4
- package/dist/session-error-wire.d.ts +46 -4
- package/dist/session-error-wire.js +23 -0
- package/dist/session-incarnation.d.ts +9 -3
- package/dist/session-sync-kernel.d.ts +42 -1
- package/dist/session-sync-kernel.js +17 -0
- package/dist/session-sync.js +16 -4
- package/dist/sql-engine-coordinates.d.ts +49 -0
- package/dist/sql-engine-coordinates.js +27 -0
- package/dist/standing-answer-grant.d.ts +31 -2
- package/dist/standing-answer-grant.js +14 -2
- package/dist/store-posture.d.ts +1 -1
- package/dist/task-a2a.d.ts +1 -1
- package/dist/task-mcp.d.ts +1 -1
- package/dist/task-settings.d.ts +62 -27
- package/dist/task-settings.js +105 -29
- package/dist/terminal.d.ts +97 -20
- package/dist/terminal.js +107 -18
- package/dist/tool-approval.d.ts +4 -3
- package/dist/tool-approval.js +12 -14
- package/dist/trace/core-keyset-guard.d.ts +196 -2
- package/dist/trace/engine-notice-wire.d.ts +8 -2
- package/dist/trace/engine-notice-wire.js +4 -2
- package/dist/trace/exit-seat.d.ts +9 -1
- package/dist/trace/exit-seat.js +1 -0
- package/dist/trace/ledger-sink.d.ts +8 -4
- package/dist/trace/ledger-sink.js +2 -2
- package/dist/trace/model-segment.d.ts +2 -2
- package/dist/trace/project.d.ts +18 -1
- package/dist/trace/project.js +16 -0
- package/dist/trace/redact.js +323 -90
- package/dist/trace/self-minted-wire.d.ts +419 -4
- package/dist/trace/self-minted-wire.js +145 -0
- 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 +8 -0
- package/dist/verifier-pause-card.js +19 -0
- package/dist/web-admin-client/apply-effective.d.ts +5 -7
- package/dist/web-admin-client/apply-effective.js +22 -2
- package/dist/web-admin-client/candidate-gate.d.ts +1 -1
- package/dist/web-admin-client/effective-keys.js +2 -0
- package/dist/web-admin-client/read-warnings.d.ts +2 -2
- package/dist/web-admin-client/types.d.ts +4 -0
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +3 -2
- package/package.json +2 -2
- package/wire-changes/server@7.141.0.json +367 -0
- package/wire-changes/server@7.142.0.json +639 -0
package/MIGRATION.md
CHANGED
|
@@ -7,6 +7,511 @@
|
|
|
7
7
|
> ⚠️ 完整清单在仓库根 `CHANGELOG.md`——它**不随 npm tarball 出包**(本文件随包)。看完整迁移窗的
|
|
8
8
|
> 权威姿势是源码 tag diff:`git diff v<旧>..v<新>`(每版都推 `v<版本>` tag);npm 包页也镜像 CHANGELOG。
|
|
9
9
|
|
|
10
|
+
## 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
|
+
|
|
12
|
+
1. **`onError` 汇点的日志行一律带引擎错自带的机器码 `code`(运维面;日志形加性,记忆事故行与起服面三只引擎座的无码占位除外;部署零动作)**:
|
|
13
|
+
引擎把「运维该按码告警」的事交给本服务时,码挂在错对象上(`err.code`),句子里不一定有那串码 —— 例:MCP 服务器没申报 `tools` 能力而部署声明的 `allowTools` 非空,引擎铸 `mcp.tools_capability_absent`,句子只说 `declared no "tools" capability`。
|
|
14
|
+
此前只有 `runner_config_advisory` 一条行把码写成结构化字段;`mcp_server_unavailable` / `a2a_peer_unavailable` / `task_degraded` / `prompt_composition_warning` / `prompt_cache_break` / 兜底 `runner_error` 把码折进 `info` / `err` 散文里。
|
|
15
|
+
现在这七条行同一条律:错带非空串 `code`、且它**是码**(不超过 64 字符的短 token:字母、数字与 `_ . : -`,并且秘密脱敏器原样放过它 —— `sk-…` / `AKIA…` / `ghp_…` 这类长得像码的凭据不是码)⇒ 行里多结构化字段 `code`(逐字);读不出(没有 / 不是串 / 空串 / 读取时抛)或不是码 ⇒ 该键缺席,不补占位。
|
|
16
|
+
「是不是码」只问一只判官(`codeFieldOf` 里的读口 + 判官;折码运维线索与执行车道占位读的故障词读的是同一只):`code` 是别人写的串,一句话或一把凭据都能挂在上面;wire 上同一个值在 message 尾注里被脱敏器遮掉,日志行与指标标签若照印就是日志露、wire 遮。`rewind_snapshot_failed` 早已带码,形不动。记忆引擎事故行(`memory_engine_incident` 与计数 `memory_engine_incident_total`)读同一只判官:此前它自写一份读口(码是什么都照写,无码写 `code:null` / 标签 `code="none"`),现在是码才带,无码或不是码 ⇒ `code` 键与 `code` 标签缺席,不再写 `null` / `none`。起服面三只 operator 面引擎座(`memory_compliance_incident` / `memory_origin_incident` / `memory_consolidation_incident`)同判官:此前各写一份 `code: err.code ?? null`,现在三座共用一只落点工厂、`code` 位读同一只判官,无码或不是码 ⇒ 键缺席;事件名与 `detail` 句不变。子代额外工具故障行 `subagent_extra_tools_error` 的 `code`(引擎的 `config.extra_tool_names`,或部署工厂自己抛的错)同判官:此前是串就原样进行,现在不是码 ⇒ 键缺席。`info` / `err` 句的级别与计数器一字未动;句文本已按本节第 5 条改走运维文本座(凭据形遮掉、控制字符剥掉、界 200 码元),不再是抛出物原文。
|
|
17
|
+
读面收紧(`runner_config_advisory` 行与它的指标标签 `code`):码是空串、不是码(超长 / 含空白 / 凭据形)、或抛出物不是 `Error` 实例时,此前写成 `code:""` / 原样的串 / 读抛出物上的串码,现在键缺席(与其余六条同一读口、同一判官)。已读到的引擎告警码(`config.*` / `mcp.*`)都是 `Error` 实例上的短 token 非空串,不受影响。
|
|
18
|
+
**谁需要**:按码(而不是按句子)路由引擎运维告警的日志管道。**谁受伤**:无(加性字段);只有按 `code:""`、按「非 `Error` 抛出物上的 `code`」、按「不是码的串」(超长 / 含空白 / 凭据形),按记忆事故行的 `code:null` / 计数标签 `code="none"`,按起服面三只引擎座的 `code:null`,或按 `subagent_extra_tools_error` 里不是码的 `code` 串匹配的规则会失配。**出路**:告警规则改按 `code` 字段匹配;无需动作(要找「没有码的记忆事故」或「没有码的起服面引擎座事件」就按 `code` 键 / 标签缺席匹配)。**回滚**:回到上一版即回到旧行形。
|
|
19
|
+
|
|
20
|
+
2. **一次性兜底 warn(每进程每 tag 一次)由 stderr 裸文本行改为一行 JSON 日志(运维面;日志形变更;部署零动作)**:
|
|
21
|
+
此前 `[sema] fail-open: <tag>` 作为**裸文本**直写 stderr,而日志器写 stderr 的日志都是 JSON 行 —— 把 stderr 当 JSON 行流收的日志管道,在每个 tag 第一次走兜底时撞上一行解析不了的文本。
|
|
22
|
+
现在同一句话(逐字)做一行 JSON 日志的 `msg`:`{"ts":…,"level":"warn","msg":"[sema] fail-open: <tag>","tag":"<tag>","count":<n>}`,字段闭集 `{ tag, count }`(`count` = 此刻为止该 tag 的累计命中数)。这一行不随 `LOG_LEVEL`(级别钉在 warn)、
|
|
23
|
+
不依赖日志器装配(boot 之前的兜底同样出),仍是每进程每 tag 一次;这一行不再是裸文本(stderr 上别处的非 JSON 文本,如引擎的 `process.emitWarning`,不在本条范围)。结构化 `fail_open` 日志行、`fail_open_total{tag,cls}` 指标、`SEMA_FAILOPEN_PROBE` 探针文件三件一字未动。
|
|
24
|
+
**谁需要**:把 stderr 当 JSON 行流收的日志管道;按文字子串找这一行的黑盒断言(文字没变,照读)。**谁受伤**:锚住整行 / 行首的匹配(`^\[sema\] fail-open:`)会失配。**出路**:改按子串 `[sema] fail-open: <tag>` 或 JSON 的 `msg` 字段匹配;要计数读 `fail_open_total{tag}`。**回滚**:回到上一版即回到裸文本行。
|
|
25
|
+
|
|
26
|
+
3. **停驻赎回在认领之前判卡的主体的车道裁定:不被许可本部署车道的主体,对停驻卡的 approve / deny 答 `409 resume_blocked_by_policy`(7.139.0 起的行为,当时未披露;本条是文字订正,零行为变更)**:
|
|
27
|
+
`POST /v1/approvals/:sessionId/decide` 复活停驻的后台子代之前,走与续跑家族同一只执行上下文解析器:根会话行那一格 → 车道 → **卡的主体**(停驻那一刻 checkpoint 上的主体,不是发决定的人)的车道裁定。
|
|
28
|
+
中心对这位主体的裁定 `required: true` 而 `allowedLanes` 不含本部署的车道 ⇒ `409 resume_blocked_by_policy`,体 `blockedBy: "execution_lane_not_allowed"` · `allowedLanes` · `lane` · `retriable: true`;
|
|
29
|
+
能复活的停驻行上 approve 与 deny 同答(deny 也要复活子代、让它在这条车道上读到拒绝再往下跑);停驻行不被认领、卡仍待决、被门的工具零执行。7.138.x 及以前这一形照常复活。
|
|
30
|
+
复活不了的停驻行(行上没有根会话锚)在这一判之前分流、不判车道:approve 照旧 `409 decide.row_unrevivable`,deny 照旧作废这张卡(200)。
|
|
31
|
+
续跑家族的任务级入口(`/answer` · `/plan_review` · `/wake` · 任务级 `/decide`)早已同判同折,码与体不变(7.139.0 节第 16 条的「这些拒」包括这一只)。
|
|
32
|
+
**谁受伤**:中心在任务停驻之后收窄了某位主体车道的部署 —— 那位主体停驻的卡决不动;SLA 拒扫不替停驻卡代决;拒句尾点名的 `POST /v1/runs/:id/cancel` 只结算 run 行,停驻的后台子代没有 run 行。
|
|
33
|
+
**出路**:在中心把本部署的车道放回这位主体的 `allowedLanes` 再决(卡一直待决,放回之后照常决);不打算放回 ⇒ 会话属主或 operator 发 `POST /v1/sessions/:id/children/retire`,
|
|
34
|
+
结清以该会话为根的全部后台子代(停驻的作废卡、在跑的停掉;是整棵树,不是单张卡)。
|
|
35
|
+
**升级前做**:无。**回滚**:无需(只改文字)。
|
|
36
|
+
|
|
37
|
+
4. **折码的运维线索(订正 7.141.0 节第 30 条读面那一半):读面上的再读不再出 `[terminal] outward_failure_code_folded` 行,改计数 + 每进程一次 warn;长得像码的秘密报 `<not-a-code>`(运维面;日志形变更;安全;部署零动作)**:
|
|
38
|
+
7.141.0 节第 30 条说,读面上的再读(`at=run.result` / `at=ev.done.result`)同一读面同一原码每进程只一行(表有界,1024 条)。本版起这两种行不再出现 ——
|
|
39
|
+
读面上的再读按**被折的码座**计数:`fail_open_total{tag="server.terminal.stored-result-code-folded",cls="F"}` 每折一座加一(一次读里,因由码 `terminal.code` 一座、cascade 每一级的 `attempts[].errorCode` 各一座 —— 折了三座就加三,不是加一);每进程一次结构化 warn `fail_open`(`tag` 同上,`detail` = 第一次被折的那一座的字段句
|
|
40
|
+
`original=<码 | <not-a-code>> outward=internal.store_error messageBytes=<n> at=<run.result | ev.done.result>`)与一次性兜底 warn 那一行(`msg` = `[sema] fail-open: server.terminal.stored-result-code-folded`,行形见第 2 条);
|
|
41
|
+
配了 `SEMA_FAILOPEN_PROBE` 的部署,探针文件每折一座一行。`at=exit` 那一行(结果第一次离开引擎,每折一座一行)不变。
|
|
42
|
+
另:码形之内、却被秘密脱敏器认作凭据形的码(`sk-…` / `AKIA…` 之类)在 `original=` 处报 `<not-a-code>`,不再报原值(写口那一行与读面的 `detail` 同判)。
|
|
43
|
+
**谁受伤**:按 `[terminal] outward_failure_code_folded` 且 `at=run.result` / `at=ev.done.result` 写的告警 / 看板(那两种行不再出现);按 `original=` 原值聚合、而那个值本就是秘密的规则(改报 `<not-a-code>`)。
|
|
44
|
+
**出路**:读面上的再读改看计数器 `fail_open_total{tag="server.terminal.stored-result-code-folded"}`(或 warn `fail_open` 的 `tag`);要逐座明细就开探针文件。**回滚**:回到 7.141.0 即回到那两种行(仍不带失败句原文)。
|
|
45
|
+
|
|
46
|
+
5. **起服面运维行里抛出物的句子经出口座:凭据形遮掉、控制字符剥掉、界 200 码元(运维面;日志形变更;安全;部署零动作)**:
|
|
47
|
+
起服面(装配、起服自检、关停收割、配置拉取与应用、保留期清扫、交给各店 / 车道的失败回调)运维日志里装异常句的字段(`err` / `error` / `detail` / `info` / `lastError` / `why`,事件名不变),
|
|
48
|
+
旧形是抛出物原文(`String(e)` 或 `e.message`,多行照原样);新形与 `tool_trace` / hook 失败句同一行规则:认出的凭据形换成 `«redacted…»` 记号,控制与双向字符剥掉(多行折成一行),
|
|
49
|
+
超过 200 码元截断并以 `…` 收尾(记号计入界)。k8s 车道起服自检三行在内:`sandbox_secret_seat_unverified.detail`、`sandbox_egress_policy_check_crashed.error`、读不到时的 `sandbox_egress_policy_gap.detail`;
|
|
50
|
+
异常句先转一手再进行的同改:`counter_flush_degraded.error`、`memory_consolidation_default_off_no_cheap_model.detail` 里嵌的引擎拒句那一段、`config_loaded_lkg.why`(起服拉配置失败回落 LKG;
|
|
51
|
+
旧形只剥控制字符、截 120 码元,不认凭据形)。致命退出那一行不变(整句多行、只过凭据形脱敏)。
|
|
52
|
+
**谁受伤**:按异常原文全文排障的人(长句被截、多行的折成一行);按某个字段整句精确匹配的告警(凭据形处换成记号)。**出路**:原因句的前 200 码元照旧在(错误类与首句,凭据形之外逐字);
|
|
53
|
+
规则改按事件名与字段前缀匹配。**回滚**:回到上一版即回到原文。
|
|
54
|
+
|
|
55
|
+
6. **会话列表不再漏掉存档读不出的会话:行带加性键 `unreadable: { errorCode }`(行为面:列表不再静默漏行;wire 加性;部署零动作)**:
|
|
56
|
+
文件后端(`DB_BACKEND=local`)上,会话头坏了、整份截在会话头半截、或存档读不出来(权限不对、I/O 故障)的会话,此前从 `GET /v1/sessions` 里消失(引擎的会话仓列表跳过它),
|
|
57
|
+
而同一只会话的 `GET /v1/sessions/:id` 与 `…/head` 答 500。本版起它照样是列表里的一行:行上的格出自会话行(`owner` / `title` / `pinned` / `lastActivityAt` / `firstActivityAt` / `rowTag` /
|
|
58
|
+
run 四位 / `tempo`,与好行同读),`objectivePreview: null`,另带 `unreadable: { errorCode }` —— present-iff 这只会话的头的叶子读不出,键闭集只有 `errorCode`,值 = 读口打开这只会话时答的码
|
|
59
|
+
(`corrupt_session`:会话头坏 / 截在头里;`internal.error`:I/O 级读不出)。同一张码表也是全局兜底答码的那一张,两处不会分叉;各读口的答复逐字不变。
|
|
60
|
+
边档里没有格、存档头又读不出的会话(7.104.0 之前写下、此后从没被读过)没有可读的属主,仍不列(运维面照旧点名它)。SQL 后端的行从不带这只键(叶子是会话行上一列,一行坏事件照旧在列表里)。
|
|
61
|
+
订正契约 §17.2 的旧句「整份读不出的会话不出现在列表里」—— 那是本版之前文件后端的行为。
|
|
62
|
+
**谁受伤**:把列表每一行都当「点开就能读」的端(这些行点开得 500,就是读口一向答的码);不认识新键的端会把它画成一行没有预览的普通会话;按列表行数计数的面多出这些行;
|
|
63
|
+
跨会话对端目录在文件后端上多出这些会话(与 SQL 后端坏事件行今天的读法相同);`?q=` 搜索不命中它们(没有预览)。
|
|
64
|
+
**出路**:按 `unreadable` 在场分支(灰显 / 提示读不出 / 只给删除);`DELETE /v1/sessions/:id` 对属主照常删掉它;要修就把它的存档文件(数据根 `sessions/` 目录下)从留存副本恢复、或修好文件权限 / 磁盘,行上的标记随之消失。**回滚**:回到上一版,这些会话重新从列表里消失(数据不动)。
|
|
65
|
+
7. **🔴 记忆同步中心必须声明自己的同步身份 `MEMORY_SYNC_SERVE_IDENTITY`;中心侧同步口只服务点名这一身份的轮(BREAKING 部署面:中心升级要加一行 env;行为收紧;wire 加性)**:
|
|
66
|
+
**同步身份** = 客户端到达中心同步口用的基址的规范形:小写协议与主机、无缺省端口、路径去尾斜杠,不带 userinfo / 查询串 / 片段 / 凭据形的段,≤ 190 字符。客户端腿发的 `peer` 自 7.139.0 起就是它自己 `MEMORY_SYNC_URL` 的规范形(本版不变)。
|
|
67
|
+
① DB 记忆平面的中心(`MEMORY_ENGINE_BACKEND=pg|mysql`)用新旋钮 `MEMORY_SYNC_SERVE_IDENTITY` 声明它;没声明 ⇒ `POST /v1/memory/sync/:scope` 答 501 `feature.memory_sync_serve_disabled`(鉴权之后),每个客户端的每一轮都失败(客户端那一层出 `memory_sync_layer_failed`,下一轮重试)。
|
|
68
|
+
声明不是规范形(大写主机、`:443`、尾斜杠……)/ 带凭据 / 查询 / 片段 / 非 http(s) / 超宽 ⇒ **拒启**,拒句给出规范形(不静默规范化);引擎关着也读、也拒。
|
|
69
|
+
② 入站 `peer` 不是同步身份的规范形 ⇒ 400 `request.field_invalid`(`field: "peer"`,`reason` ∈ `not-http-url` / `userinfo` / `query` / `fragment` / `credential` / `too-long` / `not-canonical`;不回显值)。7.139.0 之前的客户端发的标签 `"central"` 落这一格(`not-http-url`)。
|
|
70
|
+
③ `peer` 是规范形但 ≠ 声明 ⇒ 409 `config.memory_sync_target_mismatch`,整轮零读零写(此前按 `(scope, peer)` 新开一只游标 —— 别名客户端在中心上是第二条同步线;那些已经写下的旧游标行本版不动、不读)。拒句只点名本中心声明的身份。
|
|
71
|
+
④ 同步口与 `GET /v1/memory/export` 的 501 `capability.memory_store_required` 改读能力事实(执行位 / 导出读面在不在),不再读 `MEMORY_ENGINE_BACKEND` 的词;能力面加位 `memorySyncServe`(`false` | `{ identity }`)与 `memoryExport`(boolean)。
|
|
72
|
+
**谁需要**:多台客户端经不同地址连同一台中心的部署(别名不再悄悄分叉);要读中心身份的会话记忆同步触发口(本节第 8 条)。**谁受伤**:没声明身份就升级的中心(同步全停,直到声明);7.139.0 之前的客户端(400);经别名到达的客户端(409);
|
|
73
|
+
嵌入方装了同步执行位、后端名写 `file` 的部署(两口从 501 变成受理)。**出路**:**升级序 = 先客户端、后中心** —— 先把所有客户端升到 ≥ 7.139.0,再升中心并在同一次发布里加 `MEMORY_SYNC_SERVE_IDENTITY=<客户端 MEMORY_SYNC_URL 的规范形>`(写错了拒启句会给出规范形);
|
|
74
|
+
别名客户端把 `MEMORY_SYNC_URL` 改成声明的那一个(409 的拒句点名它)—— 改了地址的客户端在它那一侧游标照旧绑旧身份,会停驻在对端轴上,按 7.141.0 的处置删游标。**回滚**:回到上一版即回到旧收法(声明被忽略)。
|
|
75
|
+
|
|
76
|
+
8. **会话记忆同步触发口 `POST /v1/sessions/:id/memory/sync`;同步一轮从不整轮失败(wire 加性;运维面日志形变更;嵌入方类型面 BREAKING;部署零动作)**:
|
|
77
|
+
① 新口:本机形(file 记忆引擎 + `MEMORY_SYNC_URL` + 持久 run 账面)上壳在 fork 之前调它,体恰好 `{ "target": <会话要去的那台引擎 GET /v1/capabilities 上的 memorySyncServe.identity,逐字> }`;答 200 + 引擎的同步报告(`layers` 逐层结局,或整轮 `refused`:
|
|
78
|
+
`config.memory_sync_target_mismatch` = 目标不是本机同步腿到达的那台 / `session_active` = 会话有在飞 run,或读完它的记忆观测之后又受理了 run / 会话记录前进了)。读集 = 会话最近一条已结 run 的记忆观测;取不到 ⇒ 409 `conflict.session_memory_unobserved`。读集里被同步腿覆盖的项目层经 `syncOnce(…, { reading })` **永久**加入本进程的后台同步集(此后每一轮后台同步都带上它、直到进程退出:多一份游标、每轮多几次往返)。能力位 `sessionMemorySync`;位为假时 501(`feature.memory_sync_disabled` /
|
|
79
|
+
`capability.run_store_required` / `capability.session_ownership_required`)。
|
|
80
|
+
② 同步一轮里一层失败只结束那一层,别的层照跑、轮照样落定(此前在轮末汇总抛错,同一轮成功层的结果随之丢掉);客户端侧后台轮的轮级日志行 `memory_sync_failed` **退役**(中心侧同步口答 500 `internal.error` 的那一臂照旧发同名 warn 行 `memory_sync_failed`,不在本条),逐层失败各一行 `memory_sync_layer_failed` / `memory_sync_layer_parked`(键不变);这两行与 `memory_sync_cursor_write_failed` 的 `err` 值改由不抛的读口出 —— 错误的消息原文,不再带 `Error: ` 前缀,打印不出的抛出物记 `<unprintable>`(此前 `String(err)`:那种抛出物会让轮在失败行里再抛)。
|
|
81
|
+
③ 同步层名(`MEMORY_SYNC_SCOPE`,缺省 `MEMORY_SCOPE`)带凭据形的段 ⇒ **起服拒**(这个名字随每一份报告逐字上 wire);`MEMORY_SYNC_URL` 的起服拒句改由同步身份的同一只铸点出(判据不变,句子变)。
|
|
82
|
+
④ 嵌入方类型面:自建 `ServiceDeps` 带 `memorySyncLeg` 的,它多要 `peer` 与 `syncOnce`(tsc 红即通告);`MemorySyncRunner.syncOnce` 的兑现值由 `{ layers }` 改为 `{ calls }`(每层每次调用如它落定的那样),不再 reject。
|
|
83
|
+
**谁需要**:把本机会话推上云的壳;运维(部分层失败不再抹掉成功层)。**谁受伤**:按 `memory_sync_failed` 告警的规则;按旧拒句子串匹配 `MEMORY_SYNC_URL` 起服失败的规则;同步层名带令牌形的本机部署(起不来);上面 ④ 的嵌入方。
|
|
84
|
+
**出路**:客户端侧告警改认 `memory_sync_layer_failed` / `memory_sync_layer_parked`(中心侧 500 那一臂照旧认 `memory_sync_failed`);起服失败按 env 键名匹配;同步层改名;嵌入方按 `createMemorySyncRunner` 装配即可。**回滚**:回到上一版(新口随之消失,能力位缺席)。
|
|
85
|
+
|
|
86
|
+
9. **隔离车道(e2b / k8s / local-docker)的附件改由恢复点放进工作区(行为修复;部署零动作)**:
|
|
87
|
+
此前附件物化在引擎恢复相之前碰执行环境:e2b 上会话带附件的续跑腿跑在一只为写附件新建的沙箱上(停驻的那只没被恢复,停驻前的工作区不在,不报错);
|
|
88
|
+
无附件的 e2b / local-docker 续跑腿在引擎读收据句柄那一步抛 `connect_failed`;k8s 续跑腿多起一只 pod(先前那只靠 pod 收割兜),续跑前新绑的附件不在恢复出来的 pod 里。
|
|
89
|
+
现在隔离车道的附件只在恢复点放(沙箱铸出或恢复之后、交给任务之前);其余车道照旧在执行环境建立时放。k8s 续跑腿若在恢复之前已有一只 pod,先删掉它并写一行运维 warn `sandbox_pod_released_before_restore`。
|
|
90
|
+
**谁受伤**:无;e2b 的附件写失败从「执行环境建立失败」变成「这一次连接失败」(同码 `connect_failed`、同样带写失败句)。**出路**:无需动作。**回滚**:回到上一版即回到旧形(上面三种病随之回来)。
|
|
91
|
+
**已知限制(7.141.0 既有;本版不改)**:空间开的隔离车道会话里,若 run 在首次触到执行环境之前就停驻(pod 还没起、没有快照对象),续跑走停驻车道、不恢复 `latest`,run 结束提交的快照会覆盖此前 run 的改动,且不报警。修法候选:没有对象的停驻快照,续跑改作一次新连接、走 establish。
|
|
92
|
+
|
|
93
|
+
10. **项目包:没有 git 的项目以 `application/vnd.sema.project-bundle` 上传、绑进隔离车道的会话作为工作区的种子(wire 加性);附件一经绑定不再改绑(行为收窄);嵌入方附件店类型面 BREAKING**:
|
|
94
|
+
① **行为面(收窄)**:提交体 `attachmentIds` 里的附件已绑在别的会话上 ⇒ 新提交 `409 attachment.bound_elsewhere`(体 `id`),此前同属主下后绑会把它从前一个会话移过来。
|
|
95
|
+
同会话重绑(首交重试、续跑腿重放)照旧受理、不改绑定时刻;续跑腿重放存量体时这只拒不 4xx,写一行运维 warn `attachment_refused_on_resume`、该 id 跳过。
|
|
96
|
+
**谁受伤**:把同一只已上传的附件交给多个会话的调用方。**出路**:每个会话各上传一次(SQL 后端按 sha256 去重,不多占对象存储;local 后端多一份字节)。
|
|
97
|
+
② **wire 面(加性)**:`POST /v1/attachments` 新受理 mime 值 `application/vnd.sema.project-bundle`(gzip 的 POSIX tar,顶层即工作根);体读不出项目包 ⇒ `400 attachment.bundle_invalid`,体 `reason`(七词闭集,见契约附录 A.1)与 `path`(读得出、且不是放不下的超长路径才在)。
|
|
98
|
+
提交体带项目包而这条腿的车道不隔离 ⇒ `409 attachment.bundle_lane_not_isolated`(体 `id` · `lane`);会话已有种子或同一提交体带第二只 ⇒ `409 attachment.bundle_seed_fixed`(体 `id`);
|
|
99
|
+
「会话已有种子」由附件店在绑定那一步原子地判(两次并发的提交各带一只新项目包到同一会话 ⇒ 恰一只受理);店拒了提交体那只新项目包时,体里其余附件一只都不绑(提交体上读得到的拒 —— 已绑别的会话、车道不隔离、第二只新项目包 —— 同样在任何绑定之前到)。读与绑之间才被别的会话抢走的普通附件不在此列:请求答 409,同一次提交里已先绑上的种子与同组未被抢走的附件不回滚。
|
|
100
|
+
嵌入方类型面(自建 `ServiceDeps.taskAttachmentStore`):`bind` 的兑现值由「此刻绑在本会话上的 id 数组」改为 `{ bound, refused }`,两条绑定律(不改绑 · 一只会话一只种子)由店判(BREAKING;tsc 红即通告)。PG 店 `PgTaskAttachmentStore` 不从包根导出(包的 `exports` 表也不放深路径);它的构造参数由查询函数改为池,只对直接 import 本仓源码路径的嵌入方可见。
|
|
101
|
+
种子只在隔离车道的恢复点铸出新工作区时解到工作根本身(恢复出来的工作区从不播种、fork 不搬、不进目标里的附件告知);运维 info 行 `workspace_seeded{sessionId, bundleId, entries}`。
|
|
102
|
+
③ **部署面**:配了 `ATTACHMENT_MIME_ALLOWLIST` 的部署,要用项目包就把 `application/vnd.sema.project-bundle` 加进白名单(否则上传 415 `attachment.mime_not_allowed`);
|
|
103
|
+
隔离车道的沙箱镜像要带支持 gzip 的 `tar`(k8s 工作区快照早已靠它;e2b 自定义模板与 local-docker 镜像自查),缺 ⇒ 带种子的会话在执行环境建立时被拒、句子点名 `tar`;
|
|
104
|
+
镜像若在工作目录预置了内容,与项目顶层同名 ⇒ 被拒、句子点名路径(不覆写、不合并)。
|
|
105
|
+
**谁需要**:用壳把没有 git 的本机项目交到云端隔离车道继续的用户。**谁受伤**:见 ①;顶层恰有 `attachments` 目录的项目(包被拒,改名);
|
|
106
|
+
e2b / local-docker / `WORKSPACE_PERSIST=off` 的 k8s 上,每个新回合都从上传态开始(车道本就不留工作区;壳读能力位 `workspaceSync.persist === "space"` 判跨回合持久)。
|
|
107
|
+
**升级前做**:配了 mime 白名单的部署按需加一项;无 DDL、无数据迁移。**回滚**:回到上一版 ⇒ 项目包 mime 的附件当普通附件放进 `attachments/`(不解包),改绑回到「移过去」。
|
|
108
|
+
**已知限制(SQL 两方言;本版不改)**:同一会话已有种子时并发提交,若撞锁序死锁、重试(4 次)耗尽 ⇒ 店错(不是 `409 attachment.bundle_seed_fixed`);TiDB 另有:另一笔未绑的项目包被长锁占住、超过锁等待上限时答 1205(同样是店错,不是 409)。
|
|
109
|
+
11. **local 车道有序关停截断的审批卡:`crashConverged[].cause` 与决断口同一个词;前世审计判孤儿的 `PARKING` 问起服即 `VOID`(行为面;wire 值变化;零新键、零新词;部署零动作)**:
|
|
110
|
+
此前有序关停(SIGTERM / SIGINT / SIGHUP)截断、停车行在关停宽限窗内没提交的**后台 / 委派子代**卡,重启后三个读面三个词:问账行记 `shutdown_before_park`(关停那一拍),`GET /v1/approvals` 的
|
|
111
|
+
`crashConverged[].cause` 却是 `crashed_before_park`(审计账的关停记号按腿落,子代卡的腿不在协调器追踪视野里),决断口先答 `425`,对账器走到它再收成 `DENIED` / `routing_failure_fail_closed`。
|
|
112
|
+
现在只有一个词:有序关停是进程的事实 —— 审计账每一世在审批收尾等待结束那一拍落一行 `interrupted_by_shutdown`,这一世此刻没结清的卡一律 `shutdown_before_park`;起服收敛把审计判为孤儿的前世
|
|
113
|
+
`PARKING` 行与 `STREAM_PENDING` 同一拍处置(停车行其实已提交 ⇒ `PARKED`,运维日志一行 `approval_crash_convergence_park_committed`,同批仍在停驻途中的兄弟随之 `VOID` / `batch_bound_elsewhere`;
|
|
114
|
+
否则 `VOID`,成因与 `crashConverged` 同词)。「停车行提交了没有」读后端的只读口,与这一世开没开 `DURABLE_APPROVAL` 无关(前世已提交的停驻不因这一世关着 durable 被收掉)。
|
|
115
|
+
**wire 值的变化(local 车道;键与闭集不变)**:① `crashConverged[].cause`:有序关停截断、收尾结束时仍未结清的后台 / 委派子代卡 `crashed_before_park` → `shutdown_before_park`(`orphanState` / `resumeSafe` 不变);
|
|
116
|
+
② 前世 `PARKING` 孤儿的决断口 `POST /v1/tasks/:taskId/asks/:askId/decision`:`425` →(对账后)`410 gone.ask {state:"DENIED", cause:"routing_failure_fail_closed"}` 改为起服即 `410 gone.ask {state:"VOID", cause:<crashConverged 同词>}`;
|
|
117
|
+
晚答 `404 tool_approval.not_pending` 体的 `cause` 与按问读口 `GET /v1/tool-approvals/:approvalId`(`parked` → `void` + `cause`)同步变化。SQL 车道(`DB_BACKEND=mysql|pg`)零变化。
|
|
118
|
+
**审计账本形**(`<数据根>/approval-ask-audit/ledger.jsonl`,留盘给取证):关停记录 `{kind:"interrupted_by_shutdown", atMs}` 不再带 `taskId`;上一版写的带 `taskId` 的旧行照读(零迁移)。
|
|
119
|
+
**升级后的历史读数**:上一版已收敛过的组照新规则重投影 —— 那一世走完了有序收尾、而旧规则因腿证据缺席判成 `crashed_before_park` 的组,升级后 `crashConverged[].cause` 读 `shutdown_before_park`;
|
|
120
|
+
它们的问账行早已是终态(`VOID` / `DENIED`),终态行不改写,所以这一批历史问上两处的词可能不同,随审批账本留存窗整问删除而消失。
|
|
121
|
+
**起服拒(行为收紧)**:起服收敛写不进审计收敛行(盘满 / 只读;那一行是这一组的幂等锚与成因上界)⇒ 拒启,问账一字不动;此前写丢被吞、照常起服。出路:修好数据根再起,照收、同一个词。
|
|
122
|
+
**谁需要**:有序重启后读 `crashConverged`、或对旧卡作答的壳(子代卡此前被说成「崩了」,作答先撞 425 再拿到「路由失败」)。**谁受伤**:按 `cause === "crashed_before_park"` 判「崩溃」的消费方少数到这类卡(两词处置相同);
|
|
123
|
+
依赖「起服后 `PARKING` 孤儿先 425、之后 `DENIED`」时序的断言;审计账本盘坏了的 local 部署(由照常起改为拒启)。**出路**:按闭集两词读;作答见 410 即消卡;按拒启句修盘。**回滚**:回到上一版时新形关停记录(缺 `taskId`)被计坏行、经 F 类座披露(`server.approval-ask-audit.corrupt-record-skipped`),那几组回到上一版的答法;已收成 `VOID` / `PARKED` 的问账行保持终态。
|
|
124
|
+
|
|
125
|
+
12. **嵌入方(自建 `StoreBackend`、不走 `createStoreBackend` 的进程):`StoreBackend.checkpointReadView()` 的返回型多一口 `findCheckpointCandidatesForAsk()`(BREAKING,类型面;零别名)**:
|
|
126
|
+
这只只读口原先只交 `listPendingSessionIds()`(审批账本留存读它);local 车道的起服收敛现在也经它跑对账器判据 ① 的候选读口(第 6 条:前世已提交的停驻不因这一世关着 `DURABLE_APPROVAL` 被收掉),
|
|
127
|
+
返回型按 `ReturnType<StoreBackend["checkpointReadView"]>` 读(两口:`listPendingSessionIds()` 与 `findCheckpointCandidatesForAsk(scope, sessionId, toolCallId, sinceMs)`)。本服务自带的三个后端零动作(SQL 孪生与 local 交的本就是整只 checkpoint 店)。
|
|
128
|
+
**谁受伤**:自建后端的嵌入方(tsc 红即通知)。**出路**:有 checkpoint 店就交它本身;没有就交恒空读口 `{ listPendingSessionIds: async () => [], findCheckpointCandidatesForAsk: async () => [] }`(没有店 ⇒ 没有停驻)。
|
|
129
|
+
**回滚**:回到上一版,多出的成员无人读。
|
|
130
|
+
13. **结果上组合腿的自由文本过脱敏:`verification.findings[]` / `verification.evidence` / `attempts[].diagnostics` / `attempts[].gateError`(行为面;安全;wire 值可能变;部署零动作)**:
|
|
131
|
+
`verify:true` 任务结果的 `verification.findings[]` / `verification.evidence`、`cascade:true` 任务结果的 `attempts[].diagnostics` 与 `attempts[].gateError` 此前原样落 run 行 / 账本 `done` 行、
|
|
132
|
+
原样上同步 200 体 / `GET /v1/runs/:id` / `GET /v1/runs/:id/events`。本版起它们经本服务的结果脱敏器(前三片与 `result` 同一只,`gateError` 与 `terminal.message` 同一只):
|
|
133
|
+
认出的凭据片段换成 `«redacted…»` 记号,键集、数组条数与顺序不变;判词 / 轮数 / 验证器花费、每级的序号 / 模型 / 状态 / 是否通过逐字;升级前落盘的存量行在读面上同样脱。
|
|
134
|
+
每级的失败码 `attempts[].errorCode` 与 `terminal.code` 同一只出口封口折:出了本服务码形的(驱动原生码、长得像凭据的串)读作 `internal.store_error`,原码只进运维线索 —— 写口(结果第一次离开引擎)每折一座一行 `outward_failure_code_folded`,读面上的再读改记 fail-open 计数(按被折的码座计)与每进程一次 warn(第 4 条)(此前级码原样)。
|
|
135
|
+
completed 因由的 `terminal.detail.finishReasonUnknown` 过服务商回声的形状闸(可见 ASCII、1–128 字符):越界 ⇒ 该键缺席;completed 臂上不认识的成员按自由文本脱。
|
|
136
|
+
**谁受伤**:按判词 / 门异常原文逐字比对或存档的消费方;把 `finishReasonUnknown` 当任意串读的端;按 `attempts[].errorCode` 读驱动原生码的端(此后与 `terminal.code` 同读 `internal.store_error`)。**出路**:按条数与判词分支照旧;比对改按记号之外的文本;
|
|
137
|
+
`finishReasonUnknown` 缺席读作「服务商的词不在回声形内」。**回滚**:回到上一版即回到原文(本版落库时已脱的字节不会复原)。
|
|
138
|
+
|
|
139
|
+
14. **`GET /v1/runs/:id/events` 的停驻尾帧一律是状态帧:挂起前尚未落账的 `model_usage` 行写在 `suspended` / `needs_review` 之前,`verify:true` 的停驻与不带 `verify` 的停驻同序(行为面;wire 事件序;订正 7.141.0 节第 32 条 ①;部署零动作)**:
|
|
140
|
+
7.141.0 节第 32 条 ① 写的是「`verify:true` 任务停驻期间回放的最后一帧是一帧 `model_usage`,排在状态帧之后;不带 `verify` 的停驻以状态帧收尾;两形同序的修正不在本版」。本版起两形同序:停驻帧是这一腿主线写下的最后一帧(晚到的子代转发帧、完成后追加的 `suggestions` 是旁路写,本来就可能排在状态帧之后,不在此列)。
|
|
141
|
+
成因与改法:停驻行此前先写、挂起前的用量行紧随其后;不带 `verify` 的停驻在最后一个 `turn_end` 就把用量结清了,所以尾帧恰好是 `suspended`;`verify:true` 的任务是只回结果的组合腿、没有 `turn_end`,挂起前的用量只有停驻这一拍才落账。
|
|
142
|
+
(不带 `verify` 的形上,最后一个 `turn_end` 之后、停驻之前还有未结清的用量时,同样的尾巴也在。)现在停驻行只经一只写口:先把这一片未落账的用量结清(`model_usage`;没有用量就不写),再写 `suspended` / `needs_review`。
|
|
143
|
+
后台腿、同步 detach 腿、续跑腿的再停与重开臂、续跑 verify 臂同序。用量行落不下 ⇒ 停驻帧照落、随后把失败抛给调用方 —— 失败语义与此前逐字同(后台腿按「停驻没落定」收场:行 `failed`、手里那张卡作废;detach 腿的兜底停驻与续跑腿的重开臂照旧吞掉它)。
|
|
144
|
+
终局帧的序不变(用量行本来就在 `done` 之前);`model_usage` 行的内容、逐行求和与 `stats.modelUsage` 回声不变,变的只是用量行在流里的位置。
|
|
145
|
+
**谁需要**:按「主线最后一帧 = 当前状态」读事件流的客户端(此前 verify 停驻上要改读最后一只状态帧)。**谁受伤**:按「`model_usage` 紧跟在 `suspended` / `needs_review` 之后」配对计费行的解析器 —— 用量行现在在停驻帧之前,按位置配对的会错位。
|
|
146
|
+
**出路**:按 `model_usage` 行逐条求和(与位置无关),或读 `GET /v1/runs/:id` 的 `stats.modelUsage`;读「当前状态」可以读事件流的最后一帧,也可以读 `GET /v1/runs/:id` 的 `status`。**升级前做**:无。**回滚**:回到 7.141.0 即回到停驻帧在前的序。
|
|
147
|
+
|
|
148
|
+
15. **同键重放的同步体改成首答的信封 + `replay: true`,不再是 run 行读面(wire 形;BREAKING 对按重放形解析的消费方;订正 7.141.0 节第 32 条 ②)**:
|
|
149
|
+
同一把 `Idempotency-Key` 再投 `POST /v1/tasks` / `POST /v1/tasks/stream`,命中既有行(另一个进程 / 副本 / 重启之后)时,此前的体是 `GET /v1/runs/:id` 的读面加 `replay: true`(`result` 是对象,外加 `status` / `errorCode` / `error` / `heldBy` / `cancelRequested` 等读面键),
|
|
150
|
+
与首答(引擎结果,`result` 是串)的信封对不上 —— 7.141.0 节第 32 条 ② 写的「外层形不同;重放回首答同一形的修正不在本版」。本版起重放与首答同一个信封,同一个铸点(`buildSyncSubmitBody`):
|
|
151
|
+
— 命中的行**已终局** ⇒ 体 = 引擎结果本身(`terminal` / `stats` / `taskId` / `sessionId` / `result`(串)……在顶层,终局体不带 `status`),加 `replay: true`;
|
|
152
|
+
— 命中的行**停在门上**(`suspended` / `needs_review`)⇒ 体 = 引擎结果 + 回执三键 `{ taskId, sessionId, status }`(与同步停驻的首答同形),加 `replay: true`;
|
|
153
|
+
— 命中的行**还在跑**(首投在别的进程上没落定),或行上没有结果可交 ⇒ 首答在这一刻不存在:体只有回执三键 `{ taskId, sessionId, status }` 加 `replay: true`(`status` 是那一行此刻的词:在跑 ⇒ `running`;结果已被清空的终局行 ⇒ 它的终局词;失联的行与读面同判折成 `failed`),去 `GET /v1/runs/:taskId` 轮询 / 读行。
|
|
154
|
+
流式腿:`done.result` 是同一份体,帧上的 `replay: true` 照旧(已知差:停驻体上的回执三键,同步腿的首答带、流式腿的首答 `done.result` 不带,流式重放照同步腿带)。`POST /v1/runs` 与 A2A 的重放回执(202 `{ taskId, sessionId, status }`)不变。体上没有 `wiringManifest`、`notice`、`warnings`(照旧:它们说的是首帧的活捕获 / 本次请求)。
|
|
155
|
+
**键差**(重放体与上一版相比):没有了 `status`(终局)/ `errorCode` / `error` / `supervisorCost` / `suggestions` / `jobId` / `source` / `heldBy` / `cancelRequested` / `msSinceLastActivity` / `crossSliceUsage`;`result` 由对象变成串;引擎结果的其余顶层键(`terminal` / `stats` 等)现在在顶层。
|
|
156
|
+
**谁需要**:按首答形解析同步体的调用方(SDK / CLI / client-core 的同步路径)—— 重放体不用另写一支解析。**谁受伤**:按 `replay === true` 分流、再读 `body.result`(对象)/ `body.status` / `body.errorCode` 的重放分支。
|
|
157
|
+
**出路**:读顶层的引擎结果(判终局 / 停驻读 `terminal.kind`,与首答同);要读面键就读 `GET /v1/runs/:taskId`(`taskId` 在体里)。**升级前做**:无(部署零动作);**回滚**:回到 7.141.0 即回到读面形。
|
|
158
|
+
|
|
159
|
+
16. **http hook 名单在拨出点执行:请求 `settings.allowedHttpHookUrls` 在场而不放行 ⇒ 这条 http hook 一个字节都不发;`settings.httpHookAllowedEnvVars` 与条目 `allowedEnvVars` 取交(安全;行为面:名单在场时 http hook 可能被拒;wire 加性;部署零动作)**:
|
|
160
|
+
① **wire 面(加性)**:`settings` 受理键多两只 `allowedHttpHookUrls` / `httpHookAllowedEnvVars`(上一版新提交答 `400 request.body_shape`);能力位 `taskSettings.httpHookAllowlists`(与 `taskSettings.hooks` 同谓词,单用户车道 true)—— 端见位才发;
|
|
161
|
+
`hook_notice` 两族的 `reason` 各多一词 `url_not_allowed`(`hook_non_blocking_failure` / `hook_managed_unrun`;按开集读未知词的消费端零动作)。
|
|
162
|
+
② **行为面**:两张名单是请求 `settings` 这一层的(设置源 `flagSettings`),读法与判决只在契约包;http 条目**拨出之前**问判官 —— URL 名单在场而这条的 `url` 不命中、名单是空的 `[]`、或名单不是串数组 ⇒ 不发出(零字节),
|
|
163
|
+
非托管组是非阻断故障(故障帧 + 运维 warn `hook_http_withheld`),托管组失效关闭(`PreToolUse` 在没有否决时折 `ask`);帧的句子点名 `settings.hooks.<event>`、规则词(`url` / `empty` / `malformed`)与出路。
|
|
164
|
+
变量名单在场 ⇒ header 只插值条目 `allowedEnvVars` 与它的交集,名单外的名字置空(既有置空行,只点名不带值)。两键都缺席 ⇒ 与上一版逐字同。提交面不判名单的值(坏形照收,在拨出点由判官拦)。
|
|
165
|
+
**谁需要**:单用户部署上带着组织或用户 http hook 名单的端(hook 在本服务上执行,名单只有在拨出处才执行得了)。**谁受伤**:带了名单而 hook 地址不在名单里的请求(那条 hook 不再发出;托管组上 `PreToolUse` 改问人);
|
|
166
|
+
上一版两键新提交即 400,停驻任务的存量体里不会有它们 ⇒ 已在跑的任务零变化。**出路**:把 hook 地址的模式加进 `settings.allowedHttpHookUrls`(模式文法见契约包;例 `https://hooks.example.com/*`),变量名加进 `settings.httpHookAllowedEnvVars`;
|
|
167
|
+
或不发这两张名单(不限)。**回滚**:回到上一版 ⇒ 两键新提交重新 400,不带名单的请求行为不变。
|
|
168
|
+
17. **🔴 问账行的成因拆成两列:SQL 后端 `approval_ask.denied_reason` 改名 `ending_cause`、加一列 `park_trigger`;local 后端问账日志整本重写一次(本服务起服时自己改;升级前备份、先停光旧副本再起本版;回滚 = 恢复备份,或下面三句手工改回;嵌入方类型面 BREAKING;wire 零变化)**:
|
|
169
|
+
旧形:一列 `denied_reason VARCHAR(64)`,`PARKING` / `PARKED` 行上是转 park 的触发成因,`VOID` / `DENIED` 行上是终态成因;对账器收 `PARKING` 行时终态成因覆盖触发成因。
|
|
170
|
+
新形:`ending_cause VARCHAR(64)`(终态成因;到 `VOID` / `DENIED` 的转移带着它写)+ `park_trigger VARCHAR(64)`(触发成因;只由转 park 的那一次写,此后不变)。新建的库直接建成新形。
|
|
171
|
+
本条**不用手跑 `ALTER`**:起服时在一次性迁移锁内依次 —— ① `denied_reason` 在 ⇒ 改名 `ending_cause`(MySQL 协议 `CHANGE COLUMN`、PostgreSQL `RENAME COLUMN`);② `park_trigger` 不在 ⇒ 加列;
|
|
172
|
+
③ `PARKING` / `PARKED` 行上那一格搬进 `park_trigger`,再把这两态上的 `ending_cause` 置空。中途被打断,下次起服从断点续;第二次起服零命中。库账号要有 DDL 权限(起服建表本就要求)。
|
|
173
|
+
终态行上早已被覆盖掉的触发词没有出处可补 —— 如实缺席(决断口 `410` / 晚答 `404` / 按问读口读的终态成因逐字不变)。
|
|
174
|
+
`DB_BACKEND=local`:问账日志 `approval-asks/asks.jsonl` 的记录信封号 1 → 2;窗内信封 1 的记录按旧律译读(行快照按行的状态、转移补丁按目标态),起服一次压实把整本重写成信封 2。
|
|
175
|
+
起服行 `one_time_migrations_applied` 的三个读数键:`askCauseColumnsChanged`(表形改动 0–2 处;SQL)· `askParkTriggersMoved`(搬了几行触发词;SQL)· `askJournalRecordsUpgraded`(重写前读到的信封 1 记录数;local)。
|
|
176
|
+
**升级步**:① 备份整个库 / 整个数据根(回滚的前提)。② 推荐先停光全部旧副本再起本版:改名之后仍在跑的旧副本对 `approval_ask` 的每一条读写都响亮失败(不会写错列),重叠期间它们上的审批卡读写报错。
|
|
177
|
+
③ 窗口:本条迁移自引入它的版本发布日起 30 天内每次起服都跑,窗关之后的第一个小版本删码 —— **跳版升级要在窗内先起一次带本条的版本**:删码之后,SQL 库上仍带 `denied_reason` ⇒ 起服拒
|
|
178
|
+
(退役 schema 探针,拒句点名出路);local 数据根里仍有信封 1 的记录 ⇒ 问账店拒启(`unknown envelope version`)。
|
|
179
|
+
**回滚**:旧版对改名后的表读写失败、对信封 2 的日志拒启。支持形 = 恢复升级前的备份;SQL 也可手工改回(终态行上本版记下的触发成因随之丢):
|
|
180
|
+
MySQL 协议 `UPDATE approval_ask SET ending_cause = park_trigger WHERE state IN ('PARKING', 'PARKED') AND park_trigger IS NOT NULL; ALTER TABLE approval_ask DROP COLUMN park_trigger; ALTER TABLE approval_ask CHANGE COLUMN ending_cause denied_reason VARCHAR(64) NULL;`;
|
|
181
|
+
PostgreSQL 前两句同,第三句 `ALTER TABLE approval_ask RENAME COLUMN ending_cause TO denied_reason;`。local:恢复数据根备份(或移开 `approval-asks/asks.jsonl` —— 其上的每张审批卡作废)。
|
|
182
|
+
**嵌入方类型面(BREAKING,零别名)**:`StoreBackend.approvalAsk()` 的行型 `AskRow.deniedReason` → `endingCause` + `parkTrigger`;转移补丁 `AskTransitionPatch.deniedReason` → `endingCause`(值域 = 结局成因闭集;补丁没有触发成因那一键);
|
|
183
|
+
终局 claim 的败方读数 `current.cause`(`{ kind, cause }`)→ `current.endingCause` / `current.parkTrigger`(各是词本身,读不出即缺席);按状态分派的读口 `causeOfAskRow` 与型 `AskRowCause` 删除,换 `askRowEndingCause` / `askRowParkTrigger`;
|
|
184
|
+
`StoreBackend.runOneTimeMigrations()` 的报告多三键(上列)。自建问店的嵌入方:到 `VOID` / `DENIED` 的转移写终态成因格,赢下 `STREAM_PENDING → PARKING` 的 `claimTerminal(expire, { cause })` 写触发成因格,其后不再写它。
|
|
185
|
+
— **谁需要**:排查「这张卡为什么进了投递面、后来又为什么被收掉」的运维与取证。— **谁受伤**:滚动升级重叠期的旧副本(审批读写报错)、回滚(只剩恢复备份或手工三句)、自建问店 / 读行型的嵌入方(tsc 红)。
|
|
186
|
+
— **出路**:如上升级步;嵌入方按上列改名。
|
|
187
|
+
18. **沙箱 git 平面接上有效配置块 `sandboxGit`:中心投影的块热生效,坏块读作没有任何 origin 并一行 warn `web_admin_sandbox_git_refused`;本版平面读数不变;嵌入方 `ServiceDeps.sandboxGitPlane` 由值改为读函数(部署面零动作;运维面多两行日志;嵌入方类型面 BREAKING)**:
|
|
188
|
+
① **部署面**:块的唯一来源是中心有效配置 —— 控制台按部署登记册投影,只在本 worker 自己的拉取上(配了 `SEMA_WEB_ADMIN_WORKER`)出现;没有 env 旋钮,本地配置源(`CONFIG_PROVIDER=local`)没有这一块。
|
|
189
|
+
块随有效配置的每次提交热换代(刷新拍 / 迟到起服 / LKG 起服都一样),不签重启;中心凭证换人降档时随整份中心配置撤下。块判不过契约(重复 origin / 超过 16 项 / 非规范 origin / `connectUrl` 不是 https / 不是对象)⇒
|
|
190
|
+
当作没有任何 origin,一行 warn `web_admin_sandbox_git_refused`(`version` / `issues` 逐条坐标 + 契约拒句 / `effect`,不回显值),同一份候选的其余配置照常落地;块换代一行 info `web_admin_sandbox_git { version, origins }`。
|
|
191
|
+
已经建起的沙箱 pod 的路由表在建 pod 时定下:删 / 加 origin 对新 pod 生效。
|
|
192
|
+
② **本版平面读数不变**:取值口的 worker 凭据仍没接线,`GET /v1/capabilities` 的 `credentialPlane.sandboxGit` 停在 `no_caller_credential`(或更前的词),没有 pod 挂代理。
|
|
193
|
+
这个值现在每次读时求值(起服读数 + 当前生效配置的块),不再是起服时算一次的读数。
|
|
194
|
+
③ **嵌入方类型面**:自建 `ServiceDeps` 带 `sandboxGitPlane` 的,它由读数(`SandboxGitPlane`)改为读函数(`() => SandboxGitPlane`;能力位每次请求调它)—— tsc 红即通知;组合根交的是平面座的 `now`。
|
|
195
|
+
④ **同版(部署零动作)**:run 行记下登录令牌的化身号(`sub_inc` ⇒ `task_run.identity_principal_inc`,零 DDL);超过 64 字符的声明不记、一行 warn `run_identity_claim_unrecorded { claim, chars, max }`(scope 超过 190 字符铸不出元组的旧行为同一行告警)。
|
|
196
|
+
嵌入方自建的鉴权桥验证器交出在场而不是非空串的 `principalInc` ⇒ 身份不装(计数 `auth_bridge_verify_total{outcome="malformed"}`),声明缺席时不铸这一键即可。
|
|
197
|
+
**谁需要**:多租户 k8s 部署里要让成员用自己的 Gitea 凭据 clone / push 的团队、在控制台增删 origin 要不重启就生效的运维。**谁受伤**:坏块的部署(平面读 `no_origins`);按 `sandboxGitPlane` 读数装配的嵌入方。
|
|
198
|
+
**出路**:按 warn 行点名的坐标修控制台上的块;嵌入方交读函数。**升级前做**:无。**回滚**:回到上一版 ⇒ 块被忽略(平面读 `no_origins` 那一侧不变),run 行化身号一格回到恒空。
|
|
199
|
+
19. **自由文本脱敏的两处已知漏形(安全披露;零行为变更;部署零动作)**:
|
|
200
|
+
这两形在本版与此前各版都**不遮**,不是本版引入;写在这里,是让按「凭据不会以明文出现在日志 / 转录里」配告警、做审计的部署知道它们在射程外:
|
|
201
|
+
— **复合凭据名在自由文本里的 `名=值`**:`api_key` / `apikey` / `api-key` / `access_token` / `refresh_token` / `id_token` / `private_key` / `x-amz-signature` / `x-amz-security-token` / `x-amz-credential` 在自由文本里没有名字锚:后面的值只有自身形状被别的臂认出(`ghp_…` / `sk-…` / `AKIA…` 这类)时才遮,否则在结果、账本回放、流式与同步体、运维日志行上都原样 ——
|
|
202
|
+
与旁边有没有私钥栅栏无关(私钥块本身照遮)。同一批名字在 JSON 字段(`{"api_key": "…"}`)与 URL 参数(`?api_key=…`)位上照遮;`password` / `passwd` / `pwd` / `secret` / `client_secret` 在赋值符两侧零空白的 `名=值` 形上、值是以字母数字起头的字面量时照遮(`$VAR` / `%s` / `<占位>` / 表达式 / `None` 一类不算值)。
|
|
203
|
+
— **强锚名紧贴在前一枚凭据的尾巴上**(`-----END PRIVATE KEY-----password=…`;PGP 收尾栅栏、PuTTY 的 `Private-MAC:` 行、AWS 键 id 同形;中间没有空白、换行、`?` / `&` 或引号):
|
|
204
|
+
流式 done 帧、同步体、运维日志行上原样;run 行与账本回放上被遮(读面多过一遍脱敏)。
|
|
205
|
+
**谁受伤**:无(零行为变更)。**读法 / 出路**:要靠脱敏挡住的凭据,别以这两种形写进 prompt、工具输出或错误句;放进 JSON 字段 / URL 参数 / `Authorization` 头这类结构化位置照遮;
|
|
206
|
+
已有的日志与转录可按这两种形自查。修好的那一版,这些值改成 `«redacted»`(那一版的本文件另写一条)。**升级前做**:无;**回滚**:无关。
|
|
207
|
+
20. **用户面通告多一键 `eventId`(每次投递的身份),live 帧自此带 `id:` 行;有账本口的腿上,断流后通告与文件卡的死直写不再记「丢帧」,文件卡账本孪生的写失败改记计数(wire 加性;运维面计数口径变化;部署零动作)**:
|
|
208
|
+
`engine_notice` 帧的载荷由五键(`code` · `message` · `detail` · `sessionId` · `ts`)变六键:多 `eventId`(非空串,uuidv7 形)。server 在分流器扇出时给每一条通告铸一枚,同腿的 live 帧与 durable 账本行是同一只行,所以同值;
|
|
209
|
+
live 帧因此发 `id:` 行(值逐字 = 载荷 `eventId`;此前通告帧没有 `id:` 行,契约 §0.6「无锚不发行」名单里不再有它);`GET /v1/runs/:id/events` 的 `id:` 仍是行 `seq`(两个 id 域不可互推)。
|
|
210
|
+
同一内容的两次投递是两枚。本版之前写下的账本行没有这一键,重放不补。读者从 live 换到 events 车道只能从 0 重放,重放里会再看到 live 上已见过的通告 —— 按载荷 `eventId` 认同一件事(契约附录 D.1「投递律」)。
|
|
211
|
+
无新帧、无新端点、无新能力位、无新拒码;账本行 `data` 是 JSON,多一键不动 SQL。
|
|
212
|
+
遥测(运维面):`frame=engine_notice` 与 `frame=file_link` 的 `server.stream.frame-dropped-stream-closed`(断流丢帧)自此**只在本腿没有账本口的部署上记**(无 run 店 ⇒ 无 durable run 行);有账本口的腿上,客户端已断时这一帧在账本里,账本孪生即送达,不再另记 ——
|
|
213
|
+
丢没丢只由账本那一笔判:通告写失败记 `server.engine-notice.durable-append-failed`(旧有),文件卡账本孪生写失败改记 `server.ledger.forward-append-failed`(`type=file_link`;修前静默吞,工具面仍不 fault;流已断时账本那一笔失败 = 这张文件卡整张没送达)。
|
|
214
|
+
所以有 run 店的部署上这个丢帧计数会掉:不是壳修好了,是有账本口的那部分不再被当成丢。live 可以多于账本:账本那一笔写失败时,用户在线上看见了这一条、重放里没有。
|
|
215
|
+
本版保证到哪:在该腿把终局帧入链之前发出的通告,账本里先于终局帧(按停的中断说明即是);终局帧之后才发出的通告(引擎收尾阶段的通告、非 detach 断连之后引擎中止尾巴上的通告、无在册腿时发出的通告)不在保证内(契约附录 D.1)。
|
|
216
|
+
**谁需要**:从 live 换到 events 车道的客户端(无报告 id 的通告码,如中断说明,此前跨车道会渲两次);读遥测查「通告丢没丢」的运维(此前计数把没丢的也算成丢)。
|
|
217
|
+
**谁受伤**:① 严格按「五键」校验通告载荷的消费端(多一键);② 把 live 流最后一枚 `id:` 当续流游标的消费端:游标现在可能落在通告帧上(值仍是 uuidv7,与其它 live 帧同域);
|
|
218
|
+
③ 按 `frame-dropped-stream-closed` 做看板 / 告警的运维:有 run 店的部署上计数会掉;④ 本版之前写下的账本行没有 `eventId`,对它们跨车道仍去不了重。
|
|
219
|
+
**出路**:消费端接受第六键、按 `eventId` 去重(键缺席回到流内序);看板改按 `server.engine-notice.durable-append-failed` 与 `server.ledger.forward-append-failed` 读「没落账」,按 `frame-dropped-stream-closed` 读「无账本腿上真丢」。
|
|
220
|
+
**回滚**:回到上一版,通告帧回到五键、无 `id:` 行,计数口径回到旧样;已写下的账本行多着一键,旧版读口逐字透传,不受影响。
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
21. **更正(7.138.0 节第 19 条 ②,文书;零行为变化)**:待决工具审批行被拒的拒体是**顶层** `reason: "tool_identity_missing"`(`src/http/refusal-body.ts:37`,与 `blockedBy` / `field` 同一层),不是 `detail.reason` —— 本仓拒体没有 `detail` 对象。读那一条的消费方按顶层 `reason` 读;7.138.0 节原文不改(已发节字节不动)。
|
|
224
|
+
|
|
225
|
+
## 7.141.0 —— 起服自有凭据值被引擎拒收改发结构化 warn `own_credential_value_not_withheld`(运维面;日志形变更) · 两条用户面文案订正(起服行 `tool_policy_single_user_default` 的 `posture`、`SENSITIVE_WRITE_PATTERNS` 说明;文字,零行为变更) · `/decide` 续跑腿批准后被取消:终局文案改「已取消、不可再续」(行为面;文字;码不变) · 会话同步导入的 `anchors[]` 必须指向这次导入声明的条目(新提交 400;出口过滤存量悬空锚) · 流式口每帧带 `event:` 行(BREAKING)· 回退锚写入腿内落定(有界) · device 车道 `DEVICE_RELAY_URL` 必声明(URL 或 `none`;缺席拒起) · 显式 `DB_BACKEND=mysql|pg` 而该引擎的坐标缺席 ⇒ 起服拒,与 `SESSION_BACKEND` 怎么写无关(行为收紧,fail-closed;运维面) · 起服多一次只读普查:存量停驻行里带「无 `kind` 的 batch 成员」的行数(运维面;零动作;不改任何一行) · 🔴 local 后端数据根一次性迁移:会话的建档时刻与 fork 谱系搬进会话元数据边档、带属主戳的会话存档改写成匿名(本服务起服时自己改;升级前备份数据根、先停光旧进程;回滚只有恢复备份)· 仍带戳的存档 fork / 改日志推送答 409 `conflict`(行为收紧)· 先清后导之后建档时刻不变(行为修复) · 本机形(`DB_BACKEND=local`)后台子代的转录活过重启、随记录同亡;接线清单 `fleet.subagentTranscripts` 在 local 上改答 `full`、`rows` 档不再由本服务产出(行为变更;wire 值变化) · 记忆同步停驻:游标用不了的层只点名删游标一条出路,`GET /v1/sessions/:id/memory-status` 加性键 `memorySync`、停驻层的运维行改名 `memory_sync_layer_parked`(wire 加性;运维面日志形变更;订正 7.139.0 / 7.140.0 两节的处置句) · 在飞 run 的权限模式切档口 `POST /v1/runs/:id/permission-mode`(wire 加性;能力位 `permissionModeWrite` 按部署翻真) · `settings.permissions.deny` / `ask` 的条目可带出处层 `{ rule, layer }`:user 层的 `/` 形路径规则读在执行环境的配置根(wire 条目型放宽 + 能力位 `settings.permissions.layers`;端见位才发) · `GET /v1/runs/:id` 的 `heldBy` 终态行恒 `null`(一个条件:`null` = claim 已释放;wire 值域变化) · 运维队列行 / `/stream` `pending` 帧恰带授予绑定一臂,升级前停驻的卡投 `boundGrantAbsence: "unreadable"`(wire 值域变化) · 沙箱三车道读拒表字节地板的接线与新旋钮 `SANDBOX_READ_FLOOR`(keep | off,缺省 keep;本版地板模块不服务任何车道 ⇒ 三车道照旧不守,零行为变化;起服行多一个字段) · `REMOTE_EXEC` 是有序车道表,表里不止一条 ⇒ 起服拒(部署 env 形变 BREAKING;单词零变化) · `MEMORY_ENGINE_BACKEND=tidb` 改名 `mysql`(旧词拒启;`memoryEngine.backend` 值变化,BREAKING) · `config.d/remote-exec.json` 非空串字段只含空白 ⇒ 起服拒(行为收紧) · 契约包 settings-schema 16.0.0 的其余读点(设备入口拒句取契约 · 本地配置一次读、过深文档成被拒文档 `too_deep`) · SQL 后端(`DB_BACKEND=mysql|pg`)的主 runner 接线清单 `session.store` 由 `process_local` 改答 `declared_durable`(会话店补上顶层耐久声明;wire 值变化;只改读数) · `workflow_complete` 补投帧多可选键 `diagnostics`(引擎的诊断教学文本;过脱敏、有界;wire 加性;零 DDL;崩溃恢复补投不带) · `GET /v1/capabilities` 加能力位 `mcpTransportKinds`(请求面读器与引擎今天能拨的 MCP 传输种类;wire 加性;提交面不放宽)· `GET /health` 加性键 `engineLease: { lingerMs, tickMs }`(引擎附着租约窗上 wire;运维面)· 名单型 env 旋钮点到自有凭据名的起服拒句一句只用一套序号(文字;运维面)· 订正 7.139.0 节第 23 条 ⑤:服务进程被 `SIGKILL` 时暂存目录留在目标旁(文字订正) · 折码的运维 warn 行 `outward_failure_code_folded` 不再带失败句原文、读面同一原码只一行(运维面;日志形变更;安全) · 验证器自己停驻:恢复凭据不再外出、那张卡结算时作废、读面上不合本服务码形的存量失败码读作 `internal.store_error`(行为面;安全 / 修复) · 订正 7.140.0 节第 7 / 10 / 12 / 13 条的四处说法、第 8 条补一句(文字订正) · 契约包 settings-schema 16.0.0 · 引擎 7.60.0
|
|
226
|
+
|
|
227
|
+
1. **起服自有凭据值被引擎拒收改发结构化 warn(运维面;日志形变更;部署零动作)**:本进程自有凭据变量(配置目录 secret 名与模型条目 `apiKeyEnv`)的值被引擎判「不是凭据值」(空白 / 占位词 / 一个字符重复 / 不足 8 字符)时,
|
|
228
|
+
那一个值不按值扣、名照扣、不拒启(能力位 `inherit_env.own_credential_values_withheld` 答 false)—— 这件事此前是一行裸 stderr 文本,现在是日志器的一行 `warn`,事件名 `own_credential_value_not_withheld`,字段 `{ name, reason }`
|
|
229
|
+
(`reason` 是引擎拒句原文,不回显值;起服第一步日志器还没建时当拍以同一行形写 stderr,不缓冲;每个变量只一次)。
|
|
230
|
+
**谁受伤**:按旧裸文本(`own credential <名>: its value is not withheld by value …`)grep 的告警规则会失明。**出路**:改按事件名与 `name` 字段筛;给该变量一个真值(至少 8 字符、不是占位词)即可消掉这一行。扣留行为与能力位一字未动。
|
|
231
|
+
2. **两条用户面文案订正(文字;零行为变更)**:① 单用户 turnkey 起服行 `tool_policy_single_user_default`(info)的 `posture` 不再写「ALL write/hand/MCP tool surfaces auto-allowed」,改说「部署工具策略层是 allow-all 基线、不是逐调用放行 —— 每次调用仍由本次运行的权限模式与引擎写门裁」;
|
|
232
|
+
事件名 / 级别 / 字段名不变。② `SENSITIVE_WRITE_PATTERNS` 的说明(`GET /v1/config/catalog` 该行、README 两语、USAGE 9.4c)写出射程:守卫集拒文件工具(Write / Edit / NotebookEdit),shell 命令写同一路径不被它拒绝、走普通审批问。
|
|
233
|
+
**谁受伤**:按 `posture` 旧字面子串匹配的规则会失配(该字段是给人读的说明,不是机读位)。**出路**:无需动作。
|
|
234
|
+
3. **`/decide` 续跑腿(含计划审阅批准)在批过的动作开跑之前被取消:终局 `message` 改成「已取消、不可再续」(行为面;文字;码不变)**:此前 run 行与账本 `done` 行上是引擎的通用句「the checkpoint was REOPENED (pending): the same approval can be resumed again」,而本服务按取消语义已把这张卡 expire
|
|
235
|
+
(待办队列没有它、再决断 `404 not_found.plan_review`)。现在本服务亲手 expire 了一张 pending 的卡时,失败终局的 `message` 是 `Cancelled — the approved action never started, and the cancel settled this approval: it cannot be resumed (start a new run to continue)`;
|
|
236
|
+
`errorCode`(仍是 `resume.reopened_unstarted`)、`retriable`、待办队列、决断路由全部不变。`/wake` 的会话 park(取消后仍留着)与非取消的重开形里引擎原句原样。
|
|
237
|
+
**谁受伤**:按旧英文句子子串(`REOPENED`)判「可再续」的客户端 —— 请改读 `GET /v1/approvals` / 决断路由 / `retriable`。**已知限制**:码与文案分属两个来源(码名里的「重开」说的是引擎当时的动作);取消与引擎真失败赛跑且卡被 expire 的形,失败细节不再出现在 `message`(失败码保留)。取消落在引擎 claim 之前(`checkpoint.resume_aborted`)且卡被本服务 expire 时,行与账本终局行同样换成这一句(码仍是 `cancelled`)。
|
|
238
|
+
4. **会话同步导入(`POST /v1/sessions/:id/sync/import` 第一阶段)体里的 `anchors[]` 必须指向这次导入声明的条目 ⇒ 不在声明集里的锚整次导入 400;`GET …/sync/manifest` 先读锚再读条目 id,并不再交出存量里的悬空锚(行为收紧;wire 码不新)**:
|
|
239
|
+
每条锚必须是带串型 `eventId` 与串型 `entryId` 的对象,且 `entryId` 是体里 `entryIds` 的一员;第一条违例 ⇒ `400 request.field_invalid`,句子点名第几条锚与它的 `entryId`
|
|
240
|
+
(`anchors: [1].entryId "…" is not among the entryIds this import declares`;元素不是对象或缺串型字段时 `anchors: [1] must be an object with a string eventId and a string entryId`),
|
|
241
|
+
不回显其它锚、不回显声明集。判在分类(409 `conflict`)、执行格与活动的判(409)、补 mirror、开暂存之前:拒时不写锚 / 日志 / 会话行,不开暂存、不拿租约,执行格不动。
|
|
242
|
+
为什么「声明集」就是全部:导入落定的日志是体里声明的那份 —— 提交整段换装,`fresh` / `fast_forward` / `identical` 不留声明集没有的条目,`overwrite-dst` 的 `fork` / `stale` 把目的端独有的条目整段抹掉
|
|
243
|
+
(并先擦掉指向它们的旧锚),所以指向目的端独有条目的锚不是「已落日志的合法锚」,而是这次导入刚抹掉的条目的悬空锚;请求读完 id 之后别的写者才长出来的条目同样不在声明里,指向它的锚同样拒(保守方向)。
|
|
244
|
+
`owner` 仍不读(锚一律重钉到导入主体)。`anchors` 不是数组仍是 `400 request.body_shape`。
|
|
245
|
+
出口读序同改:manifest 先读锚、再读条目 id(锚是先有条目后落的、日志只增不减,先读锚得到的每条锚,后读的 id 列表里一定有它指向的条目);此前先读 id 后读锚,源端会话是活的时,
|
|
246
|
+
两次读之间一轮收尾就会让 manifest 交出指向比自己 id 列表更新的条目的锚。manifest 的形与键不变。
|
|
247
|
+
存量里的悬空锚(更早的版本在导入口收下过、指向 manifest 自己 `entryIds` 之外的锚)同样不出 manifest —— 导出按入口门的同一只谓词滤掉,逐条计数(指标 `fail_open_total` 的 tag `server.session-sync.dangling-anchor-export`)并在探针文件(`SEMA_FAILOPEN_PROBE`)留一行;店里的行不删、没有新动词
|
|
248
|
+
(累计计数 = 本进程导出时碰到存量悬空锚的次数;同一条行每次导出再数一次,现存多少读锚表)。此前它们随 manifest 出门,原样拼回推送体就被入口门拒,那只会话从此推不出去;现在往返自愈。
|
|
249
|
+
上一版:第一阶段只判 `anchors` 是数组,指向声明集外的锚照收并落库(续跑锚解到一个不存在的条目),`null` 元素在重放腿抛 TypeError 答 `500`,缺串型字段的元素把 `undefined` 递给锚店。本地文件店与 SQL 店同形(判在任何店调用之前)。
|
|
250
|
+
— **谁需要**:靠会话同步把续跑锚推上云端的壳 / 客户端 —— 经这个入口,云端的续跑锚不再被写成指向已抹条目或不存在条目的悬空锚。
|
|
251
|
+
— **谁受伤**:推送体里带一条指向声明集外的锚的调用方(自己拼体、`anchors` 与 `entryIds` 不是同一时刻读的;或源端锚表里有一条指向本次推送日志里没有的条目)—— 整单 400,不再受理。上一版已落库的悬空锚本版不删行(它们仍在锚表里、仍解不到条目),但不再随 manifest 出门;自己从别处拿到带着它们的体去推的调用方会被点名拒;
|
|
252
|
+
`overwrite-dst` 提交与随后的擦除步之间进程死掉的残余窗口也照旧(重试落 `identical` 臂,不再擦)。
|
|
253
|
+
— **补偿**:按句子里的下标核对那条锚 —— 它指向的条目不在你声明的 `entryIds` 里:要么那条锚本来就解不到条目(从 `anchors` 去掉,或在源端删掉),要么你的 `entryIds` 读旧了(重读 manifest 再推,**不要**删锚);
|
|
254
|
+
`overwrite-dst` 要保留的锚改指源端声明的条目。**回滚**:回到上一版即回到「悬空锚照收」(零数据面)。
|
|
255
|
+
5. **`POST /v1/tasks/stream` 的每一帧都带 `event: <type>` 行(BREAKING,wire;`data` 逐字不变)**:这条流上的引擎帧、终帧 `done`(正常 · 同键重放 · 在飞合流的跟随方 · 开流之后的拒)与开流时补投的完成帧
|
|
256
|
+
此前只有 `data:` 行,本版与 `meta` / 心跳 / 审批 · 提问 · 表单帧一样写成 `[id: <eventId>\n]event: <type>\ndata: <json>\n\n`(事件名 = 载荷 `type`;心跳 `event: heartbeat` + `data: {}`),
|
|
257
|
+
与 `GET /v1/runs/:id/events` 同一只帧形。
|
|
258
|
+
**谁受伤**:只读默认 `message` 通道的读者 —— 浏览器 `EventSource.onmessage` 经字节透传的中继、把无名帧落到 `message` 再按 `event:` 名分派的自写解析器:升级后收不到任何内容帧与 `done`。
|
|
259
|
+
按载荷 `type` 分派的读者(`@sema-agent/sdk` 的 `tasks.stream`,以及经它读本流的壳)与只解析 `data:` 行的读者零改。
|
|
260
|
+
**出路**:按事件名监听(`addEventListener("<type>", …)`),或按 `data:` 行解析、按载荷 `type` 分派。**回滚**:回到上一版即回到旧帧形(无存储格式变化)。
|
|
261
|
+
6. **回退锚写入:流式腿在 `done` 之前落定;计量 `resume_anchor_capture_failed` 退役(运维面)**:`POST /v1/tasks/stream` 的回退锚(`resumeAt` 用的 taskId 手柄)在 `done` 帧写出之前写完
|
|
262
|
+
(此前不等,读到 `done` 马上回退可能撞 `404 resume_at.unknown_event`),`done` 因此晚到一次锚店写的时长,至多 2 s(锚店挂住 ⇒ 到点放手、`done` 照发、那次提示词没有回退手柄)。三条腿(流式 / `POST /v1/runs` / 续跑)锚写失败或到期改记登记过的 fail-open:
|
|
263
|
+
计数 `fail_open_total{tag="server.resume-anchor.capture-failed",cls="F"}`、探针行 `leg=<stream|bg|resume> kind=<prompt|turn> reason=<error|timeout> …`、每进程一次 warn;run 照常收尾。
|
|
264
|
+
**谁受伤**:看板 / 告警读 `resume_anchor_capture_failed` 的部署 —— 这只计量不再出现。**出路**:改读 `fail_open_total{tag="server.resume-anchor.capture-failed"}`。
|
|
265
|
+
7. **device 车道:设备入口 `DEVICE_RELAY_URL` 必须声明 —— ws(s) URL 或字面 `none`,缺席 / 空串 / 只含空白起服拒(部署面,行为收紧,fail-closed;嵌入方类型面 BREAKING)**:
|
|
266
|
+
设备拨哪里只有运维知道,服务不再替运维把「没写」读成「直拨引擎地址」—— 那一读让撤掉中继声明与本来就直拨折成同一个值,撤声明而根会话上还有设备绑定时,
|
|
267
|
+
设备改拨引擎地址(入口已收窄则拨不到)、绑定却留在会话上,起服零信号。`REMOTE_EXEC=device` 而 `DEVICE_RELAY_URL` 缺席、空串或只含空白 ⇒ 起服拒,拒在车道必需 env 门(与其余车道的必需键同一句,点名键名);写了却不合文法 ⇒ 起服拒,拒句点名两种合法值。
|
|
268
|
+
两种合法值:ws(s) URL(逐字上 `GET /v1/capabilities` 的 `deviceExecutor.relayUrl`,形门不变)或字面 `none`(没有中继,设备按引擎地址 + `deviceExecutor.wsPath` 拨号,能力面不带 `relayUrl`)。
|
|
269
|
+
只认 `none` 这一拼法(`None` / `off` / `direct` 照旧被 URL 形门拒)。其它车道不读这根 env。
|
|
270
|
+
`none` 而根会话上还有设备绑定 ⇒ 起服 warn `device_relay_withdrawn_with_bindings`,`bindings` = 绑定条数(不带会话 id);没有绑定 ⇒ 不响。
|
|
271
|
+
**谁需要**:设备经托管入口(中继 / 网关)拨号的部署 —— 撤中继声明从此必须明说「设备改拨引擎地址」,不再静默困住已绑设备。
|
|
272
|
+
**谁受伤**:所有没写 `DEVICE_RELAY_URL` 的 device 车道部署(含设备一直直拨引擎地址的部署);`REMOTE_EXEC=device` 而 local 形 `config.d/remote-exec.json` 把车道换成别的车道的部署同样要写。
|
|
273
|
+
嵌入方:`ServiceConfig` 的 device 车道臂 `relayUrl?: string` 改为必填 `relay: { kind: "url"; url: string } | { kind: "none" }`;设备店接口多一个必填方法 `countDeviceBindings()`
|
|
274
|
+
(类型面,编译红即消费点清单,没有别名)。
|
|
275
|
+
**升级前做(出路)**:设备直拨引擎地址的部署在服务进程环境里加一行 `DEVICE_RELAY_URL=none`,即与升级前逐字同(能力面与拨号行为都不变);用中继的部署原样保留 URL,零动作。
|
|
276
|
+
用仓里两份根 compose 起服的部署:这两份已把 `DEVICE_RELAY_URL` 透传进服务容器,在 `.env` / 宿主环境里写这一行即可。
|
|
277
|
+
配置目录(`GET /v1/config/catalog`)的这一行带 `enumValues: ["none"]`,生效值 `none` 原样显示。
|
|
278
|
+
设备绑定数逐行过放置格的解码:有一行放置列不成形(设备在而属主列缺等)⇒ `none` 下起服拒、点名那一行(该行在别处读到时同样拒);URL 下不读。
|
|
279
|
+
**以后撤中继声明的顺序**:先恢复引擎自己的入口(设备拨得到引擎地址 + `wsPath`),再把值改成 `none`;起服那行 warn 会点名还有几条绑定押在这个入口上。**回滚**:回到上一版即恢复「缺席 = 直拨」,无数据面改动。
|
|
280
|
+
8. **显式 `DB_BACKEND=mysql|pg` 而该引擎的坐标缺席 ⇒ 起服拒,与 `SESSION_BACKEND` 怎么写无关(行为收紧,fail-closed;运维面)**:
|
|
281
|
+
修前同一个声明在不同的 `SESSION_BACKEND` 写法下走不同的路:`DB_BACKEND=pg` + `SESSION_BACKEND` 未设 / `mysql` + 没有 `PG_HOST` ⇒ 起服抛 `missing required env: PG_HOST`;
|
|
282
|
+
`DB_BACKEND=pg` + `SESSION_BACKEND=auto`(「坐标不在就不探测」)或 `SESSION_BACKEND=memory` + 零 `PG_*` ⇒ **起服成功、跑在内存里**,`/health` 照样 200,
|
|
283
|
+
能力位 `store` 报 `{ declared: "pg", backend: "memory", durable: false }` —— 一个自以为在持久化的部署其实重启即丢(`REQUIRE_PRINCIPAL=true` 同形)。
|
|
284
|
+
本版起显式 `DB_BACKEND=mysql|pg` 而该引擎的主机坐标(`MYSQL_HOST` / `PG_HOST`)缺席 ⇒ **配置期拒启**,上述各写法(以及 `REQUIRE_PRINCIPAL=true`)同一句拒句:
|
|
285
|
+
`DB_BACKEND=pg declares the PostgreSQL engine, but its connection coordinates are not set (missing: PG_HOST, PG_USER, PG_DATABASE) — … Refusing to boot rather than starting non-durable under that declaration (whatever SESSION_BACKEND says). To persist: set PG_HOST, PG_USER, PG_DATABASE …; to run without SQL: DB_BACKEND=local … or DB_BACKEND=memory.`
|
|
286
|
+
拒句点名缺的坐标键名(`MYSQL_HOST` / `MYSQL_USER` / `MYSQL_DATABASE` 同形),不回显任何值。
|
|
287
|
+
**谁受伤**:靠 `SESSION_BACKEND=auto` 静默内存起服过活的开发 / 预发环境(写了 `DB_BACKEND=pg|mysql`、没配坐标、一直跑内存而不自知),以及 `DB_BACKEND=pg|mysql` + `SESSION_BACKEND=memory` + 零坐标的部署 —— 升级后起服失败。
|
|
288
|
+
**升级前做(出路)**:要持久 ⇒ 补齐坐标(`PG_HOST` / `PG_USER` / `PG_DATABASE` · `MYSQL_*` 同形);要无 SQL 的部署 ⇒ 把 `DB_BACKEND` 改成 `local`(单用户文件店)或 `memory`(纯内存)一行。
|
|
289
|
+
坐标齐的部署、`DB_BACKEND=local|memory`、不写 `DB_BACKEND` 的部署(含 `SESSION_BACKEND=auto` 而零坐标的内存形)零变化;主机在场而 `*_USER` / `*_DATABASE` 缺的半配置仍是原来的 `missing required env`。
|
|
290
|
+
同族:`MEMORY_ENGINE_BACKEND=pg|tidb` 要绑的池没开而 `DB_BACKEND` 已点名该引擎时,拒句不再说「要 `DB_BACKEND=…`」(那指错了修法),改点名真正开店的条件(持久会话后端:`SESSION_BACKEND` 未设、`mysql` 或 `auto`,不是 `memory`;与必需的坐标键)。
|
|
291
|
+
**回滚**:回到上一版即恢复旧行为(静默内存),无数据面改动。
|
|
292
|
+
9. **起服多一次只读普查:SQL 后端的 `checkpoint` 表里还有几行存量停驻行,其规则提议带着「无 `kind` 的 batch 成员」(运维面;零动作;不改任何一行)**:
|
|
293
|
+
引擎的规则提议读者为一个旧形留着一条存量读臂 —— batch 成员没有 `kind`、只有四个命令文本键时读成 `command`;这条臂只有在「零行还靠它」时才能删。本版起每次起服(MySQL 协议与 PostgreSQL 同一份实现)
|
|
294
|
+
在后台(不挡起服就绪)只读扫一遍 `checkpoint` 表(所有状态的行;`rule_suggestions` 列与 blob 里的 `pendingAction.ruleOffers` 两个载体,各按它自己的读者读:列按本店回读口的窗,blob 按引擎整只数组),出一行 info `approval_batch_kindless_rows { count }`(零也出,是「已扫完且为零」的正面证据),
|
|
295
|
+
每个带旧形成员的行另在 `fail_open_total{tag="server.approval-batch.kindless-row"}` 记一次(探针行 `row=<行指纹> carriers=…`,行指纹不是令牌)。
|
|
296
|
+
**不翻行、不删臂、不改任何一行的读法**。读不出形的 cell(坏 JSON / 不是列该有的形)不计入行数,另出一行 warn `approval_batch_kindless_census_unreadable_cells { cells }`;扫失败(库抖 / 权限)只出一行 warn `approval_batch_kindless_census_failed`、不出 info、不拒启(半途读数不会冒充零)。
|
|
297
|
+
**谁受伤**:无 —— 零 wire、零 DDL、零写;代价是起服后台多一次按键集分页的只读扫描(列载体取 `IS NOT NULL` 的行、blob 载体 `LIKE` 预筛,没有提议的行不出库)。**升级前做**:无。**回滚**:无需。
|
|
298
|
+
范围(如实):只扫 SQL 后端的 `checkpoint` 表;`local` 文件账本、存卡 `approval_ask.card_json`、账本帧不扫;读数逐页读到、不是原子快照(页间别的副本的写入可以让一行被漏数或多数一行;滚动升级窗里仍停在旧版本的副本之后写下的旧形行,下次起服才数得到)。
|
|
299
|
+
|
|
300
|
+
10. **🔴 local 后端(`DB_BACKEND=local`,含缺省推导的 local)数据根一次性迁移:会话的建档时刻与 fork 谱系搬进会话元数据边档,带属主戳的会话存档改写成匿名(本服务起服时自己改;升级前备份数据根、先停光旧进程再起本版;回滚只有恢复备份)**:
|
|
301
|
+
local 店的行事实(属主 / 化身 / 执行放置 / 建档时刻 / fork 谱系)只住在数据根的 `session-incarnations.json`(每只会话一格);`sessions/*.jsonl` 里的会话存档只是匿名的对话内容 ——
|
|
302
|
+
本服务交给引擎的写不再带属主,交出的会话元数据(交给引擎的会话、`GET /v1/sessions/:id` 的 `createdAt`、列表行的 `firstActivityAt`)都取自那一格。
|
|
303
|
+
起服的一次性迁移(M33;窗 = 发布日 + 30 天,窗内每次起服都跑,第二次起零命中):① 每只会话存档的建档时刻与 fork 谱系补进它那一格(盘上有存档而没有格的,建一格);
|
|
304
|
+
② 存档首行仍带属主戳的(更早的版本导入 / 换装写下的,及其 fork 后代)改写成匿名 —— 条目逐条不变(含发言者归属);每只改写前先在数据根的 `session-archive-m33/` 下写一份快照、改写后删,
|
|
305
|
+
进程在半途被杀 ⇒ 下一次起服先从快照补完再做别的。改不了的存档原样留着、一行一条 warn 点名(`local_archive_kept_stamped`,`reason` = `invalid` 导入检查不收它的日志 /
|
|
306
|
+
`normalizes` 重导会改它的内容 / `records_skipped` 读它时跳过了读不出的记录);首行读不出的点名 `local_archive_unreadable`。读数在起服行 `one_time_migrations_applied` 的五个 `localArchive*` 字段
|
|
307
|
+
(嵌入方 `OneTimeMigrationReport` 多五键,BREAKING 类型面)。
|
|
308
|
+
**快照目录的常设拒启**:起服时 `session-archive-m33/` 里有消化不了的快照(或本条迁移删码之后那里仍有文件)⇒ 拒启 `config.local_archive_snapshot_present`,拒句点名文件与两条出路。
|
|
309
|
+
**仍带戳的存档**(迁移留着的,或跳过本条迁移所在的版本直接升上来的数据根):读、续跑、拉取照常;`POST /v1/sessions/:id/fork` 与改日志的推送(会话同步导入的提交)同答 `409 conflict`,句子「this session's stored archive still carries an owner stamp … delete the session and push it again」(什么都没写,行不动;从头再同步照样撞 —— 出路就是句里那一条)。
|
|
310
|
+
**行为修复**:`replaceEntries`(先清后导)之后列表行的 `firstActivityAt` 与会话视图的 `createdAt` 不再变成换装时刻。
|
|
311
|
+
— **谁需要**:local 部署上 fork / 推送更早版本导入过的会话的用户 —— 修前 fork 出来的子会话存档带着别人的戳,换装以存档自己的戳为写条件。
|
|
312
|
+
— **谁受伤**:① 回滚:上一版读本版写过的 `session-incarnations.json` 严格拒启(格里多了两键)—— 回滚只有恢复升级前的备份,备份之后的会话改动随之丢;
|
|
313
|
+
② 迁移留着的带戳存档:fork 与改日志的推送被拒;③ 数据根很大时第一次起服多花一次整档读写(每只带戳存档读一遍、写一遍)。
|
|
314
|
+
— **补偿**:升级前备份整个数据根(含 `sessions/` 与各 `session-*.json`);停光旧进程再起本版;按 warn 行点名的会话,删掉后重推(推到不存在的会话 = 新建)。
|
|
315
|
+
**窗**:迁移码在窗关之后的第一个小版本删除;跳过本版的升级,至少在窗内起一次本版。
|
|
316
|
+
11. **本机形(`DB_BACKEND=local`)的后台子代转录活过重启:它住进宿主会话店的委派分区,随后台记录同亡;接线清单 `fleet.subagentTranscripts` 在 local 上由 `rows` 改答 `full`,`rows` 档不再由本服务的任何装配产出;主 runner 的 `session.store` 在 local 上由 `process_local` 改答 `declared_durable`(行为变更;wire 值变化;HTTP 体的形不变)**:
|
|
317
|
+
此前 local 部署上后台子代(`run_in_background` 的 Agent 调用)的转录住在进程内的短 TTL 店(空闲 1 小时即清):后台记录(行 + 终态快照)活过重启,对话不活 —— 重启后对已结束的子代 `SendMessage` 续不上,
|
|
318
|
+
按帧上的 `transcriptId` 读子代转录答 `404`。现在 local 后端的会话店与 SQL 两种后端一样声明了委派分区,每只新派的后台子代的转录生来就是 `<数据根>/sessions/` 下的一只**分区会话**(存档行头记着它的委派元组:父会话、根会话、子代 id;首写不可变):
|
|
319
|
+
① 活过重启:重启后对已结束 / 失败的子代 `SendMessage` 在后台复活它,带着原上下文接着答(回执说 `was revived in the background with its prior context intact`);
|
|
320
|
+
② 属主读 `GET /v1/sessions/<transcriptId>` ⇒ `200`,体上带 `agent: { id, parentSessionId, rootSessionId }`(与 SQL 后端同一只读面);属主 = 发起它的那棵委派树的根会话的属主,在建行那一笔写下;
|
|
321
|
+
③ 不进会话列表(`GET /v1/sessions`、`/resume` 的列表),随后台记录同亡:记录被收割时(`BG_AGENT_RETENTION_MS`,缺省 7 天)转录一并删除;记录已不在的分区会话由分区孤儿腿按同一视界收(这条腿此前在 local 上不可用);
|
|
322
|
+
④ 会话同步往子代 id 上写(`POST /v1/sessions/<id>/sync/import` 的整段换装与两阶段提交,含「内容与店里相同」那一支)⇒ `409 conflict.session_placed` + 固定句 + `detail.placement_kind`(与 SQL 后端同码同体),子代的存档与边档一字不动;
|
|
323
|
+
⑤ 子代停在审批上时,停驻只核它的转录在不在宿主店、属主对不对得上;此前「停驻时把私店里的转录拷进宿主店」的做法退役(声明了分区的部署上,能停驻的后台子代生来就在宿主店)。
|
|
324
|
+
`subagent_type: "fork"` 的后台子代不进分区(各后端同):它的转录是从父会话分叉出来、住宿主会话店的一只普通会话,记录被收割时保留(归会话留存管),①–④ 不适用于它;
|
|
325
|
+
引擎也不复活它(重启前后都一样:`SendMessage` 的工具结果是错误,`revive.fork_unsupported`)。
|
|
326
|
+
`wiring_manifest` 帧与 `GET /v1/diagnostics/wiring` 的 `fleet.subagentTranscripts` 在 local 上由 `rows` 改答 `full`。本服务的装配从此只产出 `full`(`DB_BACKEND=mysql` / `pg` / `local`)与 `none`(没有后台记录店的 `DB_BACKEND=memory`);
|
|
327
|
+
`rows` 仍是引擎闭集里的词(调用方自挂的 runner 仍可能答它),开集读者照旧。主 runner 的 `session.store` 在 local 上由 `process_local` 改答 `declared_durable`(会话暖缓存层此前不转发内层店的耐久声明,本版转发),起服自检把 local 记作持久介质;
|
|
328
|
+
子代 runner 的那一格仍答 `process_local`(它的普通子任务会话本就住进程内的短 TTL 店);SQL 两种后端的 `session.store` 同样改答 `declared_durable`(本节第 24 条)。
|
|
329
|
+
**谁需要**:用本机 cli / TUI 跑长任务、会派后台子代的单用户 —— 重启、升级之后还能接着跟已结束的子代说话,还能读它的转录。
|
|
330
|
+
**谁受伤**:① 数据根变大:后台子代转录留到记录被收割为止(缺省 7 天),重度委派的用户 `sessions/` 目录会长;
|
|
331
|
+
② 本机会话店在每次收尾、登记、执行格读写与同步提交时都要判一次「这是不是分区会话」,判法是把那只会话的存档读一遍 —— 长会话每跑一次多一次整档读(引擎把这一读改成只读行头之后消失);
|
|
332
|
+
③ 升级前停驻时被拷进宿主店的子代转录仍是**普通会话**:出现在会话列表里、不随记录删除(不迁移);④ 升级前派出、转录还在私店里的子代照旧活不过这次重启(不迁移);
|
|
333
|
+
⑤ 带身份的本机部署上,升级前停驻时拷进宿主店、没有属主的子代转录,升级后批准再停驻会被否决(普通会话没有记录的委派树,不被认领);
|
|
334
|
+
⑥ 对子代 id 推会话同步的调用方从此收 `409`;⑦ 删掉根会话不连带删子代转录(子代转录跟着后台记录走)。
|
|
335
|
+
**补偿 / 出路**:① 调小 `BG_AGENT_RETENTION_MS` 即少留(行与转录一起);③ 不想留的旧子代转录 `DELETE /v1/sessions/<id>` 删掉;⑤ 升级前先把停驻待批的审批处理完;⑥ 换一个会话 id 推。
|
|
336
|
+
**回滚**:回到上一版后,本版写下的子代转录文件留在 `<数据根>/sessions/` 下(引擎的文件仓不把分区会话列进会话列表,上一版也不收割它们 —— 要清就删文件),后台子代回到私店形。
|
|
337
|
+
12. **记忆同步停驻:游标用不了的层只点名一条出路(删游标);停驻在用户面上读得到 —— `GET /v1/sessions/:id/memory-status` 加性键 `memorySync`;停驻层的运维行由 `memory_sync_layer_failed` 换成 `memory_sync_layer_parked`(wire 加性;运维面日志形变更;部署零动作)**:
|
|
338
|
+
一层的同步游标被同步引擎在 scope / 对端 / 店任一轴拒,或读不成游标 ⇒ 这一层停驻(零请求、文件不动,每一轮照样停,直到删掉它)。本服务对停驻只点名**删掉这一层的游标文件**这一条出路
|
|
339
|
+
(下一轮从空基线重收敛:拉中心这一层有的、推本店有的、不推删除;两边都改过的条目按冲突报)。这是**保守合并**:自上一轮以来本地删掉的条目会被中心拉回来,中心删掉的条目会被本地推回去 —— 不丢条目,但删除要重做。
|
|
340
|
+
本服务不写、不改、不删游标(不改绑、不做旧游标的迁移或自动绑定、没有确认旋钮),引擎游标拒句里的「改绑」不再出现在本服务的任何一句里;升级前写下的旧游标同属「用不了的游标」,同样停驻、同一条出路;
|
|
341
|
+
一次性搬迁搬不动的更早游标文件(`sync-cursor-central.json` 读不成对象或没有 scope)那一行 `memory_sync_cursor_not_relocated` 也只点名删掉它(上一版还说「从备份恢复」)。
|
|
342
|
+
运维行 `memory_sync_layer_parked`(warn)字段 `reason` / `scope` / `cursorPath` / `axis?` / `found?` / `wayOut` / `note`;瞬态失败(中心不可达、读游标文件的 I/O 错)仍是 `memory_sync_layer_failed`。
|
|
343
|
+
用户面:`memory-status` 的 `memorySync`(有同步腿 ⇔ 在场)= `{ parked: [{ scope, wayOut: "delete_cursor" }] }`,`parked: []` = 在同步;部署事实,不随会话、不随 `?scope=`;游标盘路径不上 wire。
|
|
344
|
+
**订正 7.139.0 节第 1 条 ①(文字)**:「中心没换 ⇒ 把游标的 `"peer"` 改成新身份」与随后「补 `store`」两步不再是本服务点名的处置 —— 处置只剩删游标(该条的 ②);
|
|
345
|
+
**订正 7.140.0 节第 5 条(文字)**:那一层停驻时出的是 `memory_sync_layer_parked`(本版起),不再是 `memory_sync_layer_failed`。
|
|
346
|
+
**谁受伤**:按 `memory_sync_layer_failed` 认游标被拒的告警会漏掉停驻;按引擎拒句子串(`cursor is for` / `two ways out`)匹配的规则失配;中心没换而走删游标的部署,自上一轮以来一侧删掉的条目会从另一侧回来(改 `peer` 本可保留它们)。
|
|
347
|
+
**出路**:告警改认 `memory_sync_layer_parked`(`scope` / `cursorPath` / `axis` / `found` 机读);删游标之前先把要删的条目在两侧删干净可减少回来的条目;握有那只游标文件可信备份的,换回备份仍可用(本服务不点名、不拦)。
|
|
348
|
+
**回滚**:回到上一版,停驻层的运维行回到 `memory_sync_layer_failed`(句子回到引擎的两条出路),`memorySync` 键消失;零数据面。
|
|
349
|
+
13. **在飞 run 的权限模式切档口 `POST /v1/runs/:id/permission-mode`(wire 加性;能力位 `permissionModeWrite` 由恒 false 改为按部署;部署零动作)**:
|
|
350
|
+
体 `{ mode }`(引擎模式闭集),直通引擎的切档动词,200 体原样带引擎回执 `permissionMode`(`{ requested?, effective, foldedBy? }`)、本服务折了词时另带 `admission`,以及 `persisted`(准入的词有没有写回这条 run 的存储体)。
|
|
351
|
+
切档口与提交口经**同一只受理判官**:运维 `AUTONOMY` 地板、托管写围栏、任务 settings 的 `disableAutoMode` 在两口上同折同拒(拒码 `422 request.host_posture_refused` 与提交口同句);提交口的答案与拒序与上一版逐字同。
|
|
352
|
+
能力位 = 持久 run 账面 ∧ checkpoint 店(`DURABLE_APPROVAL`);没有 checkpoint 店的部署位仍 false、那一口答 501。
|
|
353
|
+
写回走 run 的认领栅栏且认腿(停驻后被续跑的新腿接手 ⇒ 旧腿迟到的回写零写):SQL 后端在 `checkpoint_ctx` 既有行上一条 `UPDATE`(两方言同句),**零 DDL**;local 后端原子写既有档。
|
|
354
|
+
**谁需要**:回合内切档的壳 / 客户端。**谁受伤**:从严切松的调用(按部署折 / 拒,与提交口同答);切档与停驻同时到 ⇒ `persisted:false`,续跑回到切档前的词。
|
|
355
|
+
**壳 / 客户端**:先读能力位再渲可写开关;渲染引擎回执的 `effective`(不是自己发的词);`persisted:false` ⇒ 续跑后重切。老 server 没有这一口(位恒 false)。**回滚**:回到上一版即无此口,存储体里已写回的词按同一读法照读(零数据面迁移)。
|
|
356
|
+
|
|
357
|
+
14. **后台 run 与续跑腿停驻没落定就以失败收场 ⇒ 先作废手里那张卡、再放认领;后台 run 的计量一条腿只记一次(行为修复;零 wire、零 DDL;部署零动作)**:
|
|
358
|
+
① run 停在审批 / 计划审阅门上(卡已在 checkpoint 店里)而记这次停驻的账本写抛(停驻行 / 用量行 / 记停驻之前的清单行与缓冲文本),或 `/decide` 之后的续跑腿在后面的门上再停、写再停账本行抛:
|
|
359
|
+
此前 run 行收成 `failed`、会话认领释放,那张卡仍 pending(列在 `GET /v1/approvals` 与收件箱里,决定口照样受理,续跑在没有认领的会话上驱动、结局回不到 run);
|
|
360
|
+
现在这条腿**先**按卡自己的 scope 作废那张卡(它离开待决面,再决断答 404),**再**落 `failed` 行、放认领。不在本 run 会话上的卡(cascade 级上的停驻)照旧不动。
|
|
361
|
+
作废没做成(checkpoint 店读 / 写抛、卡的会话对不上)⇒ 照样 `failed`,`fail_open_total{tag="server.park.held-card-void-failed"}` 计一次(detail 带 `leg=bg|resume`)+ 一次 warn,卡回到此前的形(由审批兜底收割收走)。
|
|
362
|
+
② 后台 run 的计量只在腿收场那一拍记一次:结局已落定之后的账本写再抛(完成后的建议补全行、终帧之后流再抛)不再让 `tasks_total` 把这条 run 计两次、`runs_active` 多减一次(`GET /metrics/summary` 的 `runsActive` 不再为负)。
|
|
363
|
+
`runs_active` 的减一与 `task_duration_seconds` 的那一笔从「结局行写下」挪到「腿收场」:请求了 `suggestNextPrompts` 的 run 多算建议补全那一段。
|
|
364
|
+
**谁需要**:看待决列表 / 审批收件箱的人,按 `/metrics`、`/metrics/summary` 看 run 数的运维。**谁受伤**:想在那一形里接着批那张卡的人(此前批下去也回不到 run);按建议补全开关混看时长的看板有一段偏移。
|
|
365
|
+
**补偿**:同会话重新提交(对话还在,`failed` 行带原错误文案);时长按有无 `suggestNextPrompts` 分开看。**回滚**:回到上一版即回到此前的两形(零数据面)。
|
|
366
|
+
15. **`settings.permissions.deny` / `ask` 的条目可以带出处层:`{ "rule": "<规则>", "layer": "<来源>" }`(wire 条目型放宽 + 能力位 `settings.permissions.layers`;纯串照旧,读法不变)**:
|
|
367
|
+
来源词 = `userSettings` / `projectSettings` / `localSettings` / `flagSettings` / `policySettings` / `foreignProjectSettings`。只有 `/` 开头的路径规则随层变:`userSettings` 的读在执行环境的配置根
|
|
368
|
+
(host 车道 = `SEMA_CONFIG_DIR`,缺省 `~/.sema`;沙箱车道 = 转给沙箱的 `SEMA_CONFIG_DIR`,否则执行环境 home 下的 `.sema`,home 解不出 ⇒ 422 `home_unresolvable`),其余来源与纯串一样读在任务根;
|
|
369
|
+
`~/`、`//`、相对形在每一层读法相同。层只决定规则读在哪,不决定准入档。一桶仍至多 1000 条(带层条目与纯串同计)。
|
|
370
|
+
**之前**:user 层写的 `Read(/secret/**)` 被端折成 `settings.permissions.deny` 里的一个串,守的是任务根下的 `secret`,配置根(`SEMA_CONFIG_DIR`,缺省 `~/.sema`)下的 `secret` 照读。
|
|
371
|
+
**现在**:端把它作为带层条目 `{ "rule": "Read(/secret/**)", "layer": "userSettings" }` 发来时,它守配置根下的 `secret`、不再守任务根下的 —— 与参照实现读 user 层 `/` 的位置相同;别的层与纯串条目读法不变。
|
|
372
|
+
**出路**:要守每个项目自己的目录,把规则放进项目层,或写相对形 `secret/**`(工作目录下任意深度);固定位置写 `//` 绝对形。沙箱车道上配置根读不出时:往沙箱 env 名单里加 `SEMA_CONFIG_DIR`,或声明 `REMOTE_EXEC_HOME_DIR`。
|
|
373
|
+
**回滚 / 混版副本**:带层条目的请求交给本版之前的服务会被拒(新提交 400,续跑 409),不会被静默读丢;没有改动的端照旧发纯串,读法不变。
|
|
374
|
+
**已知限制**:`allow` 桶只收纯串(带层条目 400 `bad_entry`),user 层的 `/` 形 allow 今天仍按任务根放行;Windows 形 home 的 device 车道没有声明 home 的出路(`REMOTE_EXEC_HOME_DIR` 只收 `/` 开头),那里 user 层的 `/` 形规则请写成 `//` 绝对形。
|
|
375
|
+
16. **`GET /v1/runs/:id` 的 `heldBy`:一个条件 —— `null` = 这条 run 的 claim 已释放,非空 ⇔ 此刻有副本持有;终态行恒 `null`(行为变更;wire 值域变化;部署零动作)**:
|
|
376
|
+
此前终态行上 `heldBy` 仍是跑这条 run 的副本 id,契约写「变 `null` **或** 进终态 = 已释放」两读法。现在终态行(`completed` / `failed` / `blocked`,含 `errorCode` 为 `cancelled` /
|
|
377
|
+
`run.stalled` / `run.orphaned` / `approval.expired` 的收割落盘)投 `null`;`running`、`suspended`、`needs_review` 给持有副本的 id;读面把久未心跳的 `running` 折成 `failed`
|
|
378
|
+
(`errorCode:"run.stalled"`)的那一形照旧给失联副本的 id(盘上仍 `running`,claim 仍被占着),收割落盘之后 ⇒ `null`。
|
|
379
|
+
`GET /v1/runs?idempotencyKey=` 与提交面同键重放(`replay: true`)的体是同一个读面,同改。存储里的 `instance_id` 列不变。
|
|
380
|
+
**谁需要**:按 `heldBy === null` 判「claim 已释放」的客户端 —— 真引擎上终于读得到 `null`。**谁受伤**:把终态行的 `heldBy` 当「哪个副本跑完的」来读的调用方。
|
|
381
|
+
**补偿**:那条历史事实读部署日志 / 指标(按 `taskId`),或直接查存储行的 `instance_id` 列。**回滚**:回到上一版即回到终态行给 id(零数据面)。
|
|
382
|
+
17. **停驻的工具审批卡:运维队列行(`GET /v1/approvals` 的 `pending[]`)与 `/v1/approvals/stream` 的 `pending` 帧恰带 `boundGrantDigest` / `boundGrantAbsence` 之一(行为修复;wire 值域变化;部署零动作)**:
|
|
383
|
+
读法与助手收件箱行相同 —— 摘要是串 ⇒ 摘要;否则摘要键不在且行上的缺席词是闭集成员 ⇒ 那个词;否则 ⇒ `"unreadable"`。本服务 7.128.x 及以前写下、升级前停驻的卡(两者都不说)
|
|
384
|
+
此前在队列两面两键都不带、在收件箱行上是 `"unreadable"`;现在三面都是 `"unreadable"`(本文件 7.129.0 节「升级前停驻的卡两者都不说」说的是停驻行本身;读面上它们一律读作 `"unreadable"`)。
|
|
385
|
+
集外缺席词同读 `"unreadable"`(此前队列两面缺席);摘要在却不是串的行读 `"unreadable"`,即使行上另有 `not_bindable` —— 这种行的 `rememberRefused` 由缺席变 `true`,与 `/decide` 的回执对齐。
|
|
386
|
+
SQL 后端为技能卡清单多读的整行读失败时,行保留 `boundGrantDigest`(只丢清单与成因词)。本服务不改写任何一行。
|
|
387
|
+
**谁需要**:读队列行决卡的壳 / 运维台(只认一种形)。**谁受伤**:按「两键都不在」识别老卡的读者 —— 改读 `boundGrantAbsence === "unreadable"`。**补偿**:无需动作;读不出绑定的卡照旧可以批这一次(「本会话放行」记不住,与此前同)。
|
|
388
|
+
**回滚**:回到上一版即回到队列两面对这些卡两键皆缺(零数据面)。
|
|
389
|
+
18. **脱敏:私钥 armor 与 JSON 秘密字段的三处结构读法收紧(行为面,安全;部署零动作)**:① 不带引号、粘在起始栅栏前的值(`password=x-----BEGIN PRIVATE KEY-----`)吃掉栅栏开头一截时照起块,整块与被吃的值各自照遮(PEM / SSH2 / PuTTY 同);
|
|
390
|
+
② 体已经起了、文本里没有真收尾(上游截断)时,整段读法从起始栅栏遮到本段(到下一枚起始栅栏或窗尾)最后一段体形串(≥8 位 base64 串)之后 —— PEM 不设体上界,SSH2 在体上界之内;
|
|
391
|
+
JSON 读法下窗 = 栅栏所在的串值,兄弟键原样;体没起的起始栅栏(说明文字、代码里提到它)不动;有界日志行的读法不变;③ shell 命令串里内嵌的 JSON(`\"secret\":\"…\"`,以及再字符串化一层的 `\\\"` 形)的值照遮,记号两侧写回读到的引号形。
|
|
392
|
+
**谁受伤**:体起了、没收尾的私钥块之后(含文档里示例私钥体之后的正文)、本段最后一段体形串之前的说明文字在 trace / 读面里一并换成记号(有界日志行上一版即如此)。
|
|
393
|
+
**出路**:无需动作;要看原文读未脱敏的源。
|
|
394
|
+
19. **沙箱三车道(e2b / k8s / local-docker)读拒表字节地板:新旋钮 `SANDBOX_READ_FLOOR`(闭集 `keep | off`,缺省 `keep`;词外 / 空串拒启)· 起服行 `remote_exec_enabled.sandboxReadFloor`(运维面;本版零行为变化;部署零动作)**:
|
|
395
|
+
三条沙箱车道守不守读拒表的字节地板 = 读地板模块服务这条车道 ∧ 本键不是 `off`;本版模块不服务任何车道,三车道的 `keepsReadFloor` 仍是 `false`,沙箱里每一次起动的命令行 / 选项与上一版逐字同。
|
|
396
|
+
起服行 `remote_exec_enabled` 在这三条车道上多一个字段 `sandboxReadFloor`:`unserved`(模块还没服务这条车道)/ `off`(部署关了)/ `kept`(守)。别的车道上本键无作用、也不出这个字段。
|
|
397
|
+
将来某车道进服务集(那一版的 MIGRATION 写部署前提:内核、架构、非 root 的镜像用户、k8s 上 configmaps 的 create)时,不满足前提的沙箱上带读拒表的命令会被拒起(`spawn_error`,首句点名原因词);那时不想守的部署设 `SANDBOX_READ_FLOOR=off`。
|
|
398
|
+
**谁受伤**:本版部署无人;按 `remote_exec_enabled` 的字段全集做严格校验的日志管线会看到一个新字段。嵌入方:给 k8s 车道传 `podSpecPatch` 的,补丁里的卷名多两只保留名 `sema-floor-x86-64` / `sema-floor-aarch64`
|
|
399
|
+
(适配器给地板二进制自铸的卷),补丁用到它们 ⇒ 开 pod 时被拒,拒句点名保留名(部署 env 面没有这个入口)。**出路**:无需动作(嵌入方给补丁卷换个名)。**回滚**:回到上一版即无此键与字段(零数据面)。
|
|
400
|
+
20. **`REMOTE_EXEC` 的形是部署声明的有序车道表(逗号分隔、首项缺省);本引擎每个进程只装一条车道 ⇒ 表里不止一条起服拒(部署 env 形变,BREAKING;单词零变化)**:
|
|
401
|
+
契约包 16.0.0 把 worker 的执行车道由单值改为有序车道集 `runtime.execution.lanes`,渲成 env 是 `REMOTE_EXEC=<lanes 按序逗号连接>`。本服务读同一个形:逗号分段,每段逐字是一个车道词(不 trim、不折大小写),
|
|
402
|
+
不许空段、不许同一车道出现两次;写着契约退役车道值(`remote-docker`)⇒ 拒句给出契约的去向句。单词 = 一条车道的表,装配、必需 env 判与拒句都与上一版逐字同。
|
|
403
|
+
表里不止一条车道 ⇒ 起服拒:`REMOTE_EXEC="k8s,device" declares 2 execution lanes (k8s, device; the first is the default) — this engine wires exactly one execution lane per process, so device would never run anything while the deployment declares it. Refusing to start rather than serving "k8s" alone: declare one lane per engine (REMOTE_EXEC=k8s) and run a separate engine for each further lane.`
|
|
404
|
+
这一拒先于各车道的必需 env 判(缺件的多车道表也先说这一句)。
|
|
405
|
+
**谁受伤**:由中心(或自写渲染器)下发两条及以上车道的部署 —— 上一版同样拒启(整串被当成一个认不出的词),本版拒句换成上面这句。只写一个车道词的部署零动作。
|
|
406
|
+
接中心(`CONFIG_PROVIDER=remote`)的部署:中心答的 `workers` 行若仍是旧形单值 `runtime.execution.lane`,契约包的读法把它当墓碑拒、整份读不进 ⇒ 每一次拉取失败,
|
|
407
|
+
部署停在盘上 LKG / env,能力面 `centerWiring.effectivePull` 读作 `false`(拉取恢复前,中心改的配置到不了这台引擎)。
|
|
408
|
+
**出路**:一台引擎一条车道:`REMOTE_EXEC=<首项>`,其余车道各起一台引擎。接中心的部署的**升级序**:中心先把存下来的 `workers` 行跑一次契约包的一次性迁移
|
|
409
|
+
(`npx @sema-agent/settings-schema migrate <config.d 目录>`:`lane: L` ⇒ `lanes: [L]`,一元表与旧单值逐位同),再升本版引擎。**回滚**:回到上一版即回到单词读法(零数据面)。
|
|
410
|
+
21. **记忆持久面方言词 `MEMORY_ENGINE_BACKEND=tidb` 改名 `mysql`:旧词起服拒;`memoryEngine.backend` / `memoryPosture.backend` 在 MySQL 族部署上由 `"tidb"` 改报 `"mysql"`(部署 env 形变 BREAKING;wire 值变化)**:
|
|
411
|
+
MySQL 族那只 SQL 店只有一个字,与 `DB_BACKEND=mysql` 同字。`MEMORY_ENGINE_BACKEND=tidb` ⇒ 起服拒,拒句 `env MEMORY_ENGINE_BACKEND="tidb" must be one of: file, pg, mysql`。
|
|
412
|
+
池、表、行与记忆数据零改动(同一只池、同一组表);方言与店的配对规则不变(`mysql` 要 `DB_BACKEND=mysql`,`pg` 要 `DB_BACKEND=pg`)。
|
|
413
|
+
`GET /v1/capabilities` 的 `memoryEngine.backend` 与诊断面 `memoryPosture.backend` 在这类部署上答 `"mysql"`;`capability.memory_store_required` / `capability.memory_engine_required` 的 501 文案里的 `pg|tidb` / `pg/tidb` 同换(码不变)。
|
|
414
|
+
**谁受伤**:部署环境写着 `MEMORY_ENGINE_BACKEND=tidb` 的(拒启);按 `memoryEngine.backend === "tidb"` 分支的客户端;按 501 文案子串匹配的规则;
|
|
415
|
+
嵌入方:`ServiceConfig.memoryEngineBackend` 的值域由 `"file" | "pg" | "tidb"` 改为 `"file" | "pg" | "mysql"`(类型面 BREAKING,零别名;tsc 红即消费点清单)。
|
|
416
|
+
**出路**:升级前把部署环境改成 `MEMORY_ENGINE_BACKEND=mysql`(只此一处,数据零动作);中心存下来的配置行由契约包的一次性迁移改写(`npx @sema-agent/settings-schema migrate <config.d 目录>`)。客户端改认 `"mysql"`。
|
|
417
|
+
**回滚**:回到上一版前把这一行改回 `tidb`(上一版不认 `mysql` 作记忆方言)。
|
|
418
|
+
22. **`config.d/remote-exec.json`(本地配置模式的车道文件)里的非空串字段只含空白 = 空 ⇒ 起服拒(行为收紧,fail-closed;部署面)**:
|
|
419
|
+
沙箱镜像、命名空间、主机、用户名、设备序列号、工作目录、挂载路径等此前拒空串的字段,写成纯空白(空格 / 制表 / 换行 …)此前被收下、拿去起容器或拉 pod,起服之后才响。
|
|
420
|
+
现在与空串同一条拒、同一句话:起服拒,拒句 `config.d/remote-exec.json under <根> is invalid: … must not be empty or whitespace-only — give it a real value (an optional key can simply be left out)`(点名那一格,不回显值)。
|
|
421
|
+
文件在即判:这条车道由文件驱动还是由 env 驱动都一样。非空白的值(含前后带空白的)逐字承运,不 trim。
|
|
422
|
+
**谁受伤**:车道文件里有纯空白字段的部署(病态输入)。**出路**:删掉那一键(可选字段:缺席 = 缺省行为),或给真值(必填的镜像 / 命名空间 / 主机 / 用户名 / 序列号只能给真值)。**回滚**:回到上一版即收下空白(不建议)。
|
|
423
|
+
23. **契约包 16.0.0 的其余读点(运维面;部署零动作)**:① 设备入口 `DEVICE_RELAY_URL` 的字面 `none` 与值文法取自契约包:写了却不合文法 ⇒ 拒句 `env DEVICE_RELAY_URL <契约规则句> — found: <契约拒因词>; got <脱敏后的值>`(此前是本服务自己的句子);
|
|
424
|
+
缺席 / 空串 / 只含空白只由车道必需 env 门拒,拒句与其余车道必需键同一句(本节第 7 条已按此写);两份根 compose 的 `DEVICE_RELAY_URL` 透传行移进由车道表生成的区段(值与行为不变)。
|
|
425
|
+
② `CONFIG_PROVIDER=local` 的本地配置一次读完:读得出的树与被拒的树同一条路;一份文档嵌得过深(根下 199 层以上)⇒ 它是一份被拒文档,成因词 `too_deep`,与同树别的被拒文档一起交出(此前整份读抛,起服走「源不可达」、刷新拍记失败);
|
|
426
|
+
被拒的那一读也报目录里没人读的文件(此前被拒时不报)。模型面组拒的拒句表多一个 `too_deep` 句。③ 契约包退役组拒码 `config.summarize_model_missing`(本服务从未铸它,零行为)。
|
|
427
|
+
**谁受伤**:按设备入口旧拒句文字匹配的规则;按「被拒的本地读不报没人读的文件」写的告警(现在多报)。**出路**:无需动作。**回滚**:回到上一版即回到旧句子与旧读法(零数据面)。
|
|
428
|
+
24. **SQL 后端(`DB_BACKEND=mysql` / `pg`)的会话店补上顶层耐久声明:主 runner 的接线清单 `session.store` 由 `process_local` 改答 `declared_durable`(wire 值变化;只改读数,存取行为不变;部署零动作)**:
|
|
429
|
+
此前两种 SQL 会话店只声明了委派分区的耐久(子代转录),没有声明顶层的会话耐久;引擎对缺席的读法是进程内,于是真持久的 SQL 部署上,主 runner 的 `wiring_manifest` 帧与 `GET /v1/diagnostics/wiring` 的 `session.store`、
|
|
430
|
+
起服日志 `wiring_static` 的 `sessionDurability` 一律答 `process_local` —— 会话明明落在库里的两张真表上。现在 MySQL 协议与 PostgreSQL 两种会话店都声明 `durable`(与 local 后端、与委派分区的耐久读同一只常量),读数答 `declared_durable`;
|
|
431
|
+
会话暖缓存层(缺省 `SESSION_CACHE_TTL_SEC=300` 时包着真店)逐字转发内层声明,开不开缓存读数一样。起服自检的「声明持久 × 介质」对表在 `mysql` / `pg` 上零判决,不新增任何拒启。
|
|
432
|
+
引擎在续跑找不到会话(`resume.session_not_found`)时,于错误句末附的「装配说明」(检查点店声明持久而会话店不声明)此前在装了持久检查点店的 SQL 部署上是一句误报,现在不再附上;错误码与句子的其余部分不变。
|
|
433
|
+
不变的:子代 runner 的那一格仍答 `process_local`(它自己的普通子任务会话住进程内的短 TTL 店,委派分区的持久走分区声明、`fleet.subagentTranscripts` 照旧);会话店仍是进程内店的部署(`DB_BACKEND=memory`,或 `DB_BACKEND=mysql|pg` 而 `SESSION_BACKEND=memory`)仍答 `process_local`;HTTP 体的形、键集、会话的读写与重放一字未动。
|
|
434
|
+
**谁需要**:读清单判断「这台部署的会话重启后还在不在」的壳 / 控制台 / 运维面(此前对 SQL 部署读到的是错的)。**谁受伤**:无(数据面与存取行为不变);只有把「SQL 部署的 `session.store` 恒为 `process_local`」写死成分支的读者会改走 `declared_durable` 那一支,那一支才对应事实。
|
|
435
|
+
**补偿**:无需动作。**回滚**:回到上一版即回到旧读数(零数据面)。
|
|
436
|
+
25. **`workflow_complete` 补投帧(与 bg / 续跑账本行)多一只可选键 `diagnostics`:引擎在 workflow 完成通知上铸的诊断教学文本(wire 加性;行为面;部署零动作,零 DDL)**:
|
|
437
|
+
异步 workflow 跑完之后、下一次开流从会话收件补投的 `workflow_complete` 帧此前只带 `type · runId · status · summary`(7.135.0 起再加 `completionId`)。引擎在同一次完成的 live 通知上给一段诊断教学文本 ——
|
|
438
|
+
至多 5 行未完成 agent 的摘要、完整记录的读取手柄句、journal 坐标、续跑句 —— 补投路径却把它丢了;原腿已不在(断线重连 / 重启 / 空闲态到达)时,补投帧是它仅有的去处。
|
|
439
|
+
现在补投帧带它:键 `diagnostics`(串,非空才铸),是引擎为同一次完成铸的那段诊断文本(live `task_notification`〔`task_type:"workflow"`〕帧上同名键携同一段;
|
|
440
|
+
补投路径上引擎在交给本服务之前已按「人类读者」档抹过主机路径与 URL〔`[redacted-path]` / `[redacted-url]`,journal 坐标句里的部署路径因此可能已被抹〕,live 帧不经这一档,两张脸文字不保证逐字节相等;读取手柄句不含路径,不受影响)。
|
|
441
|
+
出门前过脱敏(与 live 帧上 `diagnostics` 同一个脱敏范围,入会话收件时洗一次,凭据形被遮成记号,店里只放洗过的字节),至多 4000 码元(超界从界上切,切点不落进本服务的 `«redacted:…»` 记号内部;引擎自己写进文本的 `[redacted…]` 记号若恰被界切开会留半枚,不露原值)。
|
|
442
|
+
收件条目的 `payload` 列(既有 TEXT 列)多放一个键,**零 DDL**:`workflow_complete` 的 `payload` 现在至多 `{"completionId"?, "diagnostics"?}` 两键。
|
|
443
|
+
**已知限制(如实)**:崩溃恢复补投(副本崩了、本服务重启后补投没来得及送达的完成)与本服务代为终结的孤儿 workflow **不带** `diagnostics` —— 引擎不把这段文本持久在 workflow 记录行上,本服务不编、不从别处拼;
|
|
444
|
+
这两条路上缺席读作「没有诊断文本」,`summary` 与按 `runId` 去重照旧。同一条路也包括「已入箱、尚未记作送达」时副本崩了的窄窗:恢复扫的重投按 `runId` 替换已入箱的那条(至少一次投递的既有语义),该条随之没有 `diagnostics`。
|
|
445
|
+
**谁需要**:渲染补投帧的壳 / SDK。**谁受伤**:无(additive)—— 唯一要留意的是对 `workflow_complete` 帧做封闭键集校验的一侧(多一只可选键);滚动升级窗里旧副本入箱的条目没有这一键(帧上缺席,照旧)。
|
|
446
|
+
**出路**:消费方按可选键读(缺席 = 这一条没有诊断文本,不是失败);封闭键集校验的一侧把 `diagnostics` 加进可选键。**回滚**:回到上一版即回到旧帧形(`payload` 列里已有的 `diagnostics` 被旧读法忽略,零数据面)。
|
|
447
|
+
|
|
448
|
+
26. **`GET /v1/capabilities` 加能力位 `mcpTransportKinds`:请求面读器与引擎今天能拨的 MCP 传输种类(wire 加性;提交面不放宽;部署零动作)**:
|
|
449
|
+
值是字符串数组,书写序,今天恒 `["stdio","http"]`,每种部署形都在场、不随部署形变。它**只回答**「语法 / 实现支持哪些传输种类」:本部署收不收调用方自带的 `mcpServers` 仍读 `mcpInjection`,「端到端可达」没有任何位承诺。
|
|
450
|
+
引擎自己还有一个 `host` 种类(要宿主回调席),请求面读器不收、本服务不装席,不在位里。
|
|
451
|
+
**提交面一字未动**:`mcpServers[].transport.kind` 不在位里的词(`host` / `sse` / `sdk` / `websocket` …)在新提交与 `POST /v1/capabilities/mcp/probe` 上照旧整次 `400`;位只是让客户端在**投影阶段**(拼 `mcpServers` 之前)
|
|
452
|
+
就知道某条目的目标传输读不读得了 —— 只拒那一台、其余照投,而不是整次提交挨 `400`。值的来源只有一处(契约包请求传输形 `kind` 联合型的两向编译钉),位不可能与读器的词表分叉。
|
|
453
|
+
**谁需要**:投影 `mcpServers` 的客户端(终端壳 / 客户端核心包)与要早知道某类条目进不来的 SDK 调用方。**谁受伤**:无 —— 加一个键;按「能力位键集严格相等」解码的客户端会多见一个键。
|
|
454
|
+
**客户端**:先读位再投影;位缺席 = 老 server,读作 `["stdio","http"]`(契约承诺的旧版下限 7.135.0);**位里出现不认识的词按「不支持该种类」处理,不让整份能力解析失败**(位以后会随新种类长词)。**回滚**:回到上一版即无此位(按上一句读)。
|
|
455
|
+
|
|
456
|
+
27. **`GET /health` 加性键 `engineLease: { lingerMs, tickMs }`:引擎附着租约窗上 wire(wire 加性;运维面;部署零动作)**:
|
|
457
|
+
装了自退腿(`ENGINE_AUTO_EXIT` 开,或 `SEMA_PARENT_PID` 在场)的引擎,`/health`(无鉴权)多一个对象键:`lingerMs` = 自退腿会执行的**最短**静默窗(父还活着的窗 `ENGINE_LINGER_MS` 与父死之后的孤儿窗
|
|
458
|
+
`ENGINE_ORPHAN_LINGER_MS` 取小;孤儿窗只在装了看门狗时存在),`tickMs` = 自退检查的采样拍(自退发生在**生效窗**满之后、至多再晚一拍;父还活着时生效的是较长的父活着的窗,所以实际自退可以比 `lingerMs` 晚得多 —— `lingerMs` 是安全节拍的上界(触点比它密,在任何状态下都先于自退),不是自退时刻的预言)。两个数是起服已解析的真值,与起服日志 `engine_lease_armed` 同一组窗,不是旋钮回声。
|
|
459
|
+
**取最短而不是「此刻生效」**:此刻生效的窗在父死那一拍从长窗掉到孤儿窗,按旧读数定节拍的壳会在下一次读 `/health` 之前被拆台;最短窗不随状态变,触点比它密,在任何状态下都留得住引擎
|
|
460
|
+
(附着着 SSE 流时本来就留得住,约束的是没有 SSE 的纯轮询壳)。
|
|
461
|
+
**在场 ⇔ 装了自退腿 ∧ 腿还在观察**:服务器形部署(两键都没设)、自退触发后、别的原因进入排空后腿收摊 ⇒ 键缺席(不补 0、不报 `null`)。自退判据与窗长一字未动。
|
|
462
|
+
**谁需要**:持租约的壳(以前只能按交给 spawn 的那份推节拍,别处起的短窗引擎窗长不上 wire,第二句仍会撞上已自退的引擎)。**谁受伤**:无(加一个键)。
|
|
463
|
+
**壳**:启动时读一次,触点节拍留余量(例如 `lingerMs` 的一半);键缺席 = 老 worker 或没装自退腿,按自己交给 spawn 的那份推。**回滚**:回到上一版键消失。
|
|
464
|
+
|
|
465
|
+
28. **名单型 env 旋钮点到本服务自有凭据名的起服拒句:一句只用一套序号(文字;运维面;零行为变更)**:
|
|
466
|
+
`LSP_ENV_ALLOW` / `BAKE_ENV_ALLOW` / `E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` / `K8S_SANDBOX_ENV` 点到本服务自有凭据名而起服拒的那句话,此前把同一项报成两种数法:`env <旋钮>: entry #2 of 2 is …`(第几段,1 起)
|
|
467
|
+
后面又带引擎那一句 `inheritEnv[0] names <名>, which is …`(引擎自己入参数组的下标,这里每次只交一个名所以恒为 0)。现在句子只有一套序号 `entry #k of n`(k 从 1 起 = 名单里第 k 项),引擎只作判官
|
|
468
|
+
(它的拒句不再转述进来),句尾括号收成 `(the engine refuses it on any allow list)`;随引擎那一句回显过的「那个声明过的名」也不再出现(第 k 项就是你写的第 k 个名)。
|
|
469
|
+
同源的一处:模型目录换代时「名单正在交出的名被新条目的 `apiKeyEnv` 并进自有凭据」的候选整拒句(`env <旋钮> hands on <名>, which this candidate makes this deployment's own credential — …`)同样不再带 `inheritEnv[0] …` 一句。
|
|
470
|
+
其余起服拒因(空段 / 非变量名形 / 点到名单型旋钮名)的句子一字未动;拒不拒、码、出路都不变。
|
|
471
|
+
**谁受伤**:按旧句里引擎那一句的子串(`inheritEnv[0]` / `which is this deployment's own credential and cannot be inherited by a child`)匹配的告警 / 脚本会失配。
|
|
472
|
+
**出路**:改按句首 `env <旋钮>: entry #k of n is this deployment's own credential — ` 匹配(这一段不变)。**回滚**:回到上一版即回到旧句子。
|
|
473
|
+
|
|
474
|
+
29. **订正 7.139.0 节第 23 条 ⑤:暂存目录残留的第三因 —— 服务进程被 `SIGKILL`(文字订正;零行为变更)**:
|
|
475
|
+
7.139.0 节第 23 条 ⑤ 只列了两因(清理往返失败、文件系统为打开着的文件留了隐藏项)。漏了第三因:**服务进程被 `SIGKILL`**(`kill -9`、内存杀手、容器被强停)时没有活着的一方去清暂存 ——
|
|
476
|
+
正在传输的那次写在目标旁留下 `.<名>.stage-<12 位十六进制>/`,里面是在传的新内容(上传途中被杀只有前半截,传完才被杀则是整份);**目标逐字仍是旧内容**,整文件替换的保证不受影响。ssh 车道上被强杀的写都留下了;其余四条远端车道走同一段暂存脚本,同形。
|
|
477
|
+
host 车道的暂存是引擎的,同形的残留名是 `<目标>.tmp.<进程号>.<十六进制>`。这只目录确认没有另一个进程正在写同一个目标之后直接删;**本版不自动清**(下一次对同一目标的写不会扫陈旧暂存)。`Ctrl-C` 取消的那一次写不留。
|
|
478
|
+
已发的 7.139.0 节不改,订正记在这里;USAGE「文件写入的中断语义」一节同说。**谁受伤**:被强杀过的远端工作区里多出的隐藏目录(体积至多等于那次写的文件)。**出路**:手删。**回滚**:不适用(文字)。
|
|
479
|
+
|
|
480
|
+
30. **折码的运维 warn 行 `outward_failure_code_folded`:不再带失败句原文;读面上同一原码只一行(运维面;日志形变更;安全;部署零动作)**:
|
|
481
|
+
失败码不合本服务码形的失败折成 `internal.store_error` 时的那一行,旧形是 `[terminal] outward_failure_code_folded original=<码> outward=internal.store_error` 加第二个实参 `{ message: <原始失败句> }`;
|
|
482
|
+
新形只一个串实参:`[terminal] outward_failure_code_folded original=<码> outward=internal.store_error messageBytes=<失败句字节数> at=<exit | run.result | ev.done.result>`。
|
|
483
|
+
失败句只报字节数;码只在它是码(字母、数字与 `_ . : -`,不超过 64 字符)时报原值,否则报 `<not-a-code>`。`at=exit` 是结果第一次离开引擎,每折一次一行(与以前同);
|
|
484
|
+
`at=run.result` / `at=ev.done.result` 是存量行在读面上被再读,同一读面同一原码每进程只一行(进程重启后重新报一次;表有界,读过超过 1024 个不同原码时最早的那个再读会再报一行)。
|
|
485
|
+
**谁受伤**:按第二实参取失败句的日志规则 / 告警(那一位不在了);按「行尾是 `outward=…`」匹配的严格解析。**出路**:失败句读结果(`GET /v1/runs/:id → result.terminal.message`,`kind: "failed"` 那一臂,过脱敏);
|
|
486
|
+
规则改按句首 `[terminal] outward_failure_code_folded original=` 与 `key=value` 字段取;只关心新失败的告警加 `at=exit` 条件。**回滚**:回到上一版即回到旧句形(第二实参重新带原文)。
|
|
487
|
+
|
|
488
|
+
31. **验证器自己停驻时:恢复凭据不再外出 · 那张卡结算时当场作废 · 读面上不合本服务码形的存量失败码读作 `internal.store_error`(行为面;安全 / 修复;wire 值少一键(`verification.verifierPause.checkpointToken` 删键);部署零动作)**:
|
|
489
|
+
`verify:true` 任务里验证器那一腿自己停在耐久门上时,结果的 `verification.verifierPause`(`unverifiedReason: "verifier_paused"`)带着那张卡的恢复凭据 `checkpointToken`;
|
|
490
|
+
上一版它原样落 run 行、账本 `done` 行与 `POST /v1/tasks` 的 200 体,`GET /v1/runs/:id` 与 `GET /v1/runs/:id/events` 照样回放,同处的 `checkpointGate` 也没过门的脱敏。
|
|
491
|
+
本版这些出口(含续跑决定腿落的行与账本)经同一只出口封口:`verifierPause` 上不再有 `checkpointToken`,`checkpointGate` 的自由文本过脱敏,`status` / `sessionId` / `checkpointGate` 照常在;
|
|
492
|
+
升级前已落盘、仍带凭据的行本版不改写,读面上同样摘掉。
|
|
493
|
+
① **卡**:那张卡落在验证器自己的会话上,本服务续不回它(上一版对它决定答 `409 conflict.resume_context_unavailable`,只等兜底收割,缺省 30 天)。本版在结算时(后台提交腿、同步提交腿、续跑的 verify 臂)
|
|
494
|
+
按卡自己的 scope 当场作废:它不再出现在 `GET /v1/approvals` / `/v1/approvals/stream` / `/v1/assistant/inbox` 上,对那只会话决定答 `404`。不新增持久态,不新增码。
|
|
495
|
+
作废没做成(checkpoint 店出错)⇒ 卡回到上一版的形(列在待决面、到期收回),计数 `fail_open_total{tag="server.verifier-pause.card-void-failed"}` + 一次 warn。
|
|
496
|
+
② **读面折码**:更早落盘、失败码不合本服务码形(小写、`.` 分族;例:数据库驱动原码 `ER_BAD_FIELD_ERROR` / SQLSTATE `42703`)的存量行,`GET /v1/runs/:id` 与 events 回放上读作 `internal.store_error`(原码进 `message` 尾注),与新落盘的行同形;码不是串的形不合行原样交出,不折。折码的运维行按第 30 条的定形句出:读面上按(读面, 原码)每进程只一行(`at=run.result` / `at=ev.done.result`),写口每折一次一行(`at=exit`);行内只有 `original` / `outward` / `messageBytes` / `at` 四个字段,零自由文本(失败句只报字节数,码形座里装着文字的报 `<not-a-code>`)。
|
|
497
|
+
— **谁需要**:看待决列表的人与壳(那里不再躺着一张点不动的卡);读 run 行 / 账本 / 同步体的下游(恢复凭据不该出现在这些面上)。
|
|
498
|
+
— **谁受伤**:想让验证器把那一步做完的人(上一版也做不到;run 的判词照旧 `unverified` / `verifier_paused`);按旧失败码筛很老的 run 行的消费方(读面上那一码变成 `internal.store_error`,原码在 `message` 尾注里)。
|
|
499
|
+
— **补偿**:重新提交带 `verify` 的任务再验一次。
|
|
500
|
+
— **已知限制**:作废只结清卡,引擎为它钉住的验证器会话不在这里释放,留在副本内存里直到进程重启(引擎给出「作废并释放」的动词那一版收);编排(leader)路径上的验证器卡本版不作废(凭据同样不外出,卡留到兜底收割)。
|
|
501
|
+
— **回滚**:回到上一版即回到凭据随结果外出、卡挂在待决面上的形(零数据面迁移;本版作废掉的卡留在作废态)。
|
|
502
|
+
|
|
503
|
+
32. **订正 7.140.0 节第 7 / 10 / 12 / 13 条的四处说法,第 8 条补一句(文字订正;零行为变更)**:7.140.0 发出后的黑盒复跑读到下面四处与已发句子不符(①–④),另有一处已发句子没说全(⑤);读法以本条为准,已发的 7.140.0 节不改。
|
|
504
|
+
① **第 7 条与第 10 条「`GET /v1/runs/:id/events` 的尾帧是 `suspended` / `needs_review`」**:`verify:true` 任务停驻期间(审批门、计划审阅门、资源限)回放的最后一帧是一帧 `model_usage`,排在状态帧 `suspended` / `needs_review` 之后;
|
|
505
|
+
不带 `verify` 的停驻以状态帧收尾。按「最后一帧 = 当前状态」读事件流的客户端,在 verify 停驻上改读最后一只状态帧,或读 `GET /v1/runs/:id` 的 `status`。两形同序的修正不在本版。
|
|
506
|
+
② **第 7 条「同 `Idempotency-Key` 重放答同一份」**:`POST /v1/tasks` 同键重放与首答的 `taskId` / `sessionId` / `status` 三键同值,外层形不同 —— 首答是平铺的结果体加 `status`,重放是 `{ taskId, sessionId, status, result: {…} }`
|
|
507
|
+
(首答的 `result` 是串、重放的 `result` 是对象)。同步提交的重放外层形不同在上一版已有,不是第 7 条引入;按首答形解析重放的调用方只读那三键(两形同值)。重放回首答同一形的修正不在本版。
|
|
508
|
+
③ **第 12 条 ①(`adb`)与 ③(`host`)「对不上 ⇒ 首连拒 / 那只环境拒起(命令面 `shell_unavailable` …)」**:主张与环境里的 `$HOME` 对不上时,不带路径的命令答 `shell_unavailable`(拒句点名主张与实测值);
|
|
509
|
+
带路径的命令(读写相对路径、`cat ~/…`)先被读边界拒,答 `read_unestablished`,句子不点名家目录;两形都零命令执行。家目录对不上的部署上看到 `read_unestablished`,先按第 12 条 ① / ③ 核声明与 `$HOME`。首拒统一点名根因的修正不在本版。
|
|
510
|
+
④ **第 13 条 ②「operator 抹除点名个人层 —— 上一版 200(落在部署的店上,对个人层是空擦)」**:以 `select.ids` + `expectedScopes: ["<个人层键>"]` 构造的那一形,上一版(7.139.0)实答 `400 config.memory_erasure_scope`,不是 200 空擦;
|
|
511
|
+
7.140.0 起答 `409 memory.erasure_store_unjudged`,不变。其它点名个人层的构造的上一版答法本条不改述(未逐形复核)。
|
|
512
|
+
⑤ **第 8 条补一句**:`run-local`(一次性 CLI)设 `READ_DENY_FLOOR_REQUIRED=true` 时,除了在准备期拒(退出码 1、零模型调用),它自己的 stderr 上同样出那一行 warn `read_deny_floor_required_unkept`(与 HTTP 服务起服同一行)。
|
|
513
|
+
**谁受伤**:无(文字)。**出路**:按本条读。**回滚**:不适用(文字)。
|
|
514
|
+
|
|
10
515
|
## 7.140.0 —— 依赖方向门(测试门;零 wire、零行为) · `CONFIG_PROVIDER=local`:`config.d` 里读不出的文档成被拒文档,候选整拒、拒句点名文件与形(行为变更;运维面) · 脱敏:PEM 私钥 armor 体里夹着由别的凭据装着的假收尾 ⇒ 整块照遮(安全) · SQL 方言字 `"tidb"` → `"mysql"`(嵌入方类型面 BREAKING;起服日志的后端字同换) · 🔴 记忆同步:同步层是个人平面键的 file 部署,这一层改同步会话读写的那只店,旧游标升级后被拒一次(删游标,不改绑) · 记忆同步层引擎读不出 ⇒ 起服拒(行为收紧) · `verify:true` 任务停在审批 / 计划审阅门上:run 行停驻、会话保持占用(行为变更) · 新旋钮 `READ_DENY_FLOOR_REQUIRED`(缺省 false;安全) · `REMOTE_EXEC=host` 不再被代声明「记忆能持久」(行为面) · `verify:true` 任务撞资源限停驻(行为变更) · 请求自带的 MCP / A2A 声明写着引擎永远不发的头 ⇒ 新提交 400(行为收紧) · 执行环境的家目录在每只环境开起来时被对证,对不上 ⇒ 那只环境拒起(六条车道;行为收紧;安全) · 记忆诸口答在请求点名的层住的那只店上:两店部署上条目 id / 店级账本的请求带层座 `scope`、落到个人店的抹除 `409 memory.erasure_store_unjudged`(行为变更;wire 加性;嵌入方 `ServiceDeps.sessionMemoryStatus` 改形,BREAKING 类型面) · 订正 7.138.0 节第 23 条 ⑩:扣留次序是先记后判(文字订正) · 契约包 settings-schema 15.2.0 · 引擎 7.60.0
|
|
11
516
|
|
|
12
517
|
1. **依赖方向门(测试门;零 wire、零行为;部署与嵌入方零动作)**:`src/` 读引擎(`@sema-agent/core`)的方式进了一道本仓的测试门 —— 说明符闭集、禁深路径与沿文件系统走引擎安装目录、
|