cron-scheduler について
cron-schedulerは、定期ジョブを定義・登録するスキルで、スキルやgbrainの処理を自動化するエージェント運用者向けです。時間の分散、静穏時間、冪等性、レポート保存、ラッパー経由のgbrain呼び出しを扱い、管理対象の脳には別の同期手順を示します。
主な機能
- 01スケジュールの衝突確認と時間分散
- 02タイムゾーン対応の静穏時間
- 03安全な再実行を前提とするジョブ
- 04結果のレポート保存
- 05ラッパー経由のgbrain呼び出し
活用シーン
- 01スキルの定期実行を設定
- 02gbrainの定期同期を構成
- 03静穏時間中の通知を保留
- 04複数ソースの脳の同期を設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ garrytan/ gbrain --skill cron-schedulerインストール後、Claude Code で/cron-schedulerを入力して読み込まれたか確認します。
詳細
Cron スケジューラー
規約:
skills/conventions/test-before-bulk.mdを参照してください。すべての cron ジョブは、まず 3~5 件を対象にテストしてください。
契約
このスキルでは、以下を保証します。
- スケジュールの分散:5 分枠につき最大 1 ジョブとし、重複を防止します
- 静穏時間の制御:タイムゾーンに対応し、ユーザーが起きている場合は上書きできます
- 簡潔なジョブプロンプト:ジョブには「skills/X/SKILL.md を読み込んで実行する」と記述します(インラインで 3000 語のプロンプトを記述しません)
- 冪等性:ジョブを 2 回実行しても、副作用が重複しません
- レポートとして結果を保存:
reports/{job-name}/{YYYY-MM-DD-HHMM}.md - エントリーポイントを 1 つに統一:すべてのジョブ、ワークスペーススクリプト、フックは、
GBRAIN_HOMEを設定し、標準エラー出力と終了コードを保持する 1 つのラッパーを通じて gbrain を呼び出します (ラッパー)
フェーズ
- ジョブを定義する。 名前、スケジュール(cron 式)、実行するスキル、タイムアウトを指定します。
- スケジュールを検証する。 既存のジョブと重複しないことを確認します(5 分オフセットルール)。
- スロット::05、:10、:15、:20、:25、:30、:35、:40、:45、:50
- 重複が検出された場合は、次に利用可能なスロットを提案します
- 静穏時間を確認する。 デフォルト:現地時間の午後 11 時~午前 8 時。
- 上書き:ユーザー起床フラグ(ユーザーがアクティブな場合、静穏時間を一時停止します)
- 静穏時間中:出力を保留キューに保存します
- 朝に連絡があった時点で、保留中の内容を送信します
- ホストスケジューラーに登録する。 OpenClaw cron、Railway cron、crontab、またはプロセスマネージャーを使用します。登録する各エントリーは
agentTurnではなく、Minions 経由で実行してください。 書き換えパターンについてはskills/conventions/cron-via-minions.mdを参照してください(PGLite では--followを使用し、Postgres ではサイクルスロットに--idempotency-keyを指定して fire-and-forget 方式を使用します)。GBrain の v0.11.0 への移行では、組み込みハンドラーのエントリーが自動的に書き換えられます。ホスト固有のハンドラーには、docs/guides/plugin-handlers.mdに従ったコードレベルの登録が必要です。 - 簡潔なプロンプトを記述する。 ジョブプロンプトは 1 行にします:「skills/{name}/SKILL.md を読み込んで実行する。」
- ラッパーを通じて gbrain を呼び出す。 cron は、シェルとは異なる
HOMEと環境で実行されます。そのため、gbrain(またはbun run src/cli.ts)をそのまま実行すると、データベースが見つからず(すべての検索結果が無言で空になる)、または 2 つ目のホストとして動作する(refresh_not_owner)可能性があります。cron-schedule.md にあるラッパーgbrain-run <args>を登録してください。このラッパーはGBRAIN_HOMEを設定し(HOMEは使用しません)、brain の環境ファイルを読み込んで、インストール済みのバイナリを実行します。標準エラー出力をファイルに記録し、終了コードを確認し、フックの出力を標準出力に出さないようにしてください。また、各呼び出しには 10 秒以上のタイムアウトを設定してください。 以下の行ではgbrain-runを使用します。doctor はそのままのコマンドを表示します。gbrain doctor --only cron_gbrain_homeは、src/cli.tsを直接実行する、または brain のGBRAIN_HOMEを指定せずに gbrain を呼び出す crontab の行やスクリプトがある場合に警告します。
冪等性の要件
すべての cron ジョブは冪等でなければなりません。
- 同じジョブを 2 回実行しても同じ結果になります(ページやタイムラインのエントリーが重複しません)
- チェックポイントの状態ファイルを使用して進捗を追跡し、中断した実行を再開します
- 新しい出力を作成する前に、既存の出力を確認します
出力形式
ジョブ設定を保存しました。レポート:「ジョブ '{name}' を {cron expression} にスケジュールしました。次回実行:{time}。」
複数ソースの脳:ソースごとのエントリではなく、sync --all を使用してください
脳にアクティブなソースが2つ以上ある場合(gbrain sources list に表示される、アーカイブされていない local_path が null ではないソース)、ソースごとに N 個のエントリを設定するのではなく、1つにまとめた cron 行を使用してください。
推奨(複数ソース):
*/5 * * * * gbrain-run sync --all --parallel 4 --workers 4 --skip-failed >> /tmp/gbrain-cron.log 2>&1
これにより、ソースごとの N 個の行を置き換え、crontab を編集することなく、今後追加されるソースも自動で対象になります。同時実行数の目安:実行中は parallel × workers × 2 ≈ 32 接続です(ファイルごとの各ワーカーが2接続のプールを開きます)。Postgres の max_connections 設定値を超えないようにしてください。
非推奨(旧方式):gbrain sync --source default と gbrain sync --source zion-brain のエントリを5分ずらして個別に設定する方法です。新しいソースを追加するたびに手動で競合を回避する必要があり、処理の遅いソースが、旧方式のグローバルな gbrain-sync ロックをめぐって処理の速いソースと競合する可能性があります(v0.40.3.0 以降では gbrain-sync:<sourceId> のソースごとのロックを使いますが、ソースごとの cron パターンでは --all --parallel が実際に提供する並列処理のメリットを得られません)。
gbrain doctor は、アクティブなソースが2つ以上あることを検出すると、推奨行を sync_consolidation チェックとして表示します。その場でコピーして使用できます。
マネージドブレイン
マネージドブレインでは上記の行を使用できません。マネージド同期では --no-pull が必要で、--skip-failed は拒否されます(writer_coordinator_required)。まずモードを確認してください。gbrain sources writer status --json は "mode": "managed" または "mode": "classic" を報告し、bindings には各ソースの所有ホストが表示されます。
マネージドブレインでは、ソースを所有するホスト上に、代わりに次の行を設定してください。
*/15 * * * * gbrain-run sources refresh <id> >> /tmp/gbrain-cron.log 2>&1; gbrain-run sync --all --no-pull --hard-deadline 13m >> /tmp/gbrain-cron.log 2>&1
- マネージドチェックアウトが上流のコミットを取得する方法は
gbrain sources refresh <id>だけです(フェッチしてgit merge --ff-onlyを実行し、そのチェックアウト上のソースをマネージド同期します)。リモートを追跡するチェックアウトごとに、実際のソース ID を指定して refresh を1つ追加してください。リモートのないチェックアウトでは削除してください。refresh が拒否された場合も同期を実行するため、;は意図的なものです。 refresh_diverged:チェックアウトに、上流にはないコミットがあります。つまり、gbrain の外部で何かがコミットしています(通常は、チェックアウト内のファイルを書き換えてgit commitを実行するスクリプトです)。その書き込み処理を修正して、gbrain git commit-push -- <paths>でコミットするようにしてください。その後、拒否メッセージに従って調整してください(ユーザーの同意を得てからgbrain git commit-push --push-only --keep-checkoutを実行します)。チェックアウトを強制更新しないでください(スクリプトとマネージドチェックアウト)。--hard-deadline 13mを指定すると、15分の間隔内に処理が収まります。マネージド同期ではソースごとのロックを取得しないため、実行が次の実行時刻まで続くと、次の実行と重複します。期限で停止した実行はresumableとなり、次の実行で続行されます。ソースは1つずつ処理されるため、--parallelは適用されません。- ソースの
owner_unavailableが発生した場合は、そのdetailを確認してください。classic Postgres ブレインでのunbound_sourceは通常の状態で、classic 同期は停止しません。同期行はそのままにしてください。それ以外の詳細は、そのソースが別のホストに所有されていることを意味します。ここで設定するのではなく、そのホストにソースごとの行(gbrain sync --source <id> --no-pull --hard-deadline 13mと、そのソースの refresh)を設定してください。 - ファイルの処理に失敗した場合は、ファイルを修正してコミットした後、失敗した実行で指定したオプションを使って通常の
gbrain sync --source <id> --no-pull …を再実行してください。次回の同期では、直近の実行で記録された項目が再試行されます。--skip-failedは追加しないでください(--retry-failedはマネージドブレインでは通常の同期と同じ動作をする非推奨のエイリアスです)。
アクティブなソースが2つ以上あるマネージドブレインでは、gbrain doctor はこのマネージド用の行を sync_consolidation に表示します。
失敗した場合
gbrain のエラー code、終了コード、[AGENT] ブロック、または通知ブロックについては、エージェントオペレータープロトコルに従ってください。このスキル固有の対応は次のとおりです。
- スケジュールされた
gbrain syncでsync_in_progress/lock_busyが発生する:前の実行がまだ動作しています。間隔を広げるか、ジョブの開始時刻をずらしてください。重複して実行されるスケジュールを追加してはいけません。 - cron の変更後、Doctor がソースの古さを報告する:スケジュールを再度変更する前に、
gbrain sources status <id>で保留中の項目やエラーがないか確認してください。 - 同期ログに
checkpoint_validation_timeoutがある:エラーに表示された再試行コマンドを実行してください。リクエストをキャンセルしてはいけません。 - スケジュールされた同期で
writer_coordinator_requiredが発生する:brain は管理対象です。この行を管理対象 brainの手順に置き換えてください。--skip-failedを付けたり、--no-pullなしで再試行したりしてはいけません。 gbrain sources refreshでsync_in_progressが発生する:管理対象の同期カーソルが未完了で、refresh はその完了を待ちません。拒否メッセージに表示されたgbrain sync --source <id> --no-pull …コマンドを実行してください。次の tick で refresh が実行されます。- 同期で
worktree_refreshingが発生する:refresh がそのチェックアウトの処理を終了するか、マージしています。そのままにしてください。次の tick で同期されます。 - ジョブの検索結果がすべて空になる、またはログに
no_brainやGBRAIN_DB_ACCESS no_urlが表示される:ジョブは brain の設定なしで実行されています。ラッパー経由で gbrain を呼び出してください。stderr が/dev/nullに送られたジョブで結果が空でも、「メモがない」証拠にはなりません。 - 同じ refresh が手動では成功するのに、cron で
refresh_not_ownerが発生する:ジョブが別の gbrain ホームを解決しているため、別のホストとして扱われています。拒否メッセージには、読み込まれた ID ファイル、HOME、GBRAIN_HOMEが示されます。ラッパーで所有者のGBRAIN_HOMEを設定してください。host.jsonをコピーしたり削除したりしてはいけません。 --jsonを使う呼び出しで gbrain の出力を解析できない:ラッパーが実行する何かが stdout に出力しています。そのフックの出力はログファイルに送ってください。- ジョブではタイムアウトする呼び出しが、手動では完了する:コールドスタートには数秒かかります。シェルとそれを起動するランタイムの両方で、タイムアウトを少なくとも 10 s に引き上げ、ウォーム CLI ソケットを使用してください。
- スケジュールされた書き込みで終了コード 10 が返る:リクエストは受け付けられ、まだ保留中です。消失したわけでも、「見つからない」わけでもありません。再試行または報告する前に、
gbrain write-request <request_id>をポーリングしてください。
アンチパターン
- ジョブを同じ分(すべて :00)にスケジュールする
- cron ジョブに 3000 語のプロンプトを直接記述する(スキルファイルへの参照を使用してください)
- まず 3~5 件でテストせずに cron ジョブを実行する
- 再実行時に異なる出力を生成するジョブ(冪等ではない)
- 静穏時間中に通知を送る(代わりに保留キューに保存してください)
- ラッパーの代わりに、cron の行、スクリプト、フックで裸の
gbrainやbun run src/cli.tsを使う または、GBRAIN_HOMEではなくHOMEを設定するラッパーを使う - gbrain 呼び出しに
2>/dev/nullを使う、または終了コードを無視する - 管理対象チェックアウトでファイルを書き込み、
gbrain git commit-push -- <paths>ではなく通常のgit commitを実行するスクリプト - デバッグ中に
envやプロセスの環境変数をログやトランスクリプトに出力する(データベース URL とキーが含まれます) gbrain sync --all --parallel N --workers Nを使えば、将来のソースも自動的に取り込む 1 行に置き換えられるのに、ソースごとにgbrain sync --source <id>の cron エントリを分ける