バグ探し禁止!?海外IT現場で学んだ「逆張りコードレビュー」と、完璧な設計図(WPF)を捨てる勇気

そのレビュー、バグ探しちゃダメですよ?

ども!海外の片隅で、今日も元気にC#をブン回しております、現役ITエンジニアです。

普段はクライアントアプリの開発がメインで、特にC#とWPF(Windows Presentation Foundation)を使った設計・開発をゴリゴリやっています。そう、あのWindowsのデスクトップアプリを作るやつですね。最近はWebだクラウドだと華やかな世界が目立ちますが、製造業の制御システム(HMI)とか、金融系のリッチなトレーディングツールとか、「絶対に落ちちゃいけない」「リッチなUIが必須」っていうニッチだけど超重要な分野で、WPFはまだまだ現役バリバリなんです。

さて、このブログは「これから海外でエンジニアとして働いてみたい!」と夢見る皆さんに向けて、僕がこっちで実際に体験した「リアルな気づき」や「知ってると得する(かもしれない)人生術」を発信しています。

技術力?もちろん大事です。C#の最新動向、.NETの進化、WPFのニッチなTIPS。それも大事。

でもね、海外で「ああ、こいつと一緒に仕事してよかったな」と思われるエンジニアになるために必要なのって、それだけじゃないんですよ。むしろ、技術力と同じくらい、いや、時と場合によってはそれ以上に**「文化的な柔軟性」「アンラーニング(学びほぐし)のスキル」**がモノを言う世界なんです。

今日は、まさに僕が日本で叩き込まれた「常識」が、こっちでガラガラと音を立てて崩れ去った、ある金曜日の午後の話をしようと思います。

日本でWPFを使ってカッチリした設計をやってきた人ほど、「え、そんなのアリなの!?」って思うかもしれません。でも、この「定番のひねり(Unexpected Twist)」こそが、僕のエンジニア人生観を変え、海外でサバイブするための最強の武器になったんです。


日本時代の「完璧」という呪い

話の前提として、僕の日本時代の話を少しだけ。

僕は、自他共に認める「完璧主義」のエンジニアでした。特にWPF開発においては、その思想は宗教的ですらあったと思います。

WPFを使うなら、アーキテクチャは当然MVVM (Model-View-ViewModel)。これは絶対。

View(XAML)とViewModel(C#)は完全に分離。ViewがViewModelの存在を知っていても、ViewModelはViewの存在を一切知らない。コードビハインド(XAMLの裏にC#を書くこと)なんてもってのほか。見つけ次第、リファクタリング対象です。

DI (Dependency Injection) コンテナ(Prismとか)を使って依存関係をきっちり管理し、Interfaceを介してすべてを疎結合にする。ユニットテストのカバレッジは最低でも90%を目指す。

なぜなら、WPFは自由度が高すぎるから。XAMLでリッチな見た目を追求できる反面、油断するとすぐにViewとロジックが癒着し、あっという間に「スパゲッティ・コード」が出来上がる。だからこそ、強固な「設計(アーキテクチャ)」でガチガチに縛り上げ、変更容易性とテスト容易性を確保するんだ、と。

設計ドキュメント?当然です。

クラス図、シーケンス図、状態遷移図。コードを1行書く前に、まず設計図が「芸術品」レベルで完璧じゃないと気が済まない。この設計図さえあれば、誰が実装しても同じものができる。それが「プロの仕事」だと信じて疑っていませんでした。

当然、コードレビューも厳しかった。

「この命名規則、規約と違いますね」

「このLINQ、もっと効率的に書けます。IQueryableを意識してください」

「ここのエラーハンドリング、考慮漏れがあります」

レビューは「バグ」と「規約違反」を見つける場所。まさに「マサカリ」が飛び交う戦場でした。厳しく指摘し合うことこそが、品質を担保する唯一の道だと信じていたんです。

海外の現場と「普通」のレビュー

そんな僕が、期待と不安を胸に、今の海外のITチームにジョインしたわけです。

多国籍チーム。英語が飛び交う環境。

当然、こっちにもコードレビュー(PR: Pull Request)はあります。

最初の数週間は、もうビクビクでしたよ。

「(うわ、この設計思想、英語でうまく説明できなかったらどうしよう…)」

「”What’s this messy code?” (この汚いコード何?) とか言われたら泣くぞ…」

「WPFのこのXAMLの書き方、マニアックすぎるって怒られるかな…」

ところが、最初のレビューコメントは、意外なほどアッサリしたものでした。

LGTM (Looks Good To Me)

Approved!

Nice work! 👍

……あれ?

もっとこう…僕が日本でやっていたみたいに、設計思想の是非について熱く語り合ったり、パフォーマンスの限界について議論したり、命名規則の統一性についてツッコミを入れたりしないの?と。

もちろん、クリティカルなバグや、明らかな設計ミス(例えば、セキュリティホールになりかねない実装)には、ちゃんと指摘が入ります。それは世界共通。

でも、日本でやっていたような「重箱の隅をつつく」ような指摘は、驚くほど少ない。

日本が「100点満点からの減点法」だとしたら、こっちは「まずは動くものを作ってくれてありがとう」という「加点法」がベースにある感じ。

「ああ、海外ってこんなもんなのか。意外とユルいな」

「まぁ、スピード重視の文化ってことなのかな」

なんて、僕が少し「海外のやり方」に慣れてきた(とんだ勘違いだったわけですが)入社して数ヶ月が経った、ある金曜日の午後のことでした。

事件は、いつもの会議室で起きました。

「ムダコード大賞」の開幕

その日は、週の終わりにある「Weekly Tech Review」の日。

まぁ、よくある技術的な振り返り会とか、知見の共有会みたいなものですね。

ところが、会議室に入ると、シニアエンジニアのマーク(仮名・ビール腹が素敵な、いつも陽気なチームの兄貴分)が、プロジェクターの前でニヤニヤしながら立ってるんです。

「OK、Gents (野郎ども)! 今週もお疲れ! さて、今日のTech Reviewだけど、ちょっとルールを変更する!」

メンバーたちが「またかよ」「今度は何?」みたいな顔でザワザワしてる中、僕は「え、何が始まるの?」とキョトン。

マークが第一声、こう言い放ちました。

「今日のレビュー会は、**『バグ探し禁止』**だ! いいか? もし誰かの発表中に『それってバグじゃね?』とか『パフォーマンス最悪じゃん』とか、そういう『正しい』指摘をしたら、そいつは来週の金曜、全員分のビールを奢ることになるからな!」

えええ!?

レビュー会なのに、バグ探しちゃダメなの?

品質について議論しちゃダメなの?

意味が分からない。

マークは、得意げに続けます。

「今日のお題はこれだ!**『今週、最もクリエイティブだったけど、ボツになったコード』**を発表してくれ!」

「……は?」

「いかに『エレガントな無駄』を実装したか。いかに『本流から外れた』技術で遊んでみたか。それが審査基準だ! 優勝者には、俺からこの『ゴールデン・ラバーダック』(デスクに飾ってある金色の安っぽいアヒルのオモチャ)を授与する!」

ポカーン、ですよ。

頭が真っ白になりました。

これこそが、このチームに(というか、マークが勝手に始めた)謎の伝統、「Muda-code Award(ムダコード大賞)」だったんです。

まさに、ユーザーさんがくれたフックにあった「Ugly Sweater Contest(ダサいセーターコンテスト)」の「セーターがtoo nice(良すぎる)と減点」の、ITエンジニア版。

「コードが『マトモすぎる』と減点」

「『ボツになった(=失敗した)』コードこそが称賛される」

という、僕の常識とは真逆の価値観が支配する、奇妙な儀式の始まりでした。

「失敗」を大声で笑う同僚たち

僕はもう、パニックです。

「ボツになったコード?」「無駄?」

それって、エンジニアの「恥」じゃないですか。

日本で「完璧な設計図」を信奉していた僕にとって、「失敗した実装」なんていうのは、隠すべきものであって、ましてや人前で「どうだ!」と発表するなんて、ありえない。

その時、僕の頭をよぎったのは、まさに今週、僕が泣く泣くボツにしたWPFのコードでした。

あるカスタムコントロール(※WPFで使うオリジナルのUI部品)を作っていたんです。デザイナー(UI/UX担当)の無茶振りに応えるために、XAMLのAttached Propertyとか、Value Converterとか、Dependency Propertyとか、WPFの「マニアック」とされる機能をフル活用して、それはもう「芸術的」なXAMLコードを書き上げたんです。

結果、どうなったか。

「……ごめん、これ、コードが複雑になりすぎて、君以外誰もメンテナンスできないよ。それに、ちょっとやりすぎだ。もっとシンプルな実装に戻そう」

と、シニア(マークとは別の人)に却下されたばかりだったんです。

「うわ…あの『美しすぎるけどクソメンテしにくいコード』のことか…?」

「あれを発表しろってのか? 恥ずかしすぎる…」

僕が一人で冷や汗をダラダラかいている横で、同僚たちはやけに楽しそう。(※フックの「家族の反応」を「同僚の反応」に置き換え)

トップバッターは、ロシア出身のアンドレイ。

「俺、今週DBのパフォーマンスチューニングやってたんだけどさ。このSQL、見てくれよ。トランザクション分離レベルをあえていじり倒して、ダーティリード(※データの不整合を許容する、普通は危険とされる読み取り方)を使いまくって、理論上は最速のクエリを組んでみたんだ。もちろん、100回に1回はデータがバグるけどな!ガハハ!」

マークが「おー!クレイジー!でもその発想、特定のバッチ処理なら使えるかもな!」とか煽ってる。

次はインド出身のプリヤ。

「私は、社内ツールのローカライズ(多言語対応)を、新しく出たAIライブラリで自動化しようとしたの。でも、学習データが足りなくて、ドイツ語の『キャンセル』が『戦車(Panzer)』って翻訳されちゃって、ドイツ支社から『戦争でも始める気か!』ってクレームが来たわ(笑)」

チーム全員、大爆笑。

「ヤバい!」「そのAI、うちのチャットボットにも使おうぜ!絶対カオスになる!」

完璧主義者(僕)の葛藤

僕は、その光景を呆然と眺めていました。

彼らが語っているのは、どう考えても「失敗談」です。

プロダクトに採用されなかった「ゴミコード」のはずです。

顧客からクレームが来た「失態」のはずです。

なのに、誰も彼らを責めない。

それどころか、「その発想は面白い!」「その技術、別のとこで使えないか?」「その失敗、最高!」と、称賛し、爆笑し、そこから新しいアイデアを見つけようとしている。

僕が日本で信じていた「品質至上主義」とは、真逆の世界。

僕が日本で学んだ「失敗は悪」という価値観とは、180度違う世界。

「海外のエンジニアって、こんなに不真面目なのか?」

「こんなことしてて、プロジェクトは炎上しないのか?」

WPFで「完璧なMVVM」を追求し、「完璧な設計図」こそが正義だと信じてきた僕にとって、この「無駄の称賛」と「失敗の共有」は、カルチャーショックを通り越して、もはや恐怖ですらありました。

でもね。

この「一見ふざけた定番のひねり」こそが、実は海外でエンジニアとして(特に、僕のようにC#やWPFみたいなカッチリした技術を扱うエンジニアが)サバイブするための、超重要な「人生術」だったんです。

僕らが日本で学ぶ「完璧主義」が、いかにイノベーションの邪魔をし、個人のメンタルをすり減らしていたか。

この「ムダコード大賞」が、どうやって僕のガチガチだった「完璧主義」の呪いを解き、結果として(ふざけてるように見えるのに)チームの生産性を爆発的に上げることになったのか。

そして、これが(フックの予告通り)さらにヤバい、このチームの「最終伝統」へと繋がっていくのですが…それはまた別のお話。

次回(承)では、ついに僕が震える手で発表することになる「美しすぎるWPF(ボツ案)」と、それに対するマークの衝撃的なフィードバック、そして「完璧な設計図」を捨てる勇気について、ガッツリ語ろうと思います。

震える手で発表した「芸術的WPF」と、完璧主義の呪いが解けた瞬間

(「起」のつづき)

「ムダコード大賞」の会場は、同僚たちの「やらかし自慢」で、もはや爆笑の渦です。

ロシア人のアンドレイが「意図的にバグらせたSQL」を語り、インド人のプリヤが「AI翻訳で顧客を怒らせた話」を披露する。

みんな、自分が書いたコードが「ボツになった」こと、「失敗した」ことを、まるで武勇伝のように語っています。

僕は、その熱気にあてられて、クラクラしていました。

「(なんなんだ、この人たち…)」

僕の日本での常識では、「ボToolsになったコード」は「敗北」です。

費やした時間、リソース、すべてが無駄。エンジニアとしての評価が下がる、恥ずべき「負債」。

だから、失敗したら、バレないようにこっそり修正するか、あるいは「あれは最初から実験でしたから(キリッ)」と自分に言い訳して、フォルダの奥深くに封印する。それが「普通」だと思っていました。

でも、目の前の光景は真逆です。

彼らは「失敗」をオープンにし、それを「笑い」に変え、さらに「学び」のネタにしている。

僕が日本でやっていた「完璧な設計図」へのこだわり。

レビューでの「マサカリ」。

あれは一体、何を守るためだったんだろう?

「品質」? もちろんそうだ。

でも、その「完璧な品質」を追求するあまり、僕たちは「試してみること」を恐れていなかったか?

「恥ずかしいコード」を書くことを恐れるあまり、新しい挑戦を避けていなかったか?

僕の頭の中は、ぐるぐると疑問符で埋め尽くされていました。

その時です。

ニヤニヤしながら全員の発表を聞いていたマーク(主催者)が、ついに僕に目を向けました。

「OK、OK! みんな最高にクレイジーだ! ……さて、トリは我らがニューフェイス! ミスター『ジャパニーズ・クオリティ』!」

うわ、こっち見た。最悪だ。

「なぁ、君みたいな真面目なエンジニアが、今週どんな『エレガントな無駄』をやらかしたのか、俺は興味津々だよ。C#とWPFで、なんか『美しすぎるゴミ』は作らなかったのかい?」

会場の視線が一斉に僕に突き刺さります。

もう、逃げ場はありません。

僕は、PCの画面を切り替えながら、震える声で話し始めました。

「あー…えーっと。今週、デザイナーの無茶振りで、あるカスタムコントロールを作ってまして…」

それは、製造ラインの稼働状況を示す、ちょっと特殊なインジケーター(表示灯)でした。

デザイナーの要求はこうです。

「ステータスが『正常』『警告』『異常』『メンテナンス中』の4つあるんだけど、それぞれで色が変わるだけじゃなくて、デザインもちょっと変わって、さらに『異常』の時は、WPF特有の『グロー効果(ぼんやり光るやつ)』をアニメーションさせて点滅させて欲しい。あ、もちろん、その光る色も『異常』の種類によって変えたいから、データバインド(※)できるようにしといて」

(※WPFを知らない人向けに解説すると、「画面の見た目」と「裏側のデータ」を連動させる仕組みのことです)

この無茶振り。

日本時代の僕なら、まず「そんな複雑なことするより、シンプルにアイコンを4つ用意しませんか?」と交渉したでしょう。

でも、こっちのデザイナーは「技術的に可能なら、まずやってみようよ!」というスタム。

だから、僕はやったんです。

C#エンジニア、WPFエンジニアとしてのプライドにかけて。

「…で、僕はこれを、Prism(※MVVMフレームワーク)の流儀に則って、コードビハインド(※Viewの裏のコード)を一切使わずに、XAML(※見た目を定義する言語)だけで実現しようとしました」

僕は、プロジェクターにそのコードを映し出しました。

Attached Property(添付プロパティ)を駆使して、本来コントロールが持っていないはずの「光り方の状態」を外部から注入できるようにし、

DataTrigger(データトリガー)を何重にもネストさせて、ViewModelから飛んでくる「ステータス」と「異常種別」の組み合わせ(全12パターン)を分岐させ、

ValueConverter(値コンバータ)で、飛んできた「異常種別コード」を動的に「光る色(Brush)」に変換し、

VisualStateManager(VSM)とStoryboard(アニメーション定義)を使って、滑らかな点滅アニメーションをXAML内部に実装しました。

それはもう、自分でも「芸術品だ」と思えるほどのXAMLでした。

ロジックは一切XAMLにはなく、ViewModel側はただ「ステータス」を切り替えるだけ。

完璧な、完璧なMVVMアーキテクチャ。

「…というコードを、2日間かけて書き上げました」

僕は、ゴクリと唾を飲み込みました。

「でも、これ、アーキテクト(設計主任)に見せたら、『…君は天才か?』って呆れ顔で言われた後、『このXAML、君以外に誰がメンテナンスできるんだ? 悪いけど、やりすぎだ。オーバーエンジニアリング(過剰設計)だよ』って言われて、全部ボツになりました」

シーン…。

さっきまでの爆笑がウソのように、会議室が静まり返りました。

(あ、やばい。引かれた。完全に「イタい奴」だと思われた…)

「(結局、デザイナーの要求が強すぎたんで、最終的には『正常』『警告』『メンテ』はシンプルなSVG画像にして、『異常』の時だけ点滅するGIFアニメを表示する、っていう超絶ダサい実装に落ち着きました…)」

もう、恥ずかしくて死にそうでした。

日本での「完璧な設計」へのこだわりが、ここでは「過剰設計」と一刀両断された。

僕の2日間の努力は、完全に「無駄」になった。

僕は、ビールを奢る覚悟(バグじゃないけど、チームに迷惑をかけた的な意味で)を決めました。

すると、一番に口を開いたのは、意外にもロシア人のアンドレイでした。

「…おい。さっきのXAML、もう一回見せてくれ」

「え?」

「そのAttached Propertyの使い方…クレイジーだ。そんな方法でStoryboardを外からキックできるのか。俺、知らなかった」

続いて、プリヤも前のめりになって言いました。

「私も! そのValueConverterでBrush(色)を動的に生成してる部分、どうなってるの? 私、今やってる画面で、ステータスごとに背景色を変えたいんだけど、いつもCSSみたいに定義済みの色しか使えなくて困ってたのよ!」

え…?

僕が「失敗作」「恥ずかしいコード」として晒した、あの複雑怪奇なXAML(ゴミ)に、みんなが食いついてきたんです。

「あ、いや、ここはDependency Propertyで…」

「このConverterは、引数で渡ってきた文字列を…」

僕がタジタジになりながら解説すると、

「なるほど!」

「その手があったか!」

と、さっきまで僕を「哀れな奴」という目で見ていた(ように感じた)同僚たちが、目を輝かせてメモを取り始めたんです。

そして、最後に主催者のマークが、ポン、と僕の肩を叩きました。

「最高じゃないか」

「え?」

「最高だよ、その『美しすぎるボツコード』! それこそが、この『ムダコード大賞』の精神だ!」

マークは、プロジェクターの前に戻ると、全員に向かって言いました。

「いいか、みんな。今、彼がやったことこそが、俺たちがこの『バカげた会』をやってる理由だ」

「彼がこの『完璧すぎるWPF』を2日もかけて作ったこと。これは『無駄』か? プロダクトには入らなかったから、コスト的には『無駄』だ。でもな…」

マークは、プリヤを指差しました。

「プリヤは、彼のコードから『動的に色を変えるヒント』を得た」

次にアンドレイを指差します。

「アンドレイは『新しいアニメーションの起動方法』を知った」

「そして一番大事なのは、俺たちチーム全員が、『このレベルのXAMLは、やりすぎ(過剰設計)だ』という『共通の物差し』を手に入れたことだ」

「もし彼が、『失敗した』『恥ずかしい』って、このコードをこっそり捨ててたらどうだ? 彼の2日間の努力は、本当にただの『無駄』で終わってた。プリヤもアンドレイも何も学べず、俺たちも『どこまでが適切な設計か』を知る機会を失ってた」

「完璧主義は、バグを減らす。それは正しい」

マークは、僕の目をまっすぐ見て言いました。

「でもな、『完璧』を恐れるあまり、『挑戦』を隠す文化は、チームを殺すんだ」

「『失敗』は、隠したら『負債』になる。でも、こうやって全員で笑い飛ばして『共有』すれば、それはチーム全員の『資産』になるんだよ」


…僕は、頭をガツンと殴られたような衝撃を受けました。

日本で信じてきた「完璧であること」の正義。

失敗を隠す文化。

それが、いかにチーム全体の成長を阻害していたか。

「失敗を恐れるな」なんて言葉は、使い古された標語だと思っていました。

でも、このチームは、「失敗を安全に共有し、爆笑し、資産に変える」という、具体的な「仕組み(=ムダコード大賞)」を持っていたんです。

この日を境に、僕のエンジニアとしての価値観は、180度変わりました。

「完璧な設計図」を捨てる勇気。

「まず(雑でもいいから)動くものを作ってみて、そこから学ぶ」という考え方。

僕のWPF開発スタイルも、カッチリしたMVVM一辺倒から、「ここは保守性重視」「ここはパフォーマンス重視」「ここは(メンテを捨ててでも)リッチな表現を優先」といった、柔軟なアプローチに変わっていきました。

そして、この「失敗を資産に変える」という考え方が、実はこのチームのもう一つの、さらにヤバい「最終伝統」(フックの予告)に繋がっていくんですが…それは、また次のお話で。

リリースノートに「バグあり」!? 炎上させるための最終訓練

(「承」のつづき)

「ムダコード大賞」のあの日から、僕のエンジニア人生は変わりました。

あれだけ呪いのように憑りついていた「完璧主義」が、スッと軽くなったんです。

もちろん、品質を疎かにするようになったわけじゃありません。

C#でクリーンなコードを書くこと。WPFで保守性の高いMVVMを設計すること。その「理想」は今も持っています。

でも、前との決定的な違いは、「完璧じゃないことを恐れなくなった」こと。

レビューで「この書き方、ちょっと自信ないんだけどどう思う?」と素直に聞けるようになった。

「(うわ、ダサい実装だけど)とりあえず動くバージョンを先にPR(Pull Request)しちゃおう。フィードバックもらってからリファクタリングしよ」と、スピードを優先できるようになった。

僕が「失敗(という名の学習)」をオープンにするようになったら、不思議なことに、チームの仲間たちも僕に対して、よりオープンに技術的なディスカussionをしてくれるようになりました。

「なぁ、このWPFのXAML、君のあの『芸術的ボツコード』のテクニック、一部使ってみたんだけどさ…」

なんて、アンドレイ(ロシア人)が相談してきたり。

「失敗を共有すれば資産になる」

マークが言っていたあの言葉を、僕は「なるほど、いいこと言うなぁ」なんてレベルじゃなく、実体験として噛み締めていました。

そう、あの「ムダコード大賞」(=定番のひねり)は、僕にとって最高の「人生術」だったんです。

……と、僕がすっかりこのチームの「柔軟な」やり方に馴染み、C#のコードもWPFのXAMLも、肩の力を抜いて書けるようになってきた、数ヶ月後のこと。

その日は、四半期に一度の「メジャーリリース」を翌日に控えた、木曜日の午後でした。

海外のIT現場とはいえ、さすがにメジャーリリース前はピリつきます。

QAチームからのバグ報告がレッドアラートで飛び交い、僕ら開発陣も「マジかよ、こんなエッジケース!」と悲鳴を上げながら、必死でC#のコードを修正していました。

日本時代の「リリース前夜」の地獄絵図と、まぁ、これは万国共通です。

「完璧な状態でリリースするぞ!」と、チーム全員が最後の追い込みをかけていました。

僕は、割り当てられたクリティカルなバグを全て潰し、ふと、QAのバグ管理システム(JIRAとか)を眺めていました。

「よし、クリティカルとメジャー(重要)なバグは全部『Done』になったな。あとは…」

ん?

僕は、あるチケット(バグ報告)で手が止まりました。

ステータスは「Open(未対応)」。

優先度は「Minor(軽微)」。

内容はこうです。

「特定の条件下(OSがドイツ語設定、かつ特定の画面解像度)において、あの『製造ラインのインジケーター』のグロー効果(ぼんやり光るやつ)が、『異常』じゃない時も、うっすらと点灯し続けてしまう」

……あ。

これ、僕が数ヶ月前に「芸術的ボツコード」で実装しようとしていた、あの「グロー効果」の、簡易版の、バグだ。

(結局、あのアニメーションは簡易版が採用されていた)

「Minor(軽微)」とはいえ、バグはバグ。しかも画面(UI)のバグは目立つ。

リリース前に修正すべきです。

僕はすぐに、修正方法を頭に思い浮かべました。(WPFのVisualTreeを辿って、トリガーの条件式を一つ直せばいいだけだ)

「やれやれ、最後の最後に見落としか」

僕は、コーヒーを淹れ直そうと席を立ったマーク(あの「ムダコード大賞」の主催者)を呼び止めました。

「マーク! ちょっといいすか。JIRAに『Minor』で残ってるバグが一個あります。これ、僕がすぐ直せますよ。今夜対応しちゃいます」

「ああ?」

マークは、僕が指差すJIRAのチケット番号を見ると、一瞬キョトンとした顔をし、次の瞬間、ニヤァ…と、あの「ムダコード大賞」の時と同じ、意地の悪い笑みを浮かべました。

「あー、それ? それ、直さなくていいよ

「……は?」

「いや、だから。そのバグは、修正しない。そのままリリースする」

僕は、耳を疑いました。

何を言ってるんだ、この人は。

「いや、でも、バグですよ? 軽微とはいえ、ドイツ支社の人から『なんかチカチカしてウザい』って報告が来てるじゃないですか。僕が今から1時間あれば直せます」

「だから、いいんだって」

「よくないですよ! リリースノートに『既知の不具合』として載せるんですか? カッコ悪いじゃないですか!」

僕の剣幕に、マークは「やれやれ」と肩をすくめました。

そして、僕を手招きし、会議室のホワイトボードの前に連れて行きました。

「なぁ」

と、マークはペンを取り、円を一つ書きました。

「君が日本でやってた『完璧なリリース』ってのは、これだ」

彼は、その円を指差します。

「バグがゼロ。QAのテストも100%パス。完璧なプロダクト。違うか?」

「…はい。それが理想です」

「じゃあ聞くが」とマークは続けます。

「もし、この『完璧なリリース』の直後に、誰も予期しなかった『超クリティカルなバグ』(例えば、サーバーが全停止するとか、顧客データが吹っ飛ぶとか)が見つかったら、どうする?」

「そりゃあ…」僕は答えに詰まります。

「緊急メンテナンスを入れて、大至急ロールバック(切り戻し)して、原因を特定して、ホットフィックス(緊急修正パッチ)を当てます…」

「その『ロールバック』の手順、本当に動くか、テストしたことあるか?」

「…それは、ステージング環境(本番そっくりなテスト環境)では…」

本番でやったことあるか?

マークの目が、鋭く光りました。

「いいか? 火災訓練(Fire Drill)ってのは、ベルを鳴らして『避難してください』って練習するだけじゃ、意味がねぇんだ」

「?」

「本当に火事が起きた時、パニックにならずに、スプリンクラー(監視アラート)がちゃんと作動して、防火扉(ロールバック手順)がちゃんと閉まって、消防隊(サポートチーム)が正しい場所に放水(顧客対応)できるか。それを確認するには…」

マークは、ホワイトボードに書いた「完璧な円」に、わざとペンで「黒い点(バグ)」を描き加えました。

実際に、本番環境で『小さなボヤ』を起こしてみるしかねぇんだよ

僕は、全身に鳥肌が立つのを感じました。

「まさか、そのドイツ語OSのバグって…」

「そう。それが今四半期の**『ゴールデン・バグ(意図的に残されたバグ)』**だ」

マークが明かした「最終伝統」。

それこそが、このチームが密かに行っている、最もクレイジーな訓練。

**「意図的障害(カオス)注入訓練」**通称「ファイヤー・ドリル」でした。

(※フックの「Ugly Sweater(ムダコード大賞)」が「内輪の失敗(開発)」の称賛だったのに対し、これは「本番環境(外部)」にまで『ひねり』を加えていた)

マークが説明します。

「俺たちは、四半期に一度、あえて『軽微』で『機能不全に陥らない』けど『必ず誰かが見つける』バグを一つ、意図的にリリースに混ぜ込む」

「もちろん、修正パッチはもう準備済みだ」と彼は自分のPCを指差します。

「そして、リリースと同時にタイマーをスタートさせる」

目的は3つ。

  1. 監視(モニタリング)が生きているか?「そのバグを、俺たち開発陣が『発見』するより先に、Datadog(監視ツール)が『異常』として検知できるか」
  2. サポート(顧客対応)が機能しているか?「顧客(今回はドイツ支社)からの問い合わせ(チケット)が、サポートチーム経由で、どれだけ早く、正確に開発チーム(俺たち)にエスカレーションされてくるか」
  3. 切り戻し(デプロイ)が迅速か?「『バグ発見』のトリガー(アラートか、顧客チケットか)が入ってから、俺たちが準備済みのホットフィックスを、どれだけ安全に、素早く本番環境に適用できるか」

「そんな…」僕は唖然とします。

「そんなの、サポートチームが可哀想じゃないですか! 顧客をダマすことになるんじゃ…」

「ダマす?」マークは首を横に振ります。

「逆だ。これは、俺たち開発チームから、サポートチームへの『挑戦状』であり、『最大の信頼』の証だ」

「『お前ら(サポート)がちゃんと機能してるか、試させてもらうぜ?』ってな。もちろん、サポートのマネージャーには話は通してある。『今週のリリース、何か一つ『ボヤ』を起こすから、準備しとけよ』ってな。だが、それが『何のバグか』は、彼らも知らない」

「だから、彼らも必死だ。俺たち開発陣の『ボヤ』を、誰よりも早く見つけて、『ほらよ、消しといたぜ!』ってドヤ顔で報告するために、リリース日は目を皿のようにしてる」

これが、僕が体験した「海外のIT現場」の、最も過激な「ひねり(Twist)」でした。

日本で僕が信じていた「完璧なリリース(=バグゼロ)」という「クラシック(古典)」。

それを、「あえてバグを仕込むことで、組織全体の『回復力(レジリエンス)』を鍛える」という、真逆の「ひねり」で上書きしていたんです。

「(『ムダコード大賞』で、失敗を『資産』に変えることを学んだ…)」

「(そしてこの『ファイヤー・ドリル』で、本番の『障害』すらも『訓練(資産)』に変えるのか…!)」

僕が「完璧な設計図」にこだわっていた頃には、想像もつかない世界でした。

WPFのコードがどうとか、C#の書き方がどうとか、そんなミクロな話じゃない。

チームが、組織が、「失敗」をどう扱うかという、根本的な「文化(カルチャー)」の違い。

僕は、ゴクリと唾を飲み込みました。

いよいよ明日、僕が数ヶ月前に関わった、あの「グロー効果」のバグが、意図的に世界中にリリースされる。

そして、このクレイジーな「最終伝統」は、僕にとんでもない「気づき」と、エンジニアとしての「次なるステージ」を突きつけることになるのですが…それは、この物語の「結び」で語ることにしましょう。

最強のエンジニアは「バグ」を恐れない。彼らは「回復力」を設計する

(「転」のつづき)

そして、運命のメジャーリリース日。

僕らの新しいコードは、全世界のクライアント(顧客)のマシンに向かってデプロイされていきました。

もちろん、あの「ドイツ語OSでのみ、うっすら光り続けるWPFコントロール」という「ゴールデン・バグ」と共に。

僕は、正直、生きた心地がしませんでした。

「(本当に大丈夫か…?)」

「(もし、このバグが『軽微』じゃなくて、何か別の重大な障害を引き起こしたら…?)」

「(これ、日本では『仕込みバグ』って言って、クビが飛ぶやつじゃ…)」

僕のそんな不安をよそに、シニアエンジニアのマーク(あの意地悪な笑顔の)は、いつも通りコーヒーを飲んでいます。

リリースから約2時間後。

ついに、その時は来ました。

Datadog(監視アラート)が鳴るより早く、サポートチーム専用のSlackチャンネルが発火しました。

ALERT [Support]: TICKET #4589 - German Office reports UI flickering on monitoring screen. (Severity: Medium)

(来た!)

僕の心臓が跳ね上がりました。

サポートチームが、顧客からの第一報をキャッチし、即座に「中優先度」として開発チームにエスカレーションしてきたんです。

マークが、ニヤリともせず、静かにSlackに返信します。

[Dev] Roger. Investigating. (承知。調査する)

そして、僕の方を向いて、一言。

「さあ、やれ。『訓練』だ」

僕は、この日のために準備されていた「ホットフィックス(緊急修正パッチ)」のブランチに切り替え、デプロイボタンを押す…

…寸前で、マークに手を止められました。

「待て」

「え?」

「まだだ。サポートチームに、もう一手間、仕事をさせてやれ」

マークはSlackにこう打ち込みました。

[Dev] @Support-Team, can you confirm the OS version and resolution? Need logs from the client. (OSのバージョンと解像度を教えて。クライアントのログも必要だ)

これは、「俺たち(開発)は、まだ原因が特定できていない」というフリです。

サポートチームは「ぐぬぬ…」とでも言いたげに、即座にドイツ支社と連携し、必要な情報を集めて返してきました。

[Support] Confirmed. German Win10, specific resolution. Logs attached. This seems to be the WPF glow effect bug we saw in staging. (確認した。ドイツ語Win10、特定の解像度だ。ログ添付。これ、テスト環境で見たWPFのグロー効果のバグじゃないか?)

(そうだよ! 当たりだよ!)と僕は心の中で叫びます。

サポートチームが「原因」にたどり着いた。

ここで初めて、マークが僕に頷きます。

「OK、Go」

僕は、ホットフィックスのデプロイボタンを押しました。

自動化されたCI/CDパイプラインが作動し、C#のコードがビルドされ、テストが走り、修正パッチが全世界に配信されていきます。

リリース(14:00)

顧客がバグ発見、サポートに連絡(16:10)

サポートが開発にエスカレーション(16:12)

開発とサポートが連携(フリ)し、原因特定(16:25)

ホットフィックス、デプロイ開始(16:26)

全顧客に修正パッチ配信完了(16:40)

「バグ発生」の第一報から、わずか30分弱で「完全鎮火」です。

Slackに、マークが書き込みます。

[Dev] Fix #4590 deployed. Please ask German office to restart the app. (修正パッチ展開済み。ドイツ支社にアプリ再起動を促してくれ)

数分後。

[Support] Confirmed. Flicker is gone. Closing ticket. …Nice try, Dev-Team. Too easy. (確認した。点滅は消えた。チケットを閉じる。…やるじゃん開発チーム。まぁ、簡単すぎたけどな)

[Dev] Glad you were awake, Support. Next time, we'll make it harder ;) (起きててくれてよかったよ、サポート。次はもっと難しくするぜ)

僕は、この一連の「茶番」とも言えるやり取りを見て、全身の力が抜けると同時に、とんでもない「気づき」に打ちのめされていました。


「完璧な設計図」を捨てた日

日本で僕が信じていた「完璧主義」。

C#とWPFの「完璧なMVVMアーキテクチャ」。

「完璧なリリース」。

それらは全て、「失敗しないこと(Prevention)」をゴールにしていました。

バグをゼロにすること。

設計図通りに作ること。

それが「品質」だと信じていました。

でも、このチームは違った。

彼らが目指していたのは、「失敗しても、すぐに立ち直れること(Resilience=回復力)」だったんです。

考えてみてください。

この「ゴールデン・バグ」の訓練。

彼らは、バグをゼロにしようとはしなかった。

その代わり、

  1. 監視(Observability) を強化し、「いつ壊れたか」を誰よりも早く知る仕組みを作った。
  2. サポート(Human Pipeline) との連携を訓練し、「顧客への影響」を最速で把握する流れを作った。
  3. デプロイ(Deployability) を自動化し、「どれだけ安全に、早く」修正を届けられるか、その速度を追求した。

「ムダコード大賞」(承)で学んだのは、「失敗を共有すれば『資産』になる」ということ。

そして、この「ゴールデン・バグ」(転)で学んだのは、「障害は『訓練』であり、『回復力』こそが本当の品質である」ということ。

これこそが、僕がこのブログで、これから海外で働こうとする皆さんに一番伝えたかった「人生術」です。


これから海外で戦う君たちへ

もし君が、僕と同じように「完璧主義」の呪いにかかっているなら。

もし君が、C#のコードやWPFのXAMLを、誰にも文句を言わせない「芸術品」に仕上げることに心血を注いでいるなら。

少しだけ、立ち止まって考えてみてほしい。

君のその「完璧なコード」は、明日、君がチームを去った後、誰かが安全に「変更」できるだろうか?

君のその「完璧な設計図」は、予期せぬ「障害」が起きた時、チームの「回復」を助けてくれるだろうか?

海外の現場(特に流れの速いIT業界)で求められるのは、「間違えないエンジニア」ではありません。

そんな人間は存在しないからです。

求められるのは、「安全に失敗でき、その失敗から爆速で学び、システム全体を昨日より少しだけ強くできるエンジニア」です。

「バグを恐れるな」とは言いません。バグは怖いです。

でも、「バグが起きる」ことを前提に、システムを設計してください。

君が書くC#のコードに、適切なログ(監視の目)を仕込んでください。

君が作るWPFのアプリに、安全に切り戻しできる仕組み(回復の手段)を組み込んでください。

君の技術力(C# / WPF)は、そのための「道具」です。

完璧なアーキテクチャを作ることが「目的」じゃない。

変化に強く、回復力の高いシステムを作ること。

それこそが、僕らエンジニアの本当の仕事なんだと、僕はあのクレイジーな「最終伝統」から学びました。

君のその「完璧主義」、そろそろ捨ててみませんか?

「失敗」を笑い飛ばし、「障害」で訓練する、最高にエキサイティングな世界が、海の外で君を待っていますよ。

コメント

タイトルとURLをコピーしました