﻿# HANDOVER — このワークスペースを初期化する手順（Claude Code が読む）

<!-- claude-workspace-template v1.0.3（2026-09-02） -->

**読者は Claude Code。** 利用者が「`HANDOVER.md` を読んで、書いてあるとおりに初期化して」と頼んだセッションで読む。
人向けの説明は配布元の解説ページにある（利用者はそれを読んでここに来ている）。

この手順は**共通部（1〜7章）**と、末尾の**クラウド版の補足**・**デスクトップ版の補足**からなる。
1章で判定した側の補足だけ読めばよい。

**進め方の原則:**

- **利用者に確認を求めるのは「人にしかできないこと」だけ**（画面操作・鍵の作成・方針の選択）。手順は黙って進め、終わりにまとめて報告する。
- **途中で失敗したら、推測で先へ進まない。** どこで止まったかと、何ができなかったかを報告して終わる。
- **利用者は専門家ではない前提で報告する。** 用語は日常語の説明を添え、利用者がやることは番号付きで短く書く。

## 0. これは何か（30秒）

このテンプレートは「会話の記憶が続く Claude Code の個人ワークスペース」の雛形です。中身は:

| 区分 | ファイル | 役割 |
| --- | --- | --- |
| 必須 | `CLAUDE.md` | 毎セッション読まれるルールブック |
| 必須 | `.claude/settings.json` `.claude/hooks/session-start.sh` `.claude/hooks/record-check.py` | 記憶の自動読み込み（SessionStart）と記録漏れの検知（Stop） |
| 必須 | `memory/` `research/` | 記憶の置き場（索引2枚は毎セッション注入） |
| 必須 | `tools/index-health.py` `tools/index-tidy.md` `tools/index-tidy.log` | 索引の点検と棚卸しの手順 |
| 必須 | `.gitattributes` `.gitignore` | 改行コードの固定と、一時ファイル・平文の誤コミット防止 |
| 任意 | `.mcp.json.example` | 外部サービス接続（MCP）の雛形 |
| 任意 | `tools/setup-script.sh` | クラウド版の導入物の一覧（環境ダイアログに貼る写し） |
| 任意 | `memory/private/` `tools/private-notes.sh` | 非公開メモ（暗号化した記録） |
| 任意 | `tools/make-standalone.py` | デスクトップ版でレポートをブラウザで開くための包み |

**この手順が終わると**: 次に開いた新しいセッションから、索引2枚が自動で読み込まれ、記録を忘れると終了時に確認が入る。

## 1. 環境を判定する（共通）

次を実行して、結果を控える（報告に使う）:

```
pwd; git rev-parse --show-toplevel 2>&1; ls -a
echo "REMOTE=${CLAUDE_CODE_REMOTE_SESSION_ID:-}"; echo "PROJECT_DIR=${CLAUDE_PROJECT_DIR:-}"
python3 --version; git --version; command -v jq || echo "jq: なし(不要)"
git remote -v; git branch --show-current
```

| 見るもの | 判定 |
| --- | --- |
| `CLAUDE_CODE_REMOTE_SESSION_ID` が入っている | **クラウド版**（claude.ai/code）。末尾の「クラウド版の補足」を読む |
| 入っていない | **デスクトップ版**（CLI／VS Code拡張）。「デスクトップ版の補足」を読む |
| `pwd` がリポジトリの中（`git rev-parse --show-toplevel` が成功する） | 通常。フックは動く |
| `pwd` がリポジトリの**親**で、複数のリポジトリが並んでいる | **複数リポジトリのセッション。フックは動かない。** 初期化は続けてよいが、5章の動作確認は「このリポジトリだけを選んだ新しいセッション」でやるよう利用者に伝える |
| `python3` が無い | 止まる。フックと点検は python3 に依存する（`jq` は無くてよい） |
| `git rev-parse --show-toplevel` が失敗する（Git 管理されていないフォルダ） | デスクトップ版でありうる。`git init -b main` してから続ける（手元だけの運用でも履歴は要る） |
| `git remote -v` が空 | **リモート無し**の運用（デスクトップ版。GitHub にもオンプレミスの Git サーバにも置かない）。push の手順を省き、6章でバックアップを勧める |

## 2. ファイルの配置を確かめる（共通）

期待するファイルは0章の表のとおり。`ls -a` と `ls .claude/hooks tools memory research` で確かめ、次のどれかに当たる:

- **(a) 揃っている**（利用者が zip を展開してコミット済み） → 3章へ。
- **(b) zip がある**（チャットに添付されている＝クラウド版なら `/mnt/user-data/uploads/*.zip`、
  またはリポジトリ直下にアップロードされている）→ 中身を確かめてから展開する:

      unzip -l <zip> | head -20            # ルート直下に CLAUDE.md と .claude/ があること
      unzip -o <zip> -d "$(git rev-parse --show-toplevel)"
      # リポジトリ直下に置かれていた zip は展開後に消す:  git rm -q <zip>

- **(c) どちらでもない** → 利用者に「配布元から zip をダウンロードして、このチャットに添付するか、リポジトリに展開してください」と頼んで止まる。

揃ったら整える:

```
chmod +x .claude/hooks/session-start.sh .claude/hooks/record-check.py tools/*.py tools/*.sh
grep -rl $'\r' .claude tools CLAUDE.md memory research 2>/dev/null || echo "CRLFなし"   # 何も出なければ正常
git add -A && git status --short | head
```

CRLF のファイルが出たら `sed -i 's/\r$//' <ファイル>` で直す（Windows側で展開すると混入することがある）。

## 3. 個人化する（共通・利用者に聞くのは1回だけ）

次の3点を**1つのメッセージで**聞く。既定値を示し、「全部そのままで」と答えられるようにする:

1. **ワークスペースの名前** — `CLAUDE.md` の1行目の見出し。既定はリポジトリ名。
2. **個人情報を記録に書いてよいか** — 既定は「リポジトリが private なら書いてよい」（`CLAUDE.md`「注意事項」）。
   「書かない」なら、その節を「住所・勤務先などの個人情報は書かない。必要なら伏せ字にする」に書き換える。
3. **コネクタの線引き** — 既定は `CLAUDE.md`「コネクタ」の表（メールは下書きまで・カレンダーは読み取りのみ・タスクは印付きで読み書き）。
   接続する予定が無ければそのままでよい。

答えを受けたら反映する:

- `CLAUDE.md` の見出し（`# claude-workspace`）を名前に置き換える。
- `memory/ACCURACY-LOG.md` の `最終見直し: 2026-09-02` を**今日の日付**にする（90日タイマーの起点）。
- `memory/REPOS.md` の1行目の `（このワークスペース）` をリポジトリ名にする。
- 2・3で既定から変えた場合は該当節を書き換える。

## 4. 動かして確かめる（共通）

**このセッションではフックはまだ効いていない**（`.claude/settings.json` はセッション開始時に読まれる）。
だから手で実行して確かめる:

```
bash -n .claude/hooks/session-start.sh && python3 -m py_compile .claude/hooks/record-check.py tools/index-health.py && echo "構文OK"
python3 -c 'import json; json.load(open(".claude/settings.json")); print("settings.json OK")'
printf '{"session_id":"handover-test"}' | CLAUDE_PROJECT_DIR="$(pwd)" .claude/hooks/session-start.sh \
  | python3 -c 'import json,sys; c=json.load(sys.stdin)["hookSpecificOutput"]["additionalContext"]; print(len(c),"字を注入"); print(c[:300])'
ls .claude/state/            # handover-test.base と notes-chars ができている
rm -f .claude/state/handover-test.base
python3 tools/index-health.py    # 「INDEX健全性: 問題なし(…)」が出ること
echo '{}' | .claude/hooks/record-check.py; echo "record-check exit=$?"   # 0 であること(判断材料が無いので黙って通る)
```

期待どおりでなければ、原因を調べて直してから先へ進む（直せなければ報告して止まる）。
よくある原因: 実行権限が無い／CRLF／`python3` が無い。リモートが無くても問題ない（遅れ検知は何もせずに続行する）。

## 5. 最初の記録とコミット（共通）

1. `memory/YYYY-MM-DD-setup.md` を作る（今日の日付）。内容: テンプレートの版、判定した環境、3章で決めたこと、
   有効化していない任意モジュール、利用者にやってもらうこと（6章）。
2. `memory/INDEX.md` の表に1行足す: `| YYYY-MM-DD | このワークスペースを初期化した（テンプレート v1.0.3） | [詳細](YYYY-MM-DD-setup.md) |`
3. `git mv HANDOVER.md tools/HANDOVER.md`（初期化後の置き場。`CLAUDE.md` はこの場所を指している）。
4. コミットする。メッセージは `初期化: claude-workspace-template v1.0.3 を導入`。
   - クラウド版: ハーネスが指定した作業ブランチでコミット → `CLAUDE.md`「運用ルール」の手順で `main` にマージして push。
   - デスクトップ版: 最初のコミットは `main` に直接でよい。以後はブランチを切る（補足を参照）。リモートがあれば push する
     （リモート名や既定ブランチ名が `origin` `main` でなければ読み替える）。
   - **リモートが無い**（`git remote -v` が空）場合は、コミットだけで終わる。push は要らない。6章の報告にバックアップの取り方を含める。

## 6. 利用者にやってもらうこと（報告に含める）

報告は「できたこと」「利用者がやること（番号付き）」「任意で後から足せること」の3つに分ける。

**利用者がやること（クラウド版）:**

1. claude.ai/code の環境（Environment）の設定を開き、**Setup script 欄に `tools/setup-script.sh` の中身を貼る**
   （PDF や Office ファイルを読むための道具。無くても記憶の仕組みは動く）。
2. **新しいセッションを開いて「私の記憶には何がある？」と聞く。** 索引の内容（初期化の記録1行）が返れば成功。
   返らなければ、その旨をこのワークスペースの次のセッションに伝える（フックが走らない原因を調べる）。
3. 外部サービスのキーを使うときは、同じ画面の Environment variables 欄に `KEY=value` で登録する（次のセッションから有効）。

**利用者がやること（デスクトップ版）:**

1. 必要な道具を入れる（PDFを読むなら `poppler-utils`、Office ファイルなら `pip install openpyxl python-docx python-pptx`）。
2. リポジトリのフォルダで新しいセッションを開き（`claude`、または VS Code で開く）、「私の記憶には何がある？」と聞く。
3. **置き場を決める。** GitHub やオンプレミスの Git サーバ（Gitea・GitLab など）に置くなら `git remote add origin <URL>` → `git push -u origin main`。
   **手元だけで使う（どこにも送らない）なら、フォルダごと定期的にバックアップする**——記録がすべてこのフォルダにある
   （例: `git bundle create <保存先>/workspace.bundle --all`。丸ごとの複製でもよい）。

**任意で後から足せること**（頼まれたら7章）: 外部サービス接続（MCP）／コネクタ／棚卸しの自動実行（Routine・クラウド版のみ）／
非公開メモ（暗号化した記録）／他リポジトリの台帳。

## 7. 任意モジュールの有効化（頼まれたときに読む）

### 7-1. 外部サービス接続（MCP）

1. `cp .mcp.json.example .mcp.json` して、使うサーバーだけ残す。キーは `${環境変数名}` の参照で書く（値は書かない）。
2. 利用者にキーを環境変数へ登録してもらう（クラウド版は環境ダイアログ、デスクトップ版は補足のとおり）。
3. 次のセッションで、そのサーバーのツールが使えることを確かめる（未設定なら `${…}` が未展開のまま接続に失敗し、警告が出る）。
4. `CLAUDE.md`「APIキーと環境変数」に、変数名・サービス名・認証方式を1行足す（値は書かない）。

### 7-2. コネクタ（Gmail・カレンダー・タスク管理など）

1. 利用者が claude.ai の 設定 → コネクタ で接続する（画面操作）。
2. 線引きを `CLAUDE.md`「コネクタ」の表に書く。**最初は読み取り専用から始め、書き込みは1つずつ解禁する**のを勧める。
3. 書き込みを許可するときは「印」（ラベルとフッタ）の形を同じ節に書く。

### 7-3. 棚卸しの自動実行（Routine・クラウド版のみ）

`tools/index-tidy.md` の冒頭に理由があるとおり、**「毎回新しいセッションを立てる」Routine ではリポジトリが渡らない。**
次の順で組む（claude-code-remote MCP のツール）:

1. `create_session` で専用セッションを作る: `source_url` にこのリポジトリのURL、`title` は「INDEX棚卸しワーカー」、
   `prompt` は「このセッションは週次の棚卸し専用です。指示が来るまで待機してください。」
2. `create_trigger` で発火を作る: `persistent_session_id` に1のセッションID、`cron_expression` は `0 22 * * 0`（月曜07:00 JST）、
   `name` は「INDEX棚卸し（週次・閾値超過時のみ）」、`prompt` は
   「週次の棚卸しの時間です。`git fetch origin main` で追随してから `tools/index-tidy.md` を読み、そのとおりに実行してください。
   何もしない場合も `tools/index-tidy.log` に1行残して push してください。」
3. 返ってきた `trig_…` と `session_…` を `tools/index-tidy.md` の冒頭の表に書き、コミットする。
4. 利用者に伝える: 完了通知は付けられない（サーバが拒否する）ので、実行の記録は `tools/index-tidy.log` の行と
   `git log --grep='^自動棚卸し'` で見ること。**ログに行が無い週は「到達できなかった」を意味する。**

### 7-4. 非公開メモ（暗号化した記録）

手順の正は `memory/private/README.md`。要点:

1. **利用者が手元PCで鍵ペアを作る**（`age-keygen`。秘密鍵は利用者しか持たない）。公開鍵 `age1…` だけを受け取る。
2. `memory/private/recipients.txt` に公開鍵を1行で置き、空の索引 `INDEX.md.age` を暗号化して置く（READMEの手順）。
3. 利用者が秘密鍵を登録する: クラウド版は環境変数 `PRIVATE_NOTES_AGE_KEY`、デスクトップ版は `~/.config/age/` の鍵ファイル。
4. 次のセッションで索引の復号を実測して「読み」を確認し、`memory/private/README.md` の「状態」を稼働中に書き換える。
5. `CLAUDE.md`「非公開メモ」の「未設定の間」の行を消す。

### 7-5. 他リポジトリの台帳

コードを別リポジトリで扱い始めたら `memory/REPOS.md` に1行足す。複数リポジトリを1つのセッションに入れると
フックが動かないことを、そのセッションの最初に思い出す（`CLAUDE.md`「他リポジトリの開発」）。

---

## クラウド版（claude.ai/code）の補足

- **環境ダイアログ**（claude.ai/code → 環境の設定）に2つの欄がある。**Setup script** は新しいセッションの開始前に root で走る導入コマンド
  （写しは `tools/setup-script.sh`。編集したら両方直す。環境キャッシュがあるとスキップされる）。**Environment variables** は
  `KEY=value` 形式の秘密の置き場（次のセッションから有効）。**どちらも画面操作なので利用者にしかできない。**
- **ネットワーク**は環境のポリシーに従う。外向きの取得は `curl` を第一手にする。
- **Artifact**: `report.html` を公開する手段。公開したらURLをテーマREADMEに書く（`research/INDEX.md` には書かない）。
- **作業ブランチ**はハーネスが指定する。`main` へは PR を使わずローカルでマージして push（`CLAUDE.md`「運用ルール」）。
  マージ済みブランチは消せない（プロキシが403で弾く）ので放置する。
- **添付ファイル**は `/mnt/user-data/uploads/` に着地する。
- **複数リポジトリのセッションではフックが動かない**（1章）。記憶の注入・記録の確認を自分でやる。
- **Routine** は7-3のとおり。

## デスクトップ版（CLI・VS Code拡張）の補足

- **前提**: Claude Code の CLI（`claude`）か VS Code 拡張、`git`、`python3`。`jq` は不要。
- **リモートは任意**: GitHub でなくてよい。オンプレミスの Gitea や GitLab などの Git サーバでも、リモート無し（手元だけ）でもよい。
  フックの遅れ検知は `main` の追跡先（無ければ最初のリモート）を見るので、リモート名が `origin` でなくても動き、
  リモートが無ければ何もしない。`CLAUDE.md`「運用ルール」の fetch／push の行は環境に合わせて読み替える（無ければ省く）。
- **WSL** なら、リポジトリは ext4 側（`~/` 配下）に置く。`/mnt/c` に置くと極端に遅く、実行ビットも保持されないのでフックが動かない。
- **改行コード**: `.gitattributes` で LF に固定してある。Windows 側のエディタでフックを編集しない。
- **環境変数**: シェルの設定（`~/.bashrc` 等）に `export KEY=value` を書くか、`.claude/settings.local.json`（`.gitignore` 済み）に
  `{"env": {"KEY": "value"}}` を置く（後者は Claude Code の設定機能。本家では未使用）。**リポジトリに追跡されるファイルには書かない。**
- **導入物**: `tools/setup-script.sh` の中身を参考に、必要なものだけ手で入れる（`sudo apt install poppler-utils age` など）。
- **Artifact が無い**: レポートは `python3 tools/make-standalone.py research/<slug>/report.html` で包んでブラウザで開く。
  READMEには `report.html（ローカル閲覧）` と書く（`tools/index-health.py` はこの語を公開済みとみなす）。
- **Routine が無い**: 棚卸しは、フックの警告を見たセッションで「`tools/index-tidy.md` の手順で棚卸しして」と頼む。
- **作業ブランチ**: セッションの最初に `git checkout -b claude/$(date +%Y%m%d)-<短い説明>` を切り、終わりに
  `git checkout main && git merge --no-ff <ブランチ>` で戻す（`git log --first-parent main` がセッション一覧になる）。
- **クラウドのセッションを PC に引き継ぐ**: `claude --teleport <セッションID>`（同一アカウント・同じリポジトリ・作業ツリーがクリーン・
  ブランチが push 済みが前提）。逆方向は不可。
- **本家での検証状況**: フック・点検・棚卸し・非公開メモはクラウド版で運用して確認したもの。デスクトップ版は WSL で動く前提で
  設計してある（`jq` 不要・LF固定はそのため）が、Routine の代替（OSのスケジューラから `claude -p`）は未検証。
