# Shakedown

> コード差分・設計ドキュメントから、リリース前に変更を実際に揺さぶって欠陥を洗い出すための QAランブック(shakedown計画書)を3層構造で生成するスキル。 第1層でクリティカルパス分析(ゴールデンパス・リスク分岐・自動テスト済みと手動必須の切り分け)、 第2層で優先度タグ付きシナリオ全量とユーザー合意ゲート、 第3層で実行者・反証可能な期待結果・証跡欄を持つ実行可能チェックリストを生成する。 PRD や Figma を前提とせず、内部リファクタ・バックエンド専用変更・非同期ジョブ・管理画面にも使える。 「QAシナリオを作って」「QA計画を立てて」「シェイクダウンして」「手動QAの計画を作って」 「リリース前の確認項目を洗い出して」「QAランブックを作って」「クリティカルパスを整理して」 「この変更のQA観点を洗い出して」といった依頼で積極的に使うこと。 単体〜結合レベルのテストケース列挙は tdd-test-cases、PRD(Notion)起点のフラットな チェックリスト生成は対象リポジトリの /self-qa が担当なので、それらの依頼には使わない。

- Skill: `maro114510/shakedown` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add maro114510/shakedown`
- Raw SKILL.md: https://api.skillmd.com/api/skills/maro114510/shakedown/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: maro114510 (https://skillmd.com/u/maro114510)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/maro114510/shakedown

---


# shakedown

実装者本人の盲点を突くための QA ランブックを生成する。対象は自動テストが構造的に拾えない欠陥である: 初見の操作者だけが引っかかる UI 挙動、本番で一度も実行されたことのない経路、非同期ジョブのスケール限界、使用中データへの破壊的操作。

成果物は文書だが、このスキルの責任範囲は文書生成で終わらない。QA の失敗は「文書に書いた」と「実際に実行・追跡される」の間のギャップで起きる。だから「Blocking 項目を実装者以外が実行する割り当て」と「発見した問題の Issue 化導線」までを文書構造として縛る。

## 原則(全 Step を支配する)

1. **接地(anchor)必須**: すべてのシナリオは diff のハンク、コードの file:line、または設計ドキュメントのセクションを根拠として引用する。LLM 生成テストの最大の失敗要因は「仕様に存在しない挙動の発明」であり、anchor はその防壁である。**Blocking は実在する anchor を必須とし、`[unanchored]` のまま Blocking タグで合意ゲートに出さない。**接地できないが重要な横断リスク(キャッシュ不整合、下流消費者への影響など)は削除せず、タグを Should-verify に落として anchor 欄に `[unanchored]` と明記し、合意ゲートで見えるようにする。UI 要素(ボタン名・ラベル・遷移先)はソースに実在する文字列だけを引用する。見ていない要素の名前を発明しない。
2. **反証可能な期待結果**: 「正しく動作すること」のような失敗しようがない期待結果を書かない。観測可能な状態(表示文言、遷移先、DB 行、ログ行、レスポンス)を名指しする。失敗しえない項目は存在価値がないので削除する。
3. **数値リスクスコアを出さない**: 影響度・発生確率・可逆性・頻度は優先度タグを決める内部ヒューリスティックとして使い、出力は 1 行の監査可能な根拠にする(例: `Blocking — 不可逆(本番クーポンを直接更新する)・ゴールデンパス上`)。人は文には反論できるが `3×4×2=24` には反論できない。**不可逆な副作用を持つシナリオは他の要素に関わらず自動的に Blocking とする。**
4. **やりすぎない**: 「念のため」のシナリオを許容しない。すべてのシナリオはリスク根拠に紐づく。Blocking は最大 7 件(超えたら統合か降格を強制する。この圧力自体が品質を上げる)。マップは 15 ノード以内。該当しない機能タイプの観点は出さない。
5. **合意ゲート後は formatting, not authoring**: Step 7 は Step 6 までに提示・合意された事実だけを整形する。最終文書の生成中に新しいシナリオ・手順・制約を初出させない。
6. **簡潔な文体で書く**: 生成するすべての文書で括弧書きを避ける。補足したいことは本文の文として書くか、書く価値がなければ削る。1 シナリオ 1 文、チェックリスト項目は最短の文で書く。長い文書は読まれず、読まれないランブックは偽の安心を生む。

## Step 1: 入力の解決

`$ARGUMENTS` を解釈する:

| 入力 | 取得方法 |
|---|---|
| PR 番号・PR URL | `gh pr diff <n>` + `gh pr view <n> --json title,body,files` |
| diff 範囲(`main..feature` 等) | `git diff <range>` |
| `.md` パス | design doc / 実装計画として Read する。diff は `git diff origin/main...HEAD` で補完する |
| 引数なし | `git diff origin/main...HEAD`。origin/main がなければ `git symbolic-ref refs/remotes/origin/HEAD` または `gh repo view --json defaultBranchRef -q .defaultBranchRef.name` でデフォルトブランチを特定し、そのブランチとの diff を取る |
| `ticket <ID>` | 保存ファイル名と関連ドキュメント探索に使う |

- diff と設計ドキュメントの両方が得られない場合のみ停止し、対象の指定を求める。`.md` パスが指定され設計ドキュメントとして読み込めた場合は、diff が空でも Step 2 以降に進む。
- 文書にスタンプする基準 SHA を確定する。ブランチ作業なら `git rev-parse HEAD`。PR を対象にする場合は `gh pr view <n> --json headRefOid` で取得した PR head の SHA を基準とし、anchor の file:line もこの SHA 時点の内容を `git show <SHA>:<path>` で照合する。マージ後に main が先行していても、現在のファイル状態と混同しない。
- 基準 SHA より後の変更が対象の前提を覆していると気づいた場合は、黙って続行せず、その事実を [要確認] として Step 6 の合意ゲートで提示する。
- 変更に関連する design doc / 実装計画がリポジトリ内にあるか軽く探索する(`docs/` 配下をチケット ID・変更ディレクトリ名で rg)。あれば読む。**diff とドキュメントの矛盾を見つけたら、それ自体を Blocking シナリオにする**(「doc は X と言い、コードは Y をしている。どちらが意図か確認する」)。矛盾シナリオの期待結果は「どちらが正か判断され、正でない側の修正方針が記録されること」とする。doc を正と決めつけない。PRD や Figma は前提にしない(パスや URL が渡されたら補助情報として使ってよい)。

## Step 2: 機能タイプの推定

diff のパスと内容から該当タイプを推定する(複数該当あり)。判定シグナルの詳細と各タイプの重点観点は `references/viewpoints.md` の該当セクションだけを読む。

| タイプ | 典型シグナル |
|---|---|
| カスタマー向け UI | mobile 系、顧客向け web ディレクトリ |
| 内部運用者向け管理画面 | ope / admin / internal 系 web ディレクトリ |
| 純バックエンド / API | server / services、proto・GraphQL 契約のみの変更 |
| 非同期 / バッチジョブ | jobs / batch ディレクトリ、`*_job*` ファイル、scheduler・cron 定義 |
| フィーチャーフラグ配下 | フラグ定義(環境変数 `FEATURE_FLAG_*` 等)の追加・変更・参照 |

リポジトリに `.github/labeler.yml` があればパス分類の正解表として参照する。

判定が曖昧な場合、およびリスク許容度など後の判断が割れそうな点は、**ここで 1 回だけ** AskUserQuestion にまとめて聞く(Step 6 の合意ゲートとは別。以降の Step に質問を分散させない)。自明なら聞かずに進む。

## Step 3: 第 1 層 — クリティカルパス分析(毎回必須)

変更が影響する導線のマクロ構造を作る。これは描画物ではなく分析であり、フローが単純でも省略しない。

1. **ゴールデンパス 1 本**: この変更の価値が通る主要導線を、ユーザーに見える操作・判断点の粒度で書く(画面単位でも内部状態単位でもない。マップの目的は検証対象の選択であってアーキテクチャ文書ではない)。
2. **リスク分岐**: 各分岐点で最もリスクの高い分岐**だけ**を追加する。全分岐網羅をしない。
3. **隠れた導線**: 「本番で一度も実行されたことのない経路」(新設の操作種別、create に対する delete などミラー方向の未検証側)をコードから探し、見つけたらマークする。
4. **検証責任の切り分け表**: 観点ごとに「自動テストで固定済み / 手動 QA 必須 / どちらにも落ちていない」を表にする。「Unit/E2E でカバーする前提」と書く場合は、そのテストが実在することを確認してから書く。実在しなければ「どちらにも落ちていない」に置く。この欄が空でないことが、検証責任の穴(どこにも落ちない境界値バグ)を防ぐ。

描画形式は分岐の実在で切り替える:

- **分岐が 2 つ以上ある** → Mermaid `flowchart LR`。15 ノード以内。diff が触るノードを `classDef changed` でマークし、リスク分岐ノードには第 2 層のシナリオ ID(S1, S2, …)を添える。ノードラベル内の `"` は `#quot;` と書く(生の `"` はラベルを終端させ、`\"` は Mermaid が解釈できず描画が壊れる)。
- **線形フロー**(小さな diff の大半) → Mermaid を使わず番号付きステップリストにする。分岐のない flowchart は装飾であり、読む価値を生まない。

## Step 4: 第 2 層 — シナリオ候補の洗い出し

`references/viewpoints.md` の共通セクションと該当機能タイプのセクションを適用し、シナリオ候補の全量を作る。

各シナリオは 1 行で書く:

```
S<n> [タグ] <シナリオ名> — <1行根拠> — anchor: <file:line | docセクション>
```

タグは 3 種:

- `[Blocking]` — 失敗したらリリースを止める。最大 7 件。anchor は file:line か doc セクションが実在すること必須。接地できなければ Blocking にしない。
- `[Should-verify]` — 確認すべきだが単独ではリリースを止めない。接地できない重要な横断リスクはここに置き、anchor 欄に `[unanchored]` と書く。
- `[Wont-verify]` — 意図的に検証しない。**理由必須**(この diff のスコープ外 / 自動テスト済み(テストへの参照付き) / コストがリスクを上回る)。これは優先度ではなくスコープ決定である。「検証しないと決めたものの一覧」こそユーザーが本当に承認する対象なので、雑に書かない。

ルール:

- 1 シナリオ = 1 ゴール・1 フロー。
- 不可逆な副作用(本番データ書き換え、外部 API での発行・課金、通知送信)を持つものは自動的に Blocking。ただし anchor が実在しない限り Blocking タグは付けない。
- 第 1 層の分岐ノードとシナリオ ID を相互参照させる。

## Step 5: anchor 検証(Blocking のみ)

合意ゲートに出す前に、Blocking シナリオの捏造を独立した目で潰す。Agent ツールで読み取り専用のサブエージェントを 1 体起動し、対象リポジトリのパス・基準 SHA・Blocking シナリオの一覧を渡して次を依頼する。`subagent_type: fork` は使わない — fork は親の会話履歴をそのまま継承するため、シナリオを作った本人の判断を引き継いでしまい、独立検証の意味がなくなる:

> 以下の各シナリオについて、根拠(anchor)が実在するか反証を試みよ。anchor の file:line を実際に読み、引用された UI 文字列・関数・分岐が存在するか、シナリオの前提が diff の内容と整合するかを確認する。存在しない・diff と無関係なら REFUTED とし、理由を返す。

REFUTED が返った Blocking シナリオは、再アンカーして Blocking のまま残すか、再アンカーできなければ Should-verify に格下げして anchor 欄に `[unanchored]` と明記し、合意ゲートで見えるようにする。Blocking タグのまま `[unanchored]` で通過させない。黙って握り潰さない。

この検証を実施した日付と結果(全件 VERIFIED、または REFUTED の件数と対応)を、Step 7 で生成するランブックの概要表に 1 行で記録する。ランブック本体に検証の実施記録を残すことで、捏造ゼロの主張を成果物単体で確認できるようにする。

## Step 6: 合意ゲート

以下を提示する。明示的な確認対象は **Blocking と Wont-verify のみ**とする。ゲートは 1 分で読める量に保つ — 全量を確認対象にすると締切下で読まれなくなり、未読の承認が「合意済み」を偽装する。Should-verify は一覧表示するが既定承認とし、ユーザーは自由に追加・削除・タグ変更できる。

```markdown
## shakedown 合意確認

### 対象
- diff: <SHA>, <base>...<head> / 機能タイプ: <types>

### Blocking <n> 件 — 要確認
- S1 <名前> — <1行根拠> — anchor: <file:line>
- ...

### Wont-verify <n> 件 — 要確認
- S8 <名前> — 理由: <理由>
- ...

### Should-verify <n> 件 — 既定承認・編集可
- S4 <名前> — <1行根拠>
- ...

### Blocking の一次実行者
Blocking は実装者以外の実行を推奨する。実装者は自分のコードのメンタルモデルを
既に持っているため、初見の操作者だけが引っかかる欠陥を構造的に見落とす。
生成するチェックリストはそのまま 15 分のデスクチェック台本として渡せる。
- 実行者: [要確認]
- 実装者本人しかいない場合はその旨と、実装から時間を置いて実行する宣言を記録する。

この構成でランブック生成に進んでよいですか。追加・削除・タグ変更・実行者の指定があれば教えてください。
```

**End your response here and wait for the user's reply. Do not proceed to Step 7 until approval is received.**

修正依頼があれば反映し、変更点だけを再提示して再度承認を待つ。

## Step 7: 第 3 層 — ランブック生成と保存

`references/template.md` のテンプレートに、合意済みの内容**だけ**を流し込む(formatting, not authoring)。

- **Blocking = READ-DO 形式**: 前提条件・番号付き手順・反証可能な期待結果・実行者・証跡欄を持ち、初見の他者が質問なしで実行できる自己完結性にする。
- **Should-verify = DO-CONFIRM 形式**: 1 行確認のチェックボックス。証跡不要。この形式差だけで文書の重さが半分以下になる。
- **pass/fail に落ちない観察の置き場**: 仕様どおりだが危険に見える挙動、判断を要する気づきは、チェック項目にせず問題台帳に種別「懸念」で記録する。チェックリストは二値で判定できる項目だけで構成する。
- **メタ情報を発明しない**: 実施環境・実装者名など生成時に確定できない概要表の項目は、値を推測せず [要確認] のまま残す。
- **問題台帳**: 台帳直下に「問題を発見したらその場で create-github-issues スキルにより機能 Epic の Sub-issue として起票し、Issue 番号を台帳に記録する。自由記述のまま放置しない」という導線を明記する。
- **確認完了(sign-off)**: 完了基準を測定可能な形で埋め込む — Blocking 失敗 0 件、問題台帳に Issue 番号が空欄の行が 0 件、Blocking 実行者が記名済み。満たされない限り完了にできない旨をルールとして文書自体に書く。
- **SHA スタンプ**: 概要表に生成時 SHA を記録し、「HEAD がこの SHA から動いたら本ランブックは陳腐化している。再生成すること」の注記を入れる。実行されない古い計画書ほど危険な偽の安心はない。
- **再ベースライン**: 同一チケットの旧ランブックが保存先に既にある場合、新版に「なぜ作り直すのか」節(旧実装と現行実装の差分表、旧版の結果のうち無効になったものの明示)を必ず設け、旧版の冒頭に新版へのリンクと陳腐化の注記を追記する。

保存先: `docs/qa/shakedowns/<YYYYMMDD>-<チケットID or slug>-shakedown.md`。ディレクトリがなければ `mkdir -p` で作成する。チケット ID がない場合の slug は変更内容を表す kebab-case の英小文字とする。例: `coupon-admin-deactivation`。

保存後、パスと次のアクション(Blocking 実行者への引き渡し)を報告して終了する。

## 棲み分け

- **tdd-test-cases**: 単体〜結合レベルのテストケース列挙はそちらが担当。第 1 層の切り分け表で「自動テストで固定すべきだがテストがない」と判明した観点は、本スキルで抱え込まず tdd-test-cases に回すことを報告に含める。
- **/self-qa**(対象リポジトリのコマンド): PRD(Notion)+ Figma 起点のチェックリスト生成。本スキルは拡張も置換もしない。出力形式・保存先も共有しない。
- 本スキルが出すのは「人間が実際に手を動かして変更を揺さぶる実行計画書」であり、自動テストの代替ではない。

