问题
codeksei host seed-proactive --provider hermes 返回 created: true + 3 个 jobId,bridge sync_checkin_cron 确实写入了 ~/.hermes/cron/jobs.json,但 Hermes gateway 进程在内存中缓存的 scheduler 没有重新加载,导致:
- gateway agent.log 中完全没有新 job 的 running/completed 记录
cronjob list(走 Hermes cron store 的 hot read)只看到旧 job
checkin-schedule-state.json 的 nextWakeAt 到期后无人续约,整个 proactive 循环静默死亡
复现步骤
- 确保 Hermes gateway 正在运行(
hermes gateway status)
- 跑
codeksei host seed-proactive --provider hermes --user ... --workspace ...
- 返回
status: seeded,created: true × 3
- 立刻查
cat ~/.hermes/cron/jobs.json → 可以看到新 job 已写入
- 等待 next_run_at 到期 → gateway agent.log 无任何 cron.scheduler 日志
cronjob list → 新 job 不存在(gateway scheduler 未 pickup)
第二次跑 seed-proactive 后,由于某种时序(可能是 gateway 偶发 reload),jobs 有时能被 pickup。
根因分析
调用链:
seed-proactive
→ seedProactiveCheckin()
→ syncHostedCheckinPlanSetViaHermes()
→ syncCheckinCronViaHermesRepoLocal()
→ invokeHermesRepoLocalBridge() // spawnSync Python bridge
→ bridge.py _handle_sync_checkin_cron()
→ cron.jobs.create_job() // 写入 jobs.json ✅
bridge.py 通过 from cron.jobs import create_job 直接操作 Hermes cron store,写入 jobs.json 成功。
但 Hermes gateway 的 cron scheduler 在启动时把 jobs 加载到内存调度器(APScheduler 或类似),之后只通过自己的 cronjob create/update/remove API 维护调度。外部进程直接改 jobs.json 不会触发 scheduler reload。
建议修复方向
方案 A:bridge 写完后发 reload 信号
bridge.py 在 _handle_sync_checkin_cron 写完 jobs 后,向 Hermes gateway 发一个轻量 reload 信号(如写一个 ~/.hermes/cron/.reload sentinel 文件,或调 gateway 的 internal API)。gateway 的 cron ticker 检测到信号后重新 load jobs from disk。
方案 B:改用 Hermes cronjob API
bridge 不直接操作 cron.jobs,而是调 Hermes 的 cronjob REST/CLI API(hermes cron create 或 internal endpoint),这样 scheduler 和 store 自动同步。
方案 C:scheduler 定期从 disk reload
在 gateway 的 cron ticker(已有 60s interval)中加一个 file-watcher 或 mtime check,如果 jobs.json 比 scheduler 的上次 load 更新,自动 reload。
环境
- Codeksei:
7c925fa (feat: add governance pulse surfaces)
- Hermes:
codex/hermes-local-integration branch
- Platform: macOS, Weixin channel, codex-mode profile
- Hosted Hermes: hosted-mode canonical config
临时 workaround
从 Hermes 侧直接用 hermes cronjob create 创建 checkin job,绕过 seed-proactive。已验证此路可达。
相关代码
src/host/delegation/seed-proactive.ts → seedProactiveCheckin()
src/host/recipes/hermes/wake-forwarder.ts → syncHostedCheckinPlanSetViaHermes()
src/host/recipes/hermes/repo-local.ts → syncCheckinCronViaHermesRepoLocal()
tools/hermes_repo_local/bridge.py → _handle_sync_checkin_cron()(L511)
- Hermes
cron/scheduler.py → 需要 reload 机制
问题
codeksei host seed-proactive --provider hermes返回created: true+ 3 个 jobId,bridgesync_checkin_cron确实写入了~/.hermes/cron/jobs.json,但 Hermes gateway 进程在内存中缓存的 scheduler 没有重新加载,导致:cronjob list(走 Hermes cron store 的 hot read)只看到旧 jobcheckin-schedule-state.json的nextWakeAt到期后无人续约,整个 proactive 循环静默死亡复现步骤
hermes gateway status)codeksei host seed-proactive --provider hermes --user ... --workspace ...status: seeded,created: true× 3cat ~/.hermes/cron/jobs.json→ 可以看到新 job 已写入cronjob list→ 新 job 不存在(gateway scheduler 未 pickup)第二次跑 seed-proactive 后,由于某种时序(可能是 gateway 偶发 reload),jobs 有时能被 pickup。
根因分析
调用链:
bridge.py 通过
from cron.jobs import create_job直接操作 Hermes cron store,写入jobs.json成功。但 Hermes gateway 的 cron scheduler 在启动时把 jobs 加载到内存调度器(APScheduler 或类似),之后只通过自己的
cronjob create/update/removeAPI 维护调度。外部进程直接改jobs.json不会触发 scheduler reload。建议修复方向
方案 A:bridge 写完后发 reload 信号
bridge.py 在
_handle_sync_checkin_cron写完 jobs 后,向 Hermes gateway 发一个轻量 reload 信号(如写一个~/.hermes/cron/.reloadsentinel 文件,或调 gateway 的 internal API)。gateway 的 cron ticker 检测到信号后重新 load jobs from disk。方案 B:改用 Hermes cronjob API
bridge 不直接操作
cron.jobs,而是调 Hermes 的 cronjob REST/CLI API(hermes cron create或 internal endpoint),这样 scheduler 和 store 自动同步。方案 C:scheduler 定期从 disk reload
在 gateway 的 cron ticker(已有 60s interval)中加一个 file-watcher 或 mtime check,如果
jobs.json比 scheduler 的上次 load 更新,自动 reload。环境
7c925fa(feat: add governance pulse surfaces)codex/hermes-local-integrationbranch临时 workaround
从 Hermes 侧直接用
hermes cronjob create创建 checkin job,绕过 seed-proactive。已验证此路可达。相关代码
src/host/delegation/seed-proactive.ts→ seedProactiveCheckin()src/host/recipes/hermes/wake-forwarder.ts→ syncHostedCheckinPlanSetViaHermes()src/host/recipes/hermes/repo-local.ts→ syncCheckinCronViaHermesRepoLocal()tools/hermes_repo_local/bridge.py→ _handle_sync_checkin_cron()(L511)cron/scheduler.py→ 需要 reload 机制