Skip to content

[REQ-128][CODE] plugin 事务与生命周期:kind 分流收口 + wrapper 模板 + buildPluginTxItems + 卸载臂 #809

Description

@jinjunnn

大白话

宿主端真正把一个 managed plugin 装进去、记上账、卸得掉。三件事:

  1. kind 分流收口 —— 今天 admission 有两处兜底式 ternary(else → 'mcp'),
    一个新 profile 若只在合同侧登记,会被静默当成 MCP 装进去,而且 TypeScript 不会红(两处 as 断言)。
  2. wrapper 模板 —— 顶层不 import 上游,import("./upstream.js") 放进 server() 内。
    这样引擎里那个第二个加载器(ConfigExternalPlugin,ABI 不同、会自己调 npm.add、失败静默吞)
    只求值到一个无副作用空壳后解码拒绝,V1 调 server() 时才载入第三方。
    这替掉了原方案里「全局剥 plugin 键」整张票 —— 全局剥会关掉用户所有合法 V2 插件。
  3. 卸载臂 —— 今天未知 kind 是 fail-closed 拒绝,即「装得上、卸不掉」。

方案基线

Phase 4 基线 §4 D1/D3/D4 · §5 第 3/6/7/8 类 · §6 T2b

四条最容易做错的(基线里已写死判据)

  • 第 7 类要 A+B 两条都测:五个 profile 的 exact mapping(期望键集从 PROFILE_REGISTRY_V1 派生)
    加上未登记第六 profile 的具名拒绝。只测后者的话,一个把 opencode-plugin 错映成 skill 的表完全满足断言
  • 第 8 类四条一起断(目录 / plugin[] / grants / 账本记录消失)。第四条走生产卸载后重读账本,
    禁止断言中间值 graphAfter === null(那是自己拼等价链,假闸形态⑧)。
  • file item key 必须是 plugin--<name>--f<i> —— 否则 ext-health-probe-router.ts:40-41 会 fail-closed 拒掉整次安装。
  • server() 返回值验证归本票:对固定 canary 断言返回键恰为两项两个值都是 function
    只断「键存在」的话 {event:1,"permission.ask":1} 就能过,而真实引擎在 plugin/index.ts:255/:288-290 直接调用这两个值

依赖:T1。out of scope(含「不复用不改 installPluginFromCas」)与完整退出条件见基线 §6 T2b 行。

Refs #699

Metadata

Metadata

Assignees

Labels

area:contractsContracts, schemas, or compatibilityarea:runtimeServices, jobs, infrastructure, or operationsarea:securitySecurity or access controlprio:P1High-value near-term deliverytype:featureNew user or system capability

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions