A containerized development stack described in one s-expression file: an Emacs console, Gendl engines on Clozure CL and SBCL, and a monitor. One command reads the file, starts the containers on a shared network, and writes MCP client configuration so an AI agent can evaluate code inside any of them.
The point is reproducibility. A hand-assembled engineering box exists only on the machine it was assembled on. A Basalt deployment is a file, so the same environment comes up on a laptop, on a rented server, or on fifty of them, and a colleague gets it by cloning a repository. It is infrastructure as code aimed at a target most such tooling was not built for: a live Lisp image a human and an agent share.
Clone the repository and start the deployment. Images are pulled as needed, each container receives a generated instance name, services are health-validated, and startup prints the roster with the ports each one actually publishes.
Deployment and instance names are generated per start — read yours off your own roster. The repository lives at gitlab.genworks.com/genworks/basalt, mirrored to github.com/genworks/basalt for public issues and pull requests.
A standard deployment is four services, each answering on its declared hostname. Which services a machine runs is declared in a file, not discovered by reading its history.
Additional services arrive by small configuration overlay repositories — licensed GDL Enterprise engines among them. The ingress (reverse proxy) and dashboard roles are typically filled by commercial binaries, licensed separately. A deployment comes up without either, and ports can be published directly.
Every full start is a new deployment under a freshly generated name; the previous name is retired to a log and never reused. Containers carry generated instance names of their own — a restart keeps a container's name, a recreate assigns a fresh one. So an environment is never confused with its predecessor, and a report names exactly which incarnation misbehaved.
Several deployments can share one host, each with its own compose project, network, and port offset. Service hostnames stay the same inside each deployment, so nothing configured against a service name needs to know which instance it runs in.
Startup generates MCP client registries covering every service the deployment declares — Claude Desktop, Claude Code, Codex, and Grok formats — through Lisply-MCP. An agent evaluates code in the running engines the same way you do at the REPL, and the console's own terminal agents come preconfigured with the identical service roster.