Skip to content

Commit b71ada6

Browse files
authored
docs: add Hermes issue triage example (#539)
Co-authored-by: hushen <190065939+918154429@users.noreply.github.com>
1 parent 9db4df4 commit b71ada6

3 files changed

Lines changed: 138 additions & 2 deletions

File tree

examples/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Start with [primitives-matrix.md](../docs/primitives-matrix.md) to map capabilit
2929
| 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) |
3030
| 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) |
3131
| 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) |
32-
| 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) |
32+
| 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) |
3333

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

@@ -41,5 +41,5 @@ L2 patterns ship multi-tool skills inside one starter folder — see `starters/<
4141
| 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` |
4242
| 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` |
4343
| 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) |
44-
| 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) |||| |
44+
| 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) |
4545
| 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/) |

examples/hermes/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
| [daily-triage.md](./daily-triage.md) | Daily Triage (L1 report → L2 assisted) |
88
| [pr-babysitter.md](./pr-babysitter.md) | PR Babysitter (L1 report → L2 worktree + verifier) |
99
| [ci-sweeper.md](./ci-sweeper.md) | CI Sweeper (L1 report → L2 worktree + verifier) |
10+
| [issue-triage.md](./issue-triage.md) | Issue Triage (L1 propose-only → L2 allowlisted labels) |
1011

1112
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.
1213

examples/hermes/issue-triage.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Issue Triage — Hermes Agent (`hermes cron`)
2+
3+
Keep the issue queue legible so humans and Daily Triage always know the top five
4+
actionable items. Hermes runs the shared `issue-triage` skill in a fresh cron
5+
session and keeps routine output local while the loop earns trust.
6+
7+
Week one is deliberately **propose-only**: the job updates
8+
`issue-triage-state.md` with suggested priority and labels, but never changes an
9+
issue or repository.
10+
11+
## Setup
12+
13+
Install and configure [Hermes Agent](https://hermes-agent.nousresearch.com/docs),
14+
then copy the shared state example and skill:
15+
16+
```bash
17+
hermes setup
18+
19+
cp starters/issue-triage/issue-triage-state.md.example \
20+
issue-triage-state.md
21+
22+
mkdir -p ~/.hermes/skills/issue-triage
23+
cp templates/SKILL.md.issue-triage \
24+
~/.hermes/skills/issue-triage/SKILL.md
25+
26+
hermes skills list | grep issue-triage
27+
```
28+
29+
Use `.hermes/skills/issue-triage/` instead when the skill should be available
30+
only inside this project. The job also needs read-only access to the issue
31+
tracker, for example through an authenticated GitHub CLI or a GitHub-capable
32+
skill. Do not grant write access for the week-one loop.
33+
34+
## Week one — propose only
35+
36+
Start with a two-hour cadence on an active repository. `--workdir "$PWD"` pins
37+
the repository and injects its `AGENTS.md`, `CLAUDE.md`, or `.cursorrules` into
38+
the cron session.
39+
40+
```bash
41+
hermes cron create "0 */2 * * *" \
42+
--name "Issue triage" \
43+
--deliver local \
44+
--skill issue-triage \
45+
--workdir "$PWD" \
46+
"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."
47+
```
48+
49+
- `--deliver local` writes output to `~/.hermes/cron/output/`; routine reports
50+
do not enter a human chat or connected home channel.
51+
- `--skill issue-triage` attaches the shared classifier without authorizing
52+
GitHub writes.
53+
- For a quieter repository, use a daily cadence such as `0 9 * * 1-5`.
54+
- If issue reads use a separate GitHub skill, repeat `--skill` to attach it while
55+
keeping its credentials read-only.
56+
57+
Run one tick manually before relying on the schedule:
58+
59+
```bash
60+
hermes cron list
61+
hermes cron run <job-id>
62+
hermes cron status
63+
```
64+
65+
## State file
66+
67+
The state shape matches the shared
68+
[`issue-triage` pattern](../../patterns/issue-triage.md) and starter:
69+
70+
```markdown
71+
# Issue Triage State
72+
Last run: 2026-08-19 09:00 UTC
73+
Open actionable: 14 (was 17)
74+
New since last run: 3
75+
Needs human: 2
76+
77+
## Top 5 (by loop score)
78+
- #487 (bug, p1, 2d old) — "Crash on export with large files" — suggested: bug, needs-repro, area:export
79+
80+
## Proposed Labels (not applied — L1)
81+
- #487: `bug`, `needs-repro`, `area:export`
82+
83+
## Possible Duplicates (human confirm)
84+
- #488 — possible duplicate of #412
85+
86+
## Noise / Ignored
87+
- #460 — usage question; redirect candidate for human review
88+
```
89+
90+
Each run prunes resolved entries, keeps proposed actions concise, and records
91+
uncertainty instead of silently deciding it away. Do not copy credentials,
92+
private issue content, or other secrets into the state file.
93+
94+
## Pairing with Daily Triage
95+
96+
Issue Triage runs every two hours or daily and maintains the detailed queue in
97+
`issue-triage-state.md`. Daily Triage reads its Top 5 and carries only issue
98+
numbers and short summaries into `STATE.md` High Priority; it does not duplicate
99+
full issue bodies.
100+
101+
## After the reports earn trust
102+
103+
Keep `--deliver local` during calibration. A human may later switch delivery to
104+
`origin`, a configured home channel such as `slack` or `feishu`, or a specific
105+
`platform:chat_id:thread_id` after reviewing channel `allowFrom` and mention
106+
rules. Delivery changes where the report appears, not what the loop may do.
107+
108+
L2 may apply only allowlisted labels such as `area:*`, `needs-repro`, and
109+
`needs-info`, and only after an independent verifier passes. It still never
110+
auto-closes issues or applies P0, P1, `security`, or `breaking-change` labels.
111+
Pause the job before changing this boundary:
112+
113+
```bash
114+
hermes cron pause <job-id>
115+
hermes cron edit <job-id> --prompt "<reviewed L2 prompt>"
116+
hermes cron resume <job-id>
117+
```
118+
119+
## Safety and human gates
120+
121+
- Week one: propose only; never label, comment, assign, close, or reopen.
122+
- Possible duplicates always need human confirmation.
123+
- Auth, payments, security, billing, infrastructure, and public API items remain
124+
human-owned.
125+
- Large bursts of new issues and unclear reproductions go to `Needs human`.
126+
- Keep issue-tracker credentials read-only until a human explicitly approves an
127+
L2 label allowlist and verifier.
128+
129+
## References
130+
131+
- [Issue Triage pattern](../../patterns/issue-triage.md)
132+
- [Issue Triage starter](../../starters/issue-triage/)
133+
- [Hermes Daily Triage](./daily-triage.md)
134+
- [Safety and human gates](../../docs/safety.md)
135+
- [Primitives matrix](../../docs/primitives-matrix.md)

0 commit comments

Comments
 (0)