ストーリー・ウォークスルー は何をしますか?
ユーザーは、自分が当事者ではなかった問題を理解したいと考えています。コンポーネント、用語、物事が起こる順序を知りません。調査結果の一覧や差分の要約は役に立ちません。ストーリーなら役に立ちます。各登場人物を一度紹介し、それぞれが何を行うかを起こる順序で示し、障害が自然に発生するまでを語ります。
まず調査してください。ストーリーはその背後にある事実と同じくらい優れているため、コード、ログ、チケット、ドキュメント、履歴を読んでから執筆してください。会話の中で既に調査が行われている場合は、繰り返すのではなくそれを再利用してください。
回答の構成
フレームを設定する一文で始めます。例:「コードを知らなくてもわかるように、最初からすべてのストーリーを説明します。」その後、以下のセクションを使用します。実際に言うことが何もないセクションは、水増しせずにスキップします。
登場人物
ストーリーに必要なすべての登場人物(コンポーネント、クラス、メッセージ、タイマー、データ、またプロセスの場合は関係者、チーム、フォーム、設定)を紹介し、それ以外は紹介しません。それぞれに太字の名前と、それが何であり、このストーリーで何を行うかを一文か二文で説明します。
- 各登場人物を正確に名前付けし、コードにリンクします。
price_cache_key()をファイル:行のリンク付きで書き、「キービルダー」とは書きません。あいまいなラベルは、読み手が立ち止まってその意味を考えさせる原因になります。登場人物が複数のコード(メソッドとその周りのフレームワークフック)にまたがる場合は、その旨をここで説明します。コード以外の問題の場合は、代わりにソース(ドキュメントと手順、フォームフィールド、または設定パス)にリンクします。 - 抽象的なメカニズムに対して1つの物理メタファーを選び、ストーリー全体でそれを維持します。 例えば、メッセージヘッダーは「封筒にホチキス止めされたメモ」、キャッシュは「ホワイトボード」、ロックは「鍵」になります。メタファーを実際の名前の隣で紹介します(「価格キャッシュ、各Webサーバーの隣にあるホワイトボード」)。これにより、読み手はコードにメタファーをマッピングできます。途中でメタファーを切り替えたり、2つ重ねたりしないでください。
- 各登場人物が従うルールを、イタリック体でその登場人物自身の考えとして表現します:「今日は、自分の時計が示す任意の日付です。」 バグやプロセスの失敗は通常、2つの妥当なルールが衝突することから発生し、これによりその衝突が後で可視化されます。
章
時間順に何が起こるかを、1章につき1ステップで説明します:## 第1章:真夜中前に買い物客が価格を確認する、## 第2章:新しい価格が到着する、など。何が起こるかを示す短いタイトルにします。
- 各章は短く(数文か数箇条書きに)抑えます。
- 章の重要な詳細を太字にします。読み手が見逃してはならない事実です(「インポートがホワイトボードの間違った隅を消去する」)。
- 2つのことが同時に起こる場合は、それに独立した章を割り当て、両方を交互に示します。
- 障害の章では、正確なエラーメッセージを引用符付きブロック引用として引用し、どのコードがそれをキャッチして何をログに記録するかを示します。
なぜ症状がそのように見えるのか
障害の後、観察されたパターン(最初の数時間だけ、一部のサーバーだけで、再起動後だけ)を説明します。それをチケットやログが実際に示したものに結び付けます。これはストーリーが正しいことの確認であり、そのまま残します。
問題が障害ではなくリスクである場合
時々、ストーリーは何かがうまくいかない可能性についてです。レビューコメント、潜在的なバグ、「もしも」です。何も失敗していないため、ストーリーを固定するログ行やチケットの症状はありません。読み手は引用されたエラーを見るとそれが発生したと想定するため、異なる伝え方をします。
- それが発生していないことを早期に述べます。 冒頭の行または最初の章で、これはログやテストで見られたものではなく、コードを読んで見つかった可能性のある障害であると述べます。
- 条件を明確にします。 障害の章では、障害が発生するために真でなければならない条件を番号付きで正確にリストします(「1. 操作がスコープ終了後に別のサービスを呼び出す、かつ 2. その呼び出しの周囲に新しいスコープが開いていない」)。その後、何が問題になるか(アサート、例外の種類、行)を指定します。誰も見たことのないエラーメッセージは引用しないでください。例外を指定する場合は、それがコードを読んで得られたものであると述べます。
- 「なぜ症状がこのように見えるのか」を「なぜ今日は何もヒットしないのか」に置き換えます。 実際の各呼び出し元またはフローをウォークスルーし、どの条件を満たさないかをリンク付きで示します。このセクションはストーリーの重みを担います。なぜなら、読み手はリスクが現実のものかどうかを判断する必要があるからです。
- 確認していない呼び出し元を探します。 リスクに対する「どの程度悪いか」のリストを作成することは、未確認のパス(通常の場所の外部で行われる呼び出し、異なるトランスポート、バックグラウンドタスク)が現れる場所です。それぞれを「未確認」としてリストし、省略せずに、どのような証拠があるか(たとえば、それをトレースせずに実施したクリーンなテスト実行など)を述べます。
- 修正セクションでコストを比較します。 リスクに対する修正は、実際の障害を引き戻す可能性があります。その場合は、修正が何にもヒットしないリスクと、発生する障害をトレードオフすることを明確に述べます。
なぜ今始まったのか
動作がリグレッションである場合、何が変更され、いつ、なぜその変更がそれ自体で理にかなっていたかを述べます。PRまたはコミットを、最初に言葉で指定し、IDを括弧内に記述します。読み手は、以前の変更が不注意ではなく、不完全だったに過ぎないことを知る必要があります。
どの程度悪いのか
実際の影響(データ、数値、アラート、ログノイズ)をリストします。確認済みのものと推測されたものは分離します。読み手はこれらの主張を他の人に繰り返すためです。
- 各主張を、確認済み(およびその方法:テスト、ログクエリ、エンドツーエンドで読まれたコードパス)か、未確認かとしてマークします。
- 何かが検証しない限り、「データは問題ない」とは書かないでください。もっともらしい主張が間違っていることが判明すると、正直に「未確認」と書くよりも信頼を失います。
修正方法
オプションを小さいものから大きいもの(例:クイックフィックスと適切な修正)の順に提示し、それぞれがストーリーの用語で何を変更するか(「両方の登場人物に同じカレンダーを与える」)とその限界を示します。最後に短い推奨事項で締めくくります。
スタイル
- 平易な言葉を使います。すべての用語は最初に登場したときに定義するか、省略します。
- コード識別子はメタファーの隣でバッククォートで囲み、ストーリーがコードに追跡可能なままになるようにします。
- 長いブロックよりも短い段落と箇条書きを優先します。
CLAUDE.mdまたはAGENTS.mdファイルからのユーザーの記述スタイルルールに従います。
ストーリーの後
登場人物に関するフォローアップの質問(「つまりXがハンドラーですか?」)を想定します。登場人物を正確なコードに固定して回答します。何が実行されるかを順序付きで ファイル:行 のリンク付きでリストし、重要な部分を行う部分を示します。質問が、元のストーリーで何かがあいまいに名前付けされていたことを示す場合は、その名前付けを守るのではなく回答で修正します。
例
references/example-stale-prices.md には、スタイルキャッシュのバグに関する完全なストーリーと、それで間違っていた点に関するメモが含まれています。セッションで最初のストーリーを書く前にそれを読んで、長さとトーンを調整してください。