@sema-agent/server 7.128.0 → 7.129.1
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 +140 -0
- package/USAGE.md +114 -18
- package/dist/approval-card.d.ts +53 -26
- package/dist/approval-card.js +40 -11
- package/dist/approval-crash-convergence.js +4 -4
- package/dist/bake-runner/main.js +2 -1
- package/dist/boot/execution-env.js +1 -0
- package/dist/boot/memory-consolidation.d.ts +46 -16
- package/dist/boot/memory-consolidation.js +15 -8
- package/dist/boot/side-query-lane.d.ts +7 -20
- package/dist/boot/side-query-lane.js +0 -24
- package/dist/boot/stage-01-config.js +3 -0
- package/dist/boot/stage-06-runners.js +1 -1
- package/dist/boot/stores.js +2 -2
- package/dist/boot/web-admin.js +17 -10
- package/dist/boot/webfetch-summarize-lane.d.ts +10 -7
- package/dist/boot/webfetch-summarize-lane.js +2 -3
- package/dist/brain.js +6 -9
- package/dist/capabilities/builtin-tools.d.ts +2 -2
- package/dist/capabilities/engine-capabilities.d.ts +14 -0
- package/dist/capabilities/engine-capabilities.js +12 -0
- package/dist/capability-facts.d.ts +3 -1
- package/dist/capability-facts.js +1 -0
- package/dist/config-catalog.js +5 -1
- package/dist/config-types.d.ts +7 -3
- package/dist/config.js +7 -1
- package/dist/egress-redirect.d.ts +12 -0
- package/dist/egress-redirect.js +7 -0
- package/dist/entry-mode-clamp-notice.d.ts +30 -0
- package/dist/entry-mode-clamp-notice.js +13 -0
- package/dist/exec-bounds.d.ts +69 -0
- package/dist/exec-bounds.js +37 -0
- package/dist/fleet/fleet-bus.d.ts +7 -0
- package/dist/fleet/fleet-bus.js +1 -0
- package/dist/hooks/hook-llm.js +6 -2
- package/dist/host-lsp-manager.d.ts +3 -3
- package/dist/http/admission.js +5 -2
- package/dist/http/resume-legs.js +46 -27
- package/dist/http/route-ctx.d.ts +1 -1
- package/dist/http/routes/approvals-assistant.js +6 -4
- package/dist/http/routes/capabilities.js +1 -0
- package/dist/http/routes/session-sync.js +3 -4
- package/dist/http/routes/sessions.js +4 -17
- package/dist/http/send.d.ts +1 -1
- package/dist/http/send.js +4 -3
- package/dist/http/wire-types.d.ts +3 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/observability/fail-open.d.ts +7 -3
- package/dist/observability/fail-open.js +7 -3
- package/dist/observability/secret-env-scrub.d.ts +37 -3
- package/dist/observability/secret-env-scrub.js +2 -2
- package/dist/parked-decide.js +5 -2
- package/dist/plugins/memory-embedder.js +5 -0
- package/dist/plugins/one-time-migrations.d.ts +180 -9
- package/dist/plugins/one-time-migrations.js +315 -3
- package/dist/plugins/pg-pool.js +3 -1
- package/dist/plugins/remote-env-e2b.d.ts +31 -9
- package/dist/plugins/remote-env-e2b.js +77 -26
- package/dist/plugins/remote-env-host.d.ts +17 -20
- package/dist/plugins/remote-env-host.js +20 -30
- package/dist/plugins/remote-env-k8s.d.ts +12 -4
- package/dist/plugins/remote-env-k8s.js +22 -31
- package/dist/plugins/session-policy-store-sql.d.ts +16 -4
- package/dist/plugins/session-policy-store-sql.js +17 -20
- package/dist/plugins/session-rules-column.d.ts +16 -0
- package/dist/plugins/session-rules-column.js +6 -0
- package/dist/plugins/tidb-pool.js +4 -1
- package/dist/read-face-posture.d.ts +2 -1
- package/dist/request-value-closure.js +1 -1
- package/dist/retired-card-words.d.ts +17 -0
- package/dist/retired-card-words.js +49 -0
- package/dist/rule-entry-list.js +2 -0
- package/dist/run-local.js +10 -3
- package/dist/server-secret-env.d.ts +77 -85
- package/dist/server-secret-env.js +40 -26
- package/dist/session-policy-wire.d.ts +61 -124
- package/dist/session-policy-wire.js +59 -121
- package/dist/session-sync.d.ts +8 -6
- package/dist/session-sync.js +6 -5
- package/dist/spec-fields.d.ts +3 -2
- package/dist/standing-answer-grant.d.ts +17 -9
- package/dist/standing-answer-grant.js +11 -8
- package/dist/task-settings.d.ts +6 -1
- package/dist/task-settings.js +1 -1
- package/dist/tool-approval.d.ts +14 -7
- package/dist/tool-approval.js +23 -18
- package/dist/trace/core-keyset-guard.d.ts +3 -3
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +1 -0
- package/dist/trace/project.d.ts +7 -4
- package/dist/trace/project.js +6 -75
- package/dist/trace/tool-output-media.d.ts +2 -1
- package/dist/trace/tool-output-media.js +3 -25
- package/dist/web-admin-client/apply-effective.js +28 -11
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/facade.js +1 -1
- package/dist/web-admin-client/read-face.d.ts +73 -20
- package/dist/web-admin-client/read-face.js +76 -36
- package/dist/web-admin-client/skills-mcp.d.ts +1 -1
- package/dist/web-admin-client/skills-mcp.js +1 -1
- package/dist/web-admin-client/types.d.ts +3 -3
- package/package.json +3 -3
- package/dist/mcp-tool-axes.d.ts +0 -62
- package/dist/mcp-tool-axes.js +0 -47
package/MIGRATION.md
CHANGED
|
@@ -7,6 +7,146 @@
|
|
|
7
7
|
> ⚠️ 完整清单在仓库根 `CHANGELOG.md`——它**不随 npm tarball 出包**(本文件随包)。看完整迁移窗的
|
|
8
8
|
> 权威姿势是源码 tag diff:`git diff v<旧>..v<新>`(每版都推 `v<版本>` tag);npm 包页也镜像 CHANGELOG。
|
|
9
9
|
|
|
10
|
+
## 7.129.1 —— k8s / e2b 车道:带超时的命令不再被静默切断(行为修复)· 新旋钮 `K8S_LIVENESS_MS` · 两只活性旋钮非正值拒启
|
|
11
|
+
|
|
12
|
+
1. **一条命令的界只来自调用方说出口的那些**(零 DDL):墙钟 `timeout`、流式面自己的 `readTimeoutMs`;两样都没说时才由车道活性界(无输出满 N 毫秒即切,
|
|
13
|
+
缺省 120 s)兜底。界从调用开始算、覆盖全程(含 e2b 建命令那一段;那一段另受 e2b SDK 自己的建命令握手约束,缺省 60 s,比命令的界早时先由它切)。
|
|
14
|
+
引擎的 Bash 工具每一发都带超时,所以 Bash 调用从此不再被活性界切断(安静的长构建跑到它的超时)。`timedOut` / `timeoutSec` 仍不全是跑满:e2b 上建命令
|
|
15
|
+
卡住被那只 60 s 握手切掉、或沙箱中途死掉时,这一发仍以 `timeout` 码回来,Bash 照旧报「Command timed out after <N>s」(独立的码属于引擎的码表)。
|
|
16
|
+
活性切断的句子三车道一句,点名旋钮;错误码仍是引擎的 `timeout`。
|
|
17
|
+
- **新旋钮** `K8S_LIVENESS_MS`(ms,`E2B_LIVENESS_MS` 的孪生:同一只解析器;缺席 ⇒ 120 s;只在 `REMOTE_EXEC=k8s` 时求值)。两只旋钮都**只管没有显式超时的
|
|
18
|
+
命令** —— 此前为了让带超时的长构建跑完而调大 `E2B_LIVENESS_MS` 的部署,可以调回缺省(调大只会放宽引擎探针与文件读写的挂死护栏)。
|
|
19
|
+
- 🔴 **两只活性旋钮的值必须是正数**:非数、`0`、负数 ⇒ **拒启**,拒句点名旋钮(`E2B_LIVENESS_MS=0` 此前照收,结果是每条 e2b 命令都建不起来)。
|
|
20
|
+
升级前删掉这类设置或改成正数。嵌入方直接构造 k8s / e2b 执行环境时传非正的 `livenessMs` ⇒ 构造即抛。
|
|
21
|
+
- **受伤方**:依赖「120 s 无输出即杀」兜底带超时调用的部署 —— 带超时的挂死命令要等到它自己的超时(Bash 不传参数时 120 s,与改前同;显式最长到引擎上限)。
|
|
22
|
+
出路:给命令更短的超时;不带超时的调用照旧受活性界,可调小两只旋钮。
|
|
23
|
+
- **受伤方(调大过引擎的 `BASH_DEFAULT_TIMEOUT_MS` 的部署)**:每一发不传超时参数的 Bash 都带着这个调大了的超时,从此失去 120 s 的挂死护栏 —— 挂死的命令
|
|
24
|
+
要等满它,且没有本服务的旋钮能补回。出路:把 `BASH_DEFAULT_TIMEOUT_MS` 调回,或给需要护栏的命令显式的短超时。
|
|
25
|
+
- **读面**:e2b 车道的墙钟切断、活性切断与建命令期限到点此前报 `unknown`,现在报 `timeout`(e2b 上把这类切断当 `unknown` 读的消费方改读 `timeout`);
|
|
26
|
+
k8s 流式 exec 此前忽略 `timeout`,现在照它切。
|
|
27
|
+
- **e2b 建命令被切之后才到的句柄**:一到即被杀、输出丢弃;在**看见**它不在跑之前(供应商答了杀,或 `wait()` 以成功 / 非零退出结算 —— 流先断了、连接期限到点不算看见,进程哪怕已死也继续持有)该环境的挂起(`suspendVM`)照旧以
|
|
28
|
+
`command_in_flight` 拒。杀被供应商拒时记一行 warn `e2b_abandoned_start_kill_failed`(沙箱 id / 进程号 / 拒因类名),继续等看见退出;杀被拒且退出看不见的环境从此不能挂起、VM 计费到任务结束(fail-closed),出路 = 让命令退出或结束任务。建命令一直悬着(供应商既不交回
|
|
29
|
+
句柄、也不报失败)、或杀被拒而进程不退出的那一种,挂起会一直拒(说不出那条命令没在跑,不快照在跑的命令);任务结束销毁环境不受影响。建命令**以失败
|
|
30
|
+
告终**(含 SDK 自己的 60 s 握手到点)时在途保护即撤,与 7.129.0 同 —— 供应商若其实已起了那个进程、只是回执丢了,它不受这道保护。
|
|
31
|
+
|
|
32
|
+
## 7.129.0 —— 引擎 7.51.2 提货 · 会话规则一种文法与列改名(🔴 先停旧副本再起新)· 卡词换与存量一次性改写 · 读拒三席热生效 · 直连不跟重定向 · 两只告警标签改名
|
|
33
|
+
|
|
34
|
+
1. **引擎 7.51.2(精确钉;7.51.0 的硬破坏 + 7.51.1 / 7.51.2 两补丁)**:本服务随引擎的硬破坏在下列第 2–13 条;引擎自己的收窄直接落到部署上的见第 14 条。DDL 只有第 2 条的一处列改名(SQL 后端,由起服一次性迁移做,不用手跑);第 3 条的存量改写同样由起服一次性迁移做。
|
|
35
|
+
2. **会话规则:一种文法、两只拒码、装规则的列改名(BREAKING,调用方 + 持久面;🔴 升级序硬约束)**:规则体只剩三只桶 `toolAllow` / `toolDeny` / `allowDirs`;
|
|
36
|
+
`toolAllow` / `toolDeny` 装**规则条目** —— 工具名、`mcp__<server>`、工具自己文法的规则(`toolDeny: ["Bash(rm:*)"]` 按每一段命令的首词匹配 `rm`(连接链任一段的首词是 `rm` 即拒);写成路径的 `/bin/rm`
|
|
37
|
+
不是这个名字);`commandAllow` / `commandDeny` 退役。
|
|
38
|
+
- **写**(`PUT /v1/sessions/:id/policy`、sync/import 的 `policy` 面):`commandDeny: ["rm"]` 的新写法是 `toolDeny: ["Bash(rm:*)"]` —— 它不拒旧桶还拒的两类:写成路径的
|
|
39
|
+
`/bin/rm …`、读不成一条命令名的命令行(管道、`&&`、命令替换);要这两类也拒,整只拒 shell(`toolDeny: ["Bash"]`)。`commandAllow` 没有对应写法(没有「只收窄 shell」的条目:
|
|
40
|
+
要么列出允许的工具,其中 shell 写成 `Bash(<命令>:*)` 条目,要么不收窄)。拒码换成两只:
|
|
41
|
+
规则体形不对(不是对象、有不是桶的键 —— 含退役命令桶 —— 桶不是一列字符串、空白目录)⇒ `400 rules.invalid_shape`,体顶层 `field` / `got`(值的类型);
|
|
42
|
+
条目读成「什么都不是」(退役工具名、无前缀 `__` 名、铸不出的协议段、`*`、`mcp__*`、`Monitor(…)`、空串)⇒ `400 rules.inert_entry`,体顶层 `field` / `entry` / `reason` /
|
|
43
|
+
`verdict?` / `guidance?` / `currentName?`。**`rules.legacy_tool_name` 退役、无别名**(体里的 `name` 改叫 `entry`);`rules` 缺席 / 不是对象不再是 `request.body_shape`,
|
|
44
|
+
桶形问题不再是 `request.field_invalid`。按旧码分支的消费端改按这两码分支(`rules.` 前缀族判仍成立)。
|
|
45
|
+
- **存量(SQL 后端)**:升级后第一次起服,一次性迁移 M17 把装规则的列 `session_policy.rules` 改名 `rule_entries`。带 `commandAllow` / `commandDeny` 的行:退役桶**不改写**、
|
|
46
|
+
一个字节不动 —— 新文法写不出上面那两类拒,替你改写就是放宽 —— 这些行读回 `500 corrupt`(该会话的规则面 500、新任务起不来;引擎文件店对同一形同判),每次起服一行 warn
|
|
47
|
+
`session_rule_row_retired_bucket`(点名 `policyKey` / `sessionId` / `buckets`)。**出路**:在库里把那一行的 `rule_entries` 改写成新文法(`rev` / `gen` 不动;按上面「写」那条的
|
|
48
|
+
配方,并决定那两类要不要整只拒 shell),或删会话(`DELETE /v1/sessions/:id`,规则随之删)。升级前想先处理:在 7.128.x 上用 operator 的 `PUT` 把命令桶换成
|
|
49
|
+
`toolDeny` 里的 `Bash` 与 `Monitor`(两版都执行:整只拒 shell,比旧桶严),升级后再按需要放成 `Bash(<命令>:*)` 条目 —— **不要**在 7.128.x 上直接写 `Bash(rm:*)`:
|
|
50
|
+
7.128.x 收这串字样但不执行它,换掉命令桶的那一刻起到升级之前 `rm` 不再被拒。找这些行:
|
|
51
|
+
`SELECT policy_key, session_id FROM session_policy WHERE CAST(rule_entries AS CHAR) LIKE '%"commandDeny"%' OR CAST(rule_entries AS CHAR) LIKE '%"commandAllow"%'`
|
|
52
|
+
(PG:`rule_entries::text LIKE …`;升级前列名还是 `rules`)。
|
|
53
|
+
- **存量里旧文法写下的条目(同一次改名里改写;行自带文法戳)**:7.129.0 起每一行会话规则自带文法戳 `grammar`(写口判官盖、店整只存、读回原样交出;`GET` / `PUT`
|
|
54
|
+
回包与同步导出的记录里多一个键 `grammar`,本版写下的每一行都是 `1`)。没有戳的行是戳之前写下的行,引擎按它存下时的文法(0)读:那种文法把 `toolAllow` 的条目当整串工具名比,
|
|
55
|
+
`Bash(rm:*)` / `Edit(src/**)` / `Bash(*)` 这类条目匹配不到任何工具 = 不放行任何东西;7.129.0 的文法把它们读成规则。引擎自己守住这一点(无戳行里这类 allow 条目照旧什么都
|
|
56
|
+
不放行,并通告一次),M17 在改列名的同一步里把每一行改写成当前文法的同一句话:行交给引擎在它自己的文法里读,引擎读成「名了不存在的工具」的 `toolAllow` 条目删掉(名单**保持在场**:
|
|
57
|
+
删到空就是空名单 = 什么都不放行,与升级前同判),其余条目原样,**每一行**盖 `grammar: 1`,`rev` / `gen` 不动、按原文逐字节比对后回写。改写之后库里没有无戳行,引擎的旧文法读法与通告
|
|
58
|
+
在本服务上不再触发。`toolDeny` 里的条目一个字节不动、不点名:引擎的文法只修订 allow 方向的读法,deny 方向的 `Bash(rm:*)` 在两种文法下都是一条拒 `rm` 的规则(7.128.x 上它不拒任何东西,
|
|
59
|
+
升级后拒 —— 收紧,与写的人的本意同向;要知道哪些会话带这类条目,读行即可)。`toolAllow` 里的 `*`:7.128.x 把它当一个匹配不到任何工具的名字、名单里其余条目照放;引擎 7.51.2 读无戳行时(文法 0)仍把带 `*` 的 allow 名单**整张**读成作废(引擎的已知限制,已向引擎请托修正),
|
|
60
|
+
这遮住了同一名单里其余条目在旧文法下各算什么 —— 所以改名那一拍对这类行**不改写、不盖戳**,只各打一条 warn `session_rule_row_old_grammar_entries`(`wildcardMasked: true`,点名键与会话)。升级后这类会话每个调用都拒(fail-closed 方向),
|
|
61
|
+
要恢复:运维(operator)去掉 `*` 重写那一行(非 operator 删 `*` 是放宽,写口拒;重写前复核同一名单里 `Bash(rm:*)` 这类条目 —— 重写后它们成为新文法的放行规则);引擎修正后这些留在原文法里的行自动按 7.128.x 的意思读。deny 名单里的 `*` 只自己作废、其余条目照拒。有被删条目的行改名那一次起服各打一条 warn
|
|
62
|
+
`session_rule_row_old_grammar_entries`(`policyKey` / `sessionId` / `toolAllowDropped`;之后起服不再报;改名那次起服中途失败的,见下面的收据一条)。被删的条目若本意就是新文法的规则,
|
|
63
|
+
升级后用 `PUT` 按新文法写回那一行。带退役命令桶的行同样过这一步(桶本身仍原样、读回仍 `corrupt`;其余条目照判、照盖戳)—— 人按上一条出路删掉桶的那一刻,行已是当前文法的真话。
|
|
64
|
+
终名 `rule_entries` 只在每一行都改写完之后出现:列先从 `rules` 改成进行中的名 `rule_entries_old_grammar`,改写在它下面跑,改完再改成终名。改写没走完(出错或进程被杀)⇒ 列停在
|
|
65
|
+
进行中的名、这次起服拒;下一次起服从它续改(已带戳的行零动作),改完才出终名 —— 没有一拍会把没改的行留在终名之下。
|
|
66
|
+
**收据随改写落,不随成功落**:一行有被删条目的改写提交的那一刻它的收据(键与被删的条目)就记下;这次起服之后的任何一步失败 —— 改写半途、终名改名、改名后的扫描、后续迁移 ——
|
|
67
|
+
拒因都带着已记下的收据(结构化在错误对象上,句子里也有一份),起服日志在抛之前先打出来:一行 `one_time_migrations_interrupted` 加每个有被删条目的行一条
|
|
68
|
+
`session_rule_row_old_grammar_entries`(只盖戳的改写不记:戳不丢信息,重来再判零动作)。
|
|
69
|
+
**起服日志里 M17 收据只在改写发生的那一拍出现,保存它**:改写过的行下一次起服再判零命中(行已是新形),不会再出现 —— 两次起服的收据并起来才是全部。
|
|
70
|
+
进程恰在改写与那一行日志之间被杀、或一条改写的确认在连接上丢了,没有别处可查被删的条目(收据没有耐久载体);有此顾虑的部署升级前备份 `session_policy`。
|
|
71
|
+
- **写口上的文法戳**:`PUT` / 同步导入的规则值若带着 `rev` 却没有 `grammar`(回传了 7.128.x 读回的行再加条目、或导入一份无戳的导出),引擎按存量行的文法读它 ——
|
|
72
|
+
括号形 allow 条目拒 `400 rules.inert_entry`(`reason: "earlier_grammar"`,理由词闭集的新成员),出路是只写三只桶(不带 `rev`;写口盖当前文法的戳)或去掉那条条目;
|
|
73
|
+
`grammar` 坏 / 比引擎新 ⇒ `400 rules.invalid_shape`(`field: "grammar"`)。本服务没有发布过把无戳行写进 `rule_entries` 列的版本(7.129.0 是第一个引擎 7.51.x 版),
|
|
74
|
+
所以不存在「升级前有意写下的括号形 allow 行被收紧」一说;若部署曾手工把 7.51.0 / 7.51.1 引擎的行写进库 —— 不是本服务的任何版本写的 —— 这类无戳行按文法 0 读、括号形 allow
|
|
75
|
+
条目不放行、起服每层一次通告,运维按通告重写。**回滚**:带戳的行回到 ≤7.128.x 本来就读不到(列名不同,见下面「回滚」);列名改回之后,`grammar` 对 ≤7.128.x 是一个它不读的多余键,不另加回滚步骤。
|
|
76
|
+
- **升级序**:7.128.x 及以前的副本读不出文法戳、按整串工具名读规则 —— 它把 `Bash(rm:*)` 读成一个不存在的工具名、那条命令拒在它上面**不生效**。列改名就是为了让
|
|
77
|
+
旧副本读不到新文法的行:第一只 7.129.0 副本起服之后,还在跑的 ≤7.128.x 副本的规则读写在库里找不到列、响亮失败(它上面的会话任务起不来、规则面 500;在跑的腿
|
|
78
|
+
留着已执行的规则快照,不放宽),≤7.128.x 二进制对着这只库起服即拒(`config.schema_mismatch`:缺 `rules`、多 `rule_entries`)。**先停掉全部 ≤7.128.x 副本,再起 7.129.0**
|
|
79
|
+
—— 这样没有失败窗;滚动升级的代价是上面那段失败,直到旧副本被换掉。
|
|
80
|
+
- **回滚**:≤7.128.x 不能对着迁过的库起服。确要回滚:先把列名改回(PG `ALTER TABLE session_policy RENAME COLUMN rule_entries TO rules`;MySQL 协议
|
|
81
|
+
`ALTER TABLE session_policy CHANGE COLUMN rule_entries rules JSON NOT NULL`;列停在进行中的名 `rule_entries_old_grammar` 时从那个名改回),并接受本版写下的
|
|
82
|
+
`Bash(…)` / `Edit(…)` 这类条目在旧版上读成不存在的工具名、**不生效**(改回旧桶写法,或在回滚前删掉这些会话规则)。
|
|
83
|
+
- **local 后端**:规则在引擎自己的文件店里,不改列名、不改写:带命令桶的规则文件读回 `corrupt`(该会话任务起不来),出路在引擎的拒句里(改文件,或删掉它 = 放弃那份规则)。
|
|
84
|
+
回滚同样会让 `Bash(…)` 条目在旧版上不生效。引擎文件店**没有**上面那一步改写,也不需要:引擎 7.51.2 按行自带的文法读,7.128.x 写下的(无戳)文件按文法 0 读 —— `toolAllow` 里 `Bash(rm:*)` 这类条目照旧什么都不放行(**不放宽**),
|
|
85
|
+
引擎起服每层通告一次;要让它们成为新文法的规则,升级后按通告重写那份规则(写口盖戳)。`toolDeny` 里的同类条目升级后开始拒(收紧)。无需升级前删条目。
|
|
86
|
+
- **停驻的 run**:checkpoint 文档里的祖先会话规则快照(`state.inheritedGate.ancestorRules`)由**引擎**在停驻时写下,本服务不铸、不改写 —— 它是引擎行摘要覆盖的成员,
|
|
87
|
+
改它续跑就被拒 `requirements_damaged`,所以上面两条的剔除**不及**停驻行。快照若带命令桶,续跑时引擎对每个调用都拒;快照同样是无戳行,引擎续跑时按文法 0 读 ——
|
|
88
|
+
`toolAllow` 里旧文法写下的 `Bash(rm:*)` 这类条目照旧什么都不放行(**不放宽**;`toolDeny` 的同类开始拒)。只有带命令桶的快照仍是每个调用都拒,那一种的出路才是升级前决掉或取消。
|
|
89
|
+
3. **卡词 / 类词换(BREAKING,消费方)**:`ruleOffersAbsence` 取 `mandated` / `allow_outranked` / `ask_rule_matched` / `lane_cannot_speak`(`shadowed` 退役);`askClass` / `classes` 不再出现
|
|
90
|
+
`governance_unavailable`(并入 `rule_unreadable`)。消费方按新闭集重排分支,认不出的词按缺席处置(本服务读活卡帧的读法同)。
|
|
91
|
+
- **存量卡与停驻行(一次性迁移 M18,零动作;停驻行不改写)**:7.128.x 及以前落库、带 `shadowed` 或 `governance_unavailable` 的审批卡(`approval_ask.card_json`,本服务自己写的)
|
|
92
|
+
起服时改写一次(SQL 两后端;`shadowed` 删键,`governance_unavailable` 换成 `rule_unreadable`、类集去重),起服日志行 `one_time_migrations_applied` 的
|
|
93
|
+
`retiredCardWordAskRowsRewritten` / `retiredCardWordRowsUnreadable` 是读数(后者非零 = 有卡行的 JSON 读不懂,那些行照旧按坏行处置)。
|
|
94
|
+
**待决停驻行(`checkpoint` 文档)是引擎写的,本服务一个字节不改**:引擎的行摘要覆盖停驻行上的类对 `askClass` / `classes`,改写它们会让续跑被拒(`requirements_damaged`);引擎续跑也不按今天的闭集
|
|
95
|
+
重判它们,带着旧词的停驻行照常续跑。本服务读停驻行(运维队列行、耐久 `/decide` 的 remember 判据)时按同一只改写读 —— SQL 后端与 local 车道引擎 File 店的所有停驻行同此 ——
|
|
96
|
+
每读到一次计一次 `server.approval-card.retired-card-word-read`(载体 `parked row`):那些行被决掉 / 收割之前,同一行每读一次都计,计数涨不代表有新行。
|
|
97
|
+
起服改写够不着的卡(滚动升级窗里 7.128.x 副本新写的、local 车道的文件 ask 账)读时同样按这一只改写读,载体 `card_json`(SQL 后端上若还有 ≤7.128.x 副本在跑,
|
|
98
|
+
它们新写的旧词卡也在这里计数;先停旧副本再起新即可避开)。窗(本版发布日 + 30 天,登记在 `src/plugins/one-time-migrations.ts`)关后读侧改写与起服改写一起删,
|
|
99
|
+
之后仍带旧词的卡整卡读不出、仍带旧词的停驻行按坏行处置(运维队列行缺那一位、remember 按强制 = 只放行这一次),停驻行的旧词对引擎续跑始终无害。
|
|
100
|
+
跳版升级越过删码那一版之前,先在带本条的版本上起服一次(管存卡)。
|
|
101
|
+
- **回滚**:M18 改写出来的卡形(删键 / `rule_unreadable`)7.128.x 读得懂;读不懂的是本版之后新铸的词 `allow_outranked` / `ask_rule_matched` —— 带它们的卡回滚后
|
|
102
|
+
整卡读不出(`.strict()` 读面:断连重放跳过、幂等重入走回落),带它们的停驻行在 7.128.x 上读成「按强制」(只放行这一次)。回滚前先把待批卡处置完。
|
|
103
|
+
停驻行没被本版改写过,回滚后仍是 7.128.x 引擎自己写下的字节。
|
|
104
|
+
- **「本会话放行」读引擎的绑定词**:卡(活卡 / 停驻行 / 运维队列行)的可记性只读引擎 7.51.0 在卡上盖的 `boundGrantDigest` / `boundGrantAbsence`(新上活卡帧、inbox 行、
|
|
105
|
+
队列行三面,`card_json` 不带)。**升级前停驻**的卡两者都不说 ⇒ `remember:"session"` 只放行这一次(回执 `rememberApplied:false`,队列行 `rememberRefused:true`)——
|
|
106
|
+
答一次即可;之后停驻的卡照常可记。
|
|
107
|
+
- **门记录回放(读面)**:`tool_end.gate` 按引擎的档案读法回放 —— 上一代引擎写下的词原样到达(`governance_unavailable`、放行理由 `rule_unreadable`、出身 `unresolvable`),
|
|
108
|
+
任何一代引擎都没铸过的词整条不上帧。消费方对门记录里认不出的词按通用渲染,不要按今天的词表丢整条。
|
|
109
|
+
4. **`routePairing` 去掉 `ok:unpinned`(BREAKING,读面)**:没声明根的部署凭据配对现在读 `broken:credential_mismatch`。本服务的部署凭据只随显式网关根装配,常规部署零动作。
|
|
110
|
+
5. **工具名单里没人答应的名照跑(行为变化)**:`allowTools` / `excludeTools` / 子代 `denyTools` / `allowTools` 里没有任何工具答应的名字不再拒 run(7.126.0–7.128.x 拒
|
|
111
|
+
`config.tool_face_control` / `config.agent.unknown_tool`);条目原样保留,运维行 `runner_config_advisory` 告知一次并带该写的拼法。两码只剩任何工具名都不可能有的拼法。
|
|
112
|
+
6. **媒体块准入(零动作)**:引擎 7.51.0 起 MCP 服务器与宿主自定义工具交回的媒体块同样过引擎准入;随包 USAGE 里「这些块不验(引擎下一 minor 收)」一句由此作废,已改写。
|
|
113
|
+
被拒的块在 `tool_end.output` 上是一段文字占位;运维行 `tool_result.media_refused`。
|
|
114
|
+
7. **缺省部署自动整理恢复(零动作)**:7.127.2 节第 3 条披露的「缺省部署上每条整理都被引擎拒」由引擎修好,自动腿真起跑。
|
|
115
|
+
8. **模型端点回重定向 ⇒ 不跟(行为变化)**:引擎的模型请求、hook 直连腿(会话标题器等)与记忆 embedder 都不再跟随重定向,端点回 3xx ⇒ 该次调用失败
|
|
116
|
+
(`endpoint answered with a redirect (HTTP <n>); it was not followed …`)。升级前把会重定向的根(`http` → `https`、搬过家的网关、尾斜杠)
|
|
117
|
+
换成最终端点:`MODEL_GATEWAY_BASEURL` / `MODEL_GATEWAY_FALLBACK_URLS` / `ANTHROPIC_BASE_URL` / 目录条目的 `baseUrl` / `MEMORY_EMBEDDER_ENDPOINT`。
|
|
118
|
+
9. **网关 key 换值 = 重启(零动作)**:`MODEL_API_KEY` 在启动时读一次(以前同样如此,只是装配源码写成了「每次请求现读」);目录条目自己的凭据照旧热应用(两处例外 —— 降级壳目标、记忆整理席 —— 见 USAGE 模型路由段)。
|
|
119
|
+
10. **`createPerModelKeyBrain` 公面导出删除(BREAKING,嵌入方)**:把 per-model 凭据交给引擎的座位 —— 摘要器 `createWebFetchSummarizer(brain, model, { getApiKeyAndHeaders })`、
|
|
120
|
+
任务 `TaskSpec.getApiKeyAndHeaders`、side-query 用 `createSideQueryLane`;不要再在 brain 外面包一层注入 `options.apiKey`。
|
|
121
|
+
11. **手动整理阀门的写判官是引擎那一只,债计数改名(零动作;告警标签要改)**:阀门的写判官座由本服务代答「无异议」改为引擎导出的同一只构造器;7.127.0 节第 4 条写的 fail-open 计数
|
|
122
|
+
`server.memory-consolidation.operator-valve-unjudged` 退役,换成 `server.memory-consolidation.operator-valve-layers-unfed`(含义收窄:判官已被问,但人的规则 / 部署策略 / 项目根三层没喂)——
|
|
123
|
+
你的告警若按旧标签配,改成新标签。手动阀门的放行范围与 7.128.x 相同:人的持久路径规则、`APPROVAL_DENY` 之类的部署名单都拦不住它;这些只约束自动整理腿。
|
|
124
|
+
12. **中心下发的读拒规则下一拍热生效(行为修复,零动作)**:`readFace` 域的 `denyPatterns` / `denyBuiltinTiers` / `denyBuiltinExclude` 发布与撤回在下一拍 refresh 当场落配并换进全部 boot Runner
|
|
125
|
+
(下一个任务按新规则判;在飞的任务保留它准备时的那一份)。`/health` 不再为这三席签 `read-face` 重启理由 —— 按该理由滚动 fleet 的编排器对 deny 成员不会再收到它,因为变更已经生效;本机 env 写过的键仍恒赢。
|
|
126
|
+
13. **续跑腿失败后卡回到人手里(行为变化,读面)**:一条没停驻的失败续跑腿之后,卡是否回到待决只按店里那一行判(此前按三个失败码判)。plan_review / 抢占续跑 / wake 的续跑腿
|
|
127
|
+
任何失败都重开(引擎只对工具审批记「批过的那一步开跑了」):`GET /v1/runs/:id` 读回 `needs_review` / `suspended` 而不是 `failed`,卡可再决;被取消的续跑腿按取消结算(卡过期、行终局)。
|
|
128
|
+
按「失败码在三码名单里」判重开的消费方改读 park 事件的 `reopened` 键或 `GET /v1/approvals` 列不列。
|
|
129
|
+
14. **随引擎 7.51.0 落到部署上的收窄(升级前逐条看,本服务不改它们的语义)**:
|
|
130
|
+
- `auto` 模式下读不出目标的删除(`rm -rf $UNSET/` 这类)不再交分类器放行,改为出审批卡,没有审批人则拒 —— 依赖分类器放行这类删除的 `auto` 部署:把目标写成字面,或答卡。
|
|
131
|
+
- MCP 条目的静态头与 `principalHeader` 同名(不分大小写)或静态头同名多拼写 ⇒ 该 MCP 服务器在连接时被拒(`config.protocol_header_collision`,不挂)—— 升级前从条目里删掉那只静态头;
|
|
132
|
+
配了中心的部署先用控制台的撞名普查 / 预检脚本过一遍。
|
|
133
|
+
- A2A 对端卡片点名的 RPC 源不在声明里 ⇒ 带头 / 带主体的请求被拒(`config.protocol_endpoint_unbound`),且该对端的请求不再跟重定向 —— 把 RPC 源声明为 `url`、卡片位置为 `cardUrl`。
|
|
134
|
+
- 续跑一条停驻的 shell 调用时,读站若仍答不出(沉默)⇒ 拒,句子含 `This approval is spent` —— 重新提交该调用。
|
|
135
|
+
- 会话 `toolAllow` 是收窄姿态:一行命令的**每一段**都要被某条目点名(`cat x` 与 `git status && cat x` 同拒,句含 `no entry covers "cat x"`)。
|
|
136
|
+
- `config.permission_mode_unavailable` 的 `detail.requested` 读作「被折的那个词」(子腿什么都没请求时 = 它继承的词),子腿任何一臂的折叠都另铸一份到父会话的流 —— 按 `childSessionId` 去重,不要按「每子一行」计数。
|
|
137
|
+
15. **本服务自己的凭据在任何 `inheritEnv` 词下不进模型驱动的 shell(安全,行为修复;零 DDL、零旋钮)**:起服把配置目录全部 `type:"secret"` 名 + 名单型旋钮名向引擎
|
|
138
|
+
声明一次为自有凭据;`inheritEnv:"all"`(单用户 host 上 cli / desktop 交互 lane 每次提交发它)= 整份用户环境**减**它们 —— 用户自己的 `GH_TOKEN` / `NPM_TOKEN` 照进,
|
|
139
|
+
本服务的 `SERVICE_AUTH_TOKEN(S)` / `APPROVAL_HMAC_KEYS` / `MODEL_API_KEY` 从此不进(此前逐字进:模型一条 `curl` 可自批自己的审批卡);`"scrub"` 读数不变。
|
|
140
|
+
名单还含生效配置里每条模型条目的 `apiKeyEnv`(本服务替该模型从自己环境取钥匙的变量名):中心热应用新增 / 改名条目时在模型目录换代前重声明(名单只随落地的世代
|
|
141
|
+
增长 —— 改名后旧名照扣到重启;没落地的候选不留痕);条目的 `apiKeyEnv` 若是引擎扣不住的名(含空白 / `PATH` 这类运行时回填名)⇒ 该候选整拒、不半落(起服落 LKG /
|
|
142
|
+
env,刷新拍下一拍重判;`run-local` 一个面都不采,拒行 `config_apply_refused`)。
|
|
143
|
+
- **受伤方**:靠 `"all"` 让模型 shell 拿到本服务凭据的流程。出路:把那枚令牌另放一个不在配置目录里、也不是任何模型条目 `apiKeyEnv` 的名(`SERVICE_AUTH_TOKENS` 表里另加一条、值同时放在 `MY_SVC_TOKEN`),
|
|
144
|
+
`"all"` 下照给;或显式授予(请求体 `settings.env`)。
|
|
145
|
+
- **嵌入方**:`RemoteHostExecutionEnv` 的 `inheritEnv` 选项型改为引擎的 `InheritEnvPolicy`;白名单点到本服务自有凭据名 ⇒ **构造时**抛(拒句带名),spawn 时再拒;
|
|
146
|
+
`inheritProcessEnv` 整键删(改写 `inheritEnv:"all"` / `[]`;在场即构造拒、拒句指路 —— 不读它,`false` 不会静默退回缺省 scrub)。
|
|
147
|
+
- **能力位**:`GET /v1/capabilities` 顶层新键 `inherit_env.own_credentials_withheld: true`(引擎能力词原样;值 = 最近一次成功声明的名单 ⊇ 当前生效配置应声明的集合)。壳按它闸发不发 `"all"`;老 worker 上这一键缺席 ⇒ 别发 `"all"`。
|
|
148
|
+
- **告警标签**:`secret_env_scrubbed_total{kind}` 的 `config-catalog` / `name-list-knob` 两词退役,读数进引擎的 `own-credential` 桶 —— 按旧标签写的规则改标签。
|
|
149
|
+
|
|
10
150
|
## 7.128.0 —— 本地 `config.d/skills.json` 生效 · 部署侧 MCP `toolAxes` 进引擎(坏形整条不挂)· 宿主 shell 两行运维行 · 7.127.2 第 1 条两句订正(升级零动作)
|
|
11
151
|
|
|
12
152
|
1. **本地部署的 `config.d/skills.json` 开始生效(行为修复,零 DDL、无配置变化)**:`CONFIG_PROVIDER=local` 的部署此前只装出厂技能,`config.d/skills.json` 的条目从不进名册(零提示;
|
package/USAGE.md
CHANGED
|
@@ -108,6 +108,14 @@ ANTHROPIC_API_KEY=sk-ant-… # 可选:ANTHROPIC_BASE_URL / ANTHROPIC_VERSION /
|
|
|
108
108
|
只设 `MODEL_GATEWAY_FALLBACK_URLS` 不设主网关同拒(`config.gateway_fallback_without_primary`)。只走 Anthropic 路由的部署
|
|
109
109
|
不设网关合法;此时 `MODEL_API_KEY`(网关的凭据)不装载、不发往任何路由(启动通知 `model_gateway_key_unpaired`)。
|
|
110
110
|
中心 / config.d 下发的候选目录里有解析不到的条目 ⇒ 候选的模型面这一组被拒、上一代模型面继续服务(同候选其余组照落)。
|
|
111
|
+
- **凭据什么时候生效**:网关 key `MODEL_API_KEY`(以及 `ANTHROPIC_API_KEY` / `ANTHROPIC_AUTH_TOKEN`)在启动时读一次,**换值 = 重启本服务**
|
|
112
|
+
—— 没有热应用通道(以前的版本同样如此:这几把 key 只来自启动时的环境变量;引擎 7.51.0 起模型路由的构造配置也只读一次)。
|
|
113
|
+
目录条目**自己的**凭据(`apiKeyEnv` 点名的变量、`sealedApiKey`)跟着中心 / config.d 的模型面热应用走,不用重启:新起的任务与调用
|
|
114
|
+
用新的一代(在跑的任务用它起跑时那一代)。两处例外:降级壳焊住的目标连凭据身份一起按 `degrade-route` 重启片走;**记忆整理席**的模型在启动时定
|
|
115
|
+
(重启生效),它的凭据却跟着热应用 —— 同名条目把端点和凭据一起换掉时,重启之前整理请求会带**新**凭据打**旧**端点,这种换法之后请重启本服务。
|
|
116
|
+
- **模型端点回重定向 ⇒ 不跟、该次调用响亮失败**(引擎 7.51.0 起的模型请求;hook 直连腿 —— 会话标题器等 —— 与记忆 embedder 同一条):请求只去被判过的那个根,
|
|
117
|
+
句子 `endpoint answered with a redirect (HTTP <n>); it was not followed and no credential was sent anywhere else — …`。出路:把最终端点写进 base URL
|
|
118
|
+
(`http` 根被重定向到 `https`、网关搬家、尾斜杠重定向都是这一形)。
|
|
111
119
|
- 🔴 **目录里的 anthropic 条目要本机真有 anthropic 路由**(7.101.0 起):`provider:"anthropic"` 的目录条目只在本服务配了
|
|
112
120
|
`ANTHROPIC_API_KEY` / `ANTHROPIC_AUTH_TOKEN` 时可用;没配 ⇒ 该条目**不进可选目录**(`GET /v1/models` 不列、不当缺省,缺省顺延到下一条
|
|
113
121
|
可用条目),启动 / 刷新日志一行 `web_admin_model_no_brain`(带码 `config.model_no_brain` 与出路),显式点它(`body.model` /
|
|
@@ -414,7 +422,7 @@ MODEL_CODE_ROLES=default,subagent # 不设=全中立;仅这些角色在「
|
|
|
414
422
|
|
|
415
423
|
| env | 缺省 | 说明 |
|
|
416
424
|
|---|---|---|
|
|
417
|
-
| `MEMORY_EMBEDDER_ENDPOINT` | 缺省 | OpenAI 兼容服务的**基址**(`https://host/v1`)或**完整**端点(`https://host/v1/embeddings`),两种写法都收(query 原样保留,Azure 形可用)。必须是 http(s) 合法 URL 且**不得带 `user:pass@` 凭据**(会被传输层错误/日志/记忆冲突文案反复复制;要 auth 走下面的 API_KEY)
|
|
425
|
+
| `MEMORY_EMBEDDER_ENDPOINT` | 缺省 | OpenAI 兼容服务的**基址**(`https://host/v1`)或**完整**端点(`https://host/v1/embeddings`),两种写法都收(query 原样保留,Azure 形可用)。必须是 http(s) 合法 URL 且**不得带 `user:pass@` 凭据**(会被传输层错误/日志/记忆冲突文案反复复制;要 auth 走下面的 API_KEY),否则拒启。端点回重定向 ⇒ 这次 embedding 失败、不跟(请求体与 `Authorization` 只去这里声明的端点;写最终端点) |
|
|
418
426
|
| `MEMORY_EMBEDDER_MODEL` | 缺省 | 模型名,原样进请求体 `{model, input}` |
|
|
419
427
|
| `MEMORY_EMBEDDER_DIM` | 缺省 | 声明维度(**正整数**,如 `1024`)。必须与模型真实维度一致 |
|
|
420
428
|
| `MEMORY_EMBEDDER_TIMEOUT_MS` | `30000`(`[1000, 300000]`) | 单次 embed 的活性上限。挂死的端点会把整条记忆写入路径吊住 |
|
|
@@ -1109,11 +1117,13 @@ READ_DENY_PATTERNS='[{"pattern":"**/secrets/**"},{"pattern":".ssh","caseSensitiv
|
|
|
1109
1117
|
① **本机 env 显式恒赢**(逐键判)——env 是这台机器的部署主权,下发值不会静默盖掉它,被忽略的键留一条
|
|
1110
1118
|
`web_admin_read_face_env_wins` warn;② **坏值整域拒**——任何一个成员过不了引擎自己的校验器就整域不落、
|
|
1111
1119
|
保留 env 前值 + `web_admin_read_face_invalid` warn(半应用一份 READ 姿态比不应用更危险);
|
|
1112
|
-
③
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
(
|
|
1116
|
-
`
|
|
1120
|
+
③ **四席全热**(`face` 自 server 7.69.0 起;三个 deny 键自 core 7.51.0 起 —— 引擎把读拒三席也交付为活体座席):
|
|
1121
|
+
下发或撤回 `face` / `denyPatterns` / `denyBuiltinTiers` / `denyBuiltinExclude` 任一成员,下一拍 refresh
|
|
1122
|
+
(≤60s,或手动 `POST /v1/admin/config/refresh`)当场落进配置并换进全部 Runner,**不重启、也不签 `read-face` 重启理由**
|
|
1123
|
+
(已在飞的任务保留它准备时的读拒判,新任务读新规则;**撤回**一个成员 = 该席回到本机 env / 引擎缺省的姿态,不会停在上一份发布上)。
|
|
1124
|
+
哪几席是热的由引擎逐席答(`SWAPPABLE_DEP_SEATS`),落配、换席与重启理由读同一个答案;引擎没有活体座的席才会走
|
|
1125
|
+
`/health` 的 `restart.reasons` 带 `read-face` 通告、由编排器重启兑现。每次换席引擎在各 boot Runner 上各留一条 operator 通告
|
|
1126
|
+
`config.read_deny_swapped`,经运维日志 `engine_notice` 行落地(不上会话流);本服务另留 `read_face_swapped` 行(只报换了哪几席)。
|
|
1117
1127
|
当前生效档可从 `GET /v1/capabilities` 的 `readFace` 位读
|
|
1118
1128
|
(`"open"`/`"roots"`/`null`=本部署未钉,引擎默认当家;deny 表内容属策略内容,**不上**能力面);
|
|
1119
1129
|
**来源**(env / center / posture / engine-default)在 operator 面 `GET /v1/diagnostics/wiring` 的 `readFace.source`。
|
|
@@ -1457,14 +1467,18 @@ invalid_using_default` 警告 + 退回缺省值」这条臂随词表放宽一并
|
|
|
1457
1467
|
|
|
1458
1468
|
**🔴 模型可驱动的 host shell 没有点名放回旋钮(刻意,7.104.0 写明)**:凭据形变量不交给模型能驱动的 shell —— 这条腿恒走缺省剥除
|
|
1459
1469
|
(本服务不给它传点名名单),部署配置里没有任何键能改它的继承模式;`inheritEnv:[names]` 是**嵌入方**用本包构造执行环境时的选项
|
|
1460
|
-
(下一段),不是 sema-server 部署方的旋钮(引擎 CHANGELOG 里把它说成部署方出路的那一句,对 sema-server 部署不成立)
|
|
1470
|
+
(下一段),不是 sema-server 部署方的旋钮(引擎 CHANGELOG 里把它说成部署方出路的那一句,对 sema-server 部署不成立)。7.129.0 起这条腿的三个继承词只在引擎
|
|
1471
|
+
一处判(`inheritedHostEnv`),本服务自己的凭据名起服向引擎声明一次、任何词都不交(下面「请求级 `inheritEnv`」段)。被剥变量的
|
|
1461
1472
|
出路**按用途分**:git 凭据走 git 配置文件 / credential helper(隔离全局配置的两条 git 腿 —— project-memory 读仓、center-plugins 克隆 ——
|
|
1462
1473
|
另见 `docs/DEPLOY-PREREQS.md` 7.103.2 那一节的「按腿分」);带口令的出网代理走不带口令的形(`~/.gitconfig` 里只带用户名的 `http.proxy` + credential helper,见
|
|
1463
1474
|
`docs/DEPLOY-PREREQS.md`「带口令的出网代理」);语言服务器 / bake-runner 走各自的名单 `LSP_ENV_ALLOW` / `BAKE_ENV_ALLOW`;沙箱车道走
|
|
1464
1475
|
`E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` / `K8S_SANDBOX_ENV`。要不要给 host shell 加部署级名单属于能力面变更(安全轴),不在文档里顺手给。
|
|
1465
1476
|
|
|
1466
1477
|
**请求级 `inheritEnv`(7.106.0 起)—— 调用方声明,不是部署旋钮**:提交体顶层键 `inheritEnv:"all"` 让**这一条请求**的模型驱动 host shell
|
|
1467
|
-
继承整份用户环境(CC
|
|
1478
|
+
继承整份用户环境(CC 交互形,用户自己的凭据形变量在内)—— 🔴 **但不含本服务自己的凭据**(7.129.0 起,引擎 7.51.1):配置目录全部 `type:"secret"` 名
|
|
1479
|
+
(`SERVICE_AUTH_TOKEN(S)` / `APPROVAL_HMAC_KEYS` / `MODEL_API_KEY` …)与名单型旋钮名起服已向引擎声明为本进程自有凭据,生效配置里每条模型条目的 `apiKeyEnv` 也在名单里
|
|
1480
|
+
(中心热应用新增 / 改名条目时在模型目录换代前重声明,名单只随落地的世代增长 —— 改名后旧名照扣到重启,没落地的候选不留痕;条目的 `apiKeyEnv` 是引擎扣不住的名 ⇒ 该候选整拒),`"all"` = 整份环境**减**它们,任何继承词都不把它们
|
|
1481
|
+
交给模型 shell(能力位 `inherit_env.own_credentials_withheld` = 最近一次声明 ⊇ 当前生效配置应声明的集合;真要让模型 shell 持某枚令牌 ⇒ 另放一个不在配置目录、也不是任何模型条目 `apiKeyEnv` 的名,或经 `settings.env` 显式授予);`"scrub"` / 缺席 = 上面的缺省剥除。🔴 **`"all"` 只在单用户部署兑现**:`REQUIRE_PRINCIPAL=true`
|
|
1468
1482
|
⇒ 422 `request.host_posture_refused`(射程与写容纳面那条腿同一只谓词,`TASK_WRITE_FACE_ESCALATION` 不管它);非 host 车道带键 ⇒ 400。部署方
|
|
1469
1483
|
**没有**旋钮能替调用方打开它,也没有旋钮能在单用户部署上关掉它(单用户部署的用户把他自己的环境交给他自己驱动的 shell);起服一行 info
|
|
1470
1484
|
`task_inherit_env_honored {honored}` 告诉你这台机器认不认。上面「部署级名单不给模型驱动 shell」那条不变 —— 两件事是两条轴(部署名单 vs 调用方 × 单用户射程)。
|
|
@@ -1489,7 +1503,8 @@ bake-runner 要用 ⇒ `LSP_ENV_ALLOW` / `BAKE_ENV_ALLOW` 点名放回。
|
|
|
1489
1503
|
`E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` / `K8S_SANDBOX_ENV`)另走同一只名单解析:形错拒启点名第几段、不回显原值,点名任一只名单型旋钮拒启,
|
|
1490
1504
|
本进程环境里没有的名按序号一行 `config_env_entry_rejected`,旋钮原文按凭据类对待(配置目录只回在场位、不进任何子进程)。
|
|
1491
1505
|
几处只在**没点到的键**上不同:语言服务器在缺省剥除的结果之上放回点名键(没点到的照剥,非密钥键照常在);host shell 的
|
|
1492
|
-
`inheritEnv:[names]` 与三只沙箱名单是 hermetic 的(没点到的一律不交,与引擎 `NodeExecutionEnv`
|
|
1506
|
+
`inheritEnv:[names]` 与三只沙箱名单是 hermetic 的(没点到的一律不交,与引擎 `NodeExecutionEnv` 同名选项同义;7.129.0 起 host shell 的名单由引擎读 ——
|
|
1507
|
+
点到本服务自有凭据名 ⇒ 执行环境构造时即拒,拒句带名)。
|
|
1493
1508
|
两处都不向对方看齐:host shell 改成「剥后放回」等于在模型可驱动的 shell 上放宽,语言服务器改成 hermetic 会让它当场找不到自己的工具链。
|
|
1494
1509
|
|
|
1495
1510
|
**沙箱带外 env 名单(`E2B_SANDBOX_ENV` / `DOCKER_SANDBOX_ENV` / `K8S_SANDBOX_ENV`,前两只 7.101.0 起、`K8S_SANDBOX_ENV` 7.126.0 起,同上一段的解析与谓词)**:沙箱里的工具要用本服务
|
|
@@ -1679,7 +1694,9 @@ curl -N http://<host>:8090/v1/tasks/stream -H 'content-type: application/json' \
|
|
|
1679
1694
|
> `GET /v1/runs/:id/events`(异步 run 的活流与重连面)上它同样先于子代的首个 `task_progress`。
|
|
1680
1695
|
> - **`tool_end.output` 两形**:串,或块数组。块里可有图像 / 文档 `{ type, data, mimeType }` —— 本流上整块逐字(`data` 是字节编码,不过文本脱敏),
|
|
1681
1696
|
> 一帧最大约为部署媒体预算的 4/3(缺省约 40 MiB),请按块 `data` 长界帧;读得慢的连接(本帧媒体 + 还没送出去的字节 > 64 MiB)上本帧媒体降成描述符。
|
|
1682
|
-
> 媒体块 `data`
|
|
1697
|
+
> 媒体块 `data` 的内容由引擎准入负责:引擎 7.51.0 起工具结果席只有一只媒体准入 —— 引擎自己的工具、MCP 服务器、宿主自定义工具与 hook 替换交回的块一律过它
|
|
1698
|
+
> (不是 base64、媒体类型不在闭集、超上限、字节没有所称类型的签名 ⇒ 拒;被拒的块在结果里换成一段点名工具与拒因的文字占位,从不带字节;运维行记一条 `tool_result.media_refused`)。
|
|
1699
|
+
> 本服务零动作,不在 wire 上对 `data` 做任何改写。
|
|
1683
1700
|
> 账本面不存媒体字节 —— 账本行与 `GET /v1/runs/:id/events`(断线重连面;对 `POST /v1/runs` 提交的异步 run 它**就是活流**,所以这类客户端拿不到整图,整图只在本流、子代 tail 流与会话存档 `GET /v1/sessions/:id` 上)
|
|
1684
1701
|
> 里,带 `data` 的媒体块换成 `{ type, mimeType?, bytes, truncated: true }`(帧级 `truncated: true` 与 `totalChars` = 原值真实大小 —— 文本块字符数 + 媒体块 `data` 串长,引擎已截断的帧保留引擎给的值);无 `data` 且 `truncated: true` 的块渲染成「未送达」。
|
|
1685
1702
|
> **同一条律也管 `tool_end.structured`**:Read 读图像 / PDF 的卡 `{ type: "image" | "document", file: { base64?, type, originalSize, … } }` 里 `file.base64` 是同一份字节的第二份编码(引擎只在 ≤48K 字符时随卡),
|
|
@@ -1825,9 +1842,15 @@ curl -N http://<host>:8090/v1/tasks/stream -H 'content-type: application/json' \
|
|
|
1825
1842
|
> 规则点名库目录 ⇒ 在任何占位与模型调用之前拒,运维行 `engine_notice` 一条 `memory.consolidation_refused`(`detail.refusalCode: "memory.consolidation_write_refused"`);
|
|
1826
1843
|
> 只点名产物文件 ⇒ 应用时拒、什么都不写,一条 `memory.consolidation_incomplete`(`stop: "refused"`);用户任务不受影响。没有主体的 run 读不到任何人的持久规则(只剩部署策略那一层)。
|
|
1827
1844
|
> ⚠️ **引擎 7.50.x 上这条腿在缺省部署上每一次都被拒**:只要部署的敏感路径守卫在场(`SENSITIVE_WRITE_PATTERNS` 未设即在场),引擎问写判官时递给部署策略的是一只已中止的信号,守卫判不了库目录的真实落点、按 `target_unresolved` 拒 —— 与规则、权限模式无关(`memory.consolidation_refused`,人读句只带拒因前 200 字)。修复随引擎提货;要整理用手动阀门,不要为此设 `SENSITIVE_WRITE_PATTERNS=off`(见 MIGRATION 7.127.2 第 3 条)。
|
|
1828
|
-
> - **手动阀门**(`POST /v1/admin/memory/consolidation/run`)
|
|
1829
|
-
>
|
|
1830
|
-
>
|
|
1845
|
+
> - **手动阀门**(`POST /v1/admin/memory/consolidation/run`)没有腿,但它的写判官座与自动腿是**同一只**引擎判官构造器(此前由本服务代答「无异议」)。喂给它的部署事实是部署的合成规则店与
|
|
1846
|
+
> `~/` 行的 home(`REMOTE_EXEC_HOME_DIR`;未声明时 host / in-process 车道取本机 home、e2b 取 `/home/user`,k8s / ssh 等车道缺席)。**这两样在手动阀门上今天都读不到人的行**:
|
|
1847
|
+
> 阀门不带主体(没有来源能回答「这个库属于谁」),引擎读的是匿名地板、不读任何人的持久路径行 —— 所以「`~/` 收紧行无处锚定 ⇒ 拒闭」这条引擎规则在生产上走不到
|
|
1848
|
+
> (只有调用方自己带着主体去喂这只构造器时才走得到),与下一句的「三层没喂」是同一件事的两面。
|
|
1849
|
+
> **三层没喂,所以手动阀门今天仍不受它们约束**:人的持久路径规则(阀门没有来源能回答「这个库属于谁」)、部署的审批名单 / 自治档 / 敏感路径守卫(`APPROVAL_DENY=Write` 拦不住手动阀门)、
|
|
1850
|
+
> 项目根(相对行无处锚定)。这些只约束自动整理腿。每次被问记一次 fail-open 计数 `server.memory-consolidation.operator-valve-layers-unfed`(计数 + 探针行 + 一次性告警)—— 这是一笔显式登记的欠账,
|
|
1851
|
+
> 不是常态;读谁的规则、怎么喂部署策略待设计,落地后本句改写。
|
|
1852
|
+
> 驱动的每一条通告 —— 非收敛停的 `memory.consolidation_incomplete`、问判官**之前**推不出库家落点时同码拒的 `memory.consolidation_refused`(生产上可达,与判官答什么无关)——
|
|
1853
|
+
> 都经同一只 `engine_notice` 转发器进运维行;早问拒仍按路由的码臂答 `409 memory.consolidation_refused`。
|
|
1831
1854
|
> - **怎么让整理写**:删掉或收窄点名记忆库路径的规则;只想禁止自动整理就设 `MEMORY_AUTO_CONSOLIDATION=off`。
|
|
1832
1855
|
> - `MEMORY_CONSOLIDATION_SCOPES=user:local[,org:acme]`:阀门的 scope 表 = 这台 worker **声明**它会折叠哪些库。
|
|
1833
1856
|
> **恰好一条**时它是两个口省略 `scope` 的唯一缺省;零条或多条时省略 `scope` 一律 400(在两个库之间替人挑
|
|
@@ -2041,7 +2064,7 @@ curl -N http://<host>:8090/v1/tasks/stream -H 'content-type: application/json' \
|
|
|
2041
2064
|
| HTTP `429` + `errorCode:"limit.cost_quota_exceeded"` | per-principal 累计成本配额越顶(`MAX_PRINCIPAL_COST_USD`;**进场门**,不打断在跑的 run) | 看 `Retry-After` / 体 `retryAfterSec` 退避(体 `windowResetsAt` = 当代窗滚过的时刻);窗滚过或调高上限后放行 |
|
|
2042
2065
|
| HTTP `400` + `errorCode:"request.id_invalid"` | 调用方给的 id 形不对。**会话 id 的形门只有一只** = 任意版本 canonical uuid(壳预设的 v4 也过门):会话口 `:id`(fork / 抹除 / 会话策略 / 2c 同步)与提交口(`POST /v1/tasks` / `/v1/tasks/stream` / `/v1/runs` 体里的 `sessionId`,A2A 的 `contextId` 同)同判,提交口的句子在句首之后点名「改用 uuid、自己记映射」;`GET /v1/sendfile-links?before=` 游标与 `body.taskId` 幂等键要求 uuidv7(时间序 / 幂等键契约) | 按 `errorCode` 分支;句子各自点名要求的形(`must be a canonical uuid` / `must be a uuidv7 …`),只作展示、别锚文案 |
|
|
2043
2066
|
| HTTP `400` + `errorCode:"request.field_invalid"`(`PATCH /v1/sessions/:id` / 2c 导入的 `title`) | 标题不合形:1–120 个 Unicode 字符、**首尾不得有空白**(服务端不代为 trim,先于 C0 判)、不得含 C0 控制字符;`title: null` 清回自动标题;空串是 `request.body_shape` | 客户端送出前自行 trim;按 `errorCode` 分支,句子只作展示 |
|
|
2044
|
-
| HTTP `400` + `errorCode:"config.tool_face_control"`(7.126.0 起;流式 / 后台腿是 `failed` 终局带同码) | 请求的 `allowTools` / `excludeTools`
|
|
2067
|
+
| HTTP `400` + `errorCode:"config.tool_face_control"`(7.126.0 起;流式 / 后台腿是 `failed` 终局带同码) | 请求的 `allowTools` / `excludeTools` 里有一个**任何工具名都不可能有**的拼法(空白、括号不配、空名)(或 `allowTools` 写了 `mcp__*`、`excludeTools` 写了 `*`);引擎开跑前拒。7.129.0 起(引擎 7.51.0)这台部署上**没人答应**的名字不再拒:照跑,条目原样留在表里(今天什么都不准 / 不拒,之后挂上同名工具即生效),运维行 `runner_config_advisory` 告知一次。拒时:主模型零调用、标题器零调用(7.127.0 起;7.126.x 上标题器仍会为这次提交调一次模型)。这次提交留下的会话无标题、零消息 | 只列这台部署挂得出的工具名;句子点名那一条与它在哪张表里 |
|
|
2045
2068
|
| HTTP `429` + `errorCode:"usage.window_exhausted"` | 部署级治理窗耗尽(`USAGE_WINDOWS`,token 或 $ 天花板先满者) | 看响应体 `retryAfterSec` 退避;窗滑动/桶到期后放行 |
|
|
2046
2069
|
| `terminal:{kind:"failed", code:"usage.window_exhausted"}` | 已受理的 run 在 **turn 边界**撞上治理窗且无法 durable 挂起 | 同上退避后重投;配好 checkpoint 基建则改为 `suspended` 等窗自动续跑 |
|
|
2047
2070
|
| HTTP `501`(`/v1/runs`) | 内存模式不支持异步 | 配持久存储(`DB_BACKEND=mysql` / `pg` + 坐标;7.106.0 起给了坐标必须点名 `DB_BACKEND`) |
|
|
@@ -2064,8 +2087,9 @@ tag 词表与每条的最坏后果见 `docs/FAIL-OPEN-CENSUS.md`。引擎装配
|
|
|
2064
2087
|
按 `code` / `classification` / `level` 打标;其中 `shell-gate-off` 在本 session 显式声明 `permissionMode:
|
|
2065
2088
|
"bypassPermissions"` 时是调用方要的姿态,降为 **info** 并标 `expected`——只有没表态落到引擎默认 off 的无壳直连
|
|
2066
2089
|
形才 warn。子代 `agents[].denyTools` / `allowTools` 的**名字**归引擎开跑前一只判(7.126.0 起与根 run 的 `allowTools` / `excludeTools` 是同一只工具选择器):
|
|
2067
|
-
没有任何工具答应的名字(无人挂的名、退役拼法 / 大小写孪生 `bash` / `BASH`)
|
|
2068
|
-
|
|
2090
|
+
7.129.0 起(引擎 7.51.0)没有任何工具答应的名字(无人挂的名、退役拼法 / 大小写孪生 `bash` / `BASH`)**不再拒跑**:条目原样保留(今天什么都不拒 / 不准,之后挂上同名工具即生效),
|
|
2091
|
+
运维行 `runner_config_advisory` 每条告知一次(句子带该写的拼法;委派工具声明了逐次注入工具的名册,引擎列得出子代工具池);仍开跑前拒(`config.agent.unknown_tool`)的只剩
|
|
2092
|
+
任何工具名都不可能有的拼法(空白、括号不配、空名)与非字符串条目。名字按工具名原拼写 `Bash` —— `denyTools:["bash"]` 拒不了 `Bash`。这两张表管子代可挂载的**全部**工具 —— 委派池、内建 hands(`Read` / `Edit` / `Write` / `NotebookEdit` / `Bash` / `Grep` /
|
|
2069
2093
|
`Glob` …)、引擎自己的工具(`Monitor` / `Artifact` / `Skill` / 记忆工具 …)与父的 MCP 挂载:`denyTools:["Write"]` ⇒ 子代没有 `Write`,`denyTools:["Monitor"]` ⇒ 子代没有
|
|
2070
2094
|
`Monitor`;`allowTools` 只列调用方工具 ⇒ 子代只剩那几只与它这条腿的协议工具(要什么就点名什么,`mcp__<srv>` 点整台服务器)。内建只读子代(Explore / Plan)没有
|
|
2071
2095
|
`Edit` / `Write` / `NotebookEdit`。要按路径 / 命令拦而保留工具,写调用方权限策略的 deny 规则。
|
|
@@ -2291,6 +2315,31 @@ k8s 车道每条 run 一只新 pod(pod 寿命 = 泄漏护栏,不跨 run 复用)
|
|
|
2291
2315
|
|
|
2292
2316
|
自检是**读数,不是边界**:起服之后加入的节点在下一次起服读到;射程里的三面(所在节点、宿主 DNAT、CNI 不执行)读不出,不在闭集里。
|
|
2293
2317
|
|
|
2318
|
+
### 9.3f 沙箱车道的命令静默切断:显式超时优先(`K8S_LIVENESS_MS`,7.129.1 起)
|
|
2319
|
+
|
|
2320
|
+
k8s 与 e2b 两条沙箱车道各有一只**活性界**:一条命令无输出满这么久(缺省 120 s)即判挂死、切断。一条命令由它的调用方**说出口**的界约束,活性界只在调用方什么都没说时兜底:
|
|
2321
|
+
|
|
2322
|
+
- **带显式超时 ⇒ 只受这个超时约束**,无输出多久都不切。引擎的 Bash 工具每一发都带超时(`timeout` 参数;不传时引擎给缺省值 120 s,上限 600 s)—— 所以 Bash 调用一律走这一条。
|
|
2323
|
+
引擎的缺省值可由进程 env `BASH_DEFAULT_TIMEOUT_MS` 调大:调大它就是调大每一发不传参数的 Bash 的挂死护栏(挂死的命令要等满它),本服务没有旋钮能再收紧 —— 要护栏就调回它,或给命令显式的短超时。
|
|
2324
|
+
安静的长构建(Gradle / R8 一段几分钟不出声)给命令一个够长的 `timeout` 即可;超出引擎上限的工作用 `run_in_background`。
|
|
2325
|
+
- 流式调用自己说了静默界(`readTimeoutMs`)⇒ 照它。
|
|
2326
|
+
- 两样都没说(引擎自己的 git 探针、文件读写这类)⇒ 车道活性界兜底,它是这条命令唯一的挂死护栏。
|
|
2327
|
+
|
|
2328
|
+
界从调用开始算,覆盖命令全程 —— 含 e2b 供应商建命令那一段(命令还没起跑,自然没有输出):建命令卡住按这条命令最早的那一界切(说了超时按超时,没说界按活性界)。
|
|
2329
|
+
e2b SDK 自己的建命令握手另有一界(缺省 60 s),比命令的界早时先由它切:超时或活性界长于 60 s 的命令(含缺省 120 s 的活性界)建命令卡住在约 60 s 被切 —— 缓冲 exec(Bash 走的这一面)报 `timeout`,流式 exec 报 `connect_failed`。
|
|
2330
|
+
|
|
2331
|
+
| 旋钮 | 车道 | 缺省 | 说明 |
|
|
2332
|
+
|---|---|---|---|
|
|
2333
|
+
| `K8S_LIVENESS_MS` | `REMOTE_EXEC=k8s` | 缺席 ⇒ 120000(ms) | 7.129.1 起;与 `E2B_LIVENESS_MS` 同一只解析器:必须是正数,非数 / `0` / 负数拒启;只在本车道被选中时求值 |
|
|
2334
|
+
| `E2B_LIVENESS_MS` | `REMOTE_EXEC=e2b` | 缺席 ⇒ 120000(ms) | 同上(7.129.1 起 `0` / 负数拒启;此前照收,结果是每条命令建不起来) |
|
|
2335
|
+
|
|
2336
|
+
**有显式超时时这两只旋钮不参与**:调大不会让一条带超时的 Bash 跑得更久,调小也不会更早切它 —— 要更早切就给命令更短的超时。
|
|
2337
|
+
|
|
2338
|
+
切断时报的是真正触发的那一界:活性切断的句子是 `no output for <N> s — cut off by the exec liveness bound (set K8S_LIVENESS_MS or give the command an explicit timeout)`
|
|
2339
|
+
(e2b 点名 `E2B_LIVENESS_MS`);错误码沿用引擎的 `timeout`(引擎码表把墙钟与活性两种超界归同一词,靠句子区分)。Bash 工具结果里的 `timedOut: true` / `timeoutSec: N`
|
|
2340
|
+
不再是活性切断的投影,但仍不全是「跑满了 N 秒」:e2b 上建命令卡住被那只 60 s 握手切掉、或沙箱中途死掉时,这一发仍以 `timeout` 码回来,Bash 照旧报
|
|
2341
|
+
「Command timed out after <N>s」(把它们与超时分开的独立码属于引擎的码表)。host 车道没有活性界(命令只受调用方的超时,缓冲 exec 不带超时时受 `HOST_COMMAND_TIMEOUT_MS`)。
|
|
2342
|
+
|
|
2294
2343
|
### 9.4 auto 模式(`permissionMode:"auto"`):武装三态、本地 org deny、自查(与 core 的意图武装式合修)
|
|
2295
2344
|
|
|
2296
2345
|
**背景**:此前引擎只在「组织授予」(web-admin 解出的 per-principal `runtimeCaps.autoMode === true`)时武装
|
|
@@ -2352,7 +2401,8 @@ GET /v1/capabilities?permissionMode=auto (AUTONOMY=plan 的部署)
|
|
|
2352
2401
|
运维 `AUTONOMY=plan` 与模型自己调 `EnterPlanMode`,落到的都是同一个模式词。提交之后,一条 run 的模式词只有一个源 —— 存储的提交体顶层
|
|
2353
2402
|
`permissionMode`;写它的只有提交入口与下面的 `plan_review` 写回。运维 `AUTONOMY=plan` 是**提交入口的模式词地板**:受理时盖进提交体
|
|
2354
2403
|
(请求不带模式词 ⇒ `plan`;带任何词 ⇒ 钳成 `plan`;bundle 的 `defaultMode` 不动,顶层赢),之后不再按段续跑重钳;热改 `AUTONOMY` 只影响之后提交的任务,
|
|
2355
|
-
在飞的 run
|
|
2404
|
+
在飞的 run 保持它的入口词。请求的词真被折了(带了比 `plan` 松的词)⇒ 7.129.0 起这条会话的流(`POST /v1/tasks/stream` / `POST /v1/runs` 的事件账)
|
|
2405
|
+
在开口那一拍多一帧 `engine_notice` `permission.entry_mode_clamped`,`detail: { requested, effective, ceiling, sessionId }`;没带词、带的就是 `plan` ⇒ 不发。工具表与 `default` 同面(写手、委派工具 `Agent` 都在),
|
|
2356
2406
|
写与非只读调用在**调用时**由引擎的 plan 门问(有人可答)/ 拒(无人可答)—— 问是一张审批卡,人批了就写,
|
|
2357
2407
|
**射程是写面根围栏之内**(任务 `cwd`、引擎宣告的可写目录〔记忆目录、会话 scratchpad〕、请求的 `additionalDirectories`):批准只清模式门,引擎文件工具自己的根围栏不受批准影响,
|
|
2358
2408
|
围栏外的路径批了也不写(`tool_end.errorCode` = `path_not_in_root`,拒句点名 roots;写面声明为 open 的任务除外);委派的子代以 plan 为天花板继承同一道门。所以请求体带
|
|
@@ -2480,6 +2530,7 @@ WebSearch 工具的 `tool_result` 错误文本,回到模型的对话里,**不是
|
|
|
2480
2530
|
|
|
2481
2531
|
`mcpServers[].transport`(`kind:"http"`)上有两个「用哪个头送身份」的可选键,**只能设一个**:`principalHeader`(runner 把该任务已认证的终端用户 principal 注入这个头)与 `assertionHeader`(托管连接器断言所用的头**名**)。
|
|
2482
2532
|
- 请求体(`POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs`)与部署声明(中心下发 / 本地 `config.d/mcp.json`)判据相同:两键同设 ⇒ 请求体新提交腿 `400 request.body_shape`(拒句点名条目与两键,与契约包解析期的拒句逐字相同);`assertionHeader` 不是字符串 ⇒ `400 request.field_invalid`;部署声明里同设的那一条不进。耐久 resume 腿重放存量请求体时不拒、也不摘 server:server 照挂,`principalHeader` 胜、`assertionHeader` 不生效,一行 warn `mcp_assertion_header_ignored`(`server` / `reason` / `note`)。
|
|
2533
|
+
- `assertionHeader` 的**值**是头名,本服务不铸、也不校验具体词(只判是字符串且与 `principalHeader` 互斥);头名由引擎(上游)定为 **`connector-assertion`**(无 `x-` 前缀;引擎发送座落地后本服务只认这一个值),条目填别的名 ⇒ 连接器侧 401。
|
|
2483
2534
|
- 本版只承载、不发送断言:声明了 `assertionHeader` 的 server 照常挂载,但不带断言头;每台这样的 server 一行 info `mcp_assertion_header_not_sent`(`server` / `note`)。探测口 `POST /v1/capabilities/mcp/probe` 对声明了该键的条目整条拒 `400 request.field_invalid`(探测不拨一份少了断言头的配置)。
|
|
2484
2535
|
|
|
2485
2536
|
### 9.6 trace 脱敏的射程:与出站请求体无关
|
|
@@ -2690,7 +2741,10 @@ web-admin 拉取 / fleet 公告 / 凭证续签、WebSearch、对象存储、OTLP
|
|
|
2690
2741
|
回溯到钉的那条链,每一环的清单都从目标 tag 的树里读(`git -C ../sema-core show v<目标>:wire-changes/core@<ver>.json`),取并集 —— 跳版提货
|
|
2691
2742
|
不再只读目标那一份;链断了(某环清单读不出、本地 tag 树缺了那一版)⇒ exit 2 点名。门会先 `git fetch --tags` 那个 core 克隆(不切换 checkout)。
|
|
2692
2743
|
当前钉缺省取本仓上一发版 tag 的 `package.json`,可用 `--from <x.y.z>` 显式给;`--core-repo` 必须是 core 仓的 git 根
|
|
2693
|
-
(安装树 `node_modules/@sema-agent/core` 不再接受)
|
|
2744
|
+
(安装树 `node_modules/@sema-agent/core` 不再接受)。命中的处置写进**随版认领表** `docs/core-consumption/ACK-core@<目标>.json`(维护者文件,不随包):
|
|
2745
|
+
门按 `section` + `key` 整串全等逐键放行被人核过的命中,条目的 `where` 须把这一命中现在的读点列全,读数行 `acked=` 如实带出放行条数;
|
|
2746
|
+
表里有而读数里没有的条目、读点变了的条目按过期红(`stale=`),表自报的版本或区间下界与本次不符、形坏都是 exit 2;
|
|
2747
|
+
没有通配、没有全局放行旗标,放行面只此一张表(细则在门脚本头注)。
|
|
2694
2748
|
- **core RC 探针**(维护者裁定,2026-09-28):core 出 RC tarball 时直讯本仓(`npm pack` 产物路径 + shasum + `wire-changes/core@<ver>.json` 的 commit),
|
|
2695
2749
|
当拍跑:
|
|
2696
2750
|
```bash
|
|
@@ -2882,3 +2936,45 @@ UPDATE session_policy_rev_mark SET rev = 0, gen = gen + 1 WHERE policy_key = '<w
|
|
|
2882
2936
|
|
|
2883
2937
|
解封之后这把键没有规则,下一次写从 `rev 1` 开始,世代是新的一代,持有旧快照的读者因此不会把它读成延续。**不要**删掉这条记号:
|
|
2884
2938
|
删掉会把这把键的世代交回 0,正好与那些旧快照同代。要恢复规则,解封后照常 `PUT /v1/sessions/:id/policy`(或重跑那次 2c 导入)。
|
|
2939
|
+
|
|
2940
|
+
### 9.12 会话规则:写法、两只拒码与存量行(7.129.0 起)
|
|
2941
|
+
|
|
2942
|
+
`PUT /v1/sessions/:id/policy` 与 `POST /v1/sessions/:id/sync/import` 的 `policy` 面写的是同一种规则体:一只对象,只有三只桶。
|
|
2943
|
+
|
|
2944
|
+
- `toolDeny` / `toolAllow`:**规则条目**的列表 —— 工具名(`Read`)、协议工具的命名空间(`mcp__<server>`)或工具自己文法的规则(`Bash(git push:*)`、`Edit(src/**)`、
|
|
2945
|
+
`WebFetch(domain:<host>)`)。`toolDeny: ["Bash(rm:*)"]` 按命令名拒 `rm`(连接链里任何一段跑到它都算;写成路径的 `/bin/rm` 不是这个名字 —— 要整只拒 shell 写 `Bash`)。
|
|
2946
|
+
`toolAllow` 是收窄名单:没有一条条目放行的调用被拒。
|
|
2947
|
+
- `allowDirs`:写工具只许落在这些目录里(不能按路径收住的写类工具,例如 shell,在它生效时整只被拒)。
|
|
2948
|
+
- 7.128.x 及以前的 `commandAllow` / `commandDeny` 已退役:`commandDeny: ["rm"]` 的新写法是 `toolDeny: ["Bash(rm:*)"]`,但旧桶还拒写成路径的 `/bin/rm …` 和读不成一条命令名的
|
|
2949
|
+
命令行(管道、`&&`),新写法不拒这两类;`commandAllow` 没有「只收窄 shell」的写法,要收窄就在 `toolAllow` 里列出允许的工具(shell 写成 `Bash(<命令>:*)` 条目)。
|
|
2950
|
+
|
|
2951
|
+
**两只拒码**(判官是引擎的那一只,两条写口与店里的拒同码、同一份拒体;同步导入的写口在句首加记录坐标 `policy: [i].rules: `;店里一个字节都不落):
|
|
2952
|
+
|
|
2953
|
+
- `400 rules.invalid_shape` —— 规则体形不对:`rules` 缺席或不是对象、有一个不是桶的键(含退役的命令桶,**不会被静默忽略**)、一只桶不是一列字符串、`allowDirs` 里有空目录。
|
|
2954
|
+
体顶层 `field`(哪个键;整体不是对象时是空串)与 `got`(那个值的类型,不回显值),`error` 是引擎的句子。
|
|
2955
|
+
- `400 rules.inert_entry` —— 一条条目读成「什么都不是」,写进去什么都不拒 / 不许:退役的工具名、带 `__` 却没有协议前缀的名、协议名里铸不出的段、`*`、`mcp__*`、工具没有的规则形
|
|
2956
|
+
(`Monitor(touch:*)`)、文法不成的写法(空串、`Bash(`)。体顶层 `field` / `entry` / `reason`,外加 `verdict` / `currentName` / `guidance`(有就带)。按 `reason` 改写那一条再写。
|
|
2957
|
+
|
|
2958
|
+
一条什么都不拒的 deny 已经在库里时,会话属主自己删得掉(删它不算放宽)。
|
|
2959
|
+
|
|
2960
|
+
**行自带文法戳。** 7.129.0 起每一行会话规则自带规则文法戳 `grammar`(写口判官盖,本版写下的每一行都是 `1`;店整只存、读回原样交出)—— `GET` / `PUT` 回包的 `rules` 与同步导出的
|
|
2961
|
+
记录里多这一个键。客户端改规则时只写三只桶,不要把读回的 `rev` / `gen` / `grammar` 一起回传:带着 `rev` 却没有 `grammar` 的值引擎按存量行的文法(0)读,括号形 allow 条目答
|
|
2962
|
+
`400 rules.inert_entry`(`reason: "earlier_grammar"`;出路在句子里);`grammar` 坏或比引擎新 ⇒ `400 rules.invalid_shape`(`field: "grammar"`)。
|
|
2963
|
+
|
|
2964
|
+
**存量行(`DB_BACKEND=mysql|pg`)。** 7.129.0 第一次起服时一次性迁移把装规则的列 `session_policy.rules` 改名为 `rule_entries`。带 `commandAllow` / `commandDeny` 的行:退役桶
|
|
2965
|
+
**不改写**、原样留着(新写法拒不了旧桶拒的那两类,替你改写就是放宽):读它的请求答 `500 corrupt`,这个会话上的新任务起不来,每次起服打一条 warn
|
|
2966
|
+
`session_rule_row_retired_bucket`(`policyKey` / `sessionId` / `buckets`)。出路是在库里把那一行改写成上面的写法(`rev` / `gen` 不动),或删掉会话(删会话即删规则)。
|
|
2967
|
+
同一次改名里每一行改写成当前文法的同一句话:没有戳的行是 7.128.x 写的,引擎按它存下时的文法读 —— 那种文法把 `toolAllow` 的条目当整串工具名比,`Bash(rm:*)` / `Edit(src/**)` / `Bash(*)`
|
|
2968
|
+
这类条目匹配不到任何工具、不放行任何东西,7.129.0 读成规则;引擎读成「名了不存在的工具」的 `toolAllow` 条目删掉,名单保持在场(删到空 = 什么都不放行,与升级前同判),其余条目原样,
|
|
2969
|
+
每一行盖 `grammar: 1`,`rev` / `gen` 不动。`toolDeny` 里的条目一个字节不动、不点名(deny 规则在两种文法下同义;7.128.x 上不拒,升级后拒)。`toolAllow` 里的 `*` 不删:引擎在任何文法下都把
|
|
2970
|
+
带 `*` 的 allow 名单在引擎 7.51.2 的旧文法读法下整张作废(7.128.x 其余条目照放;引擎已知限制,已请托修正)—— 改名那一拍对这类行不改写、不盖戳、只点名(`wildcardMasked`),升级后这种会话每个调用都拒,operator 去掉 `*` 重写即恢复。有被删条目的行改名那一次起服各一条 warn `session_rule_row_old_grammar_entries`
|
|
2971
|
+
(`policyKey` / `sessionId` / `toolAllowDropped`),之后不再报;被删的条目要按新文法生效,升级后 `PUT` 写回。改写在它下面跑的那一拍列叫
|
|
2972
|
+
`rule_entries_old_grammar`,改完才改成 `rule_entries`:起服在改写中途或其后的任何一步(终名改名、扫描、后续迁移)失败 ⇒ 拒因带有被删条目的行的收据、起服日志先打
|
|
2973
|
+
`one_time_migrations_interrupted` 与逐行的 `session_rule_row_old_grammar_entries` 再抛(这些收据只在改写发生的那一拍的起服日志里出现,请保存;下一次起服不再有;只盖戳的改写不记);
|
|
2974
|
+
失败或被杀时列停在进行中的名,下一次起服续改;回滚时从那个名改回(`grammar` 对旧版是一个它不读的多余键)。
|
|
2975
|
+
|
|
2976
|
+
**升级与回滚。** 7.128.x 及以前的副本按整串工具名读规则,读不懂 `Bash(rm:*)` 这类条目。改名之后它们在这只库上找不到规则列:还在跑的旧副本读写规则的请求失败、会话任务起不来,
|
|
2977
|
+
旧二进制起服被拒(`config.schema_mismatch`)—— 不会把新写法读成「没有这条拒」。所以先停掉全部旧副本再起 7.129.0。回滚到旧版之前要先把列名改回,
|
|
2978
|
+
而且本版写下的规则条目在旧版上不生效(见 `MIGRATION.md` 7.129.0 节)。`DB_BACKEND=local` 的规则在引擎自带的文件店里,不改列名:带命令桶的规则文件读回 `corrupt`,出路在引擎的拒句里。
|
|
2979
|
+
文件店也没有上面那一步判读,也不需要:引擎按行自带的文法读,7.128.x 写下的无戳文件里 `toolAllow` 的 `Bash(rm:*)` 这类条目照旧什么都不放行(不放宽),升级后按引擎通告重写。停驻的 run 里引擎写下的
|
|
2980
|
+
祖先规则快照同理(本服务不改写),升级前决掉或取消待决的停驻 run。
|