Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Start with [primitives-matrix.md](../docs/primitives-matrix.md) to map capabilit
| Pattern | Grok | Claude | Codex | OpenClaw | Cursor | Windsurf | Opencode | Hermes | GH Actions |
|---------|------|--------|-------|----------|--------|----------|----------|--------|------------|
| Daily Triage | [grok/daily-triage.md](./grok/daily-triage.md) | [claude-code/daily-triage.md](./claude-code/daily-triage.md) | [codex/daily-triage.md](./codex/daily-triage.md) | [openclaw/daily-triage.md](./openclaw/daily-triage.md) | [cursor/daily-triage.md](./cursor/daily-triage.md) | [windsurf/daily-triage.md](./windsurf/daily-triage.md) | [opencode/daily-triage.md](./opencode/daily-triage.md) | [hermes/daily-triage.md](./hermes/daily-triage.md) | [github-actions/daily-triage.yml](./github-actions/daily-triage.yml) |
| PR Babysitter | [grok/pr-babysitter.md](./grok/pr-babysitter.md) | [claude-code/pr-babysitter.md](./claude-code/pr-babysitter.md) | [codex/pr-babysitter.md](./codex/pr-babysitter.md) | [openclaw/pr-babysitter.md](./openclaw/pr-babysitter.md) | [cursor/pr-babysitter.md](./cursor/pr-babysitter.md) | [windsurf/pr-babysitter.md](./windsurf/pr-babysitter.md) | [opencode/pr-babysitter.md](./opencode/pr-babysitter.md) | | [github-actions/pr-babysitter.yml](./github-actions/pr-babysitter.yml) |
| PR Babysitter | [grok/pr-babysitter.md](./grok/pr-babysitter.md) | [claude-code/pr-babysitter.md](./claude-code/pr-babysitter.md) | [codex/pr-babysitter.md](./codex/pr-babysitter.md) | [openclaw/pr-babysitter.md](./openclaw/pr-babysitter.md) | [cursor/pr-babysitter.md](./cursor/pr-babysitter.md) | [windsurf/pr-babysitter.md](./windsurf/pr-babysitter.md) | [opencode/pr-babysitter.md](./opencode/pr-babysitter.md) | [hermes/pr-babysitter.md](./hermes/pr-babysitter.md) | [github-actions/pr-babysitter.yml](./github-actions/pr-babysitter.yml) |
| CI Sweeper | [grok/ci-sweeper.md](./grok/ci-sweeper.md) | [claude-code/ci-sweeper.md](./claude-code/ci-sweeper.md) | [codex/ci-sweeper.md](./codex/ci-sweeper.md) | [openclaw/ci-sweeper.md](./openclaw/ci-sweeper.md) | — | — | [opencode/ci-sweeper.md](./opencode/ci-sweeper.md) | — | [github-actions/ci-sweeper.yml](./github-actions/ci-sweeper.yml) |
| Post-Merge Cleanup | [grok/post-merge-cleanup.md](./grok/post-merge-cleanup.md) | [claude-code/post-merge-cleanup.md](./claude-code/post-merge-cleanup.md) | [codex/post-merge-cleanup.md](./codex/post-merge-cleanup.md) | [openclaw/post-merge-cleanup.md](./openclaw/post-merge-cleanup.md) | — | — | [opencode/post-merge-cleanup.md](./opencode/post-merge-cleanup.md) | — | [github-actions/post-merge-cleanup.yml](./github-actions/post-merge-cleanup.yml) |
| Dependency Sweeper | [grok/dependency-sweeper.md](./grok/dependency-sweeper.md) | [claude-code/dependency-sweeper.md](./claude-code/dependency-sweeper.md) | [codex/dependency-sweeper.md](./codex/dependency-sweeper.md) | [openclaw/dependency-sweeper.md](./openclaw/dependency-sweeper.md) | — | — | [opencode/dependency-sweeper.md](./opencode/dependency-sweeper.md) | — | [github-actions/dependency-sweeper.yml](./github-actions/dependency-sweeper.yml) |
Expand All @@ -41,5 +41,5 @@ L2 patterns ship multi-tool skills inside one starter folder — see `starters/<
| Claude Code | [minimal-loop-claude](../starters/minimal-loop-claude/) | via `loop-init --tool claude` | via `loop-init --tool claude` | via `loop-init --tool claude` | via `loop-init --tool claude` | via `loop-init --tool claude` | via `loop-init --tool claude` |
| Codex | [minimal-loop-codex](../starters/minimal-loop-codex/) | via `loop-init --tool codex` | via `loop-init --tool codex` | via `loop-init --tool codex` | via `loop-init --tool codex` | via `loop-init --tool codex` | via `loop-init --tool codex` |
| OpenClaw | [openclaw/daily-triage.md](./openclaw/daily-triage.md) (manual) | [openclaw/pr-babysitter.md](./openclaw/pr-babysitter.md) | [openclaw/ci-sweeper.md](./openclaw/ci-sweeper.md) | [openclaw/dependency-sweeper.md](./openclaw/dependency-sweeper.md) | [openclaw/post-merge-cleanup.md](./openclaw/post-merge-cleanup.md) | [openclaw/changelog-drafter.md](./openclaw/changelog-drafter.md) | [openclaw/issue-triage.md](./openclaw/issue-triage.md) |
| Hermes | [hermes/daily-triage.md](./hermes/daily-triage.md) (manual) | | — | — | — | — | — |
| Hermes | [hermes/daily-triage.md](./hermes/daily-triage.md) (manual) | [hermes/pr-babysitter.md](./hermes/pr-babysitter.md) (manual) | — | — | — | — | — |
| Opencode | [minimal-loop-opencode](../starters/minimal-loop-opencode/) | [pr-babysitter-opencode](../starters/pr-babysitter-opencode/) | [ci-sweeper-opencode](../starters/ci-sweeper-opencode/) | [dependency-sweeper-opencode](../starters/dependency-sweeper-opencode/) | [post-merge-cleanup-opencode](../starters/post-merge-cleanup-opencode/) | [changelog-drafter-opencode](../starters/changelog-drafter-opencode/) | [issue-triage-opencode](../starters/issue-triage-opencode/) |
1 change: 1 addition & 0 deletions examples/hermes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
| Example | Pattern |
|---------|---------|
| [daily-triage.md](./daily-triage.md) | Daily Triage (L1 report → L2 assisted) |
| [pr-babysitter.md](./pr-babysitter.md) | PR Babysitter (L1 report → L2 worktree + verifier) |

Optional **channel delivery** (Telegram, Slack, Discord, WhatsApp, SMS, Feishu) is Hermes's differentiator — the same cron job can post its summary into any connected home channel.

Expand Down
112 changes: 112 additions & 0 deletions examples/hermes/pr-babysitter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# PR Babysitter — Hermes Agent (`hermes cron`)

This is a practical, copy-pasteable example of a PR babysitter loop using Hermes.

Hermes ships a native scheduler on its **gateway** — map the loop to `hermes cron`
instead of a TUI `/loop`. Optional **channel delivery** (Feishu, Slack, Telegram,
Discord, WhatsApp, SMS) can ping blockers into the channel the team already watches
once you trust the output; week one stays on `--deliver local`.

## Cron job (week one — report only)

Isolated session each tick: reads GitHub state, updates `pr-babysitter-state.md`,
no code edits, **no merges**.

```bash
hermes cron create "*/15 * * * *" \
--name "PR babysitter" \
--deliver local \
--skill pr-review-triage \
--workdir "$PWD" \
"Run the pr-review-triage skill on all open PRs. Read pr-babysitter-state.md first, then update it with current CI status, review state, merge conflicts, and unanswered comments. Do not merge or push fixes in week one — report only. Flag anything ambiguous or high-risk for human review in pr-babysitter-state.md. End with the top 3 human actions."
```

- `--deliver local` writes output to `~/.hermes/cron/output/` only — nothing lands
in the human's chat history until you trust the output. Swap for `--deliver origin`
(current chat), a home channel name (e.g. `slack`, `feishu`), or
`platform:chat_id:thread_id` for a specific thread.
- `--workdir "$PWD"` injects `AGENTS.md` / `CLAUDE.md` / `.cursorrules` from the
project into the system prompt and pins the terminal cwd to the repo.
- Repeat `--skill` to attach multiple skills (e.g. `--skill pr-review-triage
--skill github-workflow` if PR reads go through a GitHub skill instead of `gh`).
- Operations: `hermes cron run <job-id>` for a one-off test tick, then
`pause` / `resume` / `edit` / `remove` as needed.

## Progression

- **Week one — report only.** Fresh isolated session each tick appends to
`pr-babysitter-state.md`. Read it yourself before acting on any suggestion.
Human gates all merges.
- **Week two — minimal fixes in worktrees.** Extend the prompt to propose fixes
in an isolated worktree for allowlisted low-risk PRs only — one worktree per
fix attempt via [`loop-worktree`](../../docs/QUICKSTART.md#l2-isolated-fix-attempts-loop-worktree)
so retries never collide on the same branch. Draft PRs only; never force-push.
- **Week two — verifier split.** A separate verifier approves before any fix is
committed: a second `delegate_task` call with a review-only prompt, or a chained
cron job via `hermes cron edit <fixer-id> --context-from <triage-id>` (the
upstream job's stdout is injected into the downstream prompt). Never let the
implementer mark its own work done. Escalate after 3 attempts per PR.
- **Add channel delivery.** Swap `--deliver local` for a home channel once the
output has earned trust; set channel `allowFrom` / mention rules first.

Week-two worktree lifecycle (see the
[loop-worktree subsection of the QUICKSTART](../../docs/QUICKSTART.md#l2-isolated-fix-attempts-loop-worktree)):

```bash
npx @cobusgreyling/loop-worktree create --run-id pr-217-fix-1 --pattern pr-babysitter
# fix + verifier run inside the printed worktree path
npx @cobusgreyling/loop-worktree mark --run-id pr-217-fix-1 --status rejected # verifier said no
npx @cobusgreyling/loop-worktree cleanup --older-than 24h
```

## Requirements

- [Hermes Agent](https://hermes-agent.nousresearch.com/docs) installed and
configured (`hermes setup`)
- `pr-babysitter-state.md` in the repo root (from `starters/pr-babysitter/`)
- The `pr-review-triage` skill in `~/.hermes/skills/pr-review-triage/SKILL.md`
(user-scoped) or `.hermes/skills/` (project-scoped) — the `SKILL.md` format is
shared across tools, so the starter copy works unchanged

```bash
cp starters/pr-babysitter/pr-babysitter-state.md.example pr-babysitter-state.md

mkdir -p ~/.hermes/skills/pr-review-triage
cp starters/pr-babysitter/.claude/skills/pr-review-triage/SKILL.md ~/.hermes/skills/pr-review-triage/SKILL.md

hermes skills list | grep pr-review-triage
```

## Example pr-babysitter-state.md

```markdown
# PR Babysitter State
Last run: 2026-07-05 09:00 UTC

## Open PRs

### #1234 — fix: correct login redirect
- CI: green
- Reviews: 1 approval, 1 blocking comment
- Loop action: report only (week one). Needs human triage.
- Attempts: 1 / 3
```

## Notes

- Never force-push; draft PRs by default; do not resolve review threads without
approval. Security, auth, payments, infra, or public API changes always
escalate — see [docs/safety.md](../../docs/safety.md)
- Sign loop comments on PRs: `🤖 Loop Engineering — PR Babysitter`
- Webhooks (`POST /hooks/agent`) can fire a check the moment CI finishes instead
of waiting for the next tick — keep hook endpoints on loopback or a trusted tailnet
- `hermes config set approvals.mode smart` so low-risk reads don't stall the loop
on manual gateway approvals
- Most runs should no-op on an empty watchlist. Cost check:
`npx @cobusgreyling/loop-cost --pattern pr-babysitter --cadence 15m --level L1 --conservative`;
audit readiness: `npx @cobusgreyling/loop-audit . --suggest`
- See [patterns/pr-babysitter.md](../../patterns/pr-babysitter.md) and
[starters/pr-babysitter](../../starters/pr-babysitter/) for the full pattern spec

See the [primitives matrix](../../docs/primitives-matrix.md) for how Hermes maps
to the same six-part loop shape.