How Kortix works

The architecture — repo-as-project, the control plane, ephemeral sandboxes on branches, and change requests.

A project is one git repository with a manifestkortix.yaml by default, or legacy kortix.toml — at its root. A session runs the agent in an isolated sandbox VM with the repo cloned onto a branch named after the session. The sandbox is disposable; the branch persists. Work reaches the default branch only via a merged change request.

The pieces

  • Projects — a git repo (Kortix-managed or imported GitHub) plus its manifest.
  • Sessions — isolated sandbox VMs, each on its own branch. Many run at once without interfering.
  • Agents — OpenCode, governed by the manifest's agents: map and implemented through .kortix/opencode/.
  • Change requests — the git merge layer that lands a branch on the default branch.
  • Secrets — per-project encrypted values, given to sessions as environment variables.
  • Triggers — spawn a session on a schedule or from a webhook.
  • Connections — let the agent call external tools, brokered server-side.
  • Channels — drive a project from Slack.
  • Accounts — who owns projects and who can access them.

When a session starts

  1. The control plane (the Kortix API) inserts the session (provisioning) and cuts a branch from the default branch, named after the session id.
  2. It resolves a content-addressed snapshot — the platform's default image (or your own Dockerfile, if the manifest declares a sandbox.templates entry for it) plus the Kortix runtime layer, built by the sandbox provider (Daytona by default). Unchanged projects reuse the cached image.
  3. The sandbox provider boots the VM. The kortix-agent daemon clones the repo to /workspace, fetches git credentials just-in-time, and launches OpenCode. Status → running.
  4. The agent works with secrets as env vars, committing and pushing to the session branch.
  5. It opens a change request; you review and merge — the only path to the default branch.

Disposable by design

The sandbox is thrown away on stop or idle hibernation. Only committed-and-pushed branch work survives, and only a merged change request makes it permanent.

Two config surfaces

The manifest (kortix.yaml) + .kortix/Dockerfile are Kortix-owned; .kortix/opencode/ is OpenCode-native runtime behavior. agents: is a name-keyed map that is governance only — connectors, secrets, kortix_cli, skills, which agent names are launchable, and what each may touch. Everything about how an agent behaves (prompt, mode, tools, permissions) lives in that agent's own .kortix/opencode/agents/<name>.md, a stock OpenCode agent file. default_agent is required and must name a declared, enabled agent. See Kortix vs OpenCode config. Drive any of it from a terminal with the CLI — it controls the cloud, it doesn't run the agent locally.

Legacy kortix.toml

Existing projects may still run on kortix_version: 1 (kortix.toml, [[agents]] as an array of tables, no required default_agent). Both formats are read by the platform; migrate in-app via "Upgrade to kortix.yaml." See Projects.

How Kortix works – Kortix Docs