Skip to content

嵌入式 host 直接 new AutomationEngine() 而不调用 sealNodeTypeVocabulary(),就完全拿不到节点类型校验 —— #4771 的连带回退,靠文档而非强制 #4792

Description

@os-zhuang

Blocked-by: #4771

由 PM 在复核 PR #4791(修 #4771)时提出。不阻塞那个 PR —— 它让主路径从「永远说谎」变成「永远说真话」,净收益远大于本单描述的边缘回退。

背景

#4771 把 ADR-0018 §M1 的节点类型校验从 registerFlow 挪到了 AutomationEngine.sealNodeTypeVocabulary() —— 词汇表封闭的那一刻。这是对的:插件在自己的 start() 里贡献节点类型,而 flow 在此之前就被拉起来了,所以注册时的判断是在校验一个还没成型的世界。

AutomationServicePluginkernel:bootstrapped 自动调用 seal,所以走插件的部署(绝大多数)完全没问题

问题

直接 new AutomationEngine() 而不经过 AutomationServicePlugin 的嵌入式 host,如果不自己调用 sealNodeTypeVocabulary(),就完全拿不到节点类型校验

对这部分 host 来说这是净回退:

也就是说这部分 host 用「不可靠的告警」换成了「没有告警」,而它们恰恰是那个告警本来可靠的人群。

为什么值得单独修

PR #4791 已经把这一点诚实地写进了 changeset 和 PR 描述,处理没有隐瞒。但**「文档写了」不等于「强制了」** —— 一个只有读过 changeset 的人才能拿到的检查,对没读的人就是静默消失的。这正是本仓一贯不接受的形态(ADR-0049、#4632#4776 讨论的都是这一类)。

危害程度诚实评估:。受影响的是嵌入式 host 这一小群体,且失去的是一个告警而非功能。所以这是 P3 量级,不是要紧急处理的东西 —— 但它不该只靠纪律。

一个廉价的缓解方向(供参考,不是裁定)

execute() 首次运行时,若 nodeTypeVocabularySealed 仍为 false,告警一次:大意是「节点类型校验从未运行 —— host 应在插件装载完成后调用 sealNodeTypeVocabulary()」。

理由:第一次真正执行 flow 的时刻,词汇表在实践上必然已经完整(不然那次执行本身就会 NO_EXECUTOR 失败),所以这个时点既安全又必然到达。它把「host 忘了调用」从静默变成响亮,而不需要引擎去猜 host 什么时候装完插件。

也可以考虑在那一刻顺带自动 seal,但那会让「谁决定词汇表封闭」有两个答案,可能不如只告警干净 —— 接手者自行判断,两种都可接受。

验收

  • 嵌入式 host(直接 new AutomationEngine()、注册 flow、从不 seal)在首次执行时得到一条明确告警;
  • AutomationServicePlugin 的正常路径不受影响、不多打任何日志(有测试证明);
  • 已经显式调用过 sealNodeTypeVocabulary() 的 host 同样不多打日志。

关联

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions