第一百〇一章 范围
他把手机放下之前,麦景行又发了一条:「G3 那个 Python 模块,文件名是 `supervisor_ctrl.py`,里面有一段判断,逻辑和 G1 的那条旁路几乎一样。写法换成了函数,但触发条件长得一样:双路传感器同时超出阈值,切换到降级运行模式。」
他没有立刻回复,先把 G3 的截图存下来,和 G1 的宏展开结果放在一个文件夹里比对。
G1 是 C 语言宏,1994 年写的,触发条件是宏常量:S1 和 S2 读值同时超出 `UPPER_LIMIT`,持续 `TIMEOUT_CYCLES` 个周期,切到 `SIMPLIFIED_MODE`。
G3 是 Python 函数,写入时间是近两年,触发条件是函数参数:两路都超出 `threshold`,持续 `cycle_count` 秒,切到 `degraded_mode`。
参数名不同,语言不同,写代码的人大概率不是同一批,相隔将近三十年。但逻辑在那里,两段代码描述的是同一个行为:传感器双路异常时,系统切换到简化运行。
「G2 也查一下。」他发给麦景行。
「G2 是 Java,比较老,我现在去找找。」
他重新拿起草稿,原来的评估框架摆在屏幕上。五个模块,三个代际,各自分析注释可行性,最后给出整体结论。这是最初谈合同时的思路,假设每个模块的问题是独立的。
假设现在需要重新考虑。
如果旁路逻辑在 G1 和 G3 都出现,写法不同、时代不同,但行为一致。那说明这套设计延续了三十年,绝不是某一年的偶然决定。可能是当年的工程原则传下来的,后来人看到了、理解了,继续保留。
也可能后来人没看过 G1,只是在 G3 里独立解决了相同问题,用了相同的逻辑,因为这本来就是工控行业的标准做法。
两种情况对评估结论的含义不一样。前一种,追溯的核心是一份原始设计文件,能覆盖三十年;后一种,每代代码的旁路各需要一条确认路径。

「打开船坞。」他对着屏幕说了一声。
豆包:
> 这种跨代际一致行为,在工控领域常见的模式是:最初设计文档定义了核心安全机制,后续工程师在维护和重写时遵循了相同设计原则。如果是这种情况,原始设计文档的权威性更高,找到一份就能支撑三代代码的注释。但如果每代代码各自独立实现,文档需要分别确认,复杂度会成倍增加。
Claude:
> 区分这两种情况,可以看 G2。G2 里用的是什么写法,三代之间有没有共同依赖或相互引用,能给出线索。也可以直接问泉华:这套传感器降级逻辑,当年有没有统一的设计规范,还是各代团队各自处理的?
他把第二条建议记下来,关掉船坞。这个问题直接问比自己推断快。
麦景行的消息隔了半小时才来:「G2 里面有,是一个 Java enum 常量定义,`SensorFallbackMode`,里面有个 `DEGRADED`,和另一个枚举 `SensorTrigger` 一起用。调用路径在另一个文件,但逻辑一样,两个传感器都超阈值,走降级。」
三代都有。G1 是宏,G2 是 Java enum,G3 是 Python 函数,三十年里代码架构换了两次,这个逻辑一直在。
写法换了三次,逻辑没换。三代系统穿了不同的外衣,留下的是同一个指纹。
他给方晓晨发了一条:「有一个情况需要再和您同步一下。G1 发现的旁路机制,我们在 G2 和 G3 里也找到了相似逻辑,写法各不相同,但行为一致:传感器双路异常时,系统切换到降级模式。我需要确认一件事:这三代代码里的旁路逻辑,是继承自同一份设计文档,还是各代团队各自实现的?这个答案会影响文档追溯部分的结构。」
发出去,他在椅背上靠了一下。

报告结构要重新想了。文档追溯如果有清楚的答案,报告就按三代统一逻辑写,援引同一份原始文件。追溯结果复杂,这部分单独处理,各代各自走确认路径。
方晓晨的回复来得比预期快。
「你这个问题问到点上了。工程院那边翻了一下,找到了 1996 年的一份技术备忘录,不是完整设计文件,但里面有一节专门写这套冗余失效处理原则,是 1994 年那批设计决策的文字版。我让他们扫描,发给你。」
紧接着补了一条:「后面两代应该是照着这个原则写的,但有没有人直接参考过这份文件,我不确定,你们拿到之后判断。」
他回了一个字:「好。」
备忘录的扫描件在下午两点到的,是一份模糊的 A4 文件,十八页,繁体打印,右上角有文件编号,左侧有手写批注。
他本来只是快速翻页。
翻到第七页,手指停住了。
标题一行黑字:「传感器冗余失效应对规范」。
他没有立刻继续往下读,先在脑子里把 G1 的宏名、G2 的 enum 常量名、G3 的函数参数过了一遍。三代代码,三十年,换了三种写法,留在同一个逻辑节点上。
然后他继续往下。

分段说明写的是:当主传感器和备用传感器同时读值异常,且异常持续超出设定时间窗时,系统进入简化运行模式,跳过需要双传感器输入的保护判断,维持设备基本运行,等待人工介入。
下面一段加粗:「此机制为应急保障设计,仅适用于传感器本身物理故障场景,不适用于被测物理量真实超标场景。使用前提:工程现场已由专业人员确认传感器故障,非工艺异常。」
G1 闭环了。G2 闭环了。G3 也闭环了。
「找到根文件了。」他给麦景行发了一条,把扫描件截了两页发过去。
「就是这个!」麦景行说,「G1 那段宏的触发条件和这里说的时间窗口完全对上,G2 的 enum 常量名也是 `SensorFallbackMode`,就是这个叫法。」
「所以是继承来的,不是各代独立实现的。」
麦景行:「对,Python 那边的变量命名已经换了一套风格,但逻辑没变。估计写 G3 的人看过这份规范,或者看过 G2 的代码。」
现在评估报告的框架清楚了。
这三代代码里的旁路逻辑都可以追溯到 1996 年那份备忘录,备忘录本身是 1994 年设计决策的文字版。注释的基准有了:援引文件编号,写清楚适用场景和使用前提,标注来源,由泉华安全团队在验收时确认。
他打开报告草稿,在「安全关键条目」一节的开头加了一行:「以下条目涉及跨代际传感器降级逻辑,均可追溯至文件编号[XXX],1996年备忘录。」
文件编号还没填,等方晓晨那边正式的扫描件和文件号来了再确认。

他给麦景行发了一条:「今天把文件编号落实,剩下的注释按这个框架写。」
「收到。这样算是难题解了。」
「这道难题解了,但加法还没完:五个模块里,三个代际都有这个逻辑,注释里每一处都要标。」
「嗯。但至少知道标什么了。」
窗外已经是下午三点。方晓晨那边的工程院还没发来正式文件编号,但备忘录扫描件已经足够。他把报告框架保存了一版,觉得可行性评估有了新的形状:从「五个模块能不能做注释」,变成了「三十年工控设计的一条安全主线能不能梳理清楚」。
后者更值钱,也更难。
他正准备关掉扫描件,目光又落回那行加粗字。
「不适用于被测物理量真实超标场景。」
如果泉华这些年,有任何一次触发降级,现场确认的是传感器故障,但实际上设备真的在超标运行——
那这条三十年的安全主线,就不只是注释问题了。
是安全责任雷。