Hermes Cron 原生治理 🤖

🤖 Hermes Cron 原生治理

设计原则: 不使用任何需要预定义的自定义目录。所有文件位于 Hermes 原生路径内,cron 脚本全部放入 cron 系统的默认搜索目录。


1. 🏗️ 架构

┌──────────────────────────────────────────────┐
│  cronjob: hermes-cron-master                  │
│  schedule: 0 1 * * *                          │
│  script: hermes-cron-master.sh  (no_agent)    │
│  → 脚本名解析自 ~/.hermes/scripts/            │
└──────────────────┬───────────────────────────┘
                   │
                   ▼
┌──────────────────────────────────────────────┐
│  ~/.hermes/scripts/hermes-cron-master.sh      │
│  Master Orchestrator (bash, 自包含)            │
│  ● 内置任务定义(order/timeout/deps)          │
│  ● 串行运行各任务脚本                          │
│  ● timeout 超时强杀                            │
│  ● 捕获 stdout/stderr/退出码/耗时              │
│  ● 生成日报 + stdout 输出摘要                  │
└──────┬──────────────────┬────────────────────┘
       │                  │
       ▼                  ▼
┌──────────────┐  ┌──────────────┐
│  cron-tasks/  │  │  cron-tasks/ │
│  gbrain.sh    │  │  sitemap.sh  │
└──────────────┘  └──────────────┘
       │                  │
       ▼                  ▼
┌──────────────────────────────────────────────┐
│  /opt/data/home/.cron-reports/                │
│  cron-YYYY-MM-DD.md(日报存盘)               │
│  /opt/data/cron/output/{job_id}/              │
│  (cron 系统原生保留的 stdout 输出)            │
└──────────────────────────────────────────────┘

2. 📂 原生目录布局

所有路径在默认 Hermes 安装中已存在或可推导:

路径 性质 说明
~/.hermes/scripts/hermes-cron-master.sh Cron 系统脚本目录 cron job 的 script 字段以此为查找基
~/.hermes/scripts/cron-tasks/ 任务脚本子目录 master 脚本内部通过 $(dirname "$0") 推导该位置
/opt/data/home/.cron-reports/ 日报持久化位置 位于 home(唯一持久 volume 内),自动创建
/opt/data/cron/output/{job_id}/ Cron 系统原生输出 master 脚本的 stdout 自动归档于此
/opt/data/cron/jobs.json Cron 系统原生定义 cron job 元数据,Hermes 管理

3. ⚙️ Master 编排器设计

3.1 脚本位置约定

Hermes cron 系统的 script 字段解析自 ~/.hermes/scripts/。目录布局:

~/.hermes/scripts/
├── hermes-cron-master.sh       # cron job 脚本(入口)
└── cron-tasks/                 # 各任务脚本
    ├── gbrain.sh
    └── sitemap.sh

3.2 Master 脚本结构

#!/usr/bin/env bash
set -o pipefail

# ── 路径推导(依赖 cron 系统的可预测执行上下文) ──
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
TASKS_DIR="${SCRIPT_DIR}/cron-tasks"
REPORT_DIR="${HOME}/.cron-reports"

# ── 任务定义(内联,无外部配置文件) ──
TASK_ORDER=(gbrain sitemap)
declare -A TASK_TIMEOUT
TASK_TIMEOUT[gbrain]=600
TASK_TIMEOUT[sitemap]=120
declare -A TASK_DEPS
TASK_DEPS[gbrain]=""
TASK_DEPS[sitemap]=""

# ── 路径推导结束 ──

路径推导为何可靠:

  • $(dirname "$0") 在 cron no_agent 模式下始终解析为 ~/.hermes/scripts/,因为 cron 系统启动脚本时 CWD 已设定为该目录
  • $HOME 在 cron 上下文中有定义,指向 /opt/data/home
  • TASKS_DIR 从 master 脚本位置推导,不需硬编码
  • REPORT_DIR 使用 $HOME(cron 原生值),不需硬编码

3.3 运行时行为

  1. TASK_ORDER 顺序依次运行每个任务脚本(${TASKS_DIR}/${name}.sh
  2. 每个任务用 timeout 包裹,超时退出码 124
  3. 任务失败后检查 TASK_DEPS,下游依赖任务自动跳过
  4. 捕获每个任务的 stdout/stderr(各前 2000 字符)、退出码、耗时
  5. 所有任务结束后,生成统—日报并保存到 $REPORT_DIR/cron-YYYY-MM-DD.md
  6. 输出简短摘要到 stdout → cron 系统自动转发到 Telegram + 归档到 cron/output/

4. ✅ 初始部署

步骤一:编写三个脚本文件

# 创建目录
mkdir -p ~/.hermes/scripts/cron-tasks

# 写入三个文件(略,见后文代码段)
# ~/.hermes/scripts/hermes-cron-master.sh
# ~/.hermes/scripts/cron-tasks/gbrain.sh
# ~/.hermes/scripts/cron-tasks/sitemap.sh

chmod +x ~/.hermes/scripts/hermes-cron-master.sh
chmod +x ~/.hermes/scripts/cron-tasks/*.sh

步骤二:创建 cron job

通过聊天命令创建 cron job:

hermes cron create \
  --name hermes-cron-master \
  --schedule "0 1 * * *" \
  --script hermes-cron-master.sh \
  --no-agent \
  --deliver origin

或直接请求 Hermes:

[at c] 创建 cron job,每天 1 点运行 hermes-cron-master.sh,no_agent 模式,发回本聊天

步骤三:验证

# 手动触发一次(测试模式,不修改 cron 状态)
bash ~/.hermes/scripts/hermes-cron-master.sh

# 检查日报是否生成
ls -la ~/.cron-reports/

5. ➕ 新增任务

# 1. 创建任务脚本
cat > ~/.hermes/scripts/cron-tasks/your-task.sh <<'SCRIPT'
#!/usr/bin/env bash
set -o pipefail
echo "🚀 你的任务"
# 业务逻辑
SCRIPT
chmod +x ~/.hermes/scripts/cron-tasks/your-task.sh

# 2. 编辑 master 脚本,在任务定义段落追加
#   TASK_ORDER+=(your-task)
#   TASK_TIMEOUT[your-task]=300
#   TASK_DEPS[your-task]=""

# 3. 验证语法
bash -n ~/.hermes/scripts/hermes-cron-master.sh

6. ❌ 移除任务

# 1. 删除任务脚本
rm ~/.hermes/scripts/cron-tasks/your-task.sh

# 2. 从 master 脚本中删除对应的三行数组定义

# 3. 验证
bash -n ~/.hermes/scripts/hermes-cron-master.sh

7. 🔗 依赖关系

# 无依赖
TASK_DEPS[task-a]=""

# 依赖单个任务
TASK_DEPS[task-b]="gbrain"

# 依赖多个任务
TASK_DEPS[task-c]="gbrain,sitemap"

行为: 被依赖的任务失败 → 当前任务自动跳过,日报中标注跳过原因。


8. ⏰ 超时机制

  • 每个任务独立配置超时秒数(TASK_TIMEOUT
  • 使用 Linux timeout 命令,超时发送 SIGTERM
  • 超时退出码 124,标记为 ❌ 失败(超时)
  • 不影响后续任务

9. 📊 日报机制

输出路径

输出 去向 说明
简短摘要(stdout) /opt/data/cron/output/{job_id}/ + Telegram cron 系统自动保留 + no_agent 自动转发
详细日报(Markdown) /opt/data/home/.cron-reports/cron-YYYY-MM-DD.md master 脚本额外写入,用于查阅历史

日报格式

🤖 Hermes Cron 日报 — 2026-05-16
═══════════════════════════════════════
📊 总体: 2 任务 | ✅ 1 | ❌ 0 | ⏭️  1 | ⏱️  8s

  ✅  [1] gbrain — 成功 (exit=0, 6s)
  ⏭️  [2] sitemap — 跳过 (依赖 'gbrain' 未成功)

📄 完整报告: /opt/data/home/.cron-reports/cron-2026-05-16.md

10. 🔧 运维指南

查看 cron job 状态

[at c] 列出目前所有cron

手动触发运行

# 全量
bash ~/.hermes/scripts/hermes-cron-master.sh

# 单任务(利用 master 脚本的 --task 参数)
bash ~/.hermes/scripts/hermes-cron-master.sh --task=sitemap

查看日报

# 最近一份
ls -t ~/.cron-reports/ | head -1 | xargs -I{} cat ~/.cron-reports/{}

# cron 系统输出的原始 stdout
cat /opt/data/cron/output/{job_id}/latest

修改执行时间

[at c] 把 cron 改为每天凌晨 2 点

暂停/恢复 cron

[at c] 暂停 cron hermes-cron-master
[at c] 恢复 cron hermes-cron-master

11. 设计依据

本设计基于对 Hermes 原生行为的以下观察:

Hermes 原生事实 设计推论
cron script 解析自 ~/.hermes/scripts/ 所有 cron 脚本必须在此目录下
cron no_agent 模式运行脚本时 CWD 固定 $(dirname "$0") 可靠推导脚本位置
$HOME 在 cron 上下文始终为 /opt/data/home $HOME 推导持久化路径,不硬编码
tasks_homecron_home 原生配置字段 用脚本位置推导所有路径,不用 config.yaml 定义
cron 系统原生保存 stdout 到 output/{job_id}/ 摘要输出到 stdout 即可持久化,日报存盘作为补充

— 本文档基于 Hermes 原生行为,不依赖于任何自定义目录或预定义配置