Skip to main content
deploy() turns the solution a build delivered into running software on a target. One session adapts a copy of the solution to the target, deploys it with the target’s own scripts, proves one call, and writes a result the engine checks; the deployment is recorded under the campaign, and you get a Software handle that runs, stops, starts and reads it, from this process or any later one.

Which target?

The target is the call’s; with none named, the config’s deployment.target decides (auto as packaged). A harness target is a skill the build’s harness lists on its deployment module and that holds scripts/deploy.sh; kapso deploy campaign --target k8s is refused in one line naming the targets available, the bundled ones and the harness’s (and, on a build without a harness, that a harness’s target needs --harness). kapso doctor deploy shows the session’s host and the targets’ tools: required for the configured target (with its probe, docker info for docker), advisory for the others. The three cloud targets ship with scripts exercised against fake executables and SDKs, not against an account: the first run under yours is the proof. Check first, in this order: modal app stop <app> --yes and modal.Function.from_name(app, "predict").hydrate(); that modal.Secret.from_dotenv() resolves at deploy time in the workspace; bentoml deploy . --name, the endpoint_urls field of bentoml deployment get -o json, and whether get_client().predict(inputs=…) carries the credentials bentoml cloud login saved for a protected endpoint; langgraph deploy --name from a local workspace and what it prints.

What a deployment is

  • The session. One coding-agent session on a copy of the solution, on the host deployment.cli names (the build’s host when null), staged with the target’s skill and, on a build made with a harness, the harness’s deployment page, skills, servers and hooks. It adapts the copy to the target’s entry point, runs the target’s scripts/deploy.sh, proves one call with real inputs and writes kapso_deployment.json.
  • The acceptance. The engine checks the result against what it can observe: the file parses and has its shape, the target requested (or offered, under auto), the run kind the target’s skill declares, the function’s module in the workspace, the artifacts inside it, the target’s health check, and the proof call run again (what it answered is recorded as observed and printed beside the session’s own answer). The record stays deploying until every check passed. A check that fails goes back to the session once with the finding, under the same deadline (deployment.timeout, thirty minutes as packaged); failing again, the deployment is failed with the reason.
  • The record. <campaign>/.kapso/deployments/<n>/ holds deployment.json, written before the session starts (state: deploying) and completed at its end (running, or failed with the error); the target’s skill directory copied beside it as soon as the target is known (before the session for a named target, at the session’s choice under auto), whose scripts every later call runs, a failed deployment’s --stop included; engine.log, what the engine did to the deployment; and workspace/, the solution’s working tree at the delivered commit, adapted and deployed, its own git repository. Each deployment is a full copy of the solution with its data: three deploys of a campaign with a large dataset hold it three times. A stopped deployment’s directory may be deleted; its open then refuses by name.
  • The identity. Each deployment has a name (<campaign>-<hash>-<n>, what the targets name their containers, apps and services after) and, when its target uses one, a port of this machine: the first nothing listened on when the deployment was allocated, from deployment.port_base within port_span. The port is probed, not held; the target’s deploy.sh binds it minutes later and fails naming it if something took it since. A second deployment leaves the first running under its own name and port.

env and options

--env KEY=VALUE (env={...}) are the variables the software needs at runtime: written to .env at the workspace root (owner-only; an existing file’s other lines kept), named but never valued in the session’s prompt, and set on every runtime the engine and the target’s scripts manage (the local worker, the container through --env-file, a Modal secret). Each value is taken verbatim, as docker’s --env-file takes it: no quotes removed, nothing expanded; a value with a line break is refused. The docker target keeps .env out of its image. A solution that carries its own .env has it loaded the same way, env or not. --option KEY=VALUE (options={...}) are for the target’s workflow: exported to its scripts as KAPSO_OPTION_<KEY>. The bundled targets read none; a harness target’s skill says which it takes (paper-trading takes schedule and cash).

Software

A function deployment runs in a worker process per handle: the module imports once, a raising function ends the worker (its traceback is the error) and the next call starts one again. It has no process of its own between handles, so --status and --start prove what they can, that the module imports in a worker of that call’s, and say so.

The verb’s lifecycle flags

--stop, --start and --logs act on --number, the highest by default; --status lists every deployment (a failed row carries its error, a deploying row the target requested), or the one --number names, and says so when the campaign has none yet. --stop and --start print the script’s own lines under theirs. One of the four at a time, and none of the deploy flags beside it. The summary after a deployment prints these lines pinned to the new number (with --config when one was passed), with the Python line, the proof call and the engine’s own answer to it, and the interpreter the function runs in; a deploy that fails prints the record’s path and the --stop line, since what its deploy script started may be running (a session under auto that named no target leaves nothing for --stop to run, and the line says so).

Deploying a harness build

On a build made with a harness, deploy() takes the harness from the campaign’s record (or the one you loaded, another version of the same name allowed) and stages its deployment module into the session: the page as guidance, its skills, servers and hooks. A harness that ships a target describes it in its own skill; see Write a target skill.

The config block

See Configuration.

What is refused, in one line

  • A build that delivered no candidate, or a campaign not checked out at the delivered candidate, or whose tracked files changed since (restore the delivered tree, or build again).
  • A target that is neither bundled nor the harness’s; a harness target on a build made without a harness.
  • A harness changed since it was loaded.
  • --env FOO (no value), a variable name that is not one, a value with a line break or a control character.
  • A deploy flag beside a lifecycle flag, --number on a deploy, two lifecycle flags at once.
  • A session cut at its deadline or failed to run; a result the engine could not accept after the session’s one resume. The record stays, with the reason and the way to stop what the deploy script started.
Related pages: Write a target skill · Review the result · Use a harness · Configuration · CLI · Python API Kapso is an open-source framework by Leeroo that builds software toward measurable goals through experiment campaigns. Source code: github.com/Leeroo-AI/kapso · Install: pip install leeroo-kapso · Every page as plain text: llms.txt.