実測・検証の内側

Macのふたを閉じても、senteは止まらない

「mac 閉じても sente 止まらないようにして」——この依頼に真正面から答えようとすると、すぐに壁に当たります。 macOS はふたを閉じるとハードウェアレベルで強制スリープします。 caffeinate はアイドルスリープしか防げず、蓋閉じは別の経路です。 そこで方針を変えました。sente を Mac からサーバーに移す——常駐 VM の上で tmux に入れ、ジョブの実行先を切り替える。 この記事は、その実装と、実際にファイルを作らせてレポートを書かせた記録です。

公開 2026-09-14
対象 Fly.io 常駐 VM + sente-cloud の /jobs
実測 本番環境・実ジョブ 4件すべて成功
コスト 約 $5/月(shared-cpu-2x 2GB + 10GB volume)

なぜ「頑張ってスリープさせない」は失敗するのか

先に詰まりを潰しました。ここを飛ばすと数時間を溶かします。

最初に調べた状態では、caffeinate -dims が 321時間動いていて、PreventSystemSleep も有効でした。 つまりアイドルスリープはすでに抑止できていたのに、蓋を閉じれば終わりです。 macOS の lid close は pmsetcaffeinate の外側で強制されます。

手段アイドル蓋閉じ備考
caffeinate -dims防げる不可すでに321時間稼働していたが無効
pmset disablesleep防げる不可Apple Silicon では lid close に効かない報告が多い
クラムシェル(AC + 外部ディスプレイ)防げる防げる確実だが、Mac を動かせない
サーバーで動かす無関係無関係PC の状態に依存しない

クラムシェルは確実ですが、Mac をどこにも持って行けません。 ノートを閉じて移動したい、という元の動機に合わない。なのでサーバー側に移すのが根本解だと判断しました。

構成:VM が主役、Mac は依頼者

sente は tmux の中で動くので、SSH を切っても生き残ります。

役割をはっきり分けました。実行するのは常駐 VM、依頼するのは Mac(またはスマホ)です。

fly status の実画面。machine が started、volume sente_data が接続されている
fly status -a sente-cloud — machine 891e035c676598started。volume sente_data(10GB)が /home/yuki/workspace に接続済み。

Mac を閉じても止まらない理由は単純です。sente は tmux の中で動き、sshd がコンテナの主プロセス。 さらに auto_stop_machines = falsemin_machines_running = 1 で、アイドルによる自動停止も無効化しています。

Fly VM 上で動いている sente の TUI 画面
VM の中で動いている sente の TUI。MCP 2個を認識し、provider 選択画面になっていない(=設定が正しく読めている)。

実際に使ってみる

「動きました」ではなく、ファイルを作らせました。

ジョブは target: "fly" を付けて投げるだけです。Mac は依頼を出したら、あとは何もしません。

$ curl -X POST https://sente.teai.io/jobs \
    -H 'content-type: application/json' \
    -d '{"target":"fly",
         "prompt":"/home/yuki/workspace に hello-fly.md を作って
                  「Fly VM で動きました」と1行書いて。
                  その後 cat で内容を確認して報告して。"}'
ジョブを投げてから結果を取得するまでの実画面
投げてから約24秒後、status: donerc: 0。VM が自分でファイルを書き、cat で確認して報告している。

次はもう少し実務寄りの依頼です。システム情報を調べて Markdown の表にまとめさせました。

"prompt": "/home/yuki/workspace に report.md を作って。
   今日の日付・ホスト名・CPUコア数・メモリ量・ディスク使用量を
   uname/hostname/nproc/free/df で調べて、Markdown の表にまとめて。
   最後に cat で中身を見せて。"
VM が自分で作った report.md の内容
VM が uname / hostname / nproc / free / df を実行し、自分で Markdown の表にまとめた結果。
workspace に成果物が残っている実画面
hello-fly.mdreport.md が volume 上に残る。VM を作り直しても消えない。
4/4
成功したジョブ

修正完了後、すべて rc=0

20〜25秒
ジョブ所要時間

ファイル作成+確認まで

$0
追加の推論コスト

既存の teai 残高をそのまま使用

踏んだ罠:7つすべて本番で実測

「動くはず」で書いて、ことごとく本番で転びました。

実装自体は半日でしたが、本番で動かして初めて分かる問題が7つありました。 どれもログだけでは「成功」に見えるのが厄介です。

罠の一覧(7件)
  1. worker トークンが 403WORKER_PATHS/jobs/fly/* を入れ忘れ
  2. output 報告が 403canReportJobtarget !== 'mac' で拒否。heartbeat だけ通るので「動いているように見える」
  3. 全ジョブが「こちらはデモです」 — worker が TEAI_API_KEY を export できていない。rc=0 なので成功に見える最悪のパターン
  4. ProviderNoProvidersError — 生の sente は ~/.config/sente/config.json を読む。te ランチャー経由だと動くので気づかない
  5. agent "sente" not found — VM に実在するのは build(primary)。スマホ側の名前は VM に無い
  6. sente run -p は password — prompt ではない。prompt は positional で渡す
  7. volume が root 所有 — 初回作成時に root 所有になり、workspace に書き込めない。sente が「権限がない」と判断して作業を止めた
教訓:終了コード 0 を信じない。3番目の罠は、worker のログに rc=0 status=done と出ていました。 中身は「こちらはデモです」です。API キーが空でも sente は正常終了するため、出力の中身を見るまで分かりません。 今はキーが空なら worker が起動を止めるようにしています。

Mac からどう使うか

2つの入口があります。

1. 直接入って操作する——Mac の代わりに VM の sente を触りたい場合。

fly ssh console -a sente-cloud   # 入る(root)
su - yuki                        # sente のユーザに切替
tmux attach -t sente             # sente の画面に入る

Ctrl+BD で離脱しても、sente は動き続けます。 これが「Mac を閉じても止まらない」の実体です。

2. ジョブとして投げる——スマホやブラウザから依頼する場合。target: "fly" を付けるだけです。 従来の "mac"(Mac が拾う)や "cloud"(サンドボックスで実行)と並んで選べます。

iPhone からも投げられる

実行先は Mac・クラウド・常駐 VM の3つから選べます。

sente の iPhone アプリは、依頼の内容からどこで実行するかを自分で選びます。 これまで mac(Mac で実行)と cloud(クラウドの作業箱)の2択だったところに、 3つ目の fly(常駐 VM)を足しました。

iPhone の Sente アプリ画面
iPhone の Sente アプリ。実機(iPhone 16 Pro)にインストールして起動を確認済み。

使い分けは「Mac がそこにいないかもしれないかどうか」です。エージェントへの指示にも明記してあります。

flyできないことも明示しています。Mac の ~/workspace には触れません。 ここを曖昧にすると、エージェントが「Mac のファイルを読む」依頼を VM に回して失敗するためです。

「どこで実行するか」を選ばせるのではなく、選べる材料を渡す。 エージェントに判断させるなら、それぞれの実行先で何ができて何ができないかを渡す必要があります。 ここを省くと、判断基準が「なんとなくクラウド」になります。
スリープを抑止する設定を頑張るより、実行場所を移す方が早く、確実で、結果的に安い。 常駐 VM は約 $5/月です。

ただし、これは「ローカル実行は要らない」という話ではありません。 Mac でしかできない仕事(実ブラウザの操作、手元のファイル、キーチェーン)は今までどおり target: "mac" です。 変えたのは「PC の電源状態に依存させたくない仕事」の置き場所だけです。

未検証の点も残しています。長時間ジョブ(タイムアウト 3600 秒)の実走はまだで、今回は 20〜25 秒のジョブしか試していません。 worker トークンにも有効期限があり、失効したら再発行が必要です。

Mac を閉じても、仕事は進む

sente は teai.io のエージェント基盤です。実行場所は Mac・クラウド・常駐 VM から選べます。

料金を見る →