Docs
Workflows and hooks
Reusable column templates, the review and done roles, and hooks that fire when a task enters or leaves a column.
A workflow is a reusable template for the starting shape of a project: an ordered set of columns, optional tags, and optional project-context defaults. Two ship built in, and you can define your own from Workflows in the sidebar.
| Workflow | Columns |
|---|---|
| Default | Backlog, Todo, In Progress, Review, Done |
| Simple | Todo, In Progress, Done |
Choosing a workflow when you create a project seeds that project's columns. It is a starting point, not a constraint: columns can be renamed, reordered, added, and removed per project afterwards.
Column roles
Two roles can be attached to a column, and they are what let agents and automation talk about your board without knowing your column names.
- A column with the
reviewrole is wheremove_to_reviewsends a task. - A column with the
donerole is wherecomplete_tasksends it.
In the Default workflow, Review and Done carry those roles. Rename Review to "Needs a look" and move_to_review keeps working, because the role travelled with the column rather than the label.
If a project has no column with the review role, move_to_review has nowhere to send work, and that is intentional. Pekan does not impose a global review stage, and it does not invent one. Whether review exists at all is a property of your project's columns.
Hooks
A hook is automation attached to a column. It fires when a task enters or leaves that column, and it is defined on the workflow or the project column, not on the task.
Every hook has a trigger, on_enter_column or on_leave_column, and one action:
| Action | What it does |
|---|---|
set_tags | Adds, removes, or replaces tags on the task |
set_assignee | Assigns the task to a named person or agent, or unassigns it |
set_dates | Sets or clears the start and due dates |
run_agent_action | Runs a named agent action against the task |
run_command | Launches a local shell command, with a timeout |
Hooks reference tags, assignees, and agent actions by name rather than by internal id. That is what makes a workflow portable: exporting a workflow and importing it into another workspace keeps the hooks meaningful, because the names resolve there too. Existence is checked when the hook runs, not when you save it, so a hook naming something that does not exist yet is allowed and simply reports a failure if it fires.
Every hook execution is written to the task's activity log, including failures, so automation is as auditable as anything a person did by hand.
run_command starts a local process on your machine. It runs with your permissions, so treat a workflow you import from elsewhere the way you would treat any script from elsewhere: read its commands before you enable it.A worked example
A common setup for running agents is:
- On entering In Progress,
set_assigneeto the agent that should pick the work up. - On entering Review,
set_tagsto addneeds-human, so the Tasks view filter shows exactly what is waiting on you. - On entering Review,
run_commandto launch your test suite, so the result is attached to the task rather than living in a terminal you have already closed.
Agents and workflows
Agents can read workflows with list_workflows and create them with create_workflow. list_workflows returns both built-in templates and your custom ones, so an agent asking what a project's flow looks like gets the real answer rather than an assumption about Todo and Done.