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 @@ -29,7 +29,7 @@ Start with [primitives-matrix.md](../docs/primitives-matrix.md) to map capabilit
| 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) | [cursor/post-merge-cleanup.md](./cursor/post-merge-cleanup.md) | [windsurf/post-merge-cleanup.md](./windsurf/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) | [cursor/dependency-sweeper.md](./cursor/dependency-sweeper.md) | [windsurf/dependency-sweeper.md](./windsurf/dependency-sweeper.md) | [opencode/dependency-sweeper.md](./opencode/dependency-sweeper.md) | — | [github-actions/dependency-sweeper.yml](./github-actions/dependency-sweeper.yml) |
| Changelog Drafter | [grok/changelog-drafter.md](./grok/changelog-drafter.md) | [claude-code/changelog-drafter.md](./claude-code/changelog-drafter.md) | [codex/changelog-drafter.md](./codex/changelog-drafter.md) | [openclaw/changelog-drafter.md](./openclaw/changelog-drafter.md) | [cursor/changelog-drafter.md](./cursor/changelog-drafter.md) | [windsurf/changelog-drafter.md](./windsurf/changelog-drafter.md) | [opencode/changelog-drafter.md](./opencode/changelog-drafter.md) | — | [github-actions/changelog-drafter.yml](./github-actions/changelog-drafter.yml) |
| Issue Triage | [grok/issue-triage.md](./grok/issue-triage.md) | [claude-code/issue-triage.md](./claude-code/issue-triage.md) | [codex/issue-triage.md](./codex/issue-triage.md) | [openclaw/issue-triage.md](./openclaw/issue-triage.md) | [cursor/issue-triage.md](./cursor/issue-triage.md) | [windsurf/issue-triage.md](./windsurf/issue-triage.md) | [opencode/issue-triage.md](./opencode/issue-triage.md) | | [github-actions/issue-triage.yml](./github-actions/issue-triage.yml) |
| Issue Triage | [grok/issue-triage.md](./grok/issue-triage.md) | [claude-code/issue-triage.md](./claude-code/issue-triage.md) | [codex/issue-triage.md](./codex/issue-triage.md) | [openclaw/issue-triage.md](./openclaw/issue-triage.md) | [cursor/issue-triage.md](./cursor/issue-triage.md) | [windsurf/issue-triage.md](./windsurf/issue-triage.md) | [opencode/issue-triage.md](./opencode/issue-triage.md) | [hermes/issue-triage.md](./hermes/issue-triage.md) | [github-actions/issue-triage.yml](./github-actions/issue-triage.yml) |

L2 patterns ship multi-tool skills inside one starter folder — see `starters/<pattern>/`.

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/pr-babysitter.md](./hermes/pr-babysitter.md) (manual) | [hermes/ci-sweeper.md](./hermes/ci-sweeper.md) (manual) | — | — | — | |
| Hermes | [hermes/daily-triage.md](./hermes/daily-triage.md) (manual) | [hermes/pr-babysitter.md](./hermes/pr-babysitter.md) (manual) | [hermes/ci-sweeper.md](./hermes/ci-sweeper.md) (manual) | — | — | — | [hermes/issue-triage.md](./hermes/issue-triage.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 @@ -7,6 +7,7 @@
| [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) |
| [ci-sweeper.md](./ci-sweeper.md) | CI Sweeper (L1 report → L2 worktree + verifier) |
| [issue-triage.md](./issue-triage.md) | Issue Triage (L1 propose-only → L2 allowlisted labels) |

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
135 changes: 135 additions & 0 deletions examples/hermes/issue-triage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Issue Triage — Hermes Agent (`hermes cron`)

Keep the issue queue legible so humans and Daily Triage always know the top five
actionable items. Hermes runs the shared `issue-triage` skill in a fresh cron
session and keeps routine output local while the loop earns trust.

Week one is deliberately **propose-only**: the job updates
`issue-triage-state.md` with suggested priority and labels, but never changes an
issue or repository.

## Setup

Install and configure [Hermes Agent](https://hermes-agent.nousresearch.com/docs),
then copy the shared state example and skill:

```bash
hermes setup

cp starters/issue-triage/issue-triage-state.md.example \
issue-triage-state.md

mkdir -p ~/.hermes/skills/issue-triage
cp templates/SKILL.md.issue-triage \
~/.hermes/skills/issue-triage/SKILL.md

hermes skills list | grep issue-triage
```

Use `.hermes/skills/issue-triage/` instead when the skill should be available
only inside this project. The job also needs read-only access to the issue
tracker, for example through an authenticated GitHub CLI or a GitHub-capable
skill. Do not grant write access for the week-one loop.

## Week one — propose only

Start with a two-hour cadence on an active repository. `--workdir "$PWD"` pins
the repository and injects its `AGENTS.md`, `CLAUDE.md`, or `.cursorrules` into
the cron session.

```bash
hermes cron create "0 */2 * * *" \
--name "Issue triage" \
--deliver local \
--skill issue-triage \
--workdir "$PWD" \
"Run the issue-triage skill. Read issue-triage-state.md first, then scan open issues and discussions created or updated since the last run. Update Last run, backlog counts, Top 5 prioritized items, proposed labels, possible duplicates, and the needs-human bucket. Week one is report-only: propose priority and labels, but do not apply labels, comment, close, reopen, assign, or edit source files. Treat duplicates as possible duplicates for human confirmation. Escalate ambiguous items and anything touching auth, payments, security, billing, infrastructure, or public API. End with the top five and the human decisions needed."
```

- `--deliver local` writes output to `~/.hermes/cron/output/`; routine reports
do not enter a human chat or connected home channel.
- `--skill issue-triage` attaches the shared classifier without authorizing
GitHub writes.
- For a quieter repository, use a daily cadence such as `0 9 * * 1-5`.
- If issue reads use a separate GitHub skill, repeat `--skill` to attach it while
keeping its credentials read-only.

Run one tick manually before relying on the schedule:

```bash
hermes cron list
hermes cron run <job-id>
hermes cron status
```

## State file

The state shape matches the shared
[`issue-triage` pattern](../../patterns/issue-triage.md) and starter:

```markdown
# Issue Triage State
Last run: 2026-08-19 09:00 UTC
Open actionable: 14 (was 17)
New since last run: 3
Needs human: 2

## Top 5 (by loop score)
- #487 (bug, p1, 2d old) — "Crash on export with large files" — suggested: bug, needs-repro, area:export

## Proposed Labels (not applied — L1)
- #487: `bug`, `needs-repro`, `area:export`

## Possible Duplicates (human confirm)
- #488 — possible duplicate of #412

## Noise / Ignored
- #460 — usage question; redirect candidate for human review
```

Each run prunes resolved entries, keeps proposed actions concise, and records
uncertainty instead of silently deciding it away. Do not copy credentials,
private issue content, or other secrets into the state file.

## Pairing with Daily Triage

Issue Triage runs every two hours or daily and maintains the detailed queue in
`issue-triage-state.md`. Daily Triage reads its Top 5 and carries only issue
numbers and short summaries into `STATE.md` High Priority; it does not duplicate
full issue bodies.

## After the reports earn trust

Keep `--deliver local` during calibration. A human may later switch delivery to
`origin`, a configured home channel such as `slack` or `feishu`, or a specific
`platform:chat_id:thread_id` after reviewing channel `allowFrom` and mention
rules. Delivery changes where the report appears, not what the loop may do.

L2 may apply only allowlisted labels such as `area:*`, `needs-repro`, and
`needs-info`, and only after an independent verifier passes. It still never
auto-closes issues or applies P0, P1, `security`, or `breaking-change` labels.
Pause the job before changing this boundary:

```bash
hermes cron pause <job-id>
hermes cron edit <job-id> --prompt "<reviewed L2 prompt>"
hermes cron resume <job-id>
```

## Safety and human gates

- Week one: propose only; never label, comment, assign, close, or reopen.
- Possible duplicates always need human confirmation.
- Auth, payments, security, billing, infrastructure, and public API items remain
human-owned.
- Large bursts of new issues and unclear reproductions go to `Needs human`.
- Keep issue-tracker credentials read-only until a human explicitly approves an
L2 label allowlist and verifier.

## References

- [Issue Triage pattern](../../patterns/issue-triage.md)
- [Issue Triage starter](../../starters/issue-triage/)
- [Hermes Daily Triage](./daily-triage.md)
- [Safety and human gates](../../docs/safety.md)
- [Primitives matrix](../../docs/primitives-matrix.md)