Bee role config (.paseka/bees/<role>.yaml)¶
A bee is a named role bound to an adapter, prompt template, and optional routing / completion rules. Each file under .paseka/bees/ defines one role.
Implementation: internal/colony/bee.go (Bee struct, LoadBee), plus command.go, params.go, routing.go, run_summary.go, completion.go, bee_validate.go.
Related: bee routing (subscribes / publishes), prompt templates, architecture overview (adapters, colony layout).
1. Files and loading¶
.paseka/bees/
├── scout.yaml
├── builder.yaml
├── guard.yaml
└── builder.local.yaml # optional, gitignored overlay
| Path | Purpose |
|---|---|
.paseka/bees/<role>.yaml |
Canonical role definition (committed) |
.paseka/bees/<role>.local.yaml |
Machine-local overlay; prompt_template and system_template applied at resolve time |
paseka loads bees via colony.LoadBee(colonyRoot, role) / LoadAllBees:
- Role must be non-empty and must not contain
/or... - Base file is
.paseka/bees/<role>.yaml(filename stem = role whenrole:is omitted). - Event rules,
run_summary, and adapter requirements are validated at load time. - If
<role>.local.yamlexists, itsprompt_templateandsystem_templateoverride the base at resolve time (see prompt templates).
*.local.yaml files are listed in .paseka/.gitignore and are skipped by LoadAllBees.
2. Schema¶
Go type (internal/colony/bee.go):
type Bee struct {
Role string
Adapter string
PromptTemplate string
SystemTemplate string
Sector string
Worktree bool
Intents []string
DefaultIntent string
Command Command
PostExec Command
Params map[string]any
Subscribes []SubscriptionRule
Publishes []PublicationRule
CompletionContract CompletionContract
RunSummary RunSummaryPolicy
}
Field reference¶
| YAML field | Required | Meaning |
|---|---|---|
role |
recommended | Role name. If empty, defaults to the filename stem (builder.yaml → builder). |
adapter |
no | cursor (default), pi, claude, or script. Unknown names fail load. |
prompt_template |
usually | Path relative to .paseka/prompts/. User/task turn. Optional for adapter: script (no colony default applied when omitted). |
system_template |
no | Path relative to .paseka/prompts/. Role / standing instructions injected by the adapter (see prompt templates). |
sector |
no | Default sector name from colony.yaml sectors. Task sector wins when set. |
worktree |
no | When true, adapter cwd is under .paseka/worktrees/<traceId>/ (plus sector path if any). |
intents |
no | Explicit intent vocabulary for this bee. When omitted, runtime discovers intents from _partials/<role>-intent-*.md prompt partials. |
default_intent |
no | Default intent when the caller omits --intent or passes an unknown value. When omitted, general is used if present in the vocabulary; otherwise the first discovered intent. |
params |
no | Adapter flag map (model, trust, …). Ignored when command is set (runtime warns if both are present). |
command |
script: yes | Full agent argv (string or YAML list). Replaces params-based flag mapping. |
post_exec |
no | Hook after AFK bee run and interactive bee chat. Failures are logged; they do not fail the bee run. |
subscribes |
no | Event → dispatch rules. Empty = backward-compatible allow any task.ready. See bee routing. |
publishes |
no | Advisory expected outputs; undeclared domain publishes warn only (MVP). |
completion_contract |
no | Hard post-run event requirements; violation fails the run. |
run_summary |
no | auto (default) | required | disabled — controls INSIGHT/run.summary synthesis/enforcement. |
3. Example¶
# .paseka/bees/builder.yaml
role: builder
adapter: cursor
sector: frontend
params:
model: composer-2.5
output_format: stream-json
trust: true
force: true
# Optional: override adapter flag mapping (docker-compose style).
# command: agent -p --yolo --workspace $WORKSPACE $PROMPT
prompt_template: builder.md # relative to .paseka/prompts/
worktree: true # run inside .paseka/worktrees/<traceId>/
subscribes:
- type: SIGNAL
kind: task.ready
dispatch: task
publishes:
- type: MUTATION
kind: code.proposal.isolated
Guard with a completion contract:
# .paseka/bees/guard.yaml
role: guard
adapter: cursor
prompt_template: guard.md
params:
model: composer-2.5
output_format: stream-json
trust: true
force: true
worktree: true
subscribes:
- type: MUTATION
kind: code.proposal.isolated
dispatch: direct
publishes:
- type: VERIFICATION
kind: verification.success
- type: VERIFICATION
kind: verification.failed
completion_contract:
required:
- type: VERIFICATION
kind_one_of:
- verification.success
- verification.failed
count: 1
Hivewright and main-guard (root proposal path):
# .paseka/bees/hivewright.yaml
role: hivewright
adapter: cursor
worktree: false
publishes:
- type: MUTATION
kind: code.proposal.root
# .paseka/bees/main-guard.yaml
role: main-guard
adapter: cursor
worktree: false
subscribes:
- type: MUTATION
kind: code.proposal.root
dispatch: direct
publishes:
- type: VERIFICATION
kind: verification.success
- type: VERIFICATION
kind: verification.failed
4. Adapters¶
ResolveAdapter() defaults empty adapter to cursor. Allowed values: cursor, pi, claude, script.
| Adapter | Notes |
|---|---|
cursor |
Cursor Agent CLI (agent). Params map to CLI flags unless command is set. With system_template, runtime merges system + task into the positional prompt ($PROMPT); Pi/Claude use separate append-system flags instead. |
pi |
Pi CLI (pi). Params: model, provider, thinking, output_format, plan, binary. |
claude |
Claude Code CLI; same params plumbing as other LLM adapters. |
script |
Requires command. AFK-only (bee run); bee chat is LLM-only. params ignored. prompt_template optional. |
Adapter drivers and flag mapping live in architecture overview §1. Machine-local credentials stay in ~/.config/paseka/<slug>/adapters/*.yaml.
Script bee example:
# .paseka/bees/oracle-guard.yaml
role: oracle-guard
adapter: script
command: ./scripts/oracle-guard.sh
run_summary: disabled
subscribes:
- type: MUTATION
kind: code.proposal.isolated
dispatch: direct
publishes:
- type: VERIFICATION
kind: verification.success
- type: VERIFICATION
kind: verification.failed
Script process env (in addition to command variable substitution): PASEKA_TRACE_ID, PASEKA_AGENT_ID, PASEKA_TASK_ID, PASEKA_WORKSPACE, PASEKA_COLONY_ROOT, PASEKA_RUN_DIR, PASEKA_BEE, PASEKA_EVENT_LOG, PASEKA_RESULT_FILE, PASEKA_PROMPT_FILE. Domain events still go through paseka event emit --stdin.
5. params¶
Mapped by RunParamsFromBee (internal/colony/params.go). Defaults: trust: true, force: true.
| Key | Type | Used by |
|---|---|---|
model |
string | cursor, pi, claude |
output_format |
string | cursor (stream-json, …); pi maps to --mode |
trust |
bool | cursor |
force |
bool | cursor |
plan |
bool | cursor (--plan); pi (--plan) |
binary |
string | override CLI binary name |
provider |
string | pi |
thinking |
string | pi |
When command is set, these params are not turned into CLI flags; runtime logs a warning if both command and params are present. adapter still selects result parsing, session PTY, and home-config credential injection.
6. command and post_exec¶
Both accept a shell-like string or a YAML list of strings (colony.Command). String form is split into argv without invoking a shell (quotes supported; unclosed quotes error).
command: agent -p --trust --workspace $WORKSPACE $PROMPT
# or
command: ["agent", "-p", "--model", "composer-2.5", "$PROMPT"]
post_exec: notify.sh --bee builder --status ok --summary "$RESULT"
# or
post_exec: ["curl", "-fsS", "-d", "@$META", "https://hooks.example.com/paseka"]
Variable substitution¶
Supports $NAME and ${NAME}:
| Variable | When set | Value |
|---|---|---|
$PROMPT / ${PROMPT} |
dispatch + post_exec | rendered user/task prompt; for cursor, includes system_template when set (newline-separated) |
$SYSTEM_PROMPT / ${SYSTEM_PROMPT} |
dispatch + post_exec | rendered system prompt (still written to system.txt; not duplicated in Cursor positional when using default adapter mapping) |
$SYSTEM_FILE / ${SYSTEM_FILE} |
dispatch + post_exec | path to system.txt |
$CURSOR_PLUGIN / ${CURSOR_PLUGIN} |
dispatch + chat | deprecated — no longer materialized; $PROMPT carries merged system+task for Cursor |
$WORKSPACE / ${WORKSPACE} |
dispatch + post_exec | agent working directory |
$TRACE_ID / ${TRACE_ID} |
dispatch + post_exec | current flight trail |
$AGENT_ID / ${AGENT_ID} |
dispatch + post_exec | this invocation id |
$TASK_ID / ${TASK_ID} |
dispatch + post_exec | task id when dispatched from ledger |
$COLONY_ROOT / ${COLONY_ROOT} |
dispatch + post_exec | git repo root |
$RUN_DIR / ${RUN_DIR} |
dispatch + post_exec | .paseka/runs/<traceId>/<agentId>/ |
$RESULT_FILE / ${RESULT_FILE} |
dispatch + post_exec | path to summary.md |
$RESULT / ${RESULT} |
post_exec only | human-readable run summary text |
$META / ${META} |
post_exec only | path to meta.json |
7. Sector and worktree¶
sector— default named path fromcolony.yamlsectors. Effective sector = task sector if set, else bee default (EffectiveSector). Workspace becomescolonyRoot/<sector.path>or worktree + sector path whenworktree: true.worktree: true— mutations under.paseka/worktrees/<traceId>/; audit I/O stays in.paseka/runs/.worktree: false— adapter cwd is colony root (+ sector). Used for hivewright / main-guard root proposals.
Worktree ↔ proposal kind invariants (hard)¶
Auto-synthesis and paseka doctor enforce matching worktree and declared publish/subscribe kinds:
Bee worktree |
Declares publish | Auto-publish kind | Else |
|---|---|---|---|
true |
isolated or alias code.proposal |
code.proposal.isolated |
Skip auto mutation + warn |
false |
code.proposal.root |
code.proposal.root |
Skip + warn |
true |
only root |
— | Skip + doctor error |
false |
only isolated / alias |
— | Skip + doctor error |
Subscriber mismatches (guard with worktree: false, main-guard with worktree: true) are doctor errors. Bare code.proposal alias use is a doctor warning. review: final on a task whose bee publishes code.proposal.root is rejected at task.plan load.
Fail closed: empty / missing publishes must not auto-publish mutations.
Colony sector definitions remain in architecture overview.
8. run_summary¶
Controls runtime handling of INSIGHT/run.summary:
| Value | Behavior |
|---|---|
auto (default / empty) |
Runtime may synthesize a summary when missing and policy allows |
required |
Run fails if no summary event is present after the adapter exits |
disabled |
No synthesis; useful for script / oracle bees |
Invalid values fail bee load. See also bee routing §5 and insight kinds.
9. completion_contract¶
Hard requirements checked against events.ndjson after the adapter exits. Violation → run failed even if the process exit code was zero.
completion_contract:
required:
- type: VERIFICATION
kind_one_of:
- verification.success
- verification.failed
count: 1 # default 1; must match exactly that count among allowed kinds
| Field | Meaning |
|---|---|
type |
Domain event type (SIGNAL, INSIGHT, MUTATION, VERIFICATION) |
kind_one_of |
Allowed payload.kind values (required, non-empty) |
count |
Exact match count among those kinds (default 1) |
Narrative INSIGHTs do not satisfy contracts unless listed. Full routing semantics: bee routing §6.
10. Routing fields (subscribes / publishes)¶
Documented in bee routing. Summary:
subscribes[].dispatch:task(task-ledger) ordirect(reactor runs the bee on the event).- Empty
subscribes→ anytask.readydispatch allowed. publishesis advisory in MVP.- Declaring
VERIFICATION/task.completedmarks the AFK commit gate: when another bee explicitly publishes an isolatedMUTATION/code.proposalwith a diff, runtime defers auto-complete until that commit-gate bee emitstask.completed. Root proposals do not open this defer. - Declaring
MUTATION/code.proposal.isolated(or aliascode.proposal) on the dispatched bee (typically builder) is what opens the isolated defer path when a commit-gate publisher exists in the colony. - Declaring
MUTATION/code.proposal.rooton aworktree: falsebee (typically hivewright) publishes from colony root;main-guardreviews on the same disk.
11. Prompt template resolution¶
Precedence (highest wins), from prompt templates:
- Inline
prompt:/ CLI--prompt bees/<role>.local.yaml→prompt_templatebees/<role>.yaml→prompt_templatecolony.yaml→defaults.prompt_template
Do not store prompts in ~/.config/paseka/.