第一百〇五章 边界
麦景行把那条消息发出来之后,过了两分钟没有新的内容,可能在等他问。
陆衍盯着屏幕。
「宏定义在哪里,你找到了吗?」他回。
「还没,我在全库搜。」
「不急,找到了告诉我。」
他重新打开 G1 的函数结构图,把麦景行之前整理的调用树拉出来翻了一遍。`proc_svp_h` 函数走到传感器异常这一段,触发旁路逻辑,旁路逻辑里有个条件分支,当旁路自身检测到执行状态异常时调用 `ERR_HANDLER`。这部分逻辑他之前看到过,当时 Claude 标的是「历史遗留占位符」,没有深入。
现在知道这不是占位符了。是一个错误回调入口,没有完成展开就交给信安审查去了。
窗外还亮着,但光线已经偏斜,是傍晚的颜色。
「找到了。」
消息来得比他预估的快一点。

「在哪里?」
「不在合同范围的模块里。文件路径是 `common/err_handle.h`,根目录的共享头文件夹,不在合同约定的 G1/G2/G3 模块路径下。」
路径记下来了:`common/`。
「这个头文件里 `ERR_HANDLER` 的展开是什么?」
「一个函数调用,`set_system_fault(ERR_CLASS_SENSOR, fault_code)`,然后是一条日志写入。`set_system_fault` 这个函数我也查了,在另一个公共库里,作用是把系统状态写成 FAULT,触发上层的故障中断处理流程。」
链路画在纸上:传感器异常 → 旁路触发 → 旁路执行异常 → ERR_HANDLER → set_system_fault → 系统进入 FAULT 状态。
「旁路逻辑自身出错时,这个链路负责向上报告故障,让设备进 FAULT 状态。」
「对,」麦景行回,「相当于双重保险:旁路本身是一层,旁路自己出了问题还有第二层兜底。」
说通俗一点:设备出事时该自动喊停,但喊停的那只手,牵着一段没人认领的旧绳子。

笔放下,手在桌面上停了一秒。
「这个文件,是谁维护的?」
麦景行停顿了一下。「文件头里没有明确的维护人,只有一行备注:`Platform Infrastructure Layer v1.2,1997`。」
这是合同外的东西。
他把问题摆给豆包,陈述很短:合同范围内的旁路故障处理链里,有一个错误回调入口的定义文件在合同范围外的共享层里。现在要写注释报告,这条依赖关系该怎么处理?
豆包的回复来得比他想的慢一点,分了两段。
第一段:老旧工业软件里这种情况挺常见的。公共库是全局引用的,合同一般只划到业务模块,公共层不在里头。标注上,在注释里写清楚「依赖外部公共库,见 common/ 路径」通常够用;如果需要进一步说明,可以联系客户确认公共库的维护归属。
第二段:但这个具体场景有一个地方值得单独提出来。`ERR_HANDLER` 调用点在一条安全关键路径上,如果公共库里这个函数的行为有问题,旁路的兜底机制会失效,上层不会收到正确的 FAULT 信号。普通的依赖注明到这里就不够用了。这里是一条安全链条的末端节点,注释只写「依赖外部」,读者看不到这块的安全权重,容易低估风险。
豆包第一段给了标准答案:依赖外部,注明路径就行。第二段单独提出这条调用链的安全级别问题,建议在报告里单列一节。

这个建议本身没错。但他看完第二段知道,这次不能只是在报告里单列一节。
合同范围内的安全关键代码,指向一个范围外、维护归属不明的公共库。这个事实如果只出现在报告附录里,方晓晨收到报告之前都不会知道。等报告出来,事情已经定型了。
草稿文件关掉,他打开发给方晓晨的邮件界面。
这封邮件不长。
他写明了三件事:第一,G1 旁路逻辑里存在对 `common/err_handle.h` 的调用,这个文件不在合同约定的模块路径里;第二,这条调用路径处于安全关键位置,是旁路机制的错误兜底层,如果这里有问题,设备可能在旁路执行异常时不进入正确的 FAULT 状态;第三,云帆目前尚不清楚 `common/err_handle.h` 由哪个部门负责维护,需要泉华确认。
他没有在邮件里提建议。方晓晨需要先知道这个事实,建议放在之后谈。
发出去,是晚上七点四十分。
回复来的时候他已经在整理第二天的工作清单,正好九点过。
方晓晨的邮件不长,但有一句话他读了两遍。

「`common/err_handle.h` 属于我们基础平台部门(BasePlatform 组),不归工业控制产线维护。这个依赖关系在我们这边的文档里确实没有记录,此前也没有人提过。感谢您指出,我们会内部确认。」
邮件转发给麦景行,没有附任何说明。
几分钟后,麦景行那边发过来一条:「BasePlatform 的人写了这个 common 层,工控的人用了它的错误回调,三十年来没有人把这两件事写在一起过。」
他关掉屏幕,在椅背上靠了一下。
这条依赖关系不复杂,逻辑清楚,画在纸上就是几个箭头。但它存在于一份 1994 年的工控代码里,跑过三十年的设备,每一次检修合规都只看到它的一端。
合同的边界在五个模块,代码的边界在它实际运行时用到的每一个函数。两条边界之间,有多少距离,在这次之前没有人画过。
那封邮件截图他转给了乔木:「你看一下,可能要跟泉华谈一下扩展范围的问题。」
乔木的回复是第二天早上来的,第一句话是:「BasePlatform 那边我们够不着,要谈的话,这是泉华内部的协调,需要方总推。」
第二句话是:「而且方总一推,就等于承认泉华过去三十年的合规验收里,这条链路从来没有被完整核查过。BasePlatform 不会主动认,工控产线也不会主动认。夹在中间的是方总。」