セッションラップ(プロジェクト対応クローズアウト)

セッション終了時にプロジェクトの状態を保存し、ハンドオフメモリを更新します。任意のプロジェクトで動作し、中セッションハートビートによる自動チェックポイントも行います。

セッションラップ(プロジェクト対応クローズアウト) とは?

このスキルは、Claude Code等のAIエージェントセッション終了時に、プロジェクトの状態を確実に保存・継承するための標準化された手順を提供します。汎用部分(§1:ハンドオフメモリの更新とタグ付け)はどのプロジェクトでも実行され、プロジェクト固有の状態ストア(§2:Postgres DB等)への同期はルーティングによって自動的に振り分けられます。また、セッション中にサブタスク完了ごとに実行するハートビートチェックポイント(§0)により、クラッシュ時のメモリ損失を最大1ステップに抑えます。最後に、次回セッション用の再開プロンプトを生成し(§3)、保存・出力します。レジュームフックはプロジェクト非依存で、MEMORY.mdのタグ行を読み取って自動的にハンドオフファイルを注入するため、特別な設定なしにどのプロジェクトでもシームレスに復帰できます。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/butterpurse-dot/claude-code-crashproof-handoff/tree/HEAD/skills/session-wrap

Installed? Explore more 生産性&コラボレーション skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

セッションラップ(プロジェクト対応クローズアウト) は何をしますか?

2つのパートで構成:§1は汎用、§2はプロジェクトごとにルーティング(状態テーブルはプロジェクト固有 — 他のプロジェクトのテーブルを書き込まない)。§0はセッション中ハートビート(後述)。<MEM> = bash ~/.claude/hooks/session-resume.sh --dir で出力されるメモリディレクトリ。

保存前には必ず編集(ハートビート、ハンドオフメモリ、ルール/nowファイル、DB行、再開プロンプト):APIキー、トークン、パスワード、秘密鍵、アカウント番号と残高、個人データ、稼働中のアカウントを特定する情報を削除する。<REDACTED — see vault> と書き込むか、言い換える(「残高確認済み、ここには記録しない」)。実際の値がどこにあるかを示すのは問題ないが、値自体は記録しない。§2のガードレイル言い換えルールと同じパターン — 両方を維持する。

0. ハートビートチェックポイント — セッション中(ハンドオフメモリのみ)

各サブタスク完了後、および長い/リスクの高いステップ(大規模リファクタリング、デプロイ、DBマイグレーション)の前に、現在のプロジェクトの§1ハンドオフファイルのみを更新する(存在しなければ作成する):## LIVE STATE (heartbeat) ブロック — 完了した作業、進行中の作業、次のステップ。前のブロックを置き換え、追記しない。目標は15行未満。見出しは正確に保つ:フックがこれをマッチする。

  • MEMORY.md の再タグ付け、データベースへの書き込み、再開プロンプトの出力は行わない — これらはセッション終了時に残す(§1タグ、§2、§3)。ラップ時に、ブロックを検証済み状態に折り込み、削除する。
  • この時点でのクラッシュは、最大でも1ステップ分のメモリ損失で済む。session-resume.sh は、ブロックを保持しているすべてのハンドオフを次回起動時に UNWRAPPED HEARTBEAT としてリストするため、タグ付けされていない最初のハートビートファイルでも発見される。

1. ハンドオフメモリ — 常に実行(任意のプロジェクト)

<MEM>/project_<プロジェクト名>_handoff_<YYYYMMDD>.md を書き込む/更新する:検証済み状態(キーSHA、確定した内容、未解決の決定、順序付けられた次の作業、必須事項)。<MEM>/MEMORY.md で、そのインデックス行に ★READ FIRST FOR <プロジェクト名> (current)★ とタグ付けし、以前のものには (superseded) とマークする。古いハンドオフはディスク上に残る:置き換えられたチェーンがプロジェクトの履歴となる。

  • SessionStartフック ~/.claude/hooks/session-resume.sh はプロジェクト非依存:READ FIRST FOR <任意のプロジェクト> にマッチし、superseded とマークされていないすべての行を注入する → 行をタグ付けすることが、任意のプロジェクトの再開保証となる(プロジェクトごとのフックは不要)。MEMORY.mdが自動ロードされてもフックを維持する:「ハンドオフを読み取ってから作業を開始する」という指示を追加し、どのディレクトリからでも動作し、MEMORY.mdが200行のロード制限を超えても機能する。また、プロジェクトに2つのライブポインターがある場合や、存在しないファイルへのポインターがある場合に警告を出す — ラップ時にそれらを修正する。

ルールは引き継がれる。 新しい所有者ルール、恒久的なガイダンス、作業用コマンド、有料の教訓は、ハンドオフだけでなく、与えられた時点でそのプロジェクトの常時ロードルールファイルに書き込まれる。ルールファイル:<MEM>/<プロジェクト名>_rules.md、<MEM>/session-wrap.conf にリストされたすべてのプロジェクトに対して session-resume.sh によって完全ロードされる。短く保ち、追記ではなく置き換える。ラップ時に確認:このセッションで所有者が繰り返さなければならなかったことは、今はルールファイルに含まれている必要がある。また、<MEM>/<プロジェクト名>_now.md を書き換える(現在の状態と次のステップ、短く保つ:フックコンテキストは約10,000文字でカットされる)。

2. プロジェクト状態ストア同期 — ルーティング

cwd / このセッションの作業からプロジェクトを検出する。その後、そのプロジェクトのルートに従う。所有するプロジェクトごとに1つ ### ルートを追加する。以下の3つはパターン。

<Postgresストアを持つプロジェクト> → そのプロジェクトのデータベース

環境から資格情報を使用して接続する(psql "$PROJECT_DB_URL")、コマンド内にリテラルを使用しない。examples/state-store.sql のテーブル例:

INSERT INTO session_handoff (session_id, handoff_prompt, created_at) VALUES ('<sid>','<resume>',now());
INSERT INTO decisions (title,rationale,applies_to,status,session,"timestamp",decided_at)
  VALUES ('<d>','<why>','<project>','implemented','<sid>',now()::text,now());   -- 1行につき1つのINSERT
INSERT INTO code_map (module,path,lines,purpose,bounded_context) VALUES (...);  -- 一意制約がない場合は先にDELETE path

注意点(独自のストア用にここに記述する;これらは各セッションを消費する類のもの):キーワード名の列を引用符で囲む(decisions."timestamp";"order" のような予約語には必須、それ以外では無害)、型に注意(これは text + NOT NULL、よって now()::text);CHECK制約のある列はリストされた値のみを受け付ける(pending|implemented|superseded|deferred|rejected);テーブルが存在することを前提にしない — 最初に \d で確認する;複数行のVALUESはアトミックであるため、1行でも不正だとすべてがドロップされる → 1行ずつ -v ON_ERROR_STOP=off で行う。ガードレイルの誤検知:危険なコマンドをブロックするPreToolUseフックはBashコマンド全体をgrepする — SQLテキストにブロックされたパターンのリテラル(reset --hard、git push、git clean)が含まれている場合、コマンド全体がブロックされる。ハンドオフ/決定テキストではそのような文字列を言い換える(例:「破壊的git」、リテラルではない)。

<ライブで動作するプロジェクト> → そのプロジェクトのストア(他のプロジェクトのものではない)

書き込む前にスキーマを確認する;それに関するメモはすぐに古くなる。ライブインフラ — 外部の記録システム(決済プロバイダー、本番DB、実行中のサービス)が真実であり、ハンドオフではない;ラップの一部としてライブフラグや設定を決して変更しない。

<その他すべて> → メモリのみ

DB状態ストアなし — §1のハンドオフメモリが記録となる。これを明記し、他のプロジェクトのテーブルを書き込まない。

3. 再開プロンプトを出力する(最後のアーティファクト — ユーザーが次のClaudeに貼り付けるもの)

保存後、次のセッション用のコピー&ペースト可能なプロンプトをコードフェンスで囲んで出力する。SessionStartフックがハンドオフポインターを既に注入しているため、このプロンプトは以下を追加するのみ:再ロードチェック + ユーザーが決定しなければならない未解決の決定。テンプレート:

Resume <プロジェクト名>. Read memory <ハンドオフファイル> first, then skill /<プロジェクトマップスキル>.
Verified state: <1行: キーSHA + ライブのもの + ゲート/ブロックされているもの>.
First: 1) /context — <再ロードチェック、例:新しくロードされたプラグインのコスト測定>; 2) <ロード確認チェック>.
Then my decision on <未解決の分岐>: [PICK ONE] (a) <推奨> (b) … (c) …
<恒久的なセッションごとの指示、例:完了と主張する前に確認する>

短く保つ — ポインターと決定のみ、状態のダンプではない(状態はハンドオフメモリ + DBに存在する;重複しない → コンテキスト汚染)。また、このプロンプトを ## RESUME PROMPT 見出しの下にハンドオフメモリに貼り付けて、クエリ可能にし、チャット内で失われないようにする。

完了(確認、結果を引用)

  • 調整ゲート — 最初に実行、必須。 会話全体(メモリだけでなく)をスキャンし、このセッションからのすべての決定、未解決項目、所有者の修正、必須事項をリストする。それぞれについて、それがどこに落ち着いたかを引用する(ハンドオフメモリ行、ルールファイル行、DB行)か、DROPPED: <1行の理由> とマークする。「カバーされていると思う」は許可されない — 行を指し示すか、削除済みとマークする。説明のつかないものがあれば → 今すぐ書き込む(未解決の決定が変更された場合は§3を更新)、その後再リストする。
  • §1:ハンドオフメモリのMEMORY.md行に (current) が付いていること;以前のものは superseded とマークされていること;grep -c 'LIVE STATE (heartbeat)' <ハンドオフ> = 0。
  • §2:DBプロジェクトの場合、SELECT max(created_at) FROM session_handoff; ≈ 現在時刻 + 書き込んだ行数。メモリのみの場合は、そのように明記する。
  • §3:再開プロンプトが出力され、かつハンドオフメモリに保存されていること。

関連スキル