@sema-agent/server 7.114.0 → 7.116.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 +237 -2
- package/USAGE.md +39 -3
- package/deploy/sema-up/cluster-up.sh +13 -1
- package/deploy/sema-up/kube-up.sh +13 -1
- package/deploy/sema-up/preflight.sh +13 -1
- package/deploy/sema-up/sema-up.sh +13 -1
- package/deploy/sema-up/smoke.sh +13 -1
- package/dist/adoption/wire.d.ts +0 -3
- package/dist/approval-ask-audit-store.d.ts +25 -6
- package/dist/approval-ask-audit-store.js +6 -1
- package/dist/approval-card.d.ts +25 -24
- package/dist/approval-card.js +14 -0
- package/dist/approval-crash-convergence.d.ts +60 -0
- package/dist/approval-crash-convergence.js +75 -0
- package/dist/approval-deny-reasons.d.ts +13 -0
- package/dist/approval-deny-reasons.js +2 -0
- package/dist/approval.js +7 -3
- package/dist/boot/coordinators.js +0 -12
- package/dist/boot/execution-env.js +2 -1
- package/dist/boot/exit-boundary.d.ts +3 -2
- package/dist/boot/exit-boundary.js +3 -0
- package/dist/boot/resolve-spec.js +5 -1
- package/dist/boot/shutdown.d.ts +19 -0
- package/dist/boot/shutdown.js +12 -1
- package/dist/boot/stage-07-capability-layer.js +21 -15
- package/dist/boot/stores.js +4 -4
- package/dist/capabilities/composite-members.d.ts +1 -0
- package/dist/capabilities/composite-members.js +1 -0
- package/dist/capabilities/hands-lane.d.ts +0 -23
- package/dist/capabilities/hands-lane.js +3 -2
- package/dist/capabilities/send-user-file-tool.d.ts +10 -22
- package/dist/capabilities/send-user-file-tool.js +1 -8
- package/dist/capability-facts.d.ts +296 -0
- package/dist/capability-facts.js +354 -0
- package/dist/config-catalog.js +2 -1
- package/dist/config-center/apply-effective.js +11 -11
- package/dist/config-provider.d.ts +16 -0
- package/dist/config-provider.js +11 -2
- package/dist/config-types.d.ts +20 -1
- package/dist/config.d.ts +55 -29
- package/dist/config.js +48 -25
- package/dist/deployment-governance.d.ts +15 -4
- package/dist/deployment-governance.js +20 -2
- package/dist/fleet/fleet-bus.d.ts +1 -22
- package/dist/hooks/hook-runner.d.ts +29 -3
- package/dist/hooks/hook-runner.js +30 -17
- package/dist/http/admission.d.ts +6 -0
- package/dist/http/admission.js +29 -7
- package/dist/http/approval-sweeps.js +20 -0
- package/dist/http/checkpoint-ctx.d.ts +68 -0
- package/dist/http/checkpoint-ctx.js +36 -0
- package/dist/http/durable-run-leg.js +2 -1
- package/dist/http/principal-gate.d.ts +3 -0
- package/dist/http/principal-gate.js +3 -0
- package/dist/http/resume-legs.js +19 -1
- package/dist/http/retired-skill-manifest.d.ts +23 -0
- package/dist/http/retired-skill-manifest.js +22 -0
- package/dist/http/route-ctx.d.ts +7 -0
- package/dist/http/route-table.d.ts +3 -2
- package/dist/http/route-table.js +5 -5
- package/dist/http/routes/a2a-serve.d.ts +1 -3
- package/dist/http/routes/a2a-serve.js +14 -23
- package/dist/http/routes/admin-config-refresh.js +7 -2
- package/dist/http/routes/admin-drain.js +7 -2
- package/dist/http/routes/admin-memory-optout.d.ts +0 -2
- package/dist/http/routes/admin-memory-optout.js +20 -7
- package/dist/http/routes/adoption.js +19 -5
- package/dist/http/routes/agents-roster.js +4 -2
- package/dist/http/routes/approvals-assistant.js +41 -18
- package/dist/http/routes/background.d.ts +0 -2
- package/dist/http/routes/background.js +4 -5
- package/dist/http/routes/capabilities.d.ts +2 -1
- package/dist/http/routes/capabilities.js +63 -65
- package/dist/http/routes/config-catalog.d.ts +4 -5
- package/dist/http/routes/config-catalog.js +16 -2
- package/dist/http/routes/devices.js +17 -11
- package/dist/http/routes/diagnostics.d.ts +5 -0
- package/dist/http/routes/diagnostics.js +8 -1
- package/dist/http/routes/fleet.js +4 -2
- package/dist/http/routes/images.js +30 -3
- package/dist/http/routes/leader.js +7 -1
- package/dist/http/routes/mcp-reconnect.js +17 -10
- package/dist/http/routes/memory-bundle.js +20 -6
- package/dist/http/routes/memory-compliance.js +19 -5
- package/dist/http/routes/memory-consolidation.d.ts +9 -12
- package/dist/http/routes/memory-consolidation.js +17 -3
- package/dist/http/routes/memory-origin.js +19 -5
- package/dist/http/routes/notify-wake.js +5 -3
- package/dist/http/routes/observability.js +19 -5
- package/dist/http/routes/retention-ops.js +6 -1
- package/dist/http/routes/rules.js +49 -21
- package/dist/http/routes/run-memory-capture.js +5 -2
- package/dist/http/routes/runs.js +90 -60
- package/dist/http/routes/session-sync.js +64 -53
- package/dist/http/routes/sessions-list.js +8 -5
- package/dist/http/routes/sessions.js +40 -25
- package/dist/http/routes/shared-memory.js +5 -3
- package/dist/http/routes/tasks.js +5 -3
- package/dist/http/routes/trace-usage.js +18 -11
- package/dist/http/routes/workflows.js +36 -13
- package/dist/http/server.js +4 -1
- package/dist/http/wire-types.d.ts +6 -0
- package/dist/index.d.ts +1 -1
- package/dist/leader/wire.js +2 -1
- package/dist/local-data-root.d.ts +1 -1
- package/dist/mcp-content-origin.d.ts +0 -8
- package/dist/model-entry-refusal.d.ts +10 -2
- package/dist/model-entry-refusal.js +19 -3
- package/dist/namespaced-rule-name.d.ts +54 -0
- package/dist/namespaced-rule-name.js +33 -0
- package/dist/observability/corrupt-read-seat.d.ts +4 -3
- package/dist/observability/corrupt-read-seat.js +4 -3
- package/dist/observability/fail-open.d.ts +10 -9
- package/dist/observability/fail-open.js +5 -1
- package/dist/observability/permission-rule-events.d.ts +3 -0
- package/dist/observability/permission-rule-events.js +4 -0
- package/dist/permission-rule-list.d.ts +81 -0
- package/dist/permission-rule-list.js +17 -0
- package/dist/plugins/file-run-store.d.ts +7 -1
- package/dist/plugins/file-run-store.js +20 -7
- package/dist/plugins/memory-run-store.js +2 -1
- package/dist/plugins/one-time-migrations.d.ts +4 -2
- package/dist/plugins/one-time-migrations.js +26 -3
- package/dist/plugins/pg-session-storage.js +1 -1
- package/dist/plugins/run-store-sql.js +4 -4
- package/dist/plugins/session-policy-store-sql.js +4 -2
- package/dist/plugins/store-backend.d.ts +6 -1
- package/dist/plugins/store-backend.js +2 -1
- package/dist/plugins/store-contracts.d.ts +27 -8
- package/dist/plugins/store-contracts.js +12 -3
- package/dist/plugins/tidb-session-store.js +1 -1
- package/dist/request-key-closure.js +1 -1
- package/dist/run-local.d.ts +37 -3
- package/dist/run-local.js +52 -6
- package/dist/runs.d.ts +0 -58
- package/dist/runs.js +15 -20
- package/dist/runtime-governance.d.ts +21 -1
- package/dist/runtime-governance.js +6 -1
- package/dist/security.js +2 -2
- package/dist/session-policy-wire.d.ts +40 -59
- package/dist/session-policy-wire.js +60 -32
- package/dist/spec-fields.d.ts +32 -0
- package/dist/spec-fields.js +31 -16
- package/dist/standing-answer-grant.d.ts +8 -0
- package/dist/standing-answer-grant.js +5 -0
- package/dist/task-settings.d.ts +17 -6
- package/dist/task-settings.js +16 -30
- package/dist/tool-approval.d.ts +32 -4
- package/dist/tool-approval.js +31 -8
- package/dist/trace/core-keyset-guard.d.ts +13 -8
- package/dist/trace/project.js +9 -0
- package/dist/trace/self-minted-wire.d.ts +42 -0
- package/dist/trace/self-minted-wire.js +13 -0
- package/dist/user-input-ledger.d.ts +8 -5
- package/package.json +6 -4
- package/scripts/drain-check-local.mjs +528 -0
- package/scripts/drain-check.mysql.sql +67 -0
- package/scripts/drain-check.pg.sql +71 -0
- package/scripts/retired-mode-seed-drain-local.mjs +0 -317
package/MIGRATION.md
CHANGED
|
@@ -7,6 +7,239 @@
|
|
|
7
7
|
> ⚠️ 完整清单在仓库根 `CHANGELOG.md`——它**不随 npm tarball 出包**(本文件随包)。看完整迁移窗的
|
|
8
8
|
> 权威姿势是源码 tag diff:`git diff v<旧>..v<新>`(每版都推 `v<版本>` tag);npm 包页也镜像 CHANGELOG。
|
|
9
9
|
|
|
10
|
+
## 7.116.0 —— `@sema-agent/core` 7.40.1 → 7.41.2:技能 `manifest` 退役(400)· 技能清单从围栏改成本次 run 的规则来源(也是一次放宽)· 引擎 `Skill` 卡上「本会话放行」只放行一次(新卡面位 `rememberRefused`)· 新请求键 `allowedTools` / `disallowedTools` / `userInvokedSkills` 与能力位 `userInvokedSkills` / `skillToolLists` · 停驻的 `Skill` 卡两种拒法 · 回滚到 7.115.x 前排空停驻行 · 排空配方进包 · 新询问类 `requires_user_interaction` · 停驻批准后的调用再过一次 PreToolUse · 文件店拒绝句 / 会话同步导出 / 「没人能答」拒句 / 旧工具名拒体的四处读面小改 · 服务器段铸不出的协议规则名拒 · local 重启后对上一世审批卡的作答 200 → 410 · run 死亡判决的机读码 `errorCode`(含启动期一次性迁移补码)· 两段覆盖形 `mcp__<server>` 在配置表受理 · steer 的 `priority` 交给引擎(能力位 `fleet.steerPriority` → `"engine"`)· 能力位与端点的不可用答法读同一判据(多族 403 / 404 → 501、`a2aServe` 在无后端部署上由真变假、新位 `sessionSyncFileHistory` / `workflowsJournal`)· 后台子代三张读面的文本变了 · run-local 无终端拒句按问的类说话
|
|
11
|
+
|
|
12
|
+
- **🔴 技能的 `manifest` 退役(硬破坏,零别名)**。`body.skills[].manifest` 任何值 ⇒ 400 `request.field_invalid`(句子 `skill.manifest was retired in core 7.41.0 — …`);
|
|
13
|
+
`agents[].skills[].manifest` ⇒ 那条技能按未知键整条拒(`agent.skills must be …`)。改写:`manifest.allowTools` → 技能的 `allowedTools`;`allowPaths`(写围栏)没有替身。
|
|
14
|
+
≤7.115.x 上**停驻中**、提交体里顶层技能带 `manifest` 的任务,7.116.0 续跑时引擎在认领前按名拒(`409 checkpoint.config_refused`,`field:"taskConfig"`,卡仍 pending)——
|
|
15
|
+
升级前在当前部署上答完或取消(`POST /v1/runs/:id/cancel`);子代技能(`agents[].skills[]`)带 `manifest` 的存量体续跑时不被拒,那只子代定义被整只丢掉并留一条 warn 日志 `task_agent_dropped`(任务照跑、少一只子代)。
|
|
16
|
+
- **🔴 技能清单的语义变了(行为面)**:`allowedTools` 是本次 run 的 **allow 规则来源**,不是围栏 —— 技能被激活后列着的工具本 run 内免问(清的是 `unstated` / `ordinary` 两类问,
|
|
17
|
+
与持久 allow 规则同一只谓词;deny / ask 规则、plan 模式、shell 地板、写保护、服务器标记、必须到人的问照出),**没列的工具照常判,不再因为没列被拒**;`disallowedTools` 本 run 内拒。
|
|
18
|
+
模型激活一只带清单的技能先出一张 `Skill` 卡(`askClass: "unstated"`,卡文列出批准后免问的条目);无审批席 ⇒ 那张卡被拒。
|
|
19
|
+
① *谁受影响*:靠技能清单圈工具 / 圈写路径的部署与调用方。② *不改会怎样*:没列的工具在询问类模式下被问、在 `bypassPermissions` 或部署 allow 下直接跑。
|
|
20
|
+
③ *怎么改*:圈工具 —— deny 规则(请求 `settings.permissions.deny` / 运维 `APPROVAL_DENY`)或子代定义的 `agents[].allowTools`;圈写路径 —— 会话规则 `allowDirs`
|
|
21
|
+
(`PUT /v1/sessions/:id/policy`);某只工具必须问 —— `APPROVAL_REQUIRE`(ask 规则;技能清单清不掉它,预算自动批与会话放行照旧退得掉);必须到人 —— `APPROVAL_NEVER_AUTO`;
|
|
22
|
+
shell 必须问 —— `MANUAL_MODE_SHELL_GATE=always`;没有审批席又要用技能 —— 提交体 `userInvokedSkills` 点名(不出卡)。
|
|
23
|
+
- **🔴 这也是一次放宽:请求自带技能的清单 + `userInvokedSkills` 比同版 `settings.permissions.allow` 宽**。`settings.permissions.allow` 是表态,内置工具上引擎自己的写门 / shell 普通问照问;
|
|
24
|
+
技能清单(被 `userInvokedSkills` 点名、或模型激活且卡被批准之后)把这些问也放掉 —— 写进清单的 `Write` / `Edit` / 整只 `Bash`(非 `auto` 模式)本 run 内不再问人。
|
|
25
|
+
① *谁受影响*:依赖「`default` 模式下每个 `Bash` / 写调用都会到人」的部署,尤其不认 `bypassPermissions` 的托管 / 多租户部署 —— 调用方此前拿不到这一格,现在在自己的请求里就能拿到。
|
|
26
|
+
② *技能清单清不掉的*:deny 规则(请求 / `APPROVAL_DENY` / 会话 `toolDeny`)、ask 规则(请求 `settings.permissions.ask` / `APPROVAL_REQUIRE`)、`APPROVAL_NEVER_AUTO` 与治理层的问、
|
|
27
|
+
shell 地板(`MANUAL_MODE_SHELL_GATE=always`)、写保护与读边界、plan 模式的问、服务器声明要人答的工具、删除守卫、hook 的 ask。
|
|
28
|
+
③ *怎么改*:某只工具必须问 = `APPROVAL_REQUIRE`;必须到人 = `APPROVAL_NEVER_AUTO`;shell 每次都问 = `MANUAL_MODE_SHELL_GATE=always` —— 三只都在同一份清单 + 点名下照问。
|
|
29
|
+
- **引擎的 `Skill` 卡上「本会话放行」只放行这一次**:批准一张 `Skill` 卡 = 激活技能 + 本 run 内它清单上的工具免问,卡上读不出这份授予,所以活的 `allow_session` 与耐久
|
|
30
|
+
`/decide` 的 `remember:"session"` 在这张卡上都**不记**(决定照收、回执 `rememberApplied:false`),之前记下的会话放行也不代答它 —— 同会话后面每一张技能卡都给人看。
|
|
31
|
+
之前落下的 `(会话, "Skill")` 豁免行不再生效,`GET /v1/approvals/:sessionId/exemptions` 也不再列它(按名 `DELETE …/exemptions/Skill` 仍可清掉)。
|
|
32
|
+
新的卡面位 `rememberRefused: true`(活卡帧 / `approval_request` 卡 / `livePending` 行 / 运维队列行):在场 = 这张卡上的「本会话放行」不会被记住(四个理由同一位:
|
|
33
|
+
运维治理层的门 / 必须真人逐次批 / 强制 / 应答还授予别的东西);壳读它决定渲不渲「本会话放行」,不再从 `requiresRealApproval` / `mandated` / `governanceForced` 自己推断。
|
|
34
|
+
- **新请求键**:`skills[].allowedTools` / `skills[].disallowedTools`(字符串数组,两道技能门同判;条目文法 = 持久规则文法,`*` / 写路径 / 域名什么都不授予;服务器段铸不出 / 缺段的协议名、服务器段带通配的 `mcp__*` —— 400,见下面「协议规则名」一条;条目按引擎读法取工具名:`mcp__<server>(*)` / `mcp__<server>()` 读作整台服务器、照收)·
|
|
35
|
+
顶层 `userInvokedSkills`(非空串数组 —— 人用名字点过的技能,开跑即生效、不出卡;点了这一 run 没装的技能 ⇒ 同步腿 400 `config.user_invoked_skill_unknown`,
|
|
36
|
+
异步 / 活流腿终态 run 行同码)。≤7.115.x 的 worker 对 `userInvokedSkills` 答 400 `request.body_shape`。
|
|
37
|
+
**能力位(发之前探)**:`GET /v1/capabilities` 的 `userInvokedSkills`(恒真:server 认这个顶层键)与 `skillToolLists`(恒真:技能两只清单**生效** —— ≤7.115.x 上顶层技能的两只清单照收但引擎不读、静默不生效,没有 400 可探;子代技能上是未知键整条拒)。位缺席 ⇒ 当老 server。
|
|
38
|
+
- **停驻的 `Skill` 卡(两种拒法,出路相同:让模型自己重新激活)**:
|
|
39
|
+
① *批准时被拒*:`409 resume_outcome_invalid` + `field:"boundGrantDigest"`(卡仍 pending)—— 决定里把调用换成了另一只技能(`/decide` 体的 `updatedInput`),或卡上那只技能的清单在停驻与批准之间变了,
|
|
40
|
+
或那一行是 7.115.x 上经规则 / hook 的问停驻的 `Skill` 调用(行上没有清单摘要:批准被拒、拒绝照决)。清单变了这一形在本服务上**构造不出**(没有常规路径):带清单的技能只来自请求自带的 `skills[]`,清单随提交体冻结、续跑逐字重放;部署技能加载器与配置中心下发的技能都不带清单。
|
|
41
|
+
出路是把这行决成 deny、让模型重新激活(新卡列出当前清单);原样再批同一行过不了。
|
|
42
|
+
② *批准之后被拒*:行已被消费,所以**不是 409** —— 续跑腿在执行前再过一次 PreToolUse 钩子(请求 `settings.hooks` / 部署钩子),钩子若把已批准的 `Skill` 调用改写成另一只技能(或同一只技能但清单对不上卡上的摘要),
|
|
43
|
+
那次调用**不执行**:`tool_end` 的结果文本是拒因(`isError:true`,点名两只技能、说让模型重新激活它),`tool_end.gate.disposition` 为 `{ kind: "denied", deniedBy: "policy" }`(与人那一句 yes 并存),不写第二只技能的授予行。
|
|
44
|
+
改写成同一只技能、只改 `args` 照常执行。出路:让模型自己激活那只技能(出它自己的卡)。
|
|
45
|
+
- **🔴 回滚到 7.115.x 之前排空停驻行**:7.116.0 停驻的行可能带 7.115.x(引擎 7.40)不读的技能授予节 / 卡绑定,或续跑上下文里某只技能声明的非空 `disallowedTools`(那只技能停驻时还没被激活、没有授予行可冻 —— 回滚后模型再激活它,上一版什么也不拒)—— 在 7.115.x 上续跑这种行,这一 run 的技能禁止行会丢。
|
|
46
|
+
回滚前在 7.116.0 上跑排空配方(随包只读 SQL:`node_modules/@sema-agent/server/scripts/drain-check.pg.sql`(`psql "<连接串>" -f …`)/ `drain-check.mysql.sql`(`mysql … < …`),`skill-grants-rollback` 那一行 `hit_rows` 为 0 才回滚;
|
|
47
|
+
`DB_BACKEND=local` 用随包 `node scripts/drain-check-local.mjs [<数据根>]`,首行 `SKILL-GRANTS rows=0 …` 才回滚)。本脚本的末行从两行变四行(含下面的升级前判据):`SKILL-GRANTS …` 排第一,倒数第二行仍是 `PERMISSIONS-ALLOW-LIST …`、最后一行仍是 `RETIRED-MODE-SEED …`。
|
|
48
|
+
- **🔴 排空配方现在在包里(7.116.0 起)**:此前排空 SQL 只写在不随 npm 包出的 `docs/DEPLOY-PREREQS.md` 里,只装 npm 包的部署读不到。现在两只可直接执行的 SQL 文件随包出(`scripts/drain-check.mysql.sql` / `scripts/drain-check.pg.sql`,与本地脚本同一目录、
|
|
49
|
+
每条判据一段、整只文件一次跑完出一行读数 `criterion | hit_rows | sessions`),文档里不再持有 SQL。**还没升到 7.115.0 的部署**(要在升级前数):不必先升级服务 ——
|
|
50
|
+
`d=$(mktemp -d) && (cd "$d" && npm pack @sema-agent/server@7.116.0 && tar xzf sema-agent-server-7.116.0.tgz)`,拿解开的 `$d/package/scripts/drain-check.<mysql|pg>.sql`(或本地后端的 `drain-check-local.mjs`)去跑;
|
|
51
|
+
四条判据各自该在哪个版本边界跑看该条所在的那一节(`permissions-allow-list` 见 7.115.0 节、`retired-mode-seed` 见 7.113.0 节、`skill-grants-rollback` 与 `retired-skill-manifest` 见本节)。判据与读数不变,只是搬了家并多一条。
|
|
52
|
+
- **升级到 7.116.0 之前排空「停驻、体里技能带 `manifest`」的任务(新判据 `retired-skill-manifest`)**:上面第一条说的存量停驻行 —— 顶层 `skills[]` 带 `manifest` 的续跑会被引擎按名拒(行仍 pending,只能取消重提),
|
|
53
|
+
子代 `agents[].skills[]` 带 `manifest` 的**不被拒**,而是续跑重放时那只子代定义被整只丢掉并留一条 warn 日志 `task_agent_dropped`(任务照跑、少一只可委派的子代)—— 两层的命运不同,升级前没有别的办法数出各有多少。在仍跑 ≤7.115.x 的部署上(取 7.116.0 的包里的文件,见上一条)跑 `retired-skill-manifest` 一段 / 本地脚本的
|
|
54
|
+
`RETIRED-SKILL-MANIFEST rows=…` 那一行,期望 0;非 0 ⇒ 答完或取消(`POST /v1/runs/:id/cancel`)再升级(命中行点名是哪一层:`member=skills` / `member=agents.skills`)。
|
|
55
|
+
- **新询问类 `requires_user_interaction`**:MCP 服务器在工具申报里声明 `_meta["anthropic/requiresUserInteraction"] === true` ⇒ 这只工具每次调用在**每种模式含
|
|
56
|
+
`bypassPermissions`** 都问人,只有人的答清得掉(无审批席 ⇒ 拒;无人值守腿不答);按 `askClass` 穷举的客户端加一个词。
|
|
57
|
+
- **🔴 hook 作者:停驻批准后的调用走同一只 hook 站** —— `/decide` 批准一张停驻的工具审批后,续跑腿执行那次调用之前**再跑一次 PreToolUse**(deny 生效、hook 的 allow
|
|
58
|
+
不越过人的答、人的 `updatedInput` 优先),执行后 PostToolUse / PostToolUseFailure **必跑**(修前:零命中)。⇒ 有副作用或计数的 PreToolUse 钩子对**同一次批准见两次**
|
|
59
|
+
(停驻腿一次 + 续跑腿一次)。本服务的 command 钩子(请求 `settings.hooks` / 部署钩子)今天收不到「这是续跑腿」的标记(引擎上下文里有 `legKind`,
|
|
60
|
+
本服务的钩子载荷没有转出它)—— 计数类钩子按「一次批准两次 PreToolUse」计。续跑腿上 PreToolUse 拒 / 崩 ⇒ 那次调用不执行(批准已消费)。
|
|
61
|
+
- **文件店的拒绝句不带盘上位置**:local 车道上读不出的 usage-window 账本 / 规则桶 / 会话规则高水位标记等,拒绝句(会进 run 的失败文本、HTTP 拒体)只说对象、毛病与修法,
|
|
62
|
+
文件位置只进运维日志 `file_store_corrupt_read`(本版起 usage-window 账本也进这一行)。匹配拒绝句里路径的探针改读码(码不变)与运维日志。
|
|
63
|
+
- **会话同步导出**:本会话的规则行坏了 ⇒ `GET /v1/sessions/:id/sync/manifest` 答 **500 `corrupt`**(修前:200 且少那位 principal 的规则 —— 目标端会按更松的规则跑);
|
|
64
|
+
修好或删掉那只文件再导出。别的会话的抹除不再连带删掉这条坏行。
|
|
65
|
+
- **「没人能答」的拒绝句以 ` — <出路句>` 结尾**:接了审批席、但它对这一问答 `unavailable` 的那一形(例如无人值守腿)现在也带出路句,审批席那一句是
|
|
66
|
+
`make a person reachable through the approver that is wired …`;`engine_notice` 的 `delegation.ask_unresolvable` 带 `detail.remedy`。匹配拒绝句**结尾**的探针改按开头匹配。
|
|
67
|
+
- **会话规则里的旧工具名**:`400 rules.legacy_tool_name` 拒体多两格 `verdict`(`retired` / `unprefixed_namespace`)与 `currentName`(有 1:1 继任时);库里已经存着的旧名 deny,
|
|
68
|
+
**会话属主自己删得掉**(修前只有运营方)。
|
|
69
|
+
- **🔴 协议规则名的服务器段必须是引擎铸出来的那一段(收紧:此前静默收下、永不命中的条目现在响亮拒)**。引擎给 MCP 服务器 / A2A 对端铸工具注册名时会归一服务器段
|
|
70
|
+
(字符表外的字符换成 `_`、超过长度预算截断并加摘要、连串下划线折成一个、去掉尾下划线),而规则对服务器段**逐字**比 —— 所以 `mcp__github.com`、`mcp__github.com__*`、
|
|
71
|
+
`mcp__github.com__get_file` 这类写法一只工具都匹配不到(写在 deny 表上 = 以为拒了其实没拒)。7.116.0 起下面点名的这些面都拒它(没点名的两面见本条末「已知边界」),拒句点名那一条、说明它为什么永远匹配不到,
|
|
72
|
+
并给出引擎为这个服务器名铸出来的前缀(例:`mcp__github.com__*` ⇒ 写 `mcp__github_com__*`):
|
|
73
|
+
`APPROVAL_REQUIRE` / `APPROVAL_DENY` / `APPROVAL_NEVER_AUTO` / `APPROVAL_GRANT` ⇒ 拒启;配置中心 `governance.approvalRequire` ⇒ 整组拒、保留前值、warn `sema_registry_approval_require_invalid`;
|
|
74
|
+
请求 `settings.permissions.{allow,ask,deny}` ⇒ 422;会话规则 `PUT /v1/sessions/:id/policy` 与 `POST /v1/sessions/:id/sync/import` 的 `policy` ⇒ **400 `request.field_invalid`**(店里零字节;
|
|
75
|
+
同步在建 staging 之前拒);技能的两只清单 `skills[].allowedTools` / `disallowedTools`(顶层 `skills[]` 与子代 `agents[].skills[]` 两处受理口)⇒ **400 `request.field_invalid`**
|
|
76
|
+
(句子 `skill.<清单> names "<条目>", which can never match a tool (…)`,条目按引擎的读法取工具名 —— `mcp__<server>(*)` / 带尾空格读作光杆名;服务器段带通配的 `mcp__*` 也拒,句子说服务器名不支持通配、写具体的服务器名)。会话规则两条写口对**缺段名**(`mcp__` / `mcp__<server>__` / `mcp____x`)也同样改拒(此前收下;配置表一直拒,现在一个名字一个答案)。
|
|
77
|
+
① *谁受影响*:配置里写着带点号 / 超长 / 带字符表外字符的服务器名覆盖形或全名的部署(升级后起服拒并被告知正确写法),以及这样写会话规则 / 请求权限规则的客户端
|
|
78
|
+
(含把本地会话规则同步上云的壳:本地规则里有这种条目,同步被拒)。
|
|
79
|
+
② *不改会怎样*:起服失败 / 请求与同步被拒。这些条目此前本就不生效。
|
|
80
|
+
③ *怎么改*:按拒句给出的前缀改写。**库里已经存着的这种会话规则读得出**(`GET` 照常返回),但非运营方的写:留着它 ⇒ 400、删掉它(`toolDeny` 里的那一条)⇒ 403 `loosen_forbidden`
|
|
81
|
+
(删一条 deny 今天仍算放宽)—— 由运营方的 `PUT`(operator 写可以放宽)改写成正确写法。全名的**工具段**若含字符表外字符同样匹配不到,本版不判。
|
|
82
|
+
**已知边界(两个收规则名的面本版不过这只判官)**:`/v1/rules`(持久规则写口与 `cc-import` 导入口)、子代的工具名表 `agents[].allowTools` / `denyTools` ——
|
|
83
|
+
在这两处写带铸不出服务器段的名字(如 `mcp__github.com__*`),本版仍被收下(受理门只判形)、不生效(永不命中;写在 deny 一侧 = 以为拒了其实没拒);圈工具请用上面已判的那几张表(deny 规则)。
|
|
84
|
+
- **`GET /v1/sessions?owner=`(空值,fleet-wide 调用方)**:由「不过滤、跨属主全列」改成「只列属主为空串的会话」(与存储层同一条读法:空串是一个具体的属主)。要跨属主全列,不带 `owner` 参数。
|
|
85
|
+
- **🔴 local 车道:重启后对上一世那张审批卡作答,由 200 变 410(行为面)**。挂着流内审批卡时进程崩溃 / 被杀(或有序关停没能在宽限窗内结清那张卡),
|
|
86
|
+
同一数据根重启后:≤7.115.x 的 `POST /v1/tasks/:taskId/asks/:askId/decision` 对那一问照做、答 200 + `consumerState:"absent"`(而 `GET /v1/approvals`
|
|
87
|
+
的 `crashConverged` 已把它列成收敛 —— 两个读面两个答案,那条 run 早已被重启回收);7.116.0 起启动时把它收成 `VOID`,决断答
|
|
88
|
+
**`410 gone.ask`**,体 `{state:"VOID", deniedReason:"crashed_before_park" | "shutdown_before_park"}`(与 `crashConverged[].cause` 同一个词)。
|
|
89
|
+
① *谁受影响*:local 部署(`DB_BACKEND=local` 或缺省)上,重启后仍拿着上一世的卡去决断口作答的壳 / 脚本。已经批过的问(批了、工具执行中崩)不变:
|
|
90
|
+
照旧 409 首决回显。SQL 后端不变(窗 + 宽限之后由对账器收,其间照旧 200 + `consumerState:"absent"`)。
|
|
91
|
+
② *不改会怎样*:把 410 当未知错误;按 `errorCode` 前缀 `gone.` 兜底的客户端读作「这条决定通道已关」即对。
|
|
92
|
+
③ *怎么改*:410 `gone.ask` 且 `deniedReason` 是这两个词之一 ⇒ 告诉人「上一次运行在等你答的时候结束了」,重新提交任务(新 run 会重新出卡);
|
|
93
|
+
要不要自动重发看 `crashConverged` 同一行的 `resumeSafe`。`gone.ask` 的人话句换了(现在指向 `deniedReason`),按句子匹配的探针改读码。
|
|
94
|
+
启动时这一步写不进 ask 账(盘满 / 只读)⇒ **拒启**,修好数据根再起。
|
|
95
|
+
- **`GET /v1/runs/:id` 的 `errorCode` 多三种取值(additive 读面)**:run 店自己判的终局此前只在 `error` 句子里 —— 现在同时带机读码:失联收割
|
|
96
|
+
`run.stalled`(句子 `run stalled (instance lost?)`;读面在收割落盘前提前折叠的那一形也是这个码)、local 车道重启 / 会话占用接管回收的
|
|
97
|
+
`run.orphaned`(句子 `run orphaned by engine restart`)、审批过期收割 `approval.expired`(行上早有、读面此前不投)。句子照旧。
|
|
98
|
+
① *谁受影响*:按 `error` 句子判「持有者没了」的消费端 —— 改按 `errorCode` 判;把「`errorCode` 在场」读成「core 报了错」的消费端 —— 先读 `status`,
|
|
99
|
+
再按码分支(这三码都不是请求写错,重试同一请求无意义,重新提交才有新 run)。升级前写下的行怎么补码见下一条。
|
|
100
|
+
- **升级前写下的死亡判决行:启动期一次性迁移补码,运维零动作**(持久数据面)。7.115.x 及更早写下的失联收割 / 重启回收行只有 `error` 句子、码列为空。
|
|
101
|
+
本版每次起服都把「`failed` ∧ 码列为空 ∧ 句子是那两句(会话占用接管的括注形按前缀认)」的行写回对应的码(SQL 两后端各两条 `UPDATE`;local 后端改写 `run.json`),
|
|
102
|
+
启动日志 `one_time_migrations_applied` 的 `holderDeathCodeRowsBackfilled` 是这一次写了多少行;幂等(第二次起零命中),不发 `ALTER`,不停机。
|
|
103
|
+
滚动升级窗里还在跑的 7.115.x 副本仍会写只有句子的行 —— SQL 后端的新副本在**读**这种行时同样读成码(这一半只为升级窗存在)。
|
|
104
|
+
这条迁移有窗:引入它的版本发布日 + 30 天之后的第一个小版本把写回与读侧那一半**一起删**(日期见起动日志行的 `removableAfter.M6`)⇒ **跨版跳升要经过一只还带着
|
|
105
|
+
这条迁移的版本**,并且在那之前让所有副本都升上来。删掉之后仍只有句子的行不再被判成持有者死亡:那条 run 上崩溃丢掉的 steer 不再告知用户,`GET /v1/runs/:id`
|
|
106
|
+
上 `errorCode` 缺席、只剩句子。
|
|
107
|
+
- **拒放集合的变化(逐条)**:
|
|
108
|
+
· `body.skills[].manifest`:受理 → **拒**(400 `request.field_invalid`)。
|
|
109
|
+
· `agents[].skills[].manifest`:受理(合法形) → **拒**(未知键,整条技能)。
|
|
110
|
+
· `body.skills[].allowedTools` / `disallowedTools`:受理任何值(原样透传) → 字符串数组受理、其余 **拒**(400 `request.field_invalid`)。
|
|
111
|
+
· `agents[].skills[].allowedTools` / `disallowedTools`:拒(未知键) → **受理**(字符串数组)。
|
|
112
|
+
· 顶层 `userInvokedSkills`:拒(400 `request.body_shape`) → **受理**(非空串数组);坏形 400 `request.field_invalid`。
|
|
113
|
+
· 配置表里的两段覆盖形 `mcp__<server>` / `a2a__<peer>`(`APPROVAL_REQUIRE` / `APPROVAL_DENY` / `APPROVAL_NEVER_AUTO` / `APPROVAL_GRANT` 起服、配置中心
|
|
114
|
+
`governance.approvalRequire`、请求 `settings.permissions.{allow,ask,deny}`):拒 → **受理**,读作整台服务器(与 `mcp__<server>__*` 同义)。想要一只工具就写全名。
|
|
115
|
+
`mcp__` / `mcp__<server>__` / 服务器段带通配的 `mcp__*` 照拒。服务器段须是引擎铸出来的那一段(见下一条)。
|
|
116
|
+
· 服务器段不是引擎铸出来的那一段的协议规则名(两段覆盖形 / 三段覆盖形 / 全名;运维四表、配置中心 `governance.approvalRequire`、请求三桶、会话规则两条写口):
|
|
117
|
+
受理 → **拒**(拒启 / 整组拒 / 422 / 400 `request.field_invalid`)。
|
|
118
|
+
· 会话规则两条写口上的缺段名(`mcp__` / `mcp__<server>__` / `mcp____x` / `a2a__<peer>__`):受理 → **拒**(400 `request.field_invalid`)。
|
|
119
|
+
· 会话规则:属主(非运营方)删掉一条已存的旧名 deny:拒(403 `loosen_forbidden`) → **受理**。
|
|
120
|
+
· `GET /v1/sessions/:id/sync/manifest`(本会话有坏规则行):200(少一位 principal) → **500 `corrupt`**。
|
|
121
|
+
· 委派子代的 `SendUserFile`(部署审批面点名它时):子代名册里没有 → **有**;`APPROVAL_DENY` 下调用被拒、`APPROVAL_REQUIRE` / `NEVER_AUTO` 下调用问顶层审批人。
|
|
122
|
+
要子代根本看不到它,子代定义的 `allowTools` 不写它。
|
|
123
|
+
· local 车道重启后对上一世未答的审批问 `POST /v1/tasks/:taskId/asks/:askId/decision`:受理(200)→ **拒**(410 `gone.ask`)。
|
|
124
|
+
|
|
125
|
+
- **🔴 steer 的 `priority` 交给引擎(行为面变化)**。`POST /v1/runs/:id/steer` 请求体的 `priority`(`now` / `next` / `later`)此前收下、校验、回执里回显,
|
|
126
|
+
但不交给引擎(一律按 `next` 投递);7.116.0 起每条投递腿都把它交给引擎,回执回显的就是交出去的那个档位:
|
|
127
|
+
`now` = 有在飞的 turn 时当场切断它(正在执行的工具收到中止、没启动的结算成 interrupted、本副本上挂着的审批卡被撤),run 继续、这句话排在最前;
|
|
128
|
+
run 事件流上一帧 `engine_notice` `task.turn_interrupted`(`detail.inputId` = 回执 `messageId`)是切断的证据;
|
|
129
|
+
`later` = 不再在下一个边界投,改在 run 本会停下的那一 turn 之后投(模型收尾后多走一 turn);`next` 与不带 `priority` 逐字节不变。
|
|
130
|
+
run 停在审批 / 评审门上或已结束(回执 `delivery:"queued"` / `"parked_for_wake"`)时,三档都在续跑(或 wake)的首轮投递,档位随停放条目存着。
|
|
131
|
+
① *谁受影响*:今天就在请求里带 `priority` 的调用方(SDK 的 `runs.steer` 收这个参数并原样转发)—— 带 `now` 的开始切 turn,带 `later` 的晚到。
|
|
132
|
+
② *不改会怎样*:带 `now` 的插话会中止正在执行的工具调用,并撤掉本副本上挂着的审批卡。
|
|
133
|
+
③ *怎么改*:要旧行为就不带 `priority`(或带 `"next"`);要「切断 + 插话」且 run 不在本副本跑时被拒而不是停放,用 `POST /v1/runs/:id/interrupt`。
|
|
134
|
+
- **同一个 `Idempotency-Key`、同正文、不同档位的 steer 重放**:受理(200 / 202 —— 档位没交给引擎,两次是同一条)→ **拒**(409 `steering.duplicate_input_id`,
|
|
135
|
+
引擎的幂等身份含档位)。换档请换 key。「不带 `priority`」与「带 `"next"`」是**同一档**(引擎缺省档就是 `next`),在三条投递腿上(live、`queued`、
|
|
136
|
+
`parked_for_wake`)同读:同 key 同正文互相重发是幂等重放(回执同一个 `messageId`、队列仍是原来那一条)—— 含升级前停放的 steer(上一版不交档位、条目上没有档位字段),
|
|
137
|
+
升级后用同一 key 重发同一份带 `"next"` 的请求。真换档(`next` → `later`、不带或 `next` → `now`)与同 key 换正文照旧拒。
|
|
138
|
+
- **能力位 `fleet.steerPriority`:`"advisory"` → `"engine"`(值变更,零别名)**。按 `=== "advisory"` 判「档位无效」的消费端改判 `=== "engine"`
|
|
139
|
+
(档位交给引擎,各档语义 = 引擎的定义);键缺席 = 老 server。
|
|
140
|
+
|
|
141
|
+
- **🔴 能力位与「这台部署上不可用」的端点门读同一个判据(硬破坏:一位在无后端部署上由真变假、两位值不变但广告的端点收窄、两位新增、一批端点的不可用答统一成 501)**。
|
|
142
|
+
`GET /v1/capabilities` 里凡是某个端点也在判的位,值与那个端点的不可用门出自同一只判据;此前是两边各写一份,三处在真实部署上说了假话。逐位:
|
|
143
|
+
· **`workflowsList` 值不变(= workflow 行店,与 7.115.x 同),广告的端点收窄成 list / detail / stream 三口;journal 口归新位 `workflowsJournal`**(= 行店 ∧ journal 店)。
|
|
144
|
+
在「没有存储后端 + `SELF_ORCHESTRATION_ENABLED=true`」的三种部署上(`DB_BACKEND=memory`、多租户裸起即 `REQUIRE_PRINCIPAL=true` 且未设 `DB_BACKEND`、`DB_BACKEND=mysql|pg` 而坐标没配齐)
|
|
145
|
+
行店在、journal 店缺席:`workflowsList` 为真(三口真能用),`workflowsJournal` 为假(`GET /v1/workflows/:id/journal` 每次 501 `capability.workflow_store_required`)。
|
|
146
|
+
消费方要做的:**journal 入口改读 `workflowsJournal`**(仍按 `workflowsList` 点亮 journal 的,在那三形上与 7.115.x 一样会点亮一个恒 501 的入口);新位缺席 = 老 worker,按 `workflowsList` 兜底即旧行为。
|
|
147
|
+
· **`a2aServe`:真 → 假**,在 `A2A_SERVE_ENABLED=true` 而没有 durable run store 的部署上(同上三形)。此前卡照发、`message/send` / `tasks/get` 每次答 JSON-RPC `-32004`;
|
|
148
|
+
现在这个 peer 对外不存在:`GET /.well-known/agent-card.json` 与 `POST /v1/a2a` 都 404,`-32004` 不再出现。对端 orchestrator 会看到拉卡 404(与旋钮关同一形)。
|
|
149
|
+
要它对外存在:给它一个 durable run store(`DB_BACKEND=mysql|pg|local`)。启动时有一行 warn 点名这一形。
|
|
150
|
+
· **`sessionSync`:值在三种生产后端上不变,但它广告的端点变少**;新位 **`sessionSyncFileHistory`**(SQL 两后端真,`DB_BACKEND=local` 与无后端假)接走文件历史 blob 两口
|
|
151
|
+
(`PUT /v1/sessions/:id/sync/blobs/:hash`、`GET /v1/sessions/:id/sync/history/blobs/:hash`)。local 上 `sessionSync` 为真而 blob 两口恒拒,修前同一位对它们说了「能」。
|
|
152
|
+
消费方会看到:local 引擎上新位为 `false`;同步只搬对话、不搬文件历史(任一端为 `false` 就别推 `fileHistory`、别 PUT blob)。无 blob 面时 history blob GET 由 404 `not_found.blob` 改 501。
|
|
153
|
+
`sessionSync` 的判据另加三项(会话属主面、条目流式导出面、policy 店能清),三种生产后端都具备,值不变;缺任一的装配整族 501(policy 店擦不动时此前只在 overwrite-dst 的 commit 前拒)。
|
|
154
|
+
· **自带会话策略店、且没实现清除动词(`deleteBySession`)的嵌入方:会话同步由「只有覆盖式导入被拒」变成整族 501、位为假**。≤7.115.x 上只有 consented `overwrite-dst` 的导入在 commit 前答 501 `capability.policy_purge_required`(句首 `overwrite-dst cannot proceed`),同一部署上其余同步端点(manifest / entries / plan / 普通导入 / identical 重推)照常;7.116.0 起「策略店擦得动」是 `sessionSync` 事实的一项:缺这只动词 ⇒ 整族第一口答 501 `capability.policy_purge_required`(句首 `session sync is not available on this deployment`)、能力位 `sessionSync` 为 `false`(`sessionSyncFileHistory` 随之为 `false`)。仓内自带的策略店(SQL / 引擎自带的内存与文件店)都有这只动词,**受影响的只有嵌入方自带策略店的部署**;没有挂策略店的装配不算缺(该位不判)。出路 = 给店实现 `deleteBySession`(按会话清掉全部 principal 的规则行、各键的 rev 高水位留着)。
|
|
155
|
+
· **operator 面在 `OPERATOR_PRINCIPALS` 为空时:403 → 501**。有能力位的八族(收编、记忆治理携出、出处 / 抹除、外源标记、记忆整理、opt-out 授权表、`/v1/outcomes`(仅多租户)、
|
|
156
|
+
配置目录)此时位本就为假,端点由 403 `auth.operator_only` 改答 501 `capability.operator_principals_required`,先于授权。名单非空而调用方不在名单上照旧 403。
|
|
157
|
+
按 403 判「我不是 operator」的消费方:501 这一码的出路是「这台部署没配 operator 名单」。**没有能力位的 operator 口同一条规则**(规则不需要位):`POST /v1/admin/drain` /
|
|
158
|
+
`POST /v1/admin/config/refresh` / `/v1/ops/retention/*` 三口 / `GET /v1/diagnostics/wiring`(多租户形;单用户名单空形另有本机自用律,不变)/ `POST /v1/images/register` /
|
|
159
|
+
`/v1/rules` 的跨 principal 三动词(读 / 写 / 撤销**别人的**规则;自己的规则不经运维门)—— 名单空同样由 403 改答 501,先于授权;名单非空而不在名单上照旧 403。
|
|
160
|
+
(镜像 bake 四口同一条规则;生产上那一形不可达:开 `IMAGE_BAKES_ENABLED` 而名单空在起服就被拒。)
|
|
161
|
+
· **这些面在位为假时由 404 改 501**:`/v1/approvals/*` 与 `/v1/assistant/*`(`capability.checkpoint_store_required`)、`/v1/leader*`(新码 `capability.leader_endpoint_required`)、
|
|
162
|
+
`/v1/shared-memory/*`(新码 `capability.shared_memory_required`)、`GET /v1/sessions/:id`(`capability.session_store_required`)、记忆整理两口(阀门关:新码 `feature.memory_consolidation_disabled`)、
|
|
163
|
+
`GET /v1/config/catalog`(旋钮关:新码 `feature.config_catalog_disabled`)。位值不变;按 404 判「这台没有这个面」的消费方改按 501 判(或直接读位)。错方法从 404 变成 405(路由在)。
|
|
164
|
+
· 零新旋钮、零 DDL。读法:位为真 ⇒ 它广告的每个端点都不会答「不可用」;位为假 ⇒ 至少有一个答 501(唯一例外:`a2aServe` 的两条路由答 404)。
|
|
165
|
+
|
|
166
|
+
- **后台子代的三张读面文本变了(随引擎 7.41.0 自动生效;本服务不自挂这三只工具,由引擎自挂)**:模型调 `AgentTranscript` 读后台子代时,回答**第一行**变成状态行 `State: <status> · last activity <age> ago[ · approval <卡 id> <state> (deadline in <age> | deadline passed <age> ago)]`(原来的 `Agent a… — last N tool step(s)` 退到第二行),每条步骤行多一个时间前缀 `[<age> ago] `(没结果的调用是 `[started <age> ago, no result yet] `);`TaskOutput`(后台子代)在 `status:` 之后多一行 `state: …`;`ListAgents` 的子代行多活动列(停驻的再多审批列);三张读面的 `details` 多 `agentState`(`details.steps[i]` 多 `at` / `inFlight`)。
|
|
167
|
+
① *谁受影响*:钉这三张读面首行 / 步骤行字节 / `TaskOutput` 第二行 / `ListAgents` 行列数的探针与渲染器,以及按 `details` 键在场判形的消费端。② *不改会怎样*:字节钉的探针读到新首行而红。
|
|
168
|
+
③ *怎么改*:步骤正文从 `] ` 之后读;状态读 `details.agentState`、别从文本首行抠。
|
|
169
|
+
**如实说**:`agentState` 经本服务事件流到客户端这一路,仓内没有 wire 级钉(`src` 与 `test` 里 `agentState` 零命中);文本半场随 `tool_end` 帧的 `output` 过境,`details` 是否经 `tool_end.structured` 到客户端取决于引擎对卡面 `type` 的白名单(本服务对 `structured` 只做脱敏),这三只工具的 `details` 卡在不在名单里本服务没有核过。
|
|
170
|
+
- **run-local 无终端的拒句按「问的类」说话(只换 stderr 的文字;退出码、门记录与给模型的拒因句不变)**:无 TTY 的 `run-local`(CI / cron / 管道)上被拒的审批问,stderr 那一句此前对任何问都指向同一串治理旋钮;现在按这一问的类说出路 —— 没人表态的服务器工具调用(类 `unstated`)指 `APPROVAL_GRANT`;写下的 ask 名单(类 `ask_rule`)指 `APPROVAL_REQUIRE` / `APPROVAL_NEVER_AUTO`(`APPROVAL_DENY` 是当场拒、不经这一席),`APPROVAL_AUTO_BUDGET` 那半句只在这一类问放得掉时出现;部署强制要人答的问(类 `operator_forced`)用「one of」列出能铸它的全部来源 —— `APPROVAL_NEVER_AUTO`、`commandPolicy` 的 ask 条目、或 allowlist 形里没列的命令(命令策略写在 `config.d/governance.json` 的顶层键 `commandPolicy`,文件就是治理域对象、没有外层包裹,元素 `{command, decision}`;stderr 句子里沿用旧拼法 `runtime.commandPolicy`);shell 地板(类 `shell_floor`)另一句只列 `AUTONOMY=ask` / `MANUAL_MODE_SHELL_GATE=always`;其余各类不点任何旋钮、只说去终端答;引擎没说明类时说实话、也只指向终端。① *谁受影响*:按旧 stderr 句子匹配的脚本。② *不改会怎样*:匹配落空;退出码照旧(拒 = 退 1)。③ *怎么改*:读退出码,别按 stderr 文字判。
|
|
171
|
+
|
|
172
|
+
## 7.115.0 —— `@sema-agent/core` 7.39.2 → 7.40.1:没人表态的服务器工具调用要问 · `settings.permissions.allow` 从名单翻成 allow 规则(表态,不是免问)· 升级时停驻、带 `allow` 的任务续跑被拒(升级前排空) · 运维的 allow 规则 `APPROVAL_GRANT`(新旋钮,四条腿同装) · 能力位 `settings.permissions.allowGrant` · hook 只给上下文不再替它放行 · 续跑入口取消一个码 · 随包排空脚本改名
|
|
173
|
+
|
|
174
|
+
- **🔴 询问类模式下,MCP 服务器工具 / A2A 技能的调用若没人表态 ⇒ 出卡(行为面硬破坏,引擎变更经本服务过境)**。① *谁受影响*:挂了 MCP / A2A 服务器(运维的 `config.d/mcp.json` / 配置中心,或请求体 `mcpServers` / `a2aPeers`),
|
|
175
|
+
且任务跑 `default`(不写 `permissionMode` 即此)/ `acceptEdits` / `auto` / `plan`(`plan` 下只有**只读**的服务器工具出这张卡,非只读的仍是 plan 自己的写问)的部署 —— 7.114.x 这些调用零卡直跑(引擎的 `dontAsk` 模式对这一问不出卡、直接拒;本服务的请求面不收 `dontAsk`)。现在没有规则 / hook / 审批人 / 模式释放说「这次可以」,
|
|
176
|
+
引擎出一张卡(`askClass: "unstated"`,卡句 `The agent requested permission to use <tool>, but it has not been granted yet.`);没有审批面(同步 `POST /v1/tasks` 无活审批、leader / run-local 无席)⇒ 拒。
|
|
177
|
+
② *怎么改*:**allow 规则写在哪,按腿分** —— 请求腿(`POST /v1/tasks` / `/v1/runs`,有请求体)在请求体写 `settings.permissions.allow: ["mcp__<server>__*"]`(一条覆盖整台服务器;下条);
|
|
178
|
+
没有请求体的腿 —— `run-local`(spec 由本服务自铸),以及 durable 续跑(含 leader worker 停驻后经 `/decide` 续跑的那一段)—— 由运维设 env `APPROVAL_GRANT=mcp__<server>__*`(逗号分隔;本版新旋钮,见下方「运维的 allow 规则」一条 —— 它在请求腿上同样生效)。
|
|
179
|
+
leader worker 的首跑与修复腿本键**到不了**(它们的工具策略在 leader 编排里自己折出来,不经部署治理的构造口);这两条腿今天不挂 MCP / A2A,所以没有要表态的调用。
|
|
180
|
+
两处写的都是**服务器工具 / A2A 技能**的规则(`mcp__<server>__*` / `a2a__<peer>__*` / 它们的精确名):allow 规则给出「有人表态」—— 它回答的是没人表态的服务器工具 / A2A 技能调用;内置工具上引擎自己的写门、shell 检查照问,deny / ask 照赢 —— 写 `Bash` / `Write` **不会**让它们不再被问。
|
|
181
|
+
另可:PreToolUse hook 显式回 `permissionDecision: "allow"` · 接审批面(流内审批 / `DURABLE_APPROVAL=true`)· `permissionMode: "bypassPermissions"`(只请求腿)。
|
|
182
|
+
③ *不改会怎样*:每次服务器工具调用一张卡;无审批面 ⇒ 每次被拒。拒绝句**只在**引擎判「这条腿根本没接审批人」那一形里带出路句;接了审批协调器的 HTTP 腿
|
|
183
|
+
(含同步腿审批窗为 0、当场答「没人在」的形)与无人值守腿(`run-local` / leader)上被拒时,拒绝句在 7.115.x 上**不带**出路句 —— 出路就是上面 ② 的 allow 规则 / 审批面。
|
|
184
|
+
(7.116.0 起引擎 7.41.0 补齐:两种「没人能答」都以 ` — <出路句>` 结尾、通告带 `detail.remedy`,只有审批席那一句随席位变 —— 见 7.116.0 节。)
|
|
185
|
+
- **运维的 allow 规则 `APPROVAL_GRANT`(新 env 旋钮,缺省关;零迁移,在无人值守腿上用 MCP 服务器的部署升级前设它)**。值 = 逗号分隔的工具名规则:精确名、`mcp__<server>__*`(整台服务器)、`a2a__<peer>__*`(整个 peer);命中 = 运维替这些调用表了态(回答的是没人表态的服务器工具 / A2A 技能调用),
|
|
186
|
+
未命中 = 不表态。与 `settings.permissions.allow` 同一只编译口、同一只校验,HTTP 提交(`POST /v1/tasks` / `/v1/runs`)、durable 续跑(每一次从持久化的提交体重建,含 leader worker 停驻后经 `/decide` 续跑的那一段)、停驻后台 agent 的跨副本赎回、`run-local` 四条腿同装(leader worker 的首跑与修复腿到不了),**不越过**任何一层的 deny / ask(`APPROVAL_DENY` 拒、`APPROVAL_REQUIRE` 问、请求 settings 的 deny / ask、会话规则照旧压过它)。
|
|
187
|
+
**不是白名单**(不收窄任何东西;「只许这些」是会话规则的 `toolAllow`)。坏值(退役名、无前缀短名、`mcp__figma` 两段形、反斜杠、超长、`Bash(npm:*)` 这类内容形)⇒ 启动拒,错误句点名哪一条、怎么改。
|
|
188
|
+
规则对**每个租户、每条腿**生效:`mcp__<server>__*` 也覆盖那台服务器将来新增的工具 —— 按需写窄。它给的只是「没人表态」那一句答,**不放掉任何一层自己的问**:
|
|
189
|
+
内置工具的精确名(例 `Write` / `Bash`)写进来,`default` 模式下引擎自己的写门 / 形状层照问(问压过放行)。
|
|
190
|
+
A2A 如实:运维声明的对端(配置中心 / `config.d`,刻意不收 `toolAxes`)上,每次技能调用都是引擎自己的外发标记问(`tool_marks_a2a`),不是「没人表态」那一问 —— `a2a__<peer>__*` 不放它,无人值守腿上 A2A 技能调用照旧被拒 / 停驻 / 问人;只有请求体自带的对端(单用户闸)能在 `toolAxes` 里把某个技能的 `egress` 降为 `false`,那之后才是「没人表态」那一问,这时 allow 规则才答得上。在场与否:起服日志 `approval_grant_in_force`、`GET /v1/diagnostics/wiring` 的 `serverGates.approvalGrant`。v1 只有 env 一个写入通道。
|
|
191
|
+
- **🔴 `settings.permissions.allow` = allow 规则(表态),不再是名单(行为面硬破坏)**。① *谁受影响*:把 `settings.permissions.allow` 当白名单、用来**只许**某几只工具的调用方。7.114.x:名单在场 ⇒ 名单外的工具(含全部 `mcp__*` / `a2a__*`)一律拒。
|
|
192
|
+
现在:一条 allow 规则命中 = 带理由的放行,即allow 规则给出「有人表态」—— 它回答的是没人表态的服务器工具 / A2A 技能调用;内置工具上引擎自己的写门、shell 检查照问,deny / ask 照赢。**未命中 = 不表态、照常判**(引擎自带工具按模式判,服务器工具出上一条的卡)。
|
|
193
|
+
⚠️ 与参照实现(CC)的 `permissions.allow` **不同**:CC 里 `allow: ["Edit"]` 会跳过编辑确认;这里写 `Write` / `Bash` 只是表态,`default` 模式下引擎的写门 / shell 检查照问(要免掉这些问,用 `permissionMode`)。
|
|
194
|
+
同时 allow 桶的规则形与 deny / ask 同一只判据:退役名(`Task` / `bash` …)、无协议前缀的短名、缺段或两段 MCP 名(`mcp__figma` ⇒ 写 `mcp__figma__*`)、反斜杠、超 512 字符 ⇒ 整请求 422(7.114.x 收下这些名字形);内容形 / 参数级 allow(`Bash(npm:*)`、`Read(./x)`、`WebFetch(domain:…)`)⇒ 整请求 422(7.114.x 同样 422,只是那一版的指路句是名单的读法,本版改指持久规则店)。
|
|
195
|
+
**反方向的一处(由拒变收)**:`Bash(*)` / `Read(*)` / `Edit(*)` 这类「工具名 + 通配内容」形,7.114.x 是 422(名单按整串比对,带括号的名字匹配不上任何工具);现在收下,编成那只工具的整工具 allow 规则(与写 `Bash` / `Read` / `Edit` 同读 —— 只表态,引擎的写门 / shell 检查照问)。
|
|
196
|
+
② *怎么改*:要「只许这些工具」改用真旋钮 —— 会话规则 `PUT /v1/sessions/:id/policy` 的 `toolAllow`(不在名单 ⇒ 拒;非运维只许收紧)、每请求 `excludeTools` / `excludeAllTools`、或部署场景工具面;内容形的常设放行进持久规则店(`/v1/rules/cc-import` 导入,或在卡上答 yes 时留规则;`POST /v1/rules` 是收紧方向的单步写口,不收 allow);坏形名字按 422 文案改。
|
|
197
|
+
客户端据 `GET /v1/capabilities` 的 `settings.permissions.allowGrant === true` 判断这台 server 是否按新语义收 allow(键缺席 = 旧 server,别投这只桶)。
|
|
198
|
+
③ *不改会怎样*:以 allow 收窄工具面的请求,名单外的工具照常可用(收窄失效);带坏形 allow 名字的请求 422。最坏的组合:把它当白名单用、同时请求 `permissionMode: "bypassPermissions"` 的调用方 —— 升级后名单外的工具不再被拒、也不会被问(7.114.x 上只许名单内)。
|
|
199
|
+
- **「永远不会生效的条目」拒因句改形(码不变)**:请求体 `settings.permissions.{allow,ask,deny}` 的 422、`APPROVAL_REQUIRE` / `APPROVAL_DENY` / `APPROVAL_NEVER_AUTO` / `APPROVAL_GRANT` 的启动拒、
|
|
200
|
+
配置中心 `governance.approvalRequire` 的整组拒,句首由 `… names tool(s) that can never match a live tool (these lists are RAW whole-name comparisons — …)` 改成
|
|
201
|
+
`… has an entry / entries that can never take effect — it / each would never match a live tool or cannot be compiled into a rule (names are read exactly as written: no alias folding, no protocol prefix added)`;
|
|
202
|
+
逐条 `名 → 指引` 不变。按句子前缀匹配的消费方改按错误码分派。
|
|
203
|
+
- **能力位(additive)**:`GET /v1/capabilities` 新顶层键 `settings` = `{ permissions: { allowGrant: true } }`(恒真版本位)。`taskSettings.permissions` 仍是布尔 `true`,不变。零动作;想投 allow 的客户端按上条读它。
|
|
204
|
+
- **PreToolUse hook 结果映射(行为面)**:hook **显式**回 `permissionDecision: "allow"` ⇒ 当作 hook 的放行交给引擎;hook 只给 `additionalContext` / 只给 `updatedInput` ⇒ 不再被当成放行。
|
|
205
|
+
7.114.x 上这两处映射的差别**看不出来**:那一版的引擎对 hook 的放行不读(只读 deny / ask),服务器工具不论 hook 怎么写都零卡直跑;7.115.0 起差别才可见 ——
|
|
206
|
+
显式 `allow` 的 hook 让服务器工具不再出「没人表态」卡,只给上下文 / 只改写的 hook 不再替谁表态,服务器工具照问。
|
|
207
|
+
PreToolUse hook 的显式 `allow` 同样只是表态:它让没人表态的服务器工具调用不再出卡,引擎对内置工具(编辑、shell)自己的询问照出。这与参照实现不同(那边 hook 批准即跳过询问);引擎一侧已立项按参照实现收。
|
|
208
|
+
零配置动作:想让 hook 放行的,显式回 `allow`。放行只管那条 hook 看见的参数:最终交给工具的参数若不是它看见的那一份(后面的 hook、或同一组里的另一条 hook 改写了)⇒ 这次放行不算数(要让改写后的参数也算表态,改写的那条 hook 自己回 `allow`)。部署级 hook 与任务级 hook 的复合体同一条规则。
|
|
209
|
+
- **`APPROVAL_REQUIRE` 名单 × 服务器工具**:人在卡上选「本会话不再询问」之后、以及 `APPROVAL_AUTO_BUDGET` 额度内的自动批,同一只服务器工具不再被引擎再问一次(这两处现在对引擎说明「是名单门放行的」)。零动作。
|
|
210
|
+
- **🔴 升级时仍停驻、提交时带了 `settings.permissions.allow` 的任务:续跑被拒(持久数据面硬破坏,零 DDL;升级前排空)**。① *谁受影响*:升级那一刻有停驻中的任务(等审批 / 计划审阅 / 资源停车 / 可唤醒)、
|
|
211
|
+
且它提交时请求体带了非空 `settings.permissions.allow` 的部署 —— 那份 `allow` 是按名单写的,本版不按新读法(allow 规则)重放它(那会让名单外的工具在续跑时静默放开):
|
|
212
|
+
这些任务的每一个续跑入口(`/decide`、`/resume`、`/plan_review`、带 / 不带消息的 `/wake`)答 `409 checkpoint.unsupported_version`(`retriable:true` = 卡仍 pending,**不是**「重试会成功」;挂着 run 的停驻可以取消,唤醒停驻没有可取消的 run),
|
|
213
|
+
任务字节不动、仍停驻(工具审批 / 计划审阅 / 资源停车三类挂着 `suspended` 的 run 行、会话锁仍在;`task_done` 唤醒停驻的原任务早已终局,没有 run 行、不占会话锁,被拒后那张停驻留到过期);SLA 到期拒扫跳过它们(不逐拍重试),收割器在终局时刻收。7.115.0 起新停驻的任务不受影响,提交时没带 `allow`(或带空数组)的不受影响。
|
|
214
|
+
② *怎么改*:升级**前**在仍跑 7.114.x 的部署上数这类任务(7.115.0 的包不带 SQL 文件 —— 数的办法:取 7.116.0 的包里 `scripts/drain-check.<mysql|pg>.sql` 的 `permissions-allow-list` 一段,跑法见上面 7.116.0 节;`DB_BACKEND=local` 跑**本版(7.115.0)包里**的随包脚本 `scripts/drain-check-local.mjs` ——
|
|
215
|
+
仍跑 7.114.x 时已装的包里只有旧名脚本、没有本条判据,读出的「干净」是假的;不必先升级服务:`d=$(mktemp -d) && (cd "$d" && npm pack @sema-agent/server@7.115.0 && tar xzf sema-agent-server-7.115.0.tgz) && node "$d/package/scripts/drain-check-local.mjs"`,
|
|
216
|
+
看 `PERMISSIONS-ALLOW-LIST rows=` 那一行),期望 0;非 0 ⇒ 让它们跑完,或 `POST /v1/runs/:id/cancel` 取消(唤醒停驻没有可取消的 run:唤醒它跑完,或升级后在那个会话上直接新提交)。已经升级才发现 ⇒ 有 run 行的三类取消后重提、唤醒停驻直接在该会话上新提交(要「只许这些工具」改用会话规则 `toolAllow` / 请求 `excludeTools`),或一次性回滚到 7.114.x 续跑完再升回来。
|
|
217
|
+
③ *不改会怎样*:这些任务续不了:有 run 行的三类只能取消后重提,取消之前会话锁一直被它们占着(同一会话上新提交 409 `conflict.session_active_run`);唤醒停驻续不了,但不挡同一会话上的新提交。这条拒是一次性迁移:等所有 7.114.x 停驻的任务结束后,后续版本把它删掉。
|
|
218
|
+
**配方数不到的一个入口**:workflow 子代的审批被决定后,决定投到**宿主**会话上起新一跑;宿主会话体里带非空 `allow`、续跑上下文没有读法记号且尚未被回收时,这一跑同样被拒(同一句 409)。
|
|
219
|
+
配方只数「本会话有待决行」的会话,宿主会话自己没有待决行,数不到它;撞得上的窗口 = 宿主会话闲置未超过 `REAP_RUN_STALE_SEC`(出厂 120 s,调大则更久)。
|
|
220
|
+
出路:升级前把待决的 workflow 子代审批先决掉;升级后撞上 ⇒ 在该宿主会话上重新提交任务。
|
|
221
|
+
- **🔴 随包排空脚本改名(硬破坏,零别名):`scripts/retired-mode-seed-drain-local.mjs` → `scripts/drain-check-local.mjs`**。7.115.0 起这只脚本一次跑两条判据
|
|
222
|
+
(`permissions-allow-list` 与 `retired-mode-seed`),旧名只说了一条;新名与 SQL 配方的标记 `-- drain-check:<判据>:<后端>` 同一个词(7.116.0 起 SQL 在随包的 `scripts/drain-check.*.sql` 里)。
|
|
223
|
+
① *谁受影响*:按旧文件名调这只脚本的运维脚本 / runbook(7.113.0 与 7.114.0 的包里它就叫旧名)。
|
|
224
|
+
② *怎么改*:换文件名 —— 同一只脚本,参数(可选的数据根)、退出码(0 / 1 / 2)、两条汇总行(`PERMISSIONS-ALLOW-LIST …` 与恒在最后的 `RETIRED-MODE-SEED …`)的名字与顺序都不变。
|
|
225
|
+
③ *不改会怎样*:7.115.0 的包里没有旧名的文件(也没有转发壳)⇒ `node` 报找不到文件。⚠️ 找不到文件时 `node` 的退出码是 **1**,而这只脚本自己的 rc 1 是「有命中、有停驻行」—— 只看退出码的下游会把「脚本没跑起来」读成「有停驻行」;
|
|
226
|
+
调它的运维脚本请把文件名换了再核一遍读数(末行要见到 `RETIRED-MODE-SEED rows=…`,不要只看 rc)。
|
|
227
|
+
- **停驻后台子代的跨副本赎回不读请求体的 `settings.permissions`(如实;7.114.0 起如此,本版不变)**:跨副本赎回停驻的后台子代时,父任务请求体里的 `settings.permissions`(allow / ask / deny 三桶)不进那条腿,只有部署层在(审批基线、部署治理、`APPROVAL_GRANT`)。
|
|
228
|
+
- **滚动升级窗 / 回滚(如实)**:新旧副本并存时,客户端在新副本上读到 `settings.permissions.allowGrant` 后提交的 `allow`,若落到旧副本,被按**名单**读(收窄,方向安全);
|
|
229
|
+
旧副本上停驻的这种任务没有读法记号,换成新副本后续跑同样被上一条拒(出路同上一条)。新副本停驻、带 `allow` 的任务若在窗内被旧副本续跑,旧副本不认记号、按名单读(同样是收窄)。
|
|
230
|
+
回滚到 7.114.x:7.115.0 停驻的任务里的 `allow` 同样被按名单读;带 `unstated` 类的待决卡,7.114.x 的审批队列读不出这个类词(卡照列,只是没有 `askClass` / `classes` 两键,
|
|
231
|
+
`server.approval-card.closed-word-out-of-set` 计数加一),审批流内卡店里带它的行重放时被跳过、同一问幂等重入走停驻(fail-safe)。7.114.x 的引擎能不能续跑 7.40.x 写下的这张卡:未核。
|
|
232
|
+
- **续跑入口的取消(引擎 7.40.1)**:带消息的 `POST /v1/sessions/:id/wake` 在部署 `userPromptSubmit` 门还没答完时被 `POST /v1/runs/:id/cancel` ⇒ 合成 run 行取消终局(`errorCode: "cancelled"`),那张 park 按取消语义收掉,
|
|
233
|
+
再 `wake` ⇒ 404 `not_found.parked_checkpoint`(继续会话 = 新提交一条任务)。7.114.x 同一操作报 `steering.blocked_by_hook`(409,`retriable: true`)且 park 留着 —— 那是错码的副作用。只按 `errorCode` 分派取消的消费方零动作;把这一形当「hook 拦了、稍后重试」的要改读。
|
|
234
|
+
- **「只续已有会话」两处拒的 `errorCode` 变了(状态码不变)**。① *谁受影响*:提交体带 `requireExistingSession:true`、按 `errorCode` 分派的客户端 —— `sessionId` 在本部署不存在的 404,`errorCode` 由 `not_found.resource` 变 `resume.session_not_found`;没给 `sessionId` 的 422,由 `request.unprocessable` 变 `request.field_conflict`。
|
|
235
|
+
② *怎么改*:按新码分派(`resume.session_not_found` = 要续的会话不在;`request.field_conflict` = 请求自相矛盾,补上 `sessionId` 或去掉 `requireExistingSession`)。422 那一句的句尾括注 `(resume.session_not_found)` 同时去掉(码是 `request.field_conflict`,句子不再括注另一个码);404 那一句不变。
|
|
236
|
+
③ *不改会怎样*:按旧码写的分支不再命中,这两处拒落进客户端的通用 404 / 422 处理;从 422 句子里解析 `resume.session_not_found` 的客户端解析不到。
|
|
237
|
+
- **`limits.brainCallGuardrailMs` 由受理(无效)变 400**。① *谁受影响*:提交体带 `limits.brainCallGuardrailMs`(毫秒数、`false` 或 `0`)的调用方 —— 7.114.x 受理(`POST /v1/tasks` 200 / `POST /v1/runs` 202)但这个键不生效,单次脑调用的外墙照旧是引擎缺省的一小时;现在 `400 request.field_invalid`,句子点名这个键。
|
|
238
|
+
② *怎么改*:删掉这个键(本服务没有给调用方设这道外墙的口;要别的外墙值,先要一个部署级旋钮)。
|
|
239
|
+
③ *不改会怎样*:带这个键的提交整条被拒,任务不跑。
|
|
240
|
+
- **用户可见(引擎 7.40.0,零配置动作)**:`settings.permissions.ask` 里的 `Read(<path>)` 规则现在也管 Grep / Glob 在该路径下的搜索(各出一张 Read 卡;无审批面 ⇒ 拒),`Edit(<path>)` ask 规则也管 Write / NotebookEdit;
|
|
241
|
+
Read 工具结果不再带常驻的内容安全提醒(依赖那句约束弱模型的部署,把同一句放进自己的 `appendSystemPrompt`)。
|
|
242
|
+
|
|
10
243
|
## 7.114.0(车UW,S-995;车UY)—— `settings.hooks` 工具事件 matcher:别名写成正则形的同一个错误,提交当场 400(7.112.0 只拒字面形) · `@sema-agent/settings-schema` 7.0.1 + `@sema-agent/core` 7.39.2:车道 / 存储词表改读正本 · 写了 `remote-docker` 的 `config.d/remote-exec.json` 拒启 · local 车道坏会话规则文件改拒 · 被拒的 `resumeAt` 不再挪会话叶
|
|
11
244
|
|
|
12
245
|
- **🔴 settings 面硬破坏(响亮拒,无迁移代码、无兼容形)**。① *谁受影响*:提交体 `settings.hooks` 里 PreToolUse / PostToolUse / PostToolUseFailure 的 `matcher` **选中引擎工具别名、却选不中它的正名**的 —— 7.112.0 只拒字面的 `ListPeers` / `Read|ListPeers`,
|
|
@@ -16,7 +249,7 @@
|
|
|
16
249
|
**不在本规则内(仍受理)**:大小写错的别名(`"listpeers"` —— CC 同形:区分大小写、静默不跑)与「选不到目录里任何名」另一类(含目录之外的 MCP 工具名,受理面无从区分),后者候设计(见 CHANGELOG `## Unreleased` 7.114.0 线 · 车 UW)。
|
|
17
250
|
**正则只是顺带选中别名也会被拒**:规则问的是「这只 matcher 选不选别名 / 选不选正名」,不问写的人本意 —— 一只写来匹配目录外 MCP 工具、只是顺带也选中 `ListPeers` 的正则(如 `.*Peers`、`mcp__.*|.*Peers`)同样 400,
|
|
18
251
|
而错误句说的是「改成 `ListAgents`」。出路:在正则里把别名排除掉(如 `(?!ListPeers$).*Peers`),或改成不会选中它的写法。
|
|
19
|
-
- **🔴 运行期 matcher 求值与 CC 2.1.280 同形(行为面;不是配置面硬破坏 —— 是钩子开始触发)**。① *谁受影响*:`settings.hooks` 里 matcher 带**两端空白、分隔符两侧空白或用逗号分隔**的(`" Bash"` / `"Bash "` / `"Read | Bash"` / `"Read,Bash"`)—— CC 容忍,sema 此前把它们当「选不中」(钩子永不触发、无任何声音)。② *怎么改*:无需改 —— 它们现在按作者本意命中(PreToolUse 的 deny 钩子也真拦);**区分大小写、不剥词内空白**(`bash` / `"Ba sh"` 照旧不命中,CC 同形)。含 `.` / `*` / 括号等正则字符的 matcher **一字不动**(整体当锚定正则)。③ *不改会怎样*:升级后,**以前因空白永不触发的钩子会触发** —— 若你依赖「带空白的钩子是死的」(不是合法用法),删掉那条。耐久 resume 的存量 hooks 里带空白的 matcher 在续跑腿同样开始命中。**读法**:只含 `[A-Za-z0-9_-]`、`|`、`,`、空格的 matcher 按 `[|,]` 拆、逐段 trim、大小写敏感、词内空白不剥,对所有带 matcher 的事件(含 StopFailure / PreCompact / PostCompact 与 `if` 条件名部)同一只读法。**已知与 CC 的差异(未做)**:CC 的空白 / 逗号放行按事件分档(sema 不分);CC 正则不锚定。依据:对 CC 2.1.280 的黑盒实测(空白 / 大小写)
|
|
252
|
+
- **🔴 运行期 matcher 求值与 CC 2.1.280 同形(行为面;不是配置面硬破坏 —— 是钩子开始触发)**。① *谁受影响*:`settings.hooks` 里 matcher 带**两端空白、分隔符两侧空白或用逗号分隔**的(`" Bash"` / `"Bash "` / `"Read | Bash"` / `"Read,Bash"`)—— CC 容忍,sema 此前把它们当「选不中」(钩子永不触发、无任何声音)。② *怎么改*:无需改 —— 它们现在按作者本意命中(PreToolUse 的 deny 钩子也真拦);**区分大小写、不剥词内空白**(`bash` / `"Ba sh"` 照旧不命中,CC 同形)。含 `.` / `*` / 括号等正则字符的 matcher **一字不动**(整体当锚定正则)。③ *不改会怎样*:升级后,**以前因空白永不触发的钩子会触发** —— 若你依赖「带空白的钩子是死的」(不是合法用法),删掉那条。耐久 resume 的存量 hooks 里带空白的 matcher 在续跑腿同样开始命中。**读法**:只含 `[A-Za-z0-9_-]`、`|`、`,`、空格的 matcher 按 `[|,]` 拆、逐段 trim、大小写敏感、词内空白不剥,对所有带 matcher 的事件(含 StopFailure / PreCompact / PostCompact 与 `if` 条件名部)同一只读法。**已知与 CC 的差异(未做)**:CC 的空白 / 逗号放行按事件分档(sema 不分);CC 正则不锚定。依据:对 CC 2.1.280 的黑盒实测(空白 / 大小写 / 逗号分隔;逗号的三种写法在参照实现上各 3/3 命中)。
|
|
20
253
|
- **多租户车道(`requirePrincipal: true`):字面判保留,另有一处放宽见下条**:该车道 `settings.hooks` 整只被忽略(`task_hooks_ignored`),受理面走**字面档 = 7.112.0 的字面判保留**(裸 `ListPeers` / `Read|ListPeers` 照旧 400;正则写法照旧 200),且**零调用方正则执行**;字面档与运行期共用同一只字面 / 名字表读法,所以**带空白或逗号分隔的别名**(`" ListPeers"` / `"Read | ListPeers"` / `"Read,ListPeers"`)在该车道也同拒 400(只多拒、不放宽)。上面的正则求值只在单用户车道。
|
|
21
254
|
- **受理面判序与资源闸(行为面,零新码;两条车道同一条顺序)**:matcher 超 8 192 字符 ⇒ 两条车道都不读、「未判」、照旧受理;字面 / 名字表读法(只含名字字符、`|`、`,`、空格)两条车道都先走、不占求值预算;
|
|
22
255
|
只剩正则形时,单用户车道在一次受理共享的 100 ms 墙钟预算里求值(灾难回溯的正则用尽预算 ⇒ 那一只与其后各只正则形「未判」、照旧受理),多租户车道对正则形不判。
|
|
@@ -49,11 +282,13 @@
|
|
|
49
282
|
不再是「受理、引擎在 prepare 拒」。升级前就停放、存量体里带这个键的任务续跑时**丢键照跑**(它要的提醒今天由引擎在 plan 模式下自己铸,不丢意图)。
|
|
50
283
|
- **🔴 升级前排空 ≤ core 7.33.x 时期停放的 checkpoint 行**(core 7.39.0 删掉一次性迁移):`inheritedGate` 仍带退役模式种子(`autoModeRequested` / `approverPosture` /
|
|
51
284
|
非 `"always"` 的 `shellGate`)的 pending 行 —— 只可能是 server ≤7.105.0 时期停放、至今仍 pending 的行 —— 升级后续跑被拒 `409 checkpoint.unsupported_version`
|
|
52
|
-
(行字节不动、仍 pending)。**在还跑 ≤7.112.0
|
|
285
|
+
(行字节不动、仍 pending)。**在还跑 ≤7.112.0 的部署上**用随包 `scripts/drain-check.<mysql|pg>.sql` 的 `retired-mode-seed` 一段数行(7.116.0 起在包里,取法见上面 7.116.0 节;期望 0),非 0 就答完或取消那些 run 再换钉;
|
|
53
286
|
漏排的行升级后可 `POST /v1/runs/:id/cancel` 放弃,或一次性回滚到 7.112.x 续跑完再升回来。
|
|
54
287
|
- **`DB_BACKEND=local`(File 店)车道的排空**:没有 SQL 可跑 —— 用随包的只读脚本 `scripts/retired-mode-seed-drain-local.mjs`(7.113.0 起在 npm 包里)。
|
|
55
288
|
**升级前你装的还是 ≤7.112.0,脚本不在已装的包里,但不必先升级服务**:`d=$(mktemp -d) && (cd "$d" && npm pack @sema-agent/server@7.113.0 && tar xzf sema-agent-server-7.113.0.tgz) && node "$d/package/scripts/retired-mode-seed-drain-local.mjs"`
|
|
56
289
|
(已升级的,直接 `node <安装目录>/node_modules/@sema-agent/server/scripts/retired-mode-seed-drain-local.mjs`)。
|
|
290
|
+
**改名**:7.115.0 起这只脚本叫 `scripts/drain-check-local.mjs`(同一只、多一条判据,见本文件 7.115.0 节);上面的旧文件名是 7.113.0 / 7.114.0 包里的名字(取 7.113.0 包那条命令里的旧名不用改),
|
|
291
|
+
已升到 7.115.0 及以后的安装目录里请按新名调。
|
|
57
292
|
**读哪个数据根**:不带参时 = 服务自己的那条解析 —— `LOCAL_DATA_ROOT` → `CONFIG_LOCAL_DIR` → `AGENT_DATA_DIR` → `~/.ai-agent`(脚本取的是服务 `loadConfig` 调的同一只函数,不是它自抄的一份),
|
|
58
293
|
所以请在**与服务同一份 env** 下跑;也可以把数据根当唯一参数递进去。末行 `RETIRED-MODE-SEED rows=… root=<实际读的数据根>` 回显读了哪个目录。
|
|
59
294
|
只读、不取锁;它把 `checkpoints/checkpoints.snapshot.jsonl`(压实后的行)与 `checkpoints/checkpoints.jsonl`(之后的事件)折成当前状态再判 pending 行(不要用 grep 代替:压实后老行只在快照里)。
|
package/USAGE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# 调用方手册(OA / 智能体 / 你自己)
|
|
2
2
|
|
|
3
3
|
> 一句话心智模型:**你只对一个地址发普通 HTTP 请求——LB `http://<host>:8090`;请求体里只写"要做什么"。**
|
|
4
|
-
> 工具面与安全策略由服务端 `resolveSpec` 注入,请求体**替换不了**它们(`tools` 不是受理键,传了 400;按请求只能**减**:`excludeTools` / `settings.permissions`)。
|
|
4
|
+
> 工具面与安全策略由服务端 `resolveSpec` 注入,请求体**替换不了**它们(`tools` 不是受理键,传了 400;按请求只能**减**:`excludeTools` / `settings.permissions` 的 deny · ask;7.115.0 起 `settings.permissions.allow` 是 allow 规则:allow 规则给出「有人表态」—— 它回答的是没人表态的服务器工具 / A2A 技能调用;内置工具上引擎自己的写门、shell 检查照问,deny / ask 照赢;能力位 `settings.permissions.allowGrant`)。
|
|
5
5
|
> `model` 与 `systemPrompt` / `appendSystemPrompt` 是受理键,但 `model` 只能点服务端已配置目录里的名字 / 档位词 / 模型 id(未知 ⇒ 400)。凭据永远不进模型 / 请求体。
|
|
6
6
|
> 你不"调度 worker",你只发任务;LB + TiDB 自己协调。每个字段都来自当前真实代码。
|
|
7
7
|
|
|
@@ -113,6 +113,7 @@ ANTHROPIC_API_KEY=sk-ant-… # 可选:ANTHROPIC_BASE_URL / ANTHROPIC_VERSION /
|
|
|
113
113
|
`@名` / `settings.model` / `compactionModel` / side-query)⇒ 400 `request.model_unavailable`。**7.100.0 及以前**这种条目会落到网关
|
|
114
114
|
brain、带着**它自己的** `apiKeyEnv` 钥匙打到网关。不合 settings-schema 形的条目同律(码 `config.model_entry_invalid`,如非 http(s)
|
|
115
115
|
的 `baseUrl` —— 此前被「退回部署网关」;读腿逐条丢掉的条目同样留名字,点它照样 400);目录里**每条**都不可用 ⇒ 那一代模型面这一组被拒。
|
|
116
|
+
🔴 **日志与拒因句里的条目名先过名筛**(7.115.0 起):被拒条目的名字写进启动 / 刷新日志(`sema_registry_model_no_brain` / `_entry_invalid` 的 `model`、`sema_registry_models` 行的 `unavailable`、缺省 / 档位 / 角色绑定三条 warn 里指向被拒条目的名字)与「缺省模型缺席」「被拒名被增广铸出」两句拒因之前,先问 settings-schema 的 `isReportableRefusalName`(`[A-Za-z0-9._:/@+-]` 闭形、无密钥形、无带 userinfo 的 URL 形)。**不可披露的名只写码**:warn 不带 `model`、改带 `modelNameWithheld: true`(`unavailable` 只列可披露的名并带 `unavailableNamesWithheld` 个数);拒因句里该位写 `(name withheld)`。引擎自己的判决不受影响(显式点它照样拿拒因码);**要在日志里认出是哪一条**,把目录条目名改成名筛的闭形字符集(或按 `code` / `provider` / `fields` 在目录里找)。显式选中不可用条目的 400 回显不在此列(它回显的是调用方自己点的那个名)。
|
|
116
117
|
🔴 **被拒条目的名字不许被档位 / 别名铸到别的条目上**(S-712):不可用条目恰好叫 `sonnet` / `opus` / `pro` / `best` 这类档位词或 CC 别名、
|
|
117
118
|
而档位表会铸出这个词时,这份候选的模型面整组被拒(码 `config.model_refused_name_minted`,warn `sema_registry_model_plane_refused` 点名
|
|
118
119
|
「被拒名 → 目标条目」)—— 否则显式点它、或绑它的角色,会静默跑在另一条条目的端点与账号上;出路:改名 / 修好条目,或改绑那条档位绑定。
|
|
@@ -454,6 +455,7 @@ MODEL_CASCADE_LADDER=deepseek-flash,deepseek-pro # 目录里的模型名,cheap
|
|
|
454
455
|
`multi-tenant-shared-lane` / `device-durable-store` / `device-durable-approval`)自 7.104.0 起判在这一步,**不在** `loadConfig()` 里 ——
|
|
455
456
|
只调 `loadConfig()` 的装配对这几形照起。`ctx.configSource === "local"` 时它先读 `config.d/remote-exec.json` 覆写车道(`drivesFromFile`
|
|
456
457
|
= 你的装配驱动得了的文件车道),再判;不走文件覆写的装配直接调同一份判据 `assertExecutionLaneInvariants(config)`。
|
|
458
|
+
`ctx` 的型 `ExecutionLaneComposeCtx` 也从包根导出(自己的装配里要写它的签名 / 抽 helper 时直接 import,不必手抄一份形)。
|
|
457
459
|
- **库形嵌入的 caps `store` 位**(7.106.0 起,S-866 ①;7.106.0 合并复审 X9 补一句):`createHttpServer` 的 `storePosture` dep **不传** ⇒ `GET /v1/capabilities` 的
|
|
458
460
|
`store` 取诚实下限 `{declared: <config.dbBackend>, backend: "memory", durable: false}`,且**没有 `store.sql`**(即使递了 `sqlEngineFacts`、真有 SQL 后端 ——
|
|
459
461
|
7.105.0 上这类嵌入方的顶层 `sql` 是有值的)。要 caps 说真话就把你装出来的后端事实经 `storePosture` 递进来(形 = `src/store-posture.ts` 的 `StorePosture`)。
|
|
@@ -690,7 +692,7 @@ FLEET_ADVERTISE_ADDRESS=http://<本机可达IP>:8090 # 可选:设了才启公
|
|
|
690
692
|
| 记忆整理阀门判决 + 驱动席(`MEMORY_CONSOLIDATION_DRIVER=on`,或未设而出厂缺省按目录派生 —— 7.104.0 起) | 重启生效 | 阀门开关与整理跑用的模型都在启动期定一次;中心改了 roles / 档位 / 目录条目后,**判决会翻**(派生开 ↔ 关,含只把主模型挪到整理座那一条上)或开着而座漂了 ⇒ `/health` 报 `restartRequired`,`restart.reasons` 含 `memory-consolidation`(7.100.0 新理由;7.104.0 起派生关的那台同样报) |
|
|
691
693
|
|
|
692
694
|
生效与否的观测口=`/health` 世代账键(`configTargetVersion`/`configAppliedVersion`+两 ordinal+`configApplyStaleMs`,见 API 表 `/health` 行)——target≠applied 持续=「改了没生效」的机读信号。
|
|
693
|
-
- **`run-local`(一次性本机 CLI)上三张审批名单同样执法**(7.101.0 起,TTY 问 / 无 TTY 拒):`APPROVAL_DENY` 当场拒;`APPROVAL_REQUIRE` / `APPROVAL_NEVER_AUTO` 命中 ⇒ stdin 是 TTY 就 `y/N` 问人,否则当场拒并在 stderr
|
|
695
|
+
- **`run-local`(一次性本机 CLI)上三张审批名单同样执法**(7.101.0 起,TTY 问 / 无 TTY 拒):`APPROVAL_DENY` 当场拒;`APPROVAL_REQUIRE` / `APPROVAL_NEVER_AUTO` 命中 ⇒ stdin 是 TTY 就 `y/N` 问人,否则当场拒并在 stderr 说出路(7.116.0 起按**这一问的类**说,不再对每一问打同一句全量旋钮清单:没人表态的服务器工具调用 ⇒ 指 `APPROVAL_GRANT`;名单产的问 ⇒ 点名三张名单键;部署治理盖了出身的问 ⇒ 点治理旋钮;引擎自己的问 ⇒ 不点旋钮、只说去终端答;引擎没有说明这一问的类 ⇒ 说明这一点、只给终端出路);`APPROVAL_AUTO_BUDGET` 照常生效(never-auto 不吃预算);TTY 问句带上这次调用的参数,人答 N 而停下的 run 退 1(停因 `haltedOnUserRejection`)。**无 TTY 的拒记在部署政策名下**(7.110.0 起,S-956;此前记成人拒):该次调用 `tool_end.gate.settlement` = `{kind:"policy_refused", who:{party:"policy"}}`(7.113.0 起;7.110.x–7.112.x 为 `party:"none"`),模型读到的是引擎的策略句(「部署政策拒了、此处没有交互审批,别重试,先做不需要审批的部分」)加一句拒因,而不是「用户不想继续,停下来等他」—— 不停批,模型接着做别的部分;那只要人批的动作没执行 ⇒ run 照样退 1,非 `--json` 形 stderr 停因行是 `task incomplete (approval unanswered): …`。参数展示不出而不问就拒的那一形(TTY 在场也一样)同此。这条腿没有 checkpoint 店也**不**拒启 —— 它有一只当场作答的席,名单的 ask 不需要 park(上表「无 checkpoint 店 ⇒ 整组拒」只说服务腿)。此前三张名单在这条腿上无声不生效。
|
|
694
696
|
- **仅 `/v1/tasks`(同步)+ `/v1/runs`(异步)**——`/v1/tasks/stream` 不支持(多次尝试非单流,400)。与 `verify` **互斥**(同时给 → 400)。
|
|
695
697
|
- 成本上界 = 任务的 `maxCostUsd`(防冷重跑税)。**三条 core 警示**:① 每档**冷重跑**重付输入成本(便宜档常过才划算);② 门收到**未脱敏**输出(自定义门转发外部 verifier 要脱敏);③ **写工具会跑 N 次**——**只用于只读/幂等任务**(每次升级整任务重跑)。开放式任务(找全 bug/文笔)没有可判定 oracle、级联会空转,那种用 `discuss`(广度交叉)而非级联(深度阶梯)。
|
|
696
698
|
|
|
@@ -879,6 +881,36 @@ UNATTENDED_APPROVAL_POLICY=park
|
|
|
879
881
|
(`config.env_key_retired`,任何值都拒);从 `.env` 里删掉它。要让机器多答某一类问,先立案,不开旋钮。
|
|
880
882
|
- 写面:`default` 模式不带写面 ⇒ 工作区根内(`roots`,与 7.105.0 同)。 `roots` 只约束 Write / Edit 这类结构化文件工具;shell 的根外写、Read 工具的根外读属 core `ordinary`,这些腿上由机器答(落地结果与 ≤7.108.0 的 bypass 放行同,门记录归属词见 MIGRATION 7.109.0「审计读者」)。
|
|
881
883
|
|
|
884
|
+
**可选 — 运维的 allow 规则 `APPROVAL_GRANT`(7.115.0 起;缺省关)**
|
|
885
|
+
|
|
886
|
+
```bash
|
|
887
|
+
APPROVAL_GRANT='mcp__figma__*,a2a__planner__*' # 逗号分隔的工具名规则:运维替这些服务器工具 / A2A 技能表态
|
|
888
|
+
```
|
|
889
|
+
- **为什么要它**:引擎 7.40.0 起,询问类模式下 MCP 服务器工具 / A2A 技能的调用若**没有任何层表态**,就出一张「没人表态」的卡
|
|
890
|
+
(`askClass: "unstated"`)。请求腿可以在请求体里表态(`settings.permissions.allow`);`run-local` 的 spec 是本服务自己铸的,没有请求体 ——
|
|
891
|
+
运维接的服务器在那里没人能表态:无席 ⇒ 拒、有 durable 审批块 ⇒ 每次停驻等人。本键就是运维为自己接的服务器表态的地方。
|
|
892
|
+
- **allow 规则写在哪,按腿分**:请求腿(`POST /v1/tasks` / `/v1/runs`)= 请求体 `settings.permissions.allow`;`run-local` = 本键。
|
|
893
|
+
本键在请求腿上**同样生效**(一条规则,HTTP 提交(`POST /v1/tasks` / `/v1/runs`)、durable 续跑(每一次从持久化的提交体重建,含 leader worker 停驻后经 `/decide` 续跑的那一段)、
|
|
894
|
+
停驻后台 agent 的跨副本赎回、`run-local` 四条腿同装)。**到不了**:leader worker 的首跑与修复腿(它们的工具策略在 leader 编排里自己折出来,不经部署治理的构造口);
|
|
895
|
+
这两条腿今天不挂 MCP / A2A,所以本键在那里没有对象。
|
|
896
|
+
- **值形**:精确名(`mcp__figma__get_file`)、`mcp__<server>__*` 或两段形 `mcp__<server>`(整台服务器,含它将来新增的工具;两段形 7.116.0 起受理)、`a2a__<peer>__*` / `a2a__<peer>`(整个 peer);
|
|
897
|
+
与请求体的 allow 桶**同一只**判据。坏值 ⇒ **启动拒**(错误句点名 `APPROVAL_GRANT`、哪一条、怎么改):退役名(`Task` ⇒ `Agent`)、
|
|
898
|
+
无协议前缀的短名(`figma__x`)、缺段形(`mcp__` / `mcp__figma__`,够不着任何工具)、反斜杠、超 512 字符、内容形 / 参数级
|
|
899
|
+
(`Bash(npm:*)`、`Read(./x)` —— allow 规则只收工具名形,内容形的常设放行在持久规则店:`/v1/rules/cc-import` 导入,或在卡上答 yes 时留规则)。
|
|
900
|
+
- **不越过任何一层的 deny / ask**:`APPROVAL_DENY` 拒、`APPROVAL_REQUIRE` 问、请求 settings 的 deny / ask、会话规则(`toolDeny` /
|
|
901
|
+
白名单 `toolAllow`)照旧压过它;plan 模式下服务器工具是 plan 自己的写问,本键不放它。引擎自己的安全地板(不可逆探针、写保护表、
|
|
902
|
+
读边界)照旧。无人值守腿的按类作答席不因本键多答任何一类 —— 本键只让运维**点名过的**调用不再出卡。
|
|
903
|
+
- **不是白名单**:它只给出表态,不收窄任何东西(「只许这些工具」是会话规则 `PUT /v1/sessions/:id/policy` 的 `toolAllow`)。
|
|
904
|
+
- **射程如实**:规则对**每一个租户、每一条腿**生效;`mcp__<server>__*` 也覆盖那台服务器将来新增的工具。按需写窄;要收回某一只,写
|
|
905
|
+
`APPROVAL_DENY` / `APPROVAL_REQUIRE`(压过本键),或删掉规则重启。它给的只是「没人表态」那一句答,**不放掉任何一层自己的问**:内置工具的
|
|
906
|
+
精确名(例 `Write` / `Bash`)写进来,`default` 模式下引擎自己的写门 / 形状层照问(问压过放行)—— 对内置工具它几乎不改变任何事。
|
|
907
|
+
- **A2A 如实**:运维声明的对端(配置中心 / `config.d`,刻意不收 `toolAxes`)上,每次技能调用都是引擎自己的外发标记问(`tool_marks_a2a`),不是「没人表态」那一问 —— `a2a__<peer>__*` 不放它,无人值守腿上 A2A 技能调用照旧被拒 / 停驻 / 问人;只有请求体自带的对端(单用户闸)能在 `toolAxes` 里把某个技能的 `egress` 降为 `false`,那之后才是「没人表态」那一问,这时 allow 规则才答得上。
|
|
908
|
+
- **委派子代**:子代理看不到父任务挂的 MCP 服务器工具(引擎的子代工具池只认宿主自己交的工具实例),所以本键在子代上没有对象。
|
|
909
|
+
- **看得见**:起服日志一行 `approval_grant_in_force`(条数 + 规则名);`GET /v1/diagnostics/wiring`(运维面)`serverGates.approvalGrant`
|
|
910
|
+
= 规则名原样(空表 = 未设);`GET /v1/config/catalog` 一行。客户端能力面(`/v1/capabilities`)不报它。
|
|
911
|
+
- **启动告警 `tool_policy_only_sensitive_baseline`**(既有事件,名字不改):没有审批席(`DURABLE_APPROVAL` 关)且不是单用户的部署上,若部署唯一的策略是「不是门」的那几层 —— 敏感路径守卫集(`SENSITIVE_WRITE_PATTERNS`),或 7.115.0 起只有本键 —— 起服时发一次:它们让 `spec.toolPolicy` 在场、引擎自己的 UNGATED 告警因此不再出现,而它们自己又不判写。`detail` 点名是哪一片,`guardedPatterns` / `grantRules` 两个计数。
|
|
912
|
+
- v1 只有 env 一个写入通道(配置中心与 settings 契约没有这个键)。
|
|
913
|
+
|
|
882
914
|
**可选 — 写保护名表(S-138;缺席=引擎缺省表在岗)**
|
|
883
915
|
|
|
884
916
|
```bash
|
|
@@ -1367,7 +1399,7 @@ bake-runner 要用 ⇒ `LSP_ENV_ALLOW` / `BAKE_ENV_ALLOW` 点名放回。
|
|
|
1367
1399
|
| `repo` / `council` / `debate` | — | `repo` 为 `code-review`/`scan` 必填;`council`/`debate` 仅 `code-review`,见 §5 |
|
|
1368
1400
|
| `systemPrompt` / `appendSystemPrompt` | — | 调用方自带的系统提示 / 追加段(各 ≤16384 字符,超限 400 `request.field_invalid`;`appendSystemPrompt` 必须非空串)—— 任务自带时优先于角色 / 全局缺省(见 §模型角色) |
|
|
1369
1401
|
| `model` | — | 本次用哪个模型:只能点服务端**已配置目录**里的名字 / 档位词 / 模型 id(目录见 `GET /v1/models`;请求体带不进新模型)。未知 ⇒ 400 `request.unknown_reference`(带 `available` 列表);目录里有、但本部署服务不了 ⇒ 400 `request.model_unavailable`;空串 / 非字符串 ⇒ 400 `request.field_invalid` |
|
|
1370
|
-
| ~~tools~~ | 🚫 | **不是受理键**(传了 ⇒ 400 `request.body_shape`,`unknownKeys` 点名)——工具面走场景装配;按请求只能**减**:`excludeTools` / `settings.permissions` |
|
|
1402
|
+
| ~~tools~~ | 🚫 | **不是受理键**(传了 ⇒ 400 `request.body_shape`,`unknownKeys` 点名)——工具面走场景装配;按请求只能**减**:`excludeTools` / `settings.permissions` 的 deny · ask(`allow` 7.115.0 起是 allow 规则:给出「有人表态」,回答没人表态的服务器工具 / A2A 调用;不加工具、不放掉任何一层自己的问) |
|
|
1371
1403
|
|
|
1372
1404
|
**`TaskResult`(同步 / `done` 事件里拿到的;7.64.0 起终局是**一条** `terminal` 因由,不再有 `status`/`errorCode`/`errorMessage`/`blockedReason` 四个平面键):**
|
|
1373
1405
|
```json
|
|
@@ -1385,6 +1417,7 @@ bake-runner 要用 ⇒ `LSP_ENV_ALLOW` / `BAKE_ENV_ALLOW` 点名放回。
|
|
|
1385
1417
|
| `terminal.kind` | `completed` / `blocked` / `failed` / `paused`(闭集;`timeout` 已于 core 5.8.0/server 6.0.0 退役——见 §9) |
|
|
1386
1418
|
| `terminal.code` | `failed` 臂的程序化分支:如 `"conflict"`(乐观锁丢失,可重试) |
|
|
1387
1419
|
| `terminal.reason` | `blocked` 臂:为什么做不了(缺信息/权限) |
|
|
1420
|
+
| `stats.toolCalls` | 工具调用的**尝试**次数,不是「真执行了几次」:模型每发出一次工具调用请求就计一次,计在工具查找与入参校验**之前** —— 请求了没挂载的工具(例:执行车道未点名时的 `Bash`)照样计 `1`;同一条 `Bash` 请求在真执行车道(文件落盘)与未点名车道(没挂、文件不存在)两臂同读 `1`。所以**不能**拿它判「任务真跑了工具」:判「真跑了没有」看 `tool_end.isError`(逐调用,`false` = 这次调用执行成功)与 `wiring_manifest.hands`(逐腿「有没有手」),不看这个数。它是**本腿**计数(续跑腿只计本腿)。 |
|
|
1388
1421
|
|
|
1389
1422
|
> ⚠️ **任务成败以 `terminal.kind`/`terminal.code` 为准,勿以 HTTP 状态码判**:同步腿 200=提交受理成功(任务可能
|
|
1390
1423
|
> `terminal.kind:"failed"`+`code`);`POST /v1/runs` 202=已受理(执行期结局落在终态 run 记录/`done` 帧)。执行期
|
|
@@ -1906,6 +1939,9 @@ USAGE_WINDOWS='[{"windowMs":18000000,"maxTokens":5000000,"maxCostUsd":10,"anchor
|
|
|
1906
1939
|
⚠️ 一处**如实登记的差异**:`POST /v1/runs` 的幂等重放预读在窗门之前,leader 的幂等裁决在门之后 ⇒ 窗满期间
|
|
1907
1940
|
用**同一个** `Idempotency-Key` 重投拿到的是 429 而不是原来那张 202 收据。这不丢 run:429 **不消费键**,窗一
|
|
1908
1941
|
放行,同键重投照旧回原 `leaderRunId` 且不会起第二条后台腿(第二条 = 第二次真 `git push`)。
|
|
1942
|
+
- **账本读不出(`DB_BACKEND=local`)**:账本文件坏了 ⇒ 那把键的计费与回查**拒**(`usage_window.store_corrupt`,码不变,任务失败而不是把用量当零),
|
|
1943
|
+
拒绝句只说是哪把键、怎么修(修好或删掉那只文件 —— 删 = 那把键没有用量记录),**不带文件位置**;位置在运维日志 `file_store_corrupt_read` 的
|
|
1944
|
+
`path` 里(7.116.0 起 —— 此前本服务另建的那只账本店不接这个披露座,坏值只拒不说在哪)。
|
|
1909
1945
|
- **$ 窗(core 7.0.0 起)**:`maxCostUsd` 要求 run **可计价**——模型既无 pricing 条目也无
|
|
1910
1946
|
`Model.cost` 声明时,cost 不是 0 而是**不存在**,$ 窗对它不可求值 ⇒ 任务门口拒
|
|
1911
1947
|
(`config.usage_window_unpriced`),绝不记 0 让天花板静默失效。MIXED 声明(部署里同时有 $ 窗与纯
|
|
@@ -12,7 +12,19 @@
|
|
|
12
12
|
# MODEL_GATEWAY_BASEURL MODEL_ID MODEL_API_KEY
|
|
13
13
|
# ALLOW_SMALL_CLUSTER=true 放行 <3 机(dev/CI 单节点验流程;生产必须 >=3 奇数)
|
|
14
14
|
set -euo pipefail
|
|
15
|
-
|
|
15
|
+
# >>> 自身目录(五个入口逐字同一段)
|
|
16
|
+
# HERE = 本脚本**真实文件**所在目录。经 npm bin 软链(node_modules/.bin/sema-up)调用时 $0 是软链路径,
|
|
17
|
+
# 按它的目录找 lib/ 会落进 .bin/ ⇒ 逐跳解软链。只用不带参数的 readlink(macOS 自带 bash 3.2 / BSD readlink 没有 -f)。
|
|
18
|
+
# 库要在知道 HERE 之后才找得到,所以这段不能收进库里:五个入口各持同一段,逐字一致由测试判。
|
|
19
|
+
_self="$0"; _hops=0
|
|
20
|
+
while [ -L "$_self" ]; do
|
|
21
|
+
_hops=$((_hops + 1)); [ "$_hops" -le 40 ] || { echo "软链层数过多(成环?):$0" >&2; exit 1; }
|
|
22
|
+
_dir="$(cd "$(dirname "$_self")" && pwd)"; _self="$(readlink "$_self")"
|
|
23
|
+
case "$_self" in /*) ;; *) _self="$_dir/$_self" ;; esac
|
|
24
|
+
done
|
|
25
|
+
HERE="$(cd "$(dirname "$_self")" && pwd)"
|
|
26
|
+
unset _self _hops _dir
|
|
27
|
+
# <<< 自身目录
|
|
16
28
|
# `.env` 的文法与全部读写原语只在 lib/envf.sh 定义(S-618 续):本脚本不再有自己的 setk / `. "$ENVF"`。
|
|
17
29
|
. "$HERE/lib/envf.sh"
|
|
18
30
|
# 「壳怎么接这台引擎」的渲染(S-850;sema-up.sh / kube-up.sh 同一只)。
|
|
@@ -13,7 +13,19 @@
|
|
|
13
13
|
# MODEL_GATEWAY_BASEURL MODEL_ID MODEL_API_KEY
|
|
14
14
|
# [NAMESPACE=sema][STORAGE_CLASS=集群默认][CNPG_VERSION]
|
|
15
15
|
set -euo pipefail
|
|
16
|
-
|
|
16
|
+
# >>> 自身目录(五个入口逐字同一段)
|
|
17
|
+
# HERE = 本脚本**真实文件**所在目录。经 npm bin 软链(node_modules/.bin/sema-up)调用时 $0 是软链路径,
|
|
18
|
+
# 按它的目录找 lib/ 会落进 .bin/ ⇒ 逐跳解软链。只用不带参数的 readlink(macOS 自带 bash 3.2 / BSD readlink 没有 -f)。
|
|
19
|
+
# 库要在知道 HERE 之后才找得到,所以这段不能收进库里:五个入口各持同一段,逐字一致由测试判。
|
|
20
|
+
_self="$0"; _hops=0
|
|
21
|
+
while [ -L "$_self" ]; do
|
|
22
|
+
_hops=$((_hops + 1)); [ "$_hops" -le 40 ] || { echo "软链层数过多(成环?):$0" >&2; exit 1; }
|
|
23
|
+
_dir="$(cd "$(dirname "$_self")" && pwd)"; _self="$(readlink "$_self")"
|
|
24
|
+
case "$_self" in /*) ;; *) _self="$_dir/$_self" ;; esac
|
|
25
|
+
done
|
|
26
|
+
HERE="$(cd "$(dirname "$_self")" && pwd)"
|
|
27
|
+
unset _self _hops _dir
|
|
28
|
+
# <<< 自身目录
|
|
17
29
|
# `.env` 的文法与全部读写原语(envf_get / envf_has / envf_load / envf_put / setk / setk_new / resetk)只在这一处
|
|
18
30
|
# 定义,sema-up.sh / cluster-up.sh / smoke.sh 同源(S-618 续):本脚本不再有自己的 setk / has_env / `. "$ENVF"`。
|
|
19
31
|
. "$HERE/lib/envf.sh"
|
|
@@ -4,7 +4,19 @@
|
|
|
4
4
|
# (sema cloud deploy 渲染用,同一交互协议的 infeasible:{reason,suggestion} 字段)。
|
|
5
5
|
# 只读探测,零改动,幂等。退出码:0=可部署(可能有 WARN),1=存在 BLOCK 项。
|
|
6
6
|
set -u
|
|
7
|
-
|
|
7
|
+
# >>> 自身目录(五个入口逐字同一段)
|
|
8
|
+
# HERE = 本脚本**真实文件**所在目录。经 npm bin 软链(node_modules/.bin/sema-up)调用时 $0 是软链路径,
|
|
9
|
+
# 按它的目录找 lib/ 会落进 .bin/ ⇒ 逐跳解软链。只用不带参数的 readlink(macOS 自带 bash 3.2 / BSD readlink 没有 -f)。
|
|
10
|
+
# 库要在知道 HERE 之后才找得到,所以这段不能收进库里:五个入口各持同一段,逐字一致由测试判。
|
|
11
|
+
_self="$0"; _hops=0
|
|
12
|
+
while [ -L "$_self" ]; do
|
|
13
|
+
_hops=$((_hops + 1)); [ "$_hops" -le 40 ] || { echo "软链层数过多(成环?):$0" >&2; exit 1; }
|
|
14
|
+
_dir="$(cd "$(dirname "$_self")" && pwd)"; _self="$(readlink "$_self")"
|
|
15
|
+
case "$_self" in /*) ;; *) _self="$_dir/$_self" ;; esac
|
|
16
|
+
done
|
|
17
|
+
HERE="$(cd "$(dirname "$_self")" && pwd)"
|
|
18
|
+
unset _self _hops _dir
|
|
19
|
+
# <<< 自身目录
|
|
8
20
|
# 自动数据根的路径形只在 lib/dataroot.sh 定义一次(S-851):下面「多盘机」建议句与 sema-up 自动选的根同一条规则。
|
|
9
21
|
. "$HERE/lib/dataroot.sh"
|
|
10
22
|
# 取值旗的形(S-621):判据与词表同 sema-up.sh 一处定义。
|
|
@@ -14,7 +14,19 @@
|
|
|
14
14
|
# 本机装 k3s(后两态=kube-up.sh,helm chart 驱动)
|
|
15
15
|
set -euo pipefail
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
# >>> 自身目录(五个入口逐字同一段)
|
|
18
|
+
# HERE = 本脚本**真实文件**所在目录。经 npm bin 软链(node_modules/.bin/sema-up)调用时 $0 是软链路径,
|
|
19
|
+
# 按它的目录找 lib/ 会落进 .bin/ ⇒ 逐跳解软链。只用不带参数的 readlink(macOS 自带 bash 3.2 / BSD readlink 没有 -f)。
|
|
20
|
+
# 库要在知道 HERE 之后才找得到,所以这段不能收进库里:五个入口各持同一段,逐字一致由测试判。
|
|
21
|
+
_self="$0"; _hops=0
|
|
22
|
+
while [ -L "$_self" ]; do
|
|
23
|
+
_hops=$((_hops + 1)); [ "$_hops" -le 40 ] || { echo "软链层数过多(成环?):$0" >&2; exit 1; }
|
|
24
|
+
_dir="$(cd "$(dirname "$_self")" && pwd)"; _self="$(readlink "$_self")"
|
|
25
|
+
case "$_self" in /*) ;; *) _self="$_dir/$_self" ;; esac
|
|
26
|
+
done
|
|
27
|
+
HERE="$(cd "$(dirname "$_self")" && pwd)"
|
|
28
|
+
unset _self _hops _dir
|
|
29
|
+
# <<< 自身目录
|
|
18
30
|
# `.env` 文法(写口 envf_representable + envf_encode / 读口 envf_canonical_line)的唯一定义 —— 写读两半从这一处取判据。
|
|
19
31
|
. "$HERE/lib/envf.sh"
|
|
20
32
|
# 数据根归属(S-851)与「壳怎么接」的渲染(S-850)各一处定义;preflight / kube-up / cluster-up 读同一份。
|
package/deploy/sema-up/smoke.sh
CHANGED
|
@@ -5,7 +5,19 @@
|
|
|
5
5
|
# 远程 URL 模式: smoke.sh --url=http://host:8090 --token=T (引擎面:health/auth/真任务)
|
|
6
6
|
# 每项 OK/FAIL 一行;FAIL 带原因+建议(§3d-2 报错规范);exit 0=全绿。
|
|
7
7
|
set -u
|
|
8
|
-
|
|
8
|
+
# >>> 自身目录(五个入口逐字同一段)
|
|
9
|
+
# HERE = 本脚本**真实文件**所在目录。经 npm bin 软链(node_modules/.bin/sema-up)调用时 $0 是软链路径,
|
|
10
|
+
# 按它的目录找 lib/ 会落进 .bin/ ⇒ 逐跳解软链。只用不带参数的 readlink(macOS 自带 bash 3.2 / BSD readlink 没有 -f)。
|
|
11
|
+
# 库要在知道 HERE 之后才找得到,所以这段不能收进库里:五个入口各持同一段,逐字一致由测试判。
|
|
12
|
+
_self="$0"; _hops=0
|
|
13
|
+
while [ -L "$_self" ]; do
|
|
14
|
+
_hops=$((_hops + 1)); [ "$_hops" -le 40 ] || { echo "软链层数过多(成环?):$0" >&2; exit 1; }
|
|
15
|
+
_dir="$(cd "$(dirname "$_self")" && pwd)"; _self="$(readlink "$_self")"
|
|
16
|
+
case "$_self" in /*) ;; *) _self="$_dir/$_self" ;; esac
|
|
17
|
+
done
|
|
18
|
+
HERE="$(cd "$(dirname "$_self")" && pwd)"
|
|
19
|
+
unset _self _hops _dir
|
|
20
|
+
# <<< 自身目录
|
|
9
21
|
# `.env` 的文法与读原语只在 lib/envf.sh 定义(S-618 续):本脚本读 `.env` 只经 envf_load,不 source。
|
|
10
22
|
. "$HERE/lib/envf.sh"
|
|
11
23
|
# 取值旗的形(S-621):判据同 sema-up.sh 一处定义。
|
package/dist/adoption/wire.d.ts
CHANGED
|
@@ -25,7 +25,6 @@ export declare const AdoptionSourceSchema: z.ZodObject<{
|
|
|
25
25
|
kind: z.ZodLiteral<"principal">;
|
|
26
26
|
principal: z.ZodString;
|
|
27
27
|
}, z.core.$strict>;
|
|
28
|
-
export type AdoptionSource = z.infer<typeof AdoptionSourceSchema>;
|
|
29
28
|
/** per-store 腿的动作词(183 §6 闭集;form b 只会产出前两个 + `none`)。 */
|
|
30
29
|
export declare const AdoptionLegActionSchema: z.ZodEnum<{
|
|
31
30
|
none: "none";
|
|
@@ -239,7 +238,6 @@ export declare const AdoptionRejectDetailSchema: z.ZodObject<{
|
|
|
239
238
|
overlapping: z.ZodNumber;
|
|
240
239
|
}, z.core.$strict>>;
|
|
241
240
|
}, z.core.$strict>;
|
|
242
|
-
export type AdoptionRejectDetail = z.infer<typeof AdoptionRejectDetailSchema>;
|
|
243
241
|
/**
|
|
244
242
|
* 拒绝码的**闭集**(与附录 A 的 `adoption.*` 族逐字同名)。住在 wire 契约里而不是实现里,因为落库的
|
|
245
243
|
* `adoption_log.reject_code` 与 wire 上的 `errorCode` 必须是**同一个词表** —— 两处各写一份字符串字面量,
|
|
@@ -252,5 +250,4 @@ export declare const AdoptionRequestSchema: z.ZodObject<{
|
|
|
252
250
|
fromPrincipal: z.ZodString;
|
|
253
251
|
toPrincipal: z.ZodString;
|
|
254
252
|
}, z.core.$strict>;
|
|
255
|
-
export type AdoptionRequest = z.infer<typeof AdoptionRequestSchema>;
|
|
256
253
|
//# sourceMappingURL=wire.d.ts.map
|