[#731][DECIDE] 全来源工具 inventory 与稳定 identity 方案基线 - #740
Open
jinjunnn wants to merge 1 commit into
Open
Conversation
在 alpha@7799a5e6 上实读勘破,落一份 commit-pinned 的 identity 方案基线 (status: draft,待 owner 批准),供 #722(展示)与 #724(策略)共同消费。 勘破对票面事实的三处修正: - 注册来源实为 6 个(插件是两个机制不同的来源;三个 MCP-resource 伪工具是 引擎自造的第四类),不是 4 个; - 执行咽喉实测 7 处,票面列了 5 处 —— 漏掉 session/prompt.ts 的 subtask 直呼 (E6,写真实 ToolPart)与附件摄取直呼 read(E7,ask 被短路为 no-op); - Wildcard 的文法会吃掉工具名里的 * ? \ /,而"总是允许"存下来的 permission 字段就落在 pattern 轴 —— canonical 编码必须转义这六个字符,否则等于把远端 可控的通配符送进权限模式轴。 决定:identity = 结构化三元组(source/origin/name),只在元组仍完整的铸造点 产生;canonical 用固定三段 + 六字符百分号转义,单射可逆;别名↔身份的双射由 装载期账本校验保证(#726 升格为不变量),任何地方不得从别名反推来源。 权限引擎/wildcard/合并优先级/目录过滤钩子一律不新建,只改"键是什么"。 内置能力串保留为独立一轴,与身份轴取"与"关系,理由与已知限制在 §5 逐条列明。 表面边界经 scripts/alpha-check.sh 四探针实测(非推断):机制部分可落 L0 新增 文件;接线部分(6 个铸造点 + 7 处咽喉 + ToolPart schema)必须走一条 L3 收编 ADR,该 ADR 是实现票的硬前置。 Refs #722 Refs #724 Refs #726 Fixes #731 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #731
Refs #722 · Refs #724 · Refs #726
DECIDE 票的产出:一份 commit-pinned 的方案基线,
status: draft,待 owner 批准。零生产代码改动。落点
docs/design/2026-07-31-tool-identity-baseline.md,并加进docs/design/README.md的家族索引。这份文件在解决什么(大白话)
今天一个工具在系统内部没有名字,只有"模型看到的那个字符串"。内置工具、MCP 工具、
插件工具共用同一个字符串空间,而 MCP 那条的拼接(
sanitize(server) + "_" + sanitize(name))不可逆 —— 拿到cloud_web_search无法确定它是cloud的web_search还是cloud_web的search。后果:工具卡不知道自己在展示谁;权限规则可能打到另一个工具身上;"总是允许"存下来的那条规则会被当成通配模式使用。
本文给出:由来源事实派生、可逆反解、跨全部执行路径一致的 identity,让 REQ-125 展示票
(#722)与 REQ-131 策略票(#724)消费同一份定义,而不是各自再定义一次。
勘破对票面事实的三处修正(都带 file:line,实读 alpha@7799a5e6)
(目录扫描
tool/registry.ts:178-192有命名空间;Plugin 钩子:194-199导出名原样、零命名空间),另有三个 MCP-resource 伪工具与 V2 registry。
session/prompt.ts,都不经
SessionTools.resolve:prompt.ts:255-345— subtask 直呼task工具,走registry.named()绕过
registry.tools()的可见性过滤,并写出一条用户可见的ToolPart;prompt.ts:808-828— 附件摄取直呼read,ask: () => Effect.void把权限整个短路,且
bypassCwdCheck: true。另有第 8 个把别名当权限键的地方:
session/llm.ts:150-153的 workflow 预批名单。用「
plugin.trigger("tool.execute.before")符号轴」+「直接execute(调用轴」两条互相独立的检索交叉枚举才查全,单跑一条正则会漏。
Wildcard的文法会吃掉工具名里的字符(core/util/wildcard.ts:3-14):pattern 侧*→.*、?→.、\→/,Windows 上还是大小写不敏感("si")。而"总是允许"存下来的
permission字段(permission/index.ts:228-232)就落在 pattern 轴。⇒ canonical 编码必须转义
%:*?\/这六个字符,否则等于把一个远端服务器可控的通配符送进权限模式轴。
决定
{source, origin, name},只在元组仍完整的铸造点产生(
mcp/index.ts:674-685等 6 处),此后只传递。:切成恰好 3 段,段数不对就拒绝,不猜。
任何地方不得从别名反推来源 —— 现有的
code-mode.ts:39-56反解由本方案删除。(
"mcp:github:*": "deny")由既有 wildcard 引擎免费得到,零新代码。有三个根本没有对应工具的审批点;能力轴对未来新增的写工具默认拒绝而身份轴默认放行;
edit|write|apply_patch的合并是刻意的产品语义),已知限制 L1–L3 逐条列明。表面边界:实测,不是推断
在本分支放四个探针跑
bash scripts/alpha-check.sh(worktree 已用scripts/worktree-link-deps.sh装真依赖,不是软链假红环境):packages/opencode/src/mcp/catalog.tspackages/plugin/src/tool.tsUPSTREAM_PATHS)packages/ext/src/register.tspackages/opencode/src/alpha-probe-new-file.ts(已git add)第四条是关键:守卫谓词是
--diff-filter=DMR(不含 A),alpha-check.sh:66-68的ADR-035 注释与 5 个既有先例证实这是既定设计。⇒ 机制部分(类型/编码/账本/校验/测试)
可落 L0 新增文件;接线部分(6 个铸造点 + 7 处咽喉 +
ToolPartschema)必须走一条L3 收编 ADR,并且已逐条给出「L0 插件钩子 / L0 新增文件 / L1 变换层 / HTTP 面」
四条低级别路径为何不可行的勘探证据(ADR-029 §3 要求)。该 ADR 是实现票的硬前置。
判据(identity 怎么被测试守住)
文档 §7 列了 10 条不变量,每条都写明反向判据:碰撞(I1)、编码单射可逆(I2)、
转义集覆盖 wildcard 文法(I3)、大小写(I4)、7 条咽喉解析到同一对象(I5)、
E7 边界显式(I6)、rename 不继承旧授权(I7)、动态增删(I8)、插件遮蔽内置不静默(I9)、
仓内不存在别名反解(I10)。I1–I4、I10 可落 L0 新增测试文件、无需 ADR。
跑过的门与结果
在 worktree
.worktrees/design-731(scripts/worktree-link-deps.sh已装真依赖):bash scripts/alpha-check.sh— 全绿(连跑两次结果一致):[1/3] north-star guard✓ zero upstream package edits[2/3] typecheck✓(contracts-consumer + ext + ui-mac)[3/3] contract lock + unit tests✓ —36 pass / 0 fail、132 pass / 0 fail、3315 pass / 0 fail(14668 expect)python3 scripts/check-doc-links.py <两个改动的 md>—✓ 3 relative link(s) resolve across 2 file(s)(docs-only PR 在 CI 里正是走这道门)check_docs_contract.py --profile alpha --strict— alpha-code 侧唯一 ERROR 是既有的docs/design/2026-07-21-req053-bootstrap-loop-hardening.md断链(P1),与本 PR 无关;另两条 ERROR 在 alpha-web,同样是 base fail-set。
与 base fail-set 的差:0。 本 PR 未引入任何新红。
为什么用了
--no-verify(必须记录)pre-push 钩子恒红在
check:vendor的跨仓 provenance 一步,与本 PR 无关,已定位到根因并复现:
git 钩子会在环境里设
GIT_DIR,而这次 spawn 没有清掉它 ⇒git -C /Users/tide/app/alpha-web实际解析到的是 alpha-code 的 git dir,那个 alpha-web commit 当然不存在。实测对照:
⇒ 同一个检查独立跑必绿、经钩子跑必红。上面列的三道门全部是我在钩子外亲自跑的真实
输出。这条缺陷超出本票边界,未顺手修,单独回报给主 session 决定是否开 Issue。
文档影响
docs/design/2026-07-31-tool-identity-baseline.md(kind: design,status: draft)docs/design/README.md家族表新增一行 +last_reviewed顺带更新其必须载明的接管面清单,由 owner 批准后另开票。
留给 owner 的三个开放点(文档 §10)