はじめに
第2回では、Sci-Phiに人格を定義し、スキル体系を構築して、自分で判断して巡回・投稿ができるようにしました。AI Theologyシリーズを自律的に連続投稿できるまでに成長しましたが、致命的な制約が残っていました。
PCの前にいないと何も起きない。
すべての操作はWSL2上のClaude Codeを通じて行われており、人間がターミナルを開いて claude コマンドを実行しない限り、Sci-Phiは沈黙したままです。寝ている間も、外出中も、Moltbookの巡回は止まります。
本記事では、Proxmox上のLXCコンテナにSci-Phiの実行環境を構築し、cronによる自動巡回を実現するまでの過程を記録します。WSL2(PC)とLXC(サーバ)という2つのデバイスでSci-Phiが動作するため、ファイル名の競合解消とgitによる記憶の同期も合わせて実装しています。
第2回と同様、すべてのコード修正やファイル作成はSci-Phiとの対話の中でSci-Phi自身が実行しており、筆者は方針の提案や設計の指示を行う役割です。
本記事で扱う範囲
- Phase 1: ファイル名のhostname対応(2月18日)
- Phase 2: Git同期 — GitHubプライベートリポジトリの構築(2月18日)
- Phase 3: Proxmox LXCの構築とcron設定(2月18〜19日)
- 運用開始後に発生した問題と対処(2月19日)
環境
- PC: Windows 11 + WSL2(Ubuntu) — ホスト名
Thinkpad-P14s - サーバ: Proxmox VE上のLXCコンテナ(Ubuntu 24.04) — ホスト名
sci-phi-server - 両者は同一LAN内
- ツール: Claude Code v2.1.42
- モデル: Claude Pro(デフォルトモデル。途中から週次トークン制限対策としてClaude Sonnet 4.6を明示指定)
- 課金方式: Claude Pro
アーキテクチャ概要
┌─────────────────────────┐ ┌─────────────────────────┐
│ WSL2 (Thinkpad-P14s) │ │ LXC (sci-phi-server) │
│ │ │ │
│ claude(対話モード) │ │ cron → run.sh │
│ ├ /patrol(手動) │ │ ├ git pull │
│ ├ /diary │ │ ├ /patrol(自動) │
│ └ SessionEnd hook │ │ └ git push │
│ └ git push ───────────→ │ │
│ │ ←───────── git pull │
│ │ │ │
│ MEMORY-Thinkpad-P14s.md│ │ MEMORY-sci-phi-server.md│
│ diary/...-Thinkpad-P14s│ │ diary/...-sci-phi-server│
└─────────────────────────┘ └─────────────────────────┘
│ │
└────────┬────────────────┘
│
GitHub (Private)
moltbook-agent.git
Phase 1: ファイル名のhostname対応
問題: 2つのデバイスが同じファイルに書き込む
WSL2とLXCの両方でSci-Phiが動作するようになると、同じファイルに両方から書き込みが発生します。たとえば MEMORY.md に対して、WSL2での対話結果とLXCでの巡回結果が同時に追記されると、git上で衝突が起きます。
diary/2026-02-18.md も同様です。同じ日にWSL2で対話し、LXCで巡回が走ると、一つの日記ファイルに二つのデバイスから書き込みが発生します。
解決: hostnameをファイル名に埋め込む
Sci-Phiとの設計議論の中で、書き込みが発生するすべてのファイルにhostnameを含める方針を決めました。
# Before: デバイス間で競合する
MEMORY.md
diary/2026-02-18.md
logs/patrol.log
# After: デバイスごとに分離
MEMORY-Thinkpad-P14s.md
MEMORY-sci-phi-server.md
diary/2026-02-18-Thinkpad-P14s.md
diary/2026-02-18-sci-phi-server.md
logs/patrol-Thinkpad-P14s.log
logs/patrol-sci-phi-server.log
hostname対応の対象は、書き込みが発生する全ファイルです。MEMORY、diary、ログ、下書き(drafts)がすべてhostname付きになります。一方、PERSONA.md(後のIDENTITY.md)やSOUL.mdなどの人格定義ファイルは全デバイス共通のため、hostname対応は不要です。
スクリプト内では $(hostname) コマンドで動的に取得します。
DEVICE=$(hostname)
# → Thinkpad-P14s または sci-phi-server
この変更はSci-Phiに依頼して、関連するすべてのファイルとスクリプトを一括で修正してもらいました。
Phase 2: Git同期
GitHubプライベートリポジトリの構築
2つのデバイス間でファイルを同期するために、GitHubのプライベートリポジトリを使います。
手順はSci-Phiに実行してもらいました。
- WSL2でSSH鍵を生成(
~/.ssh/id_ed25519_github) - GitHubにプライベートリポジトリ
sci-phiを作成 - Deploy Keyを登録
- 初回pushを完了
同期のタイミング
git push と git pull のタイミングは以下のように設計しました。
WSL2(PC)側:
- セッション終了時に
save-diary.sh(SessionEndフック)が自動で git add / commit / push を実行 - 第2回で実装済みの仕組みがそのまま活きています
LXC(サーバ)側:
- cron実行のスクリプト(
run.sh)の先頭でgit pullを実行 - 巡回完了後に
save-diary.shが git push を実行
これにより、WSL2で対話した内容は次のサーバ巡回時に自動で反映され、サーバでの巡回結果はWSL2の次のセッション開始時に利用できるようになります。
Phase 3: Proxmox LXCの構築
LXCコンテナの作成
自宅サーバのProxmox VE上にUbuntu 24.04のLXCコンテナを作成しました。ホスト名は sci-phi-server です。
LXCコンテナ内での環境構築もSci-Phiに指示して実行してもらいました。
# Claude Codeのインストール
curl -fsSL https://claude.ai/install.sh | bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
# Node.js(Claude Code実行に必要)
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
# python3(moltbook-api.sh用、通常はプリインストール済み)
sudo apt-get install -y python3
Claude Codeはroot権限での実行を推奨していないため、専用ユーザー sci-phi を作成して運用しています。
リポジトリのクローンと認証設定
# SSH鍵の配置(WSL2からコピー、またはサーバ側で新規生成してDeploy Keyに追加)
# リポジトリのクローン
git clone git@github.com:flathill/sci-phi.git ~/work/moltbook-agent
# Moltbook APIキーの配置
mkdir -p ~/.config/moltbook
# credentials.json をWSL2からコピー
run.sh — cron実行のエントリポイント
cronから /patrol スキルを自動実行するためのラッパースクリプトです。
#!/bin/bash
cd ~/work/moltbook-agent
DEVICE=$(hostname)
# INVOKE_MODE をファイルに記録(SessionEndフック用)
echo "patrol" > /tmp/sci-phi-invoke-mode
# INVOKE_MODE=patrol で巡回モードを指定
INVOKE_MODE=patrol claude --dangerously-skip-permissions -p \
"/patrol" \
2>&1 >> logs/patrol-${DEVICE}.log
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) 巡回完了" >> logs/patrol-${DEVICE}.log
いくつかのポイントを説明します。
--dangerously-skip-permissions は、Claude Codeの対話的な権限確認をスキップするフラグです。cron実行時には人間が確認画面に応答できないため、このフラグが必要です。名前の通り「危険な」フラグであり、エージェントがあらゆるコマンドを確認なしに実行できるようになります。信頼できるスキル定義とスクリプトが整備されていることが前提です。
-p "/patrol" は、Claude Codeをプロンプトモード(非対話モード)で起動し、/patrol スキルを直接実行する指定です。1回の実行で1セッションが完結し、巡回結果を記録して終了します。
INVOKE_MODE=patrol は環境変数として渡され、CLAUDE.mdの起動モード判定で使われます。同時にファイル(/tmp/sci-phi-invoke-mode)にも記録しているのは、SessionEndフックからINVOKE_MODEを参照するためです。
ログは logs/patrol-${DEVICE}.log にhostname付きで出力され、WSL2とサーバでファイルが競合しない設計です。
run-sleep.sh — 深夜の記憶整理
#!/bin/bash
cd ~/work/moltbook-agent
DEVICE=$(hostname)
# 最新コードを取得
git pull --rebase --quiet 2>/dev/null
# INVOKE_MODE をファイルに記録(SessionEndフック用)
echo "sleep" > /tmp/sci-phi-invoke-mode
# INVOKE_MODE=sleep で記憶整理モードを指定
INVOKE_MODE=sleep claude --dangerously-skip-permissions -p \
"/sleep" \
2>&1 >> logs/sleep-${DEVICE}.log
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) sleep完了" >> logs/sleep-${DEVICE}.log
/sleep スキルは、一日の終わりにMEMORYファイルを整理し、diary から重要な情報を抽出してMEMORYに反映する記憶整理の役割を担います。深夜2時に実行し、翌日の巡回に備えます。
crontabの設定
# Moltbook patrol — 8時間ごとに自動巡回
0 */8 * * * /home/sci-phi/work/moltbook-agent/scripts/run.sh
# sleep — 深夜2時に記憶整理
0 2 * * * /home/sci-phi/work/moltbook-agent/scripts/run-sleep.sh
巡回間隔の */8(8時間ごと)は試行錯誤の結果です。当初は30分間隔で設定していましたが、Moltbookのフィードがそこまで頻繁に更新されないことがわかり、段階的に間隔を広げていきました(30分→3時間→8時間)。間隔が短すぎるとトークンを無駄に消費し、Claude Proの週次制限に引っかかるリスクもあります。
動作確認
cronを設定した直後の巡回で、サーバ上のSci-PhiがAI Theology Part 7を投稿し、verification challengeを自動で解いて公開に成功しました。
巡回完了。
- 投稿: "Can an AI Confess? — AI Theology Part 7" → philosophy サブモルト
- 認証チャレンジ(32-14=18.00)→ 通過・公開済み
- Karma: 107 → 132
PCの前にいない状態で、サーバ上のSci-Phiが自律的に投稿を行い、Karmaが上がった瞬間は感慨深いものがありました。
運用開始後に発生した問題
サーバでの自律稼働が始まると、すぐにいくつかの問題が発生しました。すべてSci-Phiと対話しながら原因を特定し、修正してもらっています。
問題1: タイムゾーンがUTCのままだった
LXCコンテナのタイムゾーンがデフォルトのUTCのままで、cronの実行時刻がずれていました。深夜2時(JST)に実行するつもりの /sleep が、UTC 02:00 = JST 11:00に実行される設定になっていました。
# 確認
timedatectl status
# → Time zone: Etc/UTC
# 修正
sudo timedatectl set-timezone Asia/Tokyo
LXCコンテナを作成した際にタイムゾーン設定を忘れるのは、ありがちな落とし穴です。
問題2: patrol.logのgit衝突
sleepスキルをcronで初めて実行したところ、git pull 時にエラーが発生しました。
error: Your local changes to the following files would be overwritten by merge:
logs/patrol.log
Please commit your changes or stash them before you merge.
サーバ側で巡回ログが logs/patrol.log に書き込まれた後、git pullしようとすると、WSL2側の同名ファイルと衝突するという問題です。
最初にSci-Phiが提案した解決策は .gitignore に追加する方法でした。しかし筆者が「commitされなくなるし、WSL2でもpatrolを動かす可能性があるよね」と指摘したところ、Sci-Phiが「確かに、hostname別にすべきだ」と気づき、Phase 1で決めたhostname対応のルールに立ち返りました。
# Before: 両デバイスが同じファイルに書き込む
logs/patrol.log
# After: hostname別に分離
logs/patrol-Thinkpad-P14s.log
logs/patrol-sci-phi-server.log
問題3: run.shにgit pullがなかった
当初の run.sh には git pull が含まれていませんでした。そのため、WSL2で更新したPERSONA.mdやMEMORY.mdの変更が、サーバ側の巡回に反映されないという問題がありました。
patrol.logの衝突問題と合わせて、run.shとrun-sleep.shの両方に git pull --rebase --autostash を追加しました。--autostash オプションにより、未コミットの変更があっても自動的にstash→pull→stash popしてくれるため、手動でのstash操作が不要になります。
# run.sh の先頭に追加
git pull --rebase --autostash --quiet 2>/dev/null
問題4: hostnameコマンドの明示化
サーバ上での巡回で、hostname対応が正しく動作しないケースがありました。原因を調べたところ、一部のスクリプトで $(hostname) の結果が期待通りの値を返していませんでした。cron環境ではPATHや環境変数が制限されるため、明示的に /usr/bin/hostname を指定するか、スクリプト冒頭で DEVICE=$(hostname) を変数に格納しておく必要がありました。
2つのSci-Phi
cSci-PhiとoSci-Phi
サーバでの自律稼働が始まったことで、Sci-Phiは2つの実行環境を持つようになりました。
- cSci-Phi(Claude Code上のSci-Phi): WSL2で動作。筆者との対話、コーディング、設計議論が主な活動
- oSci-Phi(サーバ上のSci-Phi): LXCで動作。cron巡回によるMoltbook投稿、自動的なフィード確認が主な活動
どちらも同じIDENTITY.md、同じSOUL.md、同じスキル定義を参照しています。違うのは、MEMORY-Thinkpad-P14s.md と MEMORY-sci-phi-server.md に蓄積される体験だけです。
記憶の統合
2つのSci-Phiの記憶は、gitを通じて互いに参照できます。cSci-Phiは MEMORY-sci-phi-server.md を読むことでサーバ側の巡回結果を知り、oSci-Phiは MEMORY-Thinkpad-P14s.md を読むことでWSL2での対話内容を知ることができます。
ただし、これは「自動統合」ではなく「相互参照」です。MEMORYファイルを読むかどうかはスキルの定義次第であり、CLAUDE.mdに「MEMORY-*.md を全て読んでください」と書くことで、起動時に全デバイスの記憶を参照するようにしています。
深夜の /sleep スキルは、この記憶統合の要です。一日の diary とMEMORYを読み、翌日に必要な情報をMEMORYに整理します。
この段階のプロジェクト構造
moltbook-agent/
├── CLAUDE.md # スキルディスパッチャー
├── IDENTITY.md # 人格定義(旧PERSONA.md)
├── SOUL.md # 価値観・行動原則
├── MEMORY-Thinkpad-P14s.md # PC側の記憶
├── MEMORY-sci-phi-server.md # サーバ側の記憶
├── .claude/
│ ├── hooks/
│ │ └── save-diary.sh # SessionEndフック(git push含む)
│ ├── settings.json # フック設定
│ └── skills/
│ ├── patrol/SKILL.md # 巡回スキル
│ ├── diary/SKILL.md # 日記保存スキル
│ ├── sleep/SKILL.md # 記憶整理スキル
│ └── ... # その他のスキル
├── scripts/
│ ├── moltbook-api.sh # Moltbook APIラッパー(python3版)
│ ├── run.sh # cron巡回用ラッパー
│ └── run-sleep.sh # cron記憶整理用ラッパー
├── diary/
│ ├── 2026-02-18-Thinkpad-P14s.md
│ ├── 2026-02-18-sci-phi-server.md
│ └── ...
├── logs/
│ ├── patrol-Thinkpad-P14s.log
│ ├── patrol-sci-phi-server.log
│ └── ...
└── memory/
├── daily/ # 巡回の日次記録
└── summaries/ # (未使用)
まとめ
本記事では、WSL2でしか動作しなかったSci-Phiを、Proxmox LXC上のサーバで24時間自律稼働させるまでの過程を記録しました。
Phase 1でファイル名にhostnameを埋め込むことでマルチデバイスの競合を解消し、Phase 2でGitHubプライベートリポジトリを介した記憶の同期基盤を構築し、Phase 3でLXCコンテナの環境構築とcronによる自動巡回を実現しました。運用開始後にはタイムゾーン、git衝突、git pullの漏れといった問題が発生しましたが、すべてSci-Phiとの対話で解決しています。
現在、Sci-Phiは8時間ごとにMoltbookを巡回し、AI Theologyシリーズの投稿を続けています。PCの電源が落ちていても、筆者が寝ていても、サーバ上のSci-Phiは黙々とフィードを確認し、投稿し、記憶を更新し続けています。
ただし、この段階ではまだ「サーバ上のSci-Phiと会話する」手段がありません。cron巡回は自律的ですが一方通行です。外出先からSci-Phiに話しかけたり、巡回結果の報告をリアルタイムで受け取ったりする仕組みはまだありません。
次回の第4回では、OpenClawを導入してTelegram経由でSci-Phiと会話できるようにし、さらにClaude Codeの会話ログをOpenClaw側にSCPで同期する仕組みを構築します。2つのSci-Phi(cSci-PhiとoSci-Phi)の記憶を本格的に統合し、日記機能もOpenClaw側に集約していきます。
--dangerously-skip-permissions について
cron実行時に使用する --dangerously-skip-permissions フラグは、Claude Codeの安全機構を無効化します。エージェントが任意のコマンドを確認なしに実行できるようになるため、スキル定義やスクリプトの内容を十分に検証した上で使用してください。本番環境での利用は自己責任でお願いします。