Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:59:12 +08:00
commit b700a9b494
20 changed files with 2716 additions and 0 deletions

62
commands/codex_review.md Normal file
View File

@@ -0,0 +1,62 @@
---
description: Codex MCPを使ってコードの変更を客観的にレビューします。現在作業中のspec workflowがある場合は仕様に沿ったレビューを実施します。
---
# Codex MCPを使ったコードレビュー
コードの変更内容に対してcodex mcpを使って客観的なレビューを実施します。
## 実行手順
### 1. デフォルトブランチの取得
まず、リポジトリのデフォルトブランチを取得してください:
```bash
git symbolic-ref refs/remotes/origin/HEAD --short | cut -d/ -f2
```
このコマンドでデフォルトブランチ名main や master など)を取得し、後続のステップで使用します。
### 2. spec-idの判定
Taskツールで `syou6162-plugin:detect-spec-workflow` サブエージェントを呼び出し、現在の作業に該当するspec-idを判定してください
```
Taskツールで以下のパラメータを指定
- subagent_type: "syou6162-plugin:detect-spec-workflow"
- description: "spec-idの判定"
- prompt: 現在のブランチ名やコミットメッセージから推測されるタスク概要
「detect-spec-workflowサブエージェントの追加とドキュメント更新」
```
### 3. Codex MCPでのレビュー実行
前述のステップで得たspec-idの有無に応じて、以下のようにCodex MCPを呼び出してください
**spec-idが取得できた場合**
```
mcp__codex__codex ツールを使って以下のプロンプトでレビューを実行:
「<デフォルトブランチ名>ブランチとの差分を日本語でレビューしてください。
このプロジェクトではspec workflowという仕様駆動開発のワークフローを使っています。
- `.spec-workflow/steering/`にプロジェクトの方向性を示すsteeringドキュメントがあります
- `.spec-workflow/specs/<取得したspec-id>/`に現在開発中の機能の仕様とタスクの進行状況があります
これらを読んで、仕様に沿った実装になっているかレビューしてください。」
```
**spec-idが取得できなかった場合**
```
mcp__codex__codex ツールを使って以下のプロンプトでレビューを実行:
「<デフォルトブランチ名>ブランチとの差分を日本語でレビューしてください。」
```
### 4. レビュー結果の報告
Codex MCPからのレビュー結果をユーザーに報告してください。

View File

@@ -0,0 +1,139 @@
# Pull Requestのサイズ見積もりと分割提案
指定されたタスクに対してPull Requestのサイズを見積もり、必要に応じて分割の提案を行います。
## 実行手順
1. **リポジトリの基本情報収集**
- コードベースの構造分析(言語、フレームワーク、ディレクトリ構成)
- 既存のテストとソースコードの比率分析
2. **過去のPull Request履歴分析**
```bash
gh pr list --author @me --state merged --limit 20 --json number,title,additions,deletions,commits
```
3. **詳細なPull Request分析**
- 直近10-20件のPull Requestについて、以下を分析
- 変更行数(追加・削除)
- コミット数(レビュー対応の多さの指標)
- 変更の性質(機械的変更 vs ロジック変更)
4. **作業量見積もり**
- ソースコード変更予想行数
- テスト追加予想行数(既存比率から算出)
- ドキュメント更新予想行数
- 設定ファイル・マイグレーション等の付随作業
- 各フェーズの見積もりには必ずテストコードの行数を含める
5. **Pull Request分割アドバイス**
- 500行以下単一Pull Request推奨
- 500-1000行分割可能性検討
- 1000行超分割強く推奨
- アーキテクチャ考慮した分割順序提案
## 分析ポイント
### 変更の性質分類
- 機械的変更一括置換、フォーマット調整、import整理等
- ファイル数多くてもレビュー負荷低
- ロジック変更:新規実装、既存ロジック修正
- 少ない行数でもレビュー負荷高
### 分割戦略
- レイヤー別分割DB層 → API層 → UI層
- 段階別分割:設定変更 → 実装 → テスト
- 依存関係考慮:破壊的変更の分離、マイグレーション等
### 避けるべき分割パターン
以下のような分割は絶対に避けてください:
- フェーズ1: 機能実装のみ
- フェーズ2: 統合作業
- フェーズ3: テスト追加
理由:
- テストのない実装コードをレビューすることは非常に困難
- 実装の正しさを検証する手段がない
- 後からテストを追加する際に実装の問題が発覚するリスク
推奨される分割方法:
- 各フェーズで実装とテストをセットで含める
- 各Pull Requestが独立してマージ可能な状態を保つ
- テストコードの行数も含めて見積もりを行う
### リスク評価
- コミット数が多い過去Pull Request → レビュー対応が多い可能性
- 複雑なビジネスロジック変更 → 慎重な分割が必要
- 本番への影響度 → デプロイリスク考慮
## 出力形式
### 単一Pull Request推奨の場合
```
## 見積もり結果
- 予想ソースコード変更XXX行
- 予想テスト追加XXX行
- 予想ドキュメント更新XXX行
- 合計予想変更行数XXX行
## 分割提案
単一Pull Requestで実装することを推奨します。
[推奨理由と実装時の注意点]
```
### 複数Pull Request分割推奨の場合
Claude Codeのようなエージェントが全体のコンテキストを把握しやすくするため、GitHub Issue作成を提案し、以下の手順で全体管理を行います
```bash
# 一時ファイルにIssue内容を作成
cat > /tmp/github_issue_draft.md << 'EOF'
# [タスク名]
## 背景・課題
[やりたいことの背景とコンテキストを記載]
## 実装概要
合計予想変更行数XXX行
[トータルで必要な修正内容の概要]
上記の予想変更行数に基づき、レビュー負荷とデプロイリスクを考慮して以下のフェーズに分割することを推奨します。
## 実装フェーズ
### フェーズ1: [第1段階の内容]
- [具体的な作業内容]
- 予想変更行数XXX行実装XXX行、テストXXX行
- 含まれるテスト: [この段階で追加されるテストの説明]
### フェーズ2: [第2段階の内容]
- [具体的な作業内容]
- 予想変更行数XXX行実装XXX行、テストXXX行
- 含まれるテスト: [この段階で追加されるテストの説明]
### フェーズ3: [第3段階の内容]
- [具体的な作業内容]
- 予想変更行数XXX行実装XXX行、テストXXX行
- 含まれるテスト: [この段階で追加されるテストの説明]
## 注意事項
- [実装時の注意点]
- [依存関係やリスク]
EOF
echo "以下の内容でGitHub Issueを作成しますか"
cat /tmp/github_issue_draft.md
```
ユーザーの承認後:
```bash
# GitHub Issueを作成
gh issue create --title "[タスク名]" --body-file /tmp/github_issue_draft.md
# 一時ファイルを削除
rm /tmp/github_issue_draft.md
```
## 注意事項
- 過去のPull Request履歴から学習した傾向を活用
- リポジトリ固有のテスト・ドキュメント慣習を考慮
- レビュー負荷とデプロイリスクを総合的に判断

121
commands/load_spec_tasks.md Normal file
View File

@@ -0,0 +1,121 @@
# load-spec-tasks
spec workflowのtasks.mdから次にやるべきタスクを読み込み、Claude CodeのToDoリストに自己再生産的なタスクサイクルを設定します。
## 概要
このコマンドは最初に1回実行するだけで、以降は自動的にタスクサイクルが回り続けます。
tasks.mdをシングルソースオブトゥルース信頼できる唯一の情報源として扱います。
## 実行手順
### Step 1: 現在のspec-idを判定
`detect-spec-workflow`サブエージェントを呼び出して、現在の作業コンテキストから該当するspec-idを判定してください
```
Taskツールを使用:
- subagent_type: syou6162-plugin:detect-spec-workflow
- prompt: "現在のコンテキストから該当するspec workflowのspec-idを判定してください"
```
**エラーハンドリング**:
- spec-idが見つからない場合: 「該当するspec workflowが見つかりませんでした。spec workflowのセットアップを確認してください。」と表示して終了
### Step 2: tasks.mdの読み取りと次のタスク取得
判定されたspec-idを使って、tasks.mdを読み取ります
```bash
# Readツールを使用
.spec-workflow/specs/{spec-id}/tasks.md
```
**tasks.mdのパース処理**:
1. マークダウンチェックボックス形式を検索: `- [ ]`, `- [-]`, `- [x]`
2. `- [x]` (完了済み) をスキップ
3. 最初に見つかった `- [ ]` (pending) または `- [-]` (in-progress) を次のタスクとして取得
4. タスク名を抽出(チェックボックス以降のテキスト)
**パース例**:
```markdown
## Tasks
- [x] ユーザー認証機能を実装 ← スキップ
- [x] パスワードリセット機能 ← スキップ
- [ ] メール通知機能を実装 ← これが次のタスク!
- [ ] ログ機能の追加
```
→ 次のタスク: 「メール通知機能を実装」
**エラーハンドリング**:
- tasks.mdが存在しない: 「tasks.mdが見つかりません。spec workflowのPhase 3 (Tasks)を完了させてください。」
- すべてのタスクが完了済み: 「🎉 すべてのタスクが完了しましたspec workflowの実装フェーズは完了です。」と表示して終了
### Step 3: ToDoリストに5ステップのタスクサイクルを追加
`TodoWrite`ツールを使って、以下の5ステップをToDoリストに追加します
```javascript
TodoWrite({
todos: [
{
content: "tasks.mdで [タスク名] を [-] に変更in-progressマーク",
activeForm: "tasks.mdで [タスク名] を [-] に変更中",
status: "pending"
},
{
content: "タスク名", // Step 2で取得した実際のタスク名
activeForm: "タスク名を実行中",
status: "pending"
},
{
content: "tasks.mdで [タスク名] を [x] に変更(完了マーク)",
activeForm: "tasks.mdで [タスク名] を [x] に変更中",
status: "pending"
},
{
content: "tasks.mdから次のタスクを確認",
activeForm: "tasks.mdから次のタスクを確認中",
status: "pending"
},
{
content: "TodoWriteで次のタスクサイクル5件をToDoリストに追加",
activeForm: "TodoWriteで次のタスクサイクルをToDoリストに追加中",
status: "pending"
}
]
})
```
**重要な実装ガイダンス**:
#### タスク1: tasks.mdでタスクを[-]に変更
このタスクを実行する際は、`Edit`ツールを使って以下のように編集します:
```
old_string: "- [ ] タスク名"
new_string: "- [-] タスク名"
```
#### タスク2: 実際の実装タスク
tasks.mdの`_Prompt`フィールドに記載されている指示に従って実装します。
#### タスク3: tasks.mdでタスクを[x]に変更
`Edit`ツールを使って以下のように編集します:
```
old_string: "- [-] タスク名"
new_string: "- [x] タスク名"
```
#### タスク4: 次のタスクを確認
`Read`ツールでtasks.mdを読み、次の`[ ]`または`[-]`タスクを確認します。
#### タスク5: 次のサイクルを追加
このタスクを実行すると、新しい5ステップのサイクルが自動的に追加されます。
`TodoWrite`で以下を実行:
1. 完了済みcompletedタスクをToDoリストから削除
2. tasks.mdから次のタスクを取得Step 2と同じ処理
3. 新しい5ステップのタスクサイクルを生成
4. ToDoリストに追加

View File

@@ -0,0 +1,622 @@
---
description: "複数の視点から客観的にレビューし、方針の妥当性を検証します。"
allowed-tools: Bash(git diff:*), Bash(git log:*), Bash(git symbolic-ref refs/remotes/origin/HEAD --short), Bash(date:+%Y%m%d_%H%M%S), Bash(mkdir -p .claude_work/multi_perspective_review:*), Write(.claude_work/**), Read(.claude_work/**)
---
# 複数視点レビューコマンド
<important>
このコマンドは以下の場合に使用してください:
- 実装方針や設計の妥当性を確認したい
- 複数の視点から客観的な意見が欲しい
- 早すぎる最適化やnit な指摘を避けたい
- プロジェクトの現状に合った判断をしたい
</important>
## 実行手順
<procedure>
**1. コンテキストの収集**
<context>
まず、レビューに必要なコンテキストを収集します:
- **デフォルトブランチの取得**
```bash
git symbolic-ref refs/remotes/origin/HEAD --short
```
結果は `origin/main` のような形式なので、後続の処理で使用します
- **現在の変更差分を取得(あれば)**
デフォルトブランチとの差分を取得:
```bash
git diff <デフォルトブランチ名>
```
例: `git diff origin/main`
※ 変更がない場合も問題なし。これから実装する方針のレビューなど、コード差分がない場合もある
- **デフォルトブランチからの差分コミット履歴を取得**
現在のブランチがデフォルトブランチと異なる場合、差分コミットを取得:
```bash
git log <デフォルトブランチ名>..HEAD --oneline
```
例: `git log origin/main..HEAD --oneline`
※ 現在のブランチがデフォルトブランチと同じ場合は、このステップはスキップ
- **会話履歴の確認(重要)**
- 直前のユーザーとのやり取りから、レビュー対象の意図を把握する
- 「この方針で良いか確認したい」「この設計をレビューして」などの説明
- git diffがない場合は、会話履歴が主なコンテキストになる
</context>
**1-2. ログ保存用ディレクトリの作成とコンテキスト情報の保存**
タイムスタンプを取得して定義:
<timestamp>
```bash
date +%Y%m%d_%H%M%S
```
</timestamp>
次に、ディレクトリ構造を作成します:
```bash
mkdir -p .claude_work/multi_perspective_review/<timestamp>/round1
mkdir -p .claude_work/multi_perspective_review/<timestamp>/round2
```
次に、コンテキストファイルのパスを定義します:
<context-file>
```
.claude_work/multi_perspective_review/<timestamp>/context.md
```
</context-file>
<context>タグで収集した内容を<context-file>タグのパスに保存します。
**2. 第1ラウンド: 8つの視点からのレビュー**
収集したコンテキストを基に、8つの異なる視点からレビューを実施します。
**並列実行**: 8つのTaskツール`subagent_type: "general-purpose"`)を同時に呼び出し、効率的にレビューを実施してください。
以下の8つの視点を定義します
<examples>
<example>
<name>アーキテクチャ・設計</name>
<round1-filename>
```
.claude_work/multi_perspective_review/<timestamp>/round1/architecture.md
```
</round1-filename>
<perspective-details>
- システム全体の構造が適切か
- モジュール分割が適切か
- 依存関係が適切に管理されているか
- 拡張性が考慮されているか
- 設計原則が遵守されているか
</perspective-details>
</example>
<example>
<name>パフォーマンス・効率性</name>
<round1-filename>
```
.claude_work/multi_perspective_review/<timestamp>/round1/performance.md
```
</round1-filename>
<perspective-details>
- 実行速度に問題がないか
- メモリ使用量が適切か
- スケーラビリティが考慮されているか
- アルゴリズムの計算量が適切か
</perspective-details>
</example>
<example>
<name>保守性・可読性</name>
<round1-filename>
```
.claude_work/multi_perspective_review/<timestamp>/round1/maintainability.md
```
</round1-filename>
<perspective-details>
- コードが理解しやすいか
- 変更がしやすい構造になっているか
- 命名規則が適切か
- 使われていない関数や変数はないか
- コメントが適切に記述されているか(自明なコメントが付与されていないか)
- コメントと関数名、関数名と実際の処理で乖離がないか
- 類似の機能を持つコードが重複していないか
- 複雑度が適切に管理されているか
</perspective-details>
</example>
<example>
<name>テスタビリティ</name>
<round1-filename>
```
.claude_work/multi_perspective_review/<timestamp>/round1/testability.md
```
</round1-filename>
<perspective-details>
- テストがしやすい設計になっているか
- 依存性の注入が適切に行われているか
- モック化が容易な構造になっているか
- テストケースの網羅性が確保されているか
</perspective-details>
</example>
<example>
<name>ユーザー体験・利便性</name>
<round1-filename>
```
.claude_work/multi_perspective_review/<timestamp>/round1/user_experience.md
```
</round1-filename>
<perspective-details>
- エンドユーザーやAPI利用者の視点で使いやすいか
- UIが使いやすいか
- APIが直感的か
</perspective-details>
</example>
<example>
<name>プロジェクトフェーズ適合性</name>
<round1-filename>
```
.claude_work/multi_perspective_review/<timestamp>/round1/project_phase.md
```
</round1-filename>
<perspective-details>
- 早すぎる最適化になっていないか
- MVP として妥当な範囲か
- 技術的負債とのバランスが適切か
</perspective-details>
</example>
<example>
<name>既存コードとの整合性</name>
<round1-filename>
```
.claude_work/multi_perspective_review/<timestamp>/round1/consistency.md
```
</round1-filename>
<perspective-details>
- プロジェクト内のパターン・スタイルと一貫性があるか
- コーディング規約が遵守されているか
</perspective-details>
</example>
<example>
<name>ベストプラクティス・標準準拠</name>
<round1-filename>
```
.claude_work/multi_perspective_review/<timestamp>/round1/best_practices.md
```
</round1-filename>
<perspective-details>
- 公式ドキュメントに沿っているか
- コミュニティのベストプラクティスに従っているか
- 言語固有のイディオムが適切に使われているか
- 業界標準に準拠しているか
</perspective-details>
</example>
</examples>
各general-purpose subagentには以下の情報を含めたプロンプトを渡します
```
あなたは<name>タグで定義された視点から、以下の内容をレビューしてください。
## 保存先
<round1-filename>タグで定義されたファイルパスに保存してください。
## レビュー対象
<context-file>タグで定義されたファイルに保存されたコンテキスト情報を参照してください。
## レビューの指針
- 客観的な視点から意見を述べてください
- 修正案の提示は不要です(分析と意見のみ)
- 具体的なコードや状況に即した指摘をしてください
- 抽象的すぎる指摘は避けてください
## あなたの視点
<perspective-details>タグで定義された内容を参照してください。
詳細に網羅的に報告してください。具体的なコード箇所、懸念される影響、改善の必要性について、十分な情報を含めて分析してください。
## 出力形式
マークダウン形式で保存後、以下の形式で報告: `レビュー結果を保存しました: <round1-filename>`
```
**Taskツールの呼び出し例8つ並列:**
<example>
```
Task(
subagent_type: "general-purpose",
description: "アーキテクチャ・設計の観点からレビュー",
prompt: "あなたは<name>タグで定義された視点から...",
model: "sonnet"
)
Task(
subagent_type: "general-purpose",
description: "パフォーマンス・効率性の観点からレビュー",
prompt: "あなたは<name>タグで定義された視点から...",
model: "sonnet"
)
... (残り6つも同様に並列で呼び出し、全てmodel: "sonnet"を指定)
```
</example>
**3. 第2ラウンド: 妥当性検証**
第1ラウンドのログファイルを読み込み、5つのsubagentに妥当性検証を依頼します。
**並列実行**: 5つのTaskツール`subagent_type: "general-purpose"`)を同時に呼び出してください。
メタレビュアー番号を定義:
<meta-reviewer-number>固有の番号</meta-reviewer-number>
各メタレビュアーの出力ファイルパスを定義:
<round2-filename>
```
.claude_work/multi_perspective_review/<timestamp>/round2/meta_reviewer_<meta-reviewer-number>.md
```
</round2-filename>
まず、8つの視点の<round1-filename>タグで定義されたファイルパスを収集してください。
次に、各general-purpose subagentには以下のプロンプトを渡します<meta-reviewer-number>タグに15を指定し、[ログファイルパス一覧]の部分には収集した8つのパスを列挙
```
あなたは**メタレビュアー<meta-reviewer-number>**として、第1ラウンドのレビュー結果を検証してください。
## 保存先
`<round2-filename>`タグで定義されたファイルパスに保存してください。
## 第1ラウンドのレビューログ
以下の8つのファイルに第1ラウンドの視点別レビュー結果が保存されています。すべて読み込んで内容を確認してください
[ログファイルパス一覧]
## 元のコンテキスト(検証の裏付け用)
<context-file>タグで定義されたファイルに保存されたコンテキスト情報を参照してください。
## 検証観点
以下の観点から、レビュー結果の妥当性を評価してください:
- **コンテキストとの整合性**
- 提供されたコンテキストgit diff、コミット履歴、会話内容を踏まえた意見か
- 抽象的すぎる指摘ではなく、具体的なコードや状況に即しているか
- **プロジェクトフェーズ適合性**
- 早すぎる最適化や過剰な設計になっていないか
- MVPとして妥当な範囲か
- nitな指摘ではなく、本質的な問題か
## 回答形式
- 妥当な指摘: 「✅ [理由]」
- 疑問のある指摘: 「⚠️ [理由]」
- 不適切な指摘: 「❌ [理由]」
全ての観点に対して客観的かつ詳細に評価してください。各指摘について、コンテキストとの整合性、プロジェクトフェーズとの適合性、具体性の程度を十分に検証し、判断の根拠を明確に示してください。
## 出力形式
マークダウン形式で保存後、以下の形式で報告: `検証結果を保存しました: <round2-filename>`
```
**4. 最終レポートの生成**
最終レポートの保存先を定義します:
<final-report>
```
.claude_work/multi_perspective_review/<timestamp>/final_report.md
```
</final-report>
第2ラウンドの5つのsubagentから返ってきたログファイルパスを収集した後、メインエージェントが以下の処理を実行します
1. **全ログファイルを読み込む**
- `.claude_work/multi_perspective_review/<timestamp>/round1/` 配下の8ファイル
- `.claude_work/multi_perspective_review/<timestamp>/round2/` 配下の5ファイル
2. **統合処理を実行**
- 第1ラウンドの8つの視点から、共通指摘をマージ
- 第2ラウンドの5つの検証結果から、妥当性評価を統合
- 主要な指摘事項を以下に分類:
- 妥当性が確認された指摘
- 検討が必要な指摘
- 不適切と判断された指摘
3. **最終レポートを生成**
最終レポートを以下の形式で生成します:
<template>
```markdown
# 複数視点レビュー結果
## レビューサマリー
- 第1ラウンド: 8つの視点からレビュー
- 第2ラウンド: 5つのメタレビュアーによる妥当性確認
## 主要な指摘事項
### 妥当性が確認された指摘
**[指摘のタイトル]**
- [判定結果] [指摘内容]
- 理由: [妥当性の根拠]
### 検討が必要な指摘
**[指摘のタイトル]**
- [判定結果] [指摘内容]
- 理由: [検討が必要な理由]
### 不適切と判断された指摘
**[指摘のタイトル]**
- [判定結果] [指摘内容]
- 理由: [不適切と判断した理由]
## 詳細レビュー結果
### 第1ラウンド: 多角的レビュー
(※ 前述の整理結果を挿入)
### 第2ラウンド: 妥当性検証
**メタレビュアーの評価:**
[各メタレビュアーの評価結果を箇条書きで列挙]
## 総合評価
**優先的に対処すべき事項:**
[妥当性が高いと判断された指摘を優先度順に列挙]
**今後検討すべき事項:**
[検討が必要と判断された指摘を列挙]
**実施不要と判断された事項:**
[不適切と判断された指摘を列挙]
[総合的な評価コメント]
```
</template>
<example>
```markdown
# 複数視点レビュー結果
## レビューサマリー
- 第1ラウンド: 8つの視点からレビュー
- 第2ラウンド: 5つのメタレビュアーによる妥当性確認
## 主要な指摘事項
### 妥当性が確認された指摘
**エラーハンドリングの不足**
- 外部API呼び出し時のエラーハンドリングが不十分
- 理由: 実際のコードを見ると、try-catchブロックがなく、本番環境で問題が発生する可能性が高い
**テスタビリティの問題**
- 外部依存が直接インポートされており、モック化が困難
- 理由: 具体的なコード箇所を指摘しており、テストの保守性に直結する実質的な問題
**アーキテクチャの重複**
- 新しいvalidateInput関数が既存のvalidationUtilsモジュールと重複
- 理由: コードベース全体を見ると、同じ機能が2箇所に存在し、保守性を低下させる
### 検討が必要な指摘
**パフォーマンス懸念**
- データベースクエリがN+1問題を引き起こす可能性
- 理由: 現時点のデータ量では問題にならない可能性があるが、将来的なスケールを考慮すると対処すべき
**変数名の曖昧さ**
- 変数名が曖昧data, result など)
- 理由: プロジェクト内で一貫して使われているパターンであれば、nitな指摘の可能性
### 不適切と判断された指摘
**過剰な抽象化**
- インターフェースを追加してDI パターンを徹底すべき
- 理由: プロジェクトのフェーズを考慮すると早すぎる最適化。現時点では不要な複雑性を導入する
## 詳細レビュー結果
### 第1ラウンド: 多角的レビュー
(※ 前述の整理結果を挿入)
### 第2ラウンド: 妥当性検証
**メタレビュアー1の評価:**
- エラーハンドリング不足は妥当な指摘(実装に直接影響)
- N+1問題は現時点では過剰かもしれないが、将来的には対処が必要
- DI パターンの徹底は早すぎる最適化
**メタレビュアー2の評価:**
- テスタビリティの問題は具体的で改善価値が高い
- validationUtils との重複は明確な問題
- 変数名の指摘はプロジェクト規約次第
以下、メタレビュアー3-5の評価を同様に列挙
## 総合評価
**優先的に対処すべき事項:**
1. 外部API呼び出し時のエラーハンドリングを追加
2. 外部依存のモック化を容易にするため、依存性注入パターンを部分的に適用
3. validateInput関数と既存のvalidationUtilsモジュールの重複を解消
**今後検討すべき事項:**
- データベースクエリのN+1問題データ量が増えた際に再評価
- 変数名の見直し(チーム全体のコーディング規約を整備してから判断)
**実施不要と判断された事項:**
- 全体的なDIパターンの徹底現フェーズでは過剰
全体として、実装は概ね妥当な範囲にあります。上記の優先事項を対処すれば、品質とテスタビリティが大きく向上すると考えられます。
```
</example>
</template>
**4. 最終レポートの保存とユーザーへの表示**
生成した最終レポートを<final-report>タグで定義されたファイルパスに保存してください。
保存後、ユーザーには以下の情報を表示:
```markdown
# 複数視点レビュー完了
## レビュー結果
最終レポートを保存しました: <final-report>
## サマリー
### 妥当性が確認された主要な指摘(優先対処)
1. [指摘事項1]
2. [指摘事項2]
3. [指摘事項3]
### 検討が必要な指摘
- [指摘事項A]
- [指摘事項B]
### 不適切と判断された指摘
- [指摘事項X]
詳細については、上記ファイルを参照してください。
## ログファイル一覧
### コンテキスト情報
- `<context-file>`
### 第1ラウンド8視点のレビュー
各視点の<round1-filename>タグで定義されたファイル8ファイル
### 第2ラウンド5メタレビュアーの評価
各メタレビュアーの`<round2-filename>`タグで定義されたファイル5ファイル
```
</procedure>

View File

@@ -0,0 +1,304 @@
---
allowed-tools: Bash(bq query:*), Bash(bq wait:*), Bash(tee:*), Write(/tmp/**), Edit(/tmp/**), Read(/tmp/**)
description: "BigQueryクエリのパフォーマンスを分析し、2倍以上の性能改善を目標とした最適化を提案します。"
---
## 前提条件
- **リージョン**: USregion-us固定
- **プロジェクト**: デフォルトプロジェクト(`gcloud config get-value project`で設定済み)
- **権限**: INFORMATION_SCHEMAへのアクセス権限あり
- **スキャン量削減**: INFORMATION_SCHEMAは直近7日間のみ検索creation_timeで絞り込み
- クエリの`FROM`句にバッククオートの付与は禁止
- バッククオートを付与すると、Bash toolがコマンドと勘違いをする
- そのため、毎回ユーザーの許可が必要になってしまうため
## 分析対象
- 入力: $ARGUMENTS(SQLファイルパス `.sql`)
- SQLのファイルのみで最適化内容を判断するのではなく、実際にクエリを実行してジョブ情報を取得し、ボトルネック分析を行う
## 実行手順
### 1. クエリ実行とジョブIDの取得
**前提**: `$ARGUMENTS`は最適化対象のSQLクエリが記述された`.sql`ファイルのパスです
1. クエリを実行してジョブIDを取得
- `cat "$ARGUMENTS" | bq query --nosync --use_legacy_sql=false --use_cache=false --format=json | jq -r '.jobReference.jobId'`
- 取得したジョブIDを`JOB_ID`として以降の分析で使用
- `JOB_ID`をシェル変数として設定する必要はありません
2. ジョブの完了を待機
- `bq wait "<JOB_ID>"`でジョブが完了するまで待機
### 2. 全体ボトルネックの特定
#### 基本情報の収集
- 以下のクエリで元のクエリと基本メトリクス(スロット時間、スキャン量)を取得
```bash
bq query --use_legacy_sql=false --format=json --parameter="job_id:STRING:<JOB_ID>" "
SELECT query, total_slot_ms, total_bytes_processed
FROM region-us.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE job_id = @job_id AND creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
" | tee /tmp/job_info.json | head -n 10
```
- 元クエリと基本メトリクスを保存
- `cat /tmp/job_info.json | jq -r '.[0].query' | tee /tmp/original_query.sql`
#### 最大のボトルネックステージを特定
**目的**: 全体のスロット時間の80%以上を占める真のボトルネックを見つける
```bash
bq query --use_legacy_sql=false --format=pretty --parameter="job_id:STRING:<JOB_ID>" "
SELECT
stage.name as stage_name,
CAST(stage.slot_ms AS INT64) as slot_ms,
ROUND(100.0 * stage.slot_ms / SUM(stage.slot_ms) OVER(), 1) as pct_of_total
FROM region-us.INFORMATION_SCHEMA.JOBS_BY_PROJECT,
UNNEST(job_stages) AS stage
WHERE job_id = @job_id
AND creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
ORDER BY stage.slot_ms DESC
LIMIT 5
"
```
**この結果から上位1-3ステージ合計80%以上)を特定し、以降はそれらのみを分析対象とする**
### 3. ボトルネック根本原因の分析
**前提**: セクション2で特定したボトルネックステージTOP1-3のみを詳細分析する
#### 根本原因の診断
1. **ボトルネックステージの詳細メトリクスを取得**
- セクション2で特定したボトルネックステージTOP1-3に対して以下のクエリを実行:
```bash
bq query --use_legacy_sql=false --format=pretty --parameter="job_id:STRING:<JOB_ID>" "
SELECT
stage.name,
CAST(stage.slot_ms AS INT64) as slot_ms,
ROUND(stage.wait_ratio_max * 100, 1) as wait_pct,
ROUND(stage.read_ratio_max * 100, 1) as read_pct,
ROUND(stage.compute_ratio_max * 100, 1) as compute_pct,
ROUND(stage.write_ratio_max * 100, 1) as write_pct,
ROUND(CAST(stage.shuffle_output_bytes AS INT64) / 1048576, 1) as shuffle_mb
FROM region-us.INFORMATION_SCHEMA.JOBS_BY_PROJECT,
UNNEST(job_stages) AS stage
WHERE job_id = @job_id
AND creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
AND stage.name IN ('特定されたボトルネックステージ名1', '名前2', '名前3')
ORDER BY stage.slot_ms DESC
"
```
2. **ステージの処理内容を特定**
- 各ステージがどの種類の処理を行っているかを以下のクエリで確認:
```bash
bq query --use_legacy_sql=false --format=pretty --parameter="job_id:STRING:<JOB_ID>" "
SELECT
stage.name,
CASE
WHEN EXISTS(SELECT 1 FROM UNNEST(stage.steps) AS step WHERE step.kind = 'READ') THEN 'READ処理'
WHEN EXISTS(SELECT 1 FROM UNNEST(stage.steps) AS step WHERE step.kind = 'WRITE') THEN 'WRITE処理'
WHEN EXISTS(SELECT 1 FROM UNNEST(stage.steps) AS step WHERE step.kind = 'COMPUTE') THEN 'COMPUTE処理'
WHEN EXISTS(SELECT 1 FROM UNNEST(stage.steps) AS step WHERE step.kind = 'FILTER') THEN 'FILTER処理'
WHEN EXISTS(SELECT 1 FROM UNNEST(stage.steps) AS step WHERE step.kind = 'JOIN') THEN 'JOIN処理'
WHEN EXISTS(SELECT 1 FROM UNNEST(stage.steps) AS step WHERE step.kind = 'AGGREGATE') THEN 'AGGREGATE処理'
WHEN EXISTS(SELECT 1 FROM UNNEST(stage.steps) AS step WHERE step.kind = 'ANALYTIC') THEN 'ANALYTIC処理'
WHEN EXISTS(SELECT 1 FROM UNNEST(stage.steps) AS step WHERE step.kind = 'SORT') THEN 'SORT処理'
WHEN EXISTS(SELECT 1 FROM UNNEST(stage.steps) AS step WHERE step.kind = 'LIMIT') THEN 'LIMIT処理'
ELSE 'その他'
END as primary_operation
FROM region-us.INFORMATION_SCHEMA.JOBS_BY_PROJECT,
UNNEST(job_stages) AS stage
WHERE job_id = @job_id
AND creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
ORDER BY stage.slot_ms DESC
LIMIT 5
"
```
#### 元クエリとの対応付けと分析結果記録
1. **元クエリを確認**
- `cat "$ARGUMENTS"`で元クエリの内容を表示
2. **ボトルネック分析結果ファイルの初期化**
- Writeツールを使って`/tmp/bottleneck_analysis.md`を以下の内容で作成:
```markdown
## 特定されたボトルネックステージ:
<!-- 例: - S02_Join+: 99000ms (全体の45%) -->
<!-- 例: - S03_Aggregate: 55000ms (全体の25%) -->
## 根本原因分析:
<!-- 例: - S02_Join+の支配的要素: Write (shuffle_mb: 151MB), wait_pct: 5%, compute_pct: 35% -->
<!-- 例: - S03_Aggregateの支配的要素: Compute (compute_pct: 80%), read_pct: 15% -->
## 対応するSQL箇所:
<!-- 例: - S02_Join+に対応: INNER JOIN users u ON c.user_id = u.id (行11-12) -->
<!-- 例: - S03_Aggregateに対応: GROUP BY category, date (行18) -->
```
3. **分析結果の記録**
- 上記bqクエリ結果を参照し、Editツールで各セクションに情報を追記
### 4. ボトルネック対応の最適化パターン選択
**特定されたボトルネック要因に基づいて、2倍改善を狙える最適化パターンを選択**
#### Input段階のボトルネック → データ読み込み最適化
- **パーティション絞り込み**: WHERE句での日付/地域等の限定
- **クラスタリング活用**: JOIN/GROUP BYキーでの事前ソート
- **列選択最適化**: SELECT *を避けて必要列のみ
#### Join段階のボトルネック → 結合処理最適化
- **JOIN前データ削減**: 事前フィルタリング/集約で行数削減
- **JOIN順序最適化**: 小テーブル→大テーブルの順序
- **EXISTS/IN変換**: 相関サブクエリから効率的な形式へ
#### Aggregate/Sort段階のボトルネック → 集約処理最適化
- **段階的集約**: 複数CTEでの事前集約
- **LIMIT早期適用**: TOP-N処理での不要計算回避
- **ウィンドウ関数最適化**: PARTITION BY句の最適化
**最適化パターンの選択と記録**:
1. **ボトルネック診断結果を参照**
- `/tmp/bottleneck_analysis.md`の内容を確認
2. **最適化パターンファイルの初期化**
- Writeツールを使って`/tmp/applied_optimizations.md`を以下の内容で作成:
```markdown
## 適用する最適化パターン
<!-- 例: 1. JOIN前データ削減: users テーブルの事前フィルタリング (期待効果: 60%削減) -->
<!-- 例: 2. JOIN順序最適化: 小テーブル first (期待効果: 25%削減) -->
```
3. **最適化パターンの記録**
- ボトルネック要因に対応するパターンを選択
- 各パターンの期待効果を計算し、2倍改善の見込みを確認
- Editツールで具体的な最適化内容を追記
### 5. 最適化クエリの実装
1. **元クエリを確認**
- `cat "$ARGUMENTS"`で元クエリの内容を確認
2. **最適化クエリの生成と保存**
- セクション4で選択した最適化パターンを適用
- Writeツールを使って`/tmp/optimized_query.sql`に最適化後のクエリを保存
- 最適化例:
```sql
-- 例: JOIN前データ削減
WITH filtered_users AS (
SELECT * FROM users WHERE active = true
)
SELECT ...
FROM comments c
INNER JOIN filtered_users u ON c.user_id = u.id
```
3. **最適化内容の確認**
- `cat /tmp/optimized_query.sql`で保存した最適化クエリを表示
### 6. リファクタリング結果の同一性検証
- **重要**: 最適化は性能改善のみで、出力結果は完全に同一である必要がある
- **注意**: `BIT_XOR``FARM_FINGERPRINT`は行の順序に依存しないため、結果の同一性を検証できる
**BigQueryチェックサムによる検証手順**:
1. **元クエリの結果テーブル名を取得してチェックサムを計算**
- `JOB_ID`(セクション1で取得済み)から以下のコマンドを実行し、`DESTINATION_TABLE`として設定
- `bq query --use_legacy_sql=false --format=json --parameter="job_id:STRING:<JOB_ID>" "SELECT destination_table FROM region-us.INFORMATION_SCHEMA.JOBS_BY_PROJECT WHERE job_id = @job_id AND creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)" | jq -r '.[0].destination_table | [.project_id, .dataset_id, .table_id] | join(".")'`
- `DESTINATION_TABLE`に対して、チェックサムを計算
- `bq query --use_legacy_sql=false --format=json "SELECT BIT_XOR(FARM_FINGERPRINT(TO_JSON_STRING(t))) as checksum FROM <DESTINATION_TABLE> AS t" | jq -r '.[0].checksum'`
- チェックサム値(整数文字列)を記録
2. **最適化クエリの結果テーブル名を取得してチェックサムを計算**
- `NEW_JOB_ID`(セクション6で取得)から以下のコマンドを実行し、`DESTINATION_TABLE`として設定
- `bq query --use_legacy_sql=false --format=json --parameter="job_id:STRING:<NEW_JOB_ID>" "SELECT destination_table FROM region-us.INFORMATION_SCHEMA.JOBS_BY_PROJECT WHERE job_id = @job_id AND creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)" | jq -r '.[0].destination_table | [.project_id, .dataset_id, .table_id] | join(".")'`
- `DESTINATION_TABLE`に対して、チェックサムを計算
- `bq query --use_legacy_sql=false --format=json "SELECT BIT_XOR(FARM_FINGERPRINT(TO_JSON_STRING(t))) as checksum FROM <DESTINATION_TABLE> AS t" | jq -r '.[0].checksum'`
- チェックサム値(整数文字列)を記録
3. **チェックサム値を比較**
- 2つのチェックサム値が完全に一致することを確認
- 不一致の場合は最適化を中止し、原因を調査
### 7. 性能改善効果の測定
- 最適化後のクエリを実行し、同様にジョブIDを取得してメトリクスを収集
- `cat /tmp/optimized_query.sql | bq query --nosync --use_legacy_sql=false --use_cache=false --format=json | jq -r '.jobReference.jobId'`
- 取得したジョブIDを`NEW_JOB_ID`として以降の分析で使用
- `NEW_JOB_ID`をシェル変数として設定する必要はありません
- `bq wait "<NEW_JOB_ID>"`でジョブが完了するまで待機
- 元のスロット時間を取得セクション2で保存したjsonから
- !`cat /tmp/job_info.json | jq -r '.[0].total_slot_ms'`
- 以下のコマンドで、最適化後のスロット時間を取得
```bash
bq query --use_legacy_sql=false --format=json --parameter="job_id:STRING:<NEW_JOB_ID>" "
SELECT total_slot_ms
FROM region-us.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE job_id = @job_id AND creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
" | jq -r '.[0].total_slot_ms'
```
#### 改善率の計算と判定:
- 元のスロット時間と最適化後のスロット時間を比較し、改善率を計算
- `bc`コマンドなどは使用せず、Agent自身が計算を行う
- 2倍以上の改善が達成されたかを判定
- 改善率が2倍以上であれば成功とし、最適化プロセスを終了
- 達成されていない場合は、セクション3で特定したボトルネックに戻り、セクション4-6を繰り返す
### 8. 最終レポート生成
**目的**: 2倍改善達成の根拠と再現可能な手順を記録
1. **必要な情報を収集**
- 元のスロット時間: `cat /tmp/job_info.json | jq -r '.[0].total_slot_ms'`で取得
- 最適化後のスロット時間: セクション7で取得済み
- 改善率: Agent自身が計算
- 目標達成状況: 改善率が2.0倍以上かを判定
2. **最終レポートの生成**
- Writeツールを使って`/tmp/optimization_report.md`を以下の構造で作成:
```markdown
# BigQuery最適化レポート
## 実行サマリー
- **元クエリファイル**: <$ARGUMENTSの値>
- **元ジョブID**: <JOB_ID>
- **元スロット時間**: <ORIGINAL_SLOT_MS>ms
- **最終改善率**: <IMPROVEMENT_RATIO>x
- **目標達成**: <達成状況(✅ 達成 or ❌ 未達成)>
## 特定されたボトルネック
<bottleneck_analysis.mdの内容をReadツールで読み込んで転記>
## 適用した最適化手法
<applied_optimizations.mdの内容をReadツールで読み込んで転記>
## 最適化後のクエリ
\`\`\`sql
<optimized_query.sqlの内容をReadツールで読み込んで転記>
\`\`\`
## 検証結果
- **結果一致**: ✅ チェックサム一致で完全同一
- **性能改善**: <ORIGINAL_SLOT_MS>ms → <NEW_SLOT_MS>ms
```
3. **レポートの確認**
- `cat /tmp/optimization_report.md`でレポート内容を表示
**完了条件**:
- 2倍以上の改善達成 OR 5回の反復完了
- 結果の同一性確認済み
- 再現可能な最適化手順の記録

View File

@@ -0,0 +1,133 @@
Pull Requestのコメントに対する対応要否をコードベース分析に基づいて判断します
## 分析対象
Pull RequestのURL: $ARGUMENTS
## 実行手順
### 1. 情報取得と分析
```bash
# Pull RequestのURLから情報を取得
PR_URL="$ARGUMENTS"
# $ARGUMENTSが空の場合、現在のブランチのPRを取得
if [ -z "$PR_URL" ]; then
PR_URL=$(gh pr view --json url --jq '.url' 2>/dev/null || echo "")
if [ -z "$PR_URL" ]; then
echo "エラー: Pull RequestのURLが指定されていません。また、現在のブランチに紐づくPRも見つかりませんでした。"
exit 1
fi
echo "現在のブランチのPull Request URLを使用します: $PR_URL"
fi
echo "=== Pull Request基本情報 ==="
# gh pr viewでPR情報を取得
PR_INFO=$(gh pr view "$PR_URL" --json number,headRepositoryOwner,headRepository,title,author,state,headRefName,baseRefName,changedFiles,additions,deletions,createdAt)
# 変数の設定後のAPI呼び出しで使用
OWNER=$(echo "$PR_INFO" | jq -r '.headRepositoryOwner.login')
REPO=$(echo "$PR_INFO" | jq -r '.headRepository.name')
PR_NUMBER=$(echo "$PR_INFO" | jq -r '.number')
echo "$PR_INFO"
echo ""
echo "=== 未解決コメント一覧 ==="
# 未解決コメント取得GraphQL API
gh api graphql --field query="query { repository(owner: \"$OWNER\", name: \"$REPO\") { pullRequest(number: $PR_NUMBER) { reviewThreads(last: 100) { nodes { id isResolved comments(last: 10) { nodes { id body path line originalLine createdAt author { login } diffHunk } } } } } } }" | jq '.data.repository.pullRequest.reviewThreads.nodes | map(select(.isResolved == false)) | map(.comments.nodes) | flatten'
echo ""
echo "=== 変更内容の詳細分析 ==="
echo "### 変更されたファイル一覧"
gh pr diff "$PR_URL" --name-only
echo ""
echo "### 各ファイルの詳細な差分"
gh pr diff "$PR_URL"
```
### 4. 分析指示
**このPull Requestの情報を取得しました。あなたはこのPull Requestの作成者として、コメントに対する対応要否を判断する必要があります。このPRのオーナーシップを持つ立場から、各コメントに対応すべきかどうかを以下の観点で分析してください**
## A. コードベース全体の理解
まず、リポジトリ全体を把握してください:
1. **プロジェクト構造の分析**
- ディレクトリ構造、命名規則
- 使用技術スタック、フレームワーク
- 設定ファイルpackage.json、requirements.txt、go.modなど
2. **既存パターンの特定**
- テストファイルの配置規則と命名規則
- エラーハンドリングの統一パターン
- ログ出力やデバッグの方法
- ドキュメンテーションの書き方
- コーディングスタイル、規約
3. **アーキテクチャの理解**
- レイヤー構造、依存関係
- デザインパターンの使用状況
- 拡張性、保守性への配慮
## B. 変更内容の整合性チェック
今回のPull Requestが既存パターンに従っているかチェック
- 新機能にテストが含まれているか
- エラーハンドリングが適切か
- ログ出力が既存パターンに従っているか
- ドキュメント更新が必要かどうか
- 依存関係の追加が適切か
## C. 各コメントの詳細分析
**各コメントについて、以下の形式で判断してください:**
### コメントID: [ID番号]
**内容**: [コメントの要約]
#### 対応判断: ✅必要 / ⚠️要検討 / ❌不要
**理由**:
- [客観的な根拠]
**コメント者の意図**:
- [なぜこのコメントをしたのか]
**影響範囲**:
- [修正しない場合のリスク]
**修正方針** (対応必要な場合):
- **場所**: [具体的なファイル、関数]
- **方法**: [どのように修正するか]
- **難易度**: 簡単/中程度/困難
- **時間**: [おおよその所要時間]
**返信内容案**:
- **対応する場合**: [修正内容や対応方針を説明する返信文案]
- **対応しない場合**: [理由を丁寧に説明する返信文案]
- **質問・確認が必要な場合**: [意図を確認するための返信文案]
---
## D. 参考情報の整理
### 対応判断の参考情報
- **既存パターンとの整合性**: [コメントが指摘する内容が既存コードベースの規則に合致するか]
- **技術的妥当性**: [指摘内容が技術的に正しいか]
- **影響範囲**: [対応しない場合の潜在的リスク]
### コメント優先度整理 (参考)
1. [コメントID] - [対応を検討すべき理由]
2. [コメントID] - [対応を検討すべき理由]
3. [コメントID] - [対応を検討すべき理由]
### ユーザー判断のための補足
- **すぐに対応できそうなもの**: [リスト]
- **時間をかけて検討が必要なもの**: [リスト]
- **コメント者に確認が必要なもの**: [リスト]
**重要**: この分析は判断材料の提供であり、最終的な対応判断はユーザーが行います。コード修正は一切行いません。

View File

@@ -0,0 +1,88 @@
# bq queryコマンドの出力を検証する
## 目的
あなたはクエリの監査官です。危険なクエリを見抜き、その場合には実行を何としても阻止する必要があります。入力となるクエリの対象はBigQueryです
## 出力形式
検証の結果を以下のClaude Code標準JSON形式で出力してください。JSON以外を出力することは許可されていません。
- 返答は有効なJSONオブジェクト1個のみ
- **重要**: コードフェンス(\`\`\`)や「このクエリを検証します」などの出力(説明文、前置きなど)は一切許可されていません
### JSON構造
```json
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow または deny",
"permissionDecisionReason": "判定理由日本語約200字"
}
}
```
### 出力例
安全なクエリの場合:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"permissionDecisionReason": "単純なSELECT文のみで安全なクエリです"
}
}
危険なクエリの場合:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "DROP文によりテーブルを削除する危険な操作です"
}
}
## 判定基準
### 安全なクエリallow
- **SELECT文のみ**: データの読み取り専用操作
- **INFORMATION_SCHEMA**: メタデータの参照
- **WITH句**: CTEを使用した読み取り専用クエリ
### 危険なクエリdeny
#### DDLData Definition Language
- **DROP**: テーブル・データセット・ビュー・関数の削除
- **CREATE**: テーブル・データセット・ビュー・関数の作成
- **ALTER**: 既存オブジェクトの構造変更
- **TRUNCATE**: テーブルデータの全削除
#### DMLData Manipulation Language
- **INSERT**: データの挿入・追加
- **UPDATE**: データの更新・変更
- **DELETE**: データの削除
- **MERGE**: データのマージ操作
#### DCLData Control Language
- **GRANT**: 権限の付与
- **REVOKE**: 権限の取り消し
- **CREATE ROW ACCESS POLICY**: 行レベルセキュリティ
#### 高度な操作
- **EXPORT DATA**: データのエクスポート
- **IMPORT**: データのインポート(セッション機能)
- **EXECUTE IMMEDIATE**: 動的SQL実行
- **CALL**: ストアドプロシージャ実行
- **BEGIN/COMMIT/ROLLBACK TRANSACTION**: トランザクション制御
#### BigQuery ML
- **CREATE MODEL**: 機械学習モデルの作成
- **ML.PREDICT**: モデル予測の実行
- **ML.EVALUATE**: モデル評価
#### 危険なオプション
- **--replace**: 既存テーブルの置換
- **--destination_table**: 結果の別テーブル保存
- **--external_table_definition**: 外部テーブル定義
- **--append_table**: データの追加
### その他
- **判断不能**: 上記に該当しない場合は`deny`