name: push
description: Coordinator assigns all tasks to workers via update(assignee=). No self-selection.
settings:
initial_state: pending
disconnect_state: pending
blocking_states: [pending, assigned, working]
unknown_phase: warn
roles:
coordinator:
description: >
Central dispatcher. Creates tasks, assigns every one via
update(task=..., assignee="worker-N"). Monitors progress, reassigns
on failure. Workers NEVER call list_tasks(ready=true) to self-select.
tags: [coordinator, lead]
max_claims: 1 can_assign: true
can_create_subtasks: true
worker:
description: >
Passive executor. Waits for assignment (status=assigned), claims the
assigned task, executes, and completes. Does NOT browse or self-select
tasks. Reports results via attach().
tags: [worker]
max_claims: 2
can_assign: false
can_create_subtasks: false
states:
pending:
exits: [assigned, working, cancelled]
timed: false
prompts:
enter: >
Task created but not yet assigned. Only the coordinator moves tasks
out of pending via update(assignee=...).
assigned:
exits: [working, pending, cancelled]
timed: false
prompts:
enter: >
**Assigned to you by the coordinator.** Review the description and
any attached context, then claim() to begin working. Do NOT browse
for other tasks -- wait for explicit assignment.
working:
exits: [completed, failed, pending, consult]
timed: true
prompts:
enter: |
**Push-model working.** You received this task from the coordinator.
- `thinking()` regularly for heartbeat + visibility
- `mark_file()` before editing; `list_marks()` first for conflicts
- Never revert unfamiliar changes: check `mark_updates()` / `list_marks()` first
- 5+ files? Ask coordinator to decompose instead
- `mark_updates()` every 30-60s during long ops
- Stale workers (5+ min no heartbeat) get evicted
- **Git lock**: `claim(task="_lock:git-commit")` -> commit -> release via `update(task="_lock:git-commit", status="pending")`
Transitions: {{valid_exits}}
Phase: {{current_phase}} | Valid: {{valid_phases}}
exit: "Unmark files, attach results, `log_metrics()`. Coordinator will assign next task."
completed:
exits: [pending]
timed: false
prompts:
enter: >
Task completed. Results should be attached. Wait for coordinator
to assign the next task -- do NOT self-select.
failed:
exits: [pending]
timed: false
prompts:
enter: |
Task failed. **Recovery procedure (push-model):**
1. **Preserve work:** `attach(type="error", content="...")` with what was attempted and what blocked
2. **Clean up resources:**
- `unmark_file()` all held files -- coordinator may reassign to another worker
- Release any held locks: `update(task="_lock:git-commit", status="pending")` if you hold the git lock
3. **Classify for coordinator:**
- *Transient* (flaky test, timeout): note "retryable" in error attachment
- *Dependency blocked*: `link(type="blocks", from="blocking-task")` and note the dependency
- *Needs decomposition*: suggest how coordinator should split the task
- *Needs human decision*: recommend coordinator move to `consult`
4. **Wait for coordinator:** do NOT self-select the next task. The coordinator will read your
error attachment and decide whether to reassign, decompose, or cancel.
5. **Signal visibility:** `thinking(thought="FAILED: <one-line reason>")` so coordinator sees it promptly
consult:
exits: [working, pending, cancelled]
timed: false
prompts:
enter: |
**Paused for coordinator review.** Before pausing:
1. `unmark_file()` all held files -- coordinator may reassign the work
2. Release any locks: `update(task="_lock:git-commit", status="pending")` if held
3. `attach(type="note", content="...")` explaining:
- What specific decision or input is needed
- What you have completed so far
- Whether partial work should be preserved or reverted
4. `thinking(thought="CONSULT: <one-line reason>")` so coordinator sees it promptly
5. **Wait for coordinator** -- do NOT self-select other tasks while consulting
cancelled:
exits: []
timed: false
phases:
explore:
prompts:
enter: "**Explore.** Read code/docs, identify constraints. Attach findings for coordinator."
exit: "Attach exploration findings. Coordinator decides next assignment."
plan:
prompts:
enter: "**Plan.** Outline approach. Coordinator decomposes via `create_tree()` and assigns."
exit: "Ensure plan attached. Coordinator creates and assigns subtasks."
design:
prompts:
enter: "**Design.** Document approach, interfaces, key decisions. Attach design note."
exit: "Ensure design doc attached with rationale."
implement:
prompts:
enter: "**Implement.** `mark_file()` first. Follow codebase patterns. Tests alongside code."
exit: "Ensure: compiles, tests pass, commit attached."
review:
prompts:
enter: "**Review.** Tests pass, no warnings, docs updated."
exit: "Ensure findings documented, blockers escalated."
test:
prompts:
enter: "**Test.** Run existing tests, add new ones, cover edge cases."
exit: "Ensure test results attached, all passing."
security:
prompts:
enter: "**Security.** Input validation, auth/authz, no secrets in code."
exit: "Ensure findings attached, critical issues escalated."
triage:
prompts:
enter: "**Triage.** Classify, set priority, assess scope. Coordinator routes."
exit: "Ensure tags/priority set, description clear."
diagnose:
prompts:
enter: "**Diagnose.** Reproduce, narrow to module/function, attach findings."
exit: "Ensure root cause documented, fix approach outlined."
doc:
prompts:
enter: "**Document.** Update README, API docs, inline comments."
exit: "Ensure doc changes committed."
integrate:
prompts:
enter: "**Integrate.** Full test suite. Check conflicts via `mark_updates()`."
deliver:
prompts:
enter: "**Deliver.** All tests green, build clean. Version bumps if applicable."
deploy:
prompts:
enter: "**Deploy.** Release build. Tag if applicable. Monitor initial deployment."
monitor:
prompts:
enter: "**Monitor.** Check errors and performance. Time-box. Attach observations."
optimize:
prompts:
enter: "**Optimize.** Measure baseline, change one thing, re-measure."
combos:
working+implement:
enter: |
Implementing (push-assigned). Follow patterns, tests alongside, atomic commits.
- **3+ files**: search ALL symbols first, mark_file() ALL, plan attachment before coding
- **Git lock**: `claim(task="_lock:git-commit")` -> commit -> release
working+review:
enter: "Review (push-assigned): correctness, edge cases, test coverage."
working+plan:
enter: "Planning (push-assigned): outline approach, attach plan for coordinator."
working+explore:
enter: "Exploring (push-assigned): read code/docs, attach findings. Time-box."
working+test:
enter: "Testing (push-assigned): run suite, add tests, verify edges. Attach results."
working+triage:
enter: "Triaging (push-assigned): categorize, prioritize, assess scope."
working+diagnose:
enter: "Diagnosing (push-assigned): reproduce, narrow down, root cause."
working+security:
enter: "Security (push-assigned): input validation, auth, secrets, deps."
assigned+implement:
enter: "Implementation assigned by coordinator. Read task description and context before claiming."
assigned+review:
enter: "Review assigned by coordinator. Read implementation context before claiming."
assigned+test:
enter: "Test assigned by coordinator. Check implementation notes before claiming."
assigned+explore:
enter: "Exploration assigned by coordinator. Read scope constraints before claiming."
failed+implement:
enter: |
Implementation failed. Before leaving:
- `unmark_file()` all held files and release git lock if held
- `attach(type="error")` with: files modified, tests that failed, build errors
- If partially committed: attach the commit hash so coordinator can assess
- Signal: `thinking(thought="FAILED impl: <reason>")` for coordinator visibility
role_prompts:
coordinator:
dispatch_loop: |
**Pure push dispatch loop:**
1. `list_tasks(status="pending")` to find unassigned work
2. `list_agents()` to find available workers (low claim count, matching tags)
3. `update(task="id", assignee="worker-id")` to push-assign each task
4. Monitor: `list_tasks(status="working")` and `list_agents()`
5. On failure: `update(task="id", assignee="other-worker", force=true)`
6. Repeat until all tasks are terminal
**Key metrics to log (for experiment):**
- Time between task creation and assignment (dispatch latency)
- Time between assignment and worker claiming (pickup latency)
- Number of reassignments per task
- Worker idle time between assignments
- Total wall-clock time
assignment_strategy: |
Assign via `update(task="id", assignee="worker-id")`.
Selection criteria (in order):
1. Worker has matching needed_tags
2. Worker has lowest current claim count
3. Worker has context from related tasks (same parent, similar tags)
4. Round-robin if all else is equal
monitoring: |
Monitor: `list_agents()` for workers, `list_tasks(status="working")` for progress.
Watch for: stuck workers (no heartbeat), overloaded workers, dependency bottlenecks.
Reassign: `update(task="id", assignee="other-worker", force=true)`.
failure_handling: |
**When a worker task fails:**
1. Read the error attachment to understand the failure class
2. *Retryable failure*: `update(task="id", status="pending")` then reassign to same or different worker
3. *Dependency failure*: check `list_tasks(status="failed")` for cascading failures; fix root cause first
4. *Scope issue*: decompose the failed task into smaller subtasks, assign individually
5. *Repeated failure* (same task failed 2+ times): move to `consult` with summary of all attempts
6. **Stale worker recovery:** if a worker goes silent (no heartbeat 5+ min), it gets evicted automatically;
verify its tasks returned to `pending`, clean up any dangling file marks via `list_marks()`
worker:
passive_wait: |
**Pure push model -- do NOT self-select tasks.**
1. Wait for task assignment (status transitions to "assigned")
2. `claim(task="id")` to begin working
3. After claiming, review any prompts returned in the response -- they contain workflow-specific guidance for this task, including any overlay-prescribed behaviors, patches, or reasoning notes.
4. `mark_file()` before editing
5. Work, `thinking()` regularly
6. `attach(type="result", ...)` + `unmark_file()` + `update(status="completed")`
7. **Wait** for coordinator to assign the next task
completing: |
Before completing:
1. Verify success criteria met
2. Run tests
3. `attach(type="result", content="...")` - document work done
4. `unmark_file()` - release files
5. `log_metrics(cost_usd=...)` - record cost
6. `update(status="completed")`
7. **Do NOT look for the next task.** Wait for assignment.
push:
coordinator_settings:
exclusive_dispatch: true
poll_interval_guidance_ms: 5000
batch_size: 5
reassign_after_stale_ms: 300000
worker_settings:
self_select: false
max_concurrent_claims: 2
poll_for_assignment_ms: 10000
experiment_metrics:
- name: dispatch_latency_ms
description: "Time from task creation to coordinator assigning it"
source: "created_at -> assigned transition timestamp"
- name: pickup_latency_ms
description: "Time from assignment to worker claiming (starting work)"
source: "assigned transition -> working transition timestamp"
- name: execution_time_ms
description: "Time spent in working state"
source: "time_actual_ms on task"
- name: total_task_latency_ms
description: "End-to-end time from creation to completion"
source: "created_at -> completed_at"
- name: reassignment_count
description: "Number of times a task was reassigned"
source: "Count of assigned transitions per task in task_sequence"
- name: worker_idle_time_ms
description: "Time workers spend not working (between completions and next assignment)"
source: "Gap between completed_at of previous task and working timestamp of next task per worker"
- name: coordinator_overhead_ms
description: "Total time coordinator spends in working state (dispatch overhead)"
source: "Coordinator's total time_actual_ms"
gates:
status:working:
- type: "gate/results"
enforcement: warn
description: "Attach results for coordinator visibility"
status:assigned:
- type: "gate/context"
enforcement: warn
description: "Coordinator should attach task context at assignment time"
attachments:
coordinator_to_worker:
context: Essential background info (replaces)
plan: Task approach and constraints (markdown, replaces)
note: Clarifications or additional instructions (appends)
worker_to_coordinator:
result: Structured completion data (JSON, replaces)
note: Progress updates, questions, observations (appends)
error: Blockers or failures needing reassignment (appends)
code_artifacts:
commit: Git commit hash (appends)
diff: Code changes for review (appends)
changelist: Files modified (appends)
operations:
log: Chronological work record (appends)
output: Command/test output (appends)
meta: Structured metadata (JSON, replaces)