Skip to main content

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:
{
  "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.
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>.
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 restores from), and a cargo.state.audit.jsonl (run log). Only cargo.state.json is committed; git-ignore the rest:
.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)

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

Correct

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.
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.

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 for the full secret() vs env() rules and how to deploy the same code to a second workspace.