以下内容是基于现有图谱方法推出的设计分析,不是一次已经发生的线上冲突记录。
对一条关系来说,至少需要保留两个独立事实:
static_resolved
runtime_observed
前者回答源码与注册关系能否解析出这条边;后者回答某一批运行样本中是否记录到它。把二者合并成一个 exists=true/false,会丢掉最重要的信息:代码允许存在,不代表当前样本经过;当前样本经过,也不代表静态提取器已经理解它。
一条边需要两个事实字段
当前业务图谱会处理 View、Logic、Workflow、DSL、Action、State、接口与数据关系。不同来源能够回答的问题并不相同:
| 来源 | 可以确认的内容 | 无法单独确认的内容 |
|---|---|---|
| TypeScript AST | 导入、继承、模型引用、部分事件键 | 动态分支是否真实执行 |
| DSL / Workflow | 组件安装、业务名称、订阅与转换关系 | 当前样本是否经过 |
| 运行时追踪 | 某批请求的发送方、接收方和结果 | 未观察关系是否不存在 |
| 数据库元数据 | 表、字段和控制器映射 | 字段的完整业务语义 |
| 人工业务定义 | 代码未表达的流程含义 | 当前代码是否仍遵守定义 |
静态关系稳定、可重复,也适合构建阶段检查;它通常看不到分支可达性、动态名称和真实流量。运行时追踪能看到一次实际执行,却只代表观测窗口与采样范围。
所以“存在”和“被观察到”不应该互相覆盖。
四种组合不能使用同一结论
| 静态解析 | 运行时观察 | 暂时解释 | 禁止直接推出 |
|---|---|---|---|
| 是 | 是 | 两种来源在当前版本与样本上相互印证 | 所有分支都已覆盖 |
| 是 | 否 | 关系已声明,但当前窗口未观察 | 这一定是死代码 |
| 否 | 是 | 动态关系、提取缺口或版本漂移 | 运行时事件已经是正式架构 |
| 否 | 否 | 当前没有证据 | 关系绝对不存在 |
还有一种不属于关系冲突的情况:静态图来自一次构建,追踪来自另一个版本。缺少构建摘要、生成时间和 trace 版本时,两份数据根本不可比较。
这张矩阵的作用不是给每条边计算一个漂亮置信度,而是决定下一步应该检查源码、提取器、采样窗口还是版本对齐。
来源、版本和观测窗口必须保留
建议的边记录至少包含:
from
to
relation
static_evidence[]
runtime_observation_count
first_observed_at
last_observed_at
build_version
trace_version
status
status 可以表达:
declared
statically_resolved
runtime_observed
conflicted
stale
unresolved
这是建议的数据模型,不是当前系统已经实现的 schema。
状态也不能替代原始来源。conflicted 必须能够回到源码位置、构建版本和原始事件;否则它只是另一个无法解释的标签。运行时记录还需要采样率与丢失计数,没有丢失计数就无法区分“没有发生”和“发生但没有被记录”。
建图本身如何从大图收敛到一次修改的影响范围,由《从按钮事件到最小业务子图》负责。本文只处理多来源关系不一致时如何保留分歧。
一个尚未执行的最小实验
第一轮不需要拿完整业务图谱计算准确率,只需构造四条最小链:
- 静态可解析且实际执行;
- 静态存在但条件永远不满足;
- 使用动态名称注册,运行时可见;
- 旧版本存在、当前版本已经删除。
静态提取器与运行时追踪分别输出结果,再由人工标注关系语义。验收重点不是一个总准确率,而是错误类型能否被解释:漏掉动态关系、把类型引用误判成业务调用、把未触发路径误判为死代码,或因版本漂移制造冲突。
追踪本身也需要进入实验变量。同步日志可能改变时序,大量采集可能影响性能,关联 ID 也可能在异步边界丢失。只有记录采样、开销和丢失,运行时数据才有资格被称为观测事实。
这篇文章的停止位置
现有材料能够支撑多来源冲突模型和上述实验设计,不能支撑动态关系占比、追踪开销、静态命中率或图谱漂移速度。
在出现一条包含源码位置、运行版本、观测窗口与原始事件的脱敏冲突样本以前,这篇文章保持 essay,不把设计矩阵包装成已经完成的 lab。