# Deploy a version

What tanomis agent deploy does between your source tree and an enabled tenant, and how to read what it tells you.

One command takes a local agent directory to a version a tenant can serve. This guide explains
each stage so the output makes sense and failures are quick to place.

```bash title="Terminal"
tanomis agent deploy ./agents/support-copilot --tenant "$TANOMIS_TENANT" --dry-run
tanomis agent deploy ./agents/support-copilot --tenant "$TANOMIS_TENANT"
```

1. **Preflight** validates the manifest and the lock policy locally.
2. **Package** produces a deterministic bundle. `--dry-run` stops here and prints the plan.
3. **Build** runs remotely and streams progress to your terminal.
4. **Register** records the immutable version with its declared contract.
5. **Warm-start snapshot** is built or reused.
6. **Enable** assigns the version to the tenant you named. This is the only step that routes traffic.

## 1. Preflight

Before anything leaves your machine, the CLI:

- parses `agent.yaml` and requires a harness (`framework`);
- rejects a stray `Dockerfile` or an unsupported top-level `build` field, because the platform
  owns the image;
- flags files that look like secrets (`.env`, `*.pem`, `*.key`, names containing `credentials`)
  and excludes them from the package;
- enforces the Python lock policy: a `uv.lock` or a pinned `requirements.txt`. A bare
  `pyproject.toml` is rejected.

Fix preflight failures in the source tree; nothing was uploaded.

## 2. Package

The bundle is deterministic: repackaging the same tree yields the same checksum, which is what lets
a version be reproduced and compared later. `--dry-run` ends here and prints what would be built
and for which tenant. Use it in CI to validate a change without creating a version.

## 3. Build

The bundle is uploaded and built remotely. Progress streams to the terminal. A build failure names
the file and step; the version is not registered.

## 4. Register

The build result is registered as a new version of the agent, with the manifest contract captured
as declared: models, network egress, policy ceiling, connectors, resources, session limits.
Registration also validates the declaration against the tenant's ceilings, for example that every
`network.egress` entry is inside the tenant's egress ceiling. A rejected declaration names the
entry and the ceiling that excluded it.

## 5. Warm-start snapshot

For the new version the platform reuses a compatible golden snapshot when one exists, or builds one.
This happens before the tenant is enabled, so the first session never races it. If a snapshot
cannot be produced, the deploy still succeeds: the version is enabled, sessions start cold until a
snapshot exists, and the output says so.

> **Availability:** `cr_enabled` requests eligibility for a server-managed golden snapshot. The
> server may build one, reuse one, skip it, or not offer the capability. Only the CLI's final golden
> message establishes whether sessions warm-start; unavailable, skipped, or failed goldens leave the
> version deployed with cold starts. Do not retry a successful deploy.

## 6. Enable

The version is enabled for the tenant you passed with `--tenant`. Other tenants are untouched.
Enablement is tenant-scoped and reversible:

```bash title="Terminal"
tanomis agent get support-copilot --tenant "$TANOMIS_TENANT"     # what this tenant serves now
tanomis agent versions support-copilot --by-tenant                # who serves which version
tanomis agent disable support-copilot --tenants "$TANOMIS_TENANT" # stop serving it here
```

`disable` removes only the tenant's enablement and records an audit event. The agent and its
versions are untouched, and re-running it is safe.

The deploy output ends with the new version label and the tenant it is enabled for.
`tanomis agent versions NAME --by-tenant` lists that tenant under the new version.

## Deploy from CI

Deploys are non-interactive once the CLI is authenticated. A typical pipeline runs a dry run on
every change and a real deploy on merge, then rolls out to customer tenants deliberately with
[Roll out and roll back](/guides/deploy/rollout-and-rollback) rather than deploying straight to
them.

## Where to go next

- [Roll out and roll back](/guides/deploy/rollout-and-rollback): canary a version for named
  tenants, graduate it, or return to the known-good version.
- [Agents and versions](/concepts/agents-and-versions): why versions are immutable and what
  enablement means.
- [`tanomis agent deploy`](/cli/agent/deploy): every flag.
