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

# State & Drift

> How cargo.state.json links your code to deployed Cargo resources, why you commit it, the lock file, and detecting changes made outside the CDK with cdk refresh.

## `cargo.state.json`

Every deploy writes `cargo.state.json` — a map from each code resource
(`kind:slug`) to the real uuid Cargo assigned it, plus its outputs and a content
hash:

```json theme={null}
{
  "version": 1,
  "workspaceUuid": "fbe3...",
  "resources": {
    "connector:hubspot": { "hash": "sha256:…", "uuid": "9c26…", "outputs": { "uuid": "9c26…", "datasetUuid": "f12c…" } }
  }
}
```

It's the authoritative link from code to deployed infra. Connectors and models
are slug-addressable and self-heal, but **plays, agents, tools, files and MCP
servers have no slug** — their stored uuid is the only way to re-find them.

<Warning>
  **Commit `cargo.state.json`.** If you lose it, uuid-only resources orphan and a
  re-deploy creates duplicates. Recover a lost link with
  `cargo-ai cdk import <id> <uuid>`.
</Warning>

It records only uuids, hashes and outputs — **never secret values**.

### Lock file

During a deploy/destroy/import the CDK writes sibling files next to
`cargo.state.json` — a `cargo.state.lock` (serializes concurrent runs), a
`cargo.state.bak.json` (the snapshot [`cdk rollback`](/deploy/deploying#rollback)
restores from), and a `cargo.state.audit.jsonl` (run log). Only
`cargo.state.json` is committed; **git-ignore the rest**:

```gitignore theme={null}
.cargo-ai/            # generated by `cdk types`
cargo.state.lock
cargo.state.bak.json
cargo.state.audit.jsonl
```

A lock left by a dead process is reclaimed automatically; `--force` overrides one
you believe is stale.

## Drift

The CDK compares your code against state. It can also compare against the live
workspace to catch changes made **outside** the CDK (e.g. someone edits an agent
in the Cargo UI, or deletes a folder).

### Detect (read-only)

```bash theme={null}
cargo-ai cdk refresh
```

Re-reads every state-tracked resource and reports each as `unchanged`,
`modified externally`, or `deleted externally`. It changes nothing.

### Correct

```bash theme={null}
cargo-ai cdk deploy --refresh
```

Folds the drift into the plan before applying:

* **Modified externally** → re-applies your code over it (**code wins**).
* **Deleted externally** → the deploy **stops** and asks you to re-run with
  `--recreate-deleted` before it will recreate anything — a deliberate gate so a
  resource someone removed on purpose doesn't silently come back.

<Note>
  Drift is measured against the state captured at the last deploy, not guessed
  from code — so it reflects real changes to the live resource. A transient read
  error is reported as `unknown`, never as a deletion, so a network blip can't
  trigger a mass re-create.
</Note>

## Code and UI round-trips

Resources deployed from code remain fully editable in the Cargo UI — but the
CDK never reads those edits back into your files. What happens to UI work on
the next deploy follows directly from the hash model:

* **A plain `cdk deploy` compares code against state, not against the live
  workspace.** If you haven't changed a resource in code, it plans as
  `=` unchanged and is skipped — UI edits to it survive every deploy.
* **The moment you change that resource in code**, the next deploy pushes the
  full code spec and overwrites the resource — including anything changed in
  the UI since.
* **`cdk deploy --refresh` re-applies code over every externally-modified
  resource**, whether or not its code changed. Reach for it when you want to
  reset to what the repo says; avoid it while UI work is in flight.

The practical rule: **pick one owner per resource.** Starting a workflow in
code and finishing canvas-only parts in the UI works — but from then on treat
the UI as that resource's source of truth: leave its code definition alone, or
port the canvas changes back into code before touching it again. Run
`cargo-ai cdk refresh` before deploying to see exactly which resources have
diverged.

## Secrets and drift

Because `secret()` values are excluded from the content hash, **rotating a secret
does not show as drift** and a plain `deploy` won't push the new value (nothing
changed). To roll a rotated secret, re-apply the resource (make any other change,
or use `--refresh`). Use `env()` instead if you *want* a config value tracked in
the hash. See [Secrets & environments](/reference/secrets-and-environments) for
the full `secret()` vs `env()` rules and how to deploy the same code to a second
workspace.
