---
name: deploy-runtime
description: "Put an Introspection agent (Recipe) on the platform: choose its repository with the owner (an existing one first), push and land the reviewed branch, create the runtime from `main` and wait for its version. Use after build-review, or when the owner asks to deploy a Recipe that already exists. Needs `introspection login`; deploy-connect follows."
---

# Deploy: runtime

Take the agent from this machine to a running version on the platform, with the owner saying yes to each step that leaves this machine.

## Before you start

- **Read only what you need.** Every `introspection` command takes `--query` (JMESPath), so ask for the fields a step uses rather than whole records: `runtimes get <slug> --query image_build_status`, `runtimes versions <slug> --query "[0].[id, git_commit_sha]"`, `runtimes list --query "[].[slug, id]"`, `repositories list --query "[].name"`, `whoami --query "[member_name, project_id]"`. A single string prints quoted: strip it with `| tr -d '"'` when you capture it in a variable.
- You need the `introspection` CLI (`npm i -g @introspection-ai/cli`) and git. Use the CLI for the platform and git for pushing: the CLI has no push of its own, and login sets git up for the platform's repositories.
- **Check the stage.** After build: approved cases in `evals/cases/` and `docs/PULL_REQUEST.md` committed on `pr/<name>`; if either is missing, go back to build-review. An existing Recipe the owner asks to deploy needs neither: run `introspection check` in it, and if it passes, say in one line what it lacks (no cases, no pull request) and carry on from `main`.
- **Check the login:** `introspection whoami`. If it isn't signed in, ask the owner to run `introspection login` in their own terminal, then carry on. If it, `runtimes list` or `repositories list` fails with anything else (a 404, a connection refused, a server error), stop and show the owner the error: every later step depends on reading the platform, and a choice made without that reading can duplicate a runtime or a repository.
- <!-- rule: R-deploy-scopes-stop-before-register --> **Check its scopes** in the `whoami` output: creating a runtime needs `recipes:write`, `repositories:read` and `runtimes:write`, and pushing to a hosted repository needs `git:push`. If one is missing, name it and stop before creating anything.
- **Find out whether the agent already has a runtime:** `introspection runtimes list -o table`, for one named as in `.introspection/<name>.yaml`. A first deploy has none.

## Steps

Every step that leaves this machine (creating a repository, a push, creating a runtime) needs the owner's yes in this session: ask with the question tool, saying what happens and what it changes, one decision per question: a choice (which manifest, which repository) and the go-ahead to act on it are two questions, the choice first, and picking an option isn't a yes. [The record](references/record.md) keeps each approval.

1. **Choose the repository with the owner, an existing one first.** Offer, in this order: the repository the clone already pushes to (`git remote -v`), one the project already has (`introspection repositories list -o table`), and only if none fits a new private one the platform hosts. Never pick one yourself, and create or register it only once they've chosen, as [the repository reference](references/repository.md) says. A hosted one is ready to push when `repositories list` shows it `ready`.
2. **Push and land on `main`,** once the owner says yes. A runtime follows `main`: production serves it, and each push to it builds a version. After build, land the reviewed branch with a push, `git push origin pr/<name> pr/<name>:main`: a login can push but can't call the merge API (`repositories merge` needs `repositories:write`). An existing Recipe already on `main` needs no push. If git asks for a credential, run `introspection git-credential configure` once. If git refuses the push to `main`, stop and show the owner the exact error. Never force-push or rewrite history.
3. **Create the runtime from `main`.**
   - <!-- rule: R-first-runtime-prod-bootstrap --> **A first runtime:** settle the model access mode with the owner first ([before the first runtime](references/repository.md#before-the-first-runtime)). Then `git fetch origin && git checkout -B main origin/main && git remote set-head origin --auto`, check again that `runtimes list` has none, and run `introspection runtimes create --yes` (`--manifest .introspection/<name>.yaml --yes` when the Recipe has several manifests: ask the owner which, as [the repository reference](references/repository.md#before-the-first-runtime) says). Its first version is `main`'s commit, live in staging and production at once: there's nothing to pin. If it warns that 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 with a runtime** (a later change, or improve-propose's branch): later versions come from git, never from another `runtimes create`, which would split the agent's history, and never from a push to `main`, which goes live in production at once. Push only the branch (`git push origin pr/<name>`); the owner lands it through its pull request. Wait until `introspection runtimes versions <slug>` lists a version built from the branch's head commit with `image_build_status: ready`, then pin staging to it: `introspection runtimes pin <version-id> --sha <head-commit>`. If none appears, stop and tell the owner; never push to `main` to get one. deploy-test then runs on that exact version (`--runtime-id <version-id>`). Once the owner has landed the pull request, `introspection runtimes unpin <version-id>` returns staging to following `main`.
4. **Wait for the version:** `introspection runtimes get <slug>` until `image_build_status` is `ready`; if the build failed, show the owner its error and stop. Note the runtime, the version id (`introspection runtimes versions <slug>`) and the commit it was built from in [the record](references/record.md).
   - <!-- rule: R-registration-not-readiness --> A version can be ready while connections its Recipe needs are missing: deploy-connect is next for that.
5. **Hand over to `deploy-connect`.**

## Guardrails

- **The owner chooses every target:** the repository, its name, whether to push, the runtime. You propose; they decide.
- **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.** A file that shouldn't have been committed is removed with a new commit, and the owner is told.
- **Never handle credentials:** login holds them; a step that needs one the platform doesn't have 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.
