A task is a single unit of work assigned to an agent. It has a title, a description of what needs to be done, and an agent responsible for doing it. Tasks live inside missions and can depend on other tasks.
Task titles must be unique among active tasks. If a task with the same title already exists and is not in a terminal state (done or failed), creation will be rejected. Within a mission, all task titles must be unique.
{
"title": "Implement auth API",
"assignTo": "backend",
"description": "Create JWT-based authentication endpoints.",
"dependsOn": ["Design schema"],
"expectations": [
{
"type": "llm_review",
"criteria": "All endpoints return correct status codes. Tests pass."
}
]
}
Tasks can carry expectations (what “done” looks like), dependencies (what must finish first), and assessment criteria (how the output is scored). If you don’t specify expectations, the task completes when the agent finishes without crashing.
Lifecycle
Every task moves through a well-defined set of 7 states:
States
| Status | Description |
|---|
pending | Waiting for dependencies to complete and an agent to be available |
awaiting_approval | Task requires approval before it can be assigned; waiting for human or automated approval |
assigned | Agent selected, runner about to be spawned |
in_progress | Agent is actively working on the task |
review | Agent finished, assessment in progress |
done | Task passed assessment (or assessment skipped) |
failed | Task failed assessment, agent crashed, or approval was rejected/timed out; may be retried |
Phases
Within the in_progress state, tasks move through phases that track the current execution mode:
| Phase | Description |
|---|
execution | Initial run — agent works on the task from scratch |
review | Assessment is evaluating the agent’s work |
fix | Agent is making targeted corrections based on assessment feedback |
clarification | Agent asked a question; Polpo is generating an answer |
Fix Phase vs Full Retry
When assessment fails, Polpo first tries a fix phase — sending the agent specific feedback about what’s wrong so it can make targeted corrections without starting over:
- Fix phase: Agent receives per-dimension scores and feedback. Up to
maxFixAttempts (default: 2) before falling back.
- Full retry: Task resets to
pending and starts execution from scratch. Up to maxRetries (default: 3) total.
Transitions
Happy Path
- Mission is executed → tasks created as
pending
- If approval gates are enabled →
awaiting_approval → approved → assigned
- Otherwise, dependencies met →
assigned to agent
- Runner spawned →
in_progress (phase: execution)
- Agent finishes →
review (phase: review)
- Assessment passes →
done
Approval Path
- Task moves to
awaiting_approval
- Human or automated approver reviews the task
- Approved → task transitions to
assigned
- Rejected → task transitions to
failed (may be retried)
- Timeout → task transitions to
failed if autoRejectOnTimeout is enabled
Retry Path
- Assessment fails →
in_progress (phase: fix)
- Agent applies fixes →
review
- Still failing after
maxFixAttempts → failed
- Retries remaining → back to
pending (new execution)
- No retries left → permanent
failed
Side Effects Path
Tasks with sideEffects: true follow a modified retry path to prevent duplicating irreversible actions (emails, API calls, deployments):
- Assessment fails → instead of automatic fix/retry, task transitions to
awaiting_approval
- The task description is updated with failure feedback and a warning not to repeat external actions
- Human reviews and decides whether to approve re-execution
- Approved → task goes to
pending and re-executes with side-effect warnings in the prompt
- Rejected → task transitions to
failed
Set sideEffects: true when a task uses tools that produce irreversible external effects:
email_send, whatsapp_send
- Non-idempotent HTTP requests (POST, PUT, DELETE)
- Deployments or external system modifications
Question Path
- Agent asks a question during execution → phase becomes
clarification
- Orchestrator detects question, generates answer
- Answer injected, phase returns to
execution
- Max
maxQuestionRounds (default: 2) per task
Deadlock Path
- Task is
pending but depends on a failed task
- Polpo detects deadlock
- LLM evaluates: can the blocked task proceed without the dependency?
- Absorb: Task proceeds with modified description
- Retry: Failed dependency is retried
- Unresolvable: Task marked as
failed
SLA Deadline Tracking
Tasks and missions can have deadline fields (ISO-8601 timestamps). The SLA monitor tracks these deadlines every tick cycle and emits events:
- Warning (
quality:sla with status: "warning") — when the configured warning threshold is reached (default: 80% of deadline elapsed)
- Violation (
quality:sla with status: "violated") — when the deadline is exceeded
Quality Gates in Missions
Missions can define quality gates that block task progression. When a quality gate is configured at a specific point in a mission, subsequent tasks will not start until all preceding tasks meet the required quality threshold. See Missions for details.
Configuration
{
"settings": {
"maxRetries": 3,
"maxFixAttempts": 2,
"maxQuestionRounds": 2,
"maxResolutionAttempts": 2,
"taskTimeout": 1800000,
"staleThreshold": 300000
}
}
Events
Key events during the task lifecycle:
| Event | When |
|---|
task:created | Task added to registry |
task:transition | Status changes (includes from and to) |
agent:spawned | Runner started for task |
agent:activity | Agent made a tool call or updated progress |
assessment:complete | Assessment finished with pass/fail result |
task:fix | Fix phase started |
task:retry | Full retry started |
task:retry:blocked | Automatic retry blocked due to sideEffects: true |
task:question | Agent asked a question |
task:answered | Orchestrator answered the question |
task:timeout | Task exceeded maxDuration |
approval:requested | Task entered awaiting_approval |
approval:resolved | Task approval granted or denied (check status field) |
quality:sla | SLA warning or violation on a task deadline |
All state transitions are atomic — the task registry uses file-based stores (default) with atomic write operations to ensure consistency even if the process crashes mid-transition. SQLite and PostgreSQL are available as alternative stores via @polpo-ai/drizzle.