# Cloud Machines

A **Cloud Machine** is one isolated container for one job. Each project keeps a **Project Environment** with its code, toolchain and dependencies already set up. Every cycle run, review, preview build and terminal or Desktop starts its own Cloud Machine from that environment at an exact commit. The Cloud Machine is deleted when the job ends.

Your **Workspace** organizes people and projects. Cloud Machines run individual jobs for those projects.

<span id="when-this-matters-to-you" />

<span id="a-project-environment-a-fresh-cloud-machine-per-job" />

## A Project Environment, a fresh Cloud Machine per job

The **Project Environment** is the project after setup: the repository checked out, the toolchain installed, the dependencies in place. hlix builds it from a clean machine image and keeps it only when setup succeeds. It never contains a secret.

Every job starts a fresh Cloud Machine from it:

| Job | What runs in its Cloud Machine |
| --- | --- |
| **Cycle run** | Files, commands and tests for the cycle's checklist on its own branch. |
| **Review** | Your app, served from its preview command at the exact commit under review, plus your end-to-end suite and a browser. |
| **Preview build** | The build of the commit that was just merged, once per merge. |
| **Terminal, Desktop** | A shell or a graphical desktop at the head of the project's preview branch, while you use it. |

Concurrent cycles use separate Cloud Machines, checkouts and branches. Each can edit the same file in its own copy. If their changes collide, the conflict surfaces when the later cycle is delivered, and that cycle's next run resolves it.

Hlix refreshes the Project Environment when dependencies or setup steps change. Jobs can perform a fresh checkout and setup while that refresh completes.

## Where the source lives

Every project has a remote repository: a connected GitHub repository, or an **HLIX Repos** repository for a project created without one. A Cloud Machine only ever holds a working copy. The coder pushes the cycle branch to the repository about every minute, merges happen there, and previews build an exact commit from there. Pushed commits remain available after a Cloud Machine is deleted, and the next run continues from the published branch. Unpushed changes in a lost Cloud Machine may need to be repeated. Published files stay readable while no Cloud Machine runs.

Merges into a project's repository happen one at a time, so two cycles finishing together take turns instead of racing.

## Who runs inside it

[Hlix Code](/coders/native-hlix/) and [external coders](/coders/external-acp/) use the same isolated cycle branch and delivery checks. Choose the coder and its funding in [AI settings](/guides/connect-agents/).

<span id="lifecycle-and-cost" />

## Lifecycle

Nothing runs for a project while no job does. A coding run, review or build Cloud Machine lives exactly as long as its job. A terminal or Desktop Cloud Machine lives while you use it: an open tab keeps it alive, and it is deleted 15 minutes after the last tab closes. Cloud Machines left behind by a job that stopped before it finished are cleaned up automatically.

Between jobs, the project retains its newest Project Environment without keeping a Cloud Machine running. See [Usage and task prices](/billing/usage-and-credit/) for customer billing.

<span id="secrets-in-every-cloud-machine" />

## Secrets in every Cloud Machine

hlix writes your project's secrets into every Cloud Machine it starts, whatever the job: a cycle run, a review, a preview build and your terminal all see the same values. They are written fresh on each start and never stored in the Project Environment. Every process in the Cloud Machine receives them as its environment, which is how build-time variables reach a preview build.

The generated root `.env` is excluded from commits. If the repository already tracks a root `.env`, remove it from Git tracking before using that path for project secrets.

See [Secrets & protected files](/security/secrets-and-protected-files/) for credential handling and [Project secrets](/configure/secrets/) to manage values.

## Hosted previews from custom static builds

For a custom static build, declare its output in the repository's root `package.json`:

```json
{
  "hlix": {
    "preview": { "kind": "static", "outDir": "apps/web/dist" }
  }
}
```

hlix installs dependencies and runs the root `build` script in an isolated Cloud Machine at the preview commit, then publishes the declared directory. The directory must be inside the repository, contain `index.html`, and contain only files intended for the browser. Secrets, Git metadata and symbolic links must not be included. This declaration is for apps that need no server at runtime; it also applies when publishing the project to production.

<span id="the-coders-own-api-credential" />

## Opening a shell

`GET /v1/api/projects/:id/terminal` opens a shell in a Cloud Machine started from the Project Environment, at the head of the project's preview branch. The first request starts the Cloud Machine and answers at once; repeat the request until the terminal is available.

```bash
curl -sS "$HLIX_BASE_URL/v1/api/projects/$PROJECT_ID/terminal" \
  -H "x-api-key: $HLIX_API_KEY" \
  -H "X-Organization-Id: $HLIX_WORKSPACE_ID"
```

While it starts:

```json
{"available": false, "environmentState": "creating", "reason": "starting a terminal for this project"}
```

Once it is up:

```json
{
  "available": true,
  "webTerminalUrl": "https://…"
}
```

Open `webTerminalUrl` to use the browser terminal. Treat it as a credential and request a fresh link if it stops working.

Use `expiresAt`, when returned, to check the terminal link's expiry. The [Terminal API](/api/reference/projects/) documents the full response.

Everyone who opens the terminal on a project shares one Cloud Machine. It is temporary: anything you change there and do not push is lost when it is deleted.

Terminal access requires agency `manage` access because the Cloud Machine contains project secrets.

<span id="common-questions" />

<span id="if-a-cloud-machine-will-not-open" />

## If a Cloud Machine will not open

- `{"available": false, "environmentState": "creating", …}` — the Cloud Machine is starting. Repeat the request; it becomes available on its own. From the Project Environment this takes seconds; while the Project Environment is being rebuilt, the first start can take a few minutes.
- `{"available": false, "environmentState": "absent", …}` — the project is **archived**, so no Cloud Machine is started. Unarchive the project to use the terminal.
- `{"available": false, "reason": "could not start a terminal for this project"}` — the start failed. The next request tries a fresh Cloud Machine.
- `403` on the terminal endpoint — ask an agency member with `manage` access to open it.
- **The terminal link expired** — request terminal access again for a fresh link.

<span id="where-to-go-next" />

## Next steps

[Glossary](/concepts/glossary/)
  [Secrets & protected files](/security/secrets-and-protected-files/)
  [Agents & orchestration](/concepts/agents/)
  [Environment discovery](/cli/environment-discovery/)