2 ポイント 投稿者 GN⁺ 2023-07-17 | 1件のコメント | WhatsAppで共有
  • 工場の稼働率が10%低下すると、会社は解雇の代わりに繁忙期前の在庫を積み増そうとし、そのために3か月のバックログ制限を4か月に変更する依頼が始まった
  • IT責任者は中核ルーチンのハードコードされた値を1つ変えれば済むと考えたが、その前にチケット作成・ビジネス影響の記載・承認・キューの優先順位調整が必要だった
  • プログラマーは Module ORP572 の line 1252 で MonthsOfBacklog の値を "3" から "4" に変更し、テストを通過させたが、コードレビューで既存のポリシー違反まで修正対象になった
  • 変更範囲は Parameters ファイルのレコード化、デバッグ命令の削除、未割り当て変数の警告、ハードコードされた Employee ID、アクセス権限、テスト環境、テスト計画、ユーザー署名といった付随手続きへと膨らんだ
  • 業務上必要な変更は1行・1バイトだったが、全体の経過時間は6日で、内部手続きとポリシーが小さな変更の実際のリードタイムを大きく引き延ばした

3か月制限を4か月に変更する依頼

  • 社長の Philip は工場が10%未稼働の状態だとして、解雇よりもバックログを多く生産し、繁忙期前に在庫を積み上げたいと考えている
  • 運用マネージャーの Lee は、会社のポリシー上3か月分のバックログまでしか作れないため、制限を4か月に変えれば十分な仕事が生まれると話す
  • IT責任者の David は、レガシーソフトウェアの中核ルーチンでコード1行だけを変えればよさそうだと見て、IT Services にチケット提出を依頼する
  • ITマネージャーの Judy は依頼を Ticket# 129281 として割り当てたが、Business Impact セクションと Director の承認が必要だと言う
    • David が解雇の可能性を話すと、Judy は自らそのセクションを埋め、迅速処理に回した
    • 2日後になっても依頼は Developer Queue で14件の Bug Report の後ろにある最初の Enhancement のままだった
    • David は依頼を緊急としてマークし、Ed に直接送るよう指示した

1行の変更が手続き変更へと膨らむ過程

  • Ed は Module ORP572 line 1252 でハードコードされた変数 MonthsOfBacklog"3" から "4" に変更した
    • 単体テストを通過し、バッチテストを2回実行した
    • Operations の作業キューは予想どおり10%増加した
    • 変更は Code Review と Homer の User Acceptance Testing に進んだ
  • コードレビュー担当の Shirley は、ハードコードされた変数は会社のポリシーに反するとして、Parameters ファイルのレコードにすべきだと要求した
    • 既存の Debug 命令2つ、未割り当て変数の警告、ハードコードされた Employee ID も本番反映前に修正すべきだとした
    • Ed は ORP572 を割り当てられている以上、新しい会社ポリシーに違反する既存のエラーまで責任を負うべきだという立場だった
  • テスト環境も遅延要因になった
    • Homer は月末会計締めの統制テストのため使えず、Marge を使わなければならなかった
    • Ed には Marge へのアクセス権がなく、IT Security の Joe は David の署名なしでは権限を付与できないと言った
  • Parameters レコード作業は追加要求で拡大した
    • MonthsOfDemand という名前は海外のプログラマーには理解しづらいという理由で、より良い名前が必要だった
    • 新しい Parameter レコードには監査証跡が必要だったが、そのポリシーは文書化されておらず、Wiki の更新も3か月遅れていた
    • Ed は名前を SelectedMonthsOfBacklogDemand に変更し、そのレコードと監査証跡を維持する Module PAR634 を追加した
  • テスト担当の Tony は、Marge に 129281 は見えるがTest Planがないと指摘した
    • Ed は旧方式と新方式で実行し、WorkOrdersHours レポートの総量増加を確認すればよいと述べたが、Tony は工場全体に影響するとして、ユーザー選定の Test Cases、Expected Results、文書化された Test Runs、ユーザー sign-off を要求した
    • 2日後、Philip は David に対し、Tony に Ed のプログラムをただちに本番へ移すよう指示させた
  • 総経過時間は6日で、mission critical code の変更は1行・1バイトだった
    • Excedrin は24錠消費された
    • Hacker News に費やしたいら立ち混じりの時間は14時間と記されている

1件のコメント

 
GN⁺ 2023-07-17
Hacker Newsの意見
  • 核心は、レビュアーが「これを変えるなら、コードベースにある他の未解決の問題も一緒に直すべきだ」と要求した点にある
    こういうときは、「コード品質を上げようという方向性は良いですが、Yを変えるとX/Y/Zの承認が必要になり、さらに数日かかります。ご指摘の内容は技術的負債の対応として起票し、優先度と余力に応じて後続のPRで処理しましょう。今はこの局所的なPRをデプロイするために何が必要かに集中しましょう」と押し返すべきだ
    一番大きく学んだのは、焦点の定まったPRを作ることと、レビュアーがスコープを広げようとしたときに反論する方法だった。たいてい他のエンジニアたちは実務的に受け止めてくれた。行数とは無関係だ。コード全体のフォーマットだけを変えてロジックの変更がないこともあれば、機能フラグをいくつか変えるだけでも影響が大きいことがある。一度にやるべき変更は、焦点の定まったひとつだけだ

    • 「これを変えるなら他の未解決の問題も直すべきだ」が核心だ、という点には同意しない。ここで最悪なのは、コード1行を変えるのに6日かかっており、そのうちほぼ半分はエンジニアがこの課題を見る前だったことだ
      これが、今すぐ対処しなければ会社が解雇までしなければならないほどの高優先度案件なら、誰かが見る前の2〜3日など絶対に発生してはいけなかった。ところが、この開発プロセスではそれが「高速経路」だったように見える
      最後の2日間も、テスト計画が不十分だと判断されて、何も起きなかったように見える。「これを変えるなら他の未解決の問題も直すべきだ」が占めていたのはここでは2時間にすぎず、その部分を見る前からでも、このプロセスの核心的な問題として挙げられる点が少なくとも2〜3個はある
    • たいてい、今取り組んでいる作業と直接関係のない改善は避ける。セミコロンの抜けをひとつ足すだけでも、過剰に熱心なレビュアーの目に留まって、レガシー修正のウサギ穴に引きずり込まれることがある
      FIXMEやTODOを残すより、静かにIssueを作って忘れないようにする。この種のレビューは壊れている。技術的負債の解消は、作業完了の条件ではなく、別途計画されるべきだ
    • スコープ拡大をする人たちは、自分たちが引き起こしているアーキテクチャ上の損傷を理解していない。ひとつのコードブロックに過度に執着すると、人々はその周囲を迂回しようとする
      そうした層が積み重なると、最終的にそのコードは、環状道路の多さで悪名高いジョージア州アトランタと道徳的に同等な状態になる
    • より良い解決策は、ルールを自動化することだと思う
      新しいルールが追加されたら、自動化によって既存のすべての違反箇所にルール例外の注釈を付け、追跡もできるようにすべきだ。急いでデプロイしなければならないコードがルール違反を必要とするなら、例外注釈を追加し、あとで直す担当者として自分の名前を付ければいい
      時間をかけて、機能開発とは切り離してこうしたルール違反を修正していく文化を作れる
    • そういうことが起きたら、TODOチケットを追加すればいいだけだ。本番ブロックを解除できるし、システムもこれ以上悪化しない
  • その通り。ほとんどの会社のコードレビュープロセスは、揚げ足取りと些細なコメントで満ちている
    以前、こうしたコメントをなくしてフィードバックを速くするため、静的解析ツールに置き換えようと提案したことがあるが、その種のコードレビューは全員に必要だと返された。人々の昇進に役立ち、コードの問題を防いだという実感を与え、上級管理職がレビュアーコメント数を見てコードレビュー指標を良く見せられるからだ

    • こういうツールを過剰に使うのは嫌いだ。馬鹿げたツールを満足させるために、かえってコードを悪くしてしまうことは珍しくない
      本当の解決策は、すべてのコードが自分で書いたもののように見える必要はないと受け入れ、「このコメントはコードの客観的な誤りを扱っているのか?」と自問することだ。多くの場合、答えは「いいえ」だ
    • ここには、ときどき本物の囚人のジレンマがある。シニアがジュニアのPRをレビューするとき、良くできる部分はあっても重要ではないことが多い
      変数名が少し冗長だったり、メソッド間の空白が揃っていなかったりする程度なら、理想的には「次に同じパターンが出たときのためのフィードバック」であるべきだ。だがレビュアーの立場では、PRごとのコメント数がどれだけ指導したかの指標として見られたり、「誰がこんなのをマージさせたんだ?」という反応を心配したりして、結局コメントを残す
      レビューを受ける側は、コメントに対応しないとフィードバックへの応答性が低いと思われるのではないか、あるいは反論するとレビュアーに悪い評価を付けられるのではないかと不安になって修正する。すると更新版をまた承認してもらう必要があり、遅延のサイクルが再び始まる
    • ある環境ではその通りだ。だがレビュー過程は、変更内容とコードベースについての共有知識と理解を築く助けにもなる
    • 揚げ足取りが実際に存在するのは間違いない。おそらく、コードのどこかに問題を見つけなければならないという感覚のせいかもしれない
      ただし、人によっては些細な指摘に見えても、実際にはまったく些細ではない問題もある。自分の目で問題を見つけられない、問題を理解できない、あるいは感情を脇に置いて自分の書いたコードを見直す能力が足りないため、そう感じることがある
      私たちは皆、自分の書いたコードに愛着を持ったことがあり、それを世界で最もエレガントなコードだと思ったことがあるかもしれない。だが、ときには自分が間違っていて、それが読みにくく、欠陥があり、コードベースに害を与えていると認めなければならない
      自分よりシニアな人のコードについて、実際に問題になりうる競合状態を指摘したら、揚げ足取りだと言われたこともある。私にとって競合状態は、書かれたコードの根本的な問題なので修正すべきものだが、その人にとっては、まだ自然に壊れるのを見たことがないので受け入れ可能な状態だった
    • 静的解析ツールと同僚レビューは、互いに異なる種類の問題を捉えられる。静的コンパイル言語が、動的言語では捕まえられない一部のバグを捕まえられても、すべては捕まえられないのと同じだ
      同僚レビューは非常に有用だと思っていて、たいていは「このコードは期待どおりに動かないだろう」「このやり方だと実装が行き詰まるか、はるかに高コストになるだろう」「動くことは動くが理解しづらく、保守性に悪影響を与える。別のやり方や説明の追加を検討してほしい」「コードは問題ないが、もっと読みやすく、あるいはうまく動くようにできる。レビューを落とすほどではないが、次のコードで参考にする価値はある」といった点に集中する
  • 「Julie: ITセキュリティチームのJoeに連絡してください。権限を付与してくれます。2時間後。」は完全に非現実的だ。セキュリティチームがそんなに早く返答するはずがない

    • npm install を実行して P1 セキュリティアラートが上がった場合は例外だ
    • うちのセキュリティチームは実際にはもっと早く返答する。すべての依頼を自動で却下するが、即座に却下する
    • 私が働いているところでは経験がかなり違う。誰かに特定システムへのアクセス権を求めるチケットを起票すると、優先度をどう付けてもたいてい数分以内に処理される
      ヘルプデスクの担当者がすぐ閉じられるチケットなので、自分の指標を上げるために入ってきた瞬間につかみに来ているのではと思うことさえある
    • Wiki 編集権限に必要な AD グループに誰かを追加するのに数週間かかる
  • タイトルのように コード1行を変えるのに6日 と言うとひどく見える。
    しかしシステムはいくつかの面で改善された。設定はハードコードではなくパラメータテーブルで構成可能になり、その設定変更を追跡する監査機能も追加された
    官僚主義を擁護したいわけではない。大組織のそういう面は心から嫌いだ。ただ、当初の目標以外にも6日間で追加の価値が生まれた点は指摘したい
    だから見積もりには一定量の 付随コスト を入れるべきで、ストーリーポイントを付けるならこうした手続きコストも考慮すべきだ

    • パラメータテーブルが有用である唯一の理由は、コード変更を妨げるものが多すぎたからだ。同様にこの設定に対する監査も不要に思える。以前はコードにあったのだから、ソース管理がそのまま 監査証跡 だった
      結局のところ、2つの成果とは、コード変更の周辺にある余計な儀式を避けたという「成果」と、今後この変更がコードに入らなくなることで最初の「成果」で失った機能を取り戻したという「成果」だった
    • そのとおりだが、元の要求よりはるかに危険になりうることもしている。即時の障害や実際の本番問題がある状況で、ハードコードされた値をパラメータへ追い出すのは愚かだと思う。潜在的な落とし穴がはるかに多い
      これは「緊急なので1文字のPRを通してください。ご要望の改善事項は追跡用チケットにしました。まず本番問題を解決し、残りはその後で対応します」と言うべきだった
      レビュアーは「LGTM!」で済ませればよかった。ほとんどのエンジニアがルールとガイドラインの間をうまく渡れないなら、その組織は狂っているし、まさにこういうところで シニアリティ に価値がある
    • 第1段階は本当の優先順位を判断することだ。この件がどれだけ遅れると人々の雇用に影響するのかを、全員が把握しているべきだ
      1週間かかっても誰の雇用にも影響しないなら、プロセスに従うか、最小限だけ変えればよい。ITのせいで人々が無給休職状態なら、問題が解決するまで必要な全員が同じ部屋に、物理でも仮想でも、入っているべきだ
      ここにはその文脈がない。しかし Ed と承認ライン全体がその文脈を知らないのなら、それは システムの失敗 だ。誰かの家賃がかかっていると知っていたなら、シニアはおそらく、あとで直す2つ目のチケットをすぐ作ろうと言ったはずだ。そうでないなら、それも経営陣が解決すべき問題だ
    • 「コード1行を変えるのに6日」は単に事実を述べているだけだ。その間にシステムが改善されたという部分は 必須要件 ではなかった
    • 監査要件は、そのハードコードされた値が入っていたファイルの バージョン履歴 で満たせたはずだ。バージョン管理をしていなかったなら、もっと大きな別の問題があったはずだ
  • この話は、ハードコードされた値の1行変更が実際にはうまくいったケースだ。
    誰かが backlog の月数を賢く見せようとして 2ビット値で保存したシナリオは想像できる。0、1、2、3 しか入らないようなものだ。テスト中には、何層も下の未テストな下位サービスやローコード自動化サービスに隠れていて問題が表に出ないかもしれない
    その値を 4 に変えると backlog が 0 になるかもしれない。結果がどうなるかはわからない。そのサービスが本番キュー内のすべてのジョブをキャンセルするかもしれないし、顧客に作業がキャンセルされたというメールを送るかもしれない
    見た目には簡単な変更に見えても、方針変更が緊急案件としてソフトウェアチームに渡されたのなら、経営陣がもっと適切に計画すべきであって、場当たり的に課題の優先順位を揺さぶるべきではない

    • 要求された変更の中に 追加テスト やリスク低減に関するものはなかった
      むしろ変更の「コスト」として周辺のいろいろな部分をリファクタリングするよう求め、リスクを増やしていた
    • 失敗する道筋はいくらでもある。本当の問いは、失敗したとき責任がどこへ行くのか、なのかもしれない
      偉い上司が「私がリスクを取って押し進めると決めたし、その結果も受け入れる」と言うならよい。プログラマがその責任を負うのはよくない
    • 正しい人とプロセスに従ってはいたと思う。ただ、リードを集めて会議を設定し、作業の重要度と優先順位をそろえていれば、大きく時間を節約できたはずだ
      中核機能に対する時間に敏感で重要な更新なら、運用責任者はソフトウェアの 平均デプロイ時間 を把握しているべきで、通常の開発パイプラインに高優先度で入れるのではなく、高速処理のためのチームを編成すべきだった
    • Knight Capital を思い出す
  • コードレビューは善意から始まる。しかしどこかの 門番 が結局居座り、些細な理由で何でも拒否し始める
    本人は「コード品質」を守ることに関心があると言う。だが、修正準備ができているバグコードを長く残したり、誰も使えないよう機能を遅らせたりするより悪いことはない
    コメントは許可しつつも、レビュアーがコミットを止められないプロセスを勧める。各開発者が注意深く、作業に見合った変更を行うと信頼すべきだ。CI も使えばよく、チームによっては全体としてかなりうまく回る

    • ならエンジニアリングリーダーがその人を止めるべきだ。機能不全はいろいろな形で現れるし、過度に熱心なレビューもその一つだ
      病的なレビュアーを無視できるようにプロセスを変えるのは、せいぜい半端な対策にすぎない
      ブロックについては複雑な思いがある。大きな赤いブロック表示がうんざりするのは理解できるので、多くの場合ブロックせずに変更を求める「ソフトブロック」にしている。ただ、PRが完全に脱線している場合、たいていジュニア開発者に対しては明確なメッセージを送るのが適切だと思う
    • この方式は テストカバレッジ とテスト品質が高いときにうまく機能する。それも、開発者たちを今まさにマネージャーが必要だと思っている速度で動かせば魔法のように生まれるものではない
    • 「すべてのコード変更にはレビュアーが必要だ」というルールは嫌悪している。とてつもない妨げであり、必ずしもより良いコードにつながるわけでもない
  • これは工場労働者とソフトウェア開発者についてのメタ的な話だ。
    この会社のリーダーは、10%の低稼働を理由に工場労働者を解雇する意思がある。いくつかの変数を調整して生産性を上げることはできるが、結局のところ選択肢は完全稼働か失業かのどちらかだ。おそらくこの労働者たちは代替可能で、繁忙期に再雇用でき、従業員1人あたりが生み出す利益が非効率を許容しないため、それが可能なのだろう
    私はソフトウェア開発者として働いている。こちらの世界では、低稼働が90%をはるかに超えない限り、誰かを追い出そうとはしない。多くの人が週4時間しか働いていない。誰も私たちの分単位の時間やトイレ休憩などを管理していない
    今はソフトウェアの大規模な資本化の時期だ。永遠に続くわけではない。いつかIT世界の主要インフラが構築され、産業は保守モードへ移行する。そのとき私たちの大半は不要になり、代替可能になり、保守モードで私たちが生み出す利益は今見ているものに比べてごくわずかになるだろう
    工場労働者は、個人の生産性が低いと判断されると、たいてい数分から数時間で解雇される。私たちが生きているうちに、ソフトウェア開発者にもそういうことが起こり始めると思う

    • 「この労働者たちは代替可能で、繁忙期に再雇用できる」という点こそが違いだ。工場は、各人から意思決定と変動性を取り除くよう設計されたプロセスのシステム
      自分のスキルセットについても、それがどの程度可能か評価すべきだ
      ソフトウェアの大規模な資本化が永遠ではないという基本的な主張には同意する。すべての会社が常に新しいソフトウェアを開発するエンジニアを必要としているわけではない。映画制作のように、好況と不況のある創作ビジネスにより近い。ITより開発を選ぶなら、そのリスクは受け入れるべきだ。ただ、なぜ今が頂点であるはずなのかは分からない
  • 個人的な経験として、何年も形式的なコードレビューのあるチームで働いたあと、コードレビューのないチーム/会社に移ったことがある。誰でもどのブランチにも自由にコミットし、マージできた
    入社時にはやや複雑な気持ちだったが、実際にはとてもすがすがしく、権限を与えられている感覚があり、数日で生産的に働けるようになった

    • 以前、「カトリック式コードレビュー」、つまり push and pray をするチームで働いたことがある
      チームの目標を考えると、コードレビューのないやり方は非常によく合っていた。役員たちに「すごい新機能」をデモすることが主目的の研究開発グループだったからだ。短い通知で入ってくる依頼が多かったが、捨てるコードも多かった
      デモをすると役員が「見た目はいいけど、事業性はないですね」と言い、そのリポジトリは二度と触られなかった。もちろん、たまに私たちが作ったものが製品化されることもあり、その場合は下流チームが落書きのようなコードを本番品質に変える責任を負った。彼らは燃えるような憎しみで私たちを嫌っていた
    • 高い信頼と約80%のテストカバレッジがある小さなチームでは、このやり方が非常によく機能するのを見たことがある。PRなしのプロセスで、テストが通り、該当する場合はステークホルダーへのUXデモが成功し、自分でも満足できたら master にマージしていた
      新しいチームメンバーには、最初の2〜3か月の間、隣に座って頻繁にペア作業をし、コードも見てくれるメンターが割り当てられていた
      2.5年のプロジェクトで、20か月目に本番稼働し、スケジュールと予算を守り、当初のスコープより多くの機能を提供した。多くの日はホワイトボードの前で2〜3時間議論していた。非公式で、常に全員が参加していたわけではなかった
      奇妙なことに、このプロジェクトの間にPMが3人入れ替わった。スタンドアップ以外ではメールや連絡をしないという厳格なルールがあり、3人のうち2人はこの設定では「仕事」ができなかった。空港のIT責任者は、2年後になってようやく私たちにPMは不要だと気づいた
      コードベースで新しい作業をするなら、最低でも他の開発者1人と話さなければならないというルールがあった。私たちは大きなホワイトボードのある広い個室で、互いに数フィートの距離に座っていた。ストーリーは専用ホワイトボードに貼ったインデックスカードで管理し、要点をそこに書けないなら、もっと小さな単位に分割しなければならなかった
      各自が自分のマシンを組み立て、望むだけモニターを使えた。大規模な国際空港の請求・料金システムで、経理部長やディレクター、ほかのユーザーたちは数部屋先にいた。彼らはスタンドアップをほとんど欠かさず、リアルタイムの質問はいつでも受ける方針だった
      スタンドアップは通常、進捗報告ではなく、非公式な議論、デモ、Q&Aだった。進捗確認はホワイトボードのカードを見れば十分だった
      最終システムは、初月からその後毎月、売上を8%改善した。経理ディレクターは空港当局の理事会の前で説明しなければならなかった。航空会社との請求紛争や調整は月9日から1日に減り、月次請求業務量は18日から5日に減った。主な利用者をシニア会計士から、経験3年のジュニア会計士1人に置き換えられた
      本番バグは初年度に6件、誤請求書は0件だった。その後のデータはない。以前のリライトの試みは3年で失敗していた
    • 正直、セキュリティと監査の観点では悪夢のように聞こえる。それでも、小規模プロジェクトをやるエージェンシーや似たような環境ならあり得るだろう
  • コードレビューのプロセスを使って、変更量が多く継続的に変化するチーム以上にふさわしい形になるまで変更を人質に取るのは機能不全
    「進めながらアップグレードする」方針は、中途半端に終わった移行の長い尾を残し、新しい開発者がコードベースに慣れるのをより難しくする。製品の焦点がコードベースのすべての部分を定期的に通過する保証はないので、移行は終わらない。製品の一部領域は何年も放置される
    新しい方針への移行が重要なら、ひとつの集中プロジェクトとして切り出して進めるべきで、そうでないなら重要ではないということだ

    • その通り。経営陣が計画を事実上放棄しているのでひどい
      コードベース全体に散らばった無計画な作業の時限爆弾が、無作為で無関係な作業を通じて爆発するのを期待している
      新しい標準が重要ならコードを更新すべきだし、そうでないならやるべきではない。偶然性に頼って緊急作業を遅らせるのは計画ではない
  • これをコードレビューの問題として読むのは間違いだ。問題は、会社が原則よりも内部障壁だらけのプロセスを優先したことにある
    どんなプロセスにも抜け道が必要だ。解雇を防ぐための変更なら、あらゆる抜け道が発動されるべきだ