あなたの仕事は、単にコードを書くことではありません。意思決定をすることです。そして、その決断から学ぶことです。時間を経るにつれ、ミスは減っていきます。やがて、あなたは同じ霧の中にいる他の人々を導く存在になります。ロジックを書くことから、結果に責任を持つことへと至るその軌跡こそが、単に構文を打ち込む人と、システムを構築する人を分かつものなのです。

あなたは毎日、選択をしています。ボタンの色を選ぶような、些細に思えるものもあります。一方で、製品全体を再構築させるようなものもあります。コツは、その両者が密接に関連していることを早い段階で認識することです。不注意に下された小さな決断は、後に大きな制約となり得ますが、初期に下された困難な決断は、後から振り返れば天才的な判断に見えることがよくあります。

初期段階の選択が及ぼす影響範囲(Blast Radius)

キャリアの初期段階では、ミスが響き渡る範囲は狭いものです。悪いコミットがローカルのビルドを壊す。雑な関数が1つの画面の動作を遅くする。影響範囲(Blast Radius)は限定的です。影響を受ける人は少なく、復旧コストもほとんどかかりません。

しかし、エンジニアとして、あるいは企業として成長するにつれ、あなたの決断はより多くのシステムを横断するようになります。同じ選択であっても、スケールした環境では数週間の損失を招く可能性があります。だからこそ、代償が大きくなる前に、今、計算された選択を行う術を学ばなければならないのです。

よくある3つの罠を考えてみましょう。

  • 依存関係がサポートしていないプラットフォームを使用すると、数十、数百ものエンジニアリング時間を浪費することになりかねません。それらの時間は単にタイピングをしている時間ではありません。奇妙な互換性の問題をデバッグし、間接的なライブラリをパッチし、なぜ単純な機能の実装に四半期もの時間がかかったのかをステークホルダーに説明するための時間なのです。

  • 製品の初期段階でセッションベースの認証からJWTへ移行しておくことは、後の高コストな書き換えを防ぎます。ユーザーが数百万人に達し、ダウンタイムが実損につながる状況よりも、ユーザーが数千人のうちにログインロジックをリファクタリングする方が、はるかに容易です。

  • 見積もりを「最善の予測の2倍」に設定するのは、そのバッファを品質を守るために使う場合にのみ有効です。SNSを閲覧するためにスケジュールを水増しするのは無駄です。テストを書き、エッジケースを検討し、オブザーバビリティ(観測性)を検証するためにバッファを持たせるのは投資です。

ここにあるパターンは単純です。技術的負債は複利で増えていきます。元本が小さいうちに返済しましょう。

カットオフ日とコントロールの錯覚

締め切りは至る所にあります。リリース日、デモ日、コードフリーズ。大企業において、それらは技術的な目的よりも、心理的な目的で機能することがよくあります。誰も完全には理解していない複雑さに対して、コントロールできているという感覚を生み出すのです。

その副作用は予測可能です。カットオフ日が近づくにつれ、品質が低下します。チームはテストを削り、エラーハンドリングをコメントアウトし、誰もメンテナンスしたくないようなコードをリリースします。締め切りは守られます。カレンダーは綺麗に見えます。しかし、製品の質は悪化しています。

これが起こるのは、エンジニアが完璧なコードやエレガントなアーキテクチャを好むからです。それは私たちの本性です。しかし、完璧な答えが常に存在するわけではありません。正しい選択とは、チームの現在の状態に適合する選択です。3人のスタートアップに、規制の厳しいヘルスケアプラットフォームと同じような形式的な手続き(ceremony)は必要ありません。5年前の1,000人規模のエンジニアリング組織に合わせるのではなく、現在の自分たちの立ち位置に合わせて構築するのです。

成長が古いルールを壊すとき

これはリーダーシップ層が見落としがちな点です。会社が成長するにつれ、締め切りもまた拡大しなければなりません。プロセスが拡張します。新しいメンバーが加わり、オンボーディングが必要になります。製品が増えることでタスクは倍増します。内部セキュリティレビュー、外部監査、データガバナンスのチェックといったコンプライアンス要件も積み重なります。扱う範囲(surface area)は広がっていくのに、ゴールラインは据え置かれたままなのです。

仕事量が増えているのに同じ締め切りを適用しても、チームは速くなりません。ただ雑になるだけです。手抜きが発生し、ドキュメントは消え、インシデント対応は完全に後手に回ります。かつてクリーンなコードを届けていたエンジニアたちが、カレンダーの制約のせいで、今ではその場しのぎの応急処置(bandages)を届けることになってしまうのです。

もし会社がスケールした状態でのスピードを求めるなら、並行して進める作業ラインを増やすか、タイムラインを延長するかのどちらかを選択しなければなりません。3人増員したときよりもタイトだったスプリントの中に、際限なく増え続けるバックログを押し込むことは不可能なのです。

バッファを組み込むこと

正気を保つための習慣を一つ:何かが上手くいかないことを前提にすることです。それは悲観主義ではなく、リアリズムです。

システムは故障します。サードパーティのAPIは遅延します。プロダクトマネージャーが昨日顧客と話したことで、要件が変わることもあります。摩擦(friction)を想定して計画を立てれば、締め切りは誠実なものになります。そうすることで、スピードと品質のどちらかを選ぶ権利を手にできるのです。そのバッファがなければ、毎回、選択肢はあなたではなく状況によって決められてしまいます。スピードを選ばざるを得なくなり、それは必然的に品質を犠牲にすることを意味するのです。

そのバッファこそが、学習が行われる場所でもあります。もしすべての時間が機能開発に割り当てられてしまうと、ビルドパイプラインの改善や、クエリレイヤーのリファクタリング、APIコントラクトのドキュメント作成を行う余裕が誰も持てなくなります。チームは現在のベロシティのまま、永遠に停滞することになります。

一つのエラーを別のエラーに置き換えること

私たちは現在、奇妙なトレードオフへと突き進んでいます。人為的なエラーを、非決定論的なソフトウェアのエラーへと置き換えようとしているのです。大規模言語モデルは、ジュニアエンジニアよりも速くボイラープレートを生成し、テストを提案し、ドキュメントの草案を作成できます。しかし、それらは自信満々に行い、かつ、次のような形で間違ったことをしてしまいます