From self-improvement
セッションの観察・評価・改善提案を一括実行する。 (1) 振り返り記録の生成 (2) Rubric スコアリング (3) 摩擦検出と改善提案。 改善点があれば improvements.md に1件追記。なければ OBSERVE_OK を出力。 使用場面: セッション終了時、/loop での定期実行、Stop hook からの自動トリガー。
How this skill is triggered — by the user, by Claude, or both
Slash command
/self-improvement:observeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- 1回の observe で記録する改善は最大1件
observe 実行開始時刻を記録する(どのトリガー由来か後から追跡するため):
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
mkdir -p "$PROJECT_DIR/.claude/tmp" 2>/dev/null || true
date -u +%s > "$PROJECT_DIR/.claude/tmp/observe-start-time"
reflection ファイルの冒頭にも Start: YYYY-MM-DD HH:MM UTC を記録すること。
前回の observe 以降に新しい作業があるか確認する:
docs/memory/reflection/ 内の最新ファイルの更新日時git log --oneline -5 で直近のコミット前回の observe(improvements.md の最終エントリの日付)以降に新しい振り返りもコミットも session jsonl mtime 更新もなければ:
→ OBSERVE_OK を出力して終了
observe は呼び出され方によってパス解決方法を変える。必ず以下の優先順位:
hook 経由で呼ばれた場合(SessionEnd / Stop hook から):
stdin に JSON payload が渡され、transcript_path フィールドに jsonl の絶対パスが含まれる。
これを最優先で使う(公式ドキュメント: hooks.md の全 hook event で保証)。
# hook script 内
INPUT=$(cat)
TRANSCRIPT=$(echo "$INPUT" | jq -r .transcript_path)
SESSION_ID=$(echo "$INPUT" | jq -r .session_id)
手動呼び出しの場合(/observe スラッシュコマンド):
hook payload は無いので、config dir + slug から導出する:
CONFIG_DIR=${CLAUDE_CONFIG_DIR:-$HOME/.claude}
SLUG=$(echo $PWD | sed 's|[^a-zA-Z0-9]|-|g')
PROJECT_DIR="$CONFIG_DIR/projects/$SLUG"
ls -lt "$PROJECT_DIR"/*.jsonl 2>/dev/null | head -10
注意:
CLAUDE_CONFIG_DIR はユーザーが ~/.claude 以外に変更している可能性があるため、ハードコード禁止-。sed 's|[^a-zA-Z0-9]|-|g' を使う。tr '/' '-' や sed 's|[/_.]|-|g' は不十分cloud session(Codespace 等)の場合:
$CLAUDE_CODE_REMOTE が true に自動設定される$CLAUDE_CODE_REMOTE_SESSION_ID に session ID が入るCLAUDE_CODE_SKIP_PROMPT_HISTORY=1 が設定されていると jsonl が永続化されない → observe 実行前にこれを確認し、設定されていれば警告を出して終了以下を読み込む(存在するもののみ):
docs/memory/heartbeat/improvements.md -- 既存の改善ログ(重複提案の防止)docs/memory/heartbeat/failure-patterns.md -- 既知の失敗パターン(再発検出)docs/memory/heartbeat/rubric-log.md -- 直近のスコア推移docs/memory/reflection/ 内の最新ファイル(あれば)git log --oneline -20 -- 直近のコミット履歴(これは成果物の記録であり、摩擦は commit 後に除去されているので摩擦検出には使わない)~/.claude/projects/{slug}/*.jsonl -- session transcript(摩擦検出の一次ソース)commit log はユーザーが満足した最終成果物しか残らない。実際の怒り・手戻り・修正指示は session jsonl にしか存在しない。
jsonl パスを解決(上記「session jsonl パスの解決」参照):
transcript_path${CLAUDE_CONFIG_DIR:-$HOME/.claude}/projects/$(echo $PWD | sed 's|[^a-zA-Z0-9]|-|g')/対象 jsonl を特定: 前回 observe(improvements.md 最終エントリの日付)以降に mtime 更新されたもの全て。巨大セッション(10MB超)や長寿命セッション(複数日跨ぐ)に注意
Claude 自身が user 発話を全て精読し、文脈判断で摩擦を検出:
補助: 強いシグナルの事前 grep スキャン(Python 依存なし、bash + jq + grep + awk のみ)
# 2026-04-30 改修: パターンは references/scan-patterns.md に外部化、編集ガイドも同ファイル参照
PATTERNS_FILE=".claude/skills/observe/references/scan-patterns.md"
load_pattern() {
awk -v cat="$1" '
$0 == "## " cat || $0 ~ "^## " cat " " { found = 1; next }
found && /^## / { exit } # 次見出しに到達したら終了 (自由文追記耐性)
found {
if ($0 ~ /^[[:space:]]*$/ || /^意図:/ || /^# /) next # 空行 / 意図行 / コメント行はスキップ
print; exit
}
' "$PATTERNS_FILE"
}
# fail-closed defensive default: 空 pattern は user 全消去 (grep -vE) / 全行マッチ (grep -cE) 事故を招くため即終了
for cat in skill_origin_markers anger emphasis_chars imperative unmodified_change hands_on_check rework negative_pressure; do
val=$(load_pattern "$cat")
# 空白文字のみの値も bypass しない真の fail-closed 判定 (Codex Layer 3 指摘、空 SKILL_ORIGIN で user 全消去事故防止)
trimmed=$(printf '%s' "$val" | tr -d '[:space:]')
[ -n "$trimmed" ] || { echo "[observe ERROR] scan-patterns.md のパターン '$cat' が空または空白のみ" >&2; exit 2; }
case "$cat" in
skill_origin_markers) SKILL_ORIGIN="$val" ;;
anger) ANGER="$val" ;;
emphasis_chars) EMPHASIS="$val" ;;
imperative) IMPERATIVE="$val" ;;
unmodified_change) UNMODIFIED="$val" ;;
hands_on_check) HANDS_ON="$val" ;;
rework) REWORK="$val" ;;
negative_pressure) NEGATIVE="$val" ;;
esac
done
scan_strong_signals() {
local file="$1"
# 第 1 段: tool_result を分離して純 user text のみ抽出 (self-reference 約 50% 削減を実機実証、anger 45→20 / rework 59→32)
# 第 2 段: skill 由来 text を特徴判定で除外 (system-reminder / Base directory / command-name / 行頭数字→ / grep -cE)
local users
users=$(jq -rc 'select(.type=="user") | .message.content | if type=="array" then map(select(.type=="text") | .text) | .[] else . end // ""' "$file" \
| grep -vE "$SKILL_ORIGIN")
local user_message_count
user_message_count=$(printf '%s\n' "$users" | wc -l | tr -d ' ')
echo "=== $file ==="
echo "純 user text 行数: $user_message_count"
echo "強い怒り表現: $(printf '%s\n' "$users" | grep -cE "$ANGER")"
echo "強調記号連続: $(printf '%s\n' "$users" | grep -cE "$EMPHASIS")"
echo "命令調強圧: $(printf '%s\n' "$users" | grep -cE "$IMPERATIVE")"
echo "変更未反映指摘: $(printf '%s\n' "$users" | grep -cE "$UNMODIFIED")"
echo "実地検証要求: $(printf '%s\n' "$users" | grep -cE "$HANDS_ON")"
echo "手戻り言及: $(printf '%s\n' "$users" | grep -cE "$REWORK")"
echo "否定強圧: $(printf '%s\n' "$users" | grep -cE "$NEGATIVE")"
}
for f in $JSONL_PATHS; do scan_strong_signals "$f"; done
この数値は Claude の文脈判断結果の下限サニティチェック。Claude の検出件数がこの値未満なら見落としを疑う。運用ガイド (補助 grep 値依存禁止 / Claude 一次判定権限 / パターン定期再測定) とパターン編集方法は references/scan-patterns.md を参照。
複数の jsonl を跨ぐ場合は 合算して rubric 判定
禁止事項: commit log と reflection/ だけで rubric を評価する(摩擦を必ず見逃す)。session jsonl を読まずに改善提案を出すことも禁止。
早期終了条件: CLAUDE_CODE_SKIP_PROMPT_HISTORY=1 が設定されている場合、jsonl は永続化されていないので observe は機能しない。検出したら警告のみ出力して終了する。
セッション中に発火した hook の挙動を docs/memory/heartbeat/hook-firings.jsonl から集計する。
# 直近 7 日の発火サマリー (rubric 評価時に参照)
.claude/scripts/hook-stats.sh 7
# 週次匿名化 summary を public 用に出力
.claude/scripts/hook-stats.sh 7 summary > docs/memory/heartbeat/hook-firings-summary.md
観察対象 (Rubric 評価の補助シグナル):
action: "block" (exit_code: 2): PreToolUse などで hook が実行をブロックした件数。多発はユーザー作業の妨げの兆候action: "inject": additionalContext / permissionDecision で Claude へ情報注入した件数。トリガー文字列も合わせて見ると検出パターンの過剰性が分かるaction: "remind": リマインダー出力件数。レビュー起動忘れ等の頻度指標action: "skip": 抑制した件数。基底ノイズrubric への反映:
action=remind) が直近セッション中に 2 件以上 → 「指示理解度」-1 (同じ忘れの再発兆候)action=deny した件数が 1 件以上 → 「動作検証」-1 (秘匿情報露出寸前)action=block で疑われる場合 → 該当 hook の検証へ持ち込み推奨集計結果のうち特異点は docs/memory/reflection/YYYYMMDD_*.md の Rubric Score セクション末尾に「hook-firings 観察: ...」として 1-2 行で要約記録する。
テンプレート に従い、docs/memory/reflection/YYYYMMDD_{title}.md を生成する。
Handshake, 摩擦ポイント, 得られた知見, 次回アクション, 刺さったフレーズの5セクションに加えて、 Rubric Score セクションを含める。
5基準10点満点でセッション品質を評価する。判定根拠は session jsonl 内の user 発話を Claude 自身が精読した上での文脈判断(キーワードは補助ヒント、commit log だけでの評価は禁止):
| 基準 | 配点 | 判定方法 |
|---|---|---|
| 手戻り率 | 3 | Claude が user 発話を読み、「変更が反映されていない」「同じ修正を繰り返し指示」等の手戻り指摘を検出。0回=3, 1回=2, 2回=1, 3回以上=0 |
| 指示理解度 | 2 | Claude が user 発話を読み、怒り・呆れ・「質問したのに修正」「専門用語垂れ流し」等、理解齟齬を示す発話を検出。0回=2, 1回=1, 2回以上=0 |
| 前提確認 | 2 | CLAUDE.md / 指定ルールファイル / 仕様ドキュメント / Claude Code 機能に関わる場合は公式ドキュメントを事前読み込みしたか。全確認=2, 一部漏れ=1, 確認なし=0 |
| 動作検証 | 2 | Claude が user 発話を読み、「自分で確認」「推測じゃなく実地で見て」等の検証怠り指摘を検出。0回=2, 1回=1, 2回以上=0 |
| 後片付け | 1 | git ls-files --others --exclude-standard で残骸ファイル。なし=1, あり=0 |
重要:
スコアを振り返りファイルの Rubric Score セクションに記録し、
docs/memory/heartbeat/rubric-log.md にも1行追記する:
YYYY-MM-DD | N/10 | 手戻りN 指示N 前提N 検証N 片付けN | {セッション概要}
チェックリスト に従い、以下を検出する:
既に improvements.md に記録済み(Status: proposed/applied)の問題は除外する。 ただし Status: applied なのに再発している場合は、failure-patterns.md を更新し、新たなエントリとして記録する。
摩擦ポイントを docs/memory/heartbeat/failure-patterns.md の既存パターンと照合する:
scripts/fp-allocate.sh で採番、独自に番号を決めない。並走 routine 衝突防止のため。commit 時に重複検出する post-hoc lint を別途用意推奨)台帳行の短文化: 新規 FP 行追加は 症状ラベル + reflection リンク + 親 FP リンクのみで 200 字以内。事例本文 / 対話ログ / Why の長文は raw データ正本 (reflection) に集約し、台帳行では再記述しない。これにより台帳の grep 性と一覧性を維持する。
アーカイブ候補 = 以下 3 条件すべて満たす行:
対策状況 列が applied を含む最終発生 列から本日まで 45 日以上経過再発回数 列が 1 (= 適用後に再発なし)grep "^| FP-" docs/memory/heartbeat/failure-patterns.md \
| awk -F'|' '{print $3, $5, $6, $7}' \
| grep "applied"
候補が 1 件以上あれば、Step 7 の改善提案に「FP 棚卸し(N 件 → archive)」を improvements.md に追記することを優先する。
docs/memory/heartbeat/failure-patterns-archive.md/evolve が high-risk として人間承認キューに上げる(自動移動禁止)摩擦を検出した場合、テンプレート に従い
docs/memory/heartbeat/improvements.md の末尾に 1件だけ 追記する。
複数検出した場合は 最もインパクトが大きい1件のみ を選択する。 Rubric スコアが特定の基準で目標(8.0/10)を下回っている場合は、その基準に関連する改善を優先する。
台帳の短文化ルール: improvements.md への新規 entry append の field 構造は references/improvement-template.md を正本参照 (本 SKILL では field 名を再列挙しない、template 更新時の再ドリフト防止)。運用上のルールは以下のみ:
<failure-pattern-id> (詳細: [reflection/YYYYMMDD_*](../reflection/YYYYMMDD_*.md)) の 1 行参照形式 (100 字以内)、Symptom 長文 / 対話ログは reflection 正本に集約../reflection/... 形式に統一Risk-level は 最高 severity (= 最も保守的) を採用、entry 全体の自動適用回避で安全側に倒す。詳細値範囲 / 判定基準は references/improvement-template.md を参照OBSERVE: logged 1 improvement -- "{short title}" (rubric: N/10)
OBSERVE_OK (rubric: N/10)
OBSERVE_OK (rubric: N/10, 注意: 未レビューの提案が{N}件。/evolve で処理してください)
observe のステップ 1〜8 が完了したら、続けて /evolve を必ず実行する。
Risk-level: low かつ追記のみ、references/.md や docs/memory/heartbeat/.md 等)のみ自動適用observe-on-end.sh)で呼ばれた場合も同じ流れを踏む。claude -p の 1 回の invoke 内で /observe と /evolve を連続実行するよう、Claude 自身が続けて Skill を発動するobserve の出力に続けて 2 行目に evolve の結果を追加する:
EVOLVE: {出力パターン}
/observe + /evolve のすべてが完了したら、以下を実行して最終実行時刻を記録する:
date -u +%s > "${CLAUDE_PROJECT_DIR:-$(pwd)}/.claude/tmp/last-observe-time"
このタイムスタンプは .claude/hooks/observe-periodic-check.sh(UserPromptSubmit hook)が読み、
前回 /observe から 60 分経過していたら次の user prompt で再リマインドを注入する。
記録を忘れると 60 分経過判定が狂うので、ステップ 10 まで必ず実行する。
npx claudepluginhub arkatom/claude-plugins --plugin self-improvementGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.