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:
| Status | Set when |
|---|---|
provisioning | At session create — the row is inserted directly as provisioning. The session branch is created and the sandbox is requested during this phase. |
running | Once the sandbox is live and reachable. |
stopped | On explicit stop, or by the idle sweep that hibernates inactive sandboxes. |
failed | If 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).
ARISE_SESSION_IDandARISE_BRANCH_NAMEare the same value. - It is cut from
base_ref, which defaults to the project'sdefault_branch(usuallymain), 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 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/.arise/ ← Repo-internal Arise folder (Dockerfile + opencode config dir).
/usr/local/bin/arise-agent ← The daemon (supervisor + reverse proxy).
/usr/local/bin/arise-entrypoint ← The container ENTRYPOINT (PID 1).
/opt/arise/home ← OpenCode's HOME — its object store lives here, off the repo.OpenCode's HOME is /opt/arise/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):
| Variable | What |
|---|---|
ARISE_PROJECT_ID | UUID of this project. |
ARISE_SESSION_ID | UUID of this session. Also the branch name. |
ARISE_BRANCH_NAME | Same as ARISE_SESSION_ID — the branch your work pushes to. |
ARISE_REPO_URL | Clone URL for the project repo. |
ARISE_DEFAULT_BRANCH | The base ref (the repo's default branch). |
ARISE_BASE_REF | The ref this session branched from. |
ARISE_SERVICE_PORT | 8000 — the daemon's external port. |
ARISE_API_URL | The platform API base (…/v1). |
ARISE_AGENT_NAME | The OpenCode agent the session was created with. |
ARISE_OPENCODE_MODEL | The model to run, when set. |
ARISE_INITIAL_PROMPT | The first prompt, when the session was spawned by a trigger or created with one. |
ARISE_PROJECT_AUTO_CLONE | 1 — tells the daemon to clone the repo on boot. |
ARISE_PROJECT_SECRET_NAMES | Comma-separated names of the project's secrets. |
ARISE_PROJECT_SECRETS_REVISION | Revision marker for the secret set. |
ARISE_TOKEN | The sandbox service key. The daemon signs and validates its own control-surface requests with it. It is not a project API token, and the arise CLI does not read it — the project-scoped API routes reject it. |
ARISE_CLI_TOKEN | The project-scoped PAT the in-sandbox arise CLI authenticates with (same value as ARISE_EXECUTOR_TOKEN). |
ARISE_EXECUTOR_TOKEN | The same project-scoped PAT — acts as the launching user, scoped to the project. Also backs the arise-executor MCP gateway. |
ARISE_BOOTSTRAP_OPENCODE_SESSION | 1 when the session was created with an initial prompt — tells the daemon to open the OpenCode session at boot. |
ARISE_LLM_API_KEY · ARISE_LLM_BASE_URL | Managed LLM-gateway key + base URL, injected only on plans that use Arise's bundled model access. ARISE_YOLO_API_KEY / ARISE_YOLO_URL are aliases for the same pair. |
Not injected: ARISE_WORKSPACE (/workspace) is baked into the image, not per session. No ARISE_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 ARISE_LLM_* pair above appears only on plans that use Arise's managed model access.
The ARISE_* 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 ARISE_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 .arise/opencode), resolved from the cloned repo. See Arise vs OpenCode config.
The daemon control surface
The arise-agent binary runs as PID 1's child and fronts OpenCode on ARISE_SERVICE_PORT (8000). Everything outside /arise/* requires the HMAC-signed X-Arise-User-Context header (validated against ARISE_TOKEN).
| Path | Purpose |
|---|---|
GET /arise/health | Liveness (auth-bypassed). Reports daemon + OpenCode state, repo, branch, commit. |
POST /arise/refresh | Re-pull the session branch and restart OpenCode in place. |
POST /arise/prompt | Deliver a prompt to the running agent. |
POST /arise/abort | Abort the current run. |
POST /arise/env | Update 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). |
/arise/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.