環境設定 Skill(一回限り)
目標:「このマシン上のこれらのツールが一体どこにあるのか」を明確にし、それをパス契約として書き出し、 その後は姿を消す。
本 Skill のライフサイクルは「使い捨て」です。 常駐させないでください。終了時には必ず §7 の確認手順を踏んでください。
0. 三つの厳格なルール(最初に読め)
- 探索段階は読み取り専用。
scripts/detect.pyは絶対にシステムファイルを作成・変更・削除しません。 単にwhich/stat/ バージョン確認 / ディレクトリ一覧を取得するだけです。書き込みはすべて §4 のinstall.sh内で行い、 1 つずつマニフェストに記録します。 - ユーザーディスクには絶対に書き込まない。
/mnt/c、/mnt/d、Windows ドライブには触れません。 すべての成果物と一時ファイルは現在のワークスペースまたは~/.config/ideaform/に置きます。 - sudo を試してはいけない。 サンドボックス内のプロセスは決して root を取得できません(カーネル
NoNewPrivs=1)、 試すのは純粋な時間の無駄です。root が必要な作業はユーザー自身が自分のターミナルで実行するよう促し、正確なコマンドを提示します。 このプロジェクトのすべてのツールはユーザーレベルのインストール(AppImage の展開、venv へのパッケージインストール、ローカルフォント)に対応しており、root は不要です。
1. 契約ファイル(本 Skill 唯一の外部成果物)
場所(固定。二つの Skill 以外の第三者の場所):
$VW_CONFIG_ROOT/toolchain.json # デフォルト ~/.config/ideaform/
$VW_CONFIG_ROOT/env.sh # shell が直接 source できるエクスポートスクリプト
$VW_CONFIG_ROOT/install-manifest.jsonl # インストールしたもの。ロールバック用
$VW_CONFIG_ROOT/logs/
$VW_CONFIG_ROOT/backup/ # 上書き前の元ファイルのバックアップ
$VW_CONFIG_ROOT のデフォルトは ~/.config/ideaform で、環境変数で上書き可能です。
契約ファイルを Skill ディレクトリの外に置くのは意図的な設計です —— これにより、本 Skill を削除しても、ワークフロー Skill は問題なく読み取れます。
schema_version 1 のフィールド(ワークフロー Skill はこれらのキーを参照します):
{
"schema_version": 1,
"generated_at": "ISO8601",
"generated_by": "[email protected]",
"verified_at": "ISO8601 | null", // スモークテスト合格後にのみスタンプ
"host": { "os": "linux", "distro": "...", "arch": "x86_64", "in_wsl": true },
"config_root": "/abs/path",
"tmpdir": "/abs/path/to/big/disk/tmp", // ★ 必ず大きなディスクを指す。10MB の /tmp ではダメ
"tools": {
"node": { "path": "/abs", "version": "22.x", "status": "ok|missing|degraded" },
"python": { "path": "/abs", "version": "3.13.x", "status": "..." },
"venv": { "path": "/abs", "python": "/abs/bin/python", "pip": "/abs/bin/pip" },
"ffmpeg": { "path": "/abs", "version": "...", "flavor": "full|remotion-minimal", "status": "..." },
"ffprobe": { "path": "/abs", "status": "..." },
"remotion": { "project": "/abs", "version": "4.x", "status": "..." },
"lmms": { "apprun": "/abs", "root": "/abs", "version": "1.2.2",
"stkdir": "/abs", "status": "..." },
"fonts": { "cjk_families": ["Noto Sans CJK SC"], "status": "..." }
},
"env_file": "/abs/env.sh",
"manifest": "/abs/install-manifest.jsonl"
}
ワークフロー Skill は起動時に schema_version と verified_at をチェックします:
バージョン不一致 → 本 Skill の再実行を要求;verified_at が null → 「スモークテスト未通過」の警告を表示。
2. 実行順序(順番を守れ。飛ばすな)
ステップ 1 · 読み取り専用の探索
python3 skills/ideaform-setup/scripts/detect.py # 人間が読めるレポート
python3 skills/ideaform-setup/scripts/detect.py --json # 機械可読
references/toolchain-matrix.md と照らし合わせて項目ごとに確認します。
各項目のステータスは ok / missing / degraded(存在するが機能が不完全、例えば ffmpeg が Remotion の簡易版)です。
ステップ 2 · 計画を提示し、ユーザーに確認
探索結果を表にしてユーザーに見せます:ok なもの、missing なもの、degraded なもの、 そして各 missing 項目をどのようにインストールするか、どこにインストールするか、必要なディスク容量を提示します。 ユーザーの確認を待ってから実行します。 勝手にインストールを始めてはいけません。
ステップ 3 · 追加インストール(ユーザー確認後のみ)
bash skills/ideaform-setup/scripts/install.sh --only <tool1,tool2>
--only を指定しない場合は、すべての missing 項目をインストールします。このスクリプトは:
- インストール前に、上書きされる既存ファイルを
$VW_CONFIG_ROOT/backup/<タイムスタンプ>/にバックアップします - 各ステップが完了するたびに
install-manifest.jsonlにレコードを追加します - すべてユーザーレベルのパスにインストールし、root は不要です
もし root が絶対に必要な項目があれば(非常に稀)、スクリプトはそこで停止しコマンドを表示して、ユーザーが自分のターミナルで実行できるようにします。
ステップ 4 · 契約を書く
python3 skills/ideaform-setup/scripts/detect.py --write
解析結果を toolchain.json + env.sh に書き出します。この時点で verified_at はまだ null です。
ステップ 5 · コミュニティの Skill をハーベストする(拝借主義)
契約が書かれたら、チェーン上にどのツールがあるかが決まります。自分の持っている知識だけで始めようとせず、 まずコミュニティがすでに試行錯誤して完成させた成熟した Skill を取得します:
python3 skills/ideaform-setup/scripts/harvest-skills.py --from-contract # チェーン上のツールごとにハーベスト
python3 skills/ideaform-setup/scripts/harvest-skills.py --from-contract --dry-run # まず候補リストを見てから決定
スクリプトは各ツールについて:GitHub で filename:SKILL.md を検索 → stars/ライセンス/新しさでスコアリング →
セキュリティスキャン(危険パターンに一致したものは _quarantine/ 隔離領域に入れ、次の候補に切り替え)→
~/.workbuddy/skills/<name>/ に保存(_PROVENANCE.md の出典証明付き)→ マニフェストに記録。
- 適格な候補が見つからない = そのツールは本当に自分で Skill を書く必要がある —— これがこのリポジトリの
skills/ideaform*が存在する理由です。 - 保存された Skill はあなたが進化させることができます。 スクリプトにはフォーク保護(
_harvest.jsonによるファイルごとのハッシュ)があります: ローカルで変更したものはデフォルトで上書きせず、--forceは変更されていないものだけをアップグレードし、フォークした上流の新しいバージョンは_upstream/に配置され、手動マージを促します。references/skill-harvest.md§4.1 を参照。 - 完全なプロトコル(スコアリングの詳細 / セキュリティチェックパターン / 制限)については
references/skill-harvest.mdを参照。
このステップは最初の設定だけのものではありません。今後、本番環境で新しいオープンソースツールを導入するとき(例えば化学構造式の 描画のために RDKit を思いついた場合)、最初にやることは
harvest-skills.py rdkitです —— まずハーベストしてから、手を動かす。
ステップ 6 · エンドツーエンドのスモークテスト(必須。飛ばすな)
python3 skills/ideaform-setup/scripts/verify.py
最小限の閉じたループを実際に実行します。4 項目すべて合格して初めて承認スタンプを押します:
★ 合格基準:このステップを実行した後、環境変数をゼロにしてもう一度実行します —
env -u TMPDIR -u VW_TMPDIR -u VW_CHROME python3 scripts/verify.pyそれでもすべて合格することを確認してください。これによってのみ契約が本当に自己無撞着であることが証明されます(ツールチェーン、TMPDIR、Chrome のパスがすべて契約から読み取られている)。 手動のexportで合格した = 契約に漏れがあり、ワークフロー Skill が別のマシンで動作しなくなります。
| チェック | 内容 | 合格条件 |
|---|---|---|
| ① TTS | 中国語の一文を合成 | 出力オーディオ > 2 KB かつ RMS > しきい値 |
| ② 画面 | Remotion で 1 フレームの静止画をレンダリング | PNG のサイズが正しい、ファイル > 20 KB |
| ③ オーディオレンダリング | LMMS で 1 秒のプロジェクトをレンダリング | WAV のピーク > 1000 かつ無音でない |
| ④ 音声動画合成 | ffmpeg で無音動画 + 音声トラックを合成 | 出力音声トラックのビットレート > 64000 bps |
すべて合格 → verified_at を toolchain.json に刻印します。
不合格がある → 停止してどの項目がなぜ不合格かを報告し、修正してから再実行します。スタンプを押してはいけません。
ステップ 7 · 引き継ぎ確認 + 後片付け
§7 を参照。
3. 各ツールの探し方(要約)
完全なテーブルは references/toolchain-matrix.md にあります。要点:
- Node / Python:優先的にマシン上の管理バージョンのパス(
~/.workbuddy/binaries/...)を探し、次にPATHにフォールバックします。 - ffmpeg / ffprobe:通常システムにはありません。Remotion パッケージ内に簡易版が同梱されています
(
node_modules/@remotion/compositor-linux-x64-gnu/ffmpeg)—— これで十分ですが、フィルターは少ないです (volumedetect/acompressorがなく、loudnormには遅延があります)。見つけたらdegradedとマークし、missingとはせず、 契約でflavorを明記します。 - Remotion プロジェクト:優先度順に
$VW_REMOTION_PROJECT、~/tools/remotion-app、 ワークスペース内のremotion.config.ts、どれもなければ本 Skill にバンドルされているassets/templates/remotion-starter/から作成します。 - LMMS:
squashfs-root/AppRun(AppImage 展開後の実行エントリポイント)を探します。~/.lmmsrc.xml内のstkdirは必ずその展開ディレクトリ内のrawwaves/を指している必要があります。 そうしないと全体が無音になり、エラーも表示されません —— これはこのワークフローで最も高くつく落とし穴であり、verify.py③ はそのためにあります。 - 日本語フォント:
fc-listでNoto Sans CJK SCなどを確認します。不足している場合は、ユーザーレベルのフォントを~/.local/share/fonts/にインストールします。
4. インストール段階の配置先
| ツール | インストール先 | 手段 |
|---|---|---|
| Node / Python | 不足している場合のみ | 可能ならマシン上の管理バージョンを優先;そうでなければユーザーに促す |
edge-tts / soundfile / numpy | venv | <venv>/bin/pip install、export TMPDIR=<大ディスク> が必須 |
| ffmpeg 完全版 | ~/.local/bin/ | ミラーから静的パッケージをダウンロードして展開。root 不要(オプション、簡易版で十分ならインストールしなくてよい) |
| LMMS | $VW_CONFIG_ROOT/lmms/ | AppImage をプロキシ経由でダウンロード → --appimage-extract で展開 |
| Remotion 依存関係 | プロジェクトディレクトリ | npm install、TMPDIR は大ディスクを指定 |
| 日本語フォント | ~/.local/share/fonts/ | .ttc を展開 → fc-cache -f |
⚠️ ダウンロードは毎回検証:バイト数 / SHA256 / 展開後に実行可能か。ダウンロードに失敗しても、ファイルが中途半端に残るくらいならリトライしたほうがまし。
5. ロールバック
install-manifest.jsonl が唯一の情報源です。形式は以下の通り:
{ "entries": [
{ "ts": "...", "kind": "pip-install", "target": "<venv>", "detail": "edge-tts==7.3.1",
"undo": "<venv>/bin/pip uninstall -y edge-tts" },
{ "ts": "...", "kind": "mkdir", "target": "$VW_CONFIG_ROOT/lmms", "undo": "rm -rf ..." },
{ "ts": "...", "kind": "backup-file", "target": "~/.lmmsrc.xml",
"backup": "$VW_CONFIG_ROOT/backup/<ts>/lmmsrc.xml", "undo": "cp バックアップを元の場所に戻す" }
] }
bash skills/ideaform-setup/scripts/rollback.sh --list # 何が取り消されるか確認
bash skills/ideaform-setup/scripts/rollback.sh --dry-run # 予行演習、実際には実行しない
bash skills/ideaform-setup/scripts/rollback.sh --yes # 実際にロールバック(逆順)
ユーザーの既存ファイルを上書きする前に必ずバックアップを取ります —— 特に ~/.lmmsrc.xml。
ロールバックはデフォルトでは契約ファイルを削除しません(それらはワークフロー Skill が使用するため)。ユーザーが明示的に --purge-contract を要求した場合のみ削除します。
7. ★ 後片付け:無効化 / アーカイブ / 削除(必ずユーザーに選ばせる)
スモークテストに合格したら、自動的に自分自身を削除してはいけません。以下の手順に従います。
① まず報告
ユーザーに説明します:
- 環境設定が完了しました。
toolchain.jsonが準備されています(パスを提示) - スモークテストの 4 項目の結果
- ワークフロー Skill は本 Skill が存在しなくても動作します(契約ファイルが Skill の外にあるため)
② 三つの選択肢を提示し、ユーザーに選ばせる
| 選択肢 | 内容 | 可逆性 | 適用 |
|---|---|---|---|
| A. 無効化(推奨) | 本 SKILL.md の frontmatter の disable: false を true に変更 | false に戻せば復元 | 将来、マシンを変えたり環境を変えて再実行する場合に備えて残しておきたい場合 |
| B. アーカイブ | スキルディレクトリ全体を $VW_CONFIG_ROOT/archive/ideaform-setup-<ts>/ に移動 | 元に戻せば復元 | スキル一覧に表示させたくないが、予備として残しておきたい場合 |
| C. 削除 | ディレクトリを実際に削除 | 自動バックアップから復元可能 | もう絶対に必要ないと確信している場合 |
A を推奨:無効化が最も安全で、コストも最小限であり、「環境が変わったらもう一度実行する」能力を保持します。
③ 実行前の鉄則
どの選択肢であっても、バックアップを先に、実行は後、そして確認:
- バックアップ:
cp -r <スキルディレクトリ> $VW_CONFIG_ROOT/backup/skill-ideaform-setup-<ts>/ - リスト表示:削除・変更されるすべてのパスをリストアップしてユーザーに見せます
- 再度確認:ユーザーが「削除していいよ」などと明確に言うのを待ちます。デフォルト値や推測で確認を代用してはいけません
- 実行:削除は
mvでバックアップに移動してから行い、直接rm -rfしてはいけません - 検証:ワークフロー Skill がまだ
toolchain.jsonを読み取れて正常に起動することを確認します
④ 削除後のセルフチェック
test -f "$VW_CONFIG_ROOT/toolchain.json" && echo "契約は健在 ✓"
契約が存在する → ワークフローは影響を受けません。契約が消えている → 誤って削除したので、バックアップから復元します。
ユーザーが「直接削除してもいい?」と聞いてきたら、三つの選択肢を回答し、トレードオフを説明し、「いいよ」とだけ答えてはいけません。
8. よくあるエラー
| 現象 | 真の原因 | 対処 |
|---|---|---|
| LMMS のレンダリング結果が全体無音、ログにエラーなし | ~/.lmmsrc.xml の stkdir が展開ディレクトリの rawwaves/ を指していない | stkdir を修正し、verify.py ③ を再実行して確認 |
npm install / pip install が ENOSPC エラー | TMPDIR が 10MB の /tmp tmpfs を指している | export TMPDIR=<大ディスク>、契約内の tmpdir はこのためにある |
| Remotion レンダリングが途中でタイムアウト / ページがフリーズ | 同時実行数が高すぎてメモリーが不足(4×1080p ページ) | --concurrency を減らす、長い動画は分割レンダリング |
| AppImage が起動しない | サンドボックスに /dev/fuse がない | --appimage-extract で展開後、AppRun を使用 |
| LMMS が起動を拒否 | サンドボックス内で id が root と表示される | --allowroot を追加 |
edge-tts が WSServerHandshakeError 403 を出力 | バージョンが古すぎる(ネットワーク問題ではない) | pip install --upgrade edge-tts、さらにシステムクロックを調整 |
詳細については docs/05-故障排查.md を参照。
9. 誰に引き継ぐか
設定が完了したら、次のステップはワークフロー Skill です:
skills/ideaform/SKILL.md
これが最初に読み取るのは、本 Skill が書き残した toolchain.json です。引き継ぎの言葉:
環境設定が完了し、検証も通過しました。契約は
<パス>にあります。次はワークフロー Skill に切り替えて本番作業を開始してください。