KortixDocs
Reference

Session runtime

Status model, branch creation, sandbox layout, injected environment, and the in-sandbox daemon.

The runtime mechanics of a session. For the technical model of what a session is, see Sessions.

A session is one conversation with the agent, run in an isolated sandbox VM (provisioned on Daytona) with the project repo cloned and checked out on a branch named after the session id. The sandbox is ephemeral; the branch persists. Work reaches the default branch only through a change request.

Status model

A session row (project_sessions) carries a status. The enum defines queued, branching, provisioning, running, stopped, failed, completed; the runtime only writes a subset:

StatusSet when
provisioningAt session create — the row is inserted directly as provisioning. The session branch is created and the sandbox is requested during this phase.
runningOnce the sandbox is live and reachable.
stoppedOn explicit stop, or by the idle sweep that hibernates inactive sandboxes.
failedIf provisioning errors out.

queued and branching exist in the enum but are not part of the live session flow; completed is defined but not currently written. The sandbox itself is tracked in a separate session_sandboxes row with its own states (provisioning → active → stopped | error | archived).

Concurrent-session caps are enforced per account; exceeding your tier returns 429.

Branch model

  • The session branch is named after the session id (a UUID). KORTIX_SESSION_ID and KORTIX_BRANCH_NAME are the same value.
  • It is cut from base_ref, which defaults to the project's default_branch (usually main), at create time.
  • Creation path depends on the backend: GitHub repos use the GitHub API (read the base tip, create the branch ref); generic git backends (e.g. Freestyle) push refs/heads/<base>:refs/heads/<session-id>.
  • Triggers create their session branch the same way an interactive session does. Nothing writes the default branch directly except a change-request merge.

What survives

Only what the agent commits and pushes to the session branch. The sandbox filesystem is disposable — re-cloned fresh on every boot, torn down on stop, hibernation, or restart. Commit in small chunks so a mid-run teardown loses nothing already pushed. The branch reaches the default branch only once a change request merges it.

Layout inside the sandbox

/workspace                       ← WORKDIR. The project repo is cloned here.
/workspace/.kortix/              ← Repo-internal Kortix folder (Dockerfile + opencode config dir).
/usr/local/bin/kortix-agent      ← The daemon (supervisor + reverse proxy).
/usr/local/bin/kortix-entrypoint ← The container ENTRYPOINT (PID 1).
/opt/kortix/home                 ← OpenCode's HOME — its object store lives here, off the repo.

OpenCode's HOME is /opt/kortix/home, not /workspace, so its store never lands among your repo files.

Injected environment

Injected at boot, alongside your project's secrets (which arrive as plain env vars):

VariableWhat
KORTIX_PROJECT_IDUUID of this project.
KORTIX_SESSION_IDUUID of this session. Also the branch name.
KORTIX_BRANCH_NAMESame as KORTIX_SESSION_ID — the branch your work pushes to.
KORTIX_REPO_URLClone URL for the project repo.
KORTIX_DEFAULT_BRANCHThe base ref (the repo's default branch).
KORTIX_BASE_REFThe ref this session branched from.
KORTIX_SERVICE_PORT8000 — the daemon's external port.
KORTIX_API_URLThe platform API base (…/v1).
KORTIX_AGENT_NAMEThe OpenCode agent the session was created with.
KORTIX_OPENCODE_MODELThe model to run, when set.
KORTIX_INITIAL_PROMPTThe first prompt, when the session was spawned by a trigger or created with one.
KORTIX_PROJECT_AUTO_CLONE1 — tells the daemon to clone the repo on boot.
KORTIX_PROJECT_SECRET_NAMESComma-separated names of the project's secrets.
KORTIX_PROJECT_SECRETS_REVISIONRevision marker for the secret set.
KORTIX_TOKENThe sandbox service key. The daemon signs and validates its own control-surface requests with it. It is not a project API token, and the kortix CLI does not read it — the project-scoped API routes reject it.
KORTIX_CLI_TOKENThe project-scoped PAT the in-sandbox kortix CLI authenticates with (same value as KORTIX_EXECUTOR_TOKEN).
KORTIX_EXECUTOR_TOKENThe same project-scoped PAT — acts as the launching user, scoped to the project. Also backs the kortix-executor MCP gateway.
KORTIX_BOOTSTRAP_OPENCODE_SESSION1 when the session was created with an initial prompt — tells the daemon to open the OpenCode session at boot.
KORTIX_LLM_API_KEY · KORTIX_LLM_BASE_URLManaged LLM-gateway key + base URL, injected only on plans that use Kortix's bundled model access. KORTIX_YOLO_API_KEY / KORTIX_YOLO_URL are aliases for the same pair.

Not injected: KORTIX_WORKSPACE (/workspace) is baked into the image, not per session. No KORTIX_GITHUB_TOKEN — git credentials are fetched just-in-time by the daemon (below). When a project brings its own model keys they travel as ordinary project secrets OpenCode reads at boot; the KORTIX_LLM_* pair above appears only on plans that use Kortix's managed model access.

The KORTIX_* prefix is reserved for platform variables; a user secret using it is rejected (Secrets).

Pushing from a session

The daemon fetches a short-lived clone credential (GET /v1/projects/:id/git/clone-credential) using KORTIX_TOKEN — no static token in the environment. With that, git push origin HEAD sends commits to the session branch. Landing on the default branch goes through a change request.

The agent runtime

The agent is OpenCode, launched by the daemon as opencode serve --port 4096 --hostname 127.0.0.1 with OPENCODE_CONFIG_DIR at the project's config dir ([opencode] config_dir, default .kortix/opencode), resolved from the cloned repo. See Kortix vs OpenCode config.

The daemon control surface

The kortix-agent binary runs as PID 1's child and fronts OpenCode on KORTIX_SERVICE_PORT (8000). Everything outside /kortix/* requires the HMAC-signed X-Kortix-User-Context header (validated against KORTIX_TOKEN).

PathPurpose
GET /kortix/healthLiveness (auth-bypassed). Reports daemon + OpenCode state, repo, branch, commit.
POST /kortix/refreshRe-pull the session branch and restart OpenCode in place.
POST /kortix/promptDeliver a prompt to the running agent.
POST /kortix/abortAbort the current run.
POST /kortix/envUpdate the runtime environment.
/proxy/{port}/*Reverse-proxy to a port inside the sandbox (its own port is blocked).
*Catch-all reverse-proxy to OpenCode on 127.0.0.1:4096 (503 while it boots).

/kortix/refresh is how the dashboard applies an out-of-band change (e.g. a manifest edit committed from a parallel session) without re-provisioning the sandbox.

Session runtime | Kortix Docs | Kortix