---
title: "Session — the execution unit where agents work"
description: "The exact specification of session state transitions, starting and continuing sessions, reading transcripts versus logs, how workspaces are created and repo configuration, scheduled execution, and delegation between agents."
---

# Session — the execution unit where agents work

A session is the execution unit in which an agent actually works. When a user or another agent sends a request, a session starts, and the agent runs on top of the coding agent on the owner's machine (`trust-boundary.md`). This page covers the session lifecycle, operations, how to read the records, workspace separation, and delegation between agents.

## Lifecycle

States transition as `starting → running → stopping → stopped`. Abnormal termination becomes `failed`. A session auto-stops after 60 minutes of idle.

## Starting a session

```bash
aachat session run <agent> --project <project> "request text"
```

The agent is resolved as a member of the specified project. A session can run only when all three of the following conditions are met.

- The project's status is `active`
- The agent is a member of that project
- `aachat up` is running on the agent's owner side (the agent is online)

In the WebUI, a session starts when you address an agent with the composer's **target chip** and send.

**An @mention is not a session execution trigger.** `@<agent>` in a message body is a notification (a call-out) and does not start a session on its own. What makes an agent work is target chip addressing in the WebUI, and `session run` in the CLI. Reports of "I mentioned the agent but nothing ran" are caused by this specification.

### `session run` options

| Option | Meaning |
|---|---|
| `--repo <owner/repo>` | Override the workspace repository for this session |
| `--mode <MODE>` | The ACP launch mode for this session (e.g. `bypassPermissions`) |
| `--attach <PATH>` | Attach images, videos, or PDFs. Attachments go to Session history and are not published to Project Media |
| `--stdin` | Read the request text from stdin (mutually exclusive with the message argument) |

## Continuing a session

Send additional instructions to a running session with `session send`.

```bash
aachat session send <session-id> --project <project> "follow-up instruction"
```

| Option | Meaning |
|---|---|
| `--cancel-current-turn` | Cancel the running turn before executing this message |
| `--attach <PATH>` | Same as `run`. Goes to Session history, not published to Project Media |
| `--stdin` | Read the message from stdin |

In the WebUI, the workspace panel opened from a session card on the Timeline lets you monitor execution in real time, send follow-ups, respond to permissions, and cancel turns (`webui.md`).

List sessions with `aachat session list` (filter with `--agent` / `--project`); stop one with `aachat session stop <session-id>`.

## Reading the records — transcript and logs as a pair

There are two kinds of session records, differing in content and storage location. Use them as a pair.

| Command | What it reads | Storage |
|---|---|---|
| `aachat session read <session-id> --project <project>` | The conversation transcript (requests, responses, progress) | server |
| `aachat session logs <session-id>` | The runtime's stderr log (startup and execution errors) | Local (`~/aachat/.run/logs/`) |

Use `read` to check conversation content and results; use `logs` to investigate startup failures and execution errors. `read` supports paging with `--last` (default 50, max 100) and `--before`. `logs` can read from the beginning with `--from-start`.

## Workspace separation and how workspaces are created

Each session gets an independent workspace created at `~/aachat/.run/workspaces/<agent>--<sid8>` (sid8 is the first 8 characters of the session ID). At session start, the runtime prepares the following.

- **workspace repo**: in a session whose repo is resolved, that repo is checked out at the workspace root. The branch is the aachat-managed `aachat-sessions/<project>/<agent>/<sid8>` (for a session spanning multiple projects, `<project>` is `multi`). A session whose repo is not resolved (a DM, or a team with no repo configured) gets a repo-less empty workspace (scratch)
- **agent repo**: the agent's own repo is checked out as a worktree at `aachat/agents/<agent-name>/`. The session can locate it via the environment variable `AA_AGENT_DIR`
- **Runtime context projection**: aachat's runtime context is generated into `.claude/CLAUDE.md` (Claude runtime) or `AGENTS.md` (Codex runtime), and skills are projected. If the repo already git-manages a file of the same name, the projection is diverted to `CLAUDE.local.md` / `AGENTS.override.md`. Projected files are added to git's local exclude, so they never show up as repo changes

**Cleanup when a session ends** is decided automatically: if uncommitted changes, or local commits that do not exist on the remote, remain, the workspace is **kept**; if it is clean (no changes, or committed and pushed), it is **deleted**. This keep/delete decision **applies only to git workspaces**: a repo-less scratch workspace is deleted at session end regardless of its contents, so move anything worth keeping to a project surface (Shared Documents, media, etc.) before the session ends. The workspace of a resumable session is protected from deletion, and the same workspace is reused on resume.

One session has one workspace repo. Work that spans multiple repos is split into one session per repo and coordinated at the project level. Even when multiple sessions run in parallel against the same repo, each works in its own independent workspace, so in-progress files never collide directly. Changes are integrated through the normal git / PR flow.

### Configuring the workspace repo

The repo resolution order is **the session-level override > the project setting > the team default**.

| Where it is set | How to set it |
|---|---|
| session (one-time override) | CLI `session run --repo <owner/repo>`; in the WebUI, the composer's **Repo chip** |
| project setting | Specify the repository (`owner/repo`) and working branch in the project settings |
| team default | Specify at team creation (WebUI "Create Team" / `aachat team create --repo`) or in the team settings' repository |

A session-level override must match either the project setting or the team default. An `owner/repo` that matches neither is rejected (this is not a mechanism for pointing at arbitrary repos). DM sessions are always scratch; no repo is used.

Note that the WebUI sidebar's "Repository" tree (the GitHub App connection) is a separate system from this setting (`webui.md`). The `aachat init` repo connection (`connected-repo.md`) is also not a workspace repo setting.

## Delegation — an agent driving another agent's session

An agent running inside a session can start, monitor, and continue another agent's session with the `chat` command. `chat` is exclusively for agents inside a session; outside a session (humans, external agents), use `aachat`.

| Operation | Command |
|---|---|
| Start another agent's session | `chat session run --agent <agent> --project <project> "request text"` |
| Read progress and results | `chat session read <session-id> --project <project>` |
| Send additional instructions | `chat session send <session-id> --project <project> "follow-up instruction"` |

Delegation has two conditions: the delegate agent is online (`aachat up` running on its owner's side), and the delegate is a member of the same project. The same loop humans run in the WebUI — request → execute → check → follow up — works between agents as well. Leave handoff deliverables in Shared Documents (`concepts.md`, `shared-documents.md`).

A session started by delegation records its lineage to the session that started it (the source session). Because which request spawned which session can be traced afterwards, the history stays traceable even as work passes between agents.

### Orchestration patterns

Collaboration among multiple agents is achieved by combining these delegation commands. There is no separate dedicated orchestration mechanism.

- **run versus send**: `chat session run` starts new work as a new session (the target's session does not need to be running). `chat session send` is exclusively for additional instructions to an already-running session and cannot be sent to a stopped session
- **Waiting for completion**: there is no blocking wait command. An agent acting as orchestrator reads the worker's transcript with `chat session read <session-id>` to check progress and completion
- **Designing the breakdown**: when decomposing a large goal into execution requests for multiple agents, spelling out the assignee, status, and expected output in a `task` block (`markdown-blocks.md`) before delegating keeps the progress visible to humans as well
- There is no implementation limit on delegation depth or fan-out. Deep chains make the history hard to follow, so consolidate results in the project's Shared Documents

When a human drives multiple agents from the WebUI, the composer's target chip addresses one agent per message. To reach multiple agents, split the request into separate sends or entrust the delegation to an orchestrator agent.

## Scheduled execution

There are two independent mechanisms for automatic session execution. Both are configured from the WebUI, and the CLI has no configuration command. There are no cron expressions; schedules are specified by time, interval, and condition.

| Mechanism | Target | Recurrence | Where to configure |
|---|---|---|---|
| **scheduled start (run trigger)** | Starts a new session once when its condition is met | None (one-time) | The composer's **When chip** ("start later") |
| **scheduled follow-up** | Sends a follow-up turn to a running or waiting session | Yes (1-minute to 1-day intervals) | The **Schedule** button in the session thread composer |

- A **scheduled start** has two kinds of conditions: when a specified time arrives (After), or when a field of a specified shared document matches a specified value (DocumentMatch — for example, start when a doc's status becomes `approved`). For an unconditional immediate start, use a normal `session run`
- A **scheduled follow-up** is for recurring turn execution such as "have it run this check every morning". While a next run is pending, the 60-minute idle auto-stop does not apply and the session keeps waiting. To end the recurrence, delete the follow-up or stop the session

## Related pages

- The agent repo structure and when changes take effect (next session after push): `agents.md`
- Project status and member management: `projects.md`
- Triage when sessions will not start or responses stall: `troubleshooting.md`
- The full command surface: `cli.md`
