行为图编译:编辑树不能直接成为运行时状态机

自动关联目录:行为图编译:编辑树不能直接成为运行时状态机

核心判断:创作者行为树包含可编辑身份、层级和宽松字段;运行时需要确定顺序、已验证 Schema 和不可变程序。两者之间必须有编译边界,不能让 DS 在执行途中解释脏编辑数据。

一、实际编译链路解决了哪些高风险问题

工程中的行为工具先在 detached graph 上预检对象标识、重复节点、祖先环、未解析父节点、父级资格、固定名称、重复树类型和黑板可传输性;通过后才按深度与稳定标识顺序挂接。编译阶段按 Schema 解码黑板,规范化字段和有序子节点,计算语义哈希,缓存并冻结不可变 IR。

这条链路的价值不只是性能。它确保相同内容得到相同程序,让客户端工具和 DS 能围绕同一个语义哈希诊断,也阻止构造脚本在半棵树上观察到中间状态。

二、当前扩展点仍然过硬

已支持的行为被映射为编译器内部的一张程序表。新增行为需要修改中央编译核心,说明编辑 Schema 虽可扩展,运行语义仍是封闭集合。继续堆条件分支会让版本兼容、权限审核和测试组合失控。

三、目标设计:注册编译器,不注册任意运行时代码

struct BehaviorCompiler {
    BehaviorType type;
    SchemaVersion authoringSchema;
    IrVersion outputVersion;
    CapabilitySet requiredCapabilities;
    CompileResult Compile(const CanonicalNode&, CompileContext&);
};

CompileResult Build(DetachedGraph graph) {
    ValidateTopology(graph);
    CanonicalGraph canonical = Normalize(graph);
    for (Node n : canonical.StableOrder()) {
        auto& compiler = Registry.Require(n.type, n.schemaVersion);
        Require(Context.Grants().ContainsAll(compiler.requiredCapabilities));
        compiler.Compile(n, Context);
    }
    return FreezeIR(Context.Program(), HashOf(canonical));
}

这里的注册表仍由受信任原生代码提供,不允许内容直接注入任意 DS 指令。IR 明确版本、操作码、资源上限和能力集合;未知节点产生带路径的编译诊断,而不是运行时降级猜测。

四、缓存与热更新契约

缓存键至少包含规范内容哈希、编译器版本、IR 版本和目标能力快照。热更新先编译新 IR,再由运行时在安全点以 generation 切换;旧任务继续持有旧不可变 IR 或被明确取消,不能在原对象上边改边跑。

五、验证与反思

建立 canonical golden test:字段顺序变化不应改变哈希,子节点语义顺序变化则必须改变;相同图跨客户端工具与 DS 编译结果一致。还要模糊测试环、重复身份、未知版本和超大图,并限制编译时间与 IR 大小。

反思后的核心是:可视化编辑器的产物不是状态机本身,而是状态机的源代码。平台能力取决于编译契约是否稳定,而不是节点面板是否丰富。