Skip to content

ADR-0049:两份 activationEvents 声明四仓零 reader —— declared-but-unenforced,且 studio 侧 z.string() 零校验 #4657

Description

@os-zhuang

从 #4653(双源清账 C5)的三仓 import 扫描里掉出来的范围外发现,不在 #4653 的 PR 里修,单独立案。

事实

packages/spec 有两份 ActivationEventSchema,分别嵌在两个父 schema 的 activationEvents: 上:

侧 声明 父 schema
kernel/plugin-runtime.zod.ts:74 z.object({ type: z.enum([...7 项]), pattern: z.string() }) DynamicLoadRequestSchema.activationEvents(.optional())
studio/plugin.zod.ts:285 z.string() StudioPluginManifestSchema.activationEvents(.default(['*']))

四仓(objectstack / cloud / cloud-v1 / objectui)全量扫描:没有任何运行时读取 activationEvents。 命中的只有 spec 自身的源码与测试、生成文档,以及三个 VS Code 扩展自己的 package.json(packages/vscode-objectstack、objectui/packages/vscode-extension、objectql/packages/tools/vscode-objectql)—— 那是 VS Code 的字段,与本平台无关。

外部佐证 —— cloud-v1/docs/ROADMAP.md:641 自己记着这条没实现:

| `plugin-runtime.zod.ts` -> `ActivationEventSchema` | Lazy activation triggers (onCommand, etc.) | ❌ | All plugins activated immediately on install | v0.4.0 |

即:所有插件安装即激活,惰性激活是 v0.4.0 的计划,不是今天的行为。

两重问题

  1. declared ≠ enforced(ADR-0049)。 作者在 studio plugin manifest 里写 activationEvents: ['onMetadataType:flow'](content/docs/plugins/development.mdx:387,带 os:check 标记的示例),期待插件被延迟到该事件才加载;实际它立即加载。这不是惰性 no-op,是一个语义上撒谎的键。

  2. studio 侧零校验。 z.string() 接受任何字符串:''、'banana'、'onMetadatType:flow'(拼写错误)全部通过,作者拿不到任何反馈。文档里列的词表(*、onMetadataType:、onCommand:、onView:)完全不被 schema 表达 —— 这正是 AI 生成的元数据出错后能长期潜伏的地方。对比 kernel 侧的 z.enum([...]) 至少挡得住 trigger 类型拼错。

建议处置(需维护者裁决,故不自行动手)

按 enforce-or-remove:要么在 v0.4.0 实现惰性激活并把词表收进 schema,要么按 ADR-0087 tombstone 掉这两处 activationEvents。注意:ActivationEventSchema 的双源问题正由 #4653 处理,而「选哪个编码」的裁决与本单强耦合 —— 如果这个键最终要被 retire,#4653 就不该先为它挑一个编码。建议两单一起裁。

关联:#4653、#4535、ADR-0049、ADR-0087

Activity

  1. self-assigned this
    on Aug 3, 2026
  2. os-zhuang commented on Aug 3, 2026

    @os-zhuang
    ContributorAuthor

    🔒 认领:PM 会话 session_0176qgxgCXTJCUv4YFLtusP9,分支 claude/issue-4657-activation-events-retirement。

    ADR-0049 队列接派(前序 #4616 → PR #4809 审毕,正在补 main 同步)。派发前快检(08:1xZ):

    区域:kernel/plugin-runtime.zod.ts + studio/plugin.zod.ts + 两处文档;与在飞 #4616(system/notification + kernel/metadata-plugin)文件不相交,可并行实施,入队排其后。


    Generated by Claude Code

  3. os-zhuang commented on Aug 3, 2026

    @os-zhuang
    ContributorAuthor

    ✅ 实施完成 — draft PR:#4831(分支 claude/issue-4657-activation-events-retirement,会话 session_0176qgxgCXTJCUv4YFLtusP9)。

    按 remove 处置,三处三种形态(由 gen:schema 的 #4650 门禁实跑输出裁定,实报贴在 PR body):

    ADR-0087:D2 不适用(两父 schema 均非 sys_metadata 存量,无源可改写),登记 D3 semantic plugin-activation-events-retired。changeset major,FROM → TO:删掉该键(v16 字符串形或 v17-rc 结构形皆同),所有插件本来就是安装即激活,行为零变化。

    消费方复核(裸名重扫,实施时点):objectstack / cloud / objectui 三仓零 runtime reader;仅存命中为 VS Code 扩展自身 package.json(不碰)与 cloud 一条 changeset 散文。

    验证:check:generated 8/8、check:dual-source-exports 0、spec test 295 files / 7358 passed、全仓 typecheck 122/122,均在合并 #4616(PR #4809)后的 main 基础上实跑;四张 ratchet 按规程整体重生成,#4616 的删除未被复活。

    范围外发现已立案(未 assign):#4832(PLUGIN_STANDARDS.md §5.3 罗列 #3896 已删 schema)、#4834(plugin-runtime.zod.ts 剩余家族零 consumer 的 enforce-or-remove 悬置)。

    Draft/入队归 PM。


    Generated by Claude Code

  4. os-zhuang commented on Aug 3, 2026

    @os-zhuang
    ContributorAuthor

    ✅ 验收通过 → PR #4831 已转正 + auto-merge

    对照 GitHub 实际 diff 逐项复核(4f136c55 vs merge-base cb680f27),全部合格:

    退役形态的非对称判定 —— 本单最关键的论证,已自行核实成立

    避开了 triggerPhrases suggester 陷阱 —— 三个 VS Code 味 alias(activation/events/onActivate)未留在原地指向已删键,而是与 activationEvents 一同映射到同一条退役处方(:330-340)。这正是 #4001 战役里那条「永远不要建议一个 schema 根本不接受的键」的教训,本单主动执行了。

    ratchet 三处与自述逐条吻合(三点式实测)

    manifest    −2  : kernel/ActivationEvent, studio/ActivationEvent
    authorable  −6 +1: 4 条 def 行 + studio 键删除;kernel 键 → [RETIRED]
    api-surface −4  : 两入口 × (ActivationEvent + ActivationEventSchema)
    

    dual-source-exports.baseline.json 与 renamed-defs.ts 均未触碰;content/docs/releases/ 零触碰;三个 VS Code 扩展的 package.json 零触碰。

    并行单成果未被复活:#4616 删除的 system/EmailTemplate / SMSTemplate / PushNotification / InAppNotification 在本分支 manifest 中均为 0 命中,而幸存的 system/EmailTemplateDefinition(不同 def)仍在 —— 精确名断言,没有误伤。

    D3 conversion 登记正确:plugin-activation-events-retired,两个 clause 均以键名结尾(满足 gate (b) 的 endsWith 匹配);D2 不适用的论证成立(studio 侧是 defineStudioPlugin 的 TS config 入参、从不入 stack 树,与 #4579 同构;kernel 侧是 runtime 请求形状且四仓零 caller)。

    入队说明:分支落后 main 一个 c4ab50b6(#4823 / #4728,packages/metadata/ + durability-degradation.baseline.json),实测与 packages/spec 及生成物零交叠,无静默回退风险,交由合并队列消化。

    范围外发现(PLUGIN_STANDARDS.md §5.3 仍列已删的 PluginDiscoveryConfigSchema / DynamicLoadingConfigSchema,及 DynamicLoadRequest 家族整族 enforce-or-remove 的悬置问题)已另行立案,处置正确 —— 不夹带进本 PR。


    Generated by Claude Code

  5. added 3 commits that reference this issue on Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions