Running CodeyBox in something resembling production. This is intentionally short — the framework is small.
- Linux host with KVM available (
/dev/kvm). - .NET 10 SDK if building from source; otherwise just the runtime.
- A sandbox provider — see
sandboxes.md. Quick start:- Recommended for persistent/high-throughput headless operation:
install Incus 6.3+ and configure an existing ZFS or Btrfs pool, then set
CodeyBox.SandboxProvider=incus. Its baseline clones are copy-on-write, avoiding a full multi-gigabyte image copy for every pass. Confirm the service identity, storage pool, and host compatibility described insandbox-providers.mdbefore installing. - Simplest setup or graphical workloads: install Multipass with
sudo snap install multipass, then runsudo scripts/setup-host-networks.shto create the network profile bridges + nftables rules. SetCodeyBox.SandboxProvider=multipass. Seehost-firewall.mdfor the network setup. - Single-package fallback (shared-kernel, dev-friendly):
sudo apt install bubblewrap, setCodeyBox.SandboxProvider=bubblewrap. No host firewall enforcement.
- Recommended for persistent/high-throughput headless operation:
install Incus 6.3+ and configure an existing ZFS or Btrfs pool, then set
giton the host (used byIGitHostfor cloning seeds and pushing upstream).- Service user with:
- Write access to
GitRootDirectoryandStateDatabasePathparents. - Access to
/dev/kvm(Multipass or Incus). - Membership in
incus-adminfor Incus, or permission to runmultipass. - No SSH or other host privileges beyond the above.
- Write access to
The repository ships gitignored helper scripts under local/ for
operator-side verification (local/setup-test-networks.sh,
local/verify-host-firewall.sh, local/verify-internet-only.sh,
local/teardown-test-networks.sh). Use these to confirm host-side
egress enforcement is working before running real prompts.
export CODEYBOX_CLAUDE_API_KEY=...
export CODEYBOX_GITHUB_TOKEN=... # if upstream is github
dotnet run --project src/CodeyBox.ApiThe service binds to the standard ASP.NET Core ports (http://localhost:5000
by default). Put a reverse proxy in front of it for TLS and auth.
- All state transitions log at
Information. Pipe to your usual log sink. - SQLite at
StateDatabasePathis the durable record. Backing this up is trivial (sqlite3 state.db ".backup state.db.bak"). - The host bare repos under
GitRootDirectoryare large but not load- bearing — they can be regenerated by re-running work items if the SQLite state survives.
Items in flight during a shutdown are not cancelled. They stay in their
mid-flight state and the reaper resets each one to a safe restart point on the
next startup, incrementing recoveryAttempts. After
CodeyBox:DeadWorker:MaxRecoveryAttempts recoveries (default 10) without
reaching a terminal state, an item lands in AbandonedAfterRecoveryAttempts and
waits for POST /workitems/{id}/retry.
Per-state resume points, the reaper's fencing rules, and the caller-facing
downtime window are in recovery.md.
The startup log tells you what happened:
INF Recovering abc123 from non-terminal state Working → Queued
(recovery attempt 1, presumed lost on prior shutdown)
Every phase is safe to re-run. Work and rework stack new commits on the existing work branch, or start a fresh one if the branch is gone; auditors are stateless against the working tree; a merge re-run against an already-merged base passes post-merge verification unchanged; and the upstream push is idempotent.
MaxConcurrentWorkers controls how many work items can be in the pipeline at
once. A single item can still create additional audit, merge, smoke, and
verification sandboxes, so host sizing should use
CodeyBox:WorkerPool:MaxConcurrentSandboxes as the VM ceiling. With Multipass
on KVM, plan for ~1 GB host RAM per admitted sandbox plus the agent's memory
needs.
- Agent produced no changes. Work phase fails with "Agent produced no changes to commit". Usually a too-narrow prompt.
- Audit didn't converge. After
MaxIterationsof rework the audit phase still has Error-severity findings; the work item flips toAuditFailed. Inspect the auditor findings on the record and decide whether to relax the audit policy, fix the prompt, or merge by hand. - Tests cannot run in the sandbox. Audit scoring only counts tests that
can run in the current audit environment; tests that cannot launch because
required local infrastructure is absent are not part of the scoring or
auditing criteria.
csharp:test-passfilters near-zero-duration failures with no stack trace while still reporting real assertion and runtime failures. - Merge phase verification failed. The agent ran but the orchestrator's
post-merge check (expected SHA / clean working tree) failed. The work
item flips to
Failed; nothing was pushed to the host bare repo's base branch. - Upstream push rejected. Often a branch protection rule (force-push blocked, required reviews). The local merge is still in place; either loosen the protection for the push user or move the upstream push behind a manual gate.
- VM can't reach allowed host. Check
nft list table inet codeyboxfor the resolved IPs and re-runsetup-host-networks.shif a CDN has rotated. Seehost-firewall.mdtroubleshooting. - NuGet restore fails with "unauthorized access" before any project builds.
Failed to read NuGet.Config due to unauthorized accessmeans the sandbox image has~/.nugetowned by another uid, so the build user cannot create the settings directory NuGet writes before it reads any repository config. CodeyBox's build gates self-heal around it; a harness invokingdotnetdirectly does not. Symptoms, the self-heal paths, and the provisioning fix are in../development/build-environment.md.
Two things to back up:
- The SQLite state DB.
- Any work item record you care about that hasn't completed (in-flight items). The bare repo can be regenerated by recloning from upstream; the work item record cannot.
Once a work item is Done and the upstream push has been mirrored
elsewhere (your normal repo backups), CodeyBox has no further state of
record. The bare repo can be deleted via
IGitHost.DisposeRepositoryAsync.