comprehende について
Comprehende は、Git diff をレビュー上の論点ごとに整理する CLI とローカル UI のワークフローです。差分と関連資料から説明文書を作成し、網羅性を検証して表示またはエクスポートします。
主な機能
- 01レビュー論点ごとに差分ハンクを分類
- 02ファイルとハンクのダイジェストを生成
- 03グループを資料や変更ストーリーに関連付け
- 04Git と照合して文書の網羅性を検証
- 05ローカルレビュー UI を提供
- 06静的レビューサイトをエクスポート
活用シーン
- 01ブランチやマージリクエストのレビュー整理
- 02独立した変更ストーリーの切り分け
- 03レビューグループと実際の差分の照合
- 04検証済みレビューをローカル UI や静的サイトで共有
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ matemolnar8/ comprehende --skill comprehendeインストール後、Claude Code で/comprehendeを入力して読み込まれたか確認します。
同梱ファイルreferences/example.mdreferences/review.schema.json
詳細
Comprehende
git diff をレビュー上の懸念事項ごとにグループ化し、ローカル UI を提供します。目的は認知を委ねるのではなく、認知負荷を軽減することです。人間が変更を盲目的に受け入れるのではなく、実際の diff と照らし合わせて考えられるよう、変更の理由と内容を示します。
レビュー対象のリポジトリ内で、すべてのコマンドを実行します。カレントディレクトリはリポジトリです。固定された CLI を使用します。
npx [email protected] <command>
レビュー文書は解釈のみを記載します。タイトル、グループ、要約、ハンクへのポインターを含みます。serve は git から diff を読み取ります。
diff ではなくダイジェストを基に作業します。ダイジェストには、各ファイルにつき1行で、種類、ハンク、シンボル、対応関係、コピーのヒントが記載されます。パッチは、ステップ3の1回の呼び出しで show を使って取得します。
ワークフロー
この変更のレビュー文書がすでにある場合は、代わりに「更新」の手順に従ってください。
ステップで指定されている場合、各ステップは1回のツール呼び出しで行います。記載どおりにコマンドをまとめて実行してください。追加の往復ごとに、コンテキスト全体を再送することになります。フェーズごとにツール呼び出しを1回だけ使います。ソースを含むステップ2のバッチ、1回の show バッチ、検証で終わる1回の書き込みです。それ以降の呼び出しは、検証で指摘された箇所の修正にのみ使います。
-
base と head を指定します。ユーザーが指定した ref を使います。三点リーダー(
base...head)はマージリクエストまたはブランチの diff です。変更がすでにデフォルトブランチにある場合は、リクエストに記録された base と head の SHA を使います。変動するデフォルトブランチのHEADには、それ以降のマージも含まれるためです。head の SHA しかわからない場合、指定された base ブランチとその head のマージベースを base とします。ユーザーが指定した ref がクローンにない場合は、ステップ2の呼び出しで最初にgit fetch <remote> <ref>を実行します。base と head の両方の ref 名を決めたら完了です。 -
シェルを1回呼び出し、ref を検証し、ドラフトを作成して、ダイジェスト、ドラフト、ログ、ソースを出力します。
$REVIEW_DIRは、その呼び出し内でリポジトリ外にmktemp -dを使って作成します。ref が解決できない場合、&&によってシェルはpregroupの前に停止します。失敗した ref をユーザーに伝えてください。REVIEW_DIR=$(mktemp -d) && git rev-parse --verify --end-of-options "<base>^{commit}" && git rev-parse --verify --end-of-options "<head>^{commit}" && { npm view comprehende version || true npx [email protected] pregroup --base <base> --head <head> --data "$REVIEW_DIR/review.json" npx [email protected] digest --base <base> --head <head> cat "$REVIEW_DIR/review.json" git log --format='%s' --end-of-options <base>..<head> for f in "<sourcesDir>"/*; do echo "=== $f"; head -c 10000 "$f"; done }ソースには、リクエストまたはチケット本文、各レビューコメント(スレッドが解決済みかどうか、コメントが古くなっているかどうか、現在の行番号を含む)、コミットの件名が含まれます。ディスク上のファイルには上記のループを使います。ホストの CLI による取得は、同じ
head -c 10000を通じてこの呼び出しに加えます。MCP からしかアクセスできないソースは、この呼び出しの後に、各ソースを1回ずつ取得する並列ブロックにまとめます。リクエスト内のチケット番号、ブランチ名、またはコミットの件名にチケットが記載されている場合は、ここでそのチケットを読み取ります。ユーザーがローカルの実行ファイルを指定した場合は、
npx [email protected]の代わりに指定されたコマンドをそのまま使い、同じシェル呼び出し内でnpm viewの代わりに<executable> --versionを実行します。出力された行が CLI のバージョンです。そのバージョンがこの固定バージョン(npx [email protected])より新しい場合は、停止してユーザーに伝えてください。ユーザーが実行できる選択肢としてnpx skills updateを示してください。このコマンドは実行しないでください。この固定バージョンを使って続行するか、更新してこのスキルを再度開始するか、ユーザーの指示を待ちます。バージョンが一致する場合、または照会に失敗した場合は、続行します。pregroupはドラフトを作成します。同じ変更を受けたファイルをまとめたmirrors-<n>グループ、名前変更・コピー・移動・生成された出力をまとめたmechanicalグループ、残りをまとめたchangeグループが作られ、各グループには仮の説明文が入ります。catはドラフトを出力します。same change as、pairs with、replacesのヒントを信頼してください。削除されたファイルをreplacesするファイルと、その置き換え元のファイルは、移動ではなく新しいバージョンとして扱い、両方の経緯を読んでください。ダイジェスト、ドラフト、ログ、ソースがコンテキストに揃ったら完了です。 -
ハンクをレビュー上の懸念ごとにグループ化します。ドラフトから始め、判断に必要なパッチを取得します。すでに1つの懸念だけを含むドラフトグループは、そのまま受け入れます。読み手が最初の部分だけで立ち止まってレビューする箇所で、
changeグループを分割します。1つの懸念に関わるドラフトグループは統合します。独立したPRにできた各ストーリーに名前を付けます。依頼されたストーリーに加え、依存関係に関する各ポリシー変更(厳密なバージョン指定から範囲指定への変更、またはその逆)、独立したドキュメント、依頼されたストーリーに不要なファイルのリファクタリング、テストについてのPRに含まれる本番コードが該当します。各ストーリーは、そのグループにpartとして指定します。ストーリーが1つだけなら、partは不要です。ダイジェスト内のファイルが6つ以下の場合は、機械的な変更でもコピーでもないファイルをすべて取得します。6つを超える場合は、分割の判断材料となるハンクか、lookFor の箇条書きの根拠となるハンクだけを取得し、取得は最大8回までにします。理由はそれぞれ先に記載します(「login.tsのハンクは別にできる可能性があります」)。ドラフトのmirrors-<n>グループとmechanicalグループは取得不要です。show の呼び出しは1回です。npx [email protected] show --base <base> --head <head> --hunk "<ref>"; npx [email protected] show --base <base> --head <head> --file "<path>"ストーリーすべてに
part名があるか、ストーリーが1つだけであり、show の出力がコンテキストに含まれているか、取得が不要になった時点で完了です。 -
ドキュメントを作成します。ドキュメントの
title(必須)、ドキュメントのsummary(必須)、ドキュメントのwhy(ソースに動機が記載されている場合のみ)を記述します。各ソース項目をダイジェストと取得したハンクに照らして確認します。相違点はそれぞれ、ドキュメントのlookForの箇条書きにします(lookFor を参照)。サマリーは、ダイジェストのシンボルと種類、および取得したハンクに基づいて記述します。各グループにはwhyとsummaryを指定します。グループのsummaryは、ファイルの一覧ではなく、ハンク同士の関係を1つ述べる文にします。引用の前に、主張を述べているソース内の文を見つけ、その文だけの根拠としてそのソースを引用します(The what と The why を参照)。取得したハンクに動作変更が隠れているグループには、予測されるトレースを記したlookForの箇条書きを追加します(lookFor を参照)。ドラフトの各参照を、その参照が該当するグループに一字一句変えずにコピーします。ドラフトの参照はすでに現在の git と一致しています。パスはそのファイルのすべてのハンクを対象とします。ファイルが複数のグループに分割されている場合に限り、ハンク参照(path@oldStart+newStart。Grouping rules を参照)を記述します。ドラフトのversionとsourceはそのまま使用します。以下のフィールド形式に従い、引用符付きヒアドキュメントを使って1回のシェル呼び出しでreview.json全体を作成し、その後validateを実行します。cat > "$REVIEW_DIR/review.json" <<'EOF' <the document> EOF npx [email protected] validate --data "$REVIEW_DIR/review.json"すべてのソース項目に判定があり、すべての相違点がドキュメントの
lookForの箇条書きになっている時点で完了です。取得したハンクに示された動作変更はすべて、グループのlookForの箇条書きになっている必要があります。ドラフトの各参照は少なくとも1つのグループに含まれ、分割されたファイルの現在のハンクはすべて名前が付けられ、仮の文章は削除されている必要があります。名前の付いた各partには、ドキュメントのparts[]エントリが必要です。各dependsOnの ID は、同じpart内のグループを示す必要があります。各引用は、そのソースに記載された文を根拠とする必要があります。また、各ユニットテストが検証対象のコードと同じグループにあり、複数のグループから呼び出される各ヘルパーが、それらのグループに共通する基盤グループにあり、新しい各ハーネスがそれを実行するビルドまたは CI と同じグループにあり、各機能仕様がそのシードおよびヘルパーと同じグループにあり、1行だけの各呼び出し箇所または宣言が、それが機能するコードと同じグループにある必要があります。独立したPRにできた依頼外の作業には独自のpartを割り当て、関連する有効化作業は1つのpartにまとめ、各機械的な変更のサマリーには、読み手が何を読み飛ばせるかを記述します。あるストーリーが別のpartを前提とする場合、suggestedOrderではそのpartを先にします。フィールド形式です。各語はプレースホルダーです。この形式で有効なドキュメントを作成できます。
{ "version": 1, "source": <the draft's source object, unchanged>, "size": "small", "title": "Short name", "summary": "What the change is.", "groups": [ { "id": "helper", "title": "Group title", "why": "Why this group exists.", "summary": "What this group is.", "suggestedOrder": 0, "hunkRefs": ["src/file.ts"] } ] }そのフィールドの定義セクションで記述するよう指定されている場合は、フィールドを追加します。ドキュメントでは
why、lookFor、parts(name、summary)を指定します。sourcesにはid、kind(ticket、pr、pr-comment、commit、transcriptのいずれか)、labelに加え、あればurl、title、gist、partを指定します。グループにはpart、sources(該当する ID)、lookFor、dependsOn(グループ ID)を指定します。pr-commentソースにはauthorとbodyも必要です。また、The why の PR コメントに記載がある場合は、ピン(path、side、line)も指定します。sizeはtrivial、small、medium、large、very-largeのいずれかです。 -
validateを実行してステップ4の呼び出しを終了します。修正または Refresh での編集後は、絶対パスを指定してnpx [email protected] validate --data "$REVIEW_DIR/review.json"を実行します。次の項目をチェックします。すべてのライブハンクがグループに含まれていること、すべての参照がライブの git と一致すること、すべてのsource:ID がsourcesに存在すること、すべてのディレクトリ参照が機械的なファイルのみを含むこと、すべてのグループのpartにparts[]エントリがあること、すべてのdependsOnが同じpart内のグループを指定していること、すべての PR コメントのピン(path、side、line)がライブ行と一致すること、ドキュメントに未知のフィールドがないこと。失敗した場合は、メッセージで指摘された箇所を修正します。diff は git のものなので、そのままにしておきます。validate が終了コード 0 で終了すれば完了です。 -
ユーザーからレポートのアップロードを依頼された場合は、Export に従います。それ以外の場合は、
npx [email protected] serve --data "$REVIEW_DIR/review.json" --openを実行し、localhost の URL(127.0.0.1のみ)をユーザーに伝えます。
references/example.md は、フィールド形式を記入した任意のサンプルです。
エクスポート
静的サイトを書き出し、そのフォルダーをユーザーが指定した場所に配置します。
npx [email protected] export --data "$REVIEW_DIR/review.json" --out "$EXPORT_DIR"
$EXPORT_DIR は作業ツリーの外にある新しいディレクトリで、git リポジトリではありません。このフォルダーには UI と固定された git ペイロードが含まれます。中に git はありません。ユーザーが指定した URL またはパスを取得できれば完了です。review.json がまだ下書きの場合は、エクスポートの前に Workflow の validate までを完了します。
リフレッシュ
既存のレビューを新しいコミットやリベースに引き継ぎます。変更されていないハンクの説明文はそのまま残り、レポートで指定されたグループだけに新しい文言を加えます。
以前のドキュメントは、ユーザーが指定した review.json、またはホストされたエクスポートの api/review.json の document フィールドです。まず、新しいディレクトリにコピーします。
REVIEW_DIR=$(mktemp -d) && curl -fsSL "<site-url>/api/review.json" | jq .document > "$REVIEW_DIR/review.json"
-
1 回のシェル呼び出しで、参照を取得し、リフレッシュして、ドキュメントを出力します。参照はデフォルトでドキュメント自身の
baseRefとheadRefを再解決します。ユーザーが別の参照を指定した場合は、--headまたは--baseを渡します。git fetch --quiet <remote> && { npx [email protected] refresh --data "$REVIEW_DIR/review.json" cat "$REVIEW_DIR/review.json" }refreshは、パスと変更行が同じハンクを、開始位置が変わっていても保持し、参照先を更新します。同じファイルの同じ領域で別の行に編集されたハンクはchangedとなり、グループは維持されます。空白だけが移動した場合はreformatとなります。ハンクが差分から外れた参照は削除されます。どのグループにも含まれないすべてのハンクは、説明文のひな形を含むドラフトのupdateグループに追加されます。ディレクトリ参照の下にある新しいハンクも同様です。レポートには、新しいコミットの件名、ハンクが変わったファイルごとの 1 行(new、changed、reformat、same、goneと、そのハンクが属するグループ)、およびグループごとの変更内容が出力されます。「nothing to refresh」は、参照がドキュメントに記載されたコミットに引き続き解決されることを意味します。正しいリモートから取得するか、head を指定してから、もう一度実行してください。レポートとドキュメントがコンテキストに含まれれば完了です。 -
Workflow のステップ 2 と同じ情報源を、ステップ 1 のシェル呼び出しに追加します。ドキュメントの
lookForの箇条書きはリクエスト本文を参照するため、本文を再度読み込みます。urlがすでにsourcesにあるコメントは、エントリを維持し、現在の行と解決済みの状態だけをピンにコピーします。新しいコメントは全文を読みます。コミットの件名はレポートにあります。新しいコメントと件名がすべてコンテキストに含まれれば完了です。 -
--baseと--headに新しい範囲を設定して、レポートでnewまたはchangedと示されたハンクを対象に、1 回のshowバッチを実行します。リストされたファイルが 6 個以下の場合は、newまたはchangedのハンクをすべて取得します。6 個を超える場合は、ステップ 3 の予算をレポートに記載されたファイルに適用します。保持されたlookForの箇条書きが根拠としている場合に限り、sameまたはreformatのハンクを取得します。 -
編集ツールを使って
review.jsonを直接編集します。変更しないグループは一字一句そのまま残します。各update参照を、関連する懸念事項を扱うグループ、または新しいグループに移し、その後updateを削除します。レポートで指定されたグループでは、新規または変更されたハンクによってグループの内容が変わる場合はsummaryを書き換え、goneになったハンクに対応するlookForの箇条書きをそれぞれ削除し、changedのハンクに対応する箇条書きを取得したハンクと照らして再確認します。ハンクの意味が変わらない指定グループ(reformatのハンクだけを含むグループなど)は、説明文をそのまま残します。now emptyのグループと、そのグループを指定するすべてのdependsOnを削除します。新しいコミットで解決されたドキュメントのlookForの箇条書きは削除します。変更で対応されていない作業を求める新しいコメントは、新しい箇条書きにします。新たな負担に応じてsizeを変更し、情報源に変更があった場合に限りtitleとwhyを変更します。updateがなく、空のグループも説明文のひな形も残らず、指定された各グループの説明文が head のコードと一致すれば完了です。 -
Workflow のステップ 5 と 6 を実行します。検証後、以前と同じ場所に配信またはエクスポートします。URL の末尾に
#changesを付けてユーザーに伝えます。このページでは、今回のレビューと、refreshがその隣に保持したレビューを比較できます。
タイトル
ドキュメントの title は変更全体を表す短い名前です。必ず記入してください。
この変更を明確に表すものとして、人がすでに付けたタイトルがある場合は、それを優先します。プルリクエストのタイトル、チケットのタイトル、またはトランスクリプトで使われた名前などです。説明的で、レビュー対象の変更を表している場合は、その表現を維持します。
情報源がない、曖昧である、または別の内容を指している場合は、タイトルを新たに考えます。ブランチのスラッグ、「WIP」、「fix」はタイトルではありません。情報源のタイトルは、変更内容に合致する場合に限り維持します。
その理由
ドキュメントの why には、下記のソースだけから推測した、この作業が存在する理由を1文または2文で記載します。ソースに示されている問題または目標です。記載する前に、その問題または目標を述べているソースの文を見つけてください。「SSO ログインをサポートする」「管理者が監査ログをエクスポートできるようにする」「リトライによって API が過負荷になる」などです。変更内容だけを述べている文(「設定ページがモーダルになる」「アップロード先が S3 に移る」など)は、概要に記載します。問題や目標を述べたソースの文がない場合、またはソースの内容が混在している場合は、why を省略します。ソース自身の言葉で記述し、ソースに示されていない原因、メリット、読者のニーズを加えないでください。共通するソースがない、互いに無関係な2つのプロダクトのストーリーを挙げたリクエストにも、ドキュメントの why は記載しません。それぞれのストーリーには、独自のグループ why を設定します。
すべてのグループに why を設定します。つまり、そのグループが存在する理由です。引用には、ソースに書かれている内容だけを記載します。また、ソースが選択の理由を述べている場合に限り、そのソースを選択の理由として扱います。懸念を明確に述べているソースが最適です。それ自体のソースがない基盤グループについては、それに依存するグループを支えることを記載すれば、why として十分です。独立したサイド作業(ドキュメントのみ、テストのみなど)には独自のグループ why を設定し、ドキュメントの why には名前の挙がった動機を記載します。
ソースは読み取り、レビュー用ドキュメントにはコピーしません。ただし、PR コメントは例外です。UI に引用を表示できるよう、author と body をコピーします。チケット本文、リクエストの説明、コミット文、トランスクリプトのテキストは review.json に含めないでください。ソースに依拠する文は、[text](source:s1) の形式で文章内に引用します。
- チケットとイシュー。
sources項目を出力します。短いid(s1)、kindのticket、label(#24)に加え、情報があればurl、title、gist、partを含めます。そのストーリーのグループが同じpartを持つ場合は、チケットにpartを設定します。 - プルリクエスト。ユーザーがプルリクエストまたはマージリクエストを指定した場合は、
kindをprとし、PR #32のようなlabelと、説明から作成したgistを出力します。 - PR コメント。文章内で引用するコメントごと、およびピン留めするコメントごとに、
pr-commentソースを1つ出力します。alice on PR #32のようなlabelを付けます。authorとbodyをコピーします。スレッドをフラット化し、コメントごとに1つのソースを作成します。スレッドが未解決で、フォージが現在の行を報告しており、古くなっていないコメントをピン留めします。ピンにはpath、side、lineを指定します。sideは、ベースファイルの行ならold、ヘッドファイルの行ならnewです。GitHub では、LEFTはold、RIGHTはnew、現在の行はline(original_lineは古いコミット上の行)、未解決のスレッドはisResolvedが false、古くなったコメントはisOutdatedが true、または現在の行が null です。会話コメントには行がないため、ピンは設定しません。 - コミットメッセージ。
git log --format='%s' --end-of-options <base>..<head>を使用します。コミットに動機が記載されている場合は、kindをcommitとして出力します。labelには、そのサブログまたは同じログの SHA を指定します。これらはグループのwhyを明確にするために使用できます。ドキュメントのwhyには、上記のより強いソースのいずれかが必要です。 - トランスクリプト。すでに手元にあるコーディングエージェントのトランスクリプト(このセッションまたは過去のセッション)から、人間が述べた理由を確認できます。
kindをtranscriptとし、Cursor session · Aug 12のようなlabelとgistを指定します。urlは省略します。
文章内で引用しない場合でも、グループが使用するソースの id は、そのグループの sources 配列に指定します。sources に存在しない ID を持つ source: の href があると、validate は失敗します。
変更内容
ドキュメントの summary には、変更内容を示す1〜2文を記述します。PR に複数の独立したストーリーが含まれる場合は、それぞれを含めてください。why がなくても、すべてのレビューに summary が必要です。これは変更内容であり、変更の動機ではありません。
グループで part を使う場合は、独立したストーリーごとにドキュメントの parts[] エントリを1つ記述します。name には、その part 文字列を指定します。summary は、そのストーリーの内容を示す1文を、グループの summary と同じ文体で記述します。ドキュメントの summary では引き続き各ストーリーを示し、各パートの summary では、色付きの「概要」列に表示されるストーリーごとの変更内容を示します。どのグループにも part がない場合は、parts を省略します。
グループの summary は、各グループの内容を示す1文とし、ハンク同士の関連性を説明します。「routes.ts のルートが core.ts の新しいバリデーターを呼び出す」のように記述し、ファイルごとの要約やパスの列挙は避けます。mirrors-<n> と mechanical のドラフトグループをそのまま残す場合は、読者がスキップしてもよい部分と、その理由を安全性に結び付けて説明します。同じ変更の繰り返し、純粋な移動、または同じ内容を表す再生成された出力などが該当します。
グループ化のルール
- レビュー上の関心事ごとにグループ化します。なぜこれらのハンクをまとめて読むのか、という観点です。ディレクトリ単位でグループ化できるのは、そのディレクトリ自体が関心事である場合に限ります。
- グループは、レビュー担当者がひとまとまりの表現で名付ける一つの関心事です。そのグループでは、コード、それを確認する単体テスト、それを担う一行の呼び出し箇所、宣言、再エクスポートをまとめて読みます。ダイジェストの
pairs withヒントには、テストのモジュール名を指定します。新しい統合テストハーネスはそれ自体が関心事です。そのハーネスと、それを実行するビルドまたは CI ファイルは一つのグループであり、検証対象の本番コードのグループには含めません。新機能のコード、フィクスチャ、シードデータ、ヘルパー、それらを実行する仕様は一つのグループです。基盤の分割は、後続の複数のグループで共有する契約のために行います。複数のグループから呼び出されるヘルパーは、それを定義するファイルとともに、その基盤に含めます。読者が最初の部分だけを単独でレビューするところで、関心事を分割してください。 - 一つのハンクが複数のストーリーで重要な場合は、複数のグループに含めてもかまいません。一つのハンクに二つの関心事がある場合、そのハンクを含むグループでは両方を明記します。
dependsOnは、一つのストーリー内における実際の依存関係を示します。つまり、このグループを理解するために、先行グループが必要であることを示します。依存関係は一つのパート内にとどめます。ストーリー内の読み順は、契約と基盤、呼び出し箇所、機械的な作業の順です。独立した作業は、それぞれ独自のpartと空のdependsOnを持ちます。2つ目の機能、追加のプロダクトイベント、依存関係ポリシーの変更、単独で PR にできたドキュメントは、独立した作業です。依頼されたストーリーを実現するためだけに必要な依頼外の作業(パス名の変更、フィクスチャの配置、ローカル起動)は、そのストーリーまたは一つのハーネス用パートに含めます。依頼されたストーリーに両方が必要な場合、二つの関心事を一つのpartにまとめます。そうでなければ、別々のパートにします。partは、独立した一つのストーリーを表す短い名前(数語)で、ストーリー内のすべてのグループで同じ名前を使います。UI では、共通のパートが同じ色で表示されます。名前ごとに、ドキュメントのparts[]エントリーを一つ作成します。- 機械的な作業(インポート順の入れ替え、識別子だけの名前変更、生成コード、フォーマット、純粋な移動)は、それぞれのドラフト参照とともに独自のグループにし、リスクが見えるようにします。ドラフトの
mechanicalグループには CLI がフラグを付けたファイルがすでに含まれています。各行が引き続き該当することを確認してください(フラグ付きファイルに実際の動作変更がある場合は、そのパスに基づいて該当するストーリーに移します)。また、読者が何を読み飛ばせるかを説明する要約を記述してください。ドラフトのmirrors-<n>グループ内のファイルは、ソースと同じ変更を受けています。このグループの要約には、変更が繰り返されていることを記載します。ストーリーがあるために機械的なグループが存在する場合、そのストーリーの最後のグループにし、そこに依存するグループがないようにします。単独で PR にできた場合は、独立したパートにします。 suggestedOrderは、独立したパートも含め、レビュー全体の順序を示します。機械的な作業、独立したドキュメント、テストのみの整理は最後にします。- ドキュメントの
sizeは、人がレビューする際の負担を表します。trivial、small、medium、large、very-largeがあります。一つのグループで40個のファイルが単一のインポートを変更するだけなら、smallです。新しいコンポーネントに加えて、既存画面全体にわたる追加変更がある場合は、mediumです。後続のグループが依存する新しい契約がある場合は、largeです。それらのグループを統合する場合も、そのsizeは維持します。 - 網羅性:有効なすべてのハンクが、少なくとも一つのグループに含まれている必要があります。パスは、そのファイルの有効なハンクすべてをカバーします。グループ間で参照が重複してもかまいません。参照されていないハンクがあると
validateが失敗し、UI では「未割り当て」と表示されます。ドラフト内のすべての参照は、すでにそれぞれのハンクをカバーしています。ファイルを複数のグループに分割する場合はハンク参照が必要ですが、それ以外はドラフトのパスをそのまま使います。 - ロックファイルにはハンク参照がありません。CLI はロックファイルをドラフトから除外し、UI では独立した閉じたバケットに表示します。ハンク参照が存在するのは、ドラフトに記載されたハンクだけです。
- リベースによって行番号だけがずれた場合、パスは引き続き有効です。開始行が移動すると
path@oldStart+newStartは古くなり、validateが失敗します。refreshを実行すると参照先が更新されます(「更新」を参照)。hunkRefsのエントリーは、そのグループがファイルのすべての有効なハンクを保持している場合、パス文字列になります。ドラフトからパスをコピーしてください。末尾が/のパスは、そのディレクトリ配下にある、ほかの参照が指定していないすべての有効なハンクを保持します。最も具体的な参照が優先されます。ダイジェストでは、機械的な変更のファイルが半数以上を占めるディレクトリについて、1 行で出力します。ドラフトではそのディレクトリを 1 つの参照として保持し、その行より下に列挙されたファイルはすでにその参照に含まれています。そのファイルの 1 つを対応するストーリーに移すには、そのストーリーのグループにパスを指定します。ディレクトリ参照からはそのファイルが外れます。ディレクトリ参照が、機械的な変更ではないファイルをまだ保持している場合、validateは失敗します。ファイルが複数のグループに分割されている場合は、各ハンクをpath@oldStart+newStartとして指定します。リネームされたハンクの場合は、old/path -> new/path@oldStart+newStartとします。oldStartとnewStartは、ダイジェストの行(hunks: path@oldStart+newStart)、またはshowが出力する@@ -oldStart,oldLines +newStart,newLines @@ヘッダーからコピーしてください。識別子は(path, oldStart, newStart)であり、リネームされた場合はoldPathも含みます。画像ファイルはパスで指定します。
lookFor
lookFor は、ライブ差分を初めて読んだだけでは注意深いエンジニアも見落としそうな点を記載するためのものです。デフォルトでは lookFor を空にし、各箇条書きには取得結果を根拠として付けてください。箇条書きは、対象のハンクに対して show を実行した場所、またはダイジェストとソースですでに裏付けられている場所に限ります。各箇条書きには 1 つの指摘を記載します。必要に応じて短いリスクタグ(Subtle、Breaking、Race、Perf)を付け、その後に、head のコードが何を行い、読者にどのような結果が見えるかを事実として 1 文で記述してください。人間がライブ差分と照合して判断を確定します。擬似コード、図、折りたたまれた差分、コミット一覧、ハンク数、合否マークは含めないでください。
グループの lookFor には、そのグループのハンクに関する指摘を記載します。ハンクに隠れた動作変更がある場合は取得し、予測される実行の流れを記述してください。具体的で現実的な小さな入力、旧経路と新経路が分岐する箇所、観測できる結果を含めます。次の内容は箇条書きに値します。
- 等価性や識別性(オブジェクトとプリミティブフィールド、ポインターと内容)の変更。同じように見える 2 つの入力が、今では異なるものとして比較されます。
- アプリの動作を回避するハンク(スリープ、強制的な書き込み、再試行など)。回避策がない場合にアプリがどう動作するかを記載します。
- ソースがテスト、CI、またはツールに関する PR 内のアプリケーションソース下にあるハンク。テスト PR に含まれる本番コードであることを示し、その動作変更を記載します。
- テスト出力ではないファイルを削除または上書きするセットアップまたはティアダウンスクリプト。そのパス、実行されるタイミング、開発者が失うものを記載します。
- どのソースにも記載されていない動作変更。
- レビューコメントを解決するハンクのうち、ハンクだけでは対応内容が明らかでないもの。修正内容を記載します。
リネーム、書式変更、文言のみのドキュメントグループでは、空が正解です。ドラフトの mirrors-<n> グループと mechanical グループも、取得結果で裏付けられない限り空のままにしてください。
ドキュメントの lookFor には、変更全体とソースと head のコードとの食い違いに関する指摘を記載します。ソース項目は、チケットの各要件および受け入れ項目、プルリクエストの説明とコミットメッセージに記載された各動作上の主張、レビューコメントの各依頼です。テスト計画、手動 QA のメモ、対象外リストは文脈であり、項目ではありません。各項目のソースを読み、判定してください。判定は「依頼どおりに完了」「異なる形で完了」「未完了」「head 時点で事実ではない」のいずれかです。「依頼どおりに完了」以外の判定は、それぞれ箇条書き 1 つで記載します。ソースが何を依頼または述べているか、ダイジェストまたは取得したハンクが何を示しているか、ソースまたはコードに理由が示されている場合はその理由を記載し、理由が示されていない場合はその旨を記載します。後続のソースによって以前の依頼が変更された場合(レビューコメントがチケットの内容を上書きする場合など)、チケットの項目は「異なる形で完了」となり、箇条書きでは両方のソースを示します。変更に手動手順が必要だとソースに記載されている場合(設定を有効にする、マイグレーションを実行するなど)も、箇条書きにします。[text](source:s1) の形式で引用します。ID は sources に記載し、不明な ID があると validate は失敗します。箇条書きが不要な場合は、このフィールドを省略してください。
説明文を書く
ドキュメントのtitle、ドキュメントのwhy、グループのwhy、summary、lookForは、初めて読む疲れたエンジニア向けです。
- 1文につき1つの考えを述べます。25語ほどを超えたら文を分けます。
- 現在形を使います。誰が何をするのかを明記します。
- 実際のシンボル、パス、フラグ、コマンドを使います。
- 役に立たない言葉はすべて削ります。変更履歴のような文体や大げさな表現、「XだけでなくYも」といった言い回しは避けます。
- シンプルなグループに必要なのは、タイトル、
why、summaryだけです。あとはライブ差分で伝わります。