鯨落
アンドレイ・カルパティは、オープンソースプロジェクトの維持終了後に見られるフォーク、APIの継承、仕様標準化という「クジラの死骸(Whale Fall)」現象を分析し、技術的負債が生態系として持続するメカニズムを示唆している。
キーポイント
フォークによる生態系の形成
プロジェクトが放置されると、ハエやサメのような「スカベンジャーフォーク」が登場し、その中からLibreOfficeやJenkinsのように主要な代替プロジェクトが育つ過程を説明する。
APIとインターフェースの継承
Google Reader終了後のFeedlyやMinifluxのように、公式ライセンスに関わらず公開されたAPIやデータ形式が、後続のツール群によって事実上の標準として継承される事例を挙げる。
構造的な骨格の永続性
DockerのOCI寄付やTree-sitterの例のように、特定のプロジェクトが衰退しても、その定義したプロトコルやファイル形式(骨格)が他のエコシステム内で長期的に利用され続ける現象を指摘する。
維持されていないライブラリの継承サイクルと失敗モード
プロジェクトが放置されるとフォークが繰り返され、最終的にコードではなく概念が移植される。この「 successive recolonisation 」には重大な脆弱性がフォークを通じて継承され、監査されないまま残るという失敗モードがある。
ライセンス変更時のフォークとコミュニティの反応
プロジェクトがオープンソースからソース利用可能へライセンスを変更すると、コミュニティは直ちに最後のオープンコミットをフォークして競い合う。これにより、元のコードベースは外部の貢献を受け付けなくなり、フォークが独自に発展していく。
OSスケールでのフォークパターン
CentOS Streamの移行に伴うRocky LinuxやAlmaLinuxの台頭は、ライブラリレベルのフォークパターンがOSスケールで再現された例であり、パッケージング形式などの基盤構造は特定のディストリビューションの存亡に関わらず持続している。
抽象化レイヤーの永続性
ライセンス紛争やプロジェクトの存亡を超えて、互換性シェムを通じて元のAPI構造が長期間にわたって維持されることがある。
影響分析・編集コメントを表示
影響分析
この記事は、オープンソースエコシステムにおけるプロジェクトのライフサイクルと技術的負債の継承メカニズムを生物学的な比喩で明確に示した。開発者や組織にとって、単なるコードの維持管理だけでなく、API設計や仕様の公開が長期的な互換性エコシステムを形成することの重要性を理解する上で示唆に富む。特に大規模なインフラプロジェクトの終了時におけるフォーク戦略や標準化プロセスの予測に役立つ洞察を提供している。
編集コメント
アンドレイ・カルパティによるこの洞察は、技術的負債を単なるコストではなく、新しいイノベーションの土壌となる資源として再定義する視点を提供している。プロジェクト終了後のフォーク戦略やAPI設計の重要性を再評価する上で有益なフレームワークである。
外洋でクジラが死ぬと、その死骸は深海の底に沈み、一つの生態系となる。海洋生物学者はこれを「クジラの落下」と呼び、その死骸は重なり合う三つの段階で生命を支える。移動性の腐食生物が数ヶ月かけて軟組織を剥ぎ取り、富化機会主義者が何年もかけて骨と周囲の堆積物に定着し、化学合成細菌が数十年にわたり骨格そのものを栄養源とする。骨に蓄えられた脂質をエネルギーに変換し、特殊化した生物群集全体を支えるのだ。たった一つのクジラの落下が、本来なら不毛の海底で、50年にわたって生命を維持することができる。
マイケル・ウィンサーが、放棄されたプロジェクトの依存関係グラフに何が起こるかについて話している時、何気なくクジラの落下について言及した。それ以来、そのことが頭から離れない。
大規模なオープンソースプロジェクトがメンテナンスされなくなる。メンテナーの燃え尽きかもしれないし、背後にある会社の方向転換かもしれない。プロジェクトは更新を止めるが、消滅はしない。GitHubに残り、issueを蓄積し、最後のコミットは過去へと遠ざかり、誰かが最も緊急のパッチをマージし始めるためにフォークする。プロジェクトが十分に人気があれば、複数のフォークが現れ、ユーザーを争う。それはちょうど、メクラウナギが鯨脂を奪い合うようなものだ。ただし、ほとんどのフォークはすぐに消え、時間的余裕のある誰か、あるいは組織的な支援を得た誰かが続ける力によって、一つ二つが生き残る。OpenOfficeはこのようにしてLibreOfficeに、MySQLはMariaDBに、HudsonはJenkinsになった。それぞれが腐食生物のようなフォークであり、フォーク発表、移行ガイド、「なぜ乗り換えるべきか」というブログ記事というお決まりの流れを通じて、正統な後継へと成長したのだ。
その後、より小さなプロジェクトが、死んだプロジェクトのデータ形式をターゲットに、特定のモジュールを抽出したり、ツールを構築したりし始める。Google Readerはオープンソースではなかったが、サービス終了時には同じことが起こった。Feedly、Miniflux、FreshRSS、Tiny Tiny RSS、その他多数が空白を埋めようと殺到し、そのうちいくつかはGoogle Reader APIやFever APIを実装した。それらのAPIが優れていたからではなく、長年にわたってそれらに対応するように構築されたRSSクライアントが存在したからだ。ライセンスは問題ではなかった。インターフェースが公開されており、他のソフトウェアがそれらに依存していれば、それで十分だった。
そして、構造的な骨格、すなわちプロトコルやファイル形式、API契約は、その骨がどこから来たのかさえ知らないかもしれない特殊なコミュニティを支え続ける。OpenDocument Formatは、それを生み出したOpenOfficeコミュニティよりも長生きし、数十もの言語エコシステムにまたがる文書形式ライブラリによって支えられている。Dockerは2015年、そのコンテナランタイムとイメージ形式をOpen Container Initiativeに寄贈した。OCI仕様は現在、ランタイムに関係なくコンテナがどのように動作するかを定義している。Docker自身の支配力は衰えたが、仕様は衰えなかった。Tree-sitterはAtomのために構築されたが、GitHubがAtomをアーカイブした後、それはZed、Neovim、Helix、そしてここ数年でリリースされたほとんどのエディタ内部のシンタックスエンジンとなった。
メンテナンスされていないライブラリで私が気づき続けているパターンは、連続的な再定着だ。プロジェクトが静かになり、誰かがフォークし、他のプロジェクトがそのフォークに依存し始め、そしてそのフォークのメンテナーも燃え尽き、サイクル全体がより小さな規模で繰り返される。フォークの各世代は通常、前の世代よりも小さく、貢献者もユーザーベースも狭まり、最終的にはコードではなくアイデアそのものが移行する。別の言語エコシステムにいる誰かが、蓄積された残骸を見て、コンセプトをゼロから書き直すことを決断し、設計は引き継ぐが実装は置き去りにする。
Sassはこれを経験した。最初のリファレンス実装はRubyのgemだった。Rubyのパフォーマンスがボトルネックになった時、LibSassがC++で書き直し、sassc
連続的な再定着には厄介な失敗モードがある。Ederaは、Rustのtar-rsライブラリに差分パースのバグを発見した。これは下流のすべてのフォークに影響を与えた。tar-rs自体、async-tar、tokio-tar、そしてAstral(そのフォークはuvパッケージマネージャー内部に出荷されている)のような企業がメンテナンスする複数の内部フォークだ。調整された開示は、断片化したフォークグラフにまたがる約20の組織に連絡することを意味した。そこでは4つのライブラリバージョンのうち3つがメンテナンスされておらず、複数のメンテナーに連絡が取れなかった。この脆弱性が存在したのは、コードが連続するフォークを通じてコピーされ続け、誰もがオリジナルから継承したPAXヘッダーのパース部分を再監査する者が誰もいなかったからだ。バグは最初から骨の中に潜んでおり、すべてのフォークに継承されていたのだ。アドバイザリによってパッケージのどのフォークが影響を受けるかを発見することは、私が別途取り組んでいる問題だ。なぜなら現在、そのための優れたツールを誰も持っていないからだ。
Streamへの転換後のCentOSは、オペレーティングシステム規模で同じパターンだ。Rocky LinuxとAlmaLinuxがフォークし、それらを取り巻く富化層ではより小さなRHEL互換のリビルドが現れ、その下にある構造的な骨格、すなわちRPMパッケージング、systemdの慣習、ファイルシステム階層は、どの特定のディストリビューションが生きているか死んでいるかに関係なく、変わらず存続した。
ライセンス変更
プロジェクトがオープンソースライセンスからソース公開ライセンスに切り替えると、腐食生物段階はほぼ即座に、しばしば変更が発効する前にさえ、引き起こされる。RedisからValkeyへ、ElasticsearchからOpenSearchへ、TerraformからOpenTofuへ、そのパターンは今や十分に馴染み深く、コミュニティはそれをルーチンとして確立している。最後のオープンなコミットを急いでフォークし、短い間競争し、一つ二つの生き残りの周りに統合される。これらのケースでは、生物体は正確には死んでいない。製品としてのRedisには依然として収益とロードマップがある。しかし、オープンソースエコシステムの観点から見れば、コードの本体は外部からの貢献を受け入れなくなり、フォークはMariaDBがMySQLから離れていったように、オリジナルから離れ始める。
抽象化レイヤーは、持続する部分だ。オープンバージョンと統合したすべてのプロジェクトは、プロプライエタリ版に追随するか、フォークに切り替えるかの選択に直面し、その多くは互換性のための薄い層を構築するだけだ。それらの薄い層は、それらを生み出した論争よりも長持ちする傾向があり、ライセンス論争が冷めた何年も後も、オリジナルAPIの骨格を静かに栄養源としている。
サン・マイクロシステムズ
2010年のオラクルによるサンの買収は、単一のクジラの落下というより、むしろ群れ全体が同時に海で死んだようなものだった。Java、Solaris、ZFS、DTrace、VirtualBox、NetBeans、GlassFish、Hudson、MySQL、それぞれが別々の海底に沈み、独自の後継を生み出した。単一の支配的なフォークを生んだものもあれば(HudsonからJenkinsへ、ZFSからOpenZFSへ)、競合する系統に散らばったものもあり(MySQLだけでもMariaDB、Percona、そして短期間のDrizzleを養った。Drizzle自体が放棄された時、より小さなクジラの落下となった)、定着する前に財団間を揺れ動いたものもある(NetBeansからApacheへ、GlassFishからPayara、そしてより広範なJakarta EEエコシステムへ)。そのすべての下にある構造的な骨格、JVMバイトコード形式、ZFSのオンディスク形式、MySQLワイヤープロトコルは、サンを聞いたこともない開発者たちのプロジェクトにおいて、今も荷重を支えている。
浅瀬で死ぬプロジェクトもある。死骸はすぐにリサイクルされる。買収による人材獲得はこのように機能する。会社は吸収され、コードはプロプライエタリになるかアーカイブされ、知識は人々と共に分散し、他の者が栄養源とできる公開された死骸には蓄積されない。企業統合も同様の効果を持つ。なぜなら、大規模な独立したプロジェクトがプラットフォーム企業のプロプライエタリなサービスに組み込まれると、栄養分は水柱の中でリサイクルされ、後継が起こるほど深く沈むことはないからだ。
現在のクラウドプロバイダー下での統合のトレンドは、オープンソースにおけるクジラの落下率を低下させており、これが生態系の多様性に二次的な影響を与えているが、誰もそれを追跡していないと私は考えている。測定することは可能だろう。時を追って死んだプロジェクトのフォークと依存関係グラフを調べ、死んだ依存関係を参照する新しいプロジェクトがいくつあるか数え、npm、crates、rubygemsそれぞれにおけるクジラの落下の半減期を比較する。より深い海底を持つ、分解が遅い、構造的な骨格がより長持ちするエコシステムもあるのだろうか。
原文を表示
When a whale dies in the open ocean, its carcass sinks to the abyssal floor and becomes an ecosystem. Marine biologists call this a whale fall, and the body sustains life in three overlapping stages: mobile scavengers strip the soft tissue over months, enrichment opportunists colonise the bones and surrounding sediment for years, and chemosynthetic bacteria feed on the skeleton itself for decades, converting the lipids stored in bone into energy that supports entire communities of specialised organisms. A single whale fall can sustain life on an otherwise barren ocean floor for fifty years.
Michael Winser mentioned whale fall offhand while we were talking about what happens to the dependency graphs of abandoned projects, and it won’t leave my head.
A large open source project goes unmaintained. Maybe the maintainer burns out, maybe the company behind it pivots. The project stops getting updates but doesn’t disappear. It sits on GitHub accumulating issues, its last commit receding further into the past, and somebody forks it to start merging the most urgent patches. If the project was popular enough, multiple forks appear, competing for users the way hagfish compete for blubber, though most die quickly and one or two survive on the strength of someone with enough time or institutional support to keep going. OpenOffice became LibreOffice this way, MySQL became MariaDB, Hudson became Jenkins, each a scavenger fork that grew into the canonical replacement through a familiar sequence of fork announcement, migration guide, and “why you should switch” blog posts.
Smaller projects then start extracting specific modules or building tools that target the dead project’s data formats. Google Reader wasn’t open source, but the same thing happened when it shut down: Feedly, Miniflux, FreshRSS, Tiny Tiny RSS, and a dozen others rushed to fill the vacuum, several of them implementing the Google Reader API or the Fever API not because those were good APIs but because years of RSS clients had been built to speak them. The licence didn’t matter. The interfaces were public, other software depended on them, and that was enough.
And then the structural skeleton, the protocols and file formats and API contracts, goes on supporting specialised communities that may not even know where the bones came from. OpenDocument Format has outlasted the OpenOffice community that created it, sustained by document format libraries across dozens of language ecosystems. Docker donated its container runtime and image format to the Open Container Initiative in 2015. The OCI spec now defines how containers work regardless of runtime. Docker’s own dominance faded; the spec didn’t. Tree-sitter was built for Atom, and after GitHub archived Atom it became the syntax engine inside Zed, Neovim, Helix, and most editors shipped in the last few years.
The pattern I keep noticing with unmaintained libraries is successive recolonisation. A project goes quiet, someone forks it, other projects start depending on the fork, and then that fork maintainer burns out too and the whole cycle repeats at a smaller scale. Each generation of fork is typically smaller than the last, with fewer contributors and a narrower user base, until eventually the idea itself migrates rather than the code. Someone in another language ecosystem looks at the accumulated wreckage and decides to rewrite the concept from scratch, carrying the design forward but leaving the implementation behind.
Sass went through this. The original reference implementation was a Ruby gem. When Ruby’s performance became a bottleneck, LibSass rewrote it in C++, and the sassc
Successive recolonisation has a nasty failure mode. Edera discovered a differential parsing bug in Rust’s tar-rs library that affected every fork downstream: tar-rs itself, async-tar, tokio-tar, and multiple internal forks maintained by companies like Astral (whose fork ships inside the uv package manager). Coordinated disclosure meant contacting around twenty entities across a fragmented fork graph where three of the four library versions were unmaintained and several maintainers were unreachable. The vulnerability existed because the code had been copied forward through successive forks without anyone re-auditing the PAX header parsing that all of them inherited from the original. The bug had been sitting in the bones the whole time, inherited by every fork. Discovering which forks of a package are affected by an advisory is a problem I’m working on separately, because right now nobody has good tooling for it.
CentOS after the Stream pivot is the same pattern at operating system scale: Rocky Linux and AlmaLinux forked, smaller RHEL-compatible rebuilds appeared in the enrichment layer around them, and the structural skeleton underneath, RPM packaging, systemd conventions, filesystem hierarchy, persisted unchanged regardless of which particular distribution is alive or dead at any given moment.
Licence changes
When a project switches from an open source licence to a source-available one, the scavenger stage triggers almost immediately, often before the change even takes effect. Redis to Valkey, Elasticsearch to OpenSearch, Terraform to OpenTofu, the pattern by now is familiar enough that the community has it down to a routine: rush to fork the last open commit, compete briefly, and consolidate around one or two survivors. The organism isn’t exactly dead in these cases. Redis the product still has revenue and a roadmap. But from the perspective of the open source ecosystem the body of code has stopped accepting outside contributions, and the forks start drifting from the original the way MariaDB drifted from MySQL.
The abstraction layers are the part that lasts. Every project that integrated with the open version faces a choice between following the proprietary version or switching to the fork, and plenty of them just build a compatibility shim instead. Those shims tend to outlast the controversy that created them, feeding quietly on the skeleton of the original API years after the licence debate has cooled off.
Sun Microsystems
Oracle’s acquisition of Sun in 2010 was less a single whale fall than an entire pod dying at sea simultaneously. Java, Solaris, ZFS, DTrace, VirtualBox, NetBeans, GlassFish, Hudson, MySQL, each sank to a separate ocean floor and spawned its own succession. Some produced single dominant forks (Hudson to Jenkins, ZFS to OpenZFS), others scattered into competing lineages (MySQL alone fed MariaDB, Percona, and briefly Drizzle, which itself became a smaller whale fall when it was abandoned), and some bounced between foundations before settling (NetBeans to Apache, GlassFish to Payara and the broader Jakarta EE ecosystem). The structural skeletons underneath all of it, the JVM bytecode format, the ZFS on-disk format, the MySQL wire protocol, are still load-bearing in projects whose developers have never heard of Sun.
Some projects die in shallow water where the carcass gets recycled quickly. Acqui-hires work this way: the company gets absorbed, the code goes proprietary or gets archived, and the knowledge disperses with the people rather than accumulating in a public carcass that others can feed on. Corporate consolidation has a similar effect, because when a large independent project gets folded into a platform company’s proprietary service, the nutrients get recycled in the water column rather than sinking deep enough for succession to happen.
I think the current trend of consolidation under cloud providers is reducing the whale fall rate in open source, and that this has second-order effects on ecosystem diversity that nobody is tracking. You could measure it: look at the fork and dependency graphs of dead projects over time, count how many new projects cite a dead dependency, compare the half-life of a whale fall in npm versus crates versus rubygems. Do some ecosystems have deeper ocean floors, slower decomposition, longer-lasting structural influence? The data exists in package registries and forge APIs, but I haven’t seen anyone ask the question.
An open source ecosystem where every large project is owned by a platform company, maintained indefinitely or quietly absorbed on death, is one where those enrichment and chemosynthetic stages rarely get a chance to develop, and the small specialised organisms that depend on whale falls for food never get a chance to evolve. The healthiest ecosystems have a steady supply of whale falls, which is an odd thing to root for since it means wishing for the death of large projects, except that the deep ocean floor has no other food source.
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み