リファクタ — ひとつの構造実験
リファクタは、観測可能な振る舞いを維持しながら構造を変更します。呼び出し元が選択したひとつの変換を実行し、その結果を報告します。
プロンプト
billing-service/internal/retry/backoff.go をリファクタリング: RetryRequest から指数バックオフ計算を独立した関数に抽出する。その他の振る舞い変更はなし。ベースラインを記録し、go test ./internal/retry/... を変更前後で実行し、差分サマリ、コマンド、結果、および未チェックの項目を報告すること。
成功条件
- レポートに保存された振る舞いが明示され、
go test ./internal/retry/...が変更前後で実行されたことが引用されている。 git diff --statがinternal/retry/backoff.goのみに影響し、無関係なファイルには触れていない。- 変更対象が出力を生成する場合、ゴールデンアウトプットのハッシュが変更前後でキャプチャされ、バイト単位で比較されている(例:
sha256sum前後比較)。 - レポートの「未チェックの振る舞い」リストが、空の場合でも出力に含まれており、ゲートがスキップした任意の表面を明示している。
手順
- 保存される振る舞い、焦点を当てた受理表面、およびその呼び出し元が直面する具体的な構造問題を明示する。呼び出し元のドメイン用語と受け入れられている振る舞いの例を再利用し、変更を通じてそれらの意味を維持する。
- 正直なベースラインを記録する。これには再現可能な既存の失敗も含める。実行可能な振る舞いの比較を評価する場合、開始ソースを固定し、編集前にベースラインを構築する。そのバイナリと比較入力を保持する。候補を同じ入力とツールチェーンを使って比較する。これにより、通常のリファクタリングに実行可能比較の儀式が追加されることはない。
- ひとつの境界のある変換を適用する: 抽出、リネーム、インライン化、単純化、カプセル化、移動、またはデッドコードの削除。結果はファイルサイズだけでなく、呼び出し元が理解しなければならないことと、ドメインルールを変更する必要がある場所によって判断する。
- 焦点を当てたチェックと、変更表面によって正当化される最小のパッケージレベルの回帰チェックを実行する。
- 差分サマリ、コマンド、結果、および未チェックの振る舞いを返す。
新たに発見された振る舞いの修正を構造変更と組み合わせてはならない。赤い結果は呼び出し元への証拠となる。このスキルは自動的に元に戻したり、範囲を狭めたり、再試行したり、コミットしたり、検証したり、後続の作業をルーティングしたりしない。
責任とインターフェースのコスト
インターフェースを追加したりモジュールを分割する前に、代表的な呼び出し元を検査する。それらが調整しなければならない概念の数を数える: 必要なセットアップ、順序、状態、エラーハンドリング、繰り返されるドメインルール。有用な境界は、まとまりのあるルールをひとつの所有者の下に置き、呼び出し元がそのルールを再現せずに結果を要求できるようにする。別の名前を追加するだけ、または同じ調整を呼び出し元に押し付けるだけのラッパーは拒否する。具体性のある呼び出し元の問題がその変更を正当化しない限り、既存の境界で十分である。
抽出された操作や型には呼び出し元の語彙を使用する。振る舞いを変える命名の曖昧さは、既存のドメイン定義に属する。その区別に作業が必要な場合にのみ ドメイン を参照する。公開シンボル、永続化フィールド、またはプロトコル値のリネームは、受け入れられたスコープがそれを提供しない限り、互換性変更となる。
変換にシーム(抽出境界、インターフェース、モジュール分割)が必要であり、複数の候補シームが存在する場合、切る前にプローブを行う。プローブは廃棄可能な分離環境で実行する(スクラッチブランチ、ワークツリー、または呼び出し元のポリシーが許可するコピーツリー): シームを仮実装し、それが強制するもの(シグネチャの変更、インポートサイクル、テストの書き直し)を確認し、プローブを破棄して知識だけを保持する。停止条件: プローブは最大2回。2番目の候補シームも抵抗する場合、3番目を試みる代わりに、両方の結果を呼び出し元に報告する。最初に思いついたシームを作業ツリーに直接切るのは時期尚早なシームの失敗モードである: 間違った境界が固まるのは、それを元に戻すコストがそれと共存するコストよりも高くなるからである。
中立性ゲート
「振る舞いを保存する」は実行するための主張であり、アサートではない。変換は振る舞いが同一であるという証拠に基づいてゲートする:
- 焦点を当てたチェックとパッケージレベルの回帰チェックが、変更前後で同じ既存の失敗セットとともに合格する — 新しい赤がなく、静かに消えた赤もない(テストが実行を停止することは振る舞いの変更である)。
- 出力を生成する表面(ジェネレータ、シリアライザ、フォーマッタ、レポート)については、出力のハッシュを取得する: 変更前に同一の入力に対するゴールデンアウトプットのハッシュをキャプチャし、変更後にバイト単位で比較する。ハッシュの不一致は、表面化して説明すべき振る舞いの差分であり、無視してはならない。呼び出し元が変更を維持するか、範囲を狭めるか、元に戻すかを決定する。
- 変更表面における観測可能なエラーメッセージ、終了コード、公開シグネチャは、呼び出し元が除外しない限り振る舞いの一部である。
事後的にスキップまたは範囲を狭められた中立性ゲートは事後的な中立性の失敗モードである — 差分が何をテストしたかを決定する。レポートの未チェックの振る舞いリストで、ゲートがカバーしなかった任意の表面を明示する。
参考文献
- 振る舞いを保存する単純化
- 振る舞いシナリオ
- 上流機能リファレンス — Matt Pocock; オリジナルの AgentOps への適応。