# MiniMax H3 生成の決まりごと（2026-08-21 制定）

> 📘 **まずこれを読む（人向けのやさしい解説）**: GALLERIA 2台は何の機械か・なぜ寝るのか・どう起こすのか
> https://www.delivery-wine.com/share/h3-manager/galleria.html

2026-08-21 の「シーン1B が2時間20分止まった」件を受けて入れた仕組み。
**AIが覚えているかどうかに依存させない**ため、全部コードの側に入れてある。

## ① 解像度は「頼まれた値」でなく「尺と VRAM から」自動で決める
- 実体: `/opt/vstudio-h3/h3plan.py`（COM側の写しは `h3-manager/bin/worker.py` 内 `plan_res`）
- 判定式: **画素 × コマ数 ≤ 161M ×(VRAM/12GB)**
- 根拠(実測):

  | 設定 | 画素×コマ | 結果 |
  |---|---|---|
  | 1344×768 ×155 | 160.1M | 成功 (s1〜s8) |
  | 1344×768 ×241 | 248.8M | **OOM** 10:01 |
  | 1152×640 ×241 | 177.6M | **OOM** 10:06 |
  | 1024×576 ×241 | 142.2M | 成功 12:26 |

- 呼ぶ側は今までどおり 1344×768 を渡してよい。入らない時は**投入前に**自動で下がる
- 外したい時だけ `H3_NO_AUTORES=1`

## ② 失敗したら自動でやり直す・黙って止まらない
- `h3run2.py` は OOM を**終了コード 3**で返す（他のエラーは 1）
- `scene-runner.py` / `worker.py` はそれを見て**解像度を1段下げて最大3回**やり直す
- 直らなければ state.json / job.json に `error` を残し、**ページに赤い帯で出る**
- 見張り `~/bin/h3-project-watch.sh` はエラーを拾って `progress.json` の `failed` へ書く
  （**前の見張りは「出来たファイルがあるか」しか見ておらず、失敗を待ち続けて時間切れになった**）

## ③ 未完のジョブがある間は ComfyUI を自動停止させない
- `scene-runner.py` が `/run/vstudio-h3/active/<プロジェクト名>` にロックを置く
- `h3-comfyui-idle-stop` はロックが生きている間は止めない（30分放置のロックは掃除）
- **失敗直後に「暇だ」と誤判定して全部止まるのを防ぐため**（10:12 に実際に起きた）

## ④ 完了判定は「mp4 が実在するか」で行う
- 状態フラグ(`status:done`)を信用しない。ファイルが無ければ `queued` に戻して焼き直す
- 表示側は `out/` と `media/` の**両方**を探す
- 動画URLの `?v=` は**ファイルの更新時刻から自動**で付ける（手で書かない＝古い動画を掴ませない）

## 触る時の注意
- `pkill -f 'scene-runner.py'` は**SSHセッションごと巻き込む**ことがある（コマンド文字列に一致するため）。PID 指定で殺すこと

## ⑤ GALLERIA2(gpc002) は使っていない時に自動で寝る（BCWOL-2026-08-22）
**寝かせる**: gpc002 の `h3-idle-suspend.timer`（30秒毎に点検）が、下のどれにも当てはまらない状態が
**1分続いたらサスペンド(S3)**する。
- ComfyUI が起動中 / 生成ランナーが動いている / `/run/vstudio-h3/active` のロックが生きている
- pts の端末に直近1分の操作がある（物理コンソール tty1 は自動ログインで開きっぱなしなので対象外）
- `/run/vstudio-h3/keep-awake` が1分以内に更新されている（COM 側が「これから使う」と付ける印）
- GPU 使用率が10%以上 / 起動・復帰から1分以内
- 一時的に止めたい時: gpc002 で `touch /etc/h3-idle-suspend.disabled`

**起こす**: Wake-on-LAN。宅内には COM から直接パケットを投げられないので、**GALLERIA1(gpc001) が送信係**。
- COM から: `bc-gpu-power {status|wake|sleep} gpc002`（`/usr/local/bin/bc-gpu-power`）
- gpc001 側: `/usr/local/sbin/bc-node-power`（+ マジックパケット送信 `/usr/local/sbin/bc-wol.py`）
- **worker.py は gpc002 に投げる直前に `ensure_awake()` で自動的に起こす**（約15秒）。手動操作は不要
- NIC の WOL 設定は `wol-enable.service` で毎回入れ直す（再起動しても効く）

**注意**
- gpc002 は公開IPを持たず **gpc001 経由でしか触れない**。gpc001 を落とすと起こせなくなる
- `worker.py` を直した後は**ワーカーを再起動**しないと新しいコードが効かない（常駐プロセスのため）
  `bin/stop-worker.sh` → `bin/start-worker.sh`（apache 権限で実行）

---

## 自動スリープ（BCWOL-2026-08-23 追記：GALLERIA1 も寝るようにした）

**GALLERIA1(gpc001) も GALLERIA2(gpc002) と同じく、使っていなければ自動で寝る。**
- 判定: `/usr/local/sbin/h3-idle-suspend`（systemd タイマー `h3-idle-suspend.timer` が30秒おきに実行）
- gpc001 / gpc002 とも、無操作 **1分**で就寝
- gpc001 だけの追加の見張り（これがあるので勝手に落ちて困らない）
  - **Qwen3(Ollama) が使われている間は寝ない** … モデルがVRAMに載っている／直近2分に `POST /api/` があった
  - **gpc002 が仕事中の間は寝ない** … 入口を閉じないため
- 起こす: `bc-gpu-power wake gpc001`（COMから。gpc002 側の扉を通って WOL を出す）。実測 **36秒**で復帰
- 止めたい時: 対象機で `touch /etc/h3-idle-suspend.disabled`

### RTC(目覚まし時計)による自力起床は廃止した（2026-08-24 夜・酒井さん指示）
**GALLERIA は頼まれるまで、ずっと寝ていてよい。自分で起きる仕組みは無くした。**
- 理由: 宅内の **SH-PC(192.168.1.5) / 息子さんPC(192.168.1.7)** の WolChecker が30秒おきに COM の予約板を見て
  宅内LANから WOL を送るので、GALLERIA が自分で目を覚まして予約板を見に行く必要がない
- 実体: `/usr/lib/systemd/system-sleep/h3-rtc-wake`（両機）。寝る前に **wakealarm を必ず消すだけ**にした
  （旧版は「起こし手が居れば6時間後／居なければ20分後」に目覚ましをセットしていた＝これが「勝手に起動」の正体）
- どうしても自力起床させたい時だけ、その機で `/etc/h3-rtc-wake-minutes` に分数(5以上)を書く。`0`・空 = 目覚ましなし（既定）
- 旧版の控え: `/usr/lib/systemd/system-sleep/h3-rtc-wake.bak_20260824`。`/etc/h3-rtc-wake-minutes-long` は廃止（削除済み）
- ⚠ 残る唯一の穴: **宅内Windowsが2台とも寝ている時は外から起こせない**（起こせるようになるまで待つ／最悪は物理電源ボタン）

### ⛔ 画面ONの処理で keep-awake を置かない（2026-08-24 修正）
`h3-screen-wake`（復帰時に物理画面を点ける処理）が `/run/vstudio-h3/keep-awake` を無条件で touch していた。
そのため**予約確認のための一瞬起床でも「人が使っている」と誤判定して二度寝できず**、毎回5分間起きっぱなしになっていた
（＝酒井さんから見て「勝手に起動している」状態の正体）。**画面ON＝人が使っている、ではない。**復活させないこと。

### 承知しておくこと
- **gpc001 が寝ている間、Ver5 の「Other → Qwen3」は応答できない**。使う前に `bc-gpu-power wake gpc001` が要る
  （復帰すると COM の ollama トンネル 127.0.0.1:11435 は自動で張り直る＝実測確認済み）
- gpc001 上のトライアル版コンテナも寝ている間は止まる（テスト用のため許容と判断・2026-08-23 酒井さん了承済み）

## POCO の動画置き場は GALLERIA2（POCOMEDIA-2026-08-23）
- 保管先 `gpc002:/data/poco-media/`（1.9TB SSD）
- POCO から毎晩 01:30 に自動で預ける: POCO の `/usr/local/bin/poco-media-archive.sh`（cron・ログ `/var/log/poco-media-archive.log`）
- 扉は gpc001(2224)・gpc002(2225) のどちらでも通る。**コピーが成功した分だけ** POCO 側の中間ファイルを消す

---

## 外から起こす「予約板」方式（BCWAKE-2026-08-23）

**問題**: 自宅は公開IPを持たず、COM への逆SSHトンネル(扉)が唯一の入口。
**両機とも寝ると扉が2つとも閉じ、COM/POCO から起こす手段が無くなる**（2026-08-23 03:20 に実際に詰んだ）。

**解決**: 押す(プッシュ)のをやめ、**宅内機が自分で見に来る(プル)**。COM に予約板を置いた。

| 場所 | もの |
|---|---|
| 予約板(COM) | `https://www.delivery-wine.com/share/h3-manager/wake.php`（実体 `data/wake/<node>.req`・有効30分） |
| 合鍵 | `/etc/bc-wake-token`（COM・gpc001・gpc002・POCO・NET に同じ物。トークン無しは403） |
| 宅内機 | `/usr/local/sbin/bc-wake-check`（予約を見に行く）／`bc-wake-peek`（用が無ければ二度寝）／`bc-wake-request`（WOL前に予約を立てる） |
| 起動・復帰のたびに実行 | `bc-wake-peek.service`（起動時）／`/usr/lib/systemd/system-sleep/bcwake-resume`（復帰時） |

**動き**
1. COM/POCO/NET から予約を立てる
   - COM: `bc-gpu-power wake gpc001`（起きるまで待つ）／`bc-gpu-power request gpc001`（待たない）／`bc-gpu-power board`（予約一覧）
   - POCO・NET: `bc-galleria-wake gpc001 [--wait]` / `bc-galleria-wake board`
2. 扉が1つでも開いていれば**その場で WOL**＝従来どおり数十秒で起きる
3. 宅内Windows(SH-PC / 息子さんPC)の WolChecker が30秒おきに予約板を見て、宅内LANから WOL を送る（実測15〜31秒で復帰）
   - 起きた側は予約があれば `keep-awake` を置いてそのまま起き続ける／予約が無ければ25秒ほどで二度寝
4. **宅内Windowsが2台とも寝ている時だけ起こせない**（2026-08-24: GALLERIA自身のRTC定時起床は廃止したため）

**目覚まし時計(RTC)は使わない**（2026-08-24 廃止）… GALLERIA は WOL で起こされるまで寝続ける。詳細は上の「RTC…廃止した」節。

**注意**
- 二度寝の判定は「ComfyUI・生成プロセス・Ollama・GPU10%以上・未完ロック・keep-awake・端末を直近5分に操作」のどれかがあれば寝ない。
  **物理コンソール(tty1)も見る**ので、目の前で使っている時に落ちることはない
- WOL を出す全経路(`bc-node-power wake`)が**先に予約を立てる**ようにしてある。予約なしで起こすと25秒後に二度寝してしまうため、**新しく起こす経路を作る時も必ず `bc-wake-request` を先に呼ぶこと**
- 止めたい時: 対象機で `touch /etc/bc-wake-peek.disabled`（二度寝だけ止める）／`touch /etc/h3-idle-suspend.disabled`（自動就寝ごと止める）
- ログ: 宅内機の `/var/log/bc-wake-check.log`

## ⑦ 物理モニターは動画生成ノード表示にする（2026-08-23）
GALLERIA1/2 の物理画面は、通常のログイン画面ではなく **BASECORD VIDEO GENERATION NODE** のステータス表示にする。

- 常時表示: 各機の `h3-gpu-dashboard.service`
- 表示スクリプト: `/usr/local/sbin/h3-gpu-dashboard`
- 画面起こし: `/usr/local/sbin/h3-screen-wake`
- 表示内容: `GALLERIA1` / `GALLERIA2` の大きな見出し、状態、時刻、CPU/MEM/SWAP/DISK/GPU/VRAM/TEMP/POWER のバー
- 生成ジョブ時: `bin/worker.py` の `ensure_awake()` が、対象機を起こした後に `h3-screen-wake` を呼ぶ。つまり普段はスリープ、動画生成リクエスト時は起床して画面もONになる
- 起動時・復帰時: `h3-screen-on-boot.service` と `/usr/lib/systemd/system-sleep/h3-screen-on-resume` が画面を起こし、ダッシュボードを再描画する
- GALLERIA1 の旧BASECORDコンソール表示 `bc-console-dash.service` は、動画生成ノード表示と競合するため停止・無効化済み
- 確認: COM から `ssh -p 2224 root@127.0.0.1 'cat /dev/vcs1'`（GALLERIA1）／`ssh -p 2225 root@127.0.0.1 'cat /dev/vcs1'`（GALLERIA2）

## ⑧ スマホから頼む・宅内Windowsが起こす（BCMOBILE / BCTUNNEL-2026-08-24）

外出先のスマホから動画を頼めるようにした。起こす実務は**宅内のWindows（SH-PC・息子さんPC）**がやる。

**流れ**
1. スマホで `m.php` に頼む（合言葉つきURL）
2. 画面が①**予約板に「起こして」を書く** ②**生成ジョブを積む** ③ワーカーを起動する
3. 宅内Windowsの `WolChecker.ps1` が30秒以内に予約を拾い、**宅内LANからWOL**でGALLERIAを起こす
4. ワーカーが扉(逆SSH)の開通を待って生成 → 完成 → **完了メール**
5. アイドルで自動スリープに戻る

| もの | 場所 |
|---|---|
| スマホ用画面 | `https://www.delivery-wine.com/share/h3-manager/m.php?k=<合言葉>` |
| 合言葉 | `/etc/bc-h3-mobile-key`（root:apache 640）。cookieに1年保存するので初回だけURLに付ける |
| 完了メールの宛先 | ジョブの `notify_mail`、無ければ `/etc/bc-h3-notify-mail` |
| ワーカー守り | `/home/alma/bin/h3-worker-keeper.sh`（alma cron 毎分）。落ちていたら起こす＝**誰も画面を開かなくてもジョブが流れる** |

**起こす係は宅内Windows 2台（冗長・2026-08-24 完了）**

| PC | 置き場所 | 常駐 |
|---|---|---|
| SH-PC（酒井さん） | `C:\ProgramData\GalleriaWol\WolChecker.ps1` | スタートアップ（ログオン時） |
| 息子さんPC `192.168.1.7` (DESKTOP-B3MVV9A) | 同上（同一ファイル・同一トークン/MAC） | タスクスケジューラ `GalleriaWolChecker`（SYSTEM・起動時＋ログオン時） |

**どちらか一方が起きていれば起こせる。** 2台とも寝ている時は起こせない（GALLERIAのRTC定時起床は2026-08-24に廃止。最悪は物理電源ボタン）。

**実測（2026-08-24 03:26〜03:27・COMの予約板に書くだけ）**
- gpc002: 予約投入 → **15秒**で復帰
- gpc001: 予約投入 → **31秒**で復帰
- 復帰後、予約は自動で消える（Windows側が `act=clear`）
- ※ アイドル1分設定なので、放っておくと**すぐ寝る**。`bc-gpu-power sleep` が `already-down` を返すのは正常

**GALLERIAのMACアドレス（WOLの宛先・2026-08-24 実機確認）**
- gpc001 `a8:a1:59:75:4f:bf` ／ gpc002 `a8:a1:59:75:50:14`（どちらも `enp3s0`）

### 逆SSHトンネルの「半死」を自動で掃除する（BCTUNNEL-2026-08-24）

**症状**: 2224/2225 は listen しているのに SSH が `banner exchange` で固まり、外からは「扉が開いている」ように見えて実際は入れない。何時間も直らない。
**原因**: COM の sshd が `ClientAliveInterval 0`（＝死活を一切見ない）だった。GALLERIAがスリープするとTCPだけ半開きで残り、TCP再送タイムアウト（数時間）まで居座る。
**対処**（両方入れた）
- `/etc/ssh/sshd_config.d/60-bc-reverse-tunnel.conf` … `ClientAliveInterval 30` / `ClientAliveCountMax 3` → **90秒で片付く**。GALLERIA側 `Restart=always` が15秒後に張り直す
- `/usr/local/sbin/bc-tunnel-guard`（root cron `*/2`・ログ `/var/log/bc-tunnel-guard.log`）… 2回続けて無応答なら待受を落とす。**listen自体が無い＝就寝中は正常**として触らない
- 旧 `/home/alma/bin/galleria-tunnel-watchdog.sh`（alma cron 毎分）は**これに一本化して停止**した

### 鍵の権限（2026-08-24）
`.h3-manager/keys/galleria` `shpc` は **640 apache:apache**。600だとalmaが動かしたワーカーが
`Load key ... Permission denied` で全カット失敗する（画面から起動＝apache、cron/手動＝alma のどちらでも動くようにするため）。

### 完了メールの宛先（2026-08-24 実測）
**COM から Gmail 宛に直接送ると弾かれる**（`550-5.7.26 sender is unauthenticated` ＝ SPF/DKIM 未設定）。
既定の宛先は `staff@d-winewine.com`（lolipop 経由で到達を確認済み）。
Gmail へ直接届けたいなら、COM の SPF/DKIM を整えるのが先。

---

## ⑨ 勝手に起こさない・勝手に設定を変えない（BCWAKEGUARD-2026-08-24）

**事故**：酒井さんが GALLERIA1 をスリープさせても、COM 側の AI が状態確認のたびに
`bc-gpu-power wake gpc001` を打っていたため、10:27 / 13:51 / 14:50 / 14:58 / 15:26 / 15:33 と
何度も起こし直していた。さらに `h3-idle-suspend` のアイドル秒数（自宅の GALLERIA 制御アプリの設定）を
COM 側から書き換えていた。**便利機能を「様子見」に使いすぎたのが原因。**

### 番人を入れた（COM `/usr/local/bin/bc-gpu-power`）
| 何が起きるか | 内容 |
|---|---|
| 理由なしの起床を拒否 | `bc-gpu-power wake gpc001` だけでは動かない。`wake gpc001 "なぜ起こすのか"` が必要 |
| 人が寝かせたら札が付く | `sleep` すると `/var/lib/bc-gpu/nowake-<node>` に **12時間** の「勝手に起こすな」札。理由付き wake でも止まる |
| 札を越えられるのは生成ジョブだけ | `H3_WAKE_FORCE=1`。`bin/worker.py` の `ensure_awake()` だけが付ける |
| 記録が必ず残る | `/var/log/bc-gpu-wake.log`（`bc-gpu-power wakelog` で読める）。いつ・誰が・なぜ・どのコマンドから |
| 札の手動操作 | `bc-gpu-power hold <node>` / `unhold <node>` |

### 起こす前に、起こさずに済ませる
状態を知りたいだけなら **`bc-gpu-power doors` / `board` / `status`** で足りる。
過去の生成物は COM の `out/` に公開用コピーが残っているので、確認のために起こす必要はない。

### ⛔ 自宅側の設定ファイルを COM から書き換えない
- `gpc001:/etc/systemd/system/h3-idle-suspend.service.d/zz-galleria-control.conf`
  … **自宅の GALLERIA 制御アプリ（BASECORD for Windows 側）の設定ファイル**。COM から上書きしない。
  アイドル秒数を変えたい時は酒井さんの UI から変える
- `idle-60s.conf`（同ディレクトリ）は H3 側の既定値。こちらを触る時も理由を H3-RULES.md に残す
