:阿丽亚娜 5 号 Ariane 5——复用成功代码,不代表新场景依然安全)
这是历史中的执行控制系列的第九篇。第一篇历史中的执行控制一诺曼底登陆 D-Day 的天气窗口——没有正确的执行窗口就不执行。第二篇历史中的执行控制二切尔诺贝利——不要让错误穿过所有边界。第三篇历史中的执行控制三阿波罗 13——失败不是终点边界才是系统韧性。第四篇历史中的执行控制四图灵与 Bletchley Park——不是破解密码而是重构决策优势。第五篇历史中的执行控制五珍珠港——信号必须及时改变执行状态。第六篇历史中的执行控制六挑战者号 Challenger——工程边界不能被执行压力压过。第七篇历史中的执行控制七Therac-25——软件不能替代所有硬件安全边界。第八篇历史中的执行控制八火星气候轨道器——接口通过不代表语义一致。上一篇讲的是接口两端的语义要一致。这一篇讲一个更微妙的问题一段在旧系统里被反复验证、从未出错的代码原封不动搬到新系统里可能正好成为致命入口。摘要阿丽亚娜 5 号首飞失败常被讲成软件 bug 导致火箭爆炸的经典案例。但从 Havenlon 的视角看它真正值得讨论的不只是软件错误而是一个更深的问题在旧系统里长期有效的代码换到新场景里不一定仍然安全。这件事对今天的 AI Agent、自动化系统、企业运维和高风险执行非常重要因为它告诉我们历史成功不等于当前安全旧场景成立不代表新场景成立代码可复用不代表边界可复用。一个过去从没出事的逻辑换到新环境里可能正好成为风险入口。这就是阿丽亚娜 5 号给 Havenlon 的第九课执行不能只相信以前这样做没问题每一次高风险执行都必须重新绑定当前场景。一、先把历史讲准确1996 年 6 月 4 日阿丽亚娜 5 号运载火箭的首次发射编号 Flight 501 / V88在法属圭亚那库鲁进行箭上载有欧洲空间局ESA的Cluster——一组四颗研究卫星。升空约 37 秒后火箭突然偏离航迹在剧烈的气动应力下开始解体随后被自动自毁系统炸毁连箭带星损失约 3.7 亿美元。ESA 与 CNES 随即组建了由数学家雅克-路易·利翁Jacques-Louis Lions领衔的调查委员会7 月即发布了报告。事故的技术链条是软件工程史上被引用最多的案例之一。火箭上有两套并行的惯性参考系统SRI硬件和软件完全相同一套工作、一套热备。SRI 里有一段对齐功能的代码——它只在起飞前有意义用于对准惯性平台。这段代码是从上一代阿丽亚娜 4 号直接复用来的按照阿丽亚娜 4 的需求对齐功能在进入飞行模式后还会继续运行约 40 秒以便倒计时中断时无需重新长时间对齐。可在阿丽亚娜 5 号上这段代码起飞后根本没有任何用途却依然在运行。而阿丽亚娜 5 号的飞行轨迹比阿丽亚娜 4 号更猛水平速度高得多。这让对齐功能里一个叫BH水平偏置Horizontal Bias的内部变量变得异常大。软件在把 BH 从一个 64 位浮点数转换成 16 位有符号整数时数值超出了 16 位整数能表示的最大范围32767触发了操作数错误溢出。这里有一个最能说明本篇主题的细节。当时工程师其实分析过代码里有 7 个变量可能发生这类溢出。但为了把 SRI 处理器的负载压在80% 以下他们只给其中 4 个变量加了保护BH 等 3 个被特意留空——因为按阿丽亚娜 4 号的物理极限做手工分析这些值永远不可能大到溢出。这个判断在阿丽亚娜 4 号的场景里是完全正确的换到阿丽亚娜 5 号就不再成立了。溢出发生后工作中的 SRI 按设计自我关闭而热备的那套 SRI 跑着同一份代码、遇到同样的条件几乎在同一瞬间也失效了。随后关闭的 SRI 向主机OBC发出的是一段诊断位模式主机却把它当成了有效的飞行姿态数据据此下达了极端的喷管偏转指令——火箭猛地偏航、解体、自毁。利翁委员会的结论一句话概括失败源于惯性参考系统软件中的规格与设计错误而非某个孤立的手误。二、这不是代码写错了这么简单阿丽亚娜 5 号的失败很容易被讲成一个纯软件故事某个变量溢出、某段程序异常、系统失去制导、火箭失败。这些都对但只看到这里就会错过更深的系统教训。真正的问题是这段逻辑不是凭空出现的。它来自已有系统在过去的场景里曾经有意义带着旧系统里的假设被带进了新系统。而且它甚至不是在做一件有用的事——那段对齐代码在起飞后毫无用途却依然在运行最终亲手掀翻了这枚火箭。一个逻辑在旧系统里可能合理一个参数范围在旧轨迹里可能从未越界一个异常路径在旧场景里可能从未被触发——但新场景不是旧场景火箭变了轨迹变了速度曲线变了系统边界变了原来的假设也应该重新验证。没有重新验证就不是复用而是把旧风险悄悄带进了新的执行链。三、复用成功代码最容易复用隐藏假设工程里代码复用很常见复用成熟模块、验证过的逻辑、团队熟悉的组件——这本身没问题。真正的问题是复用代码的同时也复用了代码背后的假设。这段代码假设了什么输入范围什么运行阶段什么速度曲线什么系统边界它假设自己在哪个上下文里被调用如果这些假设没有被显式检查代码看起来是复用实际上是在把旧上下文偷偷带入新系统。BH 那个永远不会溢出的判断就是一条被原封不动继承下来的隐藏假设。这和 Havenlon 一直强调的执行前重新绑定语义非常接近。你不能只问这段代码以前有没有跑过你必须问这段代码现在运行的场景还是以前那个场景吗四、旧逻辑的新风险上下文漂移阿丽亚娜 5 号的关键教训可以用一个词概括上下文漂移——逻辑本身看起来没变但它所在的环境变了输入范围变了、速度曲线变了、接口语义变了、运行阶段变了、失效后果变了、安全边界变了。于是原本安全的逻辑变成了危险逻辑。这在今天的系统里非常常见一个运维脚本以前只用于测试环境后来被搬到生产一个交易规则以前只处理小额资产后来处理高价值资产一个审批流程以前只用于低风险操作后来接入高风险权限一个 AI Agent 工具以前只读数据后来能写入、删除、转账、重启一个策略以前只在单人账户里使用后来进入多人共同治理。表面看逻辑没变但执行上下文已经完全不同。这时候如果系统仍然说以前这样没出过事就是危险信号。Havenlon 要防止的正是这种情况旧路径不能自动继承新场景的执行权旧逻辑不能自动越过新边界旧成功不能自动成为新安全。五、测试通过不代表测试代表真实场景阿丽亚娜 5 号还提醒我们一个很现实的问题测试通过不代表系统真的安全。事实上SRI 的硬件测试过了、软件也被证明符合规格唯独完整的惯性参考系统从未在能代表阿丽亚娜 5 号真实飞行包线的配置下被测试过——否则这个溢出本可以被提前发现。很多系统都会说我们测试过、评审过、跑过模拟、有灰度、有回滚、有审批。但问题是测试是否覆盖了真实执行场景仿真是否代表真实输入边界评审是否重新验证了上下文变化不具代表性的测试反而会制造安全幻觉因为系统会以为自己已经被验证过。这和 Havenlon 的执行控制逻辑一致执行前不是只看有没有测试记录而是看当前动作是否满足当前边界。六、异常处理不是附属功能而是执行边界的一部分阿丽亚娜 5 号里还有一个关键问题异常处理本身就是执行边界。溢出发生后SRI 直接关闭把一段诊断数据当成飞行数据送了出去——一个本可局部化的问题被处理成了整箭失效。利翁委员会尖锐地指出这个异常被检测到了却被错误地处理因为当时抱持着一种观念——软件在被证明有错之前应当被视为正确。报告还特别提到SRI 的计算机其实完全可以继续输出它对姿态的最佳估计值而不是一关了之。这说明异常处理绝非细枝末节。一个系统出错不可怕可怕的是出错之后的处理方式把局部问题放大成系统失效。在高风险执行系统里异常处理必须回答异常发生后是继续还是停止是降级还是关闭是冻结最后的有效值还是输出错误状态把下游一起带偏这对 Havenlon 非常重要因为执行控制不能只设计正常路径还必须设计异常路径证据链断了怎么办策略冲突了怎么办设备状态异常怎么办上游请求不可验证怎么办Agent 输出与 Intent 不一致怎么办真正可靠的系统不是没有异常而是异常发生后不会把错误继续推进到现实执行。七、冗余不是复制同一个错误复杂系统常用冗余两套惯性参考系统、多个服务实例、多节点审批、多重签名、主备切换。但阿丽亚娜 5 号给了一记警钟——冗余不是简单复制。它的两套 SRI 跑着完全相同的软件、共享完全相同的假设、面对完全相同的未覆盖输入于是当溢出到来时主用的那套关闭热备的那套几乎在同一瞬间以同样方式失效。看起来有两套实际上只是同一个错误假设的两份副本。在 Havenlon 的世界里这个教训非常关键多审批不等于共同治理多签名不等于多边界多策略来源不等于更安全多个软件模块不等于独立裁决多个 Agent 复核不等于真正的分层不信任。如果它们共享同一份错误上下文风险仍然会一起穿透。真正的冗余应该带来差异化的边界真正的多层控制应该避免同源失败真正的共同治理应该让任何单点都无法把灾难性执行直接推到底。八、AI Agent 时代旧流程复用会更危险阿丽亚娜 5 号的故事在 AI Agent 时代会重新变得重要因为Agent 极其擅长复用复用历史流程、已有脚本、过去的操作经验、模板化审批、工具调用链、上一次成功的路径。这看起来很高效但高风险执行最怕的就是——把上一次的成功误认为这一次的安全。一个 Agent 很可能会想上次这样部署成功了、上次这样导出没问题、上次这样转账通过了、上次这个权限临时放开没出事、上次这个审批模板被接受了。但这一次的上下文可能已经变了环境变了、权限变了、数据范围变了、资产规模变了、风险窗口变了、审批成员变了、工具版本变了、攻击面变了。所以 AI Agent 的执行不能只依赖历史可行它必须在每一次高风险动作前重新绑定当前上下文。这就是 Havenlon 的位置Agent 可以提出计划SaaS 可以组织流程审批可以表达同意策略可以给出规则——但最终执行必须经过独立边界重新裁决那个唯一重要的问题这一次真的安全吗九、Havenlon 的答案每次执行都必须重新绑定当前场景Havenlon 反对的不是复用——工程系统不可能不复用企业系统不可能每次从零开始AI Agent 也不可能每一步都完全手工构造。Havenlon 反对的是未经重新绑定的复用旧逻辑可以被复用但不能自动继承执行权。每一次高风险执行都应该重新绑定当前的 Intent、身份、策略、设备状态、时间窗口、资产范围、操作对象、上下文版本、证据链状态和本地执行边界。如果这些绑定不成立系统就不应该因为以前成功过而继续放行。这就是 Havenlon 与普通自动化系统的差别普通自动化更关心如何把过去成功的流程更快地复制而 Havenlon 更关心这次复制是否仍然满足当前边界。十、从九篇看主线执行控制的第九个侧面D-Day 告诉我们没有正确窗口不执行。命令存在不等于现实允许。切尔诺贝利告诉我们不要让错误穿过所有边界。灾难往往来自多个弱边界连续放行。Apollo 13 告诉我们失败不是终点边界才是系统韧性。失败后的边界决定系统能否收敛。Bletchley Park 告诉我们不是破解密码而是重构决策优势。信息不进入边界就只是信息。珍珠港告诉我们信号必须及时改变执行状态。看见风险不够必须在窗口关闭前完成状态切换。挑战者号告诉我们工程边界不能被执行压力压过。系统最想继续的时候边界最应该能说不。Therac-25 告诉我们软件不能替代所有硬件安全边界。高风险执行必须保留独立边界。Mars Climate Orbiter 告诉我们接口通过不代表语义一致。一个语义错配就能穿过整条执行链。Ariane 5 告诉我们复用成功代码不代表新场景依然安全。旧逻辑进入新环境必须重新验证边界。这九篇共同指向 Havenlon 的核心判断执行不能只服从意图不能只服从接口不能只服从软件也不能只服从历史经验——执行必须经过当前场景下的边界裁决。结语阿丽亚娜 5 号的故事不该只被当成一个软件 bug 案例。它真正提醒我们的是成功经验本身也可能成为风险来源。因为成功经验最容易被信任被信任的东西最不容易被重新检查不被重新检查的假设最容易穿过执行链一旦进入真实执行窗口它就可能变成不可逆的结果。那段在阿丽亚娜 4 号上安全飞行了无数次的代码正是因为一贯正确才没有人再去质疑它在阿丽亚娜 5 号上是否依然成立。Havenlon 要防止的正是这种从过去成功到当前失控的滑坡。AI 和自动化时代系统会越来越快地复用过去的动作——但越是能快速复用就越需要重新绑定当前边界。不是每段成功代码都适合新场景不是每个旧流程都适合新任务不是每次历史经验都能成为当前执行依据。Ariane 5 给 Havenlon 的第九课是复用不是问题未经边界重验的复用才是问题。 真正可靠的执行系统必须在每一次高风险动作发生前重新问一次这一次场景还是原来的场景吗参考资料J. L. Lions 等ARIANE 5 — Flight 501 Failure: Report by the Inquiry BoardESA / CNES1996 年 7 月 19 日Bashar Nuseibeh,Ariane 5: Who Dunnit?, IEEE Software, 14(3), 1997Jézéquel Meyer,Design by Contract: The Lessons of Ariane, IEEE Computer, 1997Wikipedia,Ariane flight V88ESA 关于 Cluster 任务与 Ariane 501 的资料