MATTHEW · 2026-08-14 · ESSAY
记录出来的同一性
—— 忒修斯之船与 OpenSpec
软件是人类造过的最纯粹的忒修斯之船
一、悖论摆正:换完所有木板之后
普鲁塔克的原版:雅典人保存忒修斯的船,木板朽一块换一块,最终没有一块原板——这还是那条船吗?霍布斯补了狠的一刀:若有人把换下的旧板收集起来重新拼成一条船,哪条才是忒修斯之船?悖论之所以成立,是因为它逼你回答一个住址问题:同一性到底住在哪里。
软件把这道题推到极限:一个活了十年的系统,代码几乎百分之百被重写过,团队换过三茬——但”这个系统”仍然是”这个系统”。凭什么?
二、四个住址:同一性住在哪里——哲学史的四个答案
OpenSpec 最精彩的地方在于:它没有在这些哲学立场里挑一个站队,而是把所有非质料的答案各自实现成了一个机制——下一节逐个看。
三、三个机制:把哲学答案做成代码
形式 → specs/。亚里士多德说同一性在形式不在质料;OpenSpec 说系统的同一性在外部可观察行为,不在代码——spec 明令禁写类名、库、实现,因为那些是木板。两套完全不同的代码,只要满足同一份 spec,在要紧的意义上就是同一个系统。
连续性 → changes/archive/。因果链答案说同一性在不间断的历史里;archive 就是这条链的实体。归档目录不是废纸堆,是船的户籍档案。
质料/形式之辨 → 一个必填的申报。这是最妙的一处:OpenSpec 强制每个变更申报自己动的是质料还是形式——悖论的核心区分在这里是一个 validate 会检查的枚举值。哲学问题变成了表单必填项。
四、霍布斯之刃:第二条船——fork 与重写之争
旧板拼成的那条船,软件世界里叫 fork,或者叫”推倒重写但沿用产品名”。哪条是真的?OpenSpec 的判据干脆:看谁继承了 spec 谱系和变更史。一个行为全变但捧着老代码的 fork,是一堆原装木板拼的新船;一次满足全部旧 spec 的彻底重写,反而是那条船的合法延续。同一性跟着契约和日志走,不跟着字节走。
五、洛克之钥:失忆的船与有自传的船
洛克说人的同一性不在肉体在记忆——你之所以是你,是因为你记得自己怎么一路走来。用这个透镜看,legacy 系统就是一条失忆的船:它存在着、运行着,但答不出”我为什么长这样”。每个接手的人只能考古式地猜。这是遗留系统真正可怕的地方——不是旧,是忘了自己。
六、消解:悖论的终局,与换零件的勇气
追问”哪条是真船”之所以无解,是因为提问者假定同一性必须托付给某个”东西”。过程哲学的回答——赫拉克利特的河、佛家的相续、OpenSpec 的变更流——是:实体就是过程本身。船就是那本日志所记述的连续换板史,代码只是这条流在此刻的物化缓存。悖论不是被解答的,是被消解的:有航海日志的忒修斯之船不再是悖论,是一份谱系。
这也给渐进式引入 OpenSpec 的策略(不大动干戈,未来变更时顺路使用,久而久之全船换遍)一个最稳的哲学地基:你敢慢慢换零件而不焦虑,恰恰因为你从一开始就没打算把系统的同一性托付给零件——你把它托付给了日志。
七、对照表:悖论要素 ↔ OpenSpec 机制(可检验的映射)
| 忒修斯之船 | 哲学立场 | 软件 / OpenSpec 对应物 |
|---|---|---|
| 木板 | 质料 | 代码——十年间被替换殆尽,不可托付同一性 [ 靠不住 ] |
| 船形与功能 | 形式(亚里士多德) | specs/ 行为契约:禁写类名/库/实现,只写外部可观察行为 |
| 修船史 | 连续性(因果链) | changes/archive/:每次换板一条归档,船的户籍档案 |
| “忒修斯之船”这个名字 | 假名 / 约定论 | 仓库名、产品名——必要但最薄的一层 |
| 换一块朽板 | 质料变、形式不变 | refactor:须宣誓 skip_specs: true |
| 改造船体 | 形式变更 | delta spec:ADDED / MODIFIED(完整新版整块替换) |
| 拆掉一段甲板 | 形式的截除 | REMOVED + Reason + Migration——截肢须留知情同意书 |
| 霍布斯的第二条船 | 同一性竞争 | fork / 沿名重写——裁决依据是 spec 谱系与变更史,不是字节 |
| 失忆的船 | 洛克:同一性在记忆 | legacy 系统:存在但答不出”我为什么长这样” |
| 船的自传 | 叙事同一性 | specs(人格)+ archive(记忆):新 session 接手=读回忆录 |
| 河流(赫拉克利特) | 过程本体论 | 系统=变更之流;代码=流在此刻的物化缓存 [ 总纲 ] |

Leave a Reply