扩展

给 KIP 加东西的四种方式

风险不一样,判定就不该合并。

这四种扩展方式是四个完全不同的风险面,所以它们不共用一层权限判定。

方式是什么能做什么
技能 Skills渐进披露的说明文档只能提供说明,不能提供可调用的工具
MCP跨进程协议最小代价也是一个常驻子进程;只在 trusted 模式才可能生效
插件 Plugins同进程 ESM 模块在工作区放一个目录就能加工具——代价是它和宿主跑在同一份地址空间
钩子 Hooks宿主内注册的 JS 函数门禁钩子可拒绝、失败关闭;观察钩子异步、永不改变控制流

插件的五条硬规则

一、声明即全集

模块导出了清单里没声明的工具名 → 拒绝加载整个插件。「顺手多给一个工具」是隐式扩权。同样地,清单里写了 tools 能力却没有工具,也会被拒绝——声明与实现不一致,代价是权限面。

二、目录名必须等于插件 id

不一致直接拒绝。否则「谁贡献了这个工具」在审计上无法对齐。

三、同名必须显式让位

插件工具与内置工具重名时,清单里必须显式声明 reject 还是 yield。没有声明就拒绝加载,并如实告诉你和哪个内置工具同名。

没有任何一条路径会静默覆盖内置工具。 让位行为会记进账本,卸载插件后内置工具原样回到工具面。

四、卸载是全量替换

工具彻底消失——不是打禁用标记,也不是留着但拒绝执行。不残留任何未声明的插件工具。

五、开启必须给绝对路径

开了开关却没有目录 → 配置校验直接拒绝,不是静默回退。相对路径会随工作目录漂移,让「加载了哪段代码」变成一个不可审计的问题。

插件拿得到什么

插件工具不自己执行任何东西。它们被注册成执行器的一个选项,只能走既有的工具分支,顺序是:

taskPolicy → preToolGuards → 钩子门禁 → perms.checkPlugin() → 一次性审批 → 插件函数

插件函数只收到一个冻结的极小上下文:{plugin_id, tool, effect, sessionId, taskId, signal}。

诚实声明

插件不是权限沙箱。API 保证的是「插件工具的执行经过既有审批路径」,不是「插件代码被隔离」——它是宿主同进程的代码,拿到上下文之后仍然可以使用 Node 的 import 与 process。所以 safe 模式一律拒绝,且默认关闭。请只把你自己信任的代码放进插件目录。

为什么默认关闭

关闭时,程序不读插件目录(连一次 existsSync 都不做)、不加载任何模块、工具面逐位不变。开启后可以随时在设置里改回来,开关立即生效。

单个插件加载失败不会影响其它插件——一个写坏的不该拖垮全部。


这篇讲的是权限设计的一部分。回文章列表,或回首页看整体。