> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getasym.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Clones, environments, and the registry

> Clone ids, modes, states, tokens, environment membership, and where it's all recorded.

## Clones

A **clone** is one running instance of a template. It has:

| Field                   | Example                              | What it is                                                              |
| ----------------------- | ------------------------------------ | ----------------------------------------------------------------------- |
| `id`                    | `slack-a1b2`                         | Stable handle. You pass it to every command. `<template>-<random hex>`. |
| `template`              | `slack`                              | Which template it came from.                                            |
| `mode`                  | `api`                                | Which set of services is running (see below).                           |
| `composeProject`        | `asym-slack-a1b2`                    | The Docker Compose project for its containers.                          |
| `database`              | `clone_slack_a1b2`                   | Its own database inside shared Postgres.                                |
| `redisPrefix`           | `slack-a1b2:`                        | Its key namespace inside shared Redis.                                  |
| `ports`                 | `{ backend: 3001 }`                  | Host ports per service.                                                 |
| `state`                 | `running`                            | Lifecycle state (see below).                                            |
| `seed`                  | `{ fixture: "acme-corp" }`           | The last seed applied — replayed on `reset`.                            |
| `tokens`                | `{ botToken, userToken, … }`         | App credentials minted at spin (when the template provisions them).     |
| `image` / `imageDigest` | `…slack-backend:latest` @ `sha256:…` | The published image and pinned digest the clone runs from.              |
| `expose`                | `false`                              | Whether services bind `0.0.0.0` or localhost-only.                      |

A clone does **not** store which environment it belongs to. Membership lives on the
[environment](/concepts/environments) (`Environment.members`) as the single source
of truth; `status` derives a clone's environment by reverse lookup.

## Modes

A template declares **modes** — named sets of services. The first declared mode is
the default. Every template ships an `api` mode (`backend` only — the lightest
clone, enough for an agent that talks to the API or MCP server). The **Slack**
template additionally ships a `full` mode that adds the `frontend` UI; the
API-only templates (Stripe, Notion, HubSpot, GitHub, Linear) have `api` alone.

Pick one with `--mode`:

```bash theme={null}
asymmetric spin slack --mode full
```

Omit it and you get the template's first declared mode.

## Tokens

When a clone's template has a provision surface (Slack today), `spin` calls its
bootstrap endpoint once the backend is healthy and mints a default app with a
**bot token** and a **user token**. They're shown once at spin time and stored in
the registry (the clone DB keeps only hashes). Reprint or rotate them with
[`asymmetric tokens <id>`](/cli/tokens). Templates without a provision surface
simply have no tokens.

## States

A clone moves through a small state machine:

```
  creating ──▶ running ──▶ stopped ──▶ running ──▶ destroying ──▶ gone
                  │
                  └──▶ unhealthy / failed
```

| State                 | Meaning                                                 |
| --------------------- | ------------------------------------------------------- |
| `creating`            | Being built and started.                                |
| `running`             | Healthy and serving.                                    |
| `unhealthy`           | Containers up but the health check is failing.          |
| `stopped`             | Containers stopped, data preserved (`asymmetric stop`). |
| `failed`              | Spin or a lifecycle step errored.                       |
| `destroying` / `gone` | Being torn down / removed.                              |

`asymmetric doctor` flags clones in non-terminal states that need a live check.

## Environments

Clones compose into [**environments**](/concepts/environments) — the top-level
primitive you point an agent at and score. An environment has a name, a member list
(the source of truth for membership), and a rolled-up state
(`running` / `partial` / `stopped` / `failed`). Spin clones straight into one:

```bash theme={null}
asymmetric spin slack stripe --group acme   # both clones join environment "acme"
```

Or declare them in an `environment.yaml` and `asymmetric env spin` it. See
[Environments](/concepts/environments) for the full story.

## The registry

Everything above is persisted to `~/.asymmetric/registry.json` — a versioned JSON
file holding `clones` and `environments`, rewritten on every
`create` / `destroy` / `reset` / `seed` / `start` / `stop`. It's plain JSON and
safe to read (tokens are redacted from `status`/`ls`):

```bash theme={null}
asymmetric status --json
```

The schema is versioned and migrated on read: opening an older registry upgrades it
in place (v1 → v2 renamed `groups` to `environments` and rebuilt environments from
any legacy per-clone group tags, so no membership is lost on upgrade).

Because the registry is the source of truth, `status`, `doctor`, and `db` work
without touching Docker at all — they just read it. If it ever gets corrupted,
`asymmetric doctor` is the recovery path.

<Info>
  Override the registry location with `ASYM_HOME`. Point CI at a throwaway
  directory so its clones never collide with your local ones.
</Info>
