Project: skylarbpayne/hermes-workflows. "Code-first durable workflows for agent work, Review Queues, Workflow Workers, and receipts."
License: Apache License 2.0. Full license text is in LICENSE alongside this file.
Snapshot: Frozen copy of hermes-workflows-creating/SKILL.md as of 2026-07-03. The maintained version lives upstream and may have evolved since this snapshot.
Hermes Workflows — creating workflows
Use this when designing or implementing a workflow definition. This skill is generic authoring guidance, not a place for project-specific workflow shapes.
Product model
Hermes Workflows are ordinary Python orchestration code with durable execution state.
Use the public authoring primitives:
@workflow for the durable workflow entrypoint.
agent(...) for judgment-heavy or generative work.
bash(...) for deterministic local commands and receipts.
ask(...) for typed review input and external-action approval gates.
parallel(...) for fan-out/fan-in.
pipeline(...) for staged transformations over items.
goal(...) for loop-until-done semantics when available/appropriate.
Do not expose runtime plumbing (ctx.handoff, raw signals, internal waits, leases, outbox commands) in normal workflow authoring unless debugging the runtime itself.
Authoring checklist
- Define the purpose and side-effect boundary.
- Define typed dataclass inputs and outputs.
- Split steps by ownership:
- agent judgment/synthesis/editing →
agent(...)
- deterministic command/check/evidence →
bash(...)
- human decision or external side-effect authorization →
ask(...)
- Make artifacts reviewable inline in the Review Queue; paths alone are not enough.
- Add explicit gates before external effects: send, publish, schedule, commit/push/PR/merge, deploy, payment, credentials, destructive data changes.
- Record receipts: commands run, stdout/stderr/exit code, artifact paths, external handles, side-effect ledger.
- Add smoke tests that run without provider credentials by using
mock_output where appropriate.
Minimal skeleton
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Literal
from hermes_workflows import agent, ask, bash, parallel, workflow
@dataclass
class MyWorkflowInput:
topic: str
@dataclass
class DraftPacket:
title: str
body: str
risks: list[str] = field(default_factory=list)
@dataclass
class ReviewDecision:
action: Literal["approve", "request_changes", "drop"]
feedback: str | None = None
@workflow
async def my_workflow(inputs: MyWorkflowInput) -> dict:
req = inputs if isinstance(inputs, MyWorkflowInput) else MyWorkflowInput(**dict(inputs or {}))
preflight = await bash(
"python -V && git status --short",
key="preflight",
timeout_seconds=60,
)
draft = await agent(
"draft_packet",
prompt="Create a concise reviewable draft from the input.",
input={"request": req, "preflight": preflight.stdout[-4000:]},
returns=DraftPacket,
mock_output={"title": req.topic, "body": "Demo draft", "risks": []},
)
decision = await ask(
"Review this draft before any external side effect.",
key="review_draft_packet",
input={"draft": draft, "side_effects": {"published": False}},
returns=ReviewDecision,
)
return {"status": decision.action, "draft": draft, "decision": decision}
Step design rules
- Prefer small named steps with stable keys; keys should describe the public review/action, not internal plumbing.
- Keep workflow bodies intention-level. Hide retry loops, per-item keys, and feedback routing in helper functions when they get noisy.
- Rejections must roundtrip into workflow logic. If a human says
request_changes, feed the feedback into a targeted regeneration step.
- For fan-out review, use
ask(...) inside parallel(...) only when each review is independent and can emit its own Review Queue request.
- For code workflows, distinguish plan approval, implementation/review approval, and landing approval. One approval does not authorize all later side effects.
- For generated files, return paths plus summaries/checks/hashes where useful.
Testing pattern
At minimum:
PYTHONPATH=src:. python -m compileall -q path/to/workflow.py
PYTHONPATH=src:. python -m pytest -q tests/test_your_workflow.py
Test:
- first wait/review key appears;
- typed dataclass outputs rehydrate correctly;
- approval/request-changes paths behave as expected;
- side-effect flags remain false before explicit final gates;
- mock-output path runs without provider credentials;
- deterministic receipts are preserved in status/artifacts.
Placement guidance
- Runtime/package examples can live in the Hermes Workflows repo.
- Normal user/team workflows should live in the owning workspace or a separate private workflows repo and be exposed through that workspace’s workflow registry/catalog.
- Do not bake private business/blog/event workflows into the runtime package unless explicitly making a public example.
Do not put here
- One-off content/event/email/coding workflow designs for a specific user or demo.
- Personal infrastructure preferences.
- Repo-specific launch history.
- Runtime implementation details better suited to package-development docs.
1---2name: hermes-workflows-creating3description: Design and author Hermes Workflows with typed inputs/outputs, agent/bash/ask/parallel/pipeline/goal primitives, Review Queue gates, artifacts, and verification receipts. Use when creating or modifying workflow definitions.4---56> **Project:** [skylarbpayne/hermes-workflows](https://github.com/skylarbpayne/hermes-workflows). "Code-first durable workflows for agent work, Review Queues, Workflow Workers, and receipts."7>8> **License:** [Apache License 2.0](https://github.com/skylarbpayne/hermes-workflows/blob/main/LICENSE). Full license text is in [`LICENSE`](LICENSE) alongside this file.9>10> **Snapshot:** Frozen copy of [`hermes-workflows-creating/SKILL.md`](https://github.com/skylarbpayne/hermes-workflows/blob/main/src/hermes_workflows/plugin_skills/hermes-workflows-creating/SKILL.md) as of 2026-07-03. The maintained version lives upstream and may have evolved since this snapshot.1112# Hermes Workflows — creating workflows1314Use this when designing or implementing a workflow definition. This skill is generic authoring guidance, not a place for project-specific workflow shapes.1516## Product model1718Hermes Workflows are ordinary Python orchestration code with durable execution state.1920Use the public authoring primitives:2122- `@workflow` for the durable workflow entrypoint.23- `agent(...)` for judgment-heavy or generative work.24- `bash(...)` for deterministic local commands and receipts.25- `ask(...)` for typed review input and external-action approval gates.26- `parallel(...)` for fan-out/fan-in.27- `pipeline(...)` for staged transformations over items.28- `goal(...)` for loop-until-done semantics when available/appropriate.2930Do not expose runtime plumbing (`ctx.handoff`, raw signals, internal waits, leases, outbox commands) in normal workflow authoring unless debugging the runtime itself.3132## Authoring checklist33341. Define the purpose and side-effect boundary.352. Define typed dataclass inputs and outputs.363. Split steps by ownership:37 - agent judgment/synthesis/editing → `agent(...)`38 - deterministic command/check/evidence → `bash(...)`39 - human decision or external side-effect authorization → `ask(...)`404. Make artifacts reviewable inline in the Review Queue; paths alone are not enough.415. Add explicit gates before external effects: send, publish, schedule, commit/push/PR/merge, deploy, payment, credentials, destructive data changes.426. Record receipts: commands run, stdout/stderr/exit code, artifact paths, external handles, side-effect ledger.437. Add smoke tests that run without provider credentials by using `mock_output` where appropriate.4445## Minimal skeleton4647```python48from __future__ import annotations4950from dataclasses import dataclass, field51from typing import Literal5253from hermes_workflows import agent, ask, bash, parallel, workflow545556@dataclass57class MyWorkflowInput:58 topic: str596061@dataclass62class DraftPacket:63 title: str64 body: str65 risks: list[str] = field(default_factory=list)666768@dataclass69class ReviewDecision:70 action: Literal["approve", "request_changes", "drop"]71 feedback: str | None = None727374@workflow75async def my_workflow(inputs: MyWorkflowInput) -> dict:76 req = inputs if isinstance(inputs, MyWorkflowInput) else MyWorkflowInput(**dict(inputs or {}))7778 preflight = await bash(79 "python -V && git status --short",80 key="preflight",81 timeout_seconds=60,82 )8384 draft = await agent(85 "draft_packet",86 prompt="Create a concise reviewable draft from the input.",87 input={"request": req, "preflight": preflight.stdout[-4000:]},88 returns=DraftPacket,89 mock_output={"title": req.topic, "body": "Demo draft", "risks": []},90 )9192 decision = await ask(93 "Review this draft before any external side effect.",94 key="review_draft_packet",95 input={"draft": draft, "side_effects": {"published": False}},96 returns=ReviewDecision,97 )9899 return {"status": decision.action, "draft": draft, "decision": decision}100```101102## Step design rules103104- Prefer small named steps with stable keys; keys should describe the public review/action, not internal plumbing.105- Keep workflow bodies intention-level. Hide retry loops, per-item keys, and feedback routing in helper functions when they get noisy.106- Rejections must roundtrip into workflow logic. If a human says `request_changes`, feed the feedback into a targeted regeneration step.107- For fan-out review, use `ask(...)` inside `parallel(...)` only when each review is independent and can emit its own Review Queue request.108- For code workflows, distinguish plan approval, implementation/review approval, and landing approval. One approval does not authorize all later side effects.109- For generated files, return paths plus summaries/checks/hashes where useful.110111## Testing pattern112113At minimum:114115```bash116PYTHONPATH=src:. python -m compileall -q path/to/workflow.py117PYTHONPATH=src:. python -m pytest -q tests/test_your_workflow.py118```119120Test:121122- first wait/review key appears;123- typed dataclass outputs rehydrate correctly;124- approval/request-changes paths behave as expected;125- side-effect flags remain false before explicit final gates;126- mock-output path runs without provider credentials;127- deterministic receipts are preserved in status/artifacts.128129## Placement guidance130131- Runtime/package examples can live in the Hermes Workflows repo.132- Normal user/team workflows should live in the owning workspace or a separate private workflows repo and be exposed through that workspace’s workflow registry/catalog.133- Do not bake private business/blog/event workflows into the runtime package unless explicitly making a public example.134135## Do not put here136137- One-off content/event/email/coding workflow designs for a specific user or demo.138- Personal infrastructure preferences.139- Repo-specific launch history.140- Runtime implementation details better suited to package-development docs.