kasiopeiya

to-issues

Plan・仕様・PRD を曳光弾(縦スライス)に分け、それぞれ独立して着手できる Issue にする。「issue化して」「issueに分割して」と指示されたとき。

kasiopeiya 0 Updated 1w ago
GitHub

Install

npx skillscat add kasiopeiya/claude-dev-template/to-issues

Install via the SkillsCat registry.

SKILL.md

To Issues

Plan を縦スライス(曳光弾)に分け、それぞれ独立して着手できる Issue にする。

Issue の置き場は GitHub Issues。gh CLI を使う(リポジトリはローカルの git remote から解決される)。

貫く原則:コールドスタート再現性

各 Issue は 会話履歴を一切持たない別セッションの実装者 が読む前提で書く。判断基準は一文:

この Issue だけ読んで、別セッションが意図と判断を再構築できるか。ただし陳腐化する実装詳細はコードに委ねる。

「詳細に書く」と「簡潔に保つ」は対立しない。書くべき詳細(目的・WHY、却下した代替案とその理由、前提・制約・スコープ境界、受け入れ基準)と、書かない詳細(具体的なファイルパス・コードスニペット・レイヤーごとの実装手順)を分ける。

手順

1. 材料を集める

会話の文脈にあるものをそのまま使う。ユーザーが Issue の参照(番号・URL・パス)を引数で渡してきたら、Issue トラッカーから取得し、本文とコメントをすべて読む。

2. コードベースを調べる(任意)

まだ調べていなければ、現在のコードの状態を把握する。Issue のタイトル・説明はプロジェクトの用語集の語彙を使い、触れる領域の ADR に従う。

3. 縦スライスの案を作る

Plan を曳光弾の Issue に分ける。各 Issue は、すべての統合レイヤーを端から端まで貫く薄い縦スライスにする。1つのレイヤーだけを切り取る横スライスにしてはならない。

スライスには HITL と AFK がある。HITL はアーキテクチャの決定や設計レビューなど、人間とのやり取りが要るもの。AFK は人間を介さず実装・マージできるもの。可能なら AFK を選ぶ。

- 各スライスは、狭くてもすべてのレイヤー(スキーマ・API・UI・テスト)を貫く**完結した**経路を届ける - 完了したスライスは、それ単体でデモまたは検証ができる - 分けられるなら分ける。1本にまとめてよいのは、**分けるとどちらのスライスも単体でデモまたは検証できなくなるとき**だけ - トランクベース開発を前提にしており、小さなスライスに分割することは、レビューの認知負荷を下げることにもつながる - 例外は、次の開発の道具を初めて入れる立ち上げだけで、その道具だけのスライスにしてよい。利用者から見た経路を持たないので縦に貫けず、初回は変更が多く PR の差分が大きくなりすぎるからである - テスト基盤(E2E・結合テストのランナーと実行環境):テストする経路のスライスをブロッカーにする(曳光弾の E2E なら最初の薄い1経路) - CI とデプロイ経路(IaC の最初のスタックを含む) - 静的解析 - プロダクトの部品(DB スキーマ・認証・共通ライブラリ)は、初回で変更が多くても例外にしない。スタブを使えば縦スライスで通せるからである

元の資料の行は、どれかのスライスに必ず入れる。まとめて1本にするのはよいが、「作業が発生しない」「重要でない」という判断で捨ててはならない。このリポジトリでは Issue が着手の入口なので、Issue に無い行は誰にも確認されないまま消える。目標値や制約のように作業が見えない行も、「満たしているか確かめる」タスクにして残す。

4. ユーザーに確認する

分割案を番号付きリストで提示する。各スライスについて次を示す。

  • タイトル:先頭に段番号(着手順。例:2. ポイント利用)を付けた、短く内容が分かる名前。段番号の振り方は Issueの階層ガイド(docs/reference/issue-hierarchy.md)の「段番号(着手順)」に従う
  • 種別:HITL / AFK
  • ブロッカー:先に完了している必要がある他のスライス(あれば)
  • 対応するユーザーストーリー:元の資料にあれば、どのストーリーを満たすか
  • 名指し例外に当たるもの:当たる名指し例外(quick-issue の「どちらを付けるか」)と、その対象の具体名(例:scripts/x.mjs とその単体テスト、docs/old/ の削除)。無ければ「なし」。ここで人間が承認した発言が、issue:decided を付ける根拠になる(quick-issue の「人間が決めた例外」)

そのうえでユーザーに問う。

  • 粒度は妥当か(粗すぎ/細かすぎ)
  • 依存関係は正しいか
  • 統合または分割すべきスライスはあるか
  • HITL / AFK の割り当ては正しいか
  • 名指し例外に当たるものに過不足は無いか

ユーザーが分割案を承認するまで繰り返す。

5. Issue を登録する

承認された各スライスを、下の本文テンプレートで Issue として登録する。

Plan の「実装フロー(使用するSkill)」を各 Issue に必ず転記する(そのスライスが実際に触れる種別の Skill だけに絞る)。これは「issue NNN 対応して」だけで開発フローを自動追従させるための情報なので、issue 化で落とさないこと。Plan に同セクションが無ければ、変更種別から CLAUDE.md「開発フロー」の一覧で補って記載する。

各 Issue には ai-fixable / issue:needs-human-decision のどちらか一方を必ず付ける(boy-scout は付けない。正式フローを経ずに見つけた課題を後で棚卸しするためのラベルであり、/to-issues 産の Issue には当たらない)。どちらを付けるかの判定は quick-issue の「どちらを付けるか」 に従う。

「タスク一覧」「完了条件」は、登録前に該当するポリシー・rules(docs/policy-hub.md・.claude/rules/)と照合する。ポリシーに反する作業を指示していたら、タスク側を直してから登録する。実装時はポリシーが優先されるため、反したまま登録すると手戻りになる。

環境依存の識別子(アカウント名・プロジェクト番号・リソース ID・URL・エンドポイント)を本文に書くなら、configuration-policy を読み、値そのものではなく置き場所(どの設定ファイルに集約するか)をタスクに書く。

Issue は依存順(ブロッカーが先)に登録する。そうすれば「ブロッカー」欄に実際の Issue 番号を書ける。登録する前に、タイトルの先頭の段番号が「ブロッカー」欄と食い違っていないか確かめる。

6. 親に紐づける

登録した各 Issue を、GitHub の sub-issue として親にぶら下げる。親は次の順で決める。

  1. 起点 Issue(引数や会話で渡された Issue)があれば、それが親
  2. 起点 Issue が無く、登録が2件以上なら、まとめ用の親 Issue を新しく作って親にする。まとめ用の親自身は、Issueの階層ガイド の「親の決め方」で決まるフェーズ Issue にぶら下げる(親を付けない種別なら付けない)
  3. 起点 Issue が無く、登録が1件なら、その Issue を Issueの階層ガイドの「親の決め方」でフェーズ Issue にぶら下げる

まとめ用の親は、子をすべて登録した後に作る。タイトルの先頭には、子の段の最小〜最大を付ける(例:1〜3. …。Issueの階層ガイドの「段番号(着手順)」)。ラベルは ai-fixable を付ける。子が open な間は /sweep・/issue-check が飛ばし、子が全部 close されたら完了条件を見て閉じるからである。本文は次の節だけにする。

  • この変更が必要な理由:Plan 全体について、子と同じ書き方で3行書く
  • タスク一覧:子へのリンク一覧(- [ ] #123 タイトル)
  • 完了条件:「すべての sub-issue が close されていること」
  • トレース(要件定義書との対応):子と同じ書き方で書く
  • 実装フロー(使用するSkill):「sub-issue を順に処理する」
gh api graphql -f query='mutation($parent:ID!,$childUrl:String!){addSubIssue(input:{issueId:$parent,subIssueUrl:$childUrl}){subIssue{number}}}' \
  -F parent="$(gh issue view <親の番号> --json id --jq .id)" -F childUrl="<子のURL>"

紐付けに失敗しても、登録そのものは成功している。失敗したら親が付かなかったことを伝えて続行し、登録をやり直さない(同じ Issue を二重に立てることになる)。

文体:中学生が一度で追える文で書く。専門用語は使ってよい。読みにくさの原因は用語ではなく言い回しにある。

  • ❌ その位置づけが実効を持たない → ✅ そう書いてあるだけで守られない
  • ❌ 変更耐性の最大化を企図する → ✅ 変更に強くしたい
  • ❌ 根拠を取り逃がす → ✅ 使えるはずの理由を見逃す
  • ❌ 担保する・企図する・起因する → ✅ 保つ・ねらう・原因である

一文に主語と述語は1組まで。長い一文は切る。

図:次のどれか1つでも当てはまるときだけ、/design-doc-mermaid で図を描いて「対応方針」の直後に埋め込む。当てはまらないなら描かない。

  • 登場するファイル・仕組みが3つ以上あり、その参照が一直線でない(分岐・合流・双方向がある):複数の Skill が同じ policy を参照し、policy 側が別の Skill を呼び返す
  • 条件で振る舞いが分かれる、またはループする:失敗時にリトライする処理
  • 状態が移る(未着手→作業中→完了 のような遷移):Issue ラベルの遷移規則

自前で Mermaid を書き起こしてはならない(CLAUDE.md)。

## この変更が必要な理由

1文1行で、改行して3行書く(1段落にまとめない)。実装の詳細(HOW)は書かない。別セッションの実装者が、判断に迷ったとき優先順位を自力で決められる状態を目指す。

  • 1行目:何が困っているか。対象をパスかシンボルで名指す
  • 2行目:実際に起きたことを1つ(数えた件数・実際の文言・エラー出力など)
  • 3行目:放置するとどう損するか

用語・略語・その場の造語には、その行の中の丸括弧で一行の言い換えを付ける。行に分けて足すと3行に収まらない。

対応方針

ai-fixable を付けたときだけ書く(issue:needs-human-decision のときはセクションごと省き、「人間に決めてほしいこと」に書く)。別セッションが方針を決め直さず、そのまま着手できる状態を目指す。

採る案:このスライスがエンドツーエンドで何を届けるかを1文で書く。

対象 いま 変えた後
path/to/file.ts など いまの振る舞い 変えた後の振る舞い

根拠:なぜその形にするかを1文で書く。
却下した案:取らないと決めた案と理由を1行ずつ書く(無ければ「なし」)。
人間が決めた名指し例外:issue:decided を付けたときだけ、quick-issue の「人間が決めた例外」の形で1例外1行ずつ書く。

レイヤーごとの実装手順は書かない。ファイルパスやコード片はすぐ古くなるので、表の「対象」列より細かくは書かない。例外は、文章より正確に決定を表すコード片(状態機械・リデューサ・スキーマ・型)をプロトタイプが生んだときだけ。決定が読み取れる部分だけに切り詰めて貼り、プロトタイプ由来だと一言添える。

人間に決めてほしいこと

issue:needs-human-decision を付けたときだけ書く(ai-fixable のときはセクションごと省く)。人間が Issue を開いた瞬間に「何を決めればよいか」が分かる状態を目指す。

論点:人間に何を決めてほしいのかを1文で書く。

案 利点 欠点 AI の見立て
案1 有力(根拠を1文で)
案2 —

タスク一覧

実装を完了させるために必要なタスクをチェックボックス形式で列挙する。実装者はこのリストを1つずつ確認し、完了ごとに gh issue edit でチェックを更新する(CLAUDE.md の厳守ルール)。設計書・docs/requirements.md(要件定義)の更新が必要な場合は、その更新タスクも必ず含めること(Plan の「設計書・要件定義への影響」から転記)。

  • タスク1
  • タスク2
  • (必要に応じて)設計書の更新
  • (必要に応じて)requirements.md の更新

完了条件

どうなったら閉じてよいかを書く。タスクの言い換えではなく、外から観測できる状態で書く(例:npm run lint が通る)。

  • 条件1

今回作らないこと(と、作る条件)

Plan のスコープ「やらないこと」(/grill-me の Not-now リスト)を1行1論点で転記する。実装者が「ついでに」足すのを止めるためのセクション。該当が無ければ「なし」と書く(セクションごと省かない)。

  • 論点1:トリガー

grill-me で確定した仕様

下の表を埋める。1行1決定・1セル1文。却下した案も書くと、別セッションでの蒸し返しを防げる。grill-me を実施していない場合は「grill-me 未実施」と書く(セクションごと省かない)。

決めたこと なぜそう決めたか 却下した案(理由)
決定1 無ければ「なし」

トレース(要件定義書との対応)

根拠となる機能ID(非機能なら分類名)と、関連する BR・IO・AC を書く。要件が無いスライス(ハーネス・ポリシー・設計書の手直しなど)は「要件定義書に対応なし」と理由を1文で書く。親は後から付け替わることがあるので、この Issue 単体から要件へ辿れるようにする。

実装フロー(使用するSkill)

このIssueを実装する際に使う開発フローSkillを実行順に記載する(Planの「実装フロー」から転記。このスライスが触れる種別だけに絞る)。issue番号だけで開発フローを再現するための情報。種別→Skillの対応は CLAUDE.md「開発フロー」が正典。

順 変更種別 使用Skill
1 例:アプリ実装 /code-dev

ブロッカー

先に完了している必要がある Issue への参照。無ければ「なし(すぐ着手できる)」と書く。

親 Issue はクローズも変更もしてはならない。例外は `/issue-regroup` だけである。親の open な子が全部ブロッカー待ちになったときに限り、子を付け替えてその親を close する。