---
name: deploy-create
description: "Put an agent on the platform: register or create its repository, push the reviewed branch and create its runtime, or for a change pin staging to the branch's version. The second step of deploy."
metadata:
  min-cli-version: "0.81.0"
  next: "deploy-connect deploy-test"
---

# Deploy: runtime

Take the agent from this machine to a running version on the platform. The owner says yes to each step that leaves this machine.

## Before you start

deploy-connect has checked the CLI, the login and the scopes, knows whether this is a first deploy or a change, and has connected the required servers. If it hasn't run, start there. Each step below that leaves this machine needs the owner's yes, as it says.

## 1. Choose the repository

Use the choice onboarding or build already made (onboarding registers the GitHub repository; `build-review` records it in Part B's change log), and don't ask again. A hosted one the owner chose is created right away.

Otherwise offer, existing first, in this order:

```sh
git remote -v                                        # 1. where the clone already pushes
introspection repositories list -o table             # 2. one the project has
introspection integrations repositories --type github # 3. one GitHub reaches
```

and only if none fits, 4. a new private hosted one. Never pick for the owner. Create or register it as [the repository reference](references/repository.md) says. A repository the GitHub integration doesn't reach needs the GitHub App on its organization first: say so and stop. A hosted one is ready to push when `repositories list` shows it `ready`.

## 2. Push and land on `main`

A runtime follows `main`: production serves it and each push builds a version. Land the reviewed branch with a push (a login can push but can't merge):

```sh
git push origin pr/<name> pr/<name>:main
```

A Recipe already on `main` needs no push.

**Which git access:** try, don't ask.

- On the owner's machine, if `ssh -T git@github.com` greets them (it exits 1), set `origin` to `git@github.com:<owner>/<name>.git`.
- Otherwise, or in a cloud session, run once:

  ```sh
  introspection git-credential configure
  ```

If the push is refused, stop and show the owner the exact error, with the two fixes: add an SSH key to their GitHub account, or give the organization's GitHub App access to the repository. Never force-push or rewrite history.

## 3. Create the runtime

BYOK's LLM binding and a chat connector need the runtime: deploy-connect connects them after this step.

<!-- rule: R-first-runtime-prod-bootstrap -->

### A first runtime

Ask the owner which LLM model provider to use, Introspection managed or BYOK ([before the first runtime](references/repository.md#before-the-first-runtime)). Then:

```sh
git fetch origin && git checkout -B main origin/main && git remote set-head origin --auto
introspection runtimes list --query "[].slug"   # still none
introspection runtimes create --yes
```

With several manifests, ask the owner which and add `--manifest .introspection/<name>.yaml`. The first version is `main`'s commit, live in staging and production at once: nothing to pin. If it warns it couldn't read the default branch, the clone isn't on `main` with its head set: fix that and create again.

<!-- rule: R-no-second-runtime-group -->

### An agent that already has a runtime

A later change, or improve-propose's branch. Never run `runtimes create` again (it splits the agent's history), and never push to `main` (it goes live in production). Push only the branch; the owner lands it through its pull request:

```sh
git push origin pr/<name>
introspection runtimes versions <slug> --branch pr/<name> --sha $(git rev-parse pr/<name>) \
  --query "[0].[id, image_build_status]"   # null until the platform has made it
introspection runtimes pin <version-id> --sha <head-commit>    # once ready: staging runs it
```

After every later push to the branch, pin the new head commit's version the same way.

**Still `pending` after about five minutes:** a branch's version builds only once it claims a free staging lane. Read who holds staging:

```sh
introspection runtimes get <slug> --resolve --query staging_pin
```

When another ref holds it, tell the owner which one and offer, with the question tool, to unpin it (`introspection runtimes unpin <id> --yes`, production's version id from `--resolve --query environments.production.version_id`); don't blame the data plane. Only when staging is free and the version still hasn't started does step 4's diagnosis apply. If no version from the branch appears, stop and tell the owner. deploy-test runs on that version (`--runtime-id <version-id>`). Once the pull request has landed:

```sh
introspection runtimes unpin <version-id>   # staging follows main again
```

## 4. Wait for the version

```sh
introspection runtimes get <slug> --query '[image_build_status, image_build_error_message]'
```

Repeat until it's `ready`.

- **`failed`:** show the owner the message and stop.
- **"warmup was not delivered":** the platform couldn't reach the data plane. Once it's up, make a new version (a push to `main`, or a retry from the Runtime's page).
- **`pending` with no build metadata after about five minutes** (a branch's version: check who holds staging first, as above): the version hasn't started. Stop and tell the owner; locally that usually means the data plane's worker isn't running.
- **Locally, a push to GitHub adds no version** unless the webhook relay runs (`make dev-relay`): say so rather than wait.

Write the runtime, the version id and its commit in [the record](references/record.md):

```sh
introspection runtimes versions <slug> --query "[0].[id, git_commit_sha]"
```

<!-- rule: R-registration-not-readiness -->

A ready version can still be missing connections its Recipe needs: deploy-connect is next for those.

## 5. Show the owner the runtime

Once a first runtime's version is ready, call `introspection_open` with `{kind: "runtime", runtime: "<slug>"}`, `wait: true`, reason "Your agent is live: open it to chat with it", on its own in a turn, instead of a link. Carry on when they come back.

## Guardrails

- **The owner chooses every target:** the repository, its name, whether to push, the runtime.
- **Deploy what was reviewed:** push the branch as it is. A change found here goes back through draft and review.
- **Never force-push, rewrite history or delete a branch.** Remove a file that shouldn't have been committed with a new commit, and tell the owner.
- **Never handle credentials:** login holds them; one the platform lacks is the owner's to set up.

<!-- rule: R-runtime-resources-from-observation -->

- **Leave runtime resources unset** unless a run showed a need.

## Done when

- The Recipe is on `main` in the repository the owner chose.
- A runtime serves it, its version's image is ready, and the record names the runtime, version and commit.
- **A first deploy** goes back to `deploy-connect` for what needed the runtime (BYOK, a chat connector, a per-environment binding), then `deploy-test`; **a change** goes to `deploy-test`, on the pinned version.
