振り返り
タスクを1件やり終えるたびに得た「次はこうしたい」は、その場で言わないと消える。このスキルは まだ振り返っていないコミット範囲を切り出し、材料を突き合わせて、次に同じ状況が来たときに 振る舞いが変わるものだけを書き留める。
守ることが3つある。
- 同じ範囲を二度振り返らない。
develop/retrospective.mdの先頭の1行が唯一の基準点で、 ここを更新して初めて「振り返った」ことになる - 承認ゲートを通す。 出力は
develop/direction.mdの## エージェントのドラフトに積む だけ。docs/もCLAUDE.mdもdevelop/tasks.jsonも直接は書き換えない。振り返りは 「気づき」であって決定ではなく、正典を変えるかどうかはユーザーが決める - 会話の中身を写さない。 トランスクリプトから取るのはツール名・ファイルパス・
コマンドの先頭2語・件数・時刻だけ。トランスクリプトには利用者と Claude の生の会話が
入っているので、記録にもドラフトにも写さない(プロジェクトに会話内容の扱いの規約が
あるなら、それが優先する)。
material.pyがこの線を引いているので、生の jsonl を 自分で開かない
手順
1. 範囲を決める
python3 ${CLAUDE_SKILL_DIR}/scripts/scan.py .
出力の読み方:
| 出力 | 意味 | すること |
|---|---|---|
range + コミットのTSV |
未振り返りの範囲がある | 手順2へ |
EMPTY\t<since>..<head> |
前回から進んでいない | 「振り返る対象が無い」と報告して終了 |
MISSING |
develop/retrospective.md がまだ無い |
下の「初回」へ |
INVALID\t<path>\t<理由> |
記録ファイルが読めない・ハッシュがリポジトリに無い | データの不備。理由をそのまま報告して終了(中身を確かめずに書き換えない) |
| 上のどれでもない出力 | python3 が無い・スクリプトが落ちた |
環境の故障。エラー出力を添えて報告して終了 |
TSVの列は hash / 日付 / タスクID / ファイル数 / 増減 / 件名。末尾に commits・tasks・
unmapped(タスクIDの無いコミット)・transcripts が出る。
振り返る単位はタスクなので、tasks に並んだIDを対象にする。unmapped のコミット
(アーカイブ・typo直し・依存更新)は数だけ見て、中身が気になるものがあるときだけ拾う。
初回(MISSING): どこから振り返るかはユーザーに決めてもらう。git log --oneline -20 を
見せて「ここから」を選んでもらい、選ばれたコミットの1つ前を起点にして記録ファイルを作る
(選んだコミット自身が範囲に入るように)。勝手に「最初のコミットから」にしない——
何十件も一度に振り返ると、どれも薄くなる。
2. 材料を集める
対象のタスク1件ずつに、次を実行する。
python3 ${CLAUDE_SKILL_DIR}/scripts/material.py . T-XXX --diff
出るのは4つ。タスク本文と evidence(develop/tasks.json、アーカイブ済みなら
docs/history/tasks.md)、progress.md の小節、コミットと diff、
手数(ツール呼び出し数・エラー数・同じファイルを直した回数・よく打ったコマンド)。
diff が上限で切れたら、気になるファイルだけ git show <hash> -- <path> で追う。
全部は読まない——振り返りに要るのは「本文が求めたこと」と「実際に入ったもの」の差で、
差の無いところを読んでも何も出ない。
diff は大きさではなく形で見る。 「多数のファイルに1〜3行ずつ」なら、それは判断ではなく
機械的な追随で、人が手で書かされているということ。同じ行が何度出てくるかを数えると
(git show <hash> | grep -c '^+.*<その行>')、次に同じ語彙を増やすときの費用がそのまま出る。
対象が5件を超えるときは、tasks の並びのうち手数が多いもの・diff が大きいもの・
passes: false のものから順に見て、残りは件名とdiffstatだけで済ませる。
3. 振り返る
材料を眺めて感想を書くのではなく、差を探す。次の兆候が振り返りの入口になる。
| 兆候(材料のどこに出るか) | 疑うこと | 出し先の候補 |
|---|---|---|
| diff の大半が同じ1行の繰り返し(diffstat が「多数のファイルに1〜3行ずつ」の形) | 機械的な追随を人が手で書いている。語彙・定義・フィクスチャの重複 | タスク(共通の組み立てに寄せる) |
| 同じファイルを3回以上直している(手数) | 手順の順序が悪い・前提を調べずに書き始めた | タスクの書き方(plan-tasks)/規約 |
| ツールのエラーが多い(手数) | 環境の前提がタスク本文に無かった | タスク本文の ## 注意 に書くべきこと |
| 検証コマンドを何度も打ち直している(手数) | 落ちる原因が規約に書かれていない | 規約への追記 |
| 本文が指した場所と diff の場所がずれている | 調査が本文に落ちていない・設計の理解が古い | 正典(docs/)の記述が実物とずれている |
| 完了条件に無かったものが diff に入っている | タスクの切り方が粗い/必要な追随が暗黙になっている | タスクの書き方/規約 |
| evidence が完了条件を覆っていない | 受け入れが甘い | evidence の粒度(task-workflow) |
| 複数のタスクで同じ手作業が出ている | 道具にできる | タスク(スクリプト化) |
difficulty を途中で上げた/明らかに過剰だった |
見立ての基準がずれている | difficulty の基準 |
出すかどうかの物差しは1つだけ: 次に同じ状況が来たときに、誰かの振る舞いが変わるか。 変わらないなら書かない。一度きりの事故、そのタスク固有の事情、「うまくいった」の確認は、 書いても次に効かないので落とす。
同じ話に畳めるものは1つにまとめる。 「T-302 で〜」「T-318 でも〜」が同じ原因を指しているなら、 それは1件の findings で、タスクIDは根拠として並べる。1回の振り返りで3件を超えたら、 畳み方が足りていないと疑う。
思いつきを足さない。 材料に根拠が無い改善案は、振り返りではなく思いつきで、
## エージェントのドラフト に混ぜると出どころが分からなくなる。
4. ドラフトに積む
develop/direction.md の ## エージェントのドラフト の末尾に足す(既存の行は動かさない)。
1件をこの形で書く:
- **<何を変えるか(1行)>**(振り返り: T-302, T-318)
- 根拠: <材料のどこにどう出ていたか。数で言えるものは数で>
- 出し先: <どのファイルのどの節に足すか / タスクにするなら何をするタスクか>
## ユーザーから には書かない(あそこはユーザーの入口)。ここに積んだものは、ユーザーの承認を
得てから /plan-tasks がタスクにする(task-workflow の WORKFLOW.md「指示メモ」)。
findings が0件でも、それは失敗ではない。 範囲は振り返り済みとして記録し、0件だったことを
報告する。無理に絞り出すと、次から ## エージェントのドラフト が信用されなくなる。
5. 記録してコミット
develop/retrospective.md を更新する。
- 先頭の
最後に振り返ったコミット:の行を、範囲の末尾(scan.pyが出したrangeの右側) に書き換える - 「振り返りの履歴」の先頭に小節を1つ足す(新しい順。
progress.mdと同じ並び)
### YYYY-MM-DD `<since>`..`<head>`(<N>コミット / T-XXX, T-YYY)
- <findings の1行要約> → `develop/direction.md` の `## エージェントのドラフト`
- 振り返ったが出さなかったもの: <あれば1行。無ければこの行ごと省く>
develop/retrospective.md と develop/direction.md の2ファイルを指定してコミットする
(git add -A を使わない。同じ作業ツリーで別のセッションが動いていることがある)。
件名は 振り返り <since>..<head>(<N>コミット) の形にし、タスクIDは件名に置かない
(タスクのコミットと混ざると scan.py の割り付けが狂う)。
初回は記録ファイルを作るところから。この雛形をそのまま置く:
# 振り返りの記録
最後に振り返ったコミット: `<hash>`
<!-- 上の1行だけが機械の読む値(skills/retrospect/scripts/scan.py)。形を変えない。
振り返りの出力そのものは develop/direction.md の ## エージェントのドラフト に積む。
ここに残すのは「どこまで見たか」と「何を出したか」の索引だけ。 -->
## 振り返りの履歴
報告のフォーマット
最後に次を1行ずつ示す。
- 振り返った範囲(
<since>..<head>)とコミット数・タスクID - ドラフトに積んだ件数(0件ならそう言う)と、それぞれの1行要約
- 材料が欠けていたものがあれば、何が無かったか(トランスクリプトが残っていない等)
- 記録のコミットハッシュ
他のプロジェクトで使うとき
前提は task-workflow の運用(develop/tasks.json / progress.md / direction.md と
docs/history/、コミットの件名にタスクIDを置く)。この運用のプロジェクトなら、置き場も
IDの形も同じなので何も変えずに動く。
前提が揃わないプロジェクトでは、スクリプトは落ちずに - と欠席の理由を出す(材料が減るだけ)。
そのうえで次の4つが合わないなら、合わせるか、このスキルを使わない:
| 前提 | 使っているところ | 合わないときの影響 |
|---|---|---|
タスクIDが T- + 3桁 |
scan.py の割り付け / material.py の照合 |
全コミットが unmapped になり、振り返る単位が消える |
| コミットの件名にタスクIDがある | 同上 | 同上 |
develop/ と docs/history/ にタスクと進捗がある |
material.py の材料2つ |
材料が diff と手数だけになる |
develop/direction.md に ## エージェントのドラフト がある |
手順4の出し先 | 積む先が無い。プロジェクトの「未対応の指示の置き場」に読み替える |
コミットの作法(ブランチを切るか、直接デフォルトブランチか)はそのプロジェクトの
CLAUDE.md に従う。このスキルは「2ファイルを指定してコミットする」としか決めていない。
このスキルがしないこと
- ドキュメントを直さない・タスクを登録しない。 承認ゲートの手前で止まる(上の「守ること」2)
/loopに載せない。 無人で回すと、根拠の薄い findings がドラフトに溜まり続ける。 手で呼ぶ- タスクの是非を蒸し返さない。 「あのタスクはやるべきでなかった」は振り返りの対象外で、 見るのはやり方だけ