Code</>sensei is a thin orchestration layer. It does not host your application, run your database, or proxy your traffic. Everything runs on a server you control. The platform's job is to translate the high-level intent — "deploy this commit of that repository onto that server" — into a sequence of repeatable, inspectable shell operations on the target machine.
The agent model
Most platforms run an in-server agent process that polls a control plane. Code</>sensei does not. Instead, a background worker opens a transient SSH session to your server when there is work to do and disconnects when the work is finished. This has three consequences worth calling out.
First, there is no agent process to update, monitor, or accidentally break. The only software the platform leaves on your server are the release directories your deploys created and the systemd units it wrote to run them. If you cancel your account, those files keep running unchanged.
Second, there is no inbound connection from the platform to your server outside an active deploy window. The platform's worker is the client; your server is the server. SSH key authentication gates the session.
Third, every deploy is fully recorded. The full log of the SSH session, including stdin (commands run) and stdout/stderr (their output), is streamed to your browser in real time and persisted on the deployment row in the platform's database. There is no opaque agent behaviour — what you see in the log is exactly what ran.
Release layout on disk
Each deploy lands in a timestamped directory under a per-project root. The layout follows the Capistrano / Mina convention because it composes well with atomic symlink swaps:
/srv/codesensei/<project-slug>/
current -> releases/2026-05-21T14-32-08/
releases/
2026-05-21T14-32-08/ <-- newest, currently active
2026-05-20T18-04-55/ <-- previous, kept for rollback
2026-05-19T09-12-01/ <-- two deploys back
shared/
.env
media/
logs/
The current symlink is the only path your systemd unit
references. Activation is the single ln -snf call that
flips that symlink to the new release directory. Until that call, the
old release is still serving traffic; after it, the new release is.
There is no in-between half-deployed state.
The shared/ directory holds anything that must survive
across releases: the .env file, user-uploaded media, log
files. Code</>sensei symlinks those into each new release
directory at build time, so your application code does not need to be
aware of the release layout.
What the worker runs on the server
The deploy script is generated per-deploy from a Jinja2 blueprint that varies by the project's technology field. For a Django project on Debian, the rendered script does roughly the following:
- Create the new release directory under
/srv/codesensei/<slug>/releases/. git clone --depth 1 --branch <branch>the project repository into the release directory.- Create or reuse a Python virtual environment at
shared/venv/, thenpip install -r requirements.txt. - Symlink
shared/.env,shared/media/, andshared/logs/into the release directory. ./manage.py migrate --noinput../manage.py collectstatic --noinput.- Write the systemd unit at
/etc/systemd/system/<slug>.servicewith the rightEnvironmentFile,WorkingDirectory, and the gunicorn or uvicorn invocation appropriate to the project type. - Append the reverse-proxy block that maps the project's public hostname to the application socket and reload the edge proxy.
- Flip the
currentsymlink to the new release directory. systemctl restart <slug>.service.- Optionally prune old release directories beyond the configured retention (default: keep the last five).
Node.js deploys follow the same shape but substitute
npm ci / npm run build for the Python steps
and use PM2 or a systemd unit running node directly.
Failure handling
If any step in the script exits non-zero, the worker aborts the
deploy before flipping the current symlink. The
previous release is still serving traffic; from your application's
point of view, the failed deploy never happened. The platform's
deployment row is marked failed, the captured log is
persisted, and the partially-built release directory is left in place
so you can SSH in and inspect it.
If the systemd restart fails after the symlink flip (rare, usually a bad environment variable), the deploy is marked failed and the previous release directory still exists; rolling back is a single click and is fast because nothing needs to be rebuilt.
What runs where
| Component | Location | Role |
|---|---|---|
| Web app (this site) | codesensei.cloud | Orchestration, UI, billing, account state |
| Background worker | codesensei.cloud | Runs the actual SSH session that performs the deploy |
| Message broker | codesensei.cloud | Valkey/Redis on the same VM as the web app; queues deploys |
| Application | Your server | Your code, your data, your processes — we do not have a copy |
| Database | Your server (typically) | Whatever your project uses; we never connect to it |
The deploy queue
Clicking New deploy creates a deployment row in queued state and enqueues a background job. The job is picked up by the next available worker on the platform, which transitions the row to running, opens the SSH session, executes the deploy script, captures stdout/stderr line by line, and transitions the row to succeeded or failed when the script exits.
The queue is per-server-FIFO: only one deploy runs against any given server at a time. If you queue a second deploy while the first is still running, the new one waits in queued until its predecessor finishes. Queueing across different servers is concurrent — shipping ten unrelated apps at the same time is supported.
If a deploy job exceeds the platform-side timeout (default twenty
minutes, configurable per project), the worker terminates the SSH
session and marks the deployment row failed with a
timeout reason. The half-built release directory on your
server is left in place for inspection; the current
symlink has not moved.
Why "no in-server agent" matters
The agentless model has a few practical consequences worth calling out beyond the security framing in Security.
Upgrades cost nothing. When we add a new feature to the deploy script — say, automatic database backups before destructive migrations — every server inherits the new behaviour on its next deploy. There is no scheduled agent-version sweep, no failure mode in which half your servers are running the old version and half the new.
Servers can sit idle indefinitely. If you stop deploying for six months, nothing on your server changes. No agent is phoning home in the background to a control plane that may have moved. When you come back, the next deploy fires the platform's current worker against the unchanged server state and the platform handles any distribution upgrades in stride.
Air-gapped subnets work. If your server lives behind a firewall that only allows inbound SSH from a fixed allow-list and denies outbound traffic except for HTTPS to your Git provider, the platform's deploy model still works. The worker connects in, the server pulls code, the deploy completes, the connection closes. There is no persistent connection that needs to stay open through the firewall.