# Your first cairn session


This tutorial walks cairn's continuity loop once so you can see how your agent keeps work alive across a reset. The agent creates a task, records an observation on it, scaffolds a handoff, then resumes that task in a fresh session with one call. Those are the three writes that make up the heartbeat: `task_create`, `observe`, and `handoff`, all read back with `task_bootstrap`. The returned text after each call is explained, so you can tell what the agent reads back.

cairn has to be installed and reachable over MCP first; if it is not, see [Install cairn](/cairn/get-started/install-cairn). Each call below is shown the way the agent issues it over MCP, and the text after it is what cairn sends back.

## Create a task

A task is a node in the graph: a slug-addressed unit of work that carries a status, a description, edges, metadata, and its observations. The agent creates one by calling `task_create` with a `name`:

```text
task_create(name="wire up the export endpoint")
```

cairn mints a slug from the name, stamps today's UTC date as its namespace, and returns:

```text
Created 2026-06-22-wire-up-the-export-endpoint.
```

The date prefix is system-owned, so the agent passes a plain name and cairn handles the namespacing. `task_create` also adopts the new task as the [current task](/cairn/concepts/the-current-task-pointer), but only when none is set yet. Nothing was selected before this call, so the agent is now pointed at `2026-06-22-wire-up-the-export-endpoint`, and the writes that follow act on it without naming it again.

## Record an observation

An observation is the cheapest write cairn has, and the heartbeat of the loop: a freeform note the agent appends to a task as it works. It records one with `observe`:

```text
observe(text="export route returns 500 when the date filter is absent; needs a default range")
```

The note writes against the current task and returns:

```text
Observed on 2026-06-22-wire-up-the-export-endpoint.
```

The agent leans on `observe`. It does not move the current pointer and it never blocks, so leaving a trail of what the agent found, decided, and ruled out costs almost nothing, and that trail is what a later session reads back. To write against a different task without switching, the agent passes `task_id`. For the discipline behind the heartbeat, see [The cairn-method](/cairn/concepts/the-cairn-method).

## Write a handoff

A handoff is a resumable summary of where a task stands, and the `summary` is its load-bearing field. The agent scaffolds one with `handoff`:

```text
handoff(summary="export endpoint half-built; 500 on missing date filter, default range still TODO")
```

cairn writes a skeleton note (frontmatter, a state snapshot, and empty sections to overwrite with the rich body), records the event, and returns the path it wrote to:

```text
Handoff scaffolded for 2026-06-22-wire-up-the-export-endpoint at /…/2026-06-22_14-03-09_export-endpoint-half-built.md
```

There is no trailing period after the path. The tool is deterministic: it lays down a skeleton and returns the path, nothing more. It never drives an authoring turn; that is what the `/handoff` slash command does, and a person types that one. See [Tasks, observations, and handoffs](/cairn/concepts/tasks-observations-handoffs) for the tool-versus-command split.

## Resume

Close the MCP client and reopen it. The graph survives the reset; the conversation does not. That is the whole point: the plan lives outside the chat, so a fresh session reloads it.

In the new session the current pointer is empty, so the agent names the task explicitly and orients on it with `task_bootstrap`:

```text
task_bootstrap(task_id="2026-06-22-wire-up-the-export-endpoint")
```

One call returns the task's computed state and its open handoffs:

```text
2026-06-22-wire-up-the-export-endpoint  [open]
  recent:
    - export route returns 500 when the date filter is absent; needs a default range
  handoffs:
    - export endpoint half-built; 500 on missing date filter, default range still TODO (/…/2026-06-22_14-03-09_export-endpoint-half-built.md)
```

The observation and the handoff summary are both back, reloaded into a session that knew nothing a moment ago. `task_bootstrap` records no event; it is a read. Because the agent passed `task_id`, the call switched the current pointer to that task, so the writes it makes next land there. For the no-id and unset-pointer cases, see [The current-task pointer](/cairn/concepts/the-current-task-pointer).

That is the full heartbeat: the agent created a task, left an observation, scaffolded a handoff, and resumed the whole thing from a clean session with one call. From here, [Plan and resume](/cairn/get-started/plan-and-resume) builds a small plan as a graph of phases and runs the same loop across it, and [The cairn-method](/cairn/concepts/the-cairn-method) explains the discipline this heartbeat is part of.
