feat(core): define mesh capability boundary - #11211
Conversation
985b0d8
into
codex/multi-agent-mesh-foundation
|
Thanks for the PR! Template looks good ✓ — all nine sections present and filled in. One trivial variance: the heading reads Worth saying up front, because it shapes everything below: this PR merged into Problem: this is step 2 of a committed implementation plan ( Direction: the shape is right, but this is a trust boundary for autonomous agents, which is precisely the surface to escalate rather than auto-approve. The PR itself flags two items as "pending owner confirmation rather than being treated as settled product behavior": MCP names failing closed, and Size: core paths touched ( Approach: the scope is genuinely minimal — one classification table, three pure functions, and doc edits that carefully record what this step does not prove. No drive-by refactors, no unrelated churn. My one substantive question is duplication: Risk: no Stage 1e high-risk path match. Moving on to code review. 🔍 中文说明感谢贡献! 模板完整 ✓ —— 九个章节齐全且都有实质内容。一个很小的差异:标题写的是 先说明一个影响下面所有判断的事实:本 PR 于 问题: 这是已提交实施计划( 方向: 形态是对的,但这是自主 agent 的信任边界,恰恰是应该上报而不是自动批准的那类改动。PR 自己也把两项标为「等待 owner 确认,未作为已确定产品行为」:MCP 名字 fail closed,以及 规模: 触及核心路径( 方案: 范围确实很小——一张分类表、三个纯函数,以及谨慎记录了本步骤不证明什么的文档改动。没有顺手重构,没有无关改动。我唯一实质性的疑问是重复: 风险: 未命中 Stage 1e 高风险路径。 进入代码审查 🔍 — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
Code reviewBefore reading the diff I wrote down what I'd do for "give mesh agents a read-only tool ceiling that definitions can narrow but not widen": a single name→verdict table as committed data, a compile-time exhaustiveness guard so a new The good parts are worth naming, because they're the reason this isn't a bigger concern:
Three things I'd want a human to look at, none of them blocking on a staging branch: 1. 2. There are now three parallel notions of "read-only tool", and they disagree. 3. The ceiling is currently asserted, not enforced. Nothing imports Two smaller notes: TestingStating plainly what evidence this section carries: the PR's own CI, read through the API. I did not build or run any PR code — triage is static, and executed code could read the write PAT in this environment. On this PR's head commit there are 73 check-runs and not one of them is a test, lint, typecheck or build job. Every entry is bot orchestration. So there is zero automated test evidence attached to this PR — which the diff itself documents as intended for stacked child PRs. The load-bearing signal is the deferred gate, #11206, whose head
Read that second table carefully: the three checks that would actually exercise this code — unit tests, lint/typecheck, integration — were still running at review time, and macOS and Windows unit runs are skipped. Nothing has failed. Nothing load-bearing has passed either. The step's own acceptance doc says "The step is not complete until #11206 CI passes after the child PR merges", and that condition is not yet met. Not verified, and why:
Sandboxed verification would settle this, but not yet: 中文说明代码审查在读 diff 之前,我先写下了自己对「给 mesh agent 一个只能收窄、不能放宽的只读工具上限」的做法:一张以提交数据形式存在的「名字→判定」表、一个编译期穷尽性约束(让新增的 值得点名的优点,也是这件事没有变成更大隐患的原因:
有三点希望有人看一眼,在 staging 分支上都不构成阻塞: 1. 2. 现在有三套并行的「只读工具」定义,而且彼此不一致。 3. 目前这个上限是被声明的,而不是被执行的。 没有任何文件 import 另外两点小注: 测试明确说明本节携带的证据:本 PR 自己的 CI,通过 API 读取。我没有构建或运行任何 PR 代码——triage 是静态的,而执行代码可能读到本环境中的 write PAT。 在本 PR 的 head 提交上有 73 个 check-run,其中没有一个是测试、lint、typecheck 或构建 job。全部是 bot 编排类。所以本 PR 上没有任何自动化测试证据——diff 自己把这一点记录为 stacked 子 PR 的预期行为。 真正承重的信号是被推迟的门禁 #11206,它的 head 请看上面第二张表:真正会执行到这段代码的三个检查——单测、lint/typecheck、集成测试——在审查时仍在运行,而 macOS 和 Windows 的单测被跳过。没有失败项,但也没有任何承重项通过。本步骤的验收文档自己写着「The step is not complete until #11206 CI passes after the child PR merges」,这个条件目前尚未满足。 未验证项及原因:
沙箱验证可以定论,但还不是现在:在第 4/5 步把谓词接线之后,对 #11206 跑 — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
|
Confidence: 3/5 — the code is clean and the exhaustiveness guard is genuinely well done, but the ceiling this PR declares isn't enforced by anything yet, and two of its policy choices are explicitly waiting on a product owner. Stepping back. My independent proposal and this PR agree on almost everything: table-as-data, compile-time exhaustiveness, intersection from the ceiling down, reuse of the existing AST classifier. Where I'd have gone differently is the shell predicate. I'd have reused Would I curse or thank the author maintaining this in six months? Mostly thank them. The So the verdict is defer, and I want to be precise about why, because none of it is a defect I'd ask to have fixed:
I tried to resolve an owner to hand this to and could not:
Nothing here should hold up the next numbered step. It should hold up #11206's merge to 中文说明Confidence: 3/5 —— 代码是干净的,穷尽性约束做得确实好,但本 PR 声明的这个上限目前还没有任何东西去执行,而其中两项策略选择明确在等产品 owner 拍板。 退一步看整体。我的独立提案和本 PR 在几乎所有点上都一致:表即数据、编译期穷尽性、从上限向下取交集、复用现有 AST 分类器。我会做得不同的地方是 shell 谓词。我会复用 六个月后维护它,我会骂作者还是谢作者?大部分是谢。 所以结论是暂缓(defer),我想把原因说准确,因为其中没有一条是我会要求修的缺陷:
我尝试解析出一个 owner 来接手,但没能成功:
这些都不应该拖住下一个编号步骤。它们应该拖住 #11206 合入 — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
What this PR does
This is mesh implementation step 2. It adds one fail-closed classification table covering every built-in core tool and the six planned thread tools, derives the effective tool configuration by intersecting the built-in ceiling with the agent definition, and reuses the existing shell AST classifier to reject anything not classified as read-only.
The design and acceptance documents are updated in the same commit to record the stacked child-PR workflow and the exact boundary this step proves.
Why it is needed
Mesh agents share one long-lived body across threads, so v1 needs a hard read-only ceiling that agent definitions can narrow but never widen. Unknown names, including MCP tools, default to deny. Thread tools are always supplied by the mesh runtime rather than inherited from a persona definition.
This child PR depends on the runtime preparation already carried by the foundation branch from #11200, #11204, and #11202. It does not copy or modify those runtime hot paths.
Reviewer Test Plan
How to verify
Run
cd packages/core && npx vitest run src/agents/mesh/capability.test.ts. Expect all 10 tests to pass. Confirm that everyToolNamesvalue appears exactly once in the classification table, an unlisted or MCP name is denied, a narrowed agent definition cannot re-enable a denied tool, all thread tools remain present, read-only shell commands are allowed, and write or unknown commands are refused with their classifier reason.Evidence (Before & After)
N/A — internal capability policy and tests only.
Tested on
Environment (optional)
Named Vitest file in a build-less worktree using the documented local test harness.
Risk & Scope
web_fetch/web_searchare classified as denied. Both policy choices remain pending owner confirmation rather than being treated as settled product behavior.Linked Issues
Parent delivery PR: #11206.
中文说明
本 PR 做什么
这是 mesh 实现的第 2 步。它新增一张 fail-closed 分类表,覆盖 core 的全部内置工具和计划中的六个 thread 工具;通过内置上限与 agent definition 取交集生成有效工具配置;并复用现有 shell AST 分类器,拒绝所有未判定为只读的命令。
同一个提交也更新了设计与验收文档,记录 stacked 子 PR 工作流,以及本步骤实际证明的边界。
为什么需要
Mesh agent 会跨线程复用一个长期执行体,因此 v1 需要一个 agent definition 只能收窄、不能放宽的只读硬上限。所有未知名字(包括 MCP 工具)默认拒绝。Thread 工具由 mesh runtime 固定提供,不从 persona definition 继承。
这个子 PR 依赖 foundation 分支已经承载的 #11200、#11204 和 #11202 runtime 前置改动,不复制也不修改这些 runtime 热路径。
Reviewer Test Plan
如何验证
运行
cd packages/core && npx vitest run src/agents/mesh/capability.test.ts,预期 10 个测试全部通过。确认每个ToolNames值都在分类表中恰好出现一次;未列出名字和 MCP 名字会被拒绝;收窄后的 agent definition 无法重新启用被拒绝工具;全部 thread 工具仍存在;只读 shell 命令允许,写命令与未知命令会带分类原因被拒绝。Evidence (Before & After)
N/A——仅内部能力策略和测试。
Tested on
Environment
在 build-less worktree 中使用文档规定的本地测试 harness,仅运行指定 Vitest 文件。
Risk & Scope
web_fetch/web_search当前归类为 deny。这两项都等待 owner 确认,未作为已确定产品行为。Linked Issues
父交付 PR:#11206。