# Slash commands


cairn registers six slash commands when it loads under a kli host: `/observe`, `/handoff`, `/task`, `/tasks`, `/workon`, and `/where`. They are the hand-typed surface over the same task graph the [MCP tools](/cairn/reference/tools) reach over the wire: a line you type at the prompt instead of a tool the model calls. Two of them, `/observe` and `/handoff`, do something an agent can also do for itself. The other four are operator conveniences the model never sees.

The commands depend on a host that offers a command surface. cairn registers them only against a `:commands/v1` provider. A headless run with no such provider registers nothing, so there are no slash commands when cairn is served straight over [`kli mcp-serve cairn`](/cairn/cli/mcp-serve). For that path, use the tools directly.

A command's first word names it; everything typed after the first word is one free-text tail passed to the runner. `/where` takes no tail.

## The six commands

| Command | Syntax | Effect | Model-visible | MCP analogue |
| --- | --- | --- | --- | --- |
| `/observe` | `/observe <text>` | Record an observation on the current task. | yes | [`observe`](/cairn/reference/tools#observe) |
| `/handoff` | `/handoff [guidance]` | Compose and record a resumable handoff for the current task. | yes | [`handoff`](/cairn/reference/tools#handoff) (the turn authors the body; the tool only scaffolds) |
| `/task` | `/task [id]` | Show the current task, or select one by id. | no | partial — pointer read/set, like [`task_bootstrap`](/cairn/reference/tools#task-bootstrap) without the open-handoffs readout |
| `/tasks` | `/tasks [query]` | List recent tasks, or run a task-graph query. | no | [`task_query`](/cairn/reference/tools#task-query) |
| `/workon` | `/workon [id]` | Select a task and seed a re-entry turn. | no | none |
| `/where` | `/where` | Show the resolved database path, project, and how it was resolved. | no | none |

**Model visibility** is the `:model-visible` metadata on each command. `/observe` and `/handoff` carry no such metadata, so their effect rides in the conversation the model reads. `/task`, `/tasks`, `/workon`, and `/where` are registered with `:model-visible nil`: they run and print to you, but their echo is hidden from the model. That split lets an operator inspect or steer the graph without spending the readout as context. See [Reads, writes, and capabilities](/cairn/concepts/reads-writes-and-capabilities) for the boundary the operator surfaces sit behind.

A command and its MCP analogue are not the same call. `/observe` invokes the `observe` tool unchanged. `/handoff` and `/workon` do work the tools cannot: `/handoff` drives an authoring turn and `/workon` injects a deterministic block, and both patch the transcript. The other operator surfaces — `/task`, `/tasks`, and `/where` — have their own output shapes. The sections below give each command's exact behavior and the verbatim text it prints. In the example blocks, a leading `>` marks the line you type; every other line is what cairn prints back.

## /observe

Record an observation on the current task.

Syntax: `/observe <text>`

`/observe` is a thin wrapper over the [`observe`](/cairn/reference/tools#observe) tool: it passes your tail as the `text` argument, invokes the tool, and returns the tool's result unchanged. The observation lands on the current task; it does not move the current-task pointer. On success the result is the tool's own line:

```text
> /observe rotation test still red at the 30-day boundary
Observed on 2026-06-22-auth-rotation.
```

With no tail, the command fails before reaching the tool:

```text
> /observe
Usage: /observe <text>
```

`/observe` is model-visible, so the observation and its confirmation enter the conversation. From a non-kli MCP client, call the [`observe`](/cairn/reference/tools#observe) tool directly — same effect, same return text.

## /handoff

Compose and record a resumable handoff for the current task.

Syntax: `/handoff [guidance]`

`/handoff` is richer than the [`handoff`](/cairn/reference/tools#handoff) tool, but the command itself does little. Its only deterministic act is to start one interactive authoring turn and reply `Composing a handoff...`. The session is then handed an instruction to compose a one-line summary, call the `handoff` tool to scaffold and record the document, read the scaffold back, and overwrite it with a rich body. Those steps are what the turn is told to do, not guarantees the command performs. The tool, by contrast, only scaffolds a deterministic skeleton and records the event; it never writes prose. Any tail you pass is guidance threaded into that authoring instruction:

```text
> /handoff
Composing a handoff...

> /handoff focus on the rotation regression; the refresh path is done
Composing a handoff...
```

Because it drives an authoring turn, `/handoff` needs an interactive session. Headless, with no agent-session service, it declines and writes nothing:

```text
Handoff authoring needs an interactive session.
```

From a non-kli MCP client, the [`handoff`](/cairn/reference/tools#handoff) tool is the right call: it scaffolds the skeleton and you supply the body yourself.

## /task

Show the current task, or select one by id.

Syntax: `/task [id]`

With no tail, `/task` prints the current task's computed state: its status, description, parent, children, edges, metadata, and recent observations. With no current task set, it says so and offers recent slugs:

```text
> /task
No current task. Recent: 2026-06-22-auth-rotation, 2026-06-21-search-index
```

With a tail, `/task <id>` sets the current-task pointer to that slug and prints the task's state. An unknown id leaves the pointer untouched and lists recent slugs instead:

```text
> /task 2026-06-22-auth-rotation
Current task set to 2026-06-22-auth-rotation.
2026-06-22-auth-rotation  [active]
  …computed task state…

> /task no-such-task
No task no-such-task. Recent: 2026-06-22-auth-rotation, 2026-06-21-search-index
```

`/task` is hidden from the model: it reads or moves the pointer without entering the conversation. The model's own way to orient and adopt a task is [`task_bootstrap`](/cairn/reference/tools#task-bootstrap), which adds open handoffs; `/task` is the bare pointer surface. See [The current task pointer](/cairn/concepts/the-current-task-pointer).

## /tasks

List recent tasks, or run a task-graph query.

Syntax: `/tasks [query]`

`/tasks` runs the [TQ query language](/cairn/reference/tq-language) against the live graph and renders the result. With no tail, it runs the built-in `recent` view. With a tail, it interprets your tail as a TQ program, read with `*read-eval*` disabled so the form is walked and never evaluated. The query runs scoped to the current task, so current-relative forms like the `(current)` source and the current-scoped views `(query "plan")` and `(query "plan-frontier")` resolve against the pointer.

```text
> /tasks
…the recent view…

> /tasks (-> (query "plan-frontier") (:ids))
…ready phases…
```

Three failure channels carry the underlying message verbatim, which is what lets you correct the query in place:

```text
Parse error: <message>
Query error: <message>
The query could not be executed.
```

`/tasks` is hidden from the model. It is read-only: it runs the read query engine, so it does not accept TQ's `!`-forms — the write source `define!` and the mutation steps such as `:set-status!`. To define a view or mutate the graph through TQ, use the [`task_query_write`](/cairn/reference/tools#task-query-write) tool.

## /workon

Select a task and seed a re-entry turn.

Syntax: `/workon [id]`

`/workon` has no MCP analogue. It does something only a host with a transcript can. It selects the target task — your tail, or the single most recent task when you pass none — sets the current-task pointer, records a `resume` event on the task, and injects a resume block straight into the durable transcript so the model re-enters the work with state in hand. The injected block opens with a fixed line, then the task's computed state and its open handoffs:

```text
Following the cairns - resuming 2026-06-22-auth-rotation.

2026-06-22-auth-rotation  [active]
  …computed task state…
  …open handoffs, newest first…
```

The command itself replies with a short confirmation, hidden from the model:

```text
Working on 2026-06-22-auth-rotation.
```

When there is no task to work on — no tail and no recent task — it says so and writes nothing:

```text
No task to work on.
```

An unknown id lists recent slugs and leaves the pointer untouched, the same shape `/task` uses for a miss. The transcript injection is a one-shot context patch. Headless, or when no agent context is bound, the selection and the event still happen but no block is written. Under a kli host, `/workon` is the operator counterpart to the model calling [`task_bootstrap`](/cairn/reference/tools#task-bootstrap) on re-entry.

## /where

Show the resolved database path, project, and how it was resolved.

Syntax: `/where`

`/where` takes no tail and has no MCP analogue. It reports which store the session is talking to and how that store was chosen. The output is a fixed template:

```text
Database: /…/cairn.db
Resolved by: project
Project: proj-1a2b3c4d5e6f (auth-service)
Source: kli-dir
```

`Resolved by` is the precedence step that won — `override`, `db-path`, `data-dir`, `project`, or `global`, highest first. `Project` is the content-addressed project id and its display name. `Source` is how the project root was found: `setting`, `kli-dir`, `repo`, or `scratch`. When the session falls back to the reserved scratch project, a final line is appended:

```text
Scratch: yes
```

`/where` is hidden from the model. See [Events, projection, and reconcile](/cairn/concepts/events-projection-and-reconcile) for how the store behind that path is built and rebuilt.

## Related

- [Tools](/cairn/reference/tools) — the fourteen MCP tools these commands sit over, with full parameter tables and return text.
- [Serve cairn over MCP](/cairn/cli/mcp-serve) — the headless surface, where the tools travel but the slash commands do not.
- [The current task pointer](/cairn/concepts/the-current-task-pointer) — what `/task` and `/workon` move, and the adopt-when-unset rule.
- [TQ language](/cairn/reference/tq-language) — the query language `/tasks` runs, including why it refuses `!`-forms.
- [`handoff` tool](/cairn/reference/tools#handoff) — the deterministic scaffold `/handoff` authors on top of.
