š Triangle of Art
"Inscribe. Illuminate. Banish."
The Triangle of Art is a hardened Docker-based sandbox designed for summoning and containing LLM coding agents (Aider, Claude, Qwen, Gemini, and Codex). It provides a restricted environment where these entities can execute code, run tests, and manipulate files without escaping their tether or accessing the Magician's host filesystem.
ā„ The Philosophy
This Grimoire exists because the Magician understands the true nature of the forces we wield.
- Containment of Volatile Ethers: The ecosystem of
npm is vast but treacherous. To execute its scripts directly on the host machine is to invite chaos into one's home.
- Binding the Spirits: LLM Agents are powerful, yet unpredictable entities. Like the Djinn of old, they are capricious. They must be strictly bound within a hardened vessel (Docker) lest they wreak havoc on the summoner's filesystem.
- The Solomonic Metaphor: We are the modern Solomons. We trap these spirits in a vessel and command them to build our temples (software). The Triangle of Art is that vesselāpolished, secure, and inescapable.
- The Gathering: This circle was cast not just for one spirit (Gemini), but to compare and command them allāAider, Claude, and their kināunder a single, unified law.
ā„ The Wards (Security Model)
Unlike standard containers, the Triangle employs Recursive Containment:
- The Veil (pre-commit): Automated hooks scan every commit to ensure no "True Names" (API keys) or private SSH secrets leak into the grimoire's history.
- The Pact (Resource Limits): CPU and Memory are strictly bound by
Perimeter to prevent the entity from consuming the host's life-force (system resources).
- The Binding: Filesystem access is limited to the mounted workspace and pact directories, with UID/GID mirroring so the container runs as the host user.
- The Socket (Opt-In): Host Docker access is disabled by default. Set
DOCKER_SOCK_PATH=/var/run/docker.sock in .env only if you intentionally need it.
- The Veil of Locality: Serena's MCP and dashboard ports are bound to
127.0.0.1 by default.
- The Rootless Forge (Opt-In): Use the
dind-rootless profile and DOCKER_HOST=tcp://dind-rootless:2375 for Docker-in-Docker without mounting the host socket.
- Host support required: user namespaces enabled,
/etc/subuid + /etc/subgid entries for your user, cgroup v2, and newuidmap, newgidmap, slirp4netns, fuse-overlayfs installed.
Rootless Docker-in-Docker (Host Prep)
On default Ubuntu, unprivileged user namespaces are typically enabled already.
Ubuntu 24.04+ Specifics
On Ubuntu 24.04 and newer, AppArmor restricts unprivileged user namespaces by default. You must disable this restriction:
-
Temporarily disable the restriction:
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
-
Make it permanent:
echo "kernel.apparmor_restrict_unprivileged_userns=0" | sudo tee /etc/sysctl.d/60-apparmor-namespace.conf
General Requirements
To enable the remaining requirements:
- Install required helpers:
sudo apt-get update
sudo apt-get install -y uidmap slirp4netns fuse-overlayfs
- Ensure subuid/subgid mappings exist for your user:
echo "$(id -un):100000:65536" | sudo tee -a /etc/subuid /etc/subgid
Log out and back in after changing these files.
- Verify cgroup v2:
stat -fc %T /sys/fs/cgroup
If this is not cgroup2fs, rootless Docker may not work. Enabling cgroup v2 requires a host configuration change (systemd/kernel cmdline); only do this if it matches your security policy.
- Confirm support:
cat /proc/sys/kernel/unprivileged_userns_clone
command -v newuidmap newgidmap slirp4netns fuse-overlayfs
ā„ The Rituals
1. Consecration
Prepare your host environment, create the cache chambers, and install the protective hooks. Requires docker and python3; uses uv or pip to install pre-commit if needed.
./invoke consecrate
Tip: Say "Yes" when asked to add invoke to your PATH. This lets you run rituals from anywhere.
2. The Inscription
Build the manifestation's physical form by pulling the necessary tools and layers.
./invoke inscribe
3. Illumination
Wake the spirit and light the Triangle. This starts the manifestation.
./invoke illuminate
4. Communion
Engage with the entities through their specific channels.
./invoke commune
./invoke Aider
./invoke Claude
./invoke Codex
./invoke Gemini
./invoke Qwen
./invoke Serena
5. The Familiars (MCP Servers)
The Triangle hosts powerful spirits known as Model Context Protocols (MCP) servers to assist the coding agents.
Serena
Serena runs as an MCP server inside its own container. It is enabled by default when you illuminate the Triangle.
./invoke Serena
Default endpoints:
Inside the vessel, assistants connect to Serena at:
The Serena container config is stored in Pacts/Serena/serena_config.yml.
The logs are kept in .residue/serena/logs.
Context7
A documentation and knowledge retrieval spirit.
Inside the vessel, assistants can connect to Context7 at:
Git
A spirit that grants direct control over the repository's version history.
Inside the vessel, assistants can connect to the Git server at:
Note: The consecrate ritual automatically configures the agents to speak with all available spirits (Serena, Context7, and Git).
Template MCP client configs are created in Pacts/* during consecration.
If your client expects a different MCP config format, update the corresponding file.
ā„ The Rituals on macOS
For those practicing the Art on macOS, the path requires the Docker Desktop talisman.
0. Preparation
The Triangle requires Docker. On macOS, install Docker Desktop (Intel or Apple Silicon as appropriate).
- Verify installation with
docker version and docker compose version.
- Ensure
git is installed (xcode-select --install).
1. The Invocation
Clone the grimoire and enter the circle:
git clone https://gitlab.com/alex.gosselin/triangle-of-art.git
cd triangle-of-art
chmod +x invoke
2. Execution
Follow the standard rituals:
./invoke consecrate - Prepares the environment.
./invoke inscribe - Builds the vessel.
- Note: This downloads base images and may take time.
./invoke illuminate - Starts the manifestation.
- Note: Uses a lightweight Linux VM; expect some resource usage.
3. Communion
Talk to the spirits:
./invoke Claude # or Aider, Gemini, etc.
4. Banishment
Cleanly shut down:
./invoke banish
ā„ Casting the Circle (Custom Workspace)
By default, the spirits are bound to the local ./The Circle directory. To manifest the environment onto a different project folder on your host machine, use the --circle (or -c) option:
# Bind the vessel to a specific project directory
./invoke illuminate -c "/path/to/your/other/project"
# Or using the long flag
./invoke illuminate --circle "/path/to/your/other/project"
What this does:
- Mounts your specified path to /home/vassal/project inside the vessel.
- Ensures all tools (Aider, Claude, etc.) operate within that directory.
- Persistent history and "residue" (logs/caches) remain stored in your central .residue folder, keeping the project folder clean.
ā„ Customizing the Manifestation
The rituals can be customized using CLI flags or by passing arguments directly to the underlying Docker commands.
1. Custom Compose File
If you have a customized Perimeter file, you can specify it using the --file (or -f) option:
./invoke illuminate -f "CustomPerimeter.yml"
2. Passing Arguments to Inscribe
You can pass flags like --no-cache or --pull directly to the inscribe ritual:
./invoke inscribe --no-cache
To enable passwordless sudo inside the container (opt-in), rebuild with:
./invoke inscribe --enable-sudo
3. Passing Arguments to Illuminate
Similarly, you can pass flags like --force-recreate or --build to the illuminate ritual:
./invoke illuminate --force-recreate
ā„ The Grimoire Structure
| Component | Ritual Object | Purpose |
|---|
| Inscription | Dockerfile | The blueprints for the manifestation's body. |
| Perimeter | docker-compose | Defines the boundaries of the manifestation zone. |
| Grimoire | Makefile | The master list of executable rituals and incantations. |
| Pacts/ | Agent configs | Per-agent config folders mounted into the vessel. |
| The Circle/ | Workspace | The only physical space the Vassal is allowed to touch. |
| .residue/ | Cache store | The temporary energy left behind by manifestations. |
| .env | Secrets | API keys used by the summoned entities. |
| The Veil | pre-commit | .pre-commit-config.yaml + .secrets.baseline. |
| .gitlab-ci.yml | CI ritual | Builds the vessel in GitLab CI. |
ā„ The Pact (System Prompt)
Hidden within Pacts/The Pact lies a template system prompt. This scroll contains instructions for the spirits, listing the available MCP tools and operational guidelines.
It is not active by default, to avoid overriding project-specific instructions.
To bind the spirits to this Pact:
ln -s Pacts/The\ Pact AGENTS.md
# Or for specific spirits:
ln -s Pacts/The\ Pact CLAUDE.md
Note: This creates a symbolic link in your project root. If you wish to customize the instructions, delete the link and create your own AGENTS.md.
ā„ Extending the Grimoire
This Triangle is a foundation, meant to be built upon. You are encouraged to summon new spirits (MCP servers), inscribe new tools, and refine the rituals.
See CONTRIBUTING.md for instructions on how to extend the Triangle and share your discoveries.
ā„ Banishment
When the work is done, you must clear the circle to ensure no residue remains. This wipes the temporary caches and destroys the manifestation.
./invoke banish
ā„ The Final Covenant
This grimoire is licensed under the JSON License.
"The Software shall be used for Good, not Evil."
By invoking these scripts and illuminating the Triangle, the Magician agrees to this pact. Those who intend to use these spirits for malice will find the wards of this repository turned against them.