Skip to the content.

评分模型

为什么是两个数字

风险(Risk)和置信度(Confidence)回答不同的问题:

合并成一个分数会丢掉关键信息。考虑两种情形:

情形 风险 置信度 正确处置
删除 public 方法,调用方清晰可见 高 高 立刻修,影响明确
删除 public 方法,调用方可能来自反射 高 低 需要人工确认,不能假定没事
改了内部实现细节,只有一个日志调用方 低 高 可延后
配置项改了,读取方位置不明 中 低 需要确认配置是否生效

第三种和第四种如果用单一分数,可能落在同一个值——但它们需要的动作完全不同。

风险公式

R = 100 × (0.25·S + 0.20·D + 0.20·B + 0.20·C + 0.15·U)

S  变更本身的风险(changeRisk)      ← 来自变更类型的种子值
D  传播深度衰减(depth)              ← 越远越弱
B  行为变化可能性(behavior)         ← 影响类型 × 用法权重
C  影响对象重要程度(criticality)    ← 调用方数量 + 是否公开 API
U  分析不确定性(uncertainty)        ← 1 - 置信度

等级划分:

等级 分数区间
CRITICAL ≥ 80
HIGH ≥ 60
MEDIUM ≥ 40
LOW ≥ 20
INFO < 20

各因子怎么算

S — 变更风险:直接取变更类型的种子值(见 变更识别规则)。

D — 深度衰减:max(0.15, 1.0 - (depth-1) × 0.15)。 深度 1 是 1.0,深度 2 是 0.85,深度 5 是 0.4,到深度 7 之后触底 0.15。 越远的影响越不可靠,这是合理的先验。

B — 行为变化可能性:

B = 影响类型权重 × (0.4 + 0.6 × 用法权重)

影响类型权重:SECURITY 1.0 / BEHAVIOR 0.9 / COMPILE 0.85 / API_CONTRACT 0.85 / DATA 0.8 / CONFIG 0.65 / TYPE 0.6。

用法权重是关键修正:

对方怎么用这个返回值 权重
参与分支条件(CONDITION) 1.0
直接返回(RETURN) 0.9
赋值给变量(ASSIGNMENT) 0.8
作为实参(ARGUMENT) 0.7
赋值但没人用(IGNORED) 0.45
只打日志(LOG_ONLY) 0.2

这解释了报告里最常见的一个现象:同一个方法改动,不同调用方的风险差好几倍。

C — 重要程度:0.35 + min(0.5, 调用方数量 × 0.05) + (公开 API ? 0.15 : 0)。 调用方越多越重要,公开 API 额外加分。

U — 不确定性:1 - 置信度。

置信度怎么算

置信度是沿路径连乘衰减的结果:

confidence(起点) = 1.0
confidence(下一跳) = confidence(当前) × 边系数 × 0.82

边系数按关系类型区分(只衡量链接可靠度,不含用法强度):

关系 系数
CALLS 基础置信度
CALLS_API × 0.95
REFERENCES_TYPE × 0.85
IMPLEMENTS / EXTENDS × 0.9
READS_TABLE / WRITES_TABLE × 0.75
USES_CONFIG × 0.85
TESTS 0(测试不参与传播)

基础置信度来自解析质量:单一候选的调用 0.85,有歧义的多候选 0.6,动态分派更低。

置信度低于 0.15 的路径会被剪掉——再传下去也没有信息量。

等级:HIGH ≥ 0.8、MEDIUM ≥ 0.55、LOW < 0.55。

一个完整例子

变更:UserService.isActive 的分支条件改了
      S = 0.80(METHOD_CONDITION_CHANGED)

命中:OrderService.createOrder 调用它,返回值参与 if 判断
      depth = 1 → D = 1.00
      impactType = BEHAVIOR → 类型权重 0.9
      usage = CONDITION → 用法权重 1.0
      B = 0.9 × (0.4 + 0.6 × 1.0) = 0.90
      C = 0.35 + min(0.5, 3×0.05) + 0 = 0.50
      confidence = 0.85 → U = 0.15

R = 100 × (0.25×0.80 + 0.20×1.00 + 0.20×0.90 + 0.20×0.50 + 0.15×0.15)
  = 100 × (0.20 + 0.20 + 0.18 + 0.10 + 0.0225)
  = 70.25  → HIGH

同样的改动,如果调用方只打日志(usage = LOG_ONLY,权重 0.2): B = 0.9 × (0.4 + 0.12) = 0.468,总分降到约 61——从 HIGH 边缘落到 MEDIUM。

可调参数

code-association:
  max-depth: 8    # 传播最大深度,同时也是 D 因子的下限来源

其余权重固化在 RiskScorer 与 PropagationRules 中,集中在一处便于调整。