> This page is also available as Markdown: append .md to its URL. The full index of Sikaru docs is at https://docs.sikaru.ai/llms.txt. Code examples use only operations from the public API reference at https://docs.sikaru.ai/api-reference.

# Objectives and completion evidence

An **objective** gives a session an explicit outcome, a completion criterion, and optional evidence paths. Use one when you need verification and continued work toward an outcome, instead of treating any finished turn as success.

Operations on this page (Python SDK `client.execution_objectives`; CLI group `sikaru execution-objectives`, use `--schema` for each operation):

1. `create(project, session_id=..., run_id=..., idempotency_key=..., objective=..., criterion=..., evidence_paths=[...], max_rounds=...)`. `run_id` must belong to the session. `max_rounds` defaults to `3`, range `1`–`20`.
2. `get(project, objective_id)` returns the objective; read `status`.
3. `pause(project, objective_id)`, `resume(...)` (optionally `ResumeInput(source_run_id=...)` with a completed, delivered run), `cancel(...)`.

Statuses: `active`, `paused`, `blocked`, `completed`, `cancelled`. One unfinished objective per session.
Permissions: reads need `runs:read`; mutations need `runs:create`; creating or resuming in a draft session also needs `harness:write`.
Creation or resumption can return 503 when objective verification is unavailable.

```mermaid
stateDiagram-v2
    [*] --> active: create
    active --> paused: pause
    paused --> active: resume
    active --> completed: passing verdict
    active --> blocked: final round fails or is inconclusive
    active --> cancelled: cancel
    paused --> cancelled: cancel
    blocked --> cancelled: cancel
```

An objective starts `active`. You can pause and resume it. A passing verdict completes it. A final round that fails or is inconclusive blocks it. You can cancel an unfinished objective.

## Attach an objective to a session run

```python
objective = client.execution_objectives.create(
    project,
    session_id=session_id,
    run_id=run_id,
    idempotency_key="case-42-objective",
    objective="Produce the case analysis report",
    criterion="The report answers each question and cites supporting evidence.",
    evidence_paths=["report.md"],
)["objective"]
```

* `run_id` must belong to that session.
* Evidence paths refer to the run's workspace, not files on your API client's machine.
* Choose concrete completion criteria and files the task actually produces.

> **Note**
>
> Objective verification must be available in the service. Creation or resumption can return 503 when it is unavailable.

## Observe and control

```python
state = client.execution_objectives.get(project, objective["id"])["objective"]
print(state["status"])
```

Statuses include `active`, `paused`, `blocked`, `completed`, and `cancelled`. A session can have only one unfinished objective, including paused or blocked objectives. An objective's completion is distinct from a single run completing.

| Operation                      | Effect                                                                                                   |
| ------------------------------ | -------------------------------------------------------------------------------------------------------- |
| `pause(project, objective_id)` | Pauses objective progress.                                                                               |
| `resume(...)`                  | Continues it. Can select a new completed, delivered source run through `ResumeInput(source_run_id=...)`. |
| `cancel(...)`                  | Cancels the objective.                                                                                   |

These controls are separate from run cancellation. If the user wants to stop execution immediately, cancel the active run too.

When you resume with a new source run, keep the session's identity and inspect any conflict before you retry.

Read operations need `runs:read`. Objective mutations need `runs:create`.

CLI commands are under `sikaru execution-objectives`; use `--schema` for each operation.

## Bound verification rounds

Set `max_rounds` when you create an objective (default `3`, range `1`–`20`).

* The original source run is round one.
* Every independent verification round counts, including reassessment after an inconclusive verdict.
* Pausing before a verdict is recorded does not use another round.
* `maxRounds` in the objective response is the immutable admitted limit. Changing it under an existing idempotency key conflicts.

What happens on the last round:

* A passing verdict on the final round still completes the objective.
* A failed final round blocks with `Admitted objective round limit exhausted` and never queues another acting run.
* An inconclusive verdict still blocks without continuation and keeps its evidence reason.

> **Warning**
>
> An objective with all rounds recorded cannot resume, even with a different source run. Cancel it and create a new objective to explicitly admit more work. Cancellation does not cancel an already running turn. Existing session budgets can stop work earlier.

Creating or resuming an objective in a draft session also requires `harness:write`. Read, pause, and cancel keep their existing scopes.

## Next steps

#### [Sessions and steering](/run/sessions-and-steering)

Create the session and runs that objectives attach to.

#### [Evaluations](/improve/evaluations)

Measure agent quality across many tasks.