1 ポイント 投稿者 GN⁺ 2024-11-13 | 1件のコメント | WhatsAppで共有
  • ある開発者は、解雇によって収益を生むコードの唯一の貢献者がいなくなった経験をきっかけに、GitHub Enterpriseで「失ってはいけない人」を見つけるtruck factorプラグインを作ろうとした
  • 同僚たちは、この指標がすぐにGoodhart’s Lawに陥り、守るべき人ではなく「解雇してもよい人」を探す管理ツールになり得ると懸念した
  • 元のTruck-Factorリポジトリとデータはまだ利用できたが、データ収集日が不明で、READMEの手順もそのままでは再現できず、手作業での補正が必要だった
  • 再計算は複数のGitHubリポジトリをgnu parallelでクローンした後、Javaコードを実行する方式で、Linux kernelはlinguistフィルターなしでtruck factor 12、フィルター適用後は8となった
  • 元論文の数値である2015年のpreprintの90、正式publicationの57よりも結果が低くなっており、Linux kernelのbus factorが改善したとは見なしにくい

Bus Factorと危険なプラグインのアイデア

  • Bus FactorまたはTruck Factorとは、プロジェクトが知識を持つ人材不足で止まってしまうまでに、突然いなくならなければならない最小のチームメンバー数を指す
  • 2015年ごろ、会社の解雇プロセスで、会社に収益をもたらすコードベースの一部における唯一の貢献者が解雇されたことが出発点となった
  • Truck Numberを思い出した後、GitHub Enterpriseプラグインとして「解雇してはいけない人」を計算するアイデアが出た
  • 木曜午後のライトニングトークでこのプラグインを5分間紹介したところ、同僚たちは管理者がこれを「解雇できる人」を探すツールとして使う可能性があると見た
  • この反応の核心はGoodhart’s Lawだった

既存のTruck Factor研究と再現の試み

  • 元の研究は、複数の人気GitHubプロジェクトについて、プロジェクトが止まるには何人がいなくなる必要があるかを計算した
  • 対象にはLinux kernelも含まれていた
  • 記事の前半では、最初のpreprintがLinuxについて、止まるには80人が離れる必要があるとしていたと書かれており、後半では2015年のpreprintの数値が90、full publicationの数値が57と整理されている
  • mclareとともに、約10年後にtruck factorが改善したかを確認するため、結果の再現を試みた
  • 元著者たちのGitHubリポジトリはまだ利用できた

データと実行環境の制約

  • 論文のデータはJSONで提供され、元の可視化はスクレイピング可能なCSVを基にしていた
  • ただしデータ収集日は分からなかった
  • READMEの指示はそのままでは動作せず、GitHub Issueを参考に実行方法を修正する必要があった
  • 元CSVの1列目からGitHubリポジトリ一覧を取り出し、全リポジトリをクローンした
  • gnu parallelで複数のgit cloneコマンドを同時に実行した

gnu parallel、linguist、NixOSで詰まった部分

  • gnu parallel-j 8を指定したが、ノートPCの32コアがすべて使われる現象が起きた
  • 同時に見えるgit cloneプロセスは8個で、多数のgit index-packプロセスがすべてのコアを使っていた
  • 考えられる原因として、git index-packがforkされた子プロセスであるため、parallelが別のgit cloneを開始してしまう状況を推測した
  • Truck Factorコードはドキュメントファイルを除外するためにGitHubのlinguistを使う
  • NixOS環境でRubyの経験がなく、Ruby Gemsのインストールを時間内に解決できなかったため、Nix flakeでlinguistプラグインをインストールする方法やpull requestを求めた

実際の再計算手順

  • 元リポジトリをforkしてローカルにクローンし、READMEに沿って実行方法を合わせた
  • mvn packageでJavaソースをjarにコンパイルした
  • まずnumpyのGitHubリポジトリで各ステップを試してから、全リポジトリの再計算を進めた
  • mclareは元の可視化のCSVをダウンロードし、1列目をGitHubリポジトリ一覧に変換した
  • 実行フローは次のとおりだった
    • parallel -j 8 git clone ::: $(cat ../meta/repo_list.txt)でリポジトリをクローンする
    • gittruckfactor/scriptsディレクトリへ移動し、awkエラーを避ける
    • commit_log_script.shで各リポジトリのgit commit情報を抽出する
    • gittruckfactor-1.0.jarを実行して、抽出したcommitデータを処理する
  • 自宅の高速なギガビットインターネット接続で、すべてのリポジトリを逐次クローンするのに17.5分かかった
  • 各リポジトリの処理もおおよそ18分ほどかかったようだ

Linux kernel再計算結果

  • Linux kernelのサンプル出力はTF = 12、coverage = 49.98%だった
  • TF authorsにはLinus Torvalds、Mauro Carvalho Chehab、Rob Herring、Thomas Gleixner、Krzysztof Kozlowskiなどが含まれていた
  • Linus Torvaldsは5,712ファイル、6.59%と表示された
  • linguistプラグインなしでドキュメントとサードパーティライブラリを除外しなかった結果は、Linux kernelのtruck factor 12だった
  • mclareが自身のシステムにlinguistプラグインをインストールした後に得たLinux kernelのtruck factorは8だった

計算から抜け落ちている要素と次の確認事項

  • この計算はレビュー過程を反映していない
  • キャリアが上がるほど、開発者は自分でキーボードを叩いてコードを書くよりもレビューを多く行わなければならないという問題がある
  • 追加で確認する項目は次のとおり
    • truck factorの計算がgitのco-authored-byとreviewerヘッダーを反映しているか
    • 反映していないなら、それを計算に入れられるか
    • Linuxの数値が10年後に大きく変わった理由は何か
    • 元論文のように開発者aliasをマージするためにLevenshtein distance 1を適用していない点が結果に影響したか
    • Linux kernelリポジトリを2015年半ばの時点にcheckoutすると、同じコードが今でも80を出すか
    • 2016年にアルゴリズムが更新されたため、その後の数値を出し直せるか
  • 元論文の156件のcitationを調べ、より良い計算法があるか確認できる
  • Rustのような最近の大規模プロジェクトは2015年の論文に含まれていなかったため、現在の人気プロジェクトと過去の履歴を比較できる
  • 任意のgitリポジトリについて、年ごとのtruck numberを見つけるスクリプトも作れる

さらに低くなったBus Factor

  • 確認しようとしていた問いは、truck factorが時間とともに良くなったかどうかだった
  • 結果は良くなっておらず、むしろ悪化したという見方に近い
  • Linux kernelは、元論文の数値よりも今回の実行結果がはるかに低く出た
  • ドキュメントとサードパーティライブラリのフィルタリング有無によって、Linux kernelの結果は12から8へさらに低くなった
  • より多くの可視化と詳細はmclareの記事で確認できる

1件のコメント

 
GN⁺ 2024-11-13
Hacker News の意見
  • https://codescene.com/ の機能のひとつがまさにこれです。
    知識の島を見つけ、それを頻繁に変更されるコードと結び付けることで、変更が多いのに知識の分散が低く危険な ホットスポットを特定します。
    誰かが退職の意向を示したら、その人だけが知っているコードを簡単に確認できるので、引き継ぎ計画も立てやすくなります。
    悪用される可能性は考えたことがなく、本来は可視化のためのツールです。そういう使い方をするマネージャーはひどいマネージャーで、すでにそういう人なら、このツールがそれを変えるわけではないでしょう。

    • 「悪用」をあまり素朴に考えるべきではありません。ある国の情報機関に所属しているとしましょう。世界の軍事装備で使われている主要カーネル Kinux へのアクセスを禁じられている国 Tussia だとして、隣のオフィスの人がそのカーネルを自国内向けにフォークするプロジェクトを始めたことを知ったとします。
      昇進したいなら、獲得担当部門に「ナードと親密になる特殊訓練を受けた女性エージェント8人」を要請し、失敗した場合に備えてポロニウム8回分も予備として要請できるでしょう。
      完全な作り話に聞こえるかもしれませんが、シード投資を探していたあるユニコーンスタートアップのCEOが、実際に前半に当たる出来事を経験したのを知っています。
    • Pluralsight Flow が導入された職場を3回経験しましたが、そのうち2社では、マネージャーたちがすぐに指標をフィードバック、業績評価、採用・雇用判断に使い始めました。
      3社目では、開発者たちがこの流れを遠くからでも見抜き、ツールの利用や評価そのものを拒否しました。
      こうしたツールは価格が途方もなく高いので、承認した側はどうにか投資対効果を引き出さなければなりません。生産性、アウトプット、知識サイロを正しく測る方法がないため、結局「今週の Jose のPRは少ないね」のような話に流れていきます。
    • 可視化という用途自体は素晴らしいのですが、その領域にとどまれる場合に限られます。
      問題は、開発者もそれを見て、解雇不能な従業員リストに載るために対象プロジェクトやコンポーネントへ移ろうとする可能性がある点です。理想的には、労働者が一緒に動いて トラックファクターを0にし、誰も解雇しにくくできます。
      もちろんそうなると、ほぼ完全な時間の無駄になり、ブロガーの同僚たちが言っていた「すぐに Goodhart’s Law に引っかかる」という元の論点が証明されます。
    • 外部のコンサルティング会社が、会社の レイオフを支援するためにこれを使うこともあり得ます。マネージャーがどれほど優秀でも起こり得ます。
  • Amazon には、こうした数値をコードシステムから任意のマネージャーが実行できるレポートとして簡単に見られる仕組みがあり、チームが何をしているのか、どんなリスクがあるのかを確認する別の方法もたくさんあります。個人的には有用だと思います。
    バスファクターはひとつの観点にすぎず、別の観点からは、サイロ、他人と協業しないエンジニア、エンジニアを簡単に異動させにくい領域を見つけて改善できるようにしてくれます。
    開発者の中には代替可能性を恐れ、自分だけが知っているシステムこそ雇用の安定だと考える人もいますが、逆にそれは技術的リスクであり、優秀なエンジニアがより重要なプロジェクトへ移れない要因にもなり得ます。嫌いなシステムにうんざりしたときに、別の仕事をできる道でもあります。

    • 代替されることが怖いわけではありません。どこかが私を必要としていないなら、私もそこにいたいとは思いません。
      ただし、代替可能性という発想は大きなオーバーヘッドを生み、有能な人たちを最大限の能力で使えなくします。彼らは実際には代替可能ではないからです。
      ある場所では必要ですが、別の場所ではプロセスのオーバーヘッドのほうが、バスファクターよりもプロジェクト成功に対するはるかに大きなリスクになります。
    • 簡単に代替要員を補充できないという理由で、異動と昇進を拒否された開発者を知っています。
      結末は3か月以内の退職でした。
    • 「代替できないなら昇進できない」
    • 会社の収益最適化が主目的ではない従業員の立場からすると、自分だけが知っているシステムが雇用の安定になるという考えも現実的な戦略です。
    • キャリアを通じて、自分や他の開発者をできるだけ 代替可能にしようとしてきました。デジタル化業務のかなりの部分はそもそもそういう仕事ですし、知識サイロに対処するのが面倒だからでもあります。
      バックエンドでも TypeScript を多用する理由のひとつは、小さなチームが知っておくべき言語をひとつに減らせるからです。そのため、フロントエンド開発者が休暇に入っても実際に連絡を断てますし、他の人がカバーできます。誰かが転職しても痛みは少なくなります。
      一度も問題になったことはなく、代替可能性は健全なシステムの一部だと思っています。管理側に数年いて最初に学ぶのは、「誰もが代替可能であり、それはコストの問題にすぎない」ということです。だから知識レベルが高すぎると、むしろ経営陣がそのリスクを下げようとして不利に働くこともあります。特に経済的理由によるレイオフはかなりランダムでもあります。
      とはいえ、こうした滑稽な指標を使う場所で働きたいとは思いません。良い仕事をするためにレッドテープを増やせば増やすほど、一緒に働きたいと思う可能性は低くなります。こうしたものは、人々に良い仕事をさせるよりも 指標をゲーム化させがちで、生産性と品質に良くない文化を生みやすいです。
  • gnu parallel は要求どおり git clone を8個同時に実行しており、それぞれの git clone が勝手に大量の index-pack スレッドを起動している状況。
    ここでは git configpack.threads を一時的に1に設定すると助けになる。

    • ますます一般的になっている問題。2つの階層がどちらもCPUやコア数ぶん並列化してマシン全体を使おうとし、内側の階層で N²個のスレッド/プロセス が発生する。
      二乗で増えるため、CPUが多いほど問題はさらに悪化する。32コアなら 32² = 1024 で、実際には Parallel に8個を指定しているので最大256個程度の index-pack プロセスで止まっていたはず。それでもこれをさばくには大量のメモリが必要で、実際には何の得にもならない。
      解決策は、2つの階層のうち片方だけを並列化すること。
      pack.threads についての man git-config の説明はこうだ。最適なデルタ一致を探す際に生成するスレッド数を指定し、git-pack-objects(1) が pthreads 付きでコンパイルされている必要がある。そうでなければ警告とともに無視される。マルチプロセッサマシンでパッキング時間を短縮するためのオプションだが、デルタ検索ウィンドウに必要なメモリはスレッド数ぶん乗算される。0を指定すると、Git がCPU数を自動検出し、それに合わせてスレッド数を設定する。
    • git config で一時設定する代わりに、単に git -c pack.threads=1 clone を使えばよい: https://git-scm.com/docs/git#Documentation/git.txt--cltnameg...
  • この解釈はいまいち。この文章はすべてのエンジニアリングリーダー向けのものだと思う。
    バスファクター は、チームの誰か、あるいは自分自身がバスに轢かれたときにチームがどれだけ苦しむかを意味する。
    すべてのチームメンバーについて理想的なバスファクターは0。最初は「全員を使い捨てにしろ」と聞こえるかもしれないが、実際にはほぼその逆で、そこが要点。
    チームは a) 自律的で、b) 謎がないと言えるほど良い状態であるべき。理想的な状態では、全員がすべてがどう動いているかを理解している。新入社員はすぐ価値を生み始められるべきで、退職する社員は未知の領域が残っていないことに安心できるべき。
    全員のBFが0である理想的なチームは望ましい。チームメンバーが代替可能という意味であり、誰かが病気になったり休暇を取ったり実際に辞めたり排除されたりしても、すべてのメンバーが穴を埋められるという意味。
    さらに重要なのは、0 BF が 単純性 の反映であること。ソフトウェア、ビルド・テスト・デプロイのパイプライン、ドキュメント、サポート体制がすべて凝集性と一貫性を持っているべき。情報をチームメンバーの中にサイロ化するのは悪いことで、全員がビルドしデプロイできるべき。
    0 BF は健全な指標だが、メール数、コミット数、PR数、コード行数、応答速度、GitHub ヒートマップのようなもので測定されることは絶対にない。そうした指標は何も示せず、むしろ有害でひどい指標。
    こうした指標で人を評価するのは、タイプライターの前の猿と変わらない。もっと多くのスタートアップがこれを聞くべき。

    • バスファクターはいつも逆の意味で聞いてきた。「プロジェクトが継続不可能になるには何人がバスに轢かれる必要があるか」という形で、最適値はチームメンバー数と同じだと理解していた。
      同じ概念を話しているようだが、その数字が常に同じ向きで使われるわけではないことに驚く。
    • 世界中で特定の技術を持つ人が数えるほどしかいないプロジェクトで働いたことがある。その時点でのバスファクターは間違いなく1だった。
      可能性の境界を押し広げるプロジェクトでは、単純性 が選択肢ではないことがある。もちろんソフトウェアプロジェクト全体の中では小さな割合だが、前例のないことをするときは、コードを可能な限り単純に保つことよりも「そもそもこれをどうやって実現するのか」のほうが大きな心配になる。
      コード品質が低くてもよいという意味ではない。ただ、難しいことをしていると複雑なコードが必要になることがあり、何世代か後になってようやく設計パターンが整理され、その難しいことをより複雑でないコードで作れるようになる場合もある。それは10年後かもしれない。
    • 初日から誰でもコードを理解でき、ドメイン知識も必要ないものだけを作るなら、そのプロダクトやチームの 価値提案 は何なのか。
      作れる最も複雑なものがToDoアプリ程度なら、社会に大した価値は生み出せないと思う。
    • 自分の仕事がうまく、自信のある人は積極的に自分の バスファクター を下げようとする。
      バスファクターが高いということは、雇用主があなたの将来の潜在力ではなく、過去にやっておいたことのためにあなたを引き留めているという意味。
    • 軍隊はそう考える。人を失っても回り続けなければならないことを前提にしている。
  • 元論文の核心的な主張はこの部分。
    「私たちの推定はカバレッジ仮定に依存している。現在の著者集合がシステムの現在のファイル集合の50%未満しかカバーしていない場合、システムは深刻な遅延を経験するか、停止する可能性が高い」
    ここでファイルの著者は、事前計算された重みに基づいてそのファイルに意味のある貢献をしたユーザーとして定義される。

  • 一方では、この種のダッシュボード指標がすでに何らかの企業向けソフトウェアに入っていないとしたら、むしろ驚くと思う。以前の会社の経営陣は、部署内でメールを最も多く送受信した人が誰かについて 日次レポート を作れるかと実際に尋ねてきた。
    どこへ向かうのか気に入らなかったので断ったが、別の同僚が作った。予想どおり、最も多くメールを受け取り送っていたのはシステム管理者だった。複数のサーバーの自動メール送信者として彼のアカウントが設定されていたからだ。彼は1日に数百通の通知メールを自分自身に送っており、購読していたニュースレターやダイジェストメールも加わっていた。
    他方で、同僚たちが皆、自分たちの職に影響し得ることをしないでほしいと言っていたにもかかわらず、趣味プロジェクトとして押し通すなら、かなり意地の悪い行動に聞こえる。

    • 2015年に同僚たちからやめてくれと言われたときは作らなかった。
      ただ、自分が使っているオープンソースソフトウェアが、生存可能性を高めるほど知識をうまく広めているかは見てみたい。
      その意地の悪い行動は断った。
    • ばかげた指標だ。
  • 「キャリアラダーを上るほど、開発者は直接キーボードを叩く仕事を減らし、レビューをもっとすべきだ」というのは、テック企業でよくある誤解だと思う。
    優れた開発者を平凡なマネージャーに変えたいわけではない。

    • その通り。コードを書く能力は高いテックリードがいるが、リーダーシップやフィードバックのような能力はひどい。
      彼はテックリードよりシニア開発者でいるほうがずっとよいだろう。彼がマネージャーになったらチームがどれほど苦しむか、想像しがたい。
    • コードレビューを「管理」だと思っているなら、かなり深刻に懸念すべきことだ。
  • この件の悲しい皮肉は、依然として問いの立て方が間違っていることにある
    スタートアップがレイオフをしなければならないときの問いは、「誰を解雇しても既存事業を維持できるか」ではなく、「倒産しないだけの速さでプロダクトの次のバージョンを作れるチームは誰か」である
    すべての分かれ道は結局分かれ道であり、十分に早く道を選べずに死んだ会社は多い

  • CPAN はかなり以前から バスファクターを追跡してきた。たとえば https://metacpan.org/pod/Moose は左側の情報欄に Bus Factor 5 を表示している

  • 私たちはこれを 宝くじファクターと呼ぶのが好きだ
    誰かが宝くじに当たって、電気も通信網もない熱帯の島へ去っても、プロジェクトを続けられるかという意味である
    こう呼ぶと、あまり不気味ではない

    • 宝くじの当選者は2週間前に退職を通知し、本当に必要なら後で電話することもできる
      バスにはねられた人は即座にいなくなる。同じことではない
    • 良い社員は自分のプロジェクトを引き継ぎ、質問にも答えようとするだろうが、それができない場合にも備えるべきだ
    • 転職を sudden death と婉曲に表現するのは後味がよくない
      スポーツの比喩を嫌う人もいるが、少なくとも軍事的な比喩よりはましだと思う
      いずれにせよ、通常は引き継ぎがない場合も多いので、突然であること自体はそれほど重要な要素ではないかもしれない
    • バスにはねられるほうが起こりやすいことかもしれないので、その可能性も反映すべきだ
    • 高額宝くじに当たった人やバスにはねられた人は知らないが、暗号資産長者になって退職した人は何人も知っている