Skip to content
This repository was archived by the owner on Aug 26, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .claude/skills/pr-review-flow/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ Claude/Codex/CodeRabbitはDraft中に何度反復してもプレミアムリク
PR #18〜#32の実績分析(Claude/Copilotの指摘重複率、Copilotのクレジット消費が
実測で1レビューあたりプレミアムリクエスト13回相当。公式の固定値ではなく実績値)に基づく判断。

## PRを出す前に

**未確認の設計判断が成果物に焼き付いていないかを確認する。**成果物間で記述が矛盾していた、
またはどちらとも取れる判断をこのタスクで行ったなら、`docs/decision-policy.md` の
判定に照らす。確認が要る側だったのにPO確認を経ていないなら、**PRを出す前に確認する。**

**ここは最後の砦であって、確認すべき本来のタイミングではない。**正しい確認点は
実装に着手する前で、対象もコードに限らない(マイグレーション、RLS、生成型、テスト、
ドキュメント)。判断に依存する作業は確認が済むまで止める — 詳細は
`docs/decision-policy.md`。この節に引っかかった時点で、既に一手遅れている。

レビューボットもCIも「決めた方針どおりに書けているか」しか見ないため、方針が製品の意図と
逆でも全部緑になる。**機械的なチェックでは検出できない唯一の穴。**理由と実例は
`docs/decision-policy.md`「なぜこれが必要か」(理屈をここに書き写さない。片方だけ古くなる)。
Comment thread
coderabbitai[bot] marked this conversation as resolved.

## Draftフェーズ

PRはまず`gh pr create --draft`でDraft作成する。
Expand Down
9 changes: 9 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
- **権限マトリクスとRLSの検証要件 → `docs/permissions.md`。権限に関わるコードを触る前に必ず読む**
- **lint/型の運用方針と例外の作法 → `docs/lint-policy.md`。lintエラーを消す前に必ず読む**
- **テストの書き方とカバーすべきパターン → `docs/testing.md`。テストを書く/直す前に必ず読む**
- **成果物間で記述が矛盾している/判断が割れたときの止まり方 → `docs/decision-policy.md`。
「何を選ぶか」を含む実装に着手する前に必ず読む**

## ディレクトリ構成

Expand All @@ -35,6 +37,9 @@
- **ルールをpure関数に切り出す。**フィルタ、並び順、検証、集計、権限判定、日付計算。
I/Oは呼び出し側に残す。アプリを起動しないと到達できないルールは、テストされない。
- **境界では依存を引数で渡す。**現在時刻、ユーザーID。import時に時計やプロセスを掴まない。
- **成果物どうしが矛盾している/どちらとも取れる判断が必要なときは、実装に着手する前に
POに確認する。**方針が製品の意図と逆でもCIは緑になる。ここだけは機械が止められない。
止まる/進むの境界、確認の経路と書き方は `docs/decision-policy.md`。

## このリポジトリ固有の注意

Expand Down Expand Up @@ -63,6 +68,10 @@ mainはRulesetで保護されており、リポジトリ管理者(あなた)の
データモデルの変更、権限マトリクスの変更、フェーズ分割、ドキュメント間の矛盾の解消など
「何を選ぶか」を判断する作業はOpusが行う。方針が`docs/`に書かれていて、
それに沿って実装・修正するだけの作業はSonnetに任せる。
- **判断がタスクの入口にあるOpusは、それを外したときの手戻りが最も大きい。**成果物間の矛盾や
どちらとも取れる判断に出くわしたら、実装に着手する前にPOに確認する(判定・手順・理由は
`docs/decision-policy.md`)。Sonnet/Haikuが同じ状況に出くわすのはタスクの分類が誤っているときなので、
下記の3回ルールを待たず、一段ずつでもなくOpusまで上げる。
- **Haikuに任せてよいのは「正誤を機械(lint/tsc/CIの出力)が判定でき、`common/`の2経路同期・
権限/RLS・データモデルの意味判断を一切含まない」タスクに限る。**
例: レビューボットの指摘のうち妥当性判断済みで提案通り適用するだけの機械的修正、
Expand Down
144 changes: 144 additions & 0 deletions docs/decision-policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# 判断が割れたときの止まり方

成果物(`docs/prd.md` / `docs/data-model.md` / `docs/permissions.md` / `docs/roadmap.md` / `CLAUDE.md`)
の記述が矛盾している、またはどちらとも取れる判断が必要になったときの進め方。
**判断を含む実装に着手する前に読む。**

## なぜこれが必要か

このリポジトリの品質保証は「壊れたらCIが赤くなる」に依存している(`CLAUDE.md`)。
しかし**方針そのものが逆でも、CIは緑になる。**lint・tsc・テストは「決めた方針どおりに
動いているか」しか見ていない。方針が製品の意図と逆であることは、どの機械も検出しない。

つまり成果物間の矛盾やどちらとも取れる判断は、このリポジトリで**唯一、機械が止められない
種類の誤り**である。ここだけは人間(プロダクトオーナー、以下PO)への確認がゲートになる。
権限漏れを最優先で潰すのと同じ理由で(`docs/permissions.md`「なぜここを最優先するか」)、
静かに通ってしまう失敗を先に塞ぐ。

**実例(issue #34 / PR #52):**「オーナーが未参加でも招待できるか」で
`docs/permissions.md` と `docs/data-model.md` の解釈が割れていた。Opusは
「未参加でも招待可」と判断してRLS修正・テスト・CIまで一気に通したが、POの意図は逆だった。
実装が完了した後にPOから訂正が入り、方針を反転させて作り直すことになった。
判断した本人が「本来PO確認が望ましい粒度だ」と気づいていたにもかかわらず、
気づいた時点では既に実装が進んでいた。

## 対象

**権限マトリクスに限らない。**「何を選ぶか」を決める場面すべてが対象になる。

- 成果物どうしの記述が両立しない(権限、既定値、削除の意味論、スコープの線引き)
- 一つの記述が2通りに読め、どちらを採るかで挙動が変わる
- 成果物のどこにも書かれておらず、判断が必要になった

## 止まるか進むかの判定

境界を一問で切る。

> **この判断が逆だったとき、直すのに必要なのはコードの書き直しだけか。
> それとも成果物(`docs/*.md`)の書き換えも要るか。**
>
> 成果物の書き換えが要るなら、**コードを書く前に確認する。**

成果物は製品の意図を書いた場所であり、エージェントが単独で書き換えてよいものではない。
逆に、成果物を一切書き換えずに済む判断は実装の裁量の内側にある。
Comment thread
coderabbitai[bot] marked this conversation as resolved.

**例外は1つだけ。正しい側が他の記述から一意に決まる誤記・追従漏れは、直しても
「製品の意図を選び直した」ことにならないので確認は要らない**(下記「確認を挟まず進めてよい」)。
逆に言えば、**書き換えの前に選択が要るなら、その書き換えは確認の対象**である。

### 確認を挟む(実装に着手しない)

1. **成果物どうしが両立しない。**どちらかを書き換えないと実装できない
2. **一つの記述に2通り以上の解釈が成り立ち、選び方で外から観測できる挙動が変わる。**
権限の可否、既定値、保存・削除されるデータ、画面に出る/出ない(issue #34 はこれ)
3. **`docs/prd.md` の本文を、解釈の選択を伴う形で書き換えることになる。**PRDは製品の意図そのもの。
ただし対象は「どう書くか」に選択の余地がある場合に限る。Issueで内容が確定している追記や
他の記述に追従させるだけの修正は、PRDを触っていてもここには当たらない
4. **MVPに入れる / フェーズ2に送る、の線引きが動く。**スコープは工数ではなく製品の判断
5. **データモデルの意味が変わる。**カラムの意味、関係の向き、削除の意味論。
マイグレーションを伴うと、後から戻すコストが跳ね上がる

### 確認を挟まず進めてよい(記録だけ残す)

- 成果物が一貫していて、判断が「どう実装するか」に閉じている
(関数の分割、ファイル配置、命名、テストの並べ方、型の導出経路)
- 矛盾が明らかな誤記・追従漏れで、**正しい側が他の記述から一意に決まる**
(章番号のずれ、旧版のまま残った表現、表の列名の不一致)。
直したうえで、どちらを正としたかをPR本文に1行書く(確認を挟んでいないので、
Issueへの記録は要らない。記録が要るのは下記「経路の使い分け」のとおり確認を挟んだ判断だけ)
- 判断が外れてもコードを消せば元に戻る範囲に収まる
(マイグレーション、成果物の記述、公開済みの仕様に触れない)。
**「コードを消せば戻る」は、残るものがコードだけの場合に限る。**
既定値・書き込まれる行・論理削除のフラグなど**永続データを変えるもの、外部への副作用、
公開済みのAPIの形**は、コードを戻しても元に戻らないので確認側に回す
(`CLAUDE.md`「参加登録の公開設定はデフォルト非公開。既定値を反転させても何もエラーにならない」)
- 同種の判断の前例が既に `docs/` にあり、それに揃えるだけ
Comment thread
coderabbitai[bot] marked this conversation as resolved.

### グレーだったとき

**確認側に倒す。**コストが非対称だからである。確認は数行のコメント1つで済むが、
手戻りは実装・テスト・CI・成果物の書き換え一式になる。

ただし**自律性を落とさないために、確認の回数ではなく粒度をまとめる。**
1つのタスクで複数の判断が割れているなら、1つずつ聞かずにまとめて1回で聞く。
「割れているものを全部並べて一度に確認する」のが正しい止まり方であり、
「気になるたびに手を止める」ではない。

## どう確認するか

### 経路の使い分け

判断の重さではなく、**POが今応答できるかどうか**で選ぶ。

| 状況 | 経路 | 作業の扱い |
| --- | --- | --- |
| 対話セッション中でPOが応答できる | `AskUserQuestion` で選択肢として提示する | その場で応答を待つ |
| 自律作業中で即応が期待できない | 該当**Issue**にコメントする。Draft PRが既にあればPRから1行リンクする | Projectの `Status` を `Blocked` にし、別のIssueに移る |

**確認を挟んだ判断は、記録の置き場所を常にIssueとする。**`AskUserQuestion` で口頭確認した場合も、
**決定と理由をIssueコメントに書き写す。**セッションの中だけの合意はセッションの外に残らず、
次に同じ判断をする人(モデル)がまた同じところで割れる。

### 提示に書くこと

長い分析は要らない。次の5点を短く書く。

1. **何が割れているか。**成果物名と該当箇所(ファイルと節番号)を、両方とも引用する
2. **選択肢。**2〜3個。それぞれ1行
3. **自分の推奨と理由。**どれか1つを推す。「判断できません」で丸投げしない
4. **影響範囲。**どのコード・テスト・成果物を書き換えることになるか
5. **確認を待たずに進めた場合の手戻り。**外れたときに何を捨てることになるか

### 待っている間

- 止めるのは**その判断に依存する実装だけ。**依存しない調査、環境整備、
無関係な箇所の実装は進めてよい
- **判断に依存するコードを「あとで直す前提」で先に書かない。**
書かれたコードは、確認する側にとって既成事実として働く。PR #52では
実装・テスト・CIが緑になった状態で確認が行われ、訂正が「作り直し」になった
- 応答がないことを理由に自分の判断で再開しない。`Blocked` にしたなら応答が来るまで `Blocked` のまま

## 確認が取れた後

- **割れていた成果物を全部直す。**片方だけ直すと、次に同じ判断でまた割れる。
どれを直したかはPR本文に列挙する
- 判断の根拠が成果物のどこにも書かれていない「暗黙の意図」だった場合は、
**その意図を文章として成果物に書く。**次回同じ質問をしないため
- 決定と理由をIssueコメントに残す(上記「経路の使い分け」)

## Opus担当タスクで特に徹底する理由

**手戻りのコストが他のモデル層より構造的に大きい。**

- Opusに回るタスクは定義上「何を選ぶか」を含む(`CLAUDE.md`)。
判断はタスクの**入口**にあるので、外れると入口から全部やり直しになる
- Opus担当タスクは方針決定から実装・テスト・CIまで一気通貫で進む。
途中に人間もモデルの交代も挟まらないため、**誤りに気づく機会が構造的に存在しない**
- 手戻りの単位が大きい。方針が逆なら、マイグレーション・RLSポリシー・`common/` のpure関数・
両層のテスト・成果物の記述がまとめて書き直しになる(PR #52で実際にそうなった)

**Sonnet / Haiku担当タスクでこの判定に引っかかったら、タスクの分類自体が誤っている。**
Sonnet以下に回るのは「方針が `docs/` に書かれていて、それに沿って実装・修正するだけ」の
作業のはずである(`CLAUDE.md`)。成果物が割れていることに気づいたら自分で選ばず、
`CLAUDE.md` のエスカレーション手順でOpusに上げる。上げる際は、どの成果物のどこが
割れていたかを引き継ぐこと。
3 changes: 3 additions & 0 deletions docs/permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

これが正。ここを変更したら、同じPRで両層の実装とテストを変更すること。

**この表が `docs/prd.md` 4.5 や `docs/data-model.md` と食い違って見えたら、自分で解釈を選ばない。**
`docs/decision-policy.md` に従い、実装に着手する前にPOに確認する(issue #34 / #53)。

| 操作 | オーナー(登録者) | 参加登録済みの他ユーザー | 無関係のユーザー |
| --- | --- | --- | --- |
| イベントの閲覧 | ○ | ○ | ○ (全ユーザー共有カタログ) |
Expand Down
6 changes: 5 additions & 1 deletion docs/prd.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 推し活スケジュール・予算管理アプリ PRD (v0.6)
# 推し活スケジュール・予算管理アプリ PRD (v0.7)

## 1. 背景・目的

Expand Down Expand Up @@ -191,6 +191,8 @@ Web UIとMCPサーバーは同じドメインロジック・同じバリデー

開発の大半をAIエージェントに任せる前提のため、「人間が差分を読んで品質を担保する」方式は採らない。代わりに**壊れたときに機械が止める仕組み**を先に用意する。

ただし**この方式で唯一止められないものがある。方針そのものが製品の意図と逆だった場合、機械はすべて緑になる。**この穴は、成果物間で記述が矛盾している場合やどちらとも取れる判断が必要な場合に、実装着手前のプロダクトオーナー確認をゲートとして置くことで塞ぐ(理由、止まる/進むの境界、確認の経路と書き方は `docs/decision-policy.md`)。

### 8.1 静的解析(最初からerrorで入れる)

新規開発であり既存コードの負債がないため、緩い設定から始めずに最初からerrorで導入する。
Expand Down Expand Up @@ -341,6 +343,7 @@ v0.3時点の未決定事項は、すべて決定済みとした。
| `docs/permissions.md` | 権限マトリクスとRLSの検証要件(4.5 / 8.4の実施要領) |
| `docs/lint-policy.md` | lint/型の運用方針と例外の作法(8.1 / 8.2の実施要領) |
| `docs/testing.md` | テストの書き方とカバーすべきパターン(8.4の実施要領) |
| `docs/decision-policy.md` | 成果物間で記述が矛盾している/判断が割れたときの止まり方(8章の実施要領) |

> 旧「品質・CI体制の導入計画(`ai-review-pipeline-plan.md`)」は、
> `docs/lint-policy.md` / `docs/testing.md` / `docs/permissions.md` に分割済み。
Expand All @@ -354,3 +357,4 @@ v0.3時点の未決定事項は、すべて決定済みとした。
| v0.4 | 未決定事項6件をすべて決定。4.3にカレンダーの実装方針、4.7にMCPのstdio方式とリモート化見送りの理由を追記。5章にPWAの範囲と可用性を追加。6章の成功基準をPC限定に修正。7章にdate-fns/Zodを追加。8.2に生成型のCI検証、8.3にスキーマ共通化とカレンダー実装方針を追加。8.6「CIに置くジョブ」を新設(旧8.6は8.7へ)。9章を「決定事項と持ち越し」に改める |
| v0.5 | 付録の関連ドキュメントを実ファイルに合わせて修正(`ai-review-pipeline-plan.md` は lint-policy / testing / permissions に分割済み)。4.6に `is_admin` をMVPで実装しない旨を明記。`docs/roadmap.md` を追加 |
| v0.6 | 4.5の招待条件を明確化。招待できるかどうかは参加登録の有無だけで決まり、オーナーかどうかは関係ない(issue #34)。`docs/permissions.md` の「オーナーは招待○」は、オーナーが参加登録も済ませているケースを指すものであって、未参加のオーナーを例外的に許可する意味ではないことを明記 |
| v0.7 | 8章の冒頭に「方針そのものの誤りは機械が止められない」旨と、実装着手前のPO確認の運用を追加。付録に `docs/decision-policy.md` を追加(issue #53) |
Loading