首页 / 时辰吉凶

同一份代码换了协议版本,为什么合规判断全变了

同一份代码换了协议版本,为什么合规判断全变了

上周帮一个做嵌入式的同份小团队看仓库,发布前夜他们才发现:从上游拿来的代码断全一个网络库,在老分支里是换协 MIT,合并到新分支后变成了 AGPL。议版静态库直接链进了自家固件,本为变原本以为“MIT 随便用”,什合结果整条产线的规判发布计划卡住。问题不在代码,同份在于他们只在合并时看了 diff,代码断全没看 LICENSE 文件的换协版本变化。

正确顺序其实不复杂:先定版本,议版再看差异,本为变最后才谈能不能用。什合倒回去复盘,规判那天晚上他们踩的同份每一步都很典型。

合并前那一晚:先确认协议版本,而不是先看代码

他们的动作是打开 Git 历史,直接搜“license”关键字,看到 MIT 就放心了。失手点在于:搜到的是旧提交里的文本,不是当前分支的 LICENSE。

正确动作是先锁定版本。开源协议常识在版本之间的差异,第一步就体现在“协议版本号”上:GPL-2.0 和 GPL-3.0 不是同一份文本,Apache-2.0 和 Apache-1.1 的专利条款也不一样。看仓库根目录的 LICENSE、COPYING,再看 package.json、pom.xml、Cargo.toml 里的 license 字段,两处对不上就以文件为准,并记下具体版本号。

这一步的判断标准很简单:能不能说出“我用的是某某协议第几版”。说不出来,后面的判断都不作数。

把上游和本地两份 LICENSE 并排打开

他们犯的第二个错,是只看了自己仓库的 LICENSE,没看依赖树里每个包的。那个网络库是二级依赖,LICENSE 在子目录里,被主仓库的 MIT 盖住了。

具体动作:把上游原始仓库的 LICENSE 和本地引入后的 LICENSE 并排打开,逐段比对。重点看三处——协议名称和版本号、免责声明段落、附加条款(比如署名要求、专利授权、网络使用条款)。南北差异往往就藏在这几段里,而不是开头那一行标题。

如果两份文本不同,先别改代码,先问一句:是上游升级了协议版本,还是本地有人替换过?前者是合规问题,后者是流程问题,处理方式完全不同。

用依赖清单反查,而不是凭印象判断

他们的第三个失手点更隐蔽:凭记忆认为“这个库一直是宽松协议”。记忆不可靠,依赖清单才可靠。

动作是生成一份完整依赖清单,把每个包的名称、版本、协议标识列出来。npm 用 license-checker 一类工具,Python 看包元数据里的 License 字段,Java 看 POM 的 licenses 节点。工具输出会有噪音,标识写成“MIT OR Apache-2.0”这种双协议的要单独标出来,不能默认选宽松的那个。

这一步的判断点:清单里出现 AGPL、SSPL、BUSL 这类带使用场景限制的标识,就要停下来单独评估,别混在“宽松协议”里一起过。开源协议常识在这里的价值不是背条款,而是知道哪些标识必须先查再动手。

发布前最后一道:把结论写进发布检查单

他们最后没有删库,也没有连夜重写。做法是把那个网络库降回旧版本,锁住版本号,并在发布检查单里加了一行:每次合并上游前,先 diff LICENSE 文件,记录协议版本变化。

这一步的动作很小:在 CI 里加一个检查,LICENSE 文件变动时触发人工确认;在 README 里写清当前使用的协议版本和依据。判断标准是:任何人接手时,能在五分钟内说清“这个依赖是什么协议、哪一版、为什么可以用”。

如果评估下来确实不能用,下一步不是自己猜,而是找上游确认是否有其他授权方式,或者换一个协议更清晰的替代库。涉及商业分发、SaaS 部署这类场景,拿不准就找法务或官方渠道核对原文,别靠论坛帖子下结论。

协议文本本身不复杂,复杂的是版本和依赖层级。把“先定版本、再比文本、后查清单”这三步固定下来,比记住某一条条款有用得多。

作者:节气时间