View as markdown

Creating custom workflows

Hive ships with two workflows out of the box: coding, the nine-stage inbox → … → done pipeline that opens PRs, and content, a research pipeline. Most people stop there, assuming those two are the product.

They aren’t. They’re just the two pipelines someone already wrote down.

The engine underneath is generic. A workflow is nothing more than an ordered list of stages described in a YAML file — and you can author your own, per project, in a few minutes. Writing. Research. Triage. Translation. A weekly-report generator. Any task that moves through a sequence of steps, where an AI agent does the work at each step, is a workflow Hive can run. You describe the steps; the daemon runs the pipeline.

This guide takes you from the mental model to a custom workflow you can run today. Every code block, command, and output here is copy-pasteable and real. If you’re new to Hive’s core ideas, read Concepts and Getting started first.

  1. The mental model
  2. Anatomy of a descriptor
    1. Field reference
  3. Creating a workflow
    1. A. In an existing project — hive workflow new
      1. Seed from a sample instead of the blank stub
    2. B. In a fresh project — hive init --new-workflow
  4. Writing stage instructions
  5. Running a task through your workflow
  6. A complete worked example, start to finish
  7. Advanced options
  8. Gotchas (learned the hard way)
  9. See also

The mental model

Hive is a folder-as-agent pipeline. Every task is a directory, and at any moment it lives under exactly one stage folder:

<project>/.hive-state/stages/
  1-inbox/       <- a task starts here
  2-research/
  3-draft/
  4-edit/
  5-done/        <- and finishes here

That’s the whole data model. A task’s stage is which folder it’s in. Advancing a task is the folder moving from N-stage to N+1-stage. There is no hidden database tracking state — the filesystem is the state.

Two things make it move:

  • An agent stage runs an AI agent with an instruction — a markdown file telling it what to do. The agent reads the task’s prior files and writes the stage’s output file. That output becomes context for the next stage.
  • The hive daemon advances tasks for you. Enabled by default at hive init, it watches your projects, runs each ready stage’s agent, and moves the task to the next stage automatically. You author the workflow, create a task, and watch — the daemon does the driving.

That second point is the one to internalize. In normal use you never touch the folders yourself. The daemon does.

Because the model is just folders, though, you can reach in by hand when you need to — hive run to run the current stage, hive approve to advance it, or literally mv the folder to move it. That always works, and it’s invaluable for intervention: stepping a stuck task, re-running one that went sideways, nudging something past a gate. But it’s the escape hatch, not the workflow. Day to day, you create the task and let the daemon take it from there.

A workflow descriptor is the YAML that names the stages and says which are agent stages, what each one reads and writes, and what instruction drives it. That file is the thing you author. Everything else follows from it.


Anatomy of a descriptor

A descriptor is short enough to read top to bottom and understand completely. Here’s a real one — a writing pipeline that takes an idea and returns a finished piece — fully annotated:

id: "writing"                 # must match the filename (writing.yml) and the
                              # SAFE_SLUG rule: lowercase, starts with a letter,
                              # [a-z0-9-]. Cannot be a built-in (coding/content).
stages:
  - name: inbox               # stage 1. Its folder is "1-inbox".
    kind: terminal            # terminal = no agent; a gate the task rests at.
    state_file: idea.md       # the file `hive new` writes your idea into.

  - name: research            # stage 2 -> folder "2-research".
    kind: agent               # agent = Hive runs an AI agent here.
    state_file: research.md   # the file this stage PRODUCES.
    instruction: ./writing/research.md   # the markdown telling the agent what
                              # to do. Path is relative to the descriptor.

  - name: draft
    kind: agent
    state_file: draft.md
    instruction: ./writing/draft.md

  - name: edit
    kind: agent
    state_file: edit.md
    instruction: ./writing/edit.md

  - name: done                # the LAST stage MUST be terminal — a task at the
    kind: terminal            # final stage has nowhere to advance, so a
    state_file: done.md       # non-terminal last stage would be undroppable.

Read it once and the shape is clear: an entry gate, three agents that each do one job, an exit gate. The task flows top to bottom. Each agent stage names the file it produces and the instruction that drives it.

Field reference

Every field a stage can carry, and what it means:

Field Required Meaning
id yes Workflow id. Matches the filename stem and SAFE_SLUG; not a built-in.
stages yes Ordered list. Indices are implicit: stage N lives in folder N-<name>.
name yes Stage name (SAFE_SLUG). The folder is <index>-<name>.
kind yes agent (runs an agent) or terminal (a gate, no agent).
state_file yes A bare filename (no /) the stage reads/writes inside the task folder.
instruction agent stages Markdown file the agent is given. Relative to the descriptor. Exactly one of instruction or skill.
skill agent stages A skill name to invoke instead of an inline instruction.
advance_verb optional The verb that arrives at this stage (defaults to the stage name). The first stage must not declare one.
permissions optional, agent only Per-stage tool/permission scope (read-only, scoped, yolo).

The parser is strict on purpose, so a typo fails at author time instead of halfway through a run. The rules it enforces:

  • Stage indices are 1..N in order; names and folders are unique.
  • The last stage must be kind: terminal.
  • state_file is a bare basename (no /, not ./..).
  • Agent stages declare exactly one of skill or instruction.
  • instruction must point at a readable file.

None of these are arbitrary. A non-terminal last stage would leave a finished task with nowhere to go; a state_file with a slash in it would write outside the task folder at runtime. The parser catches both before you ever start a run.


Creating a workflow

You don’t write the YAML from a blank page. Hive scaffolds it for you, and which command you reach for depends on one thing: whether the project already exists.

A. In an existing project — hive workflow new

You’re already in a project and want to add a workflow to it:

cd my-project
hive workflow new writing

This scaffolds a blank inbox → work → done starter:

.hive-state/workflows/writing.yml          # the descriptor
.hive-state/workflows/writing/work.md       # the work-stage instruction (a stub)

and prints:

hive: created workflow writing at .../workflows/writing.yml
edit: .../workflows/writing/work.md (the `work` stage instruction — a placeholder until you define it)
next: hive new my-project --workflow writing "<your idea>"

Now edit the instruction(s) that the edit: line points at. The blank stub literally says “Edit this file to define what the work stage should do.” — so if you skip this step, the agent reads that sentence and does nothing useful. Define the work, then create a task.

Seed from a sample instead of the blank stub

A one-stage blank is a fine starting point when you know exactly what you’re building. More often you want a real, multi-stage pipeline to shape, not a bare stub. Pass --template:

hive workflow new writing --template writing

This renders a curated sample descriptor with your id and copies its real stage instructions in — actual briefs, not placeholders. Pass an unknown template name and Hive lists what’s available:

$ hive workflow new x --template bogus
hive workflow: unknown workflow template "bogus" (available: blank, research, writing)

The three that ship:

Template Stages
blank (default) inbox → work → done (one placeholder instruction)
writing inbox → research → draft → edit → done
research inbox → gather → synthesize → report → done

A multi-stage template prints edit: <id>/ (N stage instructions to fill in) — edit those to your taste, then create a task.

B. In a fresh project — hive init --new-workflow

Starting from nothing? Bootstrap the project and bind it to a custom workflow in a single command — no init → create → re-init dance:

hive init --new-workflow writing ~/Dev/my-writing

This runs init, scaffolds the writing descriptor and its instructions, and sets it as the project’s default_workflow. Edit the scaffolded instructions, and because the default is already bound, a plain hive new routes through it — no --workflow flag needed:

hive new my-writing "an essay on folder-as-agent pipelines"

Writing stage instructions

The descriptor is the skeleton. The instruction files are where the work actually lives — each one is a single agent’s brief, and the quality of your pipeline is the quality of these files.

There’s one convention that consistently works: tell the agent what to read (the prior stages’ outputs) and what to produce (this stage’s state_file). You don’t have to wire context by hand — earlier .md artifacts in the task folder are passed to the agent automatically. Your job is to point at the right ones and be specific about the output.

Here are the three instructions for the writing pipeline.

writing/research.md:

You are the **research** stage of a writing pipeline.

Read `idea.md` (the topic). Produce `research.md` with:
- Framing — audience, angle, the single takeaway.
- 5–8 key points worth including, each with why it matters.
- An outline (section headings, in order).
- Open questions for the draft stage.

Be specific. Do not write the piece — that is the draft stage's job.

writing/draft.md:

You are the **draft** stage.

Using `idea.md` and `research.md`, write a complete first draft in `draft.md`.
Follow the outline, keep the takeaway front and centre, plain direct voice.
A strong complete draft is the goal — the edit stage will polish.

writing/edit.md:

You are the **edit** stage.

Revise `draft.md` into a final version in `edit.md`. Tighten every sentence,
fix flow and tone, verify the takeaway lands. Output the full final text.

Notice how each stage builds on the last. research produces the outline; draft reads research.md and follows it; edit sees both idea.md and draft.md and polishes. The pipeline is a relay, and each instruction tells its runner what baton it’s receiving and what it’s handing off.


Running a task through your workflow

The setup is done. Running a task is one command.

hive new my-project --workflow writing "an essay on durable automation"

Tip: put options before the project too if you like — hive new --workflow writing my-project "…". Either ordering is accepted. (If the project’s default_workflow is writing, drop the flag entirely.)

That’s the whole interaction. Hive captures your idea into idea.md under 1-inbox/, and — with the daemon running — takes it from there. It runs research, then draft, then edit, moving the task forward one stage at a time until it lands in done. You don’t touch a thing. You just watch:

hive status            # where every task is, across all your projects

You’ll also see Hive print a manual next: line — something like mv … && hive run <id>. That’s the fallback for when the daemon is off, or for when you want to step a task yourself: hive run <id> runs its current stage now, hive approve <id> advances it, and mv moves the folder directly. Reach for these to intervene — to unstick something, re-run a stage, push past a gate. They are not the normal path. The normal path is: create the task, watch hive status, let the daemon drive.


A complete worked example, start to finish

Here’s everything above in one sequence — a fresh project to a finished essay, with the daemon doing the work in between:

# 1. A fresh project bound to a new "writing" workflow, seeded from the sample.
hive init --new-workflow writing ~/Dev/essays
cd ~/Dev/essays

# 2. Customize the stage instructions to your voice (they were copied in real,
#    not as stubs, because we seeded from the `writing` template).
$EDITOR .hive-state/workflows/writing/{research,draft,edit}.md

# 3. Create a task — no --workflow needed, the default is already "writing".
hive new essays "what folder-as-agent pipelines teach us about durable automation"

# 4. The daemon takes it from here: inbox -> research -> draft -> edit -> done.
hive status            # watch it move through the stages, across all projects
# (only if you want to step it yourself: `hive run <id>`, or `mv` the folder)

When the task reaches 5-done, edit.md holds your finished piece. The daemon got it there. You authored the workflow once and dropped in an idea — that was the entire job.


Advanced options

Once the basics click, a handful of fields let you shape pipelines that go beyond the linear-agent default.

  • kind: terminal vs agent — terminal stages are gates with no agent: the entry inbox, the exit done, or any human-review pause you want to insert mid-pipeline. Agent stages run the AI. Put a terminal stage between two agents and the task rests there until you advance it — a built-in approval gate.
  • skill instead of instruction — point a stage at a named skill rather than an inline markdown brief: skill: ce-brainstorm. Use this to reuse packaged behavior instead of re-describing it.
  • Per-stage permissions — scope an agent stage’s tools so a stage can only do what it needs to: ```yaml
    • name: research kind: agent state_file: research.md instruction: ./writing/research.md permissions: read-only # or: { preset: scoped, tools: [Read, Grep] } ``` Three presets: read-only, scoped (an allow-list of tools, dirs, and bash), and yolo (no scoping). A present-but-blank permissions: is rejected (fail-closed) — so you can never silently grant full access by leaving the key empty.
  • default_workflow — bind a workflow as the project default in .hive-state/config.yml, and hive new uses it without --workflow.
  • advance_verb — customize the verb that arrives at a stage. It defaults to the stage name, and the first stage must not declare one.

Gotchas (learned the hard way)

A few sharp edges. Each one is here because it bit someone first.

  • Edit the scaffolded instruction before running. A blank hive workflow new leaves a placeholder, and running it as-is hands the agent the literal text “Edit this file…” — which it will dutifully not act on. The edit: line in the command output tells you exactly what to open. (Seeding with --template sidesteps this entirely: you get real instructions.)
  • The last stage must be terminal. Otherwise a finished task can neither advance nor drop — it’s stranded at a stage with nowhere to go.
  • state_file is a bare filename. Something like sub/idea.md passes validation but fails at runtime. Keep it flat: idea.md, work.md.
  • id can’t shadow a built-in (coding, content), and it must match the descriptor filename.
  • Custom workflows are per project. Hive discovers them from <hive_state_path>/workflows/*.yml, and once discovered they’re available to hive new --workflow, status, run, approve, and the daemon — the same surfaces the built-ins use.

See also

  • Concepts — folder-as-agent, the stage state machine, and the marker protocol the pipeline runs on.
  • Getting started — install Hive and run your first task end to end.
  • Command reference — every hive verb, including init, new, run, approve, and status.
  • The built-in coding and content workflows — full-featured descriptors to learn from when your own pipeline outgrows the basics.