- 工場の稼働率が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件のコメント
Hacker Newsの意見
核心は、レビュアーが「これを変えるなら、コードベースにある他の未解決の問題も一緒に直すべきだ」と要求した点にある
こういうときは、「コード品質を上げようという方向性は良いですが、Yを変えるとX/Y/Zの承認が必要になり、さらに数日かかります。ご指摘の内容は技術的負債の対応として起票し、優先度と余力に応じて後続のPRで処理しましょう。今はこの局所的なPRをデプロイするために何が必要かに集中しましょう」と押し返すべきだ
一番大きく学んだのは、焦点の定まったPRを作ることと、レビュアーがスコープを広げようとしたときに反論する方法だった。たいてい他のエンジニアたちは実務的に受け止めてくれた。行数とは無関係だ。コード全体のフォーマットだけを変えてロジックの変更がないこともあれば、機能フラグをいくつか変えるだけでも影響が大きいことがある。一度にやるべき変更は、焦点の定まったひとつだけだ
これが、今すぐ対処しなければ会社が解雇までしなければならないほどの高優先度案件なら、誰かが見る前の2〜3日など絶対に発生してはいけなかった。ところが、この開発プロセスではそれが「高速経路」だったように見える
最後の2日間も、テスト計画が不十分だと判断されて、何も起きなかったように見える。「これを変えるなら他の未解決の問題も直すべきだ」が占めていたのはここでは2時間にすぎず、その部分を見る前からでも、このプロセスの核心的な問題として挙げられる点が少なくとも2〜3個はある
FIXMEやTODOを残すより、静かにIssueを作って忘れないようにする。この種のレビューは壊れている。技術的負債の解消は、作業完了の条件ではなく、別途計画されるべきだ
そうした層が積み重なると、最終的にそのコードは、環状道路の多さで悪名高いジョージア州アトランタと道徳的に同等な状態になる
新しいルールが追加されたら、自動化によって既存のすべての違反箇所にルール例外の注釈を付け、追跡もできるようにすべきだ。急いでデプロイしなければならないコードがルール違反を必要とするなら、例外注釈を追加し、あとで直す担当者として自分の名前を付ければいい
時間をかけて、機能開発とは切り離してこうしたルール違反を修正していく文化を作れる
その通り。ほとんどの会社のコードレビュープロセスは、揚げ足取りと些細なコメントで満ちている
以前、こうしたコメントをなくしてフィードバックを速くするため、静的解析ツールに置き換えようと提案したことがあるが、その種のコードレビューは全員に必要だと返された。人々の昇進に役立ち、コードの問題を防いだという実感を与え、上級管理職がレビュアーコメント数を見てコードレビュー指標を良く見せられるからだ
本当の解決策は、すべてのコードが自分で書いたもののように見える必要はないと受け入れ、「このコメントはコードの客観的な誤りを扱っているのか?」と自問することだ。多くの場合、答えは「いいえ」だ
変数名が少し冗長だったり、メソッド間の空白が揃っていなかったりする程度なら、理想的には「次に同じパターンが出たときのためのフィードバック」であるべきだ。だがレビュアーの立場では、PRごとのコメント数がどれだけ指導したかの指標として見られたり、「誰がこんなのをマージさせたんだ?」という反応を心配したりして、結局コメントを残す
レビューを受ける側は、コメントに対応しないとフィードバックへの応答性が低いと思われるのではないか、あるいは反論するとレビュアーに悪い評価を付けられるのではないかと不安になって修正する。すると更新版をまた承認してもらう必要があり、遅延のサイクルが再び始まる
ただし、人によっては些細な指摘に見えても、実際にはまったく些細ではない問題もある。自分の目で問題を見つけられない、問題を理解できない、あるいは感情を脇に置いて自分の書いたコードを見直す能力が足りないため、そう感じることがある
私たちは皆、自分の書いたコードに愛着を持ったことがあり、それを世界で最もエレガントなコードだと思ったことがあるかもしれない。だが、ときには自分が間違っていて、それが読みにくく、欠陥があり、コードベースに害を与えていると認めなければならない
自分よりシニアな人のコードについて、実際に問題になりうる競合状態を指摘したら、揚げ足取りだと言われたこともある。私にとって競合状態は、書かれたコードの根本的な問題なので修正すべきものだが、その人にとっては、まだ自然に壊れるのを見たことがないので受け入れ可能な状態だった
同僚レビューは非常に有用だと思っていて、たいていは「このコードは期待どおりに動かないだろう」「このやり方だと実装が行き詰まるか、はるかに高コストになるだろう」「動くことは動くが理解しづらく、保守性に悪影響を与える。別のやり方や説明の追加を検討してほしい」「コードは問題ないが、もっと読みやすく、あるいはうまく動くようにできる。レビューを落とすほどではないが、次のコードで参考にする価値はある」といった点に集中する
「Julie: ITセキュリティチームのJoeに連絡してください。権限を付与してくれます。2時間後。」は完全に非現実的だ。セキュリティチームがそんなに早く返答するはずがない
npm installを実行して P1 セキュリティアラートが上がった場合は例外だヘルプデスクの担当者がすぐ閉じられるチケットなので、自分の指標を上げるために入ってきた瞬間につかみに来ているのではと思うことさえある
タイトルのように コード1行を変えるのに6日 と言うとひどく見える。
しかしシステムはいくつかの面で改善された。設定はハードコードではなくパラメータテーブルで構成可能になり、その設定変更を追跡する監査機能も追加された
官僚主義を擁護したいわけではない。大組織のそういう面は心から嫌いだ。ただ、当初の目標以外にも6日間で追加の価値が生まれた点は指摘したい
だから見積もりには一定量の 付随コスト を入れるべきで、ストーリーポイントを付けるならこうした手続きコストも考慮すべきだ
結局のところ、2つの成果とは、コード変更の周辺にある余計な儀式を避けたという「成果」と、今後この変更がコードに入らなくなることで最初の「成果」で失った機能を取り戻したという「成果」だった
これは「緊急なので1文字のPRを通してください。ご要望の改善事項は追跡用チケットにしました。まず本番問題を解決し、残りはその後で対応します」と言うべきだった
レビュアーは「LGTM!」で済ませればよかった。ほとんどのエンジニアがルールとガイドラインの間をうまく渡れないなら、その組織は狂っているし、まさにこういうところで シニアリティ に価値がある
1週間かかっても誰の雇用にも影響しないなら、プロセスに従うか、最小限だけ変えればよい。ITのせいで人々が無給休職状態なら、問題が解決するまで必要な全員が同じ部屋に、物理でも仮想でも、入っているべきだ
ここにはその文脈がない。しかし Ed と承認ライン全体がその文脈を知らないのなら、それは システムの失敗 だ。誰かの家賃がかかっていると知っていたなら、シニアはおそらく、あとで直す2つ目のチケットをすぐ作ろうと言ったはずだ。そうでないなら、それも経営陣が解決すべき問題だ
この話は、ハードコードされた値の1行変更が実際にはうまくいったケースだ。
誰かが backlog の月数を賢く見せようとして 2ビット値で保存したシナリオは想像できる。0、1、2、3 しか入らないようなものだ。テスト中には、何層も下の未テストな下位サービスやローコード自動化サービスに隠れていて問題が表に出ないかもしれない
その値を 4 に変えると backlog が 0 になるかもしれない。結果がどうなるかはわからない。そのサービスが本番キュー内のすべてのジョブをキャンセルするかもしれないし、顧客に作業がキャンセルされたというメールを送るかもしれない
見た目には簡単な変更に見えても、方針変更が緊急案件としてソフトウェアチームに渡されたのなら、経営陣がもっと適切に計画すべきであって、場当たり的に課題の優先順位を揺さぶるべきではない
むしろ変更の「コスト」として周辺のいろいろな部分をリファクタリングするよう求め、リスクを増やしていた
偉い上司が「私がリスクを取って押し進めると決めたし、その結果も受け入れる」と言うならよい。プログラマがその責任を負うのはよくない
中核機能に対する時間に敏感で重要な更新なら、運用責任者はソフトウェアの 平均デプロイ時間 を把握しているべきで、通常の開発パイプラインに高優先度で入れるのではなく、高速処理のためのチームを編成すべきだった
コードレビューは善意から始まる。しかしどこかの 門番 が結局居座り、些細な理由で何でも拒否し始める
本人は「コード品質」を守ることに関心があると言う。だが、修正準備ができているバグコードを長く残したり、誰も使えないよう機能を遅らせたりするより悪いことはない
コメントは許可しつつも、レビュアーがコミットを止められないプロセスを勧める。各開発者が注意深く、作業に見合った変更を行うと信頼すべきだ。CI も使えばよく、チームによっては全体としてかなりうまく回る
病的なレビュアーを無視できるようにプロセスを変えるのは、せいぜい半端な対策にすぎない
ブロックについては複雑な思いがある。大きな赤いブロック表示がうんざりするのは理解できるので、多くの場合ブロックせずに変更を求める「ソフトブロック」にしている。ただ、PRが完全に脱線している場合、たいていジュニア開発者に対しては明確なメッセージを送るのが適切だと思う
これは工場労働者とソフトウェア開発者についてのメタ的な話だ。
この会社のリーダーは、10%の低稼働を理由に工場労働者を解雇する意思がある。いくつかの変数を調整して生産性を上げることはできるが、結局のところ選択肢は完全稼働か失業かのどちらかだ。おそらくこの労働者たちは代替可能で、繁忙期に再雇用でき、従業員1人あたりが生み出す利益が非効率を許容しないため、それが可能なのだろう
私はソフトウェア開発者として働いている。こちらの世界では、低稼働が90%をはるかに超えない限り、誰かを追い出そうとはしない。多くの人が週4時間しか働いていない。誰も私たちの分単位の時間やトイレ休憩などを管理していない
今はソフトウェアの大規模な資本化の時期だ。永遠に続くわけではない。いつかIT世界の主要インフラが構築され、産業は保守モードへ移行する。そのとき私たちの大半は不要になり、代替可能になり、保守モードで私たちが生み出す利益は今見ているものに比べてごくわずかになるだろう
工場労働者は、個人の生産性が低いと判断されると、たいてい数分から数時間で解雇される。私たちが生きているうちに、ソフトウェア開発者にもそういうことが起こり始めると思う
自分のスキルセットについても、それがどの程度可能か評価すべきだ
ソフトウェアの大規模な資本化が永遠ではないという基本的な主張には同意する。すべての会社が常に新しいソフトウェアを開発するエンジニアを必要としているわけではない。映画制作のように、好況と不況のある創作ビジネスにより近い。ITより開発を選ぶなら、そのリスクは受け入れるべきだ。ただ、なぜ今が頂点であるはずなのかは分からない
個人的な経験として、何年も形式的なコードレビューのあるチームで働いたあと、コードレビューのないチーム/会社に移ったことがある。誰でもどのブランチにも自由にコミットし、マージできた
入社時にはやや複雑な気持ちだったが、実際にはとてもすがすがしく、権限を与えられている感覚があり、数日で生産的に働けるようになった
チームの目標を考えると、コードレビューのないやり方は非常によく合っていた。役員たちに「すごい新機能」をデモすることが主目的の研究開発グループだったからだ。短い通知で入ってくる依頼が多かったが、捨てるコードも多かった
デモをすると役員が「見た目はいいけど、事業性はないですね」と言い、そのリポジトリは二度と触られなかった。もちろん、たまに私たちが作ったものが製品化されることもあり、その場合は下流チームが落書きのようなコードを本番品質に変える責任を負った。彼らは燃えるような憎しみで私たちを嫌っていた
新しいチームメンバーには、最初の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年で失敗していた
コードレビューのプロセスを使って、変更量が多く継続的に変化するチーム以上にふさわしい形になるまで変更を人質に取るのは機能不全だ
「進めながらアップグレードする」方針は、中途半端に終わった移行の長い尾を残し、新しい開発者がコードベースに慣れるのをより難しくする。製品の焦点がコードベースのすべての部分を定期的に通過する保証はないので、移行は終わらない。製品の一部領域は何年も放置される
新しい方針への移行が重要なら、ひとつの集中プロジェクトとして切り出して進めるべきで、そうでないなら重要ではないということだ
コードベース全体に散らばった無計画な作業の時限爆弾が、無作為で無関係な作業を通じて爆発するのを期待している
新しい標準が重要ならコードを更新すべきだし、そうでないならやるべきではない。偶然性に頼って緊急作業を遅らせるのは計画ではない
これをコードレビューの問題として読むのは間違いだ。問題は、会社が原則よりも内部障壁だらけのプロセスを優先したことにある
どんなプロセスにも抜け道が必要だ。解雇を防ぐための変更なら、あらゆる抜け道が発動されるべきだ