🈂️

2025/12/26時点のClaude Codeにやらせてること・セッションのログからプロジェクト特有の知見をドキュメント化していく

に公開

ふわせぐさん (@fuwasegu) の exocortex は未だ開発には使ってないんですけども。

https://github.com/fuwasegu/exocortex

似たようなことをしようと思って。

棚卸しスキル

セッションをすべて記録し、そこからプロジェクト特有の知見をドキュメントとするようにしました。

  1. セッション終了時にログをファイルに保存
  2. ログを元にプロジェクト特有の知見がないか確認しドキュメント化する「棚卸し」を実行

セッション終了時にログをファイルに保存

SessionEnd フックを使います。

.claude/settings.json

{
  "hooks": {
    "SessionEnd": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/save-session-log.sh"
          }
        ]
      }
    ]
  }
}

.claude/hooks/save-session-log.sh

#!/bin/bash
# セッション終了時に会話ログをraw/へ保存

# jq の存在チェック
if ! which jq > /dev/null 2>&1; then
  echo "Error: jq is required but not installed." >&2
  echo "Please install jq: https://jqlang.github.io/jq/download/" >&2
  exit 1
fi

# stdinからJSONを読み取り
INPUT=$(cat)

# jqでtranscript_pathを抽出
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // empty')

if [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH" ]; then
  exit 0
fi

# 保存先ディレクトリ
RAW_DIR="$(pwd)/docs/findings/raw"
mkdir -p "$RAW_DIR"

# ファイル名: session-YYYY-MM-DD-HHMMSS.jsonl
FILENAME="session-$(date +%Y-%m-%d-%H%M%S).jsonl"

# コピー
cp "$TRANSCRIPT_PATH" "$RAW_DIR/$FILENAME"

exit 0

これでセッション終了時 docs/findings/raw/ にJSONL形式で1セッション1ファイルで保存されていきます。

ログを元にプロジェクト特有の知見がないか確認しドキュメント化する「棚卸し」を実行

.claude/skills/tanaoroshi/SKILL.md

---
name: tanaoroshi
description: セッションログから価値ある Findings(発見)を抽出し、カテゴリ別に整理する
---

# 棚卸し (Tanaoroshi) Skill

セッションログから価値ある Findings(発見)を抽出し、カテゴリ別に整理する。

## 実行手順

### 1. 未処理のセッションログを取得

docs/findings/raw/session-*.jsonl

※ `raw/done/` 内のファイルは処理済みなのでスキップ

### 2. セッションログを読み込み、発見を抽出

JSONLファイルの各行はセッション中のやり取り。以下の観点で「価値ある発見」を探す。

### 3. 発見をカテゴリ別に整理

抽出した発見を Markdown ファイルとして保存し、`index.md` を更新。

### 4. 処理済みログを移動

処理したセッションログを `raw/done/` に移動。

---

## 価値ある Findings の判定基準

### 記録すべきもの

- **マニュアルに書いてないこと**: 公式ドキュメントでは説明されていない挙動
- **実際にやってみて初めてわかったこと**: 試行錯誤の結果得られた知見
- **特定の組み合わせでの挙動**: 複数の機能・設定を組み合わせた際の動作
- **ハマりポイントと解決策**: エラーや予期しない挙動とその対処法
- **ベストプラクティス**: 効率的・推奨される実装パターン
- **技術選択の理由と経緯**: なぜこの技術・バージョン・環境を選んだか(後から見返した時に意図がわかるように)
- **環境構築で遭遇した問題**: セットアップ時のエラーや依存関係の問題と解決策
- **プロジェクト固有の方針決定**: このプロジェクトで決めたルールや前提条件

### 記録しないもの

- **概念の一般的な説明**: 「エンティティとは」「シリアライザとは」など
- **公式ドキュメントのコピー**: マニュアルを読めばわかること
- **単純な使い方**: 基本的なコマンドや設定方法

### 判定の例

NG: 「API Platformでエンティティを定義する方法」
    → マニュアルに書いてある

OK: 「JSONカラムとJSONBカラムでシリアライザの挙動が異なる件」
    → 実際にやってみないとわからない

NG: 「Doctrineのリレーション設定」
    → 公式ドキュメント参照

OK: 「API PlatformとBe Frameworkで同じエンティティを扱う際の注意点」
    → 両者を組み合わせた実践的知見

OK: 「ローカルMac + PHP 8.5.1 を選んだ理由」
    → このプロジェクトでの技術選択の記録

NG: 「asdfでPHP 8.5.1をビルドする際にicu4cとOpenSSL設定が必要」
    → このプロジェクト特有の問題ではない

NG: 「asdfの使い方」
    → 公式ドキュメント参照

---

## カテゴリと保存先

| カテゴリ | ディレクトリ | 内容 |
|---------|-------------|------|
| API Platform | `docs/findings/api-platform/` | API Platform固有の発見 |
| Be Framework | `docs/findings/be-framework/` | Be Framework固有の発見 |
| Integration | `docs/findings/integration/` | 両者の連携に関する発見 |
| Environment | `docs/findings/environment/` | 環境構築、技術選択、プロジェクト方針 |
| **未分類** | `docs/findings/uncategorized/` | どのカテゴリにも当てはまらない発見 |

### カテゴリの運用ルール

- **迷ったら「未分類」に入れる** - カテゴリ判断で悩んで見落とすより、まず記録することを優先
- **未分類が溜まったら整理** - 同じ傾向の発見が複数あれば、新しいカテゴリを作成
- **カテゴリは固定ではない** - プロジェクトの進行に応じて追加・変更してよい

---

## ファイル命名規則

**具体的なトピックを反映したファイル名にする**(抽象的な名前は避ける)

# NG: 抽象的すぎる
entity.md
serializer.md
config.md

# OK: 具体的な発見を表す
json-jsonb-column-serialization.md
custom-filter-with-doctrine-extension.md
nested-entity-normalization-groups.md
api-resource-uri-template-override.md

命名パターン: `{対象}-{状況や組み合わせ}-{何についてか}.md`

---

## Markdown ファイルの書式

(ここから)
# {タイトル: 具体的な発見内容}

- **発見日**: YYYY-MM-DD
- **タグ**: 関連キーワード(カンマ区切り)

## 状況

何をしようとしていたか、どういう前提条件だったか。

## 問題 / 疑問

何が起きたか、何がわからなかったか。

## 発見 / 解決策

何がわかったか、どう解決したか。

## コード例

(該当する場合、動作確認済みのコードを記載)
(ここまで)

---

## index.md の更新

新しい finding を追加したら、`docs/findings/index.md` に参照を追加する。

(ここから)
### API Platform
- [JSON/JSONBカラムのシリアライズ挙動](api-platform/json-jsonb-column-serialization.md)
- [カスタムフィルターとDoctrine拡張の連携](api-platform/custom-filter-with-doctrine-extension.md)
(ここまで)

---

## 処理済みファイルの扱い

処理が完了したセッションログは `raw/done/` に移動する。

mv docs/findings/raw/session-2025-01-15-143022.jsonl docs/findings/raw/done/

---

## 出力(実行完了時の報告)

棚卸し完了後、以下を報告する:

1. 処理したセッションログのファイル名一覧
2. 抽出した findings の数(カテゴリ別)
3. 作成/更新したファイル一覧
4. index.md への追加項目
5. 「価値ある発見なし」と判断したログがあればその旨

これで Claude Code に「棚卸しして」と言えば、保存されたログファイルからドキュメントを生成してくれます。
棚卸し完了したログについては docs/findings/raw/done/ に移動し、以後参照しないようにしています。
削除してもいいですが、あとから再度棚卸しをしたくなったとき(スキルを改善したとき)のために残しています。

効果のほどは?

昨日思いついてやっただけなのでどうでしょうね。
棚卸しスキルの内容は、ぼくが今やろうとしていることに寄ったものなので、そのままは使えないと思います。多分。(Claudeさん賢いから動くような気もする)

Discussion