
2026/05/20 4:22
オープンソースプロジェクトが死に至る愚かな方法たち
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
オープンソースソフトウェアは、活発なツールから使えなくなった「行き詰まり」の状態に移行することが頻繁に起こります。この過ちは単なる無視ではなく、人間による放棄と構造的な脆弱性に起因するものであり、その原因には多様な要因が挙げられます。人間の要因としては、消える維持者(ゴースト・メインターネーター)が存在し、これが単純な不活動と見分けがつきにくい場合もあります。学位取得や解雇後のプロジェクトで終了する「卒業生」や「企業孤児」、活動的だが精疲労に陥っている開発者の burnout、そして管理権が到達不可能になる継承デッドロックなども含まれます。
さらに財政的・構造的な罠も指摘されています。助成金などの資金崖(フール)による資金の終了、破壊行為や悪意のある目的のために乗っ取られた維持者アカウント、元ツールの消失ながらアーティファクトが残る「ビルド考古学」などがそれです。具体的な脅威としては、「抗議ソフトウェア」と呼ばれる意図的な破損(例:left-pad インシデント)、潜在的な後継者を追い出す有毒なゲートキーピングがあります。
また、エコシステムはアーキテクチャ的漂流という課題に直面しています。プロジェクトがレガシーランタイムや旧バージョンに置き去りにされる場合、API の rug-pull によって外部依存関係が終了する例、ネイティブ言語機能がポリフィルを代替するケース、そしてライセンス変更によりユーザーが古い「オープンコア」版に制限される現象などがあります。実例としては、Google の「インフラストラクチャ墓地」、xz ソシアルエンジニアリング攻撃のようなインシデント、「シャドー維持」されておりパブリックバージョンは実際のプライベート状況に遅れているレポジトリなどが挙げられます。最終的に、これら全ては、ビルドできないコードに直面するユーザーや、サプライチェーン攻撃に晒されるリスクにある企業にとって深刻な帰結を招きます。その結果、ステークホルダーが空洞化または破損したシステムに拘束され、全体的な革新が遅延するという事態を招くことになります。
本文
『バーニーの週末』は、最も信頼に拠るべきオープンソースパッケージの相当数が既に停止していることを示し、プロジェクトがそのような運命を迎えるには様々な要因があることも明らかにしました。
メンテナ不在の場合
- ゴーストメンテナ:最も単純で一般的なケースです。最後のコミットは数年前のもので、未解決の問題が蓄積しているにもかかわらず、リポジトリがアーカイブされていないため、それを示唆するフィルタリングには表示されません。通常、メンテナは他のことに専念し、プロジェクトへの関心が薄れたため、公式に引き継ぎや停止手続きを行わなかったことが原因です。しかし、その沈黙はメンテナ自身が生還しているにもかかわらず死亡していた場合までを隠蔽するため、レジストリもリポジトリもこれを表す手段を持っていません。外部からは長期休暇中のように見え、未解決の問題が蓄積して沈黙が疑いを解く水準に達するまでは区別できないため、『バーニーの週末』リストの上位には主にこのタイプが含まれます。
- 企業の孤児:企業がチームを設けて構築・オープンソース化したプロジェクトで、その後、方向転換やリストラによりチームが消滅し、README が更新されませんでした。GitHub の組織には会社のロゴが残っており、かつて管理権を持っていたメンバーも去っていますため、現在同社に残る誰もがこのプロジェクトが自社のものだとは認識していないことがよくあります。グーグルの「霊園」と呼ばれる事例が有名ですが、一定規模を超えたどの会社にもいくつか存在し、インフラとしてではなく製品としての位置づけだったものは、廃止に関する通知さえ出されない傾向があります。
- 修士論文の孤児:大学院生によって修士課程や博士課程の研究プロジェクトのために構築され、以来卒業して他分野へ進んでしまったケースです。リポジトリは所属研究科的名义上所有していますが、継続に必要な文脈を持つ人物もおり、学術界からは新規出版に比べ既存ソフトウェアの維持に引用権限や評価上の価値が認められないため、誰も引き継ごうとはしません。研究用ソフトウェアには多くの此类の例があり、記述したコードが構築できなくなっても数年後まで論文が参照されていることがよくあります。
- 資金切れの崖:助成金または固定期間の sponsorship(支援)により運営され、通常は財団や公共ソフトウェア基金から提供されるものであったりしますが、予定通りに資金が尽きたケースです。メンテナたちは家賃を支払う他の仕事に戻り、フルタイムで機能していたプロジェクトはようやく夜間・週末の労働になり、その規模では何の意味も持ちません。支援者のロゴは README に長期にわたって残っており、これを見て健全な支援プロジェクトと誤認しやすいのがこのタイプです。
- 採用され移動:メンテナが企業により採用され、雇用契約上または単に新しい業務負荷の増大によりプロジェクトが停止したケースです。稀に競合他社が課題を撤廃するという意図的なケースもありますが、より一般的なものは悪意的ではないためで、Apple は外部オープンソース開発を禁じる典型的企业であり、メンテナが加入するとデフォルトでプロジェクトが静かになります。手前の引き継ぎを行うことが明らかな解決策ですが、それを期日に間に合わせることはほとんど誰もしません。
- 後継者による死結:元メンテナに連絡がつかず、引き継ぎ意愿者がいるものの、レジストリにおける公開権限は他者がアクセスできないアカウントと紐付いており、GitHub リポジトリにも他の管理者が存在しない状態です。また、レジストリの放棄されたパッケージ処理プロセスには元のメンテナの同意が必要であり、あるいは数ヶ月に及ぶ紛争を必要とし、明確な当事者として立ち入る立場を持つ者がいないためです。PEP 541 プロセスや npm の紛争対応ポリシーはまさにこのために存在しますが、フォークしてリネームするよりも時間がかかるのが常態です。
メンテナが存在する場合
- 燃え尽きた高原:どの指標を見ても依然として活動的です。タイプ修正や依存関係の更新がマージされ、問題には「ありがとうございます、検討します」といった反応が偶発的に現れますが、実際に設計判断やデバッグセッションが必要なものはエネルギー不足のため indefinitely 開かれたままです。フォークを提案する者も最近のアクティビティを指摘されますが、実際に shipping(リリース)するには至らない程度のものであり、これが数年間維持されていながら「完全に停止している」と感じるほどにはなっていない状態です。
- 慈愛のゾンビ:コントリビューショングラフは濃緑色で、すべてのコミットがボットによるものです。Dependabot による依存関係更新、自動マージルール、更新をきっかけにした自動リリース、そして人間が一切確認しなくても灯りを維持できるスケジュール化されたコーディングエージェントによる運用です。すべての更新基準に基づく健康スコアは良好と評価していますが、これも更新基準に基づく健康スコアの根本的な問題そのものです。
- 監禁闘争:複数の共メンテナの中で対立が生じ、互いをブロックするだけの権限を持ちつつも、単独では進めることはできないため、プロジェクトが両者によって凍結されている状態です。フォークで解決するか、いずれ一方が去って解決に向かう可能性がありますが、多くのケースでは Issue トラッカーに「何が起きているのか」と問うユーザーが増えており、矛盾する回答しか返ってこないまま放置されることになります。
- 知識の喪失:コードは動作しテストも通りますが、なぜそうなるか理解していた人物が離脱し、残っている誰も構造的な部分への触れを安全だと確信していません。実際には読み取り専用モードとなり、端部の小さなパッチ程度なら問題ありませんが、構造上の改修は試みてもリスクが高すぎるためです。数値計算や解析コードで特に多く見られ、一人の人が 10 年前の論文から実装したアルゴリズムを独自に記述した部分が核心となっているためです。
- 毒性のゲートキーピング:メンテナ自身が現場にいて攻撃的です。新規コントリビューターは厳しいレビューを受け、二度と戻ってこなくなります。バスター(Bus Factor)は常に 1 に留まり、誰もレポジトリを共有して耐えられることはありません。コミット数やクローズされた Issue 数の指標では健全に見えますが、その唯一の人物がやめてしまうとゴーストメンテナ型のケースとなり、後継者のプールが存在しなくなります。なぜなら以前から引き継ぐことを志した人は全員追いやられているためです。
サボタージュと乗っ取り
- 乗っ取られたメンテナ:コミット権限または公開権限が敵対者によって取得されます。
の事例は高度なもので、過労に喘ぐ単独メンテナに対する 2 年間のソーシャルエンジニアリングキャンペーンの結果、共同メンテナが追加され、それがバックドア付きのリリースを shipping しました。2018 年のxz
の事例は単純で、元の著者がボランティアから頼まれごとを受け、その後下流依存関係にウォレット盗みツールを追加しました。いずれのケースでも、乗っ取り中プロジェクトは以前よりも健全に見えました。なぜなら新たなメンテナが作業を遂行していたからです。event-stream - 抗議用ソフトウェア:正当なメンテナが意図的に自分のパッケージを破壊します。
とcolors
は 2022 年に著者によりサボタージュされました。同年にはfaker
がロシア・ベラルーシの IP アドレスを対象としたペイロードを shipping し、また 2016 年の npm との紛争中にnode-ipc
は完全に unpublished されました。動機は様々ですが、下流への影響は同じです:レジストリ上のコードが人々が思い描いていたものと一致しなくなり、警告なしに実行されます。left-pad
リリースパイプラインの破損
- 維持はされているが発行されていない:開発は進行しており修正も Git にマージされていますが、誰もうまくリリースできません。公開権限を持つアカウントが消え失せたり、二段階認証デバイスを失ったり、所属企業が存続しなくなったりします。下流側は最後の公開バージョンに固定されながら、必要な修正はリポジトリ上で確認可能ですがレジストリからはインストールできない状態となり、これが元の『バーニーの週末』ポストで多くの時間を費やしたシナリオです。
- メインブランチからの解放不可能:デフォルトブランチが最後のタグから十分に逸脱しており、リリースすると全員にとってbreaking change(不具合変更)となるため、誰もしり込みしたくなく、タグ付けもされません。新規コントリビューターはメインブランチにパッチを適用しますが、ユーザーは数年前のコードを実行しており、このギャップが広がり、リリースを行う作業自体がプロジェクト化してしまいますが、スタッフがつくることができません。
- 構築考古学:公開されたアティファクトは動作しますが、誰も再構成できません。CI サービスが消滅したり、ベースイメージが削除されたり、メンテナの持っていたツールバージョンやノートPC が失われたりします。新しいリリースを行うにはまずビルド環境を再構築する必要があり、それについて何が設定されていたかはそれを手がけた人間と共に消えてしまいます。
- シャドウメンテナンス:真の開発は企業のprivate monorepo 内で進行し、公開リポジトリへは定期的なsquash コードダンプ(コミットメッセージには"sync.」程度のもの)が追加されます。公開リポジトリに対する Issue や PR はどこにも到達せず、そこで作業している人間はいません。オープンソースプロジェクトは閉鎖されたプロジェクトの発行チャンネルに変質し、外部から見ればシャドウメンテナと区別がつかないためです。ただしsync が降臨する日だけは例外となります。
- 孤立したメジャーバージョン:プロジェクトは v4 で維持されており積極的に開発が続けられていますが、エコシステムの多くはまだ v1 に留まっています。v2 は書き直しであり移行できなかったため、v1 は数年前からメンテナの関心が欠如しています。「プロジェクト」が死んでいるかどうかは、どのメジャーバージョンを問うかに依存し、最もインストールされているバージョンが関心を集めているとは限りません。
- レジストリ孤児:パッケージはレジストリから解決でき、メタデータのソースコードリポジトリURL は404エラー(削除済み、private に切り替えられたか、レジストリ更新なしに移動されたか、ホスティングサービス自体が停止した)を示します。Issue を提出したりフォークしたりする場所がなく、tarball が過去に存在していたソースコントールの何とでも整合しているかを検証する手段もありません。npm の約 1.7% と Packagist の約 4% は存在しないリポジトリを指しており、そのうちかなりの数がまだインストールされています。
不可抗力
- 制裁による孤立:メンテナは能力もあり意欲もあるものの、レジストリが自国の管轄域をブロックしたり、アカウントが輸出管理の下で凍結されたりしてプッシュできません。過去数年間で npm や GitHub の数件のアカウントがこれにより停止されています。下流側からはゴーストメンテナと同じように見えますが、メンテナは他プラットフォーム上で状況を大声で説明することが多いのが特徴です。
- 削除の犠牲者:DMCA 請求商標紛争の結果、レジストリまたはホストから削除されました。
は 2020 年の削除後に復活しましたが、多くの小さなプロジェクトではそうではなく、請求の有効性にかかわらずパッケージがまだ解決するかどうかは関係ありません。youtube-dl
世の中が進んだ
- プラットフォームによる孤立:終息期(EOL)のランタイムに縛られています。Python 2 のみで動作し、CI イメージから除外された Node バージョンを必要とし、コンパイラ拡張が削除されたものに依存します。ポートリングには残っている誰一人として取り組む意欲を持たず、必要なプラットフォームが次第に利用可能な場所から姿を消していきます。
- 伝播的死:プロジェクト自体は問題がなくメンテナも存在し協力意愿がありながら、自らの依存関係ツリーの 2〜3 レベル下にリストにあるルートのいずれかにより死亡したものが存在しており、書き直さずに交換できません。プロジェクトは自らのリポジトリに変更がなくてもその死を継承するため、これは再帰的なケースです:ここに記載されているすべての項目もまた、あなたに依存するものを殺す方法でもあります。
- API の絨毯引き上げ:プロジェクトが外部サービスをラップしており、所有者が撤退しました。サービスレイヤーでは API が停止または価格変更によりアクセス不能になったクライアントライブラリであり、Twitter の 2023 年の変更と Reddit の動きが一度にその世代を殺しました。プラットフォームレイヤーではブラウザがインターフェースを廃止するか、OS が機能を制限し、NPAPI や Flash、Chrome アプリなどの上に構築されたすべてを説明します。いずれの場合もメンテナは自社の側から何もする手段がありません。
- 代替:プロジェクトが目指すことはもはや必要ありません。実装していた規格が置き換えられたか、言語自体が原生的に同じことをできるようになったためです。
出現後のObject.assign
、ES2015 後の lodash の単一関数パッケージ、多様な promise や fetch のポリフィル、そしてプロトコルレベルでは誰も発信していない形式のための多数のライブラリなど。メンテナは合理的に停止し、数十万のロックファイルが依存関係をまだ解決できるのに削除しないのが優先でインストールを続けます。object-assign
プロジェクトの分裂
- フォークの不毛地帯:意見の相違またはメンテナの離脱によりプロジェクトが 2 つ以上のフォークに分裂し、明らかに勝者がいません。下流側は分裂前の最後のバージョンに固定され、フォークが失われるリスクを負うことを望まず、インストール計数は元のバージョンに留まりつつ、開発努力は他の名前で別の場所で行われます。
とio.js
は最終的に再び統合され、Node
も FFmpeg に再統合されましたが、多くの小さな分裂は一切解決することなく残っています。libav - ライセンス変更の余波:プロジェクトがオープンソースではない何かにリライセンスされ、旧ライセンスに基づくコミュニティフォークが存在しますが、採用がそこへ集約されていません。Terraform/OpenTofu や Redis/Valkey はこの道程の途中にあり、Elasticsearch はさらに数年先です。多くのロックファイルは元の最後のオープンライセンスバージョンを指しており、現在は誰も維持しない固定点となっています。
- オープンコア空洞化:興味深い開発は商業版へ移動し、オープンソースリポジトリは無料層として保持されます。リリースは行われますが、主にバージョン番号の更新や有料製品と区別されないものであり、当初プロジェクトに参加した人々は実質的に異なる小規模なプロジェクトへと変貌しており、改名されることなくそのままです。
メルボルン・メトロ安全性キャンペーン(このポストにちなむもの)は「電車の周りを安全に」という行動可能なメッセージで締めくくられます。上記のどのパターンが当てはまるにせよ、パッケージの解決結果は同じであり、あなたのロックファイルも墨镜をかけたパーティー車でそれをぐるぐる回し続けるでしょう。誰も近づいて詳しく見なければ限りです。