Writing a new recipe
How to write, test, and register a recipe so a new bee can be triggered from Slack, Jira, or the dashboard.
After this page you can write a recipe YAML file, run it locally from the CLI, and register it in the bee catalog so anyone at Cube can trigger it. Recipes are plain YAML, so anyone on the team can write one.
Anatomy of a recipe
A recipe is a standard Goose recipe YAML file in recipes/. It has five parts that matter:
instructions: the bee's standing orders, covering role, constraints, and the three phases.parameters: the inputs the recipe accepts (repo_url,ticket_description_path, context file paths). Each has akey,input_type,requirement, anddescription.extensions: the tools the bee gets. Every recipe uses the builtindeveloperextension.prompt: the per-run task, with{{ parameter }}placeholders filled in at launch.version,title,description: metadata.
Read recipes/cleaner-bee.yaml as the reference implementation; it shows all the patterns below in one file.
Minimal skeleton
version: "1.0.0"
title: "Cube Example Bee"
description: "One line on what this bee does."
instructions: |
You are a senior software engineer at 3 Sided Cube. [Role, constraints.]
PHASE 1 - ANALYSE (max 15 actions):
- Clone the repo, read the ticket, build a worklist.
PHASE 2 - ACT (max 25 actions):
- Apply minimal, safe fixes. Flag anything needing human judgement.
PHASE 3 - SHIP (must complete, use remaining actions):
- Lint, test, branch, commit, push, open PR.
- This phase is NON-NEGOTIABLE.
parameters:
- key: repo_url
input_type: string
requirement: required
description: "GitHub repo URL"
- key: ticket_description_path
input_type: string
requirement: required
description: "File path to the ticket text"
extensions:
- type: builtin
name: developer
timeout: 300
prompt: |
Work on {{ repo_url }}. Read the ticket at {{ ticket_description_path }}.
IMPORTANT: Only touch files within the stated scope.
You MUST reach Phase 3 and open a PR. This is the most important outcome.
When you have opened the PR, STOP. Your work is done.Phases and budgets
Every recipe has three phases with explicit action limits. Without budgets the bee explores indefinitely and never ships. The budgets are soft: instructions to the model, not enforced by code. GOOSE_MAX_TURNS (set in .env, 100 in the deployed environments) is the hard backstop.
Two other rules the prompt must follow:
- Scope it. Say exactly what is in and out of scope. The more specific the ticket and prompt, the less the bee wanders.
- Mandate the PR and the stop. End with an explicit "open a PR, then STOP" condition, as in the skeleton above.
Do not use Goose's retry: blocks: the shell check runs in the workdir root, not the cloned repo, so it fails and re-triggers the whole recipe.
Test locally with the CLI
./scripts/run-agent.sh \
--recipe your-recipe \
--repo "https://github.com/3sidedcube/some-project" \
--ticket "Short, scoped task description"The runner loads .env, creates a clean temp directory, copies the context files from universal-rules/ into a context/ folder inside it, and calls goose run with your recipe. If your recipe declares context parameters (cube_standards_path, stride_checklist_path, pr_rules_path), the runner already passes them; a new context file needs a matching --params entry added in scripts/run-agent.sh. Run the recipe at least twice to verify it ships a PR reliably before opening a PR on this repo.
Make it invocable
A recipe file alone isn't reachable from the triggers. The bee catalog at bees/ is the source of truth for routing: the event router, the scheduled-bee tick, and the dashboard "Run bee" form all read from it.
- Copy
bees/TEMPLATE.yamltobees/<name>.yamland fill it in. Slack mention names, Jira labels, dashboard listing, and schedule support all live there, and therecipesblock points at your recipe file (primaryfor analysis-only bees;writer/tester/validatorroles for code-modification bees). - Validate it:
node scripts/validate-bee-catalog.js(also runs in CI, and regeneratesbees/INDEX.mdwith--write-index).
That's it: a new bee is a single PR with the catalog entry plus its recipe, no trigger or scheduler code changes. Once merged and deployed, it's triggerable from Slack, Jira, and the dashboard. See the recipes section for what the existing bees look like in practice.