关于 cron-scheduler
cron-scheduler 是用于定义和注册定时任务的技能,面向需要自动运行技能或 gbrain 作业的 Agent 操作者。它涵盖错峰调度、静默时段、幂等性、结果报告和通过配置包装器调用 gbrain,并区分托管脑库的同步安排。
主要功能
- 01检查任务时段冲突并错峰
- 02按时区处理静默时段
- 03要求任务可安全重复运行
- 04将结果保存为报告
- 05通过包装器调用 gbrain
适用场景
- 01安排定时运行某项技能
- 02配置 gbrain 定期同步
- 03避免任务在静默时段通知
- 04为多来源脑库设置同步计划
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ garrytan/ gbrain --skill cron-scheduler安装后在 Claude Code 中输入/cron-scheduler确认已加载。
详细介绍
Cron Scheduler
约定: 参见
skills/conventions/test-before-bulk.md——先在 3-5 个项目上测试每个 cron 作业。
Contract
此技能保证:
- 调度错峰:每个 5 分钟时段最多安排 1 个作业,不发生冲突
- 静默时段控制:支持时区感知,并可通过用户清醒状态覆盖
- 简短的作业提示词:作业提示词为“读取 skills/X/SKILL.md 并运行”(不内嵌 3000 字的提示词)
- 幂等性:作业可运行两次而不会产生重复副作用
- 结果保存为报告:
reports/{job-name}/{YYYY-MM-DD-HHMM}.md - 统一入口:每个作业、工作区脚本和钩子都通过同一个包装器调用 gbrain,该包装器会设置
GBRAIN_HOME,并保留标准错误输出和退出代码 (包装器)
Phases
- 定义作业。 名称、计划(cron 表达式)、要运行的技能、超时时间。
- 验证计划。 检查是否与现有作业冲突(5 分钟偏移规则)。
- 时段::05、:10、:15、:20、:25、:30、:35、:40、:45、:50
- 如果检测到冲突,建议下一个可用时段
- 检查静默时段。 默认:当地时间晚上 11 点至早上 8 点。
- 覆盖条件:用户清醒标记(如果用户处于活动状态,则暂停静默时段限制)
- 静默时段内:将输出保存到待处理队列
- 早晨联系用户时释放积压内容
- 向主机调度器注册。 OpenClaw cron、Railway cron、crontab 或进程管理器。每个已注册条目都应通过 Minions 执行,而不是
agentTurn。 重写模式见skills/conventions/cron-via-minions.md(PGLite 使用--follow,Postgres 在周期时段上使用--idempotency-key,并采用即发即弃方式)。GBrain v0.11.0 迁移会自动重写内置处理器的条目;主机特定的处理器需要按照docs/guides/plugin-handlers.md在代码层面注册。 - 编写简短提示词。 作业提示词为一行:“读取 skills/{name}/SKILL.md 并运行。”
- 通过包装器调用 gbrain。 Cron 运行时的
HOME和环境变量与 shell 不同,因此直接运行gbrain(或bun run src/cli.ts)可能找不到数据库(所有查询都会静默返回空结果),也可能作为第二个主机运行(refresh_not_owner)。注册gbrain-run <args>,即 cron-schedule.md 中的包装器: 它会设置GBRAIN_HOME(绝不设置HOME)、加载大脑的环境文件并运行已安装的二进制文件。将标准错误输出记录到文件中,检查退出代码,避免钩子输出到标准输出,并为每次调用设置至少 10 秒的超时时间。 以下代码行会写入gbrain-run;doctor 会打印裸命令。gbrain doctor --only cron_gbrain_home会警告任何直接运行src/cli.ts或在未使用大脑的GBRAIN_HOME时调用 gbrain 的 crontab 行或脚本。
Idempotency Requirement
每个 cron 作业都必须具备幂等性:
- 两次运行同一个作业会产生相同结果(不会创建重复页面或重复的时间线条目)
- 使用检查点状态文件跟踪进度,并从中断处恢复运行
- 创建新输出前,检查是否已有现存输出
Output Format
作业配置已保存。报告:“作业‘{name}’已安排在 {cron expression} 执行。下次运行时间:{time}。”
多来源脑:使用 sync --all,而不是为每个来源单独配置
当脑有 2 个或更多活动来源时(即 gbrain sources list 显示的来源具有非空 local_path 且未归档),请使用一条合并的 cron 配置,而不是为每个来源分别配置 N 条。
首选(多来源):
*/5 * * * * gbrain-run sync --all --parallel 4 --workers 4 --skip-failed >> /tmp/gbrain-cron.log 2>&1
这会取代 N 条逐来源配置,并自动纳入未来新增的来源,无需修改 crontab。并发预算:任务运行期间约有 parallel × workers × 2 ≈ 32 个连接(每个逐文件 worker 都会打开一个 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>是托管检出获取上游提交的唯一方式(先执行 fetch 和git merge --ff-only,然后在该检出中对来源执行托管同步)。对于跟踪远程仓库的每个检出,都应添加一条 refresh 配置,并使用实际的来源 ID;对于没有远程仓库的检出,则移除该配置。这里的;是有意为之:即使 refresh 拒绝执行,同步仍会运行。refresh_diverged:该检出包含上游没有的提交,说明有程序在 gbrain 之外提交了更改(通常是某个脚本在检出中写入文件并运行git commit)。请修复该写入程序,让它使用gbrain git commit-push -- <paths>提交,然后按拒绝提示进行协调(征得用户同意后运行gbrain git commit-push --push-only --keep-checkout);切勿强制操作该检出 (脚本和托管检出)。--hard-deadline 13m可确保运行时间低于 15 分钟的间隔。托管同步不使用逐来源锁,因此运行时间超过该间隔的任务会与下一次定时运行重叠。在截止时间到达时停止的任务会以resumable状态结束,下一次定时运行会继续执行。来源会逐个处理,因此--parallel不适用。- 某个来源出现
owner_unavailable:请查看其detail。在 classic Postgres 脑上,unbound_source属于正常情况,不会阻止 classic 同步;请保留同步配置行。其他任何detail都表示该来源由另一台主机负责:请在那台主机上安装逐来源配置行(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] 块或通知块时,请遵循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:受管理同步的游标尚未完成,而且刷新不会等待它。运行拒绝信息中打印的gbrain sync --source <id> --no-pull …命令;下一个定时任务会继续刷新。- 同步时出现
worktree_refreshing:刷新正在清理或合并该工作树。不要干预;下次定时同步会处理它。 - 某个任务的所有查询结果都为空,或日志显示
no_brain或GBRAIN_DB_ACCESS no_url:任务运行时没有加载 brain 的配置。通过包装器调用 gbrain;如果任务的标准错误被重定向到/dev/null,空结果并不能证明“没有笔记”。 - cron 返回
refresh_not_owner,但手动运行相同刷新可以成功:任务解析到了另一个 gbrain 主目录,因此它属于另一台主机。拒绝信息会指出读取的身份文件、HOME和GBRAIN_HOME;在包装器中设置所有者的GBRAIN_HOME。绝不要复制或删除host.json。 --json调用方无法解析 gbrain 的输出:包装器运行的某个钩子向标准输出打印了内容。将该钩子的输出发送到日志文件。- 任务中的调用超时,但手动运行可以完成:冷启动需要几秒。将 shell 和生成该进程的运行时中的超时时间都提高到至少 10 s,并使用热 CLI 套接字。
- 定时写入返回退出码 10:写入已被接受,目前仍在处理中,并非丢失或“未找到”。重试或报告前,先轮询
gbrain write-request <request_id>。
反模式
- 将多个任务安排在同一分钟运行(所有任务都在 :00)
- 在 cron 任务中内联 3000 字的提示词(应使用技能文件引用)
- 未先用 3-5 个项目测试就运行 cron 任务
- 重跑后产生不同输出的任务(不具备幂等性)
- 在静默时段发送通知(应改为保存到暂存队列)
- 在 cron 行、脚本或钩子中直接使用
gbrain或bun run src/cli.ts,而不是使用包装器;或包装器设置的是HOME而非GBRAIN_HOME - 对 gbrain 调用使用
2>/dev/null,或忽略其退出码 - 脚本在受管理的工作树中写入文件后运行普通的
git commit,而不是gbrain git commit-push -- <paths> - 调试时将
env或进程环境变量打印到日志或转录中(其中包含数据库 URL 和密钥) - 为每个来源单独设置
gbrain sync --source <id>cron 条目,而gbrain sync --all --parallel N --workers N可以用一行命令替代,并自动发现未来添加的来源。